Handle Vault 109 quest handoff

When the local player leaves COVault109, the plugin now completes MQ101 and starts MQ102 at stage 10 on the game thread, with a log entry for confirmation. Updated the changelog and architecture/dev-log docs to reflect the new Vault 109 flow, and refreshed the compiled Creation Kit script artifact.
This commit is contained in:
2026-06-30 16:21:30 +12:00
parent 4ed671464e
commit 6fdc63c36d
5 changed files with 50 additions and 2 deletions
+1
View File
@@ -10,6 +10,7 @@ For testing notes, milestone summaries, known issues, and next steps, see [`docs
## [Unreleased] ## [Unreleased]
### Added ### Added
- `COVault109` exit handoff in the plugin: when the local player leaves the solo cell, MQ101 (`War Never Changes`) is completed and MQ102 (`Out of Time`) is started at stage 10.
- Optional `isPipboyOpen` transform state so receivers can detect remote Pip-Boy open/close transitions. The state is synced and logged for diagnostics; no proxy Pip-Boy animation is driven (the third-person humanoid behavior graph has no Pip-Boy raise/use animation — it is first-person only), leaving room for a future custom third-person animation. - Optional `isPipboyOpen` transform state so receivers can detect remote Pip-Boy open/close transitions. The state is synced and logged for diagnostics; no proxy Pip-Boy animation is driven (the third-person humanoid behavior graph has no Pip-Boy raise/use animation — it is first-person only), leaving room for a future custom third-person animation.
- Optional `appearance` transform snapshots for best-effort runtime proxy body and face visuals, including height, body morph weight, body tint, hair colors, head-part IDs, and morph slider values while leaving gender switching out. - Optional `appearance` transform snapshots for best-effort runtime proxy body and face visuals, including height, body morph weight, body tint, hair colors, head-part IDs, and morph slider values while leaving gender switching out.
- Game-thread proxy appearance application for supported `appearance` fields after runtime proxy 3D is ready, with race switching deferred for future proxy-base compatibility work. - Game-thread proxy appearance application for supported `appearance` fields after runtime proxy 3D is ready, with race switching deferred for future proxy-base compatibility work.
+4 -2
View File
@@ -46,8 +46,10 @@ both send and receive paths:
creation. On entry it can send one location update so other clients hold any creation. On entry it can send one location update so other clients hold any
stale proxy, then outgoing transform packets are suppressed and remote proxy stale proxy, then outgoing transform packets are suppressed and remote proxy
representation is skipped while the local player remains inside. Looks and representation is skipped while the local player remains inside. Looks and
SPECIAL setup therefore stay visually single-player. The relay protocol is SPECIAL setup therefore stay visually single-player. When the local player
unchanged; the rule is enforced client-side by the plugin. leaves this cell, the plugin completes MQ101 (`War Never Changes`) and starts
MQ102 (`Out of Time`) at stage 10. The relay protocol is unchanged; the rule
is enforced client-side by the plugin.
14. On the game-thread update path, the proxy controller reads a copied 14. On the game-thread update path, the proxy controller reads a copied
remote-player snapshot before attempting any actor work. The snapshot is remote-player snapshot before attempting any actor work. The snapshot is
sorted by `playerId`, and only remote players with valid transform data in sorted by `playerId`, and only remote players with valid transform data in
+31
View File
@@ -9,6 +9,37 @@ failed experiments, successful tests, and next steps.
--- ---
## 2026-06-30 - Vault 109 Main Quest Handoff
### Summary
Added a game-thread quest handoff when the local player exits `COVault109`, completing `War Never Changes` and starting `Out of Time` at stage 10.
### Files Changed
- `plugin/src/main.cpp`
- `changelog.md`
- `docs/dev-log.md`
- `docs/architecture.md`
### Details
- Reused the existing `COVault109` solo-cell tracking in local transform polling so the trigger fires as soon as the previous known location was the solo cell and the current location is not.
- Runs Fallout 4 console quest commands on the plugin game-thread update path: `completequest MQ101`, `startquest MQ102`, and `setstage MQ102 10`.
- Logs the handoff with the quest editor IDs and form IDs for confirmation in `CommonwealthOnline.log`.
### Testing
- Ran `build.bat`; `CommonwealthOnline.dll` compiled and linked successfully.
- Not run in-game in this session.
- Expected result: leaving `COVault109` completes MQ101 (`0001ED86`) and starts MQ102 (`0001CC2A`) at stage 10.
- Recommended log check: confirm `CommonwealthOnline.log` contains the Vault 109 quest handoff message after exiting the cell.
### Known Issues
- In-game confirmation is still needed to verify the vanilla quest scripts accept the handoff cleanly from the custom Vault 109 flow.
### Next Steps
- Start the server, connect one Fallout 4 instance, leave `COVault109`, and verify MQ101 is completed while MQ102 is active at stage 10.
- Connect two Fallout 4 instances and confirm outgoing transform packets, server relay, remote state parsing, and visible proxy movement still work after leaving the solo cell.
---
## 2026-06-30 - Pip-Boy Third-Person Behavior Investigation ## 2026-06-30 - Pip-Boy Third-Person Behavior Investigation
### Summary ### Summary
+14
View File
@@ -13,6 +13,7 @@
#include "RE/B/BIPED_OBJECT.h" #include "RE/B/BIPED_OBJECT.h"
#include "RE/B/BipedAnim.h" #include "RE/B/BipedAnim.h"
#include "RE/B/BSFixedString.h" #include "RE/B/BSFixedString.h"
#include "RE/C/Console.h"
#include "RE/I/IAnimationGraphManagerHolder.h" #include "RE/I/IAnimationGraphManagerHolder.h"
#include "RE/P/PipboyManager.h" #include "RE/P/PipboyManager.h"
#include "RE/P/PipboyMenu.h" #include "RE/P/PipboyMenu.h"
@@ -647,6 +648,16 @@ namespace
} }
} }
void AdvanceMainQuestAfterVault109Exit()
{
RE::Console::ExecuteCommand("completequest MQ101");
RE::Console::ExecuteCommand("startquest MQ102");
RE::Console::ExecuteCommand("setstage MQ102 10");
LogInfoWithLocalPlayerPrefix(
"Player left COVault109; completed MQ101 (0001ED86) and started MQ102 (0001CC2A) at stage 10.");
}
void PollLocalPlayerTransform() void PollLocalPlayerTransform()
{ {
auto* player = TryGetLocalPlayer(); auto* player = TryGetLocalPlayer();
@@ -717,6 +728,9 @@ namespace
if (soloCellTransformSuppressed) { if (soloCellTransformSuppressed) {
LogInfoWithLocalPlayerPrefix("Local player left solo cell; transform packet sending resumed."); LogInfoWithLocalPlayerPrefix("Local player left solo cell; transform packet sending resumed.");
if (hasLastTransform && lastKnownLocation.isSoloCell && !currentLocation.isSoloCell) {
AdvanceMainQuestAfterVault109Exit();
}
soloCellTransformSuppressed = false; soloCellTransformSuppressed = false;
} }