From 45ff12256c9c1ad461cb9c7f70be3f58574ce38b Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 19 Mar 2023 18:17:05 +0100 Subject: [PATCH] Implement a qc version of copyentity that clears intrusive list data from the copied entity --- qcsrc/lib/intrusivelist.qh | 9 +++++++++ qcsrc/lib/oo.qh | 11 +++++++++-- qcsrc/lib/spawnfunc.qh | 2 +- qcsrc/server/weapons/spawning.qc | 2 -- qcsrc/server/weapons/weaponsystem.qc | 2 +- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/qcsrc/lib/intrusivelist.qh b/qcsrc/lib/intrusivelist.qh index 938a7f963..3dee9ca38 100644 --- a/qcsrc/lib/intrusivelist.qh +++ b/qcsrc/lib/intrusivelist.qh @@ -268,6 +268,15 @@ void IL_ENDFRAME() #endif } +// clears any IL data from an entity (not an intrusive list) +// it should be used only in very particular cases such as after a copyentity call +void IL_REMOVE_RAW(entity it) +{ + it.il_lists = '0 0 0'; + for (int i = 0; i < IL_MAX * 2; ++i) + it.il_links_flds[i] = nil; +} + // called when an entity is deleted with delete() / remove() // or when a player disconnects void ONREMOVE(entity this) diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh index a2cef664b..9048202fe 100644 --- a/qcsrc/lib/oo.qh +++ b/qcsrc/lib/oo.qh @@ -77,6 +77,13 @@ ACCUMULATE void ONREMOVE(entity this) {} /* this = NULL; */ \ MACRO_END +void IL_REMOVE_RAW(entity it); +void copyentity_qc(entity src, entity dst) +{ + copyentity(src, dst); // builtin function + IL_REMOVE_RAW(dst); +} + entity _clearentity_ent; STATIC_INIT(clearentity) { @@ -88,7 +95,7 @@ void clearentity(entity e) int n = e.entnum; #endif bool was_pure = is_pure(e); - copyentity(_clearentity_ent, e); + copyentity_qc(_clearentity_ent, e); if (!was_pure) make_impure(e); #ifdef CSQC e.entnum = n; @@ -175,7 +182,7 @@ void clearentity(entity e) { \ if (cname##_vtbl && !this.transmute) \ { \ - copyentity(cname##_vtbl, this); \ + copyentity_qc(cname##_vtbl, this); \ return; \ } \ spawn##base##_static(this); \ diff --git a/qcsrc/lib/spawnfunc.qh b/qcsrc/lib/spawnfunc.qh index c9bfebabd..2d9392dad 100644 --- a/qcsrc/lib/spawnfunc.qh +++ b/qcsrc/lib/spawnfunc.qh @@ -73,7 +73,7 @@ noref string __fullspawndata; void __spawnfunc_spawn(entity prototype) { entity e = new(clone); - copyentity(prototype, e); + copyentity_qc(prototype, e); IL_PUSH(g_map_entities, e); #define X(T, fld, def) { e.fld = e.__spawnfunc_##fld; e.__spawnfunc_##fld = def; } SPAWNFUNC_INTERNAL_FIELDS(X); diff --git a/qcsrc/server/weapons/spawning.qc b/qcsrc/server/weapons/spawning.qc index 0685062f5..dc7b110e2 100644 --- a/qcsrc/server/weapons/spawning.qc +++ b/qcsrc/server/weapons/spawning.qc @@ -61,8 +61,6 @@ void weapon_defaultspawnfunc(entity this, Weapon wpn) { entity replacement = spawn(); Item_CopyFields(this, replacement); - // DO NOT USE, causes #2792 - //copyentity(this, replacement); replacement.m_isreplaced = true; weapon_defaultspawnfunc(replacement, wep); } diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index fc2c3979c..df6490128 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -670,7 +670,7 @@ void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector setorigin(flash, offset); entity xflash = spawn(); - copyentity(flash, xflash); + copyentity_qc(flash, xflash); flash.viewmodelforclient = actor; -- 2.39.2