From: Mario Date: Tue, 24 Feb 2015 08:47:06 +0000 (+1100) Subject: Fix exiting bumblebee gunner, also put player in the closest side to them when entering X-Git-Tag: xonotic-v0.8.2~2059^2~13 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=60c1084d25fd08252a6f7b552d4c383b65700302;p=xonotic%2Fxonotic-data.pk3dir.git Fix exiting bumblebee gunner, also put player in the closest side to them when entering --- diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index d5bba034fc..557daaca48 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -18,7 +18,7 @@ float SendAuxiliaryXhair(entity to, float sf) WriteByte(MSG_ENTITY, rint(self.colormod_y * 255)); WriteByte(MSG_ENTITY, rint(self.colormod_z * 255)); - return TRUE; + return true; } void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id) @@ -37,7 +37,7 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id) axh.cnt = axh_id; axh.drawonlytoclient = own; axh.owner = own; - Net_LinkEntity(axh, FALSE, 0, SendAuxiliaryXhair); + Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair); } setorigin(axh, loc); @@ -234,7 +234,7 @@ entity vehicles_projectile(string _mzlfx, string _mzlsound, proj.solid = SOLID_BBOX; proj.movetype = MOVETYPE_FLYMISSILE; proj.flags = FL_PROJECTILE; - proj.bot_dodge = TRUE; + proj.bot_dodge = true; proj.bot_dodgerating = _dmg; proj.velocity = _vel; proj.touch = vehicles_projectile_explode; @@ -340,7 +340,7 @@ float vehicle_addplayerslot( entity _owner, setattachment(_slot.vehicle_hudmodel, _slot, ""); setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, ""); - return TRUE; + return true; } vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname, @@ -352,7 +352,7 @@ vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname)); vtmp = vectoangles(normalize(_target - vtag)); vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles; - vtmp = AnglesTransform_Normalize(vtmp, TRUE); + vtmp = AnglesTransform_Normalize(vtmp, true); ftmp = _aimspeed * frametime; vtmp_y = bound(-ftmp, vtmp_y, ftmp); vtmp_x = bound(-ftmp, vtmp_x, ftmp); @@ -494,7 +494,7 @@ void vehicles_showwp() rgb = Team_ColorRGB(self.team); else rgb = '1 1 1'; - WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb); + WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP, rgb); if(self.waypointsprite_attached) { WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT); @@ -703,15 +703,15 @@ void vehicles_damage(entity inflictor, entity attacker, float damage, float deat } } -float vehicles_crushable(entity e) +bool vehicles_crushable(entity e) { if(IS_PLAYER(e)) - return TRUE; + return true; if(e.flags & FL_MONSTER) - return TRUE; + return true; - return FALSE; + return false; } void vehicles_impact(float _minspeed, float _speedfac, float _maxpain) @@ -797,7 +797,7 @@ void vehicles_exit(float eject) return; } - vehicles_exit_running = TRUE; + vehicles_exit_running = true; if(IS_CLIENT(self)) { _vehicle = self.vehicle; @@ -806,7 +806,7 @@ void vehicles_exit(float eject) { _vehicle.vehicle_exit(eject); self = _oldself; - vehicles_exit_running = FALSE; + vehicles_exit_running = false; return; } } @@ -846,6 +846,7 @@ void vehicles_exit(float eject) _player.hud = HUD_NORMAL; _player.switchweapon = _vehicle.switchweapon; _player.last_vehiclecheck = time + 3; + _player.vehicle_enter_delay = time + 2; CSQCVehicleSetup(_player, HUD_NORMAL); } @@ -886,7 +887,7 @@ void vehicles_exit(float eject) self = _oldself; - vehicles_exit_running = FALSE; + vehicles_exit_running = false; } void vehicles_touch() @@ -923,28 +924,18 @@ void vehicles_touch() void vehicles_enter(entity pl, entity veh) { // Remove this when bots know how to use vehicles - if (IS_BOT_CLIENT(pl)) - if (autocvar_g_vehicles_allow_bots) - dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe() - else - return; - - if(!IS_PLAYER(pl)) - return; - - if(veh.phase > time) + if((IS_BOT_CLIENT(pl) && !autocvar_g_vehicles_allow_bots)) return; - if(pl.frozen) - return; - - if(pl.deadflag != DEAD_NO) - return; - - if(pl.vehicle) - return; + if((!IS_PLAYER(pl)) + || (veh.phase >= time) + || (pl.vehicle_enter_delay >= time) + || (pl.frozen) + || (pl.deadflag != DEAD_NO) + || (pl.vehicle) + ) { return; } - if(autocvar_g_vehicles_enter) // skip if we're using regular touch code + if(autocvar_g_vehicles_enter) // vehicle's touch function should handle this if entering via use key is disabled (TODO) if(veh.vehicle_flags & VHF_MULTISLOT) if(veh.owner) { @@ -953,7 +944,7 @@ void vehicles_enter(entity pl, entity veh) other = pl; // TODO: fix if(!veh.gunner1) - if(veh.gun1.phase <= time) + if(time >= veh.gun1.phase) if(veh.gun1.vehicle_enter) if(veh.gun1.vehicle_enter()) { @@ -962,7 +953,7 @@ void vehicles_enter(entity pl, entity veh) } if(!veh.gunner2) - if(veh.gun2.phase <= time) + if(time >= veh.gun2.phase) if(veh.gun2.vehicle_enter) if(veh.gun2.vehicle_enter()) { @@ -985,9 +976,9 @@ void vehicles_enter(entity pl, entity veh) Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_STEAL_SELF); if(autocvar_g_vehicles_steal_show_waypoint) - WaypointSprite_Spawn("intruder", 0, 0, pl, '0 0 68', world, veh.team, veh, wps_intruder, TRUE, RADARICON_DANGER, Team_ColorRGB(pl.team)); + WaypointSprite_Spawn("intruder", 0, 0, pl, '0 0 68', world, veh.team, veh, wps_intruder, true, RADARICON_DANGER, Team_ColorRGB(pl.team)); } - else return; + else { return; } RemoveGrapplingHook(pl); @@ -1005,8 +996,8 @@ void vehicles_enter(entity pl, entity veh) veh.vehicle_hudmodel.viewmodelforclient = pl; - tracebox(pl.origin, PL_MIN, PL_MAX, pl.origin, FALSE, pl); - pl.crouch = FALSE; + tracebox(pl.origin, PL_MIN, PL_MAX, pl.origin, false, pl); + pl.crouch = false; pl.view_ofs = PL_VIEW_OFS; setsize (pl, PL_MIN, PL_MAX); @@ -1016,7 +1007,7 @@ void vehicles_enter(entity pl, entity veh) pl.takedamage = DAMAGE_NO; pl.solid = SOLID_NOT; pl.movetype = MOVETYPE_NOCLIP; - pl.teleportable = FALSE; + pl.teleportable = false; pl.alpha = -1; pl.event_damage = func_null; pl.view_ofs = '0 0 0'; @@ -1105,14 +1096,14 @@ void vehicles_spawn() self.owner = world; self.touch = vehicles_touch; self.event_damage = vehicles_damage; - self.iscreature = TRUE; - self.teleportable = FALSE; // no teleporting for vehicles, too buggy - self.damagedbycontents = TRUE; + self.iscreature = true; + self.teleportable = false; // no teleporting for vehicles, too buggy + self.damagedbycontents = true; self.movetype = MOVETYPE_WALK; self.solid = SOLID_SLIDEBOX; self.takedamage = DAMAGE_AIM; self.deadflag = DEAD_NO; - self.bot_attack = TRUE; + self.bot_attack = true; self.flags = FL_NOTARGET; self.avelocity = '0 0 0'; self.velocity = '0 0 0'; @@ -1148,12 +1139,12 @@ void vehicles_spawn() float vehicle_initialize(float vehicle_id, float nodrop) { if(!autocvar_g_vehicles) - return FALSE; + return false; entity veh = get_vehicleinfo(vehicle_id); if(!veh.vehicleid) - return FALSE; + return false; if(!veh.tur_head) { VEH_ACTION(vehicle_id, VR_PRECACHE); } @@ -1193,10 +1184,10 @@ float vehicle_initialize(float vehicle_id, float nodrop) self.tur_head = spawn(); self.tur_head.owner = self; self.takedamage = DAMAGE_NO; - self.bot_attack = TRUE; - self.iscreature = TRUE; - self.teleportable = FALSE; // no teleporting for vehicles, too buggy - self.damagedbycontents = TRUE; + self.bot_attack = true; + self.iscreature = true; + self.teleportable = false; // no teleporting for vehicles, too buggy + self.damagedbycontents = true; self.vehicleid = vehicle_id; self.PlayerPhysplug = veh.PlayerPhysplug; self.event_damage = func_null; @@ -1255,7 +1246,7 @@ float vehicle_initialize(float vehicle_id, float nodrop) self.nextthink = time + game_starttime; if(MUTATOR_CALLHOOK(VehicleSpawn)) - return FALSE; + return false; - return TRUE; + return true; } diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh index c1080982b3..c102793844 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qh +++ b/qcsrc/common/vehicles/sv_vehicles.qh @@ -84,6 +84,8 @@ void(entity e, vector force, vector force_pos) physics_addforce = #541; // apply void(entity e, vector torque) physics_addtorque = #542; // add relative torque #endif // VEHICLES_USE_ODE +.float vehicle_enter_delay; // prevent players jumping to and from vehicles instantly + // functions used outside the vehicle code void vehicles_exit(bool eject); void vehicles_enter(entity pl, entity veh); diff --git a/qcsrc/common/vehicles/unit/bumblebee.qc b/qcsrc/common/vehicles/unit/bumblebee.qc index 17669b6169..ef02d6b839 100644 --- a/qcsrc/common/vehicles/unit/bumblebee.qc +++ b/qcsrc/common/vehicles/unit/bumblebee.qc @@ -114,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; @@ -141,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; @@ -217,154 +209,172 @@ float bumblebee_gunner_frame() return 1; } -void bumblebee_gunner_exit(float _exitflag) +vector bumblebee_gunner_findgoodexit(vector prefer_spot, entity gunner, entity player) { - if(IS_REAL_CLIENT(self)) + //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) { - msg_entity = self; + 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) +{ + entity player = self; + entity gunner = player.vehicle; + entity vehic = gunner.owner; + + if(IS_REAL_CLIENT(player)) + { + 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); - - 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; - - vh_player = self; - vh_vehicle = self.vehicle; - MUTATOR_CALLHOOK(VehicleExit); - self = vh_player; - self.vehicle = vh_vehicle; + CSQCVehicleSetup(player, HUD_NORMAL); + setsize(player, PL_MIN, PL_MAX); + + 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; + + fixedmakevectors(vehic.angles); + + if(player == vehic.gunner1) { vehic.gunner1 = world; } + if(player == vehic.gunner2) { vehic.gunner2 = world; v_right *= -1; } + + vector spot = real_origin(gunner); + spot += v_up * 128 + v_forward * 300 + v_right * 150; + spot = vehicles_findgoodexit(spot); + //setorigin(player, spot); - self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle; + player.velocity = 0.75 * vehic.velocity + normalize(spot - vehic.origin) * 200; + player.velocity_z += 10; - fixedmakevectors(self.vehicle.owner.angles); + gunner.phase = time + 5; + gunner.vehicle_hudmodel.viewmodelforclient = gunner; - 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"); + vh_player = player; + vh_vehicle = gunner; + MUTATOR_CALLHOOK(VehicleExit); + player = vh_player; + gunner = vh_vehicle; - vector spot = self.vehicle.owner.origin + + v_up * 128 + v_right * 300; - spot = vehicles_findgoodexit(spot); - //setorigin(self , spot); - - self.velocity = 0.75 * self.vehicle.owner.velocity + normalize(spot - self.vehicle.owner.origin) * 200; - self.velocity_z += 10; - - self.vehicle.phase = time + 5; - self.vehicle = world; + 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; + vh_player = player; + vh_vehicle = gunner; + MUTATOR_CALLHOOK(VehicleEnter); + player = vh_player; + gunner = vh_vehicle; return true; } -float vehicles_valid_pilot() +bool vehicles_valid_pilot() { - if (!IS_PLAYER(other)) + if(IS_BOT_CLIENT(other) && !autocvar_g_vehicles_allow_bots) 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(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; } @@ -381,13 +391,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(); @@ -686,14 +694,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() @@ -908,6 +916,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");