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