Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion Client/game_sa/CEntitySA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,13 +642,33 @@ bool CEntitySA::SetBonePosition(eBone boneId, const CVector& position)
RwMatrix* rwBoneMatrix = GetBoneRwMatrix(boneId);
if (!rwBoneMatrix)
return false;

CMatrixSAInterface boneMatrix(rwBoneMatrix, false);
boneMatrix.SetTranslateOnly(position);
boneMatrix.UpdateRW();
return true;
}

bool CEntitySA::GetBoneScale(eBone boneId, CVector& scale)
{
RwMatrix* rwBoneMatrix = GetBoneRwMatrix(boneId);
if (!rwBoneMatrix)
return false;

pGame->GetRenderWare()->RwMatrixGetScale(*rwBoneMatrix, scale);
return true;
}

bool CEntitySA::SetBoneScale(eBone boneId, const CVector& scale)
{
RwMatrix* rwBoneMatrix = GetBoneRwMatrix(boneId);
if (!rwBoneMatrix)
return false;

RwMatrixScale(rwBoneMatrix, reinterpret_cast<const RwV3d*>(&scale), TRANSFORM_BEFORE);
return true;
}

BYTE CEntitySA::GetAreaCode()
{
return m_pInterface->m_areaCode;
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/CEntitySA.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ class CEntitySA : public virtual CEntity
bool SetBoneRotationQuat(eBone boneId, float x, float y, float z, float w);
bool GetBonePosition(eBone boneId, CVector& position);
bool SetBonePosition(eBone boneId, const CVector& position);
bool GetBoneScale(eBone boneId, CVector& scale) override;
bool SetBoneScale(eBone boneId, const CVector& scale) override;

bool IsOnFire() override { return false; }
bool SetOnFire(bool onFire) override { return false; }
Expand Down
68 changes: 68 additions & 0 deletions Client/mods/deathmatch/logic/CClientPed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,74 @@ CVector* CClientPed::GetTransformedBonePosition(eBone bone, CVector& vecPosition
return NULL;
}

bool CClientPed::SetBoneScale(eBone boneId, const CVector& scale)
{
if (!m_pPlayerPed || boneId < BONE_ROOT || boneId > BONE_LEFTBREAST)
return false;

m_boneScales[boneId] = scale;
m_pPlayerPed->SetBoneScale(boneId, scale);
return true;
}

bool CClientPed::GetBoneScale(eBone boneId, CVector& scale) const
{
auto it = m_boneScales.find(boneId);
if (it != m_boneScales.end())
{
scale = it->second;
return true;
}

if (!m_pPlayerPed)
return false;

return m_pPlayerPed->GetBoneScale(boneId, scale);
}

bool CClientPed::ResetBoneScale(eBone boneId)
{
auto it = m_boneScales.find(boneId);
if (it == m_boneScales.end())
return false;

m_boneScales.erase(it);

if (m_pPlayerPed)
m_pPlayerPed->SetBoneScale(boneId, CVector(1.0f, 1.0f, 1.0f));

return true;
}

void CClientPed::ResetAllBoneScales()
{
m_boneScales.clear();

if (!m_pPlayerPed)
return;

CVector defaultScale(1.0f, 1.0f, 1.0f);
for (int i = BONE_ROOT; i <= BONE_HEAD; ++i)
m_pPlayerPed->SetBoneScale(static_cast<eBone>(i), defaultScale);
for (int i = BONE_RIGHTUPPERTORSO; i <= BONE_RIGHTTHUMB; ++i)
m_pPlayerPed->SetBoneScale(static_cast<eBone>(i), defaultScale);
for (int i = BONE_LEFTUPPERTORSO; i <= BONE_LEFTTHUMB; ++i)
m_pPlayerPed->SetBoneScale(static_cast<eBone>(i), defaultScale);
for (int i = BONE_LEFTHIP; i <= BONE_LEFTFOOT; ++i)
m_pPlayerPed->SetBoneScale(static_cast<eBone>(i), defaultScale);
for (int i = BONE_RIGHTHIP; i <= BONE_RIGHTFOOT; ++i)
m_pPlayerPed->SetBoneScale(static_cast<eBone>(i), defaultScale);
}

void CClientPed::ApplyBoneScales()
{
if (m_boneScales.empty() || !m_pPlayerPed)
return;

for (const auto& [bone, scale] : m_boneScales)
m_pPlayerPed->SetBoneScale(bone, scale);
}

CClientVehicle* CClientPed::GetRealOccupiedVehicle()
{
if (m_pPlayerPed)
Expand Down
12 changes: 12 additions & 0 deletions Client/mods/deathmatch/logic/CClientPed.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class CClientPed;

#include <game/CPad.h>
#include <game/TaskTypes.h>
#include <game/CPed.h>
#include <unordered_map>

class CAnimBlock;
class CClientCamera;
Expand Down Expand Up @@ -812,4 +814,14 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule

bool m_hasSyncedAnim{};
bool m_animationOverridedByClient{};

// Bone scaling
std::unordered_map<eBone, CVector> m_boneScales;

public:
bool SetBoneScale(eBone boneId, const CVector& scale);
bool GetBoneScale(eBone boneId, CVector& scale) const;
bool ResetBoneScale(eBone boneId);
void ResetAllBoneScales();
void ApplyBoneScales();
};
46 changes: 43 additions & 3 deletions Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void CLuaPedDefs::LoadFunctions()
{"setElementBoneRotation", ArgumentParserWarn<false, SetElementBoneRotation>},
{"setElementBoneQuaternion", ArgumentParserWarn<false, SetElementBoneQuaternion>},
{"setElementBoneMatrix", ArgumentParserWarn<false, SetElementBoneMatrix>},
{"setElementBoneScale", ArgumentParserWarn<false, SetElementBoneScale>},
{"setPedRotation", SetPedRotation},
{"setPedWeaponSlot", SetPedWeaponSlot},
{"setPedCanBeKnockedOffBike", SetPedCanBeKnockedOffBike},
Expand Down Expand Up @@ -69,6 +70,7 @@ void CLuaPedDefs::LoadFunctions()
{"getElementBoneRotation", ArgumentParserWarn<false, GetElementBoneRotation>},
{"getElementBoneQuaternion", ArgumentParserWarn<false, GetElementBoneQuaternion>},
{"getElementBoneMatrix", ArgumentParserWarn<false, GetElementBoneMatrix>},
{"getElementBoneScale", ArgumentParserWarn<false, GetElementBoneScale>},
{"getPedRotation", GetPedRotation},
{"getPedWeaponSlot", GetPedWeaponSlot},
{"canPedBeKnockedOffBike", CanPedBeKnockedOffBike},
Expand Down Expand Up @@ -118,6 +120,9 @@ void CLuaPedDefs::LoadFunctions()
{"isPedDead", IsPedDead},
{"isPedReloadingWeapon", ArgumentParserWarn<false, IsPedReloadingWeapon>},
{"killPedTask", ArgumentParser<killPedTask>},

{"resetElementBoneScale", ArgumentParserWarn<false, ResetElementBoneScale>},
{"resetAllElementBoneScales", ArgumentParserWarn<false, ResetAllElementBoneScales>},
};

// Add functions
Expand Down Expand Up @@ -1118,6 +1123,39 @@ bool CLuaPedDefs::SetElementBoneMatrix(CClientPed* ped, const std::uint16_t bone
return entity->SetBoneMatrix(static_cast<eBone>(bone), matrix);
}

std::variant<bool, CLuaMultiReturn<float, float, float>> CLuaPedDefs::GetElementBoneScale(CClientPed* ped, const std::uint16_t bone)
{
if (bone < BONE_ROOT || bone > BONE_LEFTBREAST)
throw std::invalid_argument("Invalid bone: " + std::to_string(bone));

CVector scale;
if (!ped->GetBoneScale(static_cast<eBone>(bone), scale))
return false;

return CLuaMultiReturn<float, float, float>(scale.fX, scale.fY, scale.fZ);
}

bool CLuaPedDefs::SetElementBoneScale(CClientPed* ped, const std::uint16_t bone, const float scaleX, const float scaleY, const float scaleZ)
{
if (bone < BONE_ROOT || bone > BONE_LEFTBREAST)
throw std::invalid_argument("Invalid bone: " + std::to_string(bone));

return ped->SetBoneScale(static_cast<eBone>(bone), CVector(scaleX, scaleY, scaleZ));
}

bool CLuaPedDefs::ResetElementBoneScale(CClientPed* ped, const std::uint16_t bone)
{
if (bone < BONE_ROOT || bone > BONE_LEFTBREAST)
throw std::invalid_argument("Invalid bone: " + std::to_string(bone));

return ped->ResetBoneScale(static_cast<eBone>(bone));
}

void CLuaPedDefs::ResetAllElementBoneScales(CClientPed* ped)
{
ped->ResetAllBoneScales();
}

bool CLuaPedDefs::UpdateElementRpHAnim(CClientPed* ped)
{
CEntity* entity = ped->GetGameEntity();
Expand All @@ -1128,15 +1166,17 @@ bool CLuaPedDefs::UpdateElementRpHAnim(CClientPed* ped)
entity->UpdateRpHAnim();

if (entity->GetModelIndex() != 0)
{
ped->ApplyBoneScales();
return true;
}

RpClump* clump = entity->GetRpClump();

if (clump)
{
((void(__cdecl*)(RpClump*))0x5DF560)(clump); // CPed::ShoulderBoneRotation
}
((void(__cdecl*)(RpClump*))0x5DF560)(clump); // CPed::ShoulderBoneRotation

ped->ApplyBoneScales();
return true;
}

Expand Down
5 changes: 5 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaPedDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,16 @@ class CLuaPedDefs : public CLuaDefs
static std::variant<bool, CLuaMultiReturn<float, float, float>> GetElementBoneRotation(CClientPed* ped, const std::uint16_t bone);
static std::variant<bool, CLuaMultiReturn<float, float, float, float>> GetElementBoneQuaternion(CClientPed* ped, const std::uint16_t bone);
static std::variant<bool, std::array<std::array<float, 4>, 4>> GetElementBoneMatrix(CClientPed* ped, const std::uint16_t bone);
static std::variant<bool, CLuaMultiReturn<float, float, float>> GetElementBoneScale(CClientPed* ped, const std::uint16_t bone);

static bool SetElementBonePosition(CClientPed* ped, const std::uint16_t bone, const CVector position);
static bool SetElementBoneRotation(CClientPed* ped, const std::uint16_t bone, const float yaw, const float pitch, const float roll);
static bool SetElementBoneQuaternion(CClientPed* ped, const std::uint16_t bone, const float x, const float y, const float z, const float w);
static bool SetElementBoneMatrix(CClientPed* ped, const std::uint16_t bone, const CMatrix matrix);
static bool SetElementBoneScale(CClientPed* ped, const std::uint16_t bone, const float scaleX, const float scaleY, const float scaleZ);

static bool ResetElementBoneScale(CClientPed* ped, const std::uint16_t bone);
static void ResetAllElementBoneScales(CClientPed* ped);

static bool UpdateElementRpHAnim(CClientPed* ped);

Expand Down
2 changes: 2 additions & 0 deletions Client/sdk/game/CEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ class CEntity
virtual bool SetBoneRotationQuat(eBone boneId, float x, float y, float z, float w) = 0;
virtual bool GetBonePosition(eBone boneId, CVector& position) = 0;
virtual bool SetBonePosition(eBone boneId, const CVector& position) = 0;
virtual bool GetBoneScale(eBone boneId, CVector& scale) = 0;
virtual bool SetBoneScale(eBone boneId, const CVector& scale) = 0;

virtual bool IsOnFire() = 0;
virtual bool SetOnFire(bool onFire) = 0;
Expand Down