]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/status_effects/sv_status_effects.qc
Set the persistent flag on the Superweapons status effect when the player has unlimit...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / status_effects / sv_status_effects.qc
1 #include "sv_status_effects.qh"
2
3 METHOD(StatusEffects, m_active, bool(StatusEffects this, entity actor))
4 {
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);
9 }
10
11 METHOD(StatusEffects, m_tick, void(StatusEffects this, entity actor))
12 {
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);
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
29 METHOD(StatusEffects, m_apply, void(StatusEffects 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;
37         StatusEffects_update(actor);
38 }
39
40 METHOD(StatusEffects, m_remove, void(StatusEffects this, entity actor, int removal_type))
41 {
42         StatusEffects 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))
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);
51 }
52
53 MUTATOR_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
66 MUTATOR_HOOKFUNCTION(status_effects, PlayerDies)
67 {
68         entity frag_target = M_ARGV(2, entity);
69
70         StatusEffects_removeall(frag_target, STATUSEFFECT_REMOVE_NORMAL);
71 }
72
73 MUTATOR_HOOKFUNCTION(status_effects, MakePlayerObserver)
74 {
75         entity player = M_ARGV(0, entity);
76
77         // no need to network updates, as there is no statuseffects object attached
78         StatusEffects_clearall(player.statuseffects_store);
79
80         // don't delete spectatee's effects!
81         if(player.statuseffects && player.statuseffects.owner == player)
82                 StatusEffects_delete(player);
83 }
84
85 MUTATOR_HOOKFUNCTION(status_effects, reset_map_global)
86 {
87         FOREACH_CLIENT(IS_PLAYER(it) && it.statuseffects,
88         {
89                 StatusEffects_clearall(it.statuseffects);
90                 StatusEffects_update(it);
91         });
92         return false;
93 }
94
95 MUTATOR_HOOKFUNCTION(status_effects, SpectateCopy)
96 {
97         entity spectatee = M_ARGV(0, entity);
98         entity client = M_ARGV(1, entity);
99
100         client.statuseffects = spectatee.statuseffects;
101 }
102
103 MUTATOR_HOOKFUNCTION(status_effects, PutClientInServer)
104 {
105         entity player = M_ARGV(0, entity);
106
107         if(player.statuseffects && player.statuseffects.owner == player)
108         {
109                 StatusEffects_clearall(player.statuseffects);
110                 StatusEffects_update(player);
111         }
112         else
113         {
114                 StatusEffects_clearall(player.statuseffects_store);
115                 player.statuseffects = NULL;
116         }
117 }