From 2d1083616732f21711bbfe76aa4458675b7f89bd Mon Sep 17 00:00:00 2001 From: Matt Haynie Date: Mon, 19 Feb 2018 15:00:19 -0800 Subject: [PATCH] * Added ce_infills_test * Added ce_infills_additive * Fixed wildly inconsistant flicker/fade durations for infills. * ce_cameratools_spec_pos now keeps previous spec_mode if mode parameter is omitted. --- CastingEssentials/CastingEssentials.vcxproj | 3 +- CastingEssentials/Modules/CameraTools.cpp | 4 +- CastingEssentials/Modules/Graphics.cpp | 219 +++++++----------- CastingEssentials/Modules/Graphics.h | 33 ++- .../PluginBase/CastingPlugin.cpp | 2 +- CastingEssentials/PluginBase/Player.cpp | 39 ++-- CastingEssentials/PluginBase/Player.h | 10 +- sdk2013 | 2 +- 8 files changed, 149 insertions(+), 163 deletions(-) diff --git a/CastingEssentials/CastingEssentials.vcxproj b/CastingEssentials/CastingEssentials.vcxproj index abb4926..4588c94 100644 --- a/CastingEssentials/CastingEssentials.vcxproj +++ b/CastingEssentials/CastingEssentials.vcxproj @@ -59,11 +59,12 @@ /EDITANDCONTINUE %(AdditionalOptions) false false + UseLinkTimeCodeGeneration - MaxSpeed + Full true true MultiThreaded diff --git a/CastingEssentials/Modules/CameraTools.cpp b/CastingEssentials/Modules/CameraTools.cpp index bdc6894..d28c977 100644 --- a/CastingEssentials/Modules/CameraTools.cpp +++ b/CastingEssentials/Modules/CameraTools.cpp @@ -707,8 +707,10 @@ void CameraTools::SpecPosition(const CCommand &command) QAngle pluginAng; CameraState::GetModule()->GetLastFramePluginView(pluginPos, pluginAng); + const ObserverMode defaultMode = (ObserverMode)Interfaces::GetHLTVCamera()->m_nCameraMode; + // Legacy support, we used to always force OBS_MODE_FIXED - if (ParseSpecPosCommand(command, pos, ang, mode, pluginPos, pluginAng, OBS_MODE_FIXED)) + if (ParseSpecPosCommand(command, pos, ang, mode, pluginPos, pluginAng, defaultMode)) SpecPosition(pos, ang, mode); } diff --git a/CastingEssentials/Modules/Graphics.cpp b/CastingEssentials/Modules/Graphics.cpp index 0cc59ab..272ed12 100644 --- a/CastingEssentials/Modules/Graphics.cpp +++ b/CastingEssentials/Modules/Graphics.cpp @@ -51,11 +51,13 @@ Graphics::Graphics() ce_outlines_debug = new ConVar("ce_outlines_debug", "0", FCVAR_NONE); ce_infills_enable = new ConVar("ce_infills_enable", "0", FCVAR_NONE, "Enables player infills."); + ce_infills_additive = new ConVar("ce_infills_additive", "0", FCVAR_NONE, "Enables additive rendering of player infills."); ce_infills_hurt_red = new ConVar("ce_infills_hurt_red", "255 0 0 64", FCVAR_NONE, "Infill for red players that are not overhealed."); ce_infills_hurt_blue = new ConVar("ce_infills_hurt_blue", "0 0 255 64", FCVAR_NONE, "Infill for blue players that are not overhealed."); ce_infills_buffed_red = new ConVar("ce_infills_buffed_red", "255 128 128 64", FCVAR_NONE, "Infill for red players that are overhealed."); ce_infills_buffed_blue = new ConVar("ce_infills_buffed_blue", "128 128 255 64", FCVAR_NONE, "Infill for blue players that are overhealed."); ce_infills_debug = new ConVar("ce_infills_debug", "0", FCVAR_NONE); + ce_infills_test = new ConCommand("ce_infills_test", []() { GetModule()->ResetPlayerHurtTimes(); }, "Replay the hurt flicker/fades for all players for testing."); ce_infills_flicker_hertz = new ConVar("ce_infills_flicker_hertz", "10", FCVAR_NONE, "Infill on-hurt flicker frequency.", true, 0, false, 1); ce_infills_flicker_intensity = new ConVar("ce_infills_flicker_intensity", "0.5", FCVAR_NONE, "Infill on-hurt flicker intensity", true, 0, true, 1); @@ -560,6 +562,7 @@ void Graphics::BuildExtraGlowData(CGlowObjectManager* glowMgr) if (infillsEnable) Interfaces::GetEngineTool()->GetWorldToScreenMatrixForView(*m_View, &worldToScreen); + for (int i = 0; i < glowMgr->m_GlowObjectDefinitions.Count(); i++) { auto& current = glowMgr->m_GlowObjectDefinitions[i]; @@ -577,16 +580,18 @@ void Graphics::BuildExtraGlowData(CGlowObjectManager* glowMgr) auto team = player->GetTeam(); if (team == TFTeam::Red || team == TFTeam::Blue) { - float infillOpacityScale = 1; - if (infillsEnable) { + player->UpdateLastHurtTime(); + Vector worldMins, worldMaxs; Vector2D screenMins, screenMaxs; if (Test_PlaneHitboxesIntersect(player->GetBaseAnimating(), screenMins, screenMaxs)) { - currentExtra.m_InfillEnabled = true; + auto& hurtInfill = currentExtra.m_Infills[(size_t)InfillType::Hurt]; + auto& buffedInfill = currentExtra.m_Infills[(size_t)InfillType::Buffed]; + currentExtra.m_StencilIndex = ++stencilIndex; if (currentExtra.m_StencilIndex >= (1 << 6)) @@ -594,87 +599,64 @@ void Graphics::BuildExtraGlowData(CGlowObjectManager* glowMgr) const auto& playerHealth = player->GetHealth(); const auto& playerMaxHealth = player->GetMaxHealth(); - auto healthPercentage = playerHealth / (float)playerMaxHealth; - auto overhealPercentage = RemapValClamped(playerHealth, playerMaxHealth, int(playerMaxHealth * 1.5 / 5) * 5, 0, 1); + const auto healthPercentage = playerHealth / (float)playerMaxHealth; + const auto overhealPercentage = RemapValClamped(playerHealth, playerMaxHealth, int(playerMaxHealth * 1.5 / 5) * 5, 0, 1); if (overhealPercentage <= 0) { - // Infill fading - infillOpacityScale = ApplyInfillTimeEffects(player->GetTimeSinceLastHurt()); - if (healthPercentage != 1) { if (bInfillDebug) - currentExtra.m_HurtInfillRectMin = screenMins; + hurtInfill.m_RectMin = screenMins; else - currentExtra.m_HurtInfillRectMin.Init(); + hurtInfill.m_RectMin.Init(); + + hurtInfill.m_Color = team == TFTeam::Red ? redInfillNormal : blueInfillNormal; + hurtInfill.m_Color.a() *= ApplyInfillTimeEffects(player->GetLastHurtTime()); // Infill fading/flickering - currentExtra.m_HurtInfillRectMax.Init( + hurtInfill.m_RectMax.Init( bInfillDebug ? screenMaxs.x : m_View->width, Lerp(healthPercentage, screenMaxs.y, screenMins.y)); - currentExtra.m_HurtInfillActive = true; + hurtInfill.m_Active = true; } - else - currentExtra.m_HurtInfillActive = false; - - currentExtra.m_BuffedInfillActive = false; } else { - currentExtra.m_HurtInfillActive = false; - currentExtra.m_BuffedInfillActive = true; + buffedInfill.m_Active = true; - currentExtra.m_BuffedInfillRectMax.Init( + buffedInfill.m_RectMax.Init( bInfillDebug ? screenMaxs.x : m_View->width, Lerp(overhealPercentage, screenMins.y, screenMaxs.y)); + hurtInfill.m_Color = team == TFTeam::Red ? redInfillBuffed : blueInfillBuffed; + if (bInfillDebug) - currentExtra.m_BuffedInfillRectMin = screenMins; + buffedInfill.m_RectMin = screenMins; else { - currentExtra.m_BuffedInfillRectMin.Init(); + buffedInfill.m_RectMin.Init(); if (overhealPercentage >= 1) - currentExtra.m_BuffedInfillRectMax.y = m_View->height; + buffedInfill.m_RectMax.y = m_View->height; } - currentExtra.m_HurtInfillRectMin.Init(); - currentExtra.m_HurtInfillRectMax.Init(); + hurtInfill.m_RectMin.Init(); + hurtInfill.m_RectMax.Init(); } } } - if (team == TFTeam::Red) + if (team == TFTeam::Red && hasRedOverride) { - if (hasRedOverride) - { - currentExtra.m_GlowColorOverride = redOverride; - currentExtra.m_ShouldOverrideGlowColor = true; - } - - currentExtra.m_HurtInfillColor = redInfillNormal; - currentExtra.m_BuffedInfillColor = redInfillBuffed; - } - else if (team == TFTeam::Blue) - { - if (hasBlueOverride) - { - currentExtra.m_GlowColorOverride = blueOverride; - currentExtra.m_ShouldOverrideGlowColor = true; - } - - currentExtra.m_HurtInfillColor = blueInfillNormal; - currentExtra.m_BuffedInfillColor = blueInfillBuffed; + currentExtra.m_GlowColorOverride = redOverride; + currentExtra.m_ShouldOverrideGlowColor = true; } - else + else if (team == TFTeam::Blue && hasBlueOverride) { - currentExtra.m_HurtInfillColor = currentExtra.m_BuffedInfillColor = Color(0, 0, 0, 0); + currentExtra.m_GlowColorOverride = blueOverride; + currentExtra.m_ShouldOverrideGlowColor = true; } - - // Apply infill time-based opacity effects - currentExtra.m_HurtInfillColor.a() *= infillOpacityScale; - currentExtra.m_BuffedInfillColor.a() *= infillOpacityScale; } } } @@ -783,13 +765,14 @@ void Graphics::DrawInfills(CMatRenderContextPtr& pRenderContext) { VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); - CRefPtrFix pGlowColorMaterial(materials->FindMaterial("vgui/white", TEXTURE_GROUP_OTHER, true)); + CRefPtrFix infillMaterial(materials->FindMaterial( + ce_infills_additive->GetBool() ? "vgui/white_additive" : "vgui/white", + TEXTURE_GROUP_OTHER, true)); CMeshBuilder meshBuilder; -#define DRAW_INFILL_VGUI 1 +#define DRAW_INFILL_VGUI 0 -#if DRAW_INFILL_VGUI constexpr float pixelOffset = 0.5; pRenderContext->MatrixMode(MATERIAL_PROJECTION); @@ -806,11 +789,10 @@ void Graphics::DrawInfills(CMatRenderContextPtr& pRenderContext) pRenderContext->MatrixMode(MATERIAL_VIEW); pRenderContext->PushMatrix(); pRenderContext->LoadIdentity(); -#endif for (const auto& currentExtra : m_ExtraGlowData) { - if (!currentExtra.m_InfillEnabled) + if (!currentExtra.AnyInfillsActive()) continue; ShaderStencilState_t stencilState; @@ -841,48 +823,47 @@ void Graphics::DrawInfills(CMatRenderContextPtr& pRenderContext) currentExtra.m_BuffedInfillRectMin.x, m_View->height - currentExtra.m_BuffedInfillRectMin.y, currentExtra.m_BuffedInfillRectMax.x, m_View->height - currentExtra.m_BuffedInfillRectMax.y); } -#endif - -#if 0 - auto random = RandomVector(0, 1); - const unsigned char randomColor[4] = - { - RandomInt(0, 255), - RandomInt(0, 255), - RandomInt(0, 255), - 255, - }; - - auto mesh = pRenderContext->GetDynamicMesh(true, nullptr, nullptr, pGlowColorMaterial); +#else + auto mesh = pRenderContext->GetDynamicMesh(true, nullptr, nullptr, infillMaterial); meshBuilder.Begin(mesh, MATERIAL_QUADS, 1); - meshBuilder.Position3f(0, 0, 0); - meshBuilder.Color4ubv(randomColor); - meshBuilder.TexCoord2f(0, ul.m_TexCoord.x, ul.m_TexCoord.y); - meshBuilder.AdvanceVertex(); - - meshBuilder.Position3f(1920, 0, 0); - meshBuilder.Color4ubv(randomColor); - meshBuilder.TexCoord2f(0, lr.m_TexCoord.x, ul.m_TexCoord.y); - meshBuilder.AdvanceVertex(); - - meshBuilder.Position3f(1920, 1080, 0); - meshBuilder.Color4ubv(randomColor); - meshBuilder.TexCoord2f(0, lr.m_TexCoord.x, lr.m_TexCoord.y); - meshBuilder.AdvanceVertex(); + for (size_t i = 0; i < currentExtra.m_Infills.size(); i++) + { + const auto& infill = currentExtra.m_Infills[i]; + if (!infill.m_Active) + continue; - meshBuilder.Position3f(ul.m_Position.x, lr.m_Position.y, 0); - meshBuilder.Color4ubv(randomColor); - meshBuilder.TexCoord2f(0, ul.m_TexCoord.x, lr.m_TexCoord.y); - meshBuilder.AdvanceVertex(); + // Upper left + meshBuilder.Position3f(infill.m_RectMin.x, m_View->height - infill.m_RectMin.y, 0); + meshBuilder.Color4ubv(infill.m_Color.GetRawColorPtr()); + meshBuilder.TexCoord2f(0, 0, 0); + meshBuilder.AdvanceVertex(); + + // Lower left + meshBuilder.Position3f(infill.m_RectMin.x, m_View->height - infill.m_RectMax.y, 0); + meshBuilder.Color4ubv(infill.m_Color.GetRawColorPtr()); + meshBuilder.TexCoord2f(0, 0, 1); + meshBuilder.AdvanceVertex(); + + // Lower right + meshBuilder.Position3f(infill.m_RectMax.x, m_View->height - infill.m_RectMax.y, 0); + meshBuilder.Color4ubv(infill.m_Color.GetRawColorPtr()); + meshBuilder.TexCoord2f(0, 1, 1); + meshBuilder.AdvanceVertex(); + + // Upper right + meshBuilder.Position3f(infill.m_RectMax.x, m_View->height - infill.m_RectMin.y, 0); + meshBuilder.Color4ubv(infill.m_Color.GetRawColorPtr()); + meshBuilder.TexCoord2f(0, 1, 0); + meshBuilder.AdvanceVertex(); + } meshBuilder.End(); mesh->Draw(); #endif } -#if DRAW_INFILL_VGUI pRenderContext->MatrixMode(MATERIAL_PROJECTION); pRenderContext->PopMatrix(); @@ -891,7 +872,12 @@ void Graphics::DrawInfills(CMatRenderContextPtr& pRenderContext) pRenderContext->MatrixMode(MATERIAL_VIEW); pRenderContext->PopMatrix(); -#endif +} + +void Graphics::ResetPlayerHurtTimes() +{ + for (Player* player : Player::Iterable()) + player->ResetLastHurtTime(); } void Graphics::BuildMoveChildLists() @@ -969,7 +955,7 @@ void Graphics::DrawGlowAlways(int nSplitScreenSlot, CMatRenderContextPtr& pRende render->SetColorModulation(vGlowColor.Base()); } - if (current.m_InfillEnabled) + if (current.AnyInfillsActive()) { pRenderContext->SetStencilWriteMask(0xFFFFFFFF); pRenderContext->SetStencilReferenceValue((current.m_StencilIndex << 2) | 1); @@ -1080,7 +1066,7 @@ void Graphics::DrawGlowOccluded(int nSplitScreenSlot, CMatRenderContextPtr& pRen render->SetColorModulation(vGlowColor.Base()); } - if (current.m_InfillEnabled) + if (current.AnyInfillsActive()) { pRenderContext->SetStencilWriteMask(0xFFFFFFFF); pRenderContext->SetStencilReferenceValue((current.m_StencilIndex << 2) | 3); @@ -1123,7 +1109,7 @@ void Graphics::DrawGlowVisible(int nSplitScreenSlot, CMatRenderContextPtr& pRend render->SetColorModulation(vGlowColor.Base()); } - if (current.m_InfillEnabled) + if (current.AnyInfillsActive()) { pRenderContext->SetStencilWriteMask(0xFFFFFFFF); pRenderContext->SetStencilReferenceValue((current.m_StencilIndex << 2) | 1); @@ -1135,39 +1121,6 @@ void Graphics::DrawGlowVisible(int nSplitScreenSlot, CMatRenderContextPtr& pRend } } -void Graphics::CleanupGlowObjectDefinitions(CGlowObjectManager* glowMgr) -{ - // This function is a workaround for an overcomplicated, broken - // linked-list-inside-a-vector hack that is intended to improve performance. - - static constexpr auto END_OF_FREE_LIST = CGlowObjectManager::GlowObjectDefinition_t::END_OF_FREE_LIST; - - // Always add a new entry to the vector in CGlowObjectManager::RegisterGlowObject - //glowMgr->m_nFirstFreeSlot = CGlowObjectManager::GlowObjectDefinition_t::END_OF_FREE_LIST; - - // Remove entries marked as "unused" (UnregisterGlowObject was called on them) from the end - { - int next = END_OF_FREE_LIST; - for (int i = glowMgr->m_GlowObjectDefinitions.Count() - 1; i >= 0; i--) - { - auto& current = glowMgr->m_GlowObjectDefinitions[i]; - - if (!current.IsUnused() && !current.m_hEntity.Get()) - { - PluginWarning("Found NULL entity in glow object list @ %i. Removing.\n", i); - glowMgr->UnregisterGlowObject(i); - } - - if (current.IsUnused()) - { - glowMgr->m_nFirstFreeSlot = i; - current.m_nNextFreeSlot = next; - next = i; - } - } - } -} - void CGlowObjectManager::ApplyEntityGlowEffects(const CViewSetup* pSetup, int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext, float flBloomScale, int x, int y, int w, int h) { VPROF_BUDGET(__FUNCTION__, VPROF_BUDGETGROUP_CE); @@ -1175,8 +1128,6 @@ void CGlowObjectManager::ApplyEntityGlowEffects(const CViewSetup* pSetup, int nS auto const graphicsModule = Graphics::GetModule(); - graphicsModule->CleanupGlowObjectDefinitions(this); - // Optimization: only do all the framebuffer shuffling if there's at least one glow to be drawn bool anyGlowAlways = false; bool anyGlowOccluded = false; @@ -1507,12 +1458,18 @@ void Graphics::OnTick(bool inGame) Graphics::ExtraGlowData::ExtraGlowData(CGlowObjectManager::GlowObjectDefinition_t* base) : m_Base(base) { m_ShouldOverrideGlowColor = false; - m_InfillEnabled = false; // Dumb assert in copy constructor gets triggered when resizing std::vector m_GlowColorOverride.Init(-1, -1, -1); - m_HurtInfillRectMin.Init(-1, -1); - m_HurtInfillRectMax.Init(-1, -1); - m_BuffedInfillRectMin.Init(-1, -1); - m_BuffedInfillRectMax.Init(-1, -1); +} + +bool Graphics::ExtraGlowData::AnyInfillsActive() const +{ + for (const auto& infill : m_Infills) + { + if (infill.m_Active) + return true; + } + + return false; } diff --git a/CastingEssentials/Modules/Graphics.h b/CastingEssentials/Modules/Graphics.h index b649f62..8114883 100644 --- a/CastingEssentials/Modules/Graphics.h +++ b/CastingEssentials/Modules/Graphics.h @@ -6,6 +6,7 @@ #define GLOWS_ENABLE #include +#include #include class C_BaseEntity; @@ -43,7 +44,9 @@ class Graphics final : public Module ConVar* ce_outlines_additive; ConVar* ce_outlines_debug; + ConCommand* ce_infills_test; ConVar* ce_infills_enable; + ConVar* ce_infills_additive; ConVar* ce_infills_debug; ConVar* ce_infills_hurt_red; ConVar* ce_infills_hurt_blue; @@ -78,6 +81,22 @@ class Graphics final : public Module void DrawGlowOccluded(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext) const; void DrawGlowVisible(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext) const; + enum class InfillType + { + Hurt, + Buffed, + + Count + }; + + struct Infill + { + bool m_Active = false; + Color m_Color; + Vector2D m_RectMin = Vector2D(-1, -1); + Vector2D m_RectMax = Vector2D(-1, -1); + }; + friend class CGlowObjectManager; struct ExtraGlowData { @@ -88,18 +107,11 @@ class Graphics final : public Module bool m_ShouldOverrideGlowColor; Vector m_GlowColorOverride; - bool m_InfillEnabled; uint8_t m_StencilIndex; - bool m_HurtInfillActive; - Color m_HurtInfillColor; - Vector2D m_HurtInfillRectMin; - Vector2D m_HurtInfillRectMax; + bool AnyInfillsActive() const; - bool m_BuffedInfillActive; - Color m_BuffedInfillColor; - Vector2D m_BuffedInfillRectMin; - Vector2D m_BuffedInfillRectMax; + std::array m_Infills; // This list is refreshed every frame and only used within a single "entry" // into our glow system, so it's ok to use pointers here rather than EHANDLES @@ -108,9 +120,10 @@ class Graphics final : public Module std::vector m_ExtraGlowData; const CViewSetup* m_View; + void ResetPlayerHurtTimes(); + void BuildMoveChildLists(); ExtraGlowData* FindExtraGlowData(int entindex); - void CleanupGlowObjectDefinitions(CGlowObjectManager* glowMgr); bool WorldToScreenMat(const VMatrix& worldToScreen, const Vector& world, Vector2D& screen); diff --git a/CastingEssentials/PluginBase/CastingPlugin.cpp b/CastingEssentials/PluginBase/CastingPlugin.cpp index 5d3d2e1..c743c1c 100644 --- a/CastingEssentials/PluginBase/CastingPlugin.cpp +++ b/CastingEssentials/PluginBase/CastingPlugin.cpp @@ -30,7 +30,7 @@ #include "Modules/SteamTools.h" #include "Modules/TeamNames.h" -const char* const PLUGIN_VERSION_ID = "r17 beta8"; +const char* const PLUGIN_VERSION_ID = "r17 beta11"; const char* const PLUGIN_FULL_VERSION = strdup(strprintf("%s %s", PLUGIN_NAME, PLUGIN_VERSION_ID).c_str()); class CastingPlugin final : public Plugin diff --git a/CastingEssentials/PluginBase/Player.cpp b/CastingEssentials/PluginBase/Player.cpp index bde211f..daf4f0e 100644 --- a/CastingEssentials/PluginBase/Player.cpp +++ b/CastingEssentials/PluginBase/Player.cpp @@ -13,6 +13,8 @@ #include #include +#undef min + bool Player::s_ClassRetrievalAvailable = false; bool Player::s_ComparisonAvailable = false; bool Player::s_ConditionsRetrievalAvailable = false; @@ -271,14 +273,32 @@ TFClassType Player::GetClass() const return TFClassType::Unknown; } -float Player::GetTimeSinceLastHurt() const +float Player::GetLastHurtTime() const { - const auto maxHealth = GetMaxHealth(); - const auto health = GetHealth(); - return Interfaces::GetEngineTool()->ClientTime() - m_LastHurtTime; } +void Player::ResetLastHurtTime() +{ + m_LastHurtTime = Interfaces::GetEngineTool()->ClientTime(); +} + +void Player::UpdateLastHurtTime() +{ + const auto tick = Interfaces::GetEngineTool()->ClientTick(); + if (tick == m_LastHurtUpdateTick) + return; + + auto health = GetHealth(); + + // Update last hurt time + if (health < m_LastHurtHealth) + m_LastHurtTime = Interfaces::GetEngineTool()->ClientTime(); + + m_LastHurtHealth = health; + m_LastHurtUpdateTick = tick; +} + int Player::GetHealth() const { if (IsValid()) @@ -288,15 +308,7 @@ int Player::GetHealth() const Assert(m_CachedHealth); if (m_CachedHealth) - { - // Update last hurt tick - if (*m_CachedHealth < m_PreviousHealth) - m_LastHurtTime = Interfaces::GetEngineTool()->ClientTime(); - - m_PreviousHealth = *m_CachedHealth; - return *m_CachedHealth; - } } Assert(!"Called " __FUNCTION__ "() on an invalid player!"); @@ -378,9 +390,6 @@ bool Player::CheckCache() const m_CachedPlayerInfoLastUpdateFrame = 0; - m_LastHurtTime = -100; - m_PreviousHealth = 125; - for (auto& wpn : m_CachedWeapons) wpn = nullptr; diff --git a/CastingEssentials/PluginBase/Player.h b/CastingEssentials/PluginBase/Player.h index 96b8977..5f97a66 100644 --- a/CastingEssentials/PluginBase/Player.h +++ b/CastingEssentials/PluginBase/Player.h @@ -40,7 +40,6 @@ class Player final bool CheckCondition(TFCond condition) const; TFClassType GetClass() const; - float GetTimeSinceLastHurt() const; int GetHealth() const; int GetMaxHealth() const; int GetMaxOverheal() const; @@ -66,6 +65,10 @@ class Player final bool IsValid() const; + void UpdateLastHurtTime(); + void ResetLastHurtTime(); + float GetLastHurtTime() const; + private: class Iterator { @@ -117,8 +120,9 @@ class Player final mutable int m_LastValidatedFrame; - mutable int m_LastHurtTime; - mutable int m_PreviousHealth; + int m_LastHurtUpdateTick = -1; + float m_LastHurtTime; + int m_LastHurtHealth; static std::unique_ptr s_Players[ABSOLUTE_PLAYER_LIMIT]; diff --git a/sdk2013 b/sdk2013 index 8455064..6358400 160000 --- a/sdk2013 +++ b/sdk2013 @@ -1 +1 @@ -Subproject commit 84550640ca8e7c3aad42120b70087eeb93cf79f2 +Subproject commit 6358400852653fdfbdfb72dfcdeadbde0b80056a