11using System . Collections . Generic ;
22using System . Collections . ObjectModel ;
33using System . Linq ;
4+ using System . Text . RegularExpressions ;
5+ using CommunityToolkit . Mvvm . ComponentModel ;
6+ using CommunityToolkit . Mvvm . DependencyInjection ;
7+ using CommunityToolkit . Mvvm . Input ;
48using CommunityToolkit . Mvvm . Messaging ;
59using Newtonsoft . Json . Linq ;
610using SOTFEdit . Infrastructure ;
913
1014namespace SOTFEdit . ViewModel ;
1115
12- public class GameStatePageViewModel
16+ public partial class GameStatePageViewModel : ObservableObject
1317{
18+ private readonly Regex _resetCrateNameIdPattern =
19+ new ( @"(\..*Crate.*\.)|(\..*Storage.*\.)|(\..*Case.*\.)|(.*\.Meds\..*)" ) ;
20+
1421 public GameStatePageViewModel ( )
1522 {
1623 SetupListeners ( ) ;
1724 }
1825
1926 public ObservableCollection < GenericSetting > Settings { get ; } = new ( ) ;
2027
28+ [ NotifyCanExecuteChangedFor ( nameof ( ResetContainersCommand ) ) ] [ ObservableProperty ]
29+ private Savegame ? _selectedSavegame ;
30+
2131 private void SetupListeners ( )
2232 {
2333 WeakReferenceMessenger . Default . Register < SelectedSavegameChangedEvent > ( this ,
@@ -26,6 +36,7 @@ private void SetupListeners()
2636
2737 private void OnSelectedSavegameChanged ( SelectedSavegameChangedEvent message )
2838 {
39+ SelectedSavegame = message . SelectedSavegame ;
2940 Settings . Clear ( ) ;
3041 var gameStateData =
3142 message . SelectedSavegame ? . SavegameStore . LoadJsonRaw ( SavegameStore . FileType . GameStateSaveData ) ;
@@ -39,6 +50,60 @@ private void OnSelectedSavegameChanged(SelectedSavegameChangedEvent message)
3950 LoadSettings ( gameState ) ;
4051 }
4152
53+ private bool HasSavegame ( )
54+ {
55+ return _selectedSavegame != null ;
56+ }
57+
58+ [ RelayCommand ( CanExecute = nameof ( HasSavegame ) ) ]
59+ public void ResetContainers ( )
60+ {
61+ if ( SelectedSavegame is not { } savegame )
62+ {
63+ return ;
64+ }
65+
66+ var gameStateData = savegame . SavegameStore . LoadJsonRaw ( SavegameStore . FileType . GameStateSaveData ) ;
67+
68+ if ( gameStateData ? . SelectToken ( "Data.GameState" ) is not { } gameStateToken ||
69+ gameStateToken . ToObject < string > ( ) is not { } gameStateJson ||
70+ JsonConverter . DeserializeRaw ( gameStateJson ) is not { } gameState ||
71+ gameState [ "NamedIntDatas" ] is not { } namedIntDatas )
72+ {
73+ WeakReferenceMessenger . Default . Send ( new SavegameStoredEvent ( "Nothing to be reset" , false ) ) ;
74+ return ;
75+ }
76+
77+ var countFixed = 0 ;
78+
79+ foreach ( var data in namedIntDatas )
80+ {
81+ if ( data [ "SaveObjectNameId" ] ? . ToObject < string > ( ) is not { } nameId ||
82+ ! _resetCrateNameIdPattern . Match ( nameId ) . Success || data [ "SaveValue" ] is not { } saveValueToken )
83+ {
84+ continue ;
85+ }
86+
87+ var oldSaveValue = saveValueToken . ToObject < int > ( ) ;
88+
89+ if ( oldSaveValue != 1 )
90+ {
91+ continue ;
92+ }
93+
94+ saveValueToken . Replace ( 0 ) ;
95+ countFixed ++ ;
96+ }
97+
98+ gameStateToken . Replace ( JsonConverter . Serialize ( gameState ) ) ;
99+
100+ var createBackups = Ioc . Default . GetRequiredService < MainViewModel > ( ) . BackupFiles ;
101+ savegame . SavegameStore . StoreJson ( SavegameStore . FileType . GameStateSaveData , gameStateData , createBackups ) ;
102+
103+ WeakReferenceMessenger . Default . Send (
104+ new SavegameStoredEvent ( $ "Reset { countFixed } containers, creates and pickups", true ) ) ;
105+ }
106+
42107 private void LoadSettings ( JToken gameState )
43108 {
44109 var children = gameState . Children ( ) ;
0 commit comments