3 // button and multiple button
5 void button_wait(entity this);
6 void button_return(entity this);
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;
13 void button_setactive(entity this, int astate)
15 int oldstate = this.active;
16 if (astate == ACTIVE_TOGGLE)
18 if (this.active == ACTIVE_ACTIVE)
19 this.active = ACTIVE_NOT;
21 this.active = ACTIVE_ACTIVE;
26 if (this.active == ACTIVE_ACTIVE && oldstate == ACTIVE_NOT)
28 // button was deactivated while it was pressed
29 if (this.wait_remaining >= 0)
31 this.nextthink = this.wait_remaining + this.ltime;
32 setthink(this, button_return);
35 else if (this.active == ACTIVE_NOT && oldstate == ACTIVE_ACTIVE)
37 // check if button is in pressed state
38 if (this.activation_time >= 0)
40 this.wait_remaining = this.wait - (time - this.activation_time);
45 void button_wait(entity this)
47 this.state = STATE_TOP;
50 this.nextthink = this.ltime + this.wait;
51 setthink(this, button_return);
53 SUB_UseTargets(this, this.enemy, NULL);
54 this.frame = 1; // use alternate textures
57 void button_done(entity this)
59 this.state = STATE_BOTTOM;
62 void button_return(entity this)
64 if (this.active != ACTIVE_ACTIVE)
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 (GetResourceAmount(this, RESOURCE_HEALTH))
72 this.takedamage = DAMAGE_YES; // can be shot again
73 this.wait_remaining = -1;
74 this.activation_time = -1;
78 void button_blocked(entity this, entity blocker)
80 // do nothing, just don't come all the way back out
84 void button_fire(entity this)
86 SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
87 this.takedamage = DAMAGE_NO; // will be reset upon return
89 if (this.state == STATE_UP || this.state == STATE_TOP)
92 this.activation_time = time;
95 _sound (this, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
97 this.state = STATE_UP;
98 SUB_CalcMove (this, this.pos2, TSPEED_LINEAR, this.speed, button_wait);
101 void button_reset(entity this)
103 SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
104 setorigin(this, this.pos1);
105 this.frame = 0; // use normal textures
106 this.state = STATE_BOTTOM;
107 this.velocity = '0 0 0';
108 setthink(this, func_null);
110 if (GetResourceAmount(this, RESOURCE_HEALTH))
111 this.takedamage = DAMAGE_YES; // can be shot again
114 void button_use(entity this, entity actor, entity trigger)
116 if(this.active != ACTIVE_ACTIVE)
123 void button_touch(entity this, entity toucher)
125 if (this.active != ACTIVE_ACTIVE)
129 if (!toucher.iscreature)
131 if(toucher.velocity * this.movedir < 0)
133 this.enemy = toucher;
135 this.enemy = toucher.owner;
139 void button_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
141 if (this.active != ACTIVE_ACTIVE)
143 if(this.spawnflags & NOSPLASH)
144 if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
146 if (this.spawnflags & BUTTON_DONTACCUMULATEDMG)
148 if (GetResourceAmount(this, RESOURCE_HEALTH) <= damage)
150 this.enemy = attacker;
156 TakeResource(this, RESOURCE_HEALTH, damage);
157 if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
159 this.enemy = attacker;
166 /*QUAKED spawnfunc_func_button (0 .5 .8) ?
167 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.
169 "angle" determines the opening direction
170 "target" all entities with a matching targetname will be used
171 "speed" override the default 40 speed
172 "wait" override the default 1 second wait (-1 = never return)
173 "lip" override the default 4 pixel lip remaining at end of move
174 "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
175 "noise" sound that is played when the button is activated
177 spawnfunc(func_button)
181 if (!InitMovingBrushTrigger(this))
183 this.effects |= EF_LOWPRECISION;
185 setblocked(this, button_blocked);
186 this.use = button_use;
188 // if (this.health == 0) // all buttons are now shootable
190 if (GetResourceAmount(this, RESOURCE_HEALTH))
192 this.max_health = GetResourceAmount(this, RESOURCE_HEALTH);
193 this.event_damage = button_damage;
194 this.takedamage = DAMAGE_YES;
197 settouch(this, button_touch);
206 this.wait_remaining = -1;
207 this.activation_time = -1;
210 precache_sound(this.noise);
212 this.active = ACTIVE_ACTIVE;
213 this.draggable = drag_undraggable;
215 this.setactive = button_setactive;
217 this.pos1 = this.origin;
218 this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
219 this.flags |= FL_NOTARGET;
221 this.reset = button_reset;