From 301529dfae814a2137adb26f5eacb109a991e508 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 4 Mar 2015 00:25:02 +1100 Subject: [PATCH] Allow spiderbot to move while in the air (fixes getting stuck on jumppads), fix dodging, add cvars to handle damage multipliers for some objects (turrets, vehicles) --- qcsrc/client/view.qc | 3 + qcsrc/common/turrets/sv_turrets.qc | 5 +- qcsrc/common/vehicles/sv_vehicles.qc | 52 ++-- qcsrc/common/vehicles/sv_vehicles.qh | 13 +- qcsrc/common/vehicles/unit/bumblebee.qc | 283 +++++++++++----------- qcsrc/common/vehicles/unit/bumblebee.qh | 2 + qcsrc/common/vehicles/unit/racer.qc | 44 +++- qcsrc/common/vehicles/unit/raptor.qc | 24 +- qcsrc/common/vehicles/unit/spiderbot.qc | 111 ++++++--- qcsrc/common/vehicles/vehicles.qc | 2 +- qcsrc/common/vehicles/vehicles.qh | 22 +- qcsrc/common/vehicles/vehicles_include.qh | 3 +- qcsrc/server/autocvars.qh | 2 + qcsrc/server/cl_player.qc | 3 + qcsrc/server/mutators/mutator_dodging.qc | 2 +- 15 files changed, 342 insertions(+), 229 deletions(-) diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 8b36f5c34..62307cb56 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1930,6 +1930,9 @@ void CSQC_UpdateView(float w, float h) HUD_Radar_Mouse(); if(hud && !intermission) + if(hud == HUD_BUMBLEBEE_GUN) + CSQC_BUMBLE_GUN_HUD(); + else VEH_ACTION(hud, VR_HUD); FPSCounter_Update(); diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index c2ebbe211..ee7d2d003 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -208,7 +208,7 @@ void turret_die() void turret_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) { - // Enougth allready! + // Enough already! if(self.deadflag == DEAD_DEAD) return; @@ -224,6 +224,9 @@ void turret_damage (entity inflictor, entity attacker, float damage, float death return; } + if(DEATH_WEAPONOFWEAPONDEATH(deathtype)) + damage = damage * autocvar_g_turrets_weapon_damagerate; + self.health -= damage; // thorw head slightly off aim when hit? diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index 4747ce460..f60d25b30 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -103,7 +103,7 @@ void vehicles_locktarget(float incr, float decr, float _lock_time) if(!(IS_VEHICLE(trace_ent) || IS_TURRET(trace_ent))) trace_ent = world; - + if(trace_ent.alpha <= 0.5 && trace_ent.alpha != 0) trace_ent = world; // invisible } @@ -634,8 +634,11 @@ void vehicles_damage(entity inflictor, entity attacker, float damage, float deat if(DEATH_ISWEAPON(deathtype, WEP_SEEKER)) damage *= autocvar_g_vehicles_tag_damagerate; + if(DEATH_WEAPONOFWEAPONDEATH(deathtype)) + damage *= autocvar_g_vehicles_weapon_damagerate; + self.enemy = attacker; - + self.pain_finished = time; if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0)) @@ -706,7 +709,7 @@ void vehicles_damage(entity inflictor, entity attacker, float damage, float deat float vehicles_crushable(entity e) { - if(IS_PLAYER(e)) + if(IS_PLAYER(e) && time >= e.vehicle_enter_delay) return true; if(IS_MONSTER(e)) @@ -847,6 +850,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); } @@ -884,7 +888,7 @@ void vehicles_exit(float eject) _vehicle.owner = world; CSQCMODEL_AUTOINIT(); - + self = _oldself; vehicles_exit_running = false; @@ -903,7 +907,7 @@ void vehicles_touch() if((self.origin_z + self.maxs_z) > (other.origin_z)) if(vehicles_crushable(other)) { - if(vlen(self.velocity) != 0) + if(vlen(self.velocity) >= 30) Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force); return; // Dont do selfdamage when hitting "soft targets". @@ -924,28 +928,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((!IS_PLAYER(pl)) + || (veh.phase >= time) + || (pl.vehicle_enter_delay >= time) + || (pl.frozen) + || (pl.deadflag != DEAD_NO) + || (pl.vehicle) + ) { return; } - if(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) { @@ -954,7 +948,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()) { @@ -963,7 +957,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()) { @@ -1093,7 +1087,7 @@ void vehicles_think() self.owner.vehicle_weapon2mode = self.vehicle_weapon2mode; VEH_ACTION(self.vehicleid, VR_THINK); - + CSQCMODEL_AUTOUPDATE(); } @@ -1144,7 +1138,7 @@ void vehicles_spawn() vehicles_reset_colors(); VEH_ACTION(self.vehicleid, VR_SPAWN); - + CSQCMODEL_AUTOINIT(); } @@ -1154,7 +1148,7 @@ float vehicle_initialize(float vehicle_id, float nodrop) return false; entity veh = get_vehicleinfo(vehicle_id); - + if(!veh.vehicleid) return false; diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh index 4e339e460..f7a7f91cb 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qh +++ b/qcsrc/common/vehicles/sv_vehicles.qh @@ -21,11 +21,12 @@ float autocvar_g_vehicles_delayspawn_jitter; float autocvar_g_vehicles_allow_bots; float autocvar_g_vehicles_teams; float autocvar_g_vehicles_teleportable; -var float autocvar_g_vehicles_vortex_damagerate = 0.5; -var float autocvar_g_vehicles_machinegun_damagerate = 0.5; -var float autocvar_g_vehicles_rifle_damagerate = 0.75; -var float autocvar_g_vehicles_vaporizer_damagerate = 0.001; -var float autocvar_g_vehicles_tag_damagerate = 5; +float autocvar_g_vehicles_vortex_damagerate = 0.5; +float autocvar_g_vehicles_machinegun_damagerate = 0.5; +float autocvar_g_vehicles_rifle_damagerate = 0.75; +float autocvar_g_vehicles_vaporizer_damagerate = 0.001; +float autocvar_g_vehicles_tag_damagerate = 5; +float autocvar_g_vehicles_weapon_damagerate = 1; // flags: .int vehicle_flags; @@ -104,6 +105,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 + void vehicles_exit(float eject); float vehicle_initialize(float vehicle_id, float nodrop); diff --git a/qcsrc/common/vehicles/unit/bumblebee.qc b/qcsrc/common/vehicles/unit/bumblebee.qc index 8bc60818b..b65a5f852 100644 --- a/qcsrc/common/vehicles/unit/bumblebee.qc +++ b/qcsrc/common/vehicles/unit/bumblebee.qc @@ -90,7 +90,7 @@ vector autocvar_g_vehicle_bumblebee_bouncepain; 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) { @@ -116,7 +116,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; @@ -143,15 +143,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; @@ -219,154 +211,173 @@ 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); + 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; + + gunner.phase = time + 5; + gunner.vehicle_hudmodel.viewmodelforclient = gunner; - self.velocity = 0.75 * self.vehicle.owner.velocity + normalize(spot - self.vehicle.owner.origin) * 200; - self.velocity_z += 10; + vh_player = player; + vh_vehicle = gunner; + MUTATOR_CALLHOOK(VehicleExit); + player = vh_player; + gunner = vh_vehicle; - 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(player, player.hud); - CSQCVehicleSetup(other, other.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)) - return false; - - if(other.deadflag != DEAD_NO) - return false; - - if(other.vehicle != world) + if(IS_BOT_CLIENT(other) && !autocvar_g_vehicles_allow_bots) 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; } @@ -383,13 +394,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(); @@ -688,14 +697,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() @@ -824,9 +833,9 @@ float v_bumblebee(float req) case VR_DEATH: { entity oldself = self; - + CSQCModel_UnlinkEntity(); - + // Hide beam if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) self.gun3.enemy.effects |= EF_NODRAW; @@ -910,6 +919,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"); diff --git a/qcsrc/common/vehicles/unit/bumblebee.qh b/qcsrc/common/vehicles/unit/bumblebee.qh index 08f9adf69..2373e9869 100644 --- a/qcsrc/common/vehicles/unit/bumblebee.qh +++ b/qcsrc/common/vehicles/unit/bumblebee.qh @@ -3,4 +3,6 @@ void bumble_raygun_read(bool bIsNew); +void CSQC_BUMBLE_GUN_HUD(); + #endif \ No newline at end of file diff --git a/qcsrc/common/vehicles/unit/racer.qc b/qcsrc/common/vehicles/unit/racer.qc index 1a54f4aa3..5f6934298 100644 --- a/qcsrc/common/vehicles/unit/racer.qc +++ b/qcsrc/common/vehicles/unit/racer.qc @@ -15,7 +15,7 @@ REGISTER_VEHICLE( #ifdef SVQC #include "../../effects.qh" -float autocvar_g_vehicle_racer; +bool autocvar_g_vehicle_racer; float autocvar_g_vehicle_racer_speed_afterburn; float autocvar_g_vehicle_racer_afterburn_cost; @@ -26,6 +26,9 @@ float autocvar_g_vehicle_racer_waterburn_speed; float autocvar_g_vehicle_racer_water_speed_forward; float autocvar_g_vehicle_racer_water_speed_strafe; +float autocvar_g_vehicle_racer_water_downforce = 0.03; +float autocvar_g_vehicle_racer_water_upforcedamper = 15; + float autocvar_g_vehicle_racer_anglestabilizer; float autocvar_g_vehicle_racer_downforce; @@ -35,7 +38,7 @@ float autocvar_g_vehicle_racer_springlength; float autocvar_g_vehicle_racer_upforcedamper; float autocvar_g_vehicle_racer_friction; -var float autocvar_g_vehicle_racer_water_time = 5; +float autocvar_g_vehicle_racer_water_time = 5; float autocvar_g_vehicle_racer_hovertype; float autocvar_g_vehicle_racer_hoverpower; @@ -90,6 +93,8 @@ float autocvar_g_vehicle_racer_bouncefactor; float autocvar_g_vehicle_racer_bouncestop; vector autocvar_g_vehicle_racer_bouncepain; +.float racer_watertime; + var vector racer_force_from_tag(string tag_name, float spring_length, float max_power); void racer_align4point(float _delta) @@ -114,16 +119,23 @@ void racer_align4point(float _delta) //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); self.velocity += push_vector * _delta; + + float uforce = autocvar_g_vehicle_racer_upforcedamper; if(pointcontents(self.origin - '0 0 64') == CONTENT_WATER) - if(self.owner.BUTTON_CROUCH && time < self.air_finished) - self.velocity_z += 30; - else - self.velocity_z += 200; + { + uforce = autocvar_g_vehicle_racer_water_upforcedamper; + + if(self.owner.BUTTON_CROUCH && time < self.air_finished) + self.velocity_z += 30; + else + self.velocity_z += 200; + } + // Anti ocilation if(self.velocity_z > 0) - self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * _delta; + self.velocity_z *= 1 - uforce * _delta; push_vector_x = (fl_push - bl_push); push_vector_x += (fr_push - br_push); @@ -376,7 +388,7 @@ float racer_frame() pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin - v_forward * 32, v_forward * vlen(self.velocity), 1); racer.wait = time; - + if(pointcontents(racer.origin) == CONTENT_WATER) { racer.vehicle_energy -= autocvar_g_vehicle_racer_waterburn_cost * frametime; @@ -409,7 +421,14 @@ float racer_frame() sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM); } - df -= v_up * (vlen(racer.velocity) * autocvar_g_vehicle_racer_downforce); + if(pointcontents(racer.origin) == CONTENT_WATER) + racer.racer_watertime = time; + + float dforce = autocvar_g_vehicle_racer_downforce; + if(time - racer.racer_watertime <= 3) + dforce = autocvar_g_vehicle_racer_water_downforce; + + df -= v_up * (vlen(racer.velocity) * dforce); player.movement = racer.velocity += df * frametime; if(!forbidWeaponUse(player)) @@ -511,12 +530,17 @@ void racer_think() vector df = self.velocity * -autocvar_g_vehicle_racer_friction; df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2); + float forced = autocvar_g_vehicle_racer_upforcedamper; + if(pointcontents(self.origin - '0 0 64') == CONTENT_WATER) + { + forced = autocvar_g_vehicle_racer_water_upforcedamper; self.velocity_z += 200; + } self.velocity += df * pushdeltatime; if(self.velocity_z > 0) - self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * pushdeltatime; + self.velocity_z *= 1 - forced * pushdeltatime; self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); diff --git a/qcsrc/common/vehicles/unit/raptor.qc b/qcsrc/common/vehicles/unit/raptor.qc index 9333dc62c..360892665 100644 --- a/qcsrc/common/vehicles/unit/raptor.qc +++ b/qcsrc/common/vehicles/unit/raptor.qc @@ -13,15 +13,15 @@ REGISTER_VEHICLE( ); #else -const float RSM_FIRST = 1; -const float RSM_BOMB = 1; -const float RSM_FLARE = 2; -const float RSM_LAST = 2; +const int RSM_FIRST = 1; +const int RSM_BOMB = 1; +const int RSM_FLARE = 2; +const int RSM_LAST = 2; #ifdef SVQC #include "../../effects.qh" -float autocvar_g_vehicle_raptor; +bool autocvar_g_vehicle_raptor; float autocvar_g_vehicle_raptor_respawntime; float autocvar_g_vehicle_raptor_takeofftime; @@ -417,7 +417,7 @@ float raptor_frame() raptor.velocity += df * frametime; player.velocity = player.movement = raptor.velocity; setorigin(player, raptor.origin + '0 0 32'); - + player.vehicle_weapon2mode = raptor.vehicle_weapon2mode; vector vf, ad; @@ -730,6 +730,17 @@ float raptor_impulse(float _imp) { switch(_imp) { + case 1: + case 230: + self.vehicle.vehicle_weapon2mode = RSM_BOMB; + CSQCVehicleSetup(self, 0); + return true; + case 2: + case 231: + self.vehicle.vehicle_weapon2mode = RSM_FLARE; + CSQCVehicleSetup(self, 0); + return true; + case 10: case 15: case 18: @@ -739,6 +750,7 @@ float raptor_impulse(float _imp) CSQCVehicleSetup(self, 0); return true; + case 11: case 12: case 16: case 19: diff --git a/qcsrc/common/vehicles/unit/spiderbot.qc b/qcsrc/common/vehicles/unit/spiderbot.qc index 85cd3e23a..9b961b509 100644 --- a/qcsrc/common/vehicles/unit/spiderbot.qc +++ b/qcsrc/common/vehicles/unit/spiderbot.qc @@ -13,16 +13,16 @@ REGISTER_VEHICLE( ); #else -const float SBRM_FIRST = 1; -const float SBRM_VOLLY = 1; -const float SBRM_GUIDE = 2; -const float SBRM_ARTILLERY = 3; -const float SBRM_LAST = 3; +const int SBRM_FIRST = 1; +const int SBRM_VOLLY = 1; +const int SBRM_GUIDE = 2; +const int SBRM_ARTILLERY = 3; +const int SBRM_LAST = 3; #ifdef SVQC #include "../../effects.qh" -float autocvar_g_vehicle_spiderbot; +bool autocvar_g_vehicle_spiderbot; float autocvar_g_vehicle_spiderbot_respawntime; @@ -43,20 +43,20 @@ float autocvar_g_vehicle_spiderbot_head_pitchlimit_up; float autocvar_g_vehicle_spiderbot_head_turnlimit; float autocvar_g_vehicle_spiderbot_head_turnspeed; -float autocvar_g_vehicle_spiderbot_health; +int autocvar_g_vehicle_spiderbot_health; float autocvar_g_vehicle_spiderbot_health_regen; float autocvar_g_vehicle_spiderbot_health_regen_pause; -float autocvar_g_vehicle_spiderbot_shield; +int autocvar_g_vehicle_spiderbot_shield; float autocvar_g_vehicle_spiderbot_shield_regen; float autocvar_g_vehicle_spiderbot_shield_regen_pause; float autocvar_g_vehicle_spiderbot_minigun_damage; float autocvar_g_vehicle_spiderbot_minigun_refire; float autocvar_g_vehicle_spiderbot_minigun_spread; -float autocvar_g_vehicle_spiderbot_minigun_ammo_cost; -float autocvar_g_vehicle_spiderbot_minigun_ammo_max; -float autocvar_g_vehicle_spiderbot_minigun_ammo_regen; +int autocvar_g_vehicle_spiderbot_minigun_ammo_cost; +int autocvar_g_vehicle_spiderbot_minigun_ammo_max; +int autocvar_g_vehicle_spiderbot_minigun_ammo_regen; float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause; float autocvar_g_vehicle_spiderbot_minigun_force; float autocvar_g_vehicle_spiderbot_minigun_solidpenetration; @@ -322,6 +322,7 @@ void spiderbot_rocket_do() self.gun2.cnt = time + self.attack_finished_single; } +.float jump_delay; float spiderbot_frame() { vector ad, vf; @@ -390,37 +391,59 @@ float spiderbot_frame() movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit); if(spider.flags & FL_ONGROUND) + spider.jump_delay = time; // reset now so movement can begin + + //if(spider.flags & FL_ONGROUND) { + if(spider.flags & FL_ONGROUND) if(spider.frame == 4 && self.tur_head.wait != 0) { sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTEN_NORM); spider.frame = 5; } - if(player.BUTTON_JUMP && self.tur_head.wait < time) + if((spider.flags & FL_ONGROUND) && player.BUTTON_JUMP && self.tur_head.wait < time) { sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTEN_NORM); //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n"); self.delay = 0; self.tur_head.wait = time + 2; + spider.jump_delay = time + 2; player.BUTTON_JUMP = 0; - spider.velocity = v_forward * 700 + v_up * 600; + + vector movefix = '0 0 0'; + if(player.movement_x > 0) movefix_x = 1; + if(player.movement_x < 0) movefix_x = -1; + if(player.movement_y > 0) movefix_y = 1; + if(player.movement_y < 0) movefix_y = -1; + + vector rt = movefix_y * v_right; + vector sd = movefix_x * v_forward; + if(movefix_y == 0 && movefix_x == 0) + sd = v_forward; // always do forward + + spider.flags &= ~FL_ONGROUND; + + spider.velocity = sd * 700 + rt * 600 + v_up * 600; spider.frame = 4; } - else + else if(time >= spider.jump_delay) { if(vlen(player.movement) == 0) { - if(self.sound_nexttime < time || self.delay != 3) + if(spider.flags & FL_ONGROUND) { - self.delay = 3; - self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav"); - //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + if(self.sound_nexttime < time || self.delay != 3) + { + self.delay = 3; + self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav"); + //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); + spider.frame = 5; } - movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); - spider.frame = 5; } else { @@ -439,16 +462,23 @@ float spiderbot_frame() if(player.movement_x > 0) { player.movement_x = 1; - spider.frame = 0; + if(spider.flags & FL_ONGROUND) + spider.frame = 0; } else if(player.movement_x < 0) { player.movement_x = -1; - spider.frame = 1; + if(spider.flags & FL_ONGROUND) + spider.frame = 1; } player.movement_y = 0; + float oldvelz = spider.velocity_z; movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia); - + spider.velocity_z = oldvelz; + float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1); + if(spider.velocity_z <= 20) // not while jumping + spider.velocity_z -= g * sys_frametime * autocvar_sv_gravity; + if(spider.flags & FL_ONGROUND) if(self.sound_nexttime < time || self.delay != 1) { self.delay = 1; @@ -462,14 +492,23 @@ float spiderbot_frame() if(player.movement_y < 0) { player.movement_y = -1; - spider.frame = 2; + if(spider.flags & FL_ONGROUND) + spider.frame = 2; } else if(player.movement_y > 0) { player.movement_y = 1; - spider.frame = 3; + if(spider.flags & FL_ONGROUND) + spider.frame = 3; } + + float oldvelz = spider.velocity_z; movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia); + spider.velocity_z = oldvelz; + float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1); + if(spider.velocity_z <= 20) // not while jumping + spider.velocity_z -= g * sys_frametime * autocvar_sv_gravity; + if(spider.flags & FL_ONGROUND) if(self.sound_nexttime < time || self.delay != 2) { self.delay = 2; @@ -705,10 +744,27 @@ void spiderbot_blowup() self.vehicle_hudmodel.viewmodelforclient = self; } -float spiderbot_impulse(float _imp) +bool spiderbot_impulse(int _imp) { switch(_imp) { + case 1: + case 230: + self.vehicle.vehicle_weapon2mode = SBRM_VOLLY; + CSQCVehicleSetup(self, 0); + return true; + case 2: + case 231: + self.vehicle.vehicle_weapon2mode = SBRM_GUIDE; + CSQCVehicleSetup(self, 0); + return true; + case 3: + case 232: + case 251: + self.vehicle.vehicle_weapon2mode = SBRM_ARTILLERY; + CSQCVehicleSetup(self, 0); + return true; + case 10: case 15: case 18: @@ -719,6 +775,7 @@ float spiderbot_impulse(float _imp) //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode))); CSQCVehicleSetup(self, 0); return true; + case 11: case 12: case 16: case 19: diff --git a/qcsrc/common/vehicles/vehicles.qc b/qcsrc/common/vehicles/vehicles.qc index 83fe5e348..81aca27c2 100644 --- a/qcsrc/common/vehicles/vehicles.qc +++ b/qcsrc/common/vehicles/vehicles.qc @@ -24,7 +24,7 @@ void vehicles_common_initialize() addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health); addstat(STAT_VEHICLESTAT_SHIELD, AS_INT, vehicle_shield); addstat(STAT_VEHICLESTAT_ENERGY, AS_INT, vehicle_energy); - + addstat(STAT_VEHICLESTAT_W2MODE, AS_INT, vehicle_weapon2mode); addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1); diff --git a/qcsrc/common/vehicles/vehicles.qh b/qcsrc/common/vehicles/vehicles.qh index bfc01b795..c803adeb0 100644 --- a/qcsrc/common/vehicles/vehicles.qh +++ b/qcsrc/common/vehicles/vehicles.qh @@ -37,10 +37,10 @@ entity get_vehicleinfo(float id); // entity properties of vehicleinfo: -.float vehicleid; // VEH_... +.int vehicleid; // VEH_... .string netname; // short name .string vehicle_name; // human readable name -.float(float) vehicle_func; // v_... +.int(int) vehicle_func; // v_... .string mdl; // currently a copy of the model .string model; // full name of model .string head_model; // full name of tur_head model @@ -48,8 +48,8 @@ entity get_vehicleinfo(float id); .string tag_head; // tur_head model tag .string tag_hud; // hud model tag .string tag_view; // cockpit model tag -.float() PlayerPhysplug; // player physics mod -.float spawnflags; +.int() PlayerPhysplug; // player physics mod +.int spawnflags; .vector mins, maxs; // vehicle hitbox size // other useful macros @@ -60,18 +60,18 @@ entity get_vehicleinfo(float id); // Vehicle Registration // ===================== -float v_null(float dummy); -void register_vehicle(float id, float(float) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname); +int v_null(int dummy); +void register_vehicle(int id, int(int) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname); void register_vehicles_done(); -const float VEH_MAXCOUNT = 24; +const int VEH_MAXCOUNT = 24; #define VEH_FIRST 1 -float VEH_COUNT; -float VEH_LAST; +int VEH_COUNT; +int VEH_LAST; #define REGISTER_VEHICLE_2(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ - float id; \ - float func(float); \ + int id; \ + int func(int); \ void RegisterVehicles_##id() \ { \ VEH_LAST = (id = VEH_FIRST + VEH_COUNT); \ diff --git a/qcsrc/common/vehicles/vehicles_include.qh b/qcsrc/common/vehicles/vehicles_include.qh index 409e94cb2..4ed5b5111 100644 --- a/qcsrc/common/vehicles/vehicles_include.qh +++ b/qcsrc/common/vehicles/vehicles_include.qh @@ -4,8 +4,7 @@ #ifdef CSQC #include "vehicles.qh" #include "cl_vehicles.qh" -#endif // CSQC -#ifdef SVQC +#elif defined(SVQC) #include "vehicles.qh" #include "sv_vehicles.qh" #endif // SVQC diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index b3a26e3ca..c8f2a35fa 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -562,6 +562,8 @@ float autocvar_g_turrets_nofire; float autocvar_g_turrets_reloadcvars; float autocvar_g_turrets_targetscan_maxdelay; float autocvar_g_turrets_targetscan_mindelay; +float autocvar_g_turrets_weapon_damagerate = 1; +float autocvar_g_turrets_player_damagerate = 1; // incorrectly named, but there is no g_player yet float autocvar_g_use_ammunition; float autocvar_g_waypointeditor; float autocvar_g_waypointeditor_auto; diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index f558fe59a..0b36b588d 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -313,6 +313,9 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp damage /= sqrt(bound(1.0, attacker.cvar_cl_handicap, 100.0)); } + if(DEATH_ISTURRET(deathtype)) + damage *= autocvar_g_turrets_player_damagerate; + if(DEATH_ISWEAPON(deathtype, WEP_TUBA)) { // tuba causes blood to come out of the ears diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc index cfe1e34ae..4abdd22d1 100644 --- a/qcsrc/server/mutators/mutator_dodging.qc +++ b/qcsrc/server/mutators/mutator_dodging.qc @@ -94,7 +94,7 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) { if (self.movement_z > 0) self.movement_z = 0; self.velocity += - + ((self.dodging_direction_y * velocity_difference) * v_right) + ((self.dodging_direction_y * velocity_difference) * v_right) + ((self.dodging_direction_x * velocity_difference) * v_forward); self.dodging_velocity_gain = self.dodging_velocity_gain - velocity_difference; -- 2.39.2