diff --git a/Build/svencoop/bulletphysics/ConstraintEditDialog.res b/Build/svencoop/bulletphysics/ConstraintEditDialog.res new file mode 100644 index 00000000..28ab9cd9 --- /dev/null +++ b/Build/svencoop/bulletphysics/ConstraintEditDialog.res @@ -0,0 +1,642 @@ +"bulletphysics/ConstraintEditDialog.res" +{ + "ConstraintEditDialog" + { + "ControlName" "Frame" + "fieldName" "ConstraintEditDialog" + "xpos" "20" + "ypos" "20" + "wide" "760" + "tall" "560" + "autoResize" "0" + "pinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "0" + "title" "#BulletPhysics_ConstraintEditor" + } + + // Name Label and TextEntry + "NameLabel" + { + "ControlName" "Label" + "fieldName" "NameLabel" + "xpos" "20" + "ypos" "40" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_Name" + "textAlignment" "west" + } + "Name" + { + "ControlName" "TextEntry" + "fieldName" "Name" + "xpos" "80" + "ypos" "40" + "wide" "180" + "tall" "24" + "tabPosition" "1" + } + + // Debug Draw Level Label and TextEntry + "DebugDrawLevelLabel" + { + "ControlName" "Label" + "fieldName" "DebugDrawLevelLabel" + "xpos" "280" + "ypos" "40" + "wide" "100" + "tall" "24" + "labelText" "#BulletPhysics_DebugDrawLevel" + "textAlignment" "west" + } + "DebugDrawLevel" + { + "ControlName" "TextEntry" + "fieldName" "DebugDrawLevel" + "xpos" "380" + "ypos" "40" + "wide" "60" + "tall" "24" + "tabPosition" "2" + } + + // Type ComboBox + "TypeLabel" + { + "ControlName" "Label" + "fieldName" "TypeLabel" + "xpos" "20" + "ypos" "80" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_Type" + "textAlignment" "west" + } + "Type" + { + "ControlName" "ComboBox" + "fieldName" "Type" + "xpos" "80" + "ypos" "80" + "wide" "180" + "tall" "24" + "tabPosition" "3" + "textHidden" "0" + "editable" "0" + "maxchars" "-1" + } + + "RotOrderLabel" + { + "ControlName" "Label" + "fieldName" "RotOrderLabel" + "xpos" "280" + "ypos" "80" + "wide" "100" + "tall" "24" + "labelText" "#BulletPhysics_RotOrder" + "textAlignment" "west" + } + "RotOrder" + { + "ControlName" "ComboBox" + "fieldName" "RotOrder" + "xpos" "380" + "ypos" "80" + "wide" "60" + "tall" "24" + "tabPosition" "4" + "textHidden" "0" + "editable" "0" + "maxchars" "-1" + } + + // RigidBody A and B ComboBoxes + "RigidBodyALabel" + { + "ControlName" "Label" + "fieldName" "RigidBodyALabel" + "xpos" "20" + "ypos" "120" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_RigidBodyA" + "textAlignment" "west" + } + "RigidBodyA" + { + "ControlName" "ComboBox" + "fieldName" "RigidBodyA" + "xpos" "80" + "ypos" "120" + "wide" "180" + "tall" "24" + "tabPosition" "5" + } + "RigidBodyBLabel" + { + "ControlName" "Label" + "fieldName" "RigidBodyBLabel" + "xpos" "280" + "ypos" "120" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_RigidBodyB" + "textAlignment" "west" + } + "RigidBodyB" + { + "ControlName" "ComboBox" + "fieldName" "RigidBodyB" + "xpos" "340" + "ypos" "120" + "wide" "140" + "tall" "24" + "tabPosition" "6" + } + + // Origin A X, Y, Z TextEntries + "OriginALabel" + { + "ControlName" "Label" + "fieldName" "OriginALabel" + "xpos" "20" + "ypos" "160" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_OriginA" + "textAlignment" "west" + } + "OriginAX" + { + "ControlName" "TextEntry" + "fieldName" "OriginAX" + "xpos" "80" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "7" + } + "OriginAY" + { + "ControlName" "TextEntry" + "fieldName" "OriginAY" + "xpos" "140" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "8" + } + "OriginAZ" + { + "ControlName" "TextEntry" + "fieldName" "OriginAZ" + "xpos" "200" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "9" + } + + // Angles A X, Y, Z TextEntries + "AnglesALabel" + { + "ControlName" "Label" + "fieldName" "AnglesALabel" + "xpos" "20" + "ypos" "200" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_AnglesA" + "textAlignment" "west" + } + "AnglesAX" + { + "ControlName" "TextEntry" + "fieldName" "AnglesAX" + "xpos" "80" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "10" + } + "AnglesAY" + { + "ControlName" "TextEntry" + "fieldName" "AnglesAY" + "xpos" "140" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "11" + } + "AnglesAZ" + { + "ControlName" "TextEntry" + "fieldName" "AnglesAZ" + "xpos" "200" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "12" + } + +// Origin B X, Y, Z TextEntries + "OriginBLabel" + { + "ControlName" "Label" + "fieldName" "OriginBLabel" + "xpos" "280" + "ypos" "160" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_OriginB" + "textAlignment" "west" + } + "OriginBX" + { + "ControlName" "TextEntry" + "fieldName" "OriginBX" + "xpos" "340" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "13" + } + "OriginBY" + { + "ControlName" "TextEntry" + "fieldName" "OriginBY" + "xpos" "400" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "14" + } + "OriginBZ" + { + "ControlName" "TextEntry" + "fieldName" "OriginBZ" + "xpos" "460" + "ypos" "160" + "wide" "50" + "tall" "24" + "tabPosition" "15" + } + + // Angles B X, Y, Z TextEntries + "AnglesBLabel" + { + "ControlName" "Label" + "fieldName" "AnglesBLabel" + "xpos" "280" + "ypos" "200" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_AnglesB" + "textAlignment" "west" + } + "AnglesBX" + { + "ControlName" "TextEntry" + "fieldName" "AnglesBX" + "xpos" "340" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "16" + } + "AnglesBY" + { + "ControlName" "TextEntry" + "fieldName" "AnglesBY" + "xpos" "400" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "17" + } + "AnglesBZ" + { + "ControlName" "TextEntry" + "fieldName" "AnglesBZ" + "xpos" "460" + "ypos" "200" + "wide" "50" + "tall" "24" + "tabPosition" "18" + } + +// MaxTolerantLinearError TextEntries + "MaxTolerantLinearErrorLabel" + { + "ControlName" "Label" + "fieldName" "MaxTolerantLinearErrorLabel" + "xpos" "20" + "ypos" "240" + "wide" "160" + "tall" "24" + "labelText" "#BulletPhysics_MaxTolerantLinearError" + "textAlignment" "west" + } + "MaxTolerantLinearError" + { + "ControlName" "TextEntry" + "fieldName" "MaxTolerantLinearError" + "xpos" "180" + "ypos" "240" + "wide" "60" + "tall" "24" + "tabPosition" "31" + } + + // Forward X, Y, Z TextEntries + "ForwardLabel" + { + "ControlName" "Label" + "fieldName" "ForwardLabel" + "xpos" "280" + "ypos" "240" + "wide" "60" + "tall" "24" + "labelText" "#BulletPhysics_Forward" + "textAlignment" "west" + } + "ForwardX" + { + "ControlName" "TextEntry" + "fieldName" "ForwardX" + "xpos" "340" + "ypos" "240" + "wide" "50" + "tall" "24" + "tabPosition" "32" + } + "ForwardY" + { + "ControlName" "TextEntry" + "fieldName" "ForwardY" + "xpos" "400" + "ypos" "240" + "wide" "50" + "tall" "24" + "tabPosition" "33" + } + "ForwardZ" + { + "ControlName" "TextEntry" + "fieldName" "ForwardZ" + "xpos" "460" + "ypos" "240" + "wide" "50" + "tall" "24" + "tabPosition" "34" + } + +//CheckButton + + "DisableCollision" + { + "ControlName" "CheckButton" + "fieldName" "DisableCollision" + "xpos" "20" + "ypos" "300" // Adjusted from 240 + "wide" "250" + "tall" "24" + "tabPosition" "19" + "labelText" "#BulletPhysics_DisableCollision" + "textAlignment" "west" + } + + "UseGlobalJointFromA" + { + "ControlName" "CheckButton" + "fieldName" "UseGlobalJointFromA" + "xpos" "290" + "ypos" "300" // Adjusted from 240 + "wide" "250" + "tall" "24" + "tabPosition" "20" + "labelText" "#BulletPhysics_UseGlobalJointFromA" + "textAlignment" "west" + } + + "UseLookAtOther" + { + "ControlName" "CheckButton" + "fieldName" "UseLookAtOther" + "xpos" "20" + "ypos" "330" // Adjusted from 270 + "wide" "250" + "tall" "24" + "tabPosition" "21" + "labelText" "#BulletPhysics_UseLookAtOther" + "textAlignment" "west" + } + + "UseGlobalJointOriginFromOther" + { + "ControlName" "CheckButton" + "fieldName" "UseGlobalJointOriginFromOther" + "xpos" "290" + "ypos" "330" // Adjusted from 270 + "wide" "250" + "tall" "24" + "tabPosition" "22" + "labelText" "#BulletPhysics_UseGlobalJointOriginFromOther" + "textAlignment" "west" + } + + "UseRigidBodyDistanceAsLinearLimit" + { + "ControlName" "CheckButton" + "fieldName" "UseRigidBodyDistanceAsLinearLimit" + "xpos" "20" + "ypos" "360" // Adjusted from 300 + "wide" "250" + "tall" "24" + "tabPosition" "23" + "labelText" "#BulletPhysics_UseRigidBodyDistanceAsLinearLimit" + "textAlignment" "west" + } + + "UseLinearReferenceFrameA" + { + "ControlName" "CheckButton" + "fieldName" "UseLinearReferenceFrameA" + "xpos" "290" + "ypos" "360" // Adjusted from 300 + "wide" "250" + "tall" "24" + "tabPosition" "24" + "labelText" "#BulletPhysics_UseLinearReferenceFrameA" + "textAlignment" "west" + } + + "Barnacle" + { + "ControlName" "CheckButton" + "fieldName" "Barnacle" + "xpos" "20" + "ypos" "390" // Adjusted from 330 + "wide" "250" + "tall" "24" + "tabPosition" "25" + "labelText" "#BulletPhysics_Barnacle" + "textAlignment" "west" + } + + "Gargantua" + { + "ControlName" "CheckButton" + "fieldName" "Gargantua" + "xpos" "290" + "ypos" "390" // Adjusted from 330 + "wide" "250" + "tall" "24" + "tabPosition" "26" + "labelText" "#BulletPhysics_Gargantua" + "textAlignment" "west" + } + + "DeactiveOnNormalActivity" + { + "ControlName" "CheckButton" + "fieldName" "DeactiveOnNormalActivity" + "xpos" "20" + "ypos" "420" // Adjusted from 360 + "wide" "250" + "tall" "24" + "tabPosition" "27" + "labelText" "#BulletPhysics_DeactiveOnNormalActivity" + "textAlignment" "west" + } + + "DeactiveOnDeathActivity" + { + "ControlName" "CheckButton" + "fieldName" "DeactiveOnDeathActivity" + "xpos" "290" + "ypos" "420" // Adjusted from 360 + "wide" "250" + "tall" "24" + "tabPosition" "28" + "labelText" "#BulletPhysics_DeactiveOnDeathActivity" + "textAlignment" "west" + } + + "DeactiveOnBarnacleActivity" + { + "ControlName" "CheckButton" + "fieldName" "DeactiveOnBarnacleActivity" + "xpos" "20" + "ypos" "450" // Adjusted from 390 + "wide" "250" + "tall" "24" + "tabPosition" "29" + "labelText" "#BulletPhysics_DeactiveOnBarnacleActivity" + "textAlignment" "west" + } + + "DeactiveOnGargantuaActivity" + { + "ControlName" "CheckButton" + "fieldName" "DeactiveOnGargantuaActivity" + "xpos" "290" + "ypos" "450" // Adjusted from 390 + "wide" "250" + "tall" "24" + "tabPosition" "30" + "labelText" "#BulletPhysics_DeactiveOnGargantuaActivity" + "textAlignment" "west" + } + + "DontResetPoseOnErrorCorrection" + { + "ControlName" "CheckButton" + "fieldName" "DontResetPoseOnErrorCorrection" + "xpos" "20" + "ypos" "480" // Adjusted from 420 + "wide" "250" + "tall" "24" + "tabPosition" "31" + "labelText" "#BulletPhysics_DontResetPoseOnErrorCorrection" + "textAlignment" "west" + } + + "FactorListPanel" + { + "ControlName" "ListPanel" + "fieldName" "FactorListPanel" + "xpos" "520" + "ypos" "40" + "wide" "200" + "tall" "500" + "AutoResize" "3" + "PinCorner" "3" + "visible" "1" + "enabled" "1" + "tabPosition" "0" + "paintbackground" "1" + } + + // OK, Cancel, and Apply Buttons (these entries are unchanged as per your request) + "OK" + { + "ControlName" "Button" + "fieldName" "OK" + "xpos" "180" + "ypos" "520" + "wide" "72" + "tall" "24" + "autoResize" "0" + "pinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "24" + "labelText" "#GameUI_OK" + "textAlignment" "west" + "dulltext" "0" + "command" "OK" + "default" "1" + } + "Cancel" + { + "ControlName" "Button" + "fieldName" "Cancel" + "xpos" "260" + "ypos" "520" + "wide" "72" + "tall" "24" + "autoResize" "0" + "pinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "25" + "labelText" "#GameUI_Cancel" + "textAlignment" "west" + "dulltext" "0" + "command" "Close" + "default" "0" + } + "Apply" + { + "ControlName" "Button" + "fieldName" "Apply" + "xpos" "340" + "ypos" "520" + "wide" "72" + "tall" "24" + "autoResize" "0" + "pinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "26" + "labelText" "#GameUI_Apply" + "textAlignment" "west" + "dulltext" "0" + "command" "Apply" + } +} \ No newline at end of file diff --git a/Build/svencoop/bulletphysics/ConstraintPage.res b/Build/svencoop/bulletphysics/ConstraintPage.res new file mode 100644 index 00000000..fa3fe6c4 --- /dev/null +++ b/Build/svencoop/bulletphysics/ConstraintPage.res @@ -0,0 +1,90 @@ +"bulletphysics/ConstraintPage.res" +{ + "ConstraintPage" + { + "ControlName" "PropertyPage" + "fieldName" "ConstraintPage" + "xpos" "0" + "ypos" "28" + "wide" "624" + "tall" "278" + "AutoResize" "0" + "PinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "0" + "paintbackground" "1" + } + "ConstraintListPanel" + { + "ControlName" "ListPanel" + "fieldName" "ConstraintListPanel" + "xpos" "0" + "ypos" "8" + "wide" "624" + "tall" "226" + "AutoResize" "3" + "PinCorner" "0" + "visible" "1" + "enabled" "1" + "tabPosition" "0" + "paintbackground" "1" + } + "ShiftUpConstraint" + { + "ControlName" "Button" + "fieldName" "ShiftUpConstraint" + "xpos" "240" + "ypos" "244" + "wide" "120" + "tall" "24" + "AutoResize" "0" + "PinCorner" "3" + "visible" "1" + "enabled" "1" + "tabPosition" "1" + "paintbackground" "1" + "labelText" "#BulletPhysics_ShiftUp" + "textAlignment" "west" + "wrap" "0" + "command" "ShiftUpConstraint" + } + "ShiftDownConstraint" + { + "ControlName" "Button" + "fieldName" "ShiftDownConstraint" + "xpos" "360" + "ypos" "244" + "wide" "120" + "tall" "24" + "AutoResize" "0" + "PinCorner" "3" + "visible" "1" + "enabled" "1" + "tabPosition" "1" + "paintbackground" "1" + "labelText" "#BulletPhysics_ShiftDown" + "textAlignment" "west" + "wrap" "0" + "command" "ShiftDownConstraint" + } + "CreateConstraint" + { + "ControlName" "Button" + "fieldName" "CreateConstraint" + "xpos" "480" + "ypos" "244" + "wide" "120" + "tall" "24" + "AutoResize" "0" + "PinCorner" "3" + "visible" "1" + "enabled" "1" + "tabPosition" "1" + "paintbackground" "1" + "labelText" "#BulletPhysics_CreateConstraint" + "textAlignment" "west" + "wrap" "0" + "command" "CreateConstraint" + } +} \ No newline at end of file diff --git a/Build/svencoop/bulletphysics/bulletphysics_english.txt b/Build/svencoop/bulletphysics/bulletphysics_english.txt index 7aea7af8..3ab926ce 100644 Binary files a/Build/svencoop/bulletphysics/bulletphysics_english.txt and b/Build/svencoop/bulletphysics/bulletphysics_english.txt differ diff --git a/Build/svencoop/bulletphysics/bulletphysics_schinese.txt b/Build/svencoop/bulletphysics/bulletphysics_schinese.txt index 13461054..656c1cea 100644 Binary files a/Build/svencoop/bulletphysics/bulletphysics_schinese.txt and b/Build/svencoop/bulletphysics/bulletphysics_schinese.txt differ diff --git a/Plugins/BulletPhysics/BaseDynamicObject.h b/Plugins/BulletPhysics/BaseDynamicObject.h index 737fdf7a..228942c7 100644 --- a/Plugins/BulletPhysics/BaseDynamicObject.h +++ b/Plugins/BulletPhysics/BaseDynamicObject.h @@ -330,12 +330,12 @@ class CBaseDynamicObject : public IDynamicObject public: - IPhysicRigidBody* FindRigidBodyByName(const std::string& name, bool allowNonNativeRigidBody) + virtual IPhysicRigidBody* FindRigidBodyByName(const std::string& name, bool allowNonNativeRigidBody) { return GetRigidBodyByName(name); } - void CreateRigidBodies(const CDynamicObjectCreationParameter& CreationParam) + virtual void CreateRigidBodies(const CDynamicObjectCreationParameter& CreationParam) { for (const auto& pRigidBodyConfig : CreationParam.m_pDynamicObjectConfig->RigidBodyConfigs) { @@ -343,20 +343,12 @@ class CBaseDynamicObject : public IDynamicObject if (pRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); - - CPhysicObjectUpdateContext ObjectUpdateContext; - - CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); - - pRigidBody->Update(&ComponentUpdateContext); - - m_RigidBodies.emplace_back(pRigidBody); + AddRigidBody(pRigidBody); } } } - void CreateConstraints(const CDynamicObjectCreationParameter& CreationParam) + virtual void CreateConstraints(const CDynamicObjectCreationParameter& CreationParam) { for (const auto& pConstraintConfig : CreationParam.m_pDynamicObjectConfig->ConstraintConfigs) { @@ -364,9 +356,7 @@ class CBaseDynamicObject : public IDynamicObject if (pConstraint) { - ClientPhysicManager()->AddPhysicComponent(pConstraint->GetPhysicComponentId(), pConstraint); - - m_Constraints.emplace_back(pConstraint); + AddConstraint(pConstraint); } } } @@ -376,6 +366,32 @@ class CBaseDynamicObject : public IDynamicObject protected: + void AddRigidBody(IPhysicRigidBody* pRigidBody) + { + ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); + + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pRigidBody->Update(&ComponentUpdateContext); + + m_RigidBodies.emplace_back(pRigidBody); + } + + void AddConstraint(IPhysicConstraint* pConstraint) + { + ClientPhysicManager()->AddPhysicComponent(pConstraint->GetPhysicComponentId(), pConstraint); + + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pConstraint->Update(&ComponentUpdateContext); + + m_Constraints.emplace_back(pConstraint); + } + void RebuildRigidBodies(const CDynamicObjectCreationParameter& CreationParam) { std::map configIdToComponentIdMap; @@ -401,9 +417,7 @@ class CBaseDynamicObject : public IDynamicObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); - - m_RigidBodies.emplace_back(pNewRigidBody); + AddRigidBody(pNewRigidBody); } } else @@ -412,9 +426,7 @@ class CBaseDynamicObject : public IDynamicObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); - - m_RigidBodies.emplace_back(pNewRigidBody); + AddRigidBody(pNewRigidBody); } } } @@ -430,6 +442,7 @@ class CBaseDynamicObject : public IDynamicObject ClientPhysicManager()->RemovePhysicComponent(pConstraint->GetPhysicComponentId()); } + m_Constraints.clear(); for (const auto& pConstraintConfig : CreationParam.m_pDynamicObjectConfig->ConstraintConfigs) @@ -444,9 +457,7 @@ class CBaseDynamicObject : public IDynamicObject if (pNewConstraint) { - ClientPhysicManager()->AddPhysicComponent(pNewConstraint->GetPhysicComponentId(), pNewConstraint); - - m_Constraints.emplace_back(pNewConstraint); + AddConstraint(pNewConstraint); } } else @@ -455,9 +466,7 @@ class CBaseDynamicObject : public IDynamicObject if (pNewConstraint) { - ClientPhysicManager()->AddPhysicComponent(pNewConstraint->GetPhysicComponentId(), pNewConstraint); - - m_Constraints.emplace_back(pNewConstraint); + AddConstraint(pNewConstraint); } } } diff --git a/Plugins/BulletPhysics/BasePhysicManager.cpp b/Plugins/BulletPhysics/BasePhysicManager.cpp index d4e07ed7..f6d29373 100644 --- a/Plugins/BulletPhysics/BasePhysicManager.cpp +++ b/Plugins/BulletPhysics/BasePhysicManager.cpp @@ -26,6 +26,55 @@ IClientPhysicManager* ClientPhysicManager() return g_pClientPhysicManager; } +StudioAnimActivityType StudioGetSequenceActivityType(model_t* mod, entity_state_t* entstate) +{ + //if (g_bIsSvenCoop) + //{ + // if (entstate->scale != 0 && entstate->scale != 1.0f) + // return StudioAnimActivityType_Idle; + //} + + if (mod->type != mod_studio) + return StudioAnimActivityType_Idle; + + auto studiohdr = (studiohdr_t*)IEngineStudio.Mod_Extradata(mod); + + if (!studiohdr) + return StudioAnimActivityType_Idle; + + int sequence = entstate->sequence; + if (sequence < 0 || sequence >= studiohdr->numseq) + return StudioAnimActivityType_Idle; + + 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_DIE_HEADSHOT || + pseqdesc->activity == ACT_DIE_CHESTSHOT || + pseqdesc->activity == ACT_DIE_GUTSHOT || + pseqdesc->activity == ACT_DIE_BACKSHOT + ) + { + return StudioAnimActivityType_Death; + } + + if ( + pseqdesc->activity == ACT_BARNACLE_HIT || + pseqdesc->activity == ACT_BARNACLE_PULL || + pseqdesc->activity == ACT_BARNACLE_CHOMP || + pseqdesc->activity == ACT_BARNACLE_CHEW + ) + { + return StudioAnimActivityType_Barnacle; + } + + return StudioAnimActivityType_Idle; +} + bool CheckPhysicComponentFilters(IPhysicComponent* pPhysicComponent, const CPhysicComponentFilters& filters) { if (pPhysicComponent->IsRigidBody()) @@ -624,8 +673,8 @@ static void LoadRigidBodiesFromKeyValues(KeyValues* pKeyValues, int allowedRigid pRigidBodyConfig->mass = pRigidBodySubKey->GetFloat("mass", BULLET_DEFAULT_MASS); pRigidBodyConfig->density = pRigidBodySubKey->GetFloat("density", BULLET_DEFAULT_DENSENTY); - pRigidBodyConfig->linearFriction = pRigidBodySubKey->GetFloat("linearFriction", BULLET_DEFAULT_LINEAR_FIRCTION); - pRigidBodyConfig->rollingFriction = pRigidBodySubKey->GetFloat("rollingFriction", BULLET_DEFAULT_ANGULAR_FIRCTION); + pRigidBodyConfig->linearFriction = pRigidBodySubKey->GetFloat("linearFriction", BULLET_DEFAULT_LINEAR_FRICTION); + pRigidBodyConfig->rollingFriction = pRigidBodySubKey->GetFloat("rollingFriction", BULLET_DEFAULT_ANGULAR_FRICTION); pRigidBodyConfig->restitution = pRigidBodySubKey->GetFloat("restitution", BULLET_DEFAULT_RESTITUTION); pRigidBodyConfig->ccdRadius = pRigidBodySubKey->GetFloat("ccdRadius", 0); pRigidBodyConfig->ccdThreshold = pRigidBodySubKey->GetFloat("ccdThreshold", BULLET_DEFAULT_CCD_THRESHOLD); @@ -725,6 +774,9 @@ static void LoadConstraintsFromKeyValues(KeyValues* pKeyValues, std::vectorGetBool("deactiveOnGargantuaActivity")) pConstraintConfig->flags |= PhysicConstraintFlag_DeactiveOnGargantuaActivity; + if (pConstraintSubKey->GetBool("dontResetPoseOnErrorCorrection")) + pConstraintConfig->flags |= PhysicConstraintFlag_DontResetPoseOnErrorCorrection; + pConstraintConfig->debugDrawLevel = pConstraintSubKey->GetInt("debugDrawLevel", BULLET_DEFAULT_DEBUG_DRAW_LEVEL); pConstraintConfig->disableCollision = pConstraintSubKey->GetBool("disableCollision", true); pConstraintConfig->useGlobalJointFromA = pConstraintSubKey->GetBool("useGlobalJointFromA", true); @@ -891,7 +943,7 @@ static void LoadConstraintsFromKeyValues(KeyValues* pKeyValues, std::vector& AnimControlConfigs) +static void LoadAnimControlsFromKeyValues(KeyValues* pKeyValues, std::vector>& AnimControlConfigs) { auto pAnimControlsKey = pKeyValues->FindKey("animControls"); @@ -899,15 +951,16 @@ static void LoadAnimControlsFromKeyValues(KeyValues* pKeyValues, std::vectorGetFirstSubKey(); pAnimControlSubKey; pAnimControlSubKey = pAnimControlSubKey->GetNextKey()) { - CClientAnimControlConfig AnimControlConfig; + auto pAnimControlConfig = std::make_shared(); - AnimControlConfig.sequence = pAnimControlSubKey->GetInt("sequence"); - AnimControlConfig.gaitsequence = pAnimControlSubKey->GetInt("gaitsequence"); - AnimControlConfig.frame = pAnimControlSubKey->GetFloat("frame"); - AnimControlConfig.activity = pAnimControlSubKey->GetInt("activity"); - AnimControlConfig.idle = pAnimControlSubKey->GetBool("idle"); + pAnimControlConfig->sequence = pAnimControlSubKey->GetInt("sequence"); + pAnimControlConfig->gaitsequence = pAnimControlSubKey->GetInt("gaitsequence"); + pAnimControlConfig->frame = pAnimControlSubKey->GetFloat("frame"); + pAnimControlConfig->activity = (decltype(pAnimControlConfig->activity))pAnimControlSubKey->GetInt("activity"); + + ClientPhysicManager()->AddPhysicConfig(pAnimControlConfig->configId, pAnimControlConfig); - AnimControlConfigs.emplace_back(AnimControlConfig); + AnimControlConfigs.emplace_back(pAnimControlConfig); } } } @@ -1301,6 +1354,9 @@ static void AddConstraintsToKeyValues(KeyValues* pKeyValues, const std::vectorflags & PhysicConstraintFlag_DeactiveOnGargantuaActivity) pConstraintSubKey->SetBool("deactiveOnGargantuaActivity", true); + if (pConstraintConfig->flags & PhysicConstraintFlag_DontResetPoseOnErrorCorrection) + pConstraintSubKey->SetBool("dontResetPoseOnErrorCorrection", true); + pConstraintSubKey->SetString("type", UTIL_GetConstraintTypeName(pConstraintConfig->type)); pConstraintSubKey->SetString("rigidbodyA", pConstraintConfig->rigidbodyA.c_str()); @@ -1579,7 +1635,7 @@ static void AddPhysicActionsToKeyValues(KeyValues* pKeyValues, const std::vector } } -static void AddAnimControlToKeyValues(KeyValues* pKeyValues, const std::vector& AnimControlConfigs) +static void AddAnimControlToKeyValues(KeyValues* pKeyValues, const std::vector>& AnimControlConfigs) { if (AnimControlConfigs.size() > 0) { @@ -1593,11 +1649,10 @@ static void AddAnimControlToKeyValues(KeyValues* pKeyValues, const std::vectorSetInt("sequence", AnimControl.sequence); - pAnimControlSubKey->SetInt("gaitsequence", AnimControl.gaitsequence); - pAnimControlSubKey->SetFloat("frame", AnimControl.frame); - pAnimControlSubKey->SetInt("activity", AnimControl.activity); - pAnimControlSubKey->SetBool("idle", AnimControl.idle); + pAnimControlSubKey->SetInt("sequence", AnimControl->sequence); + pAnimControlSubKey->SetInt("gaitsequence", AnimControl->gaitsequence); + pAnimControlSubKey->SetFloat("frame", AnimControl->frame); + pAnimControlSubKey->SetInt("activity", AnimControl->activity); } } } @@ -1727,12 +1782,15 @@ static bool ParseLegacyDeathAnimLine(CClientRagdollObjectConfig* pRagdollConfig, int sequence; float frame; if (iss >> sequence >> frame) { - CClientAnimControlConfig animConfig; - animConfig.sequence = sequence; - animConfig.frame = frame; - animConfig.activity = 1; + auto pAnimControlConfig = std::make_shared(); + + pAnimControlConfig->sequence = sequence; + pAnimControlConfig->frame = frame; + pAnimControlConfig->activity = StudioAnimActivityType_Death; + + ClientPhysicManager()->AddPhysicConfig(pAnimControlConfig->configId, pAnimControlConfig); - pRagdollConfig->AnimControlConfigs.push_back(animConfig); + pRagdollConfig->AnimControlConfigs.emplace_back(pAnimControlConfig); return true; } gEngfuncs.Con_DPrintf("ParseLegacyDeathAnimLine: failed to parse line \"%s\"", line.c_str()); @@ -2006,6 +2064,7 @@ static bool ParseLegacyBarnacleLine(CClientRagdollObjectConfig* pRagdollConfig, pActionConfig->constraint = std::format("BarnacleConstraint|@barnacle.Body|{0}", rigidbody); pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentExtraHeight] = factor1; pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentInterval] = factor2; + pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentAxis] = -1; pRagdollConfig->BarnacleControlConfig.ActionConfigs.emplace_back(pActionConfig); @@ -2634,7 +2693,7 @@ void CBasePhysicManager::SetupBonesForRagdoll(cl_entity_t* ent, entity_state_t* (*currententity) = saved_currententity; } -void CBasePhysicManager::SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t *state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig &OverrideAnim) +void CBasePhysicManager::SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t *state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig *pOverrideAnimControl) { auto saved_currententity = (*currententity); (*currententity) = ent; @@ -2645,9 +2704,20 @@ void CBasePhysicManager::SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t fakePlayerState.number = playerindex; fakePlayerState.weaponmodel = 0; - fakePlayerState.sequence = OverrideAnim.sequence; - fakePlayerState.gaitsequence = OverrideAnim.gaitsequence; - fakePlayerState.frame = OverrideAnim.frame; + fakePlayerState.sequence = pOverrideAnimControl->sequence; + fakePlayerState.gaitsequence = pOverrideAnimControl->gaitsequence; + fakePlayerState.frame = pOverrideAnimControl->frame; + +#define COPY_BYTE_ENTSTATE(attr, to, i) if (pOverrideAnimControl->attr[i] >= 0 && pOverrideAnimControl->attr[i] <= 255) to.attr[i] = pOverrideAnimControl->attr[i]; + COPY_BYTE_ENTSTATE(controller, fakePlayerState, 0); + COPY_BYTE_ENTSTATE(controller, fakePlayerState, 1); + COPY_BYTE_ENTSTATE(controller, fakePlayerState, 2); + COPY_BYTE_ENTSTATE(controller, fakePlayerState, 3); + COPY_BYTE_ENTSTATE(blending, fakePlayerState, 0); + COPY_BYTE_ENTSTATE(blending, fakePlayerState, 1); + COPY_BYTE_ENTSTATE(blending, fakePlayerState, 2); + COPY_BYTE_ENTSTATE(blending, fakePlayerState, 3); +#undef COPY_BYTE_ENTSTATE vec3_t vecSavedOrigin, vecSavedAngles; VectorCopy((*currententity)->origin, vecSavedOrigin); @@ -2672,12 +2742,27 @@ void CBasePhysicManager::SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t int iSavedSequence = ent->curstate.sequence; int iSavedGaitSequence = ent->curstate.gaitsequence; float flSavedFrame = ent->curstate.frame; + byte ubController[4]; + byte ubBlending[4]; - ent->curstate.weaponmodel = 0; - ent->curstate.sequence = OverrideAnim.sequence; - ent->curstate.gaitsequence = OverrideAnim.gaitsequence; - ent->curstate.frame = OverrideAnim.frame; + memcpy(ubController, ent->curstate.controller, sizeof(ubController)); + memcpy(ubBlending, ent->curstate.blending, sizeof(ubBlending)); + ent->curstate.weaponmodel = 0; + ent->curstate.sequence = pOverrideAnimControl->sequence; + ent->curstate.gaitsequence = pOverrideAnimControl->gaitsequence; + ent->curstate.frame = pOverrideAnimControl->frame; + +#define COPY_BYTE_ENTSTATE(attr, to, i) if (pOverrideAnimControl->attr[i] >= 0 && pOverrideAnimControl->attr[i] <= 255) to.attr[i] = pOverrideAnimControl->attr[i]; + COPY_BYTE_ENTSTATE(controller, ent->curstate, 0); + COPY_BYTE_ENTSTATE(controller, ent->curstate, 1); + COPY_BYTE_ENTSTATE(controller, ent->curstate, 2); + COPY_BYTE_ENTSTATE(controller, ent->curstate, 3); + COPY_BYTE_ENTSTATE(blending, ent->curstate, 0); + COPY_BYTE_ENTSTATE(blending, ent->curstate, 1); + COPY_BYTE_ENTSTATE(blending, ent->curstate, 2); + COPY_BYTE_ENTSTATE(blending, ent->curstate, 3); +#undef COPY_BYTE_ENTSTATE (*gpStudioInterface)->StudioDrawModel(STUDIO_RAGDOLL_SETUP_BONES); ent->curstate.weaponmodel = 0; diff --git a/Plugins/BulletPhysics/BasePhysicManager.h b/Plugins/BulletPhysics/BasePhysicManager.h index 27464e7f..78952c55 100644 --- a/Plugins/BulletPhysics/BasePhysicManager.h +++ b/Plugins/BulletPhysics/BasePhysicManager.h @@ -293,7 +293,7 @@ class CBasePhysicManager : public IClientPhysicManager void CreatePhysicObjectForEntity(cl_entity_t* ent, entity_state_t* state, model_t *mod) override; void SetupBonesForRagdoll(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex) override; - void SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig& OverrideAnim) override; + void SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig* pOverrideAnimControl) override; void UpdateBonesForRagdoll(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex) override; IPhysicObject* FindBarnacleObjectForPlayer(entity_state_t* state) override; diff --git a/Plugins/BulletPhysics/BaseRagdollObject.h b/Plugins/BulletPhysics/BaseRagdollObject.h index 8a9589cc..e119df9c 100644 --- a/Plugins/BulletPhysics/BaseRagdollObject.h +++ b/Plugins/BulletPhysics/BaseRagdollObject.h @@ -96,7 +96,7 @@ class CBaseRagdollObject : public IRagdollObject bool IsClientEntityNonSolid() const override { - if (GetActivityType() > 0) + if (GetActivityType() > StudioAnimActivityType_Idle) return false; return GetClientEntityState()->solid <= SOLID_TRIGGER ? true : false; @@ -166,27 +166,60 @@ class CBaseRagdollObject : public IRagdollObject if (CreationParam.m_model->type == mod_studio) { - ClientPhysicManager()->SetupBonesForRagdollEx(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex, m_IdleAnimConfig); + if (m_IdleAnimConfig) + { + ClientPhysicManager()->SetupBonesForRagdollEx(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex, m_IdleAnimConfig.get()); + } + else + { + ClientPhysicManager()->SetupBonesForRagdoll(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex); + } } CPhysicComponentFilters filters; ClientPhysicManager()->RemovePhysicComponentsFromWorld(this, filters); + m_keyBones.clear(); + m_nonKeyBones.clear(); + + SaveBoneRelativeTransform(CreationParam); + RebuildRigidBodies(CreationParam); RebuildConstraints(CreationParam); + SetupNonKeyBones(CreationParam); + return true; } void Update(CPhysicObjectUpdateContext* ObjectUpdateContext) override { - auto playerState = R_GetPlayerState(m_playerindex); + auto playerState = GetClientEntityState(); + + if (m_bDebugAnimEnabled && m_DebugAnimConfig) + { + playerState->sequence = m_DebugAnimConfig->sequence; + playerState->gaitsequence = m_DebugAnimConfig->gaitsequence; + playerState->frame = m_DebugAnimConfig->frame; + playerState->framerate = 0; - int iOldActivityType = GetActivityType(); +#define COPY_BYTE_ENTSTATE(attr, to, i) if (m_DebugAnimConfig->attr[i] >= 0 && m_DebugAnimConfig->attr[i] <= 255) to->attr[i] = m_DebugAnimConfig->attr[i]; + COPY_BYTE_ENTSTATE(controller, playerState, 0); + COPY_BYTE_ENTSTATE(controller, playerState, 1); + COPY_BYTE_ENTSTATE(controller, playerState, 2); + COPY_BYTE_ENTSTATE(controller, playerState, 3); + COPY_BYTE_ENTSTATE(blending, playerState, 0); + COPY_BYTE_ENTSTATE(blending, playerState, 1); + COPY_BYTE_ENTSTATE(blending, playerState, 2); + COPY_BYTE_ENTSTATE(blending, playerState, 3); +#undef COPY_BYTE_ENTSTATE + } + + auto iOldActivityType = GetActivityType(); - int iNewActivityType = StudioGetSequenceActivityType(m_model, playerState); + auto iNewActivityType = StudioGetSequenceActivityType(m_model, playerState); if (iNewActivityType == 0) { @@ -296,7 +329,7 @@ class CBaseRagdollObject : public IRagdollObject bool CalcRefDef(struct ref_params_s* pparams, bool bIsThirdPerson, void(*callback)(struct ref_params_s* pparams)) override { - if (GetActivityType() != 0) + if (GetActivityType() != StudioAnimActivityType_Idle) { if (bIsThirdPerson) { @@ -325,7 +358,7 @@ class CBaseRagdollObject : public IRagdollObject bool SetupBones(studiohdr_t* studiohdr) override { - if (GetActivityType() == 0) + if (GetActivityType() == StudioAnimActivityType_Idle) return false; for (auto pRigidBody : m_RigidBodies) @@ -413,6 +446,12 @@ class CBaseRagdollObject : public IRagdollObject { ClientPhysicManager()->AddPhysicComponent(pConstraint->GetPhysicComponentId(), pConstraint); + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pConstraint->Update(&ComponentUpdateContext); + m_Constraints.emplace_back(pConstraint); } } @@ -455,19 +494,31 @@ class CBaseRagdollObject : public IRagdollObject //TODO } - int GetOverrideActivityType(entity_state_t* entstate) override + StudioAnimActivityType GetOverrideActivityType(entity_state_t* entstate) override { for (const auto& AnimControlConfig : m_AnimControlConfigs) { - if (entstate->sequence == AnimControlConfig.sequence) + if (AnimControlConfig->gaitsequence == 0) { - return AnimControlConfig.activity; + if (entstate->sequence == AnimControlConfig->sequence) + { + return AnimControlConfig->activity; + } + } + else + { + if (entstate->sequence == AnimControlConfig->sequence && + entstate->gaitsequence == AnimControlConfig->gaitsequence) + { + return AnimControlConfig->activity; + } } } - return 0; + + return StudioAnimActivityType_Idle; } - int GetActivityType() const override + StudioAnimActivityType GetActivityType() const override { return m_iActivityType; } @@ -482,6 +533,16 @@ class CBaseRagdollObject : public IRagdollObject return m_iGargantuaIndex; } + bool IsDebugAnimEnabled() const override + { + return m_bDebugAnimEnabled; + } + + void SetDebugAnimEnabled(bool bEnabled) override + { + m_bDebugAnimEnabled = bEnabled; + } + void AddPhysicComponentsToPhysicWorld(void* world, const CPhysicComponentFilters& filters) override { for (auto pRigidBody : m_RigidBodies) @@ -634,7 +695,7 @@ class CBaseRagdollObject : public IRagdollObject return nullptr; } - void CreateRigidBodies(const CRagdollObjectCreationParameter& CreationParam) + virtual void CreateRigidBodies(const CRagdollObjectCreationParameter& CreationParam) { for (const auto& pRigidBodyConfig : CreationParam.m_pRagdollObjectConfig->RigidBodyConfigs) { @@ -642,15 +703,7 @@ class CBaseRagdollObject : public IRagdollObject if (pRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); - - CPhysicObjectUpdateContext ObjectUpdateContext; - - CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); - - pRigidBody->Update(&ComponentUpdateContext); - - m_RigidBodies.emplace_back(pRigidBody); + AddRigidBody(pRigidBody); if (CreationParam.m_studiohdr && pRigidBodyConfig->boneindex >= 0 && @@ -662,7 +715,7 @@ class CBaseRagdollObject : public IRagdollObject } } - void CreateConstraints(const CRagdollObjectCreationParameter& CreationParam) + virtual void CreateConstraints(const CRagdollObjectCreationParameter& CreationParam) { for (const auto& pConstraintConfig : CreationParam.m_pRagdollObjectConfig->ConstraintConfigs) { @@ -670,14 +723,12 @@ class CBaseRagdollObject : public IRagdollObject if (pConstraint) { - ClientPhysicManager()->AddPhysicComponent(pConstraint->GetPhysicComponentId(), pConstraint); - - m_Constraints.emplace_back(pConstraint); + AddConstraint(pConstraint); } } } - void CreateFloaters(const CRagdollObjectCreationParameter& CreationParam) + virtual void CreateFloaters(const CRagdollObjectCreationParameter& CreationParam) { for (const auto& pFloaterConfig : CreationParam.m_pRagdollObjectConfig->FloaterConfigs) { @@ -685,7 +736,7 @@ class CBaseRagdollObject : public IRagdollObject } } - IPhysicRigidBody* FindRigidBodyByName(const std::string& name, bool allowNonNativeRigidBody) + virtual IPhysicRigidBody* FindRigidBodyByName(const std::string& name, bool allowNonNativeRigidBody) { if (allowNonNativeRigidBody) { @@ -720,12 +771,66 @@ class CBaseRagdollObject : public IRagdollObject return GetRigidBodyByName(name); } + virtual void SetupNonKeyBones(const CRagdollObjectCreationParameter& CreationParam) + { + if (CreationParam.m_studiohdr) + { + for (int i = 0; i < CreationParam.m_studiohdr->numbones; ++i) + { + if (std::find(m_keyBones.begin(), m_keyBones.end(), i) == m_keyBones.end()) + m_nonKeyBones.emplace_back(i); + } + } + } + + virtual void InitCameraControl(const CClientCameraControlConfig* pCameraControlConfig, CPhysicCameraControl& CameraControl) + { + CameraControl = (*pCameraControlConfig); + + auto pRigidBody = GetRigidBodyByName(pCameraControlConfig->rigidbody); + + if (pRigidBody) + { + CameraControl.m_physicComponentId = pRigidBody->GetPhysicComponentId(); + } + } + + virtual void SaveBoneRelativeTransform(const CRagdollObjectCreationParameter& CreationParam) { + + } + virtual IPhysicRigidBody* CreateRigidBody(const CRagdollObjectCreationParameter& CreationParam, CClientRigidBodyConfig* pRigidConfig, int physicComponentId) = 0; virtual IPhysicConstraint* CreateConstraint(const CRagdollObjectCreationParameter& CreationParam, CClientConstraintConfig* pConstraintConfig, int physicComponentId) = 0; virtual void CreateFloater(const CRagdollObjectCreationParameter& CreationParam, const CClientFloaterConfig* pConfig) = 0; virtual IPhysicAction* CreateActionFromConfig(CClientPhysicActionConfig* pActionConfig) = 0; -private: +protected: + + void AddRigidBody(IPhysicRigidBody* pRigidBody) + { + ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); + + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pRigidBody->Update(&ComponentUpdateContext); + + m_RigidBodies.emplace_back(pRigidBody); + } + + void AddConstraint(IPhysicConstraint* pConstraint) + { + ClientPhysicManager()->AddPhysicComponent(pConstraint->GetPhysicComponentId(), pConstraint); + + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pConstraint->Update(&ComponentUpdateContext); + + m_Constraints.emplace_back(pConstraint); + } void RebuildRigidBodies(const CRagdollObjectCreationParameter& CreationParam) { @@ -752,9 +857,14 @@ class CBaseRagdollObject : public IRagdollObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); + AddRigidBody(pNewRigidBody); - m_RigidBodies.emplace_back(pNewRigidBody); + if (CreationParam.m_studiohdr && + pRigidBodyConfig->boneindex >= 0 && + pRigidBodyConfig->boneindex < CreationParam.m_studiohdr->numbones) + { + m_keyBones.emplace_back(pRigidBodyConfig->boneindex); + } } } else @@ -763,9 +873,14 @@ class CBaseRagdollObject : public IRagdollObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); + AddRigidBody(pNewRigidBody); - m_RigidBodies.emplace_back(pNewRigidBody); + if (CreationParam.m_studiohdr && + pRigidBodyConfig->boneindex >= 0 && + pRigidBodyConfig->boneindex < CreationParam.m_studiohdr->numbones) + { + m_keyBones.emplace_back(pRigidBodyConfig->boneindex); + } } } } @@ -781,6 +896,7 @@ class CBaseRagdollObject : public IRagdollObject ClientPhysicManager()->RemovePhysicComponent(pConstraint->GetPhysicComponentId()); } + m_Constraints.clear(); for (const auto& pConstraintConfig : CreationParam.m_pRagdollObjectConfig->ConstraintConfigs) @@ -795,9 +911,7 @@ class CBaseRagdollObject : public IRagdollObject if (pNewConstraint) { - ClientPhysicManager()->AddPhysicComponent(pNewConstraint->GetPhysicComponentId(), pNewConstraint); - - m_Constraints.emplace_back(pNewConstraint); + AddConstraint(pNewConstraint); } } else @@ -806,15 +920,13 @@ class CBaseRagdollObject : public IRagdollObject if (pNewConstraint) { - ClientPhysicManager()->AddPhysicComponent(pNewConstraint->GetPhysicComponentId(), pNewConstraint); - - m_Constraints.emplace_back(pNewConstraint); + AddConstraint(pNewConstraint); } } } } - bool UpdateActivity(int iOldActivityType, int iNewActivityType, entity_state_t* curstate) + bool UpdateActivity(StudioAnimActivityType iOldActivityType, StudioAnimActivityType iNewActivityType, entity_state_t* curstate) { if (iOldActivityType == iNewActivityType) return false; @@ -822,9 +934,9 @@ class CBaseRagdollObject : public IRagdollObject //Start death animation if (iOldActivityType == 0 && iNewActivityType > 0) { - auto found = std::find_if(m_AnimControlConfigs.begin(), m_AnimControlConfigs.end(), [curstate](const CClientAnimControlConfig& Config) { + const auto &found = std::find_if(m_AnimControlConfigs.begin(), m_AnimControlConfigs.end(), [curstate](const std::shared_ptr& pConfig) { - if (Config.sequence == curstate->sequence) + if (pConfig->sequence == curstate->sequence) return true; return false; @@ -832,7 +944,7 @@ class CBaseRagdollObject : public IRagdollObject if (found != m_AnimControlConfigs.end()) { - if (curstate->frame < found->frame) + if (curstate->frame < (*found)->frame) { return false; } @@ -853,15 +965,17 @@ class CBaseRagdollObject : public IRagdollObject int m_debugDrawLevel{ BULLET_DEFAULT_DEBUG_DRAW_LEVEL }; int m_configId{}; - int m_iActivityType{ 0 }; + StudioAnimActivityType m_iActivityType{ StudioAnimActivityType_Idle }; int m_iBarnacleIndex{ 0 }; int m_iGargantuaIndex{ 0 }; std::vector m_keyBones; std::vector m_nonKeyBones; - CClientAnimControlConfig m_IdleAnimConfig; - std::vector m_AnimControlConfigs; + std::shared_ptr m_IdleAnimConfig; + std::shared_ptr m_DebugAnimConfig; + bool m_bDebugAnimEnabled{}; + std::vector> m_AnimControlConfigs; CClientBarnacleControlConfig m_BarnacleControlConfig; diff --git a/Plugins/BulletPhysics/BaseStaticObject.h b/Plugins/BulletPhysics/BaseStaticObject.h index e774c8b8..97c467c8 100644 --- a/Plugins/BulletPhysics/BaseStaticObject.h +++ b/Plugins/BulletPhysics/BaseStaticObject.h @@ -295,7 +295,7 @@ class CBaseStaticObject : public IStaticObject public: - void CreateRigidBodies(const CStaticObjectCreationParameter& CreationParam) + virtual void CreateRigidBodies(const CStaticObjectCreationParameter& CreationParam) { for (const auto& pRigidBodyConfig : CreationParam.m_pStaticObjectConfig->RigidBodyConfigs) { @@ -303,15 +303,7 @@ class CBaseStaticObject : public IStaticObject if (pRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); - - CPhysicObjectUpdateContext ObjectUpdateContext; - - CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); - - pRigidBody->Update(&ComponentUpdateContext); - - m_RigidBodies.emplace_back(pRigidBody); + AddRigidBody(pRigidBody); } } } @@ -320,6 +312,19 @@ class CBaseStaticObject : public IStaticObject protected: + void AddRigidBody(IPhysicRigidBody* pRigidBody) + { + ClientPhysicManager()->AddPhysicComponent(pRigidBody->GetPhysicComponentId(), pRigidBody); + + CPhysicObjectUpdateContext ObjectUpdateContext; + + CPhysicComponentUpdateContext ComponentUpdateContext(&ObjectUpdateContext); + + pRigidBody->Update(&ComponentUpdateContext); + + m_RigidBodies.emplace_back(pRigidBody); + } + void RebuildRigidBodies(const CStaticObjectCreationParameter& CreationParam) { std::map configIdToComponentIdMap; @@ -345,9 +350,7 @@ class CBaseStaticObject : public IStaticObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); - - m_RigidBodies.emplace_back(pNewRigidBody); + AddRigidBody(pNewRigidBody); } } else @@ -356,9 +359,7 @@ class CBaseStaticObject : public IStaticObject if (pNewRigidBody) { - ClientPhysicManager()->AddPhysicComponent(pNewRigidBody->GetPhysicComponentId(), pNewRigidBody); - - m_RigidBodies.emplace_back(pNewRigidBody); + AddRigidBody(pNewRigidBody); } } } diff --git a/Plugins/BulletPhysics/BulletPhysicManager.cpp b/Plugins/BulletPhysics/BulletPhysicManager.cpp index f131d1d9..24e5ac95 100644 --- a/Plugins/BulletPhysics/BulletPhysicManager.cpp +++ b/Plugins/BulletPhysics/BulletPhysicManager.cpp @@ -223,8 +223,14 @@ CBulletRigidBody::CBulletRigidBody( m_pInternalRigidBody->setUserIndex(id); m_pInternalRigidBody->setUserPointer(this); - m_pInternalRigidBody->setCcdSweptSphereRadius(pRigidConfig->ccdRadius); - m_pInternalRigidBody->setCcdMotionThreshold(pRigidConfig->ccdThreshold); + float ccdRadius = pRigidConfig->ccdRadius; + float ccdThreshold = pRigidConfig->ccdThreshold; + + FloatGoldSrcToBullet(&ccdRadius); + FloatGoldSrcToBullet(&ccdThreshold); + + m_pInternalRigidBody->setCcdSweptSphereRadius(ccdRadius); + m_pInternalRigidBody->setCcdMotionThreshold(ccdThreshold); } CBulletRigidBody::~CBulletRigidBody() @@ -743,55 +749,118 @@ bool CBulletConstraint::ExtendLinearLimit(int axis, float value) btVector3 currentLimit; pDof6->getLinearLowerLimit(currentLimit); - if (currentLimit.x() < -1) { - currentLimit.setX(currentLimit.x() - value); - } - else if (currentLimit.x() > 1) { - currentLimit.setX(currentLimit.x() + value); - } - else if (currentLimit.y() < -1) { - currentLimit.setY(currentLimit.y() - value); - } - else if (currentLimit.y() > 1) { - currentLimit.setY(currentLimit.y() + value); - } - else if (currentLimit.z() < -1) { - currentLimit.setZ(currentLimit.z() - value); + if (value > 0) + { + if (currentLimit.x() < -1) { + currentLimit.setX(currentLimit.x() - value); + } + else if (currentLimit.x() > 1) { + currentLimit.setX(currentLimit.x() + value); + } + else if (currentLimit.y() < -1) { + currentLimit.setY(currentLimit.y() - value); + } + else if (currentLimit.y() > 1) { + currentLimit.setY(currentLimit.y() + value); + } + else if (currentLimit.z() < -1) { + currentLimit.setZ(currentLimit.z() - value); + } + else if (currentLimit.z() > 1) { + currentLimit.setZ(currentLimit.z() + value); + } } - else if (currentLimit.z() > 1) { - currentLimit.setZ(currentLimit.z() + value); + else if (value < 0) + { + if (currentLimit.x() < -1) { + currentLimit.setX(min(currentLimit.x() - value, 0)); + } + else if (currentLimit.x() > 1) { + currentLimit.setX(max(currentLimit.x() + value, 0)); + } + else if (currentLimit.y() < -1) { + currentLimit.setY(min(currentLimit.y() - value, 0)); + } + else if (currentLimit.y() > 1) { + currentLimit.setY(max(currentLimit.y() + value, 0)); + } + else if (currentLimit.z() < -1) { + currentLimit.setZ(min(currentLimit.z() - value, 0)); + } + else if (currentLimit.z() > 1) { + currentLimit.setZ(max(currentLimit.z() + value, 0)); + } } pDof6->setLinearLowerLimit(currentLimit); } - if (axis == -1) { btVector3 currentLimit; pDof6->getLinearUpperLimit(currentLimit); - if (currentLimit.x() < -1) { - currentLimit.setX(currentLimit.x() - value); - } - else if (currentLimit.x() > 1) { - currentLimit.setX(currentLimit.x() + value); - } - else if (currentLimit.y() < -1) { - currentLimit.setY(currentLimit.y() - value); - } - else if (currentLimit.y() > 1) { - currentLimit.setY(currentLimit.y() + value); - } - else if (currentLimit.z() < -1) { - currentLimit.setZ(currentLimit.z() - value); + if (value > 0) + { + if (currentLimit.x() < -1) { + currentLimit.setX(currentLimit.x() - value); + } + else if (currentLimit.x() > 1) { + currentLimit.setX(currentLimit.x() + value); + } + else if (currentLimit.y() < -1) { + currentLimit.setY(currentLimit.y() - value); + } + else if (currentLimit.y() > 1) { + currentLimit.setY(currentLimit.y() + value); + } + else if (currentLimit.z() < -1) { + currentLimit.setZ(currentLimit.z() - value); + } + else if (currentLimit.z() > 1) { + currentLimit.setZ(currentLimit.z() + value); + } } - else if (currentLimit.z() > 1) { - currentLimit.setZ(currentLimit.z() + value); + else if (value < 0) + { + if (currentLimit.x() < -1) { + currentLimit.setX(min(currentLimit.x() - value, 0)); + } + else if (currentLimit.x() > 1) { + currentLimit.setX(max(currentLimit.x() + value, 0)); + } + else if (currentLimit.y() < -1) { + currentLimit.setY(min(currentLimit.y() - value, 0)); + } + else if (currentLimit.y() > 1) { + currentLimit.setY(max(currentLimit.y() + value, 0)); + } + else if (currentLimit.z() < -1) { + currentLimit.setZ(min(currentLimit.z() - value, 0)); + } + else if (currentLimit.z() > 1) { + currentLimit.setZ(max(currentLimit.z() + value, 0)); + } } pDof6->setLinearUpperLimit(currentLimit); } + if (axis >= 0 && axis <= 2) + { + btVector3 currentLimit; + pDof6->getLinearLowerLimit(currentLimit); + currentLimit[axis] += value; + pDof6->setLinearLowerLimit(currentLimit); + } + + if (axis >= 3 && axis <= 5) + { + btVector3 currentLimit; + pDof6->getLinearUpperLimit(currentLimit); + currentLimit[axis - 3] += value; + pDof6->setLinearUpperLimit(currentLimit); + } + return true; } else if (m_pInternalConstraint->getConstraintType() == SLIDER_CONSTRAINT_TYPE) @@ -802,11 +871,23 @@ bool CBulletConstraint::ExtendLinearLimit(int axis, float value) { auto currentLimit = pSlider->getLowerLinLimit(); - if (currentLimit < -1) { - currentLimit = currentLimit - value; + if (value > 0) + { + if (currentLimit < -1) { + currentLimit = currentLimit - value; + } + else if (currentLimit > 1) { + currentLimit = currentLimit + value; + } } - else if (currentLimit > 1) { - currentLimit = currentLimit + value; + else if (value < 0) + { + if (currentLimit < -1) { + currentLimit = min(currentLimit - value, 0); + } + else if (currentLimit > 1) { + currentLimit = max(currentLimit + value, 0); + } } pSlider->setLowerLinLimit(currentLimit); @@ -816,16 +897,42 @@ bool CBulletConstraint::ExtendLinearLimit(int axis, float value) { auto currentLimit = pSlider->getUpperLinLimit(); - if (currentLimit < -1) { - currentLimit = currentLimit - value; + if (value > 0) + { + if (currentLimit < -1) { + currentLimit = currentLimit - value; + } + else if (currentLimit > 1) { + currentLimit = currentLimit + value; + } } - else if (currentLimit > 1) { - currentLimit = currentLimit + value; + else if (value < 0) + { + if (currentLimit < -1) { + currentLimit = min(currentLimit - value, 0); + } + else if (currentLimit > 1) { + currentLimit = max(currentLimit + value, 0); + } } pSlider->setUpperLinLimit(currentLimit); } + if (axis == 0) + { + btScalar currentLimit = pSlider->getLowerLinLimit(); + currentLimit += value; + pSlider->setLowerLinLimit(currentLimit); + } + + if (axis == 3) + { + btScalar currentLimit = pSlider->getUpperLinLimit(); + currentLimit += value; + pSlider->setUpperLinLimit(currentLimit); + } + return true; } @@ -1415,6 +1522,8 @@ btTypedConstraint* BulletCreateConstraint_Dof6Spring(const CClientConstraintConf pDof6Spring->setParam(BT_CONSTRAINT_STOP_CFM, AngularStopCFM, 5); } + pDof6Spring->setEquilibriumPoint(); + return pDof6Spring; } diff --git a/Plugins/BulletPhysics/BulletPhysicManager.h b/Plugins/BulletPhysics/BulletPhysicManager.h index f4cc36b7..f397fb82 100644 --- a/Plugins/BulletPhysics/BulletPhysicManager.h +++ b/Plugins/BulletPhysics/BulletPhysicManager.h @@ -319,4 +319,6 @@ btVector3 GetVector3FromVec3(const vec3_t src); void TransformGoldSrcToBullet(btTransform& trans); void Vector3GoldSrcToBullet(btVector3& vec); void TransformBulletToGoldSrc(btTransform& trans); -void Vector3BulletToGoldSrc(btVector3& vec); \ No newline at end of file +void Vector3BulletToGoldSrc(btVector3& vec); + +StudioAnimActivityType StudioGetSequenceActivityType(model_t* mod, entity_state_t* entstate); \ No newline at end of file diff --git a/Plugins/BulletPhysics/BulletPhysics.vcxproj b/Plugins/BulletPhysics/BulletPhysics.vcxproj index f4e524d7..fd5a1783 100644 --- a/Plugins/BulletPhysics/BulletPhysics.vcxproj +++ b/Plugins/BulletPhysics/BulletPhysics.vcxproj @@ -275,10 +275,14 @@ $(Bullet3CheckRequirements) + + + + @@ -291,6 +295,8 @@ $(Bullet3CheckRequirements) + + diff --git a/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters b/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters index ba764dc5..c27eed1c 100644 --- a/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters +++ b/Plugins/BulletPhysics/BulletPhysics.vcxproj.filters @@ -410,6 +410,24 @@ VGUI2 + + VGUI2 + + + VGUI2 + + + VGUI2 + + + VGUI2 + + + VGUI2 + + + VGUI2 + diff --git a/Plugins/BulletPhysics/BulletRagdollObject.h b/Plugins/BulletPhysics/BulletRagdollObject.h index b2c382d2..7d2f5bd0 100644 --- a/Plugins/BulletPhysics/BulletRagdollObject.h +++ b/Plugins/BulletPhysics/BulletRagdollObject.h @@ -38,7 +38,7 @@ class CBulletRagdollRigidBody : public CBulletRigidBody { if (!(m_boneindex >= 0 && m_boneindex < studiohdr->numbones)) { - Sys_Error("CBulletRagdollRigidBody::SetupJiggleBones invalid m_boneindex!"); + Sys_Error("CBulletRagdollRigidBody::ResetPose invalid m_boneindex!"); return false; } @@ -71,7 +71,7 @@ class CBulletRagdollRigidBody : public CBulletRigidBody { if (!(m_boneindex >= 0 && m_boneindex < studiohdr->numbones)) { - Sys_Error("CBulletRagdollRigidBody::SetupJiggleBones invalid m_boneindex!"); + Sys_Error("CBulletRagdollRigidBody::SetupBones invalid m_boneindex!"); return false; } @@ -181,7 +181,7 @@ class CBulletRagdollRigidBody : public CBulletRigidBody break; } - if (pRagdollObject->GetActivityType() > 0) + if (pRagdollObject->GetActivityType() > StudioAnimActivityType_Idle) { bKinematic = false; break; @@ -273,25 +273,25 @@ class CBulletRagdollConstraint : public CBulletConstraint do { - if (pRagdollObject->GetActivityType() == 0 && (m_flags & PhysicConstraintFlag_DeactiveOnNormalActivity)) + if (pRagdollObject->GetActivityType() == StudioAnimActivityType_Idle && (m_flags & PhysicConstraintFlag_DeactiveOnNormalActivity)) { bDeactivate = true; break; } - if (pRagdollObject->GetActivityType() == 1 && (m_flags & PhysicConstraintFlag_DeactiveOnDeathActivity)) + if (pRagdollObject->GetActivityType() == StudioAnimActivityType_Death && (m_flags & PhysicConstraintFlag_DeactiveOnDeathActivity)) { bDeactivate = true; break; } - if (pRagdollObject->GetActivityType() == 2 && pRagdollObject->GetBarnacleIndex() && (m_flags & PhysicConstraintFlag_DeactiveOnBarnacleActivity)) + if (pRagdollObject->GetActivityType() == StudioAnimActivityType_Barnacle && pRagdollObject->GetBarnacleIndex() && (m_flags & PhysicConstraintFlag_DeactiveOnBarnacleActivity)) { bDeactivate = true; break; } - if (pRagdollObject->GetActivityType() == 2 && pRagdollObject->GetGargantuaIndex() && (m_flags & PhysicConstraintFlag_DeactiveOnGargantuaActivity)) + if (pRagdollObject->GetActivityType() == StudioAnimActivityType_Barnacle && pRagdollObject->GetGargantuaIndex() && (m_flags & PhysicConstraintFlag_DeactiveOnGargantuaActivity)) { bDeactivate = true; break; @@ -495,11 +495,20 @@ class CBulletRagdollObject : public CBaseRagdollObject { m_AnimControlConfigs = CreationParam.m_pRagdollObjectConfig->AnimControlConfigs; - for (const auto& AnimConfig : m_AnimControlConfigs) + for (const auto& pAnimConfig : m_AnimControlConfigs) + { + if (pAnimConfig->activity == StudioAnimActivityType_Idle) + { + m_IdleAnimConfig = pAnimConfig; + break; + } + } + + for (const auto& pAnimConfig : m_AnimControlConfigs) { - if (AnimConfig.idle) + if (pAnimConfig->activity == StudioAnimActivityType_Debug) { - m_IdleAnimConfig = AnimConfig; + m_DebugAnimConfig = pAnimConfig; break; } } @@ -508,7 +517,14 @@ class CBulletRagdollObject : public CBaseRagdollObject if (CreationParam.m_model->type == mod_studio) { - ClientPhysicManager()->SetupBonesForRagdollEx(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex, m_IdleAnimConfig); + if (m_IdleAnimConfig) + { + ClientPhysicManager()->SetupBonesForRagdollEx(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex, m_IdleAnimConfig.get()); + } + else + { + ClientPhysicManager()->SetupBonesForRagdoll(CreationParam.m_entity, CreationParam.m_entstate, CreationParam.m_model, CreationParam.m_entindex, CreationParam.m_playerindex); + } } SaveBoneRelativeTransform(CreationParam); @@ -565,9 +581,9 @@ class CBulletRagdollObject : public CBaseRagdollObject Matrix3x4ToTransform(parentMatrix3x4, parentMatrix); - btTransform mergedMatrix; + TransformGoldSrcToBullet(parentMatrix); - mergedMatrix = parentMatrix * m_BoneRelativeTransform[i]; + btTransform mergedMatrix = parentMatrix * m_BoneRelativeTransform[i]; TransformBulletToGoldSrc(mergedMatrix); @@ -745,7 +761,7 @@ class CBulletRagdollObject : public CBaseRagdollObject m_iBarnacleIndex, pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentExtraHeight], pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentInterval], - pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentLimitAxis]); + (int)pActionConfig->factors[PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentAxis]); } } @@ -762,7 +778,7 @@ class CBulletRagdollObject : public CBaseRagdollObject if (pConstraint->GetFlags() & PhysicConstraintFlag_NonNative) continue; - if (pConstraint->GetFlags() & PhysicConstraintFlag_NoResetPoseOnErrorCorrection) + if (pConstraint->GetFlags() & PhysicConstraintFlag_DontResetPoseOnErrorCorrection) continue; auto pInternalConstraint = (btTypedConstraint *)pConstraint->GetInternalConstraint(); @@ -792,8 +808,12 @@ class CBulletRagdollObject : public CBaseRagdollObject if (bShouldPerformCheck) { auto errorMagnitude = BulletGetConstraintLinearErrorMagnitude(pInternalConstraint); + + float maxTol = pConstraint->GetMaxTolerantLinearError(); + + FloatGoldSrcToBullet(&maxTol); - if (errorMagnitude > pConstraint->GetMaxTolerantLinearError()) + if (errorMagnitude > maxTol) { ResetPose(GetClientEntityState()); @@ -1084,12 +1104,12 @@ class CBulletRagdollObject : public CBaseRagdollObject return nullptr; } - void CreateFloater(const CRagdollObjectCreationParameter& CreationParam, const CClientFloaterConfig* pConfig) - { + void CreateFloater(const CRagdollObjectCreationParameter& CreationParam, const CClientFloaterConfig* pConfig) override + { //TODO } - void SaveBoneRelativeTransform(const CRagdollObjectCreationParameter& CreationParam) + void SaveBoneRelativeTransform(const CRagdollObjectCreationParameter& CreationParam) override { if (!CreationParam.m_studiohdr) return; @@ -1105,41 +1125,21 @@ class CBulletRagdollObject : public CBaseRagdollObject if (parent == -1) { Matrix3x4ToTransform((*pbonetransform)[i], m_BoneRelativeTransform[i]); + TransformGoldSrcToBullet(m_BoneRelativeTransform[i]); } else { btTransform bonematrix; Matrix3x4ToTransform((*pbonetransform)[i], bonematrix); - TransformGoldSrcToBullet(bonematrix); btTransform parentmatrix; Matrix3x4ToTransform((*pbonetransform)[pbones[i].parent], parentmatrix); - TransformGoldSrcToBullet(parentmatrix); m_BoneRelativeTransform[i] = parentmatrix.inverse() * bonematrix; - } - } - } - - void SetupNonKeyBones(const CRagdollObjectCreationParameter& CreationParam) - { - for (int i = 0; i < CreationParam.m_studiohdr->numbones; ++i) - { - if (std::find(m_keyBones.begin(), m_keyBones.end(), i) == m_keyBones.end()) - m_nonKeyBones.emplace_back(i); - } - } - void InitCameraControl(const CClientCameraControlConfig *pCameraControlConfig, CPhysicCameraControl &CameraControl) - { - CameraControl = (*pCameraControlConfig); - - auto pRigidBody = GetRigidBodyByName(pCameraControlConfig->rigidbody); - - if (pRigidBody) - { - CameraControl.m_physicComponentId = pRigidBody->GetPhysicComponentId(); + TransformGoldSrcToBullet(m_BoneRelativeTransform[i]); + } } } diff --git a/Plugins/BulletPhysics/ClientPhysicCommon.h b/Plugins/BulletPhysics/ClientPhysicCommon.h index 8c3544d7..ac592cbe 100644 --- a/Plugins/BulletPhysics/ClientPhysicCommon.h +++ b/Plugins/BulletPhysics/ClientPhysicCommon.h @@ -3,6 +3,34 @@ #include #include +#define BULLET_DEFAULT_DEBUG_DRAW_LEVEL 1 +#define BULLET_WORLD_DEBUG_DRAW_LEVEL 10 +#define BULLET_DEFAULT_SOFTNESS 1.0f +#define BULLET_DEFAULT_BIAS_FACTOR 0.3f +#define BULLET_DEFAULT_RELAXTION_FACTOR 1.0f +#define BULLET_DEFAULT_LINEAR_ERP 0.3f +#define BULLET_DEFAULT_ANGULAR_ERP 0.3f +#define BULLET_DEFAULT_LINEAR_CFM 0.01f +#define BULLET_DEFAULT_ANGULAR_CFM 0.01f +#define BULLET_DEFAULT_LINEAR_STOP_ERP 0.3f +#define BULLET_DEFAULT_ANGULAR_STOP_ERP 0.3f +#define BULLET_DEFAULT_LINEAR_STOP_CFM 0.01f +#define BULLET_DEFAULT_ANGULAR_STOP_CFM 0.01f +#define BULLET_DEFAULT_CCD_THRESHOLD 0.001f +#define BULLET_DEFAULT_LINEAR_FRICTION 1.0f +#define BULLET_DEFAULT_ANGULAR_FRICTION 0.2f +#define BULLET_DEFAULT_RESTITUTION 0.0f +#define BULLET_DEFAULT_MASS 1.0f +#define BULLET_DEFAULT_DENSENTY 1.0f +#define BULLET_DEFAULT_LINEAR_SLEEPING_THRESHOLD 5.0f +#define BULLET_DEFAULT_ANGULAR_SLEEPING_THRESHOLD 3.0f +#define BULLET_DEFAULT_MAX_TOLERANT_LINEAR_ERROR 30.0f + +#define INCHES_PER_METER 1//39.3700787402f + +const float B2GScale = INCHES_PER_METER; +const float G2BScale = 1.0f / B2GScale; + enum PhysicConfigType { PhysicConfigType_None, @@ -111,6 +139,7 @@ const int PhysicRotOrder_YXZ = 2; const int PhysicRotOrder_YZX = 3; const int PhysicRotOrder_ZXY = 4; const int PhysicRotOrder_ZYX = 5; +const int PhysicRotOrder_Maximum = 6; const int PhysicConstraintFlag_Barnacle = 0x1; const int PhysicConstraintFlag_Gargantua = 0x2; @@ -118,7 +147,7 @@ const int PhysicConstraintFlag_DeactiveOnNormalActivity = 0x4; const int PhysicConstraintFlag_DeactiveOnDeathActivity = 0x8; const int PhysicConstraintFlag_DeactiveOnBarnacleActivity = 0x10; const int PhysicConstraintFlag_DeactiveOnGargantuaActivity = 0x20; -const int PhysicConstraintFlag_NoResetPoseOnErrorCorrection = 0x40; +const int PhysicConstraintFlag_DontResetPoseOnErrorCorrection = 0x40; const int PhysicConstraintFlag_NonNative = (PhysicConstraintFlag_Barnacle | PhysicConstraintFlag_Gargantua); const int PhysicConstraintFactorIdx_ConeTwistSwingSpanLimit1 = 0; @@ -189,6 +218,32 @@ const int PhysicConstraintFactorIdx_RigidBodyLinearDistanceOffset = 40; const int PhysicConstraintFactorIdx_Maximum = 64; +const float PhysicConstraintFactorDefaultValue_ConeTwistSoftness = BULLET_DEFAULT_SOFTNESS; +const float PhysicConstraintFactorDefaultValue_ConeTwistBiasFactor = BULLET_DEFAULT_BIAS_FACTOR; +const float PhysicConstraintFactorDefaultValue_ConeTwistRelaxationFactor = BULLET_DEFAULT_RELAXTION_FACTOR; + +const float PhysicConstraintFactorDefaultValue_HingeSoftness = BULLET_DEFAULT_SOFTNESS; +const float PhysicConstraintFactorDefaultValue_HingeBiasFactor = BULLET_DEFAULT_BIAS_FACTOR; +const float PhysicConstraintFactorDefaultValue_HingeRelaxationFactor = BULLET_DEFAULT_RELAXTION_FACTOR; + +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableLinearSpringX = 0; +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableLinearSpringY = 0; +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableLinearSpringZ = 0; + +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableAngularSpringX = 0; +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableAngularSpringY = 0; +const float PhysicConstraintFactorDefaultValue_Dof6SpringEnableAngularSpringZ = 0; + +const float PhysicConstraintFactorDefaultValue_LinearERP = BULLET_DEFAULT_LINEAR_ERP; +const float PhysicConstraintFactorDefaultValue_LinearCFM = BULLET_DEFAULT_LINEAR_CFM; +const float PhysicConstraintFactorDefaultValue_LinearStopERP = BULLET_DEFAULT_LINEAR_STOP_ERP; +const float PhysicConstraintFactorDefaultValue_LinearStopCFM = BULLET_DEFAULT_LINEAR_STOP_CFM; +const float PhysicConstraintFactorDefaultValue_AngularERP = BULLET_DEFAULT_ANGULAR_ERP; +const float PhysicConstraintFactorDefaultValue_AngularCFM = BULLET_DEFAULT_ANGULAR_CFM; +const float PhysicConstraintFactorDefaultValue_AngularStopERP = BULLET_DEFAULT_ANGULAR_STOP_ERP; +const float PhysicConstraintFactorDefaultValue_AngularStopCFM = BULLET_DEFAULT_ANGULAR_STOP_CFM; +const float PhysicConstraintFactorDefaultValue_RigidBodyLinearDistanceOffset = 0; + enum PhysicShape { PhysicShape_None, @@ -234,7 +289,7 @@ const int PhysicActionFactorIdx_BarnacleChewForceInterval = 1; //const int PhysicAction_BarnacleConstraintLimitAdjustment = 3; const int PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentExtraHeight = 1; const int PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentInterval = 2; -const int PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentLimitAxis = 3; +const int PhysicActionFactorIdx_BarnacleConstraintLimitAdjustmentAxis = 3; //const int PhysicAction_Maximum = 4; @@ -257,33 +312,13 @@ enum PhysicShapeDirection //const int PhysicShapeDirection_Y = 1; //const int PhysicShapeDirection_Z = 2; -#define BULLET_DEFAULT_DEBUG_DRAW_LEVEL 1 -#define BULLET_WORLD_DEBUG_DRAW_LEVEL 10 -#define BULLET_DEFAULT_SOFTNESS 1.0f -#define BULLET_DEFAULT_BIAS_FACTOR 0.3f -#define BULLET_DEFAULT_RELAXTION_FACTOR 1.0f -#define BULLET_DEFAULT_LINEAR_ERP 0.3f -#define BULLET_DEFAULT_ANGULAR_ERP 0.3f -#define BULLET_DEFAULT_LINEAR_CFM 0.01f -#define BULLET_DEFAULT_ANGULAR_CFM 0.01f -#define BULLET_DEFAULT_LINEAR_STOP_ERP 0.3f -#define BULLET_DEFAULT_ANGULAR_STOP_ERP 0.3f -#define BULLET_DEFAULT_LINEAR_STOP_CFM 0.01f -#define BULLET_DEFAULT_ANGULAR_STOP_CFM 0.01f -#define BULLET_DEFAULT_CCD_THRESHOLD 0.001f -#define BULLET_DEFAULT_LINEAR_FIRCTION 1.0f -#define BULLET_DEFAULT_ANGULAR_FIRCTION 0.2f -#define BULLET_DEFAULT_RESTITUTION 0.0f -#define BULLET_DEFAULT_MASS 1.0f -#define BULLET_DEFAULT_DENSENTY 1.0f -#define BULLET_DEFAULT_LINEAR_SLEEPING_THRESHOLD 5.0f -#define BULLET_DEFAULT_ANGULAR_SLEEPING_THRESHOLD 3.0f -#define BULLET_DEFAULT_MAX_TOLERANT_LINEAR_ERROR 30.0f//TODO: use config? - -#define INCHES_PER_METER 39.3700787402f - -const float B2GScale = INCHES_PER_METER; -const float G2BScale = (1.0f / B2GScale); +enum StudioAnimActivityType +{ + StudioAnimActivityType_Idle, + StudioAnimActivityType_Death, + StudioAnimActivityType_Barnacle, + StudioAnimActivityType_Debug, +}; const int PhysicIndexArrayFlag_FromBSP = 0x1; const int PhysicIndexArrayFlag_LoadFailed = 0x2; diff --git a/Plugins/BulletPhysics/ClientPhysicConfig.h b/Plugins/BulletPhysics/ClientPhysicConfig.h index c8c23353..9cffd232 100644 --- a/Plugins/BulletPhysics/ClientPhysicConfig.h +++ b/Plugins/BulletPhysics/ClientPhysicConfig.h @@ -75,8 +75,8 @@ class CClientRigidBodyConfig : public CClientBasePhysicConfig float mass{ 1 }; float density{ 1 }; - float linearFriction{ BULLET_DEFAULT_LINEAR_FIRCTION }; - float rollingFriction{ BULLET_DEFAULT_ANGULAR_FIRCTION }; + float linearFriction{ BULLET_DEFAULT_LINEAR_FRICTION }; + float rollingFriction{ BULLET_DEFAULT_ANGULAR_FRICTION }; float restitution{ BULLET_DEFAULT_RESTITUTION }; float ccdRadius{ 0 }; float ccdThreshold{ BULLET_DEFAULT_CCD_THRESHOLD }; @@ -152,14 +152,15 @@ class CClientFloaterConfig : public CClientBasePhysicConfig float angularDamping{}; }; -class CClientAnimControlConfig +class CClientAnimControlConfig : public CClientBasePhysicConfig { public: int sequence{}; int gaitsequence{}; float frame{}; - int activity{}; - bool idle{}; + StudioAnimActivityType activity{ StudioAnimActivityType_Idle }; + int controller[4]{ 0 }; + int blending[4]{ 0 }; }; class CClientPhysicObjectConfig : public CClientBasePhysicConfig @@ -176,8 +177,9 @@ class CClientPhysicObjectConfig : public CClientBasePhysicConfig int crc32StudioModel{}; std::vector> RigidBodyConfigs; + std::vector> ConstraintConfigs; - //Never Change + //Never save to file or load from file std::string fileName; std::string shortName; }; @@ -186,8 +188,6 @@ class CClientDynamicObjectConfig : public CClientPhysicObjectConfig { public: CClientDynamicObjectConfig(); - - std::vector> ConstraintConfigs; }; class CClientStaticObjectConfig : public CClientPhysicObjectConfig @@ -216,9 +216,8 @@ class CClientRagdollObjectConfig : public CClientPhysicObjectConfig public: CClientRagdollObjectConfig(); - std::vector> ConstraintConfigs; std::vector> FloaterConfigs; - std::vector AnimControlConfigs; + std::vector> AnimControlConfigs; CClientBarnacleControlConfig BarnacleControlConfig; CClientCameraControlConfig FirstPersonViewCameraControlConfig; CClientCameraControlConfig ThirdPersonViewCameraControlConfig; diff --git a/Plugins/BulletPhysics/ClientPhysicManager.h b/Plugins/BulletPhysics/ClientPhysicManager.h index 5a173cdf..3669ba9e 100644 --- a/Plugins/BulletPhysics/ClientPhysicManager.h +++ b/Plugins/BulletPhysics/ClientPhysicManager.h @@ -356,8 +356,8 @@ class IRagdollObject : public ICollisionPhysicObject return "#BulletPhysics_RagdollObject"; } - virtual int GetActivityType() const = 0; - virtual int GetOverrideActivityType(entity_state_t* entstate) = 0; + virtual StudioAnimActivityType GetActivityType() const = 0; + virtual StudioAnimActivityType GetOverrideActivityType(entity_state_t* entstate) = 0; virtual bool ResetPose(entity_state_t* curstate) = 0; virtual void UpdatePose(entity_state_t* curstate) = 0; @@ -367,6 +367,8 @@ class IRagdollObject : public ICollisionPhysicObject virtual void ReleaseFromGargantua() = 0; virtual int GetBarnacleIndex() const = 0; virtual int GetGargantuaIndex() const = 0; + virtual bool IsDebugAnimEnabled() const = 0; + virtual void SetDebugAnimEnabled(bool bEnabled) = 0; virtual bool SyncFirstPersonView(struct ref_params_s* pparams, void(*callback)(struct ref_params_s* pparams)) = 0; virtual bool SyncThirdPersonView(struct ref_params_s* pparams, void(*callback)(struct ref_params_s* pparams)) = 0; }; @@ -422,7 +424,7 @@ class IClientPhysicManager : public IBaseInterface virtual void CreatePhysicObjectForEntity(cl_entity_t* ent, entity_state_t* state, model_t* mod) = 0; virtual void SetupBonesForRagdoll(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex) = 0; - virtual void SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig& OverrideAnim) = 0; + virtual void SetupBonesForRagdollEx(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex, const CClientAnimControlConfig* pOverrideAnimControl) = 0; virtual void UpdateBonesForRagdoll(cl_entity_t* ent, entity_state_t* state, model_t* mod, int entindex, int playerindex) = 0; //PhysicWorld diff --git a/Plugins/BulletPhysics/PhysicDebugGUI.cpp b/Plugins/BulletPhysics/PhysicDebugGUI.cpp index 7e95e0ca..34534b14 100644 --- a/Plugins/BulletPhysics/PhysicDebugGUI.cpp +++ b/Plugins/BulletPhysics/PhysicDebugGUI.cpp @@ -190,16 +190,33 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) } else if (pPhysicComponent->IsConstraint()) { - //TODO + OpenEditConstraintDialog(pPhysicComponent->GetOwnerPhysicObject()->GetPhysicObjectId(), pPhysicComponent->GetOwnerPhysicObject()->GetPhysicConfigId(), pPhysicComponent->GetPhysicConfigId()); + return; } } } else if (code == vgui::KEY_DELETE) { - if (DeleteRigidBodyByComponentId(physicComponentId)) + auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); + + if (pPhysicComponent) { - ClientPhysicManager()->SetSelectedPhysicComponentId(0); - return; + if (pPhysicComponent->IsRigidBody()) + { + if (DeleteRigidBodyByComponent(pPhysicComponent)) + { + ClientPhysicManager()->SetSelectedPhysicComponentId(0); + return; + } + } + else if (pPhysicComponent->IsConstraint()) + { + if (DeleteConstraintByComponent(pPhysicComponent)) + { + ClientPhysicManager()->SetSelectedPhysicComponentId(0); + return; + } + } } } else if (m_EditMode != PhysicEditMode::Move && code == vgui::KEY_M) @@ -227,7 +244,7 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) { auto physicComponentId = ClientPhysicManager()->GetSelectedPhysicComponentId(); - if (physicComponentId > 0) + if (physicComponentId) { float step = 0.1f; @@ -236,7 +253,7 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) else if (vgui::input()->IsKeyDown(vgui::KEY_LALT)) step *= 0.1f; - if (UpdateRigidBodyConfigOrigin(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) + if (UpdateConfigOrigin(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) return; } } @@ -244,16 +261,16 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) { auto physicComponentId = ClientPhysicManager()->GetSelectedPhysicComponentId(); - if (physicComponentId > 0) + if (physicComponentId) { - float step = 0.1f; + float step = 0.2f; if (vgui::input()->IsKeyDown(vgui::KEY_LSHIFT)) step *= 10.0f; else if (vgui::input()->IsKeyDown(vgui::KEY_LALT)) step *= 0.1f; - if (UpdateRigidBodyConfigAngles(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) + if (UpdateConfigAngles(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) return; } } @@ -261,7 +278,7 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) { auto physicComponentId = ClientPhysicManager()->GetSelectedPhysicComponentId(); - if (physicComponentId > 0) + if (physicComponentId) { float step = 0.1f; @@ -270,7 +287,7 @@ void CPhysicDebugGUI::OnKeyCodeTyped(vgui::KeyCode code) else if (vgui::input()->IsKeyDown(vgui::KEY_LALT)) step *= 0.1f; - if (UpdateRigidBodyConfigSize(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) + if (UpdateConfigSize(physicComponentId, ConvertKeyCodeToAxis(code), ConvertKeyCodeToSign(code) * step)) return; } } @@ -622,7 +639,7 @@ void CPhysicDebugGUI::OnMousePressed(vgui::MouseCode code) return; } } - else if (m_InspectMode == PhysicInspectMode::RigidBody) + else if (m_InspectMode == PhysicInspectMode::RigidBody || m_InspectMode == PhysicInspectMode::Constraint || m_InspectMode == PhysicInspectMode::Floater) { if (OpenInspectPhysicComponentMenu(true)) { @@ -708,7 +725,7 @@ bool CPhysicDebugGUI::UpdateInspectedClientEntity(bool bSelected) vgui::localize()->ConvertANSIToUnicode(modelname.c_str(), wszModelName, sizeof(wszModelName)); - auto str = std::format(L"{0} (#{1}): {2}", vgui::localize()->Find("#BulletPhysics_Entity"), entindex, wszModelName); + auto str = std::format(L"{0}: {1}", vgui::localize()->Find("#BulletPhysics_Entity"), wszModelName); ShowInspectContentLabel(str.c_str()); @@ -743,7 +760,7 @@ bool CPhysicDebugGUI::UpdateInspectedPhysicObject(bool bSelected) vgui::localize()->ConvertANSIToUnicode(modelname.c_str(), wszModelName, sizeof(wszModelName)); - auto str = std::format(L"{0} (#{1}): {2}", vgui::localize()->Find(pPhysicObject->GetTypeLocalizationTokenString()), entindex, wszModelName); + auto str = std::format(L"{0}: {1}", vgui::localize()->Find(pPhysicObject->GetTypeLocalizationTokenString()), wszModelName); ShowInspectContentLabel(str.c_str()); @@ -768,40 +785,12 @@ bool CPhysicDebugGUI::UpdateInspectedRigidBody(bool bSelected) vgui::localize()->ConvertANSIToUnicode(pRigidBody->GetName(), wszComponentName, sizeof(wszComponentName)); - auto str = std::format(L"{0} (#{1}): {2} / {3}: {4}", + auto str = std::format(L"{0}: {1} / {2}: {3} ", vgui::localize()->Find("#BulletPhysics_RigidBody"), - pRigidBody->GetPhysicComponentId(), wszComponentName, vgui::localize()->Find("#BulletPhysics_Mass"), pRigidBody->GetMass()); - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_AlwaysDynamic) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_AlwaysDynamic")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_AlwaysKinematic) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_AlwaysKinematic")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_AlwaysStatic) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_AlwaysStatic")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_NoCollisionToWorld) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_NoCollisionToWorld")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_NoCollisionToStaticObject) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_NoCollisionToStaticObject")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_NoCollisionToDynamicObject) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_NoCollisionToDynamicObject")); - } - if (pRigidBody->GetFlags() & PhysicRigidBodyFlag_NoCollisionToRagdollObject) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_NoCollisionToRagdollObject")); - } + str += UTIL_GetFormattedRigidBodyFlags(pRigidBody->GetFlags()); ShowInspectContentLabel(str.c_str()); @@ -885,32 +874,9 @@ bool CPhysicDebugGUI::UpdateInspectedConstraint(bool bSelected) vgui::localize()->ConvertANSIToUnicode(pConstraint->GetName(), wszName, sizeof(wszName)); - auto str = std::format(L"{0} (#{1}): {2}", vgui::localize()->Find(pConstraint->GetTypeLocalizationTokenString()), pConstraint->GetPhysicComponentId(), wszName); + auto str = std::format(L"{0}: {1}", vgui::localize()->Find(pConstraint->GetTypeLocalizationTokenString()), wszName); - if (pConstraint->GetFlags() & PhysicConstraintFlag_Barnacle) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_Barnacle")); - } - if (pConstraint->GetFlags() & PhysicConstraintFlag_Gargantua) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_Gargantua")); - } - if (pConstraint->GetFlags() & PhysicConstraintFlag_DeactiveOnNormalActivity) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_DeactiveOnNormalActivity")); - } - if (pConstraint->GetFlags() & PhysicConstraintFlag_DeactiveOnDeathActivity) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_DeactiveOnDeathActivity")); - } - if (pConstraint->GetFlags() & PhysicConstraintFlag_DeactiveOnBarnacleActivity) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_DeactiveOnBarnacleActivity")); - } - if (pConstraint->GetFlags() & PhysicConstraintFlag_DeactiveOnGargantuaActivity) - { - str += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_DeactiveOnGargantuaActivity")); - } + str += UTIL_GetFormattedConstraintFlags(pConstraint->GetFlags()); ShowInspectContentLabel(str.c_str()); @@ -918,36 +884,9 @@ bool CPhysicDebugGUI::UpdateInspectedConstraint(bool bSelected) if (pConstraintConfig) { - auto str2 = std::format(L"[{0}]: ", vgui::localize()->Find("#BulletPhysics_Config")); + auto str2 = std::format(L"[{0}] ", vgui::localize()->Find("#BulletPhysics_Config")); - if (pConstraintConfig->useGlobalJointFromA) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseGlobalJointFromA")); - } - else - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseGlobalJointFromB")); - } - if (pConstraintConfig->disableCollision) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_DisableCollision")); - } - if (pConstraintConfig->useLookAtOther) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseLookAtOther")); - } - if (pConstraintConfig->useGlobalJointOriginFromOther) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseGlobalJointOriginFromOther")); - } - if (pConstraintConfig->useRigidBodyDistanceAsLinearLimit) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseRigidBodyDistanceAsLinearLimit")); - } - if (pConstraintConfig->useLinearReferenceFrameA) - { - str2 += std::format(L" ({0})", vgui::localize()->Find("#BulletPhysics_UseLinearReferenceFrameA")); - } + str2 += UTIL_GetFormattedConstraintConfigAttributes(pConstraintConfig.get()); ShowInspectContentLabel2(str2.c_str()); @@ -967,7 +906,7 @@ bool CPhysicDebugGUI::UpdateInspectedConstraint(bool bSelected) wchar_t wszRigidBodyName[64] = { 0 }; vgui::localize()->ConvertANSIToUnicode(pConstraintConfig->rigidbodyA.c_str(), wszRigidBodyName, sizeof(wszRigidBodyName)); - str3 += std::format(L"{0}: {1} / {2}: ({3:.2f}, {4:.2f}, {5:.2f}) / {6}: ({7:.2f}, {8:.2f}, {9:.2f}). ", + str3 += std::format(L"{0}: {1} / {2}: ({3:.2f}, {4:.2f}, {5:.2f}) / {6}: ({7:.2f}, {8:.2f}, {9:.2f}) ", vgui::localize()->Find("#BulletPhysics_RigidBodyA"), wszRigidBodyName, vgui::localize()->Find("#BulletPhysics_Origin"), @@ -986,7 +925,7 @@ bool CPhysicDebugGUI::UpdateInspectedConstraint(bool bSelected) wchar_t wszRigidBodyName[64] = { 0 }; vgui::localize()->ConvertANSIToUnicode(pConstraintConfig->rigidbodyB.c_str(), wszRigidBodyName, sizeof(wszRigidBodyName)); - str3 += std::format(L"{0}: {1} / {2}: ({3:.2f}, {4:.2f}, {5:.2f}) / {6}: ({7:.2f}, {8:.2f}, {9:.2f}). ", + str3 += std::format(L"{0}: {1} / {2}: ({3:.2f}, {4:.2f}, {5:.2f}) / {6}: ({7:.2f}, {8:.2f}, {9:.2f}) ", vgui::localize()->Find("#BulletPhysics_RigidBodyB"), wszRigidBodyName, vgui::localize()->Find("#BulletPhysics_Origin"), @@ -1152,86 +1091,165 @@ bool CPhysicDebugGUI::OpenInspectPhysicComponentMenu(bool bSelected) if (physicComponentId > 0) { - auto pRigidBody = UTIL_GetPhysicComponentAsRigidBody(physicComponentId); + auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); - if (pRigidBody) + if (pPhysicComponent) { - auto pPhysicObject = pRigidBody->GetOwnerPhysicObject(); - - if (pPhysicObject && (pPhysicObject->GetObjectFlags() & PhysicObjectFlag_FromConfig)) + if (pPhysicComponent->IsRigidBody()) { - auto menu = new vgui::Menu(this, "contextmenu"); - - menu->SetAutoDelete(true); - - char szFileName[64] = { 0 }; - wchar_t wszFileName[64] = { 0 }; - wchar_t wszComponentName[64] = { 0 }; - wchar_t szBuf[256] = { 0 }; + auto pRigidBody = (IPhysicRigidBody*)pPhysicComponent; - V_FileBase(pPhysicObject->GetModel()->name, szFileName, sizeof(szFileName)); - vgui::localize()->ConvertANSIToUnicode(szFileName, wszFileName, sizeof(wszFileName)); - - auto kv = new KeyValues("EditPhysicObject"); + auto pPhysicObject = pRigidBody->GetOwnerPhysicObject(); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditPhysicObject"), 1, wszFileName); - - menu->AddMenuItem("EditPhysicObject", szBuf, kv, this); - - vgui::localize()->ConvertANSIToUnicode(pRigidBody->GetName(), wszComponentName, sizeof(wszComponentName)); - - kv = new KeyValues("EditRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditRigidBody"), 1, wszComponentName); - menu->AddMenuItem("EditRigidBodyEx", szBuf, kv, this); - - kv = new KeyValues("MoveRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_MoveRigidBody"), 1, wszComponentName); - menu->AddMenuItem("MoveRigidBodyEx", szBuf, kv, this); - - kv = new KeyValues("RotateRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_RotateRigidBody"), 1, wszComponentName); - menu->AddMenuItem("RotateRigidBodyEx", szBuf, kv, this); - - kv = new KeyValues("ResizeRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_ResizeRigidBody"), 1, wszComponentName); - menu->AddMenuItem("ResizeRigidBodyEx", szBuf, kv, this); - - kv = new KeyValues("CloneRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_CloneRigidBody"), 1, wszComponentName); - menu->AddMenuItem("CloneRigidBodyEx", szBuf, kv, this); + if (pPhysicObject && (pPhysicObject->GetObjectFlags() & PhysicObjectFlag_FromConfig)) + { + auto menu = new vgui::Menu(this, "contextmenu"); + + menu->SetAutoDelete(true); + + char szFileName[64] = { 0 }; + wchar_t wszFileName[64] = { 0 }; + wchar_t wszComponentName[64] = { 0 }; + wchar_t szBuf[256] = { 0 }; + + V_FileBase(pPhysicObject->GetModel()->name, szFileName, sizeof(szFileName)); + vgui::localize()->ConvertANSIToUnicode(szFileName, wszFileName, sizeof(wszFileName)); + + auto kv = new KeyValues("EditPhysicObject"); + + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditPhysicObject"), 1, wszFileName); + + menu->AddMenuItem("EditPhysicObject", szBuf, kv, this); + + vgui::localize()->ConvertANSIToUnicode(pRigidBody->GetName(), wszComponentName, sizeof(wszComponentName)); + + kv = new KeyValues("EditRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditRigidBody"), 1, wszComponentName); + menu->AddMenuItem("EditRigidBodyEx", szBuf, kv, this); + + kv = new KeyValues("MoveRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_MoveRigidBody"), 1, wszComponentName); + menu->AddMenuItem("MoveRigidBodyEx", szBuf, kv, this); + + kv = new KeyValues("RotateRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_RotateRigidBody"), 1, wszComponentName); + menu->AddMenuItem("RotateRigidBodyEx", szBuf, kv, this); + + kv = new KeyValues("ResizeRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_ResizeRigidBody"), 1, wszComponentName); + menu->AddMenuItem("ResizeRigidBodyEx", szBuf, kv, this); + + kv = new KeyValues("CloneRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_CloneRigidBody"), 1, wszComponentName); + menu->AddMenuItem("CloneRigidBodyEx", szBuf, kv, this); + + kv = new KeyValues("DeleteRigidBodyEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); + kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_DeleteRigidBody"), 1, wszComponentName); + menu->AddMenuItem("DeleteRigidBodyEx", szBuf, kv, this); + + vgui::Menu::PlaceContextMenu(this, menu); + return true; + } + } + else if (pPhysicComponent->IsConstraint()) + { + auto pConstraint = (IPhysicConstraint*)pPhysicComponent; - kv = new KeyValues("DeleteRigidBodyEx"); - kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); - kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); - kv->SetInt("physicComponentId", pRigidBody->GetPhysicComponentId()); - kv->SetInt("rigidBodyConfigId", pRigidBody->GetPhysicConfigId()); - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_DeleteRigidBody"), 1, wszComponentName); - menu->AddMenuItem("DeleteRigidBodyEx", szBuf, kv, this); + auto pPhysicObject = pConstraint->GetOwnerPhysicObject(); - vgui::Menu::PlaceContextMenu(this, menu); - return true; + if (pPhysicObject && (pPhysicObject->GetObjectFlags() & PhysicObjectFlag_FromConfig)) + { + auto menu = new vgui::Menu(this, "contextmenu"); + + menu->SetAutoDelete(true); + + char szFileName[64] = { 0 }; + wchar_t wszFileName[64] = { 0 }; + wchar_t wszComponentName[64] = { 0 }; + wchar_t szBuf[256] = { 0 }; + + V_FileBase(pPhysicObject->GetModel()->name, szFileName, sizeof(szFileName)); + vgui::localize()->ConvertANSIToUnicode(szFileName, wszFileName, sizeof(wszFileName)); + + auto kv = new KeyValues("EditPhysicObject"); + + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditPhysicObject"), 1, wszFileName); + + menu->AddMenuItem("EditPhysicObject", szBuf, kv, this); + + vgui::localize()->ConvertANSIToUnicode(pConstraint->GetName(), wszComponentName, sizeof(wszComponentName)); + + kv = new KeyValues("EditConstraintEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pConstraint->GetPhysicComponentId()); + kv->SetInt("constraintConfigId", pConstraint->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditConstraint"), 1, wszComponentName); + menu->AddMenuItem("EditConstraintEx", szBuf, kv, this); + + kv = new KeyValues("MoveConstraintEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pConstraint->GetPhysicComponentId()); + kv->SetInt("constraintConfigId", pConstraint->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_MoveConstraint"), 1, wszComponentName); + menu->AddMenuItem("MoveConstraintEx", szBuf, kv, this); + + kv = new KeyValues("RotateConstraintEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pConstraint->GetPhysicComponentId()); + kv->SetInt("constraintConfigId", pConstraint->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_RotateConstraint"), 1, wszComponentName); + menu->AddMenuItem("RotateConstraintEx", szBuf, kv, this); + + kv = new KeyValues("CloneConstraintEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pConstraint->GetPhysicComponentId()); + kv->SetInt("constraintConfigId", pConstraint->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_CloneConstraint"), 1, wszComponentName); + menu->AddMenuItem("CloneConstraintEx", szBuf, kv, this); + + kv = new KeyValues("DeleteConstraintEx"); + kv->SetUint64("physicObjectId", pPhysicObject->GetPhysicObjectId()); + kv->SetInt("physicObjectConfigId", pPhysicObject->GetPhysicConfigId()); + kv->SetInt("physicComponentId", pConstraint->GetPhysicComponentId()); + kv->SetInt("constraintConfigId", pConstraint->GetPhysicConfigId()); + vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_DeleteConstraint"), 1, wszComponentName); + menu->AddMenuItem("DeleteConstraintEx", szBuf, kv, this); + + vgui::Menu::PlaceContextMenu(this, menu); + return true; + } } } } @@ -1467,13 +1485,16 @@ void CPhysicDebugGUI::OnCreateRigidBody(uint64 physicObjectId) auto pRigidBodyConfig = std::make_shared(); - pRigidBodyConfig->name = std::format("Unnamed ({0})", pRigidBodyConfig->configId); + pRigidBodyConfig->name = std::format("UnnamedRigidBody ({0})", pRigidBodyConfig->configId); + pRigidBodyConfig->configModified = true; pRigidBodyConfig->collisionShape = std::make_shared(); pRigidBodyConfig->collisionShape->type = PhysicShape_Sphere; pRigidBodyConfig->collisionShape->size[0] = 3; + pRigidBodyConfig->collisionShape->configModified = true; pPhysicObjectConfig->RigidBodyConfigs.emplace_back(pRigidBodyConfig); + pPhysicObjectConfig->configModified = true; ClientPhysicManager()->AddPhysicConfig(pRigidBodyConfig->configId, pRigidBodyConfig); @@ -1649,11 +1670,9 @@ void CPhysicDebugGUI::OnCloneRigidBodyEx(KeyValues* kv) } } -bool CPhysicDebugGUI::DeleteRigidBodyByComponentId(int physicComponentId) +bool CPhysicDebugGUI::DeleteRigidBodyByComponent(IPhysicComponent* pPhysicComponent) { - auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); - - if (pPhysicComponent) + if (pPhysicComponent && pPhysicComponent->IsRigidBody()) { auto pPhysicObject = pPhysicComponent->GetOwnerPhysicObject(); @@ -1677,6 +1696,18 @@ bool CPhysicDebugGUI::DeleteRigidBodyByComponentId(int physicComponentId) return false; } +bool CPhysicDebugGUI::DeleteRigidBodyByComponentId(int physicComponentId) +{ + auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); + + if (pPhysicComponent) + { + return DeleteRigidBodyByComponent(pPhysicComponent); + } + + return false; +} + void CPhysicDebugGUI::OnDeleteRigidBodyEx(KeyValues* kv) { auto physicObjectId = kv->GetUint64("physicObjectId"); @@ -1695,7 +1726,7 @@ void CPhysicDebugGUI::OnDeleteRigidBodyEx(KeyValues* kv) } } -bool CPhysicDebugGUI::UpdateRigidBodyConfigOrigin(int physicComponentId, int axis, float value) +bool CPhysicDebugGUI::UpdateConfigOrigin(int physicComponentId, int axis, float value) { auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); @@ -1703,17 +1734,36 @@ bool CPhysicDebugGUI::UpdateRigidBodyConfigOrigin(int physicComponentId, int axi { auto pPhysicObject = pPhysicComponent->GetOwnerPhysicObject(); + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + if (pPhysicObject) { - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); + if (pPhysicComponent->IsRigidBody()) + { + auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); - auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + if (pRigidBodyConfig && pPhysicObjectConfig) + { + pRigidBodyConfig->origin[axis] += value; + pRigidBodyConfig->configModified = true; - if (pRigidBodyConfig && pPhysicObjectConfig) + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + } + } + else if (pPhysicComponent->IsConstraint()) { - pRigidBodyConfig->origin[axis] += value; + auto pConstraintConfig = UTIL_GetConstraintConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); + + if (pConstraintConfig && pPhysicObjectConfig) + { + if(pConstraintConfig->useGlobalJointFromA) + pConstraintConfig->originA[axis] += value; + else + pConstraintConfig->originB[axis] += value; + pConstraintConfig->configModified = true; - return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + } } } } @@ -1721,7 +1771,7 @@ bool CPhysicDebugGUI::UpdateRigidBodyConfigOrigin(int physicComponentId, int axi return false; } -bool CPhysicDebugGUI::UpdateRigidBodyConfigAngles(int physicComponentId, int axis, float value) +bool CPhysicDebugGUI::UpdateConfigAngles(int physicComponentId, int axis, float value) { auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); @@ -1729,17 +1779,37 @@ bool CPhysicDebugGUI::UpdateRigidBodyConfigAngles(int physicComponentId, int axi { auto pPhysicObject = pPhysicComponent->GetOwnerPhysicObject(); + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + if (pPhysicObject) { - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); + if (pPhysicComponent->IsRigidBody()) + { + auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); - auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + if (pRigidBodyConfig && pPhysicObjectConfig) + { + pRigidBodyConfig->angles[axis] += value; + pRigidBodyConfig->configModified = true; - if (pRigidBodyConfig && pPhysicObjectConfig) + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + } + } + else if (pPhysicComponent->IsConstraint()) { - pRigidBodyConfig->angles[axis] += value; + auto pConstraintConfig = UTIL_GetConstraintConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); + + if (pConstraintConfig && pPhysicObjectConfig) + { + if (pConstraintConfig->useGlobalJointFromA) + pConstraintConfig->anglesA[axis] += value; + else + pConstraintConfig->anglesB[axis] += value; + + pConstraintConfig->configModified = true; - return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + } } } } @@ -1747,7 +1817,7 @@ bool CPhysicDebugGUI::UpdateRigidBodyConfigAngles(int physicComponentId, int axi return false; } -bool CPhysicDebugGUI::UpdateRigidBodyConfigSize(int physicComponentId, int axis, float value) +bool CPhysicDebugGUI::UpdateConfigSize(int physicComponentId, int axis, float value) { auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); @@ -1757,21 +1827,230 @@ bool CPhysicDebugGUI::UpdateRigidBodyConfigSize(int physicComponentId, int axis, if (pPhysicObject) { - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); - auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); - if (pRigidBodyConfig && pPhysicObjectConfig) + if (pPhysicComponent->IsRigidBody()) { - if (pRigidBodyConfig->collisionShape) + auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(pPhysicComponent->GetPhysicConfigId()); + + if (pRigidBodyConfig && pPhysicObjectConfig) { - pRigidBodyConfig->collisionShape->size[axis] += value; + if (pRigidBodyConfig->collisionShape) + { + pRigidBodyConfig->collisionShape->size[axis] += value; + pRigidBodyConfig->collisionShape->configModified = true; + } + + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); } + } + } + } - return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + return false; +} + +bool CPhysicDebugGUI::OpenEditConstraintDialog(uint64 physicObjectId, int physicObjectConfigId, int rigidBodyConfigId) +{ + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(physicObjectConfigId); + + if (!pPhysicObjectConfig) + return false; + + auto pConstraintConfig = UTIL_GetConstraintConfigFromConfigId(rigidBodyConfigId); + + if (!pConstraintConfig) + return false; + + auto dialog = new CConstraintEditDialog(this, "ConstraintEditDialog", physicObjectId, pPhysicObjectConfig, pConstraintConfig); + dialog->AddActionSignalTarget(this); + dialog->DoModal(); + + return true; +} + +void CPhysicDebugGUI::OnEditConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + if (OpenEditConstraintDialog(physicObjectId, physicObjectConfigId, constraintConfigId)) + { + ClientPhysicManager()->SetSelectedPhysicComponentId(physicComponentId); + } +} + +void CPhysicDebugGUI::OnMoveConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + ClientPhysicManager()->SetSelectedPhysicComponentId(physicComponentId); + UpdateEditMode(PhysicEditMode::Move); +} + +void CPhysicDebugGUI::OnRotateConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + ClientPhysicManager()->SetSelectedPhysicComponentId(physicComponentId); + UpdateEditMode(PhysicEditMode::Rotate); +} + +void CPhysicDebugGUI::OnResizeConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + ClientPhysicManager()->SetSelectedPhysicComponentId(physicComponentId); + UpdateEditMode(PhysicEditMode::Resize); +} + +void CPhysicDebugGUI::OnCloneConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(physicObjectConfigId); + + if (!pPhysicObjectConfig) + return; + + if (!(pPhysicObjectConfig->flags & PhysicObjectFlag_FromConfig)) + return; + + auto pConstraintConfig = UTIL_GetConstraintConfigFromConfigId(constraintConfigId); + + if (!pConstraintConfig) + return; + + auto pClonedConstraintConfig = UTIL_CloneConstraintConfig(pConstraintConfig.get()); + + pClonedConstraintConfig->name = std::format("{0}_Clone ({1})", pConstraintConfig->name, pClonedConstraintConfig->configId); + + pClonedConstraintConfig->configModified = true; + + pPhysicObjectConfig->ConstraintConfigs.emplace_back(pClonedConstraintConfig); + + pPhysicObjectConfig->configModified = true; + + ClientPhysicManager()->AddPhysicConfig(pClonedConstraintConfig->configId, pClonedConstraintConfig); + + //Update PhysicObject + + auto pPhysicObject = ClientPhysicManager()->GetPhysicObjectEx(physicObjectId); + + if (pPhysicObject->Rebuild(pPhysicObjectConfig.get())) + { + int clonedConstraintId = 0; + + pPhysicObject->EnumPhysicComponents([pClonedConstraintConfig, &clonedConstraintId](IPhysicComponent* pPhysicCompoent) { + + if (pPhysicCompoent->GetPhysicConfigId() == pClonedConstraintConfig->configId) + { + clonedConstraintId = pPhysicCompoent->GetPhysicComponentId(); + return true; + } + + return false; + }); + + if (clonedConstraintId) { + ClientPhysicManager()->SetSelectedPhysicComponentId(clonedConstraintId); + } + } +} + +bool CPhysicDebugGUI::DeleteConstraintByComponent(IPhysicComponent *pPhysicComponent) +{ + if (pPhysicComponent && pPhysicComponent->IsConstraint()) + { + auto pPhysicObject = pPhysicComponent->GetOwnerPhysicObject(); + + if (pPhysicObject) + { + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + + if (pPhysicObjectConfig) + { + if (!(pPhysicObjectConfig->flags & PhysicObjectFlag_FromConfig)) + return false; + + if (UTIL_RemoveConstraintFromPhysicObjectConfig(pPhysicObjectConfig.get(), pPhysicComponent->GetPhysicConfigId())) + { + return pPhysicObject->Rebuild(pPhysicObjectConfig.get()); + } } } } return false; +} + +bool CPhysicDebugGUI::DeleteConstraintByComponentId(int physicComponentId) +{ + auto pPhysicComponent = ClientPhysicManager()->GetPhysicComponent(physicComponentId); + + if (pPhysicComponent) + { + return DeleteConstraintByComponent(pPhysicComponent); + } + + return false; +} + +void CPhysicDebugGUI::OnDeleteConstraintEx(KeyValues* kv) +{ + auto physicObjectId = kv->GetUint64("physicObjectId"); + auto physicObjectConfigId = kv->GetInt("physicObjectConfigId"); + auto physicComponentId = kv->GetInt("physicComponentId"); + auto constraintConfigId = kv->GetInt("constraintConfigId"); + + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(physicObjectConfigId); + + if (pPhysicObjectConfig) + { + if (UTIL_RemoveConstraintFromPhysicObjectConfig(pPhysicObjectConfig.get(), constraintConfigId)) + { + ClientPhysicManager()->RebuildPhysicObjectEx(physicObjectId, pPhysicObjectConfig.get()); + } + } +} + +void CPhysicDebugGUI::OnCreateConstraint(uint64 physicObjectId) +{ + auto pPhysicObject = ClientPhysicManager()->GetPhysicObjectEx(physicObjectId); + + if (!pPhysicObject) + return; + + auto pPhysicObjectConfig = UTIL_GetPhysicObjectConfigFromConfigId(pPhysicObject->GetPhysicConfigId()); + + if (!pPhysicObjectConfig) + return; + + if (!(pPhysicObjectConfig->flags & PhysicObjectFlag_FromConfig)) + return; + + auto pConstraintConfig = std::make_shared(); + pConstraintConfig->name = std::format("UnnamedConstraint_{0}", pConstraintConfig->configId); + pConstraintConfig->configModified = true; + + pPhysicObjectConfig->ConstraintConfigs.push_back(pConstraintConfig); + pPhysicObjectConfig->configModified = true; + + ClientPhysicManager()->AddPhysicConfig(pConstraintConfig->configId, pConstraintConfig); + + ClientPhysicManager()->RebuildPhysicObjectEx(physicObjectId, pPhysicObjectConfig.get()); } \ No newline at end of file diff --git a/Plugins/BulletPhysics/PhysicDebugGUI.h b/Plugins/BulletPhysics/PhysicDebugGUI.h index 99be7570..94e77385 100644 --- a/Plugins/BulletPhysics/PhysicDebugGUI.h +++ b/Plugins/BulletPhysics/PhysicDebugGUI.h @@ -24,6 +24,8 @@ enum class PhysicEditMode Resize }; +class IPhysicComponent; + class CPhysicDebugGUI : public vgui::Frame { DECLARE_CLASS_SIMPLE(CPhysicDebugGUI, vgui::Frame); @@ -46,8 +48,10 @@ class CPhysicDebugGUI : public vgui::Frame MESSAGE_FUNC_UINT64(OnCreateStaticObject, "CreateStaticObject", physicObjectId); MESSAGE_FUNC_UINT64(OnCreateDynamicObject, "CreateDynamicObject", physicObjectId); MESSAGE_FUNC_UINT64(OnCreateRagdollObject, "CreateRagdollObject", physicObjectId); - MESSAGE_FUNC_UINT64(OnCreateRigidBody, "CreateRigidBody", physicObjectId); + MESSAGE_FUNC_PARAMS(OnEditPhysicObject, "EditPhysicObject", kv); + + MESSAGE_FUNC_UINT64(OnCreateRigidBody, "CreateRigidBody", physicObjectId); MESSAGE_FUNC_PARAMS(OnEditRigidBodyEx, "EditRigidBodyEx", kv); MESSAGE_FUNC_PARAMS(OnMoveRigidBodyEx, "MoveRigidBodyEx", kv); MESSAGE_FUNC_PARAMS(OnRotateRigidBodyEx, "RotateRigidBodyEx", kv); @@ -55,6 +59,14 @@ class CPhysicDebugGUI : public vgui::Frame MESSAGE_FUNC_PARAMS(OnCloneRigidBodyEx, "CloneRigidBodyEx", kv); MESSAGE_FUNC_PARAMS(OnDeleteRigidBodyEx, "DeleteRigidBodyEx", kv); + MESSAGE_FUNC_UINT64(OnCreateConstraint, "CreateConstraint", physicObjectId); + MESSAGE_FUNC_PARAMS(OnEditConstraintEx, "EditConstraintEx", kv); + MESSAGE_FUNC_PARAMS(OnMoveConstraintEx, "MoveConstraintEx", kv); + MESSAGE_FUNC_PARAMS(OnRotateConstraintEx, "RotateConstraintEx", kv); + MESSAGE_FUNC_PARAMS(OnResizeConstraintEx, "ResizeConstraintEx", kv); + MESSAGE_FUNC_PARAMS(OnCloneConstraintEx, "CloneConstraintEx", kv); + MESSAGE_FUNC_PARAMS(OnDeleteConstraintEx, "DeleteConstraintEx", kv); + void OnThink() override; void PerformLayout(void) override; void ApplySchemeSettings(vgui::IScheme* pScheme) override; @@ -68,10 +80,14 @@ class CPhysicDebugGUI : public vgui::Frame void SaveOpenPrompt(); void SaveConfirm(); + bool DeleteRigidBodyByComponent(IPhysicComponent* pPhysicComponent); bool DeleteRigidBodyByComponentId(int physicComponentId); + bool DeleteConstraintByComponent(IPhysicComponent* pPhysicComponent); + bool DeleteConstraintByComponentId(int physicComponentId); bool OpenEditPhysicObjectDialog(uint64 physicObjectId); bool OpenEditPhysicObjectDialogEx(uint64 physicObjectId, int physicObjectConfigId); bool OpenEditRigidBodyDialog(uint64 physicObjectId, int physicObjectConfigId, int rigidBodyConfigId); + bool OpenEditConstraintDialog(uint64 physicObjectId, int physicObjectConfigId, int constraintConfigId); bool UpdateInspectedClientEntity(bool bSelected); bool UpdateInspectedPhysicObject(bool bSelected); @@ -93,9 +109,9 @@ class CPhysicDebugGUI : public vgui::Frame void ShowInspectContentLabel3(const wchar_t* wszText); void HideInspectContentLabel3(); - bool UpdateRigidBodyConfigOrigin(int physicComponentId, int axis, float value); - bool UpdateRigidBodyConfigAngles(int physicComponentId, int axis, float value); - bool UpdateRigidBodyConfigSize(int physicComponentId, int axis, float value); + bool UpdateConfigOrigin(int physicComponentId, int axis, float value); + bool UpdateConfigAngles(int physicComponentId, int axis, float value); + bool UpdateConfigSize(int physicComponentId, int axis, float value); void LoadAvailableInspectModeIntoControls(); void LoadAvailableEditModeIntoControls(); diff --git a/Plugins/BulletPhysics/PhysicEditorDialog.cpp b/Plugins/BulletPhysics/PhysicEditorDialog.cpp index cc8ca6c2..7ecfe925 100644 --- a/Plugins/BulletPhysics/PhysicEditorDialog.cpp +++ b/Plugins/BulletPhysics/PhysicEditorDialog.cpp @@ -1,9 +1,4 @@ #include "PhysicEditorDialog.h" -#include - -#include -#include -#include #include "exportfuncs.h" @@ -12,1130 +7,6 @@ #include -//RigidBody List - -CRigidBodyListPanel::CRigidBodyListPanel(vgui::Panel* parent, const char* pName) : BaseClass(parent, pName) -{ - -} - -CBaseObjectConfigPage::CBaseObjectConfigPage(vgui::Panel* parent, const char* name, uint64 physicObjectId, const std::shared_ptr& pPhysicObjectConfig) : - BaseClass(parent, name), m_physicObjectId(physicObjectId), m_pPhysicObjectConfig(pPhysicObjectConfig) -{ - SetSize(vgui::scheme()->GetProportionalScaledValue(624), vgui::scheme()->GetProportionalScaledValue(300)); - - m_pStaticObject = new vgui::CheckButton(this, "StaticObject", "#BulletPhysics_StaticObject"); - m_pDynamicObject = new vgui::CheckButton(this, "DynamicObject", "#BulletPhysics_DynamicObject"); - m_pRagdollObject = new vgui::CheckButton(this, "RagdollObject", "#BulletPhysics_RagdollObject"); - m_pFromBSP = new vgui::CheckButton(this, "FromBSP", "#BulletPhysics_FromBSP"); - m_pFromConfig = new vgui::CheckButton(this, "FromConfig", "#BulletPhysics_FromConfig"); - m_pBarnacle = new vgui::CheckButton(this, "Barnacle", "#BulletPhysics_Barnacle"); - m_pGargantua = new vgui::CheckButton(this, "Gargantua", "#BulletPhysics_Gargantua"); - - m_pDebugDrawLevel = new vgui::TextEntry(this, "DebugDrawLevel"); - - LoadControlSettings("bulletphysics/BaseObjectConfigPage.res", "GAME"); - - vgui::ivgui()->AddTickSignal(GetVPanel()); - - vgui::ipanel()->SendMessage(GetVPanel(), new KeyValues("ResetData"), GetVPanel()); -} - -void CBaseObjectConfigPage::OnApplyChanges() -{ - SaveConfigFromControls(); -} - -void CBaseObjectConfigPage::OnResetData() -{ - LoadConfigIntoControls(); -} - -void CBaseObjectConfigPage::ApplySchemeSettings(vgui::IScheme* pScheme) -{ - BaseClass::ApplySchemeSettings(pScheme); - - m_hFont = pScheme->GetFont("ListSmall", IsProportional()); - - if (!m_hFont) - m_hFont = pScheme->GetFont("DefaultSmall", IsProportional()); - - //m_pRigidBodyListPanel->SetFont(m_hFont); -} - -void CBaseObjectConfigPage::OnKeyCodeTyped(vgui::KeyCode code) -{ - if (code == vgui::KEY_ENTER) - { - - } - - BaseClass::OnKeyCodeTyped(code); -} - -void CBaseObjectConfigPage::OnCommand(const char* command) -{ - if (!stricmp(command, "OK")) - { - - } - else - { - BaseClass::OnCommand(command); - } -} - -void CBaseObjectConfigPage::LoadConfigIntoControls() -{ -#define LOAD_INTO_TEXT_ENTRY(from, to) { auto str##to = std::format("{0}", m_pPhysicObjectConfig->from); m_p##to->SetText(str##to.c_str());} - LOAD_INTO_TEXT_ENTRY(debugDrawLevel, DebugDrawLevel); -#undef LOAD_INTO_TEXT_ENTRY - -#define LOAD_INTO_CHECK_BUTTON(from, to) m_p##to->SetSelected((m_pPhysicObjectConfig->from & PhysicObjectFlag_##to) ? true : false); - LOAD_INTO_CHECK_BUTTON(flags, StaticObject); - LOAD_INTO_CHECK_BUTTON(flags, DynamicObject); - LOAD_INTO_CHECK_BUTTON(flags, RagdollObject); - LOAD_INTO_CHECK_BUTTON(flags, FromBSP); - LOAD_INTO_CHECK_BUTTON(flags, FromConfig); - LOAD_INTO_CHECK_BUTTON(flags, Barnacle); - LOAD_INTO_CHECK_BUTTON(flags, Gargantua); -#undef LOAD_INTO_CHECK_BUTTON -} - -void CBaseObjectConfigPage::SaveConfigFromControls() -{ - char szText[256]; -#define SAVE_FROM_TEXT_ENTRY(to, from, processor) {m_p##from->GetText(szText, sizeof(szText)); m_pPhysicObjectConfig->to = processor(szText);} - - SAVE_FROM_TEXT_ENTRY(debugDrawLevel, DebugDrawLevel, atoi); - -#undef SAVE_FROM_TEXT_ENTRY - -#define SAVE_FROM_CHECK_BUTTON(to, from) if (m_p##from->IsSelected()) { m_pPhysicObjectConfig->to |= PhysicObjectFlag_##from; } else { m_pPhysicObjectConfig->to &= ~PhysicObjectFlag_##from; } - SAVE_FROM_CHECK_BUTTON(flags, Barnacle); - SAVE_FROM_CHECK_BUTTON(flags, Gargantua); -#undef SAVE_FROM_CHECK_BUTTON - - m_pPhysicObjectConfig->configModified = true; -} - -CRigidBodyPage::CRigidBodyPage(vgui::Panel* parent, const char* name, uint64 physicObjectId, const std::shared_ptr& pPhysicObjectConfig) : - BaseClass(parent, name), m_physicObjectId(physicObjectId), m_pPhysicObjectConfig(pPhysicObjectConfig) -{ - SetSize(vgui::scheme()->GetProportionalScaledValue(624), vgui::scheme()->GetProportionalScaledValue(300)); - - m_pRigidBodyListPanel = new CRigidBodyListPanel(this, "RigidBodyListPanel"); - - m_pRigidBodyListPanel->AddColumnHeader(0, "index", "#BulletPhysics_Index", vgui::scheme()->GetProportionalScaledValue(40), vgui::ListPanel::COLUMN_HIDDEN); - m_pRigidBodyListPanel->AddColumnHeader(1, "configId", "#BulletPhysics_ConfigId", vgui::scheme()->GetProportionalScaledValue(40), vgui::ListPanel::COLUMN_HIDDEN); - m_pRigidBodyListPanel->AddColumnHeader(2, "name", "#BulletPhysics_Name", vgui::scheme()->GetProportionalScaledValue(120), vgui::ListPanel::COLUMN_FIXEDSIZE); - m_pRigidBodyListPanel->AddColumnHeader(3, "shape","#BulletPhysics_Shape", vgui::scheme()->GetProportionalScaledValue(60), vgui::ListPanel::COLUMN_FIXEDSIZE); - m_pRigidBodyListPanel->AddColumnHeader(4, "bone", "#BulletPhysics_Bone", vgui::scheme()->GetProportionalScaledValue(180), vgui::ListPanel::COLUMN_FIXEDSIZE); - m_pRigidBodyListPanel->AddColumnHeader(5, "mass", "#BulletPhysics_Mass", vgui::scheme()->GetProportionalScaledValue(60), vgui::ListPanel::COLUMN_FIXEDSIZE); - m_pRigidBodyListPanel->AddColumnHeader(6, "flags", "#BulletPhysics_Flags", vgui::scheme()->GetProportionalScaledValue(80), vgui::ListPanel::COLUMN_RESIZEWITHWINDOW); - m_pRigidBodyListPanel->SetSortColumn(0); - m_pRigidBodyListPanel->SetMultiselectEnabled(false); - - m_pShiftUpRigidBody = new vgui::Button(this, "ShiftUpRigidBody", L"#BulletPhysics_ShiftUp", this, "ShiftUpRigidBody"); - m_pShiftDownRigidBody = new vgui::Button(this, "ShiftDownRigidBody", L"#BulletPhysics_ShiftDown", this, "ShiftDownRigidBody"); - m_pCreateRigidBody = new vgui::Button(this, "CreateRigidBody", L"#BulletPhysics_CreateRigidBody", this, "CreateRigidBody"); - - LoadControlSettings("bulletphysics/RigidBodyPage.res", "GAME"); - - vgui::ivgui()->AddTickSignal(GetVPanel()); - - vgui::ipanel()->SendMessage(GetVPanel(), new KeyValues("ResetData"), GetVPanel()); -} - -void CRigidBodyPage::OnResetData() -{ - ReloadAllRigidBodiesIntoListPanelItem(); -} - -void CRigidBodyPage::ApplySchemeSettings(vgui::IScheme* pScheme) -{ - BaseClass::ApplySchemeSettings(pScheme); - - m_hFont = pScheme->GetFont("ListSmall", IsProportional()); - - if (!m_hFont) - m_hFont = pScheme->GetFont("DefaultSmall", IsProportional()); - - m_pRigidBodyListPanel->SetFont(m_hFont); -} - -void CRigidBodyPage::OnKeyCodeTyped(vgui::KeyCode code) -{ - if (code == vgui::KEY_ENTER) - { - if (m_pRigidBodyListPanel->GetSelectedItemsCount() > 0) - { - auto selectItemId = m_pRigidBodyListPanel->GetSelectedItem(0); - - auto configId = m_pRigidBodyListPanel->GetItemUserData(selectItemId); - - OnOpenRigidBodyEditor(configId); - - return; - } - } - - BaseClass::OnKeyCodeTyped(code); -} - -void CRigidBodyPage::OnCommand(const char* command) -{ - if (!stricmp(command, "OK")) - { - - } - else if (!stricmp(command, "CreateRigidBody")) - { - OnCreateRigidBody(); - } - else if (!stricmp(command, "ShiftUpRigidBody")) - { - auto selectItemId = m_pRigidBodyListPanel->GetSelectedItem(0); - - auto configId = m_pRigidBodyListPanel->GetItemUserData(selectItemId); - - OnShiftUpRigidBody(configId); - } - else if (!stricmp(command, "ShiftDownRigidBody")) - { - auto selectItemId = m_pRigidBodyListPanel->GetSelectedItem(0); - - auto configId = m_pRigidBodyListPanel->GetItemUserData(selectItemId); - - OnShiftDownRigidBody(configId); - } - else - { - BaseClass::OnCommand(command); - } -} - -void CRigidBodyPage::OnOpenContextMenu(int itemId) -{ - if (!m_pRigidBodyListPanel->GetSelectedItemsCount()) - return; - - auto selectItemId = m_pRigidBodyListPanel->GetSelectedItem(0); - - auto configId = m_pRigidBodyListPanel->GetItemUserData(selectItemId); - - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(configId); - - if (!pRigidBodyConfig) - return; - - auto menu = new vgui::Menu(this, "contextmenu"); - - menu->SetAutoDelete(true); - - wchar_t szName[64] = { 0 }; - wchar_t szBuf[256] = { 0 }; - vgui::localize()->ConvertANSIToUnicode(pRigidBodyConfig->name.c_str(), szName, sizeof(szName)); - - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_EditRigidBody"), 1, szName); - menu->AddMenuItem("EditRigidBody", szBuf, new KeyValues("EditRigidBody", "configId", configId), this); - - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_CloneRigidBody"), 1, szName); - menu->AddMenuItem("CloneRigidBody", szBuf, new KeyValues("CloneRigidBody", "configId", configId), this); - - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_ShiftUpRigidBody"), 1, szName); - menu->AddMenuItem("ShiftUpRigidBody", szBuf, new KeyValues("ShiftUpRigidBody", "configId", configId), this); - - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_ShiftDownRigidBody"), 1, szName); - menu->AddMenuItem("ShiftDownRigidBody", szBuf, new KeyValues("ShiftDownRigidBody", "configId", configId), this); - - vgui::localize()->ConstructString(szBuf, sizeof(szBuf), vgui::localize()->Find("#BulletPhysics_DeleteRigidBody"), 1, szName); - menu->AddMenuItem("DeleteRigidBody", szBuf, new KeyValues("DeleteRigidBody", "configId", configId), this); - - vgui::Menu::PlaceContextMenu(this, menu); -} - -void CRigidBodyPage::OnOpenRigidBodyEditor(int configId) -{ - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(configId); - - if (!pRigidBodyConfig) - return; - - auto dialog = new CRigidBodyEditDialog(this, "RigidBodyEditDialog", m_physicObjectId, m_pPhysicObjectConfig, pRigidBodyConfig); - dialog->AddActionSignalTarget(this); - dialog->DoModal(); -} - -void CRigidBodyPage::OnEditRigidBody(int configId) -{ - OnOpenRigidBodyEditor(configId); -} - -void CRigidBodyPage::OnRefreshRigidBody(int configId) -{ - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(configId); - - if (!pRigidBodyConfig) - return; - - DeleteRigidBodyItem(configId); - - LoadRigidBodyAsListPanelItem(pRigidBodyConfig.get()); -} - -void CRigidBodyPage::OnRefreshRigidBodies() -{ - ReloadAllRigidBodiesIntoListPanelItem(); -} - -void CRigidBodyPage::LoadRigidBodyAsListPanelItem(const CClientRigidBodyConfig * pRigidBodyConfig) -{ - auto kv = new KeyValues("RigidBody"); - - kv->SetInt("index", UTIL_GetRigidBodyIndex(m_pPhysicObjectConfig.get(), pRigidBodyConfig)); - - kv->SetInt("configId", pRigidBodyConfig->configId); - - kv->SetString("name", pRigidBodyConfig->name.c_str()); - - std::wstring shape = pRigidBodyConfig->collisionShape ? UTIL_GetCollisionShapeTypeLocalizedName(pRigidBodyConfig->collisionShape->type) : L"--"; - - kv->SetWString("shape", shape.c_str()); - - auto modelindex = UNPACK_PHYSIC_OBJECT_ID_TO_MODELINDEX(m_physicObjectId); - - auto bone = UTIL_GetFormattedBoneName(modelindex, pRigidBodyConfig->boneindex); - - kv->SetString("bone", bone.c_str()); - - kv->SetFloat("mass", pRigidBodyConfig->mass); - - auto flags = UTIL_GetFormattedRigidBodyFlags(pRigidBodyConfig->flags); - - kv->SetWString("flags", flags.c_str()); - - m_pRigidBodyListPanel->AddItem(kv, pRigidBodyConfig->configId, false, true); - - kv->deleteThis(); -} - -void CRigidBodyPage::ReloadAllRigidBodiesIntoListPanelItem() -{ - m_pRigidBodyListPanel->RemoveAll(); - - for (const auto &pConfig : m_pPhysicObjectConfig->RigidBodyConfigs) - { - LoadRigidBodyAsListPanelItem(pConfig.get()); - } -} - -void CRigidBodyPage::SelectRigidBodyItem(int configId) -{ - for (int i = 0; i < m_pRigidBodyListPanel->GetItemCount(); ++i) - { - auto userData = m_pRigidBodyListPanel->GetItemUserData(i); - - if (userData == configId) - { - m_pRigidBodyListPanel->SetSingleSelectedItem(i); - break; - } - } -} - -void CRigidBodyPage::DeleteRigidBodyItem(int configId) -{ - for (int i = 0; i < m_pRigidBodyListPanel->GetItemCount(); ++i) - { - auto userData = m_pRigidBodyListPanel->GetItemUserData(i); - - if (userData == configId) - { - m_pRigidBodyListPanel->RemoveItem(i); - break; - } - } -} - -void CRigidBodyPage::OnShiftUpRigidBody(int configId) -{ - if (UTIL_ShiftUpRigidBodyIndex(m_pPhysicObjectConfig.get(), configId)) - { - ReloadAllRigidBodiesIntoListPanelItem(); - SelectRigidBodyItem(configId); - } -} - -void CRigidBodyPage::OnShiftDownRigidBody(int configId) -{ - if (UTIL_ShiftDownRigidBodyIndex(m_pPhysicObjectConfig.get(), configId)) - { - ReloadAllRigidBodiesIntoListPanelItem(); - SelectRigidBodyItem(configId); - } -} - -void CRigidBodyPage::OnCreateRigidBody() -{ - auto pRigidBodyConfig = std::make_shared(); - - pRigidBodyConfig->name = std::format("Unnamed ({0})", pRigidBodyConfig->configId); - - pRigidBodyConfig->collisionShape = std::make_shared(); - pRigidBodyConfig->collisionShape->type = PhysicShape_Sphere; - pRigidBodyConfig->collisionShape->size[0] = 3; - pRigidBodyConfig->collisionShape->configModified = true; - - pRigidBodyConfig->configModified = true; - - m_pPhysicObjectConfig->RigidBodyConfigs.emplace_back(pRigidBodyConfig); - - m_pPhysicObjectConfig->configModified = true; - - ClientPhysicManager()->AddPhysicConfig(pRigidBodyConfig->configId, pRigidBodyConfig); - - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - - LoadRigidBodyAsListPanelItem(pRigidBodyConfig.get()); -} - -void CRigidBodyPage::OnCloneRigidBody(int configId) -{ - auto pRigidBodyConfig = UTIL_GetRigidConfigFromConfigId(configId); - - if (!pRigidBodyConfig) - return; - - auto pClonedRigidBodyConfig = UTIL_CloneRigidBodyConfig(pRigidBodyConfig.get()); - - pClonedRigidBodyConfig->name = std::format("{0}_Clone ({1})", pRigidBodyConfig->name, pClonedRigidBodyConfig->configId); - - pClonedRigidBodyConfig->configModified = true; - - m_pPhysicObjectConfig->RigidBodyConfigs.emplace_back(pClonedRigidBodyConfig); - - m_pPhysicObjectConfig->configModified = true; - - ClientPhysicManager()->AddPhysicConfig(pClonedRigidBodyConfig->configId, pClonedRigidBodyConfig); - - LoadRigidBodyAsListPanelItem(pClonedRigidBodyConfig.get()); - - //Update PhysicObject - - auto pPhysicObject = ClientPhysicManager()->GetPhysicObjectEx(m_physicObjectId); - - if (pPhysicObject->Rebuild(m_pPhysicObjectConfig.get())) - { - int clonedRigidBodyId = 0; - - pPhysicObject->EnumPhysicComponents([pClonedRigidBodyConfig, &clonedRigidBodyId](IPhysicComponent* pPhysicCompoent) { - - if (pPhysicCompoent->GetPhysicConfigId() == pClonedRigidBodyConfig->configId) - { - clonedRigidBodyId = pPhysicCompoent->GetPhysicComponentId(); - return true; - } - - return false; - }); - - if (clonedRigidBodyId) { - ClientPhysicManager()->SetSelectedPhysicComponentId(clonedRigidBodyId); - } - } -} - -void CRigidBodyPage::OnDeleteRigidBody(int configId) -{ - for (int i = 0; i < m_pRigidBodyListPanel->GetItemCount(); ++i) - { - auto userData = m_pRigidBodyListPanel->GetItemUserData(i); - - if (userData == configId) - { - m_pRigidBodyListPanel->RemoveItem(i); - break; - } - } - - if (UTIL_RemoveRigidBodyFromPhysicObjectConfig(m_pPhysicObjectConfig.get(), configId)) - { - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - } -} - -//CollisionShape Editor - -CCollisionShapeEditDialog::CCollisionShapeEditDialog(vgui::Panel* parent, const char* name, - uint64 physicObjectId, - const std::shared_ptr& pPhysicObjectConfig, - const std::shared_ptr& pRigidBodyConfig, - const std::shared_ptr& pCollisionShapeConfig) : - BaseClass(parent, name), - m_physicObjectId(physicObjectId), - m_pPhysicObjectConfig(pPhysicObjectConfig), - m_pRigidBodyConfig(pRigidBodyConfig), - m_pCollisionShapeConfig(pCollisionShapeConfig) -{ - SetDeleteSelfOnClose(true); - - SetTitle("#BulletPhysics_CollisionShapeEditor", false); - - SetMinimumSize(vgui::scheme()->GetProportionalScaledValue(350), vgui::scheme()->GetProportionalScaledValue(350)); - SetSize(vgui::scheme()->GetProportionalScaledValue(350), vgui::scheme()->GetProportionalScaledValue(350)); - - m_pShape = new vgui::ComboBox(this, "Shape", 0, false); - m_pShape->AddActionSignalTarget(this); - - m_pDirectionLabel = new vgui::Label(this, "DirectionLabel", "#BulletPhysics_Direction"); - m_pDirection = new vgui::ComboBox(this, "Direction", 0, false); - - m_pSizeLabel = new vgui::Label(this, "SizeLabel", "#BulletPhysics_Size"); - m_pSizeX = new vgui::TextEntry(this, "SizeX"); - m_pSizeY = new vgui::TextEntry(this, "SizeY"); - m_pSizeZ = new vgui::TextEntry(this, "SizeZ"); - - m_pOriginLabel = new vgui::Label(this, "OriginLabel", "#BulletPhysics_Origin"); - m_pOriginX = new vgui::TextEntry(this, "OriginX"); - m_pOriginY = new vgui::TextEntry(this, "OriginY"); - m_pOriginZ = new vgui::TextEntry(this, "OriginZ"); - - m_pAnglesLabel = new vgui::Label(this, "AnglesLabel", "#BulletPhysics_Angles"); - m_pAnglesX = new vgui::TextEntry(this, "AnglesX"); - m_pAnglesY = new vgui::TextEntry(this, "AnglesY"); - m_pAnglesZ = new vgui::TextEntry(this, "AnglesZ"); - - m_pResourcePathLabel = new vgui::Label(this, "ResourcePathLabel", "#BulletPhysics_ResourcePath"); - m_pResourcePath = new vgui::TextEntry(this, "ResourcePath"); - - LoadAvailableShapesIntoControls(); - LoadAvailableShapeDirectionsIntoControls(); - - LoadControlSettings("bulletphysics/CollisionShapeEditDialog.res", "GAME"); - - vgui::ivgui()->AddTickSignal(GetVPanel()); - -} - -CCollisionShapeEditDialog::~CCollisionShapeEditDialog() -{ - -} - -void CCollisionShapeEditDialog::Activate(void) -{ - BaseClass::Activate(); - - vgui::ipanel()->SendMessage(GetVPanel(), new KeyValues("ResetData"), GetVPanel()); -} - -void CCollisionShapeEditDialog::OnResetData() -{ - LoadConfigIntoControls(); - - UpdateControlStates(); -} - -void CCollisionShapeEditDialog::OnTextChanged(vgui::Panel *panel) -{ - if (panel == m_pShape) { - UpdateControlStates(); - } -} - -void CCollisionShapeEditDialog::OnCommand(const char* command) -{ - if (!stricmp(command, "OK")) - { - SaveConfigFromControls(); - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - PostActionSignal(new KeyValues("RefreshCollisionShape")); - Close(); - return; - } - else if (!stricmp(command, "Apply")) - { - SaveConfigFromControls(); - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - PostActionSignal(new KeyValues("RefreshCollisionShape")); - return; - } - - BaseClass::OnCommand(command); -} - -void CCollisionShapeEditDialog::LoadAvailableShapesIntoControls() -{ - for (int i = 0; i < PhysicShape_Maximum; ++i) - { - auto kv = new KeyValues("UserData"); - - kv->SetInt("type", i); - - m_pShape->AddItem(UTIL_GetCollisionShapeTypeLocalizationToken(i), kv); - - kv->deleteThis(); - } -} - -void CCollisionShapeEditDialog::LoadShapeIntoControls() -{ - for (int i = 0; i < m_pShape->GetItemCount(); ++i) - { - KeyValues* kv = m_pShape->GetItemUserData(i); - - if (kv && m_pCollisionShapeConfig->type == kv->GetInt("type", PhysicShape_None)) - { - m_pShape->ActivateItemByRow(i); - return; - } - } - - m_pShape->ActivateItemByRow(0); -} - -void CCollisionShapeEditDialog::LoadAvailableShapeDirectionsIntoControls() -{ - for (int i = 0; i < PhysicShapeDirection_Maximum; ++i) - { - auto kv = new KeyValues("UserData"); - - kv->SetInt("direction", i); - - const char* XYZ[] = { "X", "Y", "Z" }; - - m_pDirection->AddItem(XYZ[i], kv); - - kv->deleteThis(); - } -} - -void CCollisionShapeEditDialog::LoadShapeDirectionIntoControls() -{ - for (int i = 0; i < m_pDirection->GetItemCount(); ++i) - { - KeyValues* kv = m_pDirection->GetItemUserData(i); - - if (kv && m_pCollisionShapeConfig->direction == kv->GetInt("direction", PhysicShapeDirection_X)) - { - m_pDirection->ActivateItemByRow(i); - return; - } - } - - m_pDirection->ActivateItemByRow(0); -} - -void CCollisionShapeEditDialog::LoadConfigIntoControls() -{ - LoadShapeIntoControls(); - - LoadShapeDirectionIntoControls(); - - auto sizeX = std::format("{0}", m_pCollisionShapeConfig->size[0]); - m_pSizeX->SetText(sizeX.c_str()); - - auto sizeY = std::format("{0}", m_pCollisionShapeConfig->size[1]); - m_pSizeY->SetText(sizeY.c_str()); - - auto sizeZ = std::format("{0}", m_pCollisionShapeConfig->size[2]); - m_pSizeZ->SetText(sizeZ.c_str()); - - auto originX = std::format("{0}", m_pCollisionShapeConfig->origin[0]); - m_pOriginX->SetText(originX.c_str()); - - auto originY = std::format("{0}", m_pCollisionShapeConfig->origin[1]); - m_pOriginY->SetText(originY.c_str()); - - auto originZ = std::format("{0}", m_pCollisionShapeConfig->origin[2]); - m_pOriginZ->SetText(originZ.c_str()); - - auto anglesX = std::format("{0}", m_pCollisionShapeConfig->angles[0]); - m_pAnglesX->SetText(anglesX.c_str()); - - auto anglesY = std::format("{0}", m_pCollisionShapeConfig->angles[1]); - m_pAnglesY->SetText(anglesY.c_str()); - - auto anglesZ = std::format("{0}", m_pCollisionShapeConfig->angles[2]); - m_pAnglesZ->SetText(anglesZ.c_str()); - - m_pResourcePath->SetText(m_pCollisionShapeConfig->resourcePath.c_str()); -} - -void CCollisionShapeEditDialog::SaveConfigFromControls() -{ - m_pCollisionShapeConfig->type = GetCurrentSelectedShapeType(); - m_pCollisionShapeConfig->direction = GetCurrentSelectedShapeDirection(); - - char szText[256] = { 0 }; - -#define SAVE_FLOAT_FROM_TEXT_ENTRY(from, to, processor) {m_p##from->GetText(szText, sizeof(szText)); m_pCollisionShapeConfig->to = processor(szText); } - - SAVE_FLOAT_FROM_TEXT_ENTRY(SizeX, size[0], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(SizeY, size[1], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(SizeZ, size[2], atof); - - SAVE_FLOAT_FROM_TEXT_ENTRY(OriginX, origin[0], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(OriginY, origin[1], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(OriginZ, origin[2], atof); - - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesX, angles[0], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesY, angles[1], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesZ, angles[2], atof); - - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesX, angles[0], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesY, angles[1], atof); - SAVE_FLOAT_FROM_TEXT_ENTRY(AnglesZ, angles[2], atof); - - SAVE_FLOAT_FROM_TEXT_ENTRY(ResourcePath, resourcePath, std::string); -#undef SAVE_FLOAT_FROM_TEXT_ENTRY - - m_pCollisionShapeConfig->configModified = true; -} - -int CCollisionShapeEditDialog::GetCurrentSelectedShapeType() -{ - int type = PhysicShape_None; - - auto pShapeKV = m_pShape->GetActiveItemUserData(); - - if (pShapeKV) - { - type = pShapeKV->GetInt("type", PhysicShape_None); - } - - return type; -} - -int CCollisionShapeEditDialog::GetCurrentSelectedShapeDirection() -{ - int direction = PhysicShapeDirection_X; - - auto pDirectionKV = m_pDirection->GetActiveItemUserData(); - - if (pDirectionKV) - { - direction = pDirectionKV->GetInt("direction", PhysicShapeDirection_X); - } - - return direction; -} - -void CCollisionShapeEditDialog::UpdateControlStates() -{ - switch (GetCurrentSelectedShapeType()) - { - case PhysicShape_Box: { - m_pDirectionLabel->SetVisible(false); - m_pDirection->SetVisible(false); - - m_pSizeLabel->SetVisible(true); - m_pSizeX->SetVisible(true); - m_pSizeY->SetVisible(true); - m_pSizeZ->SetVisible(true); - - m_pResourcePathLabel->SetVisible(false); - m_pResourcePath->SetVisible(false); - break; - } - case PhysicShape_Sphere: { - - m_pDirectionLabel->SetVisible(false); - m_pDirection->SetVisible(false); - - m_pSizeLabel->SetVisible(true); - m_pSizeX->SetVisible(true); - m_pSizeY->SetVisible(false); - m_pSizeZ->SetVisible(false); - - m_pResourcePathLabel->SetVisible(false); - m_pResourcePath->SetVisible(false); - break; - } - case PhysicShape_Capsule: - case PhysicShape_Cylinder: { - - m_pDirectionLabel->SetVisible(true); - m_pDirection->SetVisible(true); - - m_pSizeLabel->SetVisible(true); - m_pSizeX->SetVisible(true); - m_pSizeY->SetVisible(true); - m_pSizeZ->SetVisible(false); - - m_pResourcePathLabel->SetVisible(false); - m_pResourcePath->SetVisible(false); - break; - } - case PhysicShape_TriangleMesh: { - - m_pDirectionLabel->SetVisible(false); - m_pDirection->SetVisible(false); - - m_pSizeLabel->SetVisible(false); - m_pSizeX->SetVisible(false); - m_pSizeY->SetVisible(false); - m_pSizeZ->SetVisible(false); - - m_pResourcePathLabel->SetVisible(true); - m_pResourcePath->SetVisible(true); - break; - } - default:{ - - m_pDirectionLabel->SetVisible(false); - m_pDirection->SetVisible(false); - - m_pSizeLabel->SetVisible(false); - m_pSizeX->SetVisible(false); - m_pSizeY->SetVisible(false); - m_pSizeZ->SetVisible(false); - - m_pResourcePathLabel->SetVisible(false); - m_pResourcePath->SetVisible(false); - break; - } - } - - if (m_pCollisionShapeConfig->is_child) - { - m_pOriginLabel->SetVisible(true); - m_pOriginX->SetVisible(true); - m_pOriginY->SetVisible(true); - m_pOriginZ->SetVisible(true); - - m_pAnglesLabel->SetVisible(true); - m_pAnglesX->SetVisible(true); - m_pAnglesY->SetVisible(true); - m_pAnglesZ->SetVisible(true); - } - else - { - m_pOriginLabel->SetVisible(false); - m_pOriginX->SetVisible(false); - m_pOriginY->SetVisible(false); - m_pOriginZ->SetVisible(false); - - m_pAnglesLabel->SetVisible(false); - m_pAnglesX->SetVisible(false); - m_pAnglesY->SetVisible(false); - m_pAnglesZ->SetVisible(false); - } - -} - -//RigidBody Editor - -CRigidBodyEditDialog::CRigidBodyEditDialog(vgui::Panel* parent, const char* name, - uint64 physicObjectId, - const std::shared_ptr& pPhysicObjectConfig, - const std::shared_ptr& pRigidBodyConfig) : - BaseClass(parent, name), - m_physicObjectId(physicObjectId), - m_pPhysicObjectConfig(pPhysicObjectConfig), - m_pRigidBodyConfig(pRigidBodyConfig) -{ - SetDeleteSelfOnClose(true); - - SetTitle("#BulletPhysics_RigidBodyEditor", false); - - SetMinimumSize(vgui::scheme()->GetProportionalScaledValue(560), vgui::scheme()->GetProportionalScaledValue(560)); - SetSize(vgui::scheme()->GetProportionalScaledValue(560), vgui::scheme()->GetProportionalScaledValue(560)); - - m_pName = new vgui::TextEntry(this, "Name"); - m_pDebugDrawLevel = new vgui::TextEntry(this, "DebugDrawLevel"); - m_pBone = new vgui::ComboBox(this, "Bone", 0, false); - m_pShape = new vgui::ComboBox(this, "Shape", 0, false); - m_pOriginX = new vgui::TextEntry(this, "OriginX"); - m_pOriginY = new vgui::TextEntry(this, "OriginY"); - m_pOriginZ = new vgui::TextEntry(this, "OriginZ"); - m_pAnglesX = new vgui::TextEntry(this, "AnglesX"); - m_pAnglesY = new vgui::TextEntry(this, "AnglesY"); - m_pAnglesZ = new vgui::TextEntry(this, "AnglesZ"); - m_pMass = new vgui::TextEntry(this, "Mass"); - m_pDensity = new vgui::TextEntry(this, "Density"); - m_pLinearFriction = new vgui::TextEntry(this, "LinearFriction"); - m_pRollingFriction = new vgui::TextEntry(this, "RollingFriction"); - m_pRestitution = new vgui::TextEntry(this, "Restitution"); - m_pCCDRadius = new vgui::TextEntry(this, "CCDRadius"); - m_pCCDThreshold = new vgui::TextEntry(this, "CCDThreshold"); - m_pLinearSleepingThreshold = new vgui::TextEntry(this, "LinearSleepingThreshold"); - m_pAngularSleepingThreshold = new vgui::TextEntry(this, "AngularSleepingThreshold"); - m_pAlwaysDynamic = new vgui::CheckButton(this, "AlwaysDynamic", "#BulletPhysics_AlwaysDynamic"); - m_pAlwaysKinematic = new vgui::CheckButton(this, "AlwaysKinematic", "#BulletPhysics_AlwaysKinematic"); - m_pAlwaysStatic = new vgui::CheckButton(this, "AlwaysStatic", "#BulletPhysics_AlwaysStatic"); - m_pNoCollisionToWorld = new vgui::CheckButton(this, "NoCollisionToWorld", "#BulletPhysics_NoCollisionToWorld"); - m_pNoCollisionToStaticObject = new vgui::CheckButton(this, "NoCollisionToStaticObject", "#BulletPhysics_NoCollisionToStaticObject"); - m_pNoCollisionToDynamicObject = new vgui::CheckButton(this, "NoCollisionToDynamicObject", "#BulletPhysics_NoCollisionToDynamicObject"); - m_pNoCollisionToRagdollObject = new vgui::CheckButton(this, "NoCollisionToRagdollObject", "#BulletPhysics_NoCollisionToRagdollObject"); - - vgui::HFont hFallbackFont = vgui::scheme()->GetIScheme(GetScheme())->GetFont("DefaultVerySmallFallBack", false); - - if (vgui::INVALID_FONT != hFallbackFont) - { - m_pBone->SetUseFallbackFont(true, hFallbackFont); - m_pShape->SetUseFallbackFont(true, hFallbackFont); - } - - LoadAvailableBonesIntoControls(); - - LoadAvailableShapesIntoControls(); - - LoadControlSettings("bulletphysics/RigidBodyEditDialog.res", "GAME"); - - vgui::ivgui()->AddTickSignal(GetVPanel()); -} - -void CRigidBodyEditDialog::Activate(void) -{ - BaseClass::Activate(); - - vgui::ipanel()->SendMessage(GetVPanel(), new KeyValues("ResetData"), GetVPanel()); -} - -void CRigidBodyEditDialog::OnResetData() -{ - LoadConfigIntoControls(); -} - -void CRigidBodyEditDialog::OnRefreshCollisionShape() -{ - LoadShapeIntoControls(m_pRigidBodyConfig->collisionShape); - PostActionSignal(new KeyValues("RefreshRigidBody", "configId", m_pRigidBodyConfig->configId)); -} - -void CRigidBodyEditDialog::OnCommand(const char* command) -{ - if (!stricmp(command, "OK")) - { - SaveConfigFromControls(); - PostActionSignal(new KeyValues("RefreshRigidBody", "configId", m_pRigidBodyConfig->configId)); - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - Close(); - return; - } - else if (!stricmp(command, "Apply")) - { - SaveConfigFromControls(); - PostActionSignal(new KeyValues("RefreshRigidBody", "configId", m_pRigidBodyConfig->configId)); - ClientPhysicManager()->RebuildPhysicObjectEx(m_physicObjectId, m_pPhysicObjectConfig.get()); - return; - } - else if (!strcmp(command, "EditCollisionShape")) - { - OnEditCollisionShape(); - return; - } - - BaseClass::OnCommand(command); -} - -CRigidBodyEditDialog::~CRigidBodyEditDialog() -{ - -} - -void CRigidBodyEditDialog::OnEditCollisionShape() -{ - if (!m_pRigidBodyConfig->collisionShape) - { - m_pRigidBodyConfig->collisionShape = std::make_shared(); - - m_pRigidBodyConfig->collisionShape->configModified = true; - - m_pRigidBodyConfig->configModified = true; - - ClientPhysicManager()->AddPhysicConfig(m_pRigidBodyConfig->collisionShape->configId, m_pRigidBodyConfig->collisionShape); - } - - auto dialog = new CCollisionShapeEditDialog(this, "CollisionShapeEditDialog", m_physicObjectId, m_pPhysicObjectConfig, m_pRigidBodyConfig, m_pRigidBodyConfig->collisionShape); - dialog->AddActionSignalTarget(this); - dialog->DoModal(); -} - -void CRigidBodyEditDialog::LoadAvailableBonesIntoControls() -{ - if(1) - { - auto kv = new KeyValues("UserData"); - - kv->SetInt("boneindex", -1); - - m_pBone->AddItem("--", kv); - - kv->deleteThis(); - } - - auto modelindex = UNPACK_PHYSIC_OBJECT_ID_TO_MODELINDEX(m_physicObjectId); - - auto model = EngineGetModelByIndex(modelindex); - - if (model && model->type == mod_studio) - { - auto studiohdr = (studiohdr_t*)IEngineStudio.Mod_Extradata(model); - - if (studiohdr) - { - for (int i = 0; i < studiohdr->numbones; ++i) - { - auto kv = new KeyValues("UserData"); - - kv->SetString("name", UTIL_GetBoneRawName(studiohdr, i)); - kv->SetInt("boneindex", i); - - auto bone = UTIL_GetFormattedBoneNameEx(studiohdr, i); - - m_pBone->AddItem(bone.c_str(), kv); - - kv->deleteThis(); - } - } - } -} - -void CRigidBodyEditDialog::LoadBoneIntoControls(int boneindex) -{ - for (int i = 0; i < m_pBone->GetItemCount(); ++i) - { - KeyValues* kv = m_pBone->GetItemUserData(i); - - if (kv && m_pRigidBodyConfig->boneindex == kv->GetInt("boneindex", -1)) - { - m_pBone->ActivateItemByRow(i); - return; - } - } - - m_pBone->ActivateItemByRow(0); -} - -void CRigidBodyEditDialog::LoadAvailableShapesIntoControls() -{ - for (int i = 0; i < PhysicShape_Maximum; ++i) - { - auto kv = new KeyValues("UserData"); - - kv->SetInt("type", i); - - m_pShape->AddItem(UTIL_GetCollisionShapeTypeLocalizationToken(i), kv); - - kv->deleteThis(); - } -} - -void CRigidBodyEditDialog::LoadShapeIntoControls(const CClientCollisionShapeConfigSharedPtr& collisionShape) -{ - if (collisionShape) - { - for (int i = 0; i < m_pShape->GetItemCount(); ++i) - { - KeyValues* kv = m_pShape->GetItemUserData(i); - - if (kv && collisionShape->type == kv->GetInt("type", PhysicShape_None)) - { - m_pShape->ActivateItemByRow(i); - return; - } - } - } - m_pShape->ActivateItemByRow(0); -} - -void CRigidBodyEditDialog::LoadConfigIntoControls() -{ - m_pName->SetText(m_pRigidBodyConfig->name.c_str()); - - LoadBoneIntoControls(m_pRigidBodyConfig->boneindex); - - LoadShapeIntoControls(m_pRigidBodyConfig->collisionShape); - -#define LOAD_INTO_TEXT_ENTRY(from, to) { auto str##to = std::format("{0}", m_pRigidBodyConfig->from); m_p##to->SetText(str##to.c_str());} - - LOAD_INTO_TEXT_ENTRY(debugDrawLevel, DebugDrawLevel); - LOAD_INTO_TEXT_ENTRY(origin[0], OriginX); - LOAD_INTO_TEXT_ENTRY(origin[1], OriginY); - LOAD_INTO_TEXT_ENTRY(origin[2], OriginZ); - LOAD_INTO_TEXT_ENTRY(angles[0], AnglesX); - LOAD_INTO_TEXT_ENTRY(angles[1], AnglesY); - LOAD_INTO_TEXT_ENTRY(angles[2], AnglesZ); - LOAD_INTO_TEXT_ENTRY(mass, Mass); - LOAD_INTO_TEXT_ENTRY(density, Density); - LOAD_INTO_TEXT_ENTRY(linearFriction, LinearFriction); - LOAD_INTO_TEXT_ENTRY(rollingFriction, RollingFriction); - LOAD_INTO_TEXT_ENTRY(restitution, Restitution); - LOAD_INTO_TEXT_ENTRY(ccdRadius, CCDRadius); - LOAD_INTO_TEXT_ENTRY(ccdThreshold, CCDThreshold); - LOAD_INTO_TEXT_ENTRY(linearSleepingThreshold, LinearSleepingThreshold); - LOAD_INTO_TEXT_ENTRY(angularSleepingThreshold, AngularSleepingThreshold); -#undef LOAD_INTO_TEXT_ENTRY - -#define LOAD_INTO_CHECK_BUTTON(from, to) m_p##to->SetSelected((m_pRigidBodyConfig->from & PhysicRigidBodyFlag_##to) ? true : false); - LOAD_INTO_CHECK_BUTTON(flags, AlwaysDynamic); - LOAD_INTO_CHECK_BUTTON(flags, AlwaysKinematic); - LOAD_INTO_CHECK_BUTTON(flags, AlwaysStatic); - LOAD_INTO_CHECK_BUTTON(flags, NoCollisionToWorld); - LOAD_INTO_CHECK_BUTTON(flags, NoCollisionToStaticObject); - LOAD_INTO_CHECK_BUTTON(flags, NoCollisionToDynamicObject); - LOAD_INTO_CHECK_BUTTON(flags, NoCollisionToRagdollObject); -#undef LOAD_INTO_CHECK_BUTTON -} - -void CRigidBodyEditDialog::SaveConfigFromControls() -{ - m_pRigidBodyConfig->boneindex = GetCurrentSelectedBoneIndex(); - - char szText[256]; - -#define SAVE_FROM_TEXT_ENTRY(to, from, processor) {m_p##from->GetText(szText, sizeof(szText)); m_pRigidBodyConfig->to = processor(szText);} - - SAVE_FROM_TEXT_ENTRY(name, Name, std::string); - SAVE_FROM_TEXT_ENTRY(debugDrawLevel, DebugDrawLevel, atoi); - SAVE_FROM_TEXT_ENTRY(origin[0], OriginX, atof); - SAVE_FROM_TEXT_ENTRY(origin[1], OriginY, atof); - SAVE_FROM_TEXT_ENTRY(origin[2], OriginZ, atof); - SAVE_FROM_TEXT_ENTRY(angles[0], AnglesX, atof); - SAVE_FROM_TEXT_ENTRY(angles[1], AnglesY, atof); - SAVE_FROM_TEXT_ENTRY(angles[2], AnglesZ, atof); - SAVE_FROM_TEXT_ENTRY(mass, Mass, atof); - SAVE_FROM_TEXT_ENTRY(density, Density, atof); - SAVE_FROM_TEXT_ENTRY(linearFriction, LinearFriction, atof); - SAVE_FROM_TEXT_ENTRY(rollingFriction, RollingFriction, atof); - SAVE_FROM_TEXT_ENTRY(restitution, Restitution, atof); - SAVE_FROM_TEXT_ENTRY(ccdRadius, CCDRadius, atof); - SAVE_FROM_TEXT_ENTRY(ccdThreshold, CCDThreshold, atof); - SAVE_FROM_TEXT_ENTRY(linearSleepingThreshold, LinearSleepingThreshold, atof); - SAVE_FROM_TEXT_ENTRY(angularSleepingThreshold, AngularSleepingThreshold, atof); - -#undef SAVE_FROM_TEXT_ENTRY - -#define SAVE_FROM_CHECK_BUTTON(to, from) if (m_p##from->IsSelected()) { m_pRigidBodyConfig->to |= PhysicRigidBodyFlag_##from; } else { m_pRigidBodyConfig->to &= ~PhysicRigidBodyFlag_##from; } - SAVE_FROM_CHECK_BUTTON(flags, AlwaysDynamic); - SAVE_FROM_CHECK_BUTTON(flags, AlwaysKinematic); - SAVE_FROM_CHECK_BUTTON(flags, AlwaysStatic); - SAVE_FROM_CHECK_BUTTON(flags, NoCollisionToWorld); - SAVE_FROM_CHECK_BUTTON(flags, NoCollisionToStaticObject); - SAVE_FROM_CHECK_BUTTON(flags, NoCollisionToDynamicObject); - SAVE_FROM_CHECK_BUTTON(flags, NoCollisionToRagdollObject); -#undef SAVE_FROM_CHECK_BUTTON - - m_pRigidBodyConfig->configModified = true; -} - -int CRigidBodyEditDialog::GetCurrentSelectedBoneIndex() -{ - int boneindex = -1; - - auto pBoneKV = m_pBone->GetActiveItemUserData(); - - if (pBoneKV) - { - boneindex = pBoneKV->GetInt("boneindex", -1); - } - - return boneindex; -} - //Physic Editor CPhysicEditorDialog::CPhysicEditorDialog(vgui::Panel* parent, const char *name, uint64 physicObjectId, const std::shared_ptr& pPhysicObjectConfig) : @@ -1156,6 +27,9 @@ CPhysicEditorDialog::CPhysicEditorDialog(vgui::Panel* parent, const char *name, m_pRigidBodyPage = new CRigidBodyPage(this, "RigidBodyPage", m_physicObjectId, pPhysicObjectConfig); m_pRigidBodyPage->MakeReadyForUse(); + m_pConstraintPage = new CConstraintPage(this, "ConstraintPage", m_physicObjectId, pPhysicObjectConfig); + m_pConstraintPage->MakeReadyForUse(); + SetMinimumSize(vgui::scheme()->GetProportionalScaledValue(640), vgui::scheme()->GetProportionalScaledValue(384)); SetSize(vgui::scheme()->GetProportionalScaledValue(640), vgui::scheme()->GetProportionalScaledValue(384)); @@ -1163,6 +37,7 @@ CPhysicEditorDialog::CPhysicEditorDialog(vgui::Panel* parent, const char *name, m_pTabPanel->SetTabWidth(vgui::scheme()->GetProportionalScaledValue(72)); m_pTabPanel->AddPage(m_pBaseObjectConfigPage, "#BulletPhysics_Base"); m_pTabPanel->AddPage(m_pRigidBodyPage, "#BulletPhysics_RigidBody"); + m_pTabPanel->AddPage(m_pConstraintPage, "#BulletPhysics_Constraint"); m_pTabPanel->AddActionSignalTarget(this); LoadControlSettings("bulletphysics/PhysicEditorDialog.res", "GAME"); diff --git a/Plugins/BulletPhysics/PhysicEditorDialog.h b/Plugins/BulletPhysics/PhysicEditorDialog.h index 3a0476b1..a427e513 100644 --- a/Plugins/BulletPhysics/PhysicEditorDialog.h +++ b/Plugins/BulletPhysics/PhysicEditorDialog.h @@ -8,10 +8,10 @@ #include #include #include +#include #include "ClientPhysicConfig.h" - class CRigidBodyListPanel : public vgui::ListPanel { public: @@ -24,6 +24,43 @@ class CRigidBodyListPanel : public vgui::ListPanel typedef vgui::ListPanel BaseClass; }; +class CConstraintListPanel : public vgui::ListPanel +{ +public: + DECLARE_CLASS_SIMPLE(CConstraintListPanel, vgui::ListPanel); + + CConstraintListPanel(vgui::Panel* parent, const char* pName); + +private: + + typedef vgui::ListPanel BaseClass; +}; + +class CInlineTextEntryPanel; + +class CFactorListPanel : public vgui::ListPanel +{ +public: + DECLARE_CLASS_SIMPLE(CFactorListPanel, vgui::ListPanel); + + CFactorListPanel(vgui::Panel* parent, const char* pName); + ~CFactorListPanel(); + + void StartCaptureMode(); + void EndCaptureMode(); + bool IsCapturing(void) const; + int GetCapturingItemId(void) const; + int GetCapturingItemIndex(void) const; + void OnMousePressed(vgui::MouseCode code) override; +private: + + typedef vgui::ListPanel BaseClass; + bool m_bCaptureMode{}; + int m_iCaptureItemId{}; + int m_iCaptureItemIndex{}; + CInlineTextEntryPanel* m_pInlineTextEntryPanel{}; +}; + class CBaseObjectConfigPage : public vgui::PropertyPage { public: @@ -34,12 +71,10 @@ class CBaseObjectConfigPage : public vgui::PropertyPage private: MESSAGE_FUNC(OnApplyChanges, "ApplyChanges"); - MESSAGE_FUNC(OnResetData, "ResetData"); void OnKeyCodeTyped(vgui::KeyCode code) override; void OnCommand(const char* command) override; - void ApplySchemeSettings(vgui::IScheme* pScheme) override; void LoadConfigIntoControls(); void SaveConfigFromControls(); @@ -104,6 +139,49 @@ class CRigidBodyPage : public vgui::PropertyPage std::shared_ptr m_pPhysicObjectConfig; }; +class CConstraintPage : public vgui::PropertyPage +{ +public: + DECLARE_CLASS_SIMPLE(CConstraintPage, vgui::PropertyPage); + + CConstraintPage(vgui::Panel* parent, const char* name, uint64 physicObjectId, const std::shared_ptr& pPhysicObjectConfig); + +private: + + MESSAGE_FUNC(OnResetData, "ResetData"); + MESSAGE_FUNC_INT(OnOpenContextMenu, "OpenContextMenu", itemID); + MESSAGE_FUNC_INT(OnRefreshConstraint, "RefreshConstraint", configId); + MESSAGE_FUNC_INT(OnEditConstraint, "EditConstraint", configId); + MESSAGE_FUNC_INT(OnCloneConstraint, "CloneConstraint", configId); + MESSAGE_FUNC_INT(OnDeleteConstraint, "DeleteConstraint", configId); + MESSAGE_FUNC_INT(OnShiftUpConstraint, "ShiftUpConstraint", configId); + MESSAGE_FUNC_INT(OnShiftDownConstraint, "ShiftDownConstraint", configId); + MESSAGE_FUNC(OnRefreshConstraints, "RefreshConstraints"); + + void OnKeyCodeTyped(vgui::KeyCode code) override; + void OnCommand(const char* command) override; + void ApplySchemeSettings(vgui::IScheme* pScheme) override; + + void LoadConstraintAsListPanelItem(const CClientConstraintConfig* pConstraintConfig); + void ReloadAllConstraintsIntoListPanelItem(); + void OnOpenConstraintEditor(int configId); + void OnCreateConstraint(); + void SelectConstraintItem(int configId); + void DeleteConstraintItem(int configId); + + typedef vgui::PropertyPage BaseClass; +private: + vgui::HFont m_hFont{}; + + CConstraintListPanel* m_pConstraintListPanel{}; + vgui::Button* m_pShiftUpConstraint{}; + vgui::Button* m_pShiftDownConstraint{}; + vgui::Button* m_pCreateConstraint{}; + + uint64 m_physicObjectId{}; + std::shared_ptr m_pPhysicObjectConfig; +}; + class CCollisionShapeEditDialog : public vgui::Frame { public: @@ -180,7 +258,7 @@ class CRigidBodyEditDialog : public vgui::Frame void Activate(void) override; private: - MESSAGE_FUNC(OnRefreshCollisionShape, "RefreshCollisionShape"); + MESSAGE_FUNC_INT(OnRefreshCollisionShape, "RefreshCollisionShape", configId); MESSAGE_FUNC(OnResetData, "ResetData"); void OnCommand(const char* command) override; @@ -227,6 +305,100 @@ class CRigidBodyEditDialog : public vgui::Frame std::shared_ptr m_pRigidBodyConfig; }; +class CConstraintEditDialog : public vgui::Frame +{ +public: + DECLARE_CLASS_SIMPLE(CConstraintEditDialog, vgui::Frame); + + CConstraintEditDialog(vgui::Panel* parent, const char* name, + uint64 physicObjectId, + const std::shared_ptr& pPhysicObjectConfig, + const std::shared_ptr& pConstraintConfig); + ~CConstraintEditDialog(); + + void Activate(void) override; + +private: + MESSAGE_FUNC(OnItemSelected, "ItemSelected"); + MESSAGE_FUNC(OnResetData, "ResetData"); + MESSAGE_FUNC_PTR(OnTextChanged, "TextChanged", panel); + MESSAGE_FUNC_PARAMS(OnModifyFactor, "ModifyFactor", kv); + + void OnCommand(const char* command) override; + void OnKeyCodeTyped(vgui::KeyCode code) override; + + void LoadAvailableTypesIntoControls(); + void LoadAvailableRotOrdersIntoControls(); + void LoadAvailableRigidBodiesIntoControls(vgui::ComboBox* pComboBox); + void LoadAvailableFactorsIntoControls(int type); + void DeleteFactorListPanelItem(int factorIdx); + void LoadFactorAsListPanelItem(int factorIdx, const char* token, float value, float defaultValue); + void LoadFactorAsListPanelItemEx(int factorIdx, const char* name, const char* value, float defaultValue); + void LoadTypeIntoControl(int type); + void LoadRotOrderIntoControl(int rotOrder); + void LoadRigidBodyIntoControl(const std::string& rigidBodyName, vgui::ComboBox* pComboBox); + void LoadConfigIntoControls(); + void SaveTypeFromControl(); + void SaveRotOrderFromControl(); + void SaveFactorFromControls(); + void SaveRigidBodyFromControl(vgui::ComboBox* pComboBox, std::string& rigidBodyName); + void SaveConfigFromControls(); + int GetCurrentSelectedConstraintType(); + void UpdateControlStates(); + + typedef vgui::Frame BaseClass; + + vgui::TextEntry* m_pName{}; + vgui::TextEntry* m_pDebugDrawLevel{}; + + vgui::ComboBox* m_pType{}; + + vgui::ComboBox* m_pRigidBodyA{}; + vgui::ComboBox* m_pRigidBodyB{}; + + vgui::TextEntry* m_pOriginAX{}; + vgui::TextEntry* m_pOriginAY{}; + vgui::TextEntry* m_pOriginAZ{}; + vgui::TextEntry* m_pAnglesAX{}; + vgui::TextEntry* m_pAnglesAY{}; + vgui::TextEntry* m_pAnglesAZ{}; + + vgui::TextEntry* m_pOriginBX{}; + vgui::TextEntry* m_pOriginBY{}; + vgui::TextEntry* m_pOriginBZ{}; + vgui::TextEntry* m_pAnglesBX{}; + vgui::TextEntry* m_pAnglesBY{}; + vgui::TextEntry* m_pAnglesBZ{}; + + vgui::TextEntry* m_pForwardX{}; + vgui::TextEntry* m_pForwardY{}; + vgui::TextEntry* m_pForwardZ{}; + + vgui::CheckButton* m_pDisableCollision{}; + vgui::CheckButton* m_pUseGlobalJointFromA{}; + vgui::CheckButton* m_pUseLookAtOther{}; + vgui::CheckButton* m_pUseGlobalJointOriginFromOther{}; + vgui::CheckButton* m_pUseRigidBodyDistanceAsLinearLimit{}; + vgui::CheckButton* m_pUseLinearReferenceFrameA{}; + + vgui::ComboBox* m_pRotOrder{}; + vgui::TextEntry* m_pMaxTolerantLinearError{}; + + vgui::CheckButton* m_pBarnacle{}; + vgui::CheckButton* m_pGargantua{}; + vgui::CheckButton* m_pDeactiveOnNormalActivity{}; + vgui::CheckButton* m_pDeactiveOnDeathActivity{}; + vgui::CheckButton* m_pDeactiveOnBarnacleActivity{}; + vgui::CheckButton* m_pDeactiveOnGargantuaActivity{}; + vgui::CheckButton* m_pDontResetPoseOnErrorCorrection{}; + + CFactorListPanel *m_pFactorListPanel{}; + + uint64 m_physicObjectId{}; + std::shared_ptr m_pPhysicObjectConfig; + std::shared_ptr m_pConstraintConfig; +}; + class CPhysicEditorDialog : public vgui::Frame { public: @@ -244,6 +416,7 @@ class CPhysicEditorDialog : public vgui::Frame vgui::PropertySheet* m_pTabPanel{}; CBaseObjectConfigPage* m_pBaseObjectConfigPage{}; CRigidBodyPage* m_pRigidBodyPage{}; + CConstraintPage* m_pConstraintPage{}; uint64 m_physicObjectId{}; std::shared_ptr m_pPhysicObjectConfig; diff --git a/Plugins/BulletPhysics/PhysicUTIL.cpp b/Plugins/BulletPhysics/PhysicUTIL.cpp index e9e08138..123a8d78 100644 --- a/Plugins/BulletPhysics/PhysicUTIL.cpp +++ b/Plugins/BulletPhysics/PhysicUTIL.cpp @@ -6,18 +6,42 @@ #include #include -const char* VGUI2Token_PhysicObject[] = { "#BulletPhysics_None", "#BulletPhysics_StaticObject", "#BulletPhysics_DynamicObject", "#BulletPhysics_RagdollObject" }; +const char* VGUI2Token_PhysicObjectType[] = { "#BulletPhysics_None", "#BulletPhysics_StaticObject", "#BulletPhysics_DynamicObject", "#BulletPhysics_RagdollObject" }; const char* UTIL_GetPhysicObjectTypeLocalizationToken(int type) { - if (type >= 0 && type < _ARRAYSIZE(VGUI2Token_PhysicObject)) + if (type >= 0 && type < _ARRAYSIZE(VGUI2Token_PhysicObjectType)) { - return VGUI2Token_PhysicObject[type]; + return VGUI2Token_PhysicObjectType[type]; } return "#BulletPhysics_None"; } +const char* VGUI2Token_ConstraintType[] = { "#BulletPhysics_None", "#BulletPhysics_ConeTwistConstraint", "#BulletPhysics_HingeConstraint", "#BulletPhysics_PointConstraint", "#BulletPhysics_SliderConstraint", "#BulletPhysics_Dof6Constraint", "#BulletPhysics_Dof6SpringConstraint", "#BulletPhysics_FixedConstraint" }; + +const char* UTIL_GetConstraintTypeLocalizationToken(int type) +{ + if (type >= 0 && type < _ARRAYSIZE(VGUI2Token_ConstraintType)) + { + return VGUI2Token_ConstraintType[type]; + } + + return "#BulletPhysics_None"; +} + +const char* VGUI2Token_RotOrderType[] = { "#BulletPhysics_PhysicRotOrder_XYZ", "#BulletPhysics_PhysicRotOrder_XZY", "#BulletPhysics_PhysicRotOrder_YXZ", "#BulletPhysics_PhysicRotOrder_YZX", "#BulletPhysics_PhysicRotOrder_ZXY", "#BulletPhysics_PhysicRotOrder_ZYX" }; + +const char* UTIL_GetRotOrderTypeLocalizationToken(int type) +{ + if (type >= 0 && type < _ARRAYSIZE(VGUI2Token_RotOrderType)) + { + return VGUI2Token_RotOrderType[type]; + } + + return "#BulletPhysics_PhysicRotOrder_XYZ"; +} + const char* VGUI2Token_CollisionShape[] = { "#BulletPhysics_None", "#BulletPhysics_Box", "#BulletPhysics_Sphere", "#BulletPhysics_Capsule", "#BulletPhysics_Cylinder", "#BulletPhysics_MultiSphere", "#BulletPhysics_TriangleMesh", "#BulletPhysics_Compound" }; const char* UTIL_GetCollisionShapeTypeLocalizationToken(int type) @@ -39,33 +63,89 @@ std::wstring UTIL_GetFormattedRigidBodyFlags(int flags) { std::wstringstream ss; - if (flags & PhysicRigidBodyFlag_AlwaysDynamic) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_AlwaysDynamic") << L") "; - } + // Macro to format flag string +#define FORMAT_FLAGS_TO_STRING(name) if (flags & PhysicRigidBodyFlag_##name) {\ + ss << L"(" << vgui::localize()->Find("#BulletPhysics_" #name) << L") ";\ + } - if (flags & PhysicRigidBodyFlag_AlwaysKinematic) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_AlwaysKinematic") << L") "; - } + FORMAT_FLAGS_TO_STRING(AlwaysDynamic); + FORMAT_FLAGS_TO_STRING(AlwaysKinematic); + FORMAT_FLAGS_TO_STRING(AlwaysStatic); + FORMAT_FLAGS_TO_STRING(NoCollisionToWorld); + FORMAT_FLAGS_TO_STRING(NoCollisionToStaticObject); + FORMAT_FLAGS_TO_STRING(NoCollisionToDynamicObject); + FORMAT_FLAGS_TO_STRING(NoCollisionToRagdollObject); - if (flags & PhysicRigidBodyFlag_NoCollisionToWorld) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_NoCollisionToWorld") << L") "; - } +#undef FORMAT_FLAGS_TO_STRING - if (flags & PhysicRigidBodyFlag_NoCollisionToStaticObject) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_NoCollisionToStaticObject") << L") "; - } + return ss.str(); +} - if (flags & PhysicRigidBodyFlag_NoCollisionToDynamicObject) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_NoCollisionToDynamicObject") << L") "; - } +std::wstring UTIL_GetFormattedConstraintFlags(int flags) +{ + std::wstringstream ss; - if (flags & PhysicRigidBodyFlag_NoCollisionToRagdollObject) { - ss << L"(" << vgui::localize()->Find("#BulletPhysics_NoCollisionToRagdollObject") << L") "; - } + // Macro to format flag string +#define FORMAT_FLAGS_TO_STRING(name) if (flags & PhysicConstraintFlag_##name) {\ + ss << L"(" << vgui::localize()->Find("#BulletPhysics_" #name) << L") ";\ + } + + FORMAT_FLAGS_TO_STRING(Barnacle); + FORMAT_FLAGS_TO_STRING(Gargantua); + FORMAT_FLAGS_TO_STRING(DeactiveOnNormalActivity); + FORMAT_FLAGS_TO_STRING(DeactiveOnDeathActivity); + FORMAT_FLAGS_TO_STRING(DeactiveOnBarnacleActivity); + FORMAT_FLAGS_TO_STRING(DeactiveOnGargantuaActivity); + FORMAT_FLAGS_TO_STRING(DontResetPoseOnErrorCorrection); + +#undef FORMAT_FLAGS_TO_STRING return ss.str(); } +std::wstring UTIL_GetFormattedConstraintConfigAttributes(const CClientConstraintConfig *pConstraintConfig) +{ + std::wstringstream ss; + + if (pConstraintConfig->useGlobalJointFromA) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseGlobalJointFromA")); + } + else + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseGlobalJointFromB")); + } + if (pConstraintConfig->disableCollision) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_DisableCollision")); + } + else + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_DontDisableCollision")); + } + if (pConstraintConfig->useLookAtOther) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseLookAtOther")); + } + if (pConstraintConfig->useGlobalJointOriginFromOther) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseGlobalJointOriginFromOther")); + } + if (pConstraintConfig->useRigidBodyDistanceAsLinearLimit) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseRigidBodyDistanceAsLinearLimit")); + } + if (pConstraintConfig->useLinearReferenceFrameA) + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseLinearReferenceFrameA")); + } + else + { + ss << std::format(L"({0}) ", vgui::localize()->Find("#BulletPhysics_UseLinearReferenceFrameB")); + } + return ss.str(); +} + std::string UTIL_GetFormattedBoneNameEx(studiohdr_t* studiohdr, int boneindex) { if (!(boneindex >= 0 && boneindex < studiohdr->numbones)) @@ -323,6 +403,27 @@ bool UTIL_RemoveRigidBodyFromPhysicObjectConfig(CClientPhysicObjectConfig * pPhy return false; } +bool UTIL_RemoveConstraintFromPhysicObjectConfig(CClientPhysicObjectConfig* pPhysicObjectConfig, int constraintConfigId) +{ + for (auto itor = pPhysicObjectConfig->ConstraintConfigs.begin(); itor != pPhysicObjectConfig->ConstraintConfigs.end(); ) + { + const auto& p = (*itor); + + if (p->configId == constraintConfigId) + { + itor = pPhysicObjectConfig->ConstraintConfigs.erase(itor); + + pPhysicObjectConfig->configModified = true; + + return true; + } + + itor++; + } + + return false; +} + std::shared_ptr UTIL_CloneCollisionShapeConfig(const CClientCollisionShapeConfig* pOldShape) { auto pCloneShape = std::make_shared(); @@ -377,6 +478,44 @@ std::shared_ptr UTIL_CloneRigidBodyConfig(const CClientR return pCloneConfig; } +std::shared_ptr UTIL_CloneConstraintConfig(const CClientConstraintConfig* pOldConfig) +{ + auto pNewConfig = std::make_shared(); + + // Copy basic types and strings + pNewConfig->name = pOldConfig->name; + pNewConfig->type = pOldConfig->type; + pNewConfig->rigidbodyA = pOldConfig->rigidbodyA; + pNewConfig->rigidbodyB = pOldConfig->rigidbodyB; + pNewConfig->disableCollision = pOldConfig->disableCollision; + pNewConfig->useGlobalJointFromA = pOldConfig->useGlobalJointFromA; + pNewConfig->useLookAtOther = pOldConfig->useLookAtOther; + pNewConfig->useGlobalJointOriginFromOther = pOldConfig->useGlobalJointOriginFromOther; + pNewConfig->useRigidBodyDistanceAsLinearLimit = pOldConfig->useRigidBodyDistanceAsLinearLimit; + pNewConfig->useLinearReferenceFrameA = pOldConfig->useLinearReferenceFrameA; + pNewConfig->rotOrder = pOldConfig->rotOrder; + pNewConfig->flags = pOldConfig->flags; + pNewConfig->debugDrawLevel = pOldConfig->debugDrawLevel; + pNewConfig->maxTolerantLinearError = pOldConfig->maxTolerantLinearError; + pNewConfig->isLegacyConfig = pOldConfig->isLegacyConfig; + pNewConfig->boneindexA = pOldConfig->boneindexA; + pNewConfig->boneindexB = pOldConfig->boneindexB; + + // Copy vec3_t using the provided VectorCopy macro + VectorCopy(pOldConfig->originA, pNewConfig->originA); + VectorCopy(pOldConfig->anglesA, pNewConfig->anglesA); + VectorCopy(pOldConfig->originB, pNewConfig->originB); + VectorCopy(pOldConfig->anglesB, pNewConfig->anglesB); + VectorCopy(pOldConfig->forward, pNewConfig->forward); + VectorCopy(pOldConfig->offsetA, pNewConfig->offsetA); + VectorCopy(pOldConfig->offsetB, pNewConfig->offsetB); + + // Copy array of floats + std::copy(std::begin(pOldConfig->factors), std::end(pOldConfig->factors), std::begin(pNewConfig->factors)); + + return pNewConfig; +} + std::string UTIL_FormatAbsoluteModelName(model_t* mod) { if (mod->type == mod_brush) @@ -556,6 +695,8 @@ IPhysicConstraint* UTIL_GetPhysicComponentAsConstraint(int physicComponentId) return nullptr; } +//RigidBody config order related + int UTIL_GetRigidBodyIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, int configId) { auto& configs = pPhysicObjectConfig->RigidBodyConfigs; @@ -681,5 +822,111 @@ bool UTIL_ShiftDownRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig return true; } + return false; +} + +//Constraint config order related + +int UTIL_GetConstraintIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, int configId) { + const auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [configId](const std::shared_ptr& ptr) { + return ptr->configId == configId; + }); + + if (it != configs.end()) { + return std::distance(configs.begin(), it); + } + + return -1; // Return -1 if not found +} + +int UTIL_GetConstraintIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, const CClientConstraintConfig* pConstraintConfig) +{ + auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [pConstraintConfig](const std::shared_ptr& ptr) { + return ptr.get() == pConstraintConfig; + }); + + if (it != configs.begin() && it != configs.end()) { + // Find the index of the current element + std::size_t currentIndex = std::distance(configs.begin(), it); + // Calculate the index of the previous element + return currentIndex; + } + + return -1; +} + +bool UTIL_ShiftUpConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId) { + auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [configId](const std::shared_ptr& ptr) { + return ptr->configId == configId; + }); + + if (it != configs.begin() && it != configs.end()) { + auto currentIndex = std::distance(configs.begin(), it); + auto prevIndex = currentIndex - 1; + + std::iter_swap(configs.begin() + currentIndex, configs.begin() + prevIndex); + return true; + } + + return false; +} + +bool UTIL_ShiftDownConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId) { + auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [configId](const std::shared_ptr& ptr) { + return ptr->configId == configId; + }); + + if (it != configs.end() - 1 && it != configs.end()) { + auto currentIndex = std::distance(configs.begin(), it); + auto nextIndex = currentIndex + 1; + + std::iter_swap(configs.begin() + currentIndex, configs.begin() + nextIndex); + return true; + } + + return false; +} + +bool UTIL_ShiftUpConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientConstraintConfig* pConstraintConfig) { + auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [pConstraintConfig](const std::shared_ptr& ptr) { + return ptr.get() == pConstraintConfig; + }); + + if (it != configs.begin() && it != configs.end()) { + auto currentIndex = std::distance(configs.begin(), it); + auto prevIndex = currentIndex - 1; + + std::iter_swap(configs.begin() + currentIndex, configs.begin() + prevIndex); + return true; + } + + return false; +} + +bool UTIL_ShiftDownConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientConstraintConfig* pConstraintConfig) { + auto& configs = pPhysicObjectConfig->ConstraintConfigs; + + auto it = std::find_if(configs.begin(), configs.end(), [pConstraintConfig](const std::shared_ptr& ptr) { + return ptr.get() == pConstraintConfig; + }); + + if (it != configs.end() - 1 && it != configs.end()) { + auto currentIndex = std::distance(configs.begin(), it); + auto nextIndex = currentIndex + 1; + + std::iter_swap(configs.begin() + currentIndex, configs.begin() + nextIndex); + return true; + } + return false; } \ No newline at end of file diff --git a/Plugins/BulletPhysics/PhysicUTIL.h b/Plugins/BulletPhysics/PhysicUTIL.h index ba08ca1f..db449f71 100644 --- a/Plugins/BulletPhysics/PhysicUTIL.h +++ b/Plugins/BulletPhysics/PhysicUTIL.h @@ -5,9 +5,13 @@ #include const char* UTIL_GetPhysicObjectTypeLocalizationToken(int type); +const char* UTIL_GetConstraintTypeLocalizationToken(int type); +const char* UTIL_GetRotOrderTypeLocalizationToken(int type); const char* UTIL_GetCollisionShapeTypeLocalizationToken(int type); std::wstring UTIL_GetCollisionShapeTypeLocalizedName(int type); std::wstring UTIL_GetFormattedRigidBodyFlags(int flags); +std::wstring UTIL_GetFormattedConstraintFlags(int flags); +std::wstring UTIL_GetFormattedConstraintConfigAttributes(const CClientConstraintConfig* pConstraintConfig); const char* UTIL_GetBoneRawName(studiohdr_t* studiohdr, int boneindex); std::string UTIL_GetFormattedBoneNameEx(studiohdr_t* studiohdr, int boneindex); std::string UTIL_GetFormattedBoneName(int modelindex, int boneindex); @@ -25,8 +29,10 @@ std::shared_ptr UTIL_GetConstraintConfigFromConfigId(in std::shared_ptr UTIL_GetPhysicObjectConfigFromConfigId(int configId); bool UTIL_RemoveRigidBodyFromPhysicObjectConfig(CClientPhysicObjectConfig* pPhysicConfig, int rigidBodyConfigId); +bool UTIL_RemoveConstraintFromPhysicObjectConfig(CClientPhysicObjectConfig* pPhysicObjectConfig, int constraintConfigId); std::shared_ptr UTIL_CloneCollisionShapeConfig(const CClientCollisionShapeConfig* pOldShape); std::shared_ptr UTIL_CloneRigidBodyConfig(const CClientRigidBodyConfig* pOldConfig); +std::shared_ptr UTIL_CloneConstraintConfig(const CClientConstraintConfig* pOldConfig); std::string UTIL_FormatAbsoluteModelName(model_t* mod); bool UTIL_IsCollisionShapeConfigModified(const CClientCollisionShapeConfig* pCollisionShapeConfig); @@ -42,4 +48,11 @@ int UTIL_GetRigidBodyIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, bool UTIL_ShiftUpRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId); bool UTIL_ShiftUpRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientRigidBodyConfig* pRigidBodyConfig); bool UTIL_ShiftDownRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId); -bool UTIL_ShiftDownRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientRigidBodyConfig* pRigidBodyConfig); \ No newline at end of file +bool UTIL_ShiftDownRigidBodyIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientRigidBodyConfig* pRigidBodyConfig); + +int UTIL_GetConstraintIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, int configId); +int UTIL_GetConstraintIndex(const CClientPhysicObjectConfig* pPhysicObjectConfig, const CClientConstraintConfig* pConstraintConfig); +bool UTIL_ShiftUpConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId); +bool UTIL_ShiftUpConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientConstraintConfig* pConstraintConfig); +bool UTIL_ShiftDownConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, int configId); +bool UTIL_ShiftDownConstraintIndex(CClientPhysicObjectConfig* pPhysicObjectConfig, CClientConstraintConfig* pConstraintConfig); \ No newline at end of file diff --git a/Plugins/BulletPhysics/Viewport.cpp b/Plugins/BulletPhysics/Viewport.cpp index 31d82eaf..8918615e 100644 --- a/Plugins/BulletPhysics/Viewport.cpp +++ b/Plugins/BulletPhysics/Viewport.cpp @@ -121,10 +121,19 @@ bool CViewport::PhysicDebugGUIHasFocus() void CViewport::ActivateClientUI(void) { SetVisible(true); + + if (m_hOldFocus) + { + vgui::input()->SetAppModalSurface(m_hOldFocus); + vgui::input()->SetMouseFocus(m_hOldFocus); + m_hOldFocus = NULL; + } } void CViewport::HideClientUI(void) { + m_hOldFocus = vgui::input()->GetAppModalSurface(); + SetVisible(false); } diff --git a/Plugins/BulletPhysics/Viewport.h b/Plugins/BulletPhysics/Viewport.h index 38abed80..3dcec930 100644 --- a/Plugins/BulletPhysics/Viewport.h +++ b/Plugins/BulletPhysics/Viewport.h @@ -45,6 +45,7 @@ class CViewport : public vgui::Panel private: CPhysicDebugGUI* m_pPhysicDebugViewGUI{}; + vgui::VPANEL m_hOldFocus{}; }; extern CViewport *g_pViewPort; \ No newline at end of file diff --git a/Plugins/BulletPhysics/exportfuncs.cpp b/Plugins/BulletPhysics/exportfuncs.cpp index 295144d9..f63733b7 100644 --- a/Plugins/BulletPhysics/exportfuncs.cpp +++ b/Plugins/BulletPhysics/exportfuncs.cpp @@ -117,55 +117,6 @@ bool AllowCheats() return (sv_cheats->value != 0) ? true : false; } -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_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) { return ((entity_state_t *)((char *)cl_frames + size_of_frame * ((*cl_parsecount) & 63) + sizeof(entity_state_t) * index)); @@ -347,7 +298,7 @@ __forceinline int StudioDrawModel_Template(CallType pfnDrawModel, int flags, voi { auto pRagdollObject = (IRagdollObject*)pPhysicObject; - if (pRagdollObject->GetActivityType() > 0) + if (pRagdollObject->GetActivityType() > StudioAnimActivityType_Barnacle) { g_iRagdollRenderEntIndex = entindex; @@ -442,7 +393,7 @@ __forceinline int StudioDrawPlayer_Template(CallType pfnDrawPlayer, int flags, s { auto pRagdollObject = (IRagdollObject*)pPhysicObject; - if (pRagdollObject->GetActivityType() > 0) + if (pRagdollObject->GetActivityType() > StudioAnimActivityType_Barnacle) { g_iRagdollRenderEntIndex = entindex; @@ -1245,25 +1196,37 @@ void BV_OpenDebugUI_f(void) void BV_ReloadObjects_f(void) { - ClientPhysicManager()->RemoveAllPhysicObjects(PhysicObjectFlag_AnyObject, PhysicObjectFlag_FromBSP); + if (AllowCheats()) + { + ClientPhysicManager()->RemoveAllPhysicObjects(PhysicObjectFlag_AnyObject, PhysicObjectFlag_FromBSP); + } } void BV_ReloadConfigs_f(void) { - ClientPhysicManager()->FreeAllIndexArrays(PhysicIndexArrayFlag_FromExternal, PhysicIndexArrayFlag_FromBSP); - ClientPhysicManager()->RemoveAllPhysicObjectConfigs(PhysicObjectFlag_FromConfig, 0); - ClientPhysicManager()->LoadPhysicObjectConfigs(); + if (AllowCheats()) + { + ClientPhysicManager()->FreeAllIndexArrays(PhysicIndexArrayFlag_FromExternal, PhysicIndexArrayFlag_FromBSP); + ClientPhysicManager()->RemoveAllPhysicObjectConfigs(PhysicObjectFlag_FromConfig, 0); + ClientPhysicManager()->LoadPhysicObjectConfigs(); + } } void BV_ReloadAll_f(void) { - BV_ReloadConfigs_f(); - BV_ReloadObjects_f(); + if (AllowCheats()) + { + BV_ReloadConfigs_f(); + BV_ReloadObjects_f(); + } } void BV_SaveConfigs_f(void) { - ClientPhysicManager()->SavePhysicObjectConfigs(); + if (AllowCheats()) + { + ClientPhysicManager()->SavePhysicObjectConfigs(); + } } void HUD_Init(void) @@ -1272,7 +1235,6 @@ void HUD_Init(void) ClientPhysicManager()->Init(); - //bv_debug = gEngfuncs.pfnRegisterVariable("bv_debug", "0", FCVAR_CLIENTDLL); bv_debug_draw = gEngfuncs.pfnRegisterVariable("bv_debug_draw", "0", FCVAR_CLIENTDLL); bv_debug_draw_wallhack = gEngfuncs.pfnRegisterVariable("bv_debug_draw_wallhack", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE); bv_debug_draw_level_static = gEngfuncs.pfnRegisterVariable("bv_debug_draw_level_static", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE); diff --git a/Plugins/BulletPhysics/exportfuncs.h b/Plugins/BulletPhysics/exportfuncs.h index 33e7f5f2..fd7bf63a 100644 --- a/Plugins/BulletPhysics/exportfuncs.h +++ b/Plugins/BulletPhysics/exportfuncs.h @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -72,7 +73,6 @@ int EngineGetNumKnownModel(); int EngineGetMaxKnownModel(); int EngineGetModelIndex(model_t* mod); model_t* EngineGetModelByIndex(int index); -int StudioGetSequenceActivityType(model_t* mod, entity_state_t* entstate); int EngineGetMaxClientEdicts(void); cl_entity_t* EngineGetClientEntitiesBase(void); diff --git a/Plugins/Renderer/exportfuncs.cpp b/Plugins/Renderer/exportfuncs.cpp index b89a0ce9..72a9a28a 100644 --- a/Plugins/Renderer/exportfuncs.cpp +++ b/Plugins/Renderer/exportfuncs.cpp @@ -1003,7 +1003,7 @@ int HUD_GetStudioModelInterface(int version, struct r_studio_interface_s **ppint gPrivateFuncs.ClientPortalManager_ResetAll = (decltype(gPrivateFuncs.ClientPortalManager_ResetAll))GetCallAddress(addr + 12); } - +#if 0 if (1) { #define SCCLIENT_CLIENTPORTALMANAGER_GETORIGINALSURFACETEXTURE_SIG "\x8B\x2A\x24\x04\x83\xEC\x08\x2A\x2A\x2A\x2A\xC5\x9D\x1C\x81\x2A\x2A\x2A\x2A\x70\x2A\x2A\x6C" @@ -1013,7 +1013,6 @@ int HUD_GetStudioModelInterface(int version, struct r_studio_interface_s **ppint gPrivateFuncs.ClientPortalManager_GetOriginalSurfaceTexture = (decltype(gPrivateFuncs.ClientPortalManager_GetOriginalSurfaceTexture))addr; } - if (1) { #define SCCLIENT_CLIENTPORTALMANAGER_DRAWPORTALSURFACE_SIG "\x83\xEC\x2A\x2A\x8B\x74\x24\x2A\x2A\x8B\x7C\x24\x2A\x89\x4C\x24\x2A\x83\x2A\x28\x01" @@ -1024,6 +1023,80 @@ int HUD_GetStudioModelInterface(int version, struct r_studio_interface_s **ppint gPrivateFuncs.ClientPortalManager_DrawPortalSurface = (decltype(gPrivateFuncs.ClientPortalManager_DrawPortalSurface))addr; } +#else + if (1) + { + /* +.text:1004EED7 6A 01 push 1 ; alpha +.text:1004EED9 6A 01 push 1 ; blue +.text:1004EEDB 6A 01 push 1 ; green +.text:1004EEDD 6A 01 push 1 ; red +.text:1004EEDF FF 15 14 92 11 10 call ds:glColorMask +.text:1004EEE5 68 E1 0D 00 00 push 0DE1h ; cap +.text:1004EEEA FF 15 08 92 11 10 call ds:glEnable +.text:1004EEF0 +.text:1004EEF0 loc_1004EEF0: ; CODE XREF: sub_1004EA40+173¡üj +.text:1004EEF0 8B 4C 24 20 mov ecx, [esp+30h+var_10] +.text:1004EEF4 56 push esi +.text:1004EEF5 E8 66 EB FF FF call ClientPortalManager__GetOriginalSurfaceTexture + */ + const char pattern[] = "\x6A\x01\x6A\x01\x6A\x01\x6A\x01\xFF\x15\x2A\x2A\x2A\x2A\x68\xE1\x0D\x00\x00"; + PUCHAR SearchBegin = (PUCHAR)g_dwClientTextBase; + PUCHAR SearchLimit = (PUCHAR)g_dwClientTextBase + g_dwClientTextSize; + while (SearchBegin < SearchLimit) + { + PUCHAR pFound = (PUCHAR)Search_Pattern_From_Size(SearchBegin, SearchLimit - SearchBegin, pattern); + if (pFound) + { + g_pMetaHookAPI->DisasmRanges(pFound + 4, 0x50, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + + if (address[0] == 0xE8) + { + gPrivateFuncs.ClientPortalManager_GetOriginalSurfaceTexture = (decltype(gPrivateFuncs.ClientPortalManager_GetOriginalSurfaceTexture))pinst->detail->x86.operands[0].imm; + return TRUE; + } + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, NULL); + + if (gPrivateFuncs.ClientPortalManager_GetOriginalSurfaceTexture) + { + gPrivateFuncs.ClientPortalManager_DrawPortalSurface = (decltype(gPrivateFuncs.ClientPortalManager_DrawPortalSurface))g_pMetaHookAPI->ReverseSearchFunctionBeginEx(pFound, 0x600, [](PUCHAR Candidate) { + + if (Candidate[0] == 0x83 && + Candidate[1] == 0xEC) + return TRUE; + + return FALSE; + }); + + break; + } + + SearchBegin = pFound + Sig_Length(pattern); + } + else + { + break; + } + } + } + + Sig_FuncNotFound(ClientPortalManager_GetOriginalSurfaceTexture); + Sig_FuncNotFound(ClientPortalManager_DrawPortalSurface); +#endif + + + if (1) { #define SCCLIENT_CLIENTPORTALMANAGER_ENABLECLIPPLANE_SIG "\x83\xEC\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC4\x2A\x44\x24\x2A\x2A\x2A\x24\x2A\x2A\x2A\x24\x2A\x2A\x44\x24\x2A\xF3\x0F" diff --git a/Plugins/Renderer/gl_hooks.cpp b/Plugins/Renderer/gl_hooks.cpp index 2261b68b..0d2eb910 100644 --- a/Plugins/Renderer/gl_hooks.cpp +++ b/Plugins/Renderer/gl_hooks.cpp @@ -8,6 +8,7 @@ //#define R_LOADSKYNAME_SIG_SVENGINE "\x83\x3D\x2A\x2A\x2A\x2A\x00\x0F\x84\x2A\x2A\x2A\x2A\x2A\x2A\x8B\x3D" #define MOD_POINTINLEAF_SIG_SVENGINE "\x2A\x8B\x2A\x24\x2A\x85\x2A\x2A\x2A\x8B\x2A\xA4\x00\x00\x00" +#define MOD_POINTINLEAF_SIG_SVENGINE_10152 "\x8B\x54\x24\x08\x2A\x8D\x2A\xA4\x00\x00\x00\x85\xD2\x74\x2A\x83\x2A\x00" #define MOD_POINTINLEAF_SIG_HL25 "\x55\x8B\xEC\x56\x8B\x75\x0C\x85\x2A\x2A\x2A\x8B\x8E\xA4\x00\x00\x00\x85\xC9\x2A\x2A\x68" #define MOD_POINTINLEAF_SIG_NEW "\x55\x8B\xEC\x2A\x8B\x2A\x0C\x85\x2A\x74\x2A\x8B\x2A\xA4\x00\x00\x00" #define MOD_POINTINLEAF_SIG_BLOB "\x56\x8B\x74\x24\x0C\x85\xF6\x74\x2A\x8B\x86\xA4\x00\x00\x00\x85\xC0" @@ -180,6 +181,7 @@ #define R_RENDERDYNAMICLIGHTMAPS_SIG_NEW "\x55\x8B\xEC\x8B\x0D\x2A\x2A\x2A\x2A\x53\x41\x56\x89\x0D\x2A\x2A\x2A\x2A\x8B\x4D\x08\x57" #define R_RENDERDYNAMICLIGHTMAPS_SIG_HL25 "\x55\x8B\xEC\x8B\x55\x08\x83\xEC\x08\xFF\x05\x2A\x2A\x2A\x2A\xF6\x2A\x08\x14" #define R_RENDERDYNAMICLIGHTMAPS_SIG_SVENGINE "\x51\x8B\x54\x24\x08\xFF\x05\x2A\x2A\x2A\x2A\x57\x33\xFF\xF6\x42\x08\x14" +#define R_RENDERDYNAMICLIGHTMAPS_SIG_SVENGINE_10152 "\x8B\x54\x24\x04\x83\xEC\x0C\xFF\x05\x2A\x2A\x2A\x2A\x57\x33\xFF" #define R_BUILDLIGHTMAP_SIG_BLOB "\xD9\x05\x2A\x2A\x2A\x2A\xD8\x1D\x2A\x2A\x2A\x2A\x83\xEC\x18\xDF\xE0\xF6\xC4" #define R_BUILDLIGHTMAP_SIG_NEW "\x55\x8B\xEC\x83\xEC\x1C\xD9\x05\x2A\x2A\x2A\x2A\xD8\x1D\x2A\x2A\x2A\x2A\xDF\xE0" @@ -286,7 +288,8 @@ #define R_DRAWSRPITEMODEL_SIG_HL25 "\x55\x8B\xEC\x83\xEC\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\x2A\x2A\x2A\x8B\x75\x08\x2A\x8B\x2A\x94\x0B\x00\x00" #define R_DRAWSRPITEMODEL_SIG_SVENGINE "\x83\xEC\x2A\xA1\x2A\x2A\x2A\x2A\x33\xC4\x89\x44\x24\x2A\x53\x8B\x5C\x24\x2A\x55\x8B\x83\x2A\x0B\x00\x00" -#define R_LIGHTSTRENGTH_SIG_SVENGINE "\x8B\x15\x2A\x2A\x2A\x2A\x2A\x8B\x35\x2A\x2A\x2A\x2A\x2A\x8B\x7C\x24\x0C" +#define R_LIGHTSTRENGTH_SIG_SVENGINE "\x8B\x15\x2A\x2A\x2A\x2A\x2A\x8B\x35\x2A\x2A\x2A\x2A\x2A\x8B\x7C\x24\x0C" //inlined +#define R_LIGHTSTRENGTH_SIG_SVENGINE_10152 "\x8B\x54\x24\x04\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x2A\x8D\x2A\x2A\x39\x2A\x2A\x2A\x2A\x2A\x2A\x0F" //inlined #define R_LIGHTSTRENGTH_SIG_HL25 ""//inlined #define R_LIGHTSTRENGTH_SIG_NEW "\x55\x8B\xEC\x83\xEC\x0C\x8B\x4D\x08\x8B\x15\x2A\x2A\x2A\x2A\x2A\x8B\x04\x2A\x2A\x2A\x2A\x2A" #define R_LIGHTSTRENGTH_SIG_NEW2 "\x8B\x4C\x24\x04\x8B\x15\x2A\x2A\x2A\x2A\x83\xEC\x0C\x8B\x04\x2A\x2A\x2A\x2A\x2A\x3B\xC2" @@ -734,7 +737,7 @@ void R_FillAddress(void) return TRUE; return FALSE; - }); + }); } } } @@ -800,124 +803,362 @@ void R_FillAddress(void) Sig_FuncNotFound(R_SetupFrame); } - if (g_iEngineType == ENGINE_SVENGINE) - { - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_SVENGINE); - } - else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + + if (1) { - if (g_dwEngineBuildnum >= 9899) + const char pattern[] = "\x68\xE2\x0B\x00\x00\xFF\x2A\x68\xC0\x0B\x00\x00\xFF\x2A\x68\x71\x0B\x00\x00\xFF"; + /* +.text:01D56353 68 E2 0B 00 00 push 0BE2h ; cap +.text:01D56358 FF D6 call esi ; glDisable +.text:01D5635A 68 C0 0B 00 00 push 0BC0h ; cap +.text:01D5635F FF D6 call esi ; glDisable +.text:01D56361 68 71 0B 00 00 push 0B71h ; cap +.text:01D56366 FF D7 call edi ; glEnable + */ + + auto SetupGL_Call = Search_Pattern(pattern); + + if (SetupGL_Call) { - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_HL25_9899); + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))g_pMetaHookAPI->ReverseSearchFunctionBegin(SetupGL_Call, 0x600); } else { - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_HL25); + /* + .text:01D45BE0 68 E2 0B 00 00 push 0BE2h + .text:01D45BE5 FF 15 A4 1F 79 02 call dword_2791FA4 + .text:01D45BEB 68 C0 0B 00 00 push 0BC0h + .text:01D45BF0 FF 15 A4 1F 79 02 call dword_2791FA4 + .text:01D45BF6 68 71 0B 00 00 push 0B71h + .text:01D45BFB FF 15 3C 17 79 02 call dword_279173C + */ + const char pattern2[] = "\x68\xE2\x0B\x00\x00\xFF\x2A\x68\xC0\x0B\x00\x00\xFF\x2A\x68\x71\x0B\x00\x00\xFF"; + + SetupGL_Call = Search_Pattern(pattern2); + + if (SetupGL_Call) + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))g_pMetaHookAPI->ReverseSearchFunctionBegin(SetupGL_Call, 0x600); + } } } - else if (g_iEngineType == ENGINE_GOLDSRC) - { - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_NEW); - if(!gPrivateFuncs.R_SetupGL) - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_NEW2); - } - else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + + //Legacy + if (!gPrivateFuncs.R_SetupGL) { - gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_BLOB); + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_SVENGINE); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + if (g_dwEngineBuildnum >= 9899) + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_HL25_9899); + } + else + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_HL25); + } + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_NEW); + if (!gPrivateFuncs.R_SetupGL) + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_NEW2); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.R_SetupGL = (decltype(gPrivateFuncs.R_SetupGL))Search_Pattern(R_SETUPGL_SIG_BLOB); + } } Sig_FuncNotFound(R_SetupGL); - if (g_iEngineType == ENGINE_SVENGINE) - { - gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_SVENGINE); - } - else if (g_iEngineType == ENGINE_GOLDSRC_HL25) - { - gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_HL25); - } - else if (g_iEngineType == ENGINE_GOLDSRC) - { - gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_NEW); - if(!gPrivateFuncs.R_DrawSequentialPoly) - gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_NEW2); - } - else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + if (1) { - gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_BLOB); - } - Sig_FuncNotFound(R_DrawSequentialPoly); + const char R_RenderView_StringPattern[] = "R_RenderView: NULL worldmodel"; + auto R_RenderView_String = Search_Pattern_Data(R_RenderView_StringPattern); + if (!R_RenderView_String) + R_RenderView_String = Search_Pattern_Rdata(R_RenderView_StringPattern); + if (R_RenderView_String) + { + char pattern[] = "\x75\x2A\x68\x2A\x2A\x2A\x2A"; + *(DWORD*)(pattern + 3) = (DWORD)R_RenderView_String; + auto R_RenderView_PushString = Search_Pattern(pattern); + if (R_RenderView_PushString) + { + PVOID Candidate = g_pMetaHookAPI->ReverseSearchFunctionBeginEx(R_RenderView_PushString, 0x100, [](PUCHAR Candidate) { - if (g_iEngineType == ENGINE_SVENGINE) - { - gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_SVENGINE); - } - else if (g_iEngineType == ENGINE_GOLDSRC_HL25) - { - gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_HL25); - } - else if (g_iEngineType == ENGINE_GOLDSRC) - { - gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_NEW); - if(!gPrivateFuncs.R_TextureAnimation) - gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_NEW2); - } - else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) - { - gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_BLOB); - } - Sig_FuncNotFound(R_TextureAnimation); + if (Candidate[0] == 0xD9 && + Candidate[1] == 0x05) + return TRUE; - if (g_iEngineType == ENGINE_SVENGINE) - { - gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_SVENGINE); - Sig_FuncNotFound(V_RenderView); + if (Candidate[0] == 0x55 && + Candidate[1] == 0x8B && + Candidate[2] == 0xEC) + return TRUE; - gPrivateFuncs.R_RenderView_SvEngine = (decltype(gPrivateFuncs.R_RenderView_SvEngine))Search_Pattern(R_RENDERVIEW_SIG_SVENGINE); - Sig_FuncNotFound(R_RenderView_SvEngine); + return FALSE; + }); - char pattern[] = "\xDD\xD8\xDD\xD8\xE8"; - addr = (ULONG_PTR)Search_Pattern_From(gPrivateFuncs.R_RenderView_SvEngine, pattern); - Sig_AddrNotFound(R_RenderScene); - gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))GetCallAddress(addr + 4); - Sig_FuncNotFound(R_RenderScene); + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.R_RenderView_SvEngine = (decltype(gPrivateFuncs.R_RenderView_SvEngine))Candidate; + } + else + { + gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Candidate; + } + } + } } - else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + + if (gPrivateFuncs.R_RenderView && !gPrivateFuncs.V_RenderView) { - gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_HL25); - Sig_FuncNotFound(V_RenderView); + if (1) + { + const char pattern[] = "\x68\x00\x40\x00\x00\xFF"; + /* +.text:01DCDF5C 68 00 40 00 00 push 4000h ; mask +.text:01DCDF61 FF D3 call ebx ; glClear + */ + PUCHAR SearchBegin = (PUCHAR)g_dwEngineTextBase; + PUCHAR SearchLimit = (PUCHAR)g_dwEngineTextBase + g_dwEngineTextSize; + while (SearchBegin < SearchLimit) + { + PUCHAR pFound = (PUCHAR)Search_Pattern_From_Size(SearchBegin, SearchLimit - SearchBegin, pattern); + if (pFound) + { + typedef struct + { + bool bFoundCallRenderView; + }V_RenderView_SearchContext; + + V_RenderView_SearchContext ctx = { 0 }; + + g_pMetaHookAPI->DisasmRanges(pFound + 5, 0x120, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx = (V_RenderView_SearchContext*)context; + + if (address[0] == 0xE8) + { + PVOID target = (decltype(target))pinst->detail->x86.operands[0].imm; + + if (target == gPrivateFuncs.R_RenderView) + { + ctx->bFoundCallRenderView = true; + return TRUE; + } + } + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, &ctx); + + if (ctx.bFoundCallRenderView) + { + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))g_pMetaHookAPI->ReverseSearchFunctionBeginEx(pFound, 0x300, [](PUCHAR Candidate) { + + if (Candidate[0] == 0x81 && + Candidate[1] == 0xEC && + Candidate[4] == 0 && + Candidate[5] == 0) + return TRUE; + + if (Candidate[0] == 0x55 && + Candidate[1] == 0x8B && + Candidate[2] == 0xEC) + return TRUE; + + if (Candidate[0] == 0xA1 && + Candidate[5] == 0x81 && + Candidate[6] == 0xEC) + return TRUE; + + return FALSE; + }); - gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_HL25); - Sig_FuncNotFound(R_RenderView); + break; + } - gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_HL25); - Sig_FuncNotFound(R_RenderScene); + SearchBegin = pFound + Sig_Length(pattern); + } + else + { + break; + } + } + } } - else if (g_iEngineType == ENGINE_GOLDSRC) + + bool R_RenderScene_inlined = false; + + if ((gPrivateFuncs.R_RenderView_SvEngine || gPrivateFuncs.R_RenderView) && gPrivateFuncs.R_SetupGL) { - gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_NEW); - if(!gPrivateFuncs.V_RenderView) - gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_NEW2); - Sig_FuncNotFound(V_RenderView); + typedef struct + { + bool bFoundCallSetupGL; + bool* R_RenderScene_inlined; + }R_RenderView_SearchContext; + + R_RenderView_SearchContext ctx = { 0 }; - gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_NEW); - if (!gPrivateFuncs.R_RenderView) - gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_NEW2); - Sig_FuncNotFound(R_RenderView); + ctx.R_RenderScene_inlined = &R_RenderScene_inlined; - gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_NEW); - Sig_FuncNotFound(R_RenderScene); + PVOID SearchBase = gPrivateFuncs.R_RenderView_SvEngine; + if (!SearchBase) + SearchBase = gPrivateFuncs.R_RenderView; + + g_pMetaHookAPI->DisasmRanges(SearchBase, 0x500, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx = (R_RenderView_SearchContext*)context; + + if (address[0] == 0xE8) + { + PVOID target = (decltype(target))pinst->detail->x86.operands[0].imm; + + if (target == gPrivateFuncs.R_SetupGL) + { + ctx->bFoundCallSetupGL = true; + (*ctx->R_RenderScene_inlined) = true; + return TRUE; + } + else + { + R_RenderView_SearchContext ctx2 = { 0 }; + + g_pMetaHookAPI->DisasmRanges(target, 0x300, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx2 = (R_RenderView_SearchContext*)context; + + PVOID target = (decltype(target))pinst->detail->x86.operands[0].imm; + + if (target == gPrivateFuncs.R_SetupGL) + { + ctx2->bFoundCallSetupGL = true; + return TRUE; + } + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, &ctx2); + + if (ctx2.bFoundCallSetupGL) + { + gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))target; + return TRUE; + } + } + } + + if (gPrivateFuncs.R_RenderScene) + return TRUE; + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, & ctx); } - else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + + if (!gPrivateFuncs.R_RenderView_SvEngine && !gPrivateFuncs.R_RenderView) + { + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.R_RenderView_SvEngine = (decltype(gPrivateFuncs.R_RenderView_SvEngine))Search_Pattern(R_RENDERVIEW_SIG_SVENGINE); + Sig_FuncNotFound(R_RenderView_SvEngine); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_HL25); + Sig_FuncNotFound(R_RenderView); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_NEW); + if (!gPrivateFuncs.R_RenderView) + gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_NEW2); + Sig_FuncNotFound(R_RenderView); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_BLOB); + Sig_FuncNotFound(R_RenderView); + } + } + + if (!gPrivateFuncs.V_RenderView) { - gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_BLOB); - Sig_FuncNotFound(V_RenderView); + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_SVENGINE); + Sig_FuncNotFound(V_RenderView); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_HL25); + Sig_FuncNotFound(V_RenderView); - gPrivateFuncs.R_RenderView = (decltype(gPrivateFuncs.R_RenderView))Search_Pattern(R_RENDERVIEW_SIG_BLOB); - Sig_FuncNotFound(R_RenderView); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_NEW); + if (!gPrivateFuncs.V_RenderView) + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_NEW2); + Sig_FuncNotFound(V_RenderView); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.V_RenderView = (decltype(gPrivateFuncs.V_RenderView))Search_Pattern(V_RENDERVIEW_SIG_BLOB); + Sig_FuncNotFound(V_RenderView); + } + } - gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_BLOB); - Sig_FuncNotFound(R_RenderScene); + if (!R_RenderScene_inlined && !gPrivateFuncs.R_RenderScene) + { + if (g_iEngineType == ENGINE_SVENGINE) + { + char pattern[] = "\xDD\xD8\xDD\xD8\xE8"; + addr = (ULONG_PTR)Search_Pattern_From(gPrivateFuncs.R_RenderView_SvEngine, pattern); + Sig_AddrNotFound(R_RenderScene); + gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))GetCallAddress(addr + 4); + Sig_FuncNotFound(R_RenderScene); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_HL25); + Sig_FuncNotFound(R_RenderScene); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_NEW); + Sig_FuncNotFound(R_RenderScene); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.R_RenderScene = (decltype(gPrivateFuncs.R_RenderScene))Search_Pattern(R_RENDERSCENE_SIG_BLOB); + Sig_FuncNotFound(R_RenderScene); + } } if (g_iEngineType == ENGINE_SVENGINE) @@ -1165,25 +1406,49 @@ void R_FillAddress(void) } Sig_FuncNotFound(GL_EnableMultitexture); + if (g_iEngineType == ENGINE_SVENGINE) { - gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_SVENGINE); + gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_SVENGINE); } else if (g_iEngineType == ENGINE_GOLDSRC_HL25) { - gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_HL25); + gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_HL25); } else if (g_iEngineType == ENGINE_GOLDSRC) { - gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_NEW); - if(!gPrivateFuncs.R_RenderDynamicLightmaps) - gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_NEW2); + gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_NEW); + if (!gPrivateFuncs.R_DrawSequentialPoly) + gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_NEW2); } else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) { - gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_BLOB); + gPrivateFuncs.R_DrawSequentialPoly = (decltype(gPrivateFuncs.R_DrawSequentialPoly))Search_Pattern(R_DRAWSEQUENTIALPOLY_SIG_BLOB); + } + Sig_FuncNotFound(R_DrawSequentialPoly); + + if (!gPrivateFuncs.R_TextureAnimation) + { + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_SVENGINE); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_HL25); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_NEW); + if (!gPrivateFuncs.R_TextureAnimation) + gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_NEW2); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.R_TextureAnimation = (decltype(gPrivateFuncs.R_TextureAnimation))Search_Pattern(R_TEXTUREANIMATION_SIG_BLOB); + } + Sig_FuncNotFound(R_TextureAnimation); } - Sig_FuncNotFound(R_RenderDynamicLightmaps); if (g_iEngineType == ENGINE_SVENGINE) { @@ -1510,7 +1775,7 @@ void R_FillAddress(void) if (1) { - const char sigs1[] = "Mod_PointInLeaf: bad model"; + const char sigs1[] = "Mod_PointInLeaf: bad model\0"; auto BadModel_String = Search_Pattern_Data(sigs1); if (!BadModel_String) BadModel_String = Search_Pattern_Rdata(sigs1); @@ -1533,6 +1798,10 @@ void R_FillAddress(void) Candidate[2] == 0xEC) return TRUE; + if (Candidate[0] == 0x8B && + Candidate[2] == 0x24) + return TRUE; + return FALSE; }); } @@ -1544,6 +1813,8 @@ void R_FillAddress(void) if (g_iEngineType == ENGINE_SVENGINE) { gPrivateFuncs.Mod_PointInLeaf = (decltype(gPrivateFuncs.Mod_PointInLeaf))Search_Pattern(MOD_POINTINLEAF_SIG_SVENGINE); + if(!gPrivateFuncs.Mod_PointInLeaf) + gPrivateFuncs.Mod_PointInLeaf = (decltype(gPrivateFuncs.Mod_PointInLeaf))Search_Pattern(MOD_POINTINLEAF_SIG_SVENGINE_10152); } else if (g_iEngineType == ENGINE_GOLDSRC_HL25) { @@ -2338,6 +2609,8 @@ void R_FillAddress(void) if (g_iEngineType == ENGINE_SVENGINE) { gPrivateFuncs.R_LightStrength = (decltype(gPrivateFuncs.R_LightStrength))Search_Pattern(R_LIGHTSTRENGTH_SIG_SVENGINE); + if(!gPrivateFuncs.R_LightStrength) + gPrivateFuncs.R_LightStrength = (decltype(gPrivateFuncs.R_LightStrength))Search_Pattern(R_LIGHTSTRENGTH_SIG_SVENGINE_10152); Sig_FuncNotFound(R_LightStrength); } else if (g_iEngineType == ENGINE_GOLDSRC_HL25) @@ -2534,6 +2807,12 @@ void R_FillAddress(void) Candidate[2] == 0x08) return TRUE; + if (Candidate[0] == 0xA1 && + Candidate[5] == 0x83 && + Candidate[6] == 0xEC && + Candidate[7] == 0x08) + return TRUE; + return FALSE; }); @@ -2557,63 +2836,191 @@ void R_FillAddress(void) auto Sprite_PushString = (PUCHAR)Search_Pattern(pattern); if (Sprite_PushString) { - auto Sprite_Function = (PUCHAR)g_pMetaHookAPI->ReverseSearchFunctionBeginEx(Sprite_PushString, 0x300, [](PUCHAR Candidate) { + auto Sprite_Function = (PUCHAR)g_pMetaHookAPI->ReverseSearchFunctionBeginEx(Sprite_PushString, 0x300, [](PUCHAR Candidate) { + + if (Candidate[0] == 0x55 && + Candidate[1] == 0x8B && + Candidate[2] == 0xEC) + return TRUE; + + if (Candidate[0] == 0x83 && + Candidate[1] == 0xEC && + Candidate[2] == 0x08) + return TRUE; + + if (Candidate[-1] == 0x90 && + Candidate[0] >= 0x50 && + Candidate[0] <= 0x57 && + Candidate[1] >= 0x50 && + Candidate[1] <= 0x57 && + Candidate[2] >= 0x50 && + Candidate[2] <= 0x57 && + Candidate[3] >= 0x50 && + Candidate[3] <= 0x57) + return TRUE; + + return FALSE; + }); + + if (Sprite_Function) + { + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Sprite_Function; + } + } + } + } + + if (!gPrivateFuncs.Mod_LoadSpriteModel) + { + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_SVENGINE); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_HL25); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_NEW); + if (!gPrivateFuncs.Mod_LoadSpriteModel) + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_NEW2); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_BLOB); + } + } + Sig_FuncNotFound(Mod_LoadSpriteModel); + + if (1) + { + g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.Mod_LoadSpriteModel, 0x240, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + + if (address[0] == 0xE8) + { + PVOID target = (decltype(target))pinst->detail->x86.operands[0].imm; + + typedef struct + { + bool bFoundPush300h; + }Mod_LoadSpriteModel_SearchContext; + + Mod_LoadSpriteModel_SearchContext ctx = { 0 }; + + g_pMetaHookAPI->DisasmRanges(target, 0x60, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx = (Mod_LoadSpriteModel_SearchContext*)context; + + if (pinst->id == X86_INS_PUSH && + pinst->detail->x86.op_count == 1 && + pinst->detail->x86.operands[0].type == X86_OP_IMM && + pinst->detail->x86.operands[0].imm == 0x300) + { + ctx->bFoundPush300h = true; + return TRUE; + } + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, & ctx); + + if (ctx.bFoundPush300h) + { + gPrivateFuncs.Mod_LoadSpriteFrame = (decltype(gPrivateFuncs.Mod_LoadSpriteFrame))target; + return TRUE; + } + } + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, NULL); + + Sig_FuncNotFound(Mod_LoadSpriteFrame); + } + + if (1) + { + typedef struct + { + int MovRegMem_InstCount; + int MovRegMem_Reg; + PVOID MovRegMem_CandidateMem; + }Mod_LoadSpriteFrame_SearchContext; + + Mod_LoadSpriteFrame_SearchContext ctx = { 0 }; + g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.Mod_LoadSpriteFrame, 0x300, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx = (Mod_LoadSpriteFrame_SearchContext*)context; + + if (pinst->id == X86_INS_CMP && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + pinst->detail->x86.operands[0].mem.base == 0 && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && + pinst->detail->x86.operands[1].type == X86_OP_IMM && + pinst->detail->x86.operands[1].imm == 0) + { + gSpriteMipMap = (decltype(gSpriteMipMap))pinst->detail->x86.operands[0].mem.disp; + return TRUE; + } - if (Candidate[0] == 0x55 && - Candidate[1] == 0x8B && - Candidate[2] == 0xEC) - return TRUE; + if (pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[1].type == X86_OP_MEM && + pinst->detail->x86.operands[1].mem.base == 0 && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) + { + ctx->MovRegMem_Reg = pinst->detail->x86.operands[0].reg; + ctx->MovRegMem_CandidateMem = (decltype(ctx->MovRegMem_CandidateMem))pinst->detail->x86.operands[1].mem.disp; + ctx->MovRegMem_InstCount = instCount; + } - if (Candidate[0] == 0x83 && - Candidate[1] == 0xEC && - Candidate[2] == 0x08) - return TRUE; + if (instCount == ctx->MovRegMem_InstCount + 1 && + pinst->id == X86_INS_TEST && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[1].type == X86_OP_REG && + pinst->detail->x86.operands[0].reg == ctx->MovRegMem_Reg && + pinst->detail->x86.operands[1].reg == ctx->MovRegMem_Reg) + { + gSpriteMipMap = (decltype(gSpriteMipMap))ctx->MovRegMem_CandidateMem; + return TRUE; + } - if (Candidate[-1] == 0x90 && - Candidate[0] >= 0x50 && - Candidate[0] <= 0x57 && - Candidate[1] >= 0x50 && - Candidate[1] <= 0x57 && - Candidate[2] >= 0x50 && - Candidate[2] <= 0x57 && - Candidate[3] >= 0x50 && - Candidate[3] <= 0x57) - return TRUE; + if (address[0] == 0xCC) + return TRUE; - return FALSE; - }); + if (pinst->id == X86_INS_RET) + return TRUE; - if (Sprite_Function) - { - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Sprite_Function; - } - } - } - } + return FALSE; - if (!gPrivateFuncs.Mod_LoadSpriteModel) - { - if (g_iEngineType == ENGINE_SVENGINE) - { - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_SVENGINE); - } - else if (g_iEngineType == ENGINE_GOLDSRC_HL25) - { - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_HL25); - } - else if (g_iEngineType == ENGINE_GOLDSRC) - { - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_NEW); - if (!gPrivateFuncs.Mod_LoadSpriteModel) - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_NEW2); - } - else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) - { - gPrivateFuncs.Mod_LoadSpriteModel = (decltype(gPrivateFuncs.Mod_LoadSpriteModel))Search_Pattern(MOD_LOADSPRITEMODEL_BLOB); - } + }, 0, &ctx); + + Sig_VarNotFound(gSpriteMipMap); } - Sig_FuncNotFound(Mod_LoadSpriteModel); +#if 0 if (1) { const char pattern[] = "\xC7\x05\x2A\x2A\x2A\x2A\x00\x00\x00\x00\xE8"; @@ -2645,6 +3052,7 @@ void R_FillAddress(void) } } Sig_VarNotFound(gSpriteMipMap); +#endif //Engine's R_AddTEntity is not used anymore if (g_iEngineType == ENGINE_SVENGINE) @@ -2925,7 +3333,7 @@ void R_FillAddress(void) if (1) { - char pattern[] = "\x8B\x0D\x2A\x2A\x2A\x2A\x81\xF9\x00\x02\x00\x00"; + char pattern[] = "\x8B\x0D\x2A\x2A\x2A\x2A\x81\xF9\x00\x2A\x00\x00"; auto ClientDLL_AddEntity_Pattern = Search_Pattern(pattern); Sig_VarNotFound(ClientDLL_AddEntity_Pattern); @@ -3056,33 +3464,43 @@ void R_FillAddress(void) { PVOID R_RenderFinalFog = NULL; + PVOID SearchBase = gPrivateFuncs.R_RenderScene; + + if (!SearchBase) + { + SearchBase = gPrivateFuncs.R_RenderView_SvEngine; + + if (!SearchBase) + SearchBase = gPrivateFuncs.R_RenderView; + } + if (g_iEngineType == ENGINE_SVENGINE) { const char sigs[] = "\x83\x3D\x2A\x2A\x2A\x2A\x00\x2A\x2A\x68\x60\x0B\x00\x00"; - addr = (DWORD)Search_Pattern_From_Size((void*)gPrivateFuncs.R_RenderScene, 0x600, sigs); + addr = (DWORD)Search_Pattern_From_Size(SearchBase, 0x600, sigs); Sig_AddrNotFound(R_RenderFinalFog); - R_RenderFinalFog = (decltype(R_RenderFinalFog))addr; + gPrivateFuncs.R_RenderFinalFog = (decltype(gPrivateFuncs.R_RenderFinalFog))addr; g_bUserFogOn = *(int**)(addr + 2); } else if (g_iEngineType == ENGINE_GOLDSRC_HL25) { const char sigs[] = "\x83\x3D\x2A\x2A\x2A\x2A\x00\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x60\x0B\x00\x00"; - addr = (DWORD)Search_Pattern_From_Size((void*)gPrivateFuncs.R_RenderScene, 0x600, sigs); + addr = (DWORD)Search_Pattern_From_Size(SearchBase, 0x600, sigs); Sig_AddrNotFound(R_RenderFinalFog); - R_RenderFinalFog = (decltype(R_RenderFinalFog))GetCallAddress(addr + 9); + gPrivateFuncs.R_RenderFinalFog = (decltype(gPrivateFuncs.R_RenderFinalFog))GetCallAddress(addr + 9); g_bUserFogOn = *(int**)(addr + 2); } else { const char sigs[] = "\xA1\x2A\x2A\x2A\x2A\x85\xC0\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x6A\x00"; - addr = (DWORD)Search_Pattern_From_Size((void*)gPrivateFuncs.R_RenderScene, 0x600, sigs); - Sig_AddrNotFound(g_bUserFogOn); + addr = (DWORD)Search_Pattern_From_Size(SearchBase, 0x600, sigs); + Sig_AddrNotFound(R_RenderFinalFog); - R_RenderFinalFog = (decltype(R_RenderFinalFog))GetCallAddress(addr + 9); + gPrivateFuncs.R_RenderFinalFog = (decltype(gPrivateFuncs.R_RenderFinalFog))GetCallAddress(addr + 9); g_bUserFogOn = *(int**)(addr + 1); } @@ -3095,8 +3513,7 @@ void R_FillAddress(void) R_RenderFinalFog_ctx ctx = { 0 }; - g_pMetaHookAPI->DisasmRanges(R_RenderFinalFog, 0x100, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) - { + g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.R_RenderFinalFog, 0x100, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { auto pinst = (cs_insn*)inst; auto ctx = (R_RenderFinalFog_ctx*)context; @@ -3179,7 +3596,7 @@ void R_FillAddress(void) return TRUE; return FALSE; - }, 0, &ctx); + }, 0, &ctx); Sig_VarNotFound(g_UserFogDensity); Sig_VarNotFound(g_UserFogColor); @@ -3683,8 +4100,8 @@ void R_FillAddress(void) R_LoadSkys_String = Search_Pattern_Rdata(sigs); Sig_VarNotFound(R_LoadSkys_String); - char pattern[] = "\x68\x2A\x2A\x2A\x2A\xC7\x2A\x2A\x2A\x2A\x00\x00"; - *(DWORD *)(pattern + 1) = (DWORD)R_LoadSkys_String; + char pattern[] = "\x75\x2A\x68\x2A\x2A\x2A\x2A"; + *(DWORD *)(pattern + 3) = (DWORD)R_LoadSkys_String; auto R_LoadSkys_PushString = Search_Pattern(pattern); Sig_VarNotFound(R_LoadSkys_PushString); @@ -4122,10 +4539,29 @@ void R_FillAddress(void) if (g_iEngineType == ENGINE_SVENGINE) { - const char sigs[] = "\xD9\x54\x24\x2A\xD9\x05\x2A\x2A\x2A\x2A\xD9\xE8"; - addr = (DWORD)Search_Pattern_From_Size((void *)gPrivateFuncs.R_SetupGL, 0x100, sigs); + /* +void sub_1D1A030() +{ + float v0; // [esp+0h] [ebp-48h] + float v1[8]; // [esp+4h] [ebp-44h] BYREF + _BYTE v2[32]; // [esp+24h] [ebp-24h] BYREF + + if ( dword_20D7D70 == 5 && !dword_2108F6C ) + { + sub_1D3D7B0(v1, 0, 0x20u); + v1[3] = flt_234B6B4; + v1[4] = flt_234B6B8; + v1[5] = flt_234B6BC; + v1[0] = *((float *)dword_2723390 + 750 * dword_270AFBC + 722); + v1[1] = *((float *)dword_2723390 + 750 * dword_270AFBC + 723); + v1[2] = *((float *)dword_2723390 + 750 * dword_270AFBC + 724); + v1[7] = scrfov; + */ + + const char sigs[] = "\xD9\x05\x2A\x2A\x2A\x2A\xD9\x5C\x24\x1C\x89\x44\x24\x18"; + addr = (DWORD)Search_Pattern(sigs); Sig_AddrNotFound(scrfov); - scrfov = *(decltype(scrfov)*)(addr + 6); + scrfov = *(decltype(scrfov)*)(addr + 2); } else { @@ -4141,7 +4577,7 @@ void R_FillAddress(void) if (1) { - const char sigs[] = "\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08"; + const char sigs[] = "\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4"; addr = (DWORD)Search_Pattern_From_Size((void *)gPrivateFuncs.R_SetupGL, 0x700, sigs); Sig_AddrNotFound(gWorldToScreen); gWorldToScreen = *(decltype(gWorldToScreen)*)(addr + 6); @@ -4150,53 +4586,104 @@ void R_FillAddress(void) if (1) { - g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.R_RenderScene, 0x100, [](void *inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) + PVOID SearchBase = gPrivateFuncs.R_RenderScene; + int SearchLength = 0x100; + + if (!SearchBase) { - auto pinst = (cs_insn *)inst; + SearchBase = gPrivateFuncs.R_RenderView_SvEngine; + SearchLength = 0x450; + } + if (!SearchBase) + { + SearchBase = gPrivateFuncs.R_RenderView; + SearchLength = 0x450; + } - if (!gPrivateFuncs.CL_IsDevOverviewMode && address[0] == 0xE8 && address[5] == 0x85) - { - gPrivateFuncs.CL_IsDevOverviewMode = (decltype(gPrivateFuncs.CL_IsDevOverviewMode))pinst->detail->x86.operands[0].imm; - } + typedef struct + { + int Call_Candidate_instCount; + PVOID Call_Candidate; + }R_RenderScene_ctx1; - if (gPrivateFuncs.CL_IsDevOverviewMode && !gPrivateFuncs.CL_SetDevOverView && address[0] == 0xE8 && address[-5] == 0x68 && address[5] == 0x83) - { - if (g_iEngineType == ENGINE_SVENGINE) + R_RenderScene_ctx1 ctx1; + + g_pMetaHookAPI->DisasmRanges(SearchBase, SearchLength, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + auto pinst = (cs_insn*)inst; + auto ctx = (R_RenderScene_ctx1*)context; + + if (!gPrivateFuncs.CL_IsDevOverviewMode) { - r_refdef_SvEngine = *(decltype(r_refdef_SvEngine)*)(address - 4); - r_refdef.vrect = &r_refdef_SvEngine->vrect; - r_refdef.vieworg = &r_refdef_SvEngine->vieworg; - r_refdef.viewangles = &r_refdef_SvEngine->viewangles; - r_refdef.ambientlight = &r_refdef_SvEngine->ambientlight; - r_refdef.onlyClientDraws = &r_refdef_SvEngine->onlyClientDraws; + if (address[0] == 0xE8 && address[5] == 0x85 && address[6] == 0xC0) + { + ctx->Call_Candidate = (decltype(ctx->Call_Candidate))pinst->detail->x86.operands[0].imm; + ctx->Call_Candidate_instCount = instCount; + } + + if (address[0] == 0x68 && address[5] == 0xE8 && instCount > ctx->Call_Candidate_instCount && instCount <= ctx->Call_Candidate_instCount + 3) + { + gPrivateFuncs.CL_IsDevOverviewMode = (decltype(gPrivateFuncs.CL_IsDevOverviewMode))ctx->Call_Candidate; + } + } - else + + + if (gPrivateFuncs.CL_IsDevOverviewMode && !gPrivateFuncs.CL_SetDevOverView && address[0] == 0xE8 && address[-5] == 0x68 && address[5] == 0x83) { - r_refdef_GoldSrc = *(decltype(r_refdef_GoldSrc)*)(address - 4); - r_refdef.vrect = &r_refdef_GoldSrc->vrect; - r_refdef.vieworg = &r_refdef_GoldSrc->vieworg; - r_refdef.viewangles = &r_refdef_GoldSrc->viewangles; - r_refdef.ambientlight = &r_refdef_GoldSrc->ambientlight; - r_refdef.onlyClientDraws = &r_refdef_GoldSrc->onlyClientDraws; + if (g_iEngineType == ENGINE_SVENGINE) + { + r_refdef_SvEngine = *(decltype(r_refdef_SvEngine)*)(address - 4); + r_refdef.vrect = &r_refdef_SvEngine->vrect; + r_refdef.vieworg = &r_refdef_SvEngine->vieworg; + r_refdef.viewangles = &r_refdef_SvEngine->viewangles; + r_refdef.ambientlight = &r_refdef_SvEngine->ambientlight; + r_refdef.onlyClientDraws = &r_refdef_SvEngine->onlyClientDraws; + } + else + { + r_refdef_GoldSrc = *(decltype(r_refdef_GoldSrc)*)(address - 4); + r_refdef.vrect = &r_refdef_GoldSrc->vrect; + r_refdef.vieworg = &r_refdef_GoldSrc->vieworg; + r_refdef.viewangles = &r_refdef_GoldSrc->viewangles; + r_refdef.ambientlight = &r_refdef_GoldSrc->ambientlight; + r_refdef.onlyClientDraws = &r_refdef_GoldSrc->onlyClientDraws; + } + + gPrivateFuncs.CL_SetDevOverView = (decltype(gPrivateFuncs.CL_SetDevOverView))pinst->detail->x86.operands[0].imm; } - gPrivateFuncs.CL_SetDevOverView = (decltype(gPrivateFuncs.CL_SetDevOverView))pinst->detail->x86.operands[0].imm; - } + if (gPrivateFuncs.CL_IsDevOverviewMode && gPrivateFuncs.CL_SetDevOverView) + return TRUE; - if (gPrivateFuncs.CL_IsDevOverviewMode && gPrivateFuncs.CL_SetDevOverView) - return TRUE; + if (address[0] == 0xCC) + return TRUE; - if (address[0] == 0xCC) - return TRUE; + if (pinst->id == X86_INS_RET) + return TRUE; - if (pinst->id == X86_INS_RET) - return TRUE; + return FALSE; - return FALSE; - }, 0, NULL); + }, 0, &ctx1); Sig_FuncNotFound(CL_IsDevOverviewMode); Sig_FuncNotFound(CL_SetDevOverView); + } + + if (1) + { + PVOID SearchBase = gPrivateFuncs.R_RenderScene; + int SearchLength = 0x600; + + if (!SearchBase) + { + SearchBase = gPrivateFuncs.R_RenderView_SvEngine; + SearchLength = 0x800; + } + if (!SearchBase) + { + SearchBase = gPrivateFuncs.R_RenderView; + SearchLength = 0x800; + } typedef struct { @@ -4206,7 +4693,7 @@ void R_FillAddress(void) R_RenderScene_ctx2 ctx2; - g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.R_RenderScene, 0x600, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) + g_pMetaHookAPI->DisasmRanges(SearchBase, SearchLength, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { auto pinst = (cs_insn*)inst; auto ctx = (R_RenderScene_ctx2 *)context; @@ -4358,8 +4845,7 @@ void R_FillAddress(void) if (g_iEngineType == ENGINE_SVENGINE) { - g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.CL_IsDevOverviewMode, 0x50, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) - { + g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.CL_IsDevOverviewMode, 0x50, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { auto pinst = (cs_insn*)inst; if (pinst->id == X86_INS_CMP && @@ -4369,7 +4855,6 @@ void R_FillAddress(void) pinst->detail->x86.operands[1].type == X86_OP_IMM && pinst->detail->x86.operands[1].imm == 0) { - allow_cheats = (decltype(allow_cheats))pinst->detail->x86.operands[0].mem.disp; } @@ -4860,94 +5345,6 @@ void R_FillAddress(void) Sig_VarNotFound(modelorg); } - if (1) - { - typedef struct - { - int cmp_al_FF_instcount; - }R_RenderDynamicLightmaps_ctx; - - R_RenderDynamicLightmaps_ctx ctx = { 0 }; - - g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.R_RenderDynamicLightmaps, 0x150, [](void *inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) - { - auto pinst = (cs_insn *)inst; - auto ctx = (R_RenderDynamicLightmaps_ctx *)context; - - if (!lightmap_polys && - pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_MEM && - pinst->detail->x86.operands[0].mem.index != 0 && - pinst->detail->x86.operands[0].mem.base == 0 && - pinst->detail->x86.operands[0].mem.scale == 4 && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && - pinst->detail->x86.operands[1].type == X86_OP_REG && - pinst->detail->x86.operands[1].reg == X86_REG_EAX) - {//.text:01D58422 89 04 8D C8 B8 F5 03 mov lightmap_polys[ecx*4], eax - - lightmap_polys = (decltype(lightmap_polys))pinst->detail->x86.operands[0].mem.disp; - } - else if (pinst->id == X86_INS_CMP && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_REG && - pinst->detail->x86.operands[0].reg == X86_REG_AL && - pinst->detail->x86.operands[1].type == X86_OP_IMM && - pinst->detail->x86.operands[1].imm == 0xFF ) - {//.text:01D47F46 3C FF cmp al, 0FFh - - ctx->cmp_al_FF_instcount = instCount; - } - else if (!d_lightstylevalue && - ctx->cmp_al_FF_instcount && - instCount < ctx->cmp_al_FF_instcount + 5 && - pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_REG && - pinst->detail->x86.operands[1].type == X86_OP_MEM && - pinst->detail->x86.operands[1].mem.index != 0 && - pinst->detail->x86.operands[1].mem.base == 0 && - pinst->detail->x86.operands[1].mem.scale == 4 && - (PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) - {//.text:01D47F4F 8B 04 85 20 9A BC 02 mov eax, d_lightstylevalue[eax*4] - - d_lightstylevalue = (decltype(d_lightstylevalue))pinst->detail->x86.operands[1].mem.disp; - } - else if (!lightmap_modified && - pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_MEM && - pinst->detail->x86.operands[0].mem.index != 0 && - pinst->detail->x86.operands[0].mem.base == 0 && - pinst->detail->x86.operands[0].mem.scale == 4 && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && - pinst->detail->x86.operands[1].type == X86_OP_IMM && - pinst->detail->x86.operands[1].imm == 1) - {//.text:01D58489 C7 04 85 C8 C8 F5 03 01 00 00 00 mov lightmap_modified[eax*4], 1 - - lightmap_modified = (decltype(lightmap_modified))pinst->detail->x86.operands[0].mem.disp; - } - - if (d_lightstylevalue && lightmap_polys && lightmap_modified) - return TRUE; - - if (address[0] == 0xCC) - return TRUE; - - if (pinst->id == X86_INS_RET) - return TRUE; - - return FALSE; - }, 0, &ctx); - - Sig_VarNotFound(d_lightstylevalue); - Sig_VarNotFound(lightmap_polys); - Sig_VarNotFound(lightmap_modified); - } - if (1) { typedef struct @@ -5045,9 +5442,9 @@ void R_FillAddress(void) R_DrawSequentialPoly_ctx ctx = { 0 }; ctx.base = gPrivateFuncs.R_DrawSequentialPoly; - ctx.max_insts = 500; + ctx.max_insts = 1000; ctx.max_depth = 16; - ctx.walks.emplace_back(ctx.base, 0x500, 0); + ctx.walks.emplace_back(ctx.base, 0x1000, 0); while (ctx.walks.size()) { @@ -5059,7 +5456,7 @@ void R_FillAddress(void) auto pinst = (cs_insn *)inst; auto ctx = (R_DrawSequentialPoly_ctx *)context; - if (lightmap_textures && lightmap_rectchange && lightmaps && gDecalSurfs && gDecalSurfCount) + if (lightmap_textures && lightmap_rectchange && lightmaps && gDecalSurfs && gDecalSurfCount && gPrivateFuncs.R_RenderDynamicLightmaps) return TRUE; if (ctx->code.size() > ctx->max_insts) @@ -5177,24 +5574,81 @@ void R_FillAddress(void) pinst->detail->x86.operands[0].reg == ctx->decalsurf_register) {//.text:01D47C0F 40 inc eax - gDecalSurfs = (decltype(gDecalSurfs))ctx->decalsurf_candidate; - } - else if (!gDecalSurfCount && - ctx->decalsurf_candidate && - instCount < ctx->decalsurf_instcount + 5 && - pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_MEM && - pinst->detail->x86.operands[0].mem.base == 0 && - pinst->detail->x86.operands[0].mem.index == 0 && - pinst->detail->x86.operands[0].mem.scale == 1 && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp >(PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && - pinst->detail->x86.operands[1].type == X86_OP_REG && - pinst->detail->x86.operands[1].reg == ctx->decalsurf_register) - {//.text:01D47C15 A3 98 26 34 02 mov gDecalSurfCount, eax + gDecalSurfs = (decltype(gDecalSurfs))ctx->decalsurf_candidate; + } + else if (!gDecalSurfCount && + ctx->decalsurf_candidate && + instCount < ctx->decalsurf_instcount + 5 && + pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + pinst->detail->x86.operands[0].mem.base == 0 && + pinst->detail->x86.operands[0].mem.index == 0 && + pinst->detail->x86.operands[0].mem.scale == 1 && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp >(PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && + pinst->detail->x86.operands[1].type == X86_OP_REG && + pinst->detail->x86.operands[1].reg == ctx->decalsurf_register) + {//.text:01D47C15 A3 98 26 34 02 mov gDecalSurfCount, eax + + gDecalSurfCount = (decltype(gDecalSurfCount))pinst->detail->x86.operands[0].mem.disp; + } + + if (address[0] == 0xE8) + { + PVOID target = (decltype(target))pinst->detail->x86.operands[0].imm; + + typedef struct + { + bool bFoundImm14h; + bool bFoundPush200; + }R_DrawSequentialPoly_FindRenderDynamicLightsContext; + + R_DrawSequentialPoly_FindRenderDynamicLightsContext ctx2 = { 0 }; + + g_pMetaHookAPI->DisasmRanges(target, 0x300, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + + auto pinst = (cs_insn*)inst; + auto ctx2 = (R_DrawSequentialPoly_FindRenderDynamicLightsContext*)context; + + if (!ctx2->bFoundImm14h) + { + if (pinst->detail->x86.op_count >= 2 && + pinst->detail->x86.operands[pinst->detail->x86.op_count - 1].type == X86_OP_IMM && + pinst->detail->x86.operands[pinst->detail->x86.op_count - 1].imm == 0x14) + { + ctx2->bFoundImm14h = true; + } + } + + if (!ctx2->bFoundPush200) + { + if (pinst->id == X86_INS_PUSH && + pinst->detail->x86.op_count == 1 && + pinst->detail->x86.operands[0].type == X86_OP_IMM && + pinst->detail->x86.operands[0].imm == 0x200) + { + ctx2->bFoundPush200 = true; + } + } + + if(ctx2->bFoundImm14h && ctx2->bFoundPush200) + return TRUE; - gDecalSurfCount = (decltype(gDecalSurfCount))pinst->detail->x86.operands[0].mem.disp; + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, & ctx2); + + if (ctx2.bFoundImm14h && ctx2.bFoundPush200) + { + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))target; + } } if ((pinst->id == X86_INS_JMP || (pinst->id >= X86_INS_JAE && pinst->id <= X86_INS_JS)) && @@ -5232,6 +5686,119 @@ void R_FillAddress(void) Sig_VarNotFound(gDecalSurfCount); } + if (!gPrivateFuncs.R_RenderDynamicLightmaps) + { + if (g_iEngineType == ENGINE_SVENGINE) + { + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_SVENGINE); + if (!gPrivateFuncs.R_RenderDynamicLightmaps) + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_SVENGINE_10152); + } + else if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_HL25); + } + else if (g_iEngineType == ENGINE_GOLDSRC) + { + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_NEW); + if (!gPrivateFuncs.R_RenderDynamicLightmaps) + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_NEW2); + } + else if (g_iEngineType == ENGINE_GOLDSRC_BLOB) + { + gPrivateFuncs.R_RenderDynamicLightmaps = (decltype(gPrivateFuncs.R_RenderDynamicLightmaps))Search_Pattern(R_RENDERDYNAMICLIGHTMAPS_SIG_BLOB); + } + Sig_FuncNotFound(R_RenderDynamicLightmaps); + } + + if (1) + { + typedef struct + { + int cmp_al_FF_instcount; + }R_RenderDynamicLightmaps_ctx; + + R_RenderDynamicLightmaps_ctx ctx = { 0 }; + + g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.R_RenderDynamicLightmaps, 0x150, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) + { + auto pinst = (cs_insn*)inst; + auto ctx = (R_RenderDynamicLightmaps_ctx*)context; + + if (!lightmap_polys && + pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + pinst->detail->x86.operands[0].mem.index != 0 && + pinst->detail->x86.operands[0].mem.base == 0 && + pinst->detail->x86.operands[0].mem.scale == 4 && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && + pinst->detail->x86.operands[1].type == X86_OP_REG && + pinst->detail->x86.operands[1].reg == X86_REG_EAX) + {//.text:01D58422 89 04 8D C8 B8 F5 03 mov lightmap_polys[ecx*4], eax + + lightmap_polys = (decltype(lightmap_polys))pinst->detail->x86.operands[0].mem.disp; + } + else if (pinst->id == X86_INS_CMP && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[0].reg == X86_REG_AL && + pinst->detail->x86.operands[1].type == X86_OP_IMM && + pinst->detail->x86.operands[1].imm == 0xFF) + {//.text:01D47F46 3C FF cmp al, 0FFh + + ctx->cmp_al_FF_instcount = instCount; + } + else if (!d_lightstylevalue && + ctx->cmp_al_FF_instcount && + instCount < ctx->cmp_al_FF_instcount + 5 && + pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[1].type == X86_OP_MEM && + pinst->detail->x86.operands[1].mem.index != 0 && + pinst->detail->x86.operands[1].mem.base == 0 && + pinst->detail->x86.operands[1].mem.scale == 4 && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp >(PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) + {//.text:01D47F4F 8B 04 85 20 9A BC 02 mov eax, d_lightstylevalue[eax*4] + + d_lightstylevalue = (decltype(d_lightstylevalue))pinst->detail->x86.operands[1].mem.disp; + } + else if (!lightmap_modified && + pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + pinst->detail->x86.operands[0].mem.index != 0 && + pinst->detail->x86.operands[0].mem.base == 0 && + pinst->detail->x86.operands[0].mem.scale == 4 && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize && + pinst->detail->x86.operands[1].type == X86_OP_IMM && + pinst->detail->x86.operands[1].imm == 1) + {//.text:01D58489 C7 04 85 C8 C8 F5 03 01 00 00 00 mov lightmap_modified[eax*4], 1 + + lightmap_modified = (decltype(lightmap_modified))pinst->detail->x86.operands[0].mem.disp; + } + + if (d_lightstylevalue && lightmap_polys && lightmap_modified) + return TRUE; + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + }, 0, &ctx); + + Sig_VarNotFound(d_lightstylevalue); + Sig_VarNotFound(lightmap_polys); + Sig_VarNotFound(lightmap_modified); + } + if (1) { typedef struct @@ -5785,24 +6352,7 @@ void R_FillAddress(void) #endif } - if (g_iEngineType == ENGINE_SVENGINE) - { -#define CL_MAXEDICTS_SIG_SVENGINE "\x69\xC0\xB8\x0B\x00\x00\x50\xE8\x2A\x2A\x2A\x2A\xFF\x35\x2A\x2A\x2A\x2A\xA3\x2A\x2A\x2A\x2A\xE8" - DWORD addr = (DWORD)Search_Pattern(CL_MAXEDICTS_SIG_SVENGINE); - Sig_AddrNotFound(cl_max_edicts); - cl_max_edicts = *(decltype(cl_max_edicts)*)(addr + 14); - cl_entities = *(decltype(cl_entities)*)(addr + 19); - -#define GTEMPENTS_SIG_SVENGINE "\x68\x00\xE0\x5F\x00\x6A\x00\x68\x2A\x2A\x2A\x2A\xA3" - if (1) - { - DWORD addr = (DWORD)Search_Pattern(GTEMPENTS_SIG_SVENGINE); - Sig_AddrNotFound(gTempEnts); - gTempEnts = *(decltype(gTempEnts)*)(addr + 8); - } - - } - else + if (1) { //Seach "CL_Reallocate cl_entities" const char sigs1[] = "CL_Reallocate cl_entities\n"; @@ -5810,7 +6360,7 @@ void R_FillAddress(void) if (!CL_Reallocate_String) CL_Reallocate_String = Search_Pattern_Rdata(sigs1); Sig_VarNotFound(CL_Reallocate_String); - char pattern[] = "\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xA1"; + char pattern[] = "\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A"; *(DWORD*)(pattern + 1) = (DWORD)CL_Reallocate_String; auto CL_Reallocate_Call = Search_Pattern(pattern); Sig_VarNotFound(CL_Reallocate_Call); @@ -5824,15 +6374,21 @@ void R_FillAddress(void) return TRUE; } - if (Candidate[0] == 0x8B && + if (Candidate[0] == 0x8B && Candidate[1] == 0x44 && Candidate[2] == 0x24) { return TRUE; } + if (Candidate[0] == 0xFF && + Candidate[2] == 0x24) + { + return TRUE; + } + return FALSE; - }); + }); Sig_VarNotFound(CL_ReallocateDynamicData); @@ -5846,53 +6402,86 @@ void R_FillAddress(void) ctx.CL_Reallocate_Call = CL_Reallocate_Call; g_pMetaHookAPI->DisasmRanges(CL_ReallocateDynamicData, 0x150, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) - { - auto pinst = (cs_insn*)inst; - auto ctx = (CL_ReallocateDynamicData_ctx*)context; - - if (!cl_max_edicts && pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_REG && - pinst->detail->x86.operands[1].type == X86_OP_MEM && - (PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) { - // mov eax, cl_max_edicts - // add esp, 4 + auto pinst = (cs_insn*)inst; + auto ctx = (CL_ReallocateDynamicData_ctx*)context; + + if (!cl_max_edicts && pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[1].type == X86_OP_MEM && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) + { + // mov eax, cl_max_edicts + // add esp, 4 + + if (0 == memcmp(address + instLen, "\x83\xC4\x04", 3)) + { + cl_max_edicts = (decltype(cl_max_edicts))pinst->detail->x86.operands[1].mem.disp; + } + } - if (0 == memcmp(address + instLen, "\x83\xC4\x04", 3)) + if (!cl_max_edicts && pinst->id == X86_INS_IMUL && + pinst->detail->x86.op_count == 3 && + pinst->detail->x86.operands[0].type == X86_OP_REG && + pinst->detail->x86.operands[1].type == X86_OP_MEM && + pinst->detail->x86.operands[2].type == X86_OP_IMM && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) { cl_max_edicts = (decltype(cl_max_edicts))pinst->detail->x86.operands[1].mem.disp; } - } - if (!cl_entities && address > ctx->CL_Reallocate_Call && pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[1].type == X86_OP_REG && - pinst->detail->x86.operands[1].reg == X86_REG_EAX && - pinst->detail->x86.operands[0].type == X86_OP_MEM && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) - { - // mov eax, cl_max_edicts - // add esp, 4 - cl_entities = (decltype(cl_entities))pinst->detail->x86.operands[0].mem.disp; - } + if (!cl_entities && address > ctx->CL_Reallocate_Call && pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[1].type == X86_OP_REG && + pinst->detail->x86.operands[1].reg == X86_REG_EAX && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) + { + // mov eax, cl_max_edicts + // add esp, 4 + cl_entities = (decltype(cl_entities))pinst->detail->x86.operands[0].mem.disp; + } - if (cl_entities && cl_max_edicts) - return TRUE; + if (cl_entities && cl_max_edicts) + return TRUE; - if (address[0] == 0xCC) - return TRUE; + if (address[0] == 0xCC) + return TRUE; - if (pinst->id == X86_INS_RET) - return TRUE; + if (pinst->id == X86_INS_RET) + return TRUE; - return FALSE; - }, 0, &ctx); + return FALSE; + }, 0, &ctx); Sig_VarNotFound(cl_max_edicts); Sig_VarNotFound(cl_entities); + } + + if (g_iEngineType == ENGINE_SVENGINE) + { +#if 0 +#define CL_MAXEDICTS_SIG_SVENGINE "\x69\xC0\xB8\x0B\x00\x00\x50\xE8\x2A\x2A\x2A\x2A\xFF\x35\x2A\x2A\x2A\x2A\xA3\x2A\x2A\x2A\x2A\xE8" + DWORD addr = (DWORD)Search_Pattern(CL_MAXEDICTS_SIG_SVENGINE); + Sig_AddrNotFound(cl_max_edicts); + cl_max_edicts = *(decltype(cl_max_edicts)*)(addr + 14); + cl_entities = *(decltype(cl_entities)*)(addr + 19); +#endif +#define GTEMPENTS_SIG_SVENGINE "\x68\x00\xE0\x5F\x00\x6A\x00\x68\x2A\x2A\x2A\x2A\xA3" + if (1) + { + DWORD addr = (DWORD)Search_Pattern(GTEMPENTS_SIG_SVENGINE); + Sig_AddrNotFound(gTempEnts); + gTempEnts = *(decltype(gTempEnts)*)(addr + 8); + } + + } + else + { #if 0 #define CL_MAXEDICTS_SIG_NEW "\xC1\xE1\x03\x51\xE8\x2A\x2A\x2A\x2A\x8B\x15\x2A\x2A\x2A\x2A\xA3" @@ -5992,7 +6581,12 @@ void R_FillAddress(void) if (g_iEngineType == ENGINE_SVENGINE) { const char sigs[] = "\xFF\x35\x2A\x2A\x2A\x2A\xDC\x0D\x2A\x2A\x2A\x2A\xFF\x35\x2A\x2A\x2A\x2A\xE8"; - addr = (DWORD)g_pMetaHookAPI->SearchPattern((void *)gPrivateFuncs.R_RenderView_SvEngine, 0x800, sigs, sizeof(sigs) - 1); + + int SearchLength = 0x800; + if (R_RenderScene_inlined) + SearchLength = 0x1000; + + addr = (ULONG_PTR)Search_Pattern_From_Size((void *)gPrivateFuncs.R_RenderView_SvEngine, SearchLength, sigs); Sig_AddrNotFound(c_brush_polys); c_alias_polys = *(int **)(addr + 2); c_brush_polys = *(int **)(addr + 14); @@ -6000,7 +6594,7 @@ void R_FillAddress(void) else if (g_iEngineType == ENGINE_GOLDSRC_HL25) { const char sigs[] = "\xC7\x05\x2A\x2A\x2A\x2A\x00\x00\x00\x00\xC7\x05\x2A\x2A\x2A\x2A\x00\x00\x00\x00"; - addr = (DWORD)g_pMetaHookAPI->SearchPattern((void*)gPrivateFuncs.R_RenderView, 0x100, sigs, sizeof(sigs) - 1); + addr = (ULONG_PTR)Search_Pattern_From_Size((void*)gPrivateFuncs.R_RenderView, 0x100, sigs); Sig_AddrNotFound(c_brush_polys); c_brush_polys = *(int**)(addr + 2); c_alias_polys = *(int**)(addr + 12); @@ -6008,7 +6602,7 @@ void R_FillAddress(void) else { const char sigs[] = "\xA1\x2A\x2A\x2A\x2A\x8B\x0D\x2A\x2A\x2A\x2A\x50\x51"; - addr = (DWORD)g_pMetaHookAPI->SearchPattern((void *)gPrivateFuncs.R_RenderView, 0x150, sigs, sizeof(sigs) - 1); + addr = (ULONG_PTR)Search_Pattern_From_Size((void *)gPrivateFuncs.R_RenderView, 0x150, sigs); Sig_AddrNotFound(c_brush_polys); c_alias_polys = *(int **)(addr + 1); c_brush_polys = *(int **)(addr + 7); @@ -6022,8 +6616,12 @@ void R_FillAddress(void) envmap = *(int **)(addr + 11); cl_stats = *(int **)(addr + 24); + int NextSearchLength = 0x300; + if (R_RenderScene_inlined) + NextSearchLength = 0x800; + const char sigs3[] = "\xD9\x1D\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x89\x81\xDC\x02\x00\x00"; - addr = (ULONG_PTR)Search_Pattern_From_Size(addr, 0x300, sigs3); + addr = (ULONG_PTR)Search_Pattern_From_Size(addr, NextSearchLength, sigs3); Sig_AddrNotFound(cl_weaponstarttime); cl_weaponstarttime = *(float **)(addr + 2); cl_weaponsequence = *(int **)(addr + 7); @@ -6456,11 +7054,35 @@ void R_FillAddress(void) if(1) { - const char sigs1[] = "\xFF\x15\x2A\x2A\x2A\x2A\x83\xC4\x0C\x3D\x49\x44\x50\x4F"; - auto Mod_LoadModel_Pattern = Search_Pattern(sigs1); - Sig_VarNotFound(Mod_LoadModel_Pattern); + //const char sigs1[] = "\xFF\x15\x2A\x2A\x2A\x2A\x83\xC4\x0C\x3D\x49\x44\x50\x4F"; + //auto Mod_LoadModel_Pattern = Search_Pattern(sigs1); + //Sig_VarNotFound(Mod_LoadModel_Pattern); + +#define MOD_LOADMODEL_STRING_SVENGINE "Loading '%s'\n" +#define MOD_LOADMODEL_STRING "loading %s\n" + + PVOID Mod_LoadModel_String = NULL; + + if (g_iEngineType == ENGINE_SVENGINE) + { + Mod_LoadModel_String = Search_Pattern_Data(MOD_LOADMODEL_STRING_SVENGINE); + if (!Mod_LoadModel_String) + Mod_LoadModel_String = Search_Pattern_Rdata(MOD_LOADMODEL_STRING_SVENGINE); + } + else + { + Mod_LoadModel_String = Search_Pattern_Data(MOD_LOADMODEL_STRING); + if (!Mod_LoadModel_String) + Mod_LoadModel_String = Search_Pattern_Rdata(MOD_LOADMODEL_STRING); + } + Sig_VarNotFound(Mod_LoadModel_String); - gPrivateFuncs.Mod_LoadModel = (decltype(gPrivateFuncs.Mod_LoadModel))g_pMetaHookAPI->ReverseSearchFunctionBeginEx(Mod_LoadModel_Pattern, 0x600, [](PUCHAR Candidate) { + char pattern[] = "\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4"; + *(DWORD*)(pattern + 1) = (DWORD)Mod_LoadModel_String; + auto Mod_LoadModel_PushString = Search_Pattern(pattern); + Sig_VarNotFound(Mod_LoadModel_PushString); + + gPrivateFuncs.Mod_LoadModel = (decltype(gPrivateFuncs.Mod_LoadModel))g_pMetaHookAPI->ReverseSearchFunctionBeginEx(Mod_LoadModel_PushString, 0x600, [](PUCHAR Candidate) { //81 EC ?? 01 00 00 A1 ?? ?? ?? ?? 33 C4 /* @@ -6492,15 +7114,54 @@ void R_FillAddress(void) return FALSE; }); + Sig_FuncNotFound(Mod_LoadModel); - const char sigs2[] = "\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x68"; - auto Mod_LoadModel_Pattern2 = g_pMetaHookAPI->SearchPattern((PUCHAR)Mod_LoadModel_Pattern - 0x50, 0x50, sigs2, Sig_Length(sigs2)); - Sig_VarNotFound(Mod_LoadModel_Pattern2); + typedef struct + { + PVOID addr_loadname; + }Mod_LoadModel_SearchContext; + + Mod_LoadModel_SearchContext ctx = { 0 }; + + g_pMetaHookAPI->DisasmRanges((PUCHAR)Mod_LoadModel_PushString + 5, 0x50, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) + { + auto pinst = (cs_insn*)inst; + auto ctx = (Mod_LoadModel_SearchContext *)context; + + if (!loadname && + pinst->id == X86_INS_PUSH && + pinst->detail->x86.op_count == 1 && + pinst->detail->x86.operands[0].type == X86_OP_IMM && + (PUCHAR)pinst->detail->x86.operands[0].imm > (PUCHAR)g_dwEngineDataBase && + (PUCHAR)pinst->detail->x86.operands[0].imm < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize) + { + loadname = (decltype(loadname))pinst->detail->x86.operands[0].imm; + ctx->addr_loadname = address + instLen; + } + + if (loadname) + return TRUE; + + if (address[0] == 0xCC) + return TRUE; + + if (pinst->id == X86_INS_RET) + return TRUE; + + return FALSE; + + }, 0, &ctx); + + Sig_VarNotFound(loadname); + + //const char sigs2[] = "\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x68"; + //auto Mod_LoadModel_Pattern2 = (PUCHAR)Search_Pattern_From_Size((PUCHAR)Mod_LoadModel_PushString - 0x50, 0x50, sigs2); + //Sig_VarNotFound(Mod_LoadModel_Pattern2); - loadname = *(decltype(loadname)*)((PUCHAR)Mod_LoadModel_Pattern2 + sizeof(sigs2) - 1); + //loadname = *(decltype(loadname)*)((PUCHAR)Mod_LoadModel_Pattern2 + sizeof(sigs2) - 1); - g_pMetaHookAPI->DisasmRanges((PUCHAR)Mod_LoadModel_Pattern2 + sizeof(sigs2) - 1 + 4, 0x50, [](void *inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) + g_pMetaHookAPI->DisasmRanges(ctx.addr_loadname, 0x50, [](void *inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { auto pinst = (cs_insn *)inst; diff --git a/Plugins/Renderer/privatehook.h b/Plugins/Renderer/privatehook.h index 9c0b56b2..835ce6dc 100644 --- a/Plugins/Renderer/privatehook.h +++ b/Plugins/Renderer/privatehook.h @@ -16,6 +16,7 @@ typedef struct void (*R_RenderView)(void); void (*R_RenderView_SvEngine)(int a1); void (*R_RenderScene)(void); + void (*R_RenderFinalFog)(void); void (*ClientDLL_DrawNormalTriangles)(void); void (*R_NewMap)(void); void (*R_ClearParticles)(void); @@ -59,6 +60,7 @@ typedef struct int(*GL_Upload16)(byte *data, int width, int height, int iType, byte *pPal, int a6, int a7, int a8); void (*Mod_UnloadSpriteTextures)(model_t* mod); void (*Mod_LoadSpriteModel)(model_t* mod, void* buffer); + void *(*Mod_LoadSpriteFrame)(void* pin, mspriteframe_t** ppframe, int framenum); void (*R_DecalMPoly)(float *v, texture_t *ptexture, msurface_t *psurf, int vertCount); void (*R_MarkLeaves)(void); void (*R_DrawBrushModel)(cl_entity_t *e); diff --git a/include/metahook.h b/include/metahook.h index 0be257f7..9aa71365 100644 --- a/include/metahook.h +++ b/include/metahook.h @@ -32,6 +32,10 @@ typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); #undef SendMessage #endif +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif + typedef void(*cvar_callback_t)(cvar_t *pcvar); #ifndef __HLSDK_COMMAND__ diff --git a/include/vgui_controls/ListPanel.h b/include/vgui_controls/ListPanel.h index ed315546..8a5bdffe 100644 --- a/include/vgui_controls/ListPanel.h +++ b/include/vgui_controls/ListPanel.h @@ -251,7 +251,7 @@ class ListPanel : public Panel virtual void SetSortColumnEx( int iPrimarySortColumn, int iSecondarySortColumn, bool bSortAscending ); void GetSortColumnEx( int &iPrimarySortColumn, int &iSecondarySortColumn, bool &bSortAscending ) const; -private: +protected: // Cleans up allocations associated with a particular item void CleanupItem( FastSortListPanelItem *data ); diff --git a/include/vgui_controls/TextEntry.cpp b/include/vgui_controls/TextEntry.cpp index ddf4c7f7..0dee0d3a 100644 --- a/include/vgui_controls/TextEntry.cpp +++ b/include/vgui_controls/TextEntry.cpp @@ -1558,10 +1558,13 @@ void TextEntry::OnMousePressed(MouseCode code) //----------------------------------------------------------------------------- void TextEntry::OnMouseReleased(MouseCode code) { - _mouseSelection = false; - - input()->SetMouseCapture(NULL); - + if (_mouseSelection) + { + _mouseSelection = false; + + input()->SetMouseCapture(NULL); + } + // make sure something has been selected int cx0, cx1; if (GetSelectedRange(cx0, cx1))