diff --git a/include/RED4ext/Detail/AddressHashes.hpp b/include/RED4ext/Detail/AddressHashes.hpp index d7525a45f..bb91460a1 100644 --- a/include/RED4ext/Detail/AddressHashes.hpp +++ b/include/RED4ext/Detail/AddressHashes.hpp @@ -158,6 +158,18 @@ constexpr std::uint32_t Memory_PoolStorage_OOM = 0xD54F163A; constexpr std::uint32_t OpcodeHandlers = 0x39532858; #pragma endregion +#pragma region ObjectPackageExtractor +constexpr std::uint32_t ObjectPackageExtractor_Initialize = 2318998714; +constexpr std::uint32_t ObjectPackageExtractor_ExtractSync = 2038372664; +constexpr std::uint32_t ObjectPackageExtractor_ExtractAsync = 3819248393; +#pragma endregion + +#pragma region ObjectPackageReader +constexpr std::uint32_t ObjectPackageReader_ctor = 3628731410; +constexpr std::uint32_t ObjectPackageReader_OnReadHeader = 1632836642; +constexpr std::uint32_t ObjectPackageReader_ReadHeader = 1285757088; +#pragma endregion + #pragma region ResourceDepot constexpr std::uint32_t ResourceDepot = 0x659A0FC7; #pragma endregion diff --git a/include/RED4ext/ISerializable-inl.hpp b/include/RED4ext/ISerializable-inl.hpp index 4e5a86226..400343d1a 100644 --- a/include/RED4ext/ISerializable-inl.hpp +++ b/include/RED4ext/ISerializable-inl.hpp @@ -27,8 +27,9 @@ RED4EXT_INLINE void RED4ext::ISerializable::sub_20() { } -RED4EXT_INLINE void RED4ext::ISerializable::sub_28() +RED4EXT_INLINE void RED4ext::ISerializable::PostLoad(const RED4ext::PostLoadParams& aParams) { + RED4EXT_UNUSED_PARAMETER(aParams); } RED4EXT_INLINE bool RED4ext::ISerializable::sub_30() diff --git a/include/RED4ext/ISerializable.hpp b/include/RED4ext/ISerializable.hpp index c991dda68..7ef08005f 100644 --- a/include/RED4ext/ISerializable.hpp +++ b/include/RED4ext/ISerializable.hpp @@ -16,6 +16,13 @@ struct CClass; struct BaseStream; struct CString; +struct PostLoadParams +{ + bool disablePreInitialization; // 00 + uint8_t pad01[0x8 - 0x1]; // 01 +}; +RED4EXT_ASSERT_SIZE(PostLoadParams, 0x8); + struct ISerializable { ISerializable(); @@ -25,7 +32,7 @@ struct ISerializable virtual Memory::IAllocator* GetAllocator(); // 10 virtual ~ISerializable() = default; // 18 virtual void sub_20(); // 20 - virtual void sub_28(); // 28 + virtual void PostLoad(const PostLoadParams& aParams); // 28 virtual bool sub_30(); // 30 virtual void sub_38(); // 38 virtual bool sub_40(BaseStream* aStream); // 40 diff --git a/include/RED4ext/Package-inl.hpp b/include/RED4ext/Package-inl.hpp new file mode 100644 index 000000000..46dd033cf --- /dev/null +++ b/include/RED4ext/Package-inl.hpp @@ -0,0 +1,146 @@ +#ifdef RED4EXT_STATIC_LIB +#include +#endif + +#include +#include + +RED4EXT_INLINE RED4ext::ObjectPackageHeader::ObjectPackageHeader() + : rootIndex(-1) +{ +} + +RED4EXT_INLINE bool RED4ext::ObjectPackageHeader::IsEmpty() const +{ + return cruids.IsEmpty(); +} + +RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(void* aBuffer, uint32_t aSize) +{ + using func_t = void (*)(ObjectPackageReader*); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ctor); + + func(this); + + buffer = aBuffer; + size = aSize; +} + +RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const DeferredDataBuffer& aBuffer) +{ + using func_t = void (*)(ObjectPackageReader*); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ctor); + + func(this); + + buffer = aBuffer.raw->data; + size = aBuffer.raw->size; +} + +RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const DataBuffer& aBuffer) +{ + using func_t = void (*)(ObjectPackageReader*); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ctor); + + func(this); + + buffer = aBuffer.buffer.data; + size = aBuffer.buffer.size; +} + +RED4EXT_INLINE RED4ext::ObjectPackageReader::ObjectPackageReader(const RawBuffer& aBuffer) +{ + using func_t = void (*)(ObjectPackageReader*); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ctor); + + func(this); + + buffer = aBuffer.data; + size = aBuffer.size; +} + +RED4EXT_INLINE void RED4ext::ObjectPackageReader::OnReadHeader(uint64_t a1, uint64_t a2) +{ + using func_t = void (*)(ObjectPackageReader*, uint64_t, uint64_t); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_OnReadHeader); + + func(this, a1, a2); +} + +RED4EXT_INLINE void RED4ext::ObjectPackageReader::ReadHeader() +{ + using func_t = void (*)(ObjectPackageReader*, ObjectPackageHeader&); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ReadHeader); + + func(this, header); +} + +RED4EXT_INLINE void RED4ext::ObjectPackageReader::ReadHeader(RED4ext::ObjectPackageHeader& aOut) +{ + using func_t = void (*)(ObjectPackageReader*, ObjectPackageHeader&); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageReader_ReadHeader); + + func(this, aOut); +} + +RED4EXT_INLINE bool RED4ext::ObjectPackageReader::IsEmpty() const +{ + return !buffer; +} + +RED4EXT_INLINE RED4ext::ObjectPackageExtractorParams::ObjectPackageExtractorParams(const RED4ext::PackageHeader& aHeader) + : header(aHeader) + , loader(ResourceLoader::Get()) + , disablePostLoad(false) + , disableImports(false) + , disablePreInitialization(false) + , unk63(0) + , unk64(0) + , unk78(0) +{ +} + +RED4EXT_INLINE RED4ext::ObjectPackageExtractorParams::ObjectPackageExtractorParams(const RED4ext::ObjectPackageHeader& aHeader) + : ObjectPackageExtractorParams(aHeader.package) +{ +} + +RED4EXT_INLINE RED4ext::ObjectPackageExtractor::ObjectPackageExtractor(const RED4ext::ObjectPackageExtractorParams& aParams) + : unk78(0) + , loader(nullptr) + , disablePostLoad(false) + , disableImports(false) + , disablePreInitialization(false) + , unkBB(0) + , unkBC(0) + , unkF0(nullptr) + , unkF8(nullptr) + , unk100(nullptr) + , unk108(nullptr) + , unk110(nullptr) + , unk118(nullptr) +{ + using func_t = void (*)(ObjectPackageExtractor*, const ObjectPackageExtractorParams&); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageExtractor_Initialize); + + func(this, aParams); +} + +RED4EXT_INLINE void RED4ext::ObjectPackageExtractor::ExtractSync() +{ + using func_t = void (*)(ObjectPackageExtractor*); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageExtractor_ExtractSync); + + func(this); +} + +RED4EXT_INLINE RED4ext::JobHandle RED4ext::ObjectPackageExtractor::ExtractAsync() +{ + using func_t = void (*)(ObjectPackageExtractor*, JobHandle&); + static UniversalRelocFunc func(Detail::AddressHashes::ObjectPackageExtractor_ExtractAsync); + + JobHandle job; + func(this, job); + + return job; +} diff --git a/include/RED4ext/Package.hpp b/include/RED4ext/Package.hpp new file mode 100644 index 000000000..3f26cb14e --- /dev/null +++ b/include/RED4ext/Package.hpp @@ -0,0 +1,154 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace RED4ext +{ +struct PackageHeader +{ + struct Chunk + { + uint32_t typeID; + uint32_t offset; + }; + RED4EXT_ASSERT_SIZE(Chunk, 0x8); + + struct Name + { + uint32_t offset : 24; + uint32_t size : 8; + }; + RED4EXT_ASSERT_SIZE(Name, 0x4); + + struct Import + { + uint32_t offset : 23; + uint32_t size : 8; + uint32_t sync : 1; + }; + RED4EXT_ASSERT_SIZE(Import, 0x4); + + uint8_t version; // 00 + uint8_t unk01; // 01 + uint16_t unk02; // 02 + Range root; // 08 + Range chunks; // 18 + Range names; // 28 + Range imports; // 38 + void* buffer; // 48 + uint32_t size; // 50 +}; +RED4EXT_ASSERT_SIZE(PackageHeader, 0x58); +RED4EXT_ASSERT_OFFSET(PackageHeader, unk02, 0x02); +RED4EXT_ASSERT_OFFSET(PackageHeader, root, 0x08); +RED4EXT_ASSERT_OFFSET(PackageHeader, buffer, 0x48); + +struct ObjectPackageHeader +{ + ObjectPackageHeader(); + + [[nodiscard]] bool IsEmpty() const; + + int16_t rootIndex; // 00 - Set to 0 if package contains root Entity, otherwise -1 + Range cruids; // 08 + PackageHeader package; // 18 +}; +RED4EXT_ASSERT_SIZE(ObjectPackageHeader, 0x70); +RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, rootIndex, 0x0); +RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, cruids, 0x08); +RED4EXT_ASSERT_OFFSET(ObjectPackageHeader, package, 0x18); + +struct ObjectPackageReader +{ + ObjectPackageReader(void* aBuffer, uint32_t aSize); + ObjectPackageReader(const DeferredDataBuffer& aBuffer); + ObjectPackageReader(const DataBuffer& aBuffer); + ObjectPackageReader(const RawBuffer& aBuffer); + + virtual ~ObjectPackageReader() = default; // 00 + virtual void OnReadHeader(uint64_t a1, uint64_t a2); // 08 + + void ReadHeader(); + void ReadHeader(ObjectPackageHeader& aOut); + + [[nodiscard]] bool IsEmpty() const; + + void* buffer; // 08 + uint32_t size; // 10 + ObjectPackageHeader header; // 18 +}; +RED4EXT_ASSERT_SIZE(ObjectPackageReader, 0x88); +RED4EXT_ASSERT_OFFSET(ObjectPackageReader, buffer, 0x08); +RED4EXT_ASSERT_OFFSET(ObjectPackageReader, size, 0x10); +RED4EXT_ASSERT_OFFSET(ObjectPackageReader, header, 0x18); + +struct ObjectPackageExtractorParams +{ + ObjectPackageExtractorParams(const ObjectPackageHeader& aHeader); + ObjectPackageExtractorParams(const PackageHeader& aHeader); + + PackageHeader header; // 00 + ResourceLoader* loader; // 58 + bool disablePostLoad; // 60 - See ObjectPackageExtractor + bool disableImports; // 61 - See ObjectPackageExtractor + bool disablePreInitialization; // 62 - See ObjectPackageExtractor + uint8_t unk63; // 63 + uint8_t unk64; // 64 + DynArray unk68; // 68 + uint32_t unk78; // 78 + RawBuffer unk80; // 80 - Moved to ObjectPackageExtractor in ctor +}; +RED4EXT_ASSERT_SIZE(ObjectPackageExtractorParams, 0xA0); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, loader, 0x58); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disablePostLoad, 0x60); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disableImports, 0x61); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, disablePreInitialization, 0x62); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractorParams, unk80, 0x80); + +struct ObjectPackageExtractor +{ + ObjectPackageExtractor(const ObjectPackageExtractorParams& aParams); + + void ExtractSync(); + JobHandle ExtractAsync(); + + WeakPtr self; // 00 + PackageHeader header; // 10 + DynArray unk68; // 68 + uint32_t unk78; // 78 + RawBuffer unk80; // 80 + ResourceLoader* loader; // A0 + DynArray> results; // A8 + bool disablePostLoad; // B8 - Don't call serializable->PostLoad() + bool disableImports; // B9 - Don't load resource references + bool disablePreInitialization; // BA - Don't call pre-initilization during PostLoad() + uint8_t unkBB; // BB + uint8_t unkBC; // BC + DynArray> objects; // C0 + DynArray>> resources; // D0 + DynArray unkE0; // E0 + void* unkF0; // F0 + void* unkF8; // F8 + void* unk100; // 100 + void* unk108; // 108 + void* unk110; // 110 + void* unk118; // 118 +}; +RED4EXT_ASSERT_SIZE(ObjectPackageExtractor, 0x120); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, header, 0x10); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, results, 0xA8); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disablePostLoad, 0xB8); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disableImports, 0xB9); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, disablePreInitialization, 0xBA); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, objects, 0xC0); +RED4EXT_ASSERT_OFFSET(ObjectPackageExtractor, resources, 0xD0); +} // namespace RED4ext + +#ifdef RED4EXT_HEADER_ONLY +#include +#endif diff --git a/include/RED4ext/Range.hpp b/include/RED4ext/Range.hpp new file mode 100644 index 000000000..91c86f90f --- /dev/null +++ b/include/RED4ext/Range.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include + +#include + +namespace RED4ext +{ +template +struct Range +{ + Range() + : beginPtr(nullptr) + , endPtr(nullptr) + { + } + + constexpr operator bool() const noexcept + { + return IsEmpty(); + } + + [[nodiscard]] inline T* begin() const + { + return beginPtr; + } + + [[nodiscard]] inline T* end() const + { + return endPtr; + } + + [[nodiscard]] inline bool IsEmpty() const + { + return !beginPtr; + } + + [[nodiscard]] inline auto GetSize() const + { + return endPtr - beginPtr; + } + + T* beginPtr; // 00 + T* endPtr; // 08 +}; +RED4EXT_ASSERT_SIZE(Range, 0x10); +RED4EXT_ASSERT_OFFSET(Range, beginPtr, 0x0); +RED4EXT_ASSERT_OFFSET(Range, endPtr, 0x8); +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/Generated/appearance/AppearanceDefinition.hpp b/include/RED4ext/Scripting/Natives/Generated/appearance/AppearanceDefinition.hpp index 5040208ed..46033d100 100644 --- a/include/RED4ext/Scripting/Natives/Generated/appearance/AppearanceDefinition.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/appearance/AppearanceDefinition.hpp @@ -4,6 +4,15 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(appearance::AppearanceDefinition, 0x1D8); +using appearanceAppearanceDefinition = appearance::AppearanceDefinition; +} // namespace RED4ext + +/* #include #include #include @@ -52,5 +61,6 @@ RED4EXT_ASSERT_SIZE(AppearanceDefinition, 0x1D8); } // namespace appearance using appearanceAppearanceDefinition = appearance::AppearanceDefinition; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/ent/Entity.hpp b/include/RED4ext/Scripting/Natives/Generated/ent/Entity.hpp index 9412541c9..5bdeabf87 100644 --- a/include/RED4ext/Scripting/Natives/Generated/ent/Entity.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/ent/Entity.hpp @@ -4,6 +4,16 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(ent::Entity, 0x160); +using entEntity = ent::Entity; +using Entity = ent::Entity; +} // namespace RED4ext + +/* #include #include #include @@ -30,5 +40,6 @@ RED4EXT_ASSERT_SIZE(Entity, 0x160); using entEntity = ent::Entity; using Entity = ent::Entity; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/ent/EntityTemplate.hpp b/include/RED4ext/Scripting/Natives/Generated/ent/EntityTemplate.hpp index ed91d19af..ac29b767a 100644 --- a/include/RED4ext/Scripting/Natives/Generated/ent/EntityTemplate.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/ent/EntityTemplate.hpp @@ -4,6 +4,15 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE( ent::EntityTemplate, 0x2B0); +using entEntityTemplate = ent::EntityTemplate; +} // namespace RED4ext + +/* #include #include #include @@ -52,5 +61,6 @@ RED4EXT_ASSERT_SIZE(EntityTemplate, 0x2B0); } // namespace ent using entEntityTemplate = ent::EntityTemplate; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/ent/IComponent.hpp b/include/RED4ext/Scripting/Natives/Generated/ent/IComponent.hpp index 8e86faac7..9ba31335c 100644 --- a/include/RED4ext/Scripting/Natives/Generated/ent/IComponent.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/ent/IComponent.hpp @@ -4,6 +4,16 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(ent::IComponent, 0x90); +using entIComponent = ent::IComponent; +using IComponent = ent::IComponent; +} // namespace RED4ext + +/* #include #include #include @@ -32,5 +42,6 @@ RED4EXT_ASSERT_SIZE(IComponent, 0x90); using entIComponent = ent::IComponent; using IComponent = ent::IComponent; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/appearanceAppearanceDefinition.hpp b/include/RED4ext/Scripting/Natives/appearanceAppearanceDefinition.hpp new file mode 100644 index 000000000..eb309ed90 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/appearanceAppearanceDefinition.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace RED4ext +{ +struct CMesh; +struct CResource; + +namespace appearance +{ +struct AppearanceDefinition : ISerializable +{ + static constexpr const char* NAME = "appearanceAppearanceDefinition"; + static constexpr const char* ALIAS = NAME; + + CName name; // 30 + CName parentAppearance; // 38 + DynArray> partsMasks; // 40 + DynArray partsValues; // 50 + RaRef proxyMesh; // 60 + CName proxyMeshAppearance; // 68 + RaRef cookedDataPathOverride; // 70 + DynArray partsOverrides; // 78 + red::TagList visualTags; // 88 + red::TagList inheritedVisualTags; // 98 + DynArray hitRepresentationOverrides; // A8 + ent::EntityParametersBuffer parametersBuffer; // B8 + uint32_t censorFlags; // E0 + uint8_t forcedLodDistance; // E4 + uint8_t unkE5[0xF0 - 0xE5]; // E5 + DeferredDataBuffer compiledData; // F0 + ObjectPackageHeader compiledDataHeader; // 148 + DynArray> resolvedDependencies; // 1B8 + DynArray> looseDependencies; // 1C8 +}; +RED4EXT_ASSERT_SIZE(AppearanceDefinition, 0x1D8); +} // namespace appearance +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/entEntity.hpp b/include/RED4ext/Scripting/Natives/entEntity.hpp new file mode 100644 index 000000000..24d3465b0 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/entEntity.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace RED4ext +{ +namespace world { struct RuntimeScene; } + +enum class EntityStatus : uint8_t +{ + Undefined = 0, + Initializing = 1, + Detached = 2, + Attaching = 3, + Attached = 4, + Detaching = 5, + Uninitializing = 6, + Uninitialized = 7, +}; + +namespace ent +{ +struct IPlacedComponent; + +struct Entity : IScriptable +{ + static constexpr const char* NAME = "entEntity"; + static constexpr const char* ALIAS = "Entity"; + + uint32_t unk40; // 40 + uint32_t unk44; // 44 + EntityID entityID; // 48 + CName appearanceName; // 50 + uint64_t unk58; // 58 + ResourcePath templatePath; // 60 + uint64_t unk68; // 68 + uint8_t componentsStorage[0x30]; // 70 - ComponentsStorage but without Handle? + DynArray> components; // A0 - Part of ComponentsStorage + IPlacedComponent* transformComponent; // B0 + world::RuntimeScene* runtimeScene; // B8 + ScriptGameInstance* gameInstance; // C0 + void* unkC8; // C8 + void* unkD0; // D0 + uint8_t eventManager[0x138 - 0xD8]; // D8 + red::TagList visualTags; // 138 + uint8_t unk148[0x154 - 0x148]; // 148 + ECustomCameraTarget customCameraTarget; // 154 + uint8_t unk155; // 155 + EntityStatus status; // 156 + uint8_t unk157[0x15B - 0x157]; // 157 + RenderSceneLayerMask renderSceneLayerMask; // 15B + uint8_t unk15C[0x160 - 0x15C]; // 15C +}; +RED4EXT_ASSERT_SIZE(Entity, 0x160); +} // namespace ent +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/entEntityTemplate.hpp b/include/RED4ext/Scripting/Natives/entEntityTemplate.hpp new file mode 100644 index 000000000..f843bf347 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/entEntityTemplate.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace RED4ext +{ +struct CResource; +namespace ent { struct VisualTagsSchema; } + +namespace ent +{ +struct EntityTemplate : res::StreamedResource +{ + static constexpr const char* NAME = "entEntityTemplate"; + static constexpr const char* ALIAS = NAME; + + DynArray includes; // 40 + DynArray appearances; // 50 + CName defaultAppearance; // 60 + DynArray componentResolveSettings; // 68 + DynArray bindingOverrides; // 78 + DynArray backendDataOverrides; // 88 + Handle visualTagsSchema; // 98 + ObjectPackageHeader localDataHeader; // A8 + DataBuffer localData; // 118 + ObjectPackageHeader includeInstanceBufferHeader; // 140 + DataBuffer includeInstanceBuffer; // 1B0 + ObjectPackageHeader compiledDataHeader; // 1D8 + DataBuffer compiledData; // 248 + DynArray> resolvedDependencies; // 270 + DynArray> inplaceResources; // 280 + uint8_t unk290[0x2A0 - 0x290]; // 290 + uint16_t compiledEntityLODFlags; // 2A0 + uint8_t unk2A2[0x2B0 - 0x2A2]; // 2A2 +}; +RED4EXT_ASSERT_SIZE(EntityTemplate, 0x2B0); +} // namespace ent +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/entIComponent.hpp b/include/RED4ext/Scripting/Natives/entIComponent.hpp new file mode 100644 index 000000000..b16821096 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/entIComponent.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace RED4ext +{ +namespace ent +{ +struct Entity; + +struct IComponent : IScriptable +{ + static constexpr const char* NAME = "entIComponent"; + static constexpr const char* ALIAS = "IComponent"; + + CName name; // 40 + CName appearanceName; // 48 + Entity* owner; // 50 + void* unk58; // 58 + CRUID id; // 60 + ResourcePath appearancePath; // 68 + DynArray> attachments; // 70 + uint16_t unk80; // 80 + uint8_t unk82[0x8B - 0x82]; // 82 + bool isEnabled; // 8B + bool isReplicable; // 8C + uint8_t unk8D[0x90 - 0x8D]; // 8D +}; +RED4EXT_ASSERT_SIZE(IComponent, 0x90); +RED4EXT_ASSERT_OFFSET(IComponent, isEnabled, 0x8B); +} // namespace ent +} // namespace RED4ext diff --git a/src/Package.cpp b/src/Package.cpp new file mode 100644 index 000000000..c0db4ca88 --- /dev/null +++ b/src/Package.cpp @@ -0,0 +1,5 @@ +#ifndef RED4EXT_STATIC_LIB +#error Please define 'RED4EXT_STATIC_LIB' to compile this file. +#endif + +#include