]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mapobjects/trigger/counter.qc
Improve support for per-player counters by spawning an entity to store the player...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / trigger / counter.qc
1 #include "counter.qh"
2 #ifdef SVQC
3 void counter_reset(entity this);
4
5 void counter_use(entity this, entity actor, entity trigger)
6 {
7         entity store = this;
8         if(this.spawnflags & COUNTER_PER_PLAYER)
9         {
10                 if(!IS_PLAYER(actor))
11                         return;
12                 entity mycounter = NULL;
13                 IL_EACH(g_counters, it.realowner == actor && it.owner == this,
14                 {
15                         mycounter = it;
16                         break;
17                 });
18                 if(!mycounter)
19                 {
20                         mycounter = new_pure(counter);
21                         IL_PUSH(g_counters, mycounter);
22                         mycounter.owner = this;
23                         mycounter.realowner = actor;
24                         mycounter.reset = counter_reset; // NOTE: this may be useless as the player deletes their counters upon respawning
25                         mycounter.counter_cnt = 0;
26                 }
27                 store = mycounter;
28         }
29
30         store.counter_cnt += 1;
31         if (store.counter_cnt > this.count)
32                 return;
33
34         bool doactivate = (this.spawnflags & COUNTER_FIRE_AT_COUNT);
35
36         if (store.counter_cnt == this.count)
37         {
38                 if(IS_PLAYER(actor) && !(this.spawnflags & SPAWNFLAG_NOMESSAGE))
39                         Send_Notification(NOTIF_ONE, actor, MSG_CENTER, CENTER_SEQUENCE_COMPLETED);
40
41                 doactivate = true;
42
43                 if(this.respawntime)
44                 {
45                         setthink(store, counter_reset);
46                         store.nextthink = time + this.respawntime;
47                 }
48         }
49         else
50         {
51                 if(IS_PLAYER(actor) && !(this.spawnflags & SPAWNFLAG_NOMESSAGE))
52                 {
53                         if((this.count - store.counter_cnt) >= 4)
54                                 Send_Notification(NOTIF_ONE, actor, MSG_CENTER, CENTER_SEQUENCE_COUNTER);
55                         else
56                                 Send_Notification(NOTIF_ONE, actor, MSG_CENTER, CENTER_SEQUENCE_COUNTER_FEWMORE, this.count - store.counter_cnt);
57                 }
58         }
59
60         if(doactivate)
61                 SUB_UseTargets(this, actor, trigger);
62 }
63
64 void counter_reset(entity this)
65 {
66         setthink(this, func_null);
67         this.nextthink = 0;
68         this.counter_cnt = 0;
69 }
70
71 /*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage COUNTER_FIRE_AT_COUNT
72 Acts as an intermediary for an action that takes multiple inputs.
73
74 If nomessage is not set, it will print "1 more.. " etc when triggered and "sequence complete" when finished.
75 If COUNTER_FIRE_AT_COUNT is set, it will also fire all of its targets at countdown, making it behave like trigger_mulitple with limited shots
76
77 If respawntime is set, it will re-enable itself after the time once the sequence has been completed
78
79 After the counter has been triggered "count" times (default 2), it will fire all of its targets.
80 */
81 spawnfunc(trigger_counter)
82 {
83         if (!this.count)
84                 this.count = 2;
85
86         this.counter_cnt = 0;
87         this.use = counter_use;
88         this.reset = counter_reset;
89 }
90 #endif