From 5dae30b083db64c7cbd46719d7f57e2c7f9dd961 Mon Sep 17 00:00:00 2001 From: aedenthorn Date: Wed, 24 Nov 2021 23:37:25 -0500 Subject: [PATCH] etc --- UtilityGrid/GridPipe.cs | 8 + UtilityGrid/HelperEvents.cs | 245 ++++++++++++++++++++++++++ UtilityGrid/MethodPatches.cs | 58 ++++++ UtilityGrid/ModConfig.cs | 1 + UtilityGrid/ModEntry.cs | 211 ++++++---------------- UtilityGrid/PipeGroup.cs | 4 +- UtilityGrid/UtilityGrid.csproj | 5 + UtilityGrid/UtilityGridApi.cs | 25 +++ UtilityGrid/UtilityGridData.cs | 27 +++ UtilityGrid/UtilityObject.cs | 13 ++ UtilityGrid/Utils.cs | 202 +++++++++++++++------ UtilityGrid/assets/pipes.png | Bin 1184 -> 4766 bytes UtilityGrid/assets/pipes.xcf | Bin 0 -> 26928 bytes UtilityGrid/assets/water_pump.png | Bin 0 -> 868 bytes UtilityGrid/assets/water_pump.xcf | Bin 0 -> 3782 bytes WaterPump/IGenericModConfigMenuApi.cs | 49 ++++++ WaterPump/MethodPatches.cs | 18 ++ WaterPump/ModConfig.cs | 11 ++ WaterPump/ModEntry.cs | 43 +++++ WaterPump/WaterPump.csproj | 20 +++ WaterPump/manifest.json | 22 +++ 21 files changed, 754 insertions(+), 208 deletions(-) create mode 100644 UtilityGrid/GridPipe.cs create mode 100644 UtilityGrid/HelperEvents.cs create mode 100644 UtilityGrid/MethodPatches.cs create mode 100644 UtilityGrid/UtilityGridApi.cs create mode 100644 UtilityGrid/UtilityGridData.cs create mode 100644 UtilityGrid/UtilityObject.cs create mode 100644 UtilityGrid/assets/pipes.xcf create mode 100644 UtilityGrid/assets/water_pump.png create mode 100644 UtilityGrid/assets/water_pump.xcf create mode 100644 WaterPump/IGenericModConfigMenuApi.cs create mode 100644 WaterPump/MethodPatches.cs create mode 100644 WaterPump/ModConfig.cs create mode 100644 WaterPump/ModEntry.cs create mode 100644 WaterPump/WaterPump.csproj create mode 100644 WaterPump/manifest.json diff --git a/UtilityGrid/GridPipe.cs b/UtilityGrid/GridPipe.cs new file mode 100644 index 00000000..6f64058e --- /dev/null +++ b/UtilityGrid/GridPipe.cs @@ -0,0 +1,8 @@ +namespace UtilityGrid +{ + public class GridPipe + { + public int index; + public int rotation; + } +} \ No newline at end of file diff --git a/UtilityGrid/HelperEvents.cs b/UtilityGrid/HelperEvents.cs new file mode 100644 index 00000000..9898b1be --- /dev/null +++ b/UtilityGrid/HelperEvents.cs @@ -0,0 +1,245 @@ +using HarmonyLib; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewValley; +using System; +using System.Collections.Generic; + +namespace UtilityGrid +{ + /// The mod entry point. + public partial class ModEntry + { + + + public void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) + { + if (!Config.EnableMod || !(Game1.currentLocation is Farm) || !Game1.currentLocation.IsOutdoors || Game1.activeClickableMenu != null) + return; + + if (e.Button == Config.ToggleGrid) + { + Helper.Input.Suppress(e.Button); + ShowingGrid = !ShowingGrid; + Monitor.Log($"Showing grid: {ShowingGrid}"); + } + if (!ShowingGrid) + return; + if (e.Button == Config.SwitchGrid) + { + Helper.Input.Suppress(e.Button); + CurrentGrid = CurrentGrid == GridType.water ? GridType.electric : GridType.water; + Monitor.Log($"Showing grid: {CurrentGrid}"); + } + else if (e.Button == Config.SwitchTile) + { + Helper.Input.Suppress(e.Button); + CurrentTile++; + CurrentTile %= 6; + CurrentRotation = 0; + //Monitor.Log($"Showing tile: {CurrentTile},{CurrentRotation}"); + } + else if (e.Button == Config.RotateTile) + { + Helper.Input.Suppress(e.Button); + CurrentRotation++; + if (CurrentTile == 1) + CurrentRotation %= 2; + else if (CurrentTile == 4) + CurrentRotation = 0; + else + CurrentRotation %= 4; + //Monitor.Log($"Showing tile: {CurrentTile},{CurrentRotation}"); + } + else if (e.Button == Config.PlaceTile) + { + Helper.Input.Suppress(e.Button); + Dictionary pipeDict; + if (CurrentGrid == GridType.electric) + { + pipeDict = electricPipes; + } + else + { + pipeDict = waterPipes; + } + if(CurrentTile == 5) + { + Monitor.Log($"Removing tile at {Game1.currentCursorTile}"); + pipeDict.Remove(Game1.lastCursorTile); + } + else + { + Monitor.Log($"Placing tile {CurrentTile},{CurrentRotation} at {Game1.currentCursorTile}"); + pipeDict[Game1.lastCursorTile] = new GridPipe() { index = CurrentTile, rotation = CurrentRotation }; + } + RemakeGroups(CurrentGrid); + } + } + public void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) + { + if (!Config.EnableMod || !ShowingGrid) + return; + + if(!(Game1.currentLocation is Farm) || !Game1.currentLocation.IsOutdoors || Game1.activeClickableMenu != null) + { + ShowingGrid = false; + return; + } + + List groupList; + Color color; + Dictionary pipeDict; + if (CurrentGrid == GridType.electric) + { + groupList = electricGroups; + pipeDict = electricPipes; + color = Config.ElectricityColor; + } + else + { + groupList = waterGroups; + pipeDict = waterPipes; + color = Config.WaterColor; + } + foreach (var group in groupList) + { + Vector2 power = GetGroupPower(group, CurrentGrid); + float netPower = power.X + power.Y; + bool powered = power.X > 0 && netPower >= 0; + foreach (var pipe in group.pipes) + { + if (Utility.isOnScreen(new Vector2(pipe.X * 64 + 32, pipe.Y * 64 + 32), 32)) + { + if (pipe != Game1.currentCursorTile) + { + if (pipeDict[pipe].index == 4) + DrawTile(e.SpriteBatch, pipe, new GridPipe() { index = 1, rotation = 2 }, powered ? color : Color.White); + else + DrawTile(e.SpriteBatch, pipe, pipeDict[pipe], powered ? color : Color.White); + } + } + } + foreach (var kvp in group.objects) + { + float objPower; + bool enough = netPower >= 0; + if (CurrentGrid == GridType.electric) + { + objPower = kvp.Value.electric; + } + else + { + objPower = kvp.Value.water; + if (kvp.Value.electric < 0 && GetTileNetElectricPower(kvp.Key) < 0) + enough = false; + } + + if (objPower == 0) + continue; + + + string str = "" + Math.Round(objPower); + + e.SpriteBatch.DrawString(Game1.dialogueFont, str, Game1.GlobalToLocal(Game1.viewport, kvp.Key * 64) - new Vector2(16, 16) + new Vector2(-2, 2), Color.Black, 0, Vector2.Zero, 1f, SpriteEffects.None, 0.999999f); + e.SpriteBatch.DrawString(Game1.dialogueFont, str, Game1.GlobalToLocal(Game1.viewport, kvp.Key * 64) - new Vector2(16, 16), enough ? color : Config.InsufficientColor, 0, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f); + } + + } + if (CurrentTile == 4) + DrawTile(e.SpriteBatch, Game1.currentCursorTile, new GridPipe() { index = 1, rotation = 2 }, color); + else if(CurrentTile != 5) + DrawTile(e.SpriteBatch, Game1.currentCursorTile, new GridPipe() { index = CurrentTile, rotation = CurrentRotation }, color); + } + + private void GameLoop_OneSecondUpdateTicked(object sender, StardewModdingAPI.Events.OneSecondUpdateTickedEventArgs e) + { + if (!Config.EnableMod || !(Game1.currentLocation is Farm)) + return; + + RemakeAllGroups(); + + } + + private void GameLoop_SaveLoaded(object sender, StardewModdingAPI.Events.SaveLoadedEventArgs e) + { + waterPipes = new Dictionary(); + electricPipes = new Dictionary(); + ShowingGrid = false; + CurrentRotation = 0; + CurrentTile = 0; + + objectDict = SHelper.Content.Load>(dictPath, ContentSource.GameContent); + UtilityGridData gridData = Helper.Data.ReadSaveData(saveKey) ?? new UtilityGridData(); + Monitor.Log($"reading {gridData.electricData.Count} ep and {gridData.waterData.Count} wp from save"); + foreach (var arr in gridData.waterData) + { + waterPipes[new Vector2(arr[0], arr[1])] = new GridPipe() { index = arr[2], rotation = arr[3] }; + } + foreach(var arr in gridData.electricData) + { + electricPipes[new Vector2(arr[0], arr[1])] = new GridPipe() { index = arr[2], rotation = arr[3] }; + } + RemakeAllGroups(); + } + private void GameLoop_Saving(object sender, StardewModdingAPI.Events.SavingEventArgs e) + { + + UtilityGridData gridData = new UtilityGridData(waterPipes, electricPipes); + Monitor.Log($"writing {gridData.electricData.Count} ep and {gridData.waterData.Count} wp to save"); + Helper.Data.WriteSaveData(saveKey, gridData); + } + public void GameLoop_GameLaunched(object sender, StardewModdingAPI.Events.GameLaunchedEventArgs e) + { + // get Generic Mod Config Menu's API (if it's installed) + var configMenu = Helper.ModRegistry.GetApi("spacechase0.GenericModConfigMenu"); + if (configMenu is null) + return; + + // register mod + configMenu.Register( + mod: ModManifest, + reset: () => Config = new ModConfig(), + save: () => Helper.WriteConfig(Config) + ); + + configMenu.AddBoolOption( + mod: ModManifest, + name: () => "Mod Enabled?", + getValue: () => Config.EnableMod, + setValue: value => Config.EnableMod = value + ); + configMenu.AddKeybind( + mod: ModManifest, + name: () => "Toggle Grid Key", + getValue: () => Config.ToggleGrid, + setValue: value => Config.ToggleGrid = value + ); + configMenu.AddKeybind( + mod: ModManifest, + name: () => "Switch Grid Key", + getValue: () => Config.ToggleGrid, + setValue: value => Config.ToggleGrid = value + ); + configMenu.AddKeybind( + mod: ModManifest, + name: () => "Change Tile Key", + getValue: () => Config.SwitchTile, + setValue: value => Config.SwitchTile = value + ); + configMenu.AddKeybind( + mod: ModManifest, + name: () => "Rotate Tile Key", + getValue: () => Config.RotateTile, + setValue: value => Config.RotateTile = value + ); + configMenu.AddKeybind( + mod: ModManifest, + name: () => "Place Tile Key", + getValue: () => Config.PlaceTile, + setValue: value => Config.PlaceTile = value + ); + } + } +} \ No newline at end of file diff --git a/UtilityGrid/MethodPatches.cs b/UtilityGrid/MethodPatches.cs new file mode 100644 index 00000000..5de9b8c1 --- /dev/null +++ b/UtilityGrid/MethodPatches.cs @@ -0,0 +1,58 @@ +using Microsoft.Xna.Framework; +using StardewValley; + +namespace UtilityGrid +{ + public partial class ModEntry + { + // dga_add "aedenthorn.WaterPumpDGA/Bronze Water Pump" 1 + public static bool Utility_playerCanPlaceItemHere_Prefix(GameLocation location, Item item, int x, int y, ref bool __result) + { + //SMonitor.Log($"placing {item.Name}, {objectDict.ContainsKey(item.Name)}"); + if (!Config.EnableMod || !objectDict.ContainsKey(item.Name) || !(location is Farm) || !objectDict[item.Name].onlyInWater || location.Objects.ContainsKey(new Vector2(x, y))) + return true; + __result = location.isWaterTile(x / 64, y / 64); + return false; + } + public static void Object_IsSprinkler_Postfix(Object __instance, ref bool __result) + { + //SMonitor.Log($"placing {item.Name}, {objectDict.ContainsKey(item.Name)}"); + if (!Config.EnableMod || !__result || !objectDict.ContainsKey(__instance.Name)) + return; + __result = IsObjectPowered(__instance.TileLocation, objectDict[__instance.Name]); + + } + public static void Object_updateWhenCurrentLocation_Prefix(Object __instance) + { + //SMonitor.Log($"placing {item.Name}, {objectDict.ContainsKey(item.Name)}"); + if (!Config.EnableMod || !objectDict.ContainsKey(__instance.Name)) + return; + __instance.IsOn = IsObjectPowered(__instance.TileLocation, objectDict[__instance.Name]); + + } + public static Object preItem = null; + public static int minutesUntilReady = 0; + public static void Object_DayUpdate_Prefix(Object __instance, ref bool __state) + { + //SMonitor.Log($"placing {item.Name}, {objectDict.ContainsKey(item.Name)}"); + if (!Config.EnableMod || !objectDict.ContainsKey(__instance.Name)) + return; + if(!IsObjectPowered(__instance.TileLocation, objectDict[__instance.Name])) + { + preItem = __instance.heldObject.Value; + minutesUntilReady = __instance.MinutesUntilReady; + __instance.heldObject.Value = null; + __state = true; + } + + } + public static void Object_DayUpdate_Postfix(Object __instance, bool __state) + { + //SMonitor.Log($"placing {item.Name}, {objectDict.ContainsKey(item.Name)}"); + if (!__state) + return; + __instance.MinutesUntilReady = minutesUntilReady; + __instance.heldObject.Value = preItem; + } + } +} \ No newline at end of file diff --git a/UtilityGrid/ModConfig.cs b/UtilityGrid/ModConfig.cs index 63dbaaa3..cfdefd56 100644 --- a/UtilityGrid/ModConfig.cs +++ b/UtilityGrid/ModConfig.cs @@ -15,5 +15,6 @@ public class ModConfig public SButton PlaceTile { get; set; } = SButton.MouseLeft; public Color WaterColor { get; set; } = Color.Aqua; public Color ElectricityColor { get; set; } = Color.Yellow; + public Color InsufficientColor { get; set; } = Color.Red; } } diff --git a/UtilityGrid/ModEntry.cs b/UtilityGrid/ModEntry.cs index 3156a28f..90ea0ab8 100644 --- a/UtilityGrid/ModEntry.cs +++ b/UtilityGrid/ModEntry.cs @@ -5,11 +5,12 @@ using StardewValley; using System; using System.Collections.Generic; +using Object = StardewValley.Object; namespace UtilityGrid { /// The mod entry point. - public partial class ModEntry : Mod + public partial class ModEntry : Mod, IAssetLoader { public static IMonitor SMonitor; @@ -19,17 +20,32 @@ public partial class ModEntry : Mod public static ModEntry context; public static Texture2D pipeTexture; + public static readonly string dictPath = "utility_grid_object_dictionary"; + public enum GridType { + water, + electric + } + public static readonly string saveKey = "utility-grid-data"; + public static bool ShowingGrid { get; set; } = false; - public static bool ElectricGrid { get; set; } = false; + public static GridType CurrentGrid { get; set; } = GridType.water; public static int CurrentTile { get; set; } = 0; public static int CurrentRotation { get; set; } = 0; - public static int[][] intakeArray = { new int[]{0, 1, 1, 1}, new int[]{1, 0, 0, 1}, new int[]{1, 0, 0, 0}, new int[]{0, 1, 0, 1}, new int[]{1, 1, 1, 1} }; - - public Dictionary waterPipes = new Dictionary(); - public Dictionary electricPipes = new Dictionary(); - public List waterGroups = new List(); - public List electricGroups = new List(); + public static int[][] intakeArray = { + new int[] { 1, 0, 0, 0 }, + new int[] { 0, 1, 0, 1 }, + new int[] { 1, 0, 0, 1 }, + new int[] { 0, 1, 1, 1 }, + new int[] { 1, 1, 1, 1 } + }; + + public static Dictionary waterPipes = new Dictionary(); + public static Dictionary electricPipes = new Dictionary(); + public static Dictionary objectDict = new Dictionary(); + + public static List waterGroups = new List(); + public static List electricGroups = new List(); /// The mod entry point, called after the mod is first loaded. /// Provides simplified APIs for writing mods. @@ -47,168 +63,53 @@ public override void Entry(IModHelper helper) helper.Events.Input.ButtonPressed += Input_ButtonPressed; helper.Events.GameLoop.GameLaunched += GameLoop_GameLaunched; + helper.Events.GameLoop.SaveLoaded += GameLoop_SaveLoaded; + helper.Events.GameLoop.Saving += GameLoop_Saving; helper.Events.Display.RenderedWorld += Display_RenderedWorld; + helper.Events.GameLoop.OneSecondUpdateTicked += GameLoop_OneSecondUpdateTicked; var harmony = new Harmony(ModManifest.UniqueID); - // Game1 Patches - /* - harmony.Patch( - original: AccessTools.Method(typeof(Game1), "_newDayAfterFade"), - prefix: new HarmonyMethod(typeof(ModEntry), nameof(ModEntry.Game1__newDayAfterFade_Prefix)) - ); - */ + harmony.Patch( + original: AccessTools.Method(typeof(Utility), nameof(Utility.playerCanPlaceItemHere)), + prefix: new HarmonyMethod(typeof(ModEntry), nameof(ModEntry.Utility_playerCanPlaceItemHere_Prefix)) + ); + harmony.Patch( + original: AccessTools.Method(typeof(Object), nameof(Object.IsSprinkler)), + postfix: new HarmonyMethod(typeof(ModEntry), nameof(ModEntry.Object_IsSprinkler_Postfix)) + ); + harmony.Patch( + original: AccessTools.Method(typeof(Object), nameof(Object.updateWhenCurrentLocation)), + prefix: new HarmonyMethod(typeof(ModEntry), nameof(ModEntry.Object_updateWhenCurrentLocation_Prefix)) + ); pipeTexture = Helper.Content.Load("assets/pipes.png"); } - private void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) - { - if (!Config.EnableMod || !(Game1.currentLocation is Farm) || !Game1.currentLocation.IsOutdoors) - return; - if (e.Button == Config.ToggleGrid) - { - Helper.Input.Suppress(e.Button); - ShowingGrid = !ShowingGrid; - Monitor.Log($"Showing grid: {ShowingGrid}"); - } - if (!ShowingGrid) - return; - if (e.Button == Config.SwitchGrid) - { - Helper.Input.Suppress(e.Button); - ElectricGrid = !ElectricGrid; - Monitor.Log($"Showing Electric grid: {ElectricGrid}"); - } - else if (e.Button == Config.SwitchTile) - { - Helper.Input.Suppress(e.Button); - CurrentTile++; - CurrentTile %= 6; - CurrentRotation = 0; - Monitor.Log($"Showing tile: {CurrentTile},{CurrentRotation}"); - } - else if (e.Button == Config.RotateTile) - { - Helper.Input.Suppress(e.Button); - CurrentRotation++; - if (CurrentTile < 3) - CurrentRotation %= 4; - else if (CurrentTile == 3) - CurrentRotation %= 2; - else - CurrentRotation = 0; - Monitor.Log($"Showing tile: {CurrentTile},{CurrentRotation}"); - } - else if (e.Button == Config.PlaceTile) - { - Helper.Input.Suppress(e.Button); - Dictionary pipeDict; - if (ElectricGrid) - { - pipeDict = electricPipes; - } - else - { - pipeDict = waterPipes; - } - if(CurrentTile == 5) - pipeDict.Remove(Game1.lastCursorTile); - else - pipeDict[Game1.lastCursorTile] = new Point(CurrentTile, CurrentRotation); - RemakeGroups(ElectricGrid); - Monitor.Log($"Placing tile: {CurrentTile},{CurrentRotation} at {Game1.currentCursorTile}; connected? {PipeIsPowered(Game1.currentCursorTile, ElectricGrid)}"); - } - } - private void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) + + public override object GetApi() { - if (!Config.EnableMod || !ShowingGrid) - return; - Dictionary pipeDict; - Color color; - if (ElectricGrid) - { - pipeDict = electricPipes; - color = Config.ElectricityColor; - } - else - { - pipeDict = waterPipes; - color = Config.WaterColor; - } - foreach (var kvp in pipeDict) - { - if (kvp.Key == Game1.currentCursorTile) - { - continue; - } - if (Utility.isOnScreen(new Vector2(kvp.Key.X * 64 + 32, kvp.Key.Y * 64 + 32), 32)) - { - if (kvp.Value.X == 4) - DrawTile(e.SpriteBatch, kvp.Key, new Point(3, 2), ElectricGrid, PipeIsPowered(kvp.Key, ElectricGrid) ? color : Color.White); - else - DrawTile(e.SpriteBatch, kvp.Key, kvp.Value, ElectricGrid, PipeIsPowered(kvp.Key, ElectricGrid) ? color : Color.White); - } - } - if (CurrentTile == 4) - DrawTile(e.SpriteBatch, Game1.currentCursorTile, new Point(3, 2), ElectricGrid, color); - else if(CurrentTile != 5) - DrawTile(e.SpriteBatch, Game1.currentCursorTile, new Point(CurrentTile, CurrentRotation), ElectricGrid, color); + return new UtilityGridApi(); } - - - private void GameLoop_GameLaunched(object sender, StardewModdingAPI.Events.GameLaunchedEventArgs e) + /// Get whether this instance can load the initial version of the given asset. + /// Basic metadata about the asset being loaded. + public bool CanLoad(IAssetInfo asset) { - // get Generic Mod Config Menu's API (if it's installed) - var configMenu = Helper.ModRegistry.GetApi("spacechase0.GenericModConfigMenu"); - if (configMenu is null) - return; + if (!Config.EnableMod) + return false; - // register mod - configMenu.Register( - mod: ModManifest, - reset: () => Config = new ModConfig(), - save: () => Helper.WriteConfig(Config) - ); + return asset.AssetNameEquals(dictPath); + } - configMenu.AddBoolOption( - mod: ModManifest, - name: () => "Mod Enabled?", - getValue: () => Config.EnableMod, - setValue: value => Config.EnableMod = value - ); - configMenu.AddKeybind( - mod: ModManifest, - name: () => "Toggle Grid Key", - getValue: () => Config.ToggleGrid, - setValue: value => Config.ToggleGrid = value - ); - configMenu.AddKeybind( - mod: ModManifest, - name: () => "Switch Grid Key", - getValue: () => Config.ToggleGrid, - setValue: value => Config.ToggleGrid = value - ); - configMenu.AddKeybind( - mod: ModManifest, - name: () => "Change Tile Key", - getValue: () => Config.SwitchTile, - setValue: value => Config.SwitchTile = value - ); - configMenu.AddKeybind( - mod: ModManifest, - name: () => "Rotate Tile Key", - getValue: () => Config.RotateTile, - setValue: value => Config.RotateTile = value - ); - configMenu.AddKeybind( - mod: ModManifest, - name: () => "Place Tile Key", - getValue: () => Config.PlaceTile, - setValue: value => Config.PlaceTile = value - ); + /// Load a matched asset. + /// Basic metadata about the asset being loaded. + public T Load(IAssetInfo asset) + { + Monitor.Log("Loading dictionary"); + + return (T)(object)new Dictionary(); } } } \ No newline at end of file diff --git a/UtilityGrid/PipeGroup.cs b/UtilityGrid/PipeGroup.cs index da441209..413e570a 100644 --- a/UtilityGrid/PipeGroup.cs +++ b/UtilityGrid/PipeGroup.cs @@ -5,7 +5,7 @@ namespace UtilityGrid { public class PipeGroup { - public List pipes; - public float power; + public List pipes = new List(); + public Dictionary objects = new Dictionary(); } } \ No newline at end of file diff --git a/UtilityGrid/UtilityGrid.csproj b/UtilityGrid/UtilityGrid.csproj index 41b3b4bb..4c9921fa 100644 --- a/UtilityGrid/UtilityGrid.csproj +++ b/UtilityGrid/UtilityGrid.csproj @@ -4,6 +4,11 @@ net5.0 true + + + + + diff --git a/UtilityGrid/UtilityGridApi.cs b/UtilityGrid/UtilityGridApi.cs new file mode 100644 index 00000000..74059fd0 --- /dev/null +++ b/UtilityGrid/UtilityGridApi.cs @@ -0,0 +1,25 @@ +using Microsoft.Xna.Framework; + +namespace UtilityGrid +{ + public class UtilityGridApi + { + public Vector2 ElectricityToFromTile(int x, int y) + { + return ModEntry.GetTileElectricPower(new Vector2(x, y)); + } + public Vector2 WaterToFromTile(int x, int y) + { + return ModEntry.GetTileWaterPower(new Vector2(x, y)); + + } + public void RefreshElectricGrid() + { + ModEntry.RemakeGroups(ModEntry.GridType.electric); + } + public void RefreshWaterGrid() + { + ModEntry.RemakeGroups(ModEntry.GridType.water); + } + } +} \ No newline at end of file diff --git a/UtilityGrid/UtilityGridData.cs b/UtilityGrid/UtilityGridData.cs new file mode 100644 index 00000000..d6803a04 --- /dev/null +++ b/UtilityGrid/UtilityGridData.cs @@ -0,0 +1,27 @@ +using Microsoft.Xna.Framework; +using System.Collections.Generic; + +namespace UtilityGrid +{ + public class UtilityGridData + { + public List waterData = new List(); + public List electricData = new List(); + + public UtilityGridData() + { + } + + public UtilityGridData(Dictionary waterPipes, Dictionary electricPipes) + { + foreach (var kvp in waterPipes) + { + waterData.Add(new int[]{ (int)kvp.Key.X, (int)kvp.Key.Y, (int)kvp.Value.index, (int)kvp.Value.rotation }); + } + foreach (var kvp in electricPipes) + { + electricData.Add(new int[] { (int)kvp.Key.X, (int)kvp.Key.Y, (int)kvp.Value.index, (int)kvp.Value.rotation }); + } + } + } +} \ No newline at end of file diff --git a/UtilityGrid/UtilityObject.cs b/UtilityGrid/UtilityObject.cs new file mode 100644 index 00000000..8c5243ff --- /dev/null +++ b/UtilityGrid/UtilityObject.cs @@ -0,0 +1,13 @@ +using StardewValley; + +namespace UtilityGrid +{ + public class UtilityObject + { + public float water; + public float electric; + public bool onlyInWater; + public bool mustBeOn; + public Object worldObj; + } +} \ No newline at end of file diff --git a/UtilityGrid/Utils.cs b/UtilityGrid/Utils.cs index 22bf7eed..0e12550c 100644 --- a/UtilityGrid/Utils.cs +++ b/UtilityGrid/Utils.cs @@ -13,35 +13,17 @@ namespace UtilityGrid public partial class ModEntry { - private void DrawTile(SpriteBatch b, Vector2 tile, Point which, bool electric, Color color) + public static void DrawTile(SpriteBatch b, Vector2 tile, GridPipe which, Color color) { float layerDepth = (tile.Y * (16 * Game1.pixelZoom) + 16 * Game1.pixelZoom) / 10000f; - b.Draw(pipeTexture, Game1.GlobalToLocal(Game1.viewport, tile * 64), new Rectangle(which.Y * 64, which.X * 64, 64, 64), color, 0, Vector2.Zero, 1, SpriteEffects.None, layerDepth); + b.Draw(pipeTexture, Game1.GlobalToLocal(Game1.viewport, tile * 64), new Rectangle(which.rotation * 64, which.index * 64, 64, 64), color, 0, Vector2.Zero, 1, SpriteEffects.None, layerDepth); } - private bool PipeIsPowered(Vector2 tile, bool electric) + public static bool PipesAreJoined(Vector2 tile, Vector2 tile2, GridType gridType) { - List groupList; - if (electric) - { - groupList = electricGroups; - } - else - { - groupList = waterGroups; - } - foreach (var g in groupList) - { - if (g.pipes.Contains(tile)) - return g.power > 0; - } - return false; - } - private bool PipesAreJoined(Vector2 tile, Vector2 tile2, bool electric) - { - Dictionary pipeDict; - if (electric) + Dictionary pipeDict; + if (gridType == GridType.electric) { pipeDict = electricPipes; } @@ -69,22 +51,27 @@ private bool PipesAreJoined(Vector2 tile, Vector2 tile2, bool electric) return false; } - private bool HasIntake(Point pipeRot, int which) + public static bool HasIntake(GridPipe pipe, int which) { - return intakeArray[pipeRot.X][(which + pipeRot.Y) % 4] == 1; + return intakeArray[pipe.index][(which + pipe.rotation) % 4] == 1; } - private void RemakeGroups(bool electric) + public static void RemakeAllGroups() { - Dictionary pipeDict; + RemakeGroups(GridType.water); + RemakeGroups(GridType.electric); + } + public static void RemakeGroups(GridType gridType) + { + Dictionary pipeDict; List groupList; - if (electric) + if (gridType == GridType.electric) { - pipeDict = new Dictionary(electricPipes); + pipeDict = new Dictionary(electricPipes); groupList = electricGroups; } else { - pipeDict = new Dictionary(waterPipes); + pipeDict = new Dictionary(waterPipes); groupList = waterGroups; } groupList.Clear(); @@ -92,15 +79,21 @@ private void RemakeGroups(bool electric) while(pipeDict.Count > 0) { var tile = pipeDict.Keys.ToArray()[0]; - var group = new PipeGroup { pipes = new List() { tile }, power = PipePower(tile, electric) }; - Monitor.Log($"Creating new group; power: {group.power}"); + var group = new PipeGroup { pipes = new List() { tile } }; + var obj = GetUtilityObjectAtTile(tile); + if(obj != null) + { + group.objects[tile] = obj; + } + + //SMonitor.Log($"Creating new group; power: {group.input}"); pipeDict.Remove(tile); - AddTilesToGroup(tile, ref group, pipeDict, electric); + AddTilesToGroup(tile, ref group, pipeDict, gridType); groupList.Add(group); } } - private void AddTilesToGroup(Vector2 tile, ref PipeGroup group, Dictionary pipeDict, bool electric) + public static void AddTilesToGroup(Vector2 tile, ref PipeGroup group, Dictionary pipeDict, GridType gridType) { Vector2[] adjecents = new Vector2[] { tile + new Vector2(0,1),tile + new Vector2(1,0),tile + new Vector2(-1,0),tile + new Vector2(0,-1)}; @@ -108,31 +101,138 @@ private void AddTilesToGroup(Vector2 tile, ref PipeGroup group, Dictionary 0) + power.X += obj.electric; + else if (obj.electric < 0) + power.Y += obj.electric; + } + return power; + } + public static Vector2 GetTileWaterPower(Vector2 tile) + { + Vector2 power = Vector2.Zero; + foreach (var group in waterGroups) + { + if (group.objects.ContainsKey(tile)) + { + return GetGroupWaterPower(group); + } + } + return power; + } + public static Vector2 GetGroupWaterPower(PipeGroup group) + { + Vector2 power = Vector2.Zero; + foreach (var kvp in group.objects) + { + if (kvp.Value.electric < 0) + { + Vector2 ePower = GetTileElectricPower(kvp.Key); + if (ePower.X + ePower.Y < 0) // unpowered + continue; + } + var obj = kvp.Value; + + if (obj.water > 0) + power.X += obj.water; + else if (obj.water < 0) + power.Y += obj.water; + } + return power; + } + + public static bool IsObjectPowered(Vector2 tile, UtilityObject obj) + { + if(obj.water < 0) + { + var netPower = GetTileNetWaterPower(tile); + if (netPower < 0) + return false; + } + if(obj.electric < 0) + { + var netPower = GetTileNetElectricPower(tile); + if (netPower < 0) + return false; + } + return true; + } + + public static UtilityObject GetUtilityObjectAtTile(Vector2 tile) + { + if (!Game1.getFarm().Objects.ContainsKey(tile)) + return null; + var obj = Game1.getFarm().Objects[tile]; + if (!objectDict.ContainsKey(obj.Name) && (obj.modData.ContainsKey("aedenthorn.UtilityGrid/" + GridType.water) || obj.modData.ContainsKey("aedenthorn.UtilityGrid/" + GridType.electric))) + { + objectDict[obj.Name] = new UtilityObject(); + if (obj.modData.ContainsKey("aedenthorn.UtilityGrid/" + GridType.water)) + { + objectDict[obj.Name].water = float.Parse(obj.modData["aedenthorn.UtilityGrid/" + GridType.water], CultureInfo.InvariantCulture); + } + if (obj.modData.ContainsKey("aedenthorn.UtilityGrid/" + GridType.electric)) + { + objectDict[obj.Name].electric = float.Parse(obj.modData["aedenthorn.UtilityGrid/" + GridType.electric], CultureInfo.InvariantCulture); + } + } + if (objectDict.ContainsKey(obj.Name)) + { + UtilityObject outObj = objectDict[obj.Name]; + outObj.worldObj = obj; + return outObj; + } + return null; } } } \ No newline at end of file diff --git a/UtilityGrid/assets/pipes.png b/UtilityGrid/assets/pipes.png index 99849369fca5cb1d8a47103e0433678933aaabfe..de682c217bd8692e5677ef8b4c5732b33c8e71cf 100644 GIT binary patch delta 4357 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%0A{y11kgs0k4AF^0Nw(VkpU!=e*y=S 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 literal 0 HcmV?d00001 diff --git a/UtilityGrid/assets/water_pump.png b/UtilityGrid/assets/water_pump.png new file mode 100644 index 0000000000000000000000000000000000000000..36852c59f4d5ec73510f46c764ae81592e4c8700 GIT binary patch literal 868 zcmV-q1DpJbP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00PWOL_t(Y$DNhSOB+!Xhrh&$ zws8n!$QWaSeP|HT)|QH>iwdPeE0%(ERVbAH3te;}2nt>HKPcUF=RznHL4>Y~6dCA) z4q~U)Cisd;X=>y25lOlj=Vp=_t$5&)$vyXc=QsD9JJ-j7jj6q5j&G@#+4pAwd;pJb z-YG}IP%o=TM*S^h#q&z)Cr@9``=l|ox7^yM9xJUgL2I;uF}3%r-$@QC3IKjda*a~4 zAXJn~`zUG?K-?dR$50YU0L*+IfYScHYxo1QNYogPkV$O=ND{#34+b3SdLM z*+rN9k?|qwWtE_!h(rJqKxV4|SdbUb<`@|tasd`*7rFgl6f>V^Go3|AoCnRocmL9j zax^9bplb%*eMy$G85f{mjS9bQx@O>a{&5C(wzrD`u$0Zv-Iqky3;;`k{R*NqZ7PkL zLE_qF1_lSJ6s*5`OY4;$0m!d^u_{(8b?;2bvj=MDZ3QksV`>+Gp3W{Yob$GMD%ebC zk5sUk&bkzcJ!nq&&^3epz9dVlt9)EpuJrxts;EM9!gsg=8v?Mkv03$N2k)#`A6fw@ zm0JV^AeBy23-_`r1!_x2mDA3Cm|p-2#hfQS7H>T=SODZegp-=zREj4G6pa+j2gKys zukXhO*kzQQ3QRqRe8_Iw<&DH+6$P46eV8ogwkN<2w2!_}U@x#8(7~F=_aGXR52|IY zvpzx~nR;$I6Aw5508G{beizMYXSJd+nVnFu(nvP(Fgq0pR;>{V08FLGxzkPm-T7!t zb|vzcx`Kk3*($JdcV@z?l|S8`nQ#W@Hnu9AXzJCi910ItF2Qt~P zb)hkit{I|K`G<28uFiWh`q=p@x@J)73L^QJP3W_Txn)aM-Sf%1T7WItdbTc_`Q>-` u?%ldR<+WkEe+EP;Lk(}Hz1DpDvBy9EuPvC4f8h`S0000 literal 0 HcmV?d00001 diff --git a/UtilityGrid/assets/water_pump.xcf b/UtilityGrid/assets/water_pump.xcf new file mode 100644 index 0000000000000000000000000000000000000000..9ac2ef4faaca6815099c5dcd6e4c90fffc7e7591 GIT binary patch literal 3782 zcmds4L2uj06&?;LiK3k}+m>w)J*eFlhy!Fv6~dw_DpjgdhZLBNu{*F2LJC@rLJ_g! zz_L9nAnw|$dLV;odU-po5uRRt$_*V4TbALk6BCsf1V!s)R28~s*ivmG`jxaOd z_rCWY$w%_h4#J)1rH{9sln(83nPA+)ED3<|2h4Xc6$Q(;F!dHpVq$z7Q^OPv-cb-$T+v%J$M%Gm%?XT{oX*t?>>1l= zQ2v&X{J)aD_|uG-!u0-$YTsJh9Ef6jo5S8->0Nn$^RSEC7GwTE;9q=-6}J{s*hO4% zjhV_<(bgVRS(g)KAa z-!mkwgUE|P|C#J^O*IfzT!$PLqIpFUd)g@W3S{PS&6{yAN2VT!O|C@oVy-o(-19VY z>G5Wh_LU~Q1RHsM`o(1*yJSttnsWy2uU8s}2G*2uU8F%ANLM3DckDHfzc_As-8@Lt z>;reZ1rl|e{bN9#On_i4ehq-I=Fg57&w-+M2PVJzQF$5A!Q1m5EZBS`eEkmFa5c%r#Le(}hj0L@{Gmt4v+f zL^({iQlT441zv&$<_3Lvxq)4>ie!~JgZ8H@&4mV5k#S|DK^#aKr7Dlj%E8Nnidjaf z%28zlxLn3Hmn$0wfG8CZj40Jt0)$oGlU`~Cr5a2gC82}Ka|w*W#kIXSh+fIVywZVI zHx4#dUlj-1D`TLoE)D2vet;TTsF9_Gv4t90OtWUpLX9j2n_P)v#Z0SBnPs647OT~$ zuhifrSZMk5^GhGQWHrfZa|Z1%R~mx`R+Diy(jX4RMvd&TRXh6psAk!yksZ~1VB5yU z+BN?O5H$jV5jFZsfUw&8(o3zOMrV`LB=l_ZX9A{N^f*V1SX(%YaUOaBemcp)|I5=rp6o>3BlL|(pYKJYMM7U9 z6uB@&0}u^pL6iK6(9%ys_nW|0e=ql8X8##O8nsw8y8|Eyi-+VyoGs{t#Qk~Wxv{iOlwHznM z&Oc-hV@}m-6&ZDu>P5?OKKMvw@rTrjtg3KoX_o5HDqckD#I2k&VOG^*Rl}Nv)tmQ7 z^%L@`_#&lW5%Cb+$bM->v8Y%u(kJQv;d7f_Q*vd*_|+VUEiK0UNisGUXfPSW)UJ>v zkCGWbDU9gJ^fB?4N70ezos3RL+V97|8=buTt>>TWBjx1HDffJSdNLY)_L(}0PDh|V z*H2%M_%Q^2oc<`s=KlBVN@yVhP$Ti@=g$RI%*K{0MvGM{yK1b5Zqq+qb}aoWp@fI zb@Ti@fG8Y-f*YCA*VY9R#srD@jE%antzCJ5RTi^*$RF3PX=z-;6#xRkkQmSRtfrdY@R!VbrlK77jygXZ$E+y=}`G>Y>8k z44LJyAqzv_SHox+f;vnez7E+T1a_GIC`0dBW>Z)x%MZ^(h{7Q(u*j0WjxLZeCP>6* zY?Q^0cI5%qUd$TEAAfL7OXFHhXbF?qX)BjxgrZwx2j>CgXe|oInP{j{1FhA1J6%`7 Y9|!S2D7k@u2W|pkUVNf7VsvBjZy~S0hX4Qo literal 0 HcmV?d00001 diff --git a/WaterPump/IGenericModConfigMenuApi.cs b/WaterPump/IGenericModConfigMenuApi.cs new file mode 100644 index 00000000..eb776cc6 --- /dev/null +++ b/WaterPump/IGenericModConfigMenuApi.cs @@ -0,0 +1,49 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; + +namespace GroundhogDay +{ + /// The API which lets other mods add a config UI through Generic Mod Config Menu. + public interface IGenericModConfigMenuApi + { + /********* + ** Methods + *********/ + /**** + ** Must be called first + ****/ + /// Register a mod whose config can be edited through the UI. + /// The mod's manifest. + /// Reset the mod's config to its default values. + /// Save the mod's current config to the config.json file. + /// Whether the options can only be edited from the title screen. + /// Each mod can only be registered once, unless it's deleted via before calling this again. + void Register(IManifest mod, Action reset, Action save, bool titleScreenOnly = false); + + /// Add a key binding at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddKeybind(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Add a boolean option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddBoolOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Remove a mod from the config UI and delete all its options and pages. + /// The mod's manifest. + void Unregister(IManifest mod); + } +} diff --git a/WaterPump/MethodPatches.cs b/WaterPump/MethodPatches.cs new file mode 100644 index 00000000..7ec05776 --- /dev/null +++ b/WaterPump/MethodPatches.cs @@ -0,0 +1,18 @@ +using StardewValley; + +namespace WaterPump +{ + /// The mod entry point. + public partial class ModEntry + { + + private static bool Utility_playerCanPlaceItemHere_Prefix() + { + if (Config.EnableMod && (Game1.dayOfMonth != 0 || Game1.year != 1 || Game1.currentSeason != "spring")) + { + SMonitor.Log($"Repeating {Utility.getDateString()}"); + Game1.dayOfMonth--; + } + } + } +} \ No newline at end of file diff --git a/WaterPump/ModConfig.cs b/WaterPump/ModConfig.cs new file mode 100644 index 00000000..a156d18d --- /dev/null +++ b/WaterPump/ModConfig.cs @@ -0,0 +1,11 @@ + +using StardewModdingAPI; + +namespace WaterPump +{ + public class ModConfig + { + public bool EnableMod { get; set; } = true; + + } +} diff --git a/WaterPump/ModEntry.cs b/WaterPump/ModEntry.cs new file mode 100644 index 00000000..988b2df0 --- /dev/null +++ b/WaterPump/ModEntry.cs @@ -0,0 +1,43 @@ +using HarmonyLib; +using StardewModdingAPI; +using StardewValley; + +namespace WaterPump +{ + /// The mod entry point. + public partial class ModEntry : Mod + { + + public static IMonitor SMonitor; + public static IModHelper SHelper; + public static ModConfig Config; + + public static ModEntry context; + + /// The mod entry point, called after the mod is first loaded. + /// Provides simplified APIs for writing mods. + public override void Entry(IModHelper helper) + { + Config = Helper.ReadConfig(); + + if (!Config.EnableMod) + return; + + context = this; + + SMonitor = Monitor; + SHelper = helper; + + helper.Events.Input.ButtonPressed += Input_ButtonPressed; + helper.Events.GameLoop.GameLaunched += GameLoop_GameLaunched; + + var harmony = new Harmony(ModManifest.UniqueID); + + harmony.Patch( + original: AccessTools.Method(typeof(Utility), nameof(Utility.playerCanPlaceItemHere)), + prefix: new HarmonyMethod(typeof(ModEntry), nameof(ModEntry.Utility_playerCanPlaceItemHere_Prefix)) + ); + + } + } +} \ No newline at end of file diff --git a/WaterPump/WaterPump.csproj b/WaterPump/WaterPump.csproj new file mode 100644 index 00000000..95bd1a14 --- /dev/null +++ b/WaterPump/WaterPump.csproj @@ -0,0 +1,20 @@ + + + 1.0.0 + net5.0 + true + + + + + + + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/WaterPump/manifest.json b/WaterPump/manifest.json new file mode 100644 index 00000000..35a997fd --- /dev/null +++ b/WaterPump/manifest.json @@ -0,0 +1,22 @@ +{ + "Name": "Water Pump", + "Author": "aedenthorn", + "Version": "0.1.0", + "Description": "Water Pump.", + "UniqueID": "aedenthorn.WaterPump", + "EntryDll": "WaterPump.dll", + "MinimumApiVersion": "3.13.0-beta.20211018", + "ModUpdater": { + "Repository": "StardewValleyMods", + "User": "aedenthorn", + "Directory": "_releases", + "ModFolder": "WaterPump" + }, + "UpdateKeys": [ "Nexus:" ], + "Dependencies": [ + { + "UniqueID": "Platonymous.ModUpdater", + "IsRequired": false + } + ] +} \ No newline at end of file