Xonotic
button.qc
Go to the documentation of this file.
1 #include "button.qh"
2 #ifdef SVQC
3 // button and multiple button
4 
5 void button_wait(entity this);
6 void button_return(entity this);
7 
8 // in case button is deactivated by a relay_deactivate while it pressed down
9 // set both fields to -1 in button_return!!
10 .float wait_remaining;
11 .float activation_time;
12 
13 void button_setactive(entity this, int astate)
14 {
15  int oldstate = this.active;
16  if (astate == ACTIVE_TOGGLE)
17  {
18  if (this.active == ACTIVE_ACTIVE)
19  this.active = ACTIVE_NOT;
20  else
21  this.active = ACTIVE_ACTIVE;
22  }
23  else
24  this.active = astate;
25 
26  if (this.active == ACTIVE_ACTIVE && oldstate == ACTIVE_NOT)
27  {
28  // button was deactivated while it was pressed
29  if (this.wait_remaining >= 0)
30  {
31  this.nextthink = this.wait_remaining + this.ltime;
32  setthink(this, button_return);
33  }
34  }
35  else if (this.active == ACTIVE_NOT && oldstate == ACTIVE_ACTIVE)
36  {
37  // check if button is in pressed state
38  if (this.activation_time >= 0)
39  {
40  this.wait_remaining = this.wait - (time - this.activation_time);
41  }
42  }
43 }
44 
45 void button_wait(entity this)
46 {
47  this.state = STATE_TOP;
48  if(this.wait >= 0)
49  {
50  this.nextthink = this.ltime + this.wait;
51  setthink(this, button_return);
52  }
53  SUB_UseTargets(this, this.enemy, NULL);
54  this.frame = 1; // use alternate textures
55 }
56 
57 void button_done(entity this)
58 {
59  this.state = STATE_BOTTOM;
60 }
61 
62 void button_return(entity this)
63 {
64  if (this.active != ACTIVE_ACTIVE)
65  {
66  return;
67  }
68  this.state = STATE_DOWN;
69  SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, button_done);
70  this.frame = 0; // use normal textures
71  if (GetResource(this, RES_HEALTH))
72  this.takedamage = DAMAGE_YES; // can be shot again
73  this.wait_remaining = -1;
74  this.activation_time = -1;
75 }
76 
77 
78 void button_blocked(entity this, entity blocker)
79 {
80  // do nothing, just don't come all the way back out
81 }
82 
83 
84 void button_fire(entity this)
85 {
87  this.takedamage = DAMAGE_NO; // will be reset upon return
88 
89  if (this.state == STATE_UP || this.state == STATE_TOP)
90  return;
91 
92  this.activation_time = time;
93 
94  if (this.noise != "")
95  _sound (this, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
96 
97  this.state = STATE_UP;
98  SUB_CalcMove (this, this.pos2, TSPEED_LINEAR, this.speed, button_wait);
99 }
100 
101 void button_reset(entity this)
102 {
104  setorigin(this, this.pos1);
105  this.frame = 0; // use normal textures
106  this.state = STATE_BOTTOM;
107  this.velocity = '0 0 0';
108  this.wait_remaining = -1;
109  this.activation_time = -1;
110  this.active = ACTIVE_ACTIVE;
111  setthink(this, func_null);
112  this.nextthink = 0;
113  if (GetResource(this, RES_HEALTH))
114  this.takedamage = DAMAGE_YES; // can be shot again
115 }
116 
117 void button_use(entity this, entity actor, entity trigger)
118 {
119  if(this.active != ACTIVE_ACTIVE)
120  return;
121 
122  this.enemy = actor;
123  button_fire(this);
124 }
125 
126 void button_touch(entity this, entity toucher)
127 {
128  if (this.active != ACTIVE_ACTIVE)
129  return;
130  if (!toucher)
131  return;
132  if (!toucher.iscreature)
133  return;
134  if(toucher.velocity * this.movedir < 0)
135  return;
136  this.enemy = toucher;
137  if (toucher.owner)
138  this.enemy = toucher.owner;
139  button_fire (this);
140 }
141 
142 void button_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
143 {
144  if (this.active != ACTIVE_ACTIVE)
145  return;
146  if(this.spawnflags & NOSPLASH)
147  if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
148  return;
150  {
151  if (GetResource(this, RES_HEALTH) <= damage)
152  {
153  this.enemy = attacker;
154  button_fire(this);
155  }
156  }
157  else
158  {
159  TakeResource(this, RES_HEALTH, damage);
160  if (GetResource(this, RES_HEALTH) <= 0)
161  {
162  this.enemy = attacker;
163  button_fire(this);
164  }
165  }
166 }
167 
168 
169 /*QUAKED spawnfunc_func_button (0 .5 .8) ?
170 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.
171 
172 "angle" determines the opening direction
173 "target" all entities with a matching targetname will be used
174 "speed" override the default 40 speed
175 "wait" override the default 1 second wait (-1 = never return)
176 "lip" override the default 4 pixel lip remaining at end of move
177 "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
178 "noise" sound that is played when the button is activated
179 */
180 spawnfunc(func_button)
181 {
182  SetMovedir(this);
183 
184  if (!InitMovingBrushTrigger(this))
185  return;
186  this.effects |= EF_LOWPRECISION;
187 
188  setblocked(this, button_blocked);
189  this.use = button_use;
190 
191 // if (this.health == 0) // all buttons are now shootable
192 // this.health = 10;
193  if (GetResource(this, RES_HEALTH))
194  {
195  this.max_health = GetResource(this, RES_HEALTH);
196  this.event_damage = button_damage;
197  this.takedamage = DAMAGE_YES;
198  }
199  else
200  settouch(this, button_touch);
201 
202  if (!this.speed)
203  this.speed = 40;
204  if (!this.wait)
205  this.wait = 1;
206  if (!this.lip)
207  this.lip = 4;
208 
209  if(this.wait < 0 && q3compat)
210  this.wait = 0.1; // compatibility for q3: -1 = return immediately
211 
212  if(this.noise != "")
213  precache_sound(this.noise);
214 
215  this.draggable = drag_undraggable;
216 
217  this.setactive = button_setactive;
218 
219  this.pos1 = this.origin;
220  this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
221  this.flags |= FL_NOTARGET;
222 
223  this.reset = button_reset;
224 
225  button_reset(this);
226 }
227 #endif
const int HITTYPE_SPLASH
automatically set by RadiusDamage
Definition: all.qh:27
float state
Definition: subs.qh:32
const int NOSPLASH
Definition: defs.qh:12
float speed
Definition: subs.qh:41
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Definition: cl_resources.qc:15
string noise
Definition: progsdefs.qc:209
const int ACTIVE_TOGGLE
Definition: defs.qh:40
entity() spawn
#define STATE_TOP
Definition: sys-pre.qh:30
const int TSPEED_LINEAR
Definition: subs.qh:71
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition: triggers.qc:366
spawnfunc(info_player_attacker)
Definition: sv_assault.qc:283
origin
Definition: ent_cs.qc:114
vector size
Definition: csprogsdefs.qc:114
float ltime
Definition: progsdefs.qc:107
float effects
Definition: csprogsdefs.qc:111
#define STATE_DOWN
Definition: sys-pre.qh:33
void SUB_CalcMove(entity this, vector tdest, float tspeedtype, float tspeed, void(entity this) func)
Definition: subs.qc:256
float spawnflags
Definition: progsdefs.qc:191
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
Definition: cl_resources.qc:31
RES_HEALTH
Definition: ent_cs.qc:126
int q3compat
Definition: quake3.qh:3
vector movedir
Definition: progsdefs.qc:203
entity enemy
Definition: sv_ctf.qh:143
const int CH_TRIGGER
Definition: sound.qh:12
float wait
Definition: subs.qh:39
const int ACTIVE_ACTIVE
Definition: defs.qh:37
#define NULL
Definition: post.qh:17
float max_health
const float VOL_BASE
Definition: sound.qh:36
float takedamage
Definition: progsdefs.qc:147
const float ATTEN_NORM
Definition: sound.qh:30
float nextthink
Definition: csprogsdefs.qc:121
#define STATE_UP
Definition: sys-pre.qh:32
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
float flags
Definition: csprogsdefs.qc:129
float lip
Definition: subs.qh:40
#define _sound(e, c, s, v, a)
Definition: sound.qh:50
bool drag_undraggable(entity draggee, entity dragger)
Definition: cheats.qc:897
int active
Definition: defs.qh:34
vector pos1
Definition: subs.qh:50
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition: anim.qh:6
setorigin(ent, v)
#define setthink(e, f)
#define use
Definition: csprogsdefs.qh:50
float FL_NOTARGET
Definition: progsdefs.qc:238
#define DEATH_ISSPECIAL(t)
Definition: all.qh:35
const int ACTIVE_NOT
Definition: defs.qh:36
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
vector pos2
Definition: subs.qh:50
float DAMAGE_NO
Definition: progsdefs.qc:282
float EF_LOWPRECISION
var void func_null()
const int BUTTON_DONTACCUMULATEDMG
Definition: button.qh:4
float DAMAGE_YES
Definition: progsdefs.qc:283
#define STATE_BOTTOM
Definition: sys-pre.qh:31