Skip to content

Commit 460b375

Browse files
numberZeronerzhul
authored andcommittedApr 6, 2018
Fix SAOM (#7200)
* Bugfix
1 parent 91615f9 commit 460b375

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed
 

Diff for: ‎src/content_sao.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
272272
// Get properties
273273
m_env->getScriptIface()->
274274
luaentity_GetProperties(m_id, &m_prop);
275+
// Notify the environment of the new properties
276+
m_env->updateActiveObject(this);
275277
// Initialize HP from properties
276278
m_hp = m_prop.hp_max;
277279
// Activate entity, supplying serialized state

Diff for: ‎src/server/serveractiveobjectmap.cpp

+35-17
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525

2626
static constexpr float granularity = 16.0 * BS;
2727

28+
static v3s16 getChunkPos(const v3f &pos)
Has conversations. Original line has conversations.
29+
{
30+
return v3s16(
31+
std::floor(pos.X / granularity),
32+
std::floor(pos.Y / granularity),
33+
std::floor(pos.Z / granularity));
34+
}
35+
2836
static aabb3s16 calcBox(const aabb3f &cb)
2937
{
30-
return aabb3s16(
31-
std::floor(cb.MinEdge.X / granularity),
32-
std::floor(cb.MinEdge.Y / granularity),
33-
std::floor(cb.MinEdge.Z / granularity),
34-
std::ceil(cb.MaxEdge.X / granularity),
35-
std::ceil(cb.MaxEdge.Y / granularity),
36-
std::ceil(cb.MaxEdge.Z / granularity));
38+
return { getChunkPos(cb.MinEdge), getChunkPos(cb.MaxEdge) };
3739
}
3840

3941
void ServerActiveObjectMap::addObject(ServerActiveObject *object)
@@ -46,10 +48,12 @@ void ServerActiveObjectMap::addObject(ServerActiveObject *object)
4648
"object ID in use: " + std::to_string(id));
4749
w.object = object;
4850
w.has_box = w.object->getCollisionBox(&cb);
51+
w.pos = getChunkPos(w.object->getBasePosition());
4952
if (w.has_box) {
5053
w.box = calcBox(cb);
5154
addObjectRefs(id, w.box);
5255
}
56+
addObjectRef(id, w.pos);
5357
objects.emplace(id, w);
5458
}
5559

@@ -61,6 +65,7 @@ ServerActiveObject *ServerActiveObjectMap::removeObject(u16 id)
6165
Wrapper w = pw->second;
6266
if (w.has_box)
6367
removeObjectRefs(id, w.box);
68+
removeObjectRef(id, w.pos);
6469
objects.erase(pw);
6570
return w.object;
6671
}
@@ -79,19 +84,22 @@ void ServerActiveObjectMap::updateObject(u16 id)
7984
return;
8085
}
8186
Wrapper &w = pw->second;
87+
v3s16 pos = getChunkPos(w.object->getBasePosition());
8288
aabb3f cb;
8389
aabb3s16 box;
8490
bool has_box = w.object->getCollisionBox(&cb);
8591
if (has_box)
8692
box = calcBox(cb);
87-
if (w.has_box && has_box && w.box == box)
93+
if (w.has_box && has_box && w.box == box && pos == w.pos)
8894
return;
8995
if (w.has_box)
9096
removeObjectRefs(id, w.box);
97+
removeObjectRef(id, w.pos);
9198
w.box = box;
9299
w.has_box = has_box;
93100
if (w.has_box)
94101
addObjectRefs(id, w.box);
102+
addObjectRef(id, w.pos);
95103
}
96104

97105
void ServerActiveObjectMap::updateObject(ServerActiveObject *object)
@@ -151,28 +159,38 @@ std::unordered_set<u16> ServerActiveObjectMap::getObjectsNearBox(const aabb3s16
151159
return result;
152160
}
153161

162+
void ServerActiveObjectMap::addObjectRef(u16 id, v3s16 pos)
163+
{
164+
refmap.emplace(pos, id);
165+
}
166+
167+
void ServerActiveObjectMap::removeObjectRef(u16 id, v3s16 pos)
168+
{
169+
auto bounds = refmap.equal_range(pos);
170+
for (auto iter = bounds.first; iter != bounds.second;) {
171+
if (iter->second == id)
172+
iter = refmap.erase(iter);
173+
else
174+
++iter;
175+
}
176+
}
177+
154178
void ServerActiveObjectMap::addObjectRefs(u16 id, const aabb3s16 &box)
155179
{
156180
v3s16 p;
157181
for (p.Z = box.MinEdge.Z; p.Z <= box.MaxEdge.Z; p.Z++)
158182
for (p.Y = box.MinEdge.Y; p.Y <= box.MaxEdge.Y; p.Y++)
159183
for (p.X = box.MinEdge.X; p.X <= box.MaxEdge.X; p.X++)
160-
refmap.emplace(p, id);
184+
addObjectRef(id, p);
161185
}
162186

163187
void ServerActiveObjectMap::removeObjectRefs(u16 id, const aabb3s16 &box)
164188
{
165189
v3s16 p;
166190
for (p.Z = box.MinEdge.Z; p.Z <= box.MaxEdge.Z; p.Z++)
167191
for (p.Y = box.MinEdge.Y; p.Y <= box.MaxEdge.Y; p.Y++)
168-
for (p.X = box.MinEdge.X; p.X <= box.MaxEdge.X; p.X++) {
169-
auto bounds = refmap.equal_range(p);
170-
for (auto iter = bounds.first; iter != bounds.second;)
171-
if (iter->second == id)
172-
refmap.erase(iter++);
173-
else
174-
++iter;
175-
}
192+
for (p.X = box.MinEdge.X; p.X <= box.MaxEdge.X; p.X++)
193+
removeObjectRef(id, p);
176194
}
177195

178196
bool ServerActiveObjectMap::isFreeId(u16 id)

Diff for: ‎src/server/serveractiveobjectmap.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct ServerActiveObjectMap
3939
{
4040
ServerActiveObject *object;
4141
aabb3s16 box;
42+
v3s16 pos;
4243
bool has_box;
4344
};
4445

@@ -108,9 +109,6 @@ struct ServerActiveObjectMap
108109
* @note Due to inexact nature of floating-point computations, it is
109110
* undefined whether an object lying exactly at the boundary is included
110111
* in the list or not.
111-
* @note Objects with base position outside of the collision box may not
112-
* be returned.
113-
* @note Objects without valid collision box are not returned.
114112
*/
115113
std::vector<u16> getObjectsInsideRadius(v3f pos, float radius);
116114

@@ -134,6 +132,8 @@ struct ServerActiveObjectMap
134132
const std::unordered_map<u16, Wrapper> &getObjects() const { return objects; }
135133

136134
private:
135+
void addObjectRef(u16 id, v3s16 pos);
136+
void removeObjectRef(u16 id, v3s16 pos);
137137
void addObjectRefs(u16 id, const aabb3s16 &box);
138138
void removeObjectRefs(u16 id, const aabb3s16 &box);
139139
std::unordered_set<u16> getObjectsNearBox(const aabb3s16 &box);

0 commit comments

Comments
 (0)
Please sign in to comment.