Skip to content

Commit 2a7d01b

Browse files
committedSep 29, 2015
Some map border related fixes
1. Check for entity addition success in spawn_item implementation 2. Check for success in item_drop callback, so that the player doesn't lose the item if they are outside bounds and try to drop it. 3. When existing player joins game, check that their position is inside map bounds. If not, set their position to the return value of findSpawnPos(). 4. Make findSpawnPos() respect the border 2 fixes a lua crash if a player drops an item outside map bounds. 3 fixes an assertion crash if a player leaves when being outside map bounds, and then rejoins.
1 parent 0cde032 commit 2a7d01b

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed
 

Diff for: ‎builtin/game/item.lua

+6-2
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,16 @@ function core.item_drop(itemstack, dropper, pos)
349349
v.y = v.y*2 + 2
350350
v.z = v.z*2
351351
obj:setvelocity(v)
352+
return itemstack
352353
end
353354

354355
else
355-
core.add_item(pos, itemstack)
356+
if core.add_item(pos, itemstack) then
357+
return itemstack
358+
end
356359
end
357-
return itemstack
360+
-- If we reach this, adding the object to the
361+
-- environment failed
358362
end
359363

360364
function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)

Diff for: ‎builtin/game/item_entity.lua

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ function core.spawn_item(pos, item)
44
-- Take item in any format
55
local stack = ItemStack(item)
66
local obj = core.add_entity(pos, "__builtin:item")
7-
obj:get_luaentity():set_item(stack:to_string())
7+
-- Don't use obj if it couldn't be added to the map.
8+
if obj then
9+
obj:get_luaentity():set_item(stack:to_string())
10+
end
811
return obj
912
end
1013

11-
-- If item_entity_ttl is not set, enity will have default life time
14+
-- If item_entity_ttl is not set, enity will have default life time
1215
-- Setting it to -1 disables the feature
1316

1417
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
@@ -81,7 +84,7 @@ core.register_entity(":__builtin:item", {
8184
if data and type(data) == "table" then
8285
self.itemstring = data.itemstring
8386
self.always_collect = data.always_collect
84-
if data.age then
87+
if data.age then
8588
self.age = data.age + dtime_s
8689
else
8790
self.age = dtime_s

Diff for: ‎src/server.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -3263,10 +3263,6 @@ v3f Server::findSpawnPos()
32633263
return nodeposf * BS;
32643264
}
32653265

3266-
// Default position is static_spawnpoint
3267-
// We will return it if we don't found a good place
3268-
v3s16 nodepos(nodeposf.X, nodeposf.Y, nodeposf.Z);
3269-
32703266
s16 water_level = map.getWaterLevel();
32713267

32723268
bool is_good = false;
@@ -3286,7 +3282,7 @@ v3f Server::findSpawnPos()
32863282
if (groundheight > water_level + 6) // Don't go to high places
32873283
continue;
32883284

3289-
nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y);
3285+
v3s16 nodepos(nodepos2d.X, groundheight, nodepos2d.Y);
32903286

32913287
s32 air_count = 0;
32923288
for (s32 i = 0; i < 10; i++) {
@@ -3295,7 +3291,11 @@ v3f Server::findSpawnPos()
32953291
content_t c = map.getNodeNoEx(nodepos).getContent();
32963292
if (c == CONTENT_AIR || c == CONTENT_IGNORE) {
32973293
air_count++;
3298-
if (air_count >= 2){
3294+
if (air_count >= 2) {
3295+
nodeposf = intToFloat(nodepos, BS);
3296+
// Don't spawn the player outside map boundaries
3297+
if (objectpos_over_limit(nodeposf))
3298+
continue;
32993299
is_good = true;
33003300
break;
33013301
}
@@ -3304,7 +3304,7 @@ v3f Server::findSpawnPos()
33043304
}
33053305
}
33063306

3307-
return intToFloat(nodepos, BS);
3307+
return nodeposf;
33083308
}
33093309

33103310
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
33533353

33543354
// Add player to environment
33553355
m_env->addPlayer(player);
3356+
} else {
3357+
// If the player exists, ensure that they respawn inside legal bounds
3358+
// This fixes an assert crash when the player can't be added
3359+
// to the environment
3360+
if (objectpos_over_limit(player->getPosition())) {
3361+
actionstream << "Respawn position for player \""
3362+
<< name << "\" outside limits, resetting" << std::endl;
3363+
v3f pos = findSpawnPos();
3364+
player->setPosition(pos);
3365+
}
33563366
}
33573367

33583368
// Create a new player active object

0 commit comments

Comments
 (0)
Please sign in to comment.