Huge update (again)
This commit is contained in:
parent
ff1692be90
commit
9d43c1c90e
178
api.lua
178
api.lua
@ -1,128 +1,78 @@
|
||||
local FUEL_EFFICIENCY = 3 -- How many moves can the turtle do with a second of fuel
|
||||
|
||||
local MOVE_COST = 100
|
||||
local FUEL_EFFICIENCY = 300
|
||||
tl = {}
|
||||
local function getv(dir)
|
||||
if dir==0 then return {x=0,y=0,z=1}
|
||||
elseif dir==1 then return {x=1,y=0,z=0}
|
||||
elseif dir==2 then return {x=0,y=0,z=-1}
|
||||
elseif dir==3 then return {x=-1,y=0,z=0} end
|
||||
end
|
||||
|
||||
local function turtle_can_go(nname)
|
||||
return nname == "air" or minetest.registered_nodes[nname].liquidtype ~= "none"
|
||||
local function tl_move(turtle, cptr, dir)
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
if info.energy < MOVE_COST then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local spos = info.spos
|
||||
local npos = vector.add(spos, dir)
|
||||
if minetest.get_node(npos).name == "air" then
|
||||
minetest.set_node(npos, {name = "turtle:turtle2"})
|
||||
info.npos = npos
|
||||
info.moving = true
|
||||
info.energy = info.energy - MOVE_COST
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
else
|
||||
cptr.X = 0
|
||||
end
|
||||
end
|
||||
|
||||
function tl.forward(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
if info.fuel == 0 then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local spos = info.spos
|
||||
local dir = info.dir
|
||||
local npos = vector.add(spos, getv(dir))
|
||||
if turtle_can_go(minetest.get_node(npos).name) then
|
||||
info.npos = npos
|
||||
info.moving = true
|
||||
info.fuel = info.fuel - 1
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
else
|
||||
cptr.X = 0
|
||||
end
|
||||
local dir = turtles.get_turtle_info(turtle).dir
|
||||
tl_move(turtle, cptr, minetest.facedir_to_dir(dir))
|
||||
end
|
||||
|
||||
function tl.backward(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
if info.fuel == 0 then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local spos = info.spos
|
||||
local dir = info.dir
|
||||
local npos = vector.add(spos, getv((dir+2)%4))
|
||||
if turtle_can_go(minetest.get_node(npos).name) then
|
||||
info.npos = npos
|
||||
info.moving = true
|
||||
info.fuel = info.fuel - 1
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
else
|
||||
cptr.X = 0
|
||||
end
|
||||
local dir = turtles.get_turtle_info(turtle).dir
|
||||
tl_move(turtle, cptr, vector.multiply(minetest.facedir_to_dir(dir), -1))
|
||||
end
|
||||
|
||||
function tl.up(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
if info.fuel == 0 then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local spos = info.spos
|
||||
local npos = vector.add(spos, {x=0, y=1, z=0})
|
||||
if turtle_can_go(minetest.get_node(npos).name) then
|
||||
info.npos = npos
|
||||
info.moving = true
|
||||
info.fuel = info.fuel - 1
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
else
|
||||
cptr.X = 0
|
||||
end
|
||||
tl_move(turtle, cptr, {x = 0, y = 1, z = 0})
|
||||
end
|
||||
|
||||
function tl.down(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
if info.fuel == 0 then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local spos = info.spos
|
||||
local npos = vector.add(spos, {x=0, y=-1, z=0})
|
||||
if turtle_can_go(minetest.get_node(npos).name) then
|
||||
info.npos = npos
|
||||
info.moving = true
|
||||
info.fuel = info.fuel - 1
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
else
|
||||
cptr.X = 0
|
||||
end
|
||||
tl_move(turtle, cptr, {x = 0, y = -1, z = 0})
|
||||
end
|
||||
|
||||
function tl.turnleft(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
info.ndir = (info.dir+3)%4
|
||||
info.rotate = math.pi/2
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
info.ndir = (info.dir + 3) % 4
|
||||
info.rotate = math.pi / 2
|
||||
info.moving = true
|
||||
cptr.paused = true
|
||||
end
|
||||
|
||||
function tl.turnright(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
info.ndir = (info.dir+1)%4
|
||||
info.rotate = -math.pi/2
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
info.ndir = (info.dir + 1) % 4
|
||||
info.rotate = - math.pi / 2
|
||||
info.moving = true
|
||||
cptr.paused = true
|
||||
end
|
||||
|
||||
local function write_string_at(cptr, addr, str)
|
||||
for i=1, string.len(str) do
|
||||
cptr[u16(addr-1+i)] = string.byte(str, i)
|
||||
for i = 1, string.len(str) do
|
||||
cptr[u16(addr - 1 + i)] = string.byte(str, i)
|
||||
end
|
||||
cptr.X = string.len(str)
|
||||
end
|
||||
|
||||
local function turtle_detect(turtle, cptr, dir)
|
||||
local info = get_turtle_info(turtle)
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
local pos = vector.add(info.spos, dir)
|
||||
local name = minetest.get_node(pos).name
|
||||
write_string_at(cptr, cptr.X, name)
|
||||
end
|
||||
|
||||
function tl.detect(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
turtle_detect(turtle, cptr, getv(info.dir))
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
turtle_detect(turtle, cptr, minetest.facedir_to_dir(info.dir))
|
||||
end
|
||||
|
||||
function tl.detectup(turtle, cptr)
|
||||
@ -134,27 +84,12 @@ function tl.detectdown(turtle, cptr)
|
||||
end
|
||||
|
||||
local function turtle_dig(turtle, cptr, dir)
|
||||
local info = get_turtle_info(turtle)
|
||||
local dpos = vector.add(info.spos, dir)
|
||||
local dnode = minetest.get_node(dpos)
|
||||
if turtle_can_go(dnode.name) or dnode.name == "ignore" then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local drops = minetest.get_node_drops(dnode.name, "default:pick_mese")
|
||||
local _, dropped_item
|
||||
for _, dropped_item in ipairs(drops) do
|
||||
local leftover = turtle_invs:add_item(turtle,dropped_item)
|
||||
minetest.add_item(info.spos,leftover)
|
||||
end
|
||||
minetest.remove_node(dpos)
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
-- TODO
|
||||
end
|
||||
|
||||
function tl.dig(turtle, cptr)
|
||||
local info = get_turtle_info(turtle)
|
||||
turtle_dig(turtle, cptr, getv(info.dir))
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
turtle_dig(turtle, cptr, minetest.facedir_to_dir(info.dir))
|
||||
end
|
||||
|
||||
function tl.digup(turtle, cptr)
|
||||
@ -166,28 +101,12 @@ function tl.digdown(turtle, cptr)
|
||||
end
|
||||
|
||||
local function turtle_place(turtle, cptr, dir, slot)
|
||||
local info = get_turtle_info(turtle)
|
||||
local ppos = vector.add(info.spos, dir)
|
||||
local dnode = minetest.get_node(ppos)
|
||||
if (not turtle_can_go(dnode.name)) or dnode.name == "ignore" then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
local stack = turtle_invs:get_stack(turtle, slot)
|
||||
if stack:is_empty() or minetest.registered_nodes[stack:get_name()] == nil then
|
||||
cptr.X = 0
|
||||
return
|
||||
end
|
||||
minetest.set_node(ppos, {name=stack:get_name()})
|
||||
stack:take_item()
|
||||
turtle_invs:set_stack(turtle, slot, stack)
|
||||
cptr.X = u16(-1)
|
||||
cptr.paused = true
|
||||
-- TODO
|
||||
end
|
||||
|
||||
function tl.place(turtle, cptr, slot)
|
||||
local info = get_turtle_info(turtle)
|
||||
turtle_place(turtle, cptr, getv(info.dir), slot)
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
turtle_place(turtle, cptr, minetest.facedir_to_dir(info.dir), slot)
|
||||
end
|
||||
|
||||
function tl.placeup(turtle, cptr, slot)
|
||||
@ -200,13 +119,16 @@ end
|
||||
|
||||
local function stack_set_count(stack, count)
|
||||
stack = stack:to_table()
|
||||
if stack==nil then return nil end
|
||||
stack.count=count
|
||||
if stack == nil then return nil end
|
||||
stack.count = count
|
||||
return ItemStack(stack)
|
||||
end
|
||||
|
||||
function tl.refuel(turtle, cptr, slot, nmax)
|
||||
local info = get_turtle_info(turtle)
|
||||
-- TODO: update that
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
info.energy = info.energy + 100 * MOVE_COST
|
||||
--[[local info = get_turtle_info(turtle)
|
||||
local stack = turtle_invs:get_stack(turtle, slot)
|
||||
local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = {stack}})
|
||||
if fuel.time <= 0 then
|
||||
@ -235,5 +157,5 @@ function tl.refuel(turtle, cptr, slot, nmax)
|
||||
turtle_invs:set_stack(turtle, slot, stack)
|
||||
end
|
||||
info.fuel = info.fuel+FUEL_EFFICIENCY*count*fuel.time
|
||||
cptr.X = u16(FUEL_EFFICIENCY*count*fuel.time)
|
||||
cptr.X = u16(FUEL_EFFICIENCY*count*fuel.time)]]
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
function create_cptr_memory()
|
||||
tbl = {}
|
||||
for i=0, 65535 do tbl[i] = 0 end
|
||||
local tbl = {}
|
||||
for i = 0, 65535 do tbl[i] = 0 end
|
||||
tbl[0xff00] = 0x4d
|
||||
tbl[0xff01] = 0x2a
|
||||
tbl[0xff02] = 0xff
|
||||
|
16
cptr.lua
16
cptr.lua
@ -10,8 +10,8 @@ local function file_exists(name)
|
||||
return false
|
||||
end
|
||||
|
||||
function loadpkg(na)
|
||||
local modpath = minetest.get_modpath("forth_computer")
|
||||
local function loadpkg(na)
|
||||
local modpath = minetest.get_modpath("turtle")
|
||||
local ol = package.cpath
|
||||
local sp
|
||||
if file_exists(modpath.."/INIT.LUA") then
|
||||
@ -21,7 +21,7 @@ function loadpkg(na)
|
||||
else
|
||||
sp = {modpath.."/?.so.32", modpath.."/?.so.64"}
|
||||
end
|
||||
for i=1,#sp do
|
||||
for i=1, #sp do
|
||||
package.cpath = sp[i]
|
||||
e, lib = pcall(require, na)
|
||||
package.cpath = ol
|
||||
@ -157,13 +157,13 @@ dofile(modpath.."/api.lua")
|
||||
|
||||
function run_computer(turtle, cptr)
|
||||
if cptr.stopped then return end
|
||||
cptr.cycles = math.max(MAX_CYCLES,cptr.cycles+CYCLES_PER_STEP)
|
||||
while 1 do
|
||||
cptr.cycles = math.max(MAX_CYCLES, cptr.cycles + CYCLES_PER_STEP)
|
||||
while true do
|
||||
instr = cptr[cptr.PC]
|
||||
local f = ITABLE[instr]
|
||||
if f == nil then return end
|
||||
cptr.PC = bit32.band(cptr.PC+1, 0xffff)
|
||||
setfenv(f, {cptr = cptr, turtle=turtle, receive=receive, delete_message=delete_message, set_channel=set_channel, send_message=send_message, u16=u16, u32=u32, s16=s16, s32=s32, read=read, write=write, readC=readC, writeC=writeC, push=push, pop=pop, rpush=rpush, rpop=rpop, bit32=bit32, math=math, tl=tl})
|
||||
cptr.PC = u16(cptr.PC + 1)
|
||||
setfenv(f, {cptr = cptr, turtle = turtle, receive = receive, delete_message = delete_message, set_channel = set_channel, send_message = send_message, u16 = u16, u32 = u32, s16 = s16, s32 = s32, read = read, write = write, readC = readC, writeC = writeC, push = push, pop = pop, rpush = rpush, rpop = rpop, bit32 = bit32, math = math, tl = tl})
|
||||
f()
|
||||
cptr.cycles = cptr.cycles - 1
|
||||
if cptr.paused or cptr.cycles <= 0 then
|
||||
@ -315,7 +315,7 @@ for i, v in pairs(ITABLE_RAW) do
|
||||
end
|
||||
|
||||
function on_computer_digiline_receive(turtle, channel, msg)
|
||||
local info = get_turtle_info(turtle)
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
local cptr = info.cptr
|
||||
cptr.digiline_events[channel] = msg
|
||||
end
|
||||
|
21
db.lua
Normal file
21
db.lua
Normal file
@ -0,0 +1,21 @@
|
||||
db = {}
|
||||
|
||||
local worldpath = minetest.get_worldpath() .. "/"
|
||||
function db.read_file(filename)
|
||||
local file = io.open(worldpath .. filename, "r")
|
||||
if file == nil then
|
||||
return {}
|
||||
end
|
||||
local contents = file:read("*all")
|
||||
file:close()
|
||||
if contents == "" or contents == nil then
|
||||
return {}
|
||||
end
|
||||
return minetest.deserialize(contents)
|
||||
end
|
||||
|
||||
function db.write_file(filename, data)
|
||||
local file = io.open(worldpath .. filename, "w")
|
||||
file:write(minetest.serialize(data))
|
||||
file:close()
|
||||
end
|
@ -165,7 +165,6 @@ FORTH
|
||||
: HEX 16 BASE ! ;
|
||||
: DECIMAL 10 BASE ! ;
|
||||
: TUCK SWAP OVER ;
|
||||
: NIP SWAP DROP ;
|
||||
: ABS DUP 0< IF NEGATE THEN ;
|
||||
: (marker) LATEST ! (here) ! ;
|
||||
: TYPE DUP 0> IF OVER + SWAP ?DO I C@ EMIT LOOP ELSE 2DROP THEN ;
|
||||
|
12
init.lua
12
init.lua
@ -1,6 +1,10 @@
|
||||
turtles = {}
|
||||
|
||||
local modpath = minetest.get_modpath("turtle")
|
||||
--dofile(modpath.."/turtle.lua")
|
||||
dofile(modpath.."/computer_memory.lua")
|
||||
dofile(modpath.."/forth_floppy.lua")
|
||||
dofile(modpath.."/cptr.lua")
|
||||
dofile(modpath.."/t.lua")
|
||||
dofile(modpath .. "/db.lua")
|
||||
dofile(modpath .. "/computer_memory.lua")
|
||||
dofile(modpath .. "/forth_floppy.lua")
|
||||
dofile(modpath .. "/cptr.lua")
|
||||
dofile(modpath .. "/screen.lua")
|
||||
dofile(modpath .. "/t2.lua")
|
||||
|
60
screen.lua
Normal file
60
screen.lua
Normal file
@ -0,0 +1,60 @@
|
||||
screen = {}
|
||||
|
||||
local MAX_LINE_LENGTH = 28
|
||||
local function lines(str)
|
||||
local t = {}
|
||||
local function helper(line) table.insert(t, line) return "" end
|
||||
helper((str:gsub("(.-)\r?\n", helper)))
|
||||
return t
|
||||
end
|
||||
|
||||
local function newline(text, toadd)
|
||||
local f = lines(text)
|
||||
table.insert(f, toadd)
|
||||
return table.concat(f, "\n", 2)
|
||||
end
|
||||
|
||||
local function add_char(text, char)
|
||||
local ls = lines(text)
|
||||
local ll = ls[#ls]
|
||||
if char == "\n" or char == "\r" then
|
||||
return newline(text, "")
|
||||
elseif string.len(ll) >= MAX_LINE_LENGTH then
|
||||
return newline(text, char)
|
||||
else
|
||||
return text .. char
|
||||
end
|
||||
end
|
||||
|
||||
local function escape(text)
|
||||
-- Remove all \0's in the string, that cannot be done using string.gsub as there can't be \0's in a pattern
|
||||
text2 = ""
|
||||
for i=1, string.len(text) do
|
||||
if string.byte(text, i) ~= 0 then text2 = text2 .. string.sub(text, i, i) end
|
||||
end
|
||||
return minetest.formspec_escape(text2)
|
||||
end
|
||||
|
||||
function screen.new()
|
||||
return "\n\n\n\n\n\n\n\n\n\n"
|
||||
end
|
||||
|
||||
function screen.add_text(text, toadd)
|
||||
for i = 1, string.len(toadd) do
|
||||
text = add_char(text, string.sub(toadd, i, i))
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
function screen.create_text_formspec(text, basex, basey)
|
||||
local f = lines(text)
|
||||
s = ""
|
||||
i = basey - 0.25
|
||||
for _,x in ipairs(f) do
|
||||
s = s .. "]label[" .. basex .. "," .. tostring(i) .. ";" .. escape(x)
|
||||
i = i + 0.3
|
||||
end
|
||||
s = s .. "]field[" .. tostring(basex + 0.3) .. "," .. tostring(i + 0.4) .. ";4.4,1;f;;]"
|
||||
return s:sub(2, -1)
|
||||
end
|
||||
|
347
t2.lua
Normal file
347
t2.lua
Normal file
@ -0,0 +1,347 @@
|
||||
local DEBUG = true
|
||||
|
||||
-------------------------
|
||||
-- Read data from file --
|
||||
-------------------------
|
||||
|
||||
local turtle_infos = db.read_file("turtle_infos")
|
||||
local floppies = db.read_file("floppies")
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
for id, info in pairs(turtle_infos) do
|
||||
info.turtle = nil
|
||||
info.playernames = {}
|
||||
end
|
||||
db.write_file("turtle_infos", turtle_infos)
|
||||
db.write_file("floppies", floppies)
|
||||
end)
|
||||
|
||||
function turtles.get_turtle_info(turtle_id)
|
||||
if turtle_infos[turtle_id] == nil then
|
||||
turtle_infos[turtle_id] = {}
|
||||
end
|
||||
return turtle_infos[turtle_id]
|
||||
end
|
||||
|
||||
function turtles.get_turtle_inventory(turtle_id)
|
||||
local info = turtles.get_turtle_info(turtle_id)
|
||||
return minetest.get_meta(info.spos):get_inventory()
|
||||
end
|
||||
|
||||
function turtles.create_turtle_id()
|
||||
return #turtle_infos + 1
|
||||
end
|
||||
|
||||
function turtles.create_floppy_id()
|
||||
return #floppies + 1
|
||||
end
|
||||
|
||||
function turtles.update_formspec(turtle_id)
|
||||
local info = turtles.get_turtle_info(turtle_id)
|
||||
local pos = info.spos
|
||||
local formspec = "size[9,10]"..
|
||||
screen.create_text_formspec(info.screen, 0, 0)..
|
||||
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;4.8,0;4,4;]"..
|
||||
"image_button[1,4.6;2.5,1;turtle_execute.png;reboot;]"..
|
||||
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";floppy;0,4.6;1,1;]"..
|
||||
"list[current_player;main;0.5,6;8,4;]"
|
||||
if info.formspec ~= formspec then
|
||||
info.formspec = formspec
|
||||
info.formspec_changed = true
|
||||
end
|
||||
end
|
||||
|
||||
local function on_screen_digiline_receive(turtle, channel, msg)
|
||||
if channel == "screen" then
|
||||
local info = turtles.get_turtle_info(turtle)
|
||||
info.screen = screen.add_text(info.screen, msg)
|
||||
turtles.update_formspec(turtle)
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_floppy_meta(stack)
|
||||
if stack.metadata == "" or stack.metadata == nil then
|
||||
local id = turtles.create_floppy_id()
|
||||
stack.metadata = tostring(id)
|
||||
floppies[id] = string.rep(string.char(0), 16384)
|
||||
return floppies[id], true
|
||||
elseif string.len(stack.metadata) >= 1000 then
|
||||
local id = turtles.create_floppy_id()
|
||||
floppies[id] = stack.metadata
|
||||
stack.metadata = tostring(id)
|
||||
return floppies[id], true
|
||||
else
|
||||
if floppies[tonumber(stack.metadata)] == nil then
|
||||
floppies[tonumber(stack.metadata)] = string.rep(string.char(0), 16384)
|
||||
end
|
||||
return floppies[tonumber(stack.metadata)], false
|
||||
end
|
||||
end
|
||||
|
||||
local function set_floppy_contents(name, contents)
|
||||
floppies[tonumber(name)] = contents
|
||||
end
|
||||
|
||||
function on_disk_digiline_receive(turtle_id, channel, msg)
|
||||
if channel == "boot" then
|
||||
if string.len(msg) ~= 1 and string.len(msg) ~= 65 then return end -- Invalid message, it comes probably from the disk itself
|
||||
local page = string.byte(msg, 1)
|
||||
if page == nil then return end
|
||||
local inv = turtles.get_turtle_inventory(turtle_id)
|
||||
local stack = inv:get_stack("floppy", 1):to_table()
|
||||
if stack == nil then return end
|
||||
if stack.name ~= "turtle:floppy" then return end
|
||||
local floppy_contents, update = handle_floppy_meta(stack)
|
||||
if update then
|
||||
inv:set_stack("floppy", 1, ItemStack(stack))
|
||||
end
|
||||
msg = string.sub(msg, 2, -1)
|
||||
if string.len(msg) == 0 then -- read
|
||||
turtle_receptor_send(turtle_id, channel,
|
||||
string.sub(floppy_contents, page * 64 + 1, page * 64 + 64))
|
||||
else -- write
|
||||
floppy_contents = string.sub(floppy_contents, 1, page * 64) ..
|
||||
msg ..
|
||||
string.sub(floppy_contents, page * 64 + 65, -1)
|
||||
set_floppy_contents(stack.metadata, floppy_contents)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_craftitem("turtle:floppy", {
|
||||
description = "Floppy disk",
|
||||
inventory_image = "floppy.png",
|
||||
stack_max = 1,
|
||||
})
|
||||
|
||||
local progs = {
|
||||
["Empty"] = string.rep(string.char(0), 16536),
|
||||
["Forth Boot Disk"] = create_forth_floppy(),
|
||||
}
|
||||
|
||||
minetest.register_node("turtle:floppy_programmator",{
|
||||
description = "Floppy disk programmator",
|
||||
tiles = {"floppy_programmator_top.png", "floppy_programmator_bottom.png", "floppy_programmator_right.png",
|
||||
"floppy_programmator_left.png", "floppy_programmator_back.png", "floppy_programmator_front.png"},
|
||||
groups = {cracky = 3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("floppy", 1)
|
||||
meta:set_int("selected", 1)
|
||||
local s = "size[8,5.5;]" ..
|
||||
"dropdown[0,0;5;pselector;"
|
||||
for key, _ in pairs(progs) do
|
||||
s = s .. key .. ","
|
||||
end
|
||||
s = string.sub(s, 1, -2)
|
||||
s = s .. ";1]" ..
|
||||
"button[5,0;2,1;prog;Program]" ..
|
||||
"list[current_name;floppy;7,0;1,1;]" ..
|
||||
"list[current_player;main;0,1.5;8,4;]"
|
||||
meta:set_string("formspec", s)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("floppy")
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if stack:get_name() == "turtle:floppy" then return 1 end
|
||||
return 0
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.prog then
|
||||
local inv = meta:get_inventory()
|
||||
local prog = progs[fields.pselector]
|
||||
local stack = inv:get_stack("floppy", 1):to_table()
|
||||
if stack == nil then return end
|
||||
if stack.name ~= "turtle:floppy" then return end
|
||||
local contents, update = handle_floppy_meta(stack)
|
||||
set_floppy_contents(stack.metadata, prog)
|
||||
if update then
|
||||
inv:set_stack("floppy", 1, ItemStack(stack))
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
function turtle_receptor_send(turtle, channel, msg)
|
||||
on_screen_digiline_receive(turtle, channel, msg)
|
||||
on_computer_digiline_receive(turtle, channel, msg)
|
||||
on_disk_digiline_receive(turtle, channel, msg)
|
||||
--on_turtle_command_receive(turtle, channel, msg)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname:sub(1, 7) ~= "turtle:" then return end
|
||||
local turtle_id = tonumber(formname:sub(8, -1))
|
||||
if fields.f ~= nil and fields.f ~= "" then
|
||||
if string.len(fields.f) > 80 then
|
||||
fields.f = string.sub(fields.f, 1, 80)
|
||||
end
|
||||
turtle_receptor_send(turtle_id, "screen", fields.f)
|
||||
turtles.update_formspec(turtle_id)
|
||||
return
|
||||
end
|
||||
if fields.reboot then
|
||||
local info = turtles.get_turtle_info(turtle_id)
|
||||
info.cptr = create_cptr()
|
||||
return
|
||||
end
|
||||
if fields.quit then
|
||||
local info = turtles.get_turtle_info(turtle_id)
|
||||
info.playernames[player:get_player_name()] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_node("turtle:turtle", {
|
||||
description = "Turtle",
|
||||
drawtype = "airlike",
|
||||
inventory_image = "turtle_turtle_inv.png",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
after_place_node = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("floppy", 1)
|
||||
inv:set_size("main", 8 * 4)
|
||||
inv:set_size("craft", 3 * 3)
|
||||
inv:set_size("craft_output", 1)
|
||||
local id = turtles.create_turtle_id()
|
||||
meta:set_int("turtle_id", id)
|
||||
local info = turtles.get_turtle_info(id)
|
||||
info.spos = vector.new(pos)
|
||||
info.dir = 0
|
||||
info.energy = 0
|
||||
info.screen = screen.new()
|
||||
info.cptr = create_cptr()
|
||||
info.playernames = {}
|
||||
turtles.update_formspec(id)
|
||||
local le = minetest.add_entity(pos, "turtle:turtle"):get_luaentity()
|
||||
info.turtle = le
|
||||
le.turtle_id = id
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("turtle:turtle2", {
|
||||
description = "turtle:turtle2 (You hacker you)",
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
drawtype = "airlike",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
})
|
||||
|
||||
local function done_move(pos, spos, npos)
|
||||
return vector.dot(vector.subtract(npos, spos),
|
||||
vector.subtract(npos, pos)) <= 0
|
||||
end
|
||||
|
||||
local function done_rotation(yaw, nyaw, rotate_speed)
|
||||
return (nyaw - yaw + rotate_speed - math.pi / 2) % (2 * math.pi) < math.pi
|
||||
end
|
||||
|
||||
minetest.register_entity("turtle:turtle", {
|
||||
physical = true,
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
collides_with_objects = false,
|
||||
visual = "wielditem", -- TODO: change that to a mesh, and add animations
|
||||
visual_size = {x = 2/3, y = 2/3},
|
||||
textures = {"default:wood"},
|
||||
on_activate = function(self, staticdata)
|
||||
local id = tonumber(staticdata)
|
||||
if id ~= nil then
|
||||
self.turtle_id = id
|
||||
if turtle_infos[self.turtle_id] == nil then
|
||||
minetest.set_node(vector.round(self.object:getpos()), {name = "air"})
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
local info = turtles.get_turtle_info(self.turtle_id)
|
||||
info.turtle = self
|
||||
end
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
if self.turtle_id == nil then return end
|
||||
local info = turtles.get_turtle_info(self.turtle_id)
|
||||
if info.rotate then
|
||||
self.object:setyaw(self.object:getyaw() + info.rotate * dtime)
|
||||
end
|
||||
if info.moving then
|
||||
if info.npos ~= nil then
|
||||
local pos = self.object:getpos()
|
||||
local npos = info.npos
|
||||
local spos = info.spos
|
||||
if done_move(pos, spos, npos) then
|
||||
self.object:setpos(npos)
|
||||
self.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
info.spos = npos
|
||||
info.npos = nil
|
||||
info.moving = nil
|
||||
local meta = minetest.get_meta(spos):to_table()
|
||||
minetest.set_node(spos, {name = "air"})
|
||||
minetest.set_node(npos, {name = "turtle:turtle"})
|
||||
minetest.get_meta(npos):from_table(meta)
|
||||
turtles.update_formspec(self.turtle_id)
|
||||
else
|
||||
self.object:setvelocity(vector.subtract(npos, spos))
|
||||
end
|
||||
elseif info.ndir ~= nil then
|
||||
local yaw = self.object:getyaw()
|
||||
local rotate_speed = info.rotate
|
||||
local nyaw = info.ndir * math.pi/2
|
||||
if done_rotation(yaw, nyaw, rotate_speed) then
|
||||
self.object:setyaw(nyaw)
|
||||
info.dir = info.ndir
|
||||
info.ndir = nil
|
||||
info.rotate = nil
|
||||
info.moving = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if not info.moving then
|
||||
run_computer(self.turtle_id, info.cptr)
|
||||
end
|
||||
if info.formspec_changed then
|
||||
for playername, _ in pairs(info.playernames) do
|
||||
if DEBUG then
|
||||
print(info.screen)
|
||||
print("------------------------------------")
|
||||
end
|
||||
minetest.show_formspec(playername, "turtle:" .. tostring(self.turtle_id), info.formspec)
|
||||
end
|
||||
info.formspec_changed = nil
|
||||
end
|
||||
end,
|
||||
on_rightclick = function(self, clicker)
|
||||
local info = turtles.get_turtle_info(self.turtle_id)
|
||||
local name = clicker:get_player_name()
|
||||
info.playernames[name] = true
|
||||
minetest.show_formspec(name, "turtle:" .. tostring(self.turtle_id), info.formspec)
|
||||
end,
|
||||
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
self.object:remove()
|
||||
local info = turtles.get_turtle_info(self.turtle_id)
|
||||
local pos = info.spos
|
||||
minetest.add_item(pos, "turtle:turtle")
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
|
||||
for list, nslots in pairs({["main"] = 8 * 4, ["floppy"] = 1, ["craft"] = 3 * 3}) do
|
||||
for slot = 1, nslots do
|
||||
minetest.add_item(pos, inv:get_stack(list, slot))
|
||||
end
|
||||
end
|
||||
|
||||
if info.npos then
|
||||
minetest.set_node(info.npos, {name = "air"})
|
||||
end
|
||||
minetest.set_node(pos, {name = "air"})
|
||||
turtle_infos[self.turtle_id] = nil
|
||||
end,
|
||||
get_staticdata = function(self)
|
||||
return tostring(self.turtle_id)
|
||||
end,
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user