diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/luaentity_sao.cpp | 13 | ||||
-rw-r--r-- | src/server/luaentity_sao.h | 5 | ||||
-rw-r--r-- | src/server/player_sao.cpp | 2 | ||||
-rw-r--r-- | src/server/serveractiveobject.cpp | 16 | ||||
-rw-r--r-- | src/server/serveractiveobject.h | 50 |
5 files changed, 64 insertions, 22 deletions
diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index b39797531..c7277491a 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -112,6 +112,15 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) } } +void LuaEntitySAO::dispatchScriptDeactivate() +{ + // Ensure that this is in fact a registered entity, + // and that it isn't already gone. + // The latter also prevents this from ever being called twice. + if (m_registered && !isGone()) + m_env->getScriptIface()->luaentity_Deactivate(m_id); +} + void LuaEntitySAO::step(float dtime, bool send_recommended) { if(!m_properties_sent) @@ -302,7 +311,7 @@ u16 LuaEntitySAO::punch(v3f dir, { if (!m_registered) { // Delete unknown LuaEntities when punched - m_pending_removal = true; + markForRemoval(); return 0; } @@ -335,7 +344,7 @@ u16 LuaEntitySAO::punch(v3f dir, clearParentAttachment(); clearChildAttachments(); m_env->getScriptIface()->luaentity_on_death(m_id, puncher); - m_pending_removal = true; + markForRemoval(); } actionstream << puncher->getDescription() << " (id=" << puncher->getId() << diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index e060aa06d..6883ae1b9 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -71,6 +71,11 @@ public: bool getSelectionBox(aabb3f *toset) const; bool collideWithObjects() const; +protected: + void dispatchScriptDeactivate(); + virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(); } + virtual void onMarkedForRemoval() { dispatchScriptDeactivate(); } + private: std::string getPropertyPacket(); void sendPosition(bool do_interpolate, bool is_movement_end); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 62515d1c9..232c6a01d 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -531,7 +531,7 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item) void PlayerSAO::disconnected() { m_peer_id = PEER_ID_INEXISTENT; - m_pending_removal = true; + markForRemoval(); } void PlayerSAO::unlinkPlayerSessionAndSave() diff --git a/src/server/serveractiveobject.cpp b/src/server/serveractiveobject.cpp index 8cb59b2d6..96b433d1d 100644 --- a/src/server/serveractiveobject.cpp +++ b/src/server/serveractiveobject.cpp @@ -73,3 +73,19 @@ void ServerActiveObject::dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> & m_messages_out.pop(); } } + +void ServerActiveObject::markForRemoval() +{ + if (!m_pending_removal) { + onMarkedForRemoval(); + m_pending_removal = true; + } +} + +void ServerActiveObject::markForDeactivation() +{ + if (!m_pending_deactivation) { + onMarkedForDeactivation(); + m_pending_deactivation = true; + } +} diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 2764d159e..25653a1ad 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -70,6 +70,10 @@ public: virtual bool environmentDeletes() const { return true; } + // Safely mark the object for removal or deactivation + void markForRemoval(); + void markForDeactivation(); + // Create a certain type of ServerActiveObject static ServerActiveObject* create(ActiveObjectType type, ServerEnvironment *env, u16 id, v3f pos, @@ -214,31 +218,15 @@ public: u16 m_known_by_count = 0; /* - - Whether this object is to be removed when nobody knows about - it anymore. - - Removal is delayed to preserve the id for the time during which - it could be confused to some other object by some client. - - This is usually set to true by the step() method when the object wants - to be deleted but can be set by anything else too. - */ - bool m_pending_removal = false; - - /* - Same purpose as m_pending_removal but for deactivation. - deactvation = save static data in block, remove active object - - If this is set alongside with m_pending_removal, removal takes - priority. - */ - bool m_pending_deactivation = false; - - /* A getter that unifies the above to answer the question: "Can the environment still interact with this object?" */ inline bool isGone() const { return m_pending_removal || m_pending_deactivation; } + inline bool isPendingRemoval() const + { return m_pending_removal; } + /* Whether the object's static data has been stored to a block */ @@ -250,6 +238,9 @@ public: v3s16 m_static_block = v3s16(1337,1337,1337); protected: + virtual void onMarkedForDeactivation() {} + virtual void onMarkedForRemoval() {} + virtual void onAttach(int parent_id) {} virtual void onDetach(int parent_id) {} @@ -258,6 +249,27 @@ protected: std::unordered_set<u32> m_attached_particle_spawners; /* + Same purpose as m_pending_removal but for deactivation. + deactvation = save static data in block, remove active object + + If this is set alongside with m_pending_removal, removal takes + priority. + Note: Do not assign this directly, use markForDeactivation() instead. + */ + bool m_pending_deactivation = false; + + /* + - Whether this object is to be removed when nobody knows about + it anymore. + - Removal is delayed to preserve the id for the time during which + it could be confused to some other object by some client. + - This is usually set to true by the step() method when the object wants + to be deleted but can be set by anything else too. + Note: Do not assign this directly, use markForRemoval() instead. + */ + bool m_pending_removal = false; + + /* Queue of messages to be sent to the client */ std::queue<ActiveObjectMessage> m_messages_out; |