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
238 changes: 233 additions & 5 deletions Client/mods/deathmatch/logic/CClientIFP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ WORD CClientIFP::ReadSequencesWithDummies(std::unique_ptr<CAnimBlendHierarchy>&
MoveSequencesWithDummies(pAnimationHierarchy, MapOfSequences);
WORD cSequences = m_kcIFPSequences + wUnknownSequences;

// As we need support for all 32 bones, we must change the total sequences count
// As we need support for all 64 bones (32 ped + 32 cutscene ped), we must change the total sequences count
pAnimationHierarchy->SetNumSequences(cSequences);
return cSequences;
}
Expand Down Expand Up @@ -243,7 +243,7 @@ std::int32_t CClientIFP::ReadSequenceVersion1(SAnim& Anim)
RoundSize(Anim.Base.Size);
ReadBytes(&Anim.Name, Anim.Base.Size);

SString strBoneName = ConvertStringToKey(Anim.Name);
SString strBoneName = ConvertStringToKey(Anim.Name, true);
std::int32_t iBoneID = GetBoneIDFromName(strBoneName);

SString strCorrectBoneName = GetCorrectBoneNameFromName(strBoneName);
Expand Down Expand Up @@ -549,6 +549,25 @@ void CClientIFP::InsertAnimationDummySequence(std::unique_ptr<CAnimBlendSequence

void CClientIFP::CopyDummyKeyFrameByBoneID(BYTE* pKeyFrames, DWORD dwBoneID)
{
/* FrameData structure:
*
struct KeyFrame
{
short quaternionX;
short quaternionY;
short quaternionZ;
short quaternionW;
short time;
};

struct KeyFrameCompressed : KeyFrame
{
short translationX;
short translationY;
short translationZ;
};
*/

switch (dwBoneID)
{
case eBoneType::NORMAL: // Normal or Root, both are same
Expand Down Expand Up @@ -750,10 +769,21 @@ void CClientIFP::CopyDummyKeyFrameByBoneID(BYTE* pKeyFrames, DWORD dwBoneID)
}
}

SString CClientIFP::ConvertStringToKey(const SString& strBoneName)
SString CClientIFP::ConvertStringToKey(const SString& strBoneName, bool isANPK)
{
SString ConvertedString = strBoneName.ToLower();
// Remove white spaces
SString ConvertedString = strBoneName;

// Fix for some cutscene bones (like cssuitcase:Pelvis etc.)
if (isANPK)
{
std::size_t pos = ConvertedString.find(":");
if (pos != std::string::npos)
ConvertedString = ConvertedString.substr(pos + 1);
}

ConvertedString = ConvertedString.ToLower();

// Remove whitespaces
ConvertedString.erase(std::remove(ConvertedString.begin(), ConvertedString.end(), ' '), ConvertedString.end());
return ConvertedString;
}
Expand Down Expand Up @@ -860,6 +890,72 @@ std::int32_t CClientIFP::GetBoneIDFromName(const SString& strBoneName)
if (strBoneName == "rtoe0")
return eBoneType::R_TOE_0;

// Cutscene bones
if (strBoneName == "rthumb1")
return eBoneType::R_Thumb1;
if (strBoneName == "rthumb2")
return eBoneType::R_Thumb2;
if (strBoneName == "lthumb1")
return eBoneType::L_Thumb1;
if (strBoneName == "lthumb2")
return eBoneType::L_Thumb2;
if (strBoneName == "llip11")
return eBoneType::LLIP11;
if (strBoneName == "jaw22")
return eBoneType::JAW22;
if (strBoneName == "headnub")
return eBoneType::HEADNUB;
if (strBoneName == "lfinger0nub")
return eBoneType::L_Finger0Nub;
if (strBoneName == "rfinger0nub")
return eBoneType::R_Finger0Nub;
if (strBoneName == "ltoe0nub")
return eBoneType::L_Toe0Nub;
if (strBoneName == "rtoe0nub")
return eBoneType::R_Toe0Nub;
if (strBoneName == "rbrow1")
return eBoneType::R_BROW1;
if (strBoneName == "rbrow2")
return eBoneType::R_BROW2;
if (strBoneName == "lbrow1")
return eBoneType::L_BROW1;
if (strBoneName == "lbrow2")
return eBoneType::L_BROW2;
if (strBoneName == "rlid")
return eBoneType::R_LID;
if (strBoneName == "llid")
return eBoneType::L_LID;
if (strBoneName == "rtlip3")
return eBoneType::R_TLIP3;
if (strBoneName == "ltlip3")
return eBoneType::L_TLIP3;
if (strBoneName == "rtlip1")
return eBoneType::R_TLIP1;
if (strBoneName == "rtlip2")
return eBoneType::R_TLIP2;
if (strBoneName == "ltlip1")
return eBoneType::L_TLIP1;
if (strBoneName == "ltlip2")
return eBoneType::L_TLIP2;
if (strBoneName == "rcorner")
return eBoneType::R_CORNER;
if (strBoneName == "lcorner")
return eBoneType::L_CORNER;
if (strBoneName == "jaw1")
return eBoneType::JAW1;
if (strBoneName == "jaw2")
return eBoneType::JAW2;
if (strBoneName == "llip1")
return eBoneType::LLIP1;
if (strBoneName == "reye")
return eBoneType::R_EYE;
if (strBoneName == "leye")
return eBoneType::L_EYE;
if (strBoneName == "rcheek")
return eBoneType::R_CHEEK;
if (strBoneName == "lcheek")
return eBoneType::L_CHEEK;

// for GTA 3
if (strBoneName == "player")
return eBoneType::NORMAL;
Expand Down Expand Up @@ -976,6 +1072,72 @@ SString CClientIFP::GetCorrectBoneNameFromID(const std::int32_t& iBoneID)
if (iBoneID == eBoneType::R_TOE_0)
return "R Toe0";

// Cutscene bones
if (iBoneID == eBoneType::R_Thumb1)
return "RThumb1";
if (iBoneID == eBoneType::R_Thumb2)
return "RThumb2";
if (iBoneID == eBoneType::LLIP11)
return "llip11";
if (iBoneID == eBoneType::L_Thumb1)
return "LThumb1";
if (iBoneID == eBoneType::L_Thumb2)
return "LThumb2";
if (iBoneID == eBoneType::JAW22)
return "jaw22";
if (iBoneID == eBoneType::HEADNUB)
return "HeadNub";
if (iBoneID == eBoneType::L_Finger0Nub)
return "L Finger0Nub";
if (iBoneID == eBoneType::R_Finger0Nub)
return "R Finger0Nub";
if (iBoneID == eBoneType::L_Toe0Nub)
return "L Toe0Nub";
if (iBoneID == eBoneType::R_Toe0Nub)
return "R Toe0Nub";
if (iBoneID == eBoneType::R_BROW1)
return "rbrow1";
if (iBoneID == eBoneType::R_BROW2)
return "rbrow2";
if (iBoneID == eBoneType::L_BROW2)
return "lbrow2";
if (iBoneID == eBoneType::L_BROW1)
return "lbrow1";
if (iBoneID == eBoneType::R_LID)
return "rlid";
if (iBoneID == eBoneType::L_LID)
return "llid";
if (iBoneID == eBoneType::R_TLIP3)
return "rtlip3";
if (iBoneID == eBoneType::L_TLIP3)
return "ltlip3";
if (iBoneID == eBoneType::R_TLIP1)
return "rtlip1";
if (iBoneID == eBoneType::R_TLIP2)
return "rtlip2";
if (iBoneID == eBoneType::L_TLIP1)
return "ltlip1";
if (iBoneID == eBoneType::L_TLIP2)
return "ltlip2";
if (iBoneID == eBoneType::R_CORNER)
return "rcorner";
if (iBoneID == eBoneType::L_CORNER)
return "lcorner";
if (iBoneID == eBoneType::JAW1)
return "jaw1";
if (iBoneID == eBoneType::JAW2)
return "jaw2";
if (iBoneID == eBoneType::LLIP1)
return "llip1";
if (iBoneID == eBoneType::R_EYE)
return "reye";
if (iBoneID == eBoneType::L_EYE)
return "leye";
if (iBoneID == eBoneType::R_CHEEK)
return "rcheek";
if (iBoneID == eBoneType::L_CHEEK)
return "lcheek";

return "";
}

Expand Down Expand Up @@ -1057,6 +1219,72 @@ SString CClientIFP::GetCorrectBoneNameFromName(const SString& strBoneName)
if (strBoneName == "rtoe0")
return "R Toe0";

// Cutscene bones
if (strBoneName == "rthumb1")
return "RThumb1";
if (strBoneName == "rthumb2")
return "RThumb2";
if (strBoneName == "llip11")
return "llip11";
if (strBoneName == "lthumb1")
return "LThumb1";
if (strBoneName == "lthumb2")
return "LThumb2";
if (strBoneName == "jaw22")
return "jaw22";
if (strBoneName == "headnub")
return "HeadNub";
if (strBoneName == "lfinger0nub")
return "L Finger0Nub";
if (strBoneName == "rfinger0nub")
return "R Finger0Nub";
if (strBoneName == "ltoe0nub")
return "L Toe0Nub";
if (strBoneName == "rtoe0nub")
return "R Toe0Nub";
if (strBoneName == "rbrow1")
return "rbrow1";
if (strBoneName == "rbrow2")
return "rbrow2";
if (strBoneName == "lbrow1")
return "lbrow1";
if (strBoneName == "lbrow2")
return "lbrow2";
if (strBoneName == "rlid")
return "rlid";
if (strBoneName == "llid")
return "llid";
if (strBoneName == "rtlip3")
return "rtlip3";
if (strBoneName == "ltlip3")
return "ltlip3";
if (strBoneName == "rtlip1")
return "rtlip1";
if (strBoneName == "rtlip2")
return "rtlip2";
if (strBoneName == "ltlip1")
return "ltlip1";
if (strBoneName == "ltlip2")
return "ltlip2";
if (strBoneName == "rcorner")
return "rcorner";
if (strBoneName == "lcorner")
return "lcorner";
if (strBoneName == "jaw1")
return "jaw1";
if (strBoneName == "jaw2")
return "jaw2";
if (strBoneName == "llip1")
return "llip1";
if (strBoneName == "reye")
return "reye";
if (strBoneName == "leye")
return "leye";
if (strBoneName == "rcheek")
return "rcheek";
if (strBoneName == "lcheek")
return "lcheek";

// For GTA 3
if (strBoneName == "player")
return "Normal";
Expand Down
87 changes: 77 additions & 10 deletions Client/mods/deathmatch/logic/CClientIFP.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,44 @@ class CClientIFP final : public CClientEntity, CFileReader
R_THIGH = 51,
R_CALF = 52,
R_FOOT = 53,
R_TOE_0 = 54
R_TOE_0 = 54,

// Cutscene bones
R_Thumb1 = 28,
R_Thumb2 = 29,
LLIP11 = 30,
L_Thumb1 = 38,
L_Thumb2 = 39,

JAW22 = 40,

HEADNUB = 303,
L_Finger0Nub = 304,
R_Finger0Nub = 305,
L_Toe0Nub = 306,
R_Toe0Nub = 307,

R_BROW1 = 5001,
R_BROW2 = 5002,
L_BROW2 = 5003,
L_BROW1 = 5004,
R_LID = 5005,
L_LID = 5006,
R_TLIP3 = 5007,
L_TLIP3 = 5008,
R_TLIP1 = 5009,
R_TLIP2 = 5010,
L_TLIP1 = 5011,
L_TLIP2 = 5012,
R_CORNER = 5013,
L_CORNER = 5014,
JAW1 = 5015,
JAW2 = 5016,
LLIP1 = 5017,
R_EYE = 5018,
L_EYE = 5019,
R_CHEEK = 5020,
L_CHEEK = 5021,
};

CClientIFP(class CClientManager* pManager, ElementID ID);
Expand Down Expand Up @@ -260,7 +297,7 @@ class CClientIFP final : public CClientEntity, CFileReader

void InsertAnimationDummySequence(std::unique_ptr<CAnimBlendSequence>& pAnimationSequence, const SString& BoneName, const DWORD& dwBoneID);
void CopyDummyKeyFrameByBoneID(BYTE* pKeyFrames, DWORD dwBoneID);
SString ConvertStringToKey(const SString& strBoneName);
SString ConvertStringToKey(const SString& strBoneName, bool isANPK = false);

constexpr void RoundSize(std::uint32_t& u32Size);
constexpr bool IsKeyFramesTypeRoot(eFrameType iFrameType);
Expand All @@ -279,16 +316,46 @@ class CClientIFP final : public CClientEntity, CFileReader
bool m_bUnloading;
CAnimManager* m_pAnimManager;

// 32 because there are 32 bones in a ped model
const unsigned short m_kcIFPSequences = 32;
// 64 because there are 32 bones in a ped model + 32 possibly cutscene bones
const unsigned short m_kcIFPSequences = 64;
// We'll keep all key frames compressed by default. GTA:SA will decompress
// them, when it's going to play the animation. We don't need to worry about it.
const bool m_kbAllKeyFramesCompressed = true;

const DWORD m_karruBoneIds[32] = {0, 1, 2, 3, 4, 5, 8, 6, 7, 31, 32, 33, 34, 35, 36, 21, 22, 23, 24, 25, 26, 302, 301, 201, 41, 42, 43, 44, 51, 52, 53, 54};
const char m_karrstrBoneNames[32][24] = {
"Normal", "Pelvis", "Spine", "Spine1", "Neck", "Head", "Jaw", "L Brow",
"R Brow", "Bip01 L Clavicle", "L UpperArm", "L ForeArm", "L Hand", "L Finger", "L Finger01", "Bip01 R Clavicle",
"R UpperArm", "R ForeArm", "R Hand", "R Finger", "R Finger01", "L breast", "R breast", "Belly",
"L Thigh", "L Calf", "L Foot", "L Toe0", "R Thigh", "R Calf", "R Foot", "R Toe0"};
const DWORD m_karruBoneIds[64] = {0, 1, 2, 3, 4, 5, 8, 6, 7, 31, 32, 33, 34, 35, 36, 21,
22, 23, 24, 25, 26, 302, 301, 201, 41, 42, 43, 44, 51, 52, 53, 54,
28, 29, 30, 38, 39, 40, 303, 304, 305, 306, 307, 5001, 5002, 5003, 5004, 5005,
5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5020, 5021};
const char m_karrstrBoneNames[64][24] = {"Normal", "Pelvis",
"Spine", "Spine1",
"Neck", "Head",
"Jaw", "L Brow",
"R Brow", "Bip01 L Clavicle",
"L UpperArm", "L ForeArm",
"L Hand", "L Finger",
"L Finger01", "Bip01 R Clavicle",
"R UpperArm", "R ForeArm",
"R Hand", "R Finger",
"R Finger01", "L breast",
"R breast", "Belly",
"L Thigh", "L Calf",
"L Foot", "L Toe0",
"R Thigh", "R Calf",
"R Foot", "R Toe0",
"RThumb1", "RThumb2",
"llip11", "LThumb1",
"LThumb2", "jaw22",
"HeadNub", "L Finger0Nub",
"R Finger0Nub", "L Toe0Nub",
"R Toe0Nub", "rbrow1",
"rbrow2", "lbrow2",
"lbrow1", "rlid",
"llid", "rtlip3",
"ltlip3", "rtlip1",
"rtlip2", "ltlip1",
"ltlip2", "rcorner",
"lcorner", "jaw1",
"jaw2", "llip1",
"reye", "leye",
"rcheek", "lcheek"};
};
Loading