diff --git a/Code/client/Games/Primitives.h b/Code/client/Games/Primitives.h index 24eaed5e2..75e5abab2 100644 --- a/Code/client/Games/Primitives.h +++ b/Code/client/Games/Primitives.h @@ -263,7 +263,7 @@ struct GamePtr return *this; } - GamePtr& operator=(GamePtr&& acRhs) + GamePtr& operator=(GamePtr&& aRhs) { std::swap(m_pPointer, aRhs.m_pPointer); diff --git a/Code/client/Games/References.cpp b/Code/client/Games/References.cpp index e5f362c1e..d23169937 100644 --- a/Code/client/Games/References.cpp +++ b/Code/client/Games/References.cpp @@ -497,6 +497,12 @@ void TESObjectREFR::LockChange() noexcept ThisCall(RealLockChange, this); } +const float TESObjectREFR::GetHeight() noexcept +{ + auto boundMax = GetBoundMax(); + return boundMax.z - GetBoundMin().z; +} + bool ActorState::SetWeaponDrawn(bool aDraw) noexcept { TP_THIS_FUNCTION(TSetWeaponState, bool, ActorState, bool aDraw); diff --git a/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.cpp b/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.cpp new file mode 100644 index 000000000..5b3751c69 --- /dev/null +++ b/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.cpp @@ -0,0 +1,26 @@ + +#include +#include + +namespace HUDMenuUtils +{ +static float (*CameraWorldToCam)[4][4] = nullptr; +static const NiRect* CameraPort = nullptr; + +bool WorldPtToScreenPt3(const NiPoint3& arWorldPt, NiPoint3& arScreenPt) +{ + return NiCamera::WorldPtToScreenPt3(reinterpret_cast(CameraWorldToCam), CameraPort, &arWorldPt, + &arScreenPt.x, &arScreenPt.y, &arScreenPt.z, 1e-5f); +} +} // namespace HUDMenuUtils + +static TiltedPhoques::Initializer s_Init([]() { + POINTER_FALLOUT4(float[4][4], s_matrix, 0x145A66AA0 - 0x140000000); + POINTER_FALLOUT4(NiRect, s_port, 0x145A66B30 - 0x140000000); + + POINTER_SKYRIMSE(float[4][4], s_matrix, 0x142FE75F0 - 0x140000000); + POINTER_SKYRIMSE(NiRect, s_port, 0x142FE8B98 - 0x140000000); + + HUDMenuUtils::CameraWorldToCam = s_matrix.Get(); + HUDMenuUtils::CameraPort = s_port.Get(); +}); diff --git a/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.h b/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.h new file mode 100644 index 000000000..5401fc6e9 --- /dev/null +++ b/Code/client/Games/Skyrim/Interface/Menus/HUDMenuUtils.h @@ -0,0 +1,6 @@ +#pragma once + +namespace HUDMenuUtils +{ +bool WorldPtToScreenPt3(const NiPoint3& arWorldPt, NiPoint3& arScreenPt); +} diff --git a/Code/client/Games/Skyrim/NetImmerse/NiCamera.cpp b/Code/client/Games/Skyrim/NetImmerse/NiCamera.cpp index ca1a325c8..f2539f629 100644 --- a/Code/client/Games/Skyrim/NetImmerse/NiCamera.cpp +++ b/Code/client/Games/Skyrim/NetImmerse/NiCamera.cpp @@ -1,7 +1,7 @@ #include #include -using TWorldPtToScreenPt3 = bool(float*, const NiRect*, NiPoint3*, float*, float*, float*, float); +using TWorldPtToScreenPt3 = bool(float*, const NiRect*, const NiPoint3*, float*, float*, float*, float); static TWorldPtToScreenPt3* s_WorldPtToScreenPt3; bool NiCamera::WorldPtToScreenPt3(const NiPoint3& in, NiPoint3& out, float tolerance) @@ -12,7 +12,7 @@ bool NiCamera::WorldPtToScreenPt3(const NiPoint3& in, NiPoint3& out, float toler return ThisCall(s_w2s, this, &in, &out.x, &out.y, &out.y, tolerance); } -bool NiCamera::WorldPtToScreenPt3(float* matrix, const NiRect* port, NiPoint3* p_in, float* x_out, float* y_out, +bool NiCamera::WorldPtToScreenPt3(float* matrix, const NiRect* port, const NiPoint3* p_in, float* x_out, float* y_out, float* z_out, float zeroTolerance) { return s_WorldPtToScreenPt3(matrix, port, p_in, x_out, y_out, z_out, zeroTolerance); diff --git a/Code/client/Games/Skyrim/NetImmerse/NiCamera.h b/Code/client/Games/Skyrim/NetImmerse/NiCamera.h index d94938fc2..7bb6701a2 100644 --- a/Code/client/Games/Skyrim/NetImmerse/NiCamera.h +++ b/Code/client/Games/Skyrim/NetImmerse/NiCamera.h @@ -18,8 +18,8 @@ struct NiCamera : public NiAVObject bool WorldPtToScreenPt3(const NiPoint3& in, NiPoint3& out, float zeroTolerance = 1e-5f); - static bool WorldPtToScreenPt3(float* matrix, const NiRect* port, NiPoint3* p_in, float* x_out, float* y_out, - float* z_out, float zeroTolerance = 1e-5f); + static bool WorldPtToScreenPt3(float* matrix, const NiRect* port, const NiPoint3* p_in, float* x_out, + float* y_out, float* z_out, float zeroTolerance = 1e-5f); NiNode* parent; NiAVObject* unk; diff --git a/Code/client/Games/Skyrim/TESObjectREFR.h b/Code/client/Games/Skyrim/TESObjectREFR.h index 9efb88e03..253983f58 100644 --- a/Code/client/Games/Skyrim/TESObjectREFR.h +++ b/Code/client/Games/Skyrim/TESObjectREFR.h @@ -169,6 +169,8 @@ struct TESObjectREFR : TESForm Lock* CreateLock() noexcept; void LockChange() noexcept; + const float GetHeight() noexcept; + BSHandleRefObject handleRefObject; uintptr_t unk1C; IAnimationGraphManagerHolder animationGraphHolder; diff --git a/Code/client/Services/Debug/TestService.cpp b/Code/client/Services/Debug/TestService.cpp index 7383dcd81..f38c6109c 100644 --- a/Code/client/Services/Debug/TestService.cpp +++ b/Code/client/Services/Debug/TestService.cpp @@ -236,24 +236,15 @@ void TestService::OnDraw() noexcept } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Engine")) - { - ImGui::MenuItem("Open Rage Tab", NULL, nullptr); - ImGui::EndMenu(); - } if (ImGui::BeginMenu("Player")) { DrawPlayerDebugView(); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Entities")) - { - ImGui::MenuItem("Open Rage Tab", NULL, nullptr); - ImGui::EndMenu(); - } if (ImGui::BeginMenu("Components")) { - DrawComponentDebugView(); + ImGui::MenuItem("Show component list", nullptr, &m_bToggleComponentWindow); + ImGui::MenuItem("Show selected component in world", nullptr, &m_bDrawComponentInScreenSpace); ImGui::EndMenu(); } if (ImGui::BeginMenu("Containers")) @@ -266,13 +257,11 @@ void TestService::OnDraw() noexcept ImGui::MenuItem("Toggle anim window", nullptr, &g_EnableAnimWindow); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Misc")) - { - ImGui::MenuItem("Open Rage Tab", NULL, nullptr); - ImGui::EndMenu(); - } ImGui::EndMainMenuBar(); if (g_EnableAnimWindow) DrawAnimDebugView(); + + if (m_bToggleComponentWindow) + DrawComponentDebugView(); } diff --git a/Code/client/Services/Debug/Views/ComponentView.cpp b/Code/client/Services/Debug/Views/ComponentView.cpp index 4fa3565c7..afe739f5f 100644 --- a/Code/client/Services/Debug/Views/ComponentView.cpp +++ b/Code/client/Services/Debug/Views/ComponentView.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -12,61 +13,45 @@ #include -// Note(Force): Here for now, we decide on a proper place for this later. namespace { -static float (*guimatrix)[4][4] = nullptr; -static NiRect* guiport = nullptr; - -static TiltedPhoques::Initializer s_Init([]() { - POINTER_FALLOUT4(float[4][4], s_matrix, 0x145A66AA0 - 0x140000000); - POINTER_FALLOUT4(NiRect, s_port, 0x145A66B30 - 0x140000000); - - POINTER_SKYRIMSE(float[4][4], s_matrix, 0x142FE75F0 - 0x140000000); - POINTER_SKYRIMSE(NiRect, s_port, 0x142FE8B98 - 0x140000000); - - guimatrix = s_matrix.Get(); - guiport = s_port.Get(); -}); +#if 0 +constexpr float fFloatQuestMarkerMaxDistance = 2000.f; +constexpr float fFloatQuestMarkerMinDistance = 1000.f; -bool HUD_WorldPtToScreenPt3(NiPoint3* in, NiPoint3* out) +float CalculateFloatingQuestMarkerAlpha() { - return NiCamera::WorldPtToScreenPt3(reinterpret_cast(guimatrix), guiport, in, &out->x, &out->y, &out->z, - 1e-5f); + float v1 = fsqrt((__m128)LODWORD(this->fDistanceToPlayerSqr)).m128_f32[0] - + fFloatQuestMarkerMaxDistance) / + (fFloatQuestMarkerMinDistance - fFloatQuestMarkerMaxDistance)) * 100.0; + if (v1 > 100.0) + return FLOAT_100_0; + result = 0.0; + if (v1 >= 0.0) + return v1; + return result; } -} // namespace +#endif -static void DrawInWorldSpace(TESObjectREFR* apRefr) +static bool DrawInWorldSpace(TESObjectREFR* apRefr, ImVec2& outViewPos) { - auto calcObjectHeight = [&]() { - auto boundMax = apRefr->GetBoundMax(); - return boundMax.z - apRefr->GetBoundMin().z; - }; - - // Scale up to the top of the entity. + // Attach at the head ish. auto pos = apRefr->position; - pos.z -= calcObjectHeight(); + pos.z -= apRefr->GetHeight(); - // Note(Force): In truth this is a reference, but to ensure the compiler generates the right code - // we pass it in as a pointer NiPoint3 screenPoint{}; - HUD_WorldPtToScreenPt3(&pos, &screenPoint); - - // Here just for validation that the values are semi correct. - // RECT rect{}; - // GetWindowRect(GetForegroundWindow(), &rect); - + HUDMenuUtils::WorldPtToScreenPt3(pos, screenPoint); // Calculate window collision bounds. auto* pViewport = BSGraphics::GetMainWindow(); - NiRect bounds = { - .left = static_cast(pViewport->iWindowX), - .right = static_cast(pViewport->iWindowX + pViewport->uiWindowWidth), - .top = static_cast(pViewport->iWindowY), - .bottom = static_cast(pViewport->iWindowY + pViewport->uiWindowHeight), + const NiRect bounds = { + static_cast(pViewport->iWindowX), + static_cast(pViewport->iWindowX + pViewport->uiWindowWidth), + static_cast(pViewport->iWindowY), + static_cast(pViewport->iWindowY + pViewport->uiWindowHeight), }; // translate to screen - ImVec2 screenPos = ImVec2{ + const ImVec2 screenPos = ImVec2{ (pViewport->uiWindowWidth * screenPoint.x) + bounds.left, (pViewport->uiWindowHeight * (1.0f - screenPoint.y)) + bounds.top, }; @@ -91,158 +76,72 @@ static void DrawInWorldSpace(TESObjectREFR* apRefr) // But this is just a demo... if (IsVisible(screenPos, bounds, screenPoint.z)) { - ImGui::SetNextWindowPos(screenPos); - ImGui::Begin("AttachedWindow"); - ImGui::Button("Kill Force67"); - ImGui::End(); + outViewPos = screenPos; + return true; } + + outViewPos = {}; + return false; } +} // namespace // TODO(Force): Net Histrogram (waves) // Engine stuff. // Fix cursor. -static bool g_DrawComponentsInWorldSpace{false}; -static TESForm* g_pSelectedLocalTESForm{nullptr}; -static TESForm* g_pSelectedRemoteTESForm{nullptr}; - -#if 0 -void DrawRemoteComponent(const RemoteComponent& acComponent, const InterpolationComponent& acInterpolationc) -{ - ImGui::Begin("Entity"); - ImGui::InputScalar("Server ID", ImGuiDataType_U32, &acComponent.Id, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - ImGui::InputScalar("Cached ref ID", ImGuiDataType_U32, &acComponent.CachedRefId, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - - auto& interpolationComponent = invisibleView.get(entity); - ImGui::InputFloat("Position x", &interpolationComponent.Position.x, 0, 0, "%.3f", ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat("Position y", &interpolationComponent.Position.y, 0, 0, "%.3f", ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat("Position z", &interpolationComponent.Position.z, 0, 0, "%.3f", ImGuiInputTextFlags_ReadOnly); - ImGui::End(); -} -#endif +static TESForm* g_SelectedForm{nullptr}; void TestService::DrawComponentDebugView() { - ImGui::MenuItem("Visualize Components", nullptr, &g_DrawComponentsInWorldSpace); - - if (g_DrawComponentsInWorldSpace) - { - if (g_pSelectedLocalTESForm) - { - #if 0 - auto invisibleView = - m_world.view(); - - ImGui::Begin("Entity"); - ImGui::InputScalar("Server ID", ImGuiDataType_U32, &acComponent.Id, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - ImGui::InputScalar("Cached ref ID", ImGuiDataType_U32, &acComponent.CachedRefId, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - - auto& interpolationComponent = invisibleView.get(entity); - ImGui::InputFloat("Position x", &interpolationComponent.Position.x, 0, 0, "%.3f", - ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat("Position y", &interpolationComponent.Position.y, 0, 0, "%.3f", - ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat("Position z", &interpolationComponent.Position.z, 0, 0, "%.3f", - ImGuiInputTextFlags_ReadOnly); - ImGui::End(); - #endif - } - } + auto invisibleView = + m_world.view(entt::exclude); - if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) - { - if (ImGui::BeginTabItem("Invisible")) - { - ImGui::BeginChild("Invisible components", ImVec2(0, 100), true); - - static uint32_t s_selectedInvisibleId = 0; - static uint32_t s_selectedInvisible = 0; - - auto invisibleView = - m_world.view(); - Vector entities(invisibleView.begin(), invisibleView.end()); - - int i = 0; - for (auto entity : entities) - { - auto& remoteComponent = invisibleView.get(entity); - auto& interpolationComponent = invisibleView.get(entity); + ImGui::SetNextWindowSize(ImVec2(250, 300), ImGuiCond_FirstUseEver); + ImGui::Begin("Component view", &m_bToggleComponentWindow); - char buffer[32]; - if (ImGui::Selectable(itoa(remoteComponent.Id, buffer, 16), - s_selectedInvisibleId == remoteComponent.Id)) - s_selectedInvisibleId = remoteComponent.Id; + auto remoteView = m_world.view(); + Vector entities(remoteView.begin(), remoteView.end()); - if (s_selectedInvisibleId == remoteComponent.Id) - s_selectedInvisible = i; + static uint32_t s_selectedRemoteId = 0; + static uint32_t s_selectedRemote = 0; + static entt::entity s_selectedEnt{}; - ++i; - } - - ImGui::EndChild(); - - if (s_selectedInvisible < entities.size()) - { - auto entity = entities[s_selectedInvisible]; - //auto& remoteComponent = invisibleView.get(entity); - auto& formComponent = invisibleView.get(entity); - if (auto* pEntity = TESForm::GetById(formComponent.Id)) - { - g_pSelectedLocalTESForm = pEntity; - } - } - ImGui::EndTabItem(); - } + int i = 0; + for (auto entity : entities) + { + auto& remoteComponent = remoteView.get(entity); + auto& formComponent = remoteView.get(entity); - if (ImGui::BeginTabItem("Remote")) + char buffer[32]; + if (ImGui::Selectable(itoa(remoteComponent.Id, buffer, 16), s_selectedRemoteId == remoteComponent.Id)) { - ImGui::BeginChild("Remote components", ImVec2(0, 100), true); + s_selectedRemoteId = remoteComponent.Id; + g_SelectedForm = TESForm::GetById(formComponent.Id); + s_selectedEnt = entities[s_selectedRemote]; + } - static uint32_t s_selectedRemoteId = 0; - static uint32_t s_selectedRemote = 0; + if (s_selectedRemoteId == remoteComponent.Id) + s_selectedRemote = i; - auto remoteView = m_world.view(); - Vector entities(remoteView.begin(), remoteView.end()); + ++i; + } + ImGui::End(); - int i = 0; - for (auto entity : entities) + if (m_bDrawComponentInScreenSpace && g_SelectedForm) + { + if (auto* pObject = RTTI_CAST(g_SelectedForm, TESForm, TESObjectREFR)) + { + ImVec2 screenPos{}; + if (DrawInWorldSpace(pObject, screenPos)) { - auto& remoteComponent = remoteView.get(entity); + auto& remote = remoteView.get(s_selectedEnt); - char buffer[32]; - if (ImGui::Selectable(itoa(remoteComponent.Id, buffer, 16), s_selectedRemoteId == remoteComponent.Id)) - s_selectedRemoteId = remoteComponent.Id; + char buf[256] = {}; + snprintf(buf, 256, "ID %x, CachedRefID %x", remote.Id, remote.CachedRefId); - if (s_selectedRemoteId == remoteComponent.Id) - s_selectedRemote = i; - - ++i; - } - - ImGui::EndChild(); - - if (s_selectedRemote < entities.size()) - { - auto entity = entities[s_selectedRemote]; - - auto& remoteComponent = remoteView.get(entity); - ImGui::InputScalar("Server ID", ImGuiDataType_U32, &remoteComponent.Id, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - ImGui::InputScalar("Cached ref ID", ImGuiDataType_U32, &remoteComponent.CachedRefId, 0, 0, "%" PRIx32, - ImGuiInputTextFlags_CharsHexadecimal); - - auto& formComponent = remoteView.get(entity); - if (auto* pEntity = TESForm::GetById(formComponent.Id)) - { - g_pSelectedLocalTESForm = pEntity; - } + ImGui::GetForegroundDrawList()->AddText(ImGui::GetFont(), 30.f, screenPos, + ImColor::ImColor(255.f, 0.f, 0.f), buf); } - ImGui::EndTabItem(); } - ImGui::EndTabBar(); } } diff --git a/Code/client/Services/Generic/InputService.cpp b/Code/client/Services/Generic/InputService.cpp index 71203aceb..a8eec6ed1 100644 --- a/Code/client/Services/Generic/InputService.cpp +++ b/Code/client/Services/Generic/InputService.cpp @@ -17,61 +17,9 @@ static OverlayService* s_pOverlay = nullptr; -static void* g_menuCursor{nullptr}; -static void (*ToggleMenu)(void*, bool); - -using TWorldPtToScreenPt3 = void(void*, bool); -static TWorldPtToScreenPt3* s_WorldPtToScreenPt3; - -static bool g_guard = false; - -static void (*SRRRR)(__int64, __int64) = nullptr; - -void SomeProcessingShit(__int64 a1, __int64 queueHead) -{ - if (!g_guard) - { - SRRRR(a1, queueHead); - } -} - -static TiltedPhoques::Initializer s_LMAOLDDSA([]() { - POINTER_SKYRIMSE(void*, s_menuCursor, 0x142FC1C10 - 0x140000000); - g_menuCursor = s_menuCursor.Get(); - - POINTER_SKYRIMSE(TWorldPtToScreenPt3, s_w2s, 0x140F1A3F0 - 0x140000000); - s_WorldPtToScreenPt3 = s_w2s.Get(); - - //TiltedPhoques::Put(0x1408D6F10, 0xCC); - - TiltedPhoques::SwapCall(0x140C3B2FB, SRRRR, &SomeProcessingShit); - - struct C : TiltedPhoques::CodeGenerator - { - C() - { - lea(rax, ptr[rcx + rdx]); - ret(); - } - } gen; - - auto* pCode = gen.getCode(); - - int x = reinterpret_cast(pCode)(10, 20); - -}); - -void ToggleInput(bool v) -{ - s_WorldPtToScreenPt3(g_menuCursor, v); - g_guard = !v; -} - - void ForceKillAllInput() { MenuControls::GetInstance()->SetToggle(false); - } uint32_t GetCefModifiers(uint16_t aVirtualKey) @@ -248,13 +196,11 @@ void ProcessKeyboard(uint16_t aKey, uint16_t aScanCode, cef_key_event_type_t aTy if (aType == KEYEVENT_KEYDOWN && (aKey == VK_F2 || aKey == VK_RCONTROL)) { #if defined(TP_SKYRIM) - //TiltedPhoques::DInputHook::Get().SetEnabled(!TiltedPhoques::DInputHook::Get().IsEnabled()); + TiltedPhoques::DInputHook::Get().SetEnabled(!TiltedPhoques::DInputHook::Get().IsEnabled()); #else pRenderer->SetVisible(!active); #endif - ToggleInput(active); - - #if 0 + #if 1 if (active) while (ShowCursor(FALSE) >= 0) ; diff --git a/Code/client/Services/TestService.h b/Code/client/Services/TestService.h index de5e164eb..f914721d3 100644 --- a/Code/client/Services/TestService.h +++ b/Code/client/Services/TestService.h @@ -41,5 +41,6 @@ struct TestService entt::scoped_connection m_updateConnection; entt::scoped_connection m_drawImGuiConnection; - + bool m_bToggleComponentWindow{false}; + bool m_bDrawComponentInScreenSpace{true}; }; diff --git a/Code/server/xmake.lua b/Code/server/xmake.lua index d6b7f1c10..719672951 100644 --- a/Code/server/xmake.lua +++ b/Code/server/xmake.lua @@ -24,6 +24,7 @@ target(name) "Console", "ESLoader", "Base", + "AdminProtocol", "TiltedScript", "TiltedConnect" ) diff --git a/Code/xmake.lua b/Code/xmake.lua index 64bbaee7f..9403ea9ec 100644 --- a/Code/xmake.lua +++ b/Code/xmake.lua @@ -4,7 +4,7 @@ if is_plat("windows") then includes("client") includes("immersive_launcher") includes("tp_process") - --includes("admin") + includes("admin") end includes("common") diff --git a/Libraries/TiltedConnect b/Libraries/TiltedConnect index bf82505c6..f6ffb4b6e 160000 --- a/Libraries/TiltedConnect +++ b/Libraries/TiltedConnect @@ -1 +1 @@ -Subproject commit bf82505c63233e5bff91da6ac86448d433866b0b +Subproject commit f6ffb4b6e5ec3c414952a5c635430422b2790559 diff --git a/Libraries/TiltedReverse b/Libraries/TiltedReverse index 35d397275..263057ed1 160000 --- a/Libraries/TiltedReverse +++ b/Libraries/TiltedReverse @@ -1 +1 @@ -Subproject commit 35d397275b4930cdd3d8d9dd1dc05a84837c5701 +Subproject commit 263057ed1f8420aee724db400601de2ee765bf64