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
c2135f5
commit bdff321
Showing
27 changed files
with
1,561 additions
and
1 deletion.
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,120 @@ | ||
using HarmonyLib; | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using Netcode; | ||
using StardewValley; | ||
using StardewValley.Tools; | ||
using System; | ||
using Object = StardewValley.Object; | ||
|
||
namespace CustomSigns | ||
{ | ||
public partial class ModEntry | ||
{ | ||
private static Object placedSign; | ||
|
||
[HarmonyPatch(typeof(GameLocation), nameof(GameLocation.isCollidingPosition), new Type[] { typeof(Rectangle), typeof(xTile.Dimensions.Rectangle), typeof(bool), typeof(int), typeof(bool), typeof(Character), typeof(bool), typeof(bool), typeof(bool) })] | ||
public class isCollidingPosition_Patch | ||
{ | ||
public static bool Prefix(GameLocation __instance, Rectangle position, xTile.Dimensions.Rectangle viewport, bool isFarmer, int damagesFarmer, bool glider, Character character, bool pathfinding, bool projectile, bool ignoreCharacterRequirement, ref bool __result) | ||
{ | ||
if (!Config.EnableMod) | ||
return true; | ||
foreach(var obj in __instance.objects.Values) | ||
{ | ||
if (!customSignTypeDict.ContainsKey(obj.Name) || !obj.modData.ContainsKey(templateKey)) | ||
continue; | ||
if(obj.getBoundingBox(obj.TileLocation).Intersects(position)) | ||
{ | ||
__result = true; | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
[HarmonyPatch(typeof(Object), nameof(Object.placementAction))] | ||
public class placementAction_Patch | ||
{ | ||
public static void Postfix(Object __instance, GameLocation location, int x, int y, bool __result) | ||
{ | ||
if (!Config.EnableMod || !__result || !SHelper.Input.IsDown(Config.ModKey) || !customSignTypeDict.ContainsKey(__instance.Name)) | ||
return; | ||
Vector2 placementTile = new Vector2(x / 64, y / 64); | ||
if (!location.objects.TryGetValue(placementTile, out Object obj)) | ||
return; | ||
placedSign = obj; | ||
ReloadSignData(); | ||
OpenPlacementDialogue(); | ||
} | ||
} | ||
[HarmonyPatch(typeof(Object), nameof(Object.getBoundingBox))] | ||
public class getBoundingBox_Patch | ||
{ | ||
public static void Postfix(Object __instance, Vector2 tileLocation, ref Rectangle __result, NetRectangle ___boundingBox) | ||
{ | ||
if (!Config.EnableMod || !customSignTypeDict.ContainsKey(__instance.Name) || !__instance.modData.TryGetValue(templateKey, out string template) || !customSignDataDict.TryGetValue(template, out CustomSignData data)) | ||
return; | ||
var x = Environment.StackTrace; | ||
__result = new Rectangle((int)tileLocation.X * 64 + 32 / 2 - data.tileWidth * 64 / 2, (int)tileLocation.Y * 64 + 64 - data.tileHeight * 64, data.tileWidth * 64, data.tileHeight * 64); | ||
___boundingBox.Set(__result); | ||
} | ||
} | ||
[HarmonyPatch(typeof(Pickaxe), nameof(Pickaxe.DoFunction))] | ||
public class Pickaxe_DoFunction_Patch | ||
{ | ||
public static void Postfix(Pickaxe __instance, GameLocation location, int x, int y, int power, Farmer who) | ||
{ | ||
if (!Config.EnableMod) | ||
return; | ||
foreach(var kvp in location.objects.Pairs) | ||
{ | ||
if(kvp.Value.boundingBox.Value.Contains(x, y) && customSignTypeDict.ContainsKey(kvp.Value.Name) && kvp.Value.modData.TryGetValue(templateKey, out string template) && customSignDataDict.ContainsKey(template)) | ||
{ | ||
if (kvp.Value.performToolAction(__instance, location)) | ||
{ | ||
kvp.Value.performRemoveAction(kvp.Key, location); | ||
Game1.currentLocation.debris.Add(new Debris(kvp.Value.bigCraftable.Value ? (-kvp.Value.ParentSheetIndex) : kvp.Value.ParentSheetIndex, who.GetToolLocation(false), new Vector2(who.GetBoundingBox().Center.X, who.GetBoundingBox().Center.Y))); | ||
Game1.currentLocation.Objects.Remove(kvp.Key); | ||
return; | ||
} | ||
|
||
} | ||
} | ||
} | ||
} | ||
[HarmonyPatch(typeof(Object), nameof(Object.draw), new Type[] { typeof(SpriteBatch), typeof(int), typeof(int), typeof(float) })] | ||
public class draw_Patch | ||
{ | ||
|
||
public static bool Prefix(Object __instance, SpriteBatch spriteBatch, int x, int y, float alpha) | ||
{ | ||
if (!Config.EnableMod || __instance.isTemporarilyInvisible || !__instance.bigCraftable.Value || !customSignTypeDict.ContainsKey(__instance.Name) || !__instance.modData.TryGetValue(templateKey, out string template) || !customSignDataDict.TryGetValue(template, out CustomSignData data) || data.texture == null) | ||
return true; | ||
Vector2 position = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64 + 32, y * 64 + 64)) - new Vector2(data.texture.Width / 2, data.texture.Height) * data.scale; | ||
float draw_layer = Math.Max(0f, ((y + 1) * 64 - 24) / 10000f) + x * 1E-05f; | ||
spriteBatch.Draw(data.texture, position, null, Color.White * alpha, 0f, Vector2.Zero, data.scale, SpriteEffects.None, draw_layer); | ||
if(data.text != null) | ||
{ | ||
for(int i = 0; i < data.text.Length; i++) | ||
{ | ||
var text = data.text[i]; | ||
if (!fontDict.ContainsKey(text.fontPath)) | ||
continue; | ||
Vector2 pos; | ||
if (text.center) | ||
{ | ||
pos = new Vector2(position.X + text.X - fontDict[text.fontPath].MeasureString(text.text).X / 2 * text.scale, position.Y + text.Y); | ||
} | ||
else | ||
{ | ||
pos = new Vector2(position.X + text.X, position.Y + text.Y); | ||
} | ||
spriteBatch.DrawString(fontDict[text.fontPath], text.text, pos, text.color, 0, Vector2.Zero, text.scale, SpriteEffects.None, draw_layer + 1 / 10000f * (i+1)); | ||
} | ||
} | ||
return false; | ||
} | ||
} | ||
} | ||
} |
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,30 @@ | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
|
||
namespace CustomSigns | ||
{ | ||
public class CustomSignData | ||
{ | ||
public string texturePath; | ||
public string packID; | ||
public int tileWidth; | ||
public int tileHeight; | ||
public int heldObjectX; | ||
public int heldObjectY; | ||
public float scale = 4; | ||
public string[] types; | ||
public SignText[] text; | ||
public Texture2D texture; | ||
} | ||
|
||
public class SignText | ||
{ | ||
public string text; | ||
public int X; | ||
public int Y; | ||
public bool center = true; | ||
public string fontPath; | ||
public float scale; | ||
public Color color = Color.White; | ||
} | ||
} |
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,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<Version>1.0.0</Version> | ||
<TargetFramework>net5.0</TargetFramework> | ||
<EnableHarmony>true</EnableHarmony> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<None Remove="i18n\default.json" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Content Include="i18n\default.json"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</Content> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="4.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="manifest.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</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,75 @@ | ||
using StardewModdingAPI; | ||
using System; | ||
|
||
namespace CustomSigns | ||
{ | ||
/// <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 section title at the current position in the form.</summary> | ||
/// <param name="mod">The mod's manifest.</param> | ||
/// <param name="text">The title text shown in the form.</param> | ||
/// <param name="tooltip">The tooltip text shown when the cursor hovers on the title, or <c>null</c> to disable the tooltip.</param> | ||
void AddSectionTitle(IManifest mod, Func<string> text, Func<string> tooltip = null); | ||
|
||
/// <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); | ||
} | ||
} |
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,71 @@ | ||
using HarmonyLib; | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using Microsoft.Xna.Framework.Input; | ||
using StardewModdingAPI; | ||
using StardewValley; | ||
using StardewValley.Menus; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Rectangle = Microsoft.Xna.Framework.Rectangle; | ||
|
||
namespace CustomSigns | ||
{ | ||
public partial class ModEntry : Mod | ||
{ | ||
public static void OpenPlacementDialogue() | ||
{ | ||
if (customSignDataDict.Count == 0) | ||
{ | ||
SMonitor.Log("No custom sign templates.", LogLevel.Warn); | ||
return; | ||
} | ||
|
||
List<Response> responses = new List<Response>(); | ||
foreach(var key in customSignDataDict.Keys) | ||
{ | ||
responses.Add(new Response(key, key)); | ||
} | ||
responses.Add(new Response("cancel", SHelper.Translation.Get("cancel"))); | ||
Game1.player.currentLocation.createQuestionDialogue(SHelper.Translation.Get("which-template"), responses.ToArray(), "CS_Choose_Template"); | ||
} | ||
|
||
private static void ReloadSignData() | ||
{ | ||
customSignDataDict.Clear(); | ||
customSignTypeDict.Clear(); | ||
fontDict.Clear(); | ||
var dict = SHelper.Content.Load<Dictionary<string, CustomSignData>>(dictPath, ContentSource.GameContent); | ||
if (dict == null) | ||
{ | ||
SMonitor.Log($"No custom signs found", LogLevel.Debug); | ||
return; | ||
} | ||
foreach (var kvp in dict) | ||
{ | ||
CustomSignData data = kvp.Value; | ||
foreach (string type in data.types) | ||
{ | ||
if (!customSignTypeDict.ContainsKey(type)) | ||
{ | ||
customSignTypeDict.Add(type, new List<string>() { type }); | ||
} | ||
else | ||
{ | ||
customSignTypeDict[type].Add(type); | ||
} | ||
} | ||
if (data.packID != null && !loadedContentPacks.Contains(data.packID)) | ||
loadedContentPacks.Add(data.packID); | ||
data.texture = SHelper.Content.Load<Texture2D>(data.texturePath, ContentSource.GameContent); | ||
foreach(var text in data.text) | ||
{ | ||
if (!fontDict.ContainsKey(text.fontPath)) | ||
fontDict.Add(text.fontPath, Game1.content.Load<SpriteFont>(text.fontPath)); | ||
} | ||
} | ||
customSignDataDict = dict; | ||
} | ||
} | ||
} |
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,12 @@ | ||
| ||
using StardewModdingAPI; | ||
|
||
namespace CustomSigns | ||
{ | ||
public class ModConfig | ||
{ | ||
public bool EnableMod { get; set; } = true; | ||
public SButton ModKey { get; set; } = SButton.LeftShift; | ||
public SButton ResetKey { get; set; } = SButton.F5; | ||
} | ||
} |
Oops, something went wrong.