]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add a new function to copy fields from items to replacements, fixes #2792
authorMario <mario.mario@y7mail.com>
Fri, 6 Jan 2023 18:40:27 +0000 (04:40 +1000)
committerMario <mario.mario@y7mail.com>
Fri, 6 Jan 2023 18:40:27 +0000 (04:40 +1000)
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/random_items/sv_random_items.qc
qcsrc/server/items/items.qc
qcsrc/server/items/items.qh
qcsrc/server/weapons/spawning.qc

index 947111a08f66e80c566c4c5cc92ad0dd9d409bb4..7b41f98249ca471a7b0caf8e4dc98eab917c6e94 100644 (file)
@@ -674,10 +674,9 @@ MUTATOR_HOOKFUNCTION(lms, OnEntityPreSpawn)
        entity e = spawn();
        setthink(e, lms_extralife);
 
+       Item_CopyFields(ent, e);
+
        e.nextthink = time + 0.1;
-       e.spawnflags = ent.spawnflags;
-       e.noalign = ent.noalign;
-       setorigin(e, ent.origin);
 
        return true;
 }
index 2131228ebf2e47a13a7676b0e09d5c9fad16caac..7b270f32f602a38afe8249e511a49bcc142f93f6 100644 (file)
@@ -297,11 +297,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, SetWeaponArena)
 void replace_with_insta_cells(entity item)
 {
        entity e = new(item_vaporizer_cells);
-       setorigin(e, item.origin);
-       e.noalign = Item_ShouldKeepPosition(item);
-       e.cnt = item.cnt;
-       e.team = item.team;
-       e.spawnfunc_checked = true;
+       Item_CopyFields(item, e);
        spawnfunc_item_vaporizer_cells(e);
 }
 
@@ -438,10 +434,8 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, OnEntityPreSpawn)
                setthink(e, instagib_speed);
        }
 
+       Item_CopyFields(ent, e);
        e.nextthink = time + 0.1;
-       e.spawnflags = ent.spawnflags;
-       e.noalign = ent.noalign;
-       setorigin(e, ent.origin);
 
        return true;
 }
index 7b2459869d3c60b8de1edf542e16d07e5ce11f36..009acc355738fd80fd235d59e5a1bc3bae663d01 100644 (file)
@@ -227,28 +227,20 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
        if (item.classname == "item_strength")
        {
                entity wep = new(weapon_okhmg);
-               setorigin(wep, item.origin);
+               Item_CopyFields(item, wep);
                wep.ok_item = true;
-               wep.noalign = Item_ShouldKeepPosition(item);
-               wep.cnt = item.cnt;
-               wep.team = item.team;
                wep.respawntime = g_pickup_respawntime_superweapon;
                wep.pickup_anyway = true;
-               wep.spawnfunc_checked = true;
                Item_Initialize(wep, "weapon_okhmg"); // doesn't actually use spawnfunc
                return true;
        }
        else if (item.classname == "item_shield")
        {
                entity wep = new(weapon_okrpc);
-               setorigin(wep, item.origin);
+               Item_CopyFields(item, wep);
                wep.ok_item = true;
-               wep.noalign = Item_ShouldKeepPosition(item);
-               wep.cnt = item.cnt;
-               wep.team = item.team;
                wep.respawntime = g_pickup_respawntime_superweapon;
                wep.pickup_anyway = true;
-               wep.spawnfunc_checked = true;
                Item_Initialize(wep, "weapon_okrpc"); // doesn't actually use spawnfunc
                return true;
        }
index 183808021b92ecdbdc2324a2431a5ecdbe135c9d..c0fa7ff9697b7f1dd3d004054e032cd5ae2ad6c2 100644 (file)
@@ -269,6 +269,7 @@ entity RandomItems_ReplaceMapItem(entity item)
        entity new_item;
        if (!MUTATOR_IS_ENABLED(ok))
        {
+               // TODO: doesn't copy many fields from items
                new_item = Item_Create(strzone(new_classname), item.origin,
                        Item_ShouldKeepPosition(item));
                random_items_is_spawning = false;
@@ -280,9 +281,8 @@ entity RandomItems_ReplaceMapItem(entity item)
        else
        {
                new_item = spawn();
+               Item_CopyFields(item, new_item);
                new_item.classname = strzone(new_classname);
-               new_item.spawnfunc_checked = true;
-               new_item.noalign = Item_ShouldKeepPosition(item);
                new_item.ok_item = true;
                Item_Initialize(new_item, new_classname);
                random_items_is_spawning = false;
@@ -290,7 +290,6 @@ entity RandomItems_ReplaceMapItem(entity item)
                {
                        return NULL;
                }
-               setorigin(new_item, item.origin);
        }
        if (item.team)
        {
index e68d858a8e72e55d9ad4a156cd0b81400cafbd8e..6b653d9c33ebde54776661e4481371a217239eec 100644 (file)
@@ -795,6 +795,19 @@ void Item_FindTeam(entity this)
        });
 }
 
+void Item_CopyFields(entity this, entity to)
+{
+       setorigin(to, this.origin);
+       to.spawnflags = this.spawnflags;
+       to.noalign = Item_ShouldKeepPosition(this);
+       to.cnt = this.cnt;
+       to.team = this.team;
+       to.spawnfunc_checked = true;
+       // TODO: copy respawn times? this may not be desirable in some cases
+       //to.respawntime = this.respawntime;
+       //to.respawntimejitter = this.respawntimejitter;
+}
+
 // Savage: used for item garbage-collection
 void RemoveItem(entity this)
 {
index f00b7bdc3c2b77b314c75f573d582e5dea3066a4..95e27f8361efc99171941b86ba837baabb9bfce8 100644 (file)
@@ -75,6 +75,8 @@ void Item_Reset(entity this);
 
 void Item_FindTeam(entity this);
 
+void Item_CopyFields(entity this, entity to);
+
 bool ItemSend(entity this, entity to, int sf);
 void ItemUpdate(entity this);
 
index e38a508a90ca69e6f52c38b6bb3c38f66b663df4..b14579e24e3bbae667b168caa110e2b7ad7fdd81 100644 (file)
@@ -60,7 +60,10 @@ void weapon_defaultspawnfunc(entity this, Weapon wpn)
                                if(wep != WEP_Null)
                                {
                                        entity replacement = spawn();
-                                       copyentity(this, replacement);
+                                       Item_CopyFields(this, replacement);
+                                       // copyentity is an engine function which unintentionally copies intrusive list data
+                                       // DO NOTE USE, causes #2792
+                                       //copyentity(this, replacement);
                                        replacement.m_isreplaced = true;
                                        weapon_defaultspawnfunc(replacement, wep);
                                }