]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/func/button.qc
8e5e3530e3512759e9423ddac0975cbdc0ccdd7a
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / button.qc
1 #include "button.qh"
2 #include "../spawnflags.qh"
3 #ifdef SVQC
4 // button and multiple button
5
6 void button_wait(entity this);
7 void button_return(entity this);
8
9 void button_wait(entity this)
10 {
11         this.state = STATE_TOP;
12         if(this.wait >= 0)
13         {
14                 this.nextthink = this.ltime + this.wait;
15                 setthink(this, button_return);
16         }
17         SUB_UseTargets(this, this.enemy, NULL);
18         this.frame = 1;                 // use alternate textures
19 }
20
21 void button_done(entity this)
22 {
23         this.state = STATE_BOTTOM;
24 }
25
26 void button_return(entity this)
27 {
28         this.state = STATE_DOWN;
29         SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, button_done);
30         this.frame = 0;                 // use normal textures
31         if (this.health)
32                 this.takedamage = DAMAGE_YES;   // can be shot again
33 }
34
35
36 void button_blocked(entity this, entity blocker)
37 {
38         // do nothing, just don't come all the way back out
39 }
40
41
42 void button_fire(entity this)
43 {
44         this.health = this.max_health;
45         this.takedamage = DAMAGE_NO;    // will be reset upon return
46
47         if (this.state == STATE_UP || this.state == STATE_TOP)
48                 return;
49
50         if (this.noise != "")
51                 _sound (this, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
52
53         this.state = STATE_UP;
54         SUB_CalcMove (this, this.pos2, TSPEED_LINEAR, this.speed, button_wait);
55 }
56
57 void button_reset(entity this)
58 {
59         this.health = this.max_health;
60         setorigin(this, this.pos1);
61         this.frame = 0;                 // use normal textures
62         this.state = STATE_BOTTOM;
63         this.velocity = '0 0 0';
64         setthink(this, func_null);
65         this.nextthink = 0;
66         if (this.health)
67                 this.takedamage = DAMAGE_YES;   // can be shot again
68 }
69
70 void button_use(entity this, entity actor, entity trigger)
71 {
72         if(this.active != ACTIVE_ACTIVE)
73                 return;
74
75         this.enemy = actor;
76         button_fire(this);
77 }
78
79 void button_touch(entity this, entity toucher)
80 {
81         if (!toucher)
82                 return;
83         if (!toucher.iscreature)
84                 return;
85         if(toucher.velocity * this.movedir < 0)
86                 return;
87         this.enemy = toucher;
88         if (toucher.owner)
89                 this.enemy = toucher.owner;
90         button_fire (this);
91 }
92
93 void button_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
94 {
95         if(this.spawnflags & DOOR_NOSPLASH)
96                 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
97                         return;
98         if (this.spawnflags & BUTTON_DONTACCUMULATEDMG)
99         {
100                 if (this.health <= damage)
101                 {
102                         this.enemy = attacker;
103                         button_fire(this);
104                 }
105         }
106         else
107         {
108                 this.health = this.health - damage;
109                 if (this.health <= 0)
110                 {
111                         this.enemy = attacker;
112                         button_fire(this);
113                 }
114         }
115 }
116
117
118 /*QUAKED spawnfunc_func_button (0 .5 .8) ?
119 When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
120
121 "angle"         determines the opening direction
122 "target"        all entities with a matching targetname will be used
123 "speed"         override the default 40 speed
124 "wait"          override the default 1 second wait (-1 = never return)
125 "lip"           override the default 4 pixel lip remaining at end of move
126 "health"        if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the InstaGib laser
127 "noise"         sound that is played when the button is activated
128 */
129 spawnfunc(func_button)
130 {
131         SetMovedir(this);
132
133         if (!InitMovingBrushTrigger(this))
134                 return;
135         this.effects |= EF_LOWPRECISION;
136
137         setblocked(this, button_blocked);
138         this.use = button_use;
139
140 //      if (this.health == 0) // all buttons are now shootable
141 //              this.health = 10;
142         if (this.health)
143         {
144                 this.max_health = this.health;
145                 this.event_damage = button_damage;
146                 this.takedamage = DAMAGE_YES;
147         }
148         else
149                 settouch(this, button_touch);
150
151         if (!this.speed)
152                 this.speed = 40;
153         if (!this.wait)
154                 this.wait = 1;
155         if (!this.lip)
156                 this.lip = 4;
157
158     if(this.noise != "")
159         precache_sound(this.noise);
160
161         this.active = ACTIVE_ACTIVE;
162
163         this.pos1 = this.origin;
164         this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
165     this.flags |= FL_NOTARGET;
166
167     this.reset = button_reset;
168
169         button_reset(this);
170 }
171 #endif