diff --git a/Plugins/BulletPhysics/BulletPhysics.vcxproj b/Plugins/BulletPhysics/BulletPhysics.vcxproj
index 6085f0cd..afc35042 100644
--- a/Plugins/BulletPhysics/BulletPhysics.vcxproj
+++ b/Plugins/BulletPhysics/BulletPhysics.vcxproj
@@ -44,19 +44,19 @@
-
+
-
+
-
+
@@ -170,7 +170,7 @@ $(Bullet3CheckRequirements)
-
+
@@ -186,7 +186,7 @@ $(Bullet3CheckRequirements)
-
+
diff --git a/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters b/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters
index b23c1115..b683a06e 100644
--- a/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters
+++ b/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters
@@ -29,7 +29,7 @@
Source
-
+
Source
@@ -64,7 +64,7 @@
Header
-
+
Header
diff --git a/Plugins/BulletPhysics/corpse.cpp b/Plugins/BulletPhysics/corpse.cpp
deleted file mode 100644
index 1b0be452..00000000
--- a/Plugins/BulletPhysics/corpse.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-#include
-#include "exportfuncs.h"
-#include "privatehook.h"
-#include "corpse.h"
-#include "physics.h"
-#include "mathlib2.h"
-
-int EngineGetModelIndex(model_t *mod);
-
-typedef enum
-{
- ACT_RESET,
- ACT_IDLE,
- ACT_GUARD,
- ACT_WALK,
- ACT_RUN,
- ACT_FLY,
- ACT_SWIM,
- ACT_HOP,
- ACT_LEAP,
- ACT_FALL,
- ACT_LAND,
- ACT_STRAFE_LEFT,
- ACT_STRAFE_RIGHT,
- ACT_ROLL_LEFT,
- ACT_ROLL_RIGHT,
- ACT_TURN_LEFT,
- ACT_TURN_RIGHT,
- ACT_CROUCH,
- ACT_CROUCHIDLE,
- ACT_STAND,
- ACT_USE,
- ACT_SIGNAL1,
- ACT_SIGNAL2,
- ACT_SIGNAL3,
- ACT_TWITCH,
- ACT_COWER,
- ACT_SMALL_FLINCH,
- ACT_BIG_FLINCH,
- ACT_RANGE_ATTACK1,
- ACT_RANGE_ATTACK2,
- ACT_MELEE_ATTACK1,
- ACT_MELEE_ATTACK2,
- ACT_RELOAD,
- ACT_ARM,
- ACT_DISARM,
- ACT_EAT,
- ACT_DIESIMPLE,
- ACT_DIEBACKWARD,
- ACT_DIEFORWARD,
- ACT_DIEVIOLENT,
- ACT_BARNACLE_HIT,
- ACT_BARNACLE_PULL,
- ACT_BARNACLE_CHOMP,
- ACT_BARNACLE_CHEW,
- ACT_SLEEP,
- ACT_INSPECT_FLOOR,
- ACT_INSPECT_WALL,
- ACT_IDLE_ANGRY,
- ACT_WALK_HURT,
- ACT_RUN_HURT,
- ACT_HOVER,
- ACT_GLIDE,
- ACT_FLY_LEFT,
- ACT_FLY_RIGHT,
- ACT_DETECT_SCENT,
- ACT_SNIFF,
- ACT_BITE,
- ACT_THREAT_DISPLAY,
- ACT_FEAR_DISPLAY,
- ACT_EXCITED,
- ACT_SPECIAL_ATTACK1,
- ACT_SPECIAL_ATTACK2,
- ACT_COMBAT_IDLE,
- ACT_WALK_SCARED,
- ACT_RUN_SCARED,
- ACT_VICTORY_DANCE,
- ACT_DIE_HEADSHOT,
- ACT_DIE_CHESTSHOT,
- ACT_DIE_GUTSHOT,
- ACT_DIE_BACKSHOT,
- ACT_FLINCH_HEAD,
- ACT_FLINCH_CHEST,
- ACT_FLINCH_STOMACH,
- ACT_FLINCH_LEFTARM,
- ACT_FLINCH_RIGHTARM,
- ACT_FLINCH_LEFTLEG,
- ACT_FLINCH_RIGHTLEG,
- ACT_FLINCH_SMALL,
- ACT_FLINCH_LARGE,
- ACT_HOLDBOMB
-}activity_e;
-
-//TODO: hook Mod_LoadStudioModel?
-model_t *g_barnacle_model = NULL;
-model_t *g_gargantua_model = NULL;
-
-bool IsEntityEmitted(cl_entity_t *ent)
-{
- if(ent->player)
- return gCorpseManager.IsPlayerEmitted(ent->index);
-
- return true;
-}
-
-int StudioGetSequenceActivityType(model_t *mod, entity_state_t* entstate)
-{
- if (g_bIsSvenCoop)
- {
- if (entstate->scale != 0 && entstate->scale != 1.0f)
- return 0;
- }
-
- if (mod->type != mod_studio)
- return 0;
-
- auto studiohdr = (studiohdr_t *)IEngineStudio.Mod_Extradata(mod);
-
- if (!studiohdr)
- return 0;
-
- int sequence = entstate->sequence;
- if (sequence >= studiohdr->numseq)
- return 0;
-
- auto pseqdesc = (mstudioseqdesc_t*)((byte*)studiohdr + studiohdr->seqindex) + sequence;
-
- if (
- pseqdesc->activity == ACT_DIESIMPLE ||
- pseqdesc->activity == ACT_DIEBACKWARD ||
- pseqdesc->activity == ACT_DIEFORWARD ||
- pseqdesc->activity == ACT_DIEVIOLENT ||
- pseqdesc->activity == ACT_DIEVIOLENT ||
- pseqdesc->activity == ACT_DIE_HEADSHOT ||
- pseqdesc->activity == ACT_DIE_CHESTSHOT ||
- pseqdesc->activity == ACT_DIE_GUTSHOT ||
- pseqdesc->activity == ACT_DIE_BACKSHOT
- )
- {
- return 1;
- }
-
- if (
- pseqdesc->activity == ACT_BARNACLE_HIT ||
- pseqdesc->activity == ACT_BARNACLE_PULL ||
- pseqdesc->activity == ACT_BARNACLE_CHOMP ||
- pseqdesc->activity == ACT_BARNACLE_CHEW
- )
- {
- return 2;
- }
-
- return 0;
-}
-
-bool IsEntityBarnacle(cl_entity_t* ent)
-{
- if (ent && ent->model && ent->model->type == mod_studio)
- {
- if (g_barnacle_model)
- {
- if (g_barnacle_model == ent->model)
- {
- return (ent->curstate.sequence >= 3 && ent->curstate.sequence <= 5);
- }
- }
- else if (!strcmp(ent->model->name, "models/barnacle.mdl"))
- {
- g_barnacle_model = ent->model;
-
- return (ent->curstate.sequence >= 3 && ent->curstate.sequence <= 5);
- }
- }
-
- return false;
-}
-
-bool IsEntityGargantua(cl_entity_t* ent)
-{
- if (ent && ent->model && ent->model->type == mod_studio)
- {
- if (g_gargantua_model)
- {
- if (g_gargantua_model == ent->model)
- {
- return true;
- }
- }
- else if (!strcmp(ent->model->name, "models/garg.mdl"))
- {
- g_gargantua_model = ent->model;
-
- return true;
- }
- }
-
- return false;
-}
-
-bool IsEntityWater(cl_entity_t* ent)
-{
- if (ent && ent->model && ent->model->type == mod_brush)
- {
- if (ent->curstate.skin == -3)
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool IsEntityDeadPlayer(cl_entity_t* ent)
-{
- if (ent && ent->model && ent->model->type == mod_studio)
- {
- if (!ent->player && ent->curstate.renderfx == kRenderFxDeadPlayer &&
- ent->curstate.renderamt >= 1 &&
- ent->curstate.renderamt <= gEngfuncs.GetMaxClients())
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool IsEntityPresent(cl_entity_t* ent)
-{
- if (!ent->model)
- return false;
-
- if(!ent->index)
- return false;
-
- if (ent->curstate.messagenum != (*cl_parsecount))
- return false;
-
- if (ent->curstate.effects & EF_NODRAW)
- return false;
-
- return true;
-}
-
-CorpseManager gCorpseManager;
-
-CorpseManager::CorpseManager(void)
-{
- ClearAllPlayerDying();
-}
-
-//return entindex of dying player
-int CorpseManager::FindDyingPlayer(const char *modelname, vec3_t origin, vec3_t angles, int sequence, int body)
-{
- for (int i = 1; i < _ARRAYSIZE(PlayerDying); ++i)
- {
- if (PlayerDying[i].bIsDying &&
- PlayerDying[i].iSequence == sequence &&
- PlayerDying[i].iBody == body &&
- 0 == strcmp(PlayerDying[i].szModelName, modelname))
- {
- if (VectorDistance(origin, PlayerDying[i].vecOrigin) < 128 &&
- fabs(angles[0] - PlayerDying[i].vecAngles[0]) < 10 &&
- fabs(angles[1] - PlayerDying[i].vecAngles[1]) < 10)
- {
- return i;
- }
- }
- }
- return 0;
-}
-
-void CorpseManager::ClearAllPlayerDying()
-{
- for (int i = 0; i < _ARRAYSIZE(PlayerDying); ++i)
- {
- ClearPlayerDying(i);
- }
-}
-
-void CorpseManager::ClearPlayerDying(int entindex)
-{
- PlayerDying[entindex].bIsDying = false;
- PlayerDying[entindex].flAnimTime = 0;
- PlayerDying[entindex].iSequence = 0;
- PlayerDying[entindex].iModelIndex = 0;
- memset(PlayerDying[entindex].szModelName, 0, sizeof(PlayerDying[entindex].szModelName));
- VectorClear(PlayerDying[entindex].vecAngles);
- VectorClear(PlayerDying[entindex].vecOrigin);
-}
-
-void CorpseManager::SetPlayerDying(int entindex, entity_state_t *pplayer, model_t *model)
-{
- PlayerDying[entindex].bIsDying = true;
- PlayerDying[entindex].flClientTime = gEngfuncs.GetClientTime();
- PlayerDying[entindex].flAnimTime = pplayer->animtime;
- PlayerDying[entindex].iSequence = pplayer->sequence;
- PlayerDying[entindex].iBody = pplayer->body;
-
- if (PlayerDying[entindex].iModelIndex != EngineGetModelIndex(model))
- {
- PlayerDying[entindex].iModelIndex = EngineGetModelIndex(model);
- strncpy(PlayerDying[entindex].szModelName, model->name, 64);
- PlayerDying[entindex].szModelName[63] = 0;
- }
-
- VectorCopy(pplayer->angles, PlayerDying[entindex].vecAngles);
- VectorCopy(pplayer->origin, PlayerDying[entindex].vecOrigin);
-
- //fix angle?
- if (PlayerDying[entindex].vecAngles[0] > 180)
- PlayerDying[entindex].vecAngles[0] -= 360;
-
- if (PlayerDying[entindex].vecAngles[0] < -180)
- PlayerDying[entindex].vecAngles[0] += 360;
-
- if (PlayerDying[entindex].vecAngles[1] > 180)
- PlayerDying[entindex].vecAngles[1] -= 360;
-
- if (PlayerDying[entindex].vecAngles[1] < -180)
- PlayerDying[entindex].vecAngles[1] += 360;
-}
-
-void CorpseManager::SetPlayerEmitted(int entindex)
-{
- PlayerEmitted[entindex] = true;
-}
-
-bool CorpseManager::IsPlayerEmitted(int entindex)
-{
- return PlayerEmitted[entindex];
-}
-
-void CorpseManager::ClearAllPlayerEmitState()
-{
- for (int i = 0; i < _ARRAYSIZE(PlayerEmitted); ++i)
- {
- PlayerEmitted[i] = false;
- }
-}
-
-void CorpseManager::FreePlayerForBarnacle(int entindex)
-{
- for (auto itor = m_barnacleMap.begin(); itor != m_barnacleMap.end(); )
- {
- if (itor->second == entindex)
- {
- itor->second = 0;
- return;
- }
-
- itor++;
- }
-}
-
-void CorpseManager::NewMap(void)
-{
- g_barnacle_model = NULL;
-
- m_barnacleMap.clear();
-
- ClearAllPlayerDying();
-}
-
-void CorpseManager::AddBarnacle(int entindex, int playerindex)
-{
- auto itor = m_barnacleMap.find(entindex);
- if (itor == m_barnacleMap.end())
- {
- m_barnacleMap[entindex] = playerindex;
- }
- else if(itor->second == 0 && playerindex != 0)
- {
- itor->second = playerindex;
- }
-}
-
-void CorpseManager::AddGargantua(int entindex, int playerindex)
-{
- auto itor = m_gargantuaMap.find(entindex);
- if (itor == m_gargantuaMap.end())
- {
- m_gargantuaMap[entindex] = playerindex;
- }
- else if (itor->second == 0 && playerindex != 0)
- {
- itor->second = playerindex;
- }
-}
-
-cl_entity_t *CorpseManager::FindPlayerForBarnacle(int entindex)
-{
- auto itor = m_barnacleMap.find(entindex);
- if (itor != m_barnacleMap.end())
- {
- if (itor->second != 0)
- {
- auto playerEntity = gEngfuncs.GetEntityByIndex(itor->second);
- if (playerEntity &&
- playerEntity->player &&
- StudioGetSequenceActivityType(playerEntity->model, &playerEntity->curstate) == 2)
- {
- return playerEntity;
- }
- }
- }
-
- return NULL;
-}
-
-cl_entity_t *CorpseManager::FindPlayerForGargantua(int entindex)
-{
- auto itor = m_gargantuaMap.find(entindex);
- if (itor != m_gargantuaMap.end())
- {
- if (itor->second != 0)
- {
- auto playerEntity = gEngfuncs.GetEntityByIndex(itor->second);
- if (playerEntity &&
- playerEntity->player &&
- StudioGetSequenceActivityType(playerEntity->model, &playerEntity->curstate) == 2)
- {
- return playerEntity;
- }
- }
- }
-
- return NULL;
-}
-
-cl_entity_t *CorpseManager::FindBarnacleForPlayer(entity_state_t *player)
-{
- for (auto itor = m_barnacleMap.begin(); itor != m_barnacleMap.end(); itor++ )
- {
- auto ent = gEngfuncs.GetEntityByIndex(itor->first);
- if (IsEntityBarnacle(ent))
- {
- if (fabs(player->origin[0] - ent->origin[0]) < 1 &&
- fabs(player->origin[1] - ent->origin[1]) < 1 &&
- player->origin[2] < ent->origin[2] + 16)
- {
- itor->second = player->number;
- return ent;
- }
- }
- }
-
- return NULL;
-}
-
-cl_entity_t *CorpseManager::FindGargantuaForPlayer(entity_state_t *player)
-{
- for (auto itor = m_gargantuaMap.begin(); itor != m_gargantuaMap.end(); itor++)
- {
- auto ent = gEngfuncs.GetEntityByIndex(itor->first);
- if (IsEntityGargantua(ent) && ent->curstate.sequence == 15)
- {
- if (VectorDistance(player->origin, ent->origin) < 128)
- {
- itor->second = player->number;
- return ent;
- }
- }
- }
-
- return NULL;
-}
\ No newline at end of file
diff --git a/Plugins/BulletPhysics/corpse.h b/Plugins/BulletPhysics/corpse.h
deleted file mode 100644
index 8156a632..00000000
--- a/Plugins/BulletPhysics/corpse.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-
-typedef struct
-{
- bool bIsDying;
- float flClientTime;
- float flAnimTime;
- int iSequence;
- int iBody;
- int iModelIndex;
- char szModelName[64];
- vec3_t vecOrigin;
- vec3_t vecAngles;
-}PlayerDying_t;
-
-class CorpseManager
-{
-public:
- CorpseManager(void);
-
- void AddGargantua(int entindex, int playerindex);
- void AddBarnacle(int entindex, int playerindex);
- void NewMap(void);
- cl_entity_t *FindGargantuaForPlayer(entity_state_t *entstate);
- cl_entity_t *FindBarnacleForPlayer(entity_state_t *entstate);
- cl_entity_t *FindPlayerForBarnacle(int entindex);
- cl_entity_t *FindPlayerForGargantua(int entindex);
- void FreePlayerForBarnacle(int entindex);
-
- void ClearPlayerDying(int entindex);
- void ClearAllPlayerDying();
- void SetPlayerDying(int entindex, entity_state_t *pplayer, model_t *model);
- int FindDyingPlayer(const char *modelname, vec3_t origin, vec3_t angles, int sequence, int body);
-
- void SetPlayerEmitted(int entindex);
- bool IsPlayerEmitted(int entindex);
- void ClearAllPlayerEmitState();
-private:
- std::unordered_map m_barnacleMap;
- std::unordered_map m_gargantuaMap;
-
- PlayerDying_t PlayerDying[33];
- bool PlayerEmitted[33];
-};
-
-extern CorpseManager gCorpseManager;
\ No newline at end of file
diff --git a/Plugins/BulletPhysics/exportfuncs.cpp b/Plugins/BulletPhysics/exportfuncs.cpp
index 01945ad0..74d25f43 100644
--- a/Plugins/BulletPhysics/exportfuncs.cpp
+++ b/Plugins/BulletPhysics/exportfuncs.cpp
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include "mathlib2.h"
#include "plugins.h"
@@ -15,7 +16,7 @@
#include "exportfuncs.h"
#include "privatehook.h"
#include "message.h"
-#include "corpse.h"
+#include "ClientEntityManager.h"
#include "physics.h"
hook_t *g_phook_GameStudioRenderer_StudioSetupBones = NULL;
@@ -74,13 +75,141 @@ ref_params_t r_params = { 0 };
float(*pbonetransform)[MAXSTUDIOBONES][3][4] = NULL;
float(*plighttransform)[MAXSTUDIOBONES][3][4] = NULL;
-bool IsEntityGargantua(cl_entity_t* ent);
-bool IsEntityBarnacle(cl_entity_t* ent);
-bool IsEntityWater(cl_entity_t* ent);
-bool IsEntityDeadPlayer(cl_entity_t* ent);
-bool IsEntityPresent(cl_entity_t* ent);
+model_t* CounterStrike_RedirectPlayerModel(model_t* original_model, int PlayerNumber, int* modelindex);
-int StudioGetSequenceActivityType(model_t *mod, entity_state_t* entstate);
+typedef enum
+{
+ ACT_RESET,
+ ACT_IDLE,
+ ACT_GUARD,
+ ACT_WALK,
+ ACT_RUN,
+ ACT_FLY,
+ ACT_SWIM,
+ ACT_HOP,
+ ACT_LEAP,
+ ACT_FALL,
+ ACT_LAND,
+ ACT_STRAFE_LEFT,
+ ACT_STRAFE_RIGHT,
+ ACT_ROLL_LEFT,
+ ACT_ROLL_RIGHT,
+ ACT_TURN_LEFT,
+ ACT_TURN_RIGHT,
+ ACT_CROUCH,
+ ACT_CROUCHIDLE,
+ ACT_STAND,
+ ACT_USE,
+ ACT_SIGNAL1,
+ ACT_SIGNAL2,
+ ACT_SIGNAL3,
+ ACT_TWITCH,
+ ACT_COWER,
+ ACT_SMALL_FLINCH,
+ ACT_BIG_FLINCH,
+ ACT_RANGE_ATTACK1,
+ ACT_RANGE_ATTACK2,
+ ACT_MELEE_ATTACK1,
+ ACT_MELEE_ATTACK2,
+ ACT_RELOAD,
+ ACT_ARM,
+ ACT_DISARM,
+ ACT_EAT,
+ ACT_DIESIMPLE,
+ ACT_DIEBACKWARD,
+ ACT_DIEFORWARD,
+ ACT_DIEVIOLENT,
+ ACT_BARNACLE_HIT,
+ ACT_BARNACLE_PULL,
+ ACT_BARNACLE_CHOMP,
+ ACT_BARNACLE_CHEW,
+ ACT_SLEEP,
+ ACT_INSPECT_FLOOR,
+ ACT_INSPECT_WALL,
+ ACT_IDLE_ANGRY,
+ ACT_WALK_HURT,
+ ACT_RUN_HURT,
+ ACT_HOVER,
+ ACT_GLIDE,
+ ACT_FLY_LEFT,
+ ACT_FLY_RIGHT,
+ ACT_DETECT_SCENT,
+ ACT_SNIFF,
+ ACT_BITE,
+ ACT_THREAT_DISPLAY,
+ ACT_FEAR_DISPLAY,
+ ACT_EXCITED,
+ ACT_SPECIAL_ATTACK1,
+ ACT_SPECIAL_ATTACK2,
+ ACT_COMBAT_IDLE,
+ ACT_WALK_SCARED,
+ ACT_RUN_SCARED,
+ ACT_VICTORY_DANCE,
+ ACT_DIE_HEADSHOT,
+ ACT_DIE_CHESTSHOT,
+ ACT_DIE_GUTSHOT,
+ ACT_DIE_BACKSHOT,
+ ACT_FLINCH_HEAD,
+ ACT_FLINCH_CHEST,
+ ACT_FLINCH_STOMACH,
+ ACT_FLINCH_LEFTARM,
+ ACT_FLINCH_RIGHTARM,
+ ACT_FLINCH_LEFTLEG,
+ ACT_FLINCH_RIGHTLEG,
+ ACT_FLINCH_SMALL,
+ ACT_FLINCH_LARGE,
+ ACT_HOLDBOMB
+}activity_e;
+
+int StudioGetSequenceActivityType(model_t* mod, entity_state_t* entstate)
+{
+ if (g_bIsSvenCoop)
+ {
+ if (entstate->scale != 0 && entstate->scale != 1.0f)
+ return 0;
+ }
+
+ if (mod->type != mod_studio)
+ return 0;
+
+ auto studiohdr = (studiohdr_t*)IEngineStudio.Mod_Extradata(mod);
+
+ if (!studiohdr)
+ return 0;
+
+ int sequence = entstate->sequence;
+ if (sequence >= studiohdr->numseq)
+ return 0;
+
+ auto pseqdesc = (mstudioseqdesc_t*)((byte*)studiohdr + studiohdr->seqindex) + sequence;
+
+ if (
+ pseqdesc->activity == ACT_DIESIMPLE ||
+ pseqdesc->activity == ACT_DIEBACKWARD ||
+ pseqdesc->activity == ACT_DIEFORWARD ||
+ pseqdesc->activity == ACT_DIEVIOLENT ||
+ pseqdesc->activity == ACT_DIEVIOLENT ||
+ pseqdesc->activity == ACT_DIE_HEADSHOT ||
+ pseqdesc->activity == ACT_DIE_CHESTSHOT ||
+ pseqdesc->activity == ACT_DIE_GUTSHOT ||
+ pseqdesc->activity == ACT_DIE_BACKSHOT
+ )
+ {
+ return 1;
+ }
+
+ if (
+ pseqdesc->activity == ACT_BARNACLE_HIT ||
+ pseqdesc->activity == ACT_BARNACLE_PULL ||
+ pseqdesc->activity == ACT_BARNACLE_CHOMP ||
+ pseqdesc->activity == ACT_BARNACLE_CHEW
+ )
+ {
+ return 2;
+ }
+
+ return 0;
+}
entity_state_t *R_GetPlayerState(int index)
{
@@ -127,12 +256,15 @@ model_t *EngineGetModelByIndex(int index)
void RagdollDestroyCallback(int entindex)
{
- gCorpseManager.FreePlayerForBarnacle(entindex);
+ ClientEntityManager()->FreePlayerForBarnacle(entindex);
}
-//EngineSetupBones
+/*
+ Purpose : StudioSetupBones hook handler
+*/
-void R_StudioSetupBones(void)
+template
+__forceinline void StudioSetupBones_Template(CallType pfnSetupBones, void* pthis = nullptr, int dummy = 0)
{
if ((g_iRagdollRenderState & (RagdollRenderState_Monster | RagdollRenderState_Player)) && !(g_iRagdollRenderState & RagdollRenderState_Jiggle))
{
@@ -140,11 +272,12 @@ void R_StudioSetupBones(void)
return;
}
- gPrivateFuncs.R_StudioSetupBones();
+ pfnSetupBones(pthis, dummy);
- if (IsEntityBarnacle((*currententity)))
+ if (ClientEntityManager()->IsEntityBarnacle((*currententity)))
{
- auto player = gCorpseManager.FindPlayerForBarnacle((*currententity)->index);
+ auto player = ClientEntityManager()->FindPlayerForBarnacle((*currententity)->index);
+
if (player)
{
gPhysicsManager.MergeBarnacleBones((*pstudiohdr), player->index);
@@ -158,118 +291,29 @@ void R_StudioSetupBones(void)
}
}
-//ClientSetupBones
-
-void __fastcall GameStudioRenderer_StudioSetupBones(void *pthis, int)
+__forceinline void R_StudioSetupBones_originalcall_wrapper(void* pthis, int dummy)
{
- if ((g_iRagdollRenderState & (RagdollRenderState_Monster | RagdollRenderState_Player)) && !(g_iRagdollRenderState & RagdollRenderState_Jiggle))
- {
- if (gPhysicsManager.SetupBones((*pstudiohdr), g_iRagdollRenderEntIndex))
- return;
- }
-
- gPrivateFuncs.GameStudioRenderer_StudioSetupBones(pthis, 0);
-
- if (IsEntityBarnacle((*currententity)))
- {
- auto player = gCorpseManager.FindPlayerForBarnacle((*currententity)->index);
- if (player)
- {
- gPhysicsManager.MergeBarnacleBones((*pstudiohdr), player->index);
- }
- }
-
- if ((g_iRagdollRenderState & (RagdollRenderState_Monster | RagdollRenderState_Player)) && (g_iRagdollRenderState & RagdollRenderState_Jiggle))
- {
- if (gPhysicsManager.SetupJiggleBones((*pstudiohdr), g_iRagdollRenderEntIndex))
- return;
- }
+ return gPrivateFuncs.R_StudioSetupBones();
}
-//EngineDrawModel
-
-int R_StudioDrawModel(int flags)
+void R_StudioSetupBones(void)
{
- if ((flags & STUDIO_RENDER) &&
- !(*currententity)->player &&
- (*currententity)->index &&
- (*currententity)->curstate.messagenum == (*cl_parsecount) &&
- (*currententity)->curstate.renderfx != kRenderFxDeadPlayer &&
- ((*currententity)->curstate.scale == 1.0f || (*currententity)->curstate.scale == 0.0f)
- )
- {
- int entindex = (*currententity)->index;
- auto model = (*currententity)->model;
-
- auto ragdoll = gPhysicsManager.FindRagdoll(entindex);
- if (!ragdoll)
- {
- auto cfg = gPhysicsManager.LoadRagdollConfig(model);
-
- if (cfg && cfg->state == 1 && bv_enable->value)
- {
- gPrivateFuncs.R_StudioDrawModel(0);
-
- ragdoll = gPhysicsManager.CreateRagdoll(cfg, entindex);
-
- goto has_ragdoll;
- }
- }
- else
- {
- has_ragdoll:
-
- int iActivityType = StudioGetSequenceActivityType(model, &(*currententity)->curstate);
-
- if (iActivityType == 0)
- {
- iActivityType = gPhysicsManager.GetSequenceActivityType(ragdoll, &(*currententity)->curstate);
- }
-
- if (gPhysicsManager.UpdateKinematic(ragdoll, iActivityType, &(*currententity)->curstate))
- {
- //Monster don't have barnacle animation
- }
-
- if (ragdoll->m_iActivityType > 0)
- {
- g_iRagdollRenderState = RagdollRenderState_Monster;
- g_iRagdollRenderEntIndex = entindex;
-
- vec3_t saved_origin;
- VectorCopy((*currententity)->origin, saved_origin);
- gPhysicsManager.GetRagdollOrigin(ragdoll, (*currententity)->origin);
-
- int result = gPrivateFuncs.R_StudioDrawModel(flags);
-
- VectorCopy(saved_origin, (*currententity)->origin);
-
- g_iRagdollRenderEntIndex = 0;
- g_iRagdollRenderState = RagdollRenderState_None;
-
- return result;
- }
- else
- {
- g_iRagdollRenderState = RagdollRenderState_Monster | RagdollRenderState_Jiggle;
- g_iRagdollRenderEntIndex = entindex;
-
- int result = gPrivateFuncs.R_StudioDrawModel(flags);
-
- g_iRagdollRenderEntIndex = 0;
- g_iRagdollRenderState = RagdollRenderState_None;
+ return StudioSetupBones_Template(R_StudioSetupBones_originalcall_wrapper);
+}
- return result;
- }
- }
- }
+//ClientSetupBones
- return gPrivateFuncs.R_StudioDrawModel(flags);
+void __fastcall GameStudioRenderer_StudioSetupBones(void *pthis, int dummy)
+{
+ return StudioSetupBones_Template(gPrivateFuncs.GameStudioRenderer_StudioSetupBones, pthis, dummy);
}
-//ClientDrawModel
+/*
+ Purpose : StudioDrawModel hook handler
+*/
-int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int flags)
+template
+__forceinline int StudioDrawModel_Template(CallType pfnDrawModel, int flags, void* pthis = nullptr, int dummy = 0)
{
if ((flags & STUDIO_RENDER) &&
!(*currententity)->player &&
@@ -289,9 +333,9 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
if (cfg && cfg->state == 1 && bv_enable->value)
{
- gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, 0);
+ pfnDrawModel(pthis, 0, 0);
- ragdoll = gPhysicsManager.CreateRagdoll(cfg, entindex);
+ ragdoll = gPhysicsManager.CreateRagdoll(model, cfg, entindex);
goto has_ragdoll;
}
@@ -312,12 +356,12 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
//Monster don't have barnacle animation
}
- if (IsEntityGargantua((*currententity)))
+ if (ClientEntityManager()->IsEntityGargantua((*currententity)))
{
g_iRagdollRenderState = RagdollRenderState_Monster | RagdollRenderState_Jiggle;
g_iRagdollRenderEntIndex = entindex;
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ int result = pfnDrawModel(pthis, 0, flags);
g_iRagdollRenderEntIndex = 0;
g_iRagdollRenderState = RagdollRenderState_None;
@@ -333,7 +377,7 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
VectorCopy((*currententity)->origin, saved_origin);
gPhysicsManager.GetRagdollOrigin(ragdoll, (*currententity)->origin);
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ int result = pfnDrawModel(pthis, 0, flags);
VectorCopy(saved_origin, (*currententity)->origin);
@@ -347,7 +391,7 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
g_iRagdollRenderState = RagdollRenderState_Monster | RagdollRenderState_Jiggle;
g_iRagdollRenderEntIndex = entindex;
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ int result = pfnDrawModel(pthis, 0, flags);
g_iRagdollRenderEntIndex = 0;
g_iRagdollRenderState = RagdollRenderState_None;
@@ -378,9 +422,9 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
if (cfg && cfg->state == 1 && bv_enable->value)
{
- gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, 0);
+ pfnDrawModel(pthis, 0, 0);
- ragdoll = gPhysicsManager.CreateRagdoll(cfg, entindex);
+ ragdoll = gPhysicsManager.CreateRagdoll(model, cfg, entindex);
goto has_ragdoll_clcorpse;
}
@@ -410,7 +454,7 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
VectorCopy((*currententity)->origin, saved_origin);
gPhysicsManager.GetRagdollOrigin(ragdoll, (*currententity)->origin);
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ int result = pfnDrawModel(pthis, 0, flags);
VectorCopy(saved_origin, (*currententity)->origin);
@@ -424,7 +468,7 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
g_iRagdollRenderState = RagdollRenderState_Monster | RagdollRenderState_Jiggle;
g_iRagdollRenderEntIndex = entindex;
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ int result = pfnDrawModel(pthis, 0, flags);
g_iRagdollRenderEntIndex = 0;
g_iRagdollRenderState = RagdollRenderState_None;
@@ -434,170 +478,32 @@ int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int fl
}
}
- return gPrivateFuncs.GameStudioRenderer_StudioDrawModel(pthis, 0, flags);
+ return pfnDrawModel(pthis, 0, flags);
}
-//EngineDrawPlayer
-
-int R_StudioDrawPlayer(int flags, struct entity_state_s *pplayer)
+__forceinline int R_StudioDrawModel_originalcall_wrapper(void* pthis, int dummy, int flags)
{
- int playerindex = pplayer->number;
-
- int entindex = ((*currententity)->curstate.renderfx == kRenderFxDeadPlayer) ? playerindex : (*currententity)->index;
-
- if (flags & STUDIO_RAGDOLL)
- {
- flags = 0;
- goto start_render;
- }
-
- if (flags & STUDIO_RENDER)
- {
- start_render:
-
- auto model = IEngineStudio.SetupPlayerModel(playerindex - 1);
-
- auto ragdoll = gPhysicsManager.FindRagdoll(entindex);
-
- if (!ragdoll)
- {
- auto cfg = gPhysicsManager.LoadRagdollConfig(model);
-
- if (cfg && cfg->state == 1 && bv_enable->value)
- {
- //Remove weapon model for me ?
- int save_weaponmodel = pplayer->weaponmodel;
- int save_sequence = pplayer->sequence;
- int save_gaitsequence = pplayer->gaitsequence;
-
- pplayer->weaponmodel = 0;
- pplayer->sequence = 0;
- pplayer->gaitsequence = 0;
-
- gPrivateFuncs.R_StudioDrawPlayer(0, pplayer);
-
- pplayer->weaponmodel = save_weaponmodel;
- pplayer->sequence = save_sequence;
- pplayer->gaitsequence = save_gaitsequence;
-
- if (!(*pstudiohdr))
- return 0;
-
- ragdoll = gPhysicsManager.CreateRagdoll(cfg, entindex);
-
- goto has_ragdoll;
- }
- }
- else
- {
- //model changed ?
- if (ragdoll->m_studiohdr != IEngineStudio.Mod_Extradata(model))
- {
- gPhysicsManager.RemoveRagdoll(playerindex);
- return gPrivateFuncs.R_StudioDrawPlayer(flags, pplayer);
- }
-
- has_ragdoll:
-
- int oldActivityType = ragdoll->m_iActivityType;
-
- int iActivityType = StudioGetSequenceActivityType(model, pplayer);
-
- if (iActivityType == 0)
- {
- iActivityType = gPhysicsManager.GetSequenceActivityType(ragdoll, pplayer);
- }
-
- if (playerindex == entindex)
- {
- if (iActivityType == 1)
- {
- gCorpseManager.SetPlayerDying(playerindex, pplayer, model);
- }
- else
- {
- gCorpseManager.ClearPlayerDying(playerindex);
- }
- }
-
- if (gPhysicsManager.UpdateKinematic(ragdoll, iActivityType, pplayer))
- {
- //Transform from whatever to barnacle anim
- if (ragdoll->m_iActivityType == 2)
- {
- cl_entity_t *barnacleEntity = gCorpseManager.FindBarnacleForPlayer(pplayer);
-
- if (barnacleEntity)
- {
- gPhysicsManager.ApplyBarnacle(ragdoll, barnacleEntity);
- }
- else
- {
- cl_entity_t *gargantuaEntity = gCorpseManager.FindGargantuaForPlayer(pplayer);
- if (gargantuaEntity)
- {
- gPhysicsManager.ApplyGargantua(ragdoll, gargantuaEntity);
- }
- }
- }
-
- //Transform from Death or barnacle to idle
- else if (oldActivityType > 0 && ragdoll->m_iActivityType == 0)
- {
- gPrivateFuncs.R_StudioDrawPlayer(0, pplayer);
-
- gPhysicsManager.ResetPose(ragdoll, pplayer);
- }
- }
-
- //Teleport ?
- else if (oldActivityType == 0 && ragdoll->m_iActivityType == 0 &&
- VectorDistance((*currententity)->curstate.origin, (*currententity)->latched.prevorigin) > 500)
- {
- gPrivateFuncs.R_StudioDrawPlayer(0, pplayer);
-
- gPhysicsManager.ResetPose(ragdoll, pplayer);
- }
-
- if (ragdoll->m_iActivityType > 0)
- {
- g_iRagdollRenderState = RagdollRenderState_Player;
- g_iRagdollRenderEntIndex = entindex;
-
- vec3_t saved_origin;
- VectorCopy((*currententity)->origin, saved_origin);
- gPhysicsManager.GetRagdollOrigin(ragdoll, (*currententity)->origin);
-
- int result = gPrivateFuncs.R_StudioDrawPlayer(flags, pplayer);
-
- VectorCopy(saved_origin, (*currententity)->origin);
-
- g_iRagdollRenderEntIndex = 0;
- g_iRagdollRenderState = RagdollRenderState_None;
- return result;
- }
- else
- {
- g_iRagdollRenderState = RagdollRenderState_Player | RagdollRenderState_Jiggle;
- g_iRagdollRenderEntIndex = (*currententity)->curstate.number;
-
- int result = gPrivateFuncs.R_StudioDrawPlayer(flags, pplayer);
+ return gPrivateFuncs.R_StudioDrawModel(flags);
+}
- g_iRagdollRenderEntIndex = 0;
- g_iRagdollRenderState = RagdollRenderState_None;
- return result;
- }
- }
- }
+int R_StudioDrawModel(int flags)
+{
+ return StudioDrawModel_Template(R_StudioDrawModel_originalcall_wrapper, flags);
+}
- return gPrivateFuncs.R_StudioDrawPlayer(flags, pplayer);
+int __fastcall GameStudioRenderer_StudioDrawModel(void *pthis, int dummy, int flags)
+{
+ return StudioDrawModel_Template(gPrivateFuncs.GameStudioRenderer_StudioDrawModel, flags, pthis, dummy);
}
-//client.dll GameStudioRenderer::StudioDrawPlayer
+/*
+
+ Purpose : StudioDrawPlayer hook handler
-model_t *CounterStrike_RedirectPlayerModel(model_t *original_model, int PlayerNumber, int *modelindex);
+*/
-int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int flags, struct entity_state_s *pplayer)
+template
+__forceinline int StudioDrawPlayer_Template(CallType pfnDrawPlayer, int flags, struct entity_state_s*pplayer, void* pthis = nullptr, int dummy = 0)
{
int playerindex = pplayer->number;
@@ -613,11 +519,11 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
{
start_render:
- auto model = IEngineStudio.SetupPlayerModel(playerindex - 1);
+ auto model = IEngineStudio.SetupPlayerModel(playerindex - 1);
if (g_bIsCounterStrike)
{
- //Counter-Strike redirect player models in pretty tricky way
+ //Counter-Strike redirects playermodel in a pretty tricky way
int modelindex = 0;
model = CounterStrike_RedirectPlayerModel(model, playerindex, &modelindex);
}
@@ -639,7 +545,7 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
pplayer->sequence = 0;
pplayer->gaitsequence = 0;
- gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, 0, pplayer);
+ pfnDrawPlayer(pthis, 0, 0, pplayer);
pplayer->weaponmodel = save_weaponmodel;
pplayer->sequence = save_sequence;
@@ -648,7 +554,7 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
if (!(*pstudiohdr))
return 0;
- ragdoll = gPhysicsManager.CreateRagdoll(cfg, entindex);
+ ragdoll = gPhysicsManager.CreateRagdoll(model, cfg, entindex);
goto has_ragdoll;
}
@@ -656,10 +562,10 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
else
{
//model changed ?
- if (ragdoll->m_studiohdr != IEngineStudio.Mod_Extradata(model))
+ if (ragdoll->m_model != model)
{
gPhysicsManager.RemoveRagdoll(entindex);
- return gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, flags, pplayer);
+ return pfnDrawPlayer(pthis, 0, flags, pplayer);
}
has_ragdoll:
@@ -677,11 +583,11 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
{
if (iActivityType == 1)
{
- gCorpseManager.SetPlayerDying(playerindex, pplayer, model);
+ ClientEntityManager()->SetPlayerDeathState(playerindex, pplayer, model);
}
else
{
- gCorpseManager.ClearPlayerDying(playerindex);
+ ClientEntityManager()->ClearPlayerDeathState(playerindex);
}
}
@@ -690,37 +596,37 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
//Transform from whatever to barnacle
if (ragdoll->m_iActivityType == 2)
{
- cl_entity_t *barnacleEntity = gCorpseManager.FindBarnacleForPlayer(pplayer);
-
- if (barnacleEntity)
+ auto BarnacleEntity = ClientEntityManager()->FindBarnacleForPlayer(pplayer);
+
+ if (BarnacleEntity)
{
- gPhysicsManager.ApplyBarnacle(ragdoll, barnacleEntity);
+ gPhysicsManager.ApplyBarnacle(ragdoll, BarnacleEntity);
}
else
{
- cl_entity_t *gargantuaEntity = gCorpseManager.FindGargantuaForPlayer(pplayer);
- if (gargantuaEntity)
+ auto GargantuaEntity = ClientEntityManager()->FindGargantuaForPlayer(pplayer);
+
+ if (GargantuaEntity)
{
- gPhysicsManager.ApplyGargantua(ragdoll, gargantuaEntity);
+ gPhysicsManager.ApplyGargantua(ragdoll, GargantuaEntity);
}
}
}
- //Transform from Death or barnacle to idle
+ //Transform from death or barnacle to idle state.
else if (oldActivityType > 0 && ragdoll->m_iActivityType == 0)
{
- gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, 0, pplayer);
+ pfnDrawPlayer(pthis, 0, 0, pplayer);
gPhysicsManager.ResetPose(ragdoll, pplayer);
}
-
}
//Teleport ?
else if (oldActivityType == 0 && ragdoll->m_iActivityType == 0 &&
VectorDistance((*currententity)->curstate.origin, (*currententity)->latched.prevorigin) > 500)
{
- gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, 0, pplayer);
+ pfnDrawPlayer(pthis, 0, 0, pplayer);
gPhysicsManager.ResetPose(ragdoll, pplayer);
}
@@ -739,7 +645,7 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
pplayer->weaponmodel = 0;
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, flags, pplayer);
+ int result = pfnDrawPlayer(pthis, 0, flags, pplayer);
pplayer->weaponmodel = saved_weaponmodel;
@@ -747,6 +653,7 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
g_iRagdollRenderEntIndex = 0;
g_iRagdollRenderState = RagdollRenderState_None;
+
return result;
}
else
@@ -754,16 +661,32 @@ int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int f
g_iRagdollRenderState = RagdollRenderState_Player | RagdollRenderState_Jiggle;
g_iRagdollRenderEntIndex = entindex;
- int result = gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, flags, pplayer);
+ int result = pfnDrawPlayer(pthis, 0, flags, pplayer);
g_iRagdollRenderEntIndex = 0;
g_iRagdollRenderState = RagdollRenderState_None;
+
return result;
}
}
}
- return gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer(pthis, 0, flags, pplayer);
+ return pfnDrawPlayer(pthis, 0, flags, pplayer);
+}
+
+__forceinline int R_StudioDrawPlayer_originalcall_wrapper(void* pthis, int dummy, int flags, struct entity_state_s* pplayer)
+{
+ return gPrivateFuncs.R_StudioDrawPlayer(flags, pplayer);
+}
+
+int R_StudioDrawPlayer(int flags, struct entity_state_s*pplayer)
+{
+ return StudioDrawPlayer_Template(R_StudioDrawPlayer_originalcall_wrapper, flags, pplayer);
+}
+
+int __fastcall GameStudioRenderer_StudioDrawPlayer(void *pthis, int dummy, int flags, struct entity_state_s*pplayer)
+{
+ return StudioDrawPlayer_Template(gPrivateFuncs.GameStudioRenderer_StudioDrawPlayer, flags, pplayer, pthis, dummy);
}
int HUD_GetStudioModelInterface(int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio)
@@ -1433,27 +1356,27 @@ int HUD_AddEntity(int type, cl_entity_t *ent, const char *model)
gPhysicsManager.CreateBrushModel(ent);
}
- if (IsEntityDeadPlayer(ent))
+ if (ClientEntityManager()->IsEntityDeadPlayer(ent))
{
int playerindex = (int)ent->curstate.renderamt;
gPhysicsManager.ChangeRagdollEntIndex(playerindex, ent->index);
}
- else if (IsEntityBarnacle(ent))
+ else if (ClientEntityManager()->IsEntityBarnacle(ent))
{
gPhysicsManager.CreateBarnacle(ent);
- gCorpseManager.AddBarnacle(ent->index, 0);
+ ClientEntityManager()->AddBarnacle(ent->index, 0);
}
- else if (IsEntityGargantua(ent))
+ else if (ClientEntityManager()->IsEntityGargantua(ent))
{
gPhysicsManager.CreateGargantua(ent);
- gCorpseManager.AddGargantua(ent->index, 0);
+ ClientEntityManager()->AddGargantua(ent->index, 0);
}
}
if (type == ET_PLAYER && ent->model)
{
- gCorpseManager.SetPlayerEmitted(ent->index);
+ ClientEntityManager()->SetPlayerEmitted(ent->index);
}
return gExportfuncs.HUD_AddEntity(type, ent, model);
@@ -1470,11 +1393,14 @@ void HUD_TempEntUpdate(
{
gExportfuncs.HUD_TempEntUpdate(frametime, client_time, cl_gravity, ppTempEntFree, ppTempEntActive, Callback_AddVisibleEntity, Callback_TempEntPlaySound);
+ //Update only if level is present
+
auto levelname = gEngfuncs.pfnGetLevelName();
+
if (levelname && levelname[0])
{
gPhysicsManager.SetGravity(cl_gravity);
- gPhysicsManager.UpdateTempEntity(ppTempEntActive, frametime, client_time);
+ gPhysicsManager.UpdateTempEntity(ppTempEntFree, ppTempEntActive, frametime, client_time);
gPhysicsManager.StepSimulation(frametime);
}
}
@@ -1483,7 +1409,7 @@ void HUD_Frame(double frametime)
{
gExportfuncs.HUD_Frame(frametime);
- gCorpseManager.ClearAllPlayerEmitState();
+ ClientEntityManager()->ClearAllPlayerEmitState();
}
void HUD_Shutdown(void)
@@ -1604,8 +1530,8 @@ void HUD_CreateEntities(void)
auto viewplayer = gEngfuncs.GetEntityByIndex((*cl_viewentity));
if (viewplayer && viewplayer->player)
{
- if (IsEntityPresent(viewplayer) &&
- !gCorpseManager.IsPlayerEmitted(viewplayer->index) &&
+ if (ClientEntityManager()->IsEntityPresent(viewplayer) &&
+ !ClientEntityManager()->IsPlayerEmitted(viewplayer->index) &&
CL_IsFirstPersonMode(viewplayer))
{
auto playerstate = R_GetPlayerState(viewplayer->index);
diff --git a/Plugins/BulletPhysics/message.cpp b/Plugins/BulletPhysics/message.cpp
index 9450d92e..6f525074 100644
--- a/Plugins/BulletPhysics/message.cpp
+++ b/Plugins/BulletPhysics/message.cpp
@@ -4,8 +4,8 @@
#include "privatehook.h"
#include "parsemsg.h"
#include "message.h"
-#include "corpse.h"
#include "event_api.h"
+#include "ClientEntityManager.h"
cvar_t *cl_minmodels = NULL;
cvar_t *cl_min_t = NULL;
@@ -153,27 +153,30 @@ int __MsgFunc_ClCorpse(const char *pszName, int iSize, void *pbuf)
BEGIN_READ(pbuf, iSize);
auto model = READ_STRING();
+
+ char szModel[64] = { 0 };
+ strncpy(szModel, model, sizeof(szModel));
+
vOrigin[0] = 0.0078125f * READ_LONG();
vOrigin[1] = 0.0078125f * READ_LONG();
vOrigin[2] = 0.0078125f * READ_LONG();
vAngles[0] = READ_COORD();
vAngles[1] = READ_COORD();
vAngles[2] = READ_COORD();
- auto delay = READ_LONG();
+ auto Delay = READ_LONG();
auto Sequence = READ_BYTE();
auto Body = READ_BYTE();
auto TeamID = READ_BYTE();
auto PlayerID = READ_BYTE();
- char szModel[64] = { 0 };
-
- CounterStrike_RedirectPlayerModelPath(model, PlayerID, TeamID, szModel, sizeof(szModel));
+ char szNewModel[64] = { 0 };
+ CounterStrike_RedirectPlayerModelPath(szModel, PlayerID, TeamID, szNewModel, sizeof(szNewModel));
g_bIsCreatingClCorpse = true;
if (PlayerID <= 0 || PlayerID > gEngfuncs.GetMaxClients())
{
- g_iCreatingClCorpsePlayerIndex = gCorpseManager.FindDyingPlayer(szModel, vOrigin, vAngles, Sequence, Body);
+ g_iCreatingClCorpsePlayerIndex = ClientEntityManager()->FindDyingPlayer(szModel, vOrigin, vAngles, Sequence, Body);
}
else
{
diff --git a/Plugins/BulletPhysics/physics.cpp b/Plugins/BulletPhysics/physics.cpp
index 2a11e874..51a9c520 100644
--- a/Plugins/BulletPhysics/physics.cpp
+++ b/Plugins/BulletPhysics/physics.cpp
@@ -1,17 +1,16 @@
-#include "exportfuncs.h"
+#include
#include
#include
#include
+#include "exportfuncs.h"
#include "enginedef.h"
#include "plugins.h"
#include "privatehook.h"
#include "physics.h"
+#include "ClientEntityManager.h"
#include "qgl.h"
#include "mathlib2.h"
-//btScalar G2BScale = 1;
-//btScalar B2GScale = 1 / G2BScale;
-
extern studiohdr_t **pstudiohdr;
extern model_t **r_model;
extern float(*pbonetransform)[128][3][4];
@@ -19,7 +18,6 @@ extern float(*plighttransform)[128][3][4];
extern cvar_t *bv_debug;
extern cvar_t *bv_simrate;
-//extern cvar_t *bv_scale;
extern cvar_t *bv_ragdoll_sleepaftertime;
extern cvar_t *bv_ragdoll_sleeplinearvel;
extern cvar_t *bv_ragdoll_sleepangularvel;
@@ -32,11 +30,6 @@ int EngineGetNumKnownModel(void);
int EngineGetMaxKnownModel(void);
int EngineGetModelIndex(model_t *mod);
model_t *EngineGetModelByIndex(int index);
-bool IsEntityPresent(cl_entity_t* ent);
-bool IsEntityGargantua(cl_entity_t* ent);
-bool IsEntityBarnacle(cl_entity_t* ent);
-bool IsEntityWater(cl_entity_t* ent);
-bool IsEntityEmitted(cl_entity_t* ent);
int StudioGetSequenceActivityType(model_t *mod, entity_state_t* entstate);
void RagdollDestroyCallback(int entindex);
@@ -64,9 +57,14 @@ void EulerMatrix(const btVector3& in_euler, btMatrix3x3& out_matrix) {
}
void MatrixEuler(const btMatrix3x3& in_matrix, btVector3& out_euler) {
+
out_euler[0] = btAsin(in_matrix[2][0]);
- if (btFabs(in_matrix[2][0]) < (1 - 0.001f)) {
+ if (in_matrix[2][0] >= (1 - 0.002f) && in_matrix[2][0] < 1.002f) {
+ out_euler[1] = btAtan2(in_matrix[1][0], in_matrix[0][0]);
+ out_euler[2] = btAtan2(in_matrix[2][1], in_matrix[2][2]);
+ }
+ else if (btFabs(in_matrix[2][0]) < (1 - 0.002f)) {
out_euler[1] = btAtan2(in_matrix[1][0], in_matrix[0][0]);
out_euler[2] = btAtan2(in_matrix[2][1], in_matrix[2][2]);
}
@@ -75,6 +73,8 @@ void MatrixEuler(const btMatrix3x3& in_matrix, btVector3& out_euler) {
out_euler[2] = 0;
}
+ out_euler[3] = 0;
+
out_euler *= SIMD_DEGS_PER_RAD;
}
@@ -190,6 +190,7 @@ CPhysicsManager::CPhysicsManager()
m_collisionConfiguration = NULL;
m_dispatcher = NULL;
m_overlappingPairCache = NULL;
+ m_overlapFilterCallback = NULL;
m_solver = NULL;
m_dynamicsWorld = NULL;
m_debugDraw = NULL;
@@ -801,6 +802,7 @@ struct GameFilterCallback : public btOverlapFilterCallback
{
auto physobj0 = (CRigBody *)body0->getUserPointer();
auto physobj1 = (CRigBody *)body1->getUserPointer();
+
if( (physobj0->flags & RIG_FL_JIGGLE) && !(physobj1->flags & RIG_FL_JIGGLE) )
{
if (!(body1->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT))
@@ -1218,12 +1220,18 @@ void CPhysicsManager::UpdateRagdollSleepState(cl_entity_t *ent, CRagdollBody *ra
return;
}
- // It has stopped moving, see if it
+ // It has stopped moving
if (client_time - ragdoll->m_flLastOriginChangeTime < bv_ragdoll_sleepaftertime->value)
{
return;
}
+ // It was just created in few seconds before
+ if (client_time - ragdoll->m_flLastRagdollCreateTime < bv_ragdoll_sleepaftertime->value)
+ {
+ return;
+ }
+
// Force it to go to sleep
ForceRagdollToSleep(ragdoll);
@@ -1296,6 +1304,10 @@ void CPhysicsManager::UpdateRagdollWaterSimulation(cl_entity_t *ent, CRagdollBod
#endif
}
+/*
+ Purpose: Perform frame-action for the given ragdoll object.
+*/
+
bool CPhysicsManager::UpdateRagdoll(cl_entity_t *ent, CRagdollBody *ragdoll, double frame_time, double client_time)
{
//Don't update if player is not emitted this frame (in firstperson mode)
@@ -1309,13 +1321,12 @@ bool CPhysicsManager::UpdateRagdoll(cl_entity_t *ent, CRagdollBody *ragdoll, dou
if (StudioGetSequenceActivityType(ent->model, &ent->curstate) != 2)
{
ReleaseRagdollFromGargantua(ragdoll);
-
return true;
}
auto gargantua = gEngfuncs.GetEntityByIndex(ragdoll->m_gargantuaindex);
- if (!IsEntityGargantua(gargantua))
+ if (!ClientEntityManager()->IsEntityGargantua(gargantua))
{
ReleaseRagdollFromGargantua(ragdoll);
return true;
@@ -1346,13 +1357,12 @@ bool CPhysicsManager::UpdateRagdoll(cl_entity_t *ent, CRagdollBody *ragdoll, dou
if (StudioGetSequenceActivityType(ent->model, &ent->curstate) != 2)
{
ReleaseRagdollFromBarnacle(ragdoll);
-
return true;
}
auto barnacle = gEngfuncs.GetEntityByIndex(ragdoll->m_barnacleindex);
- if (!IsEntityBarnacle(barnacle))
+ if (!ClientEntityManager()->IsEntityBarnacle(barnacle))
{
ReleaseRagdollFromBarnacle(ragdoll);
return true;
@@ -1438,12 +1448,12 @@ bool CPhysicsManager::UpdateRagdoll(cl_entity_t *ent, CRagdollBody *ragdoll, dou
return true;
}
-void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double frame_time, double client_time)
+void CPhysicsManager::UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY **ppTempEntActive, double frame_time, double client_time)
{
if (frame_time <= 0)
return;
- auto pTEnt = *ppTempEntActive;
+ auto pTEnt = (*ppTempEntActive);
while (pTEnt)
{
@@ -1456,15 +1466,13 @@ void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double fram
if (itor != m_ragdollMap.end())
{
UpdateRagdoll(ent, itor->second, frame_time, client_time);
-
- //Fake messagenum, just mark as active
- ent->curstate.messagenum = (*cl_parsecount);
}
}
pTEnt = pTEnt->next;
}
+ //Purpose: Remove ragdollObjects that tend to be removed.
for (auto itor = m_ragdollMap.begin(); itor != m_ragdollMap.end();)
{
int entindex = itor->first;
@@ -1473,7 +1481,8 @@ void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double fram
{
//Remove inactive tents
auto tent = &gTempEnts[entindex - ENTINDEX_TEMPENTITY];
- if (tent->entity.curstate.messagenum != (*cl_parsecount))
+
+ if (!ClientEntityManager()->IsTempEntityPresent(ppTempEntFree, ppTempEntActive, tent))
{
itor = FreeRagdollInternal(itor);
}
@@ -1486,7 +1495,7 @@ void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double fram
auto ent = gEngfuncs.GetEntityByIndex(entindex);
- if (!IsEntityPresent(ent) ||
+ if (!ClientEntityManager()->IsEntityPresent(ent) ||
!UpdateRagdoll(ent, itor->second, frame_time, client_time))
{
itor = FreeRagdollInternal(itor);
@@ -1497,6 +1506,7 @@ void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double fram
}
}
+ //Purpose: Remove staticObjects that tend to be removed.
for (auto itor = m_staticMap.begin(); itor != m_staticMap.end();)
{
if (itor->first == 0)
@@ -1507,7 +1517,7 @@ void CPhysicsManager::UpdateTempEntity(TEMPENTITY **ppTempEntActive, double fram
auto ent = gEngfuncs.GetEntityByIndex(itor->first);
- if (!IsEntityPresent(ent))
+ if (!ClientEntityManager()->IsEntityPresent(ent))
{
itor = FreeStaticInternal(itor);
}
@@ -2867,11 +2877,13 @@ ragdoll_itor CPhysicsManager::FreeRagdollInternal(ragdoll_itor &itor)
for (auto p : ragdoll->m_rigbodyMap)
{
auto rig = p.second;
+
if (rig->buoyancy)
{
m_dynamicsWorld->removeAction(rig->buoyancy);
delete rig->buoyancy;
}
+
if (rig->rigbody)
{
m_dynamicsWorld->removeRigidBody(rig->rigbody);
@@ -2957,7 +2969,7 @@ void CPhysicsManager::MergeBarnacleBones(studiohdr_t *hdr, int entindex)
return;
}
- mstudiobone_t *pbones = (mstudiobone_t *)((byte *)(*pstudiohdr) + (*pstudiohdr)->boneindex);
+ mstudiobone_t *pbones = (mstudiobone_t *)((byte *)hdr + hdr->boneindex);
auto ragdoll = itor->second;
@@ -3045,7 +3057,7 @@ bool CPhysicsManager::SetupBones(studiohdr_t *hdr, int entindex)
return false;
}
- mstudiobone_t *pbones = (mstudiobone_t *)((byte *)(*pstudiohdr) + (*pstudiohdr)->boneindex);
+ mstudiobone_t *pbones = (mstudiobone_t *)((byte *)hdr + hdr->boneindex);
auto ragdoll = itor->second;
@@ -3140,9 +3152,11 @@ bool CPhysicsManager::ChangeRagdollEntIndex(ragdoll_itor &itor, int new_entindex
void CPhysicsManager::ResetPose(CRagdollBody *ragdoll, entity_state_t *curstate)
{
+ auto studiohdr = (studiohdr_t *)IEngineStudio.Mod_Extradata(ragdoll->m_model);
+
bool bNeedResetKinematic = false;
- mstudiobone_t *pbones = (mstudiobone_t *)((byte *)ragdoll->m_studiohdr + ragdoll->m_studiohdr->boneindex);
+ mstudiobone_t *pbones = (mstudiobone_t *)((byte *)studiohdr + studiohdr->boneindex);
for (auto &p : ragdoll->m_rigbodyMap)
{
@@ -3545,17 +3559,22 @@ bool CPhysicsManager::UpdateKinematic(CRagdollBody *ragdoll, int iActivityType,
return true;
}
-CRagdollBody *CPhysicsManager::CreateRagdoll(ragdoll_config_t *cfg, int entindex)
+CRagdollBody *CPhysicsManager::CreateRagdoll(model_t *mod, ragdoll_config_t *cfg, int entindex)
{
+ auto studiohdr = (studiohdr_t*)IEngineStudio.Mod_Extradata(mod);
+
auto ragdoll = new CRagdollBody();
- mstudiobone_t *pbones = (mstudiobone_t *)((byte *)(*pstudiohdr) + (*pstudiohdr)->boneindex);
+ ragdoll->m_flLastRagdollCreateTime = gEngfuncs.GetClientTime();
+
+ mstudiobone_t *pbones = (mstudiobone_t *)((byte *)studiohdr + studiohdr->boneindex);
//Save bone relative transform
- for (int i = 0; i < (*pstudiohdr)->numbones; ++i)
+ for (int i = 0; i < studiohdr->numbones; ++i)
{
int parent = pbones[i].parent;
+
if (parent == -1)
{
Matrix3x4ToTransform((*pbonetransform)[i], ragdoll->m_boneRelativeTransform[i]);
@@ -3579,7 +3598,7 @@ CRagdollBody *CPhysicsManager::CreateRagdoll(ragdoll_config_t *cfg, int entindex
{
auto rigcontrol = &cfg->rigcontrol[i];
- CRigBody *rig = CreateRigBody((*pstudiohdr), rigcontrol);
+ CRigBody *rig = CreateRigBody(studiohdr, rigcontrol);
if (rig)
{
ragdoll->m_keyBones.emplace_back(rigcontrol->boneindex);
@@ -3599,7 +3618,7 @@ CRagdollBody *CPhysicsManager::CreateRagdoll(ragdoll_config_t *cfg, int entindex
//m_dynamicsWorld->addAction(rig->buoyancy);
}
- for (int i = 0; i < (*pstudiohdr)->numbones; ++i)
+ for (int i = 0; i < studiohdr->numbones; ++i)
{
if (std::find(ragdoll->m_keyBones.begin(), ragdoll->m_keyBones.end(), i) == ragdoll->m_keyBones.end())
ragdoll->m_nonKeyBones.emplace_back(i);
@@ -3609,21 +3628,22 @@ CRagdollBody *CPhysicsManager::CreateRagdoll(ragdoll_config_t *cfg, int entindex
{
auto cstcontrol = &cfg->cstcontrol[i];
- CreateConstraint(ragdoll, (*pstudiohdr), cstcontrol);
+ CreateConstraint(ragdoll, studiohdr, cstcontrol);
}
for (size_t i = 0; i < cfg->watercontrol.size(); ++i)
{
auto water_control = &cfg->watercontrol[i];
- CreateWaterControl(ragdoll, (*pstudiohdr), water_control);
+ CreateWaterControl(ragdoll, studiohdr, water_control);
}
ragdoll->m_entindex = entindex;
- ragdoll->m_studiohdr = (*pstudiohdr);
+ ragdoll->m_model = mod;
ragdoll->m_animcontrol = cfg->animcontrol;
ragdoll->m_barcontrol = cfg->barcontrol;
ragdoll->m_garcontrol = cfg->garcontrol;
+
VectorCopy(cfg->firstperson_angleoffset, ragdoll->m_firstperson_angleoffset);
m_ragdollMap[entindex] = ragdoll;
diff --git a/Plugins/BulletPhysics/physics.h b/Plugins/BulletPhysics/physics.h
index f9d5927f..267a1337 100644
--- a/Plugins/BulletPhysics/physics.h
+++ b/Plugins/BulletPhysics/physics.h
@@ -300,7 +300,7 @@ CRagdollBody : public CPhysicBody
{
m_barnacleindex = -1;
m_gargantuaindex = -1;
- m_studiohdr = NULL;
+ m_model = NULL;
m_pelvisRigBody = NULL;
m_headRigBody = NULL;
m_iActivityType = -1;
@@ -310,6 +310,7 @@ CRagdollBody : public CPhysicBody
m_firstperson_angleoffset[1] = 0;
m_firstperson_angleoffset[2] = 0;
m_flLastOriginChangeTime = 0;
+ m_flLastRagdollCreateTime = 0;
}
int m_barnacleindex;
@@ -317,7 +318,7 @@ CRagdollBody : public CPhysicBody
int m_iActivityType;
float m_flUpdateKinematicTime;
float m_bUpdateKinematic;
- studiohdr_t *m_studiohdr;
+ model_t *m_model;
CRigBody *m_pelvisRigBody;
CRigBody *m_headRigBody;
std::vector m_barnacleDragRigBody;
@@ -335,6 +336,7 @@ CRagdollBody : public CPhysicBody
std::vector m_garcontrol;
vec3_t m_firstperson_angleoffset;
float m_flLastOriginChangeTime;
+ float m_flLastRagdollCreateTime;
};
typedef struct brushvertex_s
@@ -550,7 +552,7 @@ class CPhysicsManager
void ResetPose(CRagdollBody *ragdoll, entity_state_t *curstate);
void ApplyBarnacle(CRagdollBody *ragdoll, cl_entity_t *barnacleEntity);
void ApplyGargantua(CRagdollBody *ragdoll, cl_entity_t *gargEntity);
- CRagdollBody *CreateRagdoll(ragdoll_config_t *cfg, int entindex);
+ CRagdollBody *CreateRagdoll(model_t* mod, ragdoll_config_t *cfg, int entindex);
CRigBody *CreateRigBody(studiohdr_t *studiohdr, ragdoll_rig_control_t *rigcontrol);
btTypedConstraint *CreateConstraint(CRagdollBody *ragdoll, studiohdr_t *hdr, ragdoll_cst_control_t *cstcontrol);
void CreateWaterControl(CRagdollBody *ragdoll, studiohdr_t *studiohdr, ragdoll_water_control_t *water_control);
@@ -565,7 +567,7 @@ class CPhysicsManager
bool UpdateRagdoll(cl_entity_t *ent, CRagdollBody *ragdoll, double frame_time, double client_time);
void UpdateRagdollWaterSimulation(cl_entity_t *ent, CRagdollBody *ragdoll, double frame_time, double client_time);
void UpdateRagdollSleepState(cl_entity_t *ent, CRagdollBody *ragdoll, double frame_time, double client_time);
- void UpdateTempEntity(TEMPENTITY **ppTempEntActive, double frame_time, double client_time);
+ void UpdateTempEntity(TEMPENTITY** ppTempEntFree, TEMPENTITY **ppTempEntActive, double frame_time, double client_time);
//bool SyncThirdPersonView(CRagdollBody *ragdoll, float *org);
bool SyncFirstPersonView(CRagdollBody *ragdoll, cl_entity_t *ent, struct ref_params_s *pparams);
void ForceRagdollToSleep(CRagdollBody *ragdoll);
diff --git a/Plugins/BulletPhysics/privatehook.cpp b/Plugins/BulletPhysics/privatehook.cpp
index f31d5a56..6dec96f9 100644
--- a/Plugins/BulletPhysics/privatehook.cpp
+++ b/Plugins/BulletPhysics/privatehook.cpp
@@ -5,8 +5,8 @@
#include "plugins.h"
#include "privatehook.h"
#include "message.h"
-#include "corpse.h"
#include "physics.h"
+#include "ClientEntityManager.h"
#define R_NEWMAP_SIG_COMMON "\x55\x8B\xEC\x83\xEC\x2A\xC7\x45\xFC\x00\x00\x00\x00\x2A\x2A\x8B\x45\xFC\x83\xC0\x01\x89\x45\xFC"
#define R_NEWMAP_SIG_BLOB R_NEWMAP_SIG_COMMON
@@ -534,7 +534,7 @@ void R_NewMap(void)
{
gPrivateFuncs.R_NewMap();
gPhysicsManager.NewMap();
- gCorpseManager.NewMap();
+ ClientEntityManager()->NewMap();
}
TEMPENTITY *efxapi_R_TempModel(float *pos, float *dir, float *angles, float life, int modelIndex, int soundtype)