mods that hopefully work for a TechAge-based pack
This commit is contained in:
1 parent
4e6b08d194
commit
c27db2a537
6234 files changed
+375578
No files matched your search
@@ -0,0 +1,108 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Door block
|
||||
|
||||
]]--
|
||||
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
-- See also gateblock!!!
|
||||
local NUM_TEXTURES = 22
|
||||
|
||||
local sTextures = "Wood,Aspen Wood,Jungle Wood,Pine Wood,"..
|
||||
"Cobblestone,Sandstone,Stone,Desert Sandstone,"..
|
||||
"Desert Stone,Silver Sandstone,Mossy Cobble,Desert Cobble,"..
|
||||
"Copper,Steel,Tin,Coral,"..
|
||||
"Glas,Obsidian Glas,Basalt Glass,Basalt Glass 2,"..
|
||||
"Ice,Gate Wood"
|
||||
|
||||
local tTextures = {
|
||||
["Wood"]=1, ["Aspen Wood"]=2, ["Jungle Wood"]=3, ["Pine Wood"]=4,
|
||||
["Cobblestone"]=5, ["Sandstone"]=6, ["Stone"]=7, ["Desert Sandstone"]=8,
|
||||
["Desert Stone"]=9, ["Silver Sandstone"]=10, ["Mossy Cobble"]=11, ["Desert Cobble"]=12,
|
||||
["Copper"]=13, ["Steel"]=14, ["Tin"]=15, ["Coral"]=16,
|
||||
["Glas"]=17, ["Obsidian Glas"]=18, ["Basalt Glass"]=19, ["Basalt Glass 2"]=20,
|
||||
["Ice"]=21, ["Gate Wood"]=22,
|
||||
}
|
||||
|
||||
local tPgns = {"default_wood.png", "default_aspen_wood.png", "default_junglewood.png", "default_pine_wood.png",
|
||||
"default_cobble.png", "default_sandstone.png", "default_stone.png", "default_desert_sandstone.png",
|
||||
"default_desert_stone_block.png", "default_silver_sandstone.png", "default_mossycobble.png", "default_desert_cobble.png",
|
||||
"default_copper_block.png", "default_steel_block.png", "default_tin_block.png", "default_coral_skeleton.png",
|
||||
"default_glass.png", "default_obsidian_glass.png", "techage_basalt_glass.png", "techage_basalt_glass2.png",
|
||||
"default_ice.png", "techage_gate.png"}
|
||||
|
||||
for idx,pgn in ipairs(tPgns) do
|
||||
minetest.register_node("techage:doorblock"..idx, {
|
||||
description = S("TechAge Door Block"),
|
||||
tiles = {
|
||||
pgn.."^[transformR90",
|
||||
pgn,
|
||||
pgn.."^[transformR90",
|
||||
pgn.."^[transformR90",
|
||||
pgn,
|
||||
pgn.."^[transformFX",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -8/16, -8/16, -1/16, 8/16, 8/16, 1/16},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
M(pos):set_string("formspec", "size[3,2]"..
|
||||
"label[0,0;Select texture]"..
|
||||
"dropdown[0,0.5;3;type;"..sTextures..";"..NUM_TEXTURES.."]"..
|
||||
"button_exit[0.5,1.5;2,1;exit;Save]")
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if fields.type then
|
||||
node.name = "techage:doorblock"..tTextures[fields.type]
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if fields.exit then
|
||||
meta:set_string("formspec", "")
|
||||
local number = techage.add_node(pos, node.name)
|
||||
meta:set_string("infotext", S("TechAge Door Block").." "..number)
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
use_texture_alpha = techage.BLEND,
|
||||
sunlight_propagates = true,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
groups = {cracky=2, choppy=2, crumbly=2, techage_door = 1,
|
||||
not_in_creative_inventory = idx==NUM_TEXTURES and 0 or 1},
|
||||
is_ground_content = false,
|
||||
drop = "techage:doorblock"..NUM_TEXTURES,
|
||||
},
|
||||
techage.register_node({"techage:doorblock"..idx}, {}))
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:doorblock"..NUM_TEXTURES,
|
||||
recipe = {
|
||||
{"techage:basalt_glass_thin", "", ""},
|
||||
{"default:mese_crystal_fragment", "",""},
|
||||
{"group:wood", "", ""},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,147 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2022 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Door/Gate Controller
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local logic = techage.logic
|
||||
|
||||
local function formspec(meta)
|
||||
local numbers = meta:get_string("numbers") or ""
|
||||
return "size[7.5,3]"..
|
||||
"field[0.5,1;7,1;numbers;"..S("Insert door/gate block number(s)")..";"..numbers.."]" ..
|
||||
"button_exit[2,2;3,1;exit;"..S("Save").."]"
|
||||
end
|
||||
|
||||
local function store_door_data(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.door_state = false
|
||||
local numbers = M(pos):get_string("numbers")
|
||||
nvm.door_blocks = {}
|
||||
for _,num in ipairs(string.split(numbers, " ")) do
|
||||
local info = techage.get_node_info(num)
|
||||
if info and info.pos then
|
||||
local node = techage.get_node_lvm(info.pos)
|
||||
table.insert(nvm.door_blocks, {pos = info.pos, name = node.name, param2 = node.param2})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function swap_door_nodes(pos, open)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if nvm.door_state ~= open then
|
||||
nvm.door_state = open
|
||||
for _,item in ipairs(nvm.door_blocks or {}) do
|
||||
if item.pos and item.name and item.param2 then
|
||||
local node = techage.get_node_lvm(item.pos)
|
||||
if open then
|
||||
if node.name == item.name then
|
||||
minetest.remove_node(item.pos)
|
||||
item.removed = true
|
||||
else
|
||||
item.removed = false
|
||||
end
|
||||
elseif techage.is_air_like(node.name) and item.removed then
|
||||
minetest.add_node(item.pos, {name = item.name, param2 = item.param2})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta3_doorcontroller", {
|
||||
description = S("TA3 Door Controller"),
|
||||
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_doorcontroller.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = M(pos)
|
||||
local mem = techage.get_mem(pos)
|
||||
logic.after_place_node(pos, placer, "techage:ta3_doorcontroller", S("TA3 Door Controller"))
|
||||
logic.infotext(meta, S("TA3 Door Controller"))
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
if techage.check_numbers(fields.numbers, player:get_player_name()) then
|
||||
swap_door_nodes(pos, false)
|
||||
meta:set_string("numbers", fields.numbers)
|
||||
logic.infotext(M(pos), S("TA3 Door Controller"))
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
store_door_data(pos)
|
||||
end
|
||||
end,
|
||||
|
||||
techage_set_numbers = function(pos, numbers, player_name)
|
||||
local meta = M(pos)
|
||||
local res = logic.set_numbers(pos, numbers, player_name, S("TA3 Door Controller"))
|
||||
if res then
|
||||
swap_door_nodes(pos, false)
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
store_door_data(pos)
|
||||
end
|
||||
return res
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata)
|
||||
swap_door_nodes(pos, false)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
techage.del_mem(pos)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
techage.register_node({"techage:ta3_doorcontroller"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "on" then
|
||||
swap_door_nodes(pos, true)
|
||||
elseif topic == "off" then
|
||||
swap_door_nodes(pos, false)
|
||||
end
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
if topic == 1 and payload[1] == 1 then
|
||||
swap_door_nodes(pos, true)
|
||||
return 0
|
||||
elseif topic == 1 and payload[1] == 0 then
|
||||
swap_door_nodes(pos, false)
|
||||
return 0
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta3_doorcontroller",
|
||||
recipe = {
|
||||
{"", "group:wood",""},
|
||||
{"techage:vacuum_tube", "", "default:mese_crystal_fragment"},
|
||||
{"", "group:wood", ""},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,477 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2020-2025 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Door/Gate Controller II
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S = techage.S
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
local mark = dofile(MP .. "/basis/mark_lib.lua")
|
||||
local logic = techage.logic
|
||||
local fly = techage.flylib
|
||||
|
||||
local NUMSLOTS = 16
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- helper functions
|
||||
--------------------------------------------------------------------------
|
||||
local function get_positions(nvm)
|
||||
local lpos = {}
|
||||
for idx,cfg in ipairs(nvm.config or {}) do
|
||||
lpos[idx] = cfg.pos
|
||||
end
|
||||
return lpos
|
||||
end
|
||||
|
||||
-- Slot state: 1 = Initial state (reset), 2 = Exchange state
|
||||
local function get_state(nvm, number)
|
||||
if nvm.config[number] then
|
||||
return nvm.config[number].state and 1 or 2
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function is_simple_node(pos, name)
|
||||
if not minecart.is_rail(pos, name) then
|
||||
local ndef = minetest.registered_nodes[name]
|
||||
return techage.can_dig_node(name, ndef) or minecart.is_cart(name) or
|
||||
doors.registered_doors[name] or doors.registered_trapdoors[name]
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Slot Configuration {
|
||||
-- pos, -- pos from the node in the inventory
|
||||
-- param2, -- param2 from the node in the inventory
|
||||
-- state, -- false = block is dug/slot is filled (set), true = block is set/slot is empty (reset)
|
||||
-- nameS, -- name of the node in the world, if state = false (set)
|
||||
-- nameR, -- name of the node in the worls, if state = true (reset)
|
||||
-- }
|
||||
local function gen_config(pos, pos_list)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.config = {}
|
||||
for idx,pos in ipairs(pos_list) do
|
||||
local node = techage.get_node_lvm(pos)
|
||||
nvm.config[idx] = {pos = pos, param2 = node.param2, state = true, nameR = node.name, nameS = "air"}
|
||||
end
|
||||
end
|
||||
|
||||
local function gen_config_initial(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
local item_list = inv:get_list("main")
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.config = {}
|
||||
nvm.pos_list = nvm.pos_list or {}
|
||||
nvm.param2_list = nvm.param2_list or {}
|
||||
local len = #nvm.pos_list
|
||||
for idx = 1, len do
|
||||
-- The status is not yet known. It is assumed that the block is set (status = true)
|
||||
-- if the inventory is empty.
|
||||
local item = item_list[idx]
|
||||
local node = techage.get_node_lvm(nvm.pos_list[idx])
|
||||
local state = (item and item:get_count() > 0) == false
|
||||
if state then
|
||||
nvm.config[idx] = {pos = nvm.pos_list[idx], param2 = nvm.param2_list[idx], state = state, nameR = node.name, nameS = "air"}
|
||||
else
|
||||
nvm.config[idx] = {pos = nvm.pos_list[idx], param2 = nvm.param2_list[idx], state = state, nameR = "air", nameS = node.name}
|
||||
end
|
||||
end
|
||||
nvm.pos_list = nil
|
||||
nvm.param2_list = nil
|
||||
end
|
||||
|
||||
local function add_node_names(pos, nvm)
|
||||
local inv = M(pos):get_inventory()
|
||||
local item_list = inv:get_list("main")
|
||||
for idx = 1, #nvm.config do
|
||||
local node = techage.get_node_lvm(nvm.config[idx].pos)
|
||||
local item = item_list[idx]
|
||||
if nvm.config[idx].state then
|
||||
nvm.config[idx].nameR = node.name
|
||||
nvm.config[idx].nameS = item:get_count() > 0 and item:get_name() or "air"
|
||||
else
|
||||
nvm.config[idx].nameR = item:get_count() > 0 and item:get_name() or "air"
|
||||
nvm.config[idx].nameS = node.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- formspec
|
||||
--------------------------------------------------------------------------
|
||||
local function formspec1(nvm, meta)
|
||||
local status = meta:get_string("status")
|
||||
local play_sound = dump(nvm.play_sound or false)
|
||||
return "size[8,7]"..
|
||||
"tabheader[0,0;tab;"..S("Ctrl,Inv")..";1;;true]"..
|
||||
"button_exit[0.7,0.0;3,1;record;"..S("Record").."]"..
|
||||
"button[4.3,0.0;3,1;ready;"..S("Done").."]"..
|
||||
"button_exit[0.7,0.9;3,1;reset;"..S("Reset").."]"..
|
||||
"button_exit[4.3,0.9;3,1;exchange;"..S("Exchange").."]"..
|
||||
"button_exit[0.7,1.8;3,1;show;"..S("Show positions").."]"..
|
||||
"checkbox[4.3,1.8;play_sound;"..S("with door sound")..";"..play_sound.."]"..
|
||||
"label[0.5,2.8;"..status.."]"..
|
||||
"list[current_player;main;0,3.3;8,4;]"
|
||||
end
|
||||
|
||||
local function formspec2(nvm)
|
||||
local lbls = {}
|
||||
for idx,item in ipairs(nvm.config or {}) do
|
||||
local x = ((idx-1) % 8) + 0.3
|
||||
local y = math.floor((idx-1) / 8) * 2.4
|
||||
if item.state then
|
||||
lbls[idx] = "label[" .. x .."," .. y .. ";" .. idx .. "]"
|
||||
else
|
||||
lbls[idx] = "label[" .. x .."," .. y .. ";" .. idx .. " *]"
|
||||
end
|
||||
end
|
||||
return "size[8,7]"..
|
||||
"tabheader[0,0;tab;"..S("Ctrl,Inv")..";2;;true]"..
|
||||
table.concat(lbls, "")..
|
||||
"list[context;main;0,0.5;8,2;]"..
|
||||
"list[current_player;main;0,3.3;8,4;]"..
|
||||
"listring[context;main]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Exchange nodes
|
||||
--------------------------------------------------------------------------
|
||||
local function remove_hidden_door_node(pos)
|
||||
local above = vector.offset(pos, 0, 1, 0)
|
||||
if minetest.get_node(above).name == "doors:hidden" then
|
||||
minetest.remove_node(above)
|
||||
end
|
||||
end
|
||||
|
||||
local function exchange_node(cfg, item)
|
||||
local node = techage.get_node_lvm(cfg.pos)
|
||||
if is_simple_node(cfg.pos, node.name) then
|
||||
local name = item:get_count() > 0 and item:get_name() or "air"
|
||||
local expected_node_name = cfg.state and cfg.nameR or cfg.nameS
|
||||
if fly.exchange_node(cfg.pos, name, cfg.param2, expected_node_name) then
|
||||
remove_hidden_door_node(cfg.pos)
|
||||
cfg.param2 = node.param2
|
||||
cfg.state = not cfg.state
|
||||
if node.name ~= "air" then
|
||||
return ItemStack(node.name)
|
||||
else
|
||||
return ItemStack()
|
||||
end
|
||||
end
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
local function exchange_nodes(pos, nvm, slot, force)
|
||||
local inv = M(pos):get_inventory()
|
||||
local item_list = inv:get_list("main")
|
||||
if item_list == nil then
|
||||
return false
|
||||
end
|
||||
local res = false
|
||||
nvm.config = nvm.config or {}
|
||||
local len = #nvm.config
|
||||
|
||||
for idx = (slot or 1), (slot or len) do
|
||||
local cfg = nvm.config[idx]
|
||||
local state = cfg.state
|
||||
local item = item_list[idx]
|
||||
if (force == nil)
|
||||
or (force == "exch")
|
||||
or (force == "dig" and item:get_count() == 0)
|
||||
or (force == "set" and item:get_count() > 0)
|
||||
or (force == "to2" and state)
|
||||
or (force == "to1" and not state) then
|
||||
item_list[idx] = exchange_node(cfg, item)
|
||||
nvm.config[idx].state = not state
|
||||
res = true
|
||||
end
|
||||
end
|
||||
inv:set_list("main", item_list)
|
||||
return res
|
||||
end
|
||||
|
||||
local function reset_config(pos, nvm)
|
||||
local inv = M(pos):get_inventory()
|
||||
local item_list = inv:get_list("main")
|
||||
|
||||
for idx, cfg in ipairs(nvm.config or {}) do
|
||||
local item = item_list[idx]
|
||||
if not cfg.state then
|
||||
item_list[idx] = exchange_node(cfg, item)
|
||||
end
|
||||
end
|
||||
inv:set_list("main", item_list)
|
||||
end
|
||||
|
||||
local function exchange_with_sound(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if nvm.play_sound then
|
||||
minetest.sound_play("doors_door_open", {
|
||||
pos = pos,
|
||||
gain = 1,
|
||||
max_hear_distance = 15})
|
||||
end
|
||||
return exchange_nodes(pos, nvm)
|
||||
end
|
||||
|
||||
local function exchange_with_learning(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
add_node_names(pos, nvm)
|
||||
return exchange_with_sound(pos)
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta3_doorcontroller2", {
|
||||
description = S("TA3 Door Controller II"),
|
||||
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_doorcontroller.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', NUMSLOTS)
|
||||
logic.after_place_node(pos, placer, "techage:ta3_doorcontroller2", S("TA3 Door Controller II"))
|
||||
logic.infotext(meta, S("TA3 Door Controller II"))
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.fs2_active = false
|
||||
|
||||
if fields.tab == "2" then
|
||||
meta:set_string("formspec", formspec2(nvm))
|
||||
nvm.fs2_active = true
|
||||
return
|
||||
elseif fields.tab == "1" then
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
nvm.fs2_active = true
|
||||
return
|
||||
elseif fields.record then
|
||||
nvm.recording = true
|
||||
meta:set_string("status", S("Recording..."))
|
||||
local name = player:get_player_name()
|
||||
minetest.chat_send_player(name, S("Click on all the blocks that are part of the door/gate"))
|
||||
mark.unmark_all(name)
|
||||
mark.start(name, NUMSLOTS)
|
||||
meta:set_string("stored_config", "")
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
elseif fields.ready and nvm.recording then
|
||||
nvm.recording = false
|
||||
local name = player:get_player_name()
|
||||
local pos_list = mark.get_poslist(name)
|
||||
gen_config(pos, pos_list)
|
||||
local text = #pos_list.." "..S("block positions are stored.")
|
||||
meta:set_string("status", text)
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
meta:set_string("stored_config", "")
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
elseif fields.exchange then
|
||||
if exchange_with_learning(pos) then
|
||||
meta:set_string("status", S("Blocks exchanged"))
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
elseif fields.show then
|
||||
local name = player:get_player_name()
|
||||
local lpos = get_positions(nvm)
|
||||
mark.mark_positions(name, lpos, 300)
|
||||
elseif fields.reset then
|
||||
reset_config(pos, nvm)
|
||||
meta:set_string("status", S("Blocks reset"))
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
elseif fields.play_sound then
|
||||
nvm.play_sound = fields.play_sound == "true"
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
end
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_move = function()
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_take = function()
|
||||
return 0
|
||||
end,
|
||||
allow_metadata_inventory_put = function()
|
||||
return 0
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or minetest.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if nvm.fs2_active then
|
||||
meta:set_string("formspec", formspec2(nvm))
|
||||
else
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
end
|
||||
end,
|
||||
|
||||
can_dig = function(pos, player)
|
||||
if player and minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
return inv:is_empty("main")
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local name = digger:get_player_name()
|
||||
mark.unmark_all(name)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
techage.register_node({"techage:ta3_doorcontroller2"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "on" then
|
||||
return exchange_with_sound(pos)
|
||||
elseif topic == "off" then
|
||||
return exchange_with_sound(pos)
|
||||
elseif topic == "exchange" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, tonumber(payload), "exch")
|
||||
elseif topic == "to1" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, tonumber(payload), "to1")
|
||||
elseif topic == "to2" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, tonumber(payload), "to2")
|
||||
elseif topic == "set" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, tonumber(payload), "set")
|
||||
elseif topic == "dig" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, tonumber(payload), "dig")
|
||||
elseif topic == "get" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return get_state(nvm, tonumber(payload))
|
||||
elseif topic == "reset" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return reset_config(pos, nvm)
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
if topic == 1 and payload[1] == 1 then
|
||||
return exchange_with_sound(pos) and 0 or 3
|
||||
elseif topic == 1 and payload[1] == 0 then
|
||||
return exchange_with_sound(pos) and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 0 then -- Exchange Block
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, payload[2] or 1, "exch") and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 1 then -- Set Block
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, payload[2] or 1, "set") and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 2 then -- Dig Block
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, payload[2] or 1, "dig") and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 3 then -- reset
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return reset_config(pos, nvm) and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 4 then -- to1
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, payload[2] or 1, "to1") and 0 or 3
|
||||
elseif topic == 9 and payload[1] == 5 then -- to2
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return exchange_nodes(pos, nvm, payload[2] or 1, "to2") and 0 or 3
|
||||
end
|
||||
return 2
|
||||
end,
|
||||
on_beduino_request_data = function(pos, src, topic, payload)
|
||||
if topic == 147 then -- Get State
|
||||
local nvm = techage.get_nvm(pos)
|
||||
return 0, {get_state(nvm, tonumber(payload[1]))}
|
||||
end
|
||||
return 2, {0}
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if nvm.config == nil then
|
||||
gen_config_initial(pos)
|
||||
elseif nvm.config[1] and nvm.config[1].nameS == nil then
|
||||
add_node_names(pos, nvm)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_alias("techage:ta3_doorcontroller3", "techage:ta3_doorcontroller2")
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "techage:ta3_doorcontroller2",
|
||||
recipe = {"techage:ta3_doorcontroller"},
|
||||
})
|
||||
|
||||
local Doors = {
|
||||
"doors:door_steel",
|
||||
"doors:prison_door",
|
||||
"doors:rusty_prison_door",
|
||||
"doors:trapdoor_steel",
|
||||
"doors:door_glass",
|
||||
"doors:door_wood",
|
||||
"doors:door_obsidian_glass",
|
||||
"doors:japanese_door",
|
||||
"doors:screen_door",
|
||||
"doors:slide_door",
|
||||
"doors:trapdoor",
|
||||
"doors:woodglass_door",
|
||||
"xpanes:door_steel_bar",
|
||||
"xpanes:trapdoor_steel_bar",
|
||||
}
|
||||
|
||||
for _, name in ipairs(Doors) do
|
||||
for _, postfix in ipairs({"a", "b", "c", "d"}) do
|
||||
techage.register_simple_nodes({name .. "_" .. postfix}, true)
|
||||
fly.protect_door_from_being_opened(name .. "_" .. postfix)
|
||||
end
|
||||
end
|
||||
|
||||
local ProtectorDoors = {
|
||||
"protector:door_steel",
|
||||
"protector:door_wood",
|
||||
"protector:trapdoor",
|
||||
"protector:trapdoor_steel",
|
||||
}
|
||||
|
||||
for _, name in ipairs(ProtectorDoors) do
|
||||
for _, postfix in ipairs({"b_1", "b_2", "t_1", "t_2"}) do
|
||||
techage.register_simple_nodes({name .. "_" .. postfix}, true)
|
||||
fly.protect_door_from_being_opened(name .. "_" .. postfix)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,306 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2020-2023 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA5 Fly Controller
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local S = techage.S
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
local mark = dofile(MP .. "/basis/mark_lib.lua")
|
||||
local fly = techage.flylib
|
||||
|
||||
local MAX_DIST = 1500
|
||||
local MAX_BLOCKS = 32
|
||||
local EX_POINTS = 40
|
||||
|
||||
local WRENCH_MENU = {
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "0.5,1,2,4,6,8",
|
||||
name = "max_speed",
|
||||
label = S("Maximum Speed"),
|
||||
tooltip = S("Maximum speed for moving blocks"),
|
||||
default = "8",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "height",
|
||||
label = S("Move block height"),
|
||||
tooltip = S("Value in the range of 0.0 to 1.0"),
|
||||
default = "1.0",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "offset",
|
||||
label = S("Object offset"),
|
||||
tooltip = S("Y-offset for non-player objects like vehicles (-0.5 to 0.5)"),
|
||||
default = "0.0",
|
||||
},
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "disable,enable",
|
||||
name = "teleport_mode",
|
||||
label = S("Teleport mode"),
|
||||
tooltip = S("Move a player without moving blocks"),
|
||||
default = "disable",
|
||||
},
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "A-B / B-A,move xyz",
|
||||
name = "opmode",
|
||||
label = S("Operational mode"),
|
||||
tooltip = S("Switch to the remote controlled 'move xyz' mode"),
|
||||
default = "A-B / B-A",
|
||||
},
|
||||
}
|
||||
|
||||
local function formspec(nvm, meta)
|
||||
local status = meta:get_string("status")
|
||||
local path = minetest.formspec_escape(meta:contains("fs_path") and meta:get_string("fs_path") or
|
||||
meta:contains("path") and meta:get_string("path") or "0,3,0")
|
||||
return "size[8,6.7]" ..
|
||||
"style_type[textarea;font=mono;textcolor=#FFFFFF;border=true]" ..
|
||||
"box[0,-0.1;7.2,0.5;#c6e8ff]" ..
|
||||
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA5 Fly Controller")) .. "]" ..
|
||||
techage.wrench_image(7.4, -0.05) ..
|
||||
"button[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" ..
|
||||
"button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" ..
|
||||
"textarea[0.4,2.1;3.8,4.4;path;" .. S("Flight route (A to B)") .. ";"..path.."]" ..
|
||||
"button[4.1,1.8;3.8,1;store;" .. S("Store") .. "]" ..
|
||||
"button[4.1,2.6;3.8,1;test;" .. S("Test") .. "]" ..
|
||||
"button[4.1,3.4;3.8,1;moveAB;" .. S("Move A-B") .. "]" ..
|
||||
"button[4.1,4.2;3.8,1;moveBA;" .. S("Move B-A") .. "]" ..
|
||||
"button[4.1,5.0;3.8,1;move;" .. S("Move") .. "]" ..
|
||||
"label[0.3,6.3;" .. status .. "]"
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta5_flycontroller", {
|
||||
description = S("TA5 Fly Controller"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_frame_ta5_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta5_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_movecontroller.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
techage.logic.after_place_node(pos, placer, "techage:ta5_flycontroller", S("TA5 Fly Controller"))
|
||||
techage.logic.infotext(meta, S("TA5 Fly Controller"))
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
if techage.get_expoints(player) < EX_POINTS then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
|
||||
if fields.record then
|
||||
nvm.lpos1 = {}
|
||||
nvm.lpos2 = {}
|
||||
nvm.moveBA = false
|
||||
nvm.running = nil
|
||||
meta:set_string("status", S("Recording..."))
|
||||
local name = player:get_player_name()
|
||||
minetest.chat_send_player(name, S("Click on all blocks that shall be moved"))
|
||||
mark.start(name, MAX_BLOCKS)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.done then
|
||||
local name = player:get_player_name()
|
||||
local pos_list = mark.get_poslist(name)
|
||||
local _, err = fly.to_path(fields.path, MAX_DIST)
|
||||
if not err then
|
||||
meta:set_string("fs_path", fields.path)
|
||||
meta:set_string("path", fields.path)
|
||||
end
|
||||
nvm.running = nil
|
||||
local text = #pos_list.." "..S("block positions are stored.")
|
||||
meta:set_string("status", text)
|
||||
nvm.lpos1 = pos_list
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.store then
|
||||
local _, err = fly.to_path(fields.path, MAX_DIST)
|
||||
if not err then
|
||||
meta:set_string("path", fields.path)
|
||||
meta:set_string("fs_path", fields.path)
|
||||
meta:set_string("status", S("Stored"))
|
||||
else
|
||||
meta:set_string("path", "0,0,0")
|
||||
meta:set_string("fs_path", fields.path)
|
||||
meta:set_string("status", err)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
nvm.moveBA = false
|
||||
nvm.running = nil
|
||||
elseif fields.test then
|
||||
local path, err = fly.to_path(fields.path, MAX_DIST)
|
||||
if err then
|
||||
meta:set_string("status", err)
|
||||
elseif path and nvm.lpos1 and nvm.lpos1[1] then
|
||||
local pos = table.copy(nvm.lpos1[1])
|
||||
if pos then
|
||||
for _, offs in ipairs(path) do
|
||||
local pos2 = vector.add(pos, offs)
|
||||
local s = string.format("[TA4 Fly Controller] %s + %s = %s", P2S(pos), P2S(offs), P2S(pos2))
|
||||
minetest.chat_send_player(player:get_player_name(), s)
|
||||
pos = pos2
|
||||
end
|
||||
meta:set_string("status", S("See chat output"))
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Recording is missing!"))
|
||||
meta:set_string("status", S("Error: Recording is missing !!"))
|
||||
end
|
||||
else
|
||||
if nvm.lpos1 then
|
||||
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Invalid path!"))
|
||||
meta:set_string("status", S("Error: Invalid path !!"))
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), S("[TA4 Fly Controller] Recording is missing!"))
|
||||
meta:set_string("status", S("Error: Recording is missing !!"))
|
||||
end
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.moveAB then
|
||||
meta:set_string("status", "")
|
||||
if fly.move_to_other_pos(pos, false) then
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.moveBA then
|
||||
meta:set_string("status", "")
|
||||
if fly.move_to_other_pos(pos, true) then
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.move then
|
||||
meta:set_string("status", "")
|
||||
if fly.move_to_other_pos(pos, nvm.moveBA) then
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local name = digger:get_player_name()
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
ta5_formspec = {menu=WRENCH_MENU, ex_points=EX_POINTS},
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
local INFO = [[Commands: 'state', 'a2b', 'b2a', 'move', 'move2']]
|
||||
|
||||
techage.register_node({"techage:ta5_flycontroller"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local move_xyz = M(pos):get_string("opmode") == "move xyz"
|
||||
if topic == "info" then
|
||||
return INFO
|
||||
elseif topic == "state" then
|
||||
return nvm.running and "running" or "stopped"
|
||||
elseif not move_xyz and topic == "a2b" then
|
||||
return fly.move_to_other_pos(pos, false)
|
||||
elseif not move_xyz and topic == "b2a" then
|
||||
return fly.move_to_other_pos(pos, true)
|
||||
elseif not move_xyz and topic == "move" then
|
||||
return fly.move_to_other_pos(pos, nvm.moveBA)
|
||||
elseif move_xyz and topic == "move2" then
|
||||
local line = fly.to_vector(payload, MAX_DIST)
|
||||
if line then
|
||||
return fly.move_to(pos, line)
|
||||
end
|
||||
return false
|
||||
elseif topic == "reset" then
|
||||
return fly.reset_move(pos)
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local move_xyz = M(pos):get_string("opmode") == "move xyz"
|
||||
if not move_xyz and topic == 11 then
|
||||
if payload[1] == 1 then
|
||||
return fly.move_to_other_pos(pos, false) and 0 or 3
|
||||
elseif payload[1] == 2 then
|
||||
return fly.move_to_other_pos(pos, true) and 0 or 3
|
||||
elseif payload[1] == 3 then
|
||||
return fly.move_to_other_pos(pos, nvm.moveBA) and 0 or 3
|
||||
end
|
||||
elseif move_xyz and topic == 18 then -- move xyz
|
||||
local line = {
|
||||
x = techage.in_range(techage.beduino_signed_var(payload[1]), -1000, 1000),
|
||||
y = techage.in_range(techage.beduino_signed_var(payload[2]), -1000, 1000),
|
||||
z = techage.in_range(techage.beduino_signed_var(payload[3]), -1000, 1000),
|
||||
}
|
||||
return fly.move_to(pos, line) and 0 or 3
|
||||
elseif move_xyz and topic == 24 then -- moveto xyz
|
||||
local dest = {
|
||||
x = techage.in_range(techage.beduino_signed_var(payload[1]), -32768, 32767),
|
||||
y = techage.in_range(techage.beduino_signed_var(payload[2]), -32768, 32767),
|
||||
z = techage.in_range(techage.beduino_signed_var(payload[3]), -32768, 32767),
|
||||
}
|
||||
return fly.move_to_abs(pos, dest, MAX_DIST) and 0 or 3
|
||||
elseif move_xyz and topic == 19 then -- reset
|
||||
return fly.reset_move(pos) and 0 or 3
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end,
|
||||
on_beduino_request_data = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == 129 then
|
||||
return 0, {nvm.running and 1 or 6}
|
||||
end
|
||||
return 2, ""
|
||||
end,
|
||||
on_node_load = function(pos, node)
|
||||
M(pos):set_string("status", "")
|
||||
techage.get_nvm(pos).running = false
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta5_flycontroller",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "dye:red", "default:steel_ingot"},
|
||||
{"techage:aluminum", "techage:ta5_aichip", "techage:aluminum"},
|
||||
{"group:wood", "basic_materials:gear_steel", "group:wood"},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,94 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Gate Block to disappear
|
||||
|
||||
]]--
|
||||
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
-- See also doorblock!!!
|
||||
local NUM_TEXTURES = 22
|
||||
|
||||
local sTextures = "Wood,Aspen Wood,Jungle Wood,Pine Wood,"..
|
||||
"Cobblestone,Sandstone,Stone,Desert Sandstone,"..
|
||||
"Desert Stone,Silver Sandstone,Mossy Cobble,Desert Cobble,"..
|
||||
"Copper,Steel,Tin,Coral,"..
|
||||
"Glas,Obsidian Glas,Basalt Glass,Basalt Glass 2,"..
|
||||
"Ice,Gate Wood"
|
||||
|
||||
local tTextures = {
|
||||
["Wood"]=1, ["Aspen Wood"]=2, ["Jungle Wood"]=3, ["Pine Wood"]=4,
|
||||
["Cobblestone"]=5, ["Sandstone"]=6, ["Stone"]=7, ["Desert Sandstone"]=8,
|
||||
["Desert Stone"]=9, ["Silver Sandstone"]=10, ["Mossy Cobble"]=11, ["Desert Cobble"]=12,
|
||||
["Copper"]=13, ["Steel"]=14, ["Tin"]=15, ["Coral"]=16,
|
||||
["Glas"]=17, ["Obsidian Glas"]=18, ["Basalt Glass"]=19, ["Basalt Glass 2"]=20,
|
||||
["Ice"]=21, ["Gate Wood"]=22,
|
||||
}
|
||||
|
||||
local tPgns = {"default_wood.png", "default_aspen_wood.png", "default_junglewood.png", "default_pine_wood.png",
|
||||
"default_cobble.png", "default_sandstone.png", "default_stone.png", "default_desert_sandstone.png",
|
||||
"default_desert_stone_block.png", "default_silver_sandstone.png", "default_mossycobble.png", "default_desert_cobble.png",
|
||||
"default_copper_block.png", "default_steel_block.png", "default_tin_block.png", "default_coral_skeleton.png",
|
||||
"default_glass.png", "default_obsidian_glass.png", "techage_basalt_glass.png", "techage_basalt_glass2.png",
|
||||
"default_ice.png", "techage_gate.png"}
|
||||
|
||||
for idx,pgn in ipairs(tPgns) do
|
||||
minetest.register_node("techage:gateblock"..idx, {
|
||||
description = S("TechAge Gate Block"),
|
||||
tiles = {pgn},
|
||||
drawtype = "glasslike",
|
||||
after_place_node = function(pos, placer)
|
||||
M(pos):set_string("formspec", "size[3,2]"..
|
||||
"label[0,0;Select texture]"..
|
||||
"dropdown[0,0.5;3;type;"..sTextures..";"..NUM_TEXTURES.."]"..
|
||||
"button_exit[0.5,1.5;2,1;exit;Save]")
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if fields.type then
|
||||
node.name = "techage:gateblock"..tTextures[fields.type]
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if fields.exit then
|
||||
meta:set_string("formspec", "")
|
||||
local number = techage.add_node(pos, node.name)
|
||||
meta:set_string("infotext", S("TechAge Gate Block").." "..number)
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
use_texture_alpha = techage.BLEND,
|
||||
sunlight_propagates = true,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
groups = {cracky=2, choppy=2, crumbly=2, techage_door = 1,
|
||||
not_in_creative_inventory = idx==NUM_TEXTURES and 0 or 1},
|
||||
is_ground_content = false,
|
||||
drop = "techage:gateblock"..NUM_TEXTURES,
|
||||
},
|
||||
techage.register_node({"techage:gateblock"..idx}, {}))
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:gateblock"..NUM_TEXTURES,
|
||||
recipe = {
|
||||
{"techage:basalt_glass", "", ""},
|
||||
{"default:mese_crystal_fragment", "",""},
|
||||
{"group:wood", "", ""},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,358 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2020-2022 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Move Controller
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local S = techage.S
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
local mark = dofile(MP .. "/basis/mark_lib.lua")
|
||||
local fly = techage.flylib
|
||||
|
||||
local MAX_DIST = techage.maximum_move_controller_distance
|
||||
local MAX_BLOCKS = techage.maximum_move_controller_blocks
|
||||
|
||||
local WRENCH_MENU = {
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "0.5,1,2,4,6,8",
|
||||
name = "max_speed",
|
||||
label = S("Maximum Speed"),
|
||||
tooltip = S("Maximum speed for moving blocks"),
|
||||
default = "8",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "height",
|
||||
label = S("Move block height"),
|
||||
tooltip = S("Value in the range of 0.0 to 1.0"),
|
||||
default = "1.0",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "offset",
|
||||
label = S("Object offset"),
|
||||
tooltip = S("Y-offset for non-player objects like vehicles (-0.5 to 0.5)"),
|
||||
default = "0.0",
|
||||
},
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "A-B / B-A,move xyz",
|
||||
name = "opmode",
|
||||
label = S("Operational mode"),
|
||||
tooltip = S("Switch to the remote controlled 'move xyz' mode"),
|
||||
default = "A-B / B-A",
|
||||
},
|
||||
}
|
||||
|
||||
local function formspec(nvm, meta)
|
||||
local status = meta:get_string("status")
|
||||
local path = minetest.formspec_escape(meta:contains("path") and meta:get_string("path") or "0,3,0")
|
||||
local buttons
|
||||
if meta:get_string("opmode") == "move xyz" then
|
||||
buttons = "field[0.4,2.3;3.8,1;path;" .. S("Move distance") .. ";" .. path .. "]" ..
|
||||
"button_exit[4.1,2.0;3.8,1;move2;" .. S("Move") .. "]" ..
|
||||
"button_exit[0.1,3.0;3.8,1;reset;" .. S("Reset") .. "]" ..
|
||||
"button_exit[4.1,3.0;3.8,1;show;" .. S("Show positions") .. "]"
|
||||
else
|
||||
buttons = "field[0.4,2.3;3.8,1;path;" .. S("Move distance (A to B)") .. ";" .. path .. "]" ..
|
||||
"button_exit[0.1,3.0;3.8,1;moveAB;" .. S("Move A-B") .. "]" ..
|
||||
"button_exit[4.1,3.0;3.8,1;moveBA;" .. S("Move B-A") .. "]" ..
|
||||
"button[4.1,2.0;3.8,1;store;" .. S("Store") .. "]" ..
|
||||
"button_exit[0.1,4.0;3.8,1;show;" .. S("Show positions") .. "]" ..
|
||||
"button_exit[4.1,4.0;3.8,1;reset;" .. S("Reset") .. "]"
|
||||
end
|
||||
return "size[8,5.5]" ..
|
||||
default.gui_bg ..
|
||||
default.gui_bg_img ..
|
||||
default.gui_slots ..
|
||||
"box[0,-0.1;7.2,0.5;#c6e8ff]" ..
|
||||
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA4 Move Controller")) .. "]" ..
|
||||
techage.wrench_image(7.4, -0.05) ..
|
||||
"button_exit[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" ..
|
||||
"button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" ..
|
||||
buttons ..
|
||||
"label[0.3,5.0;" .. status .. "]"
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_movecontroller", {
|
||||
description = S("TA4 Move Controller"),
|
||||
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.png^techage_appl_movecontroller.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
techage.logic.after_place_node(pos, placer, "techage:ta4_movecontroller", S("TA4 Move Controller"))
|
||||
techage.logic.infotext(meta, S("TA4 Move Controller"))
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
|
||||
if fields.record then
|
||||
nvm.lpos1 = {}
|
||||
nvm.lpos2 = {}
|
||||
nvm.moveBA = false
|
||||
nvm.recording = true
|
||||
nvm.running = nil
|
||||
nvm.lastpos = nil
|
||||
meta:set_string("status", S("Recording..."))
|
||||
local name = player:get_player_name()
|
||||
minetest.chat_send_player(name, S("Click on all blocks that shall be moved"))
|
||||
mark.unmark_all(name)
|
||||
mark.start(name, MAX_BLOCKS)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.done and nvm.recording then
|
||||
nvm.recording = false
|
||||
local name = player:get_player_name()
|
||||
local pos_list = mark.get_poslist(name)
|
||||
if fly.to_vector(fields.path or "", MAX_DIST) then
|
||||
meta:set_string("path", fields.path)
|
||||
end
|
||||
local text = #pos_list.." "..S("block positions are stored.")
|
||||
nvm.running = nil
|
||||
nvm.lastpos = nil
|
||||
meta:set_string("status", text)
|
||||
nvm.lpos1 = pos_list
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.store then
|
||||
if fly.to_vector(fields.path or "", MAX_DIST) then
|
||||
meta:set_string("path", fields.path)
|
||||
meta:set_string("status", S("Stored"))
|
||||
else
|
||||
meta:set_string("status", S("Error: Invalid distance !!"))
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
nvm.moveBA = false
|
||||
nvm.running = nil
|
||||
nvm.lastpos = nil
|
||||
elseif fields.moveAB then
|
||||
meta:set_string("status", "")
|
||||
if fly.move_to_other_pos(pos, false) then
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.moveBA then
|
||||
meta:set_string("status", "")
|
||||
if fly.move_to_other_pos(pos, true) then
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.move2 then
|
||||
if fly.to_vector(fields.path or "", MAX_DIST) then
|
||||
meta:set_string("path", fields.path)
|
||||
end
|
||||
local line = fly.to_vector(meta:get_string("path"), MAX_DIST)
|
||||
if line then
|
||||
fly.move_to(pos, line)
|
||||
end
|
||||
elseif fields.reset then
|
||||
fly.reset_move(pos)
|
||||
nvm.running = false
|
||||
elseif fields.show then
|
||||
local name = player:get_player_name()
|
||||
mark.mark_positions(name, nvm.lpos1, 300)
|
||||
end
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or minetest.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local name = digger:get_player_name()
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
ta4_formspec = WRENCH_MENU,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
local INFO = [[Commands: 'state', 'a2b', 'b2a', 'move']]
|
||||
|
||||
techage.register_node({"techage:ta4_movecontroller"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local move_xyz = M(pos):get_string("opmode") == "move xyz"
|
||||
if topic == "info" then
|
||||
return INFO
|
||||
elseif topic == "state" then
|
||||
return nvm.running and "running" or "stopped"
|
||||
elseif not move_xyz and topic == "a2b" then
|
||||
return fly.move_to_other_pos(pos, false)
|
||||
elseif not move_xyz and topic == "b2a" then
|
||||
return fly.move_to_other_pos(pos, true)
|
||||
elseif not move_xyz and topic == "move" then
|
||||
return fly.move_to_other_pos(pos, nvm.moveBA == false)
|
||||
elseif move_xyz and topic == "move2" then
|
||||
local line = fly.to_vector(payload, MAX_DIST)
|
||||
if line then
|
||||
return fly.move_to(pos, line)
|
||||
end
|
||||
return false
|
||||
elseif move_xyz and topic == "moveto" then
|
||||
local destpos = fly.to_vector(payload)
|
||||
if destpos then
|
||||
return fly.move_to_abs(pos, destpos, MAX_DIST)
|
||||
end
|
||||
return false
|
||||
elseif topic == "reset" then
|
||||
return fly.reset_move(pos)
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local move_xyz = M(pos):get_string("opmode") == "move xyz"
|
||||
--print("on_beduino_receive_cmnd", P2S(pos), move_xyz, topic, payload[1])
|
||||
if not move_xyz and topic == 11 then
|
||||
if payload[1] == 1 then
|
||||
return fly.move_to_other_pos(pos, false) and 0 or 3
|
||||
elseif payload[1] == 2 then
|
||||
return fly.move_to_other_pos(pos, true) and 0 or 3
|
||||
elseif payload[1] == 3 then
|
||||
return fly.move_to_other_pos(pos, nvm.moveBA == false) and 0 or 3
|
||||
end
|
||||
elseif move_xyz and topic == 18 then -- move xyz
|
||||
local line = {
|
||||
x = techage.in_range(techage.beduino_signed_var(payload[1]), -1000, 1000),
|
||||
y = techage.in_range(techage.beduino_signed_var(payload[2]), -1000, 1000),
|
||||
z = techage.in_range(techage.beduino_signed_var(payload[3]), -1000, 1000),
|
||||
}
|
||||
return fly.move_to(pos, line) and 0 or 3
|
||||
elseif move_xyz and topic == 24 then -- moveto xyz
|
||||
local dest = {
|
||||
x = techage.in_range(techage.beduino_signed_var(payload[1]), -32768, 32767),
|
||||
y = techage.in_range(techage.beduino_signed_var(payload[2]), -32768, 32767),
|
||||
z = techage.in_range(techage.beduino_signed_var(payload[3]), -32768, 32767),
|
||||
}
|
||||
return fly.move_to_abs(pos, dest, MAX_DIST) and 0 or 3
|
||||
elseif move_xyz and topic == 19 then -- reset
|
||||
return fly.reset_move(pos) and 0 or 3
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end,
|
||||
on_beduino_request_data = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == 129 then
|
||||
return 0, {nvm.running and 1 or 6}
|
||||
end
|
||||
return 2, ""
|
||||
end,
|
||||
on_node_load = function(pos, node)
|
||||
M(pos):set_string("teleport_mode", "") -- delete not working (legacy) op mode
|
||||
M(pos):set_string("status", "")
|
||||
techage.get_nvm(pos).running = false
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("techage:rack_and_pinion", {
|
||||
description = S("TA Rack and Pinion"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"techage_rack_and_pinion.png",
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -6/32, -16/32, 14.1/32, 6/32, 16/32, 16/32},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
use_texture_alpha = techage.CLIP,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 1, level = 2},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:moveblock", {
|
||||
description = "Techage Invisible Move Block",
|
||||
drawtype = "glasslike_framed_optional",
|
||||
inventory_image = 'techage_inv_invisible.png',
|
||||
tiles = {"blank.png"},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-16/32, -16/32, -16/32, 16/32, -14/32, 16/32},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
pointable = true,
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_movecontroller",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "dye:blue", "default:steel_ingot"},
|
||||
{"default:mese_crystal_fragment", "techage:ta4_wlanchip", "default:mese_crystal_fragment"},
|
||||
{"group:wood", "basic_materials:gear_steel", "group:wood"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:rack_and_pinion 10",
|
||||
recipe = {
|
||||
{"", "default:steel_ingot", ""},
|
||||
{"basic_materials:steel_bar", "default:steel_ingot", "basic_materials:steel_bar"},
|
||||
{"", "default:steel_ingot", ""},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,292 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2020-2025 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Move Controller II (replaces the ta4_movecontroller)
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local S = techage.S
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
local mark = dofile(MP .. "/basis/mark_lib.lua")
|
||||
local fly = techage.flylib2
|
||||
|
||||
local MAX_DIST = techage.maximum_move_controller_distance
|
||||
local MAX_BLOCKS = 16
|
||||
|
||||
|
||||
local WRENCH_MENU = {
|
||||
{
|
||||
type = "dropdown",
|
||||
choices = "0.5,1,2,4,6,8",
|
||||
name = "max_speed",
|
||||
label = S("Maximum Speed"),
|
||||
tooltip = S("Maximum speed for moving blocks"),
|
||||
default = "8",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "height",
|
||||
label = S("Move block height"),
|
||||
tooltip = S("Value in the range of 0.0 to 1.0"),
|
||||
default = "1.0",
|
||||
},
|
||||
{
|
||||
type = "float",
|
||||
name = "offset",
|
||||
label = S("Object offset"),
|
||||
tooltip = S("Y-offset for non-player objects like vehicles (-0.5 to 0.5)"),
|
||||
default = "0.0",
|
||||
},
|
||||
}
|
||||
|
||||
local function formspec1(nvm, meta)
|
||||
local status = meta:get_string("status")
|
||||
local base_pos = nvm.lNodes and nvm.lNodes[1] and nvm.lNodes[1].base_pos or vector.zero()
|
||||
base_pos = " " .. P2S(base_pos) or ""
|
||||
|
||||
return "size[8,7.5]" ..
|
||||
"tabheader[0,0;tab;" .. S("Control,Inventory") .. ";1;;true]" ..
|
||||
"box[0,-0.1;7.2,0.5;#c6e8ff]" ..
|
||||
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA4 Move Controller")) .. "]" ..
|
||||
techage.wrench_image(7.4, -0.05) ..
|
||||
"button[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" ..
|
||||
"button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" ..
|
||||
"button_exit[0.1,2.0;3.8,1;show;" .. S("Show start positions") .. "]" ..
|
||||
"label[4.1,2.2;" .. S("Pos 1:") .. base_pos .. "]" ..
|
||||
"button_exit[0.1,3.3;3.8,1;move;" .. S("Test move") .. "]" ..
|
||||
"button_exit[4.1,3.3;3.8,1;reset;" .. S("Reset") .. "]" ..
|
||||
"label[0.3,5.0;" .. status .. "]"
|
||||
end
|
||||
|
||||
local function presets(nvm, inv, idx, x, y)
|
||||
local node = nvm.lNodes[idx]
|
||||
local slot = inv:get_stack("main", idx)
|
||||
if node then
|
||||
if slot:is_empty() then
|
||||
return "item_image[" .. x .. "," .. y .. ";1,1;" .. node.name .. "]" ..
|
||||
"image[" .. x .. "," .. y .. ";1,1;techage_white_frame.png]"
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
local function tooltips(nvm, inv, idx, x, y)
|
||||
local node = nvm.lNodes[idx]
|
||||
local slot = inv:get_stack("main", idx)
|
||||
if node then
|
||||
if slot:is_empty() then
|
||||
if node.curr_pos then
|
||||
return "tooltip[" .. x .. "," .. y .. ";1,1;" .. S("Node at pos") .. ": " .. P2S(node.curr_pos) .. ";#0C3D32;#FFFFFF]"
|
||||
else
|
||||
return "tooltip[" .. x .. "," .. y .. ";1,1;" .. S("missing") .. ";#0C3D32;#FFFFFF]"
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
local function formspec2(nvm, meta)
|
||||
|
||||
local tbl = {}
|
||||
local inv = meta:get_inventory()
|
||||
nvm.lNodes = nvm.lNodes or {}
|
||||
for idx = 1,MAX_BLOCKS do
|
||||
local x = ((idx-1) % 8) + 0.3
|
||||
local y = math.floor((idx-1) / 8) * 2.4
|
||||
tbl[#tbl+1] = "label[" .. x .."," .. y .. ";" .. idx .. "]"
|
||||
x = ((idx-1) % 8)
|
||||
y = math.floor((idx-1) / 8) + 0.5
|
||||
tbl[#tbl+1] = presets(nvm, inv, idx, x, y)
|
||||
tbl[#tbl+1] = tooltips(nvm, inv, idx, x, y)
|
||||
end
|
||||
return "size[8,7]" ..
|
||||
"tabheader[0,0;tab;" .. S("Control,Inventory") .. ";2;;true]" ..
|
||||
table.concat(tbl, "") ..
|
||||
"list[context;main;0,0.5;8,2;]" ..
|
||||
"list[current_player;main;0,3.3;8,4;]" ..
|
||||
"listring[context;main]" ..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("techage:ta4_movecontroller2", {
|
||||
description = S("TA4 Move Controller II"),
|
||||
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.png^techage_appl_movecontroller.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', MAX_BLOCKS)
|
||||
techage.logic.after_place_node(pos, placer, "techage:ta4_movecontroller2", S("TA4 Move Controller II"))
|
||||
techage.logic.infotext(meta, S("TA4 Move Controller II"))
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
|
||||
if fields.tab == "2" then
|
||||
meta:set_string("formspec", formspec2(nvm, meta))
|
||||
return
|
||||
elseif fields.tab == "1" then
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
return
|
||||
elseif fields.record then
|
||||
nvm.recording = true
|
||||
nvm.running = nil
|
||||
meta:set_string("status", S("Recording..."))
|
||||
local name = player:get_player_name()
|
||||
minetest.chat_send_player(name, S("Click on all blocks that shall be moved"))
|
||||
mark.unmark_all(name)
|
||||
mark.start(name, MAX_BLOCKS)
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
elseif fields.done and nvm.recording then
|
||||
nvm.recording = false
|
||||
local name = player:get_player_name()
|
||||
local pos_list = mark.get_poslist(name)
|
||||
local text = #pos_list.." "..S("block positions are stored.")
|
||||
nvm.running = nil
|
||||
meta:set_string("status", text)
|
||||
nvm.lNodes = fly.get_nodes(pos_list)
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
elseif fields.move then
|
||||
nvm.lNodes = nvm.lNodes or {}
|
||||
local node = nvm.lNodes[1]
|
||||
if node then
|
||||
local dest_pos = {x = node.base_pos.x, y = node.base_pos.y + 5, z = node.base_pos.z}
|
||||
fly.move_nodes(pos, nvm, dest_pos, 0)
|
||||
end
|
||||
elseif fields.reset then
|
||||
fly.reset_nodes(pos, nvm, 0)
|
||||
elseif fields.show then
|
||||
local name = player:get_player_name()
|
||||
local lpos = fly.get_node_base_positions(nvm.lNodes or {})
|
||||
mark.mark_positions(name, lpos, 300)
|
||||
end
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not clicker or minetest.is_protected(pos, clicker:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec1(nvm, meta))
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_move = function() return 0 end,
|
||||
allow_metadata_inventory_take = function() return 0 end,
|
||||
allow_metadata_inventory_put = function() return 0 end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local name = digger:get_player_name()
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
ta4_formspec = WRENCH_MENU,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
local INFO = [[Commands: 'state', 'moveto']]
|
||||
|
||||
techage.register_node({"techage:ta4_movecontroller2"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.lNodes = nvm.lNodes or {}
|
||||
if topic == "info" then
|
||||
return INFO
|
||||
elseif topic == "state" then
|
||||
return nvm.running and "running" or "stopped"
|
||||
elseif topic == "moveto" then
|
||||
local destpos = fly.get_pos(payload)
|
||||
if destpos then
|
||||
if fly.valid_distance(nvm, destpos, 0, MAX_DIST) then
|
||||
return fly.move_nodes(pos, nvm, destpos, 0)
|
||||
else
|
||||
M(pos):set_string("status", S("Distance too large!"))
|
||||
end
|
||||
else
|
||||
M(pos):set_string("status", S("Command syntax error!"))
|
||||
end
|
||||
return false
|
||||
elseif topic == "getpos" then
|
||||
if nvm.lNodes[1] then
|
||||
local cpos = nvm.lNodes[1].curr_pos
|
||||
local spos = string.sub(P2S(cpos), 2, -2)
|
||||
return spos
|
||||
end
|
||||
elseif topic == "reset" then
|
||||
return fly.reset_nodes(pos, nvm, 0)
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.lNodes = nvm.lNodes or {}
|
||||
if topic == 24 then -- moveto xyz
|
||||
local destpos = {
|
||||
x = techage.in_range(techage.beduino_signed_var(payload[1]), -32768, 32767),
|
||||
y = techage.in_range(techage.beduino_signed_var(payload[2]), -32768, 32767),
|
||||
z = techage.in_range(techage.beduino_signed_var(payload[3]), -32768, 32767),
|
||||
}
|
||||
if fly.valid_distance(nvm, destpos, 0, MAX_DIST) then
|
||||
return fly.move_nodes(pos, nvm, destpos, 0) and 0 or 3
|
||||
else
|
||||
M(pos):set_string("status", S("Distance too large!"))
|
||||
return 3
|
||||
end
|
||||
elseif topic == 19 then -- reset
|
||||
return fly.reset_nodes(pos, nvm, 0) and 0 or 3
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end,
|
||||
on_beduino_request_data = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == 129 then
|
||||
return 0, {nvm.running and 1 or 6}
|
||||
end
|
||||
return 2, ""
|
||||
end,
|
||||
on_node_load = function(pos, node)
|
||||
M(pos):set_string("status", "")
|
||||
techage.get_nvm(pos).running = false
|
||||
--print("techage.was_normal_shutdown()", techage.was_normal_shutdown())
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_movecontroller2",
|
||||
recipe = {"techage:ta4_movecontroller"},
|
||||
type = "shapeless",
|
||||
})
|
||||
@@ -0,0 +1,149 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2021-2022 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Sound Block
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local t = {}
|
||||
for idx, ogg in ipairs(techage.OggFileList) do
|
||||
t[idx] = idx .. "," .. ogg
|
||||
end
|
||||
local OGG_FILES = table.concat(t, ",")
|
||||
|
||||
local logic = techage.logic
|
||||
|
||||
local GAIN = {0.05 ,0.1, 0.2, 0.5, 1.0}
|
||||
|
||||
|
||||
local function play_sound(pos, ogg, gain)
|
||||
minetest.sound_play(ogg, {
|
||||
pos = pos,
|
||||
gain = GAIN[gain or 1] or 1,
|
||||
max_hear_distance = 15})
|
||||
end
|
||||
|
||||
local function formspec(meta)
|
||||
local idx = meta:contains("idx") and meta:get_int("idx") or 1
|
||||
local gain = meta:contains("gain") and meta:get_int("gain") or 1
|
||||
return "size[8,8]"..
|
||||
"tablecolumns[text,width=5;text]"..
|
||||
"table[0,0;8,6;oggfiles;" .. OGG_FILES .. ";" .. idx .. "]" ..
|
||||
"dropdown[0,6.5;5.5,1.4;gain;1,2,3,4,5;" .. gain .. "]" ..
|
||||
"button[2.5,7.2;3,1;play;" .. S("Play") .. "]"
|
||||
end
|
||||
|
||||
local function play_predefined_sound(pos)
|
||||
local mem = techage.get_mem(pos)
|
||||
if not mem.blocking_time or (mem.blocking_time < minetest.get_gametime()) then
|
||||
local idx = M(pos):get_int("idx")
|
||||
local ogg = techage.OggFileList[idx or 1] or techage.OggFileList[1]
|
||||
local gain = M(pos):get_int("gain")
|
||||
play_sound(pos, ogg, gain)
|
||||
mem.blocking_time = minetest.get_gametime() + 2
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta3_soundblock", {
|
||||
description = S("TA3 Sound Block"),
|
||||
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_sound.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = M(pos)
|
||||
logic.after_place_node(pos, placer, "techage:ta3_soundblock", S("TA3 Sound Block"))
|
||||
logic.infotext(meta, S("TA3 Sound Block"))
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.oggfiles then
|
||||
local mem = techage.get_mem(pos)
|
||||
local t = minetest.explode_table_event(fields.oggfiles)
|
||||
mem.idx = t.row
|
||||
end
|
||||
if fields.gain then
|
||||
M(pos):set_int("gain", tonumber(fields.gain) or 1)
|
||||
end
|
||||
if fields.play then
|
||||
local mem = techage.get_mem(pos)
|
||||
M(pos):set_int("idx", mem.idx or 1)
|
||||
local ogg = techage.OggFileList[mem.idx or 1] or techage.OggFileList[1]
|
||||
play_sound(pos, ogg, M(pos):get_int("gain"))
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
local INFO = [[Commands: 'on', 'sound', 'gain']]
|
||||
|
||||
techage.register_node({"techage:ta3_soundblock"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "info" then
|
||||
return INFO
|
||||
elseif topic == "on" then
|
||||
play_predefined_sound(pos)
|
||||
elseif topic == "sound" then
|
||||
M(pos):set_int("idx", tonumber(payload or 1) or 1)
|
||||
elseif topic == "gain" then
|
||||
M(pos):set_int("gain", tonumber(payload or 1) or 1)
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
print("ta3_soundblock", topic, payload[1], payload[2])
|
||||
if topic == 1 then
|
||||
if payload[1] == 1 then
|
||||
play_predefined_sound(pos)
|
||||
return 0
|
||||
end
|
||||
elseif topic == 14 then
|
||||
if payload[1] == 1 then
|
||||
M(pos):set_int("gain", payload[2])
|
||||
return 0
|
||||
elseif payload[1] == 2 then
|
||||
M(pos):set_int("idx", payload[2])
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 2 -- unknown or invalid topic
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
local meta = M(pos)
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta3_soundblock",
|
||||
recipe = {
|
||||
{"", "group:wood",""},
|
||||
{"techage:vacuum_tube", "basic_materials:gold_wire", "techage:usmium_nuggets"},
|
||||
{"", "group:wood", ""},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,207 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2020-2022 Joachim Stolberg
|
||||
|
||||
AGPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Turn Controller
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local S = techage.S
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
local mark = dofile(MP .. "/basis/mark_lib.lua")
|
||||
local fly = techage.flylib
|
||||
|
||||
local MAX_BLOCKS = 16
|
||||
|
||||
local function formspec(nvm, meta)
|
||||
local status = meta:get_string("status")
|
||||
local path = meta:contains("path") and meta:get_string("path") or "0,3,0"
|
||||
return "size[8,3]" ..
|
||||
"box[0,-0.1;7.8,0.5;#c6e8ff]" ..
|
||||
"label[0.2,-0.1;" .. minetest.colorize( "#000000", S("TA4 Turn Controller")) .. "]" ..
|
||||
--techage.wrench_image(7.4, -0.05) ..
|
||||
"button[0.1,0.7;3.8,1;record;" .. S("Record") .. "]" ..
|
||||
"button[4.1,0.7;3.8,1;done;" .. S("Done") .. "]" ..
|
||||
"button[0.1,1.5;3.8,1;left;" .. S("Turn left") .. "]" ..
|
||||
"button[4.1,1.5;3.8,1;right;" .. S("Turn right") .. "]" ..
|
||||
"label[0.3,2.5;" .. status .. "]"
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_turncontroller", {
|
||||
description = S("TA4 Turn Controller"),
|
||||
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.png^techage_appl_turn.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
techage.logic.after_place_node(pos, placer, "techage:ta4_turncontroller", S("TA4 Turn Controller"))
|
||||
techage.logic.infotext(meta, S("TA4 Turn Controller"))
|
||||
local nvm = techage.get_nvm(pos)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
|
||||
if fields.record then
|
||||
nvm.lpos1 = {}
|
||||
nvm.lpos2 = {}
|
||||
meta:set_string("status", S("Recording..."))
|
||||
local name = player:get_player_name()
|
||||
minetest.chat_send_player(name, S("Click on all blocks that shall be turned"))
|
||||
mark.start(name, MAX_BLOCKS)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.done then
|
||||
local name = player:get_player_name()
|
||||
local pos_list = mark.get_poslist(name)
|
||||
local text = #pos_list.." "..S("block positions are stored.")
|
||||
meta:set_string("status", text)
|
||||
nvm.lpos = pos_list
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.left then
|
||||
meta:set_string("status", "")
|
||||
if nvm.lpos then
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "l")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
elseif fields.right then
|
||||
meta:set_string("status", "")
|
||||
if nvm.lpos then
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
local name = player:get_player_name()
|
||||
mark.stop(name)
|
||||
end
|
||||
end
|
||||
meta:set_string("formspec", formspec(nvm, meta))
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local name = digger:get_player_name()
|
||||
mark.unmark_all(name)
|
||||
mark.stop(name)
|
||||
techage.remove_node(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
local INFO = [[Commands: 'left', 'right', 'uturn']]
|
||||
|
||||
techage.register_node({"techage:ta4_turncontroller"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "info" then
|
||||
return INFO
|
||||
elseif topic == "left" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "l")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return true
|
||||
end
|
||||
return false
|
||||
elseif topic == "right" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return true
|
||||
end
|
||||
return false
|
||||
elseif topic == "uturn" then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_beduino_receive_cmnd = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == 12 then
|
||||
if payload[1] == 1 then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "l")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return 0
|
||||
end
|
||||
return 3
|
||||
elseif payload[1] == 2 then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return 0
|
||||
end
|
||||
return 3
|
||||
elseif payload[1] == 3 then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
new_posses = fly.rotate_nodes(pos, nvm.lpos, "r")
|
||||
if new_posses then
|
||||
nvm.lpos = new_posses
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 3
|
||||
end
|
||||
return 2
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end,
|
||||
on_node_load = function(pos, node)
|
||||
M(pos):set_string("status", "")
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_turncontroller",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "dye:blue", "default:steel_ingot"},
|
||||
{"techage:aluminum", "techage:baborium_ingot", "techage:aluminum"},
|
||||
{"group:wood", "basic_materials:gear_steel", "group:wood"},
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user