diff --git a/logic/command_converter.lua b/logic/command_converter.lua new file mode 100644 index 0000000..6e5acea --- /dev/null +++ b/logic/command_converter.lua @@ -0,0 +1,183 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2017-2023 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA3 Commannd Converter + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S +local DESCR = S("TA3 Command Converter") + +local logic = techage.logic + +local sDelay = "0,1,2,3,4,5,7,10,15,20,30,45,60" + +local function switch_on(pos) + logic.swap_node(pos, "techage:ta3_command_converter_on") + logic.send_cmnd(pos, "command_on", "") +end + +local function switch_off(pos) + logic.swap_node(pos, "techage:ta3_command_converter_off") + logic.send_cmnd(pos, "command_off", "") +end + +local function formspec(meta) + local numbers = meta:get_string("numbers") or "" + local command_on = meta:get_string("command_on") + local command_off = meta:get_string("command_off") + local delay_on = techage.dropdown_index(sDelay, meta:get_string("delay_on")) + local delay_off = techage.dropdown_index(sDelay, meta:get_string("delay_off")) + + return "formspec_version[4]size[10,6]".. + "box[0.2,0.2;9.6,0.6;#c6e8ff]" .. + "label[0.4,0.5;" .. minetest.colorize( "#000000", DESCR) .. "]" .. + + "field[1.0,1.5;8,0.6;numbers;" .. S("Insert destination node number(s)") .. ";" .. numbers .. "]" .. + + "label[0.6,2.7;" .. S("Receive") .. "]" .. + "label[2.8,2.7;" .. S("Sent command") .. "]" .. + "label[7.34,2.7;" .. S("Send delay (s)") .. "]" .. + + "box[0.5,3.1;1.2,0.6;#888]" .. + "label[0.6,3.4;on]" .. + "field[2.7,3.1;3.5,0.6;command_on;;" .. command_on .. "]" .. + "dropdown[7.2,3.1;2,0.6;delay_on;" .. sDelay .. ";" .. delay_on .. ";false]" .. + + "box[0.5,4.0;1.2,0.6;#888]" .. + "label[0.6,4.3;off]" .. + "field[2.7,4.0;3.5,0.6;command_off;;" .. command_off .. "]" .. + "dropdown[7.2,4.0;2,0.6;delay_off;" .. sDelay .. ";" .. delay_off .. ";false]" .. + + "button_exit[3.5,5.2;3,0.6;exit;" .. S("Save") .. "]" +end + +local function techage_set_numbers(pos, numbers, player_name) + local meta = M(pos) + local res = logic.set_numbers(pos, numbers, player_name, DESCR) + meta:set_string("formspec", formspec(meta)) + return true --res +end + +local function after_dig_node(pos, oldnode, oldmetadata, digger) + techage.remove_node(pos, oldnode, oldmetadata) + techage.del_mem(pos) +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + + print(dump(fields)) + local meta = minetest.get_meta(pos) + if fields.exit and fields.exit ~= "" then + if techage.check_numbers(fields.numbers, player:get_player_name()) then + meta:set_string("numbers", fields.numbers) + logic.infotext(M(pos), DESCR) + end + meta:set_string("command_on", fields.command_on) + meta:set_string("command_off", fields.command_off) + meta:set_int("delay_on", fields.delay_on or 0) + meta:set_int("delay_off", fields.delay_off or 0) + meta:set_string("formspec", formspec(meta)) + elseif fields.exit == "close" then + meta:set_string("formspec", formspec(meta)) + end +end + +minetest.register_node("techage:ta3_command_converter_off", { + description = DESCR, + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta3.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_command_converter.png", + }, + after_place_node = function(pos, placer) + local meta = M(pos) + logic.after_place_node(pos, placer, "techage:ta3_command_converter_off", DESCR) + logic.infotext(meta, DESCR) + meta:set_string("formspec", formspec(meta)) + end, + + on_timer = function (pos, elapsed) + switch_on(pos) + end, + + on_receive_fields = on_receive_fields, + techage_set_numbers = techage_set_numbers, + after_dig_node = after_dig_node, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:ta3_command_converter_on", { + description = DESCR, + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta3.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_command_converter_on.png", + }, + + on_timer = function (pos, elapsed) + switch_off(pos) + end, + + on_receive_fields = on_receive_fields, + techage_set_numbers = techage_set_numbers, + after_dig_node = after_dig_node, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), + drop = "techage:ta3_playerdetector_off" +}) + +minetest.register_craft({ + output = "techage:ta3_command_converter_off", + recipe = { + {"", "group:wood", "default:mese_crystal"}, + {"default:mese_crystal_fragment", "default:copper_ingot", "techage:vacuum_tube"}, + {"", "group:wood", ""}, + }, +}) + +techage.register_node({ + "techage:ta3_command_converter_off", "techage:ta3_command_converter_on" + }, { + on_recv_message = function(pos, src, topic, payload) + if topic == "on" then + local delay = M(pos):get_int("delay_on") or 0 + if delay > 0 then + minetest.get_node_timer(pos):start(delay) + else + switch_on(pos) + end + return true + elseif topic == "off" then + local delay = M(pos):get_int("delay_off") or 0 + if delay > 0 then + minetest.get_node_timer(pos):start(delay) + else + switch_off(pos) + end + return true + else + return "unsupported" + end + end, + } +) \ No newline at end of file diff --git a/logic/gaze_sensor.lua b/logic/gaze_sensor.lua new file mode 100644 index 0000000..6ae47ab --- /dev/null +++ b/logic/gaze_sensor.lua @@ -0,0 +1,221 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2017-2023 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA4 Gaze Sensor + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +local logic = techage.logic +local CYCLE_TIME = 2 +local DESCR = S("TA4 Gaze Sensor") +local MAX_PLAYER_DIST = 30 + +local WRENCH_MENU = { + { + type = "ascii", + name = "names", + label = S("Player Names"), + tooltip = S("Input the player name(s) separated by blanks.\nIf empty, only the owner is accepted."), + default = "", + }, + { + type = "numbers", + name = "numbers", + label = S("Number"), + tooltip = S("Destination block number(s)"), + default = "", + check = techage.check_numbers, + }, + { + type = "ascii", + name = "command1", + label = "On " .. S("Command"), + tooltip = S("Command to send when sensor is viewed"), + default = "on", + }, + { + type = "ascii", + name = "command2", + label = "Off " .. S("Command"), + tooltip = S("Command to send when sensor is no longer viewed"), + default = "off", + }, +} + +local function switch_on(pos) + if logic.swap_node(pos, "techage:ta4_gaze_sensor_on") then + logic.send_cmnd(pos, "command1", "on") + end +end + +local function switch_off(pos) + if logic.swap_node(pos, "techage:ta4_gaze_sensor_off") then + logic.send_cmnd(pos, "command2", "off") + end +end + +local function get_players(pos) + local meta = minetest.get_meta(pos) + local names = meta:get_string("names") or "" + local t = string.split(names, " ") or {} + t[#t + 1] = meta:get_string("owner") + return t +end + +local function player_focuses_block(pos, name) + local obj = minetest.get_player_by_name(name) + if obj then + local owner_pos = obj:get_pos() + owner_pos.y = owner_pos.y + 1.5 + local dist = vector.distance(pos, owner_pos) + if dist < MAX_PLAYER_DIST then + local dir = obj:get_look_dir() + local vec1 = vector.multiply(dir, dist) + local pos1 = vector.round(vector.add(owner_pos, vec1)) + if vector.equals(pos, pos1) then + return true + end + end + end + return false +end + +local function scan_for_player(pos) + local mem = techage.get_mem(pos) + mem.players = mem.players or get_players(pos) + for _, name in ipairs(mem.players) do + if player_focuses_block(pos, name) then + mem.player_name = name + return true + end + end + mem.player_name = "" + return false +end + +minetest.register_node("techage:ta4_gaze_sensor_off", { + description = DESCR, + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png", + "techage_filling_ta4.png^techage_frame_ta4_top.png", + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_gaze_sensor.png", + }, + after_place_node = function(pos, placer) + local meta = M(pos) + logic.after_place_node(pos, placer, "techage:ta4_gaze_sensor_off", DESCR) + logic.infotext(meta, DESCR) + minetest.get_node_timer(pos):start(CYCLE_TIME) + end, + + on_timer = function (pos, elapsed) + if scan_for_player(pos) then + switch_on(pos) + end + return true + end, + + techage_set_numbers = function(pos, numbers, player_name) + return logic.set_numbers(pos, numbers, player_name, DESCR) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + techage.remove_node(pos, oldnode, oldmetadata) + techage.del_mem(pos) + end, + + ta4_formspec = WRENCH_MENU, + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:ta4_gaze_sensor_on", { + description = DESCR, + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png", + "techage_filling_ta4.png^techage_frame_ta4_top.png", + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_gaze_sensor_on.png", + }, + + on_timer = function (pos, elapsed) + if not scan_for_player(pos) then + switch_off(pos) + end + return true + end, + + techage_set_numbers = function(pos, numbers, player_name) + return logic.set_numbers(pos, numbers, player_name, DESCR) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + techage.remove_node(pos, oldnode, oldmetadata) + techage.del_mem(pos) + end, + + ta4_formspec = WRENCH_MENU, + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), + drop = "techage:ta4_gaze_sensor_off" +}) + +minetest.register_craft({ + output = "techage:ta4_gaze_sensor_off", + recipe = { + {"dye:blue", "techage:aluminum", "dye:blue"}, + {"default:copper_ingot", "techage:ta4_wlanchip", "default:wood"}, + }, +}) + +techage.register_node({ + "techage:ta4_gaze_sensor_off", "techage:ta4_gaze_sensor_on", + }, { + on_recv_message = function(pos, src, topic, payload) + if topic == "name" then + local mem = techage.get_mem(pos) + return mem.player_name or "" + elseif topic == "state" then + local node = techage.get_node_lvm(pos) + if node.name == "techage:ta4_gaze_sensor_on" then + return "on" + else + return "off" + end + else + return "unsupported" + end + end, + on_beduino_request_data = function(pos, src, topic, payload) + if topic == 144 then -- Player Name + local mem = techage.get_mem(pos) + return 0, mem.player_name or "" + elseif topic == 142 then -- Binary State + local node = techage.get_node_lvm(pos) + if node.name == "techage:ta4_gaze_sensor_on" then + return 0, {1} + else + return 0, {0} + end + else + return 2, "" + end + end, + on_node_load = function(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + end, + } +) diff --git a/textures/techage_appl_command_converter.png b/textures/techage_appl_command_converter.png new file mode 100644 index 0000000..b6d765b Binary files /dev/null and b/textures/techage_appl_command_converter.png differ diff --git a/textures/techage_appl_command_converter_on.png b/textures/techage_appl_command_converter_on.png new file mode 100644 index 0000000..b4b6adb Binary files /dev/null and b/textures/techage_appl_command_converter_on.png differ diff --git a/textures/techage_appl_gaze_sensor.png b/textures/techage_appl_gaze_sensor.png new file mode 100644 index 0000000..6ad92ea Binary files /dev/null and b/textures/techage_appl_gaze_sensor.png differ diff --git a/textures/techage_appl_gaze_sensor_on.png b/textures/techage_appl_gaze_sensor_on.png new file mode 100644 index 0000000..7a6f9d6 Binary files /dev/null and b/textures/techage_appl_gaze_sensor_on.png differ