local oldprint=print local function print(...) for k,v in ipairs({...}) do oldprint("[Test3D] "..tostring(v)) end end print("Test3D loading.") local tInstructions = { "NOP", "ADD", "SUB", } --[[ local statedir = minetest.get_worldpath() .. '/' .. minetest.get_current_modname() .. "/" print("State directory: "..statedir) if not digiline then print("Digilines not found.") return end ]]-- local function push(pos,val) local meta = minetest.get_meta(pos) local sstack = "" local stack = string.split(meta:get_string("stack"),"\n") if #stack > 15 then print("Stack overflow at "..pos.x..","..pos.y..","..pos.z) table.remove(stack,1) end stack[#sstack+1] = tostring(val) for k,v in ipairs(stack) do sstack = sstack .. v .. "\n" end end local function pop(pos) local meta = minetest.get_meta(pos) local sstack = "" local stack = string.split(meta:get_string("stack"),"\n") local n = table.remove(stack,#stack) or 0 stack[#sstack+1] = tostring(val) for k,v in ipairs(stack) do sstack = sstack .. v .. "\n" end return tonumber(n) end local function t21_digiline_receive(pos, node, channel, msg) print(pos,node,channel,msg) meta = minetest.get_meta(pos) if meta:get_string("state") == "waiting" and meta:get_string("waitingfor") == channel then push(pos,msg) end end print("Created T21 digiline function") local function t21_set_infotext(pos) local meta=minetest.get_meta(pos) local running="false" if meta:get_int("test3d_running") == 1 then running="true" end meta:set_string("infotext","Running: "..running.."\nState: "..meta:get_string("state").."\nPC: "..tostring(meta:get_int("pc")).."\nACC: "..tostring(meta:get_int("acc")).."\nBAK: "..tostring(meta:get_int("bak"))) end local function t21_set_meta(pos) local meta = minetest.get_meta(pos) local fspec = "size[8,9]\nlabel[0,0;T21 execution node]\nfield[0.25,1;8,1;channel;Channel prefix;${channel}]\n" fspec = fspec .. "textarea[0.25,2;8,7.5;program;Program;${program}]\n" fspec = fspec .. "button_exit[0,8.5;7.9,1;;Done]\n" meta:set_string("formspec",fspec) meta:set_string("channel","") meta:set_string("program","#This is the default program.") meta:set_string("state","running") -- can be "running", or "waiting" meta:set_string("waitingfor","") -- address waiting for meta:set_int("pc",0) meta:set_int("acc",0) meta:set_int("bak",0) t21_set_infotext(pos) print("Initialized T21 at "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z)) end minetest.register_node("test3d:t21", { description = "T21 Execution Node", tiles = { { image="t21.png", animation={ type = "vertical_frames", aspect_w=16, aspect_h=16, length=18, length=1.8, }, }, }, on_construct = t21_set_meta, on_punch = function(pos, _, _, _) local meta=minetest.get_meta(pos) local cstate = meta:get_int("test3d_running") local nstate=1 if cstate==1 then nstate=0 else nstate=1 end print("State: "..tostring(cstate).." -> "..tostring(nstate)) meta:set_int("test3d_running",nstate) end, groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, digiline = { receptor = {}, effector = { action = t21_digiline_receive } }, on_receive_fields = function(pos,_,fields,sender) if fields.channel == nil or fields.program == nil then return end local meta = minetest.get_meta(pos) fields.channel = fields.channel or "" meta:set_string("channel",fields.channel) print("Channel: "..fields.channel) local tProgram = {} local lcounter = 0 for _,line in ipairs(string.split(fields.program,"\n")) do if lcounter > 14 then break end -- only 15 real lines will be stored local ltab = string.split(line," ") local valid=false if line:sub(1,1) == "#" then valid=true end if line:sub(#line,#line) == ":" then valid=true end for _,ins in ipairs(tInstructions) do if string.upper(ltab[1]) == ins then valid = true end end if valid then lcounter = lcounter + 1 tProgram[#tProgram+1] = line print("Valid: "..line) else print("Invalid: "..line) end end local sProgram = "" for _,l in ipairs(tProgram) do sProgram = sProgram .. l .. "\n" end sProgram = sProgram:sub(1,-1) meta:set_string("program",sProgram) print("Program:\n"..sProgram) meta:set_int("pc",1) end }) print("T21 node registered") minetest.register_abm({ nodenames={"test3d:t21"}, interval=1, chance=1, action = function(pos) function getDigiline(addr) digiline:receptor_send(pos,digilines.rules.default,addr,"get") minetest.get_meta(pos):set_string("state","waiting") minetest.get_meta(pos):set_string("waitingfor",addr) end local node = minetest.get_node_or_nil(pos) local meta = minetest.get_meta(pos) if meta:get_string("state") == "running" then local state = meta:get_int("test3d_running") if state == nil then state=1 end if state == 1 then local pc = meta:get_int("pc") local acc = meta:get_int("acc") local bak = meta:get_int("bak") print("Running T21 node with instance at position "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).." (PC: "..tostring(pc)..", ACC: "..tostring(acc)..", BAK: "..tostring(bak)..")") local tProgram = string.split(meta:get_string("program"),"\n") local tLine = string.split(tProgram[pc]:upper()) if pc == #tProgram then pc = 0 end meta:set_int("pc",pc+1) end end t21_set_infotext(pos) end, }) print("T21 ABMs registered") --[[ minetest.register_chatcommand("lua", { -- I'm a terrible person params = "", description = "Execute some Lua code", privs = {talk = true}, func = function( _ , text) e,lstr = pcall(loadstring(text)) minetest.chat_send_all(tostring(lstr)) end, }) ]]--