Start first-time join in COVault109 and trigger quest
Change first-time session launch to use the COVault109 start cell and invoke a start quest so the quest can place the player at its preset spawn. Replaces coc SanctuaryExt with coc COVault109, changes the spawn-detection to match the COVault109 editor ID, adds a g_vault109StartQuestIssued flag and IssueVault109StartQuest() to run `startquest CO_Vault109StartQuest` once, and updates logs and reset logic. Also updates docs (changelog.md, docs/dev-log.md) and includes the updated CommonwealthOnline_Vault109.esp binary.
This commit is contained in:
@@ -21,8 +21,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr std::uint32_t kCommonwealthWorldspaceFormId = 0x0000003C;
|
||||
constexpr std::uint32_t kSanctuaryExtCellFormId = 0x0000DD60;
|
||||
constexpr std::string_view kFirstJoinStartCellEditorId = "COVault109";
|
||||
constexpr int kSpawnPollIntervalFrames = 15;
|
||||
constexpr int kMaxSpawnWaitAttempts = 600;
|
||||
constexpr int kWorldReadyDelayPolls = 10;
|
||||
@@ -43,6 +42,7 @@ namespace
|
||||
CharGenPhase g_charGenPhase = CharGenPhase::None;
|
||||
bool g_pendingProfileBind = false;
|
||||
bool g_cocIssued = false;
|
||||
bool g_vault109StartQuestIssued = false;
|
||||
bool g_sawLooksMenuOpen = false;
|
||||
bool g_sawSpecialMenuOpen = false;
|
||||
int g_spawnPollFrameCounter = 0;
|
||||
@@ -117,7 +117,7 @@ namespace
|
||||
return a_saveName.size() >= 8 && _strnicmp(a_saveName.data(), "Exitsave", 8) == 0;
|
||||
}
|
||||
|
||||
bool IsPlayerInSanctuaryExt(const RE::PlayerCharacter& a_player)
|
||||
bool IsPlayerInFirstJoinStartCell(const RE::PlayerCharacter& a_player)
|
||||
{
|
||||
if (IsPlaceholderSpawnPosition(a_player)) {
|
||||
return false;
|
||||
@@ -128,16 +128,8 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parentCell->GetFormID() == kSanctuaryExtCellFormId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!parentCell->IsExterior()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* worldspace = parentCell->worldSpace ? parentCell->worldSpace : a_player.cachedWorldspace;
|
||||
return worldspace && worldspace->GetFormID() == kCommonwealthWorldspaceFormId;
|
||||
const auto* editorId = parentCell->GetFormEditorID();
|
||||
return editorId && _stricmp(editorId, kFirstJoinStartCellEditorId.data()) == 0;
|
||||
}
|
||||
|
||||
void LogPlayerLocation(std::string_view a_label, const RE::PlayerCharacter& a_player)
|
||||
@@ -258,6 +250,7 @@ namespace
|
||||
g_pendingProfileBind = false;
|
||||
g_pendingProfileBindServerKey.clear();
|
||||
g_cocIssued = false;
|
||||
g_vault109StartQuestIssued = false;
|
||||
g_sawLooksMenuOpen = false;
|
||||
g_sawSpecialMenuOpen = false;
|
||||
g_spawnPollFrameCounter = 0;
|
||||
@@ -271,6 +264,7 @@ namespace
|
||||
g_pendingProfileBind = true;
|
||||
g_pendingProfileBindServerKey = a_serverKey;
|
||||
g_cocIssued = false;
|
||||
g_vault109StartQuestIssued = false;
|
||||
g_sawLooksMenuOpen = false;
|
||||
g_sawSpecialMenuOpen = false;
|
||||
g_spawnPollFrameCounter = 0;
|
||||
@@ -279,15 +273,26 @@ namespace
|
||||
LogInfo(std::format("Queued first-time coc join for server {}.", a_serverKey));
|
||||
}
|
||||
|
||||
void IssueCocSanctuaryExt()
|
||||
void IssueCocFirstJoinStartCell()
|
||||
{
|
||||
if (g_cocIssued) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_cocIssued = true;
|
||||
RE::Console::ExecuteCommand("coc SanctuaryExt");
|
||||
LogInfo("Issued coc SanctuaryExt from main menu.");
|
||||
RE::Console::ExecuteCommand("coc COVault109");
|
||||
LogInfo("Issued coc COVault109 from main menu.");
|
||||
}
|
||||
|
||||
void IssueVault109StartQuest()
|
||||
{
|
||||
if (g_vault109StartQuestIssued) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_vault109StartQuestIssued = true;
|
||||
RE::Console::ExecuteCommand("startquest CO_Vault109StartQuest");
|
||||
LogInfo("Issued startquest CO_Vault109StartQuest for first-time COVault109 flow.");
|
||||
}
|
||||
|
||||
void OpenLooksMenu()
|
||||
@@ -406,13 +411,13 @@ namespace
|
||||
|
||||
if (g_charGenPhase == CharGenPhase::CocLoading) {
|
||||
if (!g_cocIssued) {
|
||||
IssueCocSanctuaryExt();
|
||||
IssueCocFirstJoinStartCell();
|
||||
}
|
||||
|
||||
const auto* player = RE::PlayerCharacter::GetSingleton();
|
||||
if (!player || !IsPlayerInSanctuaryExt(*player)) {
|
||||
if (!player || !IsPlayerInFirstJoinStartCell(*player)) {
|
||||
if (++g_spawnWaitAttempts >= kMaxSpawnWaitAttempts) {
|
||||
LogWarning("Timed out waiting for coc SanctuaryExt to finish loading.");
|
||||
LogWarning("Timed out waiting for coc COVault109 to finish loading.");
|
||||
ResetFirstJoinState();
|
||||
}
|
||||
return;
|
||||
@@ -421,16 +426,18 @@ namespace
|
||||
g_charGenPhase = CharGenPhase::WaitingForWorldReady;
|
||||
g_spawnWaitAttempts = 0;
|
||||
g_worldReadyPolls = 0;
|
||||
LogPlayerLocation("SanctuaryExt loaded, waiting for loading screen to finish", *player);
|
||||
LogPlayerLocation("COVault109 loaded, waiting for loading screen to finish", *player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_charGenPhase == CharGenPhase::WaitingForWorldReady) {
|
||||
const auto* player = RE::PlayerCharacter::GetSingleton();
|
||||
if (!player || !IsPlayerInSanctuaryExt(*player)) {
|
||||
if (!player || !IsPlayerInFirstJoinStartCell(*player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
IssueVault109StartQuest();
|
||||
|
||||
if (!IsWorldReadyForCharGen(*player)) {
|
||||
return;
|
||||
}
|
||||
@@ -534,7 +541,7 @@ namespace F4T::SessionLaunch
|
||||
|
||||
LogWarning(std::format("Server profile '{}' has no bound save file; running first-time flow.", profileKey));
|
||||
QueueFirstTimeCocJoin(profileKey);
|
||||
IssueCocSanctuaryExt();
|
||||
IssueCocFirstJoinStartCell();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -578,7 +585,7 @@ namespace F4T::SessionLaunch
|
||||
*saveFile,
|
||||
profileKey));
|
||||
QueueFirstTimeCocJoin(profileKey);
|
||||
IssueCocSanctuaryExt();
|
||||
IssueCocFirstJoinStartCell();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@@ -607,7 +614,7 @@ namespace F4T::SessionLaunch
|
||||
}
|
||||
|
||||
QueueFirstTimeCocJoin(serverKey);
|
||||
IssueCocSanctuaryExt();
|
||||
IssueCocFirstJoinStartCell();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user