Skip to content

Commit 237281b

Browse files
authored
Update Carry Chests to version 1.3.0 with new features (#14)
- Added `Enabled` property to toggle the mod on/off. - Introduced `MaximumReach` property for chest grabbing distance. - Updated `CopyTo` method to include new properties. - Implemented event handlers for button presses and menu changes. - Modified chest grabbing logic to use `MaximumReach`. - Enhanced configuration menu with new options. - Updated translations in various language files. - Revised `README.md` to reflect translation status. - Updated subproject commit for `FauxCore`.
1 parent a5794fe commit 237281b

File tree

21 files changed

+288
-80
lines changed

21 files changed

+288
-80
lines changed

CarryChests/CarryChests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<PropertyGroup>
77
<Name>Carry Chests</Name>
88
<Description>Allows you to pick up placed chests with items.</Description>
9-
<Version>1.2.1</Version>
9+
<Version>1.3.0</Version>
1010
<EnableHarmony>true</EnableHarmony>
1111
<RootNamespace>LeFauxMods.CarryChest</RootNamespace>
1212
<UniqueId>furyx639.CarryChest</UniqueId>

CarryChests/ModConfig.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
using System.Text;
33
using LeFauxMods.Common.Interface;
44
using LeFauxMods.Common.Models;
5+
using StardewModdingAPI.Utilities;
56

67
namespace LeFauxMods.CarryChest;
78

89
/// <inheritdoc cref="IModConfig{TConfig}" />
910
internal sealed class ModConfig : IModConfig<ModConfig>, IConfigWithLogAmount
1011
{
12+
/// <summary>Gets or sets a value indicating whether carrying is enabled.</summary>
13+
public bool Enabled { get; set; } = true;
14+
1115
/// <summary>Gets or sets a value indicating whether held chests can be opened.</summary>
1216
public bool OpenHeldChest { get; set; } = true;
1317

@@ -17,6 +21,9 @@ internal sealed class ModConfig : IModConfig<ModConfig>, IConfigWithLogAmount
1721
/// <summary>Gets or sets a value indicating whether empty chests will be picked up as items.</summary>
1822
public bool GrabEmptyAsItem { get; set; }
1923

24+
/// <summary>Gets or sets the maximum reach for grabbing a chest.</summary>
25+
public int MaximumReach { get; set; } = 1;
26+
2027
/// <summary>Gets or sets the amount the player will be slowed when carrying chests above the limit.</summary>
2128
public float SlownessAmount { get; set; } = -1f;
2229

@@ -26,6 +33,9 @@ internal sealed class ModConfig : IModConfig<ModConfig>, IConfigWithLogAmount
2633
/// <summary>Gets or sets a value indicating whether to allow swapping.</summary>
2734
public bool SwapChests { get; set; } = true;
2835

36+
/// <summary>Gets or sets the keybind for toggling enabled.</summary>
37+
public KeybindList ToggleEnabled { get; set; } = new();
38+
2939
/// <summary>Gets or sets the number of chests the player can carry.</summary>
3040
public int TotalLimit { get; set; } = 3;
3141

@@ -37,23 +47,27 @@ public void CopyTo(ModConfig other)
3747
{
3848
other.LogAmount = this.LogAmount;
3949
other.GrabEmptyAsItem = this.GrabEmptyAsItem;
50+
other.MaximumReach = this.MaximumReach;
4051
other.OpenHeldChest = this.OpenHeldChest;
4152
other.OverrideTool = this.OverrideTool;
4253
other.SlownessAmount = this.SlownessAmount;
4354
other.SlownessLimit = this.SlownessLimit;
4455
other.SwapChests = this.SwapChests;
56+
other.ToggleEnabled = this.ToggleEnabled;
4557
other.TotalLimit = this.TotalLimit;
4658
}
4759

4860
/// <inheritdoc />
4961
public string GetSummary() =>
5062
new StringBuilder()
5163
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.GrabEmptyAsItem),25}: {this.GrabEmptyAsItem}")
64+
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.MaximumReach),25}: {this.MaximumReach}")
5265
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.OpenHeldChest),25}: {this.OpenHeldChest}")
5366
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.OverrideTool),25}: {this.OverrideTool}")
5467
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.SlownessAmount),25}: {this.SlownessAmount}")
5568
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.SlownessLimit),25}: {this.SlownessLimit}")
5669
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.SwapChests),25}: {this.SwapChests}")
70+
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.ToggleEnabled),25}: {this.ToggleEnabled}")
5771
.AppendLine(CultureInfo.InvariantCulture, $"{nameof(this.TotalLimit),25}: {this.TotalLimit}")
5872
.ToString();
5973
}

CarryChests/ModEntry.cs

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,37 @@ private static void OnOneSecondUpdateTicked(object? sender, OneSecondUpdateTicke
7070
Log.Trace("Removing the slowness effect");
7171
}
7272

73+
private static void OnButtonsChanged(object? sender, ButtonsChangedEventArgs e)
74+
{
75+
if (!ModState.Config.ToggleEnabled.JustPressed())
76+
{
77+
return;
78+
}
79+
80+
ModState.ConfigHelper.Temp.Enabled = !ModState.Config.Enabled;
81+
ModState.ConfigHelper.Save();
82+
83+
if (ModState.Config.Enabled)
84+
{
85+
Log.Alert(I18n.Alert_ModEnabled(ModState.Config.ToggleEnabled.ToString()));
86+
return;
87+
}
88+
89+
Log.Alert(I18n.Alert_ModDisabled(ModState.Config.ToggleEnabled.ToString()));
90+
}
91+
92+
private static void OnMenuChanged(object? sender, MenuChangedEventArgs e)
93+
{
94+
if (e.OldMenu is not ItemGrabMenu { sourceItem: Chest { playerChest.Value: true } chest })
95+
{
96+
return;
97+
}
98+
99+
ModState.Backups.SyncBackup(chest);
100+
ModState.Backups.RemoveEmptySlots();
101+
ModState.FrameCounter = 0;
102+
}
103+
73104
private void OnCommandReceived(CommandReceivedEventArgs e)
74105
{
75106
switch (e.Command)
@@ -102,8 +133,8 @@ private void OnButtonPressed(object? sender, ButtonPressedEventArgs e)
102133
}
103134

104135
var tile = e.Button.TryGetController(out _) ? e.Cursor.GrabTile : e.Cursor.Tile;
105-
if (Math.Abs(Game1.player.Tile.X - tile.X) > 1 ||
106-
Math.Abs(Game1.player.Tile.Y - tile.Y) > 1 ||
136+
if (Math.Abs(Game1.player.Tile.X - tile.X) > ModState.Config.MaximumReach ||
137+
Math.Abs(Game1.player.Tile.Y - tile.Y) > ModState.Config.MaximumReach ||
107138
!Game1.currentLocation.Objects.TryGetValue(tile, out var obj)
108139
|| obj is not Chest chest)
109140
{
@@ -127,15 +158,18 @@ private void OnButtonPressed(object? sender, ButtonPressedEventArgs e)
127158
return;
128159
}
129160

130-
if (!e.Button.IsActionButton() || !ModState.Config.OpenHeldChest)
161+
if (!e.Button.IsActionButton() || !ModState.Config.OpenHeldChest || ModState.FrameCounter != 0)
131162
{
132163
return;
133164
}
134165

135166
if (Context.IsPlayerFree && Game1.player.ActiveObject is Chest heldChest)
136167
{
137168
this.Helper.Input.Suppress(e.Button);
138-
heldChest.ShowMenu();
169+
this.Helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
170+
ModState.FrameCounter = 1;
171+
ModState.StartingLidFrame = heldChest.startingLidFrame.Value;
172+
ModState.LastLidFrame = heldChest.getLastLidFrame() - ModState.StartingLidFrame;
139173
return;
140174
}
141175

@@ -159,8 +193,9 @@ GameMenu gameMenu when gameMenu.GetCurrentPage() is InventoryPage { inventory: {
159193
}
160194

161195
var slot = slots.FirstOrDefault(slot => slot.containsPoint(mouseX, mouseY));
162-
if (slot is null || !int.TryParse(slot.name, out var index) ||
163-
items[index] is not Chest chest)
196+
if (slot is null ||
197+
!int.TryParse(slot.name, out var index) ||
198+
items.ElementAtOrDefault(index) is not Chest chest)
164199
{
165200
return;
166201
}
@@ -170,9 +205,34 @@ GameMenu gameMenu when gameMenu.GetCurrentPage() is InventoryPage { inventory: {
170205
});
171206
}
172207

208+
private void OnUpdateTicked(object? sender, UpdateTickedEventArgs e)
209+
{
210+
if (!Context.IsPlayerFree || Game1.player.ActiveObject is not Chest heldChest)
211+
{
212+
this.Helper.Events.GameLoop.UpdateTicked -= this.OnUpdateTicked;
213+
return;
214+
}
215+
216+
if (ModState.FrameCounter / 5 <= ModState.LastLidFrame)
217+
{
218+
return;
219+
}
220+
221+
heldChest.ShowMenu();
222+
this.Helper.Events.GameLoop.UpdateTicked -= this.OnUpdateTicked;
223+
}
224+
173225
private void OnConfigChanged(ConfigChangedEventArgs<ModConfig> e)
174226
{
227+
this.Helper.Events.Input.ButtonPressed -= this.OnButtonPressed;
175228
this.Helper.Events.GameLoop.OneSecondUpdateTicked -= OnOneSecondUpdateTicked;
229+
230+
if (!e.Config.Enabled)
231+
{
232+
return;
233+
}
234+
235+
this.Helper.Events.Input.ButtonPressed += this.OnButtonPressed;
176236
if (e.Config.SlownessLimit > 0 && e.Config.SlownessAmount != 0)
177237
{
178238
this.Helper.Events.GameLoop.OneSecondUpdateTicked += OnOneSecondUpdateTicked;
@@ -181,12 +241,22 @@ private void OnConfigChanged(ConfigChangedEventArgs<ModConfig> e)
181241

182242
private void OnReturnedToTitle(object? sender, ReturnedToTitleEventArgs e)
183243
{
244+
this.Helper.Events.Display.MenuChanged -= OnMenuChanged;
184245
this.Helper.Events.Input.ButtonPressed -= this.OnButtonPressed;
246+
this.Helper.Events.Input.ButtonsChanged -= OnButtonsChanged;
185247
this.Helper.Events.GameLoop.OneSecondUpdateTicked -= OnOneSecondUpdateTicked;
186248
}
187249

188250
private void OnSaveLoaded(object? sender, SaveLoadedEventArgs e)
189251
{
252+
this.Helper.Events.Display.MenuChanged += OnMenuChanged;
253+
this.Helper.Events.Input.ButtonsChanged += OnButtonsChanged;
254+
255+
if (!ModState.Config.Enabled)
256+
{
257+
return;
258+
}
259+
190260
this.Helper.Events.Input.ButtonPressed += this.OnButtonPressed;
191261
if (ModState.Config.SlownessLimit > 0 && ModState.Config.SlownessAmount != 0)
192262
{

CarryChests/Services/ConfigMenu.cs

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,83 @@
1-
using LeFauxMods.Common.Integrations.GenericModConfigMenu;
21
using LeFauxMods.Common.Services;
32

43
namespace LeFauxMods.CarryChest.Services;
54

6-
/// <summary>Responsible for handling the mod configuration menu.</summary>
7-
internal sealed class ConfigMenu
5+
/// <inheritdoc />
6+
internal sealed class ConfigMenu(IModHelper helper, IManifest manifest)
7+
: BaseConfigMenu<ModConfig>(helper, manifest)
88
{
9-
private readonly IGenericModConfigMenuApi api = null!;
10-
private readonly GenericModConfigMenuIntegration gmcm;
11-
private readonly IManifest manifest;
9+
/// <inheritdoc />
10+
protected override ModConfig Config => ModState.ConfigHelper.Temp;
1211

13-
public ConfigMenu(IModHelper helper, IManifest manifest)
14-
{
15-
this.manifest = manifest;
16-
this.gmcm = new GenericModConfigMenuIntegration(manifest, helper.ModRegistry);
17-
if (!this.gmcm.IsLoaded)
18-
{
19-
return;
20-
}
21-
22-
this.api = this.gmcm.Api;
23-
this.SetupMenu();
24-
}
25-
26-
private static ModConfig Config => ModState.ConfigHelper.Temp;
12+
/// <inheritdoc />
13+
protected override ConfigHelper<ModConfig> ConfigHelper => ModState.ConfigHelper;
2714

28-
private static ConfigHelper<ModConfig> ConfigHelper => ModState.ConfigHelper;
29-
30-
private void SetupMenu()
15+
/// <inheritdoc />
16+
protected internal override void SetupOptions()
3117
{
32-
this.gmcm.Register(ConfigHelper.Reset, ConfigHelper.Save);
18+
this.Api.AddBoolOption(
19+
this.Manifest,
20+
() => this.Config.Enabled,
21+
value => this.Config.Enabled = value,
22+
I18n.ConfigOption_Enabled_Name,
23+
I18n.ConfigOption_Enabled_Description);
24+
25+
this.Api.AddNumberOption(
26+
this.Manifest,
27+
() => this.Config.MaximumReach,
28+
value => this.Config.MaximumReach = value,
29+
I18n.ConfigOption_MaximumReach_Name,
30+
I18n.ConfigOption_MaximumReach_Description,
31+
1,
32+
16);
3333

34-
this.api.AddNumberOption(
35-
this.manifest,
36-
static () => Config.TotalLimit,
37-
static value => Config.TotalLimit = value,
34+
this.Api.AddNumberOption(
35+
this.Manifest,
36+
() => this.Config.TotalLimit,
37+
value => this.Config.TotalLimit = value,
3838
I18n.ConfigOption_TotalLimit_Name,
3939
I18n.ConfigOption_TotalLimit_Description);
4040

41-
this.api.AddNumberOption(
42-
this.manifest,
43-
static () => Config.SlownessAmount,
44-
static value => Config.SlownessAmount = value,
41+
this.Api.AddNumberOption(
42+
this.Manifest,
43+
() => this.Config.SlownessAmount,
44+
value => this.Config.SlownessAmount = value,
4545
I18n.ConfigOption_SlownessAmount_Name,
4646
I18n.ConfigOption_SlownessAmount_Description);
4747

48-
this.api.AddNumberOption(
49-
this.manifest,
50-
static () => Config.SlownessLimit,
51-
static value => Config.SlownessLimit = value,
48+
this.Api.AddNumberOption(
49+
this.Manifest,
50+
() => this.Config.SlownessLimit,
51+
value => this.Config.SlownessLimit = value,
5252
I18n.ConfigOption_SlownessLimit_Name,
5353
I18n.ConfigOption_SlownessLimit_Description);
5454

55-
this.api.AddBoolOption(
56-
this.manifest,
57-
static () => Config.OpenHeldChest,
58-
static value => Config.OpenHeldChest = value,
55+
this.Api.AddBoolOption(
56+
this.Manifest,
57+
() => this.Config.OpenHeldChest,
58+
value => this.Config.OpenHeldChest = value,
5959
I18n.ConfigOption_OpenHeldChest_Name,
6060
I18n.ConfigOption_OpenHeldChest_Description);
6161

62-
this.api.AddBoolOption(
63-
this.manifest,
64-
static () => Config.OverrideTool,
65-
static value => Config.OverrideTool = value,
62+
this.Api.AddBoolOption(
63+
this.Manifest,
64+
() => this.Config.OverrideTool,
65+
value => this.Config.OverrideTool = value,
6666
I18n.ConfigOption_OverrideToool_Name,
6767
I18n.ConfigOption_OverrideTool_Description);
6868

69-
this.api.AddBoolOption(
70-
this.manifest,
71-
static () => Config.SwapChests,
72-
static value => Config.SwapChests = value,
69+
this.Api.AddBoolOption(
70+
this.Manifest,
71+
() => this.Config.SwapChests,
72+
value => this.Config.SwapChests = value,
7373
I18n.ConfigOption_SwapChests_Name,
7474
I18n.ConfigOption_SwapChests_Description);
75+
76+
this.Api.AddKeybindList(
77+
this.Manifest,
78+
() => this.Config.ToggleEnabled,
79+
value => this.Config.ToggleEnabled = value,
80+
I18n.ConfigOption_ToggleEnabled_Name,
81+
I18n.ConfigOption_ToggleEnabled_Description);
7582
}
7683
}

CarryChests/Services/ModPatches.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,16 @@ private static bool Object_drawWhenHeld_prefix(SObject __instance, SpriteBatch s
141141
}
142142

143143
var (x, y) = objectPosition;
144+
if (ModState.FrameCounter == 0)
145+
{
146+
chest.draw(spriteBatch, (int)x, (int)y + Game1.tileSize, 1f, true);
147+
return false;
148+
}
149+
150+
var currentLidFrame = ModState.StartingLidFrame + Math.Min(++ModState.FrameCounter / 5, ModState.LastLidFrame);
151+
ModState.CurrentLidFrame.SetValue(chest, currentLidFrame);
144152
chest.draw(spriteBatch, (int)x, (int)y + Game1.tileSize, 1f, true);
153+
ModState.CurrentLidFrame.SetValue(chest, ModState.StartingLidFrame);
145154
return false;
146155
}
147156

0 commit comments

Comments
 (0)