3 float autocvar_g_vehicle_bumblebee_speed_forward;
4 float autocvar_g_vehicle_bumblebee_speed_strafe;
5 float autocvar_g_vehicle_bumblebee_speed_up;
6 float autocvar_g_vehicle_bumblebee_speed_down;
7 float autocvar_g_vehicle_bumblebee_turnspeed;
8 float autocvar_g_vehicle_bumblebee_pitchspeed;
9 float autocvar_g_vehicle_bumblebee_pitchlimit;
10 float autocvar_g_vehicle_bumblebee_friction;
12 float autocvar_g_vehicle_bumblebee_energy;
13 float autocvar_g_vehicle_bumblebee_energy_regen;
14 float autocvar_g_vehicle_bumblebee_energy_regen_pause;
16 float autocvar_g_vehicle_bumblebee_health;
17 float autocvar_g_vehicle_bumblebee_health_regen;
18 float autocvar_g_vehicle_bumblebee_health_regen_pause;
20 float autocvar_g_vehicle_bumblebee_shield;
21 float autocvar_g_vehicle_bumblebee_shield_regen;
22 float autocvar_g_vehicle_bumblebee_shield_regen_pause;
24 float autocvar_g_vehicle_bumblebee_cannon_cost;
25 float autocvar_g_vehicle_bumblebee_cannon_damage;
26 float autocvar_g_vehicle_bumblebee_cannon_radius;
27 float autocvar_g_vehicle_bumblebee_cannon_refire;
28 float autocvar_g_vehicle_bumblebee_cannon_speed;
29 float autocvar_g_vehicle_bumblebee_cannon_spread;
30 float autocvar_g_vehicle_bumblebee_cannon_force;
32 float autocvar_g_vehicle_bumblebee_cannon_turnspeed;
33 float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down;
34 float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up;
35 float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
36 float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
38 float autocvar_g_vehicle_bumblebee_raygun_turnspeed;
39 float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down;
40 float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up;
41 float autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides;
43 float autocvar_g_vehicle_bumblebee_respawntime;
45 float autocvar_g_vehicle_bumblebee_blowup_radius;
46 float autocvar_g_vehicle_bumblebee_blowup_coredamage;
47 float autocvar_g_vehicle_bumblebee_blowup_edgedamage;
48 float autocvar_g_vehicle_bumblebee_blowup_forceintensity;
50 float autocvar_g_vehicle_bumblebee;
52 #define BUMB_MIN '-120 -120 -120'
53 #define BUMB_MAX '120 120 120'
55 void bumb_fire_cannon(entity _gun, string _tagname, entity _owner)
60 v = gettaginfo(_gun, gettagindex(_gun, _tagname));
61 bolt = vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav",
62 v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
63 autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0,
64 DEATH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner);
67 //bolt.velocity = v_forward * autocvar_g_vehicle_bumblebee_cannon_speed;
70 float bumb_gunner_frame()
72 entity vehic, gun, gunner;
74 vehic = self.vehicle.owner;
79 vehic.solid = SOLID_NOT;
80 setorigin(gunner, vehic.origin);
81 gunner.velocity = vehic.velocity;
82 crosshair_trace(gunner);
83 vector _ct = trace_endpos;
86 _in = ((gun == vehic.gun1) ? autocvar_g_vehicle_bumblebee_cannon_turnlimit_in : autocvar_g_vehicle_bumblebee_cannon_turnlimit_out);
87 _out = ((gun == vehic.gun1) ? autocvar_g_vehicle_bumblebee_cannon_turnlimit_out : autocvar_g_vehicle_bumblebee_cannon_turnlimit_in);
89 if(gun.lock_time < time)
93 if(trace_ent.movetype)
94 if(trace_ent.takedamage)
95 if(!trace_ent.deadflag)
99 if(trace_ent.team != gunner.team)
101 gun.enemy = trace_ent;
102 gun.lock_time = time + 5;
107 gun.enemy = trace_ent;
108 gun.lock_time = time + 5;
114 float i, distance, impact_time;
116 vector vf = real_origin(gun.enemy);
117 vector _vel = gun.enemy.velocity;
118 if(gun.enemy.movetype == MOVETYPE_WALK)
123 for(i = 0; i < 4; ++i)
125 distance = vlen(ad - gunner.origin);
126 impact_time = distance / autocvar_g_vehicle_bumblebee_cannon_speed;
127 ad = vf + _vel * impact_time;
132 UpdateAuxiliaryXhair(gunner, ad, '1 0 1', 1);
133 vehicle_aimturret(vehic, trace_endpos, gun, "fire",
134 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
135 _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed);
139 vehicle_aimturret(vehic, _ct, gun, "fire",
140 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
141 _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed);
143 if(gunner.BUTTON_ATCK)
144 if(time > gun.attack_finished_single)
145 if(vehic.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost)
147 vehic.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost;
149 bumb_fire_cannon(gun, "fire", gunner);
150 gun.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire;
153 VEHICLE_UPDATE_PLAYER(gunner, health, bumblebee);
154 VEHICLE_UPDATE_PLAYER(gunner, energy, bumblebee);
156 if(vehic.vehicle_flags & VHF_HASSHIELD)
157 VEHICLE_UPDATE_PLAYER(gunner, shield, bumblebee);
159 ad = gettaginfo(gun, gettagindex(gun, "fire"));
160 traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, gun);
161 UpdateAuxiliaryXhair(gunner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' * (1 - gunner.vehicle_reload1)), 0);
164 vehic.solid = SOLID_BBOX;
165 gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0;
173 void bumb_gunner_exit(float _exitflag)
175 dprint("^2Gunner1 exits\n");
177 if (clienttype(self) == CLIENTTYPE_REAL)
180 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
181 WriteEntity( MSG_ONE, self);
183 WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
184 WriteAngle(MSG_ONE, 0);
185 WriteAngle(MSG_ONE, self.vehicle.angles_y);
186 WriteAngle(MSG_ONE, 0);
189 setsize(self, PL_MIN,PL_MAX);
191 self.takedamage = DAMAGE_AIM;
192 self.solid = SOLID_SLIDEBOX;
193 self.movetype = MOVETYPE_WALK;
194 self.effects &~= EF_NODRAW;
196 self.PlayerPhysplug = SUB_Null;
197 self.view_ofs = PL_VIEW_OFS;
198 self.event_damage = PlayerDamage;
199 self.hud = HUD_NORMAL;
200 self.switchweapon = self.vehicle.switchweapon;
204 self.flagcarried.scale = 0.6;
205 setattachment(self.flagcarried, self, "");
206 setorigin(self.flagcarried, FLAG_CARRY_POS);
209 CSQCVehicleSetup(self, HUD_NORMAL);
210 self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle;
212 if(self == self.vehicle.owner.gunner1)
213 self.vehicle.owner.gunner1 = world;
214 else if(self == self.vehicle.owner.gunner2)
215 self.vehicle.owner.gunner2 = world;
217 dprint("^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n");
219 self.vehicle.phase = time + 1;
220 self.vehicle = world;
223 float bumb_gunner_enter()
225 RemoveGrapplingHook(other);
226 entity _gun, _gunner;
230 _gunner = self.gunner1;
231 self.gunner1 = other;
236 _gunner = self.gunner2;
237 self.gunner2 = other;
240 _gun.vehicle_pilot = other;
242 //_gun.owner = other;
243 _gunner.vehicle = _gun;
244 _gun.switchweapon = other.switchweapon;
245 _gun.vehicle_exit = bumb_gunner_exit;
248 other.angles = self.angles;
249 other.takedamage = DAMAGE_NO;
250 other.solid = SOLID_NOT;
251 other.movetype = MOVETYPE_NOCLIP;
253 other.event_damage = SUB_Null;
254 other.view_ofs = '0 0 0';
255 other.hud = _gun.hud;
256 other.PlayerPhysplug = _gun.PlayerPhysplug;
257 other.vehicle_ammo1 = self.vehicle_ammo1;
258 other.vehicle_ammo2 = self.vehicle_ammo2;
259 other.vehicle_reload1 = self.vehicle_reload1;
260 other.vehicle_reload2 = self.vehicle_reload2;
261 other.vehicle_energy = self.vehicle_energy;
262 other.PlayerPhysplug = bumb_gunner_frame;
263 other.flags &~= FL_ONGROUND;
266 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
267 WriteEntity(MSG_ONE, _gun.vehicle_viewport);
268 WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
269 WriteAngle(MSG_ONE, _gun.angles_x + self.angles_x); // tilt
270 WriteAngle(MSG_ONE, _gun.angles_y + self.angles_y); // yaw
271 WriteAngle(MSG_ONE, 0); // roll
272 _gun.vehicle_hudmodel.viewmodelforclient = other;
277 _gunner = self.gunner1;
282 _gunner = self.gunner2;
288 float vehicles_valid_pilot()
290 if(other.classname != "player")
293 if(other.deadflag != DEAD_NO)
296 if(other.vehicle != world)
299 // Remove this when bots know how to use vehicles.
300 if (clienttype(other) != CLIENTTYPE_REAL)
303 if(teamplay && other.team != self.team)
312 if(self.gunner1 != world && self.gunner2 != world)
318 if (vehicles_valid_pilot())
320 if(self.gun1.phase <= time)
321 if (bumb_gunner_enter())
324 if(self.gun2.phase <= time)
325 if (bumb_gunner_enter())
333 float bumb_pilot_frame()
339 vehic = self.vehicle;
342 if(vehic.deadflag != DEAD_NO)
345 pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0;
349 crosshair_trace(pilot);
355 newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
358 if(newvel_x > 180) newvel_x -= 360;
359 if(newvel_x < -180) newvel_x += 360;
360 if(newvel_y > 180) newvel_y -= 360;
361 if(newvel_y < -180) newvel_y += 360;
363 ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y);
364 if(ftmp > 180) ftmp -= 360; if(ftmp < -180) ftmp += 360;
365 vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
369 if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = 5;
370 else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = -20;
372 newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit);
373 ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
374 vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
376 vehic.angles_x = anglemods(vehic.angles_x);
377 vehic.angles_y = anglemods(vehic.angles_y);
378 vehic.angles_z = anglemods(vehic.angles_z);
380 makevectors('0 1 0' * vehic.angles_y);
381 newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
383 if(pilot.movement_x != 0)
385 if(pilot.movement_x > 0)
386 newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
387 else if(pilot.movement_x < 0)
388 newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
391 if(pilot.movement_y != 0)
393 if(pilot.movement_y < 0)
394 newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
395 else if(pilot.movement_y > 0)
396 newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
397 ftmp = newvel * v_right;
398 ftmp *= frametime * 0.1;
399 vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15);
403 vehic.angles_z *= 0.95;
404 if(vehic.angles_z >= -1 && vehic.angles_z <= -1)
408 if(pilot.BUTTON_CROUCH)
409 newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down;
410 else if (pilot.BUTTON_JUMP)
411 newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up;
413 vehic.velocity += newvel * frametime;
414 pilot.velocity = pilot.movement = vehic.velocity;
415 setorigin(pilot,vehic.origin + '0 0 32');
417 vehicle_aimturret(vehic, trace_endpos, self.gun3, "fire",
418 autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up,
419 autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1, autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides, autocvar_g_vehicle_bumblebee_raygun_turnspeed);
423 vehicle_aimturret(vehic, trace_endpos, self.gun1, "fire",
424 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
425 autocvar_g_vehicle_bumblebee_cannon_turnlimit_out * -1, autocvar_g_vehicle_bumblebee_cannon_turnlimit_in, autocvar_g_vehicle_bumblebee_cannon_turnspeed);
427 vehicle_aimturret(vehic, trace_endpos, self.gun2, "fire",
428 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
429 autocvar_g_vehicle_bumblebee_cannon_turnlimit_in * -1, autocvar_g_vehicle_bumblebee_cannon_turnlimit_out, autocvar_g_vehicle_bumblebee_cannon_turnspeed);
433 if(pilot.BUTTON_ATCK)
434 if(time > vehic.attack_finished_single)
435 if(vehic.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost)
437 vehic.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost;
442 bumb_fire_cannon(vehic.gun1, "fire", pilot);
447 bumb_fire_cannon(vehic.gun2, "fire", pilot);
450 vehic.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire;
454 if(vehic.vehicle_flags & VHF_SHIELDREGEN)
455 vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, TRUE);
457 if(vehic.vehicle_flags & VHF_HEALTHREGEN)
458 vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, FALSE);
460 if(vehic.vehicle_flags & VHF_ENERGYREGEN)
461 vehicles_regen(wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, FALSE);
463 VEHICLE_UPDATE_PLAYER(pilot, health, bumblebee);
464 VEHICLE_UPDATE_PLAYER(pilot, energy, bumblebee);
466 if(vehic.vehicle_flags & VHF_HASSHIELD)
467 VEHICLE_UPDATE_PLAYER(pilot, shield, bumblebee);
470 pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0;
478 self.velocity = self.velocity * 0.99;
479 self.nextthink = time + 0.1;
484 self.touch = bumb_touch;
487 void bumb_exit(float eject)
490 self.touch = vehicles_touch;
493 void bumb_spawn(float _f)
495 self.vehicle_health = autocvar_g_vehicle_bumblebee_health;
496 self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield;
497 self.movetype = MOVETYPE_TOSS;
498 self.solid = SOLID_BBOX;
499 self.movetype = MOVETYPE_FLY;
500 setorigin(self, self.origin + '0 0 25');
505 self.deadflag = DEAD_DEAD;
506 self.vehicle_exit(VHEF_NORMAL);
509 self.event_damage = SUB_Null;
510 self.solid = SOLID_CORPSE;
511 self.takedamage = DAMAGE_NO;
512 self.deadflag = DEAD_DYING;
513 self.movetype = MOVETYPE_BOUNCE;
515 RadiusDamage (self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage,
516 autocvar_g_vehicle_bumblebee_blowup_edgedamage,
517 autocvar_g_vehicle_bumblebee_blowup_radius, world, world,
518 autocvar_g_vehicle_bumblebee_blowup_forceintensity,
519 DEATH_WAKIBLOWUP, world);
521 pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
534 if not (vehicle_initialize(
535 "Bumblebee", "models/vehicles/bumblebee_body.dpm",
536 "", "models/vehicles/spiderbot_cockpit.dpm", "", "", "tag_viewport",
537 HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, FALSE,
538 bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime,
539 bumb_pilot_frame, bumb_enter, bumb_exit,
540 bumb_die, bumb_think, FALSE, autocvar_g_vehicle_bumblebee_health))
546 self.vehicle_shieldent = spawn();
547 self.vehicle_shieldent.effects = EF_LOWPRECISION;
548 setmodel(self.vehicle_shieldent, "models/vhshield.md3");
549 setattachment(self.vehicle_shieldent, self, "");
550 setorigin(self.vehicle_shieldent, real_origin(self) - self.origin);
551 self.vehicle_shieldent.scale = 512 / vlen(self.maxs - self.mins);
552 self.vehicle_shieldent.think = shieldhit_think;
553 self.vehicle_shieldent.alpha = -1;
560 self.vehicle_flags |= VHF_MULTISLOT;
562 self.gun1.owner = self;
563 self.gun2.owner = self;
564 self.gun3.owner = self;
566 setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm");
567 setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm");
568 setmodel(self.gun3, "models/vehicles/bumblebee_ray.dpm");
570 setattachment(self.gun1, self, "cannon_right");
571 setattachment(self.gun2, self, "cannon_left");
572 setattachment(self.gun3, self, "raygun");
574 vehicle_addplayerslot(self, self.gun1, HUD_RAPTOR, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit);
575 vehicle_addplayerslot(self, self.gun2, HUD_RAPTOR, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit);
578 setorigin(self.gun1.vehicle_hudmodel, '90 -27 -23');
579 setorigin(self.gun1.vehicle_viewport, '-85 0 50');
581 setorigin(self.gun2.vehicle_hudmodel, '90 27 -23');
582 setorigin(self.gun2.vehicle_viewport, '-85 0 50');
587 for(i=1; gettaginfo(self.gun1, i), gettaginfo_name; ++i)
590 dprint(" ------- ^1gettaginfo_name^2(",ftos(i),") ^3=", gettaginfo_name, "\n");
595 void spawnfunc_vehicle_bumblebee()
597 if(!autocvar_g_vehicle_bumblebee)
603 precache_model ("models/vehicles/bumblebee_body.dpm");
604 precache_model ("models/vehicles/bumblebee_plasma_left.dpm");
605 precache_model ("models/vehicles/bumblebee_plasma_right.dpm");
606 precache_model ("models/vehicles/bumblebee_ray.dpm");
607 precache_model ("models/vehicles/wakizashi_cockpit.dpm");
608 precache_model ("models/vehicles/spiderbot_cockpit.dpm");
609 precache_model ("models/vehicles/raptor_cockpit.dpm");
611 if(autocvar_g_vehicle_bumblebee_energy)
612 if(autocvar_g_vehicle_bumblebee_energy_regen)
613 self.vehicle_flags |= VHF_ENERGYREGEN;
615 if(autocvar_g_vehicle_bumblebee_shield)
616 self.vehicle_flags |= VHF_HASSHIELD;
618 if(autocvar_g_vehicle_bumblebee_shield_regen)
619 self.vehicle_flags |= VHF_SHIELDREGEN;
621 if(autocvar_g_vehicle_bumblebee_health_regen)
622 self.vehicle_flags |= VHF_HEALTHREGEN;
624 self.think = bumb_dinit;
625 self.nextthink = time + 1;
630 void bumblebee_draw()
635 void bumblebee_draw2d()
640 void bumblebee_read_extra()
645 void vehicle_bumblebee_assemble()
652 vector predict_target(entity _targ, vector _from, float _shot_speed)
655 float _distance; // How far to target
656 float _impact_time; // How long untill projectile impacts
657 vector _predict_pos; // Predicted enemy location
658 vector _original_origin;// Where target is before predicted
660 _original_origin = real_origin(_targ); // Typicaly center of target BBOX
662 _predict_pos = _original_origin;
663 for(i = 0; i < 4; ++i) // Loop a few times to increase prediction accuracy (increase loop count if accuracy is to low)
665 _distance = vlen(_predict_pos - _from); // Get distance to previos predicted location
666 _impact_time = _distance / _shot_speed; // Calculate impact time
667 _predict_pos = _original_origin + _targ.velocity * _impact_time; // Calculate new predicted location