7 float autocvar_g_vehicle_bumblebee_speed_forward;
8 float autocvar_g_vehicle_bumblebee_speed_strafe;
9 float autocvar_g_vehicle_bumblebee_speed_up;
10 float autocvar_g_vehicle_bumblebee_speed_down;
11 float autocvar_g_vehicle_bumblebee_turnspeed;
12 float autocvar_g_vehicle_bumblebee_pitchspeed;
13 float autocvar_g_vehicle_bumblebee_pitchlimit;
14 float autocvar_g_vehicle_bumblebee_friction;
16 float autocvar_g_vehicle_bumblebee_energy;
17 float autocvar_g_vehicle_bumblebee_energy_regen;
18 float autocvar_g_vehicle_bumblebee_energy_regen_pause;
20 float autocvar_g_vehicle_bumblebee_health;
21 float autocvar_g_vehicle_bumblebee_health_regen;
22 float autocvar_g_vehicle_bumblebee_health_regen_pause;
24 float autocvar_g_vehicle_bumblebee_shield;
25 float autocvar_g_vehicle_bumblebee_shield_regen;
26 float autocvar_g_vehicle_bumblebee_shield_regen_pause;
28 float autocvar_g_vehicle_bumblebee_cannon_cost;
29 float autocvar_g_vehicle_bumblebee_cannon_damage;
30 float autocvar_g_vehicle_bumblebee_cannon_radius;
31 float autocvar_g_vehicle_bumblebee_cannon_refire;
32 float autocvar_g_vehicle_bumblebee_cannon_speed;
33 float autocvar_g_vehicle_bumblebee_cannon_spread;
34 float autocvar_g_vehicle_bumblebee_cannon_force;
36 float autocvar_g_vehicle_bumblebee_cannon_ammo;
37 float autocvar_g_vehicle_bumblebee_cannon_ammo_regen;
38 float autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause;
40 var float autocvar_g_vehicle_bumblebee_cannon_lock = 0;
42 float autocvar_g_vehicle_bumblebee_cannon_turnspeed;
43 float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down;
44 float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up;
45 float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
46 float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
49 float autocvar_g_vehicle_bumblebee_raygun_turnspeed;
50 float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down;
51 float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up;
52 float autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides;
54 float autocvar_g_vehicle_bumblebee_raygun_range;
55 float autocvar_g_vehicle_bumblebee_raygun_dps;
56 float autocvar_g_vehicle_bumblebee_raygun_aps;
57 float autocvar_g_vehicle_bumblebee_raygun_fps;
59 float autocvar_g_vehicle_bumblebee_raygun;
60 float autocvar_g_vehicle_bumblebee_healgun_hps;
61 float autocvar_g_vehicle_bumblebee_healgun_hmax;
62 float autocvar_g_vehicle_bumblebee_healgun_aps;
63 float autocvar_g_vehicle_bumblebee_healgun_amax;
64 float autocvar_g_vehicle_bumblebee_healgun_sps;
66 float autocvar_g_vehicle_bumblebee_respawntime;
68 float autocvar_g_vehicle_bumblebee_blowup_radius;
69 float autocvar_g_vehicle_bumblebee_blowup_coredamage;
70 float autocvar_g_vehicle_bumblebee_blowup_edgedamage;
71 float autocvar_g_vehicle_bumblebee_blowup_forceintensity;
73 float autocvar_g_vehicle_bumblebee = 0;
76 float bumble_raygun_send ( entity to, float sf )
78 #define BUMB_MIN '-120 -120 -120'
79 #define BUMB_MAX '120 120 120'
81 void bumb_fire_cannon ( entity _gun, string _tagname, entity _owner )
83 float b = autocvar_g_vehicle_bumblebee;
89 v = gettaginfo ( _gun, gettagindex ( _gun, _tagname ) );
90 bolt = vehicles_projectile ( "bigplasma_muzzleflash", "weapons/flacexp3.wav",
91 v, normalize ( v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread ) * autocvar_g_vehicle_bumblebee_cannon_speed,
92 autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0,
93 DEATH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner );
96 //bolt.velocity = v_forward * autocvar_g_vehicle_bumblebee_cannon_speed;
102 float bumb_gunner_frame()
104 entity vehic = self.vehicle.owner;
105 entity gun = self.vehicle;
106 entity gunner = self;
109 vehic.solid = SOLID_NOT;
110 setorigin ( gunner, vehic.origin );
111 gunner.velocity = vehic.velocity;
112 crosshair_trace ( gunner );
113 vector _ct = trace_endpos;
116 float _in = ( ( gun == vehic.gun1 ) ? autocvar_g_vehicle_bumblebee_cannon_turnlimit_in : autocvar_g_vehicle_bumblebee_cannon_turnlimit_out );
117 float _out = ( ( gun == vehic.gun1 ) ? autocvar_g_vehicle_bumblebee_cannon_turnlimit_out : autocvar_g_vehicle_bumblebee_cannon_turnlimit_in );
119 if ( autocvar_g_vehicle_bumblebee_cannon_lock )
121 if ( gun.lock_time < time )
125 if ( trace_ent.movetype )
126 if ( trace_ent.takedamage )
127 if ( !trace_ent.deadflag )
131 if ( trace_ent.team != gunner.team )
133 gun.enemy = trace_ent;
134 gun.lock_time = time + 5;
139 gun.enemy = trace_ent;
140 gun.lock_time = time + 5;
147 float i, distance, impact_time;
149 vector vf = real_origin ( gun.enemy );
150 vector _vel = gun.enemy.velocity;
151 if ( gun.enemy.movetype == MOVETYPE_WALK )
156 for ( i = 0; i < 4; ++i )
158 distance = vlen ( ad - gunner.origin );
159 impact_time = distance / autocvar_g_vehicle_bumblebee_cannon_speed;
160 ad = vf + _vel * impact_time;
165 UpdateAuxiliaryXhair ( gunner, ad, '1 0 1', 1 );
166 vehicle_aimturret ( vehic, trace_endpos, gun, "fire",
167 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
168 _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed );
172 vehicle_aimturret ( vehic, _ct, gun, "fire",
173 autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up,
174 _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed );
176 if ( gunner.BUTTON_ATCK )
177 if ( time > gun.attack_finished_single )
178 if ( gun.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost )
180 gun.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost;
181 bumb_fire_cannon ( gun, "fire", gunner );
183 gun.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire;
186 VEHICLE_UPDATE_PLAYER (gunner, health, bumblebee);
188 if ( vehic.vehicle_flags & VHF_HASSHIELD )
189 VEHICLE_UPDATE_PLAYER (gunner, shield, bumblebee);
191 ad = gettaginfo ( gun, gettagindex ( gun, "fire" ) );
192 traceline ( ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, gun );
194 UpdateAuxiliaryXhair ( gunner, trace_endpos, ( '1 0 0' * gunner.vehicle_reload1 ) + ( '0 1 0' * ( 1 - gunner.vehicle_reload1 ) ), 0 );
197 UpdateAuxiliaryXhair ( vehic.owner, trace_endpos, ( '1 0 0' * gunner.vehicle_reload1 ) + ( '0 1 0' * ( 1 - gunner.vehicle_reload1 ) ), ( ( gunner == vehic.gunner1 ) ? 1 : 2 ) );
199 vehic.solid = SOLID_BBOX;
200 gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0;
201 gunner.vehicle_energy = ( gun.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo ) * 100;
207 void bumb_gunner_exit ( float _exitflag )
209 if ( clienttype ( self ) == CLIENTTYPE_REAL )
212 WriteByte ( MSG_ONE, SVC_SETVIEWPORT );
213 WriteEntity ( MSG_ONE, self );
215 WriteByte ( MSG_ONE, SVC_SETVIEWANGLES );
216 WriteAngle ( MSG_ONE, 0 );
217 WriteAngle ( MSG_ONE, self.vehicle.angles_y );
218 WriteAngle ( MSG_ONE, 0 );
221 setsize ( self, PL_MIN, PL_MAX );
223 self.takedamage = DAMAGE_AIM;
224 self.solid = SOLID_SLIDEBOX;
225 self.movetype = MOVETYPE_WALK;
226 self.effects &~= EF_NODRAW;
228 self.PlayerPhysplug = SUB_Null;
229 self.view_ofs = PL_VIEW_OFS;
230 self.event_damage = PlayerDamage;
231 self.hud = HUD_NORMAL;
232 self.switchweapon = self.vehicle.switchweapon;
234 if ( self.flagcarried )
236 self.flagcarried.scale = 0.6;
237 setattachment ( self.flagcarried, self, "" );
238 setorigin ( self.flagcarried, FLAG_CARRY_POS );
241 CSQCVehicleSetup ( self, HUD_NORMAL );
242 self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle;
244 if ( self == self.vehicle.owner.gunner1 )
245 self.vehicle.owner.gunner1 = world;
246 else if ( self == self.vehicle.owner.gunner2 )
247 self.vehicle.owner.gunner2 = world;
249 dprint ( "^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n" );
251 self.vehicle.phase = time + 5;
252 self.vehicle = world;
255 float bumb_gunner_enter()
257 RemoveGrapplingHook ( other );
258 entity _gun, _gunner;
262 _gunner = self.gunner1;
263 self.gunner1 = other;
265 else if ( !self.gunner2 )
268 _gunner = self.gunner2;
269 self.gunner2 = other;
273 dprint ( "^1ERROR:^7Tried to enter a fully occupied vehicle!\n" );
278 _gunner.vehicle = _gun;
279 _gun.switchweapon = other.switchweapon;
280 _gun.vehicle_exit = bumb_gunner_exit;
282 other.angles = self.angles;
283 other.takedamage = DAMAGE_NO;
284 other.solid = SOLID_NOT;
285 other.movetype = MOVETYPE_NOCLIP;
287 other.event_damage = SUB_Null;
288 other.view_ofs = '0 0 0';
289 other.hud = _gun.hud;
290 other.PlayerPhysplug = _gun.PlayerPhysplug;
291 other.vehicle_ammo1 = self.vehicle_ammo1;
292 other.vehicle_ammo2 = self.vehicle_ammo2;
293 other.vehicle_reload1 = self.vehicle_reload1;
294 other.vehicle_reload2 = self.vehicle_reload2;
295 other.vehicle_energy = self.vehicle_energy;
296 other.PlayerPhysplug = bumb_gunner_frame;
297 other.flags &~= FL_ONGROUND;
300 WriteByte ( MSG_ONE, SVC_SETVIEWPORT );
301 WriteEntity ( MSG_ONE, _gun.vehicle_viewport );
302 WriteByte ( MSG_ONE, SVC_SETVIEWANGLES );
303 WriteAngle ( MSG_ONE, _gun.angles_x + self.angles_x ); // tilt
304 WriteAngle ( MSG_ONE, _gun.angles_y + self.angles_y ); // yaw
305 WriteAngle ( MSG_ONE, 0 ); // roll
306 _gun.vehicle_hudmodel.viewmodelforclient = other;
308 CSQCVehicleSetup ( other, other.hud );
313 float vehicles_valid_pilot()
315 if ( other.classname != "player" )
318 if ( other.deadflag != DEAD_NO )
321 if ( other.vehicle != world )
324 if ( clienttype ( other ) != CLIENTTYPE_REAL )
325 if ( !autocvar_g_vehicles_allow_bots )
328 if ( teamplay && other.team != self.team )
337 if ( self.gunner1 != world && self.gunner2 != world )
343 if ( vehicles_valid_pilot() )
345 if ( self.gun1.phase <= time )
346 if ( bumb_gunner_enter() )
349 if ( self.gun2.phase <= time )
350 if ( bumb_gunner_enter() )
360 if ( self.gun1.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time )
361 self.gun1.vehicle_energy = min ( autocvar_g_vehicle_bumblebee_cannon_ammo,
362 self.gun1.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime );
364 if ( self.gun2.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time )
365 self.gun2.vehicle_energy = min ( autocvar_g_vehicle_bumblebee_cannon_ammo,
366 self.gun2.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime );
370 vehicles_regen( self.gun1.delay, vehicle_ammo1, autocvar_g_vehicle_bumblebee_cannon_ammo,
371 autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause,
372 autocvar_g_vehicle_bumblebee_cannon_ammo_regen, frametime, FALSE);
374 vehicles_regen( self.gun2.delay, vehicle_ammo2, autocvar_g_vehicle_bumblebee_cannon_ammo,
375 autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause,
376 autocvar_g_vehicle_bumblebee_cannon_ammo_regen, frametime, FALSE);
379 if ( self.vehicle_flags & VHF_SHIELDREGEN )
380 vehicles_regen ( self.dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, TRUE );
382 if ( self.vehicle_flags & VHF_HEALTHREGEN )
383 vehicles_regen ( self.dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, FALSE );
385 if ( self.vehicle_flags & VHF_ENERGYREGEN )
386 vehicles_regen ( self.wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, FALSE );
390 float bumb_pilot_frame()
396 vehic = self.vehicle;
400 if ( vehic.deadflag != DEAD_NO )
403 pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0;
409 crosshair_trace ( pilot );
415 newvel = vectoangles ( normalize ( trace_endpos - self.origin + '0 0 32' ) );
418 if ( newvel_x > 180 ) newvel_x -= 360;
419 if ( newvel_x < -180 ) newvel_x += 360;
420 if ( newvel_y > 180 ) newvel_y -= 360;
421 if ( newvel_y < -180 ) newvel_y += 360;
423 ftmp = shortangle_f ( pilot.v_angle_y - vang_y, vang_y );
424 if ( ftmp > 180 ) ftmp -= 360;
425 if ( ftmp < -180 ) ftmp += 360;
426 vehic.avelocity_y = bound ( -autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed );
430 if ( pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit ) ftmp = 5;
431 else if ( pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit ) ftmp = -20;
433 newvel_x = bound ( -autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit );
434 ftmp = vang_x - bound ( -autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit );
435 vehic.avelocity_x = bound ( -autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed );
437 vehic.angles_x = anglemods ( vehic.angles_x );
438 vehic.angles_y = anglemods ( vehic.angles_y );
439 vehic.angles_z = anglemods ( vehic.angles_z );
441 makevectors ( '0 1 0' * vehic.angles_y );
442 newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
444 if ( pilot.movement_x != 0 )
446 if ( pilot.movement_x > 0 )
447 newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
448 else if ( pilot.movement_x < 0 )
449 newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
452 if ( pilot.movement_y != 0 )
454 if ( pilot.movement_y < 0 )
455 newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
456 else if ( pilot.movement_y > 0 )
457 newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
458 ftmp = newvel * v_right;
459 ftmp *= frametime * 0.1;
460 vehic.angles_z = bound ( -15, vehic.angles_z + ftmp, 15 );
464 vehic.angles_z *= 0.95;
465 if ( vehic.angles_z >= -1 && vehic.angles_z <= -1 )
469 if ( pilot.BUTTON_CROUCH )
470 newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down;
471 else if ( pilot.BUTTON_JUMP )
472 newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up;
474 vehic.velocity += newvel * frametime;
475 pilot.velocity = pilot.movement = vehic.velocity;
476 setorigin ( pilot, vehic.origin + '0 0 32' );
478 vehicle_aimturret ( vehic, trace_endpos, self.gun3, "fire",
479 autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up,
480 autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1, autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides, autocvar_g_vehicle_bumblebee_raygun_turnspeed );
483 if ( ( pilot.BUTTON_ATCK || pilot.BUTTON_ATCK2 ) && vehic.vehicle_energy > autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime )
486 if ( vehic.gun3.enemy == world )
488 vehic.gun3.enemy = spawn();
489 Net_LinkEntity ( vehic.gun3.enemy, FALSE, 0, bumble_raygun_send );
490 vehic.gun3.enemy.SendFlags = BRG_SETUP;
491 vehic.gun3.enemy.think = SUB_Remove;
492 vehic.gun3.enemy.realowner = pilot;
493 vehic.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun;
496 vehic.gun3.enemy.nextthink = time + 0.1;
497 setorigin ( vehic.gun3.enemy, gettaginfo ( vehic.gun3, gettagindex ( vehic.gun3, "fire" ) ) );
498 traceline ( vehic.gun3.enemy.origin, vehic.gun3.enemy.origin + v_forward * autocvar_g_vehicle_bumblebee_raygun_range, MOVE_NORMAL, vehic );
501 if ( autocvar_g_vehicle_bumblebee_raygun )
503 Damage ( trace_ent, vehic, pilot, autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime, DEATH_GENERIC, trace_endpos, v_forward * autocvar_g_vehicle_bumblebee_raygun_fps * sys_frametime );
504 vehic.vehicle_energy -= autocvar_g_vehicle_bumblebee_raygun_aps * sys_frametime;
508 if ( trace_ent.deadflag == DEAD_NO )
509 if ( ( teamplay && trace_ent.team == pilot.team ) || !teamplay )
512 if ( trace_ent.vehicle_flags & VHF_ISVEHICLE )
514 if ( autocvar_g_vehicle_bumblebee_healgun_sps && trace_ent.vehicle_health <= trace_ent.tur_health )
515 trace_ent.vehicle_shield = min ( trace_ent.vehicle_shield + autocvar_g_vehicle_bumblebee_healgun_sps * frametime, trace_ent.tur_head.tur_health );
517 if ( autocvar_g_vehicle_bumblebee_healgun_hps )
518 trace_ent.vehicle_health = min ( trace_ent.vehicle_health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health );
520 else if ( trace_ent.flags & FL_CLIENT )
522 if ( trace_ent.health <= autocvar_g_vehicle_bumblebee_healgun_hmax && autocvar_g_vehicle_bumblebee_healgun_hps )
523 trace_ent.health = min ( trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax );
525 if ( trace_ent.armorvalue <= autocvar_g_vehicle_bumblebee_healgun_amax && autocvar_g_vehicle_bumblebee_healgun_aps )
526 trace_ent.armorvalue = min ( trace_ent.armorvalue + autocvar_g_vehicle_bumblebee_healgun_aps * frametime, autocvar_g_vehicle_bumblebee_healgun_amax );
528 trace_ent.health = min ( trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax );
530 else if ( trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET )
532 if ( trace_ent.health <= trace_ent.tur_health && autocvar_g_vehicle_bumblebee_healgun_hps )
533 trace_ent.health = min ( trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health );
534 //else ..hmmm what? ammo?
536 trace_ent.SendFlags |= TNSF_STATUS;
541 vehic.gun3.enemy.hook_end = trace_endpos;
542 vehic.gun3.enemy.SendFlags |= BRG_START;
543 vehic.gun3.enemy.SendFlags |= BRG_END;
544 vehic.wait = time + 1;
548 if ( vehic.gun3.enemy )
549 remove ( vehic.gun3.enemy );
551 vehic.gun3.enemy = world;
554 VEHICLE_UPDATE_PLAYER ( pilot, health, bumblebee);
555 VEHICLE_UPDATE_PLAYER ( pilot, energy, bumblebee);
557 pilot.vehicle_ammo1 = ( vehic.gun1.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo ) * 100;
558 pilot.vehicle_ammo2 = ( vehic.gun2.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo ) * 100;
560 if ( vehic.vehicle_flags & VHF_HASSHIELD )
561 VEHICLE_UPDATE_PLAYER ( pilot, shield, bumblebee);
564 pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0;
572 self.velocity = self.velocity * 0.99;
573 self.nextthink = time + 0.1;
578 self.touch = bumb_touch;
581 void bumb_exit ( float eject )
584 self.touch = vehicles_touch;
589 self.deadflag = DEAD_DEAD;
591 RadiusDamage ( self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage,
592 autocvar_g_vehicle_bumblebee_blowup_edgedamage,
593 autocvar_g_vehicle_bumblebee_blowup_radius, self,
594 autocvar_g_vehicle_bumblebee_blowup_forceintensity,
595 DEATH_WAKIBLOWUP, world );
597 self.movetype = MOVETYPE_NONE;
598 self.effects = EF_NODRAW;
599 self.colormod = '0 0 0';
600 self.avelocity = '0 0 0';
601 self.velocity = '0 0 0';
603 //entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime)
604 fixedmakevectors ( self.angles );
605 vehicle_tossgib ( self.gun1, self.velocity + v_right * 300 + v_up * 100 + randomvec() * 200, "cannon_right", rint ( random() ), rint ( random() ), 6, randomvec() * 300 );
606 vehicle_tossgib ( self.gun2, self.velocity + v_right * -300 + v_up * 100 + randomvec() * 200, "cannon_left", rint ( random() ), rint ( random() ), 6, randomvec() * 300 );
607 vehicle_tossgib ( self.gun3, self.velocity + v_forward * 300 + v_up * -100 + randomvec() * 200, "raygun", rint ( random() ), rint ( random() ), 6, randomvec() * 300 );
609 sound ( self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM );
610 pointparticles ( particleeffectnum ( "explosion_large" ), randomvec() * 80 + ( self.origin + '0 0 100' ), '0 0 0', 1 );
612 setorigin ( self, self.pos1 );
613 self.touch = SUB_Null;
619 if ( time >= self.wait )
620 self.think = bumb_blowup;
622 if ( random() < 0.1 )
624 sound ( self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM );
625 pointparticles ( particleeffectnum ( "explosion_small" ), randomvec() * 80 + ( self.origin + '0 0 100' ), '0 0 0', 1 );
628 self.nextthink = time + 0.1;
633 entity oldself = self;
637 oldself.gun1.vehicle_exit ( VHEF_EJECT );
644 oldself.gun2.vehicle_exit ( VHEF_EJECT );
648 self.vehicle_exit ( VHEF_EJECT );
651 self.event_damage = SUB_Null;
652 self.solid = SOLID_CORPSE;
653 self.takedamage = DAMAGE_NO;
654 self.deadflag = DEAD_DYING;
655 self.movetype = MOVETYPE_BOUNCE;
656 self.think = bumb_diethink;
657 self.nextthink = time;
658 self.wait = time + 2 + ( random() * 8 );
660 self.avelocity = '0 0.5 1' * ( random() * 400 );
661 self.avelocity -= '0 0.5 1' * ( random() * 400 );
663 self.colormod = '-0.5 -0.5 -0.5';
664 self.touch = bumb_blowup;
666 pointparticles ( particleeffectnum ( "explosion_medium" ), findbetterlocation ( self.origin, 16 ), '0 0 0', 1 );
670 void bumb_spawn ( float _f )
674 for(i=1; gettaginfo(self.gun1, i), gettaginfo_name; ++i)
677 dprint(" ------- ^1gettaginfo_name^2(",ftos(i),") ^3=", gettaginfo_name, "\n");
683 // for some reason, autosizing of the shiled entity refuses to work for this one so set it up in advance.
684 self.vehicle_shieldent = spawn();
685 self.vehicle_shieldent.effects = EF_LOWPRECISION;
686 setmodel ( self.vehicle_shieldent, "models/vhshield.md3" );
687 setattachment ( self.vehicle_shieldent, self, "" );
688 setorigin ( self.vehicle_shieldent, real_origin ( self ) - self.origin );
689 self.vehicle_shieldent.scale = 512 / vlen ( self.maxs - self.mins );
690 self.vehicle_shieldent.think = shieldhit_think;
691 self.vehicle_shieldent.alpha = -1;
692 self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW;
698 self.vehicle_flags |= VHF_MULTISLOT;
700 self.gun1.owner = self;
701 self.gun2.owner = self;
702 self.gun3.owner = self;
704 setmodel ( self.gun1, "models/vehicles/bumblebee_plasma_right.dpm" );
705 setmodel ( self.gun2, "models/vehicles/bumblebee_plasma_left.dpm" );
706 setmodel ( self.gun3, "models/vehicles/bumblebee_ray.dpm" );
708 setattachment ( self.gun1, self, "cannon_right" );
709 setattachment ( self.gun2, self, "cannon_left" );
711 // Angled bones are no fun, messes up gun-aim; so work arround it.
712 self.gun3.pos1 = self.angles;
713 self.angles = '0 0 0';
714 vector ofs = gettaginfo ( self, gettagindex ( self, "raygun" ) );
716 setattachment ( self.gun3, self, "" );
717 setorigin ( self.gun3, ofs );
718 self.angles = self.gun3.pos1;
720 vehicle_addplayerslot ( self, self.gun1, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit );
721 vehicle_addplayerslot ( self, self.gun2, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit );
723 setorigin ( self.vehicle_hudmodel, '45 0 45' ); // Move cockpit up-forward.
724 setorigin ( self.vehicle_viewport, '8 0 5' ); // Move camera up-forward too.
727 setorigin ( self.gun1.vehicle_hudmodel, '90 -27 -23' );
728 setorigin ( self.gun1.vehicle_viewport, '-85 0 50' );
730 setorigin ( self.gun2.vehicle_hudmodel, '90 27 -23' );
731 setorigin ( self.gun2.vehicle_viewport, '-85 0 50' );
736 self.vehicle_health = autocvar_g_vehicle_bumblebee_health;
737 self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield;
738 self.movetype = MOVETYPE_TOSS;
739 self.solid = SOLID_BBOX;
740 self.movetype = MOVETYPE_FLY;
741 setorigin ( self, self.origin + '0 0 25' );
744 void spawnfunc_vehicle_bumblebee()
746 if ( !autocvar_g_vehicle_bumblebee )
752 precache_model ( "models/vehicles/bumblebee_body.dpm" );
753 precache_model ( "models/vehicles/bumblebee_plasma_left.dpm" );
754 precache_model ( "models/vehicles/bumblebee_plasma_right.dpm" );
755 precache_model ( "models/vehicles/bumblebee_ray.dpm" );
756 precache_model ( "models/vehicles/wakizashi_cockpit.dpm" );
757 precache_model ( "models/vehicles/spiderbot_cockpit.dpm" );
758 precache_model ( "models/vehicles/raptor_cockpit.dpm" );
760 if ( autocvar_g_vehicle_bumblebee_energy )
761 if ( autocvar_g_vehicle_bumblebee_energy_regen )
762 self.vehicle_flags |= VHF_ENERGYREGEN;
764 if ( autocvar_g_vehicle_bumblebee_shield )
765 self.vehicle_flags |= VHF_HASSHIELD;
767 if ( autocvar_g_vehicle_bumblebee_shield_regen )
768 self.vehicle_flags |= VHF_SHIELDREGEN;
770 if ( autocvar_g_vehicle_bumblebee_health_regen )
771 self.vehicle_flags |= VHF_HEALTHREGEN;
773 if not ( vehicle_initialize (
774 "Bumblebee", "models/vehicles/bumblebee_body.dpm",
775 "", "models/vehicles/spiderbot_cockpit.dpm", "", "", "tag_viewport",
776 HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, FALSE,
777 bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime,
778 bumb_pilot_frame, bumb_enter, bumb_exit,
779 bumb_die, bumb_think, FALSE, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_shield ) )
786 float bumble_raygun_send ( entity to, float sf )
788 WriteByte ( MSG_ENTITY, ENT_CLIENT_BUMBLE_RAYGUN );
790 WriteByte ( MSG_ENTITY, sf );
791 if ( sf & BRG_SETUP )
793 WriteByte ( MSG_ENTITY, num_for_edict ( self.realowner ) );
794 WriteByte ( MSG_ENTITY, self.realowner.team );
795 WriteByte ( MSG_ENTITY, self.cnt );
797 //WriteCoord(MSG_ENTITY, autocvar_g_balance_electro_primary_range);
800 if ( sf & BRG_START )
802 WriteCoord ( MSG_ENTITY, self.origin_x );
803 WriteCoord ( MSG_ENTITY, self.origin_y );
804 WriteCoord ( MSG_ENTITY, self.origin_z );
809 WriteCoord ( MSG_ENTITY, self.hook_end_x );
810 WriteCoord ( MSG_ENTITY, self.hook_end_y );
811 WriteCoord ( MSG_ENTITY, self.hook_end_z );
825 void bumble_raygun_draw()
829 vector _vtmp1, _vtmp2;
831 _len = vlen ( self.origin - self.move_origin );
832 _dir = normalize ( self.move_origin - self.origin );
835 self.raygun_l1 = 0.5 * self.raygun_l1;
836 self.raygun_l2 = 0.5 * self.raygun_l2;
837 self.raygun_l3 = 0.5 * self.raygun_l3;
839 self.raygun_l1 += randomvec() * (_len * 0.2) * (frametime * 10);
840 self.raygun_l2 += randomvec() * (_len * 0.2) * (frametime * 5);
841 self.raygun_l3 += randomvec() * (_len * 0.2) * (frametime * 2) ;
845 for ( i = -0.1; i < 0.2; i += 0.1 )
847 df = DRAWFLAG_NORMAL; //((random() < 0.5) ? DRAWFLAG_ADDITIVE : DRAWFLAG_SCREEN);
848 sz = 2 + random() * 6;
849 al = 0.25 + random() * 0.5;
850 _vtmp1 = self.origin + _dir * _len * ( 0.25 + i );
851 _vtmp1 += ( randomvec() * ( _len * 0.2 ) * ( frametime * 2 ) ); //self.raygun_l1;
852 Draw_CylindricLine ( self.origin, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin );
854 _vtmp2 = self.origin + _dir * _len * ( 0.5 + i );
855 _vtmp2 += ( randomvec() * ( _len * 0.2 ) * ( frametime * 5 ) ); //self.raygun_l2;
856 Draw_CylindricLine ( _vtmp1, _vtmp2, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin );
858 _vtmp1 = self.origin + _dir * _len * ( 0.75 + i );
859 _vtmp1 += randomvec() * ( _len * 0.2 ) * ( frametime * 10 ); //self.raygun_l3;
860 Draw_CylindricLine ( _vtmp2, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin );
862 Draw_CylindricLine ( _vtmp1, self.move_origin + randomvec() * 32, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin );
867 void bumble_raygun_read ( float bIsNew )
869 float sf = ReadByte();
871 if ( sf & BRG_SETUP )
873 self.cnt = ReadByte(); //WriteByte(MSG_ENTITY, num_for_edict(self.realowner));
874 self.team = ReadByte(); //WriteByte(MSG_ENTITY, num_for_edict(self.realowner.team));
875 self.cnt = ReadByte(); //WriteByte(MSG_ENTITY, num_for_edict(self.cnt));
877 self.colormod = '1 0 0';
879 self.colormod = '0 1 0';
881 self.draw = bumble_raygun_draw;
883 //WriteCoord(MSG_ENTITY, autocvar_g_balance_electro_primary_range);
886 if ( sf & BRG_START )
888 self.origin_x = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_start_x);
889 self.origin_y = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_start_y);
890 self.origin_z = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_start_z);
891 setorigin ( self, self.origin );
896 self.move_origin_x = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_end_x);
897 self.move_origin_y = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_end_y);
898 self.move_origin_z = ReadCoord(); //WriteCoord(MSG_ENTITY, self.hook_end_z);
902 void bumblebee_draw()
907 void bumblebee_draw2d()
912 void bumblebee_read_extra()
917 void vehicle_bumblebee_assemble()
924 vector predict_target(entity _targ, vector _from, float _shot_speed)
927 float _distance; // How far to target
928 float _impact_time; // How long untill projectile impacts
929 vector _predict_pos; // Predicted enemy location
930 vector _original_origin;// Where target is before predicted
932 _original_origin = real_origin(_targ); // Typicaly center of target BBOX
934 _predict_pos = _original_origin;
935 for(i = 0; i < 4; ++i) // Loop a few times to increase prediction accuracy (increase loop count if accuracy is to low)
937 _distance = vlen(_predict_pos - _from); // Get distance to previos predicted location
938 _impact_time = _distance / _shot_speed; // Calculate impact time
939 _predict_pos = _original_origin + _targ.velocity * _impact_time; // Calculate new predicted location