Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_status_effects.qc
Go to the documentation of this file.
2
3METHOD(StatusEffect, m_active, bool(StatusEffect this, entity actor))
4{
5 TC(StatusEffect, this);
6 if(!actor.statuseffects)
7 return false; // safety net
8 return (actor.statuseffects.statuseffect_flags[this.m_id] & STATUSEFFECT_FLAG_ACTIVE);
9}
10
11METHOD(StatusEffect, m_tick, void(StatusEffect this, entity actor))
12{
13 StatusEffect 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))
19
20 if(data.(flg) & STATUSEFFECT_FLAG_PERSISTENT)
21 return;
22 if(time > actor.statuseffects.statuseffect_time[this.m_id])
23 {
24 this.m_remove(this, actor, STATUSEFFECT_REMOVE_TIMEOUT);
25 return;
26 }
27}
28
29METHOD(StatusEffect, m_apply, void(StatusEffect this, entity actor, float eff_time, float eff_flags))
30{
31 if(!actor.statuseffects)
32 StatusEffects_new(actor);
33
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;
38}
39
40METHOD(StatusEffect, m_remove, void(StatusEffect this, entity actor, int removal_type))
41{
42 StatusEffect data = actor.statuseffects;
43 if(!data)
44 return;
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))
48 data.statuseffect_time[this.m_id] = 0;
49 data.statuseffect_flags[this.m_id] = 0;
51}
52
53MUTATOR_HOOKFUNCTION(status_effects, SV_StartFrame)
54{
55 if(game_stopped)
56 return;
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,
60 {
61 if (it.move_movetype == MOVETYPE_NOCLIP || !it.statuseffects) continue;
62 StatusEffects_tick(it);
63 });
64}
65
72
79
81{
82 entity player = M_ARGV(0, entity);
83
84 // don't delete possible spectatee's effects!
85 if(player.statuseffects && player.statuseffects.owner == player)
86 {
87 // just to get rid of the pickup sound
89 }
90
91 return true;
92}
93
94MUTATOR_HOOKFUNCTION(status_effects, MakePlayerObserver)
95{
96 entity player = M_ARGV(0, entity);
97
98 // don't delete spectatee's effects!
99 if(player.statuseffects && player.statuseffects.owner == player)
100 {
101 // just to get rid of the pickup sound
102 // no need to network updates, as there is no statuseffects object attached
104 }
105
106 // spectator has their own ent
107 StatusEffects_clearall(player.statuseffects_store);
108
109 // don't delete spectatee's effects!
110 if(player.statuseffects && player.statuseffects.owner == player)
111 StatusEffects_delete(player);
112}
113
114MUTATOR_HOOKFUNCTION(status_effects, reset_map_global)
115{
116 FOREACH_CLIENT(IS_PLAYER(it) && it.statuseffects,
117 {
118 StatusEffects_removeall(it, STATUSEFFECT_REMOVE_NORMAL); // just to get rid of the pickup sound
119 StatusEffects_clearall(it.statuseffects);
120 StatusEffects_update(it);
121 });
122 return false;
123}
124
126{
127 entity spectatee = M_ARGV(0, entity);
128 entity client = M_ARGV(1, entity);
129
130 client.statuseffects = spectatee.statuseffects;
131}
132
134{
135 entity player = M_ARGV(0, entity);
136
137 if(player.statuseffects && player.statuseffects.owner == player)
138 {
139 StatusEffects_clearall(player.statuseffects);
140 StatusEffects_update(player);
141 }
142 else
143 {
144 StatusEffects_clearall(player.statuseffects_store);
145 player.statuseffects = NULL;
146 }
147}
#define MUTATOR_HOOKFUNCTION(...)
Definition base.qh:335
#define BITSET(var, mask, flag)
Definition bits.qh:11
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
int m_id
Definition all.qh:34
int statuseffect_flags[REGISTRY_MAX(StatusEffects)]
Definition all.qh:49
virtual void m_apply()
float statuseffect_time[REGISTRY_MAX(StatusEffects)]
Stores times of status effects, the id being the index.
Definition all.qh:48
virtual void m_remove()
Sound m_sound_rm
Definition all.qh:44
#define M_ARGV(x, type)
Definition events.qh:17
#define IS_PLAYER(s)
Definition player.qh:243
float game_stopped
Definition stats.qh:81
float time
IntrusiveList g_damagedbycontents
Definition damage.qh:135
int m_id
Definition effect.qh:19
#define IL_EACH(this, cond, body)
#define PutClientInServer
Definition _all.inc:246
#define ClientDisconnect
Definition _all.inc:242
#define TC(T, sym)
Definition _all.inc:82
@ STATUSEFFECT_REMOVE_NORMAL
Effect is being removed by a function, calls regular removal mechanics.
Definition all.qh:28
@ STATUSEFFECT_REMOVE_TIMEOUT
Definition all.qh:29
@ STATUSEFFECT_FLAG_PERSISTENT
Effect is currently being granted passively.
Definition all.qh:23
@ STATUSEFFECT_FLAG_ACTIVE
Definition all.qh:22
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
void SpectateCopy(entity this, entity spectatee)
Definition client.qc:1793
const int CH_TRIGGER
Definition sound.qh:12
const float VOL_BASE
Definition sound.qh:36
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
void StatusEffects_removeall(entity actor, int removal_type)
void StatusEffects_new(entity this)
void StatusEffects_update(entity e)
void StatusEffects_delete(entity e)
void StatusEffects_clearall(entity store)
entity frag_target
Definition sv_ctf.qc:2321
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50