aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/game/item.lua8
-rw-r--r--builtin/game/item_entity.lua9
-rw-r--r--src/server.cpp24
3 files changed, 29 insertions, 12 deletions
diff --git a/builtin/game/item.lua b/builtin/game/item.lua
index 6628a4081..0f10af8ee 100644
--- a/builtin/game/item.lua
+++ b/builtin/game/item.lua
@@ -349,12 +349,16 @@ function core.item_drop(itemstack, dropper, pos)
v.y = v.y*2 + 2
v.z = v.z*2
obj:setvelocity(v)
+ return itemstack
end
else
- core.add_item(pos, itemstack)
+ if core.add_item(pos, itemstack) then
+ return itemstack
+ end
end
- return itemstack
+ -- If we reach this, adding the object to the
+ -- environment failed
end
function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua
index 6425a10aa..190473ceb 100644
--- a/builtin/game/item_entity.lua
+++ b/builtin/game/item_entity.lua
@@ -4,11 +4,14 @@ function core.spawn_item(pos, item)
-- Take item in any format
local stack = ItemStack(item)
local obj = core.add_entity(pos, "__builtin:item")
- obj:get_luaentity():set_item(stack:to_string())
+ -- Don't use obj if it couldn't be added to the map.
+ if obj then
+ obj:get_luaentity():set_item(stack:to_string())
+ end
return obj
end
--- If item_entity_ttl is not set, enity will have default life time
+-- If item_entity_ttl is not set, enity will have default life time
-- Setting it to -1 disables the feature
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
@@ -81,7 +84,7 @@ core.register_entity(":__builtin:item", {
if data and type(data) == "table" then
self.itemstring = data.itemstring
self.always_collect = data.always_collect
- if data.age then
+ if data.age then
self.age = data.age + dtime_s
else
self.age = dtime_s
diff --git a/src/server.cpp b/src/server.cpp
index 9b1b142eb..fbdaa5918 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3263,10 +3263,6 @@ v3f Server::findSpawnPos()
return nodeposf * BS;
}
- // Default position is static_spawnpoint
- // We will return it if we don't found a good place
- v3s16 nodepos(nodeposf.X, nodeposf.Y, nodeposf.Z);
-
s16 water_level = map.getWaterLevel();
bool is_good = false;
@@ -3286,7 +3282,7 @@ v3f Server::findSpawnPos()
if (groundheight > water_level + 6) // Don't go to high places
continue;
- nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y);
+ v3s16 nodepos(nodepos2d.X, groundheight, nodepos2d.Y);
s32 air_count = 0;
for (s32 i = 0; i < 10; i++) {
@@ -3295,7 +3291,11 @@ v3f Server::findSpawnPos()
content_t c = map.getNodeNoEx(nodepos).getContent();
if (c == CONTENT_AIR || c == CONTENT_IGNORE) {
air_count++;
- if (air_count >= 2){
+ if (air_count >= 2) {
+ nodeposf = intToFloat(nodepos, BS);
+ // Don't spawn the player outside map boundaries
+ if (objectpos_over_limit(nodeposf))
+ continue;
is_good = true;
break;
}
@@ -3304,7 +3304,7 @@ v3f Server::findSpawnPos()
}
}
- return intToFloat(nodepos, BS);
+ return nodeposf;
}
PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version)
@@ -3353,6 +3353,16 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version
// Add player to environment
m_env->addPlayer(player);
+ } else {
+ // If the player exists, ensure that they respawn inside legal bounds
+ // This fixes an assert crash when the player can't be added
+ // to the environment
+ if (objectpos_over_limit(player->getPosition())) {
+ actionstream << "Respawn position for player \""
+ << name << "\" outside limits, resetting" << std::endl;
+ v3f pos = findSpawnPos();
+ player->setPosition(pos);
+ }
}
// Create a new player active object