forked from aedenthorn/StardewValleyMods
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e67e9f0
commit 6456791
Showing
30 changed files
with
1,855 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<Version>1.0.0</Version> | ||
<TargetFramework>net5.0</TargetFramework> | ||
<EnableHarmony>true</EnableHarmony> | ||
<Platforms>AnyCPU;x64</Platforms> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | ||
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="4.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Reference Include="FAudio-CS"> | ||
<HintPath>H:\tmp\ga\SteamLibrary\steamapps\common\Stardew Valley\FAudio-CS.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="assets\emote.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="assets\envelope.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="assets\icon.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="manifest.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Folder Include="assets\" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
using HarmonyLib; | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using StardewValley; | ||
using StardewValley.Tools; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
using xTile.Dimensions; | ||
using xTile.Layers; | ||
using xTile.ObjectModel; | ||
using xTile.Tiles; | ||
using Rectangle = Microsoft.Xna.Framework.Rectangle; | ||
|
||
namespace DynamicMapTiles | ||
{ | ||
public partial class ModEntry | ||
{ | ||
private static Farmer explodingFarmer; | ||
|
||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.explode))] | ||
public class GameLocation_explode_Patch | ||
{ | ||
|
||
public static void Prefix(Farmer who) | ||
{ | ||
if (!Config.ModEnabled) | ||
return; | ||
explodingFarmer = who; | ||
} | ||
} | ||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.explosionAt))] | ||
public class GameLocation_explosionAt_Patch | ||
{ | ||
public static void Postfix(GameLocation __instance, float x, float y) | ||
{ | ||
if (!Config.ModEnabled || !__instance.isTileOnMap(new Vector2(x, y)) || explodingFarmer is null) | ||
return; | ||
foreach(var layer in __instance.map.Layers) | ||
{ | ||
var tile = layer.Tiles[(int)x, (int)y]; | ||
if (tile is null) | ||
continue; | ||
if (tile.Properties.TryGetValue(explodeKey, out PropertyValue mail)) | ||
{ | ||
if (!string.IsNullOrEmpty(mail) && !explodingFarmer.mailReceived.Contains(mail)) | ||
{ | ||
explodingFarmer.mailReceived.Add(mail); | ||
} | ||
TriggerActions(new List<Layer>() { tile.Layer }, explodingFarmer, new Point((int)x, (int)y), new List<string>() { "Explode" }); | ||
layer.Tiles[(int)x, (int)y] = null; | ||
} | ||
} | ||
} | ||
} | ||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.isCollidingPosition), new Type[] { typeof(Rectangle), typeof(xTile.Dimensions.Rectangle), typeof(bool), typeof(int), typeof(bool), typeof(Character) })] | ||
public class GameLocation_isCollidingPosition_Patch | ||
{ | ||
public static bool Prefix(GameLocation __instance, Rectangle position, ref bool __result) | ||
{ | ||
if (!Config.ModEnabled || !pushingDict.TryGetValue(__instance.Name, out List<PushedTile> tiles)) | ||
return true; | ||
foreach (var tile in tiles) | ||
{ | ||
Rectangle tileRect = new Rectangle(tile.position, new Point(64, 64)); | ||
if (position.Intersects(tileRect)) | ||
{ | ||
__result = true; | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.draw))] | ||
public class GameLocation_draw_Patch | ||
{ | ||
public static void Postfix(GameLocation __instance, SpriteBatch b) | ||
{ | ||
if (!Config.ModEnabled || !pushingDict.TryGetValue(__instance.Name, out List<PushedTile> tiles)) | ||
return; | ||
foreach(var tile in tiles) | ||
{ | ||
Game1.mapDisplayDevice.DrawTile(tile.tile, new Location(tile.position.X - Game1.viewport.X, tile.position.Y - Game1.viewport.Y), (float)(tile.position.Y + 64 + (tile.tile.Layer.Id.Contains("Front") ? 16 : 0)) / 10000f); | ||
} | ||
} | ||
} | ||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.performToolAction))] | ||
public class GameLocation_performToolAction_Patch | ||
{ | ||
public static bool Prefix(GameLocation __instance, Tool t, int tileX, int tileY, ref bool __result) | ||
{ | ||
if (!Config.ModEnabled || !__instance.isTileOnMap(new Vector2(tileX, tileY))) | ||
return true; | ||
|
||
if(TriggerActions(__instance.Map.Layers.ToList(), t.getLastFarmerToUse(), new Point(tileX, tileY), new List<string>() { t.GetType().Name, t.Name })) | ||
{ | ||
__result = true; | ||
return false; | ||
} | ||
return true; | ||
} | ||
} | ||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.checkAction))] | ||
public class GameLocation_checkAction_Patch | ||
{ | ||
public static bool Prefix(GameLocation __instance, Location tileLocation, xTile.Dimensions.Rectangle viewport, Farmer who, ref bool __result) | ||
{ | ||
if (!Config.ModEnabled || !__instance.isTileOnMap(new Vector2(tileLocation.X, tileLocation.Y))) | ||
return true; | ||
if ((who.ActiveObject is not null && TriggerActions(__instance.Map.Layers.ToList(), who, new Point(tileLocation.X, tileLocation.Y), new List<string>() { "Object" + who.ActiveObject.Name, "Object" + who.ActiveObject.ParentSheetIndex })) || TriggerActions(__instance.Map.Layers.ToList(), who, new Point(tileLocation.X, tileLocation.Y), new List<string>() { "Action" })) | ||
{ | ||
__result = true; | ||
return false; | ||
} | ||
return true; | ||
} | ||
} | ||
[HarmonyPatch(typeof(Farmer), nameof(Farmer.getMovementSpeed))] | ||
public class Farmer_getMovementSpeed_Patch | ||
{ | ||
public static void Postfix(Farmer __instance, ref float __result) | ||
{ | ||
if (!Config.ModEnabled) | ||
return; | ||
var tileLoc = __instance.getTileLocation(); | ||
if (__instance.currentLocation.isTileOnMap(tileLoc)) | ||
{ | ||
var tile = __instance.currentLocation.Map.GetLayer("Back").Tiles[(int)tileLoc.X, (int)tileLoc.Y]; | ||
if (tile is not null && tile.Properties.TryGetValue(speedKey, out PropertyValue value) && float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out float mult)) | ||
{ | ||
__result *= mult; | ||
} | ||
} | ||
} | ||
} | ||
[HarmonyPatch(typeof(Farmer), nameof(Farmer.MovePosition))] | ||
public class Farmer_MovePosition_Patch | ||
{ | ||
public static void Prefix(Farmer __instance, ref Vector2[] __state) | ||
{ | ||
if (!Config.ModEnabled) | ||
return; | ||
var tileLoc = __instance.getTileLocation(); | ||
if (__instance.currentLocation.isTileOnMap(tileLoc)) | ||
{ | ||
var tile = __instance.currentLocation.Map.GetLayer("Back").Tiles[(int)tileLoc.X, (int)tileLoc.Y]; | ||
if(tile is not null && tile.Properties.TryGetValue(moveKey, out PropertyValue value)) | ||
{ | ||
var split = value.ToString().Split(' '); | ||
__instance.xVelocity = float.Parse(split[0], NumberStyles.Any, CultureInfo.InvariantCulture); | ||
__instance.yVelocity = float.Parse(split[1], NumberStyles.Any, CultureInfo.InvariantCulture); | ||
} | ||
} | ||
|
||
__state = new Vector2[] { __instance.Position, tileLoc }; | ||
} | ||
public static void Postfix(Farmer __instance, Vector2[] __state) | ||
{ | ||
if (!Config.ModEnabled || __state is null) | ||
return; | ||
var tilePos = __instance.getTileLocationPoint(); | ||
var oldTile = Utility.Vector2ToPoint(__state[1]); | ||
if(oldTile != tilePos) | ||
{ | ||
DoStepOffActions(__instance, oldTile); | ||
DoStepOnActions(__instance, tilePos); | ||
} | ||
|
||
if (__instance.currentLocation.isTileOnMap(tilePos.ToVector2()) && __instance.currentLocation.isTileOnMap(tilePos.ToVector2())) | ||
{ | ||
var backTile = __instance.currentLocation.Map.GetLayer("Back").Tiles[tilePos.X, tilePos.Y]; | ||
var backOldTile = __instance.currentLocation.Map.GetLayer("Back").Tiles[oldTile.X, oldTile.Y]; | ||
if (backTile != null && backTile.Properties.TryGetValue(slipperyKey, out PropertyValue value) && float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out float amount)) | ||
{ | ||
if (__instance.movementDirections.Contains(0)) | ||
__instance.yVelocity += amount; | ||
if (__instance.movementDirections.Contains(1)) | ||
__instance.xVelocity += amount; | ||
if (__instance.movementDirections.Contains(2)) | ||
__instance.yVelocity -= amount; | ||
if (__instance.movementDirections.Contains(3)) | ||
__instance.xVelocity -= amount; | ||
} | ||
else if (backOldTile != null && backOldTile.Properties.TryGetValue(slipperyKey, out value) && float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out amount)) | ||
{ | ||
__instance.xVelocity = 0; | ||
__instance.yVelocity = 0; | ||
} | ||
} | ||
|
||
if (__instance.movementDirections.Any() && __state[0] == __instance.Position) | ||
{ | ||
var startTile = new Point(__instance.GetBoundingBox().Center.X / 64, __instance.GetBoundingBox().Center.Y / 64); | ||
startTile += GetNextTile(__instance.FacingDirection); | ||
Point start = new Point(startTile.X * 64, startTile.Y * 64); | ||
var startLoc = new Location(start.X, start.Y); | ||
|
||
var build = __instance.currentLocation.Map.GetLayer("Buildings"); | ||
var tile = build.PickTile(startLoc, Game1.viewport.Size); | ||
|
||
if (tile is not null && tile.Properties.TryGetValue(pushKey, out PropertyValue tiles)) | ||
{ | ||
var destTile = startTile + GetNextTile(__instance.FacingDirection); | ||
foreach (var item in tiles.ToString().Split(',')) | ||
{ | ||
var split = item.Split(' '); | ||
if (split.Length == 2 && int.TryParse(split[0], out int x) && int.TryParse(split[1], out int y) && destTile.X == x && destTile.Y == y) | ||
{ | ||
PushTileWithOthers(__instance, tile, startTile); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using Microsoft.Xna.Framework; | ||
using StardewValley; | ||
using System.Collections.Generic; | ||
using xTile.Layers; | ||
|
||
namespace DynamicMapTiles | ||
{ | ||
public interface IDynamicMapTilesApi | ||
{ | ||
public bool TriggerActions(List<Layer> layers, Farmer farmer, Point tilePos, List<string> suffixes); | ||
} | ||
public class DynamicMapTilesApi : IDynamicMapTilesApi | ||
{ | ||
public bool TriggerActions(List<Layer> layers, Farmer farmer, Point tilePos, List<string> suffixes) | ||
{ | ||
return ModEntry.TriggerActions(layers, farmer, tilePos, suffixes); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.Xna.Framework; | ||
using System.Collections.Generic; | ||
|
||
namespace DynamicMapTiles | ||
{ | ||
public class DynamicTileInfo | ||
{ | ||
public List<string> locations; | ||
public List<string> layers; | ||
public List<string> tileSheets; | ||
public List<int> indexes; | ||
public List<Rectangle> rectangles; | ||
public Dictionary<string, string> properties; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.Xna.Framework; | ||
using StardewValley; | ||
using StardewValley.Objects; | ||
using System.Collections.Generic; | ||
|
||
namespace DynamicMapTiles | ||
{ | ||
public interface IAdvancedLootFrameworkApi | ||
{ | ||
List<object> LoadPossibleTreasures(string[] itemTypeList, int minItemValue, int maxItemValue); | ||
List<Item> GetChestItems(List<object> treasures, Dictionary<string, int> itemChances, int maxItems, int minItemValue, int maxItemValue, int mult, float increaseRate, int baseValue); | ||
int GetChestCoins(int mult, float increaseRate, int baseMin, int baseMax); | ||
Chest MakeChest(List<Item> chestItems, int coins, Vector2 chestSpot); | ||
Chest MakeChest(List<object> treasures, Dictionary<string, int> itemChances, int maxItems, int minItemValue, int maxItemValue, int mult, float increaseRate, int itemBaseValue, int coinBaseMin, int coinBaseMax, Vector2 chestSpot); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
using System; | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using StardewModdingAPI; | ||
using StardewModdingAPI.Utilities; | ||
using StardewValley; | ||
|
||
namespace DynamicMapTiles | ||
{ | ||
/// <summary>The API which lets other mods add a config UI through Generic Mod Config Menu.</summary> | ||
public interface IGenericModConfigMenuApi | ||
{ | ||
/********* | ||
** Methods | ||
*********/ | ||
/**** | ||
** Must be called first | ||
****/ | ||
/// <summary>Register a mod whose config can be edited through the UI.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="reset">Reset the mod's config to its default values.</param> | ||
/// <param name="save">Save the mod's current config to the <c>config.json</c> file.</param> | ||
/// <param name="titleScreenOnly">Whether the options can only be edited from the title screen.</param> | ||
/// <remarks>Each mod can only be registered once, unless it's deleted via <see cref="Unregister"/> before calling this again.</remarks> | ||
void Register(IManifest mod, Action reset, Action save, bool titleScreenOnly = false); | ||
|
||
/// <summary>Add a key binding at the current position in the form.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="getValue">Get the current value from the mod config.</param> | ||
/// <param name="setValue">Set a new value in the mod config.</param> | ||
/// <param name="name">The label text to show in the form.</param> | ||
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the field, or <c>null</c> to disable the tooltip.</param> | ||
/// <param name="fieldId">The unique field ID for use with <see cref="OnFieldChanged"/>, or <c>null</c> to auto-generate a randomized ID.</param> | ||
void AddKeybind(IManifest mod, Func<SButton> getValue, Action<SButton> setValue, Func<string> name, Func<string> tooltip = null, string fieldId = null); | ||
|
||
/// <summary>Add a boolean option at the current position in the form.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="getValue">Get the current value from the mod config.</param> | ||
/// <param name="setValue">Set a new value in the mod config.</param> | ||
/// <param name="name">The label text to show in the form.</param> | ||
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the field, or <c>null</c> to disable the tooltip.</param> | ||
/// <param name="fieldId">The unique field ID for use with <see cref="OnFieldChanged"/>, or <c>null</c> to auto-generate a randomized ID.</param> | ||
void AddBoolOption(IManifest mod, Func<bool> getValue, Action<bool> setValue, Func<string> name, Func<string> tooltip = null, string fieldId = null); | ||
|
||
/// <summary>Add an integer option at the current position in the form.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="getValue">Get the current value from the mod config.</param> | ||
/// <param name="setValue">Set a new value in the mod config.</param> | ||
/// <param name="name">The label text to show in the form.</param> | ||
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the field, or <c>null</c> to disable the tooltip.</param> | ||
/// <param name="min">The minimum allowed value, or <c>null</c> to allow any.</param> | ||
/// <param name="max">The maximum allowed value, or <c>null</c> to allow any.</param> | ||
/// <param name="interval">The interval of values that can be selected.</param> | ||
/// <param name="fieldId">The unique field ID for use with <see cref="OnFieldChanged"/>, or <c>null</c> to auto-generate a randomized ID.</param> | ||
void AddNumberOption(IManifest mod, Func<int> getValue, Action<int> setValue, Func<string> name, Func<string> tooltip = null, int? min = null, int? max = null, int? interval = null, string fieldId = null); | ||
|
||
/// <summary>Add a string option at the current position in the form.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="getValue">Get the current value from the mod config.</param> | ||
/// <param name="setValue">Set a new value in the mod config.</param> | ||
/// <param name="name">The label text to show in the form.</param> | ||
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the field, or <c>null</c> to disable the tooltip.</param> | ||
/// <param name="allowedValues">The values that can be selected, or <c>null</c> to allow any.</param> | ||
/// <param name="formatAllowedValue">Get the display text to show for a value from <paramref name="allowedValues"/>, or <c>null</c> to show the values as-is.</param> | ||
/// <param name="fieldId">The unique field ID for use with <see cref="OnFieldChanged"/>, or <c>null</c> to auto-generate a randomized ID.</param> | ||
void AddTextOption(IManifest mod, Func<string> getValue, Action<string> setValue, Func<string> name, Func<string> tooltip = null, string[] allowedValues = null, Func<string, string> formatAllowedValue = null, string fieldId = null); | ||
|
||
/// <summary>Remove a mod from the config UI and delete all its options and pages.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
void Unregister(IManifest mod); | ||
} | ||
} |
Oops, something went wrong.