diff --git a/YYToolkit/source/YYTK/Module Interface/Interface.cpp b/YYToolkit/source/YYTK/Module Interface/Interface.cpp index 8e1b7e0..4e21a7c 100644 --- a/YYToolkit/source/YYTK/Module Interface/Interface.cpp +++ b/YYToolkit/source/YYTK/Module Interface/Interface.cpp @@ -1556,7 +1556,7 @@ namespace YYTK } // Get the instance ID from the instance - int32_t instance_id = static_cast(Object.AsReal()); + int32_t instance_id = static_cast(instance.AsReal()); // Skip inactive instances / instances that don't exist CInstance* object_instance = nullptr; diff --git a/YYToolkit/source/YYTK/Shared.cpp b/YYToolkit/source/YYTK/Shared.cpp index 6396af3..6ff0dc0 100644 --- a/YYToolkit/source/YYTK/Shared.cpp +++ b/YYToolkit/source/YYTK/Shared.cpp @@ -393,8 +393,10 @@ size_t YYTK::RValue::length() CInstanceInternal& YYTK::CInstance::GetMembers() { YYTKInterface* module_interface = GetYYTKInterface(); + + // SequenceInstanceOnly is used in most new games that v3 is targetting if (!module_interface) - return this->Unmasked.Members; + return this->SequenceInstanceOnly.Members; RValue self_id_builtin; module_interface->GetBuiltin( @@ -406,10 +408,22 @@ CInstanceInternal& YYTK::CInstance::GetMembers() int32_t self_id = static_cast(self_id_builtin.AsReal()); - if (this->Unmasked.Members.m_ID == self_id) - return this->Unmasked.Members; + if (this->MembersOnly.Members.m_ID == self_id) + return this->MembersOnly.Members; + + if (this->SequenceInstanceOnly.Members.m_ID == self_id) + return this->SequenceInstanceOnly.Members; + + if (this->WithSkeletonMask.Members.m_ID == self_id) + return this->WithSkeletonMask.Members; + + module_interface->PrintError( + __FILE__, + __LINE__, + "Failed to determine CInstance member offset! Report this to GitHub and include the game name!" + ); - return this->Masked.Members; + return this->SequenceInstanceOnly.Members; } #endif // YYTK_DEFINE_INTERNAL diff --git a/YYToolkit/source/YYTK/Shared.hpp b/YYToolkit/source/YYTK/Shared.hpp index 0a75a99..68d8d9f 100644 --- a/YYToolkit/source/YYTK/Shared.hpp +++ b/YYToolkit/source/YYTK/Shared.hpp @@ -9,7 +9,7 @@ #define YYTK_MAJOR 3 #define YYTK_MINOR 3 -#define YYTK_PATCH 1 +#define YYTK_PATCH 2 #ifndef YYTK_CPP_VERSION #ifndef _MSVC_LANG @@ -2042,17 +2042,32 @@ namespace YYTK } }; + // Newer struct, later renamed to LinkedList - OLinkedList is used in older x86 games, + // and causes misalingment due to alignment changing from 8-bytes in x64 to 4-bytes in x86. template struct LinkedList { T* m_First; T* m_Last; int32_t m_Count; + int32_t m_DeleteType; }; #ifdef _WIN64 static_assert(sizeof(LinkedList) == 0x18); #endif // _WIN64 + template + struct OLinkedList + { + T* m_First; + T* m_Last; + int32_t m_Count; + }; +#ifdef _WIN64 + static_assert(sizeof(OLinkedList) == 0x18); + static_assert(sizeof(OLinkedList) == sizeof(LinkedList)); +#endif // _WIN64 + enum eBuffer_Type : int32_t { eBuffer_None = 0x0, @@ -2259,7 +2274,7 @@ namespace YYTK int32_t m_PhysicsGravityX; int32_t m_PhysicsGravityY; float m_PhysicsPixelToMeters; - LinkedList m_ActiveInstances; + OLinkedList m_ActiveInstances; LinkedList m_InactiveInstances; CInstance* m_MarkedFirst; CInstance* m_MarkedLast; @@ -2577,6 +2592,16 @@ namespace YYTK // Use GetMembers() to get a CInstanceVariables reference. union { + // Islets 1.0.0.3 Steam (x86), GM 2022.6 + struct + { + public: + CInstanceInternal Members; + } MembersOnly; +#ifdef _WIN64 + static_assert(sizeof(MembersOnly) == 0xF8); +#endif // _WIN64 + // 2023.x => 2023.8 (and presumably 2023.11) struct { @@ -2584,9 +2609,9 @@ namespace YYTK PVOID m_SequenceInstance; public: CInstanceInternal Members; - } Unmasked; + } SequenceInstanceOnly; #ifdef _WIN64 - static_assert(sizeof(Unmasked) == 0x100); + static_assert(sizeof(SequenceInstanceOnly) == 0x100); #endif // _WIN64 // 2022.1 => 2023.1 (may be used later, haven't checked) @@ -2597,9 +2622,9 @@ namespace YYTK PVOID m_SequenceInstance; public: CInstanceInternal Members; - } Masked; + } WithSkeletonMask; #ifdef _WIN64 - static_assert(sizeof(Masked) == 0x108); + static_assert(sizeof(WithSkeletonMask) == 0x108); #endif // _WIN64 }; public: