Skip to content

Commit

Permalink
Merge pull request #752 from tiltedphoques/dev
Browse files Browse the repository at this point in the history
V1.7.1
  • Loading branch information
RobbeBryssinck authored Dec 2, 2024
2 parents 02ec3a4 + 299f208 commit 683ec29
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/windows-playable-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ jobs:
git submodule sync --recursive
git submodule update --init --force --recursive --depth=1
- name: Checkout master on tag push
if: github.ref_type == 'tag'
# Checkout only if the tag was pushed to master
run: (git rev-parse HEAD) -eq (git rev-parse origin/master) -and (git checkout master)

- name: Cache xmake dependencies
uses: actions/cache@v4
with:
Expand Down
8 changes: 8 additions & 0 deletions Code/client/Services/Generic/InputService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,14 @@ LRESULT CALLBACK InputService::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR
}
ProcessKeyboard(virtualKey, scancode, KEYEVENT_CHAR, false, false);
}
// If the player tabs out/in with UI visible, this WndProc doesn't run during mouse or keyboard events.
// When player tabs in, force the UI state
else if (uMsg == WM_SETFOCUS && s_pOverlay->GetActive())
{
TiltedPhoques::DInputHook::Get().SetEnabled(true);
s_pOverlay->SetActive(true);
pRenderer->SetCursorVisible(true);
}
else if (uMsg == WM_INPUTLANGCHANGE)
{
s_currentACP = GetRealACP();
Expand Down
1 change: 1 addition & 0 deletions Code/immersive_launcher/TargetConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static constexpr TargetConfig CurrentTarget{
L"Skyrim Special Edition",
489830, 0x40000000, 35410264};
#define TARGET_NAME L"SkyrimSE"
#define TARGET_NAME_A "SkyrimSE"
#define PRODUCT_NAME L"Skyrim Together"
#define SHORT_NAME L"Skyrim Special Edition"

Expand Down
30 changes: 29 additions & 1 deletion Code/immersive_launcher/stubs/FileMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ std::wstring s_OverridePath;
DWORD(WINAPI* RealGetModuleFileNameW)(HMODULE, LPWSTR, DWORD) = nullptr;
DWORD(WINAPI* RealGetModuleFileNameA)(HMODULE, LPSTR, DWORD) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleW)(LPCWSTR) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleA)(LPSTR) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleA)(LPCSTR) = nullptr;
NTSTATUS(WINAPI* RealLdrLoadDll)(const wchar_t*, uint32_t*, UNICODE_STRING*, HANDLE*) = nullptr;
NTSTATUS(WINAPI* RealLdrGetDllHandle)(PWSTR, PULONG, PUNICODE_STRING, PVOID*) = nullptr;
NTSTATUS(WINAPI* RealLdrGetDllFullName)(HMODULE, PUNICODE_STRING) = nullptr;
Expand Down Expand Up @@ -87,6 +87,28 @@ bool IsLocalModulePath(HMODULE aHmod)
return buf.find(s_OverridePath) != std::wstring::npos;
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
HMODULE WINAPI TP_GetModuleHandleW(LPCWSTR lpModuleName)
{
constexpr auto pTarget = TARGET_NAME L".exe";
auto targetSize = std::wcslen(pTarget);

if (lpModuleName && std::wcsncmp(pTarget, lpModuleName, targetSize) == 0)
lpModuleName = nullptr;
return RealGetModuleHandleW(lpModuleName);
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
HMODULE WINAPI TP_GetModuleHandleA(LPCSTR lpModuleName)
{
constexpr auto pTarget = TARGET_NAME_A ".exe";
constexpr auto targetSize = sizeof(TARGET_NAME_A ".exe");

if (lpModuleName && std::strncmp(pTarget, lpModuleName, targetSize) == 0)
lpModuleName = nullptr;
return RealGetModuleHandleA(lpModuleName);
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
NTSTATUS WINAPI TP_LdrGetDllHandle(PWSTR DllPath, PULONG DllCharacteristics, PUNICODE_STRING DllName, PVOID* DllHandle)
{
Expand Down Expand Up @@ -300,6 +322,12 @@ void CoreStubsInit()
// TODO(Vince): we need some check if usvfs already fucked with this?
// MH_CreateHookApi(L"ntdll.dll", "LdrGetDllFullName", &TP_LdrGetDllFullName, (void**)&RealLdrGetDllFullName);
VALIDATE(MH_CreateHookApi(L"ntdll.dll", "LdrLoadDll", &TP_LdrLoadDll, (void**)&RealLdrLoadDll));

// Starting with Windows 11 24H2 the call stack has changed and GetModuleHandle() no longer
// downcalls to LdrGetDllHandleEx, so we have to hook this too.
VALIDATE(MH_CreateHookApi(L"kernel32.dll", "GetModuleHandleW", &TP_GetModuleHandleW, (void**)&RealGetModuleHandleW));
VALIDATE(MH_CreateHookApi(L"kernel32.dll", "GetModuleHandleA", &TP_GetModuleHandleA, (void**)&RealGetModuleHandleA));

VALIDATE(MH_EnableHook(nullptr));
}

Expand Down
6 changes: 4 additions & 2 deletions Code/server_runner/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,16 +223,18 @@ int main(int argc, char** argv)
}
*/

ScopedCrashHandler _(true, true);
//ScopedCrashHandler _(true, true);

RegisterQuitHandler();
// Note(Vince): This started crashing on 1.7+ lets disable it for now.
// RegisterQuitHandler();

// Keep stack free.
const auto cpRunner{std::make_unique<DediRunner>(argc, argv)};
if (bConsole)
{
cpRunner->StartTerminalIO();
}

cpRunner->RunGSThread();

return 0;
Expand Down
3 changes: 2 additions & 1 deletion Code/skyrim_ui/src/assets/i18n/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"ROOT": {
"CONNECT": "Bağlan",
"DISCONNECT": "Bağlantıyı Kopar",
"REVEAL_PLAYERS": "Oyuncuları Göster",
"RECONNECT": "Geri Bağlan",
"PLAYER_MANAGER": "Oyuncu Yöneticisi",
"SETTINGS": "Ayarlar",
Expand Down Expand Up @@ -177,4 +178,4 @@
"PARTY_INVITE": "{{from}} parti daveti attı!"
}
}
}
}
Binary file not shown.
Binary file not shown.
101 changes: 101 additions & 0 deletions GameFiles/Skyrim/scripts/source/PetFramework_ParentQuestScript.psc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Scriptname PetFramework_ParentQuestScript extends Quest
{Get/Set functions for pet count and limit checks. All other shared controls are in PetFramework_PetScript.}
;rvogel 9/2017

GlobalVariable Property PetFramework_MaxPets Auto ;Max number of pets who can follow at once, default is 2

;RefAliases to fill from DLC at runtime

ReferenceAlias Property DLC2SeverinManorEnableMarker Auto
ReferenceAlias Property HomeMarkerDLC2SeverinManor Auto

ReferenceAlias Property BYOH01DoorLakeviewManor Auto
ReferenceAlias Property BYOH02DoorWindstadManor Auto
ReferenceAlias Property BYOH03DoorHeljarchenHall Auto

ReferenceAlias Property HomeMarkerLakeviewManor Auto
ReferenceAlias Property HomeMarkerWindstadManor Auto
ReferenceAlias Property HomeMarkerHeljarchenHall Auto

Faction Property PetFramework_PetFaction Auto
Faction Property PlayerFaction Auto

Faction Property CWSonsFaction Auto
Faction Property CWImperialFaction Auto

; Setting start CurrentPetCount over the Max so the player cannot dismiss 2 pets and recruit new ones while online. Hypothetically.
Int Property CurrentPetCount = 4 Auto Hidden ;Current count of pets, this is manipulated by pet ESPs/ESLs using the functions below

Event OnInit()
debug.trace("Setting pet and player relationship to ally")
PetFramework_PetFaction.SetAlly(PlayerFaction)

;Prevent CW actors from becoming hostile to pets
PetFramework_PetFaction.SetAlly(CWSonsFaction)
PetFramework_PetFaction.SetAlly(CWImperialFaction)
EndEvent

Int Function GetCurrentPetCount()
{Called by 'child' pet ESPs/ESLs to get current count and limit}
Return CurrentPetCount
EndFunction

Int Function GetMaxPets()
{Called by 'child' pet ESPs/ESLs to get max pets}
Return PetFramework_MaxPets.GetValue() as Int
EndFunction

Function IncrementPetCount()
{Called by 'child' pet ESPs/ESLs to update active pet count}
CurrentPetCount += 1
EndFunction

Function DecrementPetCount()
{Called by 'child' pet ESPs/ESLs to update active pet count}
If(CurrentPetCount > 0)
CurrentPetCount -= 1
EndIf
EndFunction

Bool Function HasMaxPets()
{Called to check if the player has the maximum pets allowed}

If(GetCurrentPetCount() == GetMaxPets())
Return True
Else
Return False
EndIf

EndFunction


Function FillRefAliasesFromDLC()
{Called from first stage of quest to fill aliases from DLC that are unreachable by Update.esm}

;Dragonborn Refs (Marker and Chest used to check ownership)
ObjectReference DLC2SeverinManorEnableRef = (Game.GetFormFromFile(0x040396D0, "dragonborn.esm") as ObjectReference)
ObjectReference DLC2SeverinManorMarkerRef = (Game.GetFormFromFile(0x0403BD35, "dragonborn.esm") as ObjectReference)

;Hearthfire Refs (Doors)
ObjectReference DoorLakeviewManorRef = (Game.GetFormFromFile(0x03003221, "hearthfires.esm") as ObjectReference)
ObjectReference DoorWindstadManorRef = (Game.GetFormFromFile(0x0300B852, "hearthfires.esm") as ObjectReference)
ObjectReference DoorHeljarchenHallRef = (Game.GetFormFromFile(0x03010DDF, "hearthfires.esm") as ObjectReference)

;Hearthfire Refs (Markers)
ObjectReference MarkerLakeviewManorRef = (Game.GetFormFromFile(0x0300309B, "hearthfires.esm") as ObjectReference)
ObjectReference MarkerWindstadManorRef = (Game.GetFormFromFile(0x0301205C, "hearthfires.esm") as ObjectReference)
ObjectReference MarkerHeljarchenHallRef = (Game.GetFormFromFile(0x03016E05, "hearthfires.esm") as ObjectReference)

;Fill the refs
DLC2SeverinManorEnableMarker.ForceRefTo(DLC2SeverinManorEnableRef)
HomeMarkerDLC2SeverinManor.ForceRefTo(DLC2SeverinManorMarkerRef)

BYOH01DoorLakeviewManor.ForceRefTo(DoorLakeviewManorRef)
BYOH02DoorWindstadManor.ForceRefTo(DoorWindstadManorRef)
BYOH03DoorHeljarchenHall.ForceRefTo(DoorHeljarchenHallRef)

HomeMarkerLakeviewManor.ForceRefTo(MarkerLakeviewManorRef)
HomeMarkerWindstadManor.ForceRefTo(MarkerWindstadManorRef)
HomeMarkerHeljarchenHall.ForceRefTo(MarkerHeljarchenHallRef)

EndFunction
129 changes: 129 additions & 0 deletions GameFiles/Skyrim/scripts/source/PetFramework_PetQuest.psc
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
Scriptname PetFramework_PetQuest extends Quest Conditional
{Manages the pet's home location, commands, etc. Some functions are called from the pet actor script.}

PetFramework_ParentQuestScript Property PetFramework_ParentQuest Auto
Message Property PetFramework_PetDismissMessage Auto
Message Property PetFramework_PetMaxReachedMessage Auto
Faction Property PetFramework_PetFollowingFaction Auto
Faction Property PlayerFaction Auto
Faction Property PetFramework_PetFaction Auto
ReferenceAlias Property PetHomeMarker Auto
ReferenceAlias Property PetRefAlias Auto
ReferenceAlias Property PetDynamicHomeMarker Auto
Bool Property MovingTogglePackageOn = False Auto Conditional Hidden ;Hearthfire adoption/move trick - turn on a temporary package

Function MakePetAvailableToPlayer()
{Called when the quest meets the criteria for the pet to be available, i.e. purchase, rescue, whatever scenario. Without this the pet cannot be talked to or recruited.}
PetRefAlias.GetActorReference().SetFactionRank(PetFramework_PetFaction, 1)
;PetRefAlias.GetActorReference().AddToFaction(PlayerFaction)
EndFunction

Function MakePetUnavailableToPlayer()
{If for some reason we want to make the pet unavailable to player, i.e. sell it someone else, etc. this function will do that}
PetRefAlias.GetActorReference().SetFactionRank(PetFramework_PetFaction, 0)
;PetRefAlias.GetActorReference().RemoveFromFaction(PlayerFaction)
EndFunction

Function FollowPlayer(Bool snapIntoInteraction = False)
{Called when the player recruits the pet via dialogue.}

If(PetFramework_ParentQuest.HasMaxPets())
PetFramework_PetMaxReachedMessage.Show()
Else
PetFramework_PetDismissMessage.Show()
return ; STR players ignore the pets.
debug.trace("Pet Framework: " + PetRefAlias.GetActorReference() + " setting to following player")
debug.trace("Pet Framework: " + PetRefAlias.GetActorReference() + " PetFollowingFactionRank: " + PetRefAlias.GetActorReference().GetFactionRank(PetFramework_PetFollowingFaction))

;If the pet was waiting for the player, clear the actor value (no need to check just run it)
WaitForPlayer(False)

;Set the rank to 1, which will enable dialogue commands, etc. (used by shared pet framework)
PetRefAlias.GetActorReference().SetFactionRank(PetFramework_PetFollowingFaction, 1)

debug.trace("Pet Framework: " + PetRefAlias.GetActorReference() + " PetFollowingFactionRank: " + PetRefAlias.GetActorReference().GetFactionRank(PetFramework_PetFollowingFaction))

;Some animals have very long idles they get 'stuck' which feels like recruiting them didn't do anything
If(snapIntoInteraction)
PetRefAlias.GetReference().Disable()
PetRefAlias.GetReference().Enable()
EndIf

PetFramework_ParentQuest.IncrementPetCount()
debug.trace("Pet Count: " + PetFramework_ParentQuest.GetCurrentPetCount())

;Re-evaluate the package stack based on our new conditions
PetRefAlias.GetActorReference().EvaluatePackage()

EndIf

EndFunction

Function WaitForPlayer(Bool doWait = True)
{True/False: Pet will wait for the player or continue to follow.}

DEBUG.TRACE("WaitForPlayer called with value: " + doWait)

If(doWait == True)
debug.trace("PetFramework Setting pet to wait for player")
PetRefAlias.GetActorReference().SetAV("WaitingForPlayer", 1)
Else
debug.trace("PetFramework Setting pet to stop waiting for player")
PetRefAlias.GetActorReference().SetAV("WaitingForPlayer", 0)
EndIf

;Re-evaluate the package stack based on our new conditions
PetRefAlias.GetActorReference().EvaluatePackage()

EndFunction

Function SetHomeToCurrentLocation()
{Makes the "Home" of the pet right where they stand, so they will dismiss and sandbox the area (house mods, camping, etc.)}

;Move the xmarker to where the pet is standing
PetDynamicHomeMarker.GetReference().MoveTo(PetRefAlias.GetReference())
PetDynamicHomeMarker.GetReference().SetAngle(0,0,0)

;Set the home idle marker to the dynamic marker
SetNewHome(PetDynamicHomeMarker, True)

EndFunction

Function SetNewHome(ReferenceAlias newLocation, Bool dismiss = True, Bool doWarp = False)

debug.trace("Set New Home called from actor proxy")

;Clear the waiting flag
WaitForPlayer(False)

;Turn on the temporary package while we change the ref alias data for their idle package - trick from Hearthfire adoption
MovingTogglePackageOn = True ;"Hold"AI package looks at this quest var
PetRefAlias.GetActorReference().EvaluatePackage()

;Set the ref alias to be the pet's new home
PetHomeMarker.ForceRefTo(newLocation.GetReference())

;Remove them from current following faction so they actually go to their new home
If(dismiss)
PetRefAlias.GetActorReference().SetFactionRank(PetFramework_PetFollowingFaction, 0)
EndIf

Utility.Wait(0.1)

MovingTogglePackageOn = False
PetRefAlias.GetActorReference().EvaluatePackage()

If(doWarp)
Utility.Wait(0.01)
PetRefAlias.GetReference().MoveTo(newLocation.GetReference(), 0,0,0,False)
EndIf

PetFramework_PetDismissMessage.Show()
PetFramework_ParentQuest.DecrementPetCount()

debug.trace("Pet Count: " + PetFramework_ParentQuest.GetCurrentPetCount())

EndFunction



Loading

0 comments on commit 683ec29

Please sign in to comment.