- fix team selection race condition exploit in FreeCS

- fix lots of buggy round logic
- make use of HLWeaponSelect
- move from def/ to decls/def
This commit is contained in:
Marco Cawthorne 2024-08-14 17:10:08 -07:00
parent 10468ee174
commit 73638fd197
Signed by: eukara
GPG key ID: CE2032F0A2882A22
76 changed files with 317 additions and 252 deletions

View file

@ -56,10 +56,10 @@ ClientGame_ConsoleCommand(void)
{
switch(argv(0)) {
case "invnext":
HUD_DrawWeaponSelect_Back();
pSeatLocal->weaponSelectionHUD.SelectNext(false);
break;
case "invprev":
HUD_DrawWeaponSelect_Forward();
pSeatLocal->weaponSelectionHUD.SelectPrevious(false);
break;
case "lastinv":
HUD_DrawWeaponSelect_Last();

View file

@ -18,12 +18,14 @@
#include "radio.h"
#include "../../../valve/src/client/obituary.h"
#include "../../../valve/src/client/hud_sprite.h"
#include "../../../valve/src/client/HLWeaponSelect.h"
var int autocvar_cl_autoweaponswitch = TRUE;
vector g_hud_color;
vector g_hudmins;
vector g_hudres;
var string g_laser_spr;
var string g_hud1_spr;
var string g_hud2_spr;
@ -80,6 +82,7 @@ struct
float m_flTimeAlpha;
vector m_vecMoneyColor;
int m_iNightvision;
HLWeaponSelect weaponSelectionHUD;
} g_seatslocal[4], *pSeatLocal;
void HUD_DrawAmmo1(void);

View file

@ -725,10 +725,11 @@ HUD_Draw(void)
g_hud_color = autocvar_con_color * (1 / 255);
/* little point in not drawing these, even if you don't have a suit */
if (pl.m_activeWeapon)
if (pl.m_activeWeapon) {
pl.m_activeWeapon.UpdateGUI();
}
HUD_DrawWeaponSelect();
pSeatLocal->weaponSelectionHUD.Draw();
Obituary_Draw();
Textmenu_Draw();
@ -756,6 +757,10 @@ HUD_Draw(void)
void
HUD_DrawSpectator(void)
{
if (VGUI_Active() == true) {
return;
}
Textmenu_Draw();
Obituary_Draw();

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define AMMO_COUNT 13
string g_ammo_spr;

View file

@ -106,10 +106,17 @@ ClientGame_Init(float apilevel, string enginename, float engineversion)
registercommand("negative");
registercommand("enemydown");
/* hud */
registercommand("lastinv");
registercommand("invnext");
registercommand("invprev");
Obituary_Init();
Sound_Precache("nvg.on");
Sound_Precache("nvg.off");
pSeatLocal->weaponSelectionHUD = spawn(HLWeaponSelect);
}
bool

View file

@ -19,19 +19,18 @@ Nightvision_Toggle(void)
{
CSPlayer pl = (CSPlayer)pSeat->m_ePlayer;
#if 0
if (!(pl.g_items & ITEM_NIGHTVISION)) {
if (pl.HasItem("item_nightvision") == false) {
pSeatLocal->m_iNightvision = 0;
return;
}
#endif
pSeatLocal->m_iNightvision = 1 - pSeatLocal->m_iNightvision;
if (pSeatLocal->m_iNightvision)
if (pSeatLocal->m_iNightvision) {
Sound_Play(self, CHAN_AUTO, "nvg.on");
else
} else {
Sound_Play(self, CHAN_AUTO, "nvg.off");
}
}
void
@ -39,15 +38,14 @@ Nightvision_PreFrame(void)
{
CSPlayer pl = (CSPlayer)pSeat->m_ePlayer;
if (!pSeatLocal->m_iNightvision)
if (!pSeatLocal->m_iNightvision) {
return;
}
#if 0
if (!(pl.g_items & ITEM_NIGHTVISION)) {
if (pl.HasItem("item_nightvision") == false) {
pSeatLocal->m_iNightvision = 0;
return;
}
#endif
dynamiclight_add(pSeat->m_vecPredictedOrigin, 768, [1,1,1]);
}
@ -57,15 +55,14 @@ Nightvision_PostFrame(void)
{
CSPlayer pl = (CSPlayer)pSeat->m_ePlayer;
if (!pSeatLocal->m_iNightvision)
if (!pSeatLocal->m_iNightvision) {
return;
}
#if 0
if (!(pl.g_items & ITEM_NIGHTVISION)) {
if (pl.HasItem("item_nightvision") == false) {
pSeatLocal->m_iNightvision = 0;
return;
}
#endif
drawpic(video_mins, "fade_modulate", g_hudres, [0,1,0], 1.0f, 0);
}

View file

@ -37,6 +37,7 @@ hud_ammonotify.qc
vgui_spectator.qc
hud.qc
../../../valve/src/client/hud_sprite.qc
../../../valve/src/client/HLWeaponSelect.qc
../../../valve/src/client/hud_weaponselect.qc
../../../valve/src/client/scoreboard.qc
radio.qc

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void Radio_Init(void);
void Radio_PlayMessage(float);
void Radio_PlayPlayerMessage(float, float);

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void Ammo_BuyPrimary(NSClientPlayer pl, int free);
void Ammo_BuySecondary(NSClientPlayer pl, int free);
void Ammo_AutoFill(NSClientPlayer);

View file

@ -32,7 +32,6 @@ func_bomb_target:NSBrushTrigger
{
void(void) func_bomb_target;
virtual void(void) Respawn;
virtual void(entity) Touch;
};
@ -42,18 +41,12 @@ func_bomb_target::func_bomb_target(void)
g_cs_bombzones++;
}
void
func_bomb_target::Respawn(void)
{
InitBrushTrigger();
}
void
func_bomb_target::Touch(entity eToucher)
{
CSPlayer pl = (CSPlayer)eToucher;
if (!(eToucher.flags & FL_CLIENT)) {
if (isPlayer(pl) == false) {
return;
}
@ -65,5 +58,6 @@ func_bomb_target::Touch(entity eToucher)
env_message_single(pl, "Hint_you_are_in_targetzone");
pl.m_seenBombSite = true;
}
pl.gflags |= GF_BOMBZONE;
}

View file

@ -51,7 +51,7 @@ func_hostage_rescue::Respawn(void)
void
func_hostage_rescue::Touch(entity eToucher)
{
if (eToucher.flags & FL_CLIENT) {
if (isPlayer(eToucher)) {
CSPlayer pl = (CSPlayer)eToucher;
pl.gflags |= GF_RESCUEZONE;
return;

View file

@ -113,8 +113,8 @@ CSMultiplayerRules::PlayerDeath(NSClientPlayer pl)
forceinfokey(targ, "*deaths", ftos(targ.deaths));
/* update score-counter */
if (g_dmg_eTarget.flags & FL_CLIENT || g_dmg_eTarget.flags & FL_MONSTER)
if (g_dmg_eAttacker.flags & FL_CLIENT) {
if (isClient(g_dmg_eTarget) || isAI(g_dmg_eTarget))
if (isClient(g_dmg_eAttacker)) {
float vip = (g_dmg_eTarget.team == TEAM_VIP && g_dmg_eAttacker.team == TEAM_CT);
if (g_dmg_eTarget == g_dmg_eAttacker) {
@ -129,7 +129,7 @@ CSMultiplayerRules::PlayerDeath(NSClientPlayer pl)
}
/* scoreboard death icon */
if (g_dmg_eTarget.flags & FL_CLIENT) {
if (isClient(g_dmg_eTarget)) {
targ.SetInfoKey("*icon1", "d_skull");
targ.SetInfoKey("*icon1_r", "1");
targ.SetInfoKey("*icon1_g", "0");
@ -408,7 +408,7 @@ CSMultiplayerRules::TimerUpdate(void)
}
}
// This map has been played enough we think
/* This map has been played enough we think */
if (g_cs_gamestate != GAME_OVER) {
if (cvar("mp_timelimit") > 0) {
if (time >= (cvar("mp_timelimit") * 60)) {
@ -418,9 +418,9 @@ CSMultiplayerRules::TimerUpdate(void)
}
}
// Okay, this means that timelimit is not the only deciding factor
/* Okay, this means that timelimit is not the only deciding factor */
if (autocvar_mp_winlimit > 0 && g_cs_gamestate != GAME_OVER) {
// It really doesn't matter who won. Do some logging perhaps?
/* It really doesn't matter who won. Do some logging perhaps? */
if (g_cs_roundswon_ct == autocvar_mp_winlimit ||
g_cs_roundswon_t == autocvar_mp_winlimit) {
IntermissionStart();
@ -465,7 +465,7 @@ CSMultiplayerRules::TimerUpdate(void)
}
}
TimeOut();
TimerBegin(5, GAME_END); // Round is over, 5 seconds til a new round starts
TimerBegin(5, GAME_END); /* Round is over, 5 seconds til a new round starts */
} else {
TimerBegin(autocvar_mp_roundtime * 60, GAME_ACTIVE); // Unfreeze
Radio_StartMessage();
@ -485,7 +485,7 @@ Checks if it is possible for players to buy anything
bool
CSMultiplayerRules::BuyingPossible(NSClientPlayer pl)
{
if (pl.health <= 0) {
if (pl.IsDead()) {
return (false);
}
@ -537,7 +537,7 @@ CSMultiplayerRules::MakeVIP(NSClientPlayer pl)
pl.team = TEAM_VIP;
PlayerRespawn(pl, pl.team);
env_message_single(pl, "Hint_you_are_the_vip");
forceinfokey(pl, "*dead", "2");
pl.SetInfoKey("*dead", "2");
pl.SetModel("models/player/vip/vip.mdl");
}
@ -574,8 +574,9 @@ CSMultiplayerRules::RestartRound(int iWipe)
CSBot_RestartRound();
for (entity eFind = world; (eFind = findfloat(eFind, ::team, TEAM_T));) {
if (!(eFind.flags & FL_CLIENT))
if (isClient(eFind) == false) {
continue;
}
CSPlayer pl = (CSPlayer)eFind;
@ -593,8 +594,9 @@ CSMultiplayerRules::RestartRound(int iWipe)
}
}
for (entity eFind = world; (eFind = findfloat(eFind, ::team, TEAM_CT));) {
if (!(eFind.flags & FL_CLIENT))
if (isClient(eFind) == false) {
continue;
}
CSPlayer pl = (CSPlayer)eFind;
@ -614,8 +616,9 @@ CSMultiplayerRules::RestartRound(int iWipe)
/* respawn the VIP as well, but turn them back into a CT. */
for (entity eFind = world; (eFind = findfloat(eFind, ::team, TEAM_VIP));) {
if (!(eFind.flags & FL_CLIENT))
if (isClient(eFind) == false) {
continue;
}
CSPlayer pl = (CSPlayer)eFind;
pl.team = TEAM_CT;
@ -801,7 +804,7 @@ CSMultiplayerRules::SwitchTeams(void)
pl.team = TEAM_CT;
pl.charmodel += 4;
}
forceinfokey(pl, "*team", ftos(pl.team));
pl.SetInfoKey("*team", ftos(pl.team));
}
iCTW = g_cs_roundswon_ct;
@ -1032,8 +1035,7 @@ CSMultiplayerRules::PlayerRespawn(NSClientPlayer pp, int fTeam)
pl.ClearVelocity();
pl.progress = 0.0f;
/* TODO: Implement this in NSNavAI*/
//Weapons_SwitchBest(pl);
pl.SwitchToBestWeapon(false);
Ammo_AutoFill(pl);
}
@ -1052,29 +1054,32 @@ void
CSMultiplayerRules::PlayerMakePlayable(NSClientPlayer pp, int chara)
{
CSPlayer pl = (CSPlayer)pp;
/* spectator */
if (chara == 0) {
PlayerSpawn(pl);
return;
}
pl.RemoveAllItems(false);
pl.ingame = TRUE;
forceinfokey(pl, "*team", ftos(pl.team));
pl.SetInfoKey("*team", ftos(pl.team));
PlayerRespawn(pl, pl.team);
/* terrorists */
if (chara < 5) {
pl.team = TEAM_T;
if (autocvar_fcs_knifeonly == FALSE) {
pl.GiveItem("weapon_glock18");
//pl.ammo_9mm = 40;
pl.GiveAmmo(ammoNumForName("ammo_9mm"), 40);
}
} else {
pl.team = TEAM_CT;
if (autocvar_fcs_knifeonly == FALSE) {
pl.GiveItem("weapon_usp");
//pl.ammo_45acp = 24;
pl.GiveAmmo(ammoNumForName("ammo_45acp"), 24);
}
}
@ -1139,7 +1144,7 @@ CSMultiplayerRules::PlayerSpawn(NSClientPlayer pl)
/* we don't belong to any team */
pl.team = TEAM_SPECTATOR;
forceinfokey(pl, "*team", "0");
pl.SetInfoKey("*team", "0");
}
bool
@ -1195,16 +1200,28 @@ CSEv_JoinTeam_f(float flChar)
rules = (CSMultiplayerRules)g_grMode;
pl = (CSPlayer)self;
/* VIPs cannot change teams... ? */
if (pl.team == TEAM_VIP) {
centerprint(pl, "You are the VIP!\nYou cannot switch roles now.\n");
return;
}
// alive and are trying to switch teams, so subtract us from the Alive_Team counter.
if (pl.health > 0) {
if (pl.IsAlive()) {
rules.PlayerKill(pl);
}
/* team switching, var reset */
if (flChar < 5) {
pl.team = TEAM_T;
} else {
pl.team = TEAM_CT;
}
pl.frags = 0;
pl.deaths = 0;
pl.SetInfoKey("*deaths", ftos(pl.deaths));
pl.SetInfoKey("*team", ftos(pl.team));
switch (g_cs_gamestate) {
/* spawn the players immediately when its in the freeze state */
case GAME_FREEZE:
@ -1229,23 +1246,12 @@ CSEv_JoinTeam_f(float flChar)
return;
}
//PlayerMakeSpectator(pl);
rules.PlayerMakeSpectator(pl);
pl.charmodel = (int)flChar;
forceinfokey(pl, "*dead", "1");
pl.SetInfoKey("*dead", "1");
break;
}
if (flChar < 5)
pl.team = TEAM_T;
else
pl.team = TEAM_CT;
forceinfokey(pl, "*team", ftos(pl.team));
pl.frags = 0;
pl.deaths = 0;
forceinfokey(pl, "*deaths", ftos(pl.deaths));
rules.CountPlayers();
/* if no players are present in the chosen team, force restart round */

View file

@ -57,9 +57,9 @@ CSSingleplayerRules::PlayerSpawn(NSClientPlayer pl)
pl.frame = 1;
pl.SendFlags = UPDATE_ALL;
pl.customphysics = Empty;
pl.iBleeds = TRUE;
forceinfokey(pl, "*spec", "0");
forceinfokey(pl, "*deaths", ftos(pl.deaths));
pl.EnableBleeding();
pl.SetInfoKey("*spec", "0");
pl.SetInfoKey("*deaths", ftos(pl.deaths));
entity spot;

View file

@ -105,8 +105,9 @@ CSHostage::OnPlayerUse(void)
return;
}
if (m_eFollowing == world)
if (m_eFollowing == world) {
Sound_Speak(this, "hostage_entity.follow");
}
/* CT reward, first time only */
if (m_iUsedOnce == FALSE) {
@ -118,12 +119,13 @@ CSHostage::OnPlayerUse(void)
}
void
CSHostage::Pain(entity inflictor, entity attacker, int damage, vector dir, int location)
CSHostage::Pain(entity inflictor, entity attacker, int damageDealt, vector dir, int location)
{
super::Pain(inflictor, attacker, damage, dir, location);
super::Pain(inflictor, attacker, damageDealt, dir, location);
if (IsAlive() == false)
if (IsAlive() == false) {
return;
}
switch (location) {
case BODY_HEAD:
@ -147,14 +149,15 @@ CSHostage::Pain(entity inflictor, entity attacker, int damage, vector dir, int l
}
/* penalties */
if (attacker.classname != "player")
if (isPlayer(attacker) == false) {
return;
}
Money_AddMoney((NSClientPlayer)attacker, -(damage * 25i));
Money_AddMoney((NSClientPlayer)attacker, -(damageDealt * 25i));
}
void
CSHostage::Death(entity inflictor, entity attacker, int damage, vector dir, int location)
CSHostage::Death(entity inflictor, entity attacker, int damageDealt, vector dir, int location)
{
WarnAllies();
@ -171,11 +174,12 @@ CSHostage::Death(entity inflictor, entity attacker, int damage, vector dir, int
break;
}
if (attacker.classname == "player") {
if (damage >= 100)
if (isPlayer(attacker) == true) {
if (damageDealt >= 100) {
Money_AddMoney((NSClientPlayer)attacker, -2500);
else
} else {
Money_AddMoney((NSClientPlayer)attacker, -500);
}
Radio_BroadcastMessage(RADIO_HOSDOWN);
}
@ -185,7 +189,7 @@ CSHostage::Death(entity inflictor, entity attacker, int damage, vector dir, int
SetHealth(0);
/* now mark our state as 'dead' */
super::Death(inflictor, attacker, damage, dir, location);
super::Death(inflictor, attacker, damageDealt, dir, location);
SetSolid(SOLID_NOT);
}

View file

@ -52,7 +52,7 @@ info_hostage_rescue::Respawn(void)
void
info_hostage_rescue::Touch(entity eToucher)
{
if (eToucher.flags & FL_CLIENT) {
if (isPlayer(eToucher)) {
CSPlayer pl = (CSPlayer)eToucher;
pl.gflags |= GF_RESCUEZONE;
return;

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void Radio_BroadcastMessage(float fMessage);
void Radio_TeamMessage(float fMessage, float fTeam);
float Radio_DefaultStart(void);

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
Radio_BroadcastMessage

View file

@ -17,10 +17,7 @@
class
CSProjectile:NSProjectile
{
float m_flRangeModifier;
int m_iTotalPenetrations;
float m_flMaxThickness;
public:
void CSProjectile(void);
#ifdef SERVER
@ -30,5 +27,10 @@ CSProjectile:NSProjectile
virtual void _FireSingle(vector,vector,float,float);
virtual void _LaunchHitscan(vector, vector, float);
private:
float m_flRangeModifier;
int m_iTotalPenetrations;
float m_flMaxThickness;
#endif
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Vera Visions LLC.
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -12,7 +12,7 @@
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
*/
void
CSProjectile::CSProjectile(void)
@ -20,6 +20,7 @@ CSProjectile::CSProjectile(void)
}
#ifdef SERVER
void
CSProjectile::SetRangeModifier(float rangeModifier)
{
@ -38,7 +39,6 @@ CSProjectile::SetPenetrationPower(int powerLevel)
m_iTotalPenetrations = powerLevel;
}
#ifdef SERVER
void
CSProjectile::_LaunchHitscan(vector startPos, vector launchDir, float dmgMultiplier)
{

View file

@ -19,27 +19,31 @@ void Cstrike_DrawCrosshair(CSPlayer);
#endif
class
CSWeapon:NSWeapon
CSWeapon:HLWeapon
{
public:
void CSWeapon(void);
#ifdef CLIENT
virtual void AddedToInventory(void);
virtual void UpdateGUI(void);
#endif
virtual void Draw(void);
virtual void SecondaryAttack(void);
virtual void Release(void);
virtual void FiredWeaponAttack(string);
virtual void SwitchedToWeapon(void);
#ifdef CLIENT
private:
int m_iHudSlot;
int m_iHudSlotPos;
string m_ammoIcon;
string m_crossHair;
NSWeapon m_nextWeapon;
virtual void AddedToInventory(void);
virtual void UpdateGUI(void);
#endif
virtual void Draw(void);
virtual void PrimaryAttack(void);
virtual void SecondaryAttack(void);
virtual void Release(void);
virtual void FiredWeaponAttack(string);
virtual void SwitchedToWeapon(void);
};
void
@ -51,26 +55,7 @@ CSWeapon::CSWeapon(void)
void
CSWeapon::SwitchedToWeapon(void)
{
w_cstrke_switched((CSPlayer)owner);
}
void
CSWeapon::PrimaryAttack(void)
{
if (GetDefBool("altAlternates") == true) {
if (CanFire() == false) {
return;
}
m_iMode = 1 - m_iMode;
}
if (m_iMode) {
super::SecondaryAttack();
return;
}
super::PrimaryAttack();
Cstrike_ShotReset((CSPlayer)owner);
}
void
@ -139,7 +124,7 @@ CSWeapon::FiredWeaponAttack(string defName)
}
for (int i = 0i; i < numProjectiles; i++) {
CSProjectile_SpawnDef(traceInfo, owner, flRangeModifier, flPenetrationPower, bulletSpread);
CSProjectile_SpawnDef(traceInfo, ourOwner, flRangeModifier, flPenetrationPower, bulletSpread);
}
#endif
@ -162,7 +147,6 @@ CSWeapon::Draw(void)
CSPlayer ourOwner = (CSPlayer)owner;
ourOwner.cs_cross_mindist = GetDefInt("crossMinDist");
ourOwner.cs_cross_deltadist = GetDefInt("crossDeltaDist");
CStrikeView_UpdateGeomset(ourOwner);
#endif
}
@ -171,7 +155,7 @@ void
CSWeapon::Release(void)
{
owner.v_angle = input_angles;
w_cstrike_weaponrelease((CSPlayer)owner);
Cstrike_ShotMultiplierUpdate((CSPlayer)owner);
input_angles = owner.v_angle;
super::Release();
}

View file

@ -21,6 +21,7 @@
#include "entities.h"
#include "events.h"
#include "CSProjectile.h"
#include "../../../valve/src/shared/HLWeapon.h"
#define TEAM_SPECTATOR 0
#define TEAM_T 1

View file

@ -13,6 +13,7 @@ fx_smokenade.qc
item_c4bomb.qc
weapons_cstrike.qc
CSProjectile.qc
../../../valve/src/shared/HLWeapon.qc
CSWeapon.qc
pmove.qc
#endlist

View file

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
string g_c4bombled_spr;
void w_c4bomb_parse(void);

View file

@ -16,16 +16,10 @@
class CSBombEntity:NSRenderableEntity
{
#ifdef SERVER
entity m_eUser;
float m_flBeepTime;
float m_flExplodeTime;
float m_flDefusalState;
#endif
#ifdef SERVER
public:
void CSBombEntity(void);
#ifdef SERVER
virtual void Spawned(void);
virtual float SendEntity(entity, float);
virtual void ClearProgress(void);
@ -35,10 +29,17 @@ class CSBombEntity:NSRenderableEntity
#endif
#ifdef CLIENT
void CSBombEntity(void);
virtual void DrawLED(void);
virtual float predraw(void);
#endif
#ifdef SERVER
private:
entity m_eUser;
float m_flBeepTime;
float m_flExplodeTime;
float m_flDefusalState;
#endif
};
void

View file

@ -139,6 +139,7 @@ class CSPlayer:NSClientPlayer
virtual void PredictPreFrame(void);
virtual void PredictPostFrame(void);
virtual void UpdateAliveCam(void);
virtual void ClientInputFrame(void);
#else
virtual void ServerInputFrame(void);
virtual void EvaluateEntity(void);
@ -211,6 +212,22 @@ CSPlayer::UpdatePlayerAnimation(float timelength)
}
#ifdef CLIENT
void
CSPlayer::ClientInputFrame(void)
{
if (pSeatLocal->weaponSelectionHUD.Active()) {
if (input_buttons & INPUT_PRIMARY) {
pSeatLocal->weaponSelectionHUD.Trigger();
} else if (input_buttons & INPUT_SECONDARY) {
pSeatLocal->weaponSelectionHUD.Deactivate();
}
pSeat->m_flInputBlockTime = time + 0.2;
}
super::ClientInputFrame();
}
void Camera_RunPosBob(vector angles, __inout vector camera_pos);
void Camera_StrafeRoll(__inout vector camera_angle);
void Shake_Update(NSClientPlayer);

View file

@ -1,3 +1,18 @@
/*
* Copyright (c) 2016-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
enum
{

View file

@ -33,18 +33,6 @@ var bool autocvar_fcs_guns_random_recoil_direction = TRUE;
var float autocvar_fcs_guns_movement_inaccuracy = 1.0f;
var float autocvar_fcs_guns_firing_inaccuracy = 1.0f;
weapontype_t
csweapon_ranged_type(CSPlayer pl)
{
return WPNTYPE_RANGED;
}
weapontype_t
csweapon_melee_type(CSPlayer pl)
{
return WPNTYPE_CLOSE;
}
float
Cstrike_CalculateMovementInaccuracy(CSPlayer pl) {
float m = 1.0f;
@ -150,8 +138,6 @@ Cstrike_ShotMultiplierAdd(CSPlayer pl, float shots, float strength, float inaccu
}*/
}
/* generate an accuracy value that we'll pass onto TraceAttack */
float
Cstrike_CalculateAccuracy(CSPlayer pl, float divisor, float movement_penalty=1)
@ -209,19 +195,6 @@ Cstrike_ShotReset(CSPlayer pl)
pl.cs_shotmultiplier = 0;
}
void
w_cstrike_weaponrelease(CSPlayer pl)
{
//pl.punchangle[1] *= 0.95;
Cstrike_ShotMultiplierUpdate(pl);
}
void
w_cstrke_switched(CSPlayer pl)
{
Cstrike_ShotReset(pl);
}
#ifdef CLIENT
void
CStrikeView_UpdateGeomset(CSPlayer pl)

View file

@ -13,12 +13,12 @@ entityDef weapon_glock18
"ammoRequired" "1"
"model_flash" "sprites/muzzleflash2.spr"
"actFire" "5"
"actFireLast" "6"
"actHolster" "9"
"actReload" "7,12"
"actDraw" "9,11"
"actIdle" "0,1,2"
"actFire" "5"
"actFireLast" "6"
"actHolster" "9"
"actReload" "7,12"
"actDraw" "9,11"
"actIdle" "0,1,2"
"snd_fire" "Weapon_Glock.Single"
@ -35,6 +35,10 @@ entityDef weapon_glock18
"multiplierShots" "2.0"
"multiplierStrength" "0.7"
"multiplierInaccuracy" "1.0"
"weight" "5"
"altMode" "1"
"actModeOn" "3"
"actModeOff" "3"
}
entityDef projectile_glock
@ -45,7 +49,7 @@ entityDef projectile_glock
entityDef fireInfo_glock18
{
"def_onFire" "projectile_glock"
"def_onFire" "projectile_glock"
"ammoType" "ammo_9mm"
"ammoPerShot" "1"
"fireRate" "0.13"
@ -54,12 +58,12 @@ entityDef fireInfo_glock18
entityDef fireInfo_altglock18
{
"def_onFire" "projectile_glock"
"def_onFire" "projectile_glock"
"ammoType" "ammo_9mm"
"ammoPerShot" "3"
"numProjectiles" "3"
"fireRate" "0.5"
"accuracyDivisor" "75"
"actFire" "3,4"
"snd_fire" "Weapon_Glock.Burst"
"actFire" "3,4"
"snd_fire" "Weapon_Glock.Burst"
}

View file

@ -24,7 +24,6 @@ sfx_impact.flesh
sample debris/flesh1.wav
sample debris/flesh2.wav
sample debris/flesh3.wav
sample debris/flesh4.wav
sample debris/flesh5.wav
sample debris/flesh6.wav
sample debris/flesh7.wav

View file

@ -1,90 +1,45 @@
// Generic Binds
bind "ESC" "togglemenu"
bind "w" "+forward"
bind "s" "+back"
bind "a" "+moveleft"
bind "d" "+moveright"
bind "SPACE" "+jump"
bind "CTRL" "+duck"
bind "SHIFT" "+speed"
bind "0" "slot10"
bind "1" "slot1"
bind "2" "slot2"
bind "3" "slot3"
bind "4" "slot4"
bind "5" "slot5"
bind "6" "slot6"
bind "7" "slot7"
bind "8" "slot8"
bind "9" "slot9"
bind "UPARROW" "+forward"
bind "DOWNARROW" "+back"
bind "LEFTARROW" "+left"
bind "RIGHTARROW" "+right"
bind "MOUSE1" "+attack"
bind "MOUSE2" "+attack2"
bind "MWHEELDOWN" "invnext"
bind "MWHEELUP" "invprev"
bind "r" "+reload"
bind "e" "+use"
bind "TAB" "+showscores"
bind "y" "messagemode"
bind "u" "messagemode2"
bind "t" "impulse 201"
bind "f" "impulse 100"
bind "f1" "vote yes"
bind "f2" "vote no"
// Counter-Strike Binds
bind "b" "buy"
bind "m" "chooseteam"
bind "g" "drop"
bind "q" "lastinv"
// Game Variables
seta "hostname" "FreeCS Server"
seta "maxplayers" "8"
seta "mp_startmoney" "800"
seta "mp_buytime" "90"
seta "mp_freezetime" "6"
seta "mp_c4timer" "45"
seta "mp_roundtime" "5"
seta "fcs_knifeonly" "0"
seta "fcs_swapteams" "0"
seta "fcs_nopickups" "0"
seta "fcs_reward_kill" "300"
seta "fcs_penalty_pain" "-150"
seta "fcs_penalty_kill" "-1500"
seta "fcs_maxmoney" "16000"
seta "fcs_fillweapons" "0"
seta "fcs_autoreload" "0"
// 2D/HUD Variables
seta "con_color" "255 150 0"
seta "vgui_color" "255 170 0"
seta "cross_color" "0 255 0"
// physics
seta sv_stepheight 18
seta sv_airstepheight 18
seta sv_friction 4
seta sv_edgefriction 1
seta sv_stopspeed 75
seta sv_gravity 800
seta sv_airaccelerate 10
seta sv_wateraccelerate 8
seta sv_accelerate 4
seta sv_maxspeed 250
// disable some nuclide niceties
seta v_muzzledlight 0
// config compat
alias mp_timelimit timelimit
alias mp_fraglimit fraglimit
// video settings
seta gl_overbright 0
seta gl_ldr 1
seta r_lightmap_format rgb8
seta cl_movespeedkey 0.2
exec default_controls.cfg
// game specific binds
bind "b" "buy"
bind "m" "chooseteam"
bind "g" "drop"
exec cvar_defaults.cfg
// game specific cvars
seta "hostname" "FreeCS Server"
seta "maxplayers" "8"
seta "mp_startmoney" "800"
seta "mp_buytime" "90"
seta "mp_freezetime" "6"
seta "mp_c4timer" "45"
seta "mp_roundtime" "5"
seta "fcs_knifeonly" "0"
seta "fcs_swapteams" "0"
seta "fcs_nopickups" "0"
seta "fcs_reward_kill" "300"
seta "fcs_penalty_pain" "-150"
seta "fcs_penalty_kill" "-1500"
seta "fcs_maxmoney" "16000"
seta "fcs_fillweapons" "0"
seta "fcs_autoreload" "0"
// cosmetic branding changes
seta "con_color" "255 150 0"
seta "vgui_color" "255 170 0"
seta "cross_color" "0 255 0"
// physics differences from valve/
seta pm_accelerate "4"
seta pm_airaccelerate "10"
seta pm_airstepsize "18"
seta pm_crouchviewheight "30"
seta pm_edgefriction "1"
seta pm_friction "4"
seta pm_gravity "800"
seta pm_normalviewheight "54"
seta pm_stepsize "18"
seta pm_stopspeed "75"
seta pm_walkspeed "250"
seta pm_wateraccelerate "8"