diff --git a/Block/Turtle.lua b/Block/Turtle.lua new file mode 100644 index 0000000..479cd43 --- /dev/null +++ b/Block/Turtle.lua @@ -0,0 +1,125 @@ +--TODO have player context instead of passing block position to user +context = {} + +local function tostringVector(vec) return "("..vec.x..","..vec.y..","..vec.z..")" end +local function parseStringVector(str) + -- Remove Parenthesis + minetest.log("PARSGING "..str) + str = string.sub(str,2,string.len(str)-1) + minetest.log("PARSGING "..str) + local ret = {} + for word in string.gmatch(str, '([^,]+)') do + ret[#ret+1] = word + end + ret = vector.new(ret[1],ret[2],ret[3]); + minetest.log("PARSGING "..dump(ret)) + return ret; +end +local function runTurtleCommand(pos, command) + --Verify turtle exists + --return "Output from command \""..dump(command).."\"".." at location \""..dump(pos).."\"" + if command=="forward" then + if turtle_move_withHeading(pos,1,0) then + return "Went forward" + else + return "Stopped by Obstacle" + end + elseif false then + + end + return "Unknown command" +end + +local function get_formspec_terminal(fields) + local sweet_output = fields.terminal_out or {} + local parsed_output = ""; + for i=1, #sweet_output do parsed_output = parsed_output .. minetest.formspec_escape(sweet_output[i]).."," end + local saved_output = ""; + for i=1, #sweet_output do saved_output = saved_output .. minetest.formspec_escape(sweet_output[i]).."\n" end + return + "invsize[12,9;]" + .."field[0,0;0,0;pos;;"..minetest.formspec_escape(fields.pos).."]" + .."field[0,0;0,0;terminal_out_last;;"..saved_output.."]" + .."field_close_on_enter[terminal_in;false]" + .."field[0,0;12,1;terminal_in;;]" + .."set_focus[terminal_in;true]" + .."textlist[0,1;12,8;terminal_out;"..parsed_output.."]"; +end +local function get_formspec_inventory() + return "invsize[12,5;]" + .."button[0,0;2,1;open_terminal;Open Terminal]" + .."set_focus[open_terminal;true]" + .."list[context;main;8,1;4,4;]" + .."background[8,1;4,4;computertest_inventory.png]" + .."list[current_player;main;0,1;8,4;]"; +end + +minetest.register_node("computertest:turtle", { + tiles = { + "computertest_top.png", + "computertest_bottom.png", + "computertest_right.png", + "computertest_left.png", + "computertest_back.png", + "computertest_front.png", + }, + groups = {oddly_breakable_by_hand=2}, + paramtype = "light", + paramtype2 = "facedir", + light_source=14, + --on_rightclick = function(pos, node, player, itemstack, pointed_thing) + -- turtle_move_withHeading(pos,node,0,1) + --end, + on_construct = function(pos) + + local meta = minetest.get_meta(pos) + minetest.log("OLD META"..dump(meta:to_table())) + meta:from_table({ + out = "output something", + inventory = {main = { + [1] = "default:dirt",[2] = "",[3] = "",[4] = "",[5] = "",[6] = "",[7] = "",[8] = "", + [9] = "",[10] = "",[11] = "",[12] = "",[13] = "",[14] = "default:cobble",[15] = "",[16] = "", + }}, + fields = { + formspec = get_formspec_inventory(), + infotext = "Turtle"..#context + } + }) + meta:set_int("TURTLE_ID",#context) + minetest.log("OLD META"..dump(meta:to_table())) + context[#context+1] = {} + end, + on_receive_fields = function(pos, formname, fields, player) + minetest.show_formspec(player:get_player_name(),"terminal", + get_formspec_terminal({ + pos = tostringVector(pos) + }) + ); + end +}) +minetest.register_on_player_receive_fields(function(player, formname, fields) + minetest.debug("TERMINAL OUT ",dump(fields)); + + if (not fields.terminal_in or fields.terminal_in=="") then return end + + --parse last commands to remember history + local parsedChatlog = {} + for word in string.gmatch(fields.terminal_out_last, '([^\n]+)') do + parsedChatlog[#parsedChatlog+1]=word + end + fields.terminal_out_last = parsedChatlog + --Run command, give output + fields.terminal_out = fields.terminal_out_last or {} + fields.terminal_out[#fields.terminal_out+1] = runTurtleCommand(parseStringVector(fields.pos),fields.terminal_in) + minetest.debug("FIELDS:", dump(fields)); + minetest.debug("show_formspec", player:get_player_name(),formname,get_formspec_terminal(fields)); + minetest.show_formspec(player:get_player_name(),formname,get_formspec_terminal(fields)); +end) +minetest.register_craft({ + output = 'computertest:turtle', + recipe = { + {'default:dirt', '', ''}, + { '', '', ''}, + { '', '', ''}, + } +}) \ No newline at end of file diff --git a/TurtleEntity.lua b/TurtleEntity.lua new file mode 100644 index 0000000..f6c8fdf --- /dev/null +++ b/TurtleEntity.lua @@ -0,0 +1,30 @@ +minetest.register_entity("computertest:turtle", { + initial_properties = { + hp_max = 1, + weight = 5, + is_visible = true, + makes_footstep_sound = false, + physical = true, + collisionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + visual = "cube", + visual_size = { x = 0.9, y = 0.9 }, + textures = { + "computertest_top.png", + "computertest_bottom.png", + "computertest_right.png", + "computertest_left.png", + "computertest_back.png", + "computertest_front.png", + }, + automatic_rotate = false, + channel = "computertest:turtle:" .. 0, + menu = false, + id = 0, + status = 0, + removed = false, + ticket = nil, + }, + on_activate = function(self, staticdata, dtime_s) + + end +}) \ No newline at end of file diff --git a/TurtleInterface.lua b/TurtleInterface.lua new file mode 100644 index 0000000..dd178e1 --- /dev/null +++ b/TurtleInterface.lua @@ -0,0 +1,27 @@ +--- Functions in this file are callable by user-code + +function stuff() + return "Success! I am result of stuff()" +end + +--- +---@returns true on success +--- +function turtle_move_withHeading(pos,numForward,numRight) + --Get new pos + local node = minetest.get_node(pos) + local new_pos = vector.new(pos) + if node.param2%4==0 then new_pos.z=pos.z-numForward;new_pos.x=pos.x-numRight; end + if node.param2%4==1 then new_pos.x=pos.x-numForward;new_pos.z=pos.z+numRight; end + if node.param2%4==2 then new_pos.z=pos.z+numForward;new_pos.x=pos.x+numRight; end + if node.param2%4==3 then new_pos.x=pos.x+numForward;new_pos.z=pos.z-numRight; end + --Verify new pos is empty + if (minetest.get_node(new_pos).name~="air") then return false end + --Take Action + minetest.log("Moving from "..dump(pos).." to "..dump(new_pos)) + local metadata = minetest.get_meta(pos) + minetest.remove_node(pos) + minetest.add_node(new_pos, node) + minetest.get_meta(new_pos):from_table(metadata:to_table()) + return true +end \ No newline at end of file diff --git a/init.lua b/init.lua index 5d6fca6..4a7b9ec 100644 --- a/init.lua +++ b/init.lua @@ -1,92 +1,11 @@ -local function tostringVector(vec) return "("..vec.x..","..vec.y..","..vec.z..")" end ---- ----@returns true on success ---- -local function turtle_move_withHeading(pos,node,numForward,numRight) - --Get new pos - local new_pos = vector.new(pos) - if node.param2%4==0 then pos.z=pos.z-numForward;pos.x=pos.x-numRight; end - if node.param2%4==1 then pos.x=pos.x-numForward;pos.z=pos.z+numRight; end - if node.param2%4==2 then pos.z=pos.z+numForward;pos.x=pos.x+numRight; end - if node.param2%4==3 then pos.x=pos.x+numForward;pos.z=pos.z-numRight; end - --Verify new pos is empty - if (minetest.get_node(pos).name~="air") then return false end - --Take Action - pos,new_pos = new_pos,pos - minetest.log("Moving from "..dump(pos).." to "..dump(new_pos)) - minetest.remove_node(pos) - minetest.add_node(new_pos, node) - return true -end +local modpath = minetest.get_modpath("computertest") +dofile(modpath.."/TurtleInterface.lua") +dofile(modpath.."/Block/Turtle.lua") + + + -local function get_formspec(sweet_output) - sweet_output = sweet_output or {} - local parsed_output = ""; - for i=1, #sweet_output do - parsed_output = parsed_output .. minetest.formspec_escape(sweet_output[i]).."," - end - return - "invsize[12,9;]" - --.."field_close_on_enter[terminal_in;false]" - .."field[0,0;11,1;terminal_in;;]" - .."button[11,0;1,1;submit;Submit]" - .."textlist[0,1;12,4;terminal_out;"..parsed_output.."]" - .."list[context;main;8,5;4,4;]" - .."background[8,5;4,4;computertest_inventory.png]" - .."list[current_player;main;0,5;8,4;]"; -end -minetest.register_node("computertest:turtle", { - tiles = { - "computertest_top.png", - "computertest_bottom.png", - "computertest_right.png", - "computertest_left.png", - "computertest_back.png", - "computertest_front.png", - }, - groups = {oddly_breakable_by_hand=2}, - paramtype = "light", - paramtype2 = "facedir", - light_source=14, - --on_rightclick = function(pos, node, player, itemstack, pointed_thing) - -- turtle_move_withHeading(pos,node,0,1) - --end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:from_table({ - out = "output something", - inventory = {main = { - [1] = "default:dirt",[2] = "",[3] = "",[4] = "",[5] = "",[6] = "",[7] = "",[8] = "", - [9] = "",[10] = "",[11] = "",[12] = "",[13] = "",[14] = "default:cobble",[15] = "",[16] = "", - }}, - fields = { - formspec = get_formspec(), - infotext = "Turtle" - } - }) - end, - on_receive_fields = function(pos, formname, fields, sender) - --minetest.log(dump(pos).."\n\n"..dump(formname).."\n\n"..dump(fields).."\n\n"..dump(sender)) - minetest.debug("TERMINAL OUT ",dump(fields)); - formname = ""..math.random() - fields.terminal_out = fields.terminal_out or {} - fields.terminal_in = fields.terminal_in or "" - fields.terminal_out[#fields.terminal_out+1] = "Output from command \""..fields.terminal_in.."\"" - minetest.debug("show_formspec",sender:get_player_name(),formname,get_formspec(fields.terminal_out)); - minetest.show_formspec(sender:get_player_name(),formname,get_formspec(fields.terminal_out)); - end -}) -minetest.register_on_player_receive_fields(function(player, formname, fields) -end) -minetest.register_craft({ - output = 'computertest:turtle', - recipe = { - {'default:dirt', '', ''}, - { '', '', ''}, - { '', '', ''}, - } -}) \ No newline at end of file diff --git a/mod.conf b/mod.conf index f791280..e76ee89 100644 --- a/mod.conf +++ b/mod.conf @@ -1,3 +1,3 @@ name = computertest -descriptions = Adds a node +descriptions = A ComputerCraft-inspired mod for Minetest! depends = default \ No newline at end of file diff --git a/readme.md b/readme.md index 9c06fc4..eb8e2fe 100644 --- a/readme.md +++ b/readme.md @@ -1,2 +1,9 @@ # Computertest A ComputerCraft-inspired mod for Minetest! +## TODO + - Some way to upload code to turtles + - Perhaps have an "Upload Code" button + - Puts code into some file in the mod + - Add security so only people with certain upload code privilege can upload code + - Terminal would be like "Upload Code" but only one line + - This code would have access only to a turtle class/interface \ No newline at end of file