1 const vector spiderbot_MIN = '-75 -75 0';
2 const vector spiderbot_MAX = '75 75 100';
4 #define spiderbot_spawnpnt wkr_spawn
6 void spiderbot_exit(float eject);
7 void spiderbot_enter();
9 void spiderbot_rocket_explode()
13 if(self.event_damage != SUB_Null)
15 self.event_damage = SUB_Null;
16 self.think = spiderbot_rocket_explode;
17 self.nextthink = time;
21 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
22 org2 = findbetterlocation (self.origin, 16);
23 pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
24 w_deathtypestring = "dident escape the rocket barrage";
27 self.owner = self.realowner;
29 RadiusDamage (self, self.owner,
30 autocvar_g_vehicle_spiderbot_rocket_damage,
31 autocvar_g_vehicle_spiderbot_rocket_edgedamage,
32 autocvar_g_vehicle_spiderbot_rocket_radius, world,
33 autocvar_g_vehicle_spiderbot_rocket_force, DEATH_SBROCKET, world);
38 void spiderbot_rocket_touch()
42 if(other == self.owner.vehicle)
45 if(other == self.owner.vehicle.tur_head)
50 spiderbot_rocket_explode();
53 void spiderbot_rocket_unguided()
57 self.nextthink = time;
60 olddir = normalize(self.velocity);
61 newdir = normalize(self.pos1 - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise;
62 self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed;
64 UpdateCSQCProjectile(self);
66 if (self.owner.deadflag != DEAD_NO || self.cnt < time)
67 spiderbot_rocket_explode();
71 void spiderbot_rocket_guided()
73 vector newdir, olddir;
75 self.nextthink = time;
77 if not (self.owner.vehicle)
78 self.think = spiderbot_rocket_unguided;
80 crosshair_trace(self.owner);
81 olddir = normalize(self.velocity);
82 newdir = normalize(trace_endpos - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise;
83 self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed;
85 UpdateCSQCProjectile(self);
87 if (self.owner.deadflag != DEAD_NO || self.cnt < time)
88 spiderbot_rocket_explode();
91 void spiderbot_rocket_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
93 self.health -= damage;
94 self.velocity += force;
96 spiderbot_rocket_explode();
99 void spiderbot_guide_release()
102 rkt = findchainentity(owner,self.owner);
106 crosshair_trace(self.owner);
110 if(rkt.think == spiderbot_rocket_guided)
112 rkt.pos1 = trace_endpos;
113 rkt.think = spiderbot_rocket_unguided;
120 void spiderbot_rocket_do()
124 if (self.owner.BUTTON_ATCK2)
127 if (self.tur_head.frame == 9 || self.tur_head.frame == 1)
129 if(self.gun2.cnt < time && self.tur_head.frame == 9)
130 self.tur_head.frame = 1;
140 spiderbot_guide_release();
145 if(self.gun2.cnt > time)
148 if (self.tur_head.frame >= 9)
149 self.tur_head.frame = 1;
151 if not (self.owner.BUTTON_ATCK2)
154 sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
156 setsize (rocket, '-1 -1 -1', '1 1 1'); // give it some size so it can be shot
157 setorigin(rocket,gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")));
158 te_explosion (rocket.origin);
160 crosshair_trace(self.owner);
162 rocket.classname = "spiderbot_rocket";
163 rocket.bot_dodge = TRUE;
164 rocket.bot_dodgerating = autocvar_g_vehicle_spiderbot_rocket_damage;
165 rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
166 rocket.health = autocvar_g_vehicle_spiderbot_rocket_health;
167 rocket.takedamage = DAMAGE_AIM;
168 rocket.event_damage = spiderbot_rocket_damage;
169 rocket.owner = self.owner;
170 rocket.nextthink = time;
171 rocket.movetype = MOVETYPE_FLYMISSILE;
172 rocket.velocity = normalize(v_forward + (v_up * 0.5) + randomvec() * 0.25) * autocvar_g_vehicle_spiderbot_rocket_speed;
173 rocket.angles = vectoangles(rocket.velocity);
174 rocket.think = spiderbot_rocket_guided;
175 rocket.touch = spiderbot_rocket_touch;
176 rocket.flags = FL_PROJECTILE;
177 rocket.solid = SOLID_TRIGGER;
178 rocket.pos1 = trace_endpos;
180 CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
182 self.tur_head.frame += 1;
183 if (self.tur_head.frame == 9)
184 self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload;
186 self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_refire;
188 self.gun2.cnt = time + self.attack_finished_single;
192 void spiderbot_minigun_fire_Flash_Go() {
200 self.frame = self.frame + 2;
201 self.alpha = self.alpha - 0.2;
203 self.nextthink = time + 0.02;
207 void spiderbot_minigun_fire(entity gun, float trail)
211 v = gettaginfo(gun,gettagindex(gun,"barrels"));
212 v_forward = normalize(v_forward);
214 sound (gun, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
216 fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
217 autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
221 setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
224 trailparticles(self, particleeffectnum("EF_MGTURRETTRAIL"), v, trace_endpos);
227 void spiderbot_miniguns_do()
231 if((self.vehicle_reload1 == 1) || (!self.owner.BUTTON_ATCK))
234 ftmp = 1 / autocvar_g_vehicle_spiderbot_minigun_cooldown * sys_frametime;
235 self.owner.vehicle_reload1 = max(self.owner.vehicle_reload1 - ftmp, 0);
236 if(self.owner.vehicle_reload1 <= 0)
237 self.vehicle_reload1 = 0;
242 if (self.owner.BUTTON_ATCK)
246 self.gun1.angles_z += (1440 * sys_frametime);
247 self.gun2.angles_z -= (1440 * sys_frametime);
248 if(self.gun1.angles_z >= 360)
250 self.gun1.angles_z = 0;
251 self.gun2.angles_z = 360;
254 if (self.tur_head.attack_finished_single < time)
256 // Fire bullets, alternating trails left<->right
258 if(self.misc_bulletcounter == 1)
260 spiderbot_minigun_fire(self.vehicle.gun1, 0);
261 spiderbot_minigun_fire(self.vehicle.gun2, 1);
262 self.misc_bulletcounter = 0;
266 spiderbot_minigun_fire(self.vehicle.gun1, 1);
267 spiderbot_minigun_fire(self.vehicle.gun2, 0);
268 self.misc_bulletcounter += 1;
273 ftmp = autocvar_g_vehicle_spiderbot_minigun_refire / autocvar_g_vehicle_spiderbot_minigun_heat;
274 self.owner.vehicle_reload1 += ftmp;
276 if(self.owner.vehicle_reload1 >= 1)
278 self.vehicle_reload1 = 1;
279 self.owner.vehicle_reload1 = 1;
280 self.tur_head.attack_finished_single = autocvar_g_vehicle_spiderbot_minigun_cooldown + time;
283 self.tur_head.attack_finished_single = autocvar_g_vehicle_spiderbot_minigun_refire + time;
291 float spiderbot_pplug()
294 entity player,spider;
302 spider = self.vehicle;
304 player.BUTTON_ZOOM = 0;
305 player.BUTTON_CROUCH = 0;
306 player.switchweapon = 0;
308 if(player.BUTTON_USE)
316 crosshair_trace(player);
317 ad = vectoangles(normalize(trace_endpos - gettaginfo(spider.tur_head,gettagindex(spider.tur_head,"tag_hud")))) - (spider.tur_head.angles + spider.angles);
319 fixedmakevectors(spider.angles);
320 if(ad_x > 180) ad_x -= 360;
321 if(ad_x < -180) ad_x += 360;
322 if(ad_y > 180) ad_y -= 360;
323 if(ad_y < -180) ad_y += 360;
326 ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime;
327 ad_y = bound(-ftmp, ad_y, ftmp);
328 spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit);
331 ftmp = autocvar_g_vehicle_spiderbot_head_pitchspeed * sys_frametime;
332 ad_x = bound(-ftmp, ad_x, ftmp);
333 spider.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, spider.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up);
336 ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime;
337 ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);
340 if(spider.flags & FL_ONGROUND)
342 if(player.BUTTON_JUMP && self.tur_head.wait < time)
344 self.tur_head.wait = time + 2;
345 player.BUTTON_JUMP = 0;
346 spider.velocity = v_forward * 700 + v_up * 600;
351 if(vlen(player.movement) == 0)
353 movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop);
358 spider.angles_y = anglemods(spider.angles_y + ftmp);
359 spider.tur_head.angles_y -= ftmp;
361 if(player.movement_x != 0)
363 if(player.movement_x > 0)
365 player.movement_x = 1;
368 else if(player.movement_x < 0)
370 player.movement_x = -1;
373 player.movement_y = 0;
374 movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia);
376 else if(player.movement_y != 0)
378 if(player.movement_y < 0)
380 player.movement_y = -1;
383 else if(player.movement_y > 0)
385 player.movement_y = 1;
388 movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
393 movelib_groundalign4point(300,100,0.25);
396 spiderbot_miniguns_do();
397 spiderbot_rocket_do();
398 vehicle_stdproc_shiledregen(CCVAR("_shield"), frametime);
399 vehicle_stdproc_healthregen(CCVAR("_health"), frametime);
401 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
402 player.vehicle_ammo2 = spider.tur_head.frame;
404 if(spider.gun2.cnt <= time)
405 player.vehicle_reload2 = 1;
407 player.vehicle_reload2 = 1 - ((spider.gun2.cnt - time) / spider.attack_finished_single);
409 setorigin(player,spider.origin + '0 0 64');
410 player.velocity = spider.velocity;
417 void spiderbot_think()
419 if(self.flags & FL_ONGROUND)
420 movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop);
422 self.nextthink = time;
425 void spiderbot_enter()
427 // Remove this when bots know how to use the spiderbot
428 if (clienttype(other) != CLIENTTYPE_REAL)
431 self.colormod = self.tur_head.colormod = '0 0 0';
435 if(self.team != other.team)
439 self.switchweapon = other.switchweapon;
441 self.event_damage = vehicle_stdproc_damage ;
442 self.colormap = self.owner.colormap;
443 self.tur_head.colormap = self.owner.colormap;
444 self.vehicle_hudmodel.viewmodelforclient = self.owner;
446 self.owner.angles = self.angles;
447 self.owner.takedamage = DAMAGE_NO;
448 self.owner.solid = SOLID_NOT;
449 self.owner.movetype = MOVETYPE_NOCLIP;
450 self.owner.alpha = -1;
451 self.owner.PlayerPhysplug = spiderbot_pplug;
452 self.owner.vehicle = self;
453 self.owner.event_damage = SUB_Null;
454 self.owner.hud = HUD_SPIDERBOT;
455 self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health);
456 self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield);
457 self.owner.view_ofs = '0 0 0';
458 self.owner.vehicle_ammo1 = self.vehicle_ammo1;
459 self.owner.vehicle_ammo2 = self.vehicle_ammo2;
460 self.owner.vehicle_reload1 = self.vehicle_reload1;
461 self.owner.vehicle_reload2 = self.vehicle_reload2;
463 //if(other.flags & FL_ONGROUND)
464 other.flags &~= FL_ONGROUND;
466 //if(self.flags & FL_ONGROUND)
467 self.flags &~= FL_ONGROUND;
469 self.team = self.owner.team;
470 self.flags -= FL_NOTARGET;
472 if(clienttype(other) == CLIENTTYPE_REAL)
475 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
476 WriteEntity(MSG_ONE, self.vehicle_viewport);
478 WriteByte (MSG_ONE, SVC_SETVIEWANGLES); // 10 = SVC_SETVIEWANGLES
479 WriteAngle(MSG_ONE, self.tur_head.angles_x + self.angles_x); // tilt
480 WriteAngle(MSG_ONE, self.tur_head.angles_y + self.angles_y); // yaw
481 WriteAngle(MSG_ONE, 0); // roll
485 void spiderbot_exit(float eject)
490 self.flags |= FL_NOTARGET;
492 e = findchain(classname,"spiderbot_rocket");
495 if(e.owner == self.owner)
497 e.realowner = self.owner;
503 self.owner.switchweapon = self.switchweapon;
505 self.velocity = '0 0 0';
506 if(clienttype(self.owner) == CLIENTTYPE_REAL)
508 msg_entity = self.owner;
509 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
510 WriteEntity( MSG_ONE, self.owner);
512 WriteByte (MSG_ONE, SVC_SETVIEWANGLES); // 10 = SVC_SETVIEWANGLES
513 WriteAngle(MSG_ONE, 0); // tilt
514 WriteAngle(MSG_ONE, self.angles_y); // yaw
515 WriteAngle(MSG_ONE, 0); // roll
518 self.think = spiderbot_think;
519 self.nextthink = time;
520 self.owner.takedamage = DAMAGE_AIM;
521 self.owner.solid = SOLID_SLIDEBOX;
522 self.owner.movetype = MOVETYPE_WALK;
524 setsize(self.owner,PL_MIN,PL_MAX);
526 self.owner.alpha = 1;
527 self.owner.PlayerPhysplug = SUB_Null;
528 self.owner.vehicle = world;
529 self.owner.view_ofs = PL_VIEW_OFS;
530 self.owner.hud = HUD_NORMAL;
531 self.owner.event_damage = PlayerDamage;
533 self.colormap = 1024;
534 self.tur_head.colormap = 1024;
540 self.team = self.spiderbot_spawnpnt.team ;
541 if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
542 if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
543 self.tur_head.colormod = self.colormod;
546 self.vehicle_hudmodel.viewmodelforclient = self;
547 self.tur_head.nodrawtoclient = self;
549 setattachment(self.owner,world,"");
551 makevectors(self.angles);
554 setorigin(self.owner,self.origin + v_forward * 100 + '0 0 64');
555 self.owner.velocity = (v_up + v_forward * 0.25) * 750;
558 setorigin(self.owner,self.origin - v_forward * 200 + '0 0 64');
563 float spiderbot_crushable(entity e)
565 if(e.classname == "corpse")
568 if(e.classname == "player")
571 if(e.classname == "monster_zombie")
577 void spiderbot_touch()
581 if(vlen(self.velocity) == 0)
584 if not (spiderbot_crushable(other))
587 //todo: add check for velocity/angle here (so we dont cush players runing into us from behind)
589 Damage(other,self,self.owner,autocvar_g_vehicle_spiderbot_crush_dmg,DEATH_SBCRUSH,'0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicle_spiderbot_crush_force );
593 if(other.classname != "player")
596 if(other.deadflag != DEAD_NO)
599 if(other.vehicle != world)
605 float spiderbot_customizeentityforclient()
607 if(self.deadflag == DEAD_DEAD)
613 void spiderbot_spawn()
616 self.think = spiderbot_think;
617 self.nextthink = time;
619 setsize(self,spiderbot_MIN,spiderbot_MAX);
622 self.velocity = '0 0 0';
623 self.vehicle_health = CCVAR("_health");
624 self.vehicle_shield = CCVAR("_shield");
625 self.event_damage = vehicle_stdproc_damage;
626 self.iscreature = TRUE;
627 self.movetype = MOVETYPE_WALK;
628 self.solid = SOLID_SLIDEBOX;
629 self.takedamage = DAMAGE_AIM;
630 self.touch = spiderbot_touch;
631 self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1;
632 self.tur_head.angles = '0 0 0';
633 self.colormap = 1024;
634 self.tur_head.colormap = 1024;
635 self.deadflag = DEAD_NO;
636 self.bot_attack = TRUE;
637 self.flags |= FL_NOTARGET;
638 self.vehicle_hudmodel.viewmodelforclient = self;
639 self.tur_head.frame = 1;
641 setorigin(self,self.spiderbot_spawnpnt.origin + '0 0 1.25' * spiderbot_MAX_z);
642 self.angles = self.spiderbot_spawnpnt.angles;
644 if (self.team == COLOR_TEAM1)
645 self.colormod = '1.4 0.8 0.8';
646 else if (self.team == COLOR_TEAM2)
647 self.colormod = '0.8 0.8 1.4';
649 self.colormod = '0 0 0';
651 self.tur_head.colormod = self.colormod;
654 pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
657 void spiderbot_blowup()
659 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
660 pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
662 RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_SBBLOWUP, world);
664 self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
665 self.nextthink = time + autocvar_g_vehicle_spiderbot_respawntime;
666 self.think = spiderbot_spawn;
667 self.movetype = MOVETYPE_NONE;
669 setorigin(self, self.tur_aimpos);
676 self.event_damage = SUB_Null;
677 self.iscreature = FALSE;
678 self.solid = SOLID_NOT;
679 self.takedamage = DAMAGE_NO;
680 self.touch = SUB_Null;
681 self.nextthink = time + random() * 2;
682 self.think = spiderbot_blowup;
683 self.deadflag = DEAD_DEAD;
684 self.vehicle_hudmodel.viewmodelforclient = self;
686 self.tur_head.frame = 1;
690 void vewhicle_spiderbot_dinit()
693 self.spiderbot_spawnpnt = spawn();
694 self.spiderbot_spawnpnt.angles = self.angles;
696 setorigin(self,self.origin);
697 tracebox(self.origin + '0 0 100', spiderbot_MIN, spiderbot_MAX, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
698 setorigin(self.spiderbot_spawnpnt,trace_endpos);
700 if(self.team && !teamplay)
703 self.spiderbot_spawnpnt.team = self.team;
705 addstat(STAT_HUD, AS_INT, hud);
706 addstat(STAT_VEHICLESTAT_HEALTH, AS_FLOAT, vehicle_health);
707 addstat(STAT_VEHICLESTAT_SHIELD, AS_FLOAT, vehicle_shield);
708 addstat(STAT_VEHICLESTAT_ENERGY, AS_FLOAT, vehicle_energy);
709 addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1);
710 addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
711 addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2);
712 addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
714 if (self.netname == "")
715 self.netname = "spiderbot";
717 self.tur_head = spawn();
720 self.vehicle_viewport = spawn();
721 self.vehicle_hudmodel = spawn();
722 self.vehicle_flags = VHF_HASSHIELD | VHF_SHIELDREGEN | VHF_HEALTHREGEN | VHF_DEATHEJECT;
723 self.cvar_basename = "g_vehicle_spiderbot";
726 setmodel(self, "models/vehicles/spiderbot.dpm");
727 setmodel(self.tur_head, "models/vehicles/spiderbot_top.dpm");
728 setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm");
729 setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm");
730 setmodel(self.vehicle_hudmodel, "models/vehicles/spiderbot_cockpit.dpm");
731 setmodel(self.vehicle_viewport, "null");
733 setattachment(self.tur_head, self, "tag_head");
734 setattachment(self.vehicle_hudmodel, self.tur_head, "tag_hud");
735 setattachment(self.vehicle_viewport, self.vehicle_hudmodel, "");
737 setattachment(self.gun1, self.tur_head, "tag_hardpoint01");
738 setattachment(self.gun2, self.tur_head, "tag_hardpoint02");
740 self.tur_head.owner = self;
741 self.customizeentityforclient = spiderbot_customizeentityforclient;
743 self.tur_aimpos = self.origin;
747 self.vehicle_die = spiderbot_die;
748 self.vehicle_exit = spiderbot_exit;
751 void spawnfunc_vehicle_spiderbot()
753 precache_model ( "models/vhshield.md3");
754 precache_model ( "models/vehicles/spiderbot.dpm");
755 precache_model ( "models/vehicles/spiderbot_top.dpm");
756 precache_model ( "models/vehicles/spiderbot_barrels.dpm");
757 precache_model ( "models/vehicles/spiderbot_cockpit.dpm");
758 precache_model ( "models/uziflash.md3");
760 precache_sound ( "weapons/rocket_impact.wav" );
763 self.think = vewhicle_spiderbot_dinit;
764 self.nextthink = time + 0.5;