aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorhecks <42101236+hecktest@users.noreply.github.com>2021-01-02 15:14:29 +0100
committerGitHub <noreply@github.com>2021-01-02 15:14:29 +0100
commitdd5a732fa90550066bb96305b64b6648903cc822 (patch)
tree1d39d1362e7619ff459eb6da5f1c9aab7629d1b6 /src/server
parentad58fb22064c7db223cb825596c12f93f2a75a26 (diff)
downloadminetest-dd5a732fa90550066bb96305b64b6648903cc822.tar.gz
minetest-dd5a732fa90550066bb96305b64b6648903cc822.tar.bz2
minetest-dd5a732fa90550066bb96305b64b6648903cc822.zip
Add on_deactivate callback for luaentities (#10723)
Diffstat (limited to 'src/server')
-rw-r--r--src/server/luaentity_sao.cpp13
-rw-r--r--src/server/luaentity_sao.h5
-rw-r--r--src/server/player_sao.cpp2
-rw-r--r--src/server/serveractiveobject.cpp16
-rw-r--r--src/server/serveractiveobject.h50
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;