From 3dff7476f65d9edfc0f21258f7714c086fae3ea5 Mon Sep 17 00:00:00 2001 From: alphanin9 <47785076+alphanin9@users.noreply.github.com> Date: Fri, 22 Nov 2024 05:49:27 +0200 Subject: [PATCH] Refactoring and bug fixes --- deps/sharedpunk | 2 +- scripting/NGPlusBugfixing.reds | 2 +- scripting/NGPlusButtonAdder.reds | 1 + scripting/NGPlusCharacterInitialStats.reds | 29 +++++---- scripting/NGPlusOnReadyForEquipment.reds | 2 - scripting/NGPlusPlayerDevelopmentData.reds | 1 + scripting/NGPlusSpawnTagController.reds | 28 -------- scripting/NGPlusStartNewGameReplacer.reds | 32 ++++++++++ scripting/NewGamePlusSystem.reds | 29 ++++----- scripting/Scenario/NGPlusController.reds | 20 +----- .../NGPlusExpansionNewGameMenuAdditions.reds | 24 ++----- .../NGPlusGameDefinitionSelector.reds | 20 +----- ...GPlusStandaloneGameDefinitionSelector.reds | 20 +----- src/filesystem/SaveFS.cpp | 3 +- src/hooking/hooking.cpp | 60 +----------------- src/main.cpp | 1 + .../New/Nodes/ScriptableSystemsContainer.cpp | 2 +- src/redscript_api/redscriptBindings.cpp | 25 +++++++- src/util/migration/migration.cpp | 19 +++--- wolvenkit/custom_refs.txt | 25 +------- wolvenkit/layout.xml | 2 +- .../packed/archive/pc/mod/NewGamePlus.archive | Bin 3960832 -> 3960832 bytes .../archive/mod/quest/NewGamePlus.gamedef | Bin 1217 -> 1217 bytes .../mod/quest/NewGamePlus_Q001.gamedef | Bin 1232 -> 1228 bytes 24 files changed, 123 insertions(+), 224 deletions(-) delete mode 100644 scripting/NGPlusSpawnTagController.reds create mode 100644 scripting/NGPlusStartNewGameReplacer.reds diff --git a/deps/sharedpunk b/deps/sharedpunk index 326dcaa..c937366 160000 --- a/deps/sharedpunk +++ b/deps/sharedpunk @@ -1 +1 @@ -Subproject commit 326dcaa35fb199b85de1ffefe172183156ade7c0 +Subproject commit c9373668c90212848b2f33f1122a4a648d03cfec diff --git a/scripting/NGPlusBugfixing.reds b/scripting/NGPlusBugfixing.reds index 2bfa6d4..636bb14 100644 --- a/scripting/NGPlusBugfixing.reds +++ b/scripting/NGPlusBugfixing.reds @@ -42,7 +42,7 @@ public class NGPlusEP1StatusListener extends ScriptableSystem { let ngPlusSystem = GameInstance.GetNewGamePlusSystem(); // Fix: Encounter testing no longer triggers EP1 activation - if ngPlusSystem.IsInNewGamePlusSave() { + if ngPlusSystem.IsInNewGamePlusPrologue() || ngPlusSystem.IsInNewGamePlusHeistOrStandalone() { ngPlusSystem.Spew("EP1 installed, but not activated: loading..."); ngPlusSystem.LoadExpansionIntoSave(); } diff --git a/scripting/NGPlusButtonAdder.reds b/scripting/NGPlusButtonAdder.reds index d910e7c..7440919 100644 --- a/scripting/NGPlusButtonAdder.reds +++ b/scripting/NGPlusButtonAdder.reds @@ -8,6 +8,7 @@ private func AddMenuItem(const label: script_ref, spawnEvent: CName) -> // Assuming no modifications, the only call with OnNewGame as an arg should be from singleplayer menu if Equals(spawnEvent, n"OnNewGame") { + // Make this async and recall PopulateMenuItems if !GameInstance.GetNewGamePlusSystem().HasPointOfNoReturnSave() { return; } diff --git a/scripting/NGPlusCharacterInitialStats.reds b/scripting/NGPlusCharacterInitialStats.reds index 62c8331..061e506 100644 --- a/scripting/NGPlusCharacterInitialStats.reds +++ b/scripting/NGPlusCharacterInitialStats.reds @@ -47,8 +47,11 @@ private final func SetNGPlusAttributePreset() -> Void { protected cb func OnInitialize() -> Bool { let ngPlusSystem = GameInstance.GetNewGamePlusSystem(); - let isNgPlusActive = ngPlusSystem.GetNewGamePlusState(); - let isStandalone = ngPlusSystem.GetStandaloneState(); + let ngPlusQuest = ngPlusSystem.GetNewGamePlusQuest(); + + let isNgPlusActive = Equals(ngPlusQuest, ENGPlusType.StartFromQ001) || Equals(ngPlusQuest, ENGPlusType.StartFromQ101); + + let isStandalone = Equals(ngPlusQuest, ENGPlusType.StartFromQ101_ProgressionBuild); super.OnInitialize(); inkWidgetRef @@ -91,8 +94,10 @@ let m_ngPlusSaveData: ref; @wrapMethod(CharacterCreationStatsMenu) protected cb func OnInitialize() -> Bool { - this.m_isNgPlusActive = GameInstance.GetNewGamePlusSystem().GetNewGamePlusState(); - this.m_ngPlusSaveData = GameInstance.GetNewGamePlusSystem().GetProgressionData(); + let ngPlusSystem = GameInstance.GetNewGamePlusSystem(); + let ngPlusQuest = ngPlusSystem.GetNewGamePlusQuest(); + this.m_isNgPlusActive = Equals(ngPlusQuest, ENGPlusType.StartFromQ001) || Equals(ngPlusQuest, ENGPlusType.StartFromQ101); + this.m_ngPlusSaveData = ngPlusSystem.GetProgressionData(); return wrappedMethod(); } @@ -127,14 +132,14 @@ private final func ResetAllBtnBackToBaseline() -> Void { i += 1; } if this.m_isNgPlusActive { - let minAttributeValue = 3.0; + let minAttributeValue = 3; let statsSystemResults = this.m_ngPlusSaveData.GetStatsSystemResults(); - let bodyAttributeAdded: Int32 = Cast(statsSystemResults.GetBody() - minAttributeValue); - let reflexAttributeAdded: Int32 = Cast(statsSystemResults.GetReflexes() - minAttributeValue); - let techAttributeAdded: Int32 = Cast(statsSystemResults.GetTechnicalAbility() - minAttributeValue); - let intAttributeAdded: Int32 = Cast(statsSystemResults.GetIntelligence() - minAttributeValue); - let coolAttributeAdded: Int32 = Cast(statsSystemResults.GetCool() - minAttributeValue); + let bodyAttributeAdded: Int32 = Cast(statsSystemResults.GetBody()) - minAttributeValue; + let reflexAttributeAdded: Int32 = Cast(statsSystemResults.GetReflexes()) - minAttributeValue; + let techAttributeAdded: Int32 = Cast(statsSystemResults.GetTechnicalAbility()) - minAttributeValue; + let intAttributeAdded: Int32 = Cast(statsSystemResults.GetIntelligence()) - minAttributeValue; + let coolAttributeAdded: Int32 = Cast(statsSystemResults.GetCool()) - minAttributeValue; this.m_startingAttributePoints = bodyAttributeAdded + reflexAttributeAdded @@ -162,7 +167,7 @@ protected cb func OnInitialize() -> Bool { let attributeType: gamedataStatType; super.OnInitialize(); this.RequestCameraChange(n"Summary_Preview"); - if this.m_characterCustomizationState.IsExpansionStandalone() || GameInstance.GetNewGamePlusSystem().GetStandaloneState() { + if this.m_characterCustomizationState.IsExpansionStandalone() || Equals(GameInstance.GetNewGamePlusSystem().GetNewGamePlusQuest(), ENGPlusType.StartFromQ101_ProgressionBuild) { this.SkipStatsMenu(); } attributeType = gamedataStatType.Strength; @@ -279,7 +284,7 @@ protected cb func OnInitialize() -> Bool { @replaceMethod(characterCreationSummaryMenu) protected cb func OnInitialize() -> Bool { - let isStandalone = this.m_characterCustomizationState.IsExpansionStandalone() || GameInstance.GetNewGamePlusSystem().GetStandaloneState(); + let isStandalone = this.m_characterCustomizationState.IsExpansionStandalone() || Equals(GameInstance.GetNewGamePlusSystem().GetNewGamePlusQuest(), ENGPlusType.StartFromQ101_ProgressionBuild); super.OnInitialize(); this.SetUpLifePath(); diff --git a/scripting/NGPlusOnReadyForEquipment.reds b/scripting/NGPlusOnReadyForEquipment.reds index f917d3f..1b7d5a4 100644 --- a/scripting/NGPlusOnReadyForEquipment.reds +++ b/scripting/NGPlusOnReadyForEquipment.reds @@ -1,6 +1,5 @@ module NGPlus.PlayerProgression -import NGPlus.SpawnTags.NewGamePlusSpawnTagController import NGPlus.EP1Listener.NGPlusEP1StatusListener import NGPlus.Ripperdoc.NGPlusTutorialCyberwareProvider @@ -69,7 +68,6 @@ class PlayerProgressionLoader { let playerDevelopmentData = PlayerDevelopmentSystem.GetInstance(player).GetDevelopmentData(player); playerDevelopmentData.ScaleNPCsToPlayerLevel(); - NewGamePlusSpawnTagController.RestoreSpawnTags(); NGPlusEP1StatusListener.ApplyRandomEncounterDisabler(questsSystem); this.m_ngPlusSystem.Spew("PlayerProgressionLoader::LoadPlayerProgression done!"); diff --git a/scripting/NGPlusPlayerDevelopmentData.reds b/scripting/NGPlusPlayerDevelopmentData.reds index c626c91..dc1562c 100644 --- a/scripting/NGPlusPlayerDevelopmentData.reds +++ b/scripting/NGPlusPlayerDevelopmentData.reds @@ -3,6 +3,7 @@ module NGPlus.PlayerDevelopmentData @addField(PlayerDevelopmentData) let m_isInNgPlus: Bool; +// TODO: make this compatible with Replay - eventually @replaceMethod(PlayerDevelopmentData) private const final func ModifyProficiencyLevel(proficiencyIndex: Int32, isDebug: Bool, opt levelIncrease: Int32) -> Void { let Blackboard: ref; diff --git a/scripting/NGPlusSpawnTagController.reds b/scripting/NGPlusSpawnTagController.reds deleted file mode 100644 index 7462dcb..0000000 --- a/scripting/NGPlusSpawnTagController.reds +++ /dev/null @@ -1,28 +0,0 @@ -module NGPlus.SpawnTags - -public class NewGamePlusSpawnTagController { - public static func SetSpawnTags(newSpawnTag: CName) { - TweakDBManager.SetFlat(t"LifePaths.Nomad.newGameSpawnTag", newSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.Nomad"); - TweakDBManager.SetFlat(t"LifePaths.Corporate.newGameSpawnTag", newSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.Corporate"); - TweakDBManager.SetFlat(t"LifePaths.StreetKid.newGameSpawnTag", newSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.StreetKid"); - } - - public static func RestoreSpawnTags() { - // Yes, those are hardcoded - // This is not actually a problem, seeing as lifepath spawn tags are unlikely to change in our lifetime - - let nomadSpawnTag = n"#q000_nomad_wp_garage_start"; - let corpoSpawnTag = n"#q000_corpo_spwn_player_toilet_female"; - let streetKidSpawnTag = n"#q000_kid_spawn_start"; - - TweakDBManager.SetFlat(t"LifePaths.Nomad.newGameSpawnTag", nomadSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.Nomad"); - TweakDBManager.SetFlat(t"LifePaths.Corporate.newGameSpawnTag", corpoSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.Corporate"); - TweakDBManager.SetFlat(t"LifePaths.StreetKid.newGameSpawnTag", streetKidSpawnTag); - TweakDBManager.UpdateRecord(t"LifePaths.StreetKid"); - } -} \ No newline at end of file diff --git a/scripting/NGPlusStartNewGameReplacer.reds b/scripting/NGPlusStartNewGameReplacer.reds new file mode 100644 index 0000000..0daf696 --- /dev/null +++ b/scripting/NGPlusStartNewGameReplacer.reds @@ -0,0 +1,32 @@ + +@replaceMethod(characterCreationSummaryMenu) +protected cb func OnOutroComplete(anim: ref) { + let ccSystem = this.GetCharacterCustomizationSystem(); + ccSystem.FinalizeState(); + + let ngPlusSystem = GameInstance.GetNewGamePlusSystem(); + + let ngPlusQuest = ngPlusSystem.GetNewGamePlusQuest(); + + if NotEquals(ngPlusQuest, ENGPlusType.Count) && NotEquals(ngPlusQuest, ENGPlusType.Invalid) { + // Fairly safe cast, no other derivatives + ngPlusSystem.Spew(s"Starting NG+ playthrough with quest type \(ngPlusQuest)..."); + ngPlusSystem + .LaunchNewGamePlus( + this.m_characterCustomizationState as gameuiCharacterCustomizationState + ); + } else { + this + .GetSystemRequestsHandler() + .StartNewGame(this.m_characterCustomizationState); + if this.m_characterCustomizationState.IsExpansionStandalone() { + this.GetTelemetrySystem().LogPlaythroughEp1(); + } + } + + this + .GetTelemetrySystem() + .LogInitialChoiceSetStatege(telemetryInitalChoiceStage.Finished); + this.GetTelemetrySystem().LogNewGameStarted(); + super.NextMenu(); +} diff --git a/scripting/NewGamePlusSystem.reds b/scripting/NewGamePlusSystem.reds index a2c557a..3ad1e94 100644 --- a/scripting/NewGamePlusSystem.reds +++ b/scripting/NewGamePlusSystem.reds @@ -114,15 +114,12 @@ public native class NGPlusProgressionData extends IScriptable { } // End aggregator -enum ENewGamePlusStartType { +enum ENGPlusType { StartFromQ001 = 0, StartFromQ101 = 1, - StartFromQ001_NoEP1 = 2, - StartFromQ101_NoEP1 = 3, - StartFromQ101_ProgressionBuild = 4, - StartFromQ101_ProgressionBuild_NoEP1 = 5, - Count = 6, - Invalid = 7 + StartFromQ101_ProgressionBuild = 2, + Count = 3, + Invalid = 4 } public native class NewGamePlusSystem extends IGameSystem { @@ -130,14 +127,8 @@ public native class NewGamePlusSystem extends IGameSystem { public native func ParsePointOfNoReturnSaveData(saveName: script_ref) -> Bool; - public native func GetNewGamePlusState() -> Bool; - - public native func SetNewGamePlusState(newState: Bool) -> Void; - public native func GetProgressionData() -> ref; - public native func SetNewGamePlusGameDefinition(startType: ENewGamePlusStartType) -> Void ; - public native func IsSaveValidForNewGamePlus(saveName: script_ref) -> Bool; public native func ResolveNewGamePlusSaves(saves: script_ref<[String]>) -> [Int32]; @@ -148,10 +139,16 @@ public native class NewGamePlusSystem extends IGameSystem { public native func Spew(str: script_ref) -> Void; public native func Error(str: script_ref) -> Void; - public native func GetStandaloneState() -> Bool; - public native func SetStandaloneState(aNewState: Bool) -> Void; - public native func IsInNewGamePlusSave() -> Bool; + public native func IsInNewGamePlusPrologue() -> Bool; + public native func IsInNewGamePlusHeistOrStandalone() -> Bool; + + // Used in place of StartNewGame, starts new session with selected game definition + public native func LaunchNewGamePlus(state: ref) -> Void; + + // Used in place of SetNewGamePlusState() and SetStandaloneState() + public native func SetNewGamePlusQuest(type: ENGPlusType) -> Void; + public native func GetNewGamePlusQuest() -> ENGPlusType; } @addMethod(GameInstance) diff --git a/scripting/Scenario/NGPlusController.reds b/scripting/Scenario/NGPlusController.reds index 1c71c29..a5e11c6 100644 --- a/scripting/Scenario/NGPlusController.reds +++ b/scripting/Scenario/NGPlusController.reds @@ -1,5 +1,3 @@ -import NGPlus.SpawnTags.NewGamePlusSpawnTagController - public class NewGamePlusSelectionController extends gameuiSaveHandlingController { private let m_list: inkCompoundRef; private let m_noSavedGamesLabel: inkWidgetRef; @@ -28,10 +26,6 @@ public class NewGamePlusSelectionController extends gameuiSaveHandlingController private let m_sourceIndex: Int32; private let m_ngPlusSystem: ref; - private static func GetPointOfNoReturnPrefix() -> String { - return "PointOfNoReturn"; - } - // WolvenKit only lets me specify *some* things, but inkwidgets generally are just enough private final func InitializeUninitializableWKitVariables() { this.m_animDelayBetweenSlots = 0.150000006; @@ -54,7 +48,7 @@ public class NewGamePlusSelectionController extends gameuiSaveHandlingController this.m_systemHandler = this.GetSystemRequestsHandler(); this.m_ngPlusSystem = GameInstance.GetNewGamePlusSystem(); - this.m_ngPlusSystem.SetStandaloneState(false); + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); this .m_systemHandler .RegisterToCallback(n"OnSavesForLoadReady", this, n"OnSavesForLoadReady"); @@ -76,7 +70,6 @@ public class NewGamePlusSelectionController extends gameuiSaveHandlingController this.m_isInputDisabled = false; this.PlayLoadingAnimation(); this.m_isEp1Enabled = IsEP1(); - this.m_ngPlusSystem.SetNewGamePlusState(false); // HACK, NOT SURE ABOUT THIS WORKING OUT FINE } protected cb func OnUninitialize() -> Bool { @@ -85,8 +78,7 @@ public class NewGamePlusSelectionController extends gameuiSaveHandlingController protected cb func OnButtonRelease(evt: ref) -> Bool { if evt.IsAction(n"back") { - NewGamePlusSpawnTagController.RestoreSpawnTags(); - this.m_ngPlusSystem.SetNewGamePlusState(false); + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); this.m_eventDispatcher.SpawnEvent(n"OnMainMenuBack"); } } @@ -144,19 +136,13 @@ public class NewGamePlusSelectionController extends gameuiSaveHandlingController private final func OnSelectedSave(controller: ref) -> Void { let saveName = this.m_saves[controller.Index()]; - this.m_ngPlusSystem.Spew(s"Loading save \(saveName) for player progression transfer..."); - - let result = this.m_ngPlusSystem.ParsePointOfNoReturnSaveData(saveName); - - this.m_ngPlusSystem.Spew(s"Progression loader result: \(result)"); - if !result { + if !this.m_ngPlusSystem.ParsePointOfNoReturnSaveData(saveName) { // NOTE: add localization? Better error messages? controller.SetInvalid("Failed to parse progression data!\nTry going into a game and saving again."); return; } - this.m_ngPlusSystem.SetNewGamePlusState(true); this.m_eventDispatcher.SpawnEvent(n"OnAccept"); } diff --git a/scripting/Scenario/NGPlusExpansionNewGameMenuAdditions.reds b/scripting/Scenario/NGPlusExpansionNewGameMenuAdditions.reds index 971a7c9..8425a0b 100644 --- a/scripting/Scenario/NGPlusExpansionNewGameMenuAdditions.reds +++ b/scripting/Scenario/NGPlusExpansionNewGameMenuAdditions.reds @@ -1,7 +1,5 @@ module NGPlus.ExpansionNewGameAdditions -import NGPlus.SpawnTags.NewGamePlusSpawnTagController - @addField(ExpansionNewGame) private let m_ngPlusStandaloneButton: inkWidgetRef; @@ -46,11 +44,8 @@ protected cb func OnIntroComplete(anim: ref) -> Bool { protected func PriorMenu() -> Void { // Just in case... let newGamePlusSystem = GameInstance.GetNewGamePlusSystem(); + newGamePlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); - newGamePlusSystem.SetNewGamePlusState(false); - newGamePlusSystem.SetStandaloneState(false); - - NewGamePlusSpawnTagController.RestoreSpawnTags(); wrappedMethod(); } @@ -69,10 +64,8 @@ protected cb func OnHoverOverNGPlusStandalone(evt: ref) -> Bool protected cb func OnPressBaseGame(evt: ref) -> Bool { let newGamePlusSystem = GameInstance.GetNewGamePlusSystem(); - newGamePlusSystem.SetNewGamePlusState(false); - newGamePlusSystem.SetStandaloneState(false); + newGamePlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); - NewGamePlusSpawnTagController.RestoreSpawnTags(); wrappedMethod(evt); } @@ -80,10 +73,7 @@ protected cb func OnPressBaseGame(evt: ref) -> Bool { protected cb func OnPressExpansion(evt: ref) -> Bool { let newGamePlusSystem = GameInstance.GetNewGamePlusSystem(); - newGamePlusSystem.SetNewGamePlusState(false); - newGamePlusSystem.SetStandaloneState(false); - - NewGamePlusSpawnTagController.RestoreSpawnTags(); + newGamePlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); wrappedMethod(evt); } @@ -93,16 +83,10 @@ protected cb func OnPressNGPlusStandalone(evt: ref) -> Bool { this.PlaySound(n"Button", n"OnPress"); let newGamePlusSystem = GameInstance.GetNewGamePlusSystem(); - - newGamePlusSystem.SetNewGamePlusState(true); - newGamePlusSystem.SetStandaloneState(true); + newGamePlusSystem.SetNewGamePlusQuest(ENGPlusType.StartFromQ101_ProgressionBuild); this.m_characterCustomizationState.SetIsExpansionStandalone(false); - newGamePlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ101_ProgressionBuild); - - NewGamePlusSpawnTagController.SetSpawnTags(n"#q101_spwn_player"); - this.NextMenu(); } } \ No newline at end of file diff --git a/scripting/Scenario/NGPlusGameDefinitionSelector.reds b/scripting/Scenario/NGPlusGameDefinitionSelector.reds index 423bbda..bc0c472 100644 --- a/scripting/Scenario/NGPlusGameDefinitionSelector.reds +++ b/scripting/Scenario/NGPlusGameDefinitionSelector.reds @@ -1,5 +1,3 @@ -import NGPlus.SpawnTags.NewGamePlusSpawnTagController - public class NewGamePlusStartingPointController extends BaseCharacterCreationController { public let m_newGameDescription: inkTextRef; public let m_textureTop: inkImageRef; @@ -72,14 +70,7 @@ public class NewGamePlusStartingPointController extends BaseCharacterCreationCon protected cb func OnPressQ001(evt: ref) -> Bool { if evt.IsAction(n"click") && !this.m_isInputLocked { this.PlaySound(n"Button", n"OnPress"); - NewGamePlusSpawnTagController.SetSpawnTags(n"#q000_hym_theater_start"); - - if this.m_ep1Enabled { - this.m_ngPlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ001); - } else { - this.m_ngPlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ001_NoEP1); - } - + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.StartFromQ001); this.OnSelectedOption(); } } @@ -87,14 +78,7 @@ public class NewGamePlusStartingPointController extends BaseCharacterCreationCon protected cb func OnPressQ101(evt: ref) -> Bool { if evt.IsAction(n"click") && !this.m_isInputLocked { this.PlaySound(n"Button", n"OnPress"); - NewGamePlusSpawnTagController.SetSpawnTags(n"#q101_spwn_player"); - - if this.m_ep1Enabled { - this.m_ngPlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ101); - } else { - this.m_ngPlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ101_NoEP1); - } - + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.StartFromQ101); this.OnSelectedOption(); } } diff --git a/scripting/Scenario/NGPlusStandaloneGameDefinitionSelector.reds b/scripting/Scenario/NGPlusStandaloneGameDefinitionSelector.reds index 6505dc6..8a2754b 100644 --- a/scripting/Scenario/NGPlusStandaloneGameDefinitionSelector.reds +++ b/scripting/Scenario/NGPlusStandaloneGameDefinitionSelector.reds @@ -1,5 +1,3 @@ -import NGPlus.SpawnTags.NewGamePlusSpawnTagController - public class NewGamePlusStandaloneStartingPointController extends BaseCharacterCreationController { public let m_newGameDescription: inkTextRef; public let m_textureTop: inkImageRef; @@ -63,11 +61,7 @@ public class NewGamePlusStandaloneStartingPointController extends BaseCharacterC protected cb func OnPressBasegame(evt: ref) -> Bool { if evt.IsAction(n"click") && !this.m_isInputLocked { this.PlaySound(n"Button", n"OnPress"); - NewGamePlusSpawnTagController.RestoreSpawnTags(); - - this.m_ngPlusSystem.SetNewGamePlusState(false); - this.m_ngPlusSystem.SetStandaloneState(false); - + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); this.OnSelectedOption(); } } @@ -75,12 +69,7 @@ public class NewGamePlusStandaloneStartingPointController extends BaseCharacterC protected cb func OnPressQ101(evt: ref) -> Bool { if evt.IsAction(n"click") && !this.m_isInputLocked { this.PlaySound(n"Button", n"OnPress"); - - NewGamePlusSpawnTagController.SetSpawnTags(n"#q101_spwn_player"); - this.m_ngPlusSystem.SetNewGamePlusGameDefinition(ENewGamePlusStartType.StartFromQ101_ProgressionBuild_NoEP1); - this.m_ngPlusSystem.SetNewGamePlusState(true); - this.m_ngPlusSystem.SetStandaloneState(true); - + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.StartFromQ101_ProgressionBuild); this.OnSelectedOption(); } } @@ -120,10 +109,7 @@ public class NewGamePlusStandaloneStartingPointController extends BaseCharacterC this.GetTelemetrySystem().LogInitialChoiceSetStatege(telemetryInitalChoiceStage.None); this.GetCharacterCustomizationSystem().ClearState(); - this.m_ngPlusSystem.SetNewGamePlusState(false); - this.m_ngPlusSystem.SetStandaloneState(false); - - NewGamePlusSpawnTagController.RestoreSpawnTags(); + this.m_ngPlusSystem.SetNewGamePlusQuest(ENGPlusType.Invalid); super.PriorMenu(); } diff --git a/src/filesystem/SaveFS.cpp b/src/filesystem/SaveFS.cpp index 3576276..72f8f60 100644 --- a/src/filesystem/SaveFS.cpp +++ b/src/filesystem/SaveFS.cpp @@ -652,7 +652,8 @@ bool ReadSaveFileToBuffer(const Red::CString& aSaveName, std::vector& stream->ReadWrite(&aBuffer[0], static_cast(fileSize)); - constexpr auto c_testSaveStream = true; + // Tests look OK, can move to this from WKit way once we figure out FDB/persistency/inventory + constexpr auto c_testSaveStream = false; if constexpr (c_testSaveStream) { diff --git a/src/hooking/hooking.cpp b/src/hooking/hooking.cpp index a44fb96..5ef6cda 100644 --- a/src/hooking/hooking.cpp +++ b/src/hooking/hooking.cpp @@ -12,53 +12,9 @@ using namespace Red; namespace hooking { -namespace SelectGameDefinition -{ -enum class GamedefType : char -{ - Basegame = 0, - EP1 = 1, - EP1_Standalone = 2, - GamedefTypesMax = 3 -}; - -ResourcePath* m_detourFn(shared::raw::GameDefinition::SelectMainGameDefinition aCallback, ResourcePath* aDepotPath, - char aGamedefType) -{ - auto type = static_cast(aGamedefType); - - if (!PluginContext::m_isNewGamePlusActive || !PluginContext::m_isInStartNewGame) - { - return aCallback(aDepotPath, aGamedefType); - } - - // Fix for non-EP1 NG+ start - if (type >= GamedefType::EP1_Standalone) - { - return aCallback(aDepotPath, aGamedefType); - } - - *aDepotPath = PluginContext::m_ngPlusGameDefinitionHash; - - PluginContext::m_isNewGamePlusActive = false; - return aDepotPath; -} -} // namespace SelectGameDefinition - -namespace StartNewGame -{ -void __fastcall m_detourFn(shared::raw::Ink::SystemRequestsHandler::StartNewGame aCallback, - ink::ISystemRequestsHandler* aThis, Handle& aState) -{ - PluginContext::m_isInStartNewGame = true; - aCallback(aThis, aState); - PluginContext::m_isInStartNewGame = false; -} -} // namespace StartNewGame - namespace LoadFacts { -void m_detourFn(HashMap& aMap) +void OnLoadTelemetryFactMap(HashMap& aMap) { // We add our own facts to the gatherer aMap.Insert(FNV1a32("ngplus_active"), "ngplus_active"); @@ -68,15 +24,7 @@ void m_detourFn(HashMap& aMap) } // namespace LoadFacts bool InitializeHooking() { - // TODO: move this to proper game session transition using system from replay - // As soon as we have initial loading screen implemented - // Well we have it now - - shared::hook::HookWrap(&SelectGameDefinition::m_detourFn) - .OrDie("Failed to hook GameDefinition::SelectMainGameDefinition"); - shared::hook::HookWrap(&StartNewGame::m_detourFn) - .OrDie("Failed to hook SystemRequestsHandler::StartNewGame"); - shared::hook::HookAfter(&LoadFacts::m_detourFn) + shared::hook::HookAfter(&LoadFacts::OnLoadTelemetryFactMap) .OrDie("Failed to hook Telemetry::LoadFacts"); return true; @@ -84,8 +32,6 @@ bool InitializeHooking() bool DetachHooking() { - return shared::hook::Unhook() && - shared::hook::Unhook() && - shared::hook::Unhook(); + return shared::hook::Unhook(); } } // namespace hooking \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3c39e30..9613952 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(PluginHandle aHandle, EMainReason aReaso TypeInfoRegistrar::RegisterDiscovered(); + // Create struct in shared data with necessary shims for ArchiveXL/TweakXL later constexpr auto c_loadDependenciesFromPluginFolder = true; if constexpr (c_loadDependenciesFromPluginFolder) { diff --git a/src/parsing/New/Nodes/ScriptableSystemsContainer.cpp b/src/parsing/New/Nodes/ScriptableSystemsContainer.cpp index 849ce45..c7c8dc8 100644 --- a/src/parsing/New/Nodes/ScriptableSystemsContainer.cpp +++ b/src/parsing/New/Nodes/ScriptableSystemsContainer.cpp @@ -62,7 +62,7 @@ Handle& ScriptableSystemsContainerNode::GetScriptableSystem(CClass* return s_empty; } - m_handleCache.insert_or_assign(aClass, MakeScriptedHandle(aClass)); + m_handleCache.insert_or_assign(aClass, MakeScriptedHandle(aClass)); auto index = m_systemIndexMap[aClass]; diff --git a/src/redscript_api/redscriptBindings.cpp b/src/redscript_api/redscriptBindings.cpp index e3f1e5c..a83a084 100644 --- a/src/redscript_api/redscriptBindings.cpp +++ b/src/redscript_api/redscriptBindings.cpp @@ -233,6 +233,16 @@ class NewGamePlusSystem : public IGameSystem } } + void SetNewGamePlusQuest(ENGPlusType aType) + { + m_selectedNgPlusType = aType; + } + + ENGPlusType GetNewGamePlusQuest() + { + return m_selectedNgPlusType; + } + bool HasPointOfNoReturnSave() { return files::HasValidPointOfNoReturnSave(); @@ -243,6 +253,7 @@ class NewGamePlusSystem : public IGameSystem return files::IsValidForNewGamePlus(aSaveName->c_str()); } + // TODO: async this, learn how journal gets loaded DynArray ResolveNewGamePlusSaves(Red::ScriptRef>& aSaves) { if (!aSaves) @@ -285,6 +296,7 @@ class NewGamePlusSystem : public IGameSystem #pragma region Transfer bool ParsePointOfNoReturnSaveData(Red::ScriptRef& aSaveName) { + // This needs to be async if (!aSaveName) { return false; @@ -313,7 +325,7 @@ class NewGamePlusSystem : public IGameSystem auto duration = std::chrono::duration_cast(end - start); - PluginContext::Spew(std::format("Time taken: {}", duration)); + PluginContext::Spew("Time taken: {}", duration); return true; } @@ -597,7 +609,7 @@ class NewGamePlusSystem : public IGameSystem #pragma endregion #pragma region Session - ENGPlusType m_selectedNgPlusType{}; + ENGPlusType m_selectedNgPlusType = ENGPlusType::Invalid; #pragma endregion RTTI_IMPL_TYPEINFO(NewGamePlusSystem); @@ -613,18 +625,27 @@ RTTI_DEFINE_CLASS(mod::NewGamePlusSystem, { RTTI_METHOD(ParsePointOfNoReturnSaveData); RTTI_METHOD(HasPointOfNoReturnSave); RTTI_METHOD(ResolveNewGamePlusSaves); + RTTI_METHOD(GetNewGamePlusState); RTTI_METHOD(SetNewGamePlusState); + RTTI_METHOD(GetProgressionData); RTTI_METHOD(SetNewGamePlusGameDefinition); RTTI_METHOD(IsSaveValidForNewGamePlus); + RTTI_METHOD(LoadExpansionIntoSave); + RTTI_METHOD(Spew); RTTI_METHOD(Error); + RTTI_METHOD(GetStandaloneState); RTTI_METHOD(SetStandaloneState); + RTTI_METHOD(IsInNewGamePlusSave); RTTI_METHOD(IsInNewGamePlusPrologue); RTTI_METHOD(IsInNewGamePlusHeistOrStandalone); + RTTI_METHOD(LaunchNewGamePlus); + RTTI_METHOD(SetNewGamePlusQuest); + RTTI_METHOD(GetNewGamePlusQuest); }); \ No newline at end of file diff --git a/src/util/migration/migration.cpp b/src/util/migration/migration.cpp index 06d468b..b85c174 100644 --- a/src/util/migration/migration.cpp +++ b/src/util/migration/migration.cpp @@ -14,17 +14,20 @@ namespace migration static std::filesystem::path m_modulePath{}; } +namespace +{ +static constexpr std::array c_unusedFiles = {L"redscript\\DifficultyAdjustment\\NGPlusDifficultyFixes.reds", + L"redscript\\Scenario\\NGPlusStatsAdjustmentController.reds", + L"redscript\\NGPlusEP1Listener.reds", + L"redscript\\SpawnTagController.reds", + L"redscript\\NGPlusSpawnTagController.reds", + L"redscript\\DifficultyAdjustment\\NGPlusDifficultyDefaultConfig.reds", + L"tweaks\\NGPlus_BasegameFlatPatches.yaml"}; +}; + void migration::RemoveUnusedFiles() { // To be updated with more later on... - constexpr std::array c_unusedFiles = { - L"redscript\\DifficultyAdjustment\\NGPlusDifficultyFixes.reds", - L"redscript\\Scenario\\NGPlusStatsAdjustmentController.reds", - L"redscript\\NGPlusEP1Listener.reds", - L"redscript\\SpawnTagController.reds", - L"redscript\\DifficultyAdjustment\\NGPlusDifficultyDefaultConfig.reds", - L"tweaks\\NGPlus_BasegameFlatPatches.yaml", - }; auto cleanedUpAny = false; auto cleanupFailed = false; diff --git a/wolvenkit/custom_refs.txt b/wolvenkit/custom_refs.txt index 0377182..d38ff8a 100644 --- a/wolvenkit/custom_refs.txt +++ b/wolvenkit/custom_refs.txt @@ -1,13 +1,3 @@ -base\animations\anim_motion_database\cover_action.csv -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_01.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_02.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_03.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_04.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_05.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_06.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_back_01.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_left_01.effect -base\fx\characters\npc\kerenzikov\ch_kerenzikov_dodge_right_01.effect base\gameplay\gui\fullscreen\main_menu\new_game_plus_selection_1080p.xbm base\gameplay\gui\fullscreen\main_menu\new_game_plus_selection.inkatlas base\gameplay\gui\fullscreen\main_menu\new_game_plus_selection.xbm @@ -21,13 +11,10 @@ base\localization\en-us\new_game_plus\subtitles\q001\q001_restored_subtitles.jso base\localization\en-us\new_game_plus\subtitles\q101\q101_restored_subtitles.json base\localization\en-us\new_game_plus\subtitles\q116\q116_restored_subtitles.json base\localization\en-us\new_game_plus\subtitles\subtitles.json -ep1\quest\main_quests\q302\scenes\lipsync\en\q302_08_call\reed.anims -ep1\quest\main_quests\q302\scenes\lipsync\en\q302_08_call\v.anims -mod\new_ep1_requirements\journal\new_ep1_requirements.journal -mod\new_ep1_requirements\onscreens\new_ep1_requirements_onscreens.json +base\quest\side_quests\sq032\scenes\lipsync\en\sq032_00_sickness\johnny.anims +base\quest\side_quests\sq032\scenes\lipsync\en\sq032_00_sickness\v.anims mod\quest\changedQuests\NewGamePlus_act_1.questphase mod\quest\changedQuests\NewGamePlus_additional_game_elements.questphase -mod\quest\changedquests\newgameplus_cyberpunk2077.questphase mod\quest\changedQuests\NewGamePlus_cyberpunk2077.questphase mod\quest\changedQuests\NewGamePlus_persistent_content.questphase mod\quest\changedQuests\open_world\NewGamePlus_open_world_content.questphase @@ -46,10 +33,8 @@ mod\quest\newgameplus\bossEncounterTest\bossEncounterStressTest.quest mod\quest\newgameplus\bossEncounterTest\bossEncounterTest.gamedef mod\quest\newgameplus\bossEncounterTest\bossEncounterTest.quest mod\quest\newgameplus\bugfixing\ngplusBugfixing.questphase -mod\quest\newgameplus\fasttracktoq001.questphase mod\quest\newgameplus\FastTrackToQ001.questphase mod\quest\newgameplus\FastTrackToQ101New.questphase -mod\quest\newgameplus\fixhauntedweaponspreep1.questphase mod\quest\newgameplus\FixHauntedWeaponsPreEP1.questphase mod\quest\newgameplus\InitStreetStoriesAndFastTravel.questphase mod\quest\newgameplus\journal\NGPlusJournal.journal @@ -65,17 +50,13 @@ mod\quest\newgameplus\newNpc\brightman.ent mod\quest\newgameplus\newNpc\burondo.ent mod\quest\newgameplus\newNpc\cross.ent mod\quest\newgameplus\newNpc\evilJackie.ent -mod\quest\newgameplus\ngplusadditionalcontent.questphase mod\quest\newgameplus\NGPlusAdditionalContent.questphase mod\quest\newgameplus\NGPlusBossEncounterLoop.questphase mod\quest\newgameplus\NGPlusBossEncounterRetrofix.questphase mod\quest\newgameplus\progressionBuildApply\SetupProgressionBuildsForStandalone.questphase -mod\quest\newgameplus\restorehud.questphase mod\quest\newgameplus\RestoreHUD.questphase mod\quest\newgameplus\SetBandageOutfit.questphase -mod\quest\newgameplus\setplayerprogression.questphase mod\quest\newgameplus\SetPlayerProgression.questphase -mod\quest\newgameplus\vrtutorialhack\q000vrtutorial.questphase mod\quest\newgameplus\vrTutorialHack\Q000VRTutorial.questphase -mod\quest\newgameplus\vrtutorialhack\vrtutorialforq001start.questphase mod\quest\newgameplus\vrTutorialHack\VRTutorialForQ001Start.questphase +mod\quest\ping_sq032_sickness.questphase diff --git a/wolvenkit/layout.xml b/wolvenkit/layout.xml index 9086954..d9a50f8 100644 --- a/wolvenkit/layout.xml +++ b/wolvenkit/layout.xml @@ -1 +1 @@ --1095,500,320,940Normal0-10000LogViewModelfalsefalseHiddenfalseBottomLeftAssetBrowserViewModel1883.33333333333331949090falsetruetruetruefalsetrue-1095,500,320,940false01718000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft0BottomfalseBottomNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse-184.66666666666663,11.999999999999995,636,1326.6666666666667Normal0-10000ProjectExplorerViewModelfalsefalseAutoHiddenfalseTopLeftPropertiesViewModel643.3333333333334899.33333333333349090falsetruetruetruefalsetrue-184.66666666666663,11.999999999999995,636,1326.666666666666726527892true1024018000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft0TopfalseTopNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse-184.66666666666663,11.999999999999995,636,1326.6666666666667Normal0-10000PropertiesViewModelfalsefalseAutoHiddenfalseLeftLeft643.33333333333344489090falsetruetruetruefalsetrue-184.66666666666663,11.999999999999995,636,1326.666666666666737967233true1024318000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft3LeftfalseLeftNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse838.6666666666657,170,756,1270Normal0-11883.333333333333301883.3333333333333366.6666666666667AssetBrowserViewModelfalsefalseDockfalseBottomLeft2523.33333333333355109090falsetruetruetruefalsetrue838.6666666666657,170,756,127019954658false01718000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight0TopfalseTopNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse002523.33333333333351352.6666666666667909090900falsefalsefalsefalse930,355,235,914Normal0-106021305.3333333333337602TweakBrowserViewModelfalsefalseDockfalseRightLeft1305.3333333333333837.33333333333349090falsetruetruetruetruetrue930,355,235,91455422288false01818000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight5LeftfalseRightNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse002523.3333333333335837.3333333333334909090900falsefalsefalsefalse-193,729,271,711Normal0-10000LocKeyBrowserViewModelfalsefalseHiddenfalseRightLeft489.3333333333333483.33333333333339090falsetruetruetruefalsetrue-193,729,271,71160020356false01818000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight0LeftfalseRightNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse \ No newline at end of file +-1095,500,320,940Normal0-10000LogViewModelfalsefalseHiddenfalseBottomLeftAssetBrowserViewModel1883.33333333333331949090falsetruetruetruefalsetrue-1095,500,320,940false01718000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft0BottomfalseBottomNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse-184.66666666666663,11.999999999999995,636,1326.6666666666667Normal0-10000ProjectExplorerViewModelfalsefalseAutoHiddenfalseTopLeftPropertiesViewModel643.3333333333334899.33333333333349090falsetruetruetruefalsetrue-184.66666666666663,11.999999999999995,636,1326.666666666666726527892true1024518000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft0TopfalseTopNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse-184.66666666666663,11.999999999999995,636,1326.6666666666667Normal0-10000PropertiesViewModelfalsefalseAutoHiddenfalseLeftLeft643.33333333333344489090falsetruetruetruefalsetrue-184.66666666666663,11.999999999999995,636,1326.666666666666712914517true1024318000,0,124,50-1false0,0,124,24NormaltrueHorizontalLeft3LeftfalseLeftNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse838.6666666666657,170,756,1270Normal0-11883.333333333333301883.3333333333333366.6666666666667AssetBrowserViewModelfalsefalseDockfalseBottomLeft1883.3333333333333366.66666666666679090falsetruetruetruefalsetrue838.6666666666657,170,756,127019954658false01718000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight0TopfalseTopNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse001883.3333333333333974909090900falsefalsefalsefalse930,355,235,914Normal0-10000TweakBrowserViewModelfalsefalseHiddenfalseRightLeft1305.3333333333333837.33333333333349090falsetruetruetruefalsetrue930,355,235,91455422288false01818000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight5LeftfalseRightNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse-193,729,271,711Normal0-10000LocKeyBrowserViewModelfalsefalseHiddenfalseRightLeft489.3333333333333483.33333333333339090falsetruetruetruefalsetrue-193,729,271,71160020356false01818000,0,124,50-1false0,0,124,24NormaltrueHorizontalRight0LeftfalseRightNormaltruetruetruetruetruetruetruetruefalsefalsefalsefalsefalse0000909090900falsefalsefalsefalse \ No newline at end of file diff --git a/wolvenkit/packed/archive/pc/mod/NewGamePlus.archive b/wolvenkit/packed/archive/pc/mod/NewGamePlus.archive index 0e49edb6e4c465254601014849c7fc9b94d2d45e..da4c294f52d54594157d623e1d96ccf2622480ce 100644 GIT binary patch delta 1814 zcmXBUYfw~m7zXfn&t6y-1X6AbELW9FD9ehlzCW$PW$yKA# z#AX;AIZEl6b}=F|NH?*uNgYQSQil%(3?IxcqvWMTD@n(m_xI=oBUq;{>M|hEOdy7Vzl-reOCf;;NYhIpY(lR(~st~jk(TTz2mCe zp?6lBE|`ujUV3PU&u2o+hy@8ktVl3oLqd>HWCjw3gd-8iQ^-tY77~d>A<;+-5{uZ8 zI3ylPKpaRSl7u89DM%`khRjChAajv)Bm>DrvXG~dY-AoXAIU+SNG{?+79e@ZLL?t4 z2>5*NJ%y#iCZgRIGP-seou!qo)#tDfq!sZy4V#8dB{!OXQ7e_IWmx<7pXHTGul%gE z%V>stw;$Q{WiHEbblOIz(^=EBc|%QWQ)69gV@u6zt#vJWXhES}&)MrfXFgK=$JT1y zmS=fJKk753=#AZOZ>}*sIMi&kgj%do4g=wPXg1A}tc93!h>A6%Q40zRGN+}?u?B}2 zB7@=$cKuGbdx6F4+-ADCc}KeLMhcOlK)PN$_KkkE!ei=Q;jvn4y9#?V)|6H05i2~A zmZ_TPs+}G^YlX*Unb;t%XV<ttOyHTb?2mKA)9l(dv1=uq^tN~%d&z+KFx!4cJkGv+ zT|9FY+aTh!HU-1xo{E1le!IQI6 z`8-AJ+nZB&m&J>Bu?GvpXW5yh;%WA#h9ow-|e3<=PgLs@xpU&p<&wLR+84#DTqesNs*&j`a2icb&i|@&H^Bf!-$Xesk zO#Vei{%aFu>Tdp*Q!PIFLJaio71aY8(Rs`)8c|(y5IMFHmE2YRS36PpTB5nZg>w92 z3sGS>(YkQeCt`^@_7E+}P(8y+G!;ekic`9uF5m*UaDlu9YT$eH-_ai|RQ)viMfBrt z)q`>Jwk)DkOI5$%G*Iev82R5+&#Ag%qAxER=-Pnl#p`hc_k$=t89VU0GK1*PY@*3| z-2Ft$!icuu3FGppfqfWQje()%s(%xs5a2p`>N+h;CL)vcpo~hPY!H2j}6)1s)4mQK`ZWX?ggd&dp}2uD-b5g_v^hE{0g3N2eYaz$ur(FQHn=llKN_J-H@?)U%Q|9&Gh0-|Mk%Em?oN(%f%u zxUZG%4+hQ1f;41BHe^R($brJqG!%g%Q52evqEQTrMR8~bnu+330!l3co9G2}eL`A^)W7=IiFK2ii^EKtOPv8+Cm0=ST2khv+UyP`)|#X^ z_0d+ZTgyJSRJ}+0Q*OMA{<6TUI#Q$4EG7pt}SKM#B4(KAbZ zE-m*~h+WIh{#AUO-5mIWpC4jRy(kV_3$JPuFK6%W5;wBl1LD){D}~*B?I^qCD{-

*Z*(?7Lx3Jr$#8=r5qkH&TwG1vy7w5Ar+2ZZ&3qEl>`*4Z)E<1mdIPqyXxwMz} z@w0!}DL%md=Ns`w_HU!&Np{4FbG+WQ4&JdwyqSHtO?-kqd{TUiePdW0T@HVDM_kPQ zc~ZQG9pmWZJ-gY~81Z9v?>up40DkKYaV>kxC*tGm)g$5|_Wj87yiZsKeAX#m&JMW6 zjqD$N;?wM9+9h5;%08MTPOgMUmWzYz__g8|c5#jPD*I-=SPjBQc8K%Yjw$hW_9pEz z@88aj%opEf*DMn!R>4#y_OshJiVv`x_lPgDe?KIiWS1TlyPkpjkBc|6Cq59LV8?Zc zZ?SKTf64a{y&ita-p?*(hh~fSu)j?ece7U%iXXH8Enb^ZH+YMpW=y{ zj}R4S7;}b==&v}U?Kv_xQ9s^b3~%6d8w)OAzK3~Yi81$J9>9FoYs_|R-k3>rZly8z z=O~ms89{qr%a323H&NM>B{Ls)@F3Fy?XG&>5Uq-Lu9#2kU2I{oWUhIT3Rm=J$3Q^U~Qw zrz#b?{jM>4qHsM9FQx-C-k+R!;xeAd=`|KKV1t+O3EQq1a~=N8);fs(8#Lx}JJBmx zUp8#avw}pqJqm4e`S=6U1Wqdse};OGF$ZznyDEq-mKgImUVk62-^3%7QRf?W{0~v_ BCQ|?a diff --git a/wolvenkit/source/archive/mod/quest/NewGamePlus.gamedef b/wolvenkit/source/archive/mod/quest/NewGamePlus.gamedef index af70ddf21182cae1390c022bc3cd2f5269e7ee6c..63b6bae86ea23314b498b35e35a139cbc3e52b17 100644 GIT binary patch delta 64 zcmX@ed6090g2K$dpS#!?7#J1+u{aY0L(Bg)=eGlCDIkAW*{16o9TqaODi<0W7;b*X RIG2%Sos0W|&F#!qi~z4~6$}6X delta 64 zcmX@ed6090fPx# diff --git a/wolvenkit/source/archive/mod/quest/NewGamePlus_Q001.gamedef b/wolvenkit/source/archive/mod/quest/NewGamePlus_Q001.gamedef index d14e0b00635a184d3433871fcf7c773a90fb2406..687b92223762fe1ee2682fd958102ba78639277c 100644 GIT binary patch delta 235 zcmcb>d4_X>gwGik1_lszdXfE@je&t-0T3%OF)(OwY?^rpNJ|0v>Om`=CowZHumagp zZ~sW{0`?FBZ%zT(K2u*Wo~>)MrvY7YEgV~Nn+9F z-;C24RTo>oZiocw1Zt^*(tS{RHI%+Nc{{VRrxwUeC}4-uyg+&q4)OU|#1(+**GyJs GSqlJpOe{?R delta 203 zcmX@Zd4Y3+gwF*Q1_ls5b7JONHU*`eOM-<$)of!Y}kaQK!_EHs$dz`Jpw8>2{ZL3v($Sy6mRX-R%jW@1i! zNow)t?~KzKRWo*|amRvm1GUvb=}Ay}J(RvXc{8&zqu%8A%;JpGK&0eikR4FK4y6@< K^oGguENcPB9xrPE