]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/vehicles/unit/bumblebee.qc
Merge branch 'master' into Mario/vehicles
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / unit / bumblebee.qc
index d01d192d3ffcb4480c4e18b06a5f73cc7414729a..cc52716c79f4761c91fc83b3a00d768a4108f3a1 100644 (file)
@@ -51,7 +51,7 @@ float autocvar_g_vehicle_bumblebee_cannon_ammo;
 float autocvar_g_vehicle_bumblebee_cannon_ammo_regen;
 float autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause;
 
-var float autocvar_g_vehicle_bumblebee_cannon_lock = 0;
+float autocvar_g_vehicle_bumblebee_cannon_lock = 0;
 
 float autocvar_g_vehicle_bumblebee_cannon_turnspeed;
 float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down;
@@ -84,12 +84,11 @@ float autocvar_g_vehicle_bumblebee_blowup_radius;
 float autocvar_g_vehicle_bumblebee_blowup_coredamage;
 float autocvar_g_vehicle_bumblebee_blowup_edgedamage;
 float autocvar_g_vehicle_bumblebee_blowup_forceintensity;
-var vector autocvar_g_vehicle_bumblebee_bouncepain;
+vector autocvar_g_vehicle_bumblebee_bouncepain;
 
-var float autocvar_g_vehicle_bumblebee = 0;
+bool autocvar_g_vehicle_bumblebee = 0;
 
-
-float bumble_raygun_send(entity to, float sf);
+float bumble_raygun_send(entity to, int sf);
 
 void bumblebee_fire_cannon(entity _gun, string _tagname, entity _owner)
 {
@@ -97,7 +96,7 @@ void bumblebee_fire_cannon(entity _gun, string _tagname, entity _owner)
        vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav",
                                                v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
                                                autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force,  0,
-                                               DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner);
+                                               DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, true, true, _owner);
 }
 
 float bumblebee_gunner_frame()
@@ -115,7 +114,7 @@ float bumblebee_gunner_frame()
        vehic.angles_x *= -1;
        makevectors(vehic.angles);
        vehic.angles_x *= -1;
-       if((gun == vehic.gun1))
+       if(gun == vehic.gun1)
        {
                _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
                _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
@@ -142,15 +141,7 @@ float bumblebee_gunner_frame()
                                if(trace_ent.takedamage)
                                        if(!trace_ent.deadflag)
                                        {
-                                               if(teamplay)
-                                               {
-                                                       if(trace_ent.team != gunner.team)
-                                                       {
-                                                               gun.enemy = trace_ent;
-                                                               gun.lock_time = time + 5;
-                                                       }
-                                               }
-                                               else
+                                               if(DIFF_TEAM(trace_ent, gunner))
                                                {
                                                        gun.enemy = trace_ent;
                                                        gun.lock_time = time + 5;
@@ -165,7 +156,7 @@ float bumblebee_gunner_frame()
                vector vf = real_origin(gun.enemy);
                vector _vel = gun.enemy.velocity;
                if(gun.enemy.movetype == MOVETYPE_WALK)
-                       _vel_z *= 0.1;
+                       _vel.z *= 0.1;
 
 
                ad = vf;
@@ -218,156 +209,167 @@ float bumblebee_gunner_frame()
        return 1;
 }
 
-void bumblebee_gunner_exit(float _exitflag)
+vector bumblebee_gunner_findgoodexit(vector prefer_spot, entity gunner, entity player)
+{
+       //vector exitspot;
+       float mysize;
+
+       tracebox(gunner.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, player);
+       if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+               return prefer_spot;
+
+       mysize = 1.5 * vlen(PL_MAX - PL_MIN); // can't use gunner's size, as they don't have a size
+       float i;
+       vector v, v2;
+       v2 = 0.5 * (gunner.absmin + gunner.absmax);
+       for(i = 0; i < 100; ++i)
+       {
+               v = randomvec();
+               v_z = 0;
+               v = v2 + normalize(v) * mysize;
+               tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, player);
+               if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+                       return v;
+       }
+
+       return prefer_spot; // this should be considered a fallback?!
+}
+
+void bumblebee_gunner_exit(int _exitflag)
 {
-       if(IS_REAL_CLIENT(self))
+       entity player = self;
+       entity gunner = player.vehicle;
+       entity vehic = gunner.owner;
+
+       if(IS_REAL_CLIENT(player))
        {
-               msg_entity = self;
+               msg_entity = player;
                WriteByte(MSG_ONE, SVC_SETVIEWPORT);
-               WriteEntity(MSG_ONE, self);
+               WriteEntity(MSG_ONE, player);
 
                WriteByte(MSG_ONE, SVC_SETVIEWANGLES);
                WriteAngle(MSG_ONE, 0);
-               WriteAngle(MSG_ONE, self.vehicle.angles_y);
+               WriteAngle(MSG_ONE, vehic.angles.y);
                WriteAngle(MSG_ONE, 0);
        }
 
-       CSQCVehicleSetup(self, HUD_NORMAL);
-       setsize(self, PL_MIN, PL_MAX);
+       CSQCVehicleSetup(player, HUD_NORMAL);
+       setsize(player, PL_MIN, PL_MAX);
 
-       self.takedamage     = DAMAGE_AIM;
-       self.solid          = SOLID_SLIDEBOX;
-       self.movetype       = MOVETYPE_WALK;
-       self.effects        &= ~EF_NODRAW;
-       self.alpha          = 1;
-       self.PlayerPhysplug = func_null;
-       self.view_ofs       = PL_VIEW_OFS;
-       self.event_damage   = PlayerDamage;
-       self.hud            = HUD_NORMAL;
-       self.teleportable       = TELEPORT_NORMAL;
-       self.switchweapon   = self.vehicle.switchweapon;
+       player.takedamage     = DAMAGE_AIM;
+       player.solid          = SOLID_SLIDEBOX;
+       player.movetype       = MOVETYPE_WALK;
+       player.effects       &= ~EF_NODRAW;
+       player.alpha          = 1;
+       player.PlayerPhysplug = func_null;
+       player.view_ofs       = PL_VIEW_OFS;
+       player.event_damage   = PlayerDamage;
+       player.hud            = HUD_NORMAL;
+       player.teleportable       = TELEPORT_NORMAL;
+       player.switchweapon   = gunner.switchweapon;
+       player.vehicle_enter_delay = time + 2;
 
-    vh_player = self;
-    vh_vehicle = self.vehicle;
-    MUTATOR_CALLHOOK(VehicleExit);
-    self = vh_player;
-    self.vehicle = vh_vehicle;
+       fixedmakevectors(vehic.angles);
 
-       self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle;
+       if(player == vehic.gunner1) { vehic.gunner1 = world; }
+       if(player == vehic.gunner2) { vehic.gunner2 = world; v_right *= -1; }
 
-       fixedmakevectors(self.vehicle.owner.angles);
+       vector spot = real_origin(gunner);
+       spot = spot + v_up * 128 + v_forward * 300 + v_right * 150;
+       spot = bumblebee_gunner_findgoodexit(spot, gunner, player);
 
-       if(self == self.vehicle.owner.gunner1)
-       {
-               self.vehicle.owner.gunner1 = world;
-       }
-       else if(self == self.vehicle.owner.gunner2)
-       {
-               self.vehicle.owner.gunner2 = world;
-               v_right *= -1;
-       }
-       else
-               dprint("^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n");
+       // TODO: figure a way to move player out of the gunner
 
-       vector spot = self.vehicle.owner.origin + + v_up * 128 + v_right * 300;
-       spot = vehicles_findgoodexit(spot);
-       //setorigin(self , spot);
+       player.velocity = 0.75 * vehic.velocity + normalize(spot - vehic.origin) * 200;
+       player.velocity_z += 10;
 
-       self.velocity = 0.75 * self.vehicle.owner.velocity + normalize(spot - self.vehicle.owner.origin) * 200;
-       self.velocity_z += 10;
+       gunner.phase = time + 5;
+       gunner.vehicle_hudmodel.viewmodelforclient = gunner;
 
-       self.vehicle.phase = time + 5;
-       self.vehicle        = world;
+       MUTATOR_CALLHOOK(VehicleExit, player, gunner);
+
+       player.vehicle = world;
 }
 
-float bumblebee_gunner_enter()
+bool bumblebee_gunner_enter()
 {
-       RemoveGrapplingHook(other);
-       entity _gun, _gunner;
-       if(!self.gunner1)
-       {
-               _gun = self.gun1;
-               _gunner = self.gunner1;
-               self.gunner1 = other;
-       }
-       else if(!self.gunner2)
-       {
-               _gun = self.gun2;
-               _gunner = self.gunner2;
-               self.gunner2 = other;
-       }
-       else
+       entity vehic = self;
+       entity player = other;
+       entity gunner = world;
+
+       if(!vehic.gunner1 && !vehic.gunner2 && ((time >= vehic.gun1.phase) + (time >= vehic.gun2.phase)) == 2)
        {
-               dprint("^1ERROR:^7Tried to enter a fully occupied vehicle!\n");
-               return FALSE;
+               // we can have some fun
+               if(vlen(real_origin(vehic.gun2) - player.origin) < vlen(real_origin(vehic.gun1) - player.origin))
+               {
+                       gunner = vehic.gun2;
+                       vehic.gunner2 = player;
+               }
+               else
+               {
+                       gunner = vehic.gun1;
+                       vehic.gunner1 = player;
+               }
        }
-
-       _gunner            = other;
-       _gunner.vehicle    = _gun;
-       _gun.switchweapon  = other.switchweapon;
-       _gun.vehicle_exit  = bumblebee_gunner_exit;
-
-       other.angles            = self.angles;
-       other.takedamage        = DAMAGE_NO;
-       other.solid             = SOLID_NOT;
-       other.movetype          = MOVETYPE_NOCLIP;
-       other.alpha             = -1;
-       other.event_damage      = func_null;
-       other.view_ofs          = '0 0 0';
-       other.hud               = _gun.hud;
-       other.teleportable              = FALSE;
-       other.PlayerPhysplug    = _gun.PlayerPhysplug;
-       other.vehicle_ammo1     = self.vehicle_ammo1;
-       other.vehicle_ammo2     = self.vehicle_ammo2;
-       other.vehicle_reload1   = self.vehicle_reload1;
-       other.vehicle_reload2   = self.vehicle_reload2;
-       other.vehicle_energy    = self.vehicle_energy;
-       other.PlayerPhysplug    = bumblebee_gunner_frame;
-       other.flags             &= ~FL_ONGROUND;
-
-       if(IS_REAL_CLIENT(other))
+       else if(!vehic.gunner1 && time >= vehic.gun1.phase)     { gunner = vehic.gun1; vehic.gunner1 = player; }
+       else if(!vehic.gunner2 && time >= vehic.gun2.phase)             { gunner = vehic.gun2; vehic.gunner2 = player; }
+       else { dprint("Vehicle is full, fail\n"); return false; }
+
+       player.vehicle                  = gunner;
+       player.angles                   = vehic.angles;
+       player.takedamage               = DAMAGE_NO;
+       player.solid                    = SOLID_NOT;
+       player.alpha                    = -1;
+       player.movetype                 = MOVETYPE_NOCLIP;
+       player.event_damage     = func_null;
+       player.view_ofs                 = '0 0 0';
+       player.hud                              = gunner.hud;
+       player.teleportable     = false;
+       player.PlayerPhysplug   = gunner.PlayerPhysplug;
+       player.vehicle_ammo1    = vehic.vehicle_ammo1;
+       player.vehicle_ammo2    = vehic.vehicle_ammo2;
+       player.vehicle_reload1  = vehic.vehicle_reload1;
+       player.vehicle_reload2  = vehic.vehicle_reload2;
+       player.vehicle_energy   = vehic.vehicle_energy;
+       player.flags               &= ~FL_ONGROUND;
+
+       RemoveGrapplingHook(player);
+
+       gunner.switchweapon = player.switchweapon;
+       gunner.vehicle_exit = bumblebee_gunner_exit;
+       gunner.vehicle_hudmodel.viewmodelforclient = player;
+
+       if(IS_REAL_CLIENT(player))
        {
-               msg_entity = other;
-               WriteByte(MSG_ONE, SVC_SETVIEWPORT);
-               WriteEntity(MSG_ONE, _gun.vehicle_viewport);
-               WriteByte(MSG_ONE, SVC_SETVIEWANGLES);
-               WriteAngle(MSG_ONE, _gun.angles_x + self.angles_x);    // tilt
-               WriteAngle(MSG_ONE, _gun.angles_y + self.angles_y);    // yaw
-               WriteAngle(MSG_ONE, 0);                             // roll
+               msg_entity = player;
+               WriteByte(MSG_ONE,              SVC_SETVIEWPORT);
+               WriteEntity(MSG_ONE,    gunner.vehicle_viewport);
+
+               WriteByte(MSG_ONE,              SVC_SETVIEWANGLES);
+               WriteAngle(MSG_ONE,     gunner.angles_x + vehic.angles_x); // tilt
+               WriteAngle(MSG_ONE,     gunner.angles_y + vehic.angles_y); // yaw
+               WriteAngle(MSG_ONE,     0); // roll
        }
-       
-       _gun.vehicle_hudmodel.viewmodelforclient = other;
 
-       CSQCVehicleSetup(other, other.hud);
+       CSQCVehicleSetup(player, player.hud);
 
-    vh_player = other;
-    vh_vehicle = _gun;
-    MUTATOR_CALLHOOK(VehicleEnter);
-    other = vh_player;
-    _gun = vh_vehicle;
+       MUTATOR_CALLHOOK(VehicleEnter, player, gunner);
 
-       return TRUE;
+       return true;
 }
 
-float vehicles_valid_pilot()
+bool vehicles_valid_pilot()
 {
-       if (!IS_PLAYER(other))
-               return FALSE;
-
-       if(other.deadflag != DEAD_NO)
-               return FALSE;
-
-       if(other.vehicle != world)
-               return FALSE;
-
-       if (!IS_REAL_CLIENT(other))
-               if(!autocvar_g_vehicles_allow_bots)
-                       return FALSE;
+       if(IS_BOT_CLIENT(other) && !autocvar_g_vehicles_allow_bots)
+               return false;
 
-       if(teamplay && other.team != self.team)
-               return FALSE;
+       if((!IS_PLAYER(other))
+       || (other.deadflag != DEAD_NO)
+       || (other.vehicle)
+       || (DIFF_TEAM(other, self))
+       ) { return false; }
 
-       return TRUE;
+       return true;
 }
 
 void bumblebee_touch()
@@ -382,13 +384,11 @@ void bumblebee_touch()
 
        if(vehicles_valid_pilot())
        {
-               if(self.gun1.phase <= time)
-                       if(bumblebee_gunner_enter())
-                               return;
+               float phase_time = (time >= self.gun1.phase) + (time >= self.gun2.phase);
 
-               if(self.gun2.phase <= time)
-                       if(bumblebee_gunner_enter())
-                               return;
+               if(time >= other.vehicle_enter_delay && phase_time)
+               if(bumblebee_gunner_enter())
+                       return;
        }
 
        vehicles_touch();
@@ -405,13 +405,13 @@ void bumblebee_regen()
                                                                           self.gun2.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime);
 
        if(self.vehicle_flags  & VHF_SHIELDREGEN)
-               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);
+               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);
 
        if(self.vehicle_flags  & VHF_HEALTHREGEN)
-               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);
+               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);
 
        if(self.vehicle_flags  & VHF_ENERGYREGEN)
-               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);
+               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);
 
 }
 
@@ -447,58 +447,58 @@ float bumblebee_pilot_frame()
 
        vang = vehic.angles;
        newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
-       vang_x *= -1;
-       newvel_x *= -1;
-       if(newvel_x > 180)  newvel_x -= 360;
-       if(newvel_x < -180) newvel_x += 360;
-       if(newvel_y > 180)  newvel_y -= 360;
-       if(newvel_y < -180) newvel_y += 360;
-
-       ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y);
+       vang.x *= -1;
+       newvel.x *= -1;
+       if(newvel.x > 180)  newvel.x -= 360;
+       if(newvel.x < -180) newvel.x += 360;
+       if(newvel.y > 180)  newvel.y -= 360;
+       if(newvel.y < -180) newvel.y += 360;
+
+       ftmp = shortangle_f(pilot.v_angle.y - vang.y, vang.y);
        if(ftmp > 180)  ftmp -= 360;
        if(ftmp < -180) ftmp += 360;
-       vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
+       vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity.y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
 
        // Pitch
        ftmp = 0;
-       if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit)
+       if(pilot.movement.x > 0 && vang.x < autocvar_g_vehicle_bumblebee_pitchlimit)
                ftmp = 4;
-       else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit)
+       else if(pilot.movement.x < 0 && vang.x > -autocvar_g_vehicle_bumblebee_pitchlimit)
                ftmp = -8;
 
-       newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit);
-       ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
-       vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
+       newvel.x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel.x , autocvar_g_vehicle_bumblebee_pitchlimit);
+       ftmp = vang.x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel.x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
+       vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity.x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
 
-       vehic.angles_x = anglemods(vehic.angles_x);
-       vehic.angles_y = anglemods(vehic.angles_y);
-       vehic.angles_z = anglemods(vehic.angles_z);
+       vehic.angles_x = anglemods(vehic.angles.x);
+       vehic.angles_y = anglemods(vehic.angles.y);
+       vehic.angles_z = anglemods(vehic.angles.z);
 
-       makevectors('0 1 0' * vehic.angles_y);
+       makevectors('0 1 0' * vehic.angles.y);
        newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
 
-       if(pilot.movement_x != 0)
+       if(pilot.movement.x != 0)
        {
-               if(pilot.movement_x > 0)
+               if(pilot.movement.x > 0)
                        newvel += v_forward  * autocvar_g_vehicle_bumblebee_speed_forward;
-               else if(pilot.movement_x < 0)
+               else if(pilot.movement.x < 0)
                        newvel -= v_forward  * autocvar_g_vehicle_bumblebee_speed_forward;
        }
 
-       if(pilot.movement_y != 0)
+       if(pilot.movement.y != 0)
        {
-               if(pilot.movement_y < 0)
+               if(pilot.movement.y < 0)
                        newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
-               else if(pilot.movement_y > 0)
+               else if(pilot.movement.y > 0)
                        newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
                ftmp = newvel * v_right;
                ftmp *= frametime * 0.1;
-               vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15);
+               vehic.angles_z = bound(-15, vehic.angles.z + ftmp, 15);
        }
        else
        {
                vehic.angles_z *= 0.95;
-               if(vehic.angles_z >= -1 && vehic.angles_z <= -1)
+               if(vehic.angles.z >= -1 && vehic.angles.z <= -1)
                        vehic.angles_z = 0;
        }
 
@@ -589,7 +589,7 @@ float bumblebee_pilot_frame()
 
                                                        trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax);
                                                }
-                                               else if(trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+                                               else if(IS_TURRET(trace_ent))
                                                {
                                                        if(trace_ent.health  <= trace_ent.max_health && autocvar_g_vehicle_bumblebee_healgun_hps)
                                                                trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.max_health);
@@ -687,14 +687,14 @@ void bumblebee_exit(float eject)
        // Hide beam
        if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) {
                self.gun3.enemy.effects |= EF_NODRAW;
-    }
+       }
 
        self.owner.velocity = 0.75 * self.vehicle.velocity + normalize(spot - self.vehicle.origin) * 200;
        self.owner.velocity_z += 10;
        setorigin(self.owner, spot);
 
        antilag_clear(self.owner);
-    self.owner = world;
+       self.owner = world;
 }
 
 void bumblebee_blowup()
@@ -706,7 +706,7 @@ void bumblebee_blowup()
                                 DEATH_VH_BUMB_DEATH, world);
 
        sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
-       pointparticles(particleeffectnum("explosion_big"), (self.origin + '0 0 100') + (randomvec() * 80), '0 0 0', 1);
+       Send_Effect("explosion_big", (self.origin + '0 0 100') + (randomvec() * 80), '0 0 0', 1);
 
        if(self.owner.deadflag == DEAD_DYING)
                self.owner.deadflag = DEAD_DEAD;
@@ -722,7 +722,7 @@ void bumblebee_diethink()
        if(random() < 0.1)
        {
                sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
-               pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
+               Send_Effect("explosion_small", randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
        }
 
        self.nextthink = time + 0.1;
@@ -754,13 +754,13 @@ float bumble_raygun_send(entity to, float sf)
                WriteCoord(MSG_ENTITY, self.hook_end_z);
        }
 
-       return TRUE;
+       return true;
 }
 
 void spawnfunc_vehicle_bumblebee()
 {
        if(!autocvar_g_vehicle_bumblebee) { remove(self); return; }
-       if(!vehicle_initialize(VEH_BUMBLEBEE, FALSE)) { remove(self); return; }
+       if(!vehicle_initialize(VEH_BUMBLEBEE, false)) { remove(self); return; }
 }
 
 float v_bumblebee(float req)
@@ -772,14 +772,14 @@ float v_bumblebee(float req)
                        if(autocvar_g_vehicle_bumblebee_bouncepain)
                                vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z);
                                
-                       return TRUE;
+                       return true;
                }
                case VR_ENTER:
                {
                        self.touch = bumblebee_touch;
                        self.nextthink = 0;
                        self.movetype = MOVETYPE_BOUNCEMISSILE;
-                       return TRUE;
+                       return true;
                }
                case VR_THINK:
                {
@@ -801,7 +801,7 @@ float v_bumblebee(float req)
                                        self.phase = 0;
                                        self.touch();
                                        other = oldother;
-                                       return TRUE;
+                                       return true;
                                }
                                
                                if(self.gunner2)
@@ -814,11 +814,11 @@ float v_bumblebee(float req)
                                        self.phase = 0;
                                        self.touch();
                                        other = oldother;
-                                       return TRUE;
+                                       return true;
                                }               
                        }
                        
-                       return TRUE;
+                       return true;
                }
                case VR_DEATH:
                {
@@ -865,8 +865,8 @@ float v_bumblebee(float req)
                        _body.enemy = self.enemy;
                        _body.scale = 1.5;
                        _body.angles = self.angles;
-                       
-                       pointparticles(particleeffectnum("explosion_medium"), findbetterlocation(self.origin, 16), '0 0 0', 1);
+
+                       Send_Effect("explosion_medium", findbetterlocation(self.origin, 16), '0 0 0', 1);
                        
                        self.health                     = 0;
                        self.event_damage       = func_null;
@@ -882,7 +882,7 @@ float v_bumblebee(float req)
                        self.nextthink          = 0;
 
                        setorigin(self, self.pos1);
-                       return TRUE;
+                       return true;
                }
                case VR_SPAWN:
                {
@@ -909,6 +909,8 @@ float v_bumblebee(float req)
                                self.gun2.owner = self;
                                self.gun3.owner = self;
 
+                               self.gun1.classname = self.gun2.classname = "vehicle_playerslot";
+
                                setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm");
                                setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm");
                                setmodel(self.gun3, "models/vehicles/bumblebee_ray.dpm");
@@ -944,7 +946,7 @@ float v_bumblebee(float req)
                                if(self.gun3.enemy == world)
                                {                       
                                        self.gun3.enemy = spawn();
-                                       Net_LinkEntity(self.gun3.enemy, TRUE, 0, bumble_raygun_send);
+                                       Net_LinkEntity(self.gun3.enemy, true, 0, bumble_raygun_send);
                                        self.gun3.enemy.SendFlags = BRG_SETUP;                  
                                        self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun;                      
                                        self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION;
@@ -960,7 +962,7 @@ float v_bumblebee(float req)
                        self.PlayerPhysplug = bumblebee_pilot_frame;
                        
                        setorigin(self, self.origin + '0 0 25');
-                       return TRUE;
+                       return true;
                }
                case VR_SETUP:
                {
@@ -983,7 +985,7 @@ float v_bumblebee(float req)
                        self.max_health = self.vehicle_health;
                        self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield;
                                
-                       return TRUE;
+                       return true;
                }
                case VR_PRECACHE:
                {
@@ -994,141 +996,22 @@ float v_bumblebee(float req)
                        precache_model("models/vehicles/wakizashi_cockpit.dpm");
                        precache_model("models/vehicles/spiderbot_cockpit.dpm");
                        precache_model("models/vehicles/raptor_cockpit.dpm");
-                       return TRUE;
+                       return true;
                }
        }
 
-       return TRUE;
+       return true;
 }
 
 #endif // SVQC
 #ifdef CSQC
 
-#define bumb_ico  "gfx/vehicles/bumb.tga"
-#define bumb_lgun  "gfx/vehicles/bumb_lgun.tga"
-#define bumb_rgun  "gfx/vehicles/bumb_rgun.tga"
-
-#define bumb_gun_ico  "gfx/vehicles/bumb_side.tga"
-#define bumb_gun_gun  "gfx/vehicles/bumb_side_gun.tga"
-
 void CSQC_BUMBLE_GUN_HUD()
 {
-
-       if(autocvar_r_letterbox)
-               return;
-
-       vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-       // Fetch health & ammo stats
-       HUD_GETVEHICLESTATS
-
-       picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-       hudloc_y = vid_conheight - picsize_y;
-       hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
-
-       drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-       shield  *= 0.01;
-       vh_health  *= 0.01;
-       energy  *= 0.01;
-       reload1 *= 0.01;
-
-       pic2size = draw_getimagesize(bumb_gun_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-       picloc = picsize * 0.5 - pic2size * 0.5;
-
-       if(vh_health < 0.25)
-               drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-       else
-               drawpic(hudloc + picloc, bumb_gun_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-
-       drawpic(hudloc + picloc, bumb_gun_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-       drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-// Health bar
-       picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-       picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-       drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-       drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-       drawresetcliparea();
-// ..  and icon
-       picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-       picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-       if(vh_health < 0.25)
-       {
-               if(alarm1time < time)
-               {
-                       alarm1time = time + 2;
-                       vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav");
-               }
-
-               drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-       }
-       else
-       {
-               drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-               if(alarm1time)
-               {
-                       vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav");
-                       alarm1time = 0;
-               }
-       }
-
-// Shield bar
-       picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-       picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-       drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-       drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-       drawresetcliparea();
-// ..  and icon
-       picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-       picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-       if(shield < 0.25)
-       {
-               if(alarm2time < time)
-               {
-                       alarm2time = time + 1;
-                       vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav");
-               }
-               drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-       }
-       else
-       {
-               drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-               if(alarm2time)
-               {
-                       vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav");
-                       alarm2time = 0;
-               }
-       }
-
-// Gun bar
-       picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-       picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-       drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight);
-       drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-       drawresetcliparea();
-
-// ..  and icon
-       picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-       picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-       if(energy < 0.2)
-               drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-       else
-               drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-       if (scoreboard_showscores)
-               HUD_DrawScoreboard();
-       /*
-       else
-       {
-               picsize = draw_getimagesize(waki_xhair);
-               picsize_x *= 0.5;
-               picsize_y *= 0.5;
-
-
-               drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-       }
-       */
+       Vehicles_drawHUD("vehicle_gunner", "vehicle_gunner_weapon1", string_null,
+                                        "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
+                                        string_null, '0 0 0',
+                                        string_null);
 }
 
 void bumble_raygun_draw()
@@ -1169,9 +1052,9 @@ void bumble_raygun_draw()
        }
 }
 
-void bumble_raygun_read(float bIsNew)
+void bumble_raygun_read(bool bIsNew)
 {
-       float sf = ReadByte();
+       int sf = ReadByte();
 
        if(sf & BRG_SETUP)
        {
@@ -1213,175 +1096,26 @@ float v_bumblebee(float req)
        {
                case VR_HUD:
                {
-                       if(autocvar_r_letterbox)
-                               return TRUE;
-
-                       vector picsize, hudloc = '0 0 0', pic2size, picloc;
-
-                       // Fetch health & ammo stats
-                       HUD_GETVEHICLESTATS
-
-                       picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
-                       hudloc_y = vid_conheight - picsize_y;
-                       hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
-
-                       drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
-
-                       shield  *= 0.01;
-                       vh_health  *= 0.01;
-                       energy  *= 0.01;
-                       reload1 *= 0.01;
-
-                       pic2size = draw_getimagesize(bumb_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
-                       picloc = picsize * 0.5 - pic2size * 0.5;
-
-                       if(vh_health < 0.25)
-                               drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(hudloc + picloc, bumb_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
-
-                       drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-                       drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
-                       drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
-
-               // Health bar
-                       picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
-                       picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
-                       drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
-                       drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
-                       drawresetcliparea();
-               // ..  and icon
-                       picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
-                       picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
-                       if(vh_health < 0.25)
-                       {
-                               if(alarm1time < time)
-                               {
-                                       alarm1time = time + 2;
-                                       vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav");
-                               }
-
-                               drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-                       }
-                       else
-                       {
-                               drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                               if(alarm1time)
-                               {
-                                       vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav");
-                                       alarm1time = 0;
-                               }
-                       }
-
-               // Shield bar
-                       picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
-                       picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
-                       drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
-                       drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                       drawresetcliparea();
-               // ..  and icon
-                       picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
-                       picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
-                       if(shield < 0.25)
-                       {
-                               if(alarm2time < time)
-                               {
-                                       alarm2time = time + 1;
-                                       vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav");
-                               }
-                               drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-                       }
-                       else
-                       {
-                               drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                               if(alarm2time)
-                               {
-                                       vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav");
-                                       alarm2time = 0;
-                               }
-                       }
-
-                       ammo1 *= 0.01;
-                       ammo2 *= 0.01;
-
-               // Gunner1 bar
-                       picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
-                       picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
-                       drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight);
-                       drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                       drawresetcliparea();
-
-               // Right gunner slot occupied?
-                       if(!AuxiliaryXhair[1].draw2d)
-                       {
-                               shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No right gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y));
-                               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
-                               drawstring(hudloc + picloc + '1 0 0' * shield, _("No right gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
-                       }
-
-               // ..  and icon
-                       picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-                       picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
-                       if(ammo1 < 0.2)
-                               drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-               // Gunner2 bar
-                       picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
-                       picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
-                       drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo2, vid_conheight);
-                       drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                       drawresetcliparea();
-               // Left gunner slot occupied?
-                       if(!AuxiliaryXhair[2].draw2d)
-                       {
-                               shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No left gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y));
-                               drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL);
-                               drawstring(hudloc + picloc + '1 0 0' * shield, _("No left gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL);
-                       }
-
-               // ..  and icon
-                       picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale;
-                       picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
-                       if(ammo2 < 0.2)
-                               drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-                       if (scoreboard_showscores)
-                               HUD_DrawScoreboard();
-                       else
-                       {
-                               picsize = draw_getimagesize(waki_xhair);
-                               picsize_x *= 0.5;
-                               picsize_y *= 0.5;
-                               drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-                       }
-                       return TRUE;
+                       Vehicles_drawHUD("vehicle_bumble", "vehicle_bumble_weapon1", "vehicle_bumble_weapon2",
+                                                        "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
+                                                        "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
+                                                        vCROSS_HEAL);
+                       return true;
                }
                case VR_SETUP:
                {
-                       // raygun-locked
-                       AuxiliaryXhair[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
-                       AuxiliaryXhair[0].axh_scale   = 0.5;
-
-                       // Gunner1
-                       AuxiliaryXhair[1].axh_image   = "gfx/vehicles/axh-target.tga";
-                       AuxiliaryXhair[1].axh_scale   = 0.75;
-
-                       // Gunner2
-                       AuxiliaryXhair[2].axh_image   = "gfx/vehicles/axh-target.tga";
-                       AuxiliaryXhair[2].axh_scale   = 0.75;
-                       return TRUE;
+                       AuxiliaryXhair[0].axh_image = vCROSS_LOCK;  // Raygun-locked
+                       AuxiliaryXhair[1].axh_image = vCROSS_BURST; // Gunner1
+                       AuxiliaryXhair[2].axh_image = vCROSS_BURST; // Gunner2
+                       return true;
                }
                case VR_PRECACHE:
                {
-                       return TRUE;
+                       return true;
                }
        }
 
-       return TRUE;
+       return true;
 }
 
 #endif // CSQC