From b31df12e959e97f9f01a3f27fc0c47b7c2c86e9e Mon Sep 17 00:00:00 2001 From: Treer Date: Sat, 8 Feb 2020 18:00:01 +1100 Subject: [PATCH] API improvements Improvements found while using the portals API in another mod (cloudlands): * remote_portal_checkup() will check the whole portal and frame for mapgen overwrites. * Allow find_realm_anchorPos() to return nil if no realm location could be found (portal will fail to ignite). * Allow create_book_of_portals() to be invoked [indirectly] by other mods. Also lowers nether_book_close.png to be 4bpp --- README.md | 7 +++--- nodes.lua | 4 ++-- portal_api.lua | 42 ++++++++++++++++++++++----------- portal_api.txt | 9 +++---- settingtypes.txt | 4 ++-- textures/nether_book_close.png | Bin 1750 -> 961 bytes 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 46d7b5d..7404d14 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -Nether Mod for Minetest, with Portal API. +Nether Mod for Minetest, with Portals API. See portal_api.txt for how to create custom portals to your own realms. -A Book of Portals item (nether:book_of_portals) is created which -provides players with portal recipes, by default it can be found in -dungeon chests. +See settingtypes.txt or go to "Settings"->"All Settings"->"Mods"->"nether" +in the game to view the options provided by this mod. ## License of source code: diff --git a/nodes.lua b/nodes.lua index 3eaf1cd..14e3bd2 100644 --- a/nodes.lua +++ b/nodes.lua @@ -104,8 +104,8 @@ stairs.register_stair_and_slab( "nether:brick", {cracky = 2, level = 2}, {"nether_brick.png"}, - S("Nether stair"), - S("Nether slab"), + S("Nether Stair"), + S("Nether Slab"), default.node_sound_stone_defaults() ) diff --git a/portal_api.lua b/portal_api.lua index 6671ba1..13ab3ca 100644 --- a/portal_api.lua +++ b/portal_api.lua @@ -1178,7 +1178,13 @@ local function remote_portal_checkup(elapsed, portal_definition, anchorPos, orie local wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(anchorPos, orientation) local wormhole_node = minetest.get_node_or_nil(wormholePos) - if wormhole_node == nil or wormhole_node.name ~= portal_definition.wormhole_node_name then + local portalFound, portalLit = false, false + if wormhole_node ~= nil and wormhole_node.name == portal_definition.wormhole_node_name then + -- a wormhole node was there, but check the whole frame is intact + portalFound, portalLit = is_portal_at_anchorPos(portal_definition, anchorPos, orientation, false) + end + + if not portalFound or not portalLit then -- ruh roh local message = "Newly created portal at " .. minetest.pos_to_string(anchorPos) .. " was overwritten. Attempting to recreate. Issue spotted after " .. elapsed .. " seconds" minetest.log("warning", message) @@ -1312,22 +1318,27 @@ local function ignite_portal(ignition_pos, ignition_node_name) if DEBUG and destination_orientation == nil then minetest.chat_send_all("No destination_orientation given") end if destination_orientation == nil then destination_orientation = orientation end - local destination_wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(destination_anchorPos, destination_orientation) - if DEBUG then minetest.chat_send_all("Destination set to " .. minetest.pos_to_string(destination_anchorPos)) end + if destination_anchorPos == nil then + if DEBUG then minetest.chat_send_all("No portal destination available here!") end + return false + else + local destination_wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(destination_anchorPos, destination_orientation) + if DEBUG then minetest.chat_send_all("Destination set to " .. minetest.pos_to_string(destination_anchorPos)) end - -- ignition/BURN_BABY_BURN - set_portal_metadata_and_ignite(portal_definition, anchorPos, orientation, destination_wormholePos) + -- ignition/BURN_BABY_BURN + set_portal_metadata_and_ignite(portal_definition, anchorPos, orientation, destination_wormholePos) - if portal_definition.sounds.ignite ~= nil then - local local_wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(anchorPos, orientation) - minetest.sound_play(portal_definition.sounds.ignite, {pos = local_wormholePos, max_hear_distance = 20}) - end + if portal_definition.sounds.ignite ~= nil then + local local_wormholePos = portal_definition.shape.get_wormholePos_from_anchorPos(anchorPos, orientation) + minetest.sound_play(portal_definition.sounds.ignite, {pos = local_wormholePos, max_hear_distance = 20}) + end - if portal_definition.on_ignite ~= nil then - portal_definition.on_ignite(portal_definition, anchorPos, orientation) - end + if portal_definition.on_ignite ~= nil then + portal_definition.on_ignite(portal_definition, anchorPos, orientation) + end - return true + return true + end end end end @@ -1737,7 +1748,7 @@ local function create_book_of_portals() create_book( - "nether:book_of_portals", + ":nether:book_of_portals", S("Book of Portals"), "nether_book_of_portals.png", S("A definitive guide to Rifts and Portals"), @@ -2160,6 +2171,8 @@ end -- portal_name is optional, providing it allows existing portals on the surface to be reused. function nether.find_surface_target_y(target_x, target_z, portal_name) + assert(target_x ~= nil and target_z ~= nil, "Arguments `target_x` and `target_z` cannot be nil when calling find_surface_target_y()") + -- default to starting the search at -16 (probably underground) if we don't know the -- surface, like paramat's original code from before get_spawn_level() was available: -- https://github.com/minetest-mods/nether/issues/5#issuecomment-506983676 @@ -2215,6 +2228,7 @@ function nether.find_nearest_working_portal(portal_name, anchorPos, distance_lim local portal_definition = nether.registered_portals[portal_name] assert(portal_definition ~= nil, "find_nearest_working_portal() called with portal_name '" .. portal_name .. "', but no portal is registered with that name.") + assert(anchorPos ~= nil, "Argument `anchorPos` cannot be nil when calling find_nearest_working_portal()") local contenders = list_closest_portals(portal_definition, anchorPos, distance_limit, y_factor) diff --git a/portal_api.txt b/portal_api.txt index e60ba43..e6cf533 100644 --- a/portal_api.txt +++ b/portal_api.txt @@ -22,11 +22,6 @@ one kind of portal with the same frame material — such as obsidian — provide the size of the PortalShape is distinct from any other type of portal that is using the same node for its frame, and portal sizes remain small. -Stone is not a good choice for portal frame nodes as the Minetest engine may -convert it into terrain nodes if the biome-pass occurs after the portal is -created. Similarly, avoid using nodes which may be replaced by ABMs or -docoration functions without triggering the node's `on_destruct` handler. - Realms ------ @@ -200,7 +195,9 @@ Used by `nether.register_portal`. within_realm = function(pos), -- Required. Return true if a portal at pos is in the realm, rather - than the surface world. + -- than the surface world. + -- Ideally implementations are fast, as this function can be used to + -- sift through a list of portals. find_realm_anchorPos = function(surface_anchorPos), -- Required. Return a position in the realm that a portal created at diff --git a/settingtypes.txt b/settingtypes.txt index a7e35f3..dbea779 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -15,5 +15,5 @@ nether_realm_enabled (Enable Nether realm & portal) bool true # Enables the Floatlands portal api code example nether_enable_portal_example_floatlands (Enable example portal: Floatlands) bool false -# Enables the Surface travel portal api code example -nether_enable_portal_example_surfacetravel (Enable example portal: Surface travel) bool false \ No newline at end of file +# Enables the Surface-travel portal api code example +nether_enable_portal_example_surfacetravel (Enable example portal: Surface-travel) bool false \ No newline at end of file diff --git a/textures/nether_book_close.png b/textures/nether_book_close.png index d3ebeb3a3418da48cc35e9c46bf5e01fa8d9da85..7455e68fe910e09913efec996af7e21f7ce00c37 100644 GIT binary patch delta 886 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 D)As9X