diff --git a/src/playermanager.h b/src/playermanager.h index 0e0319f2..21d43c71 100644 --- a/src/playermanager.h +++ b/src/playermanager.h @@ -100,6 +100,8 @@ enum class ETargetError }; class ZEPlayer; +struct ZRClass; +struct ZRModelEntry; class ZEPlayerHandle { @@ -172,6 +174,8 @@ class ZEPlayer m_flMaxSpeed = 1.f; m_iLastInputs = IN_NONE; m_iLastInputTime = std::time(0); + m_pActiveZRClass = nullptr; + m_pActiveZRModel = nullptr; } ~ZEPlayer() @@ -227,6 +231,8 @@ class ZEPlayer void UpdateLastInputTime() { m_iLastInputTime = std::time(0); } void SetMaxSpeed(float flMaxSpeed) { m_flMaxSpeed = flMaxSpeed; } void ReplicateConVar(const char* pszName, const char* pszValue); + void SetActiveZRClass(std::shared_ptr pZRModel) { m_pActiveZRClass = pZRModel; } + void SetActiveZRModel(std::shared_ptr pZRClass) { m_pActiveZRModel = pZRClass; } uint64 GetAdminFlags() { return m_iAdminFlags; } int GetAdminImmunity() { return m_iAdminImmunity; } @@ -262,6 +268,8 @@ class ZEPlayer float GetMaxSpeed() { return m_flMaxSpeed; } uint64 GetLastInputs() { return m_iLastInputs; } std::time_t GetLastInputTime() { return m_iLastInputTime; } + std::shared_ptr GetActiveZRClass() { return m_pActiveZRClass; } + std::shared_ptr GetActiveZRModel() { return m_pActiveZRModel; } void OnSpawn(); void OnAuthenticated(); @@ -316,6 +324,8 @@ class ZEPlayer float m_flMaxSpeed; uint64 m_iLastInputs; std::time_t m_iLastInputTime; + std::shared_ptr m_pActiveZRClass; + std::shared_ptr m_pActiveZRModel; }; class CPlayerManager diff --git a/src/zombiereborn.cpp b/src/zombiereborn.cpp index d0671e27..d580d1dd 100644 --- a/src/zombiereborn.cpp +++ b/src/zombiereborn.cpp @@ -174,7 +174,7 @@ void ZR_CreateOverlay(const char* pszOverlayParticlePath, float flAlpha, float f UTIL_AddEntityIOEvent(particle, "Kill", nullptr, nullptr, "", flLifeTime + 1.0); } -ZRModelEntry::ZRModelEntry(ZRModelEntry *modelEntry) : +ZRModelEntry::ZRModelEntry(std::shared_ptr modelEntry) : szModelPath(modelEntry->szModelPath), szColor(modelEntry->szColor) { @@ -237,7 +237,7 @@ ZRClass::ZRClass(ordered_json jsonKeys, std::string szClassname) : for (auto& [key, jsonModelEntry] : jsonKeys["models"].items()) { - ZRModelEntry *modelEntry = new ZRModelEntry(jsonModelEntry); + std::shared_ptr modelEntry = std::make_shared(jsonModelEntry); vecModels.AddToTail(modelEntry); } }; @@ -303,7 +303,7 @@ void ZRClass::Override(ordered_json jsonKeys, std::string szClassname) for (auto& [key, jsonModelEntry] : jsonKeys["models"].items()) { - ZRModelEntry *modelEntry = new ZRModelEntry(jsonModelEntry); + std::shared_ptr modelEntry = std::make_shared(jsonModelEntry); vecModels.AddToTail(modelEntry); } } @@ -460,13 +460,13 @@ void CZRPlayerClassManager::LoadPlayerClass() if (bHuman) { - ZRHumanClass *pHumanClass; + std::shared_ptr pHumanClass; if (!szBase.empty()) { - ZRHumanClass *pBaseHumanClass = GetHumanClass(szBase.c_str()); + std::shared_ptr pBaseHumanClass = GetHumanClass(szBase.c_str()); if (pBaseHumanClass) { - pHumanClass = new ZRHumanClass(pBaseHumanClass); + pHumanClass = std::make_shared(pBaseHumanClass); pHumanClass->Override(jsonClass, szClassName); } else @@ -476,7 +476,7 @@ void CZRPlayerClassManager::LoadPlayerClass() } } else - pHumanClass = new ZRHumanClass(jsonClass, szClassName); + pHumanClass = std::make_shared(jsonClass, szClassName); m_HumanClassMap.Insert(hash_32_fnv1a_const(szClassName.c_str()), pHumanClass); @@ -487,13 +487,13 @@ void CZRPlayerClassManager::LoadPlayerClass() } else { - ZRZombieClass *pZombieClass; + std::shared_ptr pZombieClass; if (!szBase.empty()) { - ZRZombieClass *pBaseZombieClass = GetZombieClass(szBase.c_str()); + std::shared_ptr pBaseZombieClass = GetZombieClass(szBase.c_str()); if (pBaseZombieClass) { - pZombieClass = new ZRZombieClass(pBaseZombieClass); + pZombieClass = std::make_shared(pBaseZombieClass); pZombieClass->Override(jsonClass, szClassName); } else @@ -503,7 +503,7 @@ void CZRPlayerClassManager::LoadPlayerClass() } } else - pZombieClass = new ZRZombieClass(jsonClass, szClassName); + pZombieClass = std::make_shared(jsonClass, szClassName); m_ZombieClassMap.Insert(hash_32_fnv1a_const(szClassName.c_str()), pZombieClass); if (bTeamDefault) @@ -526,9 +526,9 @@ void split(const std::string& s, char delim, Out result) *result++ = item; } -void CZRPlayerClassManager::ApplyBaseClass(ZRClass* pClass, CCSPlayerPawn *pPawn) +void CZRPlayerClassManager::ApplyBaseClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn) { - ZRModelEntry *pModelEntry = pClass->GetRandomModelEntry(); + std::shared_ptr pModelEntry = pClass->GetRandomModelEntry(); Color clrRender; V_StringToColor(pModelEntry->szColor.c_str(), clrRender); @@ -547,6 +547,8 @@ void CZRPlayerClassManager::ApplyBaseClass(ZRClass* pClass, CCSPlayerPawn *pPawn if (const auto pPlayer = pController != nullptr ? pController->GetZEPlayer() : nullptr) { pPlayer->SetMaxSpeed(pClass->flSpeed); + pPlayer->SetActiveZRClass(pClass); + pPlayer->SetActiveZRModel(pModelEntry); } // This has to be done a bit later @@ -554,9 +556,9 @@ void CZRPlayerClassManager::ApplyBaseClass(ZRClass* pClass, CCSPlayerPawn *pPawn } // only changes that should not (directly) affect gameplay -void CZRPlayerClassManager::ApplyBaseClassVisuals(ZRClass *pClass, CCSPlayerPawn *pPawn) +void CZRPlayerClassManager::ApplyBaseClassVisuals(std::shared_ptr pClass, CCSPlayerPawn* pPawn) { - ZRModelEntry *pModelEntry = pClass->GetRandomModelEntry(); + std::shared_ptr pModelEntry = pClass->GetRandomModelEntry(); Color clrRender; V_StringToColor(pModelEntry->szColor.c_str(), clrRender); @@ -564,11 +566,18 @@ void CZRPlayerClassManager::ApplyBaseClassVisuals(ZRClass *pClass, CCSPlayerPawn pPawn->m_clrRender = clrRender; pPawn->AcceptInput("Skin", pModelEntry->GetRandomSkin()); + const auto pController = reinterpret_cast(pPawn->GetController()); + if (const auto pPlayer = pController != nullptr ? pController->GetZEPlayer() : nullptr) + { + pPlayer->SetActiveZRClass(pClass); + pPlayer->SetActiveZRModel(pModelEntry); + } + // This has to be done a bit later UTIL_AddEntityIOEvent(pPawn, "SetScale", nullptr, nullptr, pClass->flScale); } -ZRHumanClass* CZRPlayerClassManager::GetHumanClass(const char *pszClassName) +std::shared_ptr CZRPlayerClassManager::GetHumanClass(const char* pszClassName) { uint16 index = m_HumanClassMap.Find(hash_32_fnv1a_const(pszClassName)); if (!m_HumanClassMap.IsValidIndex(index)) @@ -576,7 +585,7 @@ ZRHumanClass* CZRPlayerClassManager::GetHumanClass(const char *pszClassName) return m_HumanClassMap[index]; } -void CZRPlayerClassManager::ApplyHumanClass(ZRHumanClass *pClass, CCSPlayerPawn *pPawn) +void CZRPlayerClassManager::ApplyHumanClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn) { ApplyBaseClass(pClass, pPawn); CCSPlayerController *pController = CCSPlayerController::FromPawn(pPawn); @@ -609,7 +618,7 @@ void CZRPlayerClassManager::ApplyPreferredOrDefaultHumanClass(CCSPlayerPawn *pPa // Get the human class user preference, or default if no class is set int iSlot = pController->GetPlayerSlot(); - ZRHumanClass* humanClass = nullptr; + std::shared_ptr humanClass = nullptr; const char* sPreferredHumanClass = g_pUserPreferencesSystem->GetPreference(iSlot, HUMAN_CLASS_KEY_NAME); // If the preferred human class exists and can be applied, override the default @@ -633,7 +642,7 @@ void CZRPlayerClassManager::ApplyPreferredOrDefaultHumanClassVisuals(CCSPlayerPa // Get the human class user preference, or default if no class is set int iSlot = pController->GetPlayerSlot(); - ZRHumanClass* humanClass = nullptr; + std::shared_ptr humanClass = nullptr; const char* sPreferredHumanClass = g_pUserPreferencesSystem->GetPreference(iSlot, HUMAN_CLASS_KEY_NAME); // If the preferred human class exists and can be applied, override the default @@ -647,10 +656,10 @@ void CZRPlayerClassManager::ApplyPreferredOrDefaultHumanClassVisuals(CCSPlayerPa return; } - ApplyBaseClassVisuals((ZRClass *)humanClass, pPawn); + ApplyBaseClassVisuals(humanClass, pPawn); } -ZRZombieClass* CZRPlayerClassManager::GetZombieClass(const char *pszClassName) +std::shared_ptr CZRPlayerClassManager::GetZombieClass(const char* pszClassName) { uint16 index = m_ZombieClassMap.Find(hash_32_fnv1a_const(pszClassName)); if (!m_ZombieClassMap.IsValidIndex(index)) @@ -658,7 +667,7 @@ ZRZombieClass* CZRPlayerClassManager::GetZombieClass(const char *pszClassName) return m_ZombieClassMap[index]; } -void CZRPlayerClassManager::ApplyZombieClass(ZRZombieClass *pClass, CCSPlayerPawn *pPawn) +void CZRPlayerClassManager::ApplyZombieClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn) { ApplyBaseClass(pClass, pPawn); CCSPlayerController *pController = CCSPlayerController::FromPawn(pPawn); @@ -673,7 +682,7 @@ void CZRPlayerClassManager::ApplyPreferredOrDefaultZombieClass(CCSPlayerPawn *pP // Get the zombie class user preference, or default if no class is set int iSlot = pController->GetPlayerSlot(); - ZRZombieClass* zombieClass = nullptr; + std::shared_ptr zombieClass = nullptr; const char* sPreferredZombieClass = g_pUserPreferencesSystem->GetPreference(iSlot, ZOMBIE_CLASS_KEY_NAME); // If the preferred zombie class exists and can be applied, override the default @@ -690,7 +699,7 @@ void CZRPlayerClassManager::ApplyPreferredOrDefaultZombieClass(CCSPlayerPawn *pP ApplyZombieClass(zombieClass, pPawn); } -void CZRPlayerClassManager::GetZRClassList(int iTeam, CUtlVector &vecClasses, CCSPlayerController* pController) +void CZRPlayerClassManager::GetZRClassList(int iTeam, CUtlVector>& vecClasses, CCSPlayerController* pController) { if (iTeam == CS_TEAM_T || iTeam == CS_TEAM_NONE) { @@ -1187,7 +1196,7 @@ void ZR_InfectMotherZombie(CCSPlayerController *pVictimController, std::vectorSwitchTeam(CS_TEAM_T); pVictimPawn->EmitSound("zr.amb.scream"); - ZRZombieClass *pClass = g_pZRPlayerClassManager->GetZombieClass("MotherZombie"); + std::shared_ptr pClass = g_pZRPlayerClassManager->GetZombieClass("MotherZombie"); if (pClass) g_pZRPlayerClassManager->ApplyZombieClass(pClass, pVictimPawn); else @@ -1730,7 +1739,7 @@ CON_COMMAND_CHAT(zclass, " - Find and select your Z: return; } - CUtlVector vecClasses; + CUtlVector> vecClasses; int iSlot = player->GetPlayerSlot(); bool bListingZombie = true; bool bListingHuman = true; @@ -1773,7 +1782,7 @@ CON_COMMAND_CHAT(zclass, " - Find and select your Z: { const char* sClassName = vecClasses[i]->szClassName.c_str(); bool bClassMatches = !V_stricmp(sClassName, args[1]) || (V_StringToInt32(args[1], -1) - 1) == i; - ZRClass* pClass = vecClasses[i]; + std::shared_ptr pClass = vecClasses[i]; if (bClassMatches) { diff --git a/src/zombiereborn.h b/src/zombiereborn.h index b87ba217..2b041de1 100644 --- a/src/zombiereborn.h +++ b/src/zombiereborn.h @@ -51,7 +51,7 @@ struct ZRModelEntry std::string szModelPath; CUtlVector vecSkins; std::string szColor; - ZRModelEntry(ZRModelEntry* modelEntry); + ZRModelEntry(std::shared_ptr modelEntry); ZRModelEntry(ordered_json jsonModelEntry); int GetRandomSkin() { @@ -66,12 +66,12 @@ struct ZRClass bool bEnabled; std::string szClassName; int iHealth; - CUtlVector vecModels; + CUtlVector> vecModels; float flScale; float flSpeed; float flGravity; uint64 iAdminFlag; - ZRClass(ZRClass *pClass, int iTeam) : + ZRClass(std::shared_ptr pClass, int iTeam) : iTeam(iTeam), bEnabled(pClass->bEnabled), szClassName(pClass->szClassName), @@ -84,7 +84,7 @@ struct ZRClass vecModels.Purge(); FOR_EACH_VEC(pClass->vecModels, i) { - ZRModelEntry *modelEntry = new ZRModelEntry(pClass->vecModels[i]); + std::shared_ptr modelEntry = std::make_shared(pClass->vecModels[i]); vecModels.AddToTail(modelEntry); } }; @@ -127,7 +127,7 @@ struct ZRClass void Override(ordered_json jsonKeys, std::string szClassname); bool IsApplicableTo(CCSPlayerController *pController); uint64 ParseClassFlags(const char* pszFlags); - ZRModelEntry *GetRandomModelEntry() + std::shared_ptr GetRandomModelEntry() { return vecModels[rand() % vecModels.Count()]; }; @@ -136,7 +136,7 @@ struct ZRClass struct ZRHumanClass : ZRClass { - ZRHumanClass(ZRHumanClass *pClass) : ZRClass(pClass, CS_TEAM_CT){}; + ZRHumanClass(std::shared_ptr pClass) : ZRClass(pClass, CS_TEAM_CT) {}; ZRHumanClass(ordered_json jsonKeys, std::string szClassname); }; @@ -144,7 +144,7 @@ struct ZRZombieClass : ZRClass { int iHealthRegenCount; float flHealthRegenInterval; - ZRZombieClass(ZRZombieClass *pClass) : + ZRZombieClass(std::shared_ptr pClass) : ZRClass(pClass, CS_TEAM_T), iHealthRegenCount(pClass->iHealthRegenCount), flHealthRegenInterval(pClass->flHealthRegenInterval){}; @@ -199,22 +199,22 @@ class CZRPlayerClassManager m_HumanClassMap.SetLessFunc(DefLessFunc(uint32)); }; void LoadPlayerClass(); - void ApplyBaseClassVisuals(ZRClass *pClass, CCSPlayerPawn *pPawn); - ZRHumanClass* GetHumanClass(const char *pszClassName); - void ApplyHumanClass(ZRHumanClass *pClass, CCSPlayerPawn *pPawn); + void ApplyBaseClassVisuals(std::shared_ptr pClass, CCSPlayerPawn* pPawn); + std::shared_ptr GetHumanClass(const char* pszClassName); + void ApplyHumanClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn); void ApplyPreferredOrDefaultHumanClass(CCSPlayerPawn *pPawn); void ApplyPreferredOrDefaultHumanClassVisuals(CCSPlayerPawn *pPawn); - ZRZombieClass* GetZombieClass(const char*pszClassName); - void ApplyZombieClass(ZRZombieClass *pClass, CCSPlayerPawn *pPawn); + std::shared_ptr GetZombieClass(const char* pszClassName); + void ApplyZombieClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn); void ApplyPreferredOrDefaultZombieClass(CCSPlayerPawn *pPawn); void PrecacheModels(IEntityResourceManifest* pResourceManifest); - void GetZRClassList(int iTeam, CUtlVector &vecClasses, CCSPlayerController* pController = nullptr); + void GetZRClassList(int iTeam, CUtlVector>& vecClasses, CCSPlayerController* pController = nullptr); private: - void ApplyBaseClass(ZRClass* pClass, CCSPlayerPawn *pPawn); - CUtlVector m_vecZombieDefaultClass; - CUtlVector m_vecHumanDefaultClass; - CUtlMap m_ZombieClassMap; - CUtlMap m_HumanClassMap; + void ApplyBaseClass(std::shared_ptr pClass, CCSPlayerPawn* pPawn); + CUtlVector> m_vecZombieDefaultClass; + CUtlVector> m_vecHumanDefaultClass; + CUtlMap> m_ZombieClassMap; + CUtlMap> m_HumanClassMap; }; class CZRRegenTimer : public CTimerBase