Improve support for per-player counters by spawning an entity to store the player...
authorMario <mario.mario@y7mail.com>
Mon, 18 May 2020 13:57:45 +0000 (23:57 +1000)
committerMario <mario.mario@y7mail.com>
Mon, 18 May 2020 13:57:45 +0000 (23:57 +1000)
qcsrc/common/mapobjects/trigger/counter.qc
qcsrc/common/mapobjects/trigger/counter.qh
qcsrc/server/client.qc

index db255eb..44cbd90 100644 (file)
@@ -5,11 +5,26 @@ void counter_reset(entity this);
 void counter_use(entity this, entity actor, entity trigger)
 {
        entity store = this;
-       if(this.spawnflags & COUNTER_PER_PLAYER) // FIXME: multiple counters in the map will not function correctly, and upon trigger reset the player won't be able to use it again!
+       if(this.spawnflags & COUNTER_PER_PLAYER)
        {
                if(!IS_PLAYER(actor))
                        return;
-               store = actor;
+               entity mycounter = NULL;
+               IL_EACH(g_counters, it.realowner == actor && it.owner == this,
+               {
+                       mycounter = it;
+                       break;
+               });
+               if(!mycounter)
+               {
+                       mycounter = new_pure(counter);
+                       IL_PUSH(g_counters, mycounter);
+                       mycounter.owner = this;
+                       mycounter.realowner = actor;
+                       mycounter.reset = counter_reset; // NOTE: this may be useless as the player deletes their counters upon respawning
+                       mycounter.counter_cnt = 0;
+               }
+               store = mycounter;
        }
 
        store.counter_cnt += 1;
@@ -27,8 +42,8 @@ void counter_use(entity this, entity actor, entity trigger)
 
                if(this.respawntime)
                {
-                       setthink(this, counter_reset);
-                       this.nextthink = time + this.respawntime;
+                       setthink(store, counter_reset);
+                       store.nextthink = time + this.respawntime;
                }
        }
        else
index d36bd02..403a87a 100644 (file)
@@ -4,6 +4,9 @@
 spawnfunc(trigger_counter);
 
 .float counter_cnt;
+
+IntrusiveList g_counters;
+STATIC_INIT(g_counters) { g_counters = IL_NEW(); }
 #endif
 
 const int COUNTER_FIRE_AT_COUNT = BIT(2);
index 79dca00..cb26ccc 100644 (file)
@@ -690,6 +690,10 @@ void PutPlayerInServer(entity this)
                IL_REMOVE(g_swamped, this);
        this.swampslug = NULL;
        this.swamp_interval = 0;
+       IL_EACH(g_counters, it.realowner == this,
+       {
+               delete(it);
+       });
        STAT(HUD, this) = HUD_NORMAL;
 
        this.event_damage = PlayerDamage;
@@ -1233,6 +1237,11 @@ void ClientDisconnect(entity this)
        if (this.chatbubbleentity) delete(this.chatbubbleentity);
        if (this.killindicator) delete(this.killindicator);
 
+       IL_EACH(g_counters, it.realowner == this,
+       {
+               delete(it);
+       });
+
        WaypointSprite_PlayerGone(this);
 
        bot_relinkplayerlist();