Skip to content

Commit

Permalink
etc
Browse files Browse the repository at this point in the history
  • Loading branch information
aedenthorn committed Dec 6, 2022
1 parent e67e9f0 commit 6456791
Show file tree
Hide file tree
Showing 30 changed files with 1,855 additions and 77 deletions.
38 changes: 38 additions & 0 deletions BatchMapProperties/BatchMapProperties.csproj
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>
220 changes: 220 additions & 0 deletions BatchMapProperties/CodePatches.cs
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;
}
}
}
}
}
}
}
}
19 changes: 19 additions & 0 deletions BatchMapProperties/DynamicMapTilesApi.cs
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);
}
}
}
15 changes: 15 additions & 0 deletions BatchMapProperties/DynamicTileInfo.cs
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;
}
}
16 changes: 16 additions & 0 deletions BatchMapProperties/IAdvancedLootFrameworkApi.cs
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);
}
}
72 changes: 72 additions & 0 deletions BatchMapProperties/IGenericModConfigMenuApi.cs
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);
}
}
Loading

0 comments on commit 6456791

Please sign in to comment.