forked from minetest-mods/nether
Place_Schematic uses correct frame and wormhole nodes
This requires a cache-invalidation hack borrowed from cloudlands mod. Also, null reference fixes in ensure_remote_portal_then_teleport and locate_or_build_portal, and minor improvements
This commit is contained in:
parent
7cff6b8cc2
commit
31cf6a9bc3
@ -63,7 +63,7 @@ east/west.
|
|||||||
nether.PortalShape_Traditional = {
|
nether.PortalShape_Traditional = {
|
||||||
size = vector.new(4, 5, 1), -- size of the portal, and not necessarily the size of the schematic,
|
size = vector.new(4, 5, 1), -- size of the portal, and not necessarily the size of the schematic,
|
||||||
-- which may clear area around the portal.
|
-- which may clear area around the portal.
|
||||||
schematic_filename = minetest.get_modpath("nether") .. "/schematics/nether_portal.mts",
|
schematic_filename = nether.path .. "/schematics/nether_portal.mts",
|
||||||
|
|
||||||
-- returns the coords for minetest.place_schematic() that will place the schematic on the anchorPos
|
-- returns the coords for minetest.place_schematic() that will place the schematic on the anchorPos
|
||||||
get_schematicPos_from_anchorPos = function(anchorPos, orientation)
|
get_schematicPos_from_anchorPos = function(anchorPos, orientation)
|
||||||
@ -217,6 +217,7 @@ local is_frame_node = {}
|
|||||||
local ignition_item_name
|
local ignition_item_name
|
||||||
local S = nether.get_translator
|
local S = nether.get_translator
|
||||||
local mod_storage = minetest.get_mod_storage()
|
local mod_storage = minetest.get_mod_storage()
|
||||||
|
local malleated_filenames = {}
|
||||||
|
|
||||||
|
|
||||||
local function get_timerPos_from_p1_and_p2(p1, p2)
|
local function get_timerPos_from_p1_and_p2(p1, p2)
|
||||||
@ -344,7 +345,7 @@ local function list_closest_portals(portal_definition, anchorPos, distance_limit
|
|||||||
local distance = math.hypot(y * y_factor, math.hypot(x, z))
|
local distance = math.hypot(y * y_factor, math.hypot(x, z))
|
||||||
if distance <= distance_limit or distance_limit < 0 then
|
if distance <= distance_limit or distance_limit < 0 then
|
||||||
local info = minetest.deserialize(value) or {}
|
local info = minetest.deserialize(value) or {}
|
||||||
if DEBUG then minetest.chat_send_all("found at distance " .. distance .. " from dest " .. minetest.pos_to_string(anchorPos) .. ", found: " .. minetest.pos_to_string(found_anchorPos) .. " orientation " .. info.orientation) end
|
if DEBUG then minetest.chat_send_all("found " .. found_name .. " listed at distance " .. distance .. " from dest " .. minetest.pos_to_string(anchorPos) .. ", found: " .. minetest.pos_to_string(found_anchorPos) .. " orientation " .. info.orientation) end
|
||||||
info.anchorPos = found_anchorPos
|
info.anchorPos = found_anchorPos
|
||||||
info.distance = distance
|
info.distance = distance
|
||||||
result[distance] = info
|
result[distance] = info
|
||||||
@ -381,7 +382,7 @@ end
|
|||||||
function ambient_sound_stop(timerNodeMeta)
|
function ambient_sound_stop(timerNodeMeta)
|
||||||
if timerNodeMeta ~= nil then
|
if timerNodeMeta ~= nil then
|
||||||
local soundHandle = timerNodeMeta:get_int("ambient_sound_handle")
|
local soundHandle = timerNodeMeta:get_int("ambient_sound_handle")
|
||||||
minetest.sound_stop(soundHandle)
|
minetest.sound_fade(soundHandle, -3, 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -622,12 +623,26 @@ local function build_portal(portal_definition, anchorPos, orientation, destinati
|
|||||||
|
|
||||||
minetest.place_schematic(
|
minetest.place_schematic(
|
||||||
portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation),
|
portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation),
|
||||||
portal_definition.shape.schematic_filename,
|
portal_definition.schematic_filename,
|
||||||
orientation,
|
orientation,
|
||||||
nil,
|
{ -- node replacements
|
||||||
|
["default:obsidian"] = portal_definition.frame_node_name,
|
||||||
|
["nether:portal"] = portal_definition.wormhole_node_name
|
||||||
|
},
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if DEBUG then minetest.chat_send_all("Placed portal schematic at " .. minetest.pos_to_string(portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation)) .. ", orientation " .. orientation) end
|
-- set the param2 on wormhole nodes to ensure they are the right color
|
||||||
|
local wormholeNode = {
|
||||||
|
name = portal_definition.wormhole_node_name,
|
||||||
|
param2 = get_param2_from_color_and_orientation(portal_definition.wormhole_node_color, orientation)
|
||||||
|
}
|
||||||
|
portal_definition.shape.apply_func_to_wormhole_nodes(
|
||||||
|
anchorPos,
|
||||||
|
orientation,
|
||||||
|
function(pos) minetest.swap_node(pos, wormholeNode) end
|
||||||
|
)
|
||||||
|
|
||||||
|
if DEBUG then minetest.chat_send_all("Placed " .. portal_definition.name .. " portal schematic at " .. minetest.pos_to_string(portal_definition.shape.get_schematicPos_from_anchorPos(anchorPos, orientation)) .. ", orientation " .. orientation) end
|
||||||
|
|
||||||
set_portal_metadata(portal_definition, anchorPos, orientation, destination_wormholePos)
|
set_portal_metadata(portal_definition, anchorPos, orientation, destination_wormholePos)
|
||||||
|
|
||||||
@ -701,7 +716,8 @@ local function locate_or_build_portal(portal_definition, suggested_wormholePos,
|
|||||||
set_portal_metadata_and_ignite(portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
set_portal_metadata_and_ignite(portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
||||||
|
|
||||||
else
|
else
|
||||||
result_anchorPos, result_orientation = portal_definition.shape.get_anchorPos_from_wormholePos(suggested_wormholePos, suggested_orientation)
|
result_orientation = suggested_orientation
|
||||||
|
result_anchorPos = portal_definition.shape.get_anchorPos_from_wormholePos(suggested_wormholePos, result_orientation)
|
||||||
build_portal(portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
build_portal(portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
||||||
-- make sure portal isn't overwritten by ongoing generation/emerge
|
-- make sure portal isn't overwritten by ongoing generation/emerge
|
||||||
minetest.after(2, remote_portal_checkup, 2, portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
minetest.after(2, remote_portal_checkup, 2, portal_definition, result_anchorPos, result_orientation, destination_wormholePos)
|
||||||
@ -781,7 +797,8 @@ local function ensure_remote_portal_then_teleport(player, portal_definition, loc
|
|||||||
-- debounce - check player is still standing in the *same* portal that called this function
|
-- debounce - check player is still standing in the *same* portal that called this function
|
||||||
local meta = minetest.get_meta(playerPos)
|
local meta = minetest.get_meta(playerPos)
|
||||||
local local_p1, local_p2 = portal_definition.shape:get_p1_and_p2_from_anchorPos(local_anchorPos, local_orientation)
|
local local_p1, local_p2 = portal_definition.shape:get_p1_and_p2_from_anchorPos(local_anchorPos, local_orientation)
|
||||||
if not vector.equals(local_p1, minetest.string_to_pos(meta:get_string("p1"))) then
|
local p1_at_playerPos = minetest.string_to_pos(meta:get_string("p1"))
|
||||||
|
if p1_at_playerPos == nil or not vector.equals(local_p1, p1_at_playerPos) then
|
||||||
if DEBUG then minetest.chat_send_all("the player already teleported from " .. minetest.pos_to_string(local_anchorPos) .. ", and is now standing in a different portal - " .. meta:get_string("p1")) end
|
if DEBUG then minetest.chat_send_all("the player already teleported from " .. minetest.pos_to_string(local_anchorPos) .. ", and is now standing in a different portal - " .. meta:get_string("p1")) end
|
||||||
return -- the player already teleported, and is now standing in a different portal
|
return -- the player already teleported, and is now standing in a different portal
|
||||||
end
|
end
|
||||||
@ -991,7 +1008,7 @@ local function create_book(item_name, inventory_description, inventory_image, ti
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Updates nether.book_of_portals
|
-- Updates nether:book_of_portals
|
||||||
-- A book the player can read to lean how to build the different portals
|
-- A book the player can read to lean how to build the different portals
|
||||||
local function create_book_of_portals()
|
local function create_book_of_portals()
|
||||||
|
|
||||||
@ -1045,6 +1062,46 @@ local function create_book_of_portals()
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- This is hack to work around how place_schematic() never invalidates its cache.
|
||||||
|
-- A unique schematic filename is generated for each unique set of node replacements
|
||||||
|
function get_malleated_schematic_filename(portal_definition)
|
||||||
|
|
||||||
|
local result
|
||||||
|
|
||||||
|
if portal_definition.shape ~= nil and portal_definition.shape.schematic_filename ~= nil then
|
||||||
|
|
||||||
|
local schematicFileName = portal_definition.shape.schematic_filename
|
||||||
|
local uniqueId = portal_definition.frame_node_name .. " " .. portal_definition.wormhole_node_name
|
||||||
|
|
||||||
|
if malleated_filenames[schematicFileName] == nil then malleated_filenames[schematicFileName] = {} end
|
||||||
|
local filenamesForSchematic = malleated_filenames[schematicFileName]
|
||||||
|
|
||||||
|
-- Split the schematic's filename into the path and filename
|
||||||
|
local lastSlashPos, _ = schematicFileName:find("/[^/]+$") -- find the rightmost slash
|
||||||
|
local lastBackslashPos, _ = schematicFileName:find("\\[^\\]+$") -- find the rightmost backslash
|
||||||
|
if lastSlashPos == nil then lastSlashPos = -1 end
|
||||||
|
if lastBackslashPos ~= nil then lastSlashPos = math.max(lastSlashPos, lastBackslashPos) end
|
||||||
|
local part_path = schematicFileName:sub(0, math.max(0, lastSlashPos - 1))
|
||||||
|
local part_filename = schematicFileName:sub(lastSlashPos + 1)
|
||||||
|
|
||||||
|
if filenamesForSchematic[uniqueId] == nil then
|
||||||
|
|
||||||
|
local malleationCount = 0
|
||||||
|
for _ in pairs(filenamesForSchematic) do malleationCount = malleationCount + 1 end
|
||||||
|
|
||||||
|
local malleatedFilename = part_path .. DIR_DELIM
|
||||||
|
for i = 1, malleationCount do
|
||||||
|
malleatedFilename = malleatedFilename .. '.' .. DIR_DELIM -- should work on both Linux and Windows
|
||||||
|
end
|
||||||
|
malleatedFilename = malleatedFilename .. part_filename
|
||||||
|
filenamesForSchematic[uniqueId] = malleatedFilename
|
||||||
|
end
|
||||||
|
result = filenamesForSchematic[uniqueId]
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function register_frame_node(frame_node_name)
|
function register_frame_node(frame_node_name)
|
||||||
|
|
||||||
@ -1053,7 +1110,7 @@ function register_frame_node(frame_node_name)
|
|||||||
local extended_node_def = {}
|
local extended_node_def = {}
|
||||||
for key, value in pairs(node) do extended_node_def[key] = value end
|
for key, value in pairs(node) do extended_node_def[key] = value end
|
||||||
|
|
||||||
extended_node_def.replaced_by_portalapi = {}
|
extended_node_def.replaced_by_portalapi = {} -- allows chaining or restoration of original functions, if necessary
|
||||||
|
|
||||||
-- add portal portal functionality
|
-- add portal portal functionality
|
||||||
extended_node_def.replaced_by_portalapi.mesecons = extended_node_def.mesecons
|
extended_node_def.replaced_by_portalapi.mesecons = extended_node_def.mesecons
|
||||||
@ -1200,7 +1257,7 @@ local portaldef_default = {
|
|||||||
particle_texture = "nether_particle.png",
|
particle_texture = "nether_particle.png",
|
||||||
sounds = {
|
sounds = {
|
||||||
ambient = {name = "nether_portal_ambient", gain = 0.6, length = 3},
|
ambient = {name = "nether_portal_ambient", gain = 0.6, length = 3},
|
||||||
ignite = {name = "nether_portal_ignite", gain = 0.3},
|
ignite = {name = "nether_portal_ignite", gain = 0.5},
|
||||||
extinguish = {name = "nether_portal_extinguish", gain = 0.3},
|
extinguish = {name = "nether_portal_extinguish", gain = 0.3},
|
||||||
teleport = {name = "nether_portal_teleport", gain = 0.3}
|
teleport = {name = "nether_portal_teleport", gain = 0.3}
|
||||||
}
|
}
|
||||||
@ -1222,6 +1279,8 @@ function nether.register_portal(name, portaldef)
|
|||||||
if portaldef.sounds ~= nil then setmetatable(portaldef.sounds, {__index = portaldef_default.sounds}) end
|
if portaldef.sounds ~= nil then setmetatable(portaldef.sounds, {__index = portaldef_default.sounds}) end
|
||||||
setmetatable(portaldef, {__index = portaldef_default})
|
setmetatable(portaldef, {__index = portaldef_default})
|
||||||
|
|
||||||
|
portaldef.schematic_filename = get_malleated_schematic_filename(portaldef)
|
||||||
|
|
||||||
if portaldef.particle_color == nil then
|
if portaldef.particle_color == nil then
|
||||||
-- default the particle colours to be the same as the wormhole colour
|
-- default the particle colours to be the same as the wormhole colour
|
||||||
assert(portaldef.wormhole_node_color >= 0 and portaldef.wormhole_node_color < 8, "portaldef.wormhole_node_color must be between 0 and 7 (inclusive)")
|
assert(portaldef.wormhole_node_color >= 0 and portaldef.wormhole_node_color < 8, "portaldef.wormhole_node_color must be between 0 and 7 (inclusive)")
|
||||||
|
Loading…
Reference in New Issue
Block a user