big rewrite commit
parent
05bbd3c4e3
commit
7cf9bd29d4
26
abm.lua
26
abm.lua
|
@ -1,30 +1,22 @@
|
|||
|
||||
minetest.register_abm({
|
||||
label = "Telemosaic beacon effect",
|
||||
nodenames = {"telemosaic:beacon"},
|
||||
interval = 2.0,
|
||||
chance = 2,
|
||||
catch_up = false,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
minetest.add_particlespawner({
|
||||
label = "Telemosaic beacon effect",
|
||||
nodenames = {"group:telemosaic_active"},
|
||||
interval = 2.0,
|
||||
chance = 2,
|
||||
catch_up = false,
|
||||
action = function(pos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 4,
|
||||
time = 2,
|
||||
minpos = vector.add(pos, {x=-0.2, y=0, z=-0.2}),
|
||||
maxpos = vector.add(pos, {x=0.2, y=0, z=0.2}),
|
||||
minvel = {x=0, y=1, z=0},
|
||||
maxvel = {x=0, y=2, z=0},
|
||||
minacc = {x=0, y=0, z=0},
|
||||
maxacc = {x=0, y=0, z=0},
|
||||
minexptime = 1,
|
||||
maxexptime = 2,
|
||||
minsize = 1,
|
||||
maxsize = 1.7,
|
||||
collisiondetection = false,
|
||||
collision_removal = false,
|
||||
object_collision = false,
|
||||
vertical = false,
|
||||
texture = "telemosaic_particle_arrival.png",
|
||||
glow = 9
|
||||
glow = 9
|
||||
})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
for _,protected in pairs({true, false}) do
|
||||
|
||||
local node_name_suffix = protected and "_protected" or ""
|
||||
local texture_overlay = protected and "^telemosaic_beacon_protected_overlay.png" or ""
|
||||
local description_prefix = protected and "Protected " or ""
|
||||
|
||||
minetest.register_node("telemosaic:beacon_off"..node_name_suffix, {
|
||||
description = description_prefix.."Telemosaic Beacon",
|
||||
tiles = {
|
||||
"telemosaic_beacon_off.png"..texture_overlay,
|
||||
"telemosaic_beacon_side.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {cracky = 2, telemosaic = 1, telemosaic_off = 1},
|
||||
on_rightclick = telemosaic.rightclick,
|
||||
digilines = telemosaic.digilines,
|
||||
})
|
||||
|
||||
minetest.register_node("telemosaic:beacon"..node_name_suffix, {
|
||||
description = description_prefix.."Telemosaic Beacon Active (you hacker you!)",
|
||||
tiles = {
|
||||
"telemosaic_beacon_top.png"..texture_overlay,
|
||||
"telemosaic_beacon_side.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {cracky = 2, not_in_creative_inventory = 1, telemosaic = 1, telemosaic_active = 1},
|
||||
drop = "telemosaic:beacon_off"..node_name_suffix,
|
||||
on_rightclick = telemosaic.rightclick,
|
||||
digilines = telemosaic.digilines,
|
||||
})
|
||||
|
||||
minetest.register_node("telemosaic:beacon_err"..node_name_suffix, {
|
||||
description = description_prefix.."Telemosaic Beacon Error (you hacker you!)",
|
||||
tiles = {
|
||||
"telemosaic_beacon_err.png"..texture_overlay,
|
||||
"telemosaic_beacon_side.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {cracky = 2, not_in_creative_inventory = 1, telemosaic = 1, telemosaic_error = 1},
|
||||
drop = "telemosaic:beacon_off"..node_name_suffix,
|
||||
on_rightclick = telemosaic.rightclick,
|
||||
digilines = telemosaic.digilines,
|
||||
})
|
||||
|
||||
minetest.register_node("telemosaic:beacon_disabled"..node_name_suffix, {
|
||||
description = description_prefix.."Telemosaic Beacon Disabled (you hacker you!)",
|
||||
tiles = {
|
||||
"telemosaic_beacon_disabled.png"..texture_overlay,
|
||||
"telemosaic_beacon_side.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {cracky = 2, not_in_creative_inventory = 1, telemosaic = 1, telemosaic_disabled = 1},
|
||||
drop = "telemosaic:beacon_off"..node_name_suffix,
|
||||
on_rightclick = telemosaic.rightclick,
|
||||
digilines = telemosaic.digilines,
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:beacon_off",
|
||||
recipe = {
|
||||
{"default:diamond", "doors:door_wood", "default:diamond"},
|
||||
{"default:obsidian","default:obsidian","default:obsidian"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:beacon_off_protected",
|
||||
type = "shapeless",
|
||||
recipe = {"telemosaic:beacon_off", "default:steel_ingot"}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:beacon_off",
|
||||
type = "shapeless",
|
||||
recipe = {"telemosaic:beacon_off_protected"}
|
||||
})
|
46
crafts.lua
46
crafts.lua
|
@ -1,46 +0,0 @@
|
|||
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'telemosaic:beacon_off',
|
||||
recipe = {
|
||||
{'default:diamond', 'doors:door_wood', 'default:diamond'},
|
||||
{'default:obsidian','default:obsidian','default:obsidian'}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'telemosaic:beacon_off_protected',
|
||||
type = 'shapeless',
|
||||
recipe = {"telemosaic:beacon_off", "default:steel_ingot"}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'telemosaic:extender_one',
|
||||
recipe = {
|
||||
{'default:obsidian','doors:door_wood','default:obsidian'}
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'telemosaic:extender_two',
|
||||
recipe = {
|
||||
{'', 'group:telemosaic_extender_one',''},
|
||||
{'group:telemosaic_extender_one','default:obsidian','group:telemosaic_extender_one'},
|
||||
{'', 'group:telemosaic_extender_one',''}
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = 'telemosaic:extender_three',
|
||||
recipe = {
|
||||
{'', 'group:telemosaic_extender_two',''},
|
||||
{'group:telemosaic_extender_two','default:obsidian','group:telemosaic_extender_two'},
|
||||
{'', 'group:telemosaic_extender_two',''}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- how to recycle a key
|
||||
minetest.register_craft({
|
||||
type = 'shapeless',
|
||||
recipe = {'telemosaic:key'},
|
||||
output = 'default:mese_crystal_fragment'
|
||||
})
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
local function digiline_receive(pos, _, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local set_channel = meta:get("channel") or telemosaic.default_channel
|
||||
if channel ~= set_channel then
|
||||
return
|
||||
end
|
||||
|
||||
if type(msg) == "string" then
|
||||
-- Convert string command to table
|
||||
if msg == "get" or msg == "GET" then
|
||||
msg = {command = "get"}
|
||||
|
||||
elseif msg == "enable" or msg == "disable" then
|
||||
msg = {command = msg}
|
||||
|
||||
elseif msg:match("^setchannel .+") then
|
||||
local c = string.split(msg, " ", true, 1)
|
||||
msg = {command = c[1], channel = c[2]}
|
||||
|
||||
elseif msg:match("^setdest .+") then
|
||||
local c = string.split(msg, " ", true, 1)
|
||||
local p = string.split(c[2], ",")
|
||||
msg = {command = c[1], x = p[1], y = p[2], z = p[3]}
|
||||
end
|
||||
end
|
||||
|
||||
if type(msg) ~= "table" or not msg.command then
|
||||
return
|
||||
end
|
||||
|
||||
if msg.command == "get" then
|
||||
local dest = telemosaic.get_destination(pos)
|
||||
digilines.receptor_send(pos, digilines.rules.default, set_channel, {
|
||||
state = telemosaic.get_state(pos),
|
||||
origin = pos,
|
||||
target = dest,
|
||||
pos = pos,
|
||||
destination = dest,
|
||||
})
|
||||
|
||||
elseif msg.command == "setchannel" then
|
||||
if type(msg.channel) == "string" then
|
||||
meta:set_string("channel", msg.channel)
|
||||
end
|
||||
|
||||
elseif msg.command == "enable" then
|
||||
if telemosaic.get_state(pos) == "disabled" then
|
||||
telemosaic.set_state(pos, "active")
|
||||
end
|
||||
|
||||
elseif msg.command == "disable" then
|
||||
if telemosaic.get_state(pos) == "active" then
|
||||
telemosaic.set_state(pos, "disabled")
|
||||
end
|
||||
|
||||
elseif msg.command == "setdest" then
|
||||
local dest = msg.pos or {
|
||||
x = msg.x,
|
||||
y = msg.y,
|
||||
z = msg.z
|
||||
}
|
||||
if type(dest) ~= "table" then
|
||||
return
|
||||
end
|
||||
dest.x = tonumber(dest.x)
|
||||
dest.y = tonumber(dest.y)
|
||||
dest.z = tonumber(dest.z)
|
||||
if dest.x and dest.y and dest.z then
|
||||
telemosaic.set_destination(pos, dest)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
telemosaic.digilines = {
|
||||
effector = {
|
||||
action = digiline_receive
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
local has_dye = minetest.get_modpath("dye")
|
||||
|
||||
local function pretty_str(s)
|
||||
s = string.upper(string.sub(s, 1, 1))..string.sub(s, 2)
|
||||
local i = string.find(s, "_")
|
||||
if i then
|
||||
local c = string.upper(string.sub(s, i + 1, i + 1))
|
||||
s = string.gsub(s, "_.", " "..c)
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local tiers = {"one", "two", "three"}
|
||||
|
||||
for i, range in pairs(telemosaic.extender_ranges) do
|
||||
local tier = tiers[i]
|
||||
|
||||
minetest.register_node("telemosaic:extender_"..tier, {
|
||||
description = "Telemosaic Extender, Tier "..i..(has_dye and " (Grey)" or ""),
|
||||
tiles = {
|
||||
"telemosaic_extender_"..tier..".png"
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {cracky = 2, telemosaic_extender = range, ["telemosaic_extender_"..tier] = 1},
|
||||
after_place_node = telemosaic.extender_place,
|
||||
after_dig_node = telemosaic.extender_dig,
|
||||
})
|
||||
|
||||
if has_dye then
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "telemosaic:extender_"..tier,
|
||||
recipe = {"group:telemosaic_extender_"..tier, "dye:grey"},
|
||||
})
|
||||
|
||||
for name, color in pairs(telemosaic.extender_colors) do
|
||||
minetest.register_node("telemosaic:extender_"..tier.."_"..name, {
|
||||
description = "Telemosaic Extender, Tier "..i.." ("..pretty_str(name)..")",
|
||||
tiles = {
|
||||
"telemosaic_extender_"..tier..".png^[colorize:"..color
|
||||
},
|
||||
paramtype = "light",
|
||||
groups = {
|
||||
cracky = 2, not_in_creative_inventory = 1,
|
||||
telemosaic_extender = range, ["telemosaic_extender_"..tier] = 1
|
||||
},
|
||||
after_place_node = telemosaic.extender_place,
|
||||
after_dig_node = telemosaic.extender_dig,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "telemosaic:extender_"..tier.."_"..name,
|
||||
recipe = {"group:telemosaic_extender_"..tier, "dye:"..name},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:extender_one",
|
||||
recipe = {
|
||||
{"default:obsidian", "doors:door_wood", "default:obsidian"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:extender_two",
|
||||
recipe = {
|
||||
{"", "group:telemosaic_extender_one", ""},
|
||||
{"group:telemosaic_extender_one", "default:obsidian", "group:telemosaic_extender_one"},
|
||||
{"", "group:telemosaic_extender_one", ""}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "telemosaic:extender_three",
|
||||
recipe = {
|
||||
{"", "group:telemosaic_extender_two", ""},
|
||||
{"group:telemosaic_extender_two", "default:obsidian", "group:telemosaic_extender_two"},
|
||||
{"", "group:telemosaic_extender_two", ""}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,367 @@
|
|||
|
||||
-- Keeps a track of players to prevent teleport spamming
|
||||
local recent_teleports = {}
|
||||
|
||||
|
||||
-- Not the same as `minetest.hash_node_position` and `minetest.get_position_from_hash`
|
||||
local function hash_pos(pos)
|
||||
return math.floor(pos.x + 0.5)..':'..
|
||||
math.floor(pos.y + 0.5)..':'..
|
||||
math.floor(pos.z + 0.5)
|
||||
end
|
||||
|
||||
local function unhash_pos(hash)
|
||||
local list = string.split(hash, ':')
|
||||
local p = {
|
||||
x = tonumber(list[1]),
|
||||
y = tonumber(list[2]),
|
||||
z = tonumber(list[3])
|
||||
}
|
||||
if p.x and p.y and p.z then
|
||||
return p
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Wrap this function to incorporate travel checks from another mod
|
||||
function telemosaic.travel_allowed(player, src, dest)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function telemosaic.is_protected_beacon(pos, player_name)
|
||||
if minetest.get_node(pos).name == "telemosaic:beacon_protected" then
|
||||
if minetest.is_protected(pos, player_name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function telemosaic.get_state(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
|
||||
if not def or not def.groups then return "invalid" end
|
||||
|
||||
if def.groups.telemosaic_off then return "off" end
|
||||
if def.groups.telemosaic_active then return "active" end
|
||||
if def.groups.telemosaic_disabled then return "disabled" end
|
||||
if def.groups.telemosaic_error then return "error" end
|
||||
|
||||
return "invalid"
|
||||
end
|
||||
|
||||
function telemosaic.set_state(pos, state)
|
||||
local node = minetest.get_node(pos)
|
||||
|
||||
if not string.match(node.name, "^telemosaic:beacon") then
|
||||
return -- Not a telemosaic!
|
||||
end
|
||||
|
||||
local new_name = "telemosaic:beacon"
|
||||
|
||||
if state == "off" then
|
||||
new_name = new_name.."_off"
|
||||
elseif state == "error" then
|
||||
new_name = new_name.."_err"
|
||||
elseif state == "disabled" then
|
||||
new_name = new_name.."_disabled"
|
||||
elseif state ~= "active" then
|
||||
return -- Can't set a state that doesn't exist
|
||||
end
|
||||
|
||||
if string.match(node.name, "protected$") then
|
||||
new_name = new_name.."_protected"
|
||||
end
|
||||
|
||||
-- Swap node instead of set node to keep the metadata
|
||||
minetest.swap_node(pos, {name = new_name})
|
||||
end
|
||||
|
||||
function telemosaic.is_valid_destination(pos)
|
||||
local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local pos_top = {x = pos.x, y = pos.y + 2, z = pos.z}
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
local node_above = minetest.get_node_or_nil(pos_above)
|
||||
local node_top = minetest.get_node_or_nil(pos_top)
|
||||
|
||||
if not node or not node_above or not node_top then
|
||||
-- Need to load the map
|
||||
minetest.get_voxel_manip():read_from_map(pos, pos_top)
|
||||
node = node or minetest.get_node(pos)
|
||||
node_above = node_above or minetest.get_node(pos_above)
|
||||
node_top = node_top or minetest.get_node(pos_top)
|
||||
end
|
||||
|
||||
local valid = true
|
||||
|
||||
-- Check if there is a telemosaic at the destination
|
||||
if not string.match(node.name, "^telemosaic:beacon") then
|
||||
valid = false
|
||||
end
|
||||
|
||||
-- Check if the nodes above are not walkable (yes, confusing naming)
|
||||
if node_above.name ~= "air" and node_above.name ~= "vacuum:vacuum" then
|
||||
local def = minetest.registered_nodes[node_above.name]
|
||||
if def and def.walkable then
|
||||
return valid, false
|
||||
end
|
||||
end
|
||||
if node_top.name ~= "air" and node_top.name ~= "vacuum:vacuum" then
|
||||
local def = minetest.registered_nodes[node_top.name]
|
||||
if def and def.walkable then
|
||||
return valid, false
|
||||
end
|
||||
end
|
||||
|
||||
return valid, true
|
||||
end
|
||||
|
||||
function telemosaic.check_beacon(pos, player_name, all_checks)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local dest = unhash_pos(meta:get_string("telemosaic:dest"))
|
||||
local state = telemosaic.get_state(pos)
|
||||
if not dest or state == "invalid" then
|
||||
return false
|
||||
end
|
||||
|
||||
local dist = vector.distance(pos, dest)
|
||||
local range = telemosaic.beacon_range
|
||||
|
||||
local pos1 = {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}
|
||||
local pos2 = {x = pos.x + 3, y = pos.y, z = pos.z + 3}
|
||||
local _, nodes = minetest.find_nodes_in_area(pos1, pos2, "group:telemosaic_extender")
|
||||
|
||||
for node_name, num in pairs(nodes) do
|
||||
range = range + (minetest.get_item_group(node_name, "telemosaic_extender") * num)
|
||||
end
|
||||
|
||||
if dist > range then
|
||||
-- Destination out of range, set beacon to error state
|
||||
telemosaic.set_state(pos, "error")
|
||||
if player_name then
|
||||
local needed = math.ceil(dist - range)
|
||||
minetest.chat_send_player(player_name,
|
||||
"You need to add extenders for "..needed.." nodes."
|
||||
)
|
||||
end
|
||||
return false
|
||||
elseif state == "error" or state == "off" then
|
||||
-- Not out of range anymore, set to active
|
||||
telemosaic.set_state(pos, "active")
|
||||
end
|
||||
|
||||
if not all_checks then
|
||||
return true -- Skip the destination check
|
||||
end
|
||||
|
||||
local valid, open = telemosaic.is_valid_destination(dest)
|
||||
if not valid then
|
||||
if player_name then
|
||||
minetest.chat_send_player(player_name,
|
||||
"No telemosaic at destination."
|
||||
)
|
||||
end
|
||||
return false
|
||||
elseif not open then
|
||||
if player_name then
|
||||
minetest.chat_send_player(player_name,
|
||||
"Destination is blocked."
|
||||
)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function telemosaic.get_destination(pos)
|
||||
local dest_hash = minetest.get_meta(pos):get_string("telemosaic:dest")
|
||||
return unhash_pos(dest_hash)
|
||||
end
|
||||
|
||||
function telemosaic.set_destination(pos, dest)
|
||||
local dest_hash = hash_pos(dest)
|
||||
local src_hash = hash_pos(pos)
|
||||
if src_hash == dest_hash or not telemosaic.is_valid_destination(dest) then
|
||||
return -- Don't allow setting invalid destination
|
||||
end
|
||||
minetest.get_meta(pos):set_string("telemosaic:dest", dest_hash)
|
||||
telemosaic.check_beacon(pos)
|
||||
end
|
||||
|
||||
function telemosaic.teleport(player, src, dest)
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
-- Prevent teleport spamming
|
||||
recent_teleports[player_name] = true
|
||||
minetest.after(telemosaic.teleport_delay,
|
||||
function(name)
|
||||
recent_teleports[name] = nil
|
||||
end,
|
||||
player_name
|
||||
)
|
||||
|
||||
if telemosaic.digilines then
|
||||
-- Send a digiline message about the teleport
|
||||
local channel = minetest.get_meta(src):get("channel") or telemosaic.default_channel
|
||||
digilines.receptor_send(src, digilines.rules.default, channel, {
|
||||
player = player_name,
|
||||
origin = src,
|
||||
target = dest,
|
||||
pos = src,
|
||||
destination = dest,
|
||||
})
|
||||
end
|
||||
|
||||
dest.y = dest.y + 0.5 -- Teleport the player to above the telemosaic
|
||||
player:set_pos(dest)
|
||||
|
||||
minetest.sound_play({name = "telemosaic_departure", gain = 1}, {pos = src, max_hear_distance = 30})
|
||||
minetest.sound_play({name = "telemosaic_arrival", gain = 1}, {pos = dest, max_hear_distance = 30})
|
||||
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.25,
|
||||
minpos = {x = src.x, y = src.y + 0.3, z = src.z},
|
||||
maxpos = {x = src.x, y = src.y + 2, z = src.z},
|
||||
minvel = {x = 1, y = -6, z = 1},
|
||||
maxvel = {x = -1, y = -1, z = -1},
|
||||
minacc = {x = 0, y = -2, z = 0},
|
||||
maxacc = {x = 0, y = -6, z = 0},
|
||||
minexptime = 0.1,
|
||||
minsize = 0.5,
|
||||
maxsize = 1.5,
|
||||
texture = "telemosaic_particle_departure.png",
|
||||
glow = 15,
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.25,
|
||||
minpos = {x = dest.x, y = dest.y + 0.3, z = dest.z},
|
||||
maxpos = {x = dest.x, y = dest.y + 2, z = dest.z},
|
||||
minvel = {x = -1, y = 1, z = -1},
|
||||
maxvel = {x = 1, y = 6, z = 1},
|
||||
minacc = {x = 0, y = -2, z = 0},
|
||||
maxacc = {x = 0, y = -6, z = 0},
|
||||
minexptime = 0.1,
|
||||
minsize = 0.5,
|
||||
maxsize = 1.5,
|
||||
texture = "telemosaic_particle_arrival.png",
|
||||
glow = 15,
|
||||
})
|
||||
end
|
||||
|
||||
function telemosaic.rightclick(pos, node, player, itemstack, pointed_thing)
|
||||
if player.is_fake_player or not minetest.is_player(player) then
|
||||
return itemstack -- No fake players!
|
||||
end
|
||||
|
||||
local item = itemstack:get_name()
|
||||
local player_name = player:get_player_name()
|
||||
local state = telemosaic.get_state(pos)
|
||||
|
||||
if item == "default:mese_crystal_fragment" then
|
||||
-- Try to create a telemosaic key
|
||||
if itemstack:get_count() ~= 1 then
|
||||
minetest.chat_send_player(player_name,
|
||||
"You can only use a singular mese crystal fragment to create a telemosaic key."
|
||||
)
|
||||
else
|
||||
return ItemStack({name = "telemosaic:key", metadata = hash_pos(pos)})
|
||||
end
|
||||
|
||||
elseif item == "telemosaic:key" then
|
||||
-- Try to set a new destination
|
||||
local dest_hash = itemstack:get_metadata()
|
||||
local src_hash = hash_pos(pos)
|
||||
if dest_hash ~= src_hash and not minetest.is_protected(pos, player_name) then
|
||||
local dest = unhash_pos(dest_hash)
|
||||
if not dest then
|
||||
-- This should never happen, but tell the player if it does
|
||||
minetest.chat_send_player(player_name,
|
||||
"Telemosaic key is invalid."
|
||||
)
|
||||
elseif not telemosaic.is_valid_destination(dest) then
|
||||
-- No point setting a destination that doesn't exist
|
||||
minetest.chat_send_player(player_name,
|
||||
"No telemosaic at new destination."
|
||||
)
|
||||
else
|
||||
-- Everything is good, set the destination and update the telemosaic
|
||||
minetest.get_meta(pos):set_string("telemosaic:dest", dest_hash)
|
||||
telemosaic.check_beacon(pos, player_name)
|
||||
end
|
||||
if player:get_player_control().sneak then
|
||||
return itemstack -- Don't destroy key
|
||||
end
|
||||
return ItemStack("default:mese_crystal_fragment")
|
||||
end
|
||||
|
||||
elseif state == "off" or player:get_player_control().sneak then
|
||||
-- Allow player to build on telemosaic
|
||||
local def = minetest.registered_nodes[item]
|
||||
if def and def.on_place and not vector.equals(pos, pointed_thing.above) then
|
||||
-- Need to create a fake pointed_thing to prevent recursion
|
||||
local new_pointed_thing = {
|
||||
type = "node",
|
||||
under = vector.new(pointed_thing.above),
|
||||
above = vector.new(pointed_thing.above)
|
||||
}
|
||||
return def.on_place(itemstack, player, new_pointed_thing)
|
||||
end
|
||||
|
||||
elseif state == "active" and not telemosaic.is_protected_beacon(pos, player_name) then
|
||||
if recent_teleports[player_name] then
|
||||
return itemstack -- Prevent teleport spamming, fail silently
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local dest = unhash_pos(meta:get_string("telemosaic:dest"))
|
||||
if telemosaic.check_beacon(pos, player_name, true) then
|
||||
if telemosaic.travel_allowed(player, pos, dest) then
|
||||
-- Teleport the player!
|
||||
telemosaic.teleport(player, pos, dest)
|
||||
else
|
||||
minetest.chat_send_player(player_name,
|
||||
"Travel to destination is not allowed."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
elseif state == "disabled" then
|
||||
-- Tell the player why they can't use this telemosaic
|
||||
minetest.chat_send_player(player_name,
|
||||
"Telemosaic is disabled."
|
||||
)
|
||||
|
||||
elseif state == "error" then
|
||||
-- Check why the beacon is in error state, and tell the player
|
||||
telemosaic.check_beacon(pos, player_name)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function telemosaic.extender_place(pos, player, itemstack, pointed_thing)
|
||||
local pos1 = {x = pos.x - 3, y = pos.y, z = pos.z - 3}
|
||||
local pos2 = {x = pos.x + 3, y = pos.y + 1, z = pos.z + 3}
|
||||
local nodes = minetest.find_nodes_in_area(pos1, pos2, "group:telemosaic_error")
|
||||
|
||||
for _, node_pos in pairs(nodes) do
|
||||
-- Update telemosaic, and tell them if they need more extenders
|
||||
telemosaic.check_beacon(node_pos, player:get_player_name())
|
||||
end
|
||||
end
|
||||
|
||||
function telemosaic.extender_dig(pos, oldnode, oldmetadata, player)
|
||||
local pos1 = {x = pos.x - 3, y = pos.y, z = pos.z - 3}
|
||||
local pos2 = {x = pos.x + 3, y = pos.y + 1, z = pos.z + 3}
|
||||
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"group:telemosaic_active", "group:telemosaic_disabled"})
|
||||
|
||||
for _, node_pos in pairs(nodes) do
|
||||
-- Update the telemosaic, but don't tell the player anything, they are probably removing it anyway
|
||||
telemosaic.check_beacon(node_pos)
|
||||
end
|
||||
end
|
71
init.lua
71
init.lua
|
@ -7,44 +7,43 @@ A mod which provides player-placed teleport pads
|
|||
|
||||
Copyright (C) 2015 Ben Deutsch <ben@bendeutsch.de>
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
]]
|
||||
|
||||
telemosaic = {
|
||||
-- configuration
|
||||
config = {
|
||||
-- keep emerge_delay lower than teleport_delay!
|
||||
emerge_delay = 0.5, -- seconds
|
||||
teleport_delay = tonumber(minetest.settings:get("telemosaic_teleport_delay")) or 2.0, -- seconds
|
||||
beacon_range = tonumber(minetest.settings:get("telemosaic_beacon_range")) or 20.0, -- max teleport distance
|
||||
extender_ranges = {
|
||||
-- note: not adding beacons here, since they don't extend
|
||||
-- also: base name of colored versions
|
||||
['telemosaic:extender_one'] = tonumber(minetest.settings:get("telemosaic_extender_one_range")) or 5.0,
|
||||
['telemosaic:extender_two'] = tonumber(minetest.settings:get("telemosaic_extender_two_range")) or 20.0,
|
||||
['telemosaic:extender_three'] = tonumber(minetest.settings:get("telemosaic_extender_three_range")) or 80.0,
|
||||
},
|
||||
},
|
||||
teleport_delay = tonumber(minetest.settings:get("telemosaic_teleport_delay")) or 1.0,
|
||||
beacon_range = tonumber(minetest.settings:get("telemosaic_beacon_range")) or 20.0,
|
||||
default_channel = minetest.settings:get("telemosaic_default_channel") or "telemosaic",
|
||||
extender_ranges = {
|
||||
tonumber(minetest.settings:get("telemosaic_extender_one_range")) or 5.0,
|
||||
tonumber(minetest.settings:get("telemosaic_extender_two_range")) or 20.0,
|
||||
tonumber(minetest.settings:get("telemosaic_extender_three_range")) or 80.0,
|
||||
},
|
||||
extender_colors = {
|
||||
white = "#ffffffa0",
|
||||
dark_grey = "#00000090",
|
||||
black = "#000000e0",
|
||||
violet = "#400080b0",
|
||||
blue = "#0000ffb0",
|
||||
cyan = "#00ffffb0",
|
||||
dark_green = "#007000b0",
|
||||
green = "#00ff00b0",
|
||||
yellow = "#ffff00b0",
|
||||
brown = "#402000c0",
|
||||
orange = "#ff8000b0",
|
||||
red = "#ff0000b0",
|
||||
magenta = "#ff00ffb0",
|
||||
pink = "#ff8080b0",
|
||||
},
|
||||
}
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
dofile(modpath.."/teleport.lua")
|
||||
dofile(modpath.."/crafts.lua")
|
||||
dofile(modpath.."/abm.lua")
|
||||
local MP = minetest.get_modpath("telemosaic")
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
dofile(MP.."/digilines.lua")
|
||||
end
|
||||
|
||||
dofile(MP.."/functions.lua")
|
||||
dofile(MP.."/beacon.lua")
|
||||
dofile(MP.."/extender.lua")
|
||||
dofile(MP.."/key.lua")
|
||||
dofile(MP.."/abm.lua")
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
minetest.register_tool("telemosaic:key", {
|
||||
description = "Telemosaic Key",
|
||||
inventory_image = "telemosaic_key.png",
|
||||
stack_max = 1,
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
-- Use key to toggle telemosaic on/off
|
||||
local name = player:get_player_name()
|
||||
local pos = pointed_thing.under
|
||||
local state = telemosaic.get_state(pos)
|
||||
if state == "active" and not minetest.is_protected(pos, name) then
|
||||
telemosaic.set_state(pos, "disabled")
|
||||
elseif state == "disabled" and not minetest.is_protected(pos, name) then
|
||||
telemosaic.set_state(pos, "active")
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
recipe = {"telemosaic:key"},
|
||||
output = "default:mese_crystal_fragment"
|
||||
})
|
|
@ -1,14 +1,17 @@
|
|||
#The range of the teleport beacon
|
||||
telemosaic_beacon_range (Beacon range) string 20.0
|
||||
#The base range of the teleport beacon
|
||||
telemosaic_beacon_range (Beacon range) int 20
|
||||
|
||||
#The range of the tier one extender
|
||||
telemosaic_extender_one_range (Extender tier one range) string 5.0
|
||||
#The extending range of the tier 1 extender
|
||||
telemosaic_extender_one_range (Extender tier 1 range) int 5
|
||||
|
||||
#The range of the tier two extender
|
||||
telemosaic_extender_two_range (Extender tier two range) string 20.0
|
||||
#The extending range of the tier 2 extender
|
||||
telemosaic_extender_two_range (Extender tier 2 range) int 20
|
||||
|
||||
#The range of the tier three extender
|
||||
telemosaic_extender_three_range (Extender tier three range) string 80.0
|
||||
#The extending range of the tier 3 extender
|
||||
telemosaic_extender_three_range (Extender tier 2 range) int 80
|
||||
|
||||
#The delay before player is teleported
|
||||
telemosaic_teleport_delay (Teleport delay) string 2.0
|
||||
#The minimum delay between player teleports
|
||||
telemosaic_teleport_delay (Teleport delay) float 1.0
|
||||
|
||||
# The default digilines channel for beacons
|
||||
telemosaic_default_channel (Default channel) string telemosaic
|
||||
|
|
541
teleport.lua
541
teleport.lua
|
@ -1,541 +0,0 @@
|
|||
local C = telemosaic.config
|
||||
|
||||
local recent_teleports = {}
|
||||
|
||||
local function hash_pos(pos)
|
||||
return math.floor(pos.x + 0.5) .. ':' ..
|
||||
math.floor(pos.y + 0.5) .. ':' ..
|
||||
math.floor(pos.z + 0.5)
|
||||
end
|
||||
local function unhash_pos(hash)
|
||||
local pos = {}
|
||||
local list = string.split(hash, ':')
|
||||
pos.x = tonumber(list[1])
|
||||
pos.y = tonumber(list[2])
|
||||
pos.z = tonumber(list[3])
|
||||
return pos
|
||||
end
|
||||
|
||||
local function count_extenders(pos)
|
||||
local extended = 0.0
|
||||
for z=-3,3 do
|
||||
for x=-3,3 do
|
||||
local node = minetest.get_node({ x=pos.x+x, y=pos.y, z=pos.z+z})
|
||||
local name = node.name
|
||||
-- trim color off the back
|
||||
name = string.gsub(name, '^(telemosaic:extender_%a+)_.+', '%1')
|
||||
extended = extended + ( C.extender_ranges[name] or 0.0 )
|
||||
end
|
||||
end
|
||||
--print("Total extended: " .. extended)
|
||||
return extended
|
||||
end
|
||||
|
||||
-- returns true if the beacon is in an error state (protected or not)
|
||||
local function is_err_beacon(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not node then
|
||||
-- no node or name
|
||||
return false
|
||||
end
|
||||
return node.name == "telemosaic:beacon_err" or node.name == "telemosaic:beacon_err_protected"
|
||||
end
|
||||
|
||||
-- returns true if the beacon is disabled state (protected or not)
|
||||
local function is_disabled_beacon(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if not node then
|
||||
-- no node or name
|
||||
return false
|
||||
end
|
||||
return node.name == "telemosaic:beacon_disabled" or node.name == "telemosaic:beacon_disabled_protected"
|
||||
end
|
||||
|
||||
-- swaps out the beacon with the new state suffix
|
||||
local function swap_beacon(pos, new_state_suffix)
|
||||
local node = minetest.get_node(pos)
|
||||
if not node then
|
||||
-- no node at pos
|
||||
return
|
||||
end
|
||||
|
||||
local name = node.name
|
||||
local new_node_name = "telemosaic:beacon" .. new_state_suffix
|
||||
|
||||
if string.match(name, "_protected") then
|
||||
-- protected beacon
|
||||
new_node_name = new_node_name .. "_protected"
|
||||
end
|
||||
|
||||
minetest.swap_node(pos, { name = new_node_name })
|
||||
end
|
||||
|
||||
|
||||
local function extender_place(placepos, placer, itemstack, pointed_thing)
|
||||
-- go over all possible *err* beacons, and update them
|
||||
for z=-3,3 do
|
||||
for x=-3,3 do
|
||||
local pos = { x=placepos.x+x, y=placepos.y, z=placepos.z+z }
|
||||
if is_err_beacon(pos) then
|
||||
-- candidate!
|
||||
local dest_hash = minetest.get_meta(pos):get_string('telemosaic:dest')
|
||||
|
||||
if dest_hash ~= nil and dest_hash ~= '' then
|
||||
local dest = unhash_pos(dest_hash)
|
||||
local extended = count_extenders(pos)
|
||||
local dist = vector.distance(pos, dest)
|
||||
|
||||
if dist <= C.beacon_range + extended then
|
||||
-- upgrade :-)
|
||||
swap_beacon(pos, "")
|
||||
|
||||
else
|
||||
local count = math.ceil(dist - (C.beacon_range + extended))
|
||||
minetest.chat_send_player(
|
||||
placer:get_player_name(),
|
||||
"You still need to add extensions for "..count.." nodes"
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function extender_dig(digpos, oldnode, oldmetadata, digger)
|
||||
-- go over all possible *actual* beacons, and update them
|
||||
for z=-3,3 do
|
||||
for x=-3,3 do
|
||||
local pos = { x=digpos.x+x, y=digpos.y, z=digpos.z+z }
|
||||
local node = minetest.get_node(pos)
|
||||
if node ~= nil and (node.name == 'telemosaic:beacon'
|
||||
or node.name == 'telemosaic:beacon_disabled') then
|
||||
-- candidate!
|
||||
local dest_hash = minetest.get_meta(pos):get_string('telemosaic:dest')
|
||||
if dest_hash ~= nil and dest_hash ~= '' then
|
||||
local dest = unhash_pos(dest_hash)
|
||||
local extended = count_extenders(pos)
|
||||
local dist = vector.distance(pos, dest)
|
||||
|
||||
if dist > C.beacon_range + extended then
|
||||
-- downgrade :-(
|
||||
swap_beacon(pos, "_err")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function check_teleport_dest(dest)
|
||||
-- check the destination node for beacons, and the two nodes
|
||||
-- above for "walkthrough"
|
||||
-- "ignore" is ok, we could not emerge in time then.
|
||||
local dest_bot = minetest.get_node({ x = dest.x, y = dest.y , z = dest.z })
|
||||
local dest_mid = minetest.get_node({ x = dest.x, y = dest.y+1, z = dest.z })
|
||||
local dest_top = minetest.get_node({ x = dest.x, y = dest.y+2, z = dest.z })
|
||||
--print ("Looking at " .. dest_bot.name .. ", " .. dest_mid.name .. ", " .. dest_top.name)
|
||||
local dest_ok = true
|
||||
if dest_bot.name ~= 'ignore' and not string.match(dest_bot.name, '^telemosaic:beacon') then
|
||||
dest_ok = false
|
||||
--print("Bottom is not beacon")
|
||||
end
|
||||
if dest_mid.name ~= 'ignore' and dest_mid.name ~= 'air' then
|
||||
local def = minetest.registered_nodes[dest_mid.name]
|
||||
if def and def.walkable then
|
||||
dest_ok = false
|
||||
--print("Mid is walkable")
|
||||
end
|
||||
end
|
||||
if dest_top.name ~= 'ignore' and dest_top.name ~= 'air' then
|
||||
local def = minetest.registered_nodes[dest_top.name]
|
||||
if def and def.walkable then
|
||||
dest_ok = false
|
||||
--print("Top is walkable")
|
||||
end
|
||||
end
|
||||
return dest_ok
|
||||
end
|
||||
|
||||
local function is_protected_beacon(pos, player)
|
||||
if minetest.get_node(pos).name == 'telemosaic:beacon_protected' then
|
||||
-- check protection on protected telemosaic
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
-- protected telemosaic
|
||||
return true
|
||||
end
|
||||
end
|
||||
-- not a protected telemosaic
|
||||
return false
|
||||
end
|
||||
|
||||
-- digilines optional support
|
||||
local DEFAULT_CHANNEL = "telemosaic"
|
||||
|
||||
local on_digiline_receive = function(pos, _, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local setchan = meta:contains("channel") and meta:get_string("channel") or DEFAULT_CHANNEL
|
||||
if channel ~= setchan then
|
||||
return false
|
||||
end
|
||||
if type(msg) == "string" then
|
||||
local a = string.split(msg, " ")
|
||||
msg = { command = a[1], channel = a[2] }
|
||||
elseif type(msg) ~= "table" then
|
||||
return false
|
||||
end
|
||||
if msg.command == "setchannel" then
|
||||
if type(msg.channel) == "string" then
|
||||
meta:set_string("channel", msg.channel)
|
||||
end
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- for all states but disabled and active beacons: just accept wiring and channel setting
|
||||
local telemosaic_digiline_base = {
|
||||
receptor = {},
|
||||
effector = { action = on_digiline_receive }
|
||||
}
|
||||
-- for active and disabled beacon , also implement state switching
|
||||
local telemosaic_digiline_switching = {
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = function(pos, _, channel, msg)
|
||||
if on_digiline_receive(pos, _, channel, msg) then
|
||||
local cmd = (type(msg) == "table") and msg.command or msg
|
||||
if cmd == "enable" then
|
||||
swap_beacon(pos, "")
|
||||
elseif cmd == "disable" then
|
||||
swap_beacon(pos, "_disabled")
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
-- teleports the player with given telemosaic pos
|
||||
local function do_teleport(pos, player)
|
||||
|
||||
-- prevent teleport spamming
|
||||
local player_name = player:get_player_name()
|
||||
if recent_teleports[player_name] then
|
||||
return
|
||||
end
|
||||
|
||||
if is_err_beacon(pos) or is_disabled_beacon(pos) then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local dest_hash = meta:get_string('telemosaic:dest')
|
||||
if dest_hash ~= nil and dest_hash ~= '' then
|
||||
local dest = unhash_pos(dest_hash)
|
||||
|
||||
-- test destination nodes
|
||||
local dest_ok = check_teleport_dest(dest)
|
||||
|
||||
--print("Ping to " .. dest_hash)
|
||||
local extended = count_extenders(pos)
|
||||
-- check for range before teleport (with leeway)
|
||||
local dist = vector.distance(pos, dest)
|
||||
--print("Dist :" .. (dist-0.5) .. " to " .. (C.beacon_range + extended))
|
||||
|
||||
if dest_ok and dist - 0.5 <= C.beacon_range + extended and telemosaic.travel_allowed(player, pos, dest) then
|
||||
|
||||
if telemosaic_digiline_switching ~= nil then
|
||||
local chan = meta:contains("channel") and meta:get_string("channel") or DEFAULT_CHANNEL
|
||||
digilines.receptor_send(pos, digilines.rules.default, chan, {
|
||||
player = player:get_player_name(),
|
||||
hashpos = { origin = hash_pos(pos), target = dest_hash },
|
||||
origin = pos,
|
||||
target = dest,
|
||||
})
|
||||
end
|
||||
|
||||
dest.y = dest.y + 0.5
|
||||
|
||||
minetest.sound_play( {name="telemosaic_set", gain=1}, {pos=pos, max_hear_distance=30})
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.25,
|
||||
minpos = {x=pos.x, y=pos.y+0.3, z=pos.z},
|
||||
maxpos = {x=pos.x, y=pos.y+2, z=pos.z},
|
||||
minvel = {x = 1, y = -6, z = 1},
|
||||
maxvel = {x = -1, y = -1, z = -1},
|
||||
minacc = {x = 0, y = -2, z = 0},
|
||||
maxacc = {x = 0, y = -6, z = 0},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 1,
|
||||
minsize = 0.5,
|
||||
maxsize = 1.5,
|
||||
texture = "telemosaic_particle_departure.png",
|
||||
glow = 15,
|
||||
})
|
||||
player:set_pos(dest)
|
||||
|
||||
minetest.sound_play( {name="telemosaic_teleport", gain=1}, {pos=dest, max_hear_distance=30})
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.25,
|
||||
minpos = {x=dest.x, y=dest.y+0.3, z=dest.z},
|
||||
maxpos = {x=dest.x, y=dest.y+2, z=dest.z},
|
||||
minvel = {x = -1, y = 1, z = -1},
|
||||
maxvel = {x = 1, y = 6, z = 1},
|
||||
minacc = {x = 0, y = -2, z = 0},
|
||||
maxacc = {x = 0, y = -6, z = 0},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 1,
|
||||
minsize = 0.5,
|
||||
maxsize = 1.5,
|
||||
texture = "telemosaic_particle_arrival.png",
|
||||
glow = 15,
|
||||
})
|
||||
|
||||
-- prevent teleport spamming
|
||||
recent_teleports[player_name] = true
|
||||
minetest.after(1,
|
||||
function(name)
|
||||
recent_teleports[name] = nil
|
||||
end,
|
||||
player_name)
|
||||
-- else
|
||||
-- beacon is in error, one way or another.
|
||||
-- but don't swap it out - we won't get it back otherwise!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function beacon_rightclick(pos, node, player, itemstack, pointed_thing)
|
||||
local name = itemstack:get_name()
|
||||
--print("Clicked by a " ..name)
|
||||
if name == 'default:mese_crystal_fragment' and itemstack:get_count() == 1 then
|
||||
--print("Clicked by a single key")
|
||||
itemstack = ItemStack({
|
||||
name = "telemosaic:key",
|
||||
count = 1,
|
||||
wear = 0,
|
||||
metadata = hash_pos(pointed_thing.under),
|
||||
})
|
||||
elseif name == 'telemosaic:key' then
|
||||
local posstring = itemstack:get_metadata()
|
||||
local thispos = hash_pos(pointed_thing.under)
|
||||
--print("Key with metadata " .. posstring)
|
||||
if posstring ~= thispos and not minetest.is_protected(pointed_thing.under, player:get_player_name()) then
|
||||
local dest_pos = unhash_pos(posstring)
|
||||
local extended = count_extenders(pointed_thing.under)
|
||||
if vector.distance(dest_pos, pointed_thing.under) <= C.beacon_range + extended then
|
||||
swap_beacon(pointed_thing.under, "")
|
||||
else
|
||||
swap_beacon(pointed_thing.under, "_err")
|
||||
end
|
||||
|
||||
-- set the destination anyway, it just won't work as
|
||||
-- long as the beacon is in err state
|
||||
local meta = minetest.get_meta(pointed_thing.under)
|
||||
meta:set_string('telemosaic:dest', posstring)
|
||||
--print ("set to " .. meta:get_string('telemosaic:dest'))
|
||||
itemstack = ItemStack({
|
||||
name = "default:mese_crystal_fragment",
|
||||
count = 1, wear = 0,
|
||||
})
|
||||
end
|
||||
-- elseif player:get_player_control().sneak then
|
||||
-- NOTE: shift-place commented out due to recursion-issue
|
||||
-- NOTE: https://github.com/pandorabox-io/pandorabox.io/issues/439
|
||||
-- NOTE: workaround: place another node below/behind to build on the beacon
|
||||
-- normal place
|
||||
-- local def = minetest.registered_nodes[itemstack:get_name()]
|
||||
-- if def then
|
||||
-- return def.on_place(itemstack, player, pointed_thing)
|
||||
-- end
|
||||
|
||||
elseif not is_protected_beacon(pos, player) then
|
||||
-- teleport when right-clicked
|
||||
do_teleport(pos, player)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
-- register protected and plain beacons with different suffixes, names and textures
|
||||
for _,is_protected in pairs({ true, false }) do
|
||||
|
||||
local node_name_suffix = ""
|
||||
local texture_overlay = ""
|
||||
local description_prefix = ""
|
||||
|
||||
if is_protected then
|
||||
node_name_suffix = "_protected"
|
||||
texture_overlay = "^telemosaic_beacon_protected_overlay.png"
|
||||
description_prefix = "Protected "
|
||||
end
|
||||
|
||||
minetest.register_node('telemosaic:beacon' .. node_name_suffix, {
|
||||
description = description_prefix .. 'Telemosaic beacon (on)',
|
||||
tiles = {
|
||||
'telemosaic_beacon_top.png' .. texture_overlay,
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = { cracky = 2, not_in_creative_inventory = 1 },
|
||||
drop = 'telemosaic:beacon_off',
|
||||
on_rightclick = beacon_rightclick,
|
||||
digiline = telemosaic_digiline_switching
|
||||
})
|
||||
|
||||
minetest.register_node('telemosaic:beacon_err' .. node_name_suffix, {
|
||||
description = description_prefix .. 'Telemosaic beacon (err)',
|
||||
tiles = {
|
||||
'telemosaic_beacon_err.png' .. texture_overlay,
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = { cracky = 2, not_in_creative_inventory = 1 },
|
||||
drop = 'telemosaic:beacon_off',
|
||||
on_rightclick = beacon_rightclick,
|
||||
digiline = telemosaic_digiline_base
|
||||
})
|
||||
|
||||
minetest.register_node('telemosaic:beacon_off' .. node_name_suffix, {
|
||||
description = description_prefix .. 'Telemosaic beacon',
|
||||
tiles = {
|
||||
'telemosaic_beacon_off.png' .. texture_overlay,
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = { cracky = 2 },
|
||||
on_rightclick = beacon_rightclick,
|
||||
on_construct = function(pos)
|
||||
minetest.get_meta(pos):set_string("channel", DEFAULT_CHANNEL)
|
||||
end,
|
||||
digiline = telemosaic_digiline_base
|
||||
})
|
||||
|
||||
minetest.register_node('telemosaic:beacon_disabled' .. node_name_suffix, {
|
||||
description = description_prefix .. 'Telemosaic beacon (disabled)',
|
||||
tiles = {
|
||||
'telemosaic_beacon_disabled.png' .. texture_overlay,
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
'telemosaic_beacon_side.png',
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = { cracky = 2, not_in_creative_inventory = 1 },
|
||||
drop = 'telemosaic:beacon_off',
|
||||
on_rightclick = beacon_rightclick,
|
||||
digiline = telemosaic_digiline_switching
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
|
||||
minetest.register_tool('telemosaic:key', {
|
||||
description = 'Telemosaic key',
|
||||
inventory_image = 'telemosaic_key.png',
|
||||
stack_max = 1,
|
||||
groups = { not_in_creative_inventory = 1 },
|
||||
})
|
||||
|
||||
-- extenders come in three strengths, and many colors
|
||||
|
||||
local strengths = {
|
||||
-- index starts at 1
|
||||
'one',
|
||||
'two',
|
||||
'three',
|
||||
}
|
||||
local colors = {
|
||||
-- TODO: localisation
|
||||
-- default: { name= 'grey', value= '#ffffff00'},
|
||||
{ name= 'white', value= '#ffffff80'},
|
||||
{ name= 'dark_grey', value= '#00000080'},
|
||||
{ name= 'black', value= '#000000c0'},
|
||||
{ name= 'violet', value= '#40008080'},
|
||||
{ name= 'blue', value= '#0000ff80'},
|
||||
{ name= 'cyan', value= '#00ffff80'},
|
||||
{ name= 'dark_green', value= '#00800080'},
|
||||
{ name= 'green', value= '#00ff0080'},
|
||||
{ name= 'yellow', value= '#ffff0080'},
|
||||
{ name= 'brown', value= '#80400080'},
|
||||
{ name= 'orange', value= '#ff800080'},
|
||||
{ name= 'red', value= '#ff000080'},
|
||||
{ name= 'magenta', value= '#ff00ff80'},
|
||||
{ name= 'pink', value= '#ff808080'},
|
||||
}
|
||||
|
||||
for num, strength in ipairs(strengths) do
|
||||
minetest.register_node(string.format('telemosaic:extender_%s', strength), {
|
||||
description = string.format('Telemosaic extender, tier %d', num),
|
||||
tiles = {
|
||||
string.format('telemosaic_extender_%s.png', strength)
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = { cracky = 2, [string.format('telemosaic_extender_%s', strength)] = 1 },
|
||||
after_place_node = extender_place,
|
||||
after_dig_node = extender_dig,
|
||||
})
|
||||
-- colored versions, not in creative inventory, if dyes available
|
||||
if minetest.get_modpath('dye') then
|
||||
for _,c in ipairs(colors) do
|
||||
minetest.register_node(string.format('telemosaic:extender_%s_%s', strength, c.name), {
|
||||
description = string.format('Telemosaic extender, tier %d (%s)', num, c.name),
|
||||
tiles = {
|
||||
string.format('telemosaic_extender_%s.png^[colorize:%s', strength, c.value),
|
||||
},
|
||||
paramtype = 'light',
|
||||
groups = {
|
||||
cracky = 2,
|
||||
[string.format('telemosaic_extender_%s', strength)] = 1,
|
||||
not_in_creative_inventory = 1
|
||||
},
|
||||
after_place_node = extender_place,
|
||||
after_dig_node = extender_dig,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- coloring recipes
|
||||
if minetest.get_modpath('dye') then
|
||||
for num, strength in ipairs(strengths) do
|
||||
-- uncolor
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = string.format('telemosaic:extender_%s', strength),
|
||||
recipe = { string.format('group:telemosaic_extender_%s', strength), 'dye:grey' },
|
||||
})
|
||||
-- color with dye
|
||||
for _,c in ipairs(colors) do
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = string.format('telemosaic:extender_%s_%s', strength, c.name),
|
||||
recipe = { string.format('group:telemosaic_extender_%s', strength), string.format('dye:%s', c.name) },
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
telemosaic.travel_allowed = function(player, src, dest)
|
||||
return true
|
||||
end
|
Loading…
Reference in New Issue