Merge branch 'master' into Mario/vaporizer_damage
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / button.qc
1 #ifdef SVQC
2 // button and multiple button
3
4 void() button_wait;
5 void() button_return;
6
7 void button_wait()
8 {
9         self.state = STATE_TOP;
10         self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
11         self.SUB_THINK = button_return;
12         activator = self.enemy;
13         SUB_UseTargets();
14         self.frame = 1;                 // use alternate textures
15 }
16
17 void button_done()
18 {
19         self.state = STATE_BOTTOM;
20 }
21
22 void button_return()
23 {
24         self.state = STATE_DOWN;
25         SUB_CalcMove (self.pos1, TSPEED_LINEAR, self.speed, button_done);
26         self.frame = 0;                 // use normal textures
27         if (self.health)
28                 self.takedamage = DAMAGE_YES;   // can be shot again
29 }
30
31
32 void button_blocked()
33 {
34         // do nothing, just don't come all the way back out
35 }
36
37
38 void button_fire()
39 {
40         self.health = self.max_health;
41         self.takedamage = DAMAGE_NO;    // will be reset upon return
42
43         if (self.state == STATE_UP || self.state == STATE_TOP)
44                 return;
45
46         if (self.noise != "")
47                 sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
48
49         self.state = STATE_UP;
50         SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, button_wait);
51 }
52
53 void button_reset()
54 {
55         self.health = self.max_health;
56         setorigin(self, self.pos1);
57         self.frame = 0;                 // use normal textures
58         self.state = STATE_BOTTOM;
59         if (self.health)
60                 self.takedamage = DAMAGE_YES;   // can be shot again
61 }
62
63 void button_use()
64 {
65         if(self.active != ACTIVE_ACTIVE)
66                 return;
67
68         self.enemy = activator;
69         button_fire ();
70 }
71
72 void button_touch()
73 {
74         if (!other)
75                 return;
76         if (!other.iscreature)
77                 return;
78         if(other.velocity * self.movedir < 0)
79                 return;
80         self.enemy = other;
81         if (other.owner)
82                 self.enemy = other.owner;
83         button_fire ();
84 }
85
86 void button_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
87 {
88         if(self.spawnflags & DOOR_NOSPLASH)
89                 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
90                         return;
91         self.health = self.health - damage;
92         if (self.health <= 0)
93         {
94                 self.enemy = damage_attacker;
95                 button_fire ();
96         }
97 }
98
99
100 /*QUAKED spawnfunc_func_button (0 .5 .8) ?
101 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.
102
103 "angle"         determines the opening direction
104 "target"        all entities with a matching targetname will be used
105 "speed"         override the default 40 speed
106 "wait"          override the default 1 second wait (-1 = never return)
107 "lip"           override the default 4 pixel lip remaining at end of move
108 "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
109 "sounds"
110 0) steam metal
111 1) wooden clunk
112 2) metallic click
113 3) in-out
114 */
115 void spawnfunc_func_button()
116 {
117         SetMovedir ();
118
119         if (!InitMovingBrushTrigger())
120                 return;
121         self.effects |= EF_LOWPRECISION;
122
123         self.blocked = button_blocked;
124         self.use = button_use;
125
126 //      if (self.health == 0) // all buttons are now shootable
127 //              self.health = 10;
128         if (self.health)
129         {
130                 self.max_health = self.health;
131                 self.event_damage = button_damage;
132                 self.takedamage = DAMAGE_YES;
133         }
134         else
135                 self.touch = button_touch;
136
137         if (!self.speed)
138                 self.speed = 40;
139         if (!self.wait)
140                 self.wait = 1;
141         if (!self.lip)
142                 self.lip = 4;
143
144     if(self.noise != "")
145         precache_sound(self.noise);
146
147         self.active = ACTIVE_ACTIVE;
148
149         self.pos1 = self.origin;
150         self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
151     self.flags |= FL_NOTARGET;
152
153         button_reset();
154 }
155 #endif