1+ using System . Globalization ;
2+ using System . Text ;
13using LeFauxMods . CarryChest . Services ;
24using LeFauxMods . CarryChest . Utilities ;
35using LeFauxMods . Common . Models ;
46using LeFauxMods . Common . Utilities ;
7+ using Microsoft . Xna . Framework ;
58using StardewModdingAPI . Events ;
69using StardewValley . Buffs ;
10+ using StardewValley . Menus ;
711using StardewValley . Objects ;
812
913namespace LeFauxMods . CarryChest ;
@@ -22,13 +26,93 @@ public override void Entry(IModHelper helper)
2226 ModPatches . Apply ( ) ;
2327
2428 // TBD: Command to access global inventory chests
29+ helper . ConsoleCommands . Add ( "carry_chests" , I18n . Command_CarryChests_Description ( ) , OnCommand ) ;
2530
2631 // Events
2732 helper . Events . GameLoop . GameLaunched += this . OnGameLaunched ;
2833 helper . Events . GameLoop . SaveLoaded += this . OnSaveLoaded ;
2934 helper . Events . GameLoop . ReturnedToTitle += this . OnReturnedToTitle ;
3035 }
3136
37+ private static void OnCommand ( string arg1 , string [ ] arg2 )
38+ {
39+ switch ( arg2 . ElementAtOrDefault ( 0 ) ? . ToLower ( CultureInfo . InvariantCulture ) )
40+ {
41+ case "backup" when ! Context . IsWorldReady :
42+ Log . Info ( I18n . Alert_CommandBackup_InvalidContext ( ) ) ;
43+ return ;
44+
45+ case "backup" :
46+ Game1 . activeClickableMenu = new ItemGrabMenu ( ModState . Backups ) ;
47+ return ;
48+
49+ case "help" :
50+ switch ( arg2 . ElementAtOrDefault ( 1 ) ? . ToLower ( CultureInfo . InvariantCulture ) )
51+ {
52+ case "backup" :
53+ Log . Info ( I18n . Command_Backups_Description ( ) ) ;
54+ return ;
55+
56+ case "help" :
57+ Log . Info ( I18n . Command_Help_Description ( ) ) ;
58+ return ;
59+
60+ case null :
61+ Log . Info (
62+ new StringBuilder ( )
63+ . AppendLine ( "Commands:" )
64+ . AppendLine ( )
65+ . AppendLine ( "carry_chests backup" )
66+ . AppendLine ( CultureInfo . InvariantCulture , $ "\t { I18n . Command_Backups_Description ( ) } ")
67+ . AppendLine ( )
68+ . AppendLine ( "carry_chests help" )
69+ . AppendLine ( CultureInfo . InvariantCulture , $ "\t { I18n . Command_Help_Description ( ) } ")
70+ . ToString ( ) ) ;
71+ return ;
72+
73+ default :
74+ Log . Info ( I18n . Command_Unknown_Description ( ) ) ;
75+ return ;
76+ }
77+
78+ case null :
79+ Log . Info ( I18n . Command_CarryChests_Description ( ) ) ;
80+ return ;
81+
82+ default :
83+ Log . Info ( I18n . Command_Unknown_Description ( ) ) ;
84+ return ;
85+ }
86+ }
87+
88+ private static void OnOneSecondUpdateTicked ( object ? sender , OneSecondUpdateTickedEventArgs e )
89+ {
90+ // Add status effect to the player
91+ if ( Game1 . player . Items . OfType < Chest > ( ) . Count ( ) >= ModState . Config . SlownessLimit )
92+ {
93+ Game1 . player . applyBuff (
94+ new Buff (
95+ Constants . SlowEffectKey ,
96+ duration : 60_000 ,
97+ iconTexture : Game1 . buffsIcons ,
98+ iconSheetIndex : 13 ,
99+ effects : new BuffEffects { Speed = { ModState . Config . SlownessAmount } } ,
100+ displayName : I18n . Effect_Overburdened ( ) ) ) ;
101+
102+ Log . Trace ( "Adding the slowness effect" ) ;
103+ return ;
104+ }
105+
106+ if ( ! Game1 . player . hasBuff ( Constants . SlowEffectKey ) )
107+ {
108+ return ;
109+ }
110+
111+ // Remove status effect from the player
112+ Game1 . player . buffs . Remove ( Constants . SlowEffectKey ) ;
113+ Log . Trace ( "Removing the slowness effect" ) ;
114+ }
115+
32116 private void OnGameLaunched ( object ? sender , GameLaunchedEventArgs e ) =>
33117 _ = new ConfigMenu ( this . Helper , this . ModManifest ) ;
34118
@@ -55,13 +139,13 @@ private void OnButtonPressed(object? sender, ButtonPressedEventArgs e)
55139 return ;
56140 }
57141
58- if ( InventoryHelper . SwapChest ( chest ) )
142+ if ( ModState . Config . SwapChests && chest . TrySwap ( ) )
59143 {
60144 this . Helper . Input . Suppress ( e . Button ) ;
61145 return ;
62146 }
63147
64- if ( InventoryHelper . PickUpChest ( chest , ModState . Config . TotalLimit ) )
148+ if ( chest . TryCarry ( ) )
65149 {
66150 this . Helper . Input . Suppress ( e . Button ) ;
67151 _ = chest . Location . Objects . Remove ( chest . TileLocation ) ;
@@ -93,34 +177,6 @@ private void OnConfigChanged(ConfigChangedEventArgs<ModConfig> e)
93177 }
94178 }
95179
96- private static void OnOneSecondUpdateTicked ( object ? sender , OneSecondUpdateTickedEventArgs e )
97- {
98- // Add status effect to the player
99- if ( Game1 . player . Items . OfType < Chest > ( ) . Count ( ) >= ModState . Config . SlownessLimit )
100- {
101- Game1 . player . applyBuff (
102- new Buff (
103- Constants . SlowEffectKey ,
104- duration : 60_000 ,
105- iconTexture : Game1 . buffsIcons ,
106- iconSheetIndex : 13 ,
107- effects : new BuffEffects { Speed = { ModState . Config . SlownessAmount } } ,
108- displayName : I18n . Effect_Overburdened ( ) ) ) ;
109-
110- Log . Trace ( "Adding the slowness effect" ) ;
111- return ;
112- }
113-
114- if ( ! Game1 . player . hasBuff ( Constants . SlowEffectKey ) )
115- {
116- return ;
117- }
118-
119- // Remove status effect from the player
120- Game1 . player . buffs . Remove ( Constants . SlowEffectKey ) ;
121- Log . Trace ( "Removing the slowness effect" ) ;
122- }
123-
124180 private void OnReturnedToTitle ( object ? sender , ReturnedToTitleEventArgs e )
125181 {
126182 this . Helper . Events . Input . ButtonPressed -= this . OnButtonPressed ;
@@ -134,5 +190,66 @@ private void OnSaveLoaded(object? sender, SaveLoadedEventArgs e)
134190 {
135191 this . Helper . Events . GameLoop . OneSecondUpdateTicked += OnOneSecondUpdateTicked ;
136192 }
193+
194+ // Create missing backups
195+ for ( var i = 0 ; i < Game1 . player . Items . Count ; i ++ )
196+ {
197+ var item = Game1 . player . Items [ i ] ;
198+ if ( item is not Chest chest )
199+ {
200+ if ( item is null ||
201+ ! item . modData . TryGetValue ( Constants . BetterChestsGlobalInventoryKey , out var id ) ||
202+ ! Game1 . player . team . globalInventories . ContainsKey ( id ) )
203+ {
204+ continue ;
205+ }
206+
207+ // Attempt to restore a Better Chest proxy
208+ var color = Color . Black ;
209+ if ( item . modData . TryGetValue ( Constants . BetterChestsColorKey , out var colorString ) &&
210+ int . TryParse ( colorString , out var colorValue ) )
211+ {
212+ var r = ( byte ) ( colorValue & 0xFF ) ;
213+ var g = ( byte ) ( ( colorValue >> 8 ) & 0xFF ) ;
214+ var b = ( byte ) ( ( colorValue >> 16 ) & 0xFF ) ;
215+ color = new Color ( r , g , b ) ;
216+ }
217+
218+ chest = new Chest ( true , item . ItemId )
219+ {
220+ GlobalInventoryId = id ,
221+ fridge = { Value = item . modData . ContainsKey ( Constants . BetterChestsFridgeKey ) } ,
222+ playerChoiceColor = { Value = color }
223+ } ;
224+
225+ chest . CopyFieldsFrom ( item ) ;
226+ _ = chest . modData . Remove ( Constants . BetterChestsFridgeKey ) ;
227+ _ = chest . modData . Remove ( Constants . BetterChestsColorKey ) ;
228+ _ = chest . modData . Remove ( Constants . BetterChestsGlobalInventoryKey ) ;
229+ Game1 . player . Items [ i ] = chest ;
230+ }
231+
232+ _ = ModState . Backups . TryAddBackup ( chest , Constants . Prefix ) ;
233+ }
234+
235+ // Create generic backups for any missing
236+ foreach ( var ( id , _) in Game1 . player . team . globalInventories . Pairs )
237+ {
238+ // Only create backups for known ids
239+ if ( ! id . StartsWith ( Constants . Prefix , StringComparison . OrdinalIgnoreCase ) &&
240+ ! id . StartsWith ( "furyx639.BetterChests-ProxyChestFactory-" , StringComparison . OrdinalIgnoreCase ) )
241+ {
242+ continue ;
243+ }
244+
245+ // Do not create if backup already exists
246+ if ( ModState . Backups . OfType < Chest > ( )
247+ . Any ( chest => chest . GlobalInventoryId . Equals ( id , StringComparison . OrdinalIgnoreCase ) ) )
248+ {
249+ continue ;
250+ }
251+
252+ ModState . Backups . Add ( new Chest ( true ) { GlobalInventoryId = id } ) ;
253+ }
137254 }
138255}
0 commit comments