Skip to content

Commit

Permalink
prevent team hopping, zm can only pick up knife, team score
Browse files Browse the repository at this point in the history
  • Loading branch information
EasterLee committed Dec 5, 2023
1 parent 1c1d305 commit 2befb6d
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 14 deletions.
35 changes: 35 additions & 0 deletions src/cs2_sdk/entity/cteam.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* =============================================================================
* CS2Fixes
* Copyright (C) 2023 Source2ZE
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/


#pragma once
#include "cbaseentity.h"
#include "cbaseplayercontroller.h"
#include "cbaseplayerpawn.h"

class CTeam : public Z_CBaseEntity
{
public:
DECLARE_SCHEMA_CLASS(CTeam);

SCHEMA_FIELD_POINTER(CUtlVector<CHandle<CBasePlayerController>>, m_aPlayerControllers)
SCHEMA_FIELD_POINTER(CUtlVector<CHandle<CBasePlayerPawn>>, m_aPlayers)

SCHEMA_FIELD(int32_t, m_iScore)
};
15 changes: 13 additions & 2 deletions src/cs2_sdk/entity/services.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <platform.h>
#include "globaltypes.h"
#include <entity/ccsweaponbase.h>
#include <entity/ccsplayerpawn.h>

class CBaseEntity;

Expand All @@ -39,6 +40,8 @@ struct CSMatchStats_t : public CSPerRoundStats_t
{
public:
DECLARE_SCHEMA_CLASS_INLINE(CSMatchStats_t)

SCHEMA_FIELD(int32_t, m_iEntryWins);
};

class CCSPlayerController_ActionTrackingServices
Expand Down Expand Up @@ -66,7 +69,15 @@ class CPlayer_MovementServices
SCHEMA_FIELD(float, m_flMaxspeed)
};

class CPlayer_WeaponServices
class CPlayerPawnComponent
{
public:
DECLARE_SCHEMA_CLASS(CPlayerPawnComponent);

SCHEMA_FIELD(CCSPlayerPawn*, __m_pChainEntity)
};

class CPlayer_WeaponServices : public CPlayerPawnComponent
{
public:
DECLARE_SCHEMA_CLASS(CPlayer_WeaponServices);
Expand All @@ -75,7 +86,7 @@ class CPlayer_WeaponServices
SCHEMA_FIELD(CHandle<CBasePlayerWeapon>, m_hActiveWeapon)
};

class CCSPlayer_WeaponServices : CPlayer_WeaponServices
class CCSPlayer_WeaponServices : public CPlayer_WeaponServices
{
public:
DECLARE_SCHEMA_CLASS(CCSPlayer_WeaponServices);
Expand Down
15 changes: 15 additions & 0 deletions src/cs2fixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,21 @@ void CS2Fixes::Hook_ClientCommand( CPlayerSlot slot, const CCommand &args )
#ifdef _DEBUG
Message( "Hook_ClientCommand(%d, \"%s\")\n", slot, args.GetCommandString() );
#endif
if (g_bEnableZR)
{
if (slot != -1 && !V_strncmp(args.Arg(0), "jointeam", 8))
{
const char *szTeam = g_ZRRoundState == EZRRoundState::ROUND_START ? "3" : "2";
// update args if player are trying to join team != szTeam
if (args.ArgC() < 2 || V_strncmp(args.Arg(1), szTeam, 1))
{
const char *ppArgV[] = {"jointeam", szTeam};
CCommand newArgs(2, ppArgV);
SH_CALL(g_pSource2GameClients, &IServerGameClients::ClientCommand)(slot, newArgs);
RETURN_META(MRES_SUPERCEDE);
}
}
}
}

void CS2Fixes::Hook_ClientSettingsChanged( CPlayerSlot slot )
Expand Down
10 changes: 10 additions & 0 deletions src/detours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "entity/ctriggerpush.h"
#include "entity/cgamerules.h"
#include "entity/ctakedamageinfo.h"
#include "entity/services.h"
#include "playermanager.h"
#include "igameevents.h"
#include "gameconfig.h"
Expand Down Expand Up @@ -306,7 +307,13 @@ CON_COMMAND_F(toggle_logs, "Toggle printing most logs and warnings", FCVAR_SPONL

bool FASTCALL Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices *pWeaponServices, CBasePlayerWeapon* pPlayerWeapon)
{
if (g_bEnableZR)
if (!ZR_Detour_CCSPlayer_WeaponServices_CanUse(pWeaponServices, pPlayerWeapon))
{
return false;
}

return CCSPlayer_WeaponServices_CanUse(pWeaponServices, pPlayerWeapon);
}

CUtlVector<CDetourBase *> g_vecDetours;
Expand Down Expand Up @@ -355,6 +362,9 @@ bool InitDetours(CGameConfig *gameConfig)
success = false;
CBaseEntity_TakeDamageOld.EnableDetour();

if (!CCSPlayer_WeaponServices_CanUse.CreateDetour(gameConfig))
success = false;
CCSPlayer_WeaponServices_CanUse.EnableDetour();
return success;
}

Expand Down
4 changes: 3 additions & 1 deletion src/detours.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class CTriggerPush;
class CGameConfig;
class CGameRules;
class CTakeDamageInfo;
class CCSPlayer_WeaponServices;
class CBasePlayerWeapon;

bool InitDetours(CGameConfig *gameConfig);
void FlushAllDetours();
Expand All @@ -46,4 +48,4 @@ void FASTCALL Detour_CCSWeaponBase_Spawn(CBaseEntity *, void *);
void FASTCALL Detour_TriggerPush_Touch(CTriggerPush* pPush, Z_CBaseEntity* pOther);
void FASTCALL Detour_CGameRules_Constructor(CGameRules *pThis);
void FASTCALL Detour_CBaseEntity_TakeDamageOld(Z_CBaseEntity *pThis, CTakeDamageInfo *inputInfo);
bool FASTCALL Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices *, CBasePlayerWeapon*);
bool FASTCALL Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices *, CBasePlayerWeapon *);
76 changes: 65 additions & 11 deletions src/zombiereborn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "zombiereborn.h"
#include "entity/cgamerules.h"
#include "utils/entity.h"
#include "entity/services.h"
#include "entity/cteam.h"

#include "tier0/memdbgon.h"

Expand All @@ -36,11 +38,13 @@ extern IGameEventManager2* g_gameEventManager;

void ZR_Infect(CCSPlayerController *pAttackerController, CCSPlayerController *pVictimController, bool bBroadcast);
void ZR_CheckWinConditions(bool bCheckCT);
void ZR_Cure(CCSPlayerController *pTargetController);

EZRRoundState g_ZRRoundState = EZRRoundState::ROUND_START;
static int g_iRoundNum = 0;
static int g_iInfectionCountDown = 0;


// CONVAR_TODO
bool g_bEnableZR = false;
static float g_flMaxZteleDistance = 150.0f;
Expand Down Expand Up @@ -107,10 +111,10 @@ void ZR_OnStartupServer()
g_ZRRoundState = EZRRoundState::ROUND_START;
// CONVAR_TODO
// Here we force some cvars that are essential for the scripts to work
g_pEngineServer2->ServerCommand("mp_weapons_allow_pistols 3");
g_pEngineServer2->ServerCommand("mp_weapons_allow_smgs 3");
g_pEngineServer2->ServerCommand("mp_weapons_allow_heavy 3");
g_pEngineServer2->ServerCommand("mp_weapons_allow_rifles 3");
// g_pEngineServer2->ServerCommand("mp_weapons_allow_pistols 3");
// g_pEngineServer2->ServerCommand("mp_weapons_allow_smgs 3");
// g_pEngineServer2->ServerCommand("mp_weapons_allow_heavy 3");
// g_pEngineServer2->ServerCommand("mp_weapons_allow_rifles 3");
g_pEngineServer2->ServerCommand("mp_give_player_c4 0");
g_pEngineServer2->ServerCommand("mp_friendlyfire 0");
// Legacy Lua respawn stuff, do not use these, we should handle respawning ourselves now that we can
Expand All @@ -124,6 +128,9 @@ void ZR_OnRoundPrestart(IGameEvent* pEvent)
{
g_ZRRoundState = EZRRoundState::ROUND_START;
g_iRoundNum++;

g_pEngineServer2->ServerCommand("mp_respawn_on_death_t 1");
g_pEngineServer2->ServerCommand("mp_respawn_on_death_ct 1");
}

void ZR_OnRoundStart(IGameEvent* pEvent)
Expand All @@ -141,19 +148,22 @@ void ZR_OnPlayerSpawn(IGameEvent* pEvent)
{
CCSPlayerController* pController = (CCSPlayerController*)pEvent->GetPlayerController("userid");

if (pController && g_ZRRoundState == EZRRoundState::POST_INFECTION)
if (pController)
{
// delay infection a bit
int iRoundNum = g_iRoundNum;
bool bInfect = g_ZRRoundState == EZRRoundState::POST_INFECTION;

CHandle<CCSPlayerController> handle = pController->GetHandle();
new CTimer(0.05f, false, [iRoundNum, handle]()
new CTimer(0.05f, false, [iRoundNum, handle, bInfect]()
{
CCSPlayerController* pController = (CCSPlayerController*)handle.Get();
if (iRoundNum != g_iRoundNum || !pController)
return -1.0f;

ZR_Infect(pController, pController, true);

if(bInfect)
ZR_Infect(pController, pController, true);
else
ZR_Cure(pController);
return -1.0f;
});
}
Expand Down Expand Up @@ -219,6 +229,23 @@ void ZR_StripAndGiveKnife(CCSPlayerPawn *pPawn)
pItemServices->GiveNamedItem("weapon_knife");
}

void ZR_Cure(CCSPlayerController *pTargetController)
{
if (pTargetController->m_iTeamNum() == CS_TEAM_T)
pTargetController->SwitchTeam(CS_TEAM_CT);

CCSPlayerPawn *pTargetPawn = (CCSPlayerPawn*)pTargetController->GetPawn();
if (!pTargetPawn)
return;

// set model/health/etc here
//hardcode everything for now
pTargetPawn->m_iMaxHealth = 100;
pTargetPawn->m_iHealth = 100;

pTargetPawn->SetModel("characters/models/ctm_sas/ctm_sas.vmdl");
}

void ZR_Infect(CCSPlayerController *pAttackerController, CCSPlayerController *pVictimController, bool bDontBroadcast)
{
if (pVictimController->m_iTeamNum() == CS_TEAM_CT)
Expand All @@ -234,7 +261,6 @@ void ZR_Infect(CCSPlayerController *pAttackerController, CCSPlayerController *pV

ZR_StripAndGiveKnife(pVictimPawn);
// set model/health/etc here

//hardcode everything for now
pVictimPawn->m_iMaxHealth = 10000;
pVictimPawn->m_iHealth = 10000;
Expand All @@ -253,7 +279,6 @@ void ZR_InfectMotherZombie(CCSPlayerController *pVictimController)

ZR_StripAndGiveKnife(pVictimPawn);
// set model/health/etc here

//hardcode everything for now
pVictimPawn->m_iMaxHealth = 10000;
pVictimPawn->m_iHealth = 10000;
Expand Down Expand Up @@ -369,6 +394,17 @@ bool ZR_Detour_TakeDamageOld(CCSPlayerPawn *pVictimPawn, CTakeDamageInfo *pInfo)
return false;
}

// return false to prevent player from picking it up
bool ZR_Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices *pWeaponServices, CBasePlayerWeapon* pPlayerWeapon)
{
CCSPlayerPawn *pPawn = pWeaponServices->__m_pChainEntity();
if (pPawn && pPawn->m_iTeamNum() == CS_TEAM_T && V_strncmp(pPlayerWeapon->GetClassname(), "weapon_knife", 12))
return false;

// doesn't guarantee the player will pick the weapon up, it just allows the main detour to continue to run
return true;
}

void ZR_OnPlayerHurt(IGameEvent* pEvent)
{
CCSPlayerController *pAttackerController = (CCSPlayerController*)pEvent->GetPlayerController("attacker");
Expand Down Expand Up @@ -428,6 +464,24 @@ void ZR_CheckWinConditions(bool bCheckCT)
// 8: CT win; 9: T wins; 10: draw
g_pGameRules->TerminateRound(5.0f, bCheckCT ? CSRoundEndReason::TerroristWin : CSRoundEndReason::CTWin);
g_ZRRoundState = EZRRoundState::ROUND_END;

g_pEngineServer2->ServerCommand("mp_respawn_on_death_t 0");
g_pEngineServer2->ServerCommand("mp_respawn_on_death_ct 0");

// increment team score
iTeamNum = bCheckCT ? CS_TEAM_T : CS_TEAM_CT; //?????

// so uhh.. I don't know how to get cteam the proper way..
CTeam* pTeam = nullptr;
while (nullptr != (pTeam = (CTeam*)UTIL_FindEntityByClassname(pTeam, "cs_team_manager")))
{
if (pTeam->m_iTeamNum() == iTeamNum)
{
pTeam->m_iScore = pTeam->m_iScore() + 1;
//Msg("%d, %d\n", pTeam->m_iTeamNum(), pTeam->m_iScore());
return;
}
}
}

CON_COMMAND_CHAT(ztele, "teleport to spawn")
Expand Down
1 change: 1 addition & 0 deletions src/zombiereborn.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void ZR_OnPlayerHurt(IGameEvent* pEvent);
void ZR_OnPlayerDeath(IGameEvent* pEvent);
void ZR_OnRoundFreezeEnd(IGameEvent* pEvent);
bool ZR_Detour_TakeDamageOld(CCSPlayerPawn *pVictimPawn, CTakeDamageInfo *pInfo);
bool ZR_Detour_CCSPlayer_WeaponServices_CanUse(CCSPlayer_WeaponServices *pWeaponServices, CBasePlayerWeapon* pPlayerWeapon);

// need to replace with actual cvar someday
#define CON_ZR_CVAR(name, description, variable_name, variable_type, variable_default) \
Expand Down

0 comments on commit 2befb6d

Please sign in to comment.