.float dent_net_health;
.float dent_net_armor;
.float dent_net_potential;
-.entity dent_attackers;
+
+const int BITS_PER_INT = 24;
+const int DENT_ATTACKERS_SIZE = 11; // ceil(255 / BITS_PER_INT)
+// where 255 is the max number of clients that the engine can support
+.int dent_attackers[DENT_ATTACKERS_SIZE];
bool write_damagetext(entity this, entity client, int sf)
{
net_text_prev.dent_net_potential = potential_damage;
return;
}
- else if (attacker && !IL_CONTAINS(hit.dent_attackers, attacker))
+ else if (attacker)
{
- // player is hit for the first time after respawn by this attacker
- IL_PUSH(hit.dent_attackers, attacker);
- flags |= DTFLAG_STOP_ACCUMULATION; // forcedly stop client-side damage accumulation
+ int attacker_id = etof(attacker) - 1;
+ int idx = floor(attacker_id / BITS_PER_INT);
+ int bit = attacker_id % BITS_PER_INT;
+ if (!(hit.dent_attackers[idx] & BIT(bit)))
+ {
+ // player is hit for the first time after respawn by this attacker
+ hit.dent_attackers[idx] |= BIT(bit);
+ flags |= DTFLAG_STOP_ACCUMULATION; // forcedly stop client-side damage accumulation
+ }
}
entity net_text = new_pure(net_damagetext);
MUTATOR_HOOKFUNCTION(damagetext, ClientDisconnect)
{
entity player = M_ARGV(0, entity);
- if (player.dent_attackers)
- IL_DELETE(player.dent_attackers);
-
- // NOTE this player is automatically removed from dent_attackers lists of other players
- // by intrusive list's ONREMOVE
+ int player_id = etof(player) - 1;
+ int idx = floor(player_id / BITS_PER_INT);
+ int bit = player_id % BITS_PER_INT;
+ // remove from attacker list of all players
+ FOREACH_CLIENT(IS_PLAYER(it), {
+ it.dent_attackers[idx] &= ~BIT(bit);
+ });
}
MUTATOR_HOOKFUNCTION(damagetext, PlayerSpawn)
{
entity player = M_ARGV(0, entity);
- if (player.dent_attackers == NULL)
- {
- player.dent_attackers = IL_NEW();
- return true;
- }
-
- IL_CLEAR(player.dent_attackers);
+ for (int i = 0; i < DENT_ATTACKERS_SIZE; ++i)
+ player.dent_attackers[i] = 0;
}