Xonotic
platforms.qc
Go to the documentation of this file.
1 #include "platforms.qh"
2 
3 void generic_plat_blocked(entity this, entity blocker)
4 {
5 #ifdef SVQC
6  if(this.dmg && blocker.takedamage != DAMAGE_NO)
7  {
8  if(this.dmgtime2 < time)
9  {
10  Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
11  this.dmgtime2 = time + this.dmgtime;
12  }
13 
14  // Gib dead/dying stuff
15  if(IS_DEAD(blocker))
16  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
17  }
18 #endif
19 }
20 
22 {
23  vector tmin, tmax;
24 
25  entity trigger = spawn();
26  settouch(trigger, plat_center_touch);
27  set_movetype(trigger, MOVETYPE_NONE);
28  trigger.solid = SOLID_TRIGGER;
29  trigger.enemy = this;
30 
31  tmin = this.absmin + '25 25 0';
32  tmax = this.absmax - '25 25 -8';
33  tmin_z = tmax_z - (this.pos1_z - this.pos2_z + 8);
34  if (this.spawnflags & PLAT_LOW_TRIGGER)
35  tmax_z = tmin_z + 8;
36 
37  if (this.size_x <= 50)
38  {
39  tmin_x = (this.mins_x + this.maxs_x) / 2;
40  tmax_x = tmin_x + 1;
41  }
42  if (this.size_y <= 50)
43  {
44  tmin_y = (this.mins_y + this.maxs_y) / 2;
45  tmax_y = tmin_y + 1;
46  }
47 
48  if(tmin_x < tmax_x)
49  if(tmin_y < tmax_y)
50  if(tmin_z < tmax_z)
51  {
52  setsize (trigger, tmin, tmax);
53  return;
54  }
55 
56  // otherwise, something is fishy...
57  delete(trigger);
58  objerror(this, "plat_spawn_inside_trigger: platform has odd size or lip, can't spawn");
59 }
60 
61 void plat_hit_top(entity this)
62 {
64  this.state = STATE_TOP;
65 
66  setthink(this, plat_go_down);
67  this.nextthink = this.ltime + 3;
68 }
69 
71 {
73  this.state = STATE_BOTTOM;
74 }
75 
76 void plat_go_down(entity this)
77 {
79  this.state = STATE_DOWN;
81 }
82 
83 void plat_go_up(entity this)
84 {
86  this.state = STATE_UP;
87  SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, plat_hit_top);
88 }
89 
90 void plat_center_touch(entity this, entity toucher)
91 {
92 #ifdef SVQC
93  if (!toucher.iscreature)
94  return;
95 
96  if (GetResource(toucher, RES_HEALTH) <= 0)
97  return;
98 #elif defined(CSQC)
99  if (!IS_PLAYER(toucher))
100  return;
101  if(IS_DEAD(toucher))
102  return;
103 #endif
104 
105  if (this.enemy.state == STATE_BOTTOM) {
106  plat_go_up(this.enemy);
107  } else if (this.enemy.state == STATE_TOP)
108  this.enemy.nextthink = this.enemy.ltime + 1;
109 }
110 
111 void plat_outside_touch(entity this, entity toucher)
112 {
113 #ifdef SVQC
114  if (!toucher.iscreature)
115  return;
116 
117  if (GetResource(toucher, RES_HEALTH) <= 0)
118  return;
119 #elif defined(CSQC)
120  if (!IS_PLAYER(toucher))
121  return;
122 #endif
123 
124  if (this.enemy.state == STATE_TOP) {
125  entity e = this.enemy;
126  plat_go_down(e);
127  }
128 }
129 
130 void plat_trigger_use(entity this, entity actor, entity trigger)
131 {
132  if (getthink(this))
133  return; // already activated
134  plat_go_down(this);
135 }
136 
137 
138 void plat_crush(entity this, entity blocker)
139 {
140  if((this.spawnflags & CRUSH) && (blocker.takedamage != DAMAGE_NO))
141  { // KIll Kill Kill!!
142 #ifdef SVQC
143  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
144 #endif
145  }
146  else
147  {
148 #ifdef SVQC
149  if((this.dmg) && (blocker.takedamage != DAMAGE_NO))
150  { // Shall we bite?
151  Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
152  // Gib dead/dying stuff
153  if(IS_DEAD(blocker))
154  Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, blocker.origin, '0 0 0');
155  }
156 #endif
157 
158  if (this.state == STATE_UP)
159  plat_go_down (this);
160  else if (this.state == STATE_DOWN)
161  plat_go_up (this);
162  // when in other states, then the plat_crush event came delayed after
163  // plat state already had changed
164  // this isn't a bug per se!
165  }
166 }
167 
168 void plat_use(entity this, entity actor, entity trigger)
169 {
170  this.use = func_null;
171  if (this.state != STATE_UP)
172  objerror (this, "plat_use: not in up state");
173  plat_go_down(this);
174 }
175 
176 // WARNING: backwards compatibility because people don't use already existing fields :(
177 // TODO: Check if any maps use these fields and remove these fields if it doesn't break maps
178 .string sound1, sound2;
179 
180 void plat_reset(entity this)
181 {
182  if(this.targetname && this.targetname != "")
183  {
184  setorigin(this, this.pos1);
185  this.state = STATE_UP;
186  this.use = plat_use;
187  }
188  else
189  {
190  setorigin(this, this.pos2);
191  this.state = STATE_BOTTOM;
192  this.use = plat_trigger_use;
193  }
194 
195 #ifdef SVQC
196  this.SendFlags |= SF_TRIGGER_RESET;
197 #endif
198 }
199 
201 bool set_platmovetype(entity e, string s)
202 {
203  // sets platmovetype_start and platmovetype_end based on a string consisting of two values
204 
205  int n = tokenize_console(s);
206  if(n > 0)
207  e.platmovetype_start = stof(argv(0));
208  else
209  e.platmovetype_start = 0;
210 
211  if(n > 1)
212  e.platmovetype_end = stof(argv(1));
213  else
214  e.platmovetype_end = e.platmovetype_start;
215 
216  if(n > 2)
217  if(argv(2) == "force")
218  return true; // no checking, return immediately
219 
220  if(!cubic_speedfunc_is_sane(e.platmovetype_start, e.platmovetype_end))
221  {
222  objerror(e, "Invalid platform move type; platform would go in reverse, which is not allowed.");
223  return false;
224  }
225 
226  return true;
227 }
float state
Definition: subs.qh:32
float MOVETYPE_NONE
Definition: progsdefs.qc:246
ERASEABLE bool cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
Definition: math.qh:138
string sound2
Definition: platforms.qc:178
void plat_go_up(entity this)
Definition: platforms.qc:83
void plat_reset(entity this)
Definition: platforms.qc:180
float speed
Definition: subs.qh:41
#define getthink(e)
string noise
Definition: progsdefs.qc:209
void plat_trigger_use(entity this, entity actor, entity trigger)
Definition: platforms.qc:130
string sound1
Definition: platforms.qc:178
void plat_use(entity this, entity actor, entity trigger)
Definition: platforms.qc:168
entity() spawn
#define STATE_TOP
Definition: sys-pre.qh:30
const int TSPEED_LINEAR
Definition: subs.qh:71
bool set_platmovetype(entity e, string s)
Definition: platforms.qc:201
float dmg
Definition: platforms.qh:6
float platmovetype_end_default
Definition: platforms.qc:200
float ltime
Definition: progsdefs.qc:107
void plat_outside_touch(entity this, entity toucher)
Definition: platforms.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
#define DMG_NOWEP
Definition: damage.qh:126
void plat_crush(entity this, entity blocker)
Definition: platforms.qc:138
vector absmax
Definition: csprogsdefs.qc:92
RES_HEALTH
Definition: ent_cs.qc:126
entity enemy
Definition: sv_ctf.qh:143
void plat_hit_top(entity this)
Definition: platforms.qc:61
void plat_center_touch(entity this, entity toucher)
Definition: platforms.qc:90
const int CRUSH
Definition: defs.qh:11
float platmovetype_start_default
Definition: platforms.qc:200
const int SF_TRIGGER_RESET
Definition: defs.qh:24
string noise1
Definition: progsdefs.qc:209
const float VOL_BASE
Definition: sound.qh:36
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition: damage.qc:583
#define IS_DEAD(s)
Definition: utils.qh:26
const float ATTEN_NORM
Definition: sound.qh:30
float nextthink
Definition: csprogsdefs.qc:121
const int CH_TRIGGER_SINGLE
Definition: sound.qh:13
#define STATE_UP
Definition: sys-pre.qh:32
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define tokenize_console
Definition: dpextensions.qh:24
float dmgtime
Definition: platforms.qh:7
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
void plat_go_down(entity this)
Definition: platforms.qc:76
void plat_spawn_inside_trigger(entity this)
Definition: platforms.qc:21
#define _sound(e, c, s, v, a)
Definition: sound.qh:50
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
string targetname
Definition: progsdefs.qc:194
float dmgtime2
Definition: platforms.qh:8
void generic_plat_blocked(entity this, entity blocker)
Definition: platforms.qc:3
vector pos1
Definition: subs.qh:50
setorigin(ent, v)
#define setthink(e, f)
#define use
Definition: csprogsdefs.qh:50
vector absmin
Definition: csprogsdefs.qc:92
void plat_hit_bottom(entity this)
Definition: platforms.qc:70
float time
Definition: csprogsdefs.qc:16
vector pos2
Definition: subs.qh:50
float DAMAGE_NO
Definition: progsdefs.qc:282
void set_movetype(entity this, int mt)
#define IS_PLAYER(v)
Definition: utils.qh:9
var void func_null()
const int PLAT_LOW_TRIGGER
Definition: platforms.qh:4
#define STATE_BOTTOM
Definition: sys-pre.qh:31