Add automatic quest start for Out of Time (MQ102) on COVault109 exit
When the player leaves COVault109 for the first time, the plugin now automatically starts the Out of Time quest (MQ102, FormID 0x0001CC2A) and sets it to stage 10, skipping the vault entry sequence for a smoother multiplayer transition. The implementation uses TESDataHandler::LookupForm to safely resolve the quest, includes defensive null checks, and only triggers once by checking the quest currentStage field. Appropriate logging is added for debugging. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,6 +10,7 @@ For testing notes, milestone summaries, known issues, and next steps, see [`docs
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Quest auto-start on COVault109 exit: "Out of Time" quest (MQ102) now starts automatically and sets to stage 10 when the player leaves COVault109 for the first time.
|
||||||
- Complexion texture form reference (`complexionFormId`) to appearance payload so hands, arms, and body match the synced skin tone (follows the existing hair colour pattern).
|
- Complexion texture form reference (`complexionFormId`) to appearance payload so hands, arms, and body match the synced skin tone (follows the existing hair colour pattern).
|
||||||
- Appearance protocol version 3 with an optional `tints` field (character tint layers: skin tone, complexion, makeup, beard shade) so proxies can mirror the sender's skin colour and facial detail.
|
- Appearance protocol version 3 with an optional `tints` field (character tint layers: skin tone, complexion, makeup, beard shade) so proxies can mirror the sender's skin colour and facial detail.
|
||||||
- Capture of player/NPC `tintingData` in `CaptureLocalAppearance`, plus game-thread application of tints onto runtime proxies: existing entries are updated in place by template ID, and missing entries are reconstructed against the proxy race's tint templates (skipped when no template resolves).
|
- Capture of player/NPC `tintingData` in `CaptureLocalAppearance`, plus game-thread application of tints onto runtime proxies: existing entries are updated in place by template ID, and missing entries are reconstructed against the proxy race's tint templates (skipped when no template resolves).
|
||||||
|
|||||||
@@ -7,6 +7,34 @@ failed experiments, successful tests, and next steps.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-06-30 - COVault109 Exit Quest Auto-Start
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
Added automatic quest start for "Out of Time" (MQ102, FormID: 0x0001CC2A) when the player first leaves COVault109. The quest is started and immediately set to stage 10, skipping the vault entry sequence. This provides a smoother transition into the multiplayer world after character creation.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
- `plugin/src/main.cpp`
|
||||||
|
- `changelog.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
- Added `TryStartOutOfTimeQuest()` helper function that uses `TESDataHandler::LookupForm` to safely resolve the MQ102 quest from Fallout4.esm.
|
||||||
|
- Function includes safety checks: verifies data handler availability, confirms quest form resolution, and skips if the quest is already started.
|
||||||
|
- Called during the solo cell exit detection in `PollLocalPlayerTransform()` when `soloCellTransformSuppressed` transitions from true to false.
|
||||||
|
- Logs informational messages on quest start and warnings for any resolution failures.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- Compile test: no linter errors.
|
||||||
|
- Recommended manual check: create a new character, complete Vault 111, exit into the Commonwealth world, and verify that MQ102 is started and set to stage 10 (check quest menu or `getquestcompletedstage 0001CC2A` console command).
|
||||||
|
- Verify the quest does not start if the player re-enters and exits COVault109 (safety check works).
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
- None currently known.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
- Manual in-game testing to confirm quest stage progression works correctly after auto-start.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2026-06-30 - Complexion Texture Sync (Appearance v3, Phase 2.1)
|
## 2026-06-30 - Complexion Texture Sync (Appearance v3, Phase 2.1)
|
||||||
|
|||||||
+33
-4
@@ -668,6 +668,34 @@ namespace
|
|||||||
a_transform.angleZ));
|
a_transform.angleZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TryStartOutOfTimeQuest()
|
||||||
|
{
|
||||||
|
constexpr auto MQ102_FORM_ID = 0x0001CC2A;
|
||||||
|
constexpr auto MQ102_TARGET_STAGE = 10;
|
||||||
|
|
||||||
|
auto* dataHandler = RE::TESDataHandler::GetSingleton();
|
||||||
|
if (!dataHandler) {
|
||||||
|
LogWarningWithLocalPlayerPrefix("Failed to get data handler for quest initialization.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* quest = dataHandler->LookupForm<RE::TESQuest>(MQ102_FORM_ID, "Fallout4.esm");
|
||||||
|
if (!quest) {
|
||||||
|
LogWarningWithLocalPlayerPrefix("Failed to resolve MQ102 quest form.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quest->currentStage != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quest->SetStage(MQ102_TARGET_STAGE);
|
||||||
|
|
||||||
|
LogInfoWithLocalPlayerPrefix(std::format(
|
||||||
|
"Started quest MQ102 (Out of Time) and set to stage {}, triggered by leaving COVault109.",
|
||||||
|
MQ102_TARGET_STAGE));
|
||||||
|
}
|
||||||
|
|
||||||
const char* GetSpecialMovementType(
|
const char* GetSpecialMovementType(
|
||||||
const PlayerLocation& a_previousLocation,
|
const PlayerLocation& a_previousLocation,
|
||||||
const PlayerLocation& a_currentLocation,
|
const PlayerLocation& a_currentLocation,
|
||||||
@@ -766,10 +794,11 @@ namespace
|
|||||||
LogInfoWithLocalPlayerPrefix("COVault109 is a solo cell; sending entry location update before suppressing further transforms.");
|
LogInfoWithLocalPlayerPrefix("COVault109 is a solo cell; sending entry location update before suppressing further transforms.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soloCellTransformSuppressed) {
|
if (soloCellTransformSuppressed) {
|
||||||
LogInfoWithLocalPlayerPrefix("Local player left solo cell; transform packet sending resumed.");
|
LogInfoWithLocalPlayerPrefix("Local player left solo cell; transform packet sending resumed.");
|
||||||
soloCellTransformSuppressed = false;
|
TryStartOutOfTimeQuest();
|
||||||
}
|
soloCellTransformSuppressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hasLastTransform) {
|
if (!hasLastTransform) {
|
||||||
lastSentTransform = currentTransform;
|
lastSentTransform = currentTransform;
|
||||||
|
|||||||
Reference in New Issue
Block a user