]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/vehicles/sv_vehicles.qc
Also reset oldorigin when exiting vehicle
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / sv_vehicles.qc
index 39f959d14b9f03f851f6b8edebf6d3efd90008e3..0c9ff29d913f9d7f306f98618d1f1cafbf4a8f4a 100644 (file)
@@ -24,6 +24,13 @@ bool SendAuxiliaryXhair(entity this, entity to, int sf)
        return true;
 }
 
+bool AuxiliaryXhair_customize(entity this, entity client)
+{
+       //entity e = WaypointSprite_getviewentity(client);
+       entity axh = client.(AuxiliaryXhair[this.cnt]);
+       return axh.owner == this.owner; // cheaply check if the client's axh owner is the same as our real owner
+}
+
 .vector axh_prevorigin;
 .vector axh_prevcolors;
 
@@ -39,7 +46,8 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
        {
                axh = new(auxiliary_xhair);
                axh.cnt = axh_id;
-               axh.drawonlytoclient = own;
+               //axh.drawonlytoclient = own; // not spectatable
+               setcefc(axh, AuxiliaryXhair_customize);
                axh.owner = own;
                Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair);
        }
@@ -68,6 +76,18 @@ void CSQCVehicleSetup(entity own, int vehicle_id)
 
        WriteHeader(MSG_ONE, TE_CSQC_VEHICLESETUP);
        WriteByte(MSG_ONE, vehicle_id);
+
+       if(vehicle_id == 0 || vehicle_id == HUD_NORMAL)
+       {
+               for(int i = 0; i < MAX_AXH; ++i)
+               {
+                       entity axh = own.(AuxiliaryXhair[i]);
+                       own.(AuxiliaryXhair[i]) = NULL;
+
+                       if(axh.owner == own && axh != NULL && !wasfreed(axh))
+                               delete(axh);
+               }
+       }
 }
 
 void vehicles_locktarget(entity this, float incr, float decr, float _lock_time)
@@ -249,6 +269,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
        set_movetype(proj, MOVETYPE_FLYMISSILE);
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.bot_dodge          = true;
        proj.bot_dodgerating  = _dmg;
        proj.velocity            = _vel;
@@ -433,17 +454,15 @@ void vehicles_reset_colors(entity this)
 void vehicles_clearreturn(entity veh)
 {
        // Remove "return helper" entities, if any.
-       FOREACH_ENTITY_ENT(wp00, veh,
+       IL_EACH(g_vehicle_returners, it.wp00 == veh,
        {
-               if(it.classname == "vehicle_return")
-               {
-                       it.classname = "";
-                       setthink(it, SUB_Remove);
-                       it.nextthink = time + 0.1;
+               it.classname = "";
+               setthink(it, SUB_Remove);
+               it.nextthink = time + 0.1;
+               IL_REMOVE(g_vehicle_returners, it);
 
-                       if(it.waypointsprite_attached)
-                               WaypointSprite_Kill(it.waypointsprite_attached);
-               }
+               if(it.waypointsprite_attached)
+                       WaypointSprite_Kill(it.waypointsprite_attached);
        });
 }
 
@@ -513,6 +532,7 @@ void vehicles_setreturn(entity veh)
        vehicles_clearreturn(veh);
 
        entity ret = new(vehicle_return);
+       IL_PUSH(g_vehicle_returners, ret);
        ret.wp00           = veh;
        ret.team                = veh.team;
        setthink(ret, vehicles_showwp);
@@ -541,7 +561,7 @@ void vehicle_use(entity this, entity actor, entity trigger)
        else
                this.active = ACTIVE_ACTIVE;
 
-       if(this.active == ACTIVE_ACTIVE && !IS_DEAD(this) && !gameover)
+       if(this.active == ACTIVE_ACTIVE && !IS_DEAD(this) && !game_stopped)
        {
                LOG_DEBUG("Respawning vehicle: ", this.netname);
                if(this.effects & EF_NODRAW)
@@ -666,11 +686,11 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag
                        this.vehicle_shieldent.alpha = 0.75;
 
                        if(sound_allowed(MSG_BROADCAST, attacker))
-                               spamsound (this, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);   // FIXME: PLACEHOLDER
+                               spamsound (this, CH_PAIN, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM);   // FIXME: PLACEHOLDER
                }
                else
                        if(sound_allowed(MSG_BROADCAST, attacker))
-                               spamsound (this, CH_PAIN, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+                               spamsound (this, CH_PAIN, SND_ONS_ELECTRICITY_EXPLODE, VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
 
        }
        else
@@ -678,7 +698,7 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag
                this.vehicle_health -= damage;
 
                if(sound_allowed(MSG_BROADCAST, attacker))
-                       spamsound (this, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+                       spamsound (this, CH_PAIN, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
        }
 
        if(this.damageforcescale < 1 && this.damageforcescale > 0)
@@ -737,9 +757,10 @@ void vehicles_impact(entity this, float _minspeed, float _speedfac, float _maxpa
 }
 
 // vehicle enter/exit handling
-vector vehicles_findgoodexit(entity this, vector prefer_spot)
+vector vehicles_findgoodexit(entity this, entity player, vector prefer_spot)
 {
-       tracebox(this.origin + '0 0 32', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), prefer_spot, MOVE_NORMAL, this.owner);
+       // TODO: we actually want the player's size here
+       tracebox(this.origin + '0 0 32', PL_MIN_CONST, PL_MAX_CONST, prefer_spot, MOVE_NORMAL, player);
        if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
                return prefer_spot;
 
@@ -751,7 +772,7 @@ vector vehicles_findgoodexit(entity this, vector prefer_spot)
                v = randomvec();
                v_z = 0;
                v = v2 + normalize(v) * mysize;
-               tracebox(v2, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), v, MOVE_NORMAL, this.owner);
+               tracebox(v2, PL_MIN_CONST, PL_MAX_CONST, v, MOVE_NORMAL, player);
                if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
                        return v;
        }
@@ -793,7 +814,7 @@ void vehicles_exit(entity vehic, bool eject)
                        WriteAngle(MSG_ONE, 0);
                }
 
-               setsize(player, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL));
+               setsize(player, STAT(PL_MIN,player), STAT(PL_MAX, player));
 
                player.takedamage               = DAMAGE_AIM;
                player.solid                    = SOLID_SLIDEBOX;
@@ -803,10 +824,15 @@ void vehicles_exit(entity vehic, bool eject)
                player.alpha                    = 1;
                player.PlayerPhysplug   = func_null;
                player.vehicle                  = NULL;
-               player.view_ofs         = STAT(PL_VIEW_OFS, NULL);
+               player.view_ofs         = STAT(PL_VIEW_OFS, player);
                player.event_damage     = PlayerDamage;
                player.hud                              = HUD_NORMAL;
-               PS(player).m_switchweapon = vehic.m_switchweapon;
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++ slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       player.(weaponentity).m_switchweapon = vehic.(weaponentity).m_switchweapon;
+                       delete(vehic.(weaponentity)); // no longer needed
+               }
                player.last_vehiclecheck = time + 3;
                player.vehicle_enter_delay = time + 2;
 
@@ -844,6 +870,9 @@ void vehicles_exit(entity vehic, bool eject)
 
        CSQCMODEL_AUTOINIT(vehic);
 
+       if(player)
+               player.oldorigin = player.origin; // player's location is set by the exit functions, so we need to do this after everything
+
        vehicles_exit_running = false;
 }
 
@@ -942,7 +971,7 @@ void vehicles_enter(entity pl, entity veh)
        }
        else return;
 
-       RemoveGrapplingHook(pl);
+       RemoveGrapplingHooks(pl);
 
        veh.vehicle_ammo1 = 0;
        veh.vehicle_ammo2 = 0;
@@ -959,11 +988,12 @@ void vehicles_enter(entity pl, entity veh)
        veh.vehicle_hudmodel.viewmodelforclient = pl;
 
        pl.crouch = false;
-       pl.view_ofs = STAT(PL_VIEW_OFS, NULL);
-       setsize (pl, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL));
+       pl.view_ofs = STAT(PL_VIEW_OFS, pl);
+       setsize (pl, STAT(PL_MIN, pl), STAT(PL_MAX, pl));
 
        veh.event_damage        = vehicles_damage;
        veh.nextthink           = 0;
+       pl.items &= ~IT_USING_JETPACK;
        pl.angles                       = veh.angles;
        pl.takedamage           = DAMAGE_NO;
        pl.solid                        = SOLID_NOT;
@@ -976,7 +1006,12 @@ void vehicles_enter(entity pl, entity veh)
        veh.colormap            = pl.colormap;
        if(veh.tur_head)
                veh.tur_head.colormap = pl.colormap;
-       veh.m_switchweapon = PS(pl).m_switchweapon;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               veh.(weaponentity) = new(temp_wepent);
+               veh.(weaponentity).m_switchweapon = pl.(weaponentity).m_switchweapon;
+       }
        pl.hud = veh.vehicleid;
        pl.PlayerPhysplug = veh.PlayerPhysplug;
 
@@ -1076,6 +1111,8 @@ void vehicles_spawn(entity this)
        this.solid                              = SOLID_SLIDEBOX;
        this.takedamage                 = DAMAGE_AIM;
        this.deadflag                   = DEAD_NO;
+       if(!this.bot_attack)
+               IL_PUSH(g_bot_targets, this);
        this.bot_attack                 = true;
        this.flags                              = FL_NOTARGET;
        this.avelocity                  = '0 0 0';
@@ -1097,7 +1134,15 @@ void vehicles_spawn(entity this)
        if(this.vehicle_controller)
                this.team = this.vehicle_controller.team;
 
-       FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == this, RemoveGrapplingHook(it));
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == this)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
 
        vehicles_reset_colors(this);
 
@@ -1161,9 +1206,11 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
        this.tur_head.owner                     = this;
        this.takedamage                         = DAMAGE_NO;
        this.bot_attack                         = true;
+       IL_PUSH(g_bot_targets, this);
        this.iscreature                         = true;
        this.teleportable                       = false; // no teleporting for vehicles, too buggy
        this.damagedbycontents          = true;
+       IL_PUSH(g_damagedbycontents, this);
        this.vehicleid                          = info.vehicleid;
        this.PlayerPhysplug                     = info.PlayerPhysplug;
        this.event_damage                       = func_null;
@@ -1221,7 +1268,7 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
        else
                this.nextthink = time + game_starttime;
 
-       if(MUTATOR_CALLHOOK(VehicleSpawn, this))
+       if(MUTATOR_CALLHOOK(VehicleInit, this))
                return false;
 
        return true;