]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fixed electro secondary limit being global
authorDr. Jaska <drjaska83@gmail.com>
Mon, 29 Mar 2021 13:28:16 +0000 (13:28 +0000)
committerterencehill <piuntn@gmail.com>
Mon, 29 Mar 2021 13:28:16 +0000 (13:28 +0000)
Now it tracks which electro entity has fired how many balls and destroys
the oldest ones of that electro entity, not the oldest of any electro
entity. I had to clone and edit the rubble functions to support entity
storing and comparing the owner of the child entity to given entity,
those are named electrorubble but can be renamed, they are just created
for electro, they support other entities too and not only electro balls.

qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/gibs.qc
qcsrc/common/effects/qc/rubble.qc
qcsrc/common/effects/qc/rubble.qh
qcsrc/common/weapons/weapon/electro.qc
qcsrc/lib/intrusivelist.qh

index d5af50fb3803043cf1f68072850692b78c390dd8..10dfa385d450fb5736c01935da463051fefb2f3c 100644 (file)
@@ -149,7 +149,7 @@ NET_HANDLE(casings, bool isNew)
     ang_z = ReadByte() * 360 / 256;
     return = true;
 
-    Casing casing = RubbleNew(new(casing));
+    Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
     casing.silent = (_state & 0x80);
     casing.state = (_state & 0x7F);
     casing.origin = org;
@@ -183,7 +183,7 @@ NET_HANDLE(casings, bool isNew)
 
     setsize(casing, '0 0 -1', '0 0 -1');
 
-    RubbleLimit("casing", autocvar_cl_casings_maxcount, Casing_Delete);
+    LimitedChildrenRubble(CasingsNGibs, "casing", autocvar_cl_casings_maxcount, Casing_Delete, NULL);
 }
 
 #endif
index ac69e9e0176609593299585480564813856085de..64a847e270644c0b4c3260114b91c550d703a511 100644 (file)
@@ -170,7 +170,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
        entity gib;
 
        // TODO remove some gibs according to cl_nogibs
-       gib = RubbleNew(new(gib));
+       gib = ListNewChildRubble(CasingsNGibs, new(gib));
        set_movetype(gib, MOVETYPE_BOUNCE);
        gib.gravity = 1;
        gib.solid = SOLID_CORPSE;
@@ -205,7 +205,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
        gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15);
        gib.drawmask = MASK_NORMAL;
 
-       RubbleLimit("gib", autocvar_cl_gibs_maxcount, Gib_Delete);
+       LimitedChildrenRubble(CasingsNGibs, "gib", autocvar_cl_gibs_maxcount, Gib_Delete, NULL);
 }
 
 NET_HANDLE(net_gibsplash, bool isNew)
index 27dd7d40ea69b070dc313d7a0dd3178d5f064d91..f0a29bd5ba5edf38cb8874aab28a5109cb116f25 100644 (file)
@@ -1,8 +1,8 @@
 #include "rubble.qh"
 
 #ifdef GAMEQC
-void RubbleLimit(string cname, int limit, void(entity) deleteproc)
-{
+
+void LimitedChildrenRubble(IntrusiveList list, string cname, int limit, void(entity) deleteproc, entity parent){
        // remove rubble of the same type if it's at the limit
        // remove multiple rubble if the limit has been decreased
        while (1)
@@ -13,13 +13,15 @@ void RubbleLimit(string cname, int limit, void(entity) deleteproc)
                entity oldest = NULL;
                float oldesttime = 0;
                // compare to all other matching entities
-               IL_EACH(g_rubble, it.classname == cname,
+               IL_EACH(list, it.classname == cname,
                {
-                       ++c;
-                       if(!oldest || oldesttime > it.creationtime)
-                       {
-                               oldest = it;
-                               oldesttime = it.creationtime;
+                       if(!parent ||parent == it.owner){
+                               ++c;
+                               if(!oldest || oldesttime > it.creationtime)
+                               {
+                                       oldest = it;
+                                       oldesttime = it.creationtime;
+                               }
                        }
                });
 
@@ -31,10 +33,20 @@ void RubbleLimit(string cname, int limit, void(entity) deleteproc)
        }
 }
 
-entity RubbleNew(entity e)
-{
-       e.creationtime = time;
-       IL_PUSH(g_rubble, e);
-       return e;
+
+// This function doesn't preserve linked list order but it is not needed as creationtime is used instead of list position for comparing ages.
+// IL_Replace or similiar order preserving function did not exist at the time of creating this.
+entity ReplaceOldListedChildRubble(IntrusiveList list, entity child, entity oldChild){
+       child.creationtime = oldChild.creationtime;
+       IL_REMOVE(list, oldChild);
+       IL_PUSH(list, child);
+       return child;
 }
+
+entity ListNewChildRubble(IntrusiveList list, entity child){
+       child.creationtime = time;
+       IL_PUSH(list, child);
+       return child;
+}
+
 #endif
index 406d602c145d2359a6dd4d52fa324640f9e0857b..bd75bae019425e016553c584da070ac5ea0b6376 100644 (file)
@@ -4,10 +4,17 @@
 entityclass(Rubble);
 classfield(Rubble).float creationtime;
 
-IntrusiveList g_rubble;
-STATIC_INIT(g_rubble) { g_rubble = IL_NEW(); }
+IntrusiveList CasingsNGibs;
+STATIC_INIT(CasingsNGibs) { CasingsNGibs = IL_NEW(); }
 
-void RubbleLimit(string cname, int limit, void(entity) deleteproc);
+IntrusiveList LimitedElectroBallRubbleList;
+STATIC_INIT(LimitedElectroBallRubbleList) { LimitedElectroBallRubbleList = IL_NEW(); }
+
+
+void LimitedChildrenRubble(IntrusiveList list, string cname, int limit, void(entity) deleteproc, entity parent);
+
+entity ReplaceOldListedChildRubble(IntrusiveList list, entity child, entity oldChild);
+
+entity ListNewChildRubble(IntrusiveList list, entity child);
 
-entity RubbleNew(entity e);
 #endif
index 21a2f9b0128723b4d719acc46d3d20f852e2a569..79cfa5ebf9fe124988afddc909cb0f4ba5a7a1aa 100644 (file)
@@ -297,10 +297,9 @@ void W_Electro_Orb_Stick(entity this, entity to)
        IL_PUSH(g_bot_dodge, newproj);
 
        // check if limits are enabled (we can tell by checking if the original orb is listed) and push it to the list if so
-       if(IL_CONTAINS(g_rubble, this))
+       if(IL_CONTAINS(LimitedElectroBallRubbleList, this))
        {
-               newproj.creationtime = this.creationtime;
-               IL_PUSH(g_rubble, newproj);
+               ReplaceOldListedChildRubble(LimitedElectroBallRubbleList, newproj, this);
        }
 
        delete(this);
@@ -423,8 +422,8 @@ void W_Electro_Attack_Orb(Weapon thiswep, entity actor, .entity weaponentity)
 
        if(WEP_CVAR_SEC(electro, limit) > 0)
        {
-               RubbleNew(proj);
-               RubbleLimit("electro_orb", WEP_CVAR_SEC(electro, limit), adaptor_think2use_hittype_splash);
+               ListNewChildRubble(LimitedElectroBallRubbleList, proj);
+               LimitedChildrenRubble(LimitedElectroBallRubbleList, "electro_orb", WEP_CVAR_SEC(electro, limit), adaptor_think2use_hittype_splash, actor);
        }
 
        CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound
index be3fb00fa88ad72aad651d185bc974a4a518fd8e..dce561bb5124e1bb4d287e483ec80400988cd2b0 100644 (file)
@@ -2,6 +2,10 @@
 
 #include "iter.qh"
 
+/**
+ * This limitation is only towards maximum amount of creatable lists.
+ * Lists can be given endless amount of entities, only restricted by engine limitations.
+ */
 const int IL_MAX = 128;
 
 ERASEABLE