1 #include "sv_status_effects.qh"
3 METHOD(StatusEffects, m_active, bool(StatusEffects this, entity actor))
5 TC(StatusEffects, this);
6 if(!actor.statuseffects)
7 return false; // safety net
8 return (actor.statuseffects.statuseffect_flags[this.m_id] & STATUSEFFECT_FLAG_ACTIVE);
11 METHOD(StatusEffects, m_tick, void(StatusEffects this, entity actor))
13 StatusEffects data = actor.statuseffects;
14 .int flg = statuseffect_flags[this.m_id];
15 int oldflag = data.(flg);
16 data.(flg) = BITSET(data.(flg), STATUSEFFECT_FLAG_PERSISTENT, this.m_persistent(this, actor));
17 if(oldflag != data.(flg))
18 StatusEffects_update(actor);
20 if(data.(flg) & STATUSEFFECT_FLAG_PERSISTENT)
22 if(time > actor.statuseffects.statuseffect_time[this.m_id])
24 this.m_remove(this, actor, STATUSEFFECT_REMOVE_TIMEOUT);
29 METHOD(StatusEffects, m_apply, void(StatusEffects this, entity actor, float eff_time, float eff_flags))
31 if(!actor.statuseffects)
32 StatusEffects_new(actor);
34 eff_flags |= STATUSEFFECT_FLAG_ACTIVE; // automatically enable active flag if applied (TODO?)
35 actor.statuseffects.statuseffect_time[this.m_id] = eff_time; // TODO: add onto the existing time rather than replacing it?
36 actor.statuseffects.statuseffect_flags[this.m_id] = eff_flags;
37 StatusEffects_update(actor);
40 METHOD(StatusEffects, m_remove, void(StatusEffects this, entity actor, int removal_type))
42 StatusEffects data = actor.statuseffects;
45 // NOTE: persistent effects do not make a sound on removal, this is intended as a workaround for #2620
46 if(removal_type == STATUSEFFECT_REMOVE_NORMAL && !(data.statuseffect_flags[this.m_id] & STATUSEFFECT_FLAG_PERSISTENT) && this.m_active(this, actor))
47 sound(actor, CH_TRIGGER, this.m_sound_rm, VOL_BASE, ATTEN_NORM);
48 data.statuseffect_time[this.m_id] = 0;
49 data.statuseffect_flags[this.m_id] = 0;
50 StatusEffects_update(actor);
53 MUTATOR_HOOKFUNCTION(status_effects, SV_StartFrame)
57 // TODO: explicitly only loop through entities with a valid statuseffects object
58 // NOTE: due to the way vehicles work currently, this does not function correctly! effect does not tick while inside a vehicle
59 IL_EACH(g_damagedbycontents, it.damagedbycontents,
61 if (it.move_movetype == MOVETYPE_NOCLIP || !it.statuseffects) continue;
62 StatusEffects_tick(it);
66 MUTATOR_HOOKFUNCTION(status_effects, PlayerDies)
68 entity frag_target = M_ARGV(2, entity);
70 StatusEffects_removeall(frag_target, STATUSEFFECT_REMOVE_NORMAL);
73 MUTATOR_HOOKFUNCTION(status_effects, MakePlayerObserver)
75 entity player = M_ARGV(0, entity);
77 // no need to network updates, as there is no statuseffects object attached
78 StatusEffects_clearall(player.statuseffects_store);
80 // don't delete spectatee's effects!
81 if(player.statuseffects && player.statuseffects.owner == player)
82 StatusEffects_delete(player);
85 MUTATOR_HOOKFUNCTION(status_effects, reset_map_global)
87 FOREACH_CLIENT(IS_PLAYER(it) && it.statuseffects,
89 StatusEffects_clearall(it.statuseffects);
90 StatusEffects_update(it);
95 MUTATOR_HOOKFUNCTION(status_effects, SpectateCopy)
97 entity spectatee = M_ARGV(0, entity);
98 entity client = M_ARGV(1, entity);
100 client.statuseffects = spectatee.statuseffects;
103 MUTATOR_HOOKFUNCTION(status_effects, PutClientInServer)
105 entity player = M_ARGV(0, entity);
107 if(player.statuseffects && player.statuseffects.owner == player)
109 StatusEffects_clearall(player.statuseffects);
110 StatusEffects_update(player);
114 StatusEffects_clearall(player.statuseffects_store);
115 player.statuseffects = NULL;