Improve safe spawning

This commit is contained in:
Wuzzy 2022-06-06 22:39:54 +02:00
parent 766f4cd2c9
commit 29d8fa97a0
3 changed files with 38 additions and 6 deletions

View File

@ -80,6 +80,7 @@ This is the list of all groups used for nodes. Note: If no number/rating is spec
* `container`: Node has an inventory to store item(s)
* `interactive_node`: Node can be interacted with (excluding pure container nodes)
* `no_spawn_allowed_on`: If set, players can not (initially) spawn on this block
* `spawn_allowed_in`: If set, players can spawn into this block (note: this group is ignored for the 'air' and 'ignore' nodes)
### Node categorization

View File

@ -0,0 +1,18 @@
= Safe Spawning Mod for Repixture =
This mod checks the position of the player after the initial spawn (not respawn).
If the position is unsafe, the mod tries to relocate the player to a safer position.
This mod is a workaround for Minetest sometimes picking a bad spawn position
because Minetests spawn algorithm sucks (as of Minetest version 5.5.1).
This mod fixes that. For Repixture, this mod was created due
to a low chance of the player spawning in a thistle.
## Limitations
This mod is only for the first spawn, not respawning. So Minetest still might
put the player at an unlucky position on a respawn.
## Credits
Author: Wuzzy
License: MIT License

View File

@ -2,13 +2,26 @@ local SPAWNRADIUS = 21
local MAX_SPAWN_HEIGHT = 2
-- Cache spawnable blocks
local spawnable_blocks = {}
local spawnable_blocks = { ignore = false }
local spawnable_blocks_in = { air = true, ignore = false }
-- Returns true if the node can be spawned into
local can_spawn_in = function(nodename)
-- Check cache
if spawnable_blocks_in[nodename] ~= nil then
return spawnable_blocks_in[nodename]
end
spawnable_blocks_in[nodename] = false
if minetest.get_item_group(nodename, "spawn_allowed_in") > 0 then
spawnable_blocks_in[nodename] = true
return true
end
return false
end
-- Returns true if the node with the given nodename can be spawned on
local can_spawn_on = function(nodename)
if nodename == "ignore" then
return false
end
-- Check cache
if spawnable_blocks[nodename] ~= nil then
return spawnable_blocks[nodename]
@ -59,7 +72,7 @@ local is_valid_spawn_pos = function(pos1)
if node0.name == "ignore" then
return false
end
if node1.name == "air" and node2.name == "air" and can_spawn_on(node0.name) then
if can_spawn_in(node1.name) and can_spawn_in(node2.name) and can_spawn_on(node0.name) then
return true
end
return false
@ -151,7 +164,7 @@ local function emerge_callback(blockpos, action, calls_remaining, param)
minetest.log("action", "[rp_safespawn] Failed to find new spawn position for "..param.player:get_player_name()..". Not moving player.")
end
else
minetest.log("info", "[rp_safespawn] Player spawn for "..param.player:get_player_name().." was OK. Not moving player.")
minetest.log("action", "[rp_safespawn] Player spawn for "..param.player:get_player_name().." was OK. Not moving player.")
end
end
end