Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
spiderbot.qc
Go to the documentation of this file.
1#include "spiderbot.qh"
2
3#ifdef SVQC
5#endif
6
7#ifdef GAMEQC
8
9const int SBRM_FIRST = 1;
10const int SBRM_VOLLY = 1;
11const int SBRM_GUIDE = 2;
12const int SBRM_ARTILLERY = 3;
13const int SBRM_LAST = 3;
14
15#ifdef SVQC
17
19
26
31
36
40
44
45// 'minspeed_for_pain speedchange_to_pain_factor max_damage'
47
49bool spiderbot_frame(entity this, float dt)
50{
51 entity vehic = this.vehicle;
52 return = true;
53
54 if (game_stopped)
55 {
56 vehic.solid = SOLID_NOT;
57 vehic.takedamage = DAMAGE_NO;
59 return;
60 }
61
62 vehicles_frame(vehic, this);
63
64 PHYS_INPUT_BUTTON_ZOOM(this) = false;
65 PHYS_INPUT_BUTTON_CROUCH(this) = false;
66 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
67 {
68 .entity weaponentity = weaponentities[slot];
69 this.(weaponentity).m_switchweapon = WEP_Null;
70 }
71 STAT(VEHICLESTAT_W2MODE, this) = STAT(VEHICLESTAT_W2MODE, vehic);
72
73
74#if 1 // 0 to enable per-gun impact aux crosshairs
75 // Avarage gun impact point's -> aux cross
76 vector ad = gettaginfo(vehic.tur_head, gettagindex(vehic.tur_head, "tag_hardpoint01"));
77 vector vf = v_forward;
78 ad += gettaginfo(vehic.tur_head, gettagindex(vehic.tur_head, "tag_hardpoint02"));
79 vf += v_forward;
80 ad *= 0.5;
81 v_forward = vf * 0.5;
82 traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
83 UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 0);
84#else
85 vector ad = gettaginfo(vehic.gun1, gettagindex(vehic.gun1, "barrels"));
86 traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
87 UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 0);
88 vector vf = ad;
89 ad = gettaginfo(vehic.gun2, gettagindex(vehic.gun2, "barrels"));
90 traceline(ad, ad + v_forward * max_shot_distance, MOVE_NORMAL, vehic);
91 UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload1) + ('0 1 0' * (1 - this.vehicle_reload1)), 1);
92 ad = 0.5 * (ad + vf);
93#endif
94
95 crosshair_trace(this);
98 ad = AnglesTransform_Normalize(ad, true);
99 //UpdateAuxiliaryXhair(this, trace_endpos, ('1 0 0' * this.vehicle_reload2) + ('0 1 0' * (1 - this.vehicle_reload2)), 2);
100
101 // Rotate head
103 ad.y = bound(-ftmp, ad.y, ftmp);
104 vehic.tur_head.angles.y = bound(-autocvar_g_vehicle_spiderbot_head_turnlimit, vehic.tur_head.angles.y + ad.y, autocvar_g_vehicle_spiderbot_head_turnlimit);
105
106 // Pitch head
107 ad.x = bound(-ftmp, ad.x, ftmp);
108 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);
109
110
111 //fixedmakevectors(vehic.angles);
112 makevectors(vehic.angles + '-2 0 0' * vehic.angles.x);
113
115
116 if (IS_ONGROUND(vehic))
117 vehic.jump_delay = time; // reset now so movement can begin
118
119 //if (IS_ONGROUND(vehic))
120 {
121 if (IS_ONGROUND(vehic)
122 && vehic.frame == 4 && vehic.tur_head.wait != 0)
123 {
124 sound(vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_LAND, VOL_VEHICLEENGINE, ATTEN_NORM);
125 vehic.frame = 5;
126 }
127
128 if (!PHYS_INPUT_BUTTON_JUMP(this))
129 vehic.button2 = false;
130
131 if (IS_ONGROUND(vehic) && PHYS_INPUT_BUTTON_JUMP(this)
132 && !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 }
173 vehic.frame = 5;
174 }
175 }
176 else
177 {
178 // Turn Body
179 if (CS(this).movement.x == 0 && CS(this).movement.y != 0)
181 else
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
204 float oldvelz = vehic.velocity.z;
206 vehic.velocity.z = oldvelz;
208 if (vehic.velocity.z <= 20) // not while jumping
209 vehic.velocity.z -= g * PHYS_INPUT_FRAMETIME * PHYS_GRAVITY(NULL);
210 if (IS_ONGROUND(vehic)
211 && (vehic.sound_nexttime < time || vehic.delay != 1))
212 {
213 vehic.delay = 1;
214 vehic.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav");
215 sound(vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_WALK, VOL_VEHICLEENGINE, ATTEN_NORM);
216 //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n");
217 }
218 }
219 else if (CS(this).movement.y != 0)
220 {
221 if (CS(this).movement.y < 0)
222 {
223 CS(this).movement.y = -1;
224 if (IS_ONGROUND(vehic))
225 vehic.frame = 2;
226 }
227 else if (CS(this).movement.y > 0)
228 {
229 CS(this).movement.y = 1;
230 if (IS_ONGROUND(vehic))
231 vehic.frame = 3;
232 }
233
234 float oldvelz = vehic.velocity.z;
236 vehic.velocity.z = oldvelz;
238 if (vehic.velocity.z <= 20) // not while jumping
239 vehic.velocity.z -= g * PHYS_INPUT_FRAMETIME * PHYS_GRAVITY(NULL);
240 if (IS_ONGROUND(vehic)
241 && (vehic.sound_nexttime < time || vehic.delay != 2))
242 {
243 vehic.delay = 2;
244 vehic.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav");
245 sound(vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_STRAFE, VOL_VEHICLEENGINE, ATTEN_NORM);
246 //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n");
247 }
248 }
249 }
250 }
251 }
252
255
256 if (!weaponLocked(this) && !weaponUseForbidden(this)
257 && PHYS_INPUT_BUTTON_ATCK(this))
258 {
259 vehic.cnt = time;
260 if (vehic.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && vehic.tur_head.attack_finished_single[0] <= time)
261 {
262 ++vehic.misc_bulletcounter;
263
264 entity gun = (vehic.misc_bulletcounter % 2) ? vehic.gun1 : vehic.gun2;
265
266 vector v = gettaginfo(gun, gettagindex(gun, "barrels"));
268 v += v_forward * 50;
269
270 .entity weaponentity = weaponentities[0]; // TODO: unhardcode
273
274 sound(gun, CH_WEAPON_A, SND_VEH_SPIDERBOT_MINIGUN_FIRE, VOL_BASE, ATTEN_NORM);
275 //trailparticles(this, _particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
276 Send_Effect(EFFECT_SPIDERBOT_MINIGUN_MUZZLEFLASH, v, v_forward * 2500, 1);
277
279 vehic.tur_head.attack_finished_single[0] = time + autocvar_g_vehicle_spiderbot_minigun_refire;
280 this.vehicle_ammo1 = (vehic.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100;
281 vehic.gun1.angles.z += 45;
282 vehic.gun2.angles.z -= 45;
283 if (vehic.gun1.angles.z >= 360)
284 {
285 vehic.gun1.angles.z = 0;
286 vehic.gun2.angles.z = 0;
287 }
288 }
289 }
290 else
294
295
296 spiderbot_rocket_do(vehic);
297
298 if (vehic.vehicle_flags & VHF_SHIELDREGEN)
300
301 if (vehic.vehicle_flags & VHF_HEALTHREGEN)
303
305 //this.vehicle_ammo2 = vehic.tur_head.frame;
306 this.vehicle_ammo2 = (9 - vehic.tur_head.frame) / 8 * 100; // Percentage, like ammo1
307
308 if (vehic.gun2.cnt <= time)
309 this.vehicle_reload2 = 100;
310 else
311 this.vehicle_reload2 = 100 - ((vehic.gun2.cnt - time) / vehic.attack_finished_single[0]) * 100;
312
313 setorigin(this, vehic.origin + '0 0 1' * vehic.maxs.z);
314 this.oldorigin = this.origin; // negate fall damage
315 this.velocity = vehic.velocity;
316
317 VEHICLE_UPDATE_PLAYER_RESOURCE(this, vehic, health, spiderbot, RES_HEALTH);
318
319 if (vehic.vehicle_flags & VHF_HASSHIELD)
320 VEHICLE_UPDATE_PLAYER(this, vehic, shield, spiderbot);
321}
322
323void spiderbot_exit(entity this, int eject)
324{
325 entity player = this.owner;
326
327 IL_EACH(g_projectiles, it.owner == player && it.classname == "spiderbot_rocket",
328 {
329 it.realowner = player;
330 it.owner = NULL;
331 });
332
334 this.nextthink = time;
335 this.frame = 5;
337
338 if (!player)
339 {
340 this.owner = NULL; // reset owner anyway?
341 return;
342 }
343
344 makevectors(this.angles);
345 vector spot;
346 if (eject)
347 {
348 spot = this.origin + v_forward * 100 + '0 0 64';
349 spot = vehicles_findgoodexit(this, player, spot);
350 setorigin(player, spot);
351 player.velocity = (v_up + v_forward * 0.25) * 750;
352 player.oldvelocity = player.velocity;
353 }
354 else
355 {
357 {
358 player.velocity = normalize(this.velocity) * vlen(this.velocity);
359 player.velocity.z += 200;
360 spot = this.origin + v_forward * 128 + '0 0 64';
361 spot = vehicles_findgoodexit(this, player, spot);
362 }
363 else
364 {
365 player.velocity = this.velocity * 0.5;
366 player.velocity.z += 10;
367 spot = this.origin + v_forward * 256 + '0 0 64';
368 spot = vehicles_findgoodexit(this, player, spot);
369 }
370 player.oldvelocity = player.velocity;
371 setorigin(player, spot);
372 }
373
374 antilag_clear(player, CS(player));
375 this.owner = NULL;
376}
377
379{
381 this.nextthink = this.fade_time;
382 this.alpha = 1 - (time - this.fade_time) * this.fade_rate;
383
384 if (this.cnt < time || this.alpha < 0.1)
385 {
386 if (this.alpha > 0.1)
387 {
388 sound(this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
389 Send_Effect(EFFECT_EXPLOSION_BIG, this.origin + '0 0 100', '0 0 0', 1);
390 }
391 delete(this);
392 }
393}
394
396{
397 if (this.cnt > time)
398 {
399 if (random() < 0.1)
400 {
401 sound(this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
402 Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (this.origin + '0 0 100'), '0 0 0', 1);
403 }
404 this.nextthink = time + 0.1;
405 return;
406 }
407
408 entity h = new(spiderbot_top);
409 entity g1 = new(spiderbot_gun);
410 entity g2 = new(spiderbot_gun);
411 entity b = new(spiderbot_body);
412
413 setmodel(b, MDL_VEH_SPIDERBOT_BODY);
414 setmodel(h, MDL_VEH_SPIDERBOT_TOP);
415 setmodel(g1, MDL_VEH_SPIDERBOT_GUN);
416 setmodel(g2, MDL_VEH_SPIDERBOT_GUN);
417
418 setorigin(b, this.origin);
419 b.frame = 11;
420 b.angles = this.angles;
421 setsize(b, this.mins, this.maxs);
422
423 h.solid = SOLID_BBOX; // before setorigin for immediate area grid linking
424 vector org = gettaginfo(this, gettagindex(this, "tag_head"));
425 setorigin(h, org);
427 h.velocity = v_up * (500 + random() * 500) + randomvec() * 128;
428 h.modelflags = MF_ROCKET;
429 h.effects = EF_FLAME | EF_LOWPRECISION;
430 h.avelocity = randomvec() * 360;
431
432 h.alpha = 1;
433 h.cnt = time + (3.5 * random());
434 h.fade_rate = 1 / min(this.respawntime, 10);
435 h.fade_time = time;
437 h.nextthink = time;
438
439 g1.solid = SOLID_CORPSE; // before setorigin for immediate area grid linking
440 org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint01"));
441 setorigin(g1, org);
443 g1.velocity = v_forward * 700 + (randomvec() * 32);
444 g1.avelocity = randomvec() * 180;
445
446 g2.solid = SOLID_CORPSE; // before setorigin for immediate area grid linking
447 org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint02"));
448 setorigin(g2, org);
450 g2.velocity = v_forward * 700 + (randomvec() * 32);
451 g2.avelocity = randomvec() * 180;
452
453 h.colormod = b.colormod = g1.colormod = g2.colormod = '-2 -2 -2';
454
455 SUB_SetFade(b, time + 5, min(this.respawntime, 1));
456 //SUB_SetFade(h, time, min(this.respawntime, 10));
457 SUB_SetFade(g1, time, min(this.respawntime, 10));
458 SUB_SetFade(g2, time, min(this.respawntime, 10));
459
460 RadiusDamage(this, this.enemy,
461 250,
462 15,
463 250,
464 NULL,
465 NULL,
466 250,
467 DEATH_VH_SPID_DEATH.m_id,
468 DMG_NOWEP,
469 NULL
470 );
471
472 this.alpha = this.tur_head.alpha = this.gun1.alpha = this.gun2.alpha = -1;
474 this.deadflag = DEAD_DEAD;
475 this.solid = SOLID_NOT;
476 this.tur_head.effects &= ~EF_FLAME;
477 this.vehicle_hudmodel.viewmodelforclient = this;
478}
479
480bool spiderbot_impulse(entity this, int _imp)
481{
482 switch (_imp)
483 {
484 case IMP_weapon_group_1.impulse:
485 STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_VOLLY;
486 CSQCVehicleSetup(this, 0);
487 return true;
488 case IMP_weapon_group_2.impulse:
489 STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_GUIDE;
490 CSQCVehicleSetup(this, 0);
491 return true;
492 case IMP_weapon_group_3.impulse:
493 STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_ARTILLERY;
494 CSQCVehicleSetup(this, 0);
495 return true;
496
497 case IMP_weapon_next_byid.impulse:
498 case IMP_weapon_next_bypriority.impulse:
499 case IMP_weapon_next_bygroup.impulse:
500 ++STAT(VEHICLESTAT_W2MODE, this.vehicle);
501 if (STAT(VEHICLESTAT_W2MODE, this.vehicle) > SBRM_LAST)
502 STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_FIRST;
503
504 //centerprint(this, strcat("Rocket mode is ", ftos(STAT(VEHICLESTAT_W2MODE, this.vehicle))));
505 CSQCVehicleSetup(this, 0);
506 return true;
507 case IMP_weapon_last.impulse:
508 case IMP_weapon_prev_byid.impulse:
509 case IMP_weapon_prev_bypriority.impulse:
510 case IMP_weapon_prev_bygroup.impulse:
511 --STAT(VEHICLESTAT_W2MODE, this.vehicle);
512 if (STAT(VEHICLESTAT_W2MODE, this.vehicle) < SBRM_FIRST)
513 STAT(VEHICLESTAT_W2MODE, this.vehicle) = SBRM_LAST;
514
515 //centerprint(this, strcat("Rocket mode is ", ftos(STAT(VEHICLESTAT_W2MODE, this.vehicle))));
516 CSQCVehicleSetup(this, 0);
517 return true;
518
519 /*
520 case IMP_weapon_drop.impulse: // toss gun, could be used to exit?
521 break;
522 case IMP_weapon_reload.impulse: // Manual minigun reload?
523 break;
524 */
525 }
526 return false;
527}
528
529spawnfunc(vehicle_spiderbot)
530{
532 || !vehicle_initialize(this, VEH_SPIDERBOT, false))
533 {
534 delete(this);
535 return;
536 }
537}
538
539METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance))
540{
543}
544METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance))
545{
546 STAT(VEHICLESTAT_W2MODE, instance) = SBRM_GUIDE;
547 set_movetype(instance, MOVETYPE_WALK);
548 CSQCVehicleSetup(instance.owner, 0);
549 instance.owner.vehicle_health = (GetResource(instance, RES_HEALTH) / autocvar_g_vehicle_spiderbot_health) * 100;
550 instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100;
551
552 if (instance.owner.flagcarried)
553 {
554 setattachment(instance.owner.flagcarried, instance.tur_head, "");
555 setorigin(instance.owner.flagcarried, '-20 0 120');
556 }
557}
558METHOD(Spiderbot, vr_think, void(Spiderbot thisveh, entity instance))
559{
560 if (IS_ONGROUND(instance))
562}
563METHOD(Spiderbot, vr_death, void(Spiderbot thisveh, entity instance))
564{
565 SetResourceExplicit(instance, RES_HEALTH, 0);
566 instance.event_damage = func_null;
567 instance.takedamage = DAMAGE_NO;
568 settouch(instance, func_null);
569 instance.cnt = 3.4 + time + random() * 2;
570 setthink(instance, spiderbot_blowup);
571 instance.nextthink = time;
572 instance.deadflag = DEAD_DYING;
573 instance.frame = 5;
574 instance.tur_head.effects |= EF_FLAME;
575 instance.colormod = instance.tur_head.colormod = '-1 -1 -1';
576 instance.frame = 10;
577 set_movetype(instance, MOVETYPE_TOSS);
578
579 CSQCModel_UnlinkEntity(instance); // networking the death scene would be a nightmare
580}
581METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance))
582{
583 if (!instance.gun1)
584 {
585 instance.vehicles_impulse = spiderbot_impulse;
586 instance.gun1 = new(spiderbot_gun);
587 instance.gun2 = new(spiderbot_gun);
588 setmodel(instance.gun1, MDL_VEH_SPIDERBOT_GUN);
589 setmodel(instance.gun2, MDL_VEH_SPIDERBOT_GUN);
590 setattachment(instance.gun1, instance.tur_head, "tag_hardpoint01");
591 setattachment(instance.gun2, instance.tur_head, "tag_hardpoint02");
592 instance.gravity = 2;
593 instance.mass = 5000;
594 }
595
596 instance.frame = 5;
597 instance.tur_head.frame = 1;
598 set_movetype(instance, MOVETYPE_WALK);
599 instance.solid = SOLID_SLIDEBOX;
600 instance.alpha = instance.tur_head.alpha = instance.gun1.alpha = instance.gun2.alpha = 1;
601 instance.tur_head.angles = '0 0 0';
602 instance.vehicle_exit = spiderbot_exit;
603
604 setorigin(instance, instance.pos1 + '0 0 128');
605 instance.angles = instance.pos2;
606 instance.damageforcescale = 0.03;
608 instance.vehicle_shield = autocvar_g_vehicle_spiderbot_shield;
609
610 instance.PlayerPhysplug = spiderbot_frame;
611}
612METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
613{
615 instance.vehicle_flags |= VHF_HASSHIELD;
616
618 instance.vehicle_flags |= VHF_SHIELDREGEN;
619
621 instance.vehicle_flags |= VHF_HEALTHREGEN;
622
623 instance.respawntime = autocvar_g_vehicle_spiderbot_respawntime;
625 instance.vehicle_shield = autocvar_g_vehicle_spiderbot_shield;
626 instance.max_health = GetResource(instance, RES_HEALTH);
627 instance.pushable = true; // spiderbot can use jumppads
628}
629
630#endif // SVQC
631#ifdef CSQC
632//float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6;
633//float autocvar_cl_vehicle_spiderbot_cross_size = 1;
634
635METHOD(Spiderbot, vr_hud, void(Spiderbot thisveh))
636{
637 Vehicles_drawHUD(VEH_SPIDERBOT.m_icon, "vehicle_spider_weapon1", "vehicle_spider_weapon2",
640}
641METHOD(Spiderbot, vr_crosshair, void(Spiderbot thisveh, entity player))
642{
643 string crosshair;
644
645 switch (weapon2mode)
646 {
647 case SBRM_VOLLY: crosshair = vCROSS_BURST; break;
648 case SBRM_GUIDE: crosshair = vCROSS_GUIDE; break;
649 case SBRM_ARTILLERY: crosshair = vCROSS_RAIN; break;
650 default: crosshair = vCROSS_BURST;
651 }
652
653 Vehicles_drawCrosshair(crosshair);
654}
655METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
656{
657 AuxiliaryXhair[0].axh_image = vCROSS_HINT; // Minigun1
658 AuxiliaryXhair[1].axh_image = vCROSS_HINT; // Minigun2
659}
660
661#endif // CSQC
662
663#endif // GAMEQC
664#ifdef MENUQC
665#include "raptor.qh"
666
667METHOD(Spiderbot, describe, string(Spiderbot this))
668{
669 TC(Spiderbot, this);
671 PAR(_("The %s vehicle walks and jumps around, and takes only one rider."), COLORED_NAME(this));
672 PAR(_("It can jump from very high altitudes while protecting the rider."));
673 PAR(_("It has two weapons the rider can control, which have different reticles for them similar to the %s. "
674 "The primary weapon is a machine gun, and is shot toward the green reticle. "
675 "The secondary weapon shoots rockets towards the white reticle. "
676 "The white reticle points to the front of the vehicle, while the green reticle also points to the front but with a bit of delay when the %s rotates."), COLORED_NAME(VEH_RAPTOR), COLORED_NAME(this));
677 return PAGE_TEXT;
678}
679
680#endif // MENUQC
ERASEABLE float anglemods(float v)
Definition angle.qc:13
vector AnglesTransform_ToAngles(vector v)
vector AnglesTransform_LeftDivide(vector from_transform, vector to_transform)
vector AnglesTransform_Normalize(vector t, float minimize_roll)
vector AnglesTransform_FromAngles(vector v)
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition anim.qh:6
void antilag_clear(entity e, entity store)
Definition antilag.qc:114
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
void Vehicles_drawCrosshair(string crosshair)
void Vehicles_drawHUD(string vehicle, string vehicleWeapon1, string vehicleWeapon2, string iconAmmo1, vector colorAmmo1, string iconAmmo2, vector colorAmmo2)
vector autocvar_hud_progressbar_vehicles_ammo2_color
const string vCROSS_GUIDE
vector autocvar_hud_progressbar_vehicles_ammo1_color
const string vCROSS_BURST
const string vCROSS_HINT
#define weapon2mode
const string vCROSS_RAIN
entity AuxiliaryXhair[MAX_AXH]
float cnt
Definition powerups.qc:24
float alpha
Definition items.qc:13
entity owner
Definition main.qh:87
#define COLORED_NAME(this)
Definition color.qh:195
#define setmodel(this, m)
Definition model.qh:26
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition player.qh:156
vector movement
Definition player.qh:228
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition player.qh:153
#define PHYS_INPUT_FRAMETIME
Definition player.qh:254
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition player.qh:152
#define PHYS_INPUT_BUTTON_ZOOM(s)
Definition player.qh:155
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:154
float game_stopped
Definition stats.qh:81
bool autocvar_sv_gameplayfix_gravityunaffectedbyticrate
Definition stats.qh:398
vector v_up
const float SOLID_SLIDEBOX
const float MOVE_NORMAL
vector mins
const float SOLID_CORPSE
vector velocity
const float SOLID_BBOX
const float SOLID_NOT
float time
vector v_right
vector trace_endpos
vector maxs
const float EF_FLAME
float nextthink
vector v_forward
vector origin
vector oldorigin
const int MF_ROCKET
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:943
#define DMG_NOWEP
Definition damage.qh:104
float EF_LOWPRECISION
#define gettagindex
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:120
ent angles
Definition ent_cs.qc:121
solid
Definition ent_cs.qc:165
#define IL_EACH(this, cond, body)
#define TC(T, sym)
Definition _all.inc:82
#define STAT(...)
Definition stats.qh:82
float bound(float min, float value, float max)
float random(void)
float vlen(vector v)
vector vectoangles(vector v)
vector randomvec(void)
float min(float f,...)
vector normalize(vector v)
void movelib_groundalign4point(entity this, float spring_length, float spring_up, float blendrate, float _max)
Pitches and rolls the entity to match the gound.
Definition movelib.qc:182
void movelib_brake_simple(entity this, float force)
Definition movelib.qc:163
#define movelib_move_simple(e, newdir, velo, blendrate)
Definition movelib.qh:36
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_WALK
Definition movetypes.qh:132
const int MOVETYPE_NONE
Definition movetypes.qh:129
#define PHYS_GRAVITY(s)
Definition movetypes.qh:53
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
const int MOVETYPE_TOSS
Definition movetypes.qh:135
const int MOVETYPE_BOUNCE
Definition movetypes.qh:139
#define IS_ONGROUND(s)
Definition movetypes.qh:16
var void func_null()
#define METHOD(cname, name, prototype)
Definition oo.qh:269
#define NULL
Definition post.qh:14
#define makevectors
Definition post.qh:21
#define gettaginfo
Definition post.qh:32
float DEAD_DYING
Definition progsdefs.qc:275
float deadflag
Definition progsdefs.qc:149
float DEAD_DEAD
Definition progsdefs.qc:276
fade_rate
Definition projectile.qh:14
float health
Legacy fields for the resources. To be removed.
Definition resources.qh:9
#define setthink(e, f)
vector
Definition self.qh:92
vector org
Definition self.qh:92
#define settouch(e, f)
Definition self.qh:73
float respawntime
Definition items.qh:31
float fade_time
Definition common.qh:23
IntrusiveList g_projectiles
Definition common.qh:58
const int CH_TRIGGER_SINGLE
Definition sound.qh:13
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const int CH_WEAPON_A
Definition sound.qh:7
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
#define spawnfunc(id)
Definition spawnfunc.qh:96
float autocvar_g_vehicle_spiderbot_springblend
Definition spiderbot.qc:29
const int SBRM_VOLLY
Definition spiderbot.qc:10
bool autocvar_g_vehicle_spiderbot
Definition spiderbot.qc:16
const int SBRM_GUIDE
Definition spiderbot.qc:11
float autocvar_g_vehicle_spiderbot_shield_regen
Definition spiderbot.qc:42
float autocvar_g_vehicle_spiderbot_turnspeed_strafe
Definition spiderbot.qc:24
void spiderbot_headfade(entity this)
Definition spiderbot.qc:378
bool spiderbot_impulse(entity this, int _imp)
Definition spiderbot.qc:480
float autocvar_g_vehicle_spiderbot_health_regen
Definition spiderbot.qc:38
int autocvar_g_vehicle_spiderbot_shield
Definition spiderbot.qc:41
float jump_delay
Definition spiderbot.qc:48
void spiderbot_exit(entity this, int eject)
Definition spiderbot.qc:323
float autocvar_g_vehicle_spiderbot_speed_stop
Definition spiderbot.qc:20
float autocvar_g_vehicle_spiderbot_turnspeed
Definition spiderbot.qc:23
vector autocvar_g_vehicle_spiderbot_bouncepain
Definition spiderbot.qc:46
float autocvar_g_vehicle_spiderbot_head_turnlimit
Definition spiderbot.qc:34
int autocvar_g_vehicle_spiderbot_health
Definition spiderbot.qc:37
void spiderbot_blowup(entity this)
Definition spiderbot.qc:395
const int SBRM_FIRST
Definition spiderbot.qc:9
float autocvar_g_vehicle_spiderbot_head_turnspeed
Definition spiderbot.qc:35
float autocvar_g_vehicle_spiderbot_health_regen_pause
Definition spiderbot.qc:39
const int SBRM_ARTILLERY
Definition spiderbot.qc:12
float autocvar_g_vehicle_spiderbot_speed_walk
Definition spiderbot.qc:22
float autocvar_g_vehicle_spiderbot_movement_inertia
Definition spiderbot.qc:25
float autocvar_g_vehicle_spiderbot_respawntime
Definition spiderbot.qc:18
float autocvar_g_vehicle_spiderbot_shield_regen_pause
Definition spiderbot.qc:43
float autocvar_g_vehicle_spiderbot_head_pitchlimit_down
Definition spiderbot.qc:32
const int SBRM_LAST
Definition spiderbot.qc:13
float autocvar_g_vehicle_spiderbot_springlength
Definition spiderbot.qc:27
float autocvar_g_vehicle_spiderbot_head_pitchlimit_up
Definition spiderbot.qc:33
bool spiderbot_frame(entity this, float dt)
Definition spiderbot.qc:49
float autocvar_g_vehicle_spiderbot_tiltlimit
Definition spiderbot.qc:30
float autocvar_g_vehicle_spiderbot_springup
Definition spiderbot.qc:28
float autocvar_g_vehicle_spiderbot_speed_strafe
Definition spiderbot.qc:21
void spiderbot_rocket_do(entity this)
float autocvar_g_vehicle_spiderbot_minigun_solidpenetration
float autocvar_g_vehicle_spiderbot_minigun_damage
float autocvar_g_vehicle_spiderbot_minigun_refire
int autocvar_g_vehicle_spiderbot_minigun_ammo_max
int autocvar_g_vehicle_spiderbot_minigun_ammo_regen
float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause
int autocvar_g_vehicle_spiderbot_minigun_ammo_cost
float autocvar_g_vehicle_spiderbot_minigun_force
float autocvar_g_vehicle_spiderbot_minigun_spread
ClientState CS(Client this)
Definition state.qh:47
#define PAGE_TEXT
Definition string.qh:642
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:648
#define PAGE_TEXT_INIT()
Definition string.qh:641
void SUB_SetFade(entity ent, float vanish_time, float fading_time)
Definition subs.qc:77
const int DAMAGE_NO
Definition subs.qh:79
entity enemy
Definition sv_ctf.qh:153
void CSQCModel_UnlinkEntity(entity e)
Definition sv_model.qc:139
entity tur_head
Definition sv_turrets.qh:28
void vehicles_impact(entity this, float _minspeed, float _speedfac, float _maxpain)
bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
void vehicles_regen(entity this, float timer,.float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale)
vector vehicles_findgoodexit(entity this, entity player, vector prefer_spot)
void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
void vehicles_think(entity this)
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)
void CSQCVehicleSetup(entity own, int vehicle_id)
void vehicles_frame(entity this, entity actor)
const float vehicle_shield
If ent is player this is 0..100 indicating precentage of shield left on vehicle. If ent is vehicle,...
const float vehicle_reload2
If ent is player this is 0..100 indicating percentage of secondary reload status. If ent is vehicle,...
const float vehicle_ammo1
If ent is player this is 0..100 indicating percentage of primary ammo left UNLESS value is already st...
const float vehicle_health
If ent is player this is 0..100 indicating precentage of health left on vehicle. Vehicle's value is t...
#define VEHICLE_UPDATE_PLAYER(ply, vehi, fld, vhname)
const float VOL_VEHICLEENGINE
#define VEHICLE_UPDATE_PLAYER_RESOURCE(ply, vehi, fld, vhname, res)
entity gun1
entity vehicle
entity gun2
entity vehicle_hudmodel
const float vehicle_ammo2
If ent is player this is 0..100 indicating percentage of secondary ammo left. If ent is vehicle,...
const float vehicle_reload1
If ent is player this is 0..100 indicating percentage of primary reload status. If ent is vehicle,...
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:537
void crosshair_trace(entity pl)
Definition tracing.qc:542
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
const int VHF_HASSHIELD
Vehicle has shileding.
Definition vehicle.qh:95
const int VHF_HEALTHREGEN
Vehicles health regenerates.
Definition vehicle.qh:97
const int VHF_SHIELDREGEN
Vehicles shield regenerates.
Definition vehicle.qh:96
const int MAX_WEAPONSLOTS
Definition weapon.qh:16
int max_shot_distance
Definition weapon.qh:245
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17
bool weaponUseForbidden(entity player)
bool weaponLocked(entity player)
Weapon m_switchweapon
Definition wepent.qh:25