diff --git a/CommonLibF4/cmake/sourcelist.cmake b/CommonLibF4/cmake/sourcelist.cmake index 1b67e20d..d9187a76 100644 --- a/CommonLibF4/cmake/sourcelist.cmake +++ b/CommonLibF4/cmake/sourcelist.cmake @@ -32,6 +32,7 @@ set(SOURCES include/RE/Bethesda/BGSSynchronizedAnimationManager.h include/RE/Bethesda/BGSTextureSet.h include/RE/Bethesda/BSAnimationGraph.h + include/RE/Bethesda/BSAttachTechniques.h include/RE/Bethesda/BSAudioManager.h include/RE/Bethesda/BSAudioUtil.h include/RE/Bethesda/BSBTreeFile.h @@ -40,6 +41,7 @@ set(SOURCES include/RE/Bethesda/BSExtraData.h include/RE/Bethesda/BSFadeNode.h include/RE/Bethesda/BSFixedString.h + include/RE/Bethesda/BSGeometry.h include/RE/Bethesda/BSGraphics.h include/RE/Bethesda/BSHavok.h include/RE/Bethesda/BSInputDeviceManager.h @@ -121,6 +123,8 @@ set(SOURCES include/RE/Bethesda/BSScriptUtil.h include/RE/Bethesda/BSSemaphore.h include/RE/Bethesda/BSShader.h + include/RE/Bethesda/BSShaderMaterial.h + include/RE/Bethesda/BSShaderProperty.h include/RE/Bethesda/BSSoundHandle.h include/RE/Bethesda/BSSpring.h include/RE/Bethesda/BSStorage.h @@ -146,11 +150,12 @@ set(SOURCES include/RE/Bethesda/BSTSmartPointer.h include/RE/Bethesda/BSTTuple.h include/RE/Bethesda/BSTempEffect.h - include/RE/Bethesda/BSTempEffectDebris.h + include/RE/Bethesda/BSTextureDB.h include/RE/Bethesda/BSTextureSet.h include/RE/Bethesda/BSTextureStreamer.h include/RE/Bethesda/BSThread.h include/RE/Bethesda/BSTimer.h + include/RE/Bethesda/BSVisit.h include/RE/Bethesda/CELLJobs.h include/RE/Bethesda/CRC.h include/RE/Bethesda/Calendar.h @@ -193,12 +198,14 @@ set(SOURCES include/RE/Bethesda/PowerUtils.h include/RE/Bethesda/ProcessLists.h include/RE/Bethesda/Projectiles.h + include/RE/Bethesda/ReferenceEffectController.h include/RE/Bethesda/SCRIPT_OUTPUT.h include/RE/Bethesda/SDirectory2.h include/RE/Bethesda/SWFToCodeFunctionHandler.h include/RE/Bethesda/Script.h include/RE/Bethesda/SendHUDMessage.h include/RE/Bethesda/Settings.h + include/RE/Bethesda/Sky.h include/RE/Bethesda/SplineUtils.h include/RE/Bethesda/TESBoundAnimObjects.h include/RE/Bethesda/TESBoundObjects.h @@ -361,6 +368,7 @@ set(SOURCES src/RE/Bethesda/BSScript/StructTypeInfo.cpp src/RE/Bethesda/BSScript/TypeInfo.cpp src/RE/Bethesda/BSScript/Variable.cpp + src/RE/Bethesda/BSVisit.cpp src/RE/Bethesda/CRC.cpp src/RE/Bethesda/Calendar.cpp src/RE/Bethesda/FormComponents.cpp diff --git a/CommonLibF4/include/F4SE/Impl/PCH.h b/CommonLibF4/include/F4SE/Impl/PCH.h index 1235f8ba..97d27948 100644 --- a/CommonLibF4/include/F4SE/Impl/PCH.h +++ b/CommonLibF4/include/F4SE/Impl/PCH.h @@ -660,6 +660,60 @@ namespace F4SE return to; } } + + [[nodiscard]] inline auto utf8_to_utf16(std::string_view a_in) noexcept + -> std::optional + { + const auto cvt = [&](wchar_t* a_dst, std::size_t a_length) { + return WinAPI::MultiByteToWideChar( + WinAPI::CP_UTF8, + 0, + a_in.data(), + static_cast(a_in.length()), + a_dst, + static_cast(a_length)); + }; + + const auto len = cvt(nullptr, 0); + if (len == 0) { + return std::nullopt; + } + + std::wstring out(len, '\0'); + if (cvt(out.data(), out.length()) == 0) { + return std::nullopt; + } + + return out; + } + + [[nodiscard]] inline auto utf16_to_utf8(std::wstring_view a_in) noexcept + -> std::optional + { + const auto cvt = [&](char* a_dst, std::size_t a_length) { + return WinAPI::WideCharToMultiByte( + WinAPI::CP_UTF8, + 0, + a_in.data(), + static_cast(a_in.length()), + a_dst, + static_cast(a_length), + nullptr, + nullptr); + }; + + const auto len = cvt(nullptr, 0); + if (len == 0) { + return std::nullopt; + } + + std::string out(len, '\0'); + if (cvt(out.data(), out.length()) == 0) { + return std::nullopt; + } + + return out; + } } } diff --git a/CommonLibF4/include/F4SE/Impl/WinAPI.h b/CommonLibF4/include/F4SE/Impl/WinAPI.h index 1af58224..171dee7b 100644 --- a/CommonLibF4/include/F4SE/Impl/WinAPI.h +++ b/CommonLibF4/include/F4SE/Impl/WinAPI.h @@ -2,6 +2,8 @@ namespace F4SE::WinAPI { + inline constexpr auto CP_UTF8{ static_cast(65001) }; + inline constexpr auto MAX_PATH{ 260u }; inline constexpr auto(MEM_RELEASE){ static_cast(0x00008000) }; inline constexpr auto(PAGE_EXECUTE_READWRITE){ static_cast(0x40) }; @@ -85,6 +87,14 @@ namespace F4SE::WinAPI const wchar_t* a_caption, unsigned int a_type) noexcept; + [[nodiscard]] int(MultiByteToWideChar)( + unsigned int a_codePage, + std::uint32_t a_flags, + const char* a_multiByteStr, + int a_multiByte, + wchar_t* a_wideCharStr, + int a_wideChar); + void(OutputDebugString)( const char* a_outputString) noexcept; @@ -123,6 +133,16 @@ namespace F4SE::WinAPI std::size_t a_size, std::uint32_t a_newProtect, std::uint32_t* a_oldProtect) noexcept; + + [[nodiscard]] int(WideCharToMultiByte)( + unsigned int a_codePage, + std::uint32_t a_flags, + const wchar_t* a_wideCharStr, + int a_wideChar, + char* a_multiByteStr, + int a_multiByte, + const char* a_defaultChar, + int* a_usedDefaultChar); } namespace RE diff --git a/CommonLibF4/include/RE/Bethesda/ActiveEffect.h b/CommonLibF4/include/RE/Bethesda/ActiveEffect.h index 8dd2cdb0..8e2238b1 100644 --- a/CommonLibF4/include/RE/Bethesda/ActiveEffect.h +++ b/CommonLibF4/include/RE/Bethesda/ActiveEffect.h @@ -1,5 +1,7 @@ #pragma once +#include "RE/Bethesda/BSSoundHandle.h" +#include "RE/Bethesda/ReferenceEffectController.h" #include "RE/Bethesda/TESForms.h" namespace RE @@ -8,18 +10,14 @@ namespace RE class EffectItem; class MagicItem; class MagicTarget; + class ReferenceEffect; class TESForm; class TESObjectREFR; - class ActiveEffectReferenceEffectController + namespace MagicSystem { - public: - virtual ~ActiveEffectReferenceEffectController(); - - // void ** _vtbl; // 00 - ActiveEffect* effect; // 08 - // possibly more - }; + enum class CastingSource; + } class __declspec(novtable) ActiveEffect : public BSIntrusiveRefCounted @@ -29,13 +27,6 @@ namespace RE static constexpr auto VTABLE{ VTABLE::ActiveEffect }; static constexpr auto FORM_ID{ ENUM_FORM_ID::kActiveEffect }; - bool CheckDisplacementSpellOnTarget() - { - using func_t = decltype(&ActiveEffect::CheckDisplacementSpellOnTarget); - REL::Relocation func{ REL::ID(1415178) }; - return func(this); - } - enum class Flags : std::uint32_t { kNone = 0, @@ -63,34 +54,31 @@ namespace RE virtual ~ActiveEffect(); - // void ** _vtbl; // 00 - ActiveEffectReferenceEffectController controller; - std::int32_t unk20; - float unk24; - float unk28; - float unk2C; - std::int32_t unk30; - std::int8_t unk34; - std::int8_t pad35[3]; - ObjectRefHandle target; - std::int32_t unk3C; - void* niNode; - MagicItem* item; - EffectItem* effect; // 50 - MagicTarget* magicTarget; - TESForm* sourceItem; - std::int64_t unk68; - std::int64_t unk70; - float elapsed; - float duration; - float magnitude; - stl::enumeration flags; - stl::enumeration conditionStatus; - std::uint32_t uniqueID; - std::int32_t unk90; - std::int32_t pad94; - std::int32_t actorValue; - std::int32_t unk9C; - std::int64_t unkA0; + bool CheckDisplacementSpellOnTarget() + { + using func_t = decltype(&ActiveEffect::CheckDisplacementSpellOnTarget); + REL::Relocation func{ REL::ID(1415178) }; + return func(this); + } + + // members + ActiveEffectReferenceEffectController hitEffectController; // 0C + BSSoundHandle persistentSound; // 30 + ActorHandle caster; // 38 + NiPointer sourceNode; // 40 + MagicItem* spell; // 48 + EffectItem* effect; // 50 + MagicTarget* target; // 58 + TESBoundObject* source; // 60 + BSSimpleList* hitEffects; // 68 + MagicItem* displacementSpell; // 70 + float elapsedSeconds; // 74 + float duration; // 78 + float magnitude; // 7C + stl::enumeration flags; // 80 + stl::enumeration conditionStatus; // 84 + std::uint16_t uniqueID; // 8C + stl::enumeration castingSource; // 90 }; + static_assert(sizeof(ActiveEffect) == 0x98); } diff --git a/CommonLibF4/include/RE/Bethesda/Actor.h b/CommonLibF4/include/RE/Bethesda/Actor.h index 5eb19bb7..9c376c2f 100644 --- a/CommonLibF4/include/RE/Bethesda/Actor.h +++ b/CommonLibF4/include/RE/Bethesda/Actor.h @@ -1,6 +1,7 @@ #pragma once #include "RE/Bethesda/AITimeStamp.h" +#include "RE/Bethesda/BGSDefaultObjectManager.h" #include "RE/Bethesda/BSFixedString.h" #include "RE/Bethesda/BSLock.h" #include "RE/Bethesda/BSPointerHandle.h" @@ -95,14 +96,7 @@ namespace RE namespace ActorEquipManagerEvent { - struct Event - { - uint32_t unk00; //00 - uint8_t pad04[0x7 - 0x4]; //04 - bool isUnequip; //07 - void* unk08; //08 - Actor* a; //10 equip target - }; + struct Event; } namespace MagicSystem @@ -529,11 +523,9 @@ namespace RE return func(this, a_actor, a_location, a_magnitude); } - void SetupSpecialIdle(Actor& a_actor, RE::DEFAULT_OBJECT a_defaultObject, TESIdleForm* a_idle, bool a_testConditions, TESObjectREFR* a_targetOverride) + bool PlayIdle(Actor& a_actor, TESIdleForm* a_idle, TESObjectREFR* a_target) { - using func_t = decltype(&AIProcess::SetupSpecialIdle); - REL::Relocation func{ REL::ID(1446774) }; - return func(this, a_actor, a_defaultObject, a_idle, a_testConditions, a_targetOverride); + return SetupSpecialIdle(a_actor, DEFAULT_OBJECT::kActionIdle, a_idle, true, a_target); } bool ProcessGreet(Actor* a_actor, DIALOGUE_TYPE a_type, DIALOGUE_SUBTYPE a_subType, TESObjectREFR* a_target, BGSDialogueBranch* a_branch, bool a_forceSub, bool a_stop, bool a_que, bool a_sayCallback) @@ -578,6 +570,13 @@ namespace RE return func(this, a_actor, a_instance, a_slot); } + bool SetupSpecialIdle(Actor& a_actor, RE::DEFAULT_OBJECT a_defaultObject, TESIdleForm* a_idle, bool a_testConditions, TESObjectREFR* a_targetOverride) + { + using func_t = decltype(&AIProcess::SetupSpecialIdle); + REL::Relocation func{ REL::ID(1446774) }; + return func(this, a_actor, a_defaultObject, a_idle, a_testConditions, a_targetOverride); + } + bool SetWeaponBonesCulled(const Actor& a_actor, bool a_stateToSet, WEAPON_CULL_TYPE a_weaponCullType) { using func_t = decltype(&AIProcess::SetWeaponBonesCulled); @@ -585,6 +584,13 @@ namespace RE return func(this, a_actor, a_stateToSet, a_weaponCullType); } + void StopCurrentIdle(Actor* a_actor, bool a_instant, bool a_killFlavor) + { + using func_t = decltype(&AIProcess::StopCurrentIdle); + REL::Relocation func{ REL::ID(434460) }; + return func(this, a_actor, a_instant, a_killFlavor); + } + // members MiddleLowProcessData* middleLow; // 00 MiddleHighProcessData* middleHigh; // 08 @@ -965,6 +971,13 @@ namespace RE return func(this, a_perk, a_rank); } + bool CanUseIdle(TESIdleForm* a_idle) const + { + using func_t = decltype(&Actor::CanUseIdle); + REL::Relocation func{ REL::ID(1223707) }; + return func(this, a_idle); + } + void ClearAttackStates() { using func_t = decltype(&Actor::ClearAttackStates); @@ -972,81 +985,102 @@ namespace RE return func(this); } - [[nodiscard]] TESAmmo* GetCurrentAmmo(BGSEquipIndex a_equipIndex) const + void EndInterruptPackage(bool a_notRunOnceDialogue) { - return currentProcess ? currentProcess->GetCurrentAmmo(a_equipIndex) : nullptr; + using func_t = decltype(&Actor::EndInterruptPackage); + REL::Relocation func{ REL::ID(575188) }; + return func(this, a_notRunOnceDialogue); } - [[nodiscard]] bool GetHostileToActor(Actor* a_actor) + void ExitCover() { - using func_t = decltype(&Actor::GetHostileToActor); - REL::Relocation func{ REL::ID(1148686) }; - return func(this, a_actor); + using func_t = decltype(&Actor::ExitCover); + REL::Relocation func{ REL::ID(770035) }; + return func(this); } - [[nodiscard]] ActorHandle GetMountHandle() + void GetAimVector(NiPoint3& a_aimVector) { - using func_t = decltype(&Actor::GetMountHandle); - REL::Relocation func{ REL::ID(313362) }; - return func(this); + using func_t = decltype(&Actor::GetAimVector); + REL::Relocation func{ REL::ID(554863) }; + return func(this, a_aimVector); } - [[nodiscard]] std::int16_t GetLevel() + NiAVObject* GetClosestBone(NiPoint3 a_impactLocation, NiPoint3 a_movementDirection) { - using func_t = decltype(&Actor::GetLevel); - REL::Relocation func{ REL::ID(661617) }; + using func_t = decltype(&Actor::GetClosestBone); + REL::Relocation func{ REL::ID(1180004) }; + return func(this, a_impactLocation, a_movementDirection); + } + + CFilter GetCollisionFilter() + { + using func_t = decltype(&Actor::GetCollisionFilter); + REL::Relocation func{ REL::ID(1474995) }; return func(this); } - [[nodiscard]] TESNPC* GetNPC() const noexcept; + TESCombatStyle* GetCombatStyle() + { + using func_t = decltype(&Actor::GetCombatStyle); + REL::Relocation func{ REL::ID(1270929) }; + return func(this); + } - [[nodiscard]] std::uint8_t GetPerkRank(BGSPerk* a_perk) + [[nodiscard]] TESAmmo* GetCurrentAmmo(BGSEquipIndex a_equipIndex) const { - using func_t = decltype(&Actor::GetPerkRank); - REL::Relocation func{ REL::ID(1368313) }; - return func(this, a_perk); + return currentProcess ? currentProcess->GetCurrentAmmo(a_equipIndex) : nullptr; } - [[nodiscard]] bool IsJumping() + std::uint32_t GetCurrentCollisionGroup() { - using func_t = decltype(&Actor::IsJumping); - REL::Relocation func{ REL::ID(1041558) }; + using func_t = decltype(&Actor::GetCurrentCollisionGroup); + REL::Relocation func{ REL::ID(410500) }; return func(this); } - void RemovePerk(BGSPerk* a_perk) + bool GetCurrentFireLocation(BGSEquipIndex a_index, NiPoint3& a_fireLocation) { - using func_t = decltype(&Actor::RemovePerk); - REL::Relocation func{ REL::ID(1316475) }; - return func(this, a_perk); + using func_t = decltype(&Actor::GetCurrentFireLocation); + REL::Relocation func{ REL::ID(663107) }; + return func(this, a_index, a_fireLocation); } - void Reset3D(bool a_reloadAll, std::uint32_t a_additionalFlags, bool a_queueReset, std::uint32_t a_excludeFlags) + float GetDesiredSpeed() { - using func_t = decltype(&Actor::Reset3D); - REL::Relocation func{ REL::ID(302888) }; - return func(this, a_reloadAll, a_additionalFlags, a_queueReset, a_excludeFlags); + using func_t = decltype(&Actor::GetDesiredSpeed); + REL::Relocation func{ REL::ID(106892) }; + return func(this); } - void RewardExperience(float a_amount, bool a_direct, TESObjectREFR* a_actionTarget, TESObjectREFR* a_killWeapon) + [[nodiscard]] bool GetHostileToActor(Actor* a_actor) { - using func_t = decltype(&Actor::RewardExperience); - REL::Relocation func{ REL::ID(262786) }; - return func(this, a_amount, a_direct, a_actionTarget, a_killWeapon); + using func_t = decltype(&Actor::GetHostileToActor); + REL::Relocation func{ REL::ID(1148686) }; + return func(this, a_actor); } - void SetCurrentAmmo(BGSEquipIndex a_equipIndex, TESAmmo* a_ammo) + [[nodiscard]] ActorHandle GetMountHandle() { - if (currentProcess) { - currentProcess->SetCurrentAmmo(a_equipIndex, a_ammo); - } + using func_t = decltype(&Actor::GetMountHandle); + REL::Relocation func{ REL::ID(313362) }; + return func(this); } - void TrespassAlarm(TESObjectREFR* a_refr, TESForm* a_owner, std::int32_t a_crime) + [[nodiscard]] std::int16_t GetLevel() { - using func_t = decltype(&Actor::TrespassAlarm); - REL::Relocation func{ REL::ID(1109888) }; - return func(this, a_refr, a_owner, a_crime); + using func_t = decltype(&Actor::GetLevel); + REL::Relocation func{ REL::ID(661617) }; + return func(this); + } + + [[nodiscard]] TESNPC* GetNPC() const noexcept; + + [[nodiscard]] std::uint8_t GetPerkRank(BGSPerk* a_perk) + { + using func_t = decltype(&Actor::GetPerkRank); + REL::Relocation func{ REL::ID(1368313) }; + return func(this, a_perk); } void HandleDefaultAnimationSwitch() @@ -1063,123 +1097,123 @@ namespace RE return func(this, bCullBone); } - bool PerformAction(BGSAction* a_action, TESObjectREFR* a_target) + void InitiateDoNothingPackage() { - using func_t = decltype(&Actor::PerformAction); - REL::Relocation func{ REL::ID(1057231) }; - return func(this, a_action, a_target); + using func_t = decltype(&Actor::InitiateDoNothingPackage); + REL::Relocation func{ REL::ID(89993) }; + return func(this); } - void SetGunState(GUN_STATE gun_state, bool unk = true) + bool IsCrippled() { - using func_t = decltype(&Actor::SetGunState); - REL::Relocation func{ REL::ID(977675) }; - return func(this, gun_state, unk); + using func_t = decltype(&Actor::IsCrippled); + REL::Relocation func{ REL::ID(1238666) }; + return func(this); } - void GetAimVector(NiPoint3& out) + bool IsFollowing() { - using func_t = decltype(&Actor::GetAimVector); - REL::Relocation func{ REL::ID(554863) }; - return func(this, out); + using func_t = decltype(&Actor::IsFollowing); + REL::Relocation func{ REL::ID(629579) }; + return func(this); } - uint32_t GetCurrentCollisionGroup() + [[nodiscard]] bool IsJumping() { - using func_t = decltype(&Actor::GetCurrentCollisionGroup); - REL::Relocation func{ REL::ID(410500) }; + using func_t = decltype(&Actor::IsJumping); + REL::Relocation func{ REL::ID(1041558) }; return func(this); } - CFilter GetCollisionFilter() + bool IsPathValid() { - using func_t = decltype(&Actor::GetCollisionFilter); - REL::Relocation func{ REL::ID(1474995) }; + using func_t = decltype(&Actor::IsPathValid); + REL::Relocation func{ REL::ID(1522194) }; return func(this); } - bool GetCurrentFireLocation(BGSEquipIndex index, NiPoint3& out) + bool IsPathing() { - using func_t = decltype(&Actor::GetCurrentFireLocation); - REL::Relocation func{ REL::ID(663107) }; - return func(this, index, out); + using func_t = decltype(&Actor::IsPathing); + REL::Relocation func{ REL::ID(989661) }; + return func(this); } - float GetDesiredSpeed() + bool IsPathingComplete() { - using func_t = decltype(&Actor::GetDesiredSpeed); - REL::Relocation func{ REL::ID(106892) }; + using func_t = decltype(&Actor::IsPathingComplete); + REL::Relocation func{ REL::ID(817283) }; return func(this); } - NiAVObject* GetClosestBone(NiPoint3 pos, NiPoint3 dir) + bool IsQuadruped() { - using func_t = decltype(&Actor::GetClosestBone); - REL::Relocation func{ REL::ID(1180004) }; - return func(this, pos, dir); + using func_t = decltype(&Actor::IsQuadruped); + REL::Relocation func{ REL::ID(1552322) }; + return func(this); } - bhkCharacterController* Move(float deltaTime, NiPoint3 deltaPos, bool unk) + bhkCharacterController* Move(float a_deltaTime, NiPoint3 a_deltaPos, bool a_defer) { using func_t = decltype(&Actor::Move); REL::Relocation func{ REL::ID(737625) }; - return func(this, deltaTime, deltaPos, unk); + return func(this, a_deltaTime, a_deltaPos, a_defer); } - void ExitCover() + bool PerformAction(BGSAction* a_action, TESObjectREFR* a_target) { - using func_t = decltype(&Actor::ExitCover); - REL::Relocation func{ REL::ID(770035) }; - return func(this); + using func_t = decltype(&Actor::PerformAction); + REL::Relocation func{ REL::ID(1057231) }; + return func(this, a_action, a_target); } - TESCombatStyle* GetCombatStyle() + void RemovePerk(BGSPerk* a_perk) { - using func_t = decltype(&Actor::GetCombatStyle); - REL::Relocation func{ REL::ID(1270929) }; - return func(this); + using func_t = decltype(&Actor::RemovePerk); + REL::Relocation func{ REL::ID(1316475) }; + return func(this, a_perk); } - bool IsCrippled() + void Reset3D(bool a_reloadAll, std::uint32_t a_additionalFlags, bool a_queueReset, std::uint32_t a_excludeFlags) { - using func_t = decltype(&Actor::IsCrippled); - REL::Relocation func{ REL::ID(1238666) }; - return func(this); + using func_t = decltype(&Actor::Reset3D); + REL::Relocation func{ REL::ID(302888) }; + return func(this, a_reloadAll, a_additionalFlags, a_queueReset, a_excludeFlags); } - bool IsFollowing() + void RewardExperience(float a_amount, bool a_direct, TESObjectREFR* a_actionTarget, TESObjectREFR* a_killWeapon) { - using func_t = decltype(&Actor::IsFollowing); - REL::Relocation func{ REL::ID(629579) }; - return func(this); + using func_t = decltype(&Actor::RewardExperience); + REL::Relocation func{ REL::ID(262786) }; + return func(this, a_amount, a_direct, a_actionTarget, a_killWeapon); } - bool IsPathValid() + void SetCurrentAmmo(BGSEquipIndex a_equipIndex, TESAmmo* a_ammo) { - using func_t = decltype(&Actor::IsPathValid); - REL::Relocation func{ REL::ID(1522194) }; - return func(this); + if (currentProcess) { + currentProcess->SetCurrentAmmo(a_equipIndex, a_ammo); + } } - bool IsPathing() + void SetGunState(GUN_STATE a_gunState, bool a_val = true) { - using func_t = decltype(&Actor::IsPathing); - REL::Relocation func{ REL::ID(989661) }; - return func(this); + using func_t = decltype(&Actor::SetGunState); + REL::Relocation func{ REL::ID(977675) }; + return func(this, a_gunState, a_val); } - bool IsPathingComplete() + void SetHeading(float a_angle) { - using func_t = decltype(&Actor::IsPathingComplete); - REL::Relocation func{ REL::ID(817283) }; - return func(this); + using func_t = decltype(&Actor::SetHeading); + REL::Relocation func{ REL::ID(353571) }; + return func(this, a_angle); } - bool IsQuadruped() + void TrespassAlarm(TESObjectREFR* a_refr, TESForm* a_owner, std::int32_t a_crime) { - using func_t = decltype(&Actor::IsQuadruped); - REL::Relocation func{ REL::ID(1552322) }; - return func(this); + using func_t = decltype(&Actor::TrespassAlarm); + REL::Relocation func{ REL::ID(1109888) }; + return func(this, a_refr, a_owner, a_crime); } // members diff --git a/CommonLibF4/include/RE/Bethesda/BGSStoryManagerTreeForm.h b/CommonLibF4/include/RE/Bethesda/BGSStoryManagerTreeForm.h index cd0e1810..a87e5077 100644 --- a/CommonLibF4/include/RE/Bethesda/BGSStoryManagerTreeForm.h +++ b/CommonLibF4/include/RE/Bethesda/BGSStoryManagerTreeForm.h @@ -89,17 +89,17 @@ namespace RE static constexpr auto VTABLE{ VTABLE::TESQuest }; static constexpr auto FORM_ID{ ENUM_FORM_ID::kQUST }; - bool SetStage(uint16_t stage) + struct AliasesAccess; + struct ListObjectivesAccess; + struct ListStagesAccess; + + bool SetStage(std::uint16_t stage) { using func_t = decltype(&TESQuest::SetStage); REL::Relocation func{ REL::ID(952799) }; return func(this, stage); } - struct AliasesAccess; - struct ListObjectivesAccess; - struct ListStagesAccess; - // members BSTArray instanceData; // 038 std::uint32_t currentInstanceID; // 050 diff --git a/CommonLibF4/include/RE/Bethesda/BSAttachTechniques.h b/CommonLibF4/include/RE/Bethesda/BSAttachTechniques.h new file mode 100644 index 00000000..5b36fcd6 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSAttachTechniques.h @@ -0,0 +1,47 @@ +#pragma once + +namespace RE +{ + class bhkWorld; + class NiAVObject; + class NiNode; + class TESObjectREFR; + class TESRace; + + namespace BSAttachTechniques + { + struct __declspec(novtable) AttachTechniqueInput + { + public: + static constexpr auto RTTI{ RTTI::BSAttachTechniques__AttachTechniqueInput }; + static constexpr auto VTABLE{ VTABLE::BSAttachTechniques__AttachTechniqueInput }; + + virtual ~AttachTechniqueInput(); // 00 + + // add + virtual void Clear(); // 01 + + // members + NiPointer root; // 08 + NiPointer attaching; // 10 + std::uint32_t attachPoint; // 18 + }; + static_assert(sizeof(AttachTechniqueInput) == 0x20); + } + + class __declspec(novtable) RefAttachTechniqueInput : + public BSAttachTechniques::AttachTechniqueInput // 00 + { + public: + static constexpr auto RTTI{ RTTI::RefAttachTechniqueInput }; + static constexpr auto VTABLE{ VTABLE::RefAttachTechniqueInput }; + + // members + TESObjectREFR* object; // 20 + TESRace* race; // 28 + bhkWorld* havokWorld; // 30 + std::uint32_t collisionGroup; // 38 + BSFixedString techniqueSuffix; // 40 + }; + static_assert(sizeof(RefAttachTechniqueInput) == 0x48); +} diff --git a/CommonLibF4/include/RE/Bethesda/BSContainer.h b/CommonLibF4/include/RE/Bethesda/BSContainer.h index fb3da7f5..0a5c3340 100644 --- a/CommonLibF4/include/RE/Bethesda/BSContainer.h +++ b/CommonLibF4/include/RE/Bethesda/BSContainer.h @@ -4,5 +4,7 @@ namespace RE::BSContainer { enum class ForEachResult { + kContinue = 0, + kStop = 1 }; } diff --git a/CommonLibF4/include/RE/Bethesda/BSExtraData.h b/CommonLibF4/include/RE/Bethesda/BSExtraData.h index 185d5759..d9a6a61e 100644 --- a/CommonLibF4/include/RE/Bethesda/BSExtraData.h +++ b/CommonLibF4/include/RE/Bethesda/BSExtraData.h @@ -429,18 +429,18 @@ namespace RE ctor(a_item, a_parentForm, a_filter); } - static bool AttachModToReference(TESObjectREFR& ref, BGSMod::Attachment::Mod& mod, std::uint8_t a_attachIndex, std::uint8_t a_rank) + static bool AttachModToReference(TESObjectREFR& a_ref, BGSMod::Attachment::Mod& a_mod, std::uint8_t a_attachIndex, std::uint8_t a_rank) { using func_t = decltype(&BGSObjectInstanceExtra::AttachModToReference); REL::Relocation func{ REL::ID(3303) }; - return func(ref, mod, a_attachIndex, a_rank); + return func(a_ref, a_mod, a_attachIndex, a_rank); } - bool HasMod(const BGSMod::Attachment::Mod& mod) + bool HasMod(const BGSMod::Attachment::Mod& a_mod) { using func_t = decltype(&BGSObjectInstanceExtra::HasMod); REL::Relocation func{ REL::ID(963890) }; - return func(this, mod); + return func(this, a_mod); } void AddMod(const BGSMod::Attachment::Mod& a_newMod, std::uint8_t a_attachIndex, std::uint8_t a_rank, bool a_removeInvalidMods) @@ -642,18 +642,32 @@ namespace RE }; static_assert(sizeof(ExtraPowerLinks) == 0x30); - class __declspec(novtable) ExtraBendableSplineParams : public BSExtraData + class __declspec(novtable) ExtraBendableSplineParams : + public BSExtraData // 00 { public: static constexpr auto RTTI{ RTTI::ExtraBendableSplineParams }; static constexpr auto VTABLE{ VTABLE::ExtraBendableSplineParams }; static constexpr auto TYPE{ EXTRA_DATA_TYPE::kBendableSplineParams }; - float unk18; // 18 - float thickness; // 1C - float xOffset; // 20 - float yOffset; // 24 - float zOffset; // 28 - float unk2C; // 2C + + struct ParamData_Untilv13 + { + // members + float slack; // 00 + float thickness; // 04 + NiPoint3 halfExtents; // 08 + }; + static_assert(sizeof(ParamData_Untilv13) == 0x14); + + struct ParamData : public ParamData_Untilv13 + { + // members + bool endDetached; // 14 + }; + static_assert(sizeof(ParamData) == 0x18); + + // members + ParamData data; // 18 }; static_assert(sizeof(ExtraBendableSplineParams) == 0x30); @@ -850,11 +864,11 @@ namespace RE return std::unique_ptr{ static_cast(RemoveExtra(T::TYPE).release()) }; } - bool SetBendableSplineInfo(float* thickness, float* slack, NiPoint3* unk1 = nullptr, bool* unk2 = nullptr) + bool SetBendableSplineInfo(float* a_thickness, float* a_slack, NiPoint3* a_halfExtents = nullptr, bool* a_detachedEnd = nullptr) { using func_t = decltype(&ExtraDataList::SetBendableSplineInfo); REL::Relocation func{ REL::ID(894306) }; - return func(this, thickness, slack, unk1, unk2); + return func(this, a_thickness, a_slack, a_halfExtents, a_detachedEnd); } void SetDisplayNameFromInstanceData(BGSObjectInstanceExtra* a_instExtra, TESBoundObject* a_object, const BSTSmartPointer& a_data) diff --git a/CommonLibF4/include/RE/Bethesda/BSGeometry.h b/CommonLibF4/include/RE/Bethesda/BSGeometry.h new file mode 100644 index 00000000..61a09bc5 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSGeometry.h @@ -0,0 +1,55 @@ +#pragma once + +#include "RE/Bethesda/BSGraphics.h" +#include "RE/NetImmerse/NiAVObject.h" +#include "RE/NetImmerse/NiProperty.h" + +namespace RE +{ + class BSCombinedTriShape; + class BSGeometrySegmentData; + class BSMergeInstancedTriShape; + class BSMultiIndexTriShape; + + namespace BSGraphics + { + struct IndexBuffer; + } + + namespace BSSkin + { + class Instance; + } + + class __declspec(novtable) BSGeometry : + public NiAVObject // 000 + { + public: + static constexpr auto RTTI{ RTTI::BSGeometry }; + static constexpr auto VTABLE{ VTABLE::BSGeometry }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSGeometry }; + + BSGeometry(); + virtual ~BSGeometry(); // NOLINT(modernize-use-override) 00 + + // add + virtual void UpdatePropertyControllers(NiUpdateData& a_data); // 3A + virtual BSGeometrySegmentData* GetSegmentData(); // 3B + virtual void SetSegmentData(BSGeometrySegmentData* a_data); // 3C + virtual BSGraphics::IndexBuffer* GetCustomIndexBuffer(); // 3D + virtual BSCombinedTriShape* IsBSCombinedTriShape(); // 3E + virtual BSMergeInstancedTriShape* IsBSMergeInstancedTriShape(); // 3F + virtual BSMultiIndexTriShape* IsMultiIndexTriShape(); // 40 + virtual std::uint32_t GetRenderableTris(std::uint32_t a_LODMode); // 40 + + // members + NiBound modelBound; // 120 + NiPointer properties[2]; // 130 + NiPointer skinInstance; // 140 + void* rendererData; // 148 + BSGraphics::VertexDesc vertexDesc; // 150 + std::uint8_t type; // 158 + bool registered; // 159 + }; + static_assert(sizeof(BSGeometry) == 0x160); +} diff --git a/CommonLibF4/include/RE/Bethesda/BSGraphics.h b/CommonLibF4/include/RE/Bethesda/BSGraphics.h index a89296dc..deb0b6e4 100644 --- a/CommonLibF4/include/RE/Bethesda/BSGraphics.h +++ b/CommonLibF4/include/RE/Bethesda/BSGraphics.h @@ -2,6 +2,8 @@ #include "RE/Bethesda/Atomic.h" #include "RE/Bethesda/BSTHashMap.h" +#include "RE/NetImmerse/NiColor.h" +#include "RE/NetImmerse/NiPoint2.h" #include "RE/NetImmerse/NiRect.h" #include "RE/NetImmerse/NiSmartPointer.h" #include "RE/NetImmerse/NiTexture.h" @@ -26,6 +28,15 @@ namespace RE enum class DXGI_MODE_SCALING; enum class DXGI_MODE_SCANLINE_ORDER; + enum class TextureFileFormat + { + kBMP = 0, + kJPG = 1, + kTGA = 2, + kPNG = 3, + kDDS = 4, + }; + class BSD3DResourceCreator; class NiCamera; @@ -60,11 +71,37 @@ namespace RE kEnabled }; + enum class TextureFileFormat + { + kBMP = 0, + kJPG = 1, + kTGA = 2, + kPNG = 3, + kDDS = 4, + }; + struct Buffer { - uint64_t unk00; - uint64_t rawVertexData; + public: + // members + ID3D11Buffer* buffer; // 00 + void* data; // 08 + Buffer* next; // 10 + ID3D11ShaderResourceView* shaderResource; // 18 + ID3D11UnorderedAccessView* unorderedAccess; // 20 + BSEventFlag* requestEventToWait; // 28 + std::uint32_t maxDataSize; // 30 + std::uint32_t dataSize; // 34 + std::uint32_t refCount; // 38 + BSTAtomicValue SRAcquire; // 3C + BSTAtomicValue UAVAcquire; // 40 + BSTAtomicValue pendingRequests; // 44 + std::uint32_t dataOffset; // 48 + bool invalidCpuData; // 4C + bool heapAllocated; // 4D + volatile bool pendingCopy; // 4E }; + static_assert(sizeof(Buffer) == 0x50); struct TextureHeader { @@ -234,7 +271,7 @@ namespace RE RenderTarget renderTargets[101]; // 0A58 DepthStencilTarget depthStencilTargets[13]; // 1D48 CubeMapRenderTarget cubeMapRenderTargets[2]; // 2500 - std::byte rendererLock[0x25A8 - 0x2580]; // 2580 - TODO + BSCriticalSection rendererLock; // 2580 const char* className; // 25A8 void* instance; // 25B0 bool nvapiEnabled; // 25B8 @@ -246,17 +283,17 @@ namespace RE public: using ResetRenderTargets_t = void (*)(); - void IncRef(Buffer* vertexBuffer) + void IncRef(Buffer* a_vertexBuffer) { using func_t = decltype(&BSGraphics::Renderer::IncRef); REL::Relocation func{ REL::ID(1337764) }; - return func(this, vertexBuffer); + return func(this, a_vertexBuffer); } - void DecRef(Buffer* vertexBuffer) + void DecRef(Buffer* a_vertexBuffer) { using func_t = decltype(&BSGraphics::Renderer::DecRef); REL::Relocation func{ REL::ID(194808) }; - return func(this, vertexBuffer); + return func(this, a_vertexBuffer); } // members diff --git a/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h b/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h index 41bca4ae..d11884de 100644 --- a/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h +++ b/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h @@ -38,4 +38,16 @@ namespace RE static constexpr auto VTABLE{ VTABLE::DisconnectHandler }; }; static_assert(sizeof(DisconnectHandler) == 0x10); + + struct __declspec(novtable) ScreenshotHandler : + public BSInputEventUser // 00 + { + static constexpr auto RTTI{ RTTI::ScreenshotHandler }; + static constexpr auto VTABLE{ VTABLE::ScreenshotHandler }; + + // members + bool screenshotQueued; // 10 + bool multiScreenshotQueued; // 11 + }; + static_assert(sizeof(ScreenshotHandler) == 0x18); } diff --git a/CommonLibF4/include/RE/Bethesda/BSLock.h b/CommonLibF4/include/RE/Bethesda/BSLock.h index 4891ecf7..bbd95a09 100644 --- a/CommonLibF4/include/RE/Bethesda/BSLock.h +++ b/CommonLibF4/include/RE/Bethesda/BSLock.h @@ -2,6 +2,14 @@ namespace RE { + class BSCriticalSection + { + public: + // members + WinAPI::CRITICAL_SECTION criticalSection; // 00 + }; + static_assert(sizeof(BSCriticalSection) == 0x28); + class BSNonReentrantSpinLock { public: diff --git a/CommonLibF4/include/RE/Bethesda/BSModelDB.h b/CommonLibF4/include/RE/Bethesda/BSModelDB.h index 092376a8..432f3a54 100644 --- a/CommonLibF4/include/RE/Bethesda/BSModelDB.h +++ b/CommonLibF4/include/RE/Bethesda/BSModelDB.h @@ -72,4 +72,6 @@ namespace RE return func(a_name, a_result, a_args); } }; + + using ModelDBHandle = BSResource::RHandleType, BSResource::EntryDBTraits>::CArgs>, BSResource::EntryDB>; } diff --git a/CommonLibF4/include/RE/Bethesda/BSShaderMaterial.h b/CommonLibF4/include/RE/Bethesda/BSShaderMaterial.h new file mode 100644 index 00000000..b7801268 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSShaderMaterial.h @@ -0,0 +1,142 @@ +#pragma once + +#include "RE/Bethesda/BSGraphics.h" +#include "RE/Bethesda/BSLock.h" +#include "RE/Bethesda/BSTSmartPointer.h" +#include "RE/Bethesda/BSTextureDB.h" +#include "RE/NetImmerse/NiColor.h" +#include "RE/NetImmerse/NiPoint2.h" +#include "RE/NetImmerse/NiSmartPointer.h" + +namespace RE +{ + class BSLightingShaderMaterialEnvmap; + class BSTextureSet; + class NiTexture; + + class __declspec(novtable) BSShaderMaterial : + public BSIntrusiveRefCounted // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSShaderMaterial }; + static constexpr auto VTABLE{ VTABLE::BSShaderMaterial }; + + enum class Feature + { + kNone = static_cast>(-1), + kDefault = 0, + kEnvmap, + kGlowmap, + kParallax, + kFace, + kSkinTint, + kHairTint, + kParallaxOcc, + kLandscape, + kLODLandscape, + kSnow, + kMultiLayerParallax, + kTreeAnim, + kLODObjects, + kMultiIndexSnow, + kLODObjectsHD, + kEye, + kCloud, + kLODLandscapeNoise, + kLODLandscapeBlend, + kDismemberment + }; + + enum class Type + { + kBase = 0, + kEffect = 1, + kLighting = 2, + kWater = 3 + }; + + virtual ~BSShaderMaterial(); + + // add + virtual BSShaderMaterial* Create(); // 01 + virtual void CopyMembers(const BSShaderMaterial* a_other); // 02 + virtual std::uint32_t ComputeCRC32(std::uint32_t a_uniqueID, bool a_combining); // 03 + virtual BSShaderMaterial* GetDefault(); // 04 + virtual Feature GetFeature(); // 05 + virtual Type GetType(); // 06 + virtual void ReceiveValuesFromRootMaterial(BSShaderProperty* a_property); // 07 + virtual bool DoIsCopy(const BSShaderMaterial* a_other); // 08 + + // members + NiPoint2 texCoordOffset[2]; // 0C + NiPoint2 texCoordScale[2]; // 1C + std::uint32_t hashKey; // 2C + std::uint32_t uniqueCode; // 30 + }; + static_assert(sizeof(BSShaderMaterial) == 0x38); + + struct __declspec(novtable) BSLightingShaderMaterialBase : + public BSShaderMaterial // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSLightingShaderMaterialBase }; + static constexpr auto VTABLE{ VTABLE::BSLightingShaderMaterialBase }; + + // add + virtual const BSLightingShaderMaterialEnvmap* IsLightingShaderMaterialEnvmap(); // 09 + virtual void ClearTextures(); // 0A + virtual std::uint32_t GetTextures(NiTexture** a_textures, std::uint32_t a_arraySize); // 0B + virtual void SaveBinary(NiStream* a_stream); // 0C + virtual void LoadBinary(NiStream* a_stream); // 0D + virtual void OnPrefetchTextures(TextureDBHandle* a_outHandles, const BSTextureSet* a_textureSet); // 0E + virtual void OnLoadTextureSet1(const BSTextureSet* a_textureSet, TextureDBHandle* a_inHandles); // 0F + virtual void OnLoadTextureSet2(const BSTextureSet* a_textureSet); // 10 + virtual void DoReceiveValuesFromRootMaterial(const BSShaderData& a_rootData); // 11 + + void OnLoadTextureSet(const BSTextureSet* a_textureSet, TextureDBHandle* a_inHandles) + { + return OnLoadTextureSet1(a_textureSet, a_inHandles); + } + + void OnLoadTextureSet(const BSTextureSet* a_textureSet) + { + return OnLoadTextureSet2(a_textureSet); + } + + // members + NiColor specularColor; // 38 + NiPointer diffuseTexture; // 40 + NiPointer normalTexture; // 48 + NiPointer rimSoftLightingTexture; // 50 + NiPointer smoothnessSpecMaskTexture; // 58 + NiPointer lookupTexture; // 60 + BSGraphics::TextureAddressMode textureClampMode; // 68 + NiPointer textureSet; // 70 + float materialAlpha; // 74 + float refractionPower; // 78 + float smoothness; // 7C + float specularColorScale; // 80 + float fresnelPower; // 84 + float wetnessControl_SpecScale; // 88 + float wetnessControl_SpecPowerScale; // 8C + float wetnessControl_SpecMin; // 90 + float wetnessControl_EnvMapScale; // 94 + float wetnessControl_FresnelPower; // 98 + float wetnessControl_Metalness; // 9C + float subSurfaceLightRolloff; // A0 + float rimLightPower; // A4 + float backLightPower; // A8 + float lookupScale; // AC + BSNonReentrantSpinLock loadTextureSetLock; // B0 + }; + static_assert(sizeof(BSLightingShaderMaterialBase) == 0xC0); + + struct __declspec(novtable) BSLightingShaderMaterial : + public BSLightingShaderMaterialBase // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSLightingShaderMaterial }; + static constexpr auto VTABLE{ VTABLE::BSLightingShaderMaterial }; + }; + static_assert(sizeof(BSLightingShaderMaterial) == 0xC0); +} diff --git a/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h b/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h new file mode 100644 index 00000000..2f86c1ed --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h @@ -0,0 +1,193 @@ +#pragma once + +#include "RE/Bethesda/BSLock.h" +#include "RE/NetImmerse/NiColor.h" +#include "RE/NetImmerse/NiObject.h" +#include "RE/NetImmerse/NiShadeProperty.h" + +namespace RE +{ + class BSEffectShaderData; + class BSRenderPass; + class BSShaderAccumulator; + class BSShaderMaterial; + class NiTexture; + + struct __declspec(novtable) BSShaderProperty : + public NiShadeProperty // 00 + { + private: + static constexpr auto BIT64 = static_cast(1); + + public: + static constexpr auto RTTI{ RTTI::BSShaderProperty }; + static constexpr auto VTABLE{ VTABLE::BSShaderProperty }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSShaderProperty }; + + enum class TextureTypeEnum + { + kBase = 0, + kNormal, + kGlow, + kHeight, + kEnv, + kWrinkles, + kMultilayer, + kBacklightMask, + kSmoothSpec = kBacklightMask, + + kTotal, + }; + + enum class EShaderPropertyFlag : std::uint64_t + { + kSpecular = BIT64 << 0, + kSkinned = BIT64 << 1, + kTempRefraction = BIT64 << 2, + kVertexAlpha = BIT64 << 3, + kGrayscaleToPaletteColor = BIT64 << 4, + kGrayscaleToPaletteAlpha = BIT64 << 5, + kFalloff = BIT64 << 6, + kEnvMap = BIT64 << 7, + kRGBFalloff = BIT64 << 8, + kCastShadows = BIT64 << 9, + kFace = BIT64 << 10, + kUIMaskRects = BIT64 << 11, + kModelSpaceNormals = BIT64 << 12, + kRefractionClamp = BIT64 << 13, + kMultiTextureLandscape = BIT64 << 14, + kRefraction = BIT64 << 15, + kRefractionFalloff = BIT64 << 16, + kEyeReflect = BIT64 << 17, + kHairTint = BIT64 << 18, + kScreendoorAlphaFade = BIT64 << 19, + kLocalMapClear = BIT64 << 20, + kFaceGenRGBTint = BIT64 << 21, + kOwnEmit = BIT64 << 22, + kProjectedUV = BIT64 << 23, + kMultipleTextures = BIT64 << 24, + kTesselate = BIT64 << 25, + kDecal = BIT64 << 26, + kDynamicDecal = BIT64 << 27, + kCharacterLight = BIT64 << 28, + kExternalEmittance = BIT64 << 29, + kSoftEffect = BIT64 << 30, + kZBufferTest = BIT64 << 31, + kZBufferWrite = BIT64 << 32, + kLODLandscape = BIT64 << 33, + kLODObjects = BIT64 << 34, + kNoFade = BIT64 << 35, + kTwoSided = BIT64 << 36, + kVertexColors = BIT64 << 37, + kGlowMap = BIT64 << 38, + kTransformChanged = BIT64 << 39, + kDismembermentMeatCuff = BIT64 << 40, + kTint = BIT64 << 41, + kVertexLighting = BIT64 << 42, + kUniformScale = BIT64 << 43, + kFitSlope = BIT64 << 44, + kBillboard = BIT64 << 45, + kLODLandBlend = BIT64 << 46, + kDismemberment = BIT64 << 47, + kWireframe = BIT64 << 48, + kWeaponBlood = BIT64 << 49, + kHideOnLocalMap = BIT64 << 50, + kPremultAlpha = BIT64 << 51, + kVATSTarget = BIT64 << 52, + kAnisotropicLighting = BIT64 << 53, + kSkewSpecularAlpha = BIT64 << 54, + kMenuScreen = BIT64 << 55, + kMultiLayerParallax = BIT64 << 56, + kAlphaTest = BIT64 << 57, + kInvertedFadePattern = BIT64 << 58, + kVATSTargetDrawAll = BIT64 << 59, + kPipboyScreen = BIT64 << 60, + kTreeAnim = BIT64 << 61, + kEffectLighting = BIT64 << 62, + kRefractionWritesDepth = BIT64 << 63 + }; + + class ForEachVisitor; + + class RenderPassArray + { + public: + constexpr RenderPassArray() noexcept {} // NOLINT(modernize-use-equals-default) + + // members + BSRenderPass* passList{ nullptr }; // 0 + }; + static_assert(sizeof(RenderPassArray) == 0x8); + + // add + virtual RenderPassArray* GetRenderPasses(BSGeometry* a_geom, std::uint32_t a_renderMode, BSShaderAccumulator* a_accumulator) = 0; // 2B + virtual RenderPassArray* GetRenderPasses_ShadowMapOrMask(BSGeometry*, std::uint32_t, BSShaderAccumulator*) { return nullptr; } // 2C + virtual RenderPassArray* GetRenderPasses_LocalMap(BSGeometry*, std::uint32_t, BSShaderAccumulator*) { return nullptr; } // 2D + virtual BSRenderPass* CreateVatsMaskRenderPass(BSGeometry*) { return nullptr; } // 2E + virtual std::uint16_t GetNumberofPasses([[maybe_unused]] BSGeometry* a_geom) { return 1; } // 2F + virtual BSRenderPass* GetRenderDepthPass(BSGeometry*) { return nullptr; } // 30 + virtual bool CanMerge(const BSShaderProperty* a_prop); // 31 + virtual void SetMaterialAlpha(float) { return; } // 32 + virtual float QMaterialAlpha() const { return 1.0F; } // 33 + virtual const BSFixedString& GetRootName() const; // 34 + virtual std::int32_t ForEachTexture(ForEachVisitor&) { return 1; } // 35 + virtual std::int32_t QShader() const { return 0; } // 36 + virtual void ClearUnusedMaterialValues() { return; } // 37 + virtual BSShaderProperty* ClarifyShader(BSGeometry*, bool, bool) { return nullptr; } // 38 + virtual NiTexture* GetBaseTexture() const { return nullptr; } // 39 + virtual RenderPassArray* GetWaterFogPassList(BSGeometry*) { return nullptr; } // 3A + virtual bool AcceptsEffectData() const { return false; } // 3B + virtual void PrecacheTextures() { return; } // 3C + virtual std::uint32_t DetermineUtilityShaderDecl() const { return 0; } // 3D + virtual std::uint32_t GetMaterialType() const { return 0; } // 3E + virtual void DoClearRenderPasses() { return; } // 3F + + void SetMaterial(BSShaderMaterial* a_material, bool a_unique) + { + using func_t = decltype(&BSShaderProperty::SetMaterial); + REL::Relocation func{ REL::ID(706318) }; + return func(this, a_material, a_unique); + } + + // members + float alpha; // 28 + std::int32_t lastRenderPassState; // 2C + stl::enumeration flags; // 30 + RenderPassArray renderPassList; // 38 + RenderPassArray debugRenderPassList; // 40 + BSFadeNode* fadeNode; // 48 + BSEffectShaderData* effectData; // 50 + BSShaderMaterial* material; // 58 + std::uint32_t lastAccumTime; // 60 + float lodFade; // 64 + BSNonReentrantSpinLock clearRenderPassesLock; // 68 + }; + static_assert(sizeof(BSShaderProperty) == 0x70); + + class __declspec(novtable) BSLightingShaderProperty : + public BSShaderProperty // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSLightingShaderProperty }; + static constexpr auto VTABLE{ VTABLE::BSLightingShaderProperty }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSLightingShaderProperty }; + + // members + NiColorA projectedUVParams; // 70 + NiColorA projectedUVColor; // 80 + BSShaderProperty::RenderPassArray depthMapRenderPassListA[3]; // 90 + BSRenderPass* depthRenderPass; // A8 + BSShaderProperty::RenderPassArray forwardPassList; // B0 + NiColor* emitColor; // B8 + BSFixedString rootName; // C0 + float emitColorScale; // C8 + float forcedDarkness; // CC + float specularLODFade; // D0 + float envmapLODFade; // D4 + std::uint32_t baseTechniqueID; // D8 + std::uint32_t clearCommandBufferCount; // DC + std::uint16_t debugTintIndex; // E0 + std::uint32_t stencilRef; // E4 + }; + static_assert(sizeof(BSLightingShaderProperty) == 0xE8); +} diff --git a/CommonLibF4/include/RE/Bethesda/BSTempEffect.h b/CommonLibF4/include/RE/Bethesda/BSTempEffect.h index 0e614037..d8a53f2b 100644 --- a/CommonLibF4/include/RE/Bethesda/BSTempEffect.h +++ b/CommonLibF4/include/RE/Bethesda/BSTempEffect.h @@ -1,15 +1,77 @@ #pragma once +#include "RE/Bethesda/BSAttachTechniques.h" +#include "RE/Bethesda/BSModelDB.h" +#include "RE/Bethesda/BSPointerHandle.h" +#include "RE/Bethesda/BSSoundHandle.h" +#include "RE/Bethesda/BSTArray.h" +#include "RE/Bethesda/BSTEvent.h" +#include "RE/Bethesda/BSTTuple.h" +#include "RE/Bethesda/BSTextureDB.h" +#include "RE/NetImmerse/NiMatrix3.h" #include "RE/NetImmerse/NiObject.h" -class BGSSaveGameBuffer; +#include "RE/NetImmerse/NiQuaternion.h" +#include "RE/NetImmerse/NiSmartPointer.h" -enum class TEMP_EFFECT_TYPE : std::uint32_t -{ - -}; +#define F4SE_TEMPEFFECT_UTIL(a_elem) \ + case a_elem::TYPE: \ + if constexpr (std::is_convertible_v) { \ + return static_cast(this); \ + } \ + break namespace RE { + class bhkWorld; + class BGSDecalEmitter; + class BGSImpactData; + class BGSLoadGameBuffer; + class BGSArtObjectCloneTask; + class BGSParticleObjectCloneTask; + class BGSSaveGameBuffer; + class BGSShaderParticleGeometryData; + class BSGeometry; + class BSTempEffectWeaponBlood; + class BSTempEffectScreenSpaceDecal; + class BSTempEffectGeometryDecal; + class BSTempEffectParticle; + class BSTempEffectDebris; + class BSTempEffectSPG; + class BSTerrainEffect; + class ModelReferenceEffect; + class NiAVObject; + class NiSourceTexture; + class ReferenceEffect; + class ReferenceEffectController; + class ShaderReferenceEffect; + class SummonPlacementEffect; + class TESObjectCELL; + class TESObjectREFR; + + namespace BSDeferredDecal + { + struct BSDFDecal; + } + + struct PositionPlayerEvent; + struct SkinnedDecalCSData; + + enum class TEMP_EFFECT_TYPE + { + kTerrain = 0, + kWeaponBlood = 1, + kDecal = 2, + kGeometryDecal = 3, + kParticle = 4, + kDebris = 5, + kSPG = 6, + kDefault = 7, + kRefDefault = 8, + kRefModel = 9, + kRefShader = 10, + kMagicSummon = 11 + }; + class __declspec(novtable) BSTempEffect : public NiObject // 00 { @@ -17,36 +79,398 @@ namespace RE static constexpr auto RTTI{ RTTI::BSTempEffect }; static constexpr auto VTABLE{ VTABLE::BSTempEffect }; static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kDefault }; + + // add + virtual void Initialize(); // 25 - { initialized = true; } + virtual void Attach(); // 26 - { return; } + virtual void Detach(); // 27 - { return; } + virtual bool Update(float a_arg1); // 28 + [[nodiscard]] virtual NiAVObject* Get3D() const; // 29 - { return 0; } + [[nodiscard]] virtual bool GetManagerHandlesSaveLoad() const; // 2A - { return true; } + [[nodiscard]] virtual bool GetClearWhenCellIsUnloaded() const; // 2B - { return true; } + [[nodiscard]] virtual TEMP_EFFECT_TYPE GetType() const; // 2C - { return 7; } + virtual void SaveGame(BGSSaveGameBuffer* a_buf); // 2D + virtual void LoadGame(BGSLoadGameBuffer* a_buf); // 2E + virtual void FinishLoadGame(BGSLoadGameBuffer* a_buf); // 2F - { return; } + [[nodiscard]] virtual bool IsInterfaceEffect() const; // 30 - { return false; } + virtual void SetInterfaceEffect(bool a_set); // 31 - { return; } + [[nodiscard]] virtual bool GetStackable() const; // 32 - { return false; } + virtual bool GetStackableMatch(BSTempEffect* a_effect) const; // 33 - { return false; } + virtual void Push(); // 34 - { return; } + virtual void Pop(); // 35 - { return; } + virtual void HandleDeferredDeleteImpl(); // 36 + + template < + class T, + class = std::enable_if_t< + std::negation_v< + std::disjunction< + std::is_pointer, + std::is_reference, + std::is_const, + std::is_volatile>>>> + [[nodiscard]] T* As() noexcept + { + return const_cast(static_cast(this)->As()); + } + + template < + class T, + class = std::enable_if_t< + std::negation_v< + std::disjunction< + std::is_pointer, + std::is_reference, + std::is_const, + std::is_volatile>>>> + [[nodiscard]] const T* As() const noexcept + { + switch (GetType()) { + F4SE_TEMPEFFECT_UTIL(BSTerrainEffect); + F4SE_TEMPEFFECT_UTIL(BSTempEffectWeaponBlood); + F4SE_TEMPEFFECT_UTIL(BSTempEffectScreenSpaceDecal); + F4SE_TEMPEFFECT_UTIL(BSTempEffectGeometryDecal); + F4SE_TEMPEFFECT_UTIL(BSTempEffectParticle); + F4SE_TEMPEFFECT_UTIL(BSTempEffectDebris); + F4SE_TEMPEFFECT_UTIL(BSTempEffectSPG); + F4SE_TEMPEFFECT_UTIL(BSTempEffect); + F4SE_TEMPEFFECT_UTIL(ReferenceEffect); + F4SE_TEMPEFFECT_UTIL(ModelReferenceEffect); + F4SE_TEMPEFFECT_UTIL(ShaderReferenceEffect); + F4SE_TEMPEFFECT_UTIL(SummonPlacementEffect); + default: + break; + } + + return nullptr; + } + + // members + float lifetime; // 10 + TESObjectCELL* cell; // 18 + float age; // 20 + bool initialized; // 24 + std::uint32_t effectID; // 28 + }; + static_assert(sizeof(BSTempEffect) == 0x30); + + class __declspec(novtable) BSTerrainEffect : + public BSTempEffect, // 00 + public BSTEventSink // 30 + { + public: + static constexpr auto RTTI{ RTTI::BSTerrainEffect }; + static constexpr auto VTABLE{ VTABLE::BSTerrainEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kTerrain }; + + struct BoneAdjustment + { + public: + // members + NiMatrix3 rotation; // 00 + NiAVObject* pBone; // 30 + float fZOffset; // 38 + }; + static_assert(sizeof(BoneAdjustment) == 0x40); + + ~BSTerrainEffect() override; + + // members + NiQuaternion orientation; // 38 + NiPoint3 position; // 48 + BSTArray terrainAdjustments; // 58 + BSTArray dynamicAdjustments; // 70 + NiPointer model; // 88 + BSResource::ID modelID; // 90 + ObjectRefHandle target; // 9C + NiPointer physWorld; // A0 + std::uint32_t physGroup; // A8 + NiPointer followNode; // B0 + }; + static_assert(sizeof(BSTerrainEffect) == 0xB8); + + class __declspec(novtable) BSTempEffectWeaponBlood : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSTempEffectWeaponBlood }; + static constexpr auto VTABLE{ VTABLE::BSTempEffectWeaponBlood }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kWeaponBlood }; + + ~BSTempEffectWeaponBlood() override; + + // members + NiPointer weapon; // 30 + float fBloodAmount; // 38 + }; + static_assert(sizeof(BSTempEffectWeaponBlood) == 0x40); + + class __declspec(novtable) BSTempEffectScreenSpaceDecal : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::__BSTempEffectScreenSpaceDecal }; + static constexpr auto VTABLE{ VTABLE::__BSTempEffectScreenSpaceDecal }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectScreenSpaceDecal }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kDecal }; + + ~BSTempEffectScreenSpaceDecal() override; + + // members + bool permanent; // 30 + NiPointer decal; // 38 + }; + static_assert(sizeof(BSTempEffectScreenSpaceDecal) == 0x40); + + class __declspec(novtable) BSTempEffectGeometryDecal : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSTempEffectGeometryDecal }; + static constexpr auto VTABLE{ VTABLE::BSTempEffectGeometryDecal }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectGeometryDecal }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kGeometryDecal }; + + ~BSTempEffectGeometryDecal() override; + + // members + SkinnedDecalCSData* CSData; // 30 + TextureDBHandle baseTexture; // 38 + NiPointer decalGeometry; // 40 + NiPointer geometry; // 48 + std::uint16_t* oldIndex; // 50 + NiPointer parent; // 58 + NiPointer decalParent; // 68 + alignas(0x10) NiMatrix3 projection; // 70 + NiPoint3 origin; // A0 + NiPoint3 vector; // AC + float scale; // B8 + std::int32_t numVerts; // BC + std::uint32_t bodyParts; // C0 + float decalRotation; // C4 + std::uint8_t subTex; // C8 + bool decalLoaded; // C9 + bool fading; // CA + }; + static_assert(sizeof(BSTempEffectGeometryDecal) == 0xD0); + + class __declspec(novtable) BSTempEffectParticle : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSTempEffectParticle }; + static constexpr auto VTABLE{ VTABLE::BSTempEffectParticle }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectParticle }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kParticle }; + + ~BSTempEffectParticle() override; + + // members + NiPointer particleObject; // 30 + NiPointer cloneTask; // 38 + ModelDBHandle modelHandle; // 40 + NiPointer parentNode; // 48 + NiMatrix3 rotation; // 50 + NiPoint3 position; // 80 + float scale; // 8C + std::uint32_t flags; // 90 + NiPointer followObject; // 98 + NiTransform followOffset; // A0 + BGSImpactData* decalImpactData; // E0 + BGSDecalEmitter* decalEmitter; // E8 + BSSoundHandle sound1; // F0 + BSSoundHandle sound2; // F8 + }; + static_assert(sizeof(BSTempEffectParticle) == 0x100); + + class __declspec(novtable) BSTempEffectDebris : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSTempEffectDebris }; + static constexpr auto VTABLE{ VTABLE::BSTempEffectDebris }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectDebris }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kDebris }; + + BSTempEffectDebris( + TESObjectCELL* a_parentCell, + float a_lifetime, + const char* a_fileName, + TESObjectREFR* a_sourceRef, + const NiPoint3& a_position, + const NiMatrix3& a_rotation, + const NiPoint3& a_startLinearVelocity, + const NiPoint3& a_startAngularVelocity, + float a_scale, + bool a_useCache, + bool a_addDebrisCount, + bool isFirstPerson) + { + using func_t = BSTempEffectDebris* (*)(BSTempEffectDebris*, TESObjectCELL*, float, const char*, TESObjectREFR*, const NiPoint3&, const NiMatrix3&, const NiPoint3&, const NiPoint3&, float, bool, bool, bool); + REL::Relocation func{ REL::ID(1075623) }; + func(this, a_parentCell, a_lifetime, a_fileName, a_sourceRef, a_position, a_rotation, a_startLinearVelocity, a_startAngularVelocity, a_scale, a_useCache, a_addDebrisCount, isFirstPerson); + } + + ~BSTempEffectDebris() override; + + // members + NiPointer debris3D; // 30 + const char* debrisFilename; // 38 + bool useDebrisCounter; // 40 + bool forceDelete; // 41 + bool firstPerson; // 42 + }; + static_assert(sizeof(BSTempEffectDebris) == 0x48); + + class __declspec(novtable) BSTempEffectSPG : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSTempEffectSPG }; + static constexpr auto VTABLE{ VTABLE::BSTempEffectSPG }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectSPG }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kSPG }; + + ~BSTempEffectSPG() override; + + // members + BGSShaderParticleGeometryData* SPGData; // 30 + NiPointer geometry; // 38 + float totalFadeTime; // 40 + float fadeTime; // 44 + bool fadeIn; // 48 + }; + static_assert(sizeof(BSTempEffectSPG) == 0x50); + + class __declspec(novtable) ReferenceEffect : + public BSTempEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::ReferenceEffect }; + static constexpr auto VTABLE{ VTABLE::ReferenceEffect }; + static constexpr auto Ni_RTTI{ Ni_RTTI::ReferenceEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kRefDefault }; + + ~ReferenceEffect() override; // add - virtual void Initialize() { return; }; - virtual void Attach() { return; }; - virtual void Detach() { return; }; - virtual bool Update(float) { return false; }; - virtual NiAVObject* Get3D() { return nullptr; }; - virtual bool GetManagerHandlesSaveLoad() { return false; }; - virtual bool GetClearWhenCellIsUnloaded() { return false; }; - virtual TEMP_EFFECT_TYPE GetType() { return (TEMP_EFFECT_TYPE)7; }; - virtual void SaveGame(BGSSaveGameBuffer*) { return; }; - virtual void LoadGame(BGSLoadGameBuffer*) { return; }; - virtual void FinishLoadGame(BGSLoadGameBuffer*) { return; }; - virtual bool IsInterfaceEffect() { return false; }; - virtual void SetInterfaceEffect() { return; }; - virtual bool GetStackable() { return false; }; - virtual bool GetStackableMatch(BSTempEffect*) { return false; }; - virtual void Push() { return; }; - virtual void Pop() { return; }; - virtual void HandleDeferredDeleteImpl() { return; }; - - // members - std::uint32_t unk10; - std::uint32_t pad14; - std::uint64_t unk18; - std::uint32_t unk20; - bool active; - std::uint32_t unk28; - std::uint64_t unk30; - std::uint64_t unk38; - }; - static_assert(sizeof(BSTempEffect) == 0x40); + virtual bool Init(); // 37 + virtual void Suspend(); // 38 + virtual void Resume(); // 39 + virtual void Update3D(); // 3A + virtual void ClearTarget(); // 3B + virtual void UpdateParentCell(NiAVObject* a_root); // 3C + virtual void UpdatePosition(); // 3D + virtual NiAVObject* GetAttachRoot(); // 3E + virtual bool GetAttached(); // 3F + virtual void DetachImpl(); // 40 + + // members + ReferenceEffectController* controller; // 30 + ObjectRefHandle target; // 38 + ObjectRefHandle aimAtTarget; // 3C + bool finished; // 40 + bool ownController; // 41 + }; + static_assert(sizeof(ReferenceEffect) == 0x48); + + class __declspec(novtable) ModelReferenceEffect : + public ReferenceEffect, // 00 + public SimpleAnimationGraphManagerHolder, // 48 + public BSTEventSink // 60 + { + public: + static constexpr auto RTTI{ RTTI::ModelReferenceEffect }; + static constexpr auto VTABLE{ VTABLE::ModelReferenceEffect }; + static constexpr auto Ni_RTTI{ Ni_RTTI::ModelReferenceEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kRefModel }; + + ~ModelReferenceEffect() override; + + // members + RefAttachTechniqueInput hitEffectArtData; // 70 + void* loadedDataSubBuffer; // B8 + BGSArtObject* artObject; // C0 + NiPointer cloneTask; // C8 + NiPointer artObject3D; // D0 + std::uint32_t flags; // D4 + }; + static_assert(sizeof(ModelReferenceEffect) == 0xD8); + + class BSMagicShaderParticles + { + public: + using Filter = bool(NiAVObject*); + + // members + ModelDBHandle protoSystem; // 00 + NiPointer particlesRoot; // 08 + bool hasData; // 10 + bool attached; // 11 + bool stopped; // 12 + bool useSizeAdjustments; // 13 + Filter* filterFunction; // 18 + }; + static_assert(sizeof(BSMagicShaderParticles) == 0x20); + + class __declspec(novtable) ShaderReferenceEffect : + public ReferenceEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::ShaderReferenceEffect }; + static constexpr auto VTABLE{ VTABLE::ShaderReferenceEffect }; + static constexpr auto Ni_RTTI{ Ni_RTTI::ShaderReferenceEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kRefShader }; + + ~ShaderReferenceEffect() override; + + // members + BSMagicShaderParticles particles; // 048 + BSTArray*>> textureRequests; // 068 + BSTArray> addOnObjects; // 080 + BSTArray modelHandles; // 098 + BSTArray> targetArray; // 0B0 + BSSoundHandle soundHandle; // 0C8 + NiPointer textureShaderTexture; // 0D0 + NiPointer textureBlockOutTexture; // 0D8 + NiPointer texturePaletteTexture; // 0E0 + TESBoundObject* wornObject; // 0E8 + TESEffectShader* effectData; // 0F0 + BSEffectShaderData* effectShaderData; // 0F8 + NiPointer lastRootNode; // 100 + float alphaTimer; // 104 + float addonAlpha; // 108 + float addonScale; // 10C + float effectShaderAge; // 110 + std::uint32_t flags; // 114 + std::uint32_t pushCount; // 118 + }; + static_assert(sizeof(ShaderReferenceEffect) == 0x120); + + class __declspec(novtable) SummonPlacementEffect : + public ReferenceEffect, // 00 + public SimpleAnimationGraphManagerHolder, // 48 + public BSTEventSink // 60 + { + public: + static constexpr auto RTTI{ RTTI::SummonPlacementEffect }; + static constexpr auto VTABLE{ VTABLE::SummonPlacementEffect }; + static constexpr auto Ni_RTTI{ Ni_RTTI::SummonPlacementEffect }; + static constexpr auto TYPE{ TEMP_EFFECT_TYPE::kMagicSummon }; + + ~SummonPlacementEffect() override; + + // members + BGSArtObject* artObject; // 70 + NiPoint3 fixedLocation; // 78 + NiPointer artObject3D; // 88 + void* loadedDataSubBuffer; // 90 + NiPointer cloneTask; // 98 + bool animationComplete; // 99 + }; + static_assert(sizeof(SummonPlacementEffect) == 0xA0); } + +#undef F4SE_TEMPEFFECT_UTIL diff --git a/CommonLibF4/include/RE/Bethesda/BSTempEffectDebris.h b/CommonLibF4/include/RE/Bethesda/BSTempEffectDebris.h deleted file mode 100644 index 61f2b6e8..00000000 --- a/CommonLibF4/include/RE/Bethesda/BSTempEffectDebris.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "RE/Bethesda/BSTempEffect.h" -#include "RE/NetImmerse/NiMatrix3.h" - -namespace RE -{ - class __declspec(novtable) BSTempEffectDebris : - public BSTempEffect // 00 - { - public: - static constexpr auto RTTI{ RTTI::BSTempEffectDebris }; - static constexpr auto VTABLE{ VTABLE::BSTempEffectDebris }; - static constexpr auto Ni_RTTI{ Ni_RTTI::BSTempEffectDebris }; - - //unk0 = 1.0, unk1 = false, unk2 = true - BSTempEffectDebris(TESObjectCELL* parentCell, float lifetime, const char* modelPath, TESObjectREFR* target, const NiPoint3& pos, const NiMatrix3& rot, const NiPoint3& vel, const NiPoint3& angVel, float unk0, bool unk1, bool unk2, bool isFirstPerson) - { - typedef BSTempEffectDebris* func_t(BSTempEffectDebris*, TESObjectCELL*, float, const char*, TESObjectREFR*, const NiPoint3&, const NiMatrix3&, const NiPoint3&, const NiPoint3&, float, bool, bool, bool); - REL::Relocation func{ REL::ID(1075623) }; - func(this, parentCell, lifetime, modelPath, target, pos, rot, vel, angVel, unk0, unk1, unk2, isFirstPerson); - } - - // members - std::uint64_t unk40; - }; - static_assert(sizeof(BSTempEffectDebris) == 0x48); -} diff --git a/CommonLibF4/include/RE/Bethesda/BSTextureDB.h b/CommonLibF4/include/RE/Bethesda/BSTextureDB.h new file mode 100644 index 00000000..5fed3627 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSTextureDB.h @@ -0,0 +1,40 @@ +#pragma once + +#include "RE/Bethesda/BSResource.h" +#include "RE/NetImmerse/NiSmartPointer.h" +#include "RE/NetImmerse/NiTexture.h" + +namespace RE +{ + struct BSTextureDB + { + public: + struct DBTraits + { + public: + using U_Type = NiPointer; + + struct ArgsType + { + public: + // members + std::uint32_t loadLevel; // 00 + bool isCubeMap; // 04 + bool replicateCubeMap; // 05 + bool isDDX; // 06 + bool isSRGB; // 07 + bool allowDegrade; // 08 + }; + static_assert(sizeof(ArgsType) == 0x0C); + + static BSResource::EntryDB* GetSingleton() + { + REL::Relocation**> singleton{ REL::ID(1126862) }; + return *singleton; + } + }; + static_assert(std::is_empty_v); + }; + + using TextureDBHandle = BSResource::RHandleType, BSResource::EntryDBTraits>::CArgs>, BSResource::EntryDB>; +} diff --git a/CommonLibF4/include/RE/Bethesda/BSTextureSet.h b/CommonLibF4/include/RE/Bethesda/BSTextureSet.h index 382bc16d..9647194d 100644 --- a/CommonLibF4/include/RE/Bethesda/BSTextureSet.h +++ b/CommonLibF4/include/RE/Bethesda/BSTextureSet.h @@ -1,78 +1,14 @@ #pragma once -#include "RE/Bethesda/BSLock.h" +#include "RE/Bethesda/BSFixedString.h" +#include "RE/Bethesda/BSShaderProperty.h" #include "RE/NetImmerse/NiObject.h" -#include "RE/NetImmerse/NiShadeProperty.h" #include "RE/NetImmerse/NiSmartPointer.h" namespace RE { - class BSEffectShaderData; - class BSRenderPass; - class BSShaderAccumulator; - class BSShaderMaterial; class NiTexture; - struct __declspec(novtable) BSShaderProperty : - public NiShadeProperty // 00 - { - public: - static constexpr auto RTTI{ RTTI::BSShaderProperty }; - static constexpr auto VTABLE{ VTABLE::BSShaderProperty }; - static constexpr auto Ni_RTTI{ Ni_RTTI::BSShaderProperty }; - - enum class TextureTypeEnum; - - class ForEachVisitor; - - class RenderPassArray - { - public: - constexpr RenderPassArray() noexcept {} // NOLINT(modernize-use-equals-default) - - // members - BSRenderPass* passList{ nullptr }; // 0 - }; - static_assert(sizeof(RenderPassArray) == 0x8); - - // add - virtual RenderPassArray* GetRenderPasses(BSGeometry* a_geom, std::uint32_t a_renderMode, BSShaderAccumulator* a_accumulator) = 0; // 2B - virtual RenderPassArray* GetRenderPasses_ShadowMapOrMask(BSGeometry*, std::uint32_t, BSShaderAccumulator*) { return nullptr; } // 2C - virtual RenderPassArray* GetRenderPasses_LocalMap(BSGeometry*, std::uint32_t, BSShaderAccumulator*) { return nullptr; } // 2D - virtual BSRenderPass* CreateVatsMaskRenderPass(BSGeometry*) { return nullptr; } // 2E - virtual std::uint16_t GetNumberofPasses([[maybe_unused]] BSGeometry* a_geom) { return 1; } // 2F - virtual BSRenderPass* GetRenderDepthPass(BSGeometry*) { return nullptr; } // 30 - virtual bool CanMerge(const BSShaderProperty* a_prop); // 31 - virtual void SetMaterialAlpha(float) { return; } // 32 - virtual float QMaterialAlpha() const { return 1.0F; } // 33 - virtual const BSFixedString& GetRootName() const; // 34 - virtual std::int32_t ForEachTexture(ForEachVisitor&) { return 1; } // 35 - virtual std::int32_t QShader() const { return 0; } // 36 - virtual void ClearUnusedMaterialValues() { return; } // 37 - virtual BSShaderProperty* ClarifyShader(BSGeometry*, bool, bool) { return nullptr; } // 38 - virtual NiTexture* GetBaseTexture() const { return nullptr; } // 39 - virtual RenderPassArray* GetWaterFogPassList(BSGeometry*) { return nullptr; } // 3A - virtual bool AcceptsEffectData() const { return false; } // 3B - virtual void PrecacheTextures() { return; } // 3C - virtual std::uint32_t DetermineUtilityShaderDecl() const { return 0; } // 3D - virtual std::uint32_t GetMaterialType() const { return 0; } // 3E - virtual void DoClearRenderPasses() { return; } // 3F - - // members - float alpha; // 28 - std::int32_t lastRenderPassState; // 2C - std::uint64_t flags; // 30 - RenderPassArray renderPassList; // 38 - RenderPassArray debugRenderPassList; // 40 - BSFadeNode* fadeNode; // 48 - BSEffectShaderData* effectData; // 50 - BSShaderMaterial* material; // 58 - std::uint32_t lastAccumTime; // 60 - float lodFade; // 64 - BSNonReentrantSpinLock clearRenderPassesLock; // 68 - }; - static_assert(sizeof(BSShaderProperty) == 0x70); - class __declspec(novtable) BSTextureSet : public NiObject // 00 { @@ -89,4 +25,24 @@ namespace RE virtual void SetTextureFilename(BSShaderProperty::TextureTypeEnum a_type, const char* a_filename) = 0; // 2C }; static_assert(sizeof(BSTextureSet) == 0x10); + + class __declspec(novtable) BSShaderTextureSet : + public BSTextureSet // 00 + { + public: + static constexpr auto RTTI{ RTTI::BSShaderTextureSet }; + static constexpr auto VTABLE{ VTABLE::BSShaderTextureSet }; + static constexpr auto Ni_RTTI{ Ni_RTTI::BSShaderTextureSet }; + + static BSShaderTextureSet* CreateObject() + { + using func_t = decltype(&BSShaderTextureSet::CreateObject); + REL::Relocation func{ REL::ID(993063) }; + return func(); + } + + // members + BSFixedString textureNames[10]; // 10 + }; + static_assert(sizeof(BSShaderTextureSet) == 0x60); } diff --git a/CommonLibF4/include/RE/Bethesda/BSTimer.h b/CommonLibF4/include/RE/Bethesda/BSTimer.h index c5ea62c8..ba64fc32 100644 --- a/CommonLibF4/include/RE/Bethesda/BSTimer.h +++ b/CommonLibF4/include/RE/Bethesda/BSTimer.h @@ -5,6 +5,31 @@ namespace RE class BSTimer { public: + [[nodiscard]] static BSTimer GetSingleton() + { + REL::Relocation singleton{ REL::ID(1256126) }; + return *singleton; + } + + static float QGlobalTimeMultiplier() + { + REL::Relocation value{ REL::ID(365546) }; + return *value; + } + + static float QGlobalTimeMultiplierTarget() + { + REL::Relocation value{ REL::ID(1266509) }; + return *value; + } + + void SetGlobalTimeMultiplier(float a_mult, bool a_now) + { + using func_t = decltype(&BSTimer::SetGlobalTimeMultiplier); + REL::Relocation func{ REL::ID(1419977) }; + return func(this, a_mult, a_now); + } + // members std::int64_t highPrecisionInitTime; // 00 float clamp; // 08 diff --git a/CommonLibF4/include/RE/Bethesda/BSVisit.h b/CommonLibF4/include/RE/Bethesda/BSVisit.h new file mode 100644 index 00000000..65576116 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSVisit.h @@ -0,0 +1,20 @@ +#pragma once + +namespace RE +{ + class bhkNiCollisionObject; + class BSGeometry; + class NiAVObject; + + namespace BSVisit + { + enum class BSVisitControl + { + kContinue = 0, + kStop = 1 + }; + + BSVisitControl TraverseScenegraphGeometries(NiAVObject* a_object, std::function a_func); + BSVisitControl TraverseScenegraphObjects(NiAVObject* a_object, std::function a_func); + } +} diff --git a/CommonLibF4/include/RE/Bethesda/ControlMap.h b/CommonLibF4/include/RE/Bethesda/ControlMap.h index fb0bdfc4..000273d1 100644 --- a/CommonLibF4/include/RE/Bethesda/ControlMap.h +++ b/CommonLibF4/include/RE/Bethesda/ControlMap.h @@ -73,11 +73,11 @@ namespace RE return func(this, a_context); } - bool RemapButton(BSFixedString const& id, INPUT_DEVICE device, int32_t key) + bool RemapButton(BSFixedString const& a_id, INPUT_DEVICE a_device, std::int32_t a_buttonID) { using func_t = decltype(&ControlMap::RemapButton); REL::Relocation func{ REL::ID(11351) }; - return func(this, id, device, key); + return func(this, a_id, a_device, a_buttonID); } void SaveRemappings() diff --git a/CommonLibF4/include/RE/Bethesda/Events.h b/CommonLibF4/include/RE/Bethesda/Events.h index 62da8e09..533f608a 100644 --- a/CommonLibF4/include/RE/Bethesda/Events.h +++ b/CommonLibF4/include/RE/Bethesda/Events.h @@ -17,9 +17,73 @@ namespace RE class HUDModeType; class TESObjectCELL; class TESObjectREFR; + class VATSCommand; struct InventoryUserUIInterfaceEntry; + enum class QuickContainerMode : std::int32_t + { + kLoot, + kTeammate, + kPowerArmor, + kTurret, + kWorkshop, + kCrafting, + kStealing, + kStealingPowerArmor + }; + + namespace ActorEquipManagerEvent + { + enum class Type + { + Equip = 0, + Unequip, + }; + + struct Event + { + // members + stl::enumeration changeType; // 00 + const BGSObjectInstance* itemAffected; // 08 + Actor* actorAffected; // 10 + std::uint32_t stackID; // 18 + }; + static_assert(sizeof(Event) == 0x20); + } + + struct BGSActorEvent + { + public: + // member + ActorHandle actor; // 00 + }; + static_assert(sizeof(BGSActorEvent) == 0x4); + + struct BGSActorCellEvent : public BGSActorEvent + { + public: + enum class CellFlag + { + kEnter = 0, + kLeave = 1 + }; + + // members + std::uint32_t cellID; // 04 + stl::enumeration flags; // 08 + }; + static_assert(sizeof(BGSActorCellEvent) == 0xC); + + struct BGSActorDeathEvent : public BGSActorEvent + { + public: + // members + ActorHandle attacker; // 04 + float damage; // 08 + }; + static_assert(sizeof(BGSActorDeathEvent) == 0xC); + struct BSThreadEvent { public: @@ -38,17 +102,20 @@ namespace RE }; static_assert(std::is_empty_v); - enum class QuickContainerMode : std::int32_t + struct BSTransformDeltaEvent { - kLoot, - kTeammate, - kPowerArmor, - kTurret, - kWorkshop, - kCrafting, - kStealing, - kStealingPowerArmor + public: + // members + NiMatrix3 deltaRotation; + NiPoint4 deltaTranslation; + NiPoint4 previousTranslation; + NiPoint4 previousRotation; + NiPoint4 previousScale; + NiPoint4 currentTranslation; + NiPoint4 currentRotation; + NiPoint4 currentScale; }; + static_assert(sizeof(BSTransformDeltaEvent) == 0xA0); struct ApplyColorUpdateEvent { @@ -106,6 +173,25 @@ namespace RE }; static_assert(sizeof(CellAttachDetachEvent) == 0x10); + namespace CellAttachDetachEventSource + { + struct CellAttachDetachEventSourceSingleton : + public BSTSingletonImplicit + { + public: + [[nodiscard]] static CellAttachDetachEventSourceSingleton& GetSingleton() + { + using func_t = decltype(&CellAttachDetachEventSourceSingleton::GetSingleton); + REL::Relocation func{ REL::ID(862142) }; + return func(); + } + + // members + BSTEventSource source; // 00 + }; + static_assert(sizeof(CellAttachDetachEventSourceSingleton) == 0x58); + } + class CurrentRadiationSourceCount : public BSTValueEvent { @@ -481,6 +567,25 @@ namespace RE }; static_assert(sizeof(TESDeathEvent) == 0x18); + struct TESEquipEvent + { + public: + [[nodiscard]] static BSTEventSource* GetEventSource() + { + using func_t = decltype(&TESEquipEvent::GetEventSource); + REL::Relocation func{ REL::ID(1251703) }; + return func(); + } + + // members + NiPointer actor; // 00 + std::uint32_t baseObject; // 08 + std::uint32_t originalRefr; // 0C + std::uint16_t uniqueID; // 10 + bool equipped; // 12 + }; + static_assert(sizeof(TESEquipEvent) == 0x18); + struct TESFurnitureEvent { public: @@ -504,9 +609,108 @@ namespace RE }; static_assert(sizeof(TESFurnitureEvent) == 0x18); + struct DamageImpactData + { + public: + // members + NiPoint3A location; // 00 + NiPoint3A normal; // 10 + NiPoint3A velocity; // 20 + NiPointer colObj; // 30 + }; + static_assert(sizeof(DamageImpactData) == 0x40); + + class HitData + { + public: + enum class Flag + { + kBlocked = 1 << 0, + kBlockWithWeapon = 1 << 1, + kBlockCandidate = 1 << 2, + kCritical = 1 << 3, + kCriticalOnDeath = 1 << 4, + kFatal = 1 << 5, + kDismemberLimb = 1 << 6, + kExplodeLimb = 1 << 7, + kCrippleLimb = 1 << 8, + kDisarm = 1 << 9, + kDisableWeapon = 1 << 10, + kSneakAttack = 1 << 11, + kIgnoreCritical = 1 << 12, + kPredictDamage = 1 << 13, + kPredictBaseDamage = 1 << 14, + kBash = 1 << 15, + kTimedBash = 1 << 16, + kPowerAttack = 1 << 17, + kMeleeAttack = 1 << 18, + kRicochet = 1 << 19, + kExplosion = 1 << 20 + }; + + // members + DamageImpactData impactData; // 00 + ActorHandle aggressor; // 40 + ActorHandle target; // 44 + ObjectRefHandle sourceRef; // 48 + NiPointer attackData; // 50 + BGSObjectInstanceT weapon; // 58 + SpellItem* criticalEffect; // 68 + SpellItem* hitEffect; // 70 + BSTSmartPointer VATSCommand; // 78 + const TESAmmo* ammo; // 80 + BSTArray>* damageTypes; // 88 + float healthDamage; // 90 + float totalDamage; // 94 + float physicalDamage; // 98 + float targetedLimbDamage; // 9C + float percentBlocked; // A0 + float resistedPhysicalDamage; // A4 + float resistedTypedDamage; // A8 + stl::enumeration stagger; // AC + float sneakAttackBonus; // B0 + float bonusHealthDamageMult; // B4 + float pushBack; // B8 + float reflectedDamage; // BC + float criticalDamageMult; // C0 + stl::enumeration flags; // C4 + BGSEquipIndex equipIndex; // C8 + std::uint32_t material; // D0 + stl::enumeration damageLimb; // D4 + }; + static_assert(sizeof(HitData) == 0xE0); + + class TESHitEvent + { + public: + [[nodiscard]] static BSTEventSource* GetEventSource() + { + using func_t = decltype(&TESHitEvent::GetEventSource); + REL::Relocation func{ REL::ID(1411899) }; + return func(); + } + + // members + HitData hitData; // 000 + NiPointer target; // 0E0 + NiPointer cause; // 0E8 + BSFixedString material; // 0F0 + std::uint32_t sourceFormID; // 0F8 + std::uint32_t projectileFormID; // 0FC + bool usesHitData; // 100 + }; + static_assert(sizeof(TESHitEvent) == 0x110); + struct TESMagicEffectApplyEvent { public: + [[nodiscard]] static BSTEventSource* GetEventSource() + { + using func_t = decltype(&TESMagicEffectApplyEvent::GetEventSource); + REL::Relocation func{ REL::ID(1327824) }; + return func(); + } + // members NiPointer target; // 00 NiPointer caster; // 08 @@ -514,6 +718,22 @@ namespace RE }; static_assert(sizeof(TESMagicEffectApplyEvent) == 0x18); + struct TESObjectLoadedEvent + { + public: + [[nodiscard]] static BSTEventSource* GetEventSource() + { + using func_t = decltype(&TESObjectLoadedEvent::GetEventSource); + REL::Relocation func{ REL::ID(609604) }; + return func(); + } + + // members + std::uint32_t formId; // 00 + bool loaded; // 04 + }; + static_assert(sizeof(TESObjectLoadedEvent) == 0x8); + class TutorialEvent { public: @@ -549,161 +769,4 @@ namespace RE stl::enumeration senderID; // 8 }; static_assert(sizeof(UserEventEnabledEvent) == 0xC); - - namespace CellAttachDetachEventSource - { - struct CellAttachDetachEventSourceSingleton : - public BSTSingletonImplicit - { - public: - [[nodiscard]] static CellAttachDetachEventSourceSingleton& GetSingleton() - { - using func_t = decltype(&CellAttachDetachEventSourceSingleton::GetSingleton); - REL::Relocation func{ REL::ID(862142) }; - return func(); - } - - // members - BSTEventSource source; // 00 - }; - static_assert(sizeof(CellAttachDetachEventSourceSingleton) == 0x58); - } - - struct TESObjectLoadedEvent - { - uint32_t formId; //00 - uint8_t loaded; //08 - }; - - struct TESEquipEvent - { - Actor* a; - uint32_t formId; - uint32_t refFormID; - uint16_t unk10; - bool isEquip; - }; - - struct BSTransformDeltaEvent - { - NiMatrix3 deltaRotation; - NiPoint4 deltaTranslation; - NiPoint4 previousTranslation; - NiPoint4 previousRotation; - NiPoint4 previousScale; - NiPoint4 currentTranslation; - NiPoint4 currentRotation; - NiPoint4 currentScale; - }; - - struct DamageImpactData - { - NiPoint4 hitPos; - NiPoint4 hitDirection; - NiPoint4 projectileDir; - bhkNPCollisionObject* collisionObj; - }; - static_assert(sizeof(DamageImpactData) == 0x38); - - class VATSCommand; - class HitData - { - public: - void SetAllDamageToZero() - { - flags &= 0xFFFFFE07; - calculatedBaseDamage = 0.f; - blockedDamage = 0.f; - reducedDamage = 0.f; - blockStaggerMult = 0.f; - } - - DamageImpactData impactData; - int8_t gap38[8]; - ObjectRefHandle attackerHandle; - ObjectRefHandle victimHandle; - ObjectRefHandle sourceHandle; - int8_t gap4C[4]; - BGSAttackData* attackData; - BGSObjectInstance source; - MagicItem* effect; - SpellItem* spellItem; - VATSCommand* VATScmd; - TESAmmo* ammo; - BSTArray>* damageTypes; - float calculatedBaseDamage; - float baseDamage; - float totalDamage; - float blockedDamage; - float blockMult; - float reducedDamage; - float field_A8; - float blockStaggerMult; - float sneakAttackMult; - float field_B4; - float field_B8; - float field_BC; - float criticalDamageMult; - uint32_t flags; - BGSEquipIndex equipIndex; - uint32_t materialType; - int32_t bodypartType; - int8_t gapD4[4]; - }; - static_assert(sizeof(HitData) == 0xD8); - - class TESHitEvent - { - public: - HitData hitdata; - int8_t gapD8[8]; - TESObjectREFR* victim; - TESObjectREFR* attacker; - BSFixedString matName; - uint32_t sourceFormID; - uint32_t projFormID; - bool hasHitData; - int8_t gapD1[7]; - }; - static_assert(sizeof(TESHitEvent) == 0x108); - - class HitEventSource : public BSTEventSource - { - public: - [[nodiscard]] static HitEventSource* GetSingleton() - { - REL::Relocation singleton{ REL::ID(989868) }; - return singleton.get(); - } - }; - - class ObjectLoadedEventSource : public BSTEventSource - { - public: - [[nodiscard]] static ObjectLoadedEventSource* GetSingleton() - { - REL::Relocation singleton{ REL::ID(416662) }; - return singleton.get(); - } - }; - - class EquipEventSource : public BSTEventSource - { - public: - [[nodiscard]] static EquipEventSource* GetSingleton() - { - REL::Relocation singleton{ REL::ID(485633) }; - return singleton.get(); - } - }; - - class MGEFApplyEventSource : public BSTEventSource - { - public: - [[nodiscard]] static MGEFApplyEventSource* GetSingleton() - { - REL::Relocation singleton{ REL::ID(1481228) }; - return singleton.get(); - } - }; } diff --git a/CommonLibF4/include/RE/Bethesda/FormComponents.h b/CommonLibF4/include/RE/Bethesda/FormComponents.h index 74a9432e..34411e62 100644 --- a/CommonLibF4/include/RE/Bethesda/FormComponents.h +++ b/CommonLibF4/include/RE/Bethesda/FormComponents.h @@ -69,12 +69,6 @@ namespace RE class Items; } - enum class ACTOR_VALUE_MODIFIER - { - Perm, - Temp, - Damage - }; enum class ENUM_FORM_ID; enum class IO_TASK_PRIORITY; @@ -147,6 +141,13 @@ namespace RE static_assert(sizeof(SharedVal) == 0x4); } + enum class ACTOR_VALUE_MODIFIER + { + kPermanent, + kTemporary, + kDamage + }; + class __declspec(novtable) ActorValueOwner { public: @@ -586,7 +587,7 @@ namespace RE namespace detail { [[nodiscard]] BGSKeyword* BGSKeywordGetTypedKeywordByIndex(KeywordType a_type, std::uint16_t a_index); - [[nodiscard]] uint16_t BGSKeywordGetIndexForTypedKeyword(BGSKeyword* a_keyword, KeywordType a_type); + [[nodiscard]] std::uint16_t BGSKeywordGetIndexForTypedKeyword(BGSKeyword* a_keyword, KeywordType a_type); } template @@ -641,11 +642,11 @@ namespace RE void CopyComponent(BaseFormComponent*) override { return; } // 06 void CopyComponent(BaseFormComponent*, TESForm*) override; // 05 - void SetParentGroupNumber(BGSKeyword* keyword, uint32_t i) + void SetParentGroupNumber(BGSKeyword* a_parent, std::uint32_t a_groupID) { using func_t = decltype(&BGSAttachParentArray::SetParentGroupNumber); REL::Relocation func{ REL::ID(1412266) }; - return func(this, keyword, i); + return func(this, a_parent, a_groupID); } }; static_assert(sizeof(BGSAttachParentArray) == 0x18); @@ -933,11 +934,11 @@ namespace RE [[nodiscard]] std::uint32_t GetNumKeywords() const { return numKeywords; }; - void RemoveKeyword(BGSKeyword* kwd) + void RemoveKeyword(BGSKeyword* a_keyword) { using func_t = decltype(&BGSKeywordForm::RemoveKeyword); REL::Relocation func{ REL::ID(921694) }; - return func(this, kwd); + return func(this, a_keyword); } // members @@ -1657,7 +1658,7 @@ namespace RE virtual const char* GetOverrideName() { return nullptr; } // 0A virtual bool GetCanContainFormsOfType(ENUM_FORM_ID a_type) const = 0; // 0B - LEVELED_OBJECT* AddLeveledObject(uint16_t a_level, uint16_t a_count, int8_t a_chanceNone, TESForm* a_item, ContainerItemExtra* a_itemExtra) + LEVELED_OBJECT* AddLeveledObject(std::uint16_t a_level, uint16_t a_count, int8_t a_chanceNone, TESForm* a_item, ContainerItemExtra* a_itemExtra) { using func_t = decltype(&TESLeveledList::AddLeveledObject); REL::Relocation func{ REL::ID(1163308) }; diff --git a/CommonLibF4/include/RE/Bethesda/IMenu.h b/CommonLibF4/include/RE/Bethesda/IMenu.h index d1e2882e..704341f3 100644 --- a/CommonLibF4/include/RE/Bethesda/IMenu.h +++ b/CommonLibF4/include/RE/Bethesda/IMenu.h @@ -6,7 +6,9 @@ #include "RE/Bethesda/BGSInventoryItem.h" #include "RE/Bethesda/BSFixedString.h" #include "RE/Bethesda/BSInputEventUser.h" +#include "RE/Bethesda/BSModelDB.h" #include "RE/Bethesda/BSPointerHandle.h" +#include "RE/Bethesda/BSResource.h" #include "RE/Bethesda/BSSoundHandle.h" #include "RE/Bethesda/BSStorage.h" #include "RE/Bethesda/BSTArray.h" @@ -18,6 +20,7 @@ #include "RE/Bethesda/BSTSmartPointer.h" #include "RE/Bethesda/BSTTuple.h" #include "RE/Bethesda/Events.h" +#include "RE/Bethesda/ImageSpaceData.h" #include "RE/Bethesda/InventoryUserUIUtils.h" #include "RE/Bethesda/SWFToCodeFunctionHandler.h" #include "RE/Bethesda/SendHUDMessage.h" @@ -68,12 +71,13 @@ namespace RE struct IdleInputEvent; struct InvInterfaceStateChangeEvent; struct LoadedInventoryModel; + struct ProcessObjectsLocal; struct PickRefUpdateEvent; struct PipboyValueChangedEvent; - struct UIAdvanceMenusFunctionCompleteEvent; + struct QueueSurvivalBumpDownMessage; struct RevertPlayerCharacterEvent; struct SaveLoadMessageTypeEvent; - struct QueueSurvivalBumpDownMessage; + struct UIAdvanceMenusFunctionCompleteEvent; enum class HUDColorTypes { @@ -193,6 +197,15 @@ namespace RE public BSTEventSink { public: + static constexpr auto RTTI{ RTTI::GameUIModel }; + static constexpr auto VTABLE{ VTABLE::GameUIModel }; + + [[nodiscard]] static GameUIModel* GetSingleton() + { + REL::Relocation singleton{ REL::ID(17419) }; + return *singleton; + } + void UpdateDataModels() { using func_t = decltype(&GameUIModel::UpdateDataModels); @@ -1982,6 +1995,80 @@ namespace RE }; static_assert(sizeof(ExamineMenu) == 0x810); + class __declspec(novtable) LoadingMenu : + public GameMenuBase // 00 + { + public: + static constexpr auto RTTI{ RTTI::LoadingMenu }; + static constexpr auto VTABLE{ VTABLE::LoadingMenu }; + static constexpr auto MENU_NAME{ "LoadingMenu"sv }; + + virtual ~LoadingMenu(); // 00 + + // override (GameMenuBase) + virtual void Call(const Params&) override; // 01 + virtual void MapCodeObjectFunctions() override; // 02 + virtual UI_MESSAGE_RESULTS ProcessMessage(UIMessage& a_message) override; // 03 + virtual void AdvanceMovie(float a_timeDelta, std::uint64_t a_time) override; // 04 + virtual bool OnButtonEventRelease(const BSFixedString& a_eventName) override; // 0F + + // override (BSInputEventUser) + virtual bool ShouldHandleEvent(const InputEvent*) override; // 01 + virtual void OnThumbstickEvent(const ThumbstickEvent*) override; // 04 + virtual void OnButtonEvent(const ButtonEvent*) override; // 08 + + // members + BGSLocation* loadLocation; // 0E0 + TESLoadScreen* artScreen; // 0E8 + std::byte upgrader[0x10]; // 0F0 - TODO + BSTArray validScreens; // 100 + ModelDBHandle foregroundModel; // 118 + NiAVObject* zoomTarget; // 120 + ImageSpaceLUTData LUT; // 128 + std::uint32_t numNonDefaultScreens; // 198 + float modelAggregateRotation; // 19C + float modelMinAggregateRotation; // 1A0 + float modelMaxAggregateRotation; // 1A4 + float frameTimeDelta; // 1A8 + float currentZoom; // 1AC + float minZoom; // 1B0 + float maxZoom; // 1B4 + float horizontalBound; // 1B8 + float verticalBound; // 1BC + float verticalBoundOffset; // 1BC + alignas(0x10) NiMatrix3 initialRotation; // 1D0 + NiPoint2 calcedPanMaxima; // 200 + NiPoint2 calcedPanMinima; // 208 + std::uint64_t lastAdvanceMovieTime; // 210 + std::uint64_t lastUserInteractTime; // 218 + std::uint64_t lastPanTime; // 220 + std::uint64_t lastRotationTime; // 228 + std::uint64_t lastZoomTime; // 230 + BSSoundHandle rotationSoundLoop; // 238 + BSSoundHandle zoomSoundLoop; // 240 + const BGSModelMaterialSwap* modelMaterialSwap; // 248 + NiPoint3 modelInitialRotation; // 250 + NiPoint3 modelTranslationOffset; // 25C + float modelScale; // 268 + std::uint32_t numFrames; // 26C + bool loadingIntoInterior; // 270 + bool menuAdded; // 271 + bool leftButtonDown; // 272 + bool rightButtonDown; // 273 + bool allowRotation; // 274 + bool autoRotate; // 275 + bool autoRotateInvert; // 276 + bool holoMode; // 277 + bool loadScreenShown; // 278 + bool leftStickReady; // 279 + bool rightStickReady; // 27A + bool leftStickWasPreviouslyActive; // 27B + bool rightStickWasPreviouslyActive; // 27C + bool modelRequested; // 27D + bool PCKeysDebounced; // 27E + }; + static_assert(sizeof(LoadingMenu) == 0x280); + class __declspec(novtable) LockpickingMenu : public GameMenuBase // 00 { diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h index 2bb4f8f0..908b3b5f 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h @@ -14,11 +14,56 @@ namespace RE struct ImageSpaceBaseData { public: + struct HDR // HNAM + { + public: + // members + float eyeAdaptSpeed; // 00 + float bloomBlurRadius; // 04 + float bloomThreshold; // 08 + float bloomScale; // 0C + float receiveBloomThreshold; // 10 + float white; // 14 + float sunlightScale; // 18 + float skyScale; // 1C + float eyeAdaptStrength; // 20 + }; + static_assert(sizeof(HDR) == 0x24); + + struct Cinematic // CNAM + { + public: + // members + float saturation; // 0 + float brightness; // 4 + float contrast; // 8 + }; + static_assert(sizeof(Cinematic) == 0xC); + + struct Tint // TNAM + { + public: + struct ColorF + { + public: + // members + float red; // 0 + float green; // 4 + float blue; // 8 + }; + static_assert(sizeof(ColorF) == 0xC); + + // members + float amount; // 00 + ColorF color; // 04 + }; + static_assert(sizeof(Tint) == 0x10); + // members - float hdrData[9]; // 00 - float cinematicData[3]; // 24 - float tintData[4]; // 30 - float dofData[6]; // 40 + HDR hdrData; // 00 + Cinematic cinematicData; // 24 + Tint tintData; // 30 + float dofData[6]; // 40 }; static_assert(sizeof(ImageSpaceBaseData) == 0x58); diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h index 5dbdfe1c..6e654644 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h @@ -16,7 +16,7 @@ namespace RE class ImageSpaceTexture; class NiTexture; - class ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffect { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffect }; @@ -88,14 +88,26 @@ namespace RE }; static_assert(sizeof(ImageSpaceTexture) == 0x28); - class ImageSpaceEffectFullScreenBlur : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectOption : + public ImageSpaceEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::ImageSpaceEffectOption }; + static constexpr auto VTABLE{ VTABLE::ImageSpaceEffectOption }; + + // members + NiTPrimitiveArray effectOn; // B0 + }; + static_assert(sizeof(ImageSpaceEffectOption) == 0xC8); + + class __declspec(novtable) ImageSpaceEffectFullScreenBlur : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectFullScreenBlur }; static constexpr auto VTABLE{ VTABLE::ImageSpaceEffectFullScreenBlur }; - virtual ~ImageSpaceEffectFullScreenBlur(); // 00 + virtual ~ImageSpaceEffectFullScreenBlur() override; // 00 // override (ImageSpaceEffect) virtual void Render(BSTriShape* a_geometry, ImageSpaceEffectParam* a_param) override; // 01 @@ -112,8 +124,8 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectFullScreenBlur) == 0x128); - class ImageSpaceEffectGetHit : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectGetHit : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectGetHit }; @@ -137,8 +149,8 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectGetHit) == 0x108); - class ImageSpaceEffectMotionBlur : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectMotionBlur : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectMotionBlur }; @@ -153,8 +165,8 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectMotionBlur) == 0xB0); - class ImageSpaceEffectPipboyScreen : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectPipboyScreen : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectPipboyScreen }; @@ -175,8 +187,8 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectPipboyScreen) == 0xC0); - class ImageSpaceEffectRadialBlur : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectRadialBlur : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectRadialBlur }; @@ -193,8 +205,8 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectRadialBlur) == 0xB0); - class ImageSpaceEffectTemporalAA : - public ImageSpaceEffect + class __declspec(novtable) ImageSpaceEffectTemporalAA : + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectTemporalAA }; diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceManager.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceManager.h index 8202ecbe..2758b375 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceManager.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceManager.h @@ -13,7 +13,261 @@ namespace RE class ImageSpaceManager { public: - enum class ImageSpaceEffectEnum; + enum class ImageSpaceEffectEnum + { + EFFECT_WORLD_CAMERA = 0, + EFFECT_TEMPORAL_AA_PRE_HDR = 1, + EFFECT_SUNBEAMS = 2, + EFFECT_HDR = 3, + EFFECT_HDR_CS = 4, + EFFECT_REFRACTION = 5, + EFFECT_DEPTH_OF_FIELD = 6, + EFFECT_DEPTH_OF_FIELD_SPLIT_SCREEN = 7, + EFFECT_RADIAL_BLUR = 8, + EFFECT_FULLSCREEN_BLUR = 9, + EFFECT_MOTIONBLUR = 10, + EFFECT_GETHIT = 11, + EFFECT_VATS_TARGET = 12, + EFFECT_FULLSCREEN_COLOR = 13, + EFFECT_SHADER_GAMMA_CORRECT = 14, + EFFECT_SHADER_GAMMA_CORRECT_LUT = 15, + EFFECT_SHADER_GAMMA_CORRECT_RESIZE = 16, + EFFECT_SHADER_FXAA = 17, + EFFECT_TEMPORAL_AA = 18, + EFFECT_TEMPORAL_OLD_AA = 19, + EFFECT_BOKEH_DEPTH_OF_FIELD = 20, + EFFECT_UPSAMPLE_DYNAMIC_RESOLUTION = 21, + EFFECT_ENDOFFRAME_END = 22, + EFFECT_MAP = EFFECT_ENDOFFRAME_END, + EFFECT_BLUR_START = 23, + EFFECT_BLUR3 = EFFECT_BLUR_START, + EFFECT_BLUR5 = 24, + EFFECT_BLUR7 = 25, + EFFECT_BLUR9 = 26, + EFFECT_BLUR11 = 27, + EFFECT_BLUR13 = 28, + EFFECT_BLUR15 = 29, + EFFECT_BLUR_END = EFFECT_BLUR15, + EFFECT_NONHDR_BLUR3 = 30, + EFFECT_NONHDR_BLUR5 = 31, + EFFECT_NONHDR_BLUR7 = 32, + EFFECT_NONHDR_BLUR9 = 33, + EFFECT_NONHDR_BLUR11 = 34, + EFFECT_NONHDR_BLUR13 = 35, + EFFECT_NONHDR_BLUR15 = 36, + EFFECT_BRIGHTPASS_BLUR3 = 37, + EFFECT_BRIGHTPASS_BLUR5 = 38, + EFFECT_BRIGHTPASS_BLUR7 = 39, + EFFECT_BRIGHTPASS_BLUR9 = 40, + EFFECT_BRIGHTPASS_BLUR11 = 41, + EFFECT_BRIGHTPASS_BLUR13 = 42, + EFFECT_BRIGHTPASS_BLUR15 = 43, + EFFECT_BRIGHTPASS_HDR_BLUR15_320x180CS = 44, + EFFECT_BRIGHTPASS_HDR_BLUR15_480x270CS = 45, + EFFECT_BRIGHTPASS_HDR_BLUR15_1024x1024CS = 46, + EFFECT_BLUR_CS_START = 47, + EFFECT_BLUR3_480x270CS = EFFECT_BLUR_CS_START, + EFFECT_BLUR5_480x270CS = 48, + EFFECT_BLUR7_480x270CS = 49, + EFFECT_BLUR9_480x270CS = 50, + EFFECT_BLUR11_480x270CS = 51, + EFFECT_BLUR13_480x270CS = 52, + EFFECT_BLUR15_480x270CS = 53, + EFFECT_BLUR_CS_END = EFFECT_BLUR15_480x270CS, + EFFECT_BRIGHTPASS_BLUR3_480x270CS = 54, + EFFECT_BRIGHTPASS_BLUR5_480x270CS = 55, + EFFECT_BRIGHTPASS_BLUR7_480x270CS = 56, + EFFECT_BRIGHTPASS_BLUR9_480x270CS = 57, + EFFECT_BRIGHTPASS_BLUR11_480x270CS = 58, + EFFECT_BRIGHTPASS_BLUR13_480x270CS = 59, + EFFECT_BRIGHTPASS_BLUR15_480x270CS = 60, + EFFECT_WATER_DISPLACEMENT = 61, + EFFECT_NOISE = 62, + EFFECT_RAINSPLASH = 63, + EFFECT_VLS_LIGHT = 64, + EFFECT_VLS = 65, + EFFECT_PIPBOY_SCREEN = 66, + EFFECT_HUD_GLASS = 67, + EFFECT_MOD_MENU = 68, + EFFECT_AO = 69, + EFFECT_SAO = 70, + EFFECT_SAO_CS = 71, + EFFECT_TOP_LEVEL_END = 72, + EFFECT_NIGHTVISION = EFFECT_TOP_LEVEL_END, + EFFECT_END = EFFECT_TOP_LEVEL_END, + EFFECT_SHADER_START = 72, + EFFECT_SHADER_COPY = EFFECT_SHADER_START, + EFFECT_SHADER_COPY_SCALE_BIAS = 73, + EFFECT_SHADER_COPY_VIS_ALPHA = 74, + EFFECT_SHADER_GREYSCALE = 75, + EFFECT_SHADER_DOWNSAMPLE_DEPTH = 76, + EFFECT_SHADER_COPY_STENCIL = 77, + EFFECT_SHADER_COPY_WATER_MASK = 78, + EFFECT_SHADER_COPY_SHADOWMAPTOARRAY = 79, + EFFECT_SHADER_REFRACTION = 80, + EFFECT_SHADER_DOUBLEVIS = 81, + EFFECT_SHADER_TEXTUREMASK = 82, + EFFECT_SHADER_MAP = 83, + EFFECT_SHADER_WORLD_CAMERA = 84, + EFFECT_SHADER_WORLD_CAMERA_NO_SKY_BLUR = 85, + EFFECT_SHADER_DEPTH_OF_FIELD = 86, + EFFECT_SHADER_DEPTH_OF_FIELD_FOGGED = 87, + EFFECT_SHADER_DEPTH_OF_FIELD_SPLIT_SCREEN = 88, + EFFECT_SHADER_BOKEH_DEPTH_OF_FIELD_PASS1 = 89, + EFFECT_SHADER_BOKEH_DEPTH_OF_FIELD_PASS2 = 90, + EFFECT_SHADER_BOKEH_DEPTH_OF_FIELD_PASS3 = 91, + EFFECT_SHADER_BOKEH_DEPTH_OF_FIELD_PASS4 = 92, + EFFECT_SHADER_BOKEH_DEPTH_OF_FIELD_PASS4_FOGGED = 93, + EFFECT_SHADER_DISTANT_BLUR = 94, + EFFECT_SHADER_DISTANT_BLUR_FOGGED = 95, + EFFECT_SHADER_RADIAL_BLUR = 96, + EFFECT_SHADER_RADIAL_BLUR_MED = 97, + EFFECT_SHADER_RADIAL_BLUR_HIGH = 98, + EFFECT_SHADER_HDR_BLENDINSHADER_CINEMATIC = 99, + EFFECT_SHADER_HDR_BLENDINSHADER_CINEMATIC_FADE = 100, + EFFECT_SHADER_HDR_DOWNSAMPLE16 = 101, + EFFECT_SHADER_HDR_DOWNSAMPLE4 = 102, + EFFECT_SHADER_HDR_DOWNSAMPLE16LUM = 103, + EFFECT_SHADER_HDR_DOWNSAMPLE4RGB2LUM = 104, + EFFECT_SHADER_HDR_DOWNSAMPLE4_LUMCLAMP = 105, + EFFECT_SHADER_HDR_DOWNSAMPLE4_LIGHTADAPT = 106, + EFFECT_SHADER_HDR_DOWNSAMPLE16_LUMCLAMP = 107, + EFFECT_SHADER_HDR_DOWNSAMPLE16_LIGHTADAPT = 108, + EFFECT_SHADER_HDR_DOWNSAMPLE4CS = 109, + EFFECT_SHADER_HDR_DOWNSAMPLE64RGB2LUMCS = 110, + EFFECT_SHADER_HDR_DOWNSAMPLE4LUMCS = 111, + EFFECT_SHADER_HDR_DOWNSAMPLE16LUMCS = 112, + EFFECT_SHADER_HDR_DOWNSAMPLE2_LIGHTADAPTCS = 113, + EFFECT_SHADER_BLUR_START = 114, + EFFECT_SHADER_BLUR3 = EFFECT_SHADER_BLUR_START, + EFFECT_SHADER_BLUR5 = 115, + EFFECT_SHADER_BLUR7 = 116, + EFFECT_SHADER_BLUR9 = 117, + EFFECT_SHADER_BLUR11 = 118, + EFFECT_SHADER_BLUR13 = 119, + EFFECT_SHADER_BLUR15 = 120, + EFFECT_SHADER_BLUR_END = 120, + EFFECT_SHADER_HDR_BLURX15_320CS = 121, + EFFECT_SHADER_HDR_BLURX15_480CS = 122, + EFFECT_SHADER_HDR_BLURX15_1024CS = 123, + EFFECT_SHADER_NONHDR_BLUR_START = 124, + EFFECT_SHADER_NONHDR_BLUR3 = 124, + EFFECT_SHADER_NONHDR_BLUR5 = 125, + EFFECT_SHADER_NONHDR_BLUR7 = 126, + EFFECT_SHADER_NONHDR_BLUR9 = 127, + EFFECT_SHADER_NONHDR_BLUR11 = 128, + EFFECT_SHADER_NONHDR_BLUR13 = 129, + EFFECT_SHADER_NONHDR_BLUR15 = 130, + EFFECT_SHADER_NONHDR_BLUR_END = EFFECT_SHADER_NONHDR_BLUR15, + EFFECT_SHADER_BRIGHTPASS_BLUR_START = 131, + EFFECT_SHADER_BRIGHTPASS_BLUR3 = EFFECT_SHADER_BRIGHTPASS_BLUR_START, + EFFECT_SHADER_BRIGHTPASS_BLUR5 = 132, + EFFECT_SHADER_BRIGHTPASS_BLUR7 = 133, + EFFECT_SHADER_BRIGHTPASS_BLUR9 = 134, + EFFECT_SHADER_BRIGHTPASS_BLUR11 = 135, + EFFECT_SHADER_BRIGHTPASS_BLUR13 = 136, + EFFECT_SHADER_BRIGHTPASS_BLUR15 = 137, + EFFECT_SHADER_BRIGHTPASS_BLUR_END = EFFECT_SHADER_BRIGHTPASS_BLUR15, + EFFECT_SHADER_BRIGHTPASS_HDR_BLURY15_180CS = 138, + EFFECT_SHADER_BRIGHTPASS_HDR_BLURY15_270CS = 139, + EFFECT_SHADER_BRIGHTPASS_HDR_BLURY15_1024CS = 140, + EFFECT_SHADER_WATER_DISPLACEMENT_START = 141, + EFFECT_SHADER_WATER_DISPLACEMENT_CLEAR_SIMULATION = EFFECT_SHADER_WATER_DISPLACEMENT_START, + EFFECT_SHADER_WATER_DISPLACEMENT_TEX_OFFSET = 142, + EFFECT_SHADER_WATER_DISPLACEMENT_WADING_RIPPLE = 143, + EFFECT_SHADER_WATER_DISPLACEMENT_RAIN_RIPPLE = 144, + EFFECT_SHADER_WATER_DISPLACEMENT_WADING_HEIGHTMAP = 145, + EFFECT_SHADER_WATER_DISPLACEMENT_RAIN_HEIGHTMAP = 146, + EFFECT_SHADER_WATER_DISPLACEMENT_BLEND_HEIGHTMAPS = 147, + EFFECT_SHADER_WATER_DISPLACEMENT_SMOOTH_HEIGHTMAP = 148, + EFFECT_SHADER_WATER_DISPLACEMENT_NORMALS = 149, + EFFECT_SHADER_WATER_DISPLACEMENT_END = 149, + EFFECT_SHADER_NOISE_SCROLL_AND_BLEND = 150, + EFFECT_SHADER_NOISE_NORMALMAP = 151, + EFFECT_SHADER_LOCAL_MAP = 152, + EFFECT_SHADER_LOCAL_MAP_COMPANION = 153, + EFFECT_SHADER_ALPHA_BLEND = 154, + EFFECT_SHADER_PIPBOY_SCREEN = 155, + EFFECT_SHADER_HUD_GLASS = 156, + EFFECT_SHADER_HUD_GLASS_DROPSHADOW = 157, + EFFECT_SHADER_HUD_GLASS_BLURY = 158, + EFFECT_SHADER_HUD_GLASS_BLURX = 159, + EFFECT_SHADER_HUD_GLASS_MARKERS = 160, + EFFECT_SHADER_VATS_TARGET_DEBUG = 161, + EFFECT_SHADER_VATS_TARGET = 162, + EFFECT_SHADER_MOD_MENU_EFFECT = 163, + EFFECT_SHADER_MOD_MENU_GLOW_COMPOSITE = 164, + EFFECT_SHADER_AO = 165, + EFFECT_SHADER_AO_BLUR = 166, + EFFECT_SHADER_VLS_SPOTLIGHT = 167, + EFFECT_SHADER_VLS_APPLICATION = 168, + EFFECT_SHADER_VLS_COMPOSITE = 169, + EFFECT_SHADER_VLS_SLICE_COORD = 170, + EFFECT_SHADER_VLS_SLICE_INTERP = 171, + EFFECT_SHADER_VLS_SLICE_STENCIL = 172, + EFFECT_SHADER_VLS_SLICE_SCATTER_RAY = 173, + EFFECT_SHADER_VLS_SLICE_SCATTER_INTERP = 174, + EFFECT_SHADER_VLS_SCATTER_ACCUM = 175, + EFFECT_SHADER_SAO_CAMERAZ = 176, + EFFECT_SHADER_SAO_MINIFY = 177, + EFFECT_SHADER_SAO_RAWAO = 178, + EFFECT_SHADER_SAO_BLUR_H = 179, + EFFECT_SHADER_SAO_BLUR_V = 180, + EFFECT_SHADER_SAO_RAWAO_EDITOR = 181, + EFFECT_SHADER_SAO_CAMERAZ_CS = 182, + EFFECT_SHADER_SAO_MINIFY_CS = 183, + EFFECT_SHADER_SAO_CAMERAZ_AND_MIPS_CS = 184, + EFFECT_SHADER_SAO_MIPS_CS = 185, + EFFECT_SHADER_SAO_RAWAO_CS = 186, + EFFECT_SHADER_SAO_BLUR_H_CS = 187, + EFFECT_SHADER_SAO_BLUR_V_CS = 188, + EFFECT_SHADER_MOTIONBLUR = 189, + EFFECT_SHADER_TEMPORAL_AA = 190, + EFFECT_SHADER_TEMPORAL_AA_MASKED = 191, + EFFECT_SHADER_TEMPORAL_AA_POWERARMOR = 192, + EFFECT_SHADER_GAMMA_LINEARIZE = 193, + EFFECT_SHADER_SUNBEAMS = 194, + EFFECT_SHADER_SSR_PREPASS = 195, + EFFECT_SHADER_SSR_RAYTRACING = 196, + EFFECT_SHADER_SSR_BLURH = 197, + EFFECT_SHADER_SSR_BLURV = 198, + EFFECT_SHADER_LENSFLARE = 199, + EFFECT_SHADER_RAINSPLASH_SPAWN = 200, + EFFECT_SHADER_RAINSPLASH_UPDATE = 201, + EFFECT_SHADER_RAINSPLASH_DRAW = 202, + EFFECT_SHADER_LENSFLAREVISIBILITY = 203, + EFFECT_SHADER_UPSAMPLE_DYNAMIC_RESOLUTION = 204, + EFFECT_SHADER_FULLSCREEN_COLOR = 205, + EFFECT_SHADER_HUDGLASS_CLEAR = 206, + EFFECT_SHADER_HUDGLASS_COPY = 207, + EFFECT_SHADER_CS_V_START = 208, + EFFECT_SHADER_ISBlur3_V_270_CS = 208, + EFFECT_SHADER_ISBlur5_V_270_CS = 209, + EFFECT_SHADER_ISBlur7_V_270_CS = 210, + EFFECT_SHADER_ISBlur9_V_270_CS = 211, + EFFECT_SHADER_ISBlur11_V_270_CS = 212, + EFFECT_SHADER_ISBlur13_V_270_CS = 213, + EFFECT_SHADER_ISBlur15_V_270_CS = 214, + EFFECT_SHADER_CS_V_END = 215, + EFFECT_SHADER_CS_H_START = 216, + EFFECT_SHADER_ISBlur3_H_480_CS = EFFECT_SHADER_CS_H_START, + EFFECT_SHADER_ISBlur5_H_480_CS = 217, + EFFECT_SHADER_ISBlur7_H_480_CS = 218, + EFFECT_SHADER_ISBlur9_H_480_CS = 219, + EFFECT_SHADER_ISBlur11_H_480_CS = 220, + EFFECT_SHADER_ISBlur13_H_480_CS = 221, + EFFECT_SHADER_ISBlur15_H_480_CS = 222, + EFFECT_SHADER_CS_H_END = 223, + EFFECT_SHADER_BRIGHTPASS_CS_V_START = 224, + EFFECT_SHADER_ISBrightPassBlur3_V_270_CS = 224, + EFFECT_SHADER_ISBrightPassBlur5_V_270_CS = 225, + EFFECT_SHADER_ISBrightPassBlur7_V_270_CS = 226, + EFFECT_SHADER_ISBrightPassBlur9_V_270_CS = 227, + EFFECT_SHADER_ISBrightPassBlur11_V_270_CS = 228, + EFFECT_SHADER_ISBrightPassBlur13_V_270_CS = 229, + EFFECT_SHADER_ISBrightPassBlur15_V_270_CS = 230, + EFFECT_SHADER_BRIGHTPASS_CS_V_END = 231 + }; [[nodiscard]] static ImageSpaceManager* GetSingleton() { @@ -31,7 +285,7 @@ namespace RE bool enablePartialRender; // 048 std::int32_t mainTarget; // 04C NiColorA refractionTint; // 050 - const ImageSpaceBaseData* paseData; // 060 + const ImageSpaceBaseData* baseData; // 060 const ImageSpaceBaseData* overRideBaseData; // 068 const ImageSpaceBaseData* underwaterBaseData; // 070 ImageSpaceBaseData* consoleBaseData; // 078 diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h index e7cf3f20..93bd3a6d 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h @@ -58,16 +58,30 @@ namespace RE virtual void PrintInfo(char* a_buffer) override; // 2A virtual ImageSpaceModifierInstanceForm* IsForm() override; // 2B + static ImageSpaceModifierInstanceForm* Trigger(TESImageSpaceModifier* a_mod, float a_strength, NiAVObject* a_target) + { + using func_t = ImageSpaceModifierInstanceForm* (*)(TESImageSpaceModifier*, float, NiAVObject*); + REL::Relocation func{ REL::ID(179769) }; + return func(a_mod, a_strength, a_target); + } + static ImageSpaceModifierInstanceForm* Trigger(const BSFixedString& a_name) { - using func_t = decltype(&ImageSpaceModifierInstanceForm::Trigger); + using func_t = ImageSpaceModifierInstanceForm* (*)(const BSFixedString&); REL::Relocation func{ REL::ID(1216312) }; return func(a_name); } + static void Stop(TESImageSpaceModifier* a_mod) + { + using func_t = void (*)(TESImageSpaceModifier* ); + REL::Relocation func{ REL::ID(217873) }; + return func(a_mod); + } + static void Stop(const BSFixedString& a_name) { - using func_t = decltype(&ImageSpaceModifierInstanceForm::Stop); + using func_t = void (*)(const BSFixedString&); REL::Relocation func{ REL::ID(549773) }; return func(a_name); } diff --git a/CommonLibF4/include/RE/Bethesda/InputEvent.h b/CommonLibF4/include/RE/Bethesda/InputEvent.h index fdcd70c4..98fb8815 100644 --- a/CommonLibF4/include/RE/Bethesda/InputEvent.h +++ b/CommonLibF4/include/RE/Bethesda/InputEvent.h @@ -317,6 +317,7 @@ namespace RE [[nodiscard]] float QAnalogValue() const noexcept { return value; } [[nodiscard]] bool QHeldDown(float a_heldDownSecs) const noexcept { return value != 0.0 && a_heldDownSecs <= heldDownSecs; } + [[nodiscard]] bool QHeldDown() const noexcept { return value != 0.0 && heldDownSecs > 0.0F; } [[nodiscard]] float QHeldDownSecs() const noexcept { return heldDownSecs; } [[nodiscard]] bool QJustPressed() const noexcept { return value != 0.0F && heldDownSecs == 0.0F; } [[nodiscard]] bool QReleased(float a_heldDownSecs) const noexcept { return value == 0.0F && a_heldDownSecs <= heldDownSecs; } diff --git a/CommonLibF4/include/RE/Bethesda/MagicItems.h b/CommonLibF4/include/RE/Bethesda/MagicItems.h index a92bc979..a5448222 100644 --- a/CommonLibF4/include/RE/Bethesda/MagicItems.h +++ b/CommonLibF4/include/RE/Bethesda/MagicItems.h @@ -167,13 +167,6 @@ namespace RE }; static_assert(sizeof(Data) == 0x28); - bool Cast(TESObjectREFR* caster, TESObjectREFR* target, Actor* anyActor, BSScript::IVirtualMachine* vm) - { - using func_t = decltype(&SpellItem::Cast); - REL::Relocation func{ REL::ID(1511987) }; - return func(this, caster, target, anyActor, vm); - } - // members Data data; // 108 }; diff --git a/CommonLibF4/include/RE/Bethesda/MenuControls.h b/CommonLibF4/include/RE/Bethesda/MenuControls.h index 599380cd..511c1e51 100644 --- a/CommonLibF4/include/RE/Bethesda/MenuControls.h +++ b/CommonLibF4/include/RE/Bethesda/MenuControls.h @@ -1,21 +1,19 @@ #pragma once #include "RE/Bethesda/BSInputEventReceiver.h" +#include "RE/Bethesda/BSInputEventUser.h" #include "RE/Bethesda/BSTArray.h" #include "RE/Bethesda/BSTSingleton.h" namespace RE { - class BSInputEventUser; class PipboyHandler; struct CameraZoomHandler; struct ClickHandler; - struct DisconnectHandler; struct GFxConvertHandler; struct MenuOpenHandler; struct QuickSaveLoadHandler; - struct ScreenshotHandler; class MenuControls : public BSInputEventReceiver, // 00 @@ -28,6 +26,15 @@ namespace RE return *singleton; } + bool QueueScreenshot() const + { + if (!screenshotHandler || screenshotHandler->screenshotQueued) { + return false; + } + screenshotHandler->screenshotQueued = true; + return true; + } + // members BSTArray handlers; // 18 GFxConvertHandler* convertHandler; // 30 diff --git a/CommonLibF4/include/RE/Bethesda/PlayerCharacter.h b/CommonLibF4/include/RE/Bethesda/PlayerCharacter.h index 0d2b891f..ddd91ad7 100644 --- a/CommonLibF4/include/RE/Bethesda/PlayerCharacter.h +++ b/CommonLibF4/include/RE/Bethesda/PlayerCharacter.h @@ -50,14 +50,7 @@ namespace RE class UserEventEnabledEvent; struct BGSActorCellEvent; - struct BGSActorDeathEvent - { - uint64_t flag; - float damageTaken; - uint32_t pad08; - float lastHealth; - uint32_t pad10; - }; + struct BGSActorDeathEvent; struct ItemChange; struct PickRefUpdateEvent; struct PositionPlayerEvent; diff --git a/CommonLibF4/include/RE/Bethesda/PlayerControls.h b/CommonLibF4/include/RE/Bethesda/PlayerControls.h index ae4a9a1b..768dc887 100644 --- a/CommonLibF4/include/RE/Bethesda/PlayerControls.h +++ b/CommonLibF4/include/RE/Bethesda/PlayerControls.h @@ -159,11 +159,11 @@ namespace RE return *singleton; } - bool CanPerformAction(DEFAULT_OBJECT id) + bool CanPerformAction(DEFAULT_OBJECT a_action) { using func_t = decltype(&PlayerControls::CanPerformAction); REL::Relocation func{ REL::ID(565925) }; - return func(this, id); + return func(this, a_action); } bool DoAction(DEFAULT_OBJECT a_action, ActionInput::ACTIONPRIORITY a_priority) diff --git a/CommonLibF4/include/RE/Bethesda/ProcessLists.h b/CommonLibF4/include/RE/Bethesda/ProcessLists.h index 149209f9..dccdc624 100644 --- a/CommonLibF4/include/RE/Bethesda/ProcessLists.h +++ b/CommonLibF4/include/RE/Bethesda/ProcessLists.h @@ -3,10 +3,10 @@ #include "RE/Bethesda/BSSemaphore.h" #include "RE/Bethesda/BSTEvent.h" #include "RE/Bethesda/BSTSingleton.h" +#include "RE/Bethesda/BSTempEffect.h" namespace RE { - class BSTempEffect; class SyncQueueObj; class __declspec(novtable) ProcessLists : @@ -35,6 +35,40 @@ namespace RE return func(this, a_hostileActorArray); } + void ForEachMagicTempEffect(std::function a_callback) + { + BSAutoLock locker(magicEffectsLock); + + for (auto& tempEffectPtr : magicEffects) { + const auto& tempEffect = tempEffectPtr.get(); + if (tempEffect && a_callback(tempEffect) == BSContainer::ForEachResult::kStop) { + break; + } + } + } + + void ForEachModelEffect(std::function a_callback) + { + ForEachMagicTempEffect([a_callback](BSTempEffect* a_tempEffect) { + const auto modelEffect = a_tempEffect->As(); + if (modelEffect && a_callback(modelEffect) == BSContainer::ForEachResult::kStop) { + return BSContainer::ForEachResult::kStop; + } + return BSContainer::ForEachResult::kContinue; + }); + } + + void ForEachShaderEffect(std::function a_callback) + { + ForEachMagicTempEffect([a_callback](BSTempEffect* a_tempEffect) { + const auto shaderEffect = a_tempEffect->As(); + if (shaderEffect && a_callback(shaderEffect) == BSContainer::ForEachResult::kStop) { + return BSContainer::ForEachResult::kStop; + } + return BSContainer::ForEachResult::kContinue; + }); + } + [[nodiscard]] bool IsActorTargetingREFinPackage(const TESObjectREFR* a_actor, PTYPE a_type, bool a_onlyHigh) { using func_t = decltype(&ProcessLists::IsActorTargetingREFinPackage); diff --git a/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h b/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h new file mode 100644 index 00000000..07e20464 --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h @@ -0,0 +1,120 @@ +#pragma once + +#include "RE/Bethesda/BSFixedString.h" +#include "RE/Bethesda/BSPointerHandle.h" +#include "RE/NetImmerse/NiPoint3.h" + +namespace RE +{ + class ActiveEffect; + class BGSArtObject; + class BGSLoadGameBuffer; + class BGSSaveGameBuffer; + class NiAVObject; + class NiNode; + class ReferenceEffect; + class TESEffectShader; + class TESObjectREFR; + + class __declspec(novtable) ReferenceEffectController + { + public: + static constexpr auto RTTI{ RTTI::ReferenceEffectController }; + static constexpr auto VTABLE{ VTABLE::ReferenceEffectController }; + + virtual ~ReferenceEffectController(); // 00 + + // add + virtual void HandleEvent(const BSFixedString& a_event); // 01 - { return; } + virtual float GetElapsedTime(); // 02 - { return 0.0; } + virtual float GetScale(); // 03 - { return 1.0; } + virtual void SwitchAttachedRoot(NiNode* a_root, NiNode* a_attachRoot); // 04 - { return; } + virtual const NiPoint3& GetSourcePosition(); // 05 - { return NiPoint3(); } + virtual bool GetUseSourcePosition(); // 06 - { return true; } + virtual bool GetNoInitialFlare(); // 07 - { return false; } + virtual bool GetEffectPersists(); // 08 - { return true; } + virtual bool GetGoryVisuals(); // 09 - { return false; } + virtual void RemoveHitEffect(ReferenceEffect* a_refEffect); // 0A - { return; } + virtual TESObjectREFR* GetTargetReference() = 0; // 0B + virtual BGSArtObject* GetHitEffectArt() = 0; // 0C + virtual TESEffectShader* GetHitEffectShader() = 0; // 0D + virtual bool GetManagerHandlesSaveLoad() = 0; // 0E + virtual NiAVObject* GetAttachRoot(); // 0F - { auto ref = GetTargetReference(); return ref ? ref->Get3D() : 0; } + virtual float GetParticleAttachExtent(); // 10 - { return 0.0; } + virtual bool GetUseParticleAttachExtent(); // 11 - { return false; } + virtual bool GetDoParticles(); // 12 - { return true; } + virtual bool GetParticlesUseLocalSpace(); // 13 - { return false; } + virtual bool GetUseRootWorldRotate(); // 14 - { return false; } + virtual bool GetIsRootActor(); // 15 - { auto ref = GetTargetReference(); return ref ? ref->formType = FormType::ActorCharacter : false; } + virtual bool GetClearWhenCellIsUnloaded(); // 16 - { return false; } + virtual bool EffectShouldFaceTarget(); // 17 - { return false; } + virtual TESObjectREFR* GetFacingTarget(); // 18 - { return 0; } + virtual bool GetShaderUseParentCell(); // 19 - { return true; } + virtual bool EffectAttachesToCamera(); // 1A - { return false; } + virtual bool EffectRotatesWithCamera(); // 1B - { return false; } + virtual bool GetAllowTargetRoot(); // 1C - { return true; } + virtual bool IsReadyForAttach(); // 1D - { return true; } + virtual void SetWindPoint(const NiPoint3& a_point); // 1E - { return; } + virtual const NiPoint3& GetWindPoint(); // 1F - { return NiPoint3(); } + virtual bool GetAllowNo3D(); // 20 - { return false; } + virtual void SaveGame(BGSSaveGameBuffer* a_buf); // 21 - { return; } + virtual void LoadGame(BGSLoadGameBuffer* a_buf); // 22 - { return; } + }; + static_assert(sizeof(ReferenceEffectController) == 0x8); + + class __declspec(novtable) ActiveEffectReferenceEffectController : + public ReferenceEffectController // 00 + { + public: + static constexpr auto RTTI{ RTTI::ActiveEffectReferenceEffectController }; + static constexpr auto VTABLE{ VTABLE::ActiveEffectReferenceEffectController }; + + // override (ReferenceEffectController) + void HandleEvent(const BSFixedString& a_event) override; // 01 - return { effect->HandleEvent(a_event); } + float GetElapsedTime() override; // 02 - return { effect->elapsedSeconds; } + float GetScale() override; // 03 + void SwitchAttachedRoot(NiNode* a_root, NiNode* a_attachRoot) override; // 04 - return { effect->SwitchAttachedRoot(a_root, a_attachRoot); } + const NiPoint3& GetSourcePosition() override; // 05 + bool GetUseSourcePosition() override; // 06 + bool GetNoInitialFlare() override; // 07 + bool GetEffectPersists() override; // 08 + bool GetGoryVisuals() override; // 09 + void RemoveHitEffect(ReferenceEffect* a_refEffect) override; // 0A + TESObjectREFR* GetTargetReference() override; // 0B + BGSArtObject* GetHitEffectArt() override; // 0C + TESEffectShader* GetHitEffectShader() override; // 0D + bool GetManagerHandlesSaveLoad() override; // 0E - { return false; } + bool EffectShouldFaceTarget() override; // 17 + TESObjectREFR* GetFacingTarget() override; // 18 + void SetWindPoint(const NiPoint3& a_point) override; // 1E - { windPoint = a_point; } + const NiPoint3& GetWindPoint() override; // 1F - { return windPoint; } + bool GetAllowNo3D() override; // 20 + void SaveGame(BGSSaveGameBuffer* a_buf) override; // 21 + void LoadGame(BGSLoadGameBuffer* a_buf) override; // 22 + + // members + ActiveEffect* effect; // 08 + NiPoint3 windPoint; // 10 + ObjectRefHandle target; // 18 + }; + static_assert(sizeof(ActiveEffectReferenceEffectController) == 0x20); + + class __declspec(novtable) SkyEffectController : + public ReferenceEffectController // 00 + { + public: + static constexpr auto RTTI{ RTTI::SkyEffectController }; + static constexpr auto VTABLE{ VTABLE::SkyEffectController }; + + // override (ReferenceEffectController) + void RemoveHitEffect(ReferenceEffect* a_refEffect) override; // 0A - { return; } + TESObjectREFR* GetTargetReference() override; // 0B - { return g_thePlayer; } + BGSArtObject* GetHitEffectArt() override; // 0C - { return GetSkyReferenceEffectArt(); } + TESEffectShader* GetHitEffectShader() override; // 0D - { return 0; } + bool GetManagerHandlesSaveLoad() override; // 0E - { return 0; } + NiAVObject* GetAttachRoot() override; // 0F + bool EffectAttachesToCamera() override; // 1A - { return true; } + bool EffectRotatesWithCamera() override; // 1B + }; + static_assert(sizeof(SkyEffectController) == 0x8); +} diff --git a/CommonLibF4/include/RE/Bethesda/Settings.h b/CommonLibF4/include/RE/Bethesda/Settings.h index 57ea3fe6..be1a921a 100644 --- a/CommonLibF4/include/RE/Bethesda/Settings.h +++ b/CommonLibF4/include/RE/Bethesda/Settings.h @@ -348,6 +348,12 @@ namespace RE REL::Relocation singleton{ REL::ID(8308) }; return *singleton; } + + [[nodiscard]] Setting* GetSetting(std::string_view a_name) + { + auto it = settings.find(a_name); + return it != settings.end() ? it->second : nullptr; + } }; static_assert(sizeof(GameSettingCollection) == 0x138); @@ -390,4 +396,17 @@ namespace RE } }; static_assert(sizeof(INIPrefSettingCollection) == 0x128); + + inline Setting* GetINISetting(std::string_view a_name) + { + Setting* setting = nullptr; + + auto iniPrefs = INIPrefSettingCollection::GetSingleton(); + setting = iniPrefs ? iniPrefs->GetSetting(a_name) : nullptr; + if (!setting) { + auto ini = INISettingCollection::GetSingleton(); + setting = ini ? ini->GetSetting(a_name) : nullptr; + } + return setting; + } } diff --git a/CommonLibF4/include/RE/Bethesda/Sky.h b/CommonLibF4/include/RE/Bethesda/Sky.h new file mode 100644 index 00000000..861acb7b --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/Sky.h @@ -0,0 +1,178 @@ +#pragma once + +#include "RE/Bethesda/BSModelDB.h" +#include "RE/Bethesda/BSPointerHandle.h" +#include "RE/Bethesda/BSTArray.h" +#include "RE/Bethesda/BSTList.h" +#include "RE/Bethesda/BSTSmartPointer.h" +#include "RE/Bethesda/BSTTuple.h" +#include "RE/Bethesda/ReferenceEffectController.h" +#include "RE/NetImmerse/NiColor.h" +#include "RE/NetImmerse/NiSmartPointer.h" + +namespace RE +{ + class Atmosphere; + class BGSLightingTemplate; + class BSMultiBoundNode; + class Clouds; + class ImageSpaceModifierInstanceForm; + class Moon; + class NiNode; + class NiTexture; + class Precipitation; + class ReferenceEffect; + class SkySound; + class Stars; + class Sun; + class TESClimate; + class TESImageSpace; + class TESRegion; + class TESWeather; + + class __declspec(novtable) Sky + { + public: + static constexpr auto RTTI{ RTTI::Sky }; + static constexpr auto VTABLE{ VTABLE::Sky }; + + enum class Mode + { + kNone = 0, + kInterior, + kSkyDomeOnly, + kFull, + + kTotal + }; + + enum class Flags + { + kNone = 0, + kFastTravel = 1 << 4, + kHideSky = 1 << 7, + kUpdateSunriseBegin = 1 << 9, + kUpdateSunriseEnd = 1 << 10, + kUpdateSunsetBegin = 1 << 11, + kUpdateSunsetEnd = 1 << 12, + kUpdateColorsSunriseBegin = 1 << 13, + kUpdateColorsSunsetEnd = 1 << 14, + kUpdateWind = 1 << 20, + kReleaseWeatherOverride = 1 << 21 + }; + + struct SkyStaticRefData + { + public: + // members + BSTTuple data; // 00 + }; + static_assert(sizeof(SkyStaticRefData) == 0x8); + + virtual ~Sky(); // 00 + + [[nodiscard]] static Sky* GetSingleton() + { + REL::Relocation singleton{ REL::ID(484694) }; + return *singleton; + } + + void ForceWeather(TESWeather* a_weather, bool a_override) + { + using func_t = decltype(&Sky::ForceWeather); + REL::Relocation func{ REL::ID(698558) }; + return func(this, a_weather, a_override); + } + + void ReleaseWeatherOverride() + { + if (overrideWeather) { + flags.set(Flags::kReleaseWeatherOverride); + overrideWeather = nullptr; + } + } + + void ResetWeather() + { + using func_t = decltype(&Sky::ResetWeather); + REL::Relocation func{ REL::ID(6511) }; + return func(this); + } + + // members + NiPointer root; // 008 + NiPointer moonsRoot; // 010 + NiPointer auroraRoot; // 018 + ModelDBHandle aurora3d; // 020 + BGSLightingTemplate* extLightingOverride; // 028 + ObjectRefHandle currentRoom; // 030 + ObjectRefHandle previousRoom; // 034 + float lightingTransition; // 038 + float lightingTransitionTimer; // 03C + TESClimate* currentClimate; // 040 + TESWeather* currentWeather; // 048 + TESWeather* lastWeather; // 050 + TESWeather* defaultWeather; // 058 + TESWeather* overrideWeather; // 060 + TESRegion* currentRegion; // 068 + Atmosphere* atmosphere; // 070 + Stars* stars; // 078 + Sun* sun; // 080 + Clouds* clouds; // 088 + Moon* masser; // 090 + Moon* secunda; // 098 + Precipitation* precip; // 0A0 + NiColor skyColor[19]; // 0A8 + NiColor prevSkyColorA[19]; // 18C + NiColor prevDirAmbColorsA[3][2]; // 270 + NiColorA prevSpecTintFres; // 2B8 + TESImageSpace* prevImageSpace; // 2C8 + float prevFogDistancesA[8]; // 2D0 + float prevFogHeight; // 2F0 + float prevFogPower; // 2F4 + float prevFogClamp; // 2F8 + float prevFogHighDensityScale; // 2FC + float lastExtWetness; // 300 + NiColor waterFogColor; // 304 + NiColor sunSpecularColor; // 310 + float windSpeed; // 31C + float windAngle; // 320 + float windTurbulence; // 324 + float fogDistances[8]; // 328 + float fogHeight; // 348 + float fogPower; // 34C + float fogClamp; // 350 + float fogHighDensityScale; // 354 + float currentGameHour; // 358 + float lastWeatherUpdate; // 35C + float currentWeatherPct; // 360 + float lastWindDirection; // 364 + float lastWindDirectionRange; // 368 + stl::enumeration mode; // 36C + BSSimpleList* skySoundList; // 370 + float flash; // 378 + std::uint64_t flashTime; // 380 + std::uint32_t lastMoonPhaseUpdate; // 388 + float windowReflectionTimer; // 38C + float accelBeginPct; // 390 + stl::enumeration flags; // 394 + ImageSpaceModifierInstanceForm* currentWeatherImageSpaceMod; // 398 + ImageSpaceModifierInstanceForm* currentWeatherImageSpaceMod2; // 3A0 + ImageSpaceModifierInstanceForm* lastWeatherImageSpaceMod; // 3A8 + ImageSpaceModifierInstanceForm* lastWeatherImageSpaceMod2; // 3B0 + NiColor directionalAmbientColorsA[3][2]; // 3B8 + NiColor ambientSpecularTint; // 400 + float ambientSpecularFresnel; // 40C + float auroraInStart; // 410 + float auroraIn; // 414 + float auroraOutStart; // 418 + float auroraOut; // 41C + NiPointer currentReferenceEffect; // 420 + NiPointer lastReferenceEffect; // 428 + SkyEffectController effectController; // 430 + BSTArray> storedCloudTextures; // 438 + BSTArray> storedWorldMapCloudTextures; // 450 + BSTArray skyStaticRefData; // 468 + }; + static_assert(sizeof(Sky) == 0x480); +} diff --git a/CommonLibF4/include/RE/Bethesda/TESCamera.h b/CommonLibF4/include/RE/Bethesda/TESCamera.h index ac28724f..364d15ce 100644 --- a/CommonLibF4/include/RE/Bethesda/TESCamera.h +++ b/CommonLibF4/include/RE/Bethesda/TESCamera.h @@ -205,6 +205,13 @@ namespace RE return func(this, a_state); } + void ToggleFreeCameraMode(bool a_freezeTime) + { + using func_t = decltype(&PlayerCamera::ToggleFreeCameraMode); + REL::Relocation func{ REL::ID(224913) }; + return func(this, a_freezeTime); + } + void SetState(TESCameraState* a_newstate) const { using func_t = decltype(&PlayerCamera::SetState); diff --git a/CommonLibF4/include/RE/Bethesda/TESForms.h b/CommonLibF4/include/RE/Bethesda/TESForms.h index 54a17c63..2a117361 100644 --- a/CommonLibF4/include/RE/Bethesda/TESForms.h +++ b/CommonLibF4/include/RE/Bethesda/TESForms.h @@ -822,7 +822,7 @@ namespace RE template [[nodiscard]] bool Is(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (Is(a_args) || ...); } @@ -839,13 +839,14 @@ namespace RE [[nodiscard]] bool IsAlchemyItem() const noexcept { return Is(ENUM_FORM_ID::kALCH); } [[nodiscard]] bool IsCreated() const noexcept { return (formID >> (8 * 3)) == 0xFF; } [[nodiscard]] bool IsDeleted() noexcept { return (formFlags & (1u << 5)) != 0; } + [[nodiscard]] bool IsDisabled() noexcept { return (formFlags & (1u << 11)) != 0; } [[nodiscard]] bool IsInitialized() const noexcept { return (formFlags & (1u << 3)) != 0; } [[nodiscard]] bool IsNot(ENUM_FORM_ID a_type) const noexcept { return !Is(a_type); } template [[nodiscard]] bool IsNot(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (IsNot(a_args) && ...); } @@ -1353,13 +1354,21 @@ namespace RE static constexpr auto VTABLE{ VTABLE::BGSReferenceEffect }; static constexpr auto FORM_ID{ ENUM_FORM_ID::kRFCT }; + enum class Flag + { + kNone = 0, + kFaceTarget = 1 << 0, + kAttachToCamera = 1 << 1, + kInheritRotation = 1 << 2 + }; + struct Data { public: // members - BGSArtObject* artObject; // 00 - TESEffectShader* effectShader; // 08 - std::uint32_t flags; // 10 + BGSArtObject* artObject; // 00 + TESEffectShader* effectShader; // 08 + stl::enumeration flags; // 10 }; static_assert(sizeof(Data) == 0x18); @@ -1988,25 +1997,63 @@ namespace RE }; static_assert(sizeof(BGSPerk) == 0x98); - class __declspec(novtable) BGSBodyPart - { - public: - BSFixedString PartNode; //00 - BSFixedString VATSTarget; //08 - BSFixedString TwistVariation; //10 - BSFixedString HitReactionStart; //18 - BSFixedString HitReactionEnd; //20 - BSFixedString TwistVariationX; //28 - BSFixedString TwistVariationY; //30 - BSFixedString TwistVariationZ; //38 - BSFixedString unk40; //40 - BSFixedString GoreEffectsTargetBone; //48 - void* TESModelVTable; //50 - BSFixedString LimbReplacementModel; //58 - void* TextureFileHashes; //60 - void* MaterialRelated; //68 - uint64_t unk70; //70 - }; + struct PART_DATA + { + public: + // members + float damageMult; // 00 + BGSDebris* explosionGenericDebris; // 08 + BGSExplosion* explosion; // 10 + float explosionGenericDebrisScale; // 18 + BGSDebris* dismemberGenericDebris; // 20 + BGSExplosion* dismemberExplosion; // 28 + float dismemberGenericDebrisScale; // 30 + BGSDebris* onCrippleGenericDebris; // 38 + BGSExplosion* onCrippleExplosion; // 40 + float onCrippleGenericDebrisScale; // 48 + NiPoint3 goreTranslate; // 4C + NiPoint3 goreRotate; // 58 + BGSImpactDataSet* dismemberImpactDataSet; // 68 + BGSImpactDataSet* explosionImpactDataSet; // 70 + BGSImpactDataSet* onCrippleImpactDataSet; // 78 + ActorValueInfo* actorValue; // 80 + BGSArtObject* artObject; // 88 + float explosionSpecialDebrisScale; // 90 + std::uint8_t flags; // 94 + std::uint8_t type; // 95 + std::uint8_t healthPercent; // 96 + std::uint8_t toHitChance; // 97 + std::uint8_t explosionChance; // 98 + std::uint8_t nonLethalDismembermentChance; // 99 + std::uint8_t dismemberGenericDebrisCount; // 9A + std::uint8_t onCrippleGenericDebrisCount; // 9B + std::uint8_t explosionGenericDebrisCount; // 9C + std::uint8_t dismemberDecalCount; // 9D + std::uint8_t onCrippleDecalCount; // 9E + std::uint8_t explosionDecalCount; // 9F + std::uint8_t geometrySegmentIndex; // A0 + }; + static_assert(sizeof(PART_DATA) == 0xA8); + + class BGSBodyPart + { + public: + // members + BSFixedString nodeName; // 000 + BSFixedString targetName; // 008 + BSFixedString hitReactionVariablePrefix; // 010 + BGSBodyPartDefs::HitReactionData runtimeHitReactionData; // 018 + BGSLocalizedString partName; // 040 + BSFixedString goreObjectName; // 048 + TESModel explosionSpecialDebris; // 050 + PART_DATA data; // 080 + BGSArtObject* dismemberBlood; // 128 + BGSMaterialType* bloodImpactMaterial; // 130 + BGSMaterialType* onCrippleBloodImpactMaterial; // 138 + BGSTextureSet* meatCapTextureSet; // 140 + BGSTextureSet* meatCollarTextureSet; // 148 + }; + static_assert(sizeof(BGSBodyPart) == 0x150); class __declspec(novtable) BGSBodyPartData : public TESForm, // 000 diff --git a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h index d8bd2cd1..9d9adfa7 100644 --- a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h +++ b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h @@ -49,6 +49,7 @@ namespace RE class NiNode; class NiTransform; class NonActorMagicCaster; + class ShaderReferenceEffect; class SimpleAnimationGraphManagerLoadingTask; class TargetEntry; class TBO_InstanceData; @@ -206,11 +207,11 @@ namespace RE return func(this, a_variable, a_var); }; - bool RevertAnimationGraphManager(bool unk = true) + bool RevertAnimationGraphManager(bool a_performModifyInitialAnimationStateC = true) { using func_t = decltype(&IAnimationGraphManagerHolder::RevertAnimationGraphManager); REL::Relocation func{ REL::ID(41382) }; - return func(this, unk); + return func(this, a_performModifyInitialAnimationStateC); } }; static_assert(sizeof(IAnimationGraphManagerHolder) == 0x8); @@ -683,6 +684,34 @@ namespace RE return func(this); } + ModelReferenceEffect* ApplyArtObject( + BGSArtObject* a_art, + float a_time = -1.0f, + TESObjectREFR* a_facingRef = nullptr, + bool a_attachToCamera = false, + bool a_inheritRotation = false, + NiAVObject* a_3D = nullptr, + bool a_interfaceEffect = false) + { + using func_t = decltype(&TESObjectREFR::ApplyArtObject); + REL::Relocation func{ REL::ID(357908) }; + return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect); + } + + ShaderReferenceEffect* ApplyEffectShader( + TESEffectShader* a_art, + float a_time = -1.0f, + TESObjectREFR* a_facingRef = nullptr, + bool a_attachToCamera = false, + bool a_inheritRotation = false, + NiAVObject* a_3D = nullptr, + bool a_interfaceEffect = false) + { + using func_t = decltype(&TESObjectREFR::ApplyEffectShader); + REL::Relocation func{ REL::ID(652173) }; + return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect); + } + void Enable(bool a_resetInventory) { using func_t = decltype(&TESObjectREFR::Enable); @@ -708,6 +737,13 @@ namespace RE REL::Relocation func{ REL::ID(1135470) }; return func(this); } + + [[nodiscard]] const char* GetDisplayFullName() + { + using func_t = decltype(&TESObjectREFR::GetDisplayFullName); + REL::Relocation func{ REL::ID(1212056) }; + return func(this); + } [[nodiscard]] TESBoundObject* GetObjectReference() const noexcept { return data.objectReference; } diff --git a/CommonLibF4/include/RE/Bethesda/Utilities.h b/CommonLibF4/include/RE/Bethesda/Utilities.h index 73150c3b..0be37ccf 100644 --- a/CommonLibF4/include/RE/Bethesda/Utilities.h +++ b/CommonLibF4/include/RE/Bethesda/Utilities.h @@ -1,76 +1,86 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include "RE/Bethesda/Actor.h" +#include "RE/Bethesda/BSFixedString.h" +#include "RE/Bethesda/TESBoundObjects.h" +#include "RE/Bethesda/bhkPickData.h" +#include "RE/NetImmerse/NiAVObject.h" +#include "RE/NetImmerse/NiPoint3.h" namespace RE { namespace BSUtilities { - inline NiAVObject* GetObjectByName(NiAVObject* root, const BSFixedString& name, bool tryInternal, bool dontAttach) + inline NiAVObject* GetObjectByName(NiAVObject* a_root, const BSFixedString& a_name, bool a_tryInternal, bool a_dontAttach) { using func_t = decltype(&GetObjectByName); REL::Relocation func{ REL::ID(843650) }; - return func(root, name, tryInternal, dontAttach); + return func(a_root, a_name, a_tryInternal, a_dontAttach); } } namespace CombatUtilities { - inline bool CalculateProjectileTrajectory(const NiPoint3& pos, const NiPoint3& vel, float gravity, const NiPoint3& targetPos, float X, NiPoint3& out) + inline bool CalculateProjectileLOS( + Actor* a_actor, + BGSProjectile* a_projectile, + float a_projectileSpeed, + const NiPoint3& a_launchPos, + const NiPoint3& a_targetPos, + NiPoint3* a_hitPos, + TESObjectREFR** a_collidee, + float* a_distanceFraction) { - using func_t = decltype(&CalculateProjectileTrajectory); - REL::Relocation func{ REL::ID(1575156) }; - return func(pos, vel, gravity, targetPos, X, out); + using func_t = bool (*)(Actor*, BGSProjectile*, float, const NiPoint3&, const NiPoint3&, NiPoint3*, TESObjectREFR**, float*); + REL::Relocation func{ REL::ID(798616) }; + return func(a_actor, a_projectile, a_projectileSpeed, a_launchPos, a_targetPos, a_hitPos, a_collidee, a_distanceFraction); } - inline bool CalculateProjectileLOS(Actor* a, BGSProjectile* proj, float speed, const NiPoint3& launchPos, const NiPoint3& targetPos, NiPoint3* hitPos, TESObjectREFR** collidee, float* dist) + inline bool CalculateProjectileLOS(Actor* a_actor, BGSProjectile* a_projectile, bhkPickData& a_pickData) { - typedef bool func_t(Actor*, BGSProjectile*, float, const NiPoint3&, const NiPoint3&, NiPoint3*, TESObjectREFR**, float*); - REL::Relocation func{ REL::ID(798616) }; - return func(a, proj, speed, launchPos, targetPos, hitPos, collidee, dist); + using func_t = bool (*)(Actor*, BGSProjectile*, bhkPickData&); + REL::Relocation func{ REL::ID(55339) }; + return func(a_actor, a_projectile, a_pickData); } - inline bool CalculateProjectileLOS(Actor* a, BGSProjectile* proj, bhkPickData& pick) + inline bool CalculateProjectileTrajectory( + const NiPoint3& a_projectilePos, + const NiPoint3& a_projectileVelocity, + float a_projectileGravity, + const NiPoint3& a_targetPos, + float a_heading, + NiPoint3& a_trajectoryPos) { - typedef bool func_t(Actor*, BGSProjectile*, bhkPickData&); - REL::Relocation func{ REL::ID(55339) }; - return func(a, proj, pick); + using func_t = decltype(&CalculateProjectileTrajectory); + REL::Relocation func{ REL::ID(1575156) }; + return func(a_projectilePos, a_projectileVelocity, a_projectileGravity, a_targetPos, a_heading, a_trajectoryPos); } + static REL::Relocation fWorldGravity{ REL::ID(1378547) }; }; namespace AnimationSystemUtils { - inline bool WillEventChangeState(const TESObjectREFR& ref, const BSFixedString& evn) + inline bool WillEventChangeState(const TESObjectREFR& a_ref, const BSFixedString& a_evn) { using func_t = decltype(&WillEventChangeState); REL::Relocation func{ REL::ID(35074) }; - return func(ref, evn); + return func(a_ref, a_evn); } } namespace BGSAnimationSystemUtils { - inline bool InitializeActorInstant(Actor& a, bool b) - { - using func_t = decltype(&InitializeActorInstant); - REL::Relocation func{ REL::ID(672857) }; - return func(a, b); - } - struct ActiveSyncInfo { - BSTObjectArena> otherSyncInfo; - float currentAnimTime; - float animSpeedMult; - float totalAnimTime; + public: + // members + BSTObjectArena> otherSyncInfo; // 00 + float currentAnimTime; // 40 + float animSpeedMult; // 44 + float totalAnimTime; // 48 }; + static_assert(sizeof(ActiveSyncInfo) == 0x50); inline bool GetActiveSyncInfo(const IAnimationGraphManagerHolder* a_graphHolder, ActiveSyncInfo& a_infoOut) { @@ -79,6 +89,13 @@ namespace RE return func(a_graphHolder, a_infoOut); } + inline bool InitializeActorInstant(Actor& a_actor, bool a_update3D) + { + using func_t = decltype(&InitializeActorInstant); + REL::Relocation func{ REL::ID(672857) }; + return func(a_actor, a_update3D); + } + inline bool IsActiveGraphInTransition(const TESObjectREFR* a_refr) { using func_t = decltype(&IsActiveGraphInTransition); diff --git a/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h b/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h index a598137d..97a43eb5 100644 --- a/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h +++ b/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h @@ -13,9 +13,9 @@ #include "RE/Havok/hknpCharacterSurfaceInfo.h" #include "RE/NetImmerse/NiCollisionObject.h" #include "RE/NetImmerse/NiFlags.h" +#include "RE/NetImmerse/NiMatrix3.h" #include "RE/NetImmerse/NiPoint3.h" #include "RE/NetImmerse/NiSmartPointer.h" -#include namespace RE { @@ -32,10 +32,14 @@ namespace RE class bhkWorld; class hknpBody; class hknpShape; + + struct DamageImpactData; + struct MoveData; + class hknpMotionPropertiesId { public: - enum Preset + enum class Preset { STATIC = 0, ///< No velocity allowed DYNAMIC, ///< For regular dynamic bodies, undamped and gravity factor = 1 @@ -50,18 +54,16 @@ namespace RE class hkTransformf { public: - void setIdentity() + void SetIdentity() { - m_rotation.MakeIdentity(); - m_translation = NiPoint4(); + rotation.MakeIdentity(); + translation = NiPoint4(); } - NiMatrix3 m_rotation; - NiPoint4 m_translation; + // members + NiMatrix3 rotation; + NiPoint4 translation; }; - typedef hkTransformf hkTransform; - - struct DamageImpactData; - struct MoveData; + using hkTransform = hkTransformf; class CFilter { diff --git a/CommonLibF4/include/RE/Bethesda/bhkPickData.h b/CommonLibF4/include/RE/Bethesda/bhkPickData.h index a6c8b7f2..c098b984 100644 --- a/CommonLibF4/include/RE/Bethesda/bhkPickData.h +++ b/CommonLibF4/include/RE/Bethesda/bhkPickData.h @@ -1,15 +1,14 @@ #pragma once -#include -#include -#include -#include -#include -#include +#include "RE/Bethesda/MemoryManager.h" +#include "RE/Bethesda/bhkCharacterController.h" +#include "RE/Havok/hkVector4.h" +#include "RE/Havok/hknpCollisionResult.h" +#include "RE/NetImmerse/NiPoint3.h" namespace RE { - struct __declspec(novtable) bhkPickData + struct bhkPickData { public: bhkPickData() @@ -19,6 +18,8 @@ namespace RE func(this); } + F4_HEAP_REDEFINE_NEW(bhkPickData); + void SetStartEnd(const NiPoint3& start, const NiPoint3& end) { using func_t = decltype(&bhkPickData::SetStartEnd); @@ -82,6 +83,7 @@ namespace RE return func(this); } + // members std::uint64_t field_0; std::uint16_t field_8; CFilter collisionFilter; @@ -99,7 +101,6 @@ namespace RE __int16 field_DC; char field_DE; char field_DF; - F4_HEAP_REDEFINE_NEW(bhkPickData); }; static_assert(sizeof(bhkPickData) == 0xE0); }; diff --git a/CommonLibF4/include/RE/Fallout.h b/CommonLibF4/include/RE/Fallout.h index 11a90e9b..33b33f89 100644 --- a/CommonLibF4/include/RE/Fallout.h +++ b/CommonLibF4/include/RE/Fallout.h @@ -27,6 +27,7 @@ #include "RE/Bethesda/BGSSynchronizedAnimationManager.h" #include "RE/Bethesda/BGSTextureSet.h" #include "RE/Bethesda/BSAnimationGraph.h" +#include "RE/Bethesda/BSAttachTechniques.h" #include "RE/Bethesda/BSAudioManager.h" #include "RE/Bethesda/BSAudioUtil.h" #include "RE/Bethesda/BSBTreeFile.h" @@ -35,6 +36,7 @@ #include "RE/Bethesda/BSExtraData.h" #include "RE/Bethesda/BSFadeNode.h" #include "RE/Bethesda/BSFixedString.h" +#include "RE/Bethesda/BSGeometry.h" #include "RE/Bethesda/BSGraphics.h" #include "RE/Bethesda/BSHavok.h" #include "RE/Bethesda/BSInputDeviceManager.h" @@ -116,6 +118,8 @@ #include "RE/Bethesda/BSScriptUtil.h" #include "RE/Bethesda/BSSemaphore.h" #include "RE/Bethesda/BSShader.h" +#include "RE/Bethesda/BSShaderMaterial.h" +#include "RE/Bethesda/BSShaderProperty.h" #include "RE/Bethesda/BSSoundHandle.h" #include "RE/Bethesda/BSSpring.h" #include "RE/Bethesda/BSStorage.h" @@ -141,11 +145,12 @@ #include "RE/Bethesda/BSTSmartPointer.h" #include "RE/Bethesda/BSTTuple.h" #include "RE/Bethesda/BSTempEffect.h" -#include "RE/Bethesda/BSTempEffectDebris.h" +#include "RE/Bethesda/BSTextureDB.h" #include "RE/Bethesda/BSTextureSet.h" #include "RE/Bethesda/BSTextureStreamer.h" #include "RE/Bethesda/BSThread.h" #include "RE/Bethesda/BSTimer.h" +#include "RE/Bethesda/BSVisit.h" #include "RE/Bethesda/CELLJobs.h" #include "RE/Bethesda/CRC.h" #include "RE/Bethesda/Calendar.h" @@ -188,12 +193,14 @@ #include "RE/Bethesda/PowerUtils.h" #include "RE/Bethesda/ProcessLists.h" #include "RE/Bethesda/Projectiles.h" +#include "RE/Bethesda/ReferenceEffectController.h" #include "RE/Bethesda/SCRIPT_OUTPUT.h" #include "RE/Bethesda/SDirectory2.h" #include "RE/Bethesda/SWFToCodeFunctionHandler.h" #include "RE/Bethesda/Script.h" #include "RE/Bethesda/SendHUDMessage.h" #include "RE/Bethesda/Settings.h" +#include "RE/Bethesda/Sky.h" #include "RE/Bethesda/SplineUtils.h" #include "RE/Bethesda/TESBoundAnimObjects.h" #include "RE/Bethesda/TESBoundObjects.h" diff --git a/CommonLibF4/include/RE/Havok/hknpClosestHitCollector.h b/CommonLibF4/include/RE/Havok/hknpClosestHitCollector.h index 33363c7d..c64f5399 100644 --- a/CommonLibF4/include/RE/Havok/hknpClosestHitCollector.h +++ b/CommonLibF4/include/RE/Havok/hknpClosestHitCollector.h @@ -28,9 +28,8 @@ namespace RE const hknpCollisionResult* GetHits() const override; // 05 // members - hknpCollisionResult result; //0x20 - bool hasHit; //0x80 - int8_t pad[15]; + hknpCollisionResult result; // 20 + bool hasHit; // 80 }; static_assert(sizeof(hknpClosestHitCollector) == 0x90); } diff --git a/CommonLibF4/include/RE/NetImmerse/NiAVObject.h b/CommonLibF4/include/RE/NetImmerse/NiAVObject.h index 4a5e5f05..e7896dbf 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiAVObject.h +++ b/CommonLibF4/include/RE/NetImmerse/NiAVObject.h @@ -51,6 +51,8 @@ namespace RE [[nodiscard]] bool GetAppCulled() const noexcept { return flags.flags & 1; } [[nodiscard]] std::uint64_t GetFlags() const noexcept { return flags.flags; } [[nodiscard]] bool ShadowCaster() const noexcept { return ~(flags.flags >> 40) & 1; } + void CullGeometry(bool a_cull); + void CullNode(bool a_cull); void Update(NiUpdateData& a_data); // members diff --git a/CommonLibF4/include/RE/NetImmerse/NiAlphaProperty.h b/CommonLibF4/include/RE/NetImmerse/NiAlphaProperty.h index 89ac6c80..dffb75c2 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiAlphaProperty.h +++ b/CommonLibF4/include/RE/NetImmerse/NiAlphaProperty.h @@ -55,6 +55,8 @@ namespace RE return 0; } + F4_HEAP_REDEFINE_ALIGNED_NEW(NiAlphaProperty); + void SetDestBlendMode(AlphaFunction f) { using func_t = decltype(&NiAlphaProperty::SetDestBlendMode); @@ -93,8 +95,6 @@ namespace RE // members NiTFlags flags; // 28 std::int8_t alphaTestRef; // 2A - - F4_HEAP_REDEFINE_ALIGNED_NEW(NiAlphaProperty); }; static_assert(sizeof(NiAlphaProperty) == 0x30); } diff --git a/CommonLibF4/include/RE/NetImmerse/NiCloningProcess.h b/CommonLibF4/include/RE/NetImmerse/NiCloningProcess.h index 19841497..78b7ec44 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiCloningProcess.h +++ b/CommonLibF4/include/RE/NetImmerse/NiCloningProcess.h @@ -1,20 +1,28 @@ #pragma once -#include +#include "RE/Bethesda/BSTHashMap.h" +#include "RE/NetImmerse/NiPoint3.h" namespace RE { + class NiObject; + class NiCloningProcess { public: - BSTHashMap unk00; // 00 - void* unk30; // 30 - std::uint64_t unk38; // 38 - std::uint64_t unk40; // 40 - void* unk48; // 48 - DEADBEEF - void* unk50; // 50 - bucket - std::uint64_t unk58; // 58 - std::uint32_t unk60; // 60 - copytype? 0, 1, 2 - std::uint32_t unk64; // 64 + enum class CopyType + { + kNone = 0, + kCopyExact, + kCopyUnique, + }; + + // members + BSTHashMap cloneMap; // 00 + BSTHashMap processMap; // 30 + stl::enumeration copyType; // 60 + char appendChar; // 64 + NiPoint3 scale; // 68 }; + static_assert(sizeof(NiCloningProcess) == 0x78); } diff --git a/CommonLibF4/include/RE/NetImmerse/NiObjectNET.h b/CommonLibF4/include/RE/NetImmerse/NiObjectNET.h index 0ad9a913..9b29d5f6 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiObjectNET.h +++ b/CommonLibF4/include/RE/NetImmerse/NiObjectNET.h @@ -31,7 +31,7 @@ namespace RE [[nodiscard]] std::string_view GetName() const { return name; } - [[nodiscard]] NiExtraData* GetExtraData(BSFixedString name) const noexcept; + [[nodiscard]] NiExtraData* GetExtraData(BSFixedString a_key) const noexcept; // members BSFixedString name{ "" }; // 10 diff --git a/CommonLibF4/include/RE/NetImmerse/NiRTTI.h b/CommonLibF4/include/RE/NetImmerse/NiRTTI.h index c7598748..0581281c 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiRTTI.h +++ b/CommonLibF4/include/RE/NetImmerse/NiRTTI.h @@ -6,10 +6,124 @@ namespace RE { public: [[nodiscard]] constexpr const char* GetName() const noexcept { return name; } + [[nodiscard]] constexpr const NiRTTI* GetBaseRTTI() const noexcept { return baseRTTI; } + + [[nodiscard]] constexpr bool IsKindOf(const NiRTTI* a_rtti) const noexcept + { + for (auto iter = this; iter; iter = iter->GetBaseRTTI()) { + if (iter == a_rtti) { + return true; + } + } + return false; + } // members const char* name; // 00 NiRTTI* baseRTTI; // 08 }; static_assert(sizeof(NiRTTI) == 0x10); + + namespace Ni_Impl + { + template + using remove_cvpr_t = + std::remove_pointer_t< + std::remove_reference_t< + std::remove_cv_t>>; + + template + struct types_are_compat : + std::false_type + {}; + + template + struct types_are_compat : + std::is_lvalue_reference< + std::remove_cv_t> + {}; + + template + struct types_are_compat : + std::is_pointer< + std::remove_cv_t> + {}; + + template + struct is_base_of_no_cvpr : + std::is_base_of< + remove_cvpr_t, + remove_cvpr_t> + {}; + + template + struct _has_rtti : + std::false_type + {}; + + template + struct _has_rtti> : + std::true_type + {}; + + template + struct has_rtti : + _has_rtti> + {}; + + template + struct cast_is_valid : + std::conjunction< + types_are_compat, + is_base_of_no_cvpr, + has_rtti, + has_rtti> + {}; + + template + inline constexpr bool cast_is_valid_v = cast_is_valid::value; + } +} + +// downcast +template < + class To, + class From, + std::enable_if_t< + RE::Ni_Impl::cast_is_valid_v< + To, + const From*>, + int> = 0> +To netimmerse_cast(const From* a_from) +{ + if (!a_from) { + return nullptr; + } + + REL::Relocation to{ RE::Ni_Impl::remove_cvpr_t::Ni_RTTI }; + + const RE::NiRTTI* toRTTI = to.get(); + const RE::NiRTTI* fromRTTI = a_from->GetRTTI(); + while (fromRTTI) { + if (fromRTTI == toRTTI) { + return static_cast(const_cast(a_from)); + } + fromRTTI = fromRTTI->GetBaseRTTI(); + } + + return nullptr; +} + +// upcast +template < + class To, + class From, + std::enable_if_t< + RE::Ni_Impl::cast_is_valid_v< + const From*, + To>, + int> = 0> +To netimmerse_cast(const From* a_from) +{ + return static_cast(const_cast(a_from)); } diff --git a/CommonLibF4/include/RE/NetImmerse/NiStringExtraData.h b/CommonLibF4/include/RE/NetImmerse/NiStringExtraData.h index 86548b4a..02be4e33 100644 --- a/CommonLibF4/include/RE/NetImmerse/NiStringExtraData.h +++ b/CommonLibF4/include/RE/NetImmerse/NiStringExtraData.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "RE/NetImmerse/NiExtraData.h" namespace RE { @@ -11,6 +11,8 @@ namespace RE static constexpr auto VTABLE{ VTABLE::NiStringExtraData }; static constexpr auto Ni_RTTI{ Ni_RTTI::NiStringExtraData }; - BSFixedString data; //0x18 + // members + BSFixedString data; // 18 }; + static_assert(sizeof(NiStringExtraData) == 0x20); } diff --git a/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h b/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h index 4c79b7cf..1168c00d 100644 --- a/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h +++ b/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h @@ -330,6 +330,13 @@ namespace RE::Scaleform::GFx return func(this, a_data, a_name, a_isdobj); } + std::uint32_t GetArraySize(void* a_data) const + { + using func_t = decltype(&ObjectInterface::GetArraySize); + REL::Relocation func{ REL::ID(254218) }; + return func(this, a_data); + } + bool GetMember(void* a_data, const char* a_name, Value* a_val, bool a_isdobj) const { using func_t = decltype(&ObjectInterface::GetMember); @@ -358,11 +365,29 @@ namespace RE::Scaleform::GFx return func(this, a_data, a_value); } + bool RemoveElements(void* a_data, std::uint32_t a_idx, std::int32_t a_count) + { + using func_t = decltype(&ObjectInterface::RemoveElements); + REL::Relocation func{ REL::ID(1286586) }; + return func(this, a_data, a_idx, a_count); + } + + void VisitMembers(void* a_data, ObjVisitor* a_visitor, bool a_isDObj) const + { + using func_t = decltype(&ObjectInterface::VisitMembers); + REL::Relocation func{ REL::ID(1276961) }; + return func(this, a_data, a_visitor, a_isDObj); + } + // members MovieImpl* movieRoot; // 08 }; static_assert(sizeof(ObjectInterface) == 0x10); + using ObjectVisitor = ObjectInterface::ObjVisitor; + using ArrayVisitor = ObjectInterface::ArrVisitor; + using ObjectVisitFn = std::function; + Value() noexcept = default; Value(const Value& a_rhs) : @@ -415,11 +440,21 @@ namespace RE::Scaleform::GFx _value(a_rhs) {} + Value(std::string_view a_rhs) noexcept : + _type(ValueType::kString), + _value(a_rhs.data()) + {} + Value(const wchar_t* a_rhs) noexcept : _type(ValueType::kStringW), _value(a_rhs) {} + Value(std::wstring_view a_rhs) noexcept : + _type(ValueType::kStringW), + _value(a_rhs.data()) + {} + ~Value() { if (IsManagedValue()) { @@ -603,6 +638,43 @@ namespace RE::Scaleform::GFx return _objectInterface->HasMember(_value.data, a_name.data(), IsDisplayObject()); } + void VisitMembers(ObjectVisitor* a_visitor) const + { + assert(IsObject()); + return _objectInterface->VisitMembers(_value.data, a_visitor, IsDisplayObject()); + } + + void VisitMembers(ObjectVisitFn&& a_visitor) const + { + assert(IsObject()); + + struct MemberVisitor : ObjectInterface::ObjVisitor + { + public: + MemberVisitor(ObjectVisitFn&& a_fn) : + _fn(a_fn) {} + + void Visit(const char* a_name, const Value& a_val) override + { + if (_fn) { + _fn(a_name, a_val); + } + } + + private: + ObjectVisitFn _fn; + }; + + MemberVisitor visitor{ std::forward(a_visitor) }; + return _objectInterface->VisitMembers(_value.data, std::addressof(visitor), IsDisplayObject()); + } + + std::uint32_t GetArraySize() const + { + assert(IsArray()); + return _objectInterface->GetArraySize(_value.data); + } + bool GetMember(stl::zstring a_name, Value* a_val) const { assert(IsObject()); @@ -626,12 +698,40 @@ namespace RE::Scaleform::GFx return Invoke(a_name, a_result, nullptr, 0); } + template + inline bool Invoke(const char* a_name, const std::array& a_args) + { + return Invoke(a_name, nullptr, a_args); + } + + template + inline bool Invoke(const char* a_name, Value* a_result, const std::array& a_args) + { + return Invoke(a_name, a_result, a_args.data(), a_args.size()); + } + bool PushBack(const Value& a_val) { assert(IsArray()); return _objectInterface->PushBack(_value.data, a_val); } + bool RemoveElements(std::uint32_t a_idx, std::int32_t a_count = -1) + { + assert(IsArray()); + return _objectInterface->RemoveElements(_value.data, a_idx, a_count); + } + + bool RemoveElement(std::uint32_t a_idx) + { + return RemoveElements(a_idx, 1); + } + + bool ClearElements() + { + return RemoveElements(0); + } + [[nodiscard]] Movie* GetMovie() const { assert(_objectInterface && _objectInterface->movieRoot); @@ -848,6 +948,10 @@ namespace RE::Scaleform::GFx void CreateFunction(Value* a_value, FunctionHandler* a_function, void* a_userData = nullptr); void CreateObject(Value* a_value, const char* a_className = nullptr, const GFx::Value* a_args = nullptr, std::uint32_t a_numArgs = 0); bool GetVariable(Value* a_val, const char* a_pathToVar) const; + bool SetVariable(const char* a_pathToVar, const Value& a_value, SetVarType a_setType = SetVarType::kSticky); + bool Invoke(const char* a_methodName, Value* a_result, const char* a_argFmt, ...); + bool Invoke(const char* a_methodName, Value* a_result, const Value* a_args, std::uint32_t a_numArgs); + bool InvokeArgs(const char* a_methodName, Value* a_result, const char* a_argFmt, std::va_list a_args); void Release() { diff --git a/CommonLibF4/src/F4SE/Impl/WinAPI.cpp b/CommonLibF4/src/F4SE/Impl/WinAPI.cpp index 9ef6ede1..079f59c2 100644 --- a/CommonLibF4/src/F4SE/Impl/WinAPI.cpp +++ b/CommonLibF4/src/F4SE/Impl/WinAPI.cpp @@ -22,7 +22,7 @@ #define NOGDI #define NOKERNEL //#define NOUSER -#define NONLS +//#define NONLS //#define NOMB #define NOMEMMGR #define NOMETAFILE @@ -230,6 +230,22 @@ namespace F4SE::WinAPI static_cast<::UINT>(a_type))); } + int(MultiByteToWideChar)( + unsigned int a_codePage, + std::uint32_t a_flags, + const char* a_multiByteStr, + int a_multiByte, + wchar_t* a_wideCharStr, int a_wideChar) + { + return ::MultiByteToWideChar( + static_cast<::UINT>(a_codePage), + static_cast<::DWORD>(a_flags), + static_cast<::LPCCH>(a_multiByteStr), + a_multiByte, + static_cast<::LPWSTR>(a_wideCharStr), + a_wideChar); + } + void(OutputDebugString)( const char* a_outputString) noexcept { @@ -323,4 +339,23 @@ namespace F4SE::WinAPI static_cast<::DWORD>(a_newProtect), reinterpret_cast<::PDWORD>(a_oldProtect))); } + int WideCharToMultiByte( + unsigned int a_codePage, + std::uint32_t a_flags, + const wchar_t* a_wideCharStr, + int a_wideChar, + char* a_multiByteStr, + int a_multiByte, + const char* a_defaultChar, int* a_usedDefaultChar) + { + return ::WideCharToMultiByte( + static_cast<::UINT>(a_codePage), + static_cast<::DWORD>(a_flags), + static_cast<::LPCWCH>(a_wideCharStr), + a_wideChar, + static_cast<::LPSTR>(a_multiByteStr), + a_multiByte, + static_cast<::LPCCH>(a_defaultChar), + static_cast<::LPBOOL>(a_usedDefaultChar)); + } } diff --git a/CommonLibF4/src/RE/Bethesda/BSVisit.cpp b/CommonLibF4/src/RE/Bethesda/BSVisit.cpp new file mode 100644 index 00000000..5e7dc9be --- /dev/null +++ b/CommonLibF4/src/RE/Bethesda/BSVisit.cpp @@ -0,0 +1,60 @@ +#include "RE/Bethesda/BSVisit.h" + +#include "RE/NetImmerse/NiAVObject.h" +#include "RE/NetImmerse/NiNode.h" + +namespace RE +{ + namespace BSVisit + { + BSVisitControl TraverseScenegraphGeometries(NiAVObject* a_object, std::function a_func) + { + if (!a_object) { + return BSVisitControl::kContinue; + } + + auto geom = a_object->IsGeometry(); + if (geom) { + return a_func(geom); + } + + auto result = BSVisitControl::kContinue; + auto node = a_object->IsNode(); + if (node) { + for (auto& child : node->children) { + result = TraverseScenegraphGeometries(child.get(), a_func); + if (result == BSVisitControl::kStop) { + break; + } + } + } + + return result; + } + + BSVisitControl TraverseScenegraphObjects(NiAVObject* a_object, std::function a_func) + { + if (!a_object) { + return BSVisitControl::kContinue; + } + + auto result = a_func(a_object); + if (result == BSVisitControl::kStop) { + return result; + } + + result = BSVisitControl::kContinue; + auto node = a_object->IsNode(); + if (node) { + for (auto& child : node->children) { + result = TraverseScenegraphObjects(child.get(), a_func); + if (result == BSVisitControl::kStop) { + break; + } + } + } + + return result; + } + } +} diff --git a/CommonLibF4/src/RE/Bethesda/FormComponents.cpp b/CommonLibF4/src/RE/Bethesda/FormComponents.cpp index fa9905a2..7a2c3e4c 100644 --- a/CommonLibF4/src/RE/Bethesda/FormComponents.cpp +++ b/CommonLibF4/src/RE/Bethesda/FormComponents.cpp @@ -13,7 +13,7 @@ namespace RE { return BGSKeyword::GetTypedKeywordByIndex(a_type, a_index); } - uint16_t BGSKeywordGetIndexForTypedKeyword(BGSKeyword* a_keyword, KeywordType a_type) + std::uint16_t BGSKeywordGetIndexForTypedKeyword(BGSKeyword* a_keyword, KeywordType a_type) { return BGSKeyword::GetIndexForTypedKeyword(a_keyword, a_type); } diff --git a/CommonLibF4/src/RE/NetImmerse/NiAVObject.cpp b/CommonLibF4/src/RE/NetImmerse/NiAVObject.cpp index 2b593436..3a54dd61 100644 --- a/CommonLibF4/src/RE/NetImmerse/NiAVObject.cpp +++ b/CommonLibF4/src/RE/NetImmerse/NiAVObject.cpp @@ -1,5 +1,7 @@ #include "RE/NetImmerse/NiAVObject.h" +#include "RE/Bethesda/BSGeometry.h" +#include "RE/Bethesda/BSVisit.h" #include "RE/NetImmerse/NiCollisionObject.h" #include "RE/NetImmerse/NiNode.h" #include "RE/NetImmerse/NiUpdateData.h" @@ -17,6 +19,22 @@ namespace RE NiAVObject::~NiAVObject() {} // NOLINT(modernize-use-equals-default) + void NiAVObject::CullGeometry(bool a_cull) + { + BSVisit::TraverseScenegraphGeometries(this, [&](BSGeometry* a_geo) -> BSVisit::BSVisitControl { + a_geo->SetAppCulled(a_cull); + return BSVisit::BSVisitControl::kContinue; + }); + } + + void NiAVObject::CullNode(bool a_cull) + { + BSVisit::TraverseScenegraphObjects(this, [&](NiAVObject* a_object) -> BSVisit::BSVisitControl { + a_object->SetAppCulled(a_cull); + return BSVisit::BSVisitControl::kContinue; + }); + } + void NiAVObject::Update(NiUpdateData& a_data) { UpdateDownwardPass(a_data, 0); diff --git a/CommonLibF4/src/RE/NetImmerse/NiObjectNET.cpp b/CommonLibF4/src/RE/NetImmerse/NiObjectNET.cpp index 722c9daa..730043dd 100644 --- a/CommonLibF4/src/RE/NetImmerse/NiObjectNET.cpp +++ b/CommonLibF4/src/RE/NetImmerse/NiObjectNET.cpp @@ -7,11 +7,12 @@ namespace RE NiObjectNET::NiObjectNET() { stl::emplace_vtable(this); } NiObjectNET::~NiObjectNET() {} - NiExtraData* NiObjectNET::GetExtraData(BSFixedString n) const noexcept + + NiExtraData* NiObjectNET::GetExtraData(BSFixedString a_key) const noexcept { if (extra) { for (auto it = extra->begin(); it != extra->end(); ++it) { - if ((*it)->name == n) { + if ((*it)->name == a_key) { return *it; } } diff --git a/CommonLibF4/src/RE/Scaleform/GFx/GFx_Player.cpp b/CommonLibF4/src/RE/Scaleform/GFx/GFx_Player.cpp index 61e93237..158fabf9 100644 --- a/CommonLibF4/src/RE/Scaleform/GFx/GFx_Player.cpp +++ b/CommonLibF4/src/RE/Scaleform/GFx/GFx_Player.cpp @@ -23,4 +23,24 @@ namespace RE::Scaleform::GFx { return asMovieRoot->GetVariable(a_val, a_pathToVar); } + + bool Movie::SetVariable(const char* a_pathToVar, const Value& a_value, SetVarType a_setType) + { + return asMovieRoot->SetVariable(a_pathToVar, a_value, a_setType); + } + + bool Movie::Invoke(const char* a_methodName, Value* a_result, const char* a_argFmt, ...) + { + return asMovieRoot->Invoke(a_methodName, a_result, a_argFmt); + } + + bool Movie::Invoke(const char* a_methodName, Value* a_result, const Value* a_args, std::uint32_t a_numArgs) + { + return asMovieRoot->Invoke(a_methodName, a_result, a_args, a_numArgs); + } + + bool Movie::InvokeArgs(const char* a_methodName, Value* a_result, const char* a_argFmt, std::va_list a_args) + { + return asMovieRoot->InvokeArgs(a_methodName, a_result, a_argFmt, a_args); + } } diff --git a/ExampleProject/src/main.cpp b/ExampleProject/src/main.cpp index d9f7cbe4..bdc1f7f7 100644 --- a/ExampleProject/src/main.cpp +++ b/ExampleProject/src/main.cpp @@ -44,11 +44,35 @@ extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Query(const F4SE::QueryInterface* a return true; } + +void MessageCallback(F4SE::MessagingInterface::Message* msg) +{ + switch (msg->type) + { + case F4SE::MessagingInterface::kGameDataReady: + break; + case F4SE::MessagingInterface::kNewGame: + break; + case F4SE::MessagingInterface::kPostPostLoad: + break; + default: + break; + } + +} + + extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Load(const F4SE::LoadInterface* a_f4se) { F4SE::Init(a_f4se); logger::info("hello world!"); + if (!F4SE::GetMessagingInterface()->RegisterListener(MessageCallback)) + { + logger::info("Cannot register listener!"); + return false; + } + return true; }