Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions Code/client/Games/Skyrim/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,18 @@ struct Actor : TESObjectREFR
//void Save_Reversed(uint32_t aChangeFlags, Buffer::Writer& aWriter);
};

static_assert(offsetof(Actor, currentProcess) == 0xF0);
static_assert(offsetof(Actor, flags1) == 0xE0);
static_assert(offsetof(Actor, actorValueOwner) == 0xB0);
static_assert(offsetof(Actor, actorState) == 0xB8);
static_assert(offsetof(Actor, flags2) == 0x1FC);
static_assert(offsetof(Actor, unk194) == 0x270);
static_assert(offsetof(Actor, fVoiceTimer) == 0x108);
static_assert(offsetof(Actor, unk84) == 0xE8);
static_assert(offsetof(Actor, unk17C) == 0x17C);
static_assert(offsetof(Actor, pCombatController) == 0x158);
static_assert(offsetof(Actor, magicItems) == 0x1C0);
static_assert(offsetof(Actor, equippedShout) == 0x1E0);
static_assert(offsetof(Actor, actorLock) == 0x27C);
static_assert(sizeof(Actor) == 0x2B0);
static_assert(offsetof(Actor, currentProcess) == 0xF8);
static_assert(offsetof(Actor, flags1) == 0xE8);
static_assert(offsetof(Actor, actorValueOwner) == 0xB8);
static_assert(offsetof(Actor, actorState) == 0xC0);
static_assert(offsetof(Actor, flags2) == 0x204);
static_assert(offsetof(Actor, unk194) == 0x278);
static_assert(offsetof(Actor, fVoiceTimer) == 0x110);
static_assert(offsetof(Actor, unk84) == 0xF0);
static_assert(offsetof(Actor, unk17C) == 0x184);
static_assert(offsetof(Actor, pCombatController) == 0x160);
static_assert(offsetof(Actor, magicItems) == 0x1C8);
static_assert(offsetof(Actor, equippedShout) == 0x1E8);
static_assert(offsetof(Actor, actorLock) == 0x284);
static_assert(sizeof(Actor) == 0x2B8);
static_assert(sizeof(Actor::SpellItemEntry) == 0x18);
4 changes: 4 additions & 0 deletions Code/client/Games/Skyrim/ExtraData/ExtraDataList.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ struct ExtraDataList

[[nodiscard]] bool HasQuestObjectAlias() noexcept;

#if TP_SKYRIM64
virtual ~ExtraDataList();
#endif

#if TP_FALLOUT4
void* unk0;
#endif
Expand Down
14 changes: 7 additions & 7 deletions Code/client/Games/Skyrim/PlayerCharacter.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ struct PlayerCharacter : Actor
uint64_t instanceCount;
};

uint8_t pad1[0x580 - sizeof(Actor)];
uint8_t pad1[0x588 - sizeof(Actor)];
GameArray<ObjectiveInstance> objectives;
uint8_t pad588[0x9B0 - 0x598];
Skills** pSkills;
Expand All @@ -186,10 +186,10 @@ struct PlayerCharacter : Actor
uint8_t padPlayerEnd[0xBE0 - 0xB30];
};

static_assert(offsetof(PlayerCharacter, objectives) == 0x580);
static_assert(offsetof(PlayerCharacter, pSkills) == 0x9B0);
static_assert(offsetof(PlayerCharacter, locationForm) == 0xAC8);
static_assert(offsetof(PlayerCharacter, baseTints) == 0xB10);
static_assert(offsetof(PlayerCharacter, overlayTints) == 0xB28);
static_assert(sizeof(PlayerCharacter) == 0xBE0);
static_assert(offsetof(PlayerCharacter, objectives) == 0x588);
static_assert(offsetof(PlayerCharacter, pSkills) == 0x9B8);
static_assert(offsetof(PlayerCharacter, locationForm) == 0xAD0);
static_assert(offsetof(PlayerCharacter, baseTints) == 0xB18);
static_assert(offsetof(PlayerCharacter, overlayTints) == 0xB30);
static_assert(sizeof(PlayerCharacter) == 0xBE8);

2 changes: 1 addition & 1 deletion Code/client/Games/Skyrim/TESObjectREFR.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,5 @@ struct TESObjectREFR : TESForm
uint16_t referenceFlags;
};

static_assert(sizeof(TESObjectREFR) == 0x98);
static_assert(sizeof(TESObjectREFR) == 0xA0);
static_assert(offsetof(TESObjectREFR, loadedState) == 0x68);
2 changes: 1 addition & 1 deletion Code/client/Services/Generic/InputService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void ProcessKeyboard(uint16_t aKey, uint16_t aScanCode, cef_key_event_type_t aTy

spdlog::debug("ProcessKey, type: {}, key: {}, active: {}", aType, aKey, active);

if (IsToggleKey(aKey) || (IsDisableKey(aKey) && active))
if (aType != KEYEVENT_CHAR && (IsToggleKey(aKey) || (IsDisableKey(aKey) && active)))
{
if (!overlay.GetInGame())
{
Expand Down
63 changes: 36 additions & 27 deletions Code/client/Services/Generic/PlayerService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <Games/Overrides.h>
#include <Games/References.h>
#include <AI/AIProcess.h>
#include <EquipManager.h>

PlayerService::PlayerService(World& aWorld, entt::dispatcher& aDispatcher, TransportService& aTransport) noexcept
: m_world(aWorld), m_dispatcher(aDispatcher), m_transport(aTransport)
Expand All @@ -45,17 +46,6 @@ PlayerService::PlayerService(World& aWorld, entt::dispatcher& aDispatcher, Trans
m_partyLeftConnection = aDispatcher.sink<PartyLeftEvent>().connect<&PlayerService::OnPartyLeftEvent>(this);
}

namespace
{
bool isDeathSystemEnabled = true;

bool knockdownStart = false;
double knockdownTimer = 0.0;

bool godmodeStart = false;
double godmodeTimer = 0.0;
}

void PlayerService::OnUpdate(const UpdateEvent& acEvent) noexcept
{
RunRespawnUpdates(acEvent.Delta);
Expand Down Expand Up @@ -227,14 +217,20 @@ void PlayerService::OnPartyLeftEvent(const PartyLeftEvent& acEvent) noexcept
// TODO: ft (verify)
void PlayerService::RunRespawnUpdates(const double acDeltaTime) noexcept
{
if (!isDeathSystemEnabled)
if (!m_isDeathSystemEnabled)
return;

static bool s_startTimer = false;

PlayerCharacter* pPlayer = PlayerCharacter::Get();
if (!pPlayer->actorState.IsBleedingOut())
{
#if TP_SKYRIM64
m_cachedMainSpellId = pPlayer->magicItems[0] ? pPlayer->magicItems[0]->formID : 0;
m_cachedSecondarySpellId = pPlayer->magicItems[1] ? pPlayer->magicItems[1]->formID : 0;
m_cachedPowerId = pPlayer->equippedShout ? pPlayer->equippedShout->formID : 0;
#endif

s_startTimer = false;
return;
}
Expand All @@ -259,51 +255,64 @@ void PlayerService::RunRespawnUpdates(const double acDeltaTime) noexcept
{
pPlayer->RespawnPlayer();

knockdownTimer = 1.5;
knockdownStart = true;
m_knockdownTimer = 1.5;
m_knockdownStart = true;

m_transport.Send(PlayerRespawnRequest());

s_startTimer = false;

#if TP_SKYRIM64
auto* pEquipManager = EquipManager::Get();
TESForm* pSpell = TESForm::GetById(m_cachedMainSpellId);
if (pSpell)
pEquipManager->EquipSpell(pPlayer, pSpell, 0);
pSpell = TESForm::GetById(m_cachedSecondarySpellId);
if (pSpell)
pEquipManager->EquipSpell(pPlayer, pSpell, 1);
pSpell = TESForm::GetById(m_cachedPowerId);
if (pSpell)
pEquipManager->EquipShout(pPlayer, pSpell);
#endif
}
}

// TODO: ft (verify)
// Doesn't seem to respawn quite yet
void PlayerService::RunPostDeathUpdates(const double acDeltaTime) noexcept
{
if (!isDeathSystemEnabled)
if (!m_isDeathSystemEnabled)
return;

// If a player dies in ragdoll, it gets stuck.
// This code ragdolls the player again upon respawning.
// It also makes the player invincible for 5 seconds.
if (knockdownStart)
if (m_knockdownStart)
{
knockdownTimer -= acDeltaTime;
if (knockdownTimer <= 0.0)
m_knockdownTimer -= acDeltaTime;
if (m_knockdownTimer <= 0.0)
{
PlayerCharacter::SetGodMode(true);
godmodeStart = true;
godmodeTimer = 10.0;
m_godmodeStart = true;
m_godmodeTimer = 10.0;

PlayerCharacter* pPlayer = PlayerCharacter::Get();
pPlayer->currentProcess->KnockExplosion(pPlayer, &pPlayer->position, 0.f);

FadeOutGame(false, true, 0.5f, true, 2.f);

knockdownStart = false;
m_knockdownStart = false;
}
}

if (godmodeStart)
if (m_godmodeStart)
{
godmodeTimer -= acDeltaTime;
if (godmodeTimer <= 0.0)
m_godmodeTimer -= acDeltaTime;
if (m_godmodeTimer <= 0.0)
{
PlayerCharacter::SetGodMode(false);

godmodeStart = false;
m_godmodeStart = false;
}
}
}
Expand Down Expand Up @@ -343,9 +352,9 @@ void PlayerService::RunLevelUpdates() const noexcept
}
}

void PlayerService::ToggleDeathSystem(bool aSet) const noexcept
void PlayerService::ToggleDeathSystem(bool aSet) noexcept
{
isDeathSystemEnabled = aSet;
m_isDeathSystemEnabled = aSet;

PlayerCharacter::Get()->SetPlayerRespawnMode(aSet);
}
14 changes: 13 additions & 1 deletion Code/client/Services/PlayerService.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct PlayerService
void RunDifficultyUpdates() const noexcept;
void RunLevelUpdates() const noexcept;

void ToggleDeathSystem(bool aSet) const noexcept;
void ToggleDeathSystem(bool aSet) noexcept;

World& m_world;
entt::dispatcher& m_dispatcher;
Expand All @@ -63,6 +63,18 @@ struct PlayerService
int32_t m_serverDifficulty = 6;
int32_t m_previousDifficulty = 6;

bool m_isDeathSystemEnabled = true;

bool m_knockdownStart = false;
double m_knockdownTimer = 0.0;

bool m_godmodeStart = false;
double m_godmodeTimer = 0.0;

uint32_t m_cachedMainSpellId = 0;
uint32_t m_cachedSecondarySpellId = 0;
uint32_t m_cachedPowerId = 0;

entt::scoped_connection m_updateConnection;
entt::scoped_connection m_connectedConnection;
entt::scoped_connection m_disconnectedConnection;
Expand Down
8 changes: 7 additions & 1 deletion Code/client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ static void ShowAddressLibraryError(const wchar_t* apGamePath)
auto errorDetail = fmt::format(L"Looking for it here: {}\\Data\\SKSE\\Plugins", apGamePath);

Base::TaskDialog dia(g_SharedWindowIcon, L"Error", L"Failed to load Skyrim Address Library",
L"Make sure to use the All in one Anniversary Edition", errorDetail.c_str());
L"Make sure to use the All in one (Anniversary Edition) even if you don't have the Anniversary Edition upgrade", errorDetail.c_str());
#elif TP_FALLOUT4
auto errorDetail = fmt::format(L"Looking for it here: {}\\Data\\F4SE\\Plugins", apGamePath);

Base::TaskDialog dia(g_SharedWindowIcon, L"Error", L"Failed to load Fallout 4 Address Library", L"",
errorDetail.c_str());
#endif

dia.AppendButton(0xBEED, L"Visit troubleshooting page on wiki.tiltedphoques.com");
dia.AppendButton(0xBEEF, L"Visit Address Library modpage on nexusmods.com");
const int result = dia.Show();
if (result == 0xBEEF)
Expand All @@ -37,6 +38,11 @@ static void ShowAddressLibraryError(const wchar_t* apGamePath)
SW_SHOWNORMAL);
#endif
}
else if (result == 0xBEED)
{
ShellExecuteW(nullptr, L"open", LR"(https://wiki.tiltedphoques.com/tilted-online/guides/troubleshooting/address-library-error)",
nullptr, nullptr, SW_SHOWNORMAL);
}

exit(4);
}
Expand Down
2 changes: 2 additions & 0 deletions Code/skyrim_ui/src/app/transloco-root.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export class TranslocoHttpLoader implements TranslocoLoader {
{ id: 'fr', label: 'Français' },
{ id: 'zh-CN', label: '中文(中国)'},
{ id: 'nl', label: 'Nederlands' },
{ id: 'es', label: 'Español' },
{ id: 'cs', label: 'Čeština'},
{ id: 'overwrite', label: 'Custom' },
],
defaultLang: 'en',
Expand Down
Binary file not shown.
Loading