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)