Xonotic
spiderbot.qc
Go to the documentation of this file.
1 #include "spiderbot.qh"
2 
3 #if defined(SVQC)
5 #endif
6 
7 #ifdef GAMEQC
8 
9 const int SBRM_FIRST = 1;
10 const int SBRM_VOLLY = 1;
11 const int SBRM_GUIDE = 2;
12 const int SBRM_ARTILLERY = 3;
13 const int SBRM_LAST = 3;
14 
15 #ifdef SVQC
16 bool autocvar_g_vehicle_spiderbot = true;
17 
18 float autocvar_g_vehicle_spiderbot_respawntime = 45;
19 
20 float autocvar_g_vehicle_spiderbot_speed_stop = 50;
21 float autocvar_g_vehicle_spiderbot_speed_strafe = 400;
22 float autocvar_g_vehicle_spiderbot_speed_walk = 500;
23 float autocvar_g_vehicle_spiderbot_speed_run = 700;
24 float autocvar_g_vehicle_spiderbot_turnspeed = 90;
25 float autocvar_g_vehicle_spiderbot_turnspeed_strafe = 300;
26 float autocvar_g_vehicle_spiderbot_movement_inertia = 0.15;
27 
28 float autocvar_g_vehicle_spiderbot_springlength = 150;
29 float autocvar_g_vehicle_spiderbot_springup = 20;
30 float autocvar_g_vehicle_spiderbot_springblend = 0.1;
31 float autocvar_g_vehicle_spiderbot_tiltlimit = 90;
32 
33 float autocvar_g_vehicle_spiderbot_head_pitchlimit_down = -20;
34 float autocvar_g_vehicle_spiderbot_head_pitchlimit_up = 30;
35 float autocvar_g_vehicle_spiderbot_head_turnlimit = 90;
36 float autocvar_g_vehicle_spiderbot_head_turnspeed = 110;
37 
38 int autocvar_g_vehicle_spiderbot_health = 800;
39 float autocvar_g_vehicle_spiderbot_health_regen = 10;
40 float autocvar_g_vehicle_spiderbot_health_regen_pause = 5;
41 
42 int autocvar_g_vehicle_spiderbot_shield = 200;
43 float autocvar_g_vehicle_spiderbot_shield_regen = 25;
44 float autocvar_g_vehicle_spiderbot_shield_regen_pause = 0.35;
45 
46 // 'minspeed_for_pain speedchange_to_pain_factor max_damage'
47 vector autocvar_g_vehicle_spiderbot_bouncepain = '0 0 0';
48 
49 .float jump_delay;
50 bool spiderbot_frame(entity this, float dt)
51 {
52  entity vehic = this.vehicle;
53  return = true;
54 
55  if(game_stopped)
56  {
57  vehic.solid = SOLID_NOT;
58  vehic.takedamage = DAMAGE_NO;
60  return;
61  }
62 
63  vehicles_frame(vehic, this);
64 
65  PHYS_INPUT_BUTTON_ZOOM(this) = false;
66  PHYS_INPUT_BUTTON_CROUCH(this) = false;
67  for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
68  {
69  .entity weaponentity = weaponentities[slot];
70  this.(weaponentity).m_switchweapon = WEP_Null;
71  }
72  STAT(VEHICLESTAT_W2MODE, this) = STAT(VEHICLESTAT_W2MODE, vehic);
73 
74 
75 #if 1 // 0 to enable per-gun impact aux crosshairs
76  // Avarage gun impact point's -> aux cross
77  vector ad = gettaginfo(vehic.tur_head, gettagindex(vehic.tur_head, "tag_hardpoint01"));
78  vector vf = v_forward;
79  ad += gettaginfo(vehic.tur_head, gettagindex(vehic.tur_head, "tag_hardpoint02"));
80  vf += v_forward;
81  ad = ad * 0.5;
82  v_forward = vf * 0.5;
83  traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
84  UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 0);
85 #else
86  vector ad = gettaginfo(vehic.gun1, gettagindex(vehic.gun1, "barrels"));
87  traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
88  UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 0);
89  vector vf = ad;
90  ad = gettaginfo(vehic.gun2, gettagindex(vehic.gun2, "barrels"));
91  traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
92  UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 1);
93  ad = 0.5 * (ad + vf);
94 #endif
95 
96  crosshair_trace(this);
99  ad = AnglesTransform_Normalize(ad, true);
100  //UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload2) + ('0 1 0' * (1 - this.vehicle_reload2)), 2);
101 
102  // Rotate head
103  float ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * PHYS_INPUT_FRAMETIME;
104  ad_y = bound(-ftmp, ad_y, ftmp);
105  vehic.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, vehic.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit);
106 
107  // Pitch head
108  ad_x = bound(ftmp * -1, ad_x, ftmp);
109  vehic.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, vehic.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up);
110 
111 
112  //fixedmakevectors(vehic.angles);
113  makevectors(vehic.angles + '-2 0 0' * vehic.angles_x);
114 
115  movelib_groundalign4point(vehic, autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit);
116 
117  if(IS_ONGROUND(vehic))
118  vehic.jump_delay = time; // reset now so movement can begin
119 
120  //if(IS_ONGROUND(vehic))
121  {
122  if(IS_ONGROUND(vehic))
123  if(vehic.frame == 4 && vehic.tur_head.wait != 0)
124  {
125  sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_LAND, VOL_VEHICLEENGINE, ATTEN_NORM);
126  vehic.frame = 5;
127  }
128 
129  if (!PHYS_INPUT_BUTTON_JUMP(this))
130  vehic.button2 = false;
131 
132  if((IS_ONGROUND(vehic)) && PHYS_INPUT_BUTTON_JUMP(this) && !vehic.button2 && vehic.tur_head.wait < time)
133  {
134  sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_JUMP, VOL_VEHICLEENGINE, ATTEN_NORM);
135  //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n");
136  vehic.delay = 0;
137 
138  vehic.tur_head.wait = time + 2;
139  vehic.jump_delay = time + 2;
140  vehic.button2 = true; // set spider's jump
141  //PHYS_INPUT_BUTTON_JUMP(this) = false;
142 
143  vector movefix = '0 0 0';
144  if(CS(this).movement_x > 0) movefix_x = 1;
145  if(CS(this).movement_x < 0) movefix_x = -1;
146  if(CS(this).movement_y > 0) movefix_y = 1;
147  if(CS(this).movement_y < 0) movefix_y = -1;
148 
149  vector rt = movefix_y * v_right;
150  vector sd = movefix_x * v_forward;
151  if(movefix_y == 0 && movefix_x == 0)
152  sd = v_forward; // always do forward
153 
154  UNSET_ONGROUND(vehic);
155 
156  vehic.velocity = sd * 700 + rt * 600 + v_up * 600;
157  vehic.frame = 4;
158  }
159  else if(time >= vehic.jump_delay)
160  {
161  if(!CS(this).movement)
162  {
163  if(IS_ONGROUND(vehic))
164  {
165  if(vehic.sound_nexttime < time || vehic.delay != 3)
166  {
167  vehic.delay = 3;
168  vehic.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav");
169  //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n");
170  sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_IDLE, VOL_VEHICLEENGINE, ATTEN_NORM);
171  }
172  movelib_brake_simple(vehic, autocvar_g_vehicle_spiderbot_speed_stop);
173  vehic.frame = 5;
174  }
175  }
176  else
177  {
178  // Turn Body
179  if(CS(this).movement_x == 0 && CS(this).movement_y != 0)
180  ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * PHYS_INPUT_FRAMETIME;
181  else
182  ftmp = autocvar_g_vehicle_spiderbot_turnspeed * PHYS_INPUT_FRAMETIME;
183 
184  ftmp = bound(-ftmp, vehic.tur_head.angles_y, ftmp);
185  vehic.angles_y = anglemods(vehic.angles_y + ftmp);
186  vehic.tur_head.angles_y -= ftmp;
187 
188  if(CS(this).movement_x != 0)
189  {
190  if(CS(this).movement_x > 0)
191  {
192  CS(this).movement_x = 1;
193  if(IS_ONGROUND(vehic))
194  vehic.frame = 0;
195  }
196  else if(CS(this).movement_x < 0)
197  {
198  CS(this).movement_x = -1;
199  if(IS_ONGROUND(vehic))
200  vehic.frame = 1;
201  }
202  CS(this).movement_y = 0;
203  float oldvelz = vehic.velocity_z;
204  movelib_move_simple(vehic, normalize(v_forward * CS(this).movement_x),((PHYS_INPUT_BUTTON_JUMP(this)) ? autocvar_g_vehicle_spiderbot_speed_run : autocvar_g_vehicle_spiderbot_speed_walk),autocvar_g_vehicle_spiderbot_movement_inertia);
205  vehic.velocity_z = oldvelz;
206  float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1);
207  if(vehic.velocity_z <= 20) // not while jumping
208  vehic.velocity_z -= g * PHYS_INPUT_FRAMETIME * autocvar_sv_gravity;
209  if(IS_ONGROUND(vehic))
210  if(vehic.sound_nexttime < time || vehic.delay != 1)
211  {
212  vehic.delay = 1;
213  vehic.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav");
214  sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_WALK, VOL_VEHICLEENGINE, ATTEN_NORM);
215  //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n");
216  }
217  }
218  else if(CS(this).movement_y != 0)
219  {
220  if(CS(this).movement_y < 0)
221  {
222  CS(this).movement_y = -1;
223  if(IS_ONGROUND(vehic))
224  vehic.frame = 2;
225  }
226  else if(CS(this).movement_y > 0)
227  {
228  CS(this).movement_y = 1;
229  if(IS_ONGROUND(vehic))
230  vehic.frame = 3;
231  }
232 
233  float oldvelz = vehic.velocity_z;
234  movelib_move_simple(vehic, normalize(v_right * CS(this).movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
235  vehic.velocity_z = oldvelz;
236  float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1);
237  if(vehic.velocity_z <= 20) // not while jumping
238  vehic.velocity_z -= g * PHYS_INPUT_FRAMETIME * autocvar_sv_gravity;
239  if(IS_ONGROUND(vehic))
240  if(vehic.sound_nexttime < time || vehic.delay != 2)
241  {
242  vehic.delay = 2;
243  vehic.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav");
244  sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_STRAFE, VOL_VEHICLEENGINE, ATTEN_NORM);
245  //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n");
246  }
247  }
248  }
249  }
250  }
251 
252  vehic.angles_x = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, vehic.angles_x, autocvar_g_vehicle_spiderbot_tiltlimit);
253  vehic.angles_z = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, vehic.angles_z, autocvar_g_vehicle_spiderbot_tiltlimit);
254 
255  if(!weaponLocked(this) && !weaponUseForbidden(this))
256  if(PHYS_INPUT_BUTTON_ATCK(this))
257  {
258  vehic.cnt = time;
259  if(vehic.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && vehic.tur_head.attack_finished_single[0] <= time)
260  {
261  entity gun;
262  vector v;
263  vehic.misc_bulletcounter += 1;
264 
265  gun = (vehic.misc_bulletcounter % 2) ? vehic.gun1 : vehic.gun2;
266 
267  v = gettaginfo(gun, gettagindex(gun, "barrels"));
268  v_forward = normalize(v_forward);
269  v += v_forward * 50;
270 
271  .entity weaponentity = weaponentities[0]; // TODO: unhardcode
272  fireBullet(this, weaponentity, v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_solidpenetration,
273  autocvar_g_vehicle_spiderbot_minigun_damage, 0, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN.m_id, EFFECT_BULLET);
274 
275  sound (gun, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
276  //trailparticles(this, _particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
277  Send_Effect(EFFECT_SPIDERBOT_MINIGUN_MUZZLEFLASH, v, v_forward * 2500, 1);
278 
279  vehic.vehicle_ammo1 -= autocvar_g_vehicle_spiderbot_minigun_ammo_cost;
280  vehic.tur_head.attack_finished_single[0] = time + autocvar_g_vehicle_spiderbot_minigun_refire;
281  this.vehicle_ammo1 = (vehic.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100;
282  vehic.gun1.angles_z += 45;
283  vehic.gun2.angles_z -= 45;
284  if(vehic.gun1.angles_z >= 360)
285  {
286  vehic.gun1.angles_z = 0;
287  vehic.gun2.angles_z = 0;
288  }
289  }
290  }
291  else
292  vehicles_regen(vehic, vehic.cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max,
293  autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause,
294  autocvar_g_vehicle_spiderbot_minigun_ammo_regen, dt, false);
295 
296 
297  spiderbot_rocket_do(vehic);
298 
299  if(vehic.vehicle_flags & VHF_SHIELDREGEN)
300  vehicles_regen(vehic, vehic.dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, dt, true);
301 
302  if(vehic.vehicle_flags & VHF_HEALTHREGEN)
303  vehicles_regen_resource(vehic, vehic.dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, dt, false, RES_HEALTH);
304 
305  PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
306  //this.vehicle_ammo2 = vehic.tur_head.frame;
307  this.vehicle_ammo2 = (9 - vehic.tur_head.frame) / 8 * 100; // Percentage, like ammo1
308 
309  if(vehic.gun2.cnt <= time)
310  this.vehicle_reload2 = 100;
311  else
312  this.vehicle_reload2 = 100 - ((vehic.gun2.cnt - time) / vehic.attack_finished_single[0]) * 100;
313 
314  setorigin(this, vehic.origin + '0 0 1' * vehic.maxs_z);
315  this.oldorigin = this.origin; // negate fall damage
316  this.velocity = vehic.velocity;
317 
318  VEHICLE_UPDATE_PLAYER_RESOURCE(this, vehic, health, spiderbot, RES_HEALTH);
319 
320  if(vehic.vehicle_flags & VHF_HASSHIELD)
321  VEHICLE_UPDATE_PLAYER(this, vehic, shield, spiderbot);
322 }
323 
324 void spiderbot_exit(entity this, int eject)
325 {
326  entity player = this.owner;
327 
328  IL_EACH(g_projectiles, it.owner == player && it.classname == "spiderbot_rocket",
329  {
330  it.realowner = player;
331  it.owner = NULL;
332  });
333 
334  setthink(this, vehicles_think);
335  this.nextthink = time;
336  this.frame = 5;
338 
339  if(!player)
340  {
341  this.owner = NULL; // reset owner anyway?
342  return;
343  }
344 
345  makevectors(this.angles);
346  vector spot;
347  if(eject)
348  {
349  spot = this.origin + v_forward * 100 + '0 0 64';
350  spot = vehicles_findgoodexit(this, player, spot);
351  setorigin(player, spot);
352  player.velocity = (v_up + v_forward * 0.25) * 750;
353  player.oldvelocity = player.velocity;
354  }
355  else
356  {
357  if(vdist(this.velocity, >, autocvar_g_vehicle_spiderbot_speed_strafe))
358  {
359  player.velocity = normalize(this.velocity) * vlen(this.velocity);
360  player.velocity_z += 200;
361  spot = this.origin + v_forward * 128 + '0 0 64';
362  spot = vehicles_findgoodexit(this, player, spot);
363  }
364  else
365  {
366  player.velocity = this.velocity * 0.5;
367  player.velocity_z += 10;
368  spot = this.origin + v_forward * 256 + '0 0 64';
369  spot = vehicles_findgoodexit(this, player, spot);
370  }
371  player.oldvelocity = player.velocity;
372  setorigin(player, spot);
373  }
374 
375  antilag_clear(player, CS(player));
376  this.owner = NULL;
377 }
378 
379 void spiderbot_headfade(entity this)
380 {
381  setthink(this, spiderbot_headfade);
382  this.nextthink = this.fade_time;
383  this.alpha = 1 - (time - this.fade_time) * this.fade_rate;
384 
385  if(this.cnt < time || this.alpha < 0.1)
386  {
387  if(this.alpha > 0.1)
388  {
389  sound (this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
390  Send_Effect(EFFECT_EXPLOSION_BIG, this.origin + '0 0 100', '0 0 0', 1);
391  }
392  delete(this);
393  }
394 }
395 
396 void spiderbot_blowup(entity this)
397 {
398  if(this.cnt > time)
399  {
400  if(random() < 0.1)
401  {
402  sound (this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
403  Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (this.origin + '0 0 100'), '0 0 0', 1);
404  }
405  this.nextthink = time + 0.1;
406  return;
407  }
408 
409  entity h = new(spiderbot_top), g1 = new(spiderbot_gun), g2 = new(spiderbot_gun), b = new(spiderbot_body);
410 
411  setmodel(b, MDL_VEH_SPIDERBOT_BODY);
412  setmodel(h, MDL_VEH_SPIDERBOT_TOP);
413  setmodel(g1, MDL_VEH_SPIDERBOT_GUN);
414  setmodel(g2, MDL_VEH_SPIDERBOT_GUN);
415 
416  setorigin(b, this.origin);
417  b.frame = 11;
418  b.angles = this.angles;
419  setsize(b, this.mins, this.maxs);
420 
421  vector org = gettaginfo(this, gettagindex(this, "tag_head"));
422  setorigin(h, org);
424  h.solid = SOLID_BBOX;
425  h.velocity = v_up * (500 + random() * 500) + randomvec() * 128;
426  h.modelflags = MF_ROCKET;
427  h.effects = EF_FLAME | EF_LOWPRECISION;
428  h.avelocity = randomvec() * 360;
429 
430  h.alpha = 1;
431  h.cnt = time + (3.5 * random());
432  h.fade_rate = 1 / min(this.respawntime, 10);
433  h.fade_time = time;
434  setthink(h, spiderbot_headfade);
435  h.nextthink = time;
436 
437  org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint01"));
438  setorigin(g1, org);
440  g1.solid = SOLID_CORPSE;
441  g1.velocity = v_forward * 700 + (randomvec() * 32);
442  g1.avelocity = randomvec() * 180;
443 
444  org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint02"));
445  setorigin(g2, org);
447  g2.solid = SOLID_CORPSE;
448  g2.velocity = v_forward * 700 + (randomvec() * 32);
449  g2.avelocity = randomvec() * 180;
450 
451  h.colormod = b.colormod = g1.colormod = g2.colormod = '-2 -2 -2';
452 
453  SUB_SetFade(b, time + 5, min(this.respawntime, 1));
454  //SUB_SetFade(h, time, min(this.respawntime, 10));
455  SUB_SetFade(g1, time, min(this.respawntime, 10));
456  SUB_SetFade(g2, time, min(this.respawntime, 10));
457 
458  RadiusDamage (this, this.enemy, 250, 15, 250, NULL, NULL, 250, DEATH_VH_SPID_DEATH.m_id, DMG_NOWEP, NULL);
459 
460  this.alpha = this.tur_head.alpha = this.gun1.alpha = this.gun2.alpha = -1;
462  this.deadflag = DEAD_DEAD;
463  this.solid = SOLID_NOT;
464  this.tur_head.effects &= ~EF_FLAME;
465  this.vehicle_hudmodel.viewmodelforclient = this;
466 }
467 
468 bool spiderbot_impulse(entity this, int _imp)
469 {
470  switch(_imp)
471  {
472  case IMP_weapon_group_1.impulse:
473  STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_VOLLY;
474  CSQCVehicleSetup(this, 0);
475  return true;
476  case IMP_weapon_group_2.impulse:
477  STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_GUIDE;
478  CSQCVehicleSetup(this, 0);
479  return true;
480  case IMP_weapon_group_3.impulse:
481  STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_ARTILLERY;
482  CSQCVehicleSetup(this, 0);
483  return true;
484 
485  case IMP_weapon_next_byid.impulse:
486  case IMP_weapon_next_bypriority.impulse:
487  case IMP_weapon_next_bygroup.impulse:
488  STAT(VEHICLESTAT_W2MODE, this.vehicle) += 1;
489  if(STAT(VEHICLESTAT_W2MODE, this.vehicle) > SBRM_LAST)
490  STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_FIRST;
491 
492  //centerprint(this, strcat("Rocket mode is ", ftos(STAT(VEHICLESTAT_W2MODE, this.vehicle))));
493  CSQCVehicleSetup(this, 0);
494  return true;
495  case IMP_weapon_last.impulse:
496  case IMP_weapon_prev_byid.impulse:
497  case IMP_weapon_prev_bypriority.impulse:
498  case IMP_weapon_prev_bygroup.impulse:
499  STAT(VEHICLESTAT_W2MODE, this.vehicle) -= 1;
500  if(STAT(VEHICLESTAT_W2MODE, this.vehicle) < SBRM_FIRST)
501  STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_LAST;
502 
503  //centerprint(this, strcat("Rocket mode is ", ftos(STAT(VEHICLESTAT_W2MODE, this.vehicle))));
504  CSQCVehicleSetup(this, 0);
505  return true;
506 
507  /*
508  case IMP_weapon_drop.impulse: // toss gun, could be used to exit?
509  break;
510  case IMP_weapon_reload.impulse: // Manual minigun reload?
511  break;
512  */
513  }
514  return false;
515 }
516 
517 spawnfunc(vehicle_spiderbot)
518 {
519  if(!autocvar_g_vehicle_spiderbot) { delete(this); return; }
520  if(!vehicle_initialize(this, VEH_SPIDERBOT, false)) { delete(this); return; }
521 }
522 
523 METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance))
524 {
525  if(autocvar_g_vehicle_spiderbot_bouncepain)
526  vehicles_impact(instance, autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z);
527 }
528 METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance))
529 {
530  STAT(VEHICLESTAT_W2MODE, instance) = SBRM_GUIDE;
531  set_movetype(instance, MOVETYPE_WALK);
532  CSQCVehicleSetup(instance.owner, 0);
533  instance.owner.vehicle_health = (GetResource(instance, RES_HEALTH) / autocvar_g_vehicle_spiderbot_health) * 100;
534  instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100;
535 
536  if(instance.owner.flagcarried)
537  {
538  setattachment(instance.owner.flagcarried, instance.tur_head, "");
539  setorigin(instance.owner.flagcarried, '-20 0 120');
540  }
541 }
542 METHOD(Spiderbot, vr_think, void(Spiderbot thisveh, entity instance))
543 {
544  if(IS_ONGROUND(instance))
545  movelib_brake_simple(instance, autocvar_g_vehicle_spiderbot_speed_stop);
546 }
547 METHOD(Spiderbot, vr_death, void(Spiderbot thisveh, entity instance))
548 {
549  SetResourceExplicit(instance, RES_HEALTH, 0);
550  instance.event_damage = func_null;
551  instance.takedamage = DAMAGE_NO;
552  settouch(instance, func_null);
553  instance.cnt = 3.4 + time + random() * 2;
554  setthink(instance, spiderbot_blowup);
555  instance.nextthink = time;
556  instance.deadflag = DEAD_DYING;
557  instance.frame = 5;
558  instance.tur_head.effects |= EF_FLAME;
559  instance.colormod = instance.tur_head.colormod = '-1 -1 -1';
560  instance.frame = 10;
561  set_movetype(instance, MOVETYPE_TOSS);
562 
563  CSQCModel_UnlinkEntity(instance); // networking the death scene would be a nightmare
564 }
565 METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance))
566 {
567  if(!instance.gun1)
568  {
569  instance.vehicles_impulse = spiderbot_impulse;
570  instance.gun1 = new(spiderbot_gun);
571  instance.gun2 = new(spiderbot_gun);
572  setmodel(instance.gun1, MDL_VEH_SPIDERBOT_GUN);
573  setmodel(instance.gun2, MDL_VEH_SPIDERBOT_GUN);
574  setattachment(instance.gun1, instance.tur_head, "tag_hardpoint01");
575  setattachment(instance.gun2, instance.tur_head, "tag_hardpoint02");
576  instance.gravity = 2;
577  instance.mass = 5000;
578  }
579 
580  instance.frame = 5;
581  instance.tur_head.frame = 1;
582  set_movetype(instance, MOVETYPE_WALK);
583  instance.solid = SOLID_SLIDEBOX;
584  instance.alpha = instance.tur_head.alpha = instance.gun1.alpha = instance.gun2.alpha = 1;
585  instance.tur_head.angles = '0 0 0';
586  instance.vehicle_exit = spiderbot_exit;
587 
588  setorigin(instance, instance.pos1 + '0 0 128');
589  instance.angles = instance.pos2;
590  instance.damageforcescale = 0.03;
591  SetResourceExplicit(instance, RES_HEALTH, autocvar_g_vehicle_spiderbot_health);
592  instance.vehicle_shield = autocvar_g_vehicle_spiderbot_shield;
593 
594  instance.PlayerPhysplug = spiderbot_frame;
595 }
596 METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
597 {
598  if(autocvar_g_vehicle_spiderbot_shield)
599  instance.vehicle_flags |= VHF_HASSHIELD;
600 
601  if(autocvar_g_vehicle_spiderbot_shield_regen)
602  instance.vehicle_flags |= VHF_SHIELDREGEN;
603 
604  if(autocvar_g_vehicle_spiderbot_health_regen)
605  instance.vehicle_flags |= VHF_HEALTHREGEN;
606 
607  instance.respawntime = autocvar_g_vehicle_spiderbot_respawntime;
608  SetResourceExplicit(instance, RES_HEALTH, autocvar_g_vehicle_spiderbot_health);
609  instance.vehicle_shield = autocvar_g_vehicle_spiderbot_shield;
610  instance.max_health = GetResource(instance, RES_HEALTH);
611  instance.pushable = true; // spiderbot can use jumppads
612 }
613 
614 #endif // SVQC
615 #ifdef CSQC
616 //float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6;
617 //float autocvar_cl_vehicle_spiderbot_cross_size = 1;
618 
619 METHOD(Spiderbot, vr_hud, void(Spiderbot thisveh))
620 {
621  Vehicles_drawHUD(VEH_SPIDERBOT.m_icon, "vehicle_spider_weapon1", "vehicle_spider_weapon2",
622  "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
623  "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color);
624 }
625 METHOD(Spiderbot, vr_crosshair, void(Spiderbot thisveh, entity player))
626 {
627  string crosshair;
628 
629  switch(weapon2mode)
630  {
631  case SBRM_VOLLY: crosshair = vCROSS_BURST; break;
632  case SBRM_GUIDE: crosshair = vCROSS_GUIDE; break;
633  case SBRM_ARTILLERY: crosshair = vCROSS_RAIN; break;
634  default: crosshair = vCROSS_BURST;
635  }
636 
637  Vehicles_drawCrosshair(crosshair);
638 }
639 METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
640 {
641  AuxiliaryXhair[0].axh_image = vCROSS_HINT; // Minigun1
642  AuxiliaryXhair[1].axh_image = vCROSS_HINT; // Minigun2
643 }
644 
645 #endif
646 
647 #endif
const float SOLID_NOT
Definition: csprogsdefs.qc:244
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition: player.qh:148
float DEAD_DYING
Definition: progsdefs.qc:275
const string vCROSS_BURST
Definition: cl_vehicles.qh:13
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition: player.qh:147
#define IL_EACH(this, cond, body)
float MOVETYPE_NONE
Definition: progsdefs.qc:246
vector AnglesTransform_ToAngles(vector v)
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition: player.qh:150
const float SOLID_SLIDEBOX
Definition: csprogsdefs.qc:247
float alpha
Definition: items.qc:14
float MOVETYPE_WALK
Definition: progsdefs.qc:249
const int VHF_HASSHIELD
Indicates vehicle.
Definition: vehicle.qh:64
void movelib_groundalign4point(entity this, float spring_length, float spring_up, float blendrate, float _max)
Definition: movelib.qc:185
void vehicles_regen_resource(entity this, float timer,.float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale, Resource resource)
Definition: sv_vehicles.qc:572
ERASEABLE float anglemods(float v)
Definition: angle.qc:13
float respawntime
Definition: items.qh:36
vector AnglesTransform_FromAngles(vector v)
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
const int MF_ROCKET
void Vehicles_drawCrosshair(string crosshair)
Definition: cl_vehicles.qc:299
const float EF_FLAME
Definition: csprogsdefs.qc:302
bool weaponUseForbidden(entity player)
const string vCROSS_RAIN
Definition: cl_vehicles.qh:19
float MOVETYPE_TOSS
Definition: progsdefs.qc:252
entity tur_head
Definition: sv_turrets.qh:29
vector oldorigin
Definition: csprogsdefs.qc:102
fade_rate
Definition: projectile.qh:14
entity() spawn
const float MOVE_NORMAL
Definition: csprogsdefs.qc:252
ClientState CS(Client this)
Definition: state.qh:47
void Vehicles_drawHUD(string vehicle, string vehicleWeapon1, string vehicleWeapon2, string iconAmmo1, vector colorAmmo1, string iconAmmo2, vector colorAmmo2)
Definition: cl_vehicles.qc:123
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
vector maxs
Definition: csprogsdefs.qc:113
#define PHYS_INPUT_BUTTON_ZOOM(s)
Definition: player.qh:149
void vehicles_regen(entity this, float timer,.float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale)
Definition: sv_vehicles.qc:557
spawnfunc(info_player_attacker)
Definition: sv_assault.qc:283
origin
Definition: ent_cs.qc:114
void antilag_clear(entity e, entity store)
Definition: antilag.qc:114
#define gettaginfo
Definition: post.qh:32
float MOVETYPE_BOUNCE
Definition: progsdefs.qc:256
#define METHOD(cname, name, prototype)
Definition: oo.qh:257
#define UNSET_ONGROUND(s)
Definition: movetypes.qh:18
#define DMG_NOWEP
Definition: damage.qh:126
entity owner
Definition: main.qh:73
#define gettagindex
Definition: dpextensions.qh:16
float DEAD_DEAD
Definition: progsdefs.qc:276
void crosshair_trace(entity pl)
Definition: tracing.qc:508
#define setmodel(this, m)
Definition: model.qh:26
void vehicles_impact(entity this, float _minspeed, float _speedfac, float _maxpain)
Definition: sv_vehicles.qc:746
RES_HEALTH
Definition: ent_cs.qc:126
bool weaponLocked(entity player)
entity enemy
Definition: sv_ctf.qh:143
vector mins
Definition: csprogsdefs.qc:113
const int VHF_SHIELDREGEN
Vehicle has shileding.
Definition: vehicle.qh:65
float cnt
Definition: powerups.qc:24
entity AuxiliaryXhair[MAX_AXH]
Definition: cl_vehicles.qh:24
const int CH_WEAPON_A
Definition: sound.qh:7
void fireBullet(entity this,.entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect)
Definition: tracing.qc:503
vector v_up
Definition: csprogsdefs.qc:31
const int MAX_WEAPONSLOTS
Definition: weapon.qh:13
void CSQCVehicleSetup(entity own, int vehicle_id)
Definition: sv_vehicles.qc:80
#define NULL
Definition: post.qh:17
void vehicles_think(entity this)
#define weapon2mode
Definition: cl_vehicles.qh:36
const float VOL_BASE
Definition: sound.qh:36
vector trace_endpos
Definition: csprogsdefs.qc:37
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition: player.qh:146
vector AnglesTransform_Normalize(vector t, float minimize_roll)
void vehicles_frame(entity this, entity actor)
Definition: sv_vehicles.qc:628
const float ATTEN_NORM
Definition: sound.qh:30
vector autocvar_hud_progressbar_vehicles_ammo1_color
Definition: cl_vehicles.qh:10
float nextthink
Definition: csprogsdefs.qc:121
const int CH_TRIGGER_SINGLE
Definition: sound.qh:13
const int CH_SHOTS
Definition: sound.qh:14
vector movement
vector(float skel, float bonenum) _skel_get_boneabs_hidden
IntrusiveList g_projectiles
Definition: common.qh:46
vector AnglesTransform_LeftDivide(vector from_transform, vector to_transform)
vector v
Definition: ent_cs.qc:116
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
float deadflag
Definition: progsdefs.qc:149
const int VHF_HEALTHREGEN
Vehicles shield regenerates.
Definition: vehicle.qh:66
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
const string vCROSS_HINT
Definition: cl_vehicles.qh:17
float fade_time
Definition: common.qh:22
float health
Definition: progsdefs.qc:137
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition: damage.qc:1057
vector v_right
Definition: csprogsdefs.qc:31
void CSQCModel_UnlinkEntity(entity e)
Definition: sv_model.qc:129
const float SOLID_BBOX
Definition: csprogsdefs.qc:246
vector autocvar_hud_progressbar_vehicles_ammo2_color
Definition: cl_vehicles.qh:11
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition: anim.qh:6
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
setorigin(ent, v)
#define setthink(e, f)
void SUB_SetFade(entity ent, float vanish_time, float fading_time)
Definition: subs.qc:77
void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
Definition: sv_vehicles.qc:47
vector angles
Definition: csprogsdefs.qc:104
#define sound(e, c, s, v, a)
Definition: sound.qh:52
entity vehicle
Definition: impulse.qc:21
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
#define makevectors
Definition: post.qh:21
const string vCROSS_GUIDE
Definition: cl_vehicles.qh:15
float DAMAGE_NO
Definition: progsdefs.qc:282
bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
void set_movetype(entity this, int mt)
float EF_LOWPRECISION
var void func_null()
vector vehicles_findgoodexit(entity this, entity player, vector prefer_spot)
Definition: sv_vehicles.qc:764
vector v_forward
Definition: csprogsdefs.qc:31
float solid
Definition: csprogsdefs.qc:99
const float SOLID_CORPSE
Definition: csprogsdefs.qc:249