├── .editorconfig ├── .gitattributes ├── .gitignore ├── BetterRNG ├── BetterRNG.csproj ├── Framework │ ├── Extensions.cs │ ├── IWeighted.cs │ ├── MersenneTwister.cs │ ├── ModConfig.cs │ ├── Weighted.cs │ └── WeightedGeneric.cs ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── CalendarAnywhere ├── CalendarAnywhere.csproj ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── Directory.Build.props ├── Directory.Packages.props ├── DurableFences ├── DurableFences.csproj ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── FishingMod ├── FishingMod.csproj ├── Framework │ └── ModConfig.cs ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── HealthBars ├── Framework │ └── ModConfig.cs ├── HealthBars.csproj ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── JunimoDepositAnywhere ├── JunimoDepositAnywhere.csproj ├── ModEntry.cs ├── README.md ├── manifest.json └── release-notes.md ├── MovementMod ├── Framework │ └── ModConfig.cs ├── ModEntry.cs ├── MovementMod.csproj ├── README.md ├── manifest.json └── release-notes.md ├── README.md ├── RegenMod ├── Framework │ └── ModConfig.cs ├── ModEntry.cs ├── README.md ├── RegenMod.csproj ├── manifest.json └── release-notes.md ├── Zoryn.Mods.sln ├── Zoryn.Mods.sln.DotSettings └── _Common ├── CommonHelper.cs ├── _Common.projitems └── _Common.shproj /.editorconfig: -------------------------------------------------------------------------------- 1 | # topmost editorconfig 2 | root: true 3 | 4 | ########## 5 | ## General formatting 6 | ## documentation: https://editorconfig.org 7 | ########## 8 | [*] 9 | indent_style = space 10 | indent_size = 4 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | charset = utf-8 14 | 15 | [*.{csproj,nuspec,props,targets}] 16 | indent_size = 2 17 | 18 | [*.csproj] 19 | charset = utf-8-bom 20 | insert_final_newline = false 21 | 22 | [*.{json,md}] 23 | charset = utf-8-bom 24 | 25 | 26 | ########## 27 | ## C# formatting 28 | ## documentation: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference 29 | ########## 30 | [*.cs] 31 | 32 | # sort 'system' usings first 33 | dotnet_sort_system_directives_first = true 34 | 35 | # use 'this.' qualifier 36 | dotnet_style_qualification_for_field = true:error 37 | dotnet_style_qualification_for_property = true:error 38 | dotnet_style_qualification_for_method = true:error 39 | dotnet_style_qualification_for_event = true:error 40 | 41 | # use language keywords (like int) instead of type (like Int32) 42 | dotnet_style_predefined_type_for_locals_parameters_members = true:error 43 | dotnet_style_predefined_type_for_member_access = true:error 44 | 45 | # don't use 'var' for language keywords 46 | csharp_style_var_for_built_in_types = false:error 47 | 48 | # suggest modern C# features where simpler 49 | dotnet_style_object_initializer = true:suggestion 50 | dotnet_style_collection_initializer = true:suggestion 51 | dotnet_style_coalesce_expression = true:suggestion 52 | dotnet_style_null_propagation = true:suggestion 53 | dotnet_style_explicit_tuple_names = true:suggestion 54 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 55 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 56 | csharp_style_conditional_delegate_call = true:suggestion 57 | csharp_prefer_simple_default_expression = true:suggestion 58 | 59 | # prefer method block bodies 60 | csharp_style_expression_bodied_methods = false:suggestion 61 | csharp_style_expression_bodied_constructors = false:suggestion 62 | 63 | # prefer property expression bodies 64 | csharp_style_expression_bodied_properties = true:suggestion 65 | csharp_style_expression_bodied_indexers = true:suggestion 66 | csharp_style_expression_bodied_accessors = true:suggestion 67 | 68 | # prefer inline out variables 69 | csharp_style_inlined_variable_declaration = true:warning 70 | 71 | # avoid superfluous braces 72 | csharp_prefer_braces = false:hint 73 | 74 | # apply .NET naming conventions 75 | dotnet_naming_style.pascal_case_style.capitalization=pascal_case 76 | dotnet_naming_symbols.pascal_types.applicable_kinds=namespace, class, struct, interface, enum, property, method, field, event, delegate, type_parameter, local_function 77 | dotnet_naming_symbols.pascal_types.applicable_accessibilities=* 78 | dotnet_naming_rule.most_identifiers_should_be_pascal_case.symbols=pascal_types 79 | dotnet_naming_rule.most_identifiers_should_be_pascal_case.style=pascal_case_style 80 | dotnet_naming_rule.most_identifiers_should_be_pascal_case.severity=suggestion 81 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # always normalise line endings 2 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # user-specific files 2 | *.suo 3 | *.user 4 | *.userosscache 5 | *.sln.docstates 6 | 7 | # build results 8 | [Dd]ebug/ 9 | [Rr]elease/ 10 | [Bb]in/ 11 | [Oo]bj/ 12 | _releases/ 13 | 14 | # Visual Studio cache/options 15 | .vs/ 16 | 17 | # ReSharper 18 | _ReSharper*/ 19 | *.[Rr]e[Ss]harper 20 | *.DotSettings.user 21 | 22 | # NuGet packages 23 | *.nupkg 24 | **/packages/* 25 | *.nuget.props 26 | *.nuget.targets -------------------------------------------------------------------------------- /BetterRNG/BetterRNG.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BetterRNG/Framework/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace BetterRNG.Framework; 6 | 7 | internal static class Extensions 8 | { 9 | public static T Random(this IEnumerable enumerable) 10 | { 11 | if (enumerable == null) 12 | { 13 | throw new ArgumentNullException(nameof(enumerable)); 14 | } 15 | 16 | var list = enumerable as IList ?? enumerable.ToList(); 17 | return list.Count == 0 ? default : list[ModEntry.Twister.Next(0, list.Count)]; 18 | } 19 | 20 | public static T Choose(this T[] list) where T : IWeighted 21 | { 22 | return Weighted.Choose(list); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /BetterRNG/Framework/IWeighted.cs: -------------------------------------------------------------------------------- 1 | namespace BetterRNG.Framework; 2 | 3 | internal interface IWeighted 4 | { 5 | int Weight { get; set; } 6 | object Value { get; set; } 7 | } 8 | -------------------------------------------------------------------------------- /BetterRNG/Framework/MersenneTwister.cs: -------------------------------------------------------------------------------- 1 | //https://github.com/tucano/UnityMersenneTwister/blob/master/Assets/Scripts/UnityMersenneTwister.cs 2 | 3 | using System; 4 | 5 | namespace BetterRNG.Framework; 6 | 7 | internal class MersenneTwister : Random 8 | { 9 | /// 10 | /// Creates a new pseudo-random number generator with a given seed. 11 | /// 12 | /// A value to use as a seed. 13 | public MersenneTwister(int seed) 14 | { 15 | this.init((uint)seed); 16 | } 17 | 18 | /// 19 | /// Creates a new pseudo-random number generator with a default seed. 20 | /// 21 | /// 22 | /// new (). 23 | /// is used for the seed. 24 | /// 25 | public MersenneTwister() : this(new Random().Next(int.MinValue, int.MaxValue)) /* a default initial seed is used */ 26 | { 27 | } 28 | 29 | /// 30 | /// Creates a pseudo-random number generator initialized with the given array. 31 | /// 32 | /// The array for initializing keys. 33 | public MersenneTwister(int[] initKey) 34 | { 35 | if (initKey == null) 36 | { 37 | throw new ArgumentNullException("initKey"); 38 | } 39 | 40 | uint[] initArray = new uint[initKey.Length]; 41 | 42 | for (int i = 0; i < initKey.Length; ++i) 43 | { 44 | initArray[i] = (uint)initKey[i]; 45 | } 46 | 47 | this.init(initArray); 48 | } 49 | 50 | /// 51 | /// Returns the next pseudo-random . 52 | /// 53 | /// A pseudo-random value. 54 | public virtual uint NextUInt32() 55 | { 56 | return this.GenerateUInt32(); 57 | } 58 | 59 | /// 60 | /// Returns the next pseudo-random 61 | /// up to . 62 | /// 63 | /// 64 | /// The maximum value of the pseudo-random number to create. 65 | /// 66 | /// 67 | /// A pseudo-random value which is at most . 68 | /// 69 | public virtual uint NextUInt32(uint maxValue) 70 | { 71 | return (uint)(this.GenerateUInt32() / ((double)uint.MaxValue / maxValue)); 72 | } 73 | 74 | /// 75 | /// Returns the next pseudo-random at least 76 | /// and up to . 77 | /// 78 | /// The minimum value of the pseudo-random number to create. 79 | /// The maximum value of the pseudo-random number to create. 80 | /// 81 | /// A pseudo-random value which is at least 82 | /// and at most . 83 | /// 84 | /// 85 | /// If >= . 86 | /// 87 | public virtual uint NextUInt32(uint minValue, uint maxValue) /* throws ArgumentOutOfRangeException */ 88 | { 89 | if (minValue >= maxValue) 90 | { 91 | throw new ArgumentOutOfRangeException(); 92 | } 93 | 94 | return (uint)(this.GenerateUInt32() / ((double)uint.MaxValue / (maxValue - minValue)) + minValue); 95 | } 96 | 97 | /// 98 | /// Returns the next pseudo-random . 99 | /// 100 | /// A pseudo-random value. 101 | public override int Next() 102 | { 103 | return this.Next(int.MaxValue); 104 | } 105 | 106 | /// 107 | /// Returns the next pseudo-random up to . 108 | /// 109 | /// The maximum value of the pseudo-random number to create. 110 | /// 111 | /// A pseudo-random value which is at most . 112 | /// 113 | /// 114 | /// When < 0. 115 | /// 116 | public override int Next(int maxValue) 117 | { 118 | if (maxValue <= 1) 119 | { 120 | if (maxValue < 0) 121 | { 122 | throw new ArgumentOutOfRangeException(); 123 | } 124 | 125 | return 0; 126 | } 127 | 128 | return (int)(this.NextDouble() * maxValue); 129 | } 130 | 131 | /// 132 | /// Returns the next pseudo-random 133 | /// at least 134 | /// and up to . 135 | /// 136 | /// The minimum value of the pseudo-random number to create. 137 | /// The maximum value of the pseudo-random number to create. 138 | /// A pseudo-random Int32 value which is at least and at 139 | /// most . 140 | /// 141 | /// If >= . 142 | /// 143 | public override int Next(int minValue, int maxValue) 144 | { 145 | if (maxValue < minValue) 146 | { 147 | throw new ArgumentOutOfRangeException(); 148 | } 149 | 150 | if (maxValue == minValue) 151 | { 152 | return minValue; 153 | } 154 | 155 | return this.Next(maxValue - minValue) + minValue; 156 | } 157 | 158 | /// 159 | /// Fills a buffer with pseudo-random bytes. 160 | /// 161 | /// The buffer to fill. 162 | /// 163 | /// If == . 164 | /// 165 | public override void NextBytes(byte[] buffer) 166 | { 167 | // [codekaizen: corrected this to check null before checking length.] 168 | if (buffer == null) 169 | { 170 | throw new ArgumentNullException(); 171 | } 172 | 173 | int bufLen = buffer.Length; 174 | 175 | for (int idx = 0; idx < bufLen; ++idx) 176 | { 177 | buffer[idx] = (byte)this.Next(256); 178 | } 179 | } 180 | 181 | /// 182 | /// Returns the next pseudo-random value. 183 | /// 184 | /// A pseudo-random double floating point value. 185 | /// 186 | /// 187 | /// There are two common ways to create a double floating point using MT19937: 188 | /// using and dividing by 0xFFFFFFFF + 1, 189 | /// or else generating two double words and shifting the first by 26 bits and 190 | /// adding the second. 191 | /// 192 | /// 193 | /// In a newer measurement of the randomness of MT19937 published in the 194 | /// journal "Monte Carlo Methods and Applications, Vol. 12, No. 5-6, pp. 385 ñ 393 (2006)" 195 | /// entitled "A Repetition Test for Pseudo-Random Number Generators", 196 | /// it was found that the 32-bit version of generating a double fails at the 95% 197 | /// confidence level when measuring for expected repetitions of a particular 198 | /// number in a sequence of numbers generated by the algorithm. 199 | /// 200 | /// 201 | /// Due to this, the 53-bit method is implemented here and the 32-bit method 202 | /// of generating a double is not. If, for some reason, 203 | /// the 32-bit method is needed, it can be generated by the following: 204 | /// 205 | /// (Double)NextUInt32() / ((UInt64)UInt32.MaxValue + 1); 206 | /// 207 | /// 208 | /// 209 | public override double NextDouble() 210 | { 211 | return this.compute53BitRandom(0, MersenneTwister.InverseOnePlus53BitsOf1s); 212 | } 213 | 214 | /// 215 | /// Returns a pseudo-random number greater than or equal to zero, and 216 | /// either strictly less than one, or less than or equal to one, 217 | /// depending on the value of the given parameter. 218 | /// 219 | /// 220 | /// If , the pseudo-random number returned will be 221 | /// less than or equal to one; otherwise, the pseudo-random number returned will 222 | /// be strictly less than one. 223 | /// 224 | /// 225 | /// If is , 226 | /// this method returns a double-precision pseudo-random number greater than 227 | /// or equal to zero, and less than or equal to one. 228 | /// If is , this method 229 | /// returns a double-precision pseudo-random number greater than or equal to zero and 230 | /// strictly less than one. 231 | /// 232 | public double NextDouble(bool includeOne) 233 | { 234 | return includeOne ? this.compute53BitRandom(0, MersenneTwister.Inverse53BitsOf1s) : this.NextDouble(); 235 | } 236 | 237 | /// 238 | /// Returns a pseudo-random number greater than 0.0 and less than 1.0. 239 | /// 240 | /// A pseudo-random number greater than 0.0 and less than 1.0. 241 | public double NextDoublePositive() 242 | { 243 | return this.compute53BitRandom(0.5, MersenneTwister.Inverse53BitsOf1s); 244 | } 245 | 246 | /// 247 | /// Returns a pseudo-random number between 0.0 and 1.0. 248 | /// 249 | /// 250 | /// A single-precision floating point number greater than or equal to 0.0, 251 | /// and less than 1.0. 252 | /// 253 | public float NextSingle() 254 | { 255 | return (float)this.NextDouble(); 256 | } 257 | 258 | /// 259 | /// Returns a pseudo-random number greater than or equal to zero, and either strictly 260 | /// less than one, or less than or equal to one, depending on the value of the 261 | /// given boolean parameter. 262 | /// 263 | /// 264 | /// If , the pseudo-random number returned will be 265 | /// less than or equal to one; otherwise, the pseudo-random number returned will 266 | /// be strictly less than one. 267 | /// 268 | /// 269 | /// If is , this method returns a 270 | /// single-precision pseudo-random number greater than or equal to zero, and less 271 | /// than or equal to one. If is , 272 | /// this method returns a single-precision pseudo-random number greater than or equal to zero and 273 | /// strictly less than one. 274 | /// 275 | public float NextSingle(bool includeOne) 276 | { 277 | return (float)this.NextDouble(includeOne); 278 | } 279 | 280 | /// 281 | /// Returns a pseudo-random number greater than 0.0 and less than 1.0. 282 | /// 283 | /// A pseudo-random number greater than 0.0 and less than 1.0. 284 | public float NextSinglePositive() 285 | { 286 | return (float)this.NextDoublePositive(); 287 | } 288 | 289 | public float NextSinglePositive(float max) 290 | { 291 | return (this.Next((int)Math.Round(max)) + this.NextSinglePositive()) * this.NextSinglePositive(); 292 | } 293 | 294 | 295 | /// 296 | /// Returns a pseudo-random bool based off of an array of floats 297 | /// 298 | /// 299 | public bool NextComplexBool(float[] f) 300 | { 301 | return Math.Abs(f.Random()) <= 0.5f; 302 | } 303 | 304 | public bool NextBool() 305 | { 306 | return Math.Abs(this.NextSingle()) <= 0.5f; 307 | } 308 | 309 | /// 310 | /// Generates a new pseudo-random . 311 | /// 312 | /// A pseudo-random . 313 | protected uint GenerateUInt32() 314 | { 315 | uint y; 316 | 317 | /* _mag01[x] = x * MatrixA for x=0,1 */ 318 | if (this._mti >= MersenneTwister.N) /* generate N words at one time */ 319 | { 320 | short kk = 0; 321 | 322 | for (; kk < MersenneTwister.N - MersenneTwister.M; ++kk) 323 | { 324 | y = (this._mt[kk] & MersenneTwister.UpperMask) | (this._mt[kk + 1] & MersenneTwister.LowerMask); 325 | this._mt[kk] = this._mt[kk + MersenneTwister.M] ^ (y >> 1) ^ MersenneTwister._mag01[y & 0x1]; 326 | } 327 | 328 | for (; kk < MersenneTwister.N - 1; ++kk) 329 | { 330 | y = (this._mt[kk] & MersenneTwister.UpperMask) | (this._mt[kk + 1] & MersenneTwister.LowerMask); 331 | this._mt[kk] = this._mt[kk + (MersenneTwister.M - MersenneTwister.N)] ^ (y >> 1) ^ MersenneTwister._mag01[y & 0x1]; 332 | } 333 | 334 | y = (this._mt[MersenneTwister.N - 1] & MersenneTwister.UpperMask) | (this._mt[0] & MersenneTwister.LowerMask); 335 | this._mt[MersenneTwister.N - 1] = this._mt[MersenneTwister.M - 1] ^ (y >> 1) ^ MersenneTwister._mag01[y & 0x1]; 336 | 337 | this._mti = 0; 338 | } 339 | 340 | y = this._mt[this._mti++]; 341 | y ^= MersenneTwister.temperingShiftU(y); 342 | y ^= MersenneTwister.temperingShiftS(y) & MersenneTwister.TemperingMaskB; 343 | y ^= MersenneTwister.temperingShiftT(y) & MersenneTwister.TemperingMaskC; 344 | y ^= MersenneTwister.temperingShiftL(y); 345 | 346 | return y; 347 | } 348 | 349 | /* Period parameters */ 350 | private const int N = 624; 351 | private const int M = 397; 352 | private const uint MatrixA = 0x9908b0df; 353 | /* constant vector a */ 354 | private const uint UpperMask = 0x80000000; 355 | /* most significant w-r bits */ 356 | private const uint LowerMask = 0x7fffffff; 357 | /* least significant r bits */ 358 | /* Tempering parameters */ 359 | private const uint TemperingMaskB = 0x9d2c5680; 360 | private const uint TemperingMaskC = 0xefc60000; 361 | 362 | private static uint temperingShiftU(uint y) 363 | { 364 | return (y >> 11); 365 | } 366 | 367 | private static uint temperingShiftS(uint y) 368 | { 369 | return (y << 7); 370 | } 371 | 372 | private static uint temperingShiftT(uint y) 373 | { 374 | return (y << 15); 375 | } 376 | 377 | private static uint temperingShiftL(uint y) 378 | { 379 | return (y >> 18); 380 | } 381 | 382 | private readonly uint[] _mt = new uint[MersenneTwister.N]; 383 | /* the array for the state vector */ 384 | private short _mti; 385 | 386 | private static readonly uint[] _mag01 = { 0x0, MersenneTwister.MatrixA }; 387 | 388 | private void init(uint seed) 389 | { 390 | this._mt[0] = seed & 0xffffffffu; 391 | 392 | for (this._mti = 1; this._mti < MersenneTwister.N; this._mti++) 393 | { 394 | this._mt[this._mti] = (uint)(1812433253u * (this._mt[this._mti - 1] ^ (this._mt[this._mti - 1] >> 30)) + this._mti); 395 | // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. 396 | // In the previous versions, MSBs of the seed affect 397 | // only MSBs of the array _mt[]. 398 | // 2002/01/09 modified by Makoto Matsumoto 399 | this._mt[this._mti] &= 0xffffffffu; 400 | // for >32 bit machines 401 | } 402 | } 403 | 404 | private void init(uint[] key) 405 | { 406 | int i, j, k; 407 | this.init(19650218u); 408 | 409 | int keyLength = key.Length; 410 | i = 1; 411 | j = 0; 412 | k = (MersenneTwister.N > keyLength ? MersenneTwister.N : keyLength); 413 | 414 | for (; k > 0; k--) 415 | { 416 | this._mt[i] = (uint)((this._mt[i] ^ ((this._mt[i - 1] ^ (this._mt[i - 1] >> 30)) * 1664525u)) + key[j] + j); 417 | /* non linear */ 418 | this._mt[i] &= 0xffffffffu; 419 | // for WORDSIZE > 32 machines 420 | i++; 421 | j++; 422 | if (i >= MersenneTwister.N) 423 | { 424 | this._mt[0] = this._mt[MersenneTwister.N - 1]; 425 | i = 1; 426 | } 427 | if (j >= keyLength) 428 | j = 0; 429 | } 430 | 431 | for (k = MersenneTwister.N - 1; k > 0; k--) 432 | { 433 | this._mt[i] = (uint)((this._mt[i] ^ ((this._mt[i - 1] ^ (this._mt[i - 1] >> 30)) * 1566083941u)) - i); 434 | /* non linear */ 435 | this._mt[i] &= 0xffffffffu; 436 | // for WORDSIZE > 32 machines 437 | i++; 438 | 439 | if (i < MersenneTwister.N) 440 | { 441 | continue; 442 | } 443 | 444 | this._mt[0] = this._mt[MersenneTwister.N - 1]; 445 | i = 1; 446 | } 447 | 448 | this._mt[0] = 0x80000000u; 449 | // MSB is 1; assuring non-zero initial array 450 | } 451 | 452 | 453 | // 9007199254740991.0 is the maximum double value which the 53 significand 454 | // can hold when the exponent is 0. 455 | private const double FiftyThreeBitsOf1s = 9007199254740991.0; 456 | // Multiply by inverse to (vainly?) try to avoid a division. 457 | private const double Inverse53BitsOf1s = 1.0 / MersenneTwister.FiftyThreeBitsOf1s; 458 | private const double OnePlus53BitsOf1s = MersenneTwister.FiftyThreeBitsOf1s + 1; 459 | private const double InverseOnePlus53BitsOf1s = 1.0 / MersenneTwister.OnePlus53BitsOf1s; 460 | 461 | private double compute53BitRandom(double translate, double scale) 462 | { 463 | // get 27 pseudo-random bits 464 | ulong a = (ulong)this.GenerateUInt32() >> 5; 465 | // get 26 pseudo-random bits 466 | ulong b = (ulong)this.GenerateUInt32() >> 6; 467 | 468 | // shift the 27 pseudo-random bits (a) over by 26 bits (* 67108864.0) and 469 | // add another pseudo-random 26 bits (+ b). 470 | return ((a * 67108864.0 + b) + translate) * scale; 471 | 472 | // What about the following instead of the above? Is the multiply better? 473 | // Why? (Is it the FMUL instruction? Does this count in .Net? Will the JITter notice?) 474 | //return BitConverter.Int64BitsToDouble((a << 26) + b)); 475 | } 476 | } 477 | -------------------------------------------------------------------------------- /BetterRNG/Framework/ModConfig.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Utilities; 3 | 4 | namespace BetterRNG.Framework; 5 | 6 | /// The mod configuration. 7 | internal class ModConfig 8 | { 9 | /// Whether to randomise your daily luck. 10 | public bool EnableDailyLuckOverride { get; set; } 11 | 12 | /// Whether to randomise tomorrow's weather. 13 | public bool EnableWeatherOverride { get; set; } 14 | 15 | /// The weight for sunny weather when randomising weather. 16 | public int SunnyChance { get; set; } = 60; 17 | 18 | /// The weight for debris weather (e.g. blowing leaves, wind, etc) when randomising weather. 19 | public int CloudySnowyChance { get; set; } = 15; 20 | 21 | /// The weight for rain when randomising weather. 22 | public int RainyChance { get; set; } = 15; 23 | 24 | /// The weight for storms when randomising weather. 25 | public int StormyChance { get; set; } = 5; 26 | 27 | /// The weight for snow when randomising weather. 28 | public int HarshSnowyChance { get; set; } = 5; 29 | 30 | /// The keys which reload the mod config. 31 | public KeybindList ReloadKey { get; set; } = new(SButton.F5); 32 | } 33 | -------------------------------------------------------------------------------- /BetterRNG/Framework/Weighted.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace BetterRNG.Framework; 4 | 5 | internal static class Weighted 6 | { 7 | public static T Choose(T[] list) where T : IWeighted 8 | { 9 | if (!list.Any()) 10 | return default; 11 | 12 | int totalweight = list.Sum(c => c.Weight); 13 | int choice = ModEntry.Twister.Next(totalweight); 14 | int sum = 0; 15 | 16 | foreach (var obj in list) 17 | { 18 | for (float i = sum; i < obj.Weight + sum; i++) 19 | { 20 | if (i >= choice) 21 | return obj; 22 | } 23 | sum += obj.Weight; 24 | } 25 | 26 | return list.First(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BetterRNG/Framework/WeightedGeneric.cs: -------------------------------------------------------------------------------- 1 | namespace BetterRNG.Framework; 2 | 3 | internal class WeightedGeneric : IWeighted 4 | { 5 | public object Value { get; set; } 6 | public int Weight { get; set; } 7 | 8 | public T TValue => (T)this.Value; 9 | 10 | public WeightedGeneric(int weight, T value) 11 | { 12 | this.Weight = weight; 13 | this.Value = value; 14 | } 15 | 16 | public static WeightedGeneric Create(int weight, T value) 17 | { 18 | return new WeightedGeneric(weight, value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /BetterRNG/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BetterRNG.Framework; 3 | using StardewModdingAPI; 4 | using StardewModdingAPI.Events; 5 | using StardewValley; 6 | using Zoryn.Common; 7 | 8 | namespace BetterRNG; 9 | 10 | /// The main entry point. 11 | public class ModEntry : Mod 12 | { 13 | /********* 14 | ** Properties 15 | *********/ 16 | /// The mod configuration. 17 | private ModConfig Config; 18 | 19 | private WeightedGeneric[] Weather; 20 | 21 | 22 | /********* 23 | ** Accessors 24 | *********/ 25 | internal static MersenneTwister Twister { get; private set; } 26 | 27 | 28 | /********* 29 | ** Public methods 30 | *********/ 31 | /// The mod entry point, called after the mod is first loaded. 32 | /// Provides simplified APIs for writing mods. 33 | public override void Entry(IModHelper helper) 34 | { 35 | CommonHelper.RemoveObsoleteFiles(this, "BetterRNG.pdb"); 36 | 37 | // read config 38 | this.Config = helper.ReadConfig(); 39 | 40 | // init randomness 41 | Game1.random = ModEntry.Twister = new MersenneTwister(); 42 | this.Weather = new[] 43 | { 44 | WeightedGeneric.Create(this.Config.SunnyChance, Game1.weather_sunny), 45 | WeightedGeneric.Create(this.Config.CloudySnowyChance, Game1.weather_debris), 46 | WeightedGeneric.Create(this.Config.RainyChance, Game1.weather_rain), 47 | WeightedGeneric.Create(this.Config.StormyChance, Game1.weather_lightning), 48 | WeightedGeneric.Create(this.Config.HarshSnowyChance, Game1.weather_snow) 49 | }; 50 | 51 | // hook events 52 | helper.Events.GameLoop.DayStarted += this.OnDayStarted; 53 | helper.Events.Input.ButtonsChanged += this.OnButtonsChanged; 54 | } 55 | 56 | 57 | /********* 58 | ** Private methods 59 | *********/ 60 | /// Raised after the player starts a new day. 61 | /// The event sender. 62 | /// The event arguments. 63 | private void OnDayStarted(object sender, DayStartedEventArgs e) 64 | { 65 | this.DetermineRng(); 66 | } 67 | 68 | /// 69 | /// The event sender. 70 | /// The event arguments. 71 | private void OnButtonsChanged(object sender, ButtonsChangedEventArgs e) 72 | { 73 | if (this.Config.ReloadKey.JustPressed()) 74 | { 75 | this.Config = this.Helper.ReadConfig(); 76 | this.Monitor.Log("Config reloaded", LogLevel.Info); 77 | } 78 | } 79 | 80 | /// Randomise the daily luck and weather. 81 | private void DetermineRng() 82 | { 83 | if (this.Config.EnableDailyLuckOverride) 84 | Game1.player.team.sharedDailyLuck.Value = Math.Min(0.100000001490116, ModEntry.Twister.Next(-100, 101) / 1000.0); 85 | 86 | if (Context.IsMainPlayer && this.Config.EnableWeatherOverride) 87 | { 88 | string targetWeather = this.Weather.Choose().TValue; 89 | if (targetWeather == Game1.weather_snow && Game1.season != Season.Winter) 90 | targetWeather = Game1.weather_lightning; 91 | if (targetWeather == Game1.weather_rain && Game1.season == Season.Winter) 92 | targetWeather = Game1.weather_debris; 93 | if (targetWeather == Game1.weather_lightning && Game1.season == Season.Winter) 94 | targetWeather = Game1.weather_snow; 95 | if (targetWeather == Game1.weather_festival) 96 | targetWeather = Game1.weather_sunny; 97 | 98 | Game1.weatherForTomorrow = targetWeather; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /BetterRNG/README.md: -------------------------------------------------------------------------------- 1 | **Better RNG** is a [Stardew Valley](http://stardewvalley.net/) mod which makes the game's 2 | randomness more random. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Configure](#configure) 8 | * [Compatibility](#compatibility) 9 | * [See also](#see-also) 10 | 11 | ## Install 12 | 1. [Install the latest version of SMAPI](https://smapi.io). 13 | 2. Install this mod from the releases page. 14 | 3. Run the game using SMAPI. 15 | 16 | ## Use 17 | You can edit the `config.json` file to change the mod's settings. 18 | 19 | The mod will... 20 | * **Completely** redefine the game's random number generator (RNG) to use a Mersenne Twister 21 | Generator for random happenings. This can't be turned off. If you understood how the game handles 22 | RNG, you would understand why. Everything else in the mod can be configured as desired. 23 | * Randomise daily luck every morning using the new RNG. 24 | * Randomise **tomorrow's** weather every morning based on the configured chance values (including 25 | the probability of sun, clouds or light snow, rain, lightning storm, or blizzard). 26 | 27 | Note that some days of the game have hardcoded weather, so the weather on those days can't be 28 | changed. That means the weather channel may be wrong in rare cases. 29 | 30 | ## Configure 31 | A `config.json` will appear in the mod's folder after you run the game once. You can optionally 32 | open the file in a text editor to configure the mod. If you make a mistake, just delete the file 33 | and it'll be regenerated. 34 | 35 | For the weather fields, you specify their weight relative to the other weathers. For example, two 36 | weathers set to `1` have an equal chance of being chosen. The actual values you choose only matter 37 | as a proportion to the sum; the defaults sum to 100, but that's not required. 38 | 39 | Available fields: 40 | 41 | field | purpose 42 | ------------------------- | ------- 43 | `EnableDailyLuckOverride` | Whether to randomise your daily luck. Default false. 44 | `EnableWeatherOverride` | Whether to randomise tomorrow's weather. Default false. 45 | `SunnyChance` | The weight for sunny weather when randomising weather. Default 60. 46 | `CloudySnowyChance` | The weight for debris weather (e.g. blowing leaves, wind, etc) when randomising weather. Default 15. 47 | `RainyChance` | The weight for rain when randomising weather. Default 15. 48 | `StormyChance` | The weight for storms when randomising weather. Default 5. 49 | `HarshSnowyChance` | The weight for snow when randomising weather. Default 5. 50 | 51 | ## Compatibility 52 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 53 | * Works in single-player, multiplayer, and split-screen. Some things may use the main player's RNG. 54 | * No known mod conflicts. 55 | 56 | ## See also 57 | * [Release notes](release-notes.md) 58 | -------------------------------------------------------------------------------- /BetterRNG/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Better RNG", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Makes the game's randomness more random.", 6 | "UniqueID": "Zoryn.BetterRNG", 7 | "EntryDll": "BetterRNG.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /BetterRNG/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.0 25 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Updated for Stardew Valley 1.5.5. 28 | * Added config option for the reload key. 29 | * Fixed RNG not re-randomized each day (thanks to randomC0der!). 30 | 31 | ### 2.7.3 32 | Released 29 November 2019 for SMAPI 3.0 or later. Updated by Pathoschild. 33 | 34 | * Fixed error logged before the save is loaded. 35 | 36 | ### 2.7.2 37 | Released 26 November 2019 for SMAPI 3.0 or later. Updated by Pathoschild. 38 | 39 | * Updated to Stardew Valley 1.4. 40 | * Fixed error in rare cases when another mod changes monster data. 41 | 42 | ### 2.7.1 43 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 44 | 45 | * Updated to SMAPI 3.0. 46 | 47 | ### 1.9.0 48 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 49 | 50 | * Updated to Stardew Valley 1.3 (including multiplayer). 51 | 52 | ### 1.8.0 53 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 54 | 55 | * Updated to SMAPI 1.15 & 2.0. 56 | 57 | ### 1.7.0 58 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 59 | 60 | * Updated to Stardew Valley 1.2. 61 | 62 | ### 1.6.0 63 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 64 | 65 | * Updated to SMAPI 1.9. 66 | 67 | ### 1.5.0 68 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 69 | 70 | * Updated to SMAPI 1.3. 71 | 72 | ### 1.4.0 73 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 74 | 75 | * Updated to SMAPI 1.0. 76 | * Added support for Linux/Mac. 77 | 78 | ### 1.3.0 79 | Released 03 April 2016 for SMAPI 0.39.6 or later. 80 | 81 | * Updated to SMAPI 0.39.6. 82 | 83 | ### 1.2.0 84 | Released 28 March 2016 for SMAPI 0.39.3 or later. 85 | 86 | * Updated to SMAPI 0.39.3. 87 | * Added re-randomisation when a save is loaded. 88 | * Added hotkey to reload `config.json`. 89 | 90 | ### 1.1.0 91 | Released 23 March 2016 for SMAPI 0.39.1 or later. 92 | 93 | * Updated to SMAPI 0.39.1. 94 | 95 | ### 1.0.0 96 | Released 21 March 2016 for SMAPI 0.38.4 or later. 97 | 98 | * Initial release. 99 | -------------------------------------------------------------------------------- /CalendarAnywhere/CalendarAnywhere.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CalendarAnywhere/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using StardewModdingAPI; 3 | using StardewModdingAPI.Events; 4 | using StardewValley; 5 | using StardewValley.Menus; 6 | using Zoryn.Common; 7 | 8 | namespace CalendarAnywhere; 9 | 10 | /// The main entry point. 11 | public class ModEntry : Mod 12 | { 13 | /********* 14 | ** Public methods 15 | *********/ 16 | /// The mod entry point, called after the mod is first loaded. 17 | /// Provides simplified APIs for writing mods. 18 | public override void Entry(IModHelper helper) 19 | { 20 | CommonHelper.RemoveObsoleteFiles(this, "CalendarAnywhere.pdb"); 21 | 22 | helper.Events.Input.ButtonPressed += this.OnButtonPressed; 23 | } 24 | 25 | 26 | /********* 27 | ** Private methods 28 | *********/ 29 | /// Raised after the player presses a button on the keyboard, controller, or mouse. 30 | /// The event sender. 31 | /// The event arguments. 32 | private void OnButtonPressed(object sender, ButtonPressedEventArgs e) 33 | { 34 | if (Context.IsPlayerFree && e.Button.IsUseToolButton() && this.GetTarget().Contains((int)e.Cursor.ScreenPixels.X, (int)e.Cursor.ScreenPixels.Y)) 35 | Game1.activeClickableMenu = new Billboard(); 36 | } 37 | 38 | /// Get the clickable screen area that should open the billboard menu. 39 | private Rectangle GetTarget() 40 | { 41 | return new Rectangle( 42 | x: (Game1.viewport.Width - 300) + 108, 43 | y: (Game1.tileSize / 8) + 20, 44 | width: 160, 45 | height: 41 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CalendarAnywhere/README.md: -------------------------------------------------------------------------------- 1 | **Calendar Anywhere** is a [Stardew Valley](http://stardewvalley.net/) mod which lets you open the 2 | calendar from anywhere by clicking on the date in the top-right corner. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Compatibility](#compatibility) 8 | * [See also](#see-also) 9 | 10 | ## Install 11 | 1. [Install the latest version of SMAPI](https://smapi.io). 12 | 2. Install this mod from the releases page. 13 | 3. Run the game using SMAPI. 14 | 15 | ## Use 16 | To open the calendar, place the cursor over the date in the top-right corner. The text should 17 | change temporarily to "Calendar", and clicking that (or pressing `A` on a controller) will open the 18 | calendar. 19 | 20 | ## Compatibility 21 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 22 | * Works in single-player, multiplayer, and split-screen. 23 | * No known mod conflicts. 24 | 25 | ## See also 26 | * [Release notes](release-notes.md) 27 | -------------------------------------------------------------------------------- /CalendarAnywhere/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Calendar Anywhere", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Lets you open the calendar from anywhere.", 6 | "UniqueID": "Zoryn.CalendarAnywhere", 7 | "EntryDll": "CalendarAnywhere.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /CalendarAnywhere/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.0 25 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Updated for Stardew Valley 1.5.5. 28 | 29 | ### 2.7.3 30 | Released 29 November 2019 for SMAPI 3.0 or later. Updated by Pathoschild. 31 | 32 | * Fixed clickable area misaligned when zoomed in/out. 33 | 34 | ### 2.7.1 35 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 36 | 37 | * Updated to SMAPI 3.0. 38 | 39 | ### 1.9.0 40 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 41 | 42 | * Updated to Stardew Valley 1.3 (including multiplayer). 43 | 44 | ### 1.8.0 45 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 46 | 47 | * Updated to SMAPI 1.15 & 2.0. 48 | * Fixed crash if you open the calendar while warping to a new area. 49 | 50 | ### 1.7.0 51 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 52 | 53 | * Updated to Stardew Valley 1.2. 54 | 55 | ### 1.6.0 56 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 57 | 58 | * Updated to SMAPI 1.9. 59 | 60 | ### 1.5.0 61 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 62 | 63 | * Updated to SMAPI 1.3. 64 | * Fixed the "(press F5 to reload config)" message being shown even though this mod has no config. 65 | 66 | ### 1.4.0 67 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 68 | 69 | * Updated to SMAPI 1.0. 70 | * Added support for Linux/Mac. 71 | 72 | ### 1.3.0 73 | Released 03 April 2016 for SMAPI 0.39.6 or later. 74 | 75 | * Updated to SMAPI 0.39.6. 76 | 77 | ### 1.2.0 78 | Released 28 March 2016 for SMAPI 0.39.3 or later. 79 | 80 | * Updated to SMAPI 0.39.3. 81 | 82 | ### 1.1.0 83 | Released 23 March 2016 for SMAPI 0.39.1 or later. 84 | 85 | * Updated to SMAPI 0.39.1. 86 | 87 | ### 1.0.0 88 | Released 21 March 2016 for SMAPI 0.38.4 or later. 89 | 90 | * Initial release. 91 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Zoryn 5 | https://github.com/Zoryn4163/SMAPI-Mods 6 | git 7 | 8 | 2.8.5 9 | 10 | net6.0 11 | false 12 | $(SolutionDir)\_releases 13 | 14 | 15 | -------------------------------------------------------------------------------- /Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /DurableFences/DurableFences.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DurableFences/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Events; 3 | using StardewValley; 4 | using Zoryn.Common; 5 | 6 | namespace DurableFences; 7 | 8 | /// The main entry point. 9 | public class ModEntry : Mod 10 | { 11 | /********* 12 | ** Public methods 13 | *********/ 14 | /// The mod entry point, called after the mod is first loaded. 15 | /// Provides simplified APIs for writing mods. 16 | public override void Entry(IModHelper helper) 17 | { 18 | CommonHelper.RemoveObsoleteFiles(this, "DurableFences.pdb"); 19 | 20 | helper.Events.GameLoop.OneSecondUpdateTicked += this.OnOneSecondUpdateTicked; 21 | } 22 | 23 | 24 | /********* 25 | ** Private methods 26 | *********/ 27 | /// Raised once per second after the game state is updated. 28 | /// The event sender. 29 | /// The event arguments. 30 | private void OnOneSecondUpdateTicked(object sender, OneSecondUpdateTickedEventArgs e) 31 | { 32 | foreach (GameLocation location in Game1.locations) 33 | { 34 | foreach (Object obj in location.Objects.Values) 35 | { 36 | if (obj is Fence fence) 37 | fence.health.Value = fence.maxHealth.Value; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DurableFences/README.md: -------------------------------------------------------------------------------- 1 | **Durable Fences** is a [Stardew Valley](http://stardewvalley.net/) mod which makes fences last 2 | forever. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Compatibility](#compatibility) 8 | * [See also](#see-also) 9 | 10 | ## Install 11 | 1. [Install the latest version of SMAPI](https://smapi.io). 12 | 2. Install this mod from the releases page. 13 | 3. Run the game using SMAPI. 14 | 15 | ## Use 16 | The mod will automatically prevent all fences from decaying, no action needed on your part. 17 | 18 | ## Compatibility 19 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 20 | * Works in single-player, multiplayer, and split-screen. 21 | * No known mod conflicts. 22 | 23 | ## See also 24 | * [Release notes](release-notes.md) 25 | -------------------------------------------------------------------------------- /DurableFences/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Durable Fences", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Makes fences more durable.", 6 | "UniqueID": "Zoryn.DurableFences", 7 | "EntryDll": "DurableFences.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /DurableFences/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.1 25 | Released 08 January 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Minor optimization. 28 | 29 | ### 2.8.0 30 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 31 | 32 | * Updated for Stardew Valley 1.5.5. 33 | 34 | ### 2.7.1 35 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 36 | 37 | * Updated to SMAPI 3.0. 38 | 39 | ### 1.9.0 40 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 41 | 42 | * Updated to Stardew Valley 1.3 (including multiplayer). 43 | 44 | ### 1.8.0 45 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 46 | 47 | * Updated to SMAPI 1.15 & 2.0. 48 | 49 | ### 1.7.0 50 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 51 | 52 | * Updated to Stardew Valley 1.2. 53 | 54 | ### 1.6.0 55 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 56 | 57 | * Updated to SMAPI 1.9. 58 | 59 | ### 1.5.0 60 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 61 | 62 | * Updated to SMAPI 1.3. 63 | * Fixed the "(press F5 to reload config)" message being shown even though this mod has no config. 64 | 65 | ### 1.4.0 66 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 67 | 68 | * Updated to SMAPI 1.0. 69 | * Added support for Linux/Mac. 70 | 71 | ### 1.3.0 72 | Released 03 April 2016 for SMAPI 0.39.6 or later. 73 | 74 | * Updated to SMAPI 0.39.6. 75 | 76 | ### 1.2.0 77 | Released 28 March 2016 for SMAPI 0.39.3 or later. 78 | 79 | * Updated to SMAPI 0.39.3. 80 | 81 | ### 1.1.0 82 | Released 23 March 2016 for SMAPI 0.39.1 or later. 83 | 84 | * Updated to SMAPI 0.39.1. 85 | 86 | ### 1.0.0 87 | Released 21 March 2016 for SMAPI 0.38.4 or later. 88 | 89 | * Initial release. 90 | -------------------------------------------------------------------------------- /FishingMod/FishingMod.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FishingMod/Framework/ModConfig.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Utilities; 3 | 4 | namespace FishingMod.Framework; 5 | 6 | /// The mod configuration. 7 | internal class ModConfig 8 | { 9 | /// Whether the game should consider every catch to be perfectly executed, even if it wasn't. 10 | public bool AlwaysPerfect { get; set; } 11 | 12 | /// Whether to always find treasure. 13 | public bool AlwaysFindTreasure { get; set; } 14 | 15 | /// Whether to catch fish instantly. 16 | public bool InstantCatchFish { get; set; } 17 | 18 | /// Whether to catch treasure instantly. 19 | public bool InstantCatchTreasure { get; set; } 20 | 21 | /// Whether to significantly lower the max fish difficulty. 22 | public bool EasierFishing { get; set; } 23 | 24 | /// A multiplier applied to the fish difficulty. This can a number between 0 and 1 to lower difficulty, or more than 1 to increase it. 25 | public float FishDifficultyMultiplier { get; set; } = 1; 26 | 27 | /// A value added to the fish difficulty. This can be less than 0 to decrease difficulty, or more than 0 to increase it. 28 | public float FishDifficultyAdditive { get; set; } 29 | 30 | /// A value added to the initial fishing completion. For example, a value of 1 will instantly catch the fish. 31 | public float LossAdditive { get; set; } = 2 / 1000f; 32 | 33 | /// Whether fishing tackles last forever. 34 | public bool InfiniteTackle { get; set; } = true; 35 | 36 | /// Whether fishing bait lasts forever. 37 | public bool InfiniteBait { get; set; } = true; 38 | 39 | /// The keys which reload the mod config. 40 | public KeybindList ReloadKey { get; set; } = new(SButton.F5); 41 | } 42 | -------------------------------------------------------------------------------- /FishingMod/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FishingMod.Framework; 3 | using StardewModdingAPI; 4 | using StardewModdingAPI.Events; 5 | using StardewModdingAPI.Utilities; 6 | using StardewValley; 7 | using StardewValley.Menus; 8 | using StardewValley.Tools; 9 | using Zoryn.Common; 10 | 11 | namespace FishingMod; 12 | 13 | /// The main entry point. 14 | public class ModEntry : Mod 15 | { 16 | /********* 17 | ** Properties 18 | *********/ 19 | /// The mod configuration. 20 | private ModConfig Config; 21 | 22 | /// Whether the player is in the fishing minigame. 23 | private readonly PerScreen BeganFishingGame = new(); 24 | 25 | /// The number of ticks since the player opened the fishing minigame. 26 | private readonly PerScreen UpdateIndex = new(); 27 | 28 | 29 | /********* 30 | ** Public methods 31 | *********/ 32 | /// The mod entry point, called after the mod is first loaded. 33 | /// Provides simplified APIs for writing mods. 34 | public override void Entry(IModHelper helper) 35 | { 36 | CommonHelper.RemoveObsoleteFiles(this, "FishingMod.pdb"); 37 | 38 | this.Config = helper.ReadConfig(); 39 | 40 | helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; 41 | helper.Events.Input.ButtonsChanged += this.OnButtonsChanged; 42 | } 43 | 44 | 45 | /********* 46 | ** Private methods 47 | *********/ 48 | /// Raised after the game state is updated (≈60 times per second). 49 | /// The event sender. 50 | /// The event arguments. 51 | private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) 52 | { 53 | if (!Context.IsWorldReady) 54 | return; 55 | 56 | // apply infinite bait/tackle 57 | if (e.IsOneSecond && (this.Config.InfiniteBait || this.Config.InfiniteTackle)) 58 | { 59 | if (Game1.player.CurrentTool is FishingRod rod) 60 | { 61 | if (this.Config.InfiniteBait && rod.attachments?.Length > 0 && rod.attachments[0] != null) 62 | rod.attachments[0].Stack = rod.attachments[0].maximumStackSize(); 63 | 64 | if (this.Config.InfiniteTackle && rod.attachments?.Length > 1 && rod.attachments[1] != null) 65 | rod.attachments[1].uses.Value = 0; 66 | } 67 | } 68 | 69 | // apply fishing minigame changes 70 | if (Game1.activeClickableMenu is BobberBar bobber) 71 | { 72 | //Begin fishing game 73 | if (!this.BeganFishingGame.Value && this.UpdateIndex.Value > 15) 74 | { 75 | //Do these things once per fishing minigame, 1/4 second after it updates 76 | bobber.difficulty *= this.Config.FishDifficultyMultiplier; 77 | bobber.difficulty += this.Config.FishDifficultyAdditive; 78 | 79 | if (this.Config.AlwaysFindTreasure) 80 | bobber.treasure = true; 81 | 82 | if (this.Config.InstantCatchFish) 83 | { 84 | if (bobber.treasure) 85 | bobber.treasureCaught = true; 86 | bobber.distanceFromCatching += 100; 87 | } 88 | 89 | if (this.Config.InstantCatchTreasure) 90 | if (bobber.treasure || this.Config.AlwaysFindTreasure) 91 | bobber.treasureCaught = true; 92 | 93 | if (this.Config.EasierFishing) 94 | { 95 | bobber.difficulty = Math.Max(15, Math.Max(bobber.difficulty, 60)); 96 | bobber.motionType = 2; 97 | } 98 | 99 | this.BeganFishingGame.Value = true; 100 | } 101 | 102 | if (this.UpdateIndex.Value < 20) 103 | this.UpdateIndex.Value++; 104 | 105 | if (this.Config.AlwaysPerfect) 106 | bobber.perfect = true; 107 | 108 | if (!bobber.bobberInBar) 109 | bobber.distanceFromCatching += this.Config.LossAdditive; 110 | } 111 | else 112 | { 113 | //End fishing game 114 | this.BeganFishingGame.Value = false; 115 | this.UpdateIndex.Value = 0; 116 | } 117 | } 118 | 119 | /// 120 | /// The event sender. 121 | /// The event arguments. 122 | private void OnButtonsChanged(object sender, ButtonsChangedEventArgs e) 123 | { 124 | if (this.Config.ReloadKey.JustPressed()) 125 | { 126 | this.Config = this.Helper.ReadConfig(); 127 | this.Monitor.Log("Config reloaded", LogLevel.Info); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /FishingMod/README.md: -------------------------------------------------------------------------------- 1 | **Fishing Mod** is a [Stardew Valley](http://stardewvalley.net/) mod which lets you customise the 2 | fishing experience by editing the mod settings. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Configure](#configure) 8 | * [Compatibility](#compatibility) 9 | * [See also](#see-also) 10 | 11 | ## Install 12 | 1. [Install the latest version of SMAPI](https://smapi.io). 13 | 2. Install this mod from the releases page. 14 | 3. Run the game using SMAPI. 15 | 16 | ## Use 17 | The mod lets you optionally... 18 | 19 | * always perfect catch; 20 | * always find treasure; 21 | * instant fish catch; 22 | * instant treasure catch; 23 | * change fish difficulty (multiplier or additive); 24 | * change bar drain; 25 | * set infinite tackle use; 26 | * set infinite bait. 27 | 28 | ## Configure 29 | A `config.json` will appear in the mod's folder after you run the game once. You can optionally 30 | open the file in a text editor to configure the mod. If you make a mistake, just delete the file 31 | and it'll be regenerated. 32 | 33 | Available fields: 34 | 35 | field | purpose 36 | -------------------------- | ------- 37 | `AlwaysPerfect` | Whether the game should consider every catch to be perfectly executed, even if it wasn't. Default false. 38 | `AlwaysFindTreasure` | Whether to always find treasure. Default false. 39 | `InstantCatchFish` | Whether to catch fish instantly. Default false. 40 | `InstantCatchTreasure` | Whether to catch treasure instantly. Default false. 41 | `EasierFishing` | Whether to significantly lower the max fish difficulty. 42 | `FishDifficultyMultiplier` | A multiplier applied to the fish difficulty. This can a number between 0 and 1 to lower difficulty, or more than 1 to increase it. 43 | `FishDifficultyAdditive` | A value added to the fish difficulty. This can be less than 0 to decrease difficulty, or more than 0 to increase it. 44 | `LossAdditive` | A value added to the gradual completion drain when the fish isn't inside the green bar. This can be a negative value to increase drain speed, or a positive value to decrease it. A value of 0.003 will prevent drain entirely. 45 | `InfiniteTackle` | Whether fishing tackles last forever. 46 | `InfiniteBait` | Whether fishing bait lasts forever. 47 | 48 | ## Compatibility 49 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 50 | * Works in single-player, multiplayer, and split-screen. 51 | * No known mod conflicts. 52 | 53 | ## See also 54 | * [Release notes](release-notes.md) 55 | -------------------------------------------------------------------------------- /FishingMod/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Fishing Mod", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Lets you change some things about fishing based on a config file.", 6 | "UniqueID": "Zoryn.FishingMod", 7 | "EntryDll": "FishingMod.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /FishingMod/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.1 25 | Released 08 January 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Minor optimization. 28 | 29 | ### 2.8.0 30 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 31 | 32 | * Updated for Stardew Valley 1.5.5. 33 | * Added split-screen support. 34 | * Added config option for the reload key. 35 | * Internal optimizations. 36 | 37 | ### 2.7.1 38 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 39 | 40 | * Updated to SMAPI 3.0. 41 | 42 | ### 2.6.1 43 | Released 01 September 2018 for SMAPI 2.6 or later. 44 | 45 | * Fixed unlimited tackles no longer being unlimited. 46 | 47 | ### 1.9.0 48 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 49 | 50 | * Updated to Stardew Valley 1.3 (including multiplayer). 51 | 52 | ### 1.8.0 53 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 54 | 55 | * Updated to SMAPI 1.15 & 2.0. 56 | 57 | ### 1.7.0 58 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 59 | 60 | * Updated to Stardew Valley 1.2. 61 | 62 | ### 1.6.0 63 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 64 | 65 | * Updated to SMAPI 1.9. 66 | 67 | ### 1.5.0 68 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 69 | 70 | * Updated to SMAPI 1.3. 71 | 72 | ### 1.4.0 73 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 74 | 75 | * Updated to SMAPI 1.0. 76 | * Added support for Linux/Mac. 77 | 78 | ### 1.3.1 79 | Released 06 April 2016 for SMAPI 0.39.6 or later. 80 | 81 | * Fixed the 'always find treasure' option not working. 82 | 83 | ### 1.3.0 84 | Released 03 April 2016 for SMAPI 0.39.6 or later. 85 | 86 | * Updated to SMAPI 0.39.6. 87 | 88 | ### 1.2.0 89 | Released 28 March 2016 for SMAPI 0.39.3 or later. 90 | 91 | * Updated to SMAPI 0.39.3. 92 | * Added hotkey to reload `config.json`. 93 | 94 | ### 1.1.0 95 | Released 23 March 2016 for SMAPI 0.39.1 or later. 96 | 97 | * Updated to SMAPI 0.39.1. 98 | 99 | ### 1.0.0 100 | Released 21 March 2016 for SMAPI 0.38.4 or later. 101 | 102 | * Initial release. 103 | -------------------------------------------------------------------------------- /HealthBars/Framework/ModConfig.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using StardewModdingAPI; 3 | using StardewModdingAPI.Utilities; 4 | 5 | namespace HealthBars.Framework; 6 | 7 | /// The mod configuration. 8 | internal class ModConfig 9 | { 10 | /// Whether to show a health bar for monsters at full health. 11 | public bool DisplayHealthWhenNotDamaged { get; set; } 12 | 13 | /// Whether to show the maximum health number. 14 | public bool DisplayMaxHealthNumber { get; set; } = true; 15 | 16 | /// Whether to show the current health number. 17 | public bool DisplayCurrentHealthNumber { get; set; } = true; 18 | 19 | /// Whether to draw a border around text so it's more visible on some backgrounds. 20 | public bool DisplayTextBorder { get; set; } = true; 21 | 22 | /// The text color. 23 | public Color TextColor { get; set; } = Color.White; 24 | 25 | /// The text border color. 26 | public Color TextBorderColor { get; set; } = Color.Black; 27 | 28 | /// The health bar color when the monster has low health. 29 | public Color LowHealthColor { get; set; } = Color.DarkRed; 30 | 31 | /// The health bar color when the monster has high health. 32 | public Color HighHealthColor { get; set; } = Color.LimeGreen; 33 | 34 | /// The health bar width in pixels. 35 | public int BarWidth { get; set; } = 90; 36 | 37 | /// The health bar height in pixels. 38 | public int BarHeight { get; set; } = 15; 39 | 40 | /// The health bar's vertical border width in pixels. 41 | public int BarBorderWidth { get; set; } = 2; 42 | 43 | /// The health bar's horizontal border width in pixels. 44 | public int BarBorderHeight { get; set; } = 2; 45 | 46 | /// The keys which reload the mod config. 47 | public KeybindList ReloadKey { get; set; } = new(SButton.F5); 48 | } 49 | -------------------------------------------------------------------------------- /HealthBars/HealthBars.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HealthBars/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using HealthBars.Framework; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using StardewModdingAPI; 5 | using StardewModdingAPI.Events; 6 | using StardewValley; 7 | using StardewValley.Monsters; 8 | using Zoryn.Common; 9 | 10 | namespace HealthBars; 11 | 12 | /// The main entry point. 13 | public class ModEntry : Mod 14 | { 15 | /********* 16 | ** Properties 17 | *********/ 18 | /// The mod configuration. 19 | private ModConfig Config; 20 | 21 | /// The cached health bar texture. 22 | private Texture2D BarTexture; 23 | 24 | 25 | /********* 26 | ** Public methods 27 | *********/ 28 | /// The mod entry point, called after the mod is first loaded. 29 | /// Provides simplified APIs for writing mods. 30 | public override void Entry(IModHelper helper) 31 | { 32 | CommonHelper.RemoveObsoleteFiles(this, "HealthBars.pdb"); 33 | 34 | // read config 35 | this.Config = helper.ReadConfig(); 36 | 37 | // build bar texture 38 | this.BarTexture = this.GetBarTexture(); 39 | 40 | // hook events 41 | helper.Events.Display.RenderedWorld += this.OnRenderedWorld; 42 | helper.Events.Input.ButtonsChanged += this.OnButtonsChanged; 43 | } 44 | 45 | 46 | /********* 47 | ** Private methods 48 | *********/ 49 | /// 50 | /// The event sender. 51 | /// The event arguments. 52 | private void OnRenderedWorld(object sender, RenderedWorldEventArgs e) 53 | { 54 | if (!Context.IsWorldReady) 55 | return; 56 | 57 | SpriteFont font = Game1.smallFont; 58 | SpriteBatch batch = Game1.spriteBatch; 59 | 60 | foreach (NPC npc in Game1.currentLocation.characters) 61 | { 62 | if (npc is Monster monster) 63 | this.DrawHealthBar(batch, monster, font); 64 | } 65 | } 66 | 67 | /// 68 | /// The event sender. 69 | /// The event arguments. 70 | private void OnButtonsChanged(object sender, ButtonsChangedEventArgs e) 71 | { 72 | if (this.Config.ReloadKey.JustPressed()) 73 | { 74 | this.Config = this.Helper.ReadConfig(); 75 | this.Monitor.Log("Config reloaded", LogLevel.Info); 76 | } 77 | } 78 | 79 | /// Draw a health bar for the given monster, if needed. 80 | /// The sprite batch being drawn. 81 | /// The monster whose health to display. 82 | /// The font to use for the health numbers. 83 | private void DrawHealthBar(SpriteBatch batch, Monster monster, SpriteFont font) 84 | { 85 | if (monster.MaxHealth < monster.Health) 86 | monster.MaxHealth = monster.Health; 87 | 88 | if (monster.MaxHealth == monster.Health && !this.Config.DisplayHealthWhenNotDamaged) 89 | return; 90 | 91 | Vector2 size = new Vector2(monster.Sprite.SpriteWidth, monster.Sprite.SpriteHeight) * Game1.pixelZoom; 92 | 93 | Vector2 screenLoc = Game1.GlobalToLocal(monster.position.Value); 94 | screenLoc.X += size.X / 2 - this.Config.BarWidth / 2.0f; 95 | screenLoc.Y -= this.Config.BarHeight; 96 | 97 | float fill = monster.Health / (float)monster.MaxHealth; 98 | 99 | batch.Draw(this.BarTexture, screenLoc + new Vector2(this.Config.BarBorderWidth, this.Config.BarBorderHeight), this.BarTexture.Bounds, Color.Lerp(this.Config.LowHealthColor, this.Config.HighHealthColor, fill), 0.0f, Vector2.Zero, new Vector2(fill, 1.0f), SpriteEffects.None, 0); 100 | 101 | if (this.Config.DisplayCurrentHealthNumber) 102 | { 103 | string textLeft = monster.Health.ToString(); 104 | Vector2 textSizeL = font.MeasureString(textLeft); 105 | if (this.Config.DisplayTextBorder) 106 | batch.DrawString(Game1.smallFont, textLeft, screenLoc - new Vector2(-1.0f, textSizeL.Y + 1.65f), this.Config.TextBorderColor, 0.0f, Vector2.Zero, 0.66f, SpriteEffects.None, 0); 107 | batch.DrawString(font, textLeft, screenLoc - new Vector2(0.0f, textSizeL.Y + 1.0f), this.Config.TextColor, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0); 108 | } 109 | 110 | if (this.Config.DisplayMaxHealthNumber) 111 | { 112 | string textRight = monster.MaxHealth.ToString(); 113 | Vector2 textSizeR = font.MeasureString(textRight); 114 | if (this.Config.DisplayTextBorder) 115 | batch.DrawString(Game1.smallFont, textRight, screenLoc + new Vector2(this.Config.BarWidth, 0.0f) - new Vector2(textSizeR.X - 1f, textSizeR.Y + 1.65f), this.Config.TextBorderColor, 0.0f, Vector2.Zero, 0.66f, SpriteEffects.None, 0); 116 | batch.DrawString(font, textRight, screenLoc + new Vector2(this.Config.BarWidth, 0.0f) - new Vector2(textSizeR.X, textSizeR.Y + 1.0f), this.Config.TextColor, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0); 117 | } 118 | } 119 | 120 | /// Get a health bar texture. 121 | private Texture2D GetBarTexture() 122 | { 123 | // calculate size 124 | int innerBarWidth = this.Config.BarWidth - this.Config.BarBorderWidth * 2; 125 | int innerBarHeight = this.Config.BarHeight - this.Config.BarBorderHeight * 2; 126 | 127 | // get pixels 128 | var data = new uint[innerBarWidth * innerBarHeight]; 129 | for (int i = 0; i < data.Length; i++) 130 | data[i] = 0xffffffff; 131 | 132 | // build texture 133 | var texture = new Texture2D(Game1.graphics.GraphicsDevice, innerBarWidth, innerBarHeight); 134 | texture.SetData(data); 135 | return texture; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /HealthBars/README.md: -------------------------------------------------------------------------------- 1 | **Health Bars** is a [Stardew Valley](http://stardewvalley.net/) mod which shows health bars for 2 | monsters you encounter. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Configure](#configure) 8 | * [Compatibility](#compatibility) 9 | * [See also](#see-also) 10 | 11 | ## Install 12 | 1. [Install the latest version of SMAPI](https://smapi.io). 13 | 2. Install this mod from the releases page. 14 | 3. Run the game using SMAPI. 15 | 16 | ## Use 17 | The mod will automatically show health bars for monsters you encounter. 18 | 19 | ## Configure 20 | A `config.json` will appear in the mod's folder after you run the game once. You can optionally 21 | open the file in a text editor to configure the mod. If you make a mistake, just delete the file 22 | and it'll be regenerated. 23 | 24 | Available fields: 25 | 26 | field | purpose 27 | ----------------------------- | ------- 28 | `DisplayHealthWhenNotDamaged` | Whether to show a health bar for monsters at full health. Default false. 29 | `DisplayMaxHealthNumber` | Whether to show the maximum health number. Default true. 30 | `DisplayCurrentHealthNumber` | Whether to show the current health number. Default true. 31 | `DisplayTextBorder` | Whether to draw a border around text so it's more visible on some backgrounds. Default true. 32 | `TextColor` | The text color. Default white. 33 | `TextBorderColor` | The text border color. Default black. 34 | `LowHealthColor` | The health bar color when the monster has low health. Default dark red. 35 | `HighHealthColor` | The health bar color when the monster has high health. Default lime green. 36 | `BarWidth` | The health bar width in pixels. Default 90. 37 | `BarHeight` | The health bar height in pixels. Default 15. 38 | `BarBorderWidth` | The health bar's vertical border width in pixels. Default 2. 39 | `BarBorderHeight` | The health bar's horizontal border width in pixels. Default 2. 40 | 41 | ## Compatibility 42 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 43 | * Works in single-player, multiplayer, and split-screen. 44 | * No known mod conflicts. 45 | 46 | ## See also 47 | * [Release notes](release-notes.md) 48 | -------------------------------------------------------------------------------- /HealthBars/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Health Bars", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Shows monster health bars.", 6 | "UniqueID": "Zoryn.HealthBars", 7 | "EntryDll": "HealthBars.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /HealthBars/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.1 25 | Released 08 January 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Fixed health bars drawn over menus and the HUD. 28 | * Fixed health bar position when UI scale doesn't match zoom level (thanks to Vlad-00003!). 29 | * Minor optimization. 30 | 31 | ### 2.8.0 32 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 33 | 34 | * Updated for Stardew Valley 1.5.5. 35 | 36 | ### 2.7.1 37 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 38 | 39 | * Updated to SMAPI 3.0. 40 | 41 | ### 1.9.0 42 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 43 | 44 | * Updated to Stardew Valley 1.3 (including multiplayer). 45 | 46 | ### 1.8.0 47 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 48 | 49 | * Updated to SMAPI 1.15 & 2.0. 50 | 51 | ### 1.7.0 52 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 53 | 54 | * Updated to Stardew Valley 1.2. 55 | 56 | ### 1.6.0 57 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 58 | 59 | * Updated to SMAPI 1.9. 60 | 61 | ### 1.5.0 62 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 63 | 64 | * Updated to SMAPI 1.3. 65 | 66 | ### 1.4.0 67 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 68 | 69 | * Updated to SMAPI 1.0. 70 | * Added support for Linux/Mac. 71 | 72 | ### 1.3.1 73 | Released 06 April 2016 for SMAPI 0.39.6 or later. 74 | 75 | * Fixed health bar drawing code. 76 | 77 | ### 1.3.0 78 | Released 03 April 2016 for SMAPI 0.39.6 or later. 79 | 80 | * Updated to SMAPI 0.39.6. 81 | 82 | ### 1.2.0 83 | Released 28 March 2016 for SMAPI 0.39.3 or later. 84 | 85 | * Updated to SMAPI 0.39.3. 86 | * Added hotkey to reload `config.json`. 87 | * Fixed zoom handling. 88 | * Fixed monsters that spawn after the location is loaded not having health bars. 89 | 90 | ### 1.1.0 91 | Released 23 March 2016 for SMAPI 0.39.1 or later. 92 | 93 | * Updated to SMAPI 0.39.1. 94 | 95 | ### 1.0.0 96 | Released 21 March 2016 for SMAPI 0.38.4 or later. 97 | 98 | * Initial release. 99 | -------------------------------------------------------------------------------- /JunimoDepositAnywhere/JunimoDepositAnywhere.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JunimoDepositAnywhere/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Events; 3 | using StardewValley; 4 | using StardewValley.Menus; 5 | using Zoryn.Common; 6 | 7 | namespace JunimoDepositAnywhere; 8 | 9 | /// The main entry point. 10 | public class ModEntry : Mod 11 | { 12 | /********* 13 | ** Public methods 14 | *********/ 15 | /// The mod entry point, called after the mod is first loaded. 16 | /// Provides simplified APIs for writing mods. 17 | public override void Entry(IModHelper helper) 18 | { 19 | CommonHelper.RemoveObsoleteFiles(this, "JunimoDepositAnywhere.pdb"); 20 | 21 | helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; 22 | } 23 | 24 | 25 | /********* 26 | ** Protected methods methods 27 | *********/ 28 | /// Raised after the game state is updated (≈60 times per second). 29 | /// The event sender. 30 | /// The event data. 31 | private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) 32 | { 33 | if (!Context.IsWorldReady || !e.IsMultipleOf(15)) // quarter-second 34 | return; 35 | 36 | if (Game1.activeClickableMenu is JunimoNoteMenu menu) 37 | { 38 | foreach (Bundle bundle in menu.bundles) 39 | bundle.depositsAllowed = true; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /JunimoDepositAnywhere/README.md: -------------------------------------------------------------------------------- 1 | **Junimo Deposit Anywhere** is a [Stardew Valley](http://stardewvalley.net/) mod which removes 2 | restrictions that prevent you from filling Junimo bundles from outside the Community Center. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Compatibility](#compatibility) 8 | * [See also](#see-also) 9 | 10 | ## Install 11 | 1. [Install the latest version of SMAPI](https://smapi.io). 12 | 2. Install this mod from the releases page. 13 | 3. Run the game using SMAPI. 14 | 15 | ## Use 16 | The mod lets you add items to Community Center bundles from anywhere using the built-in bundles 17 | menu from your inventory. 18 | 19 | **WARNING: completing a bundle outside the community center will invariably crash your game. Only 20 | complete the bundle from the Community Center.** 21 | 22 | ## Compatibility 23 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 24 | * Works in single-player, multiplayer, and split-screen. 25 | * No known mod conflicts. 26 | 27 | ## See also 28 | * [Release notes](release-notes.md) 29 | -------------------------------------------------------------------------------- /JunimoDepositAnywhere/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Junimo Deposit Anywhere", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Lets you deposit items into Junimo bundles from anywhere.", 6 | "UniqueID": "Zoryn.JunimoDepositAnywhere", 7 | "EntryDll": "JunimoDepositAnywhere.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /JunimoDepositAnywhere/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.0 25 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Updated for Stardew Valley 1.5.5. 28 | 29 | ### 2.7.1 30 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 31 | 32 | * Updated to SMAPI 3.0. 33 | 34 | ### 1.9.0 35 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 36 | 37 | * Updated to Stardew Valley 1.3 (including multiplayer). 38 | 39 | ### 1.8.0 40 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 41 | 42 | * Updated to SMAPI 1.15 & 2.0. 43 | 44 | ### 1.7.1 45 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 46 | 47 | * Fixed error in Stardew Valley 1.2. 48 | 49 | ### 1.7.0 50 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 51 | 52 | * Updated to Stardew Valley 1.2. 53 | 54 | ### 1.6.0 55 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 56 | 57 | * Updated to SMAPI 1.9. 58 | 59 | ### 1.5.0 60 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 61 | 62 | * Updated to SMAPI 1.3. 63 | * Fixed the "(press F5 to reload config)" message being shown even though this mod has no config. 64 | 65 | ### 1.4.0 66 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 67 | 68 | * Updated to SMAPI 1.0. 69 | * Added support for Linux/Mac. 70 | 71 | ### 1.3.0 72 | Released 03 April 2016 for SMAPI 0.39.6 or later. 73 | 74 | * Updated to SMAPI 0.39.6. 75 | 76 | ### 1.2.0 77 | Released 28 March 2016 for SMAPI 0.39.3 or later. 78 | 79 | * Updated to SMAPI 0.39.3. 80 | 81 | ### 1.1.0 82 | Released 23 March 2016 for SMAPI 0.39.1 or later. 83 | 84 | * Updated to SMAPI 0.39.1. 85 | 86 | ### 1.0.0 87 | Released 21 March 2016 for SMAPI 0.38.4 or later. 88 | 89 | * Initial release. 90 | -------------------------------------------------------------------------------- /MovementMod/Framework/ModConfig.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Utilities; 3 | 4 | namespace MovementMod.Framework; 5 | 6 | /// The mod configuration. 7 | internal class ModConfig 8 | { 9 | /********* 10 | ** Accessors 11 | *********/ 12 | /// The player speed to add when running (or 0 for no change). 13 | public int PlayerRunningSpeed { get; set; } = 5; 14 | 15 | /// The player speed to add when riding the horse (or 0 for no change). 16 | public int HorseSpeed { get; set; } = 5; 17 | 18 | /// The key which causes the player to sprint. 19 | public KeybindList SprintKey { get; set; } = new(SButton.LeftShift); 20 | 21 | /// The keys which reload the mod config. 22 | public KeybindList ReloadKey { get; set; } = new(SButton.F5); 23 | 24 | /// The multiplier applied to the player speed when sprinting. 25 | public int PlayerSprintingSpeedMultiplier { get; set; } = 2; 26 | 27 | /// The stamina drain each second while sprinting. 28 | public float SprintingStaminaDrainPerSecond { get; set; } = 15; 29 | } 30 | -------------------------------------------------------------------------------- /MovementMod/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using MovementMod.Framework; 3 | using StardewModdingAPI; 4 | using StardewModdingAPI.Events; 5 | using StardewModdingAPI.Utilities; 6 | using StardewValley; 7 | using Zoryn.Common; 8 | 9 | namespace MovementMod; 10 | 11 | /// The main entry point. 12 | public class ModEntry : Mod 13 | { 14 | /********* 15 | ** Properties 16 | *********/ 17 | /// The mod configuration. 18 | private ModConfig Config; 19 | 20 | /// The current speed boost applied to the player. 21 | private readonly PerScreen CurrentSpeed = new(); 22 | 23 | /// The last known player position. 24 | private readonly PerScreen PrevPosition = new(); 25 | 26 | private float ElapsedSeconds => (float)Game1.currentGameTime.ElapsedGameTime.TotalMilliseconds / 1000f; 27 | 28 | 29 | /********* 30 | ** Public methods 31 | *********/ 32 | /// The mod entry point, called after the mod is first loaded. 33 | /// Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files. 34 | public override void Entry(IModHelper helper) 35 | { 36 | CommonHelper.RemoveObsoleteFiles(this, "MovementMod.pdb"); 37 | 38 | this.Config = helper.ReadConfig(); 39 | 40 | helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; 41 | helper.Events.Input.ButtonsChanged += this.OnButtonChanged; 42 | 43 | this.Monitor.Log("Initialized (press F5 to reload config)"); 44 | } 45 | 46 | 47 | /********* 48 | ** Private methods 49 | *********/ 50 | /// Raised after the game state is updated (≈60 times per second). 51 | /// The event sender. 52 | /// The event arguments. 53 | private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) 54 | { 55 | if (!Context.IsWorldReady || Game1.paused || Game1.activeClickableMenu != null) 56 | return; 57 | 58 | if (Game1.currentLocation.currentEvent != null) 59 | { 60 | this.CurrentSpeed.Value = 0; 61 | return; 62 | } 63 | 64 | Farmer player = Game1.player; 65 | if (this.Config.HorseSpeed != 0 && player.mount != null) 66 | this.CurrentSpeed.Value = this.Config.HorseSpeed; 67 | if (this.Config.PlayerRunningSpeed != 0 && player.running) 68 | this.CurrentSpeed.Value = this.Config.PlayerRunningSpeed; 69 | else 70 | this.CurrentSpeed.Value = 0; 71 | 72 | if (this.Config.SprintKey.IsDown()) 73 | { 74 | if (this.Config.SprintingStaminaDrainPerSecond != 0 && player.position.Value != this.PrevPosition.Value) 75 | { 76 | float loss = this.Config.SprintingStaminaDrainPerSecond * this.ElapsedSeconds; 77 | if (player.stamina - loss > 0) 78 | { 79 | player.stamina -= loss; 80 | this.CurrentSpeed.Value *= this.Config.PlayerSprintingSpeedMultiplier; 81 | } 82 | } 83 | else 84 | this.CurrentSpeed.Value *= this.Config.PlayerSprintingSpeedMultiplier; 85 | } 86 | 87 | this.UpdateBuff(player, this.CurrentSpeed.Value); 88 | 89 | this.PrevPosition.Value = player.position.Value; 90 | } 91 | 92 | /// 93 | /// The event sender. 94 | /// The event arguments. 95 | private void OnButtonChanged(object sender, ButtonsChangedEventArgs e) 96 | { 97 | if (this.Config.ReloadKey.JustPressed()) 98 | { 99 | this.Config = this.Helper.ReadConfig(); 100 | this.Monitor.Log("Config reloaded", LogLevel.Info); 101 | } 102 | } 103 | 104 | /// Update the speed buff applied to the player. 105 | /// The player whose buffs to manage. 106 | /// The speed to set. 107 | private void UpdateBuff(Farmer player, int speed) 108 | { 109 | string buffId = this.ModManifest.UniqueID; 110 | 111 | if (speed == 0) 112 | player.buffs.Remove(buffId); 113 | 114 | else if (!player.buffs.AppliedBuffs.TryGetValue(buffId, out Buff buff) || (int)buff.effects.Speed.Value != speed) 115 | { 116 | player.applyBuff( 117 | new Buff(buffId, duration: Buff.ENDLESS) 118 | { 119 | effects = { 120 | Speed = { speed } 121 | }, 122 | visible = false 123 | } 124 | ); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /MovementMod/MovementMod.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MovementMod/README.md: -------------------------------------------------------------------------------- 1 | **Movement Modifier** is a [Stardew Valley](http://stardewvalley.net/) mod which lets you customise 2 | your movement. 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Configure](#configure) 8 | * [Compatibility](#compatibility) 9 | * [See also](#see-also) 10 | 11 | ## Install 12 | 1. [Install the latest version of SMAPI](https://smapi.io). 13 | 2. Install this mod from the releases page. 14 | 3. Run the game using SMAPI. 15 | 16 | ## Use 17 | The mod lets you walk diagonally, sprint quickly (optionally consumes stamina), and customise your 18 | speed when walking, running, or riding the horse by editing the `config.json` file. 19 | 20 | ## Configure 21 | A `config.json` will appear in the mod's folder after you run the game once. You can optionally 22 | open the file in a text editor to configure the mod. If you make a mistake, just delete the file 23 | and it'll be regenerated. 24 | 25 | Available fields: 26 | 27 | field | purpose 28 | -------------------- | ------- 29 | `PlayerRunningSpeed` | The player speed to add when running (or 0 for no change). Default 5. 30 | `HorseSpeed` | The player speed to add when riding the horse (or 0 for no change). Default 5. 31 | `SprintKey` | The key which causes the player to sprint. Default `LeftControl`. 32 | `PlayerSprintingSpeedMultiplier` | The multiplier applied to the player speed when sprinting. Default 2. 33 | `SprintingStaminaDrainPerSecond` | The stamina drain each second while sprinting. Default 15. 34 | 35 | ## Compatibility 36 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 37 | * Works in single-player, multiplayer, and split-screen. 38 | * No known mod conflicts. 39 | 40 | ## See also 41 | * [Release notes](release-notes.md) 42 | -------------------------------------------------------------------------------- /MovementMod/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Movement Modifier", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Lets you change your movement based on a config.", 6 | "UniqueID": "Zoryn.MovementModifier", 7 | "EntryDll": "MovementMod.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /MovementMod/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.0 25 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Updated for Stardew Valley 1.5.5. 28 | * Added split-screen support. 29 | * Added support for [newer keybind features in SMAPI](https://stardewvalleywiki.com/Modding:Player_Guide/Key_Bindings) (controller/mouse buttons, multi-key combos, and alternate keybinds). 30 | * Added config option for the reload key. 31 | 32 | ### 2.7.1 33 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 34 | 35 | * Updated to SMAPI 3.0. 36 | 37 | ### 2.6.0 38 | Released 01 September 2018 for SMAPI 2.6 or later. 39 | 40 | * Updated to Stardew Valley 1.3.28. 41 | 42 | ### 1.9.0 43 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 44 | 45 | * Updated to Stardew Valley 1.3 (including multiplayer). 46 | * Enabled speed boost and sprinting by default. 47 | * Simplified mod configuration. 48 | * Removed walking speed boost (can break cutscenes). 49 | 50 | ### 1.8.0 51 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 52 | 53 | * Updated to SMAPI 1.15 & 2.0. 54 | 55 | ### 1.7.0 56 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 57 | 58 | * Updated to Stardew Valley 1.2. 59 | 60 | ### 1.6.0 61 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 62 | 63 | * Updated to SMAPI 1.9. 64 | 65 | ### 1.5.0 66 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 67 | 68 | * Updated to SMAPI 1.3. 69 | 70 | ### 1.4.0 71 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 72 | 73 | * Updated to SMAPI 1.0. 74 | * Added support for Linux/Mac. 75 | 76 | ### 1.3.0 77 | Released 03 April 2016 for SMAPI 0.39.6 or later. 78 | 79 | * Updated to SMAPI 0.39.6. 80 | * Added sprint feature. 81 | 82 | ### 1.2.0 83 | Released 28 March 2016 for SMAPI 0.39.3 or later. 84 | 85 | * Updated to SMAPI 0.39.3. 86 | * Added hotkey to reload `config.json`. 87 | * Added option to override horse speed. 88 | 89 | ### 1.1.0 90 | Released 23 March 2016 for SMAPI 0.39.1 or later. 91 | 92 | * Updated to SMAPI 0.39.1. 93 | 94 | ### 1.0.0 95 | Released 21 March 2016 for SMAPI 0.38.4 or later. 96 | 97 | * Initial release. 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains my SMAPI mods for Stardew Valley. See the individual mods: 2 | 3 | * [Better RNG](BetterRNG) 4 | * [Calendar Anywhere](CalendarAnywhere) 5 | * [Durable Fences](DurableFences) 6 | * [Fishing Mod](FishingMod) 7 | * [Health Bars](HealthBars) 8 | * [Junimo Deposit Anywhere](JunimoDepositAnywhere) 9 | * [Movement Mod](MovementMod) 10 | * [Regen Mod](RegenMod) 11 | 12 | Forum post: http://community.playstarbound.com/threads/108756/ 13 | 14 | ## Compiling the mods 15 | Installing stable releases from Nexus Mods is recommended for most users. If you really want to 16 | compile the mod yourself, read on. 17 | 18 | These mods use the [crossplatform build config](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme) 19 | so they can be built on Linux, Mac, and Windows without changes. See [the build config documentation](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme) 20 | for troubleshooting. 21 | 22 | ### Compiling a mod for testing 23 | To compile a mod and add it to your game's `Mods` directory: 24 | 25 | 1. Rebuild the project in [Visual Studio](https://www.visualstudio.com/vs/community/) or [MonoDevelop](http://www.monodevelop.com/). 26 | This will compile the code and package it into the mod directory. 27 | 2. Launch the project with debugging. 28 | This will start the game through SMAPI and attach the Visual Studio debugger. 29 | 30 | ### Compiling a mod for release 31 | To package a mod for release: 32 | 33 | 1. Delete the mod's directory in `Mods`. 34 | (This ensures the package is clean and has default configuration.) 35 | 2. Recompile the mod per the previous section. 36 | 3. Create a zip file of the mod's folder in the `Mods` folder. The zip name should include the 37 | mod name and version (like `BetterRNG-1.0.zip`). 38 | -------------------------------------------------------------------------------- /RegenMod/Framework/ModConfig.cs: -------------------------------------------------------------------------------- 1 | using StardewModdingAPI; 2 | using StardewModdingAPI.Utilities; 3 | 4 | namespace RegenMod.Framework; 5 | 6 | /// The mod configuration. 7 | internal class ModConfig 8 | { 9 | /// Whether to constantly regenerate stamina. 10 | public bool RegenStaminaConstant { get; set; } 11 | 12 | /// The amount of stamina to constantly regenerate per second. 13 | public float RegenStaminaConstantAmountPerSecond { get; set; } 14 | 15 | /// Whether to regenerate stamina while standing still. 16 | public bool RegenStaminaStill { get; set; } 17 | 18 | /// The amount of stamina to regenerate per second while standing still. 19 | public float RegenStaminaStillAmountPerSecond { get; set; } 20 | 21 | /// The amount of time the player must stand still to regenerate stamina. 22 | public int RegenStaminaStillTimeRequiredMS { get; set; } = 1000; 23 | 24 | /// Whether to constantly regenerate health. 25 | public bool RegenHealthConstant { get; set; } 26 | 27 | /// The amount of stamina to constantly regenerate per second. 28 | public float RegenHealthConstantAmountPerSecond { get; set; } 29 | 30 | /// Whether to regenerate health while standing still. 31 | public bool RegenHealthStill { get; set; } 32 | 33 | /// The amount of health to regenerate per second while standing still. 34 | public float RegenHealthStillAmountPerSecond { get; set; } 35 | 36 | /// The amount of time the player must stand still to regenerate health. 37 | public int RegenHealthStillTimeRequiredMS { get; set; } = 1000; 38 | 39 | /// The keys which reload the mod config. 40 | public KeybindList ReloadKey { get; set; } = new(SButton.F5); 41 | } 42 | -------------------------------------------------------------------------------- /RegenMod/ModEntry.cs: -------------------------------------------------------------------------------- 1 | using RegenMod.Framework; 2 | using StardewModdingAPI; 3 | using StardewModdingAPI.Events; 4 | using StardewModdingAPI.Utilities; 5 | using StardewValley; 6 | using Zoryn.Common; 7 | using SFarmer = StardewValley.Farmer; 8 | 9 | namespace RegenMod; 10 | 11 | /// The main entry point. 12 | public class ModEntry : Mod 13 | { 14 | /********* 15 | ** Properties 16 | *********/ 17 | /// The mod configuration. 18 | private ModConfig Config; 19 | 20 | /// The health regen carried over from the previous tick. 21 | private readonly PerScreen Health = new(); 22 | 23 | /// The stamina regen carried over from the previous tick. 24 | private readonly PerScreen Stamina = new(); 25 | 26 | /// The time in milliseconds since the player last moved or used a tool. 27 | private readonly PerScreen TimeSinceLastMoved = new(); 28 | 29 | private float ElapsedSeconds => (float)(Game1.currentGameTime.ElapsedGameTime.TotalMilliseconds / 1000); 30 | 31 | 32 | /********* 33 | ** Public methods 34 | *********/ 35 | /// The mod entry point, called after the mod is first loaded. 36 | /// Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files. 37 | public override void Entry(IModHelper helper) 38 | { 39 | CommonHelper.RemoveObsoleteFiles(this, "RegenMod.pdb"); 40 | 41 | this.Config = helper.ReadConfig(); 42 | 43 | helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; 44 | helper.Events.Input.ButtonsChanged += this.OnButtonChanged; 45 | } 46 | 47 | 48 | /********* 49 | ** Private methods 50 | *********/ 51 | /// 52 | /// The event sender. 53 | /// The event arguments. 54 | private void OnButtonChanged(object sender, ButtonsChangedEventArgs e) 55 | { 56 | if (this.Config.ReloadKey.JustPressed()) 57 | { 58 | this.Config = this.Helper.ReadConfig(); 59 | this.Monitor.Log("Config reloaded", LogLevel.Info); 60 | } 61 | } 62 | 63 | /// Raised after the game state is updated (≈60 times per second). 64 | /// The event sender. 65 | /// The event arguments. 66 | private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) 67 | { 68 | if (!Context.IsWorldReady || Game1.paused || Game1.activeClickableMenu != null) 69 | return; 70 | 71 | SFarmer player = Game1.player; 72 | 73 | //detect movement or tool use 74 | this.TimeSinceLastMoved.Value += Game1.currentGameTime.ElapsedGameTime.TotalMilliseconds; 75 | if (player.timerSinceLastMovement == 0) 76 | this.TimeSinceLastMoved.Value = 0; 77 | if (player.UsingTool) 78 | this.TimeSinceLastMoved.Value = 0; 79 | 80 | // health regen 81 | if (this.Config.RegenHealthConstant) 82 | this.Health.Value += this.Config.RegenHealthConstantAmountPerSecond * this.ElapsedSeconds; 83 | if (this.Config.RegenHealthStill) 84 | { 85 | if (this.TimeSinceLastMoved.Value > this.Config.RegenHealthStillTimeRequiredMS) 86 | this.Health.Value += this.Config.RegenHealthStillAmountPerSecond * this.ElapsedSeconds; 87 | } 88 | if (player.health + this.Health.Value >= player.maxHealth) 89 | { 90 | player.health = player.maxHealth; 91 | this.Health.Value = 0; 92 | } 93 | else if (this.Health.Value >= 1) 94 | { 95 | player.health += 1; 96 | this.Health.Value -= 1; 97 | } 98 | else if (this.Health.Value <= -1) 99 | { 100 | player.health -= 1; 101 | this.Health.Value += 1; 102 | } 103 | 104 | // stamina regen 105 | if (this.Config.RegenStaminaConstant) 106 | this.Stamina.Value += this.Config.RegenStaminaConstantAmountPerSecond * this.ElapsedSeconds; 107 | if (this.Config.RegenStaminaStill) 108 | { 109 | if (this.TimeSinceLastMoved.Value > this.Config.RegenStaminaStillTimeRequiredMS) 110 | this.Stamina.Value += this.Config.RegenStaminaStillAmountPerSecond * this.ElapsedSeconds; 111 | } 112 | if (player.Stamina + this.Stamina.Value >= player.MaxStamina) 113 | { 114 | player.Stamina = player.MaxStamina; 115 | this.Stamina.Value = 0; 116 | } 117 | else if (this.Stamina.Value >= 1) 118 | { 119 | player.Stamina += 1; 120 | this.Stamina.Value -= 1; 121 | } 122 | else if (this.Stamina.Value <= -1) 123 | { 124 | player.Stamina -= 1; 125 | this.Stamina.Value += 1; 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /RegenMod/README.md: -------------------------------------------------------------------------------- 1 | **Regen Mod** is a [Stardew Valley](http://stardewvalley.net/) mod which lets you regenerate 2 | health and stamina passively over time (configurable). 3 | 4 | ## Contents 5 | * [Install](#install) 6 | * [Use](#use) 7 | * [Configure](#configure) 8 | * [Compatibility](#compatibility) 9 | * [See also](#see-also) 10 | 11 | ## Install 12 | 1. [Install the latest version of SMAPI](https://smapi.io). 13 | 2. Install this mod from the releases page. 14 | 3. Run the game using SMAPI. 15 | 16 | ## Use 17 | The mod will automatically regenerate your health and stamina passively over time. You can edit the 18 | `config.json` file to customise the regeneration, including... 19 | 20 | * Whether stamina regenerates (including how fast and when); 21 | * Whether stamina _drains_ over time instead; 22 | * Whether health regenerates (including how fast and when); 23 | * Whether health _drains_ over time instead. 24 | 25 | ## Configure 26 | A `config.json` will appear in the mod's folder after you run the game once. You can optionally 27 | open the file in a text editor to configure the mod. If you make a mistake, just delete the file 28 | and it'll be regenerated. 29 | 30 | Available fields: 31 | 32 | field | purpose 33 | -------------------------------- | ------- 34 | `RegenStaminaConstant` | Whether to constantly regenerate stamina. Default false. 35 | `RegenStaminaConstantAmountPerSecond` | The amount of stamina to constantly regenerate per second. Default 0. 36 | `RegenStaminaStill` | Whether to regenerate stamina while standing still. Default false. 37 | `RegenStaminaStillAmountPerSecond` | The amount of stamina to regenerate per second while standing still. Default false. 38 | `RegenStaminaStillTimeRequiredMS` | The amount of time the player must stand still to regenerate stamina, in milliseconds. Default 1000. 39 | `RegenHealthConstant` | Whether to constantly regenerate health. Default false. 40 | `RegenHealthConstantAmountPerSecond` | The amount of stamina to constantly regenerate per second. Default 0. 41 | `RegenHealthStill` | Whether to regenerate health while standing still. Default false. 42 | `RegenHealthStillAmountPerSecond` | The amount of health to regenerate per second while standing still. Default 0. 43 | `RegenHealthStillTimeRequiredMS` | The amount of time the player must stand still to regenerate health. Default 1000. 44 | 45 | ## Compatibility 46 | * Works with Stardew Valley 1.6.9+ on Linux/macOS/Windows. 47 | * Works in single-player, multiplayer, and split-screen. 48 | * No known mod conflicts. 49 | 50 | ## See also 51 | * [Release notes](release-notes.md) 52 | -------------------------------------------------------------------------------- /RegenMod/RegenMod.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RegenMod/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Regen Mod", 3 | "Author": "Zoryn", 4 | "Version": "2.8.5", 5 | "Description": "Lets the player regenerate health and stamina based on config values.", 6 | "UniqueID": "Zoryn.RegenMod", 7 | "EntryDll": "RegenMod.dll", 8 | "MinimumApiVersion": "4.1.2", 9 | "UpdateKeys": [ "GitHub:Zoryn4163/SMAPI-Mods" ] 10 | } 11 | -------------------------------------------------------------------------------- /RegenMod/release-notes.md: -------------------------------------------------------------------------------- 1 | [← back to readme](README.md) 2 | 3 | ## Release notes 4 | ## 2.8.5 5 | Released 04 November 2024 for SMAPI 4.1.2 or later. Updated by Pathoschild. 6 | 7 | * Fixed the previous update being broken on Linux/macOS. 8 | 9 | ## 2.8.4 10 | Released 04 November 2024 for SMAPI 4.1.0 or later. Updated by Pathoschild. 11 | 12 | * Updated for Stardew Valley 1.6.9. 13 | 14 | ## 2.8.3 15 | Released 19 March 2024 for SMAPI 4.0.0 or later. Updated by Pathoschild. 16 | 17 | * Updated for Stardew Valley 1.6. 18 | 19 | ## 2.8.2 20 | Released 25 June 2023 for SMAPI 3.13.0 or later. Updated by Pathoschild. 21 | 22 | * Embedded `.pdb` data into the DLL, which fixes error line numbers in Linux/macOS logs. 23 | 24 | ### 2.8.0 25 | Released 30 December 2021 for SMAPI 3.13.0 or later. Updated by Pathoschild. 26 | 27 | * Updated for Stardew Valley 1.5.5. 28 | * Added split-screen support. 29 | * Added config option for the reload key. 30 | 31 | ### 2.7.1 32 | Released 09 January 2019 for SMAPI 2.10.1 or later. Updated by Pathoschild. 33 | 34 | * Updated to SMAPI 3.0. 35 | 36 | ### 2.7.0 37 | Released 29 October 2018 for SMAPI 2.6 or later. 38 | 39 | * Internal refactoring. 40 | 41 | ### 1.9.0 42 | Released 29 April 2018 for SMAPI 2.6 or later. Updated by Pathoschild. 43 | 44 | * Updated to Stardew Valley 1.3 (including multiplayer). 45 | * Simplified configuration. 46 | 47 | ### 1.8.0 48 | Released 15 June 2017 for SMAPI 1.15 or later. Updated by Pathoschild. 49 | 50 | * Updated to SMAPI 1.15 & 2.0. 51 | 52 | ### 1.7.0 53 | Released 10 May 2017 for SMAPI 1.10 or later. Updated by Pathoschild. 54 | 55 | * Updated to Stardew Valley 1.2. 56 | 57 | ### 1.6.0 58 | Released 07 April 2017 for SMAPI 1.9 or later. Updated by Pathoschild. 59 | 60 | * Updated to SMAPI 1.9. 61 | 62 | ### 1.5.0 63 | Released 04 December 2016 for SMAPI 1.3 or later. Updated by Pathoschild. 64 | 65 | * Updated to SMAPI 1.3. 66 | 67 | ### 1.4.0 68 | Released 31 October 2016 for SMAPI 1.0 or later. Updated by Pathoschild. 69 | 70 | * Updated to SMAPI 1.0. 71 | * Added support for Linux/Mac. 72 | 73 | ### 1.3.0 74 | Released 03 April 2016 for SMAPI 0.39.6 or later. 75 | 76 | * Updated to SMAPI 0.39.6. 77 | 78 | ### 1.2.1 79 | Released 28 March 2016 for SMAPI 0.39.3 or later. 80 | 81 | * Bug fixes. 82 | 83 | ### 1.2.0 84 | Released 28 March 2016 for SMAPI 0.39.3 or later. 85 | 86 | * Updated to SMAPI 0.39.3. 87 | * Added `config.json` to customise regeneration. 88 | * Added hotkey to reload `config.json`. 89 | 90 | ### 1.1.0 91 | Released 23 March 2016 for SMAPI 0.39.1 or later. 92 | 93 | * Updated to SMAPI 0.39.1. 94 | 95 | ### 1.0.0 96 | Released 21 March 2016 for SMAPI 0.38.4 or later. 97 | 98 | * Initial release. 99 | -------------------------------------------------------------------------------- /Zoryn.Mods.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.33530.505 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{D25CE26A-DE3F-47CD-AB0F-19B580C2CB6C}" 7 | ProjectSection(SolutionItems) = preProject 8 | .editorconfig = .editorconfig 9 | .gitattributes = .gitattributes 10 | .gitignore = .gitignore 11 | Directory.Build.props = Directory.Build.props 12 | Directory.Packages.props = Directory.Packages.props 13 | README.md = README.md 14 | EndProjectSection 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterRNG", "BetterRNG\BetterRNG.csproj", "{8BE2D59D-E1F3-4902-9F8C-81CBF4B1A1B5}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalendarAnywhere", "CalendarAnywhere\CalendarAnywhere.csproj", "{37A3CBC3-5DE0-4A3F-902F-904139EFAA34}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DurableFences", "DurableFences\DurableFences.csproj", "{7B37DC4C-21FA-4979-918B-818C2FCF988E}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FishingMod", "FishingMod\FishingMod.csproj", "{9C9E4913-482D-4176-B072-96BC08697E3D}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthBars", "HealthBars\HealthBars.csproj", "{8911BA55-65A5-4022-A797-84F3AAE6BAC1}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JunimoDepositAnywhere", "JunimoDepositAnywhere\JunimoDepositAnywhere.csproj", "{69D62815-3349-422A-BD3C-DBA89DB1B5E7}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MovementMod", "MovementMod\MovementMod.csproj", "{F3A942EC-D60A-44E0-900B-B673F73419C6}" 29 | EndProject 30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegenMod", "RegenMod\RegenMod.csproj", "{1082CA14-2E7A-441E-90E3-E6E7F448E58F}" 31 | EndProject 32 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "_Common", "_Common\_Common.shproj", "{98B203BA-0D08-4789-B857-E3143330AB64}" 33 | EndProject 34 | Global 35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 36 | Debug|Any CPU = Debug|Any CPU 37 | Release|Any CPU = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 40 | {8BE2D59D-E1F3-4902-9F8C-81CBF4B1A1B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {8BE2D59D-E1F3-4902-9F8C-81CBF4B1A1B5}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {8BE2D59D-E1F3-4902-9F8C-81CBF4B1A1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {8BE2D59D-E1F3-4902-9F8C-81CBF4B1A1B5}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {37A3CBC3-5DE0-4A3F-902F-904139EFAA34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {37A3CBC3-5DE0-4A3F-902F-904139EFAA34}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {37A3CBC3-5DE0-4A3F-902F-904139EFAA34}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {37A3CBC3-5DE0-4A3F-902F-904139EFAA34}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {7B37DC4C-21FA-4979-918B-818C2FCF988E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {7B37DC4C-21FA-4979-918B-818C2FCF988E}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {7B37DC4C-21FA-4979-918B-818C2FCF988E}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {7B37DC4C-21FA-4979-918B-818C2FCF988E}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {9C9E4913-482D-4176-B072-96BC08697E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {9C9E4913-482D-4176-B072-96BC08697E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {9C9E4913-482D-4176-B072-96BC08697E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {9C9E4913-482D-4176-B072-96BC08697E3D}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {8911BA55-65A5-4022-A797-84F3AAE6BAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {8911BA55-65A5-4022-A797-84F3AAE6BAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {8911BA55-65A5-4022-A797-84F3AAE6BAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {8911BA55-65A5-4022-A797-84F3AAE6BAC1}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {69D62815-3349-422A-BD3C-DBA89DB1B5E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {69D62815-3349-422A-BD3C-DBA89DB1B5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {69D62815-3349-422A-BD3C-DBA89DB1B5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {69D62815-3349-422A-BD3C-DBA89DB1B5E7}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {F3A942EC-D60A-44E0-900B-B673F73419C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {F3A942EC-D60A-44E0-900B-B673F73419C6}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {F3A942EC-D60A-44E0-900B-B673F73419C6}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {F3A942EC-D60A-44E0-900B-B673F73419C6}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {1082CA14-2E7A-441E-90E3-E6E7F448E58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {1082CA14-2E7A-441E-90E3-E6E7F448E58F}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {1082CA14-2E7A-441E-90E3-E6E7F448E58F}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {1082CA14-2E7A-441E-90E3-E6E7F448E58F}.Release|Any CPU.Build.0 = Release|Any CPU 72 | EndGlobalSection 73 | GlobalSection(SolutionProperties) = preSolution 74 | HideSolutionNode = FALSE 75 | EndGlobalSection 76 | GlobalSection(ExtensibilityGlobals) = postSolution 77 | SolutionGuid = {B5896DFD-302D-4CE1-B29F-144185C24D93} 78 | EndGlobalSection 79 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 80 | _Common\_Common.projitems*{1082ca14-2e7a-441e-90e3-e6e7f448e58f}*SharedItemsImports = 5 81 | _Common\_Common.projitems*{37a3cbc3-5de0-4a3f-902f-904139efaa34}*SharedItemsImports = 5 82 | _Common\_Common.projitems*{69d62815-3349-422a-bd3c-dba89db1b5e7}*SharedItemsImports = 5 83 | _Common\_Common.projitems*{7b37dc4c-21fa-4979-918b-818c2fcf988e}*SharedItemsImports = 5 84 | _Common\_Common.projitems*{8911ba55-65a5-4022-a797-84f3aae6bac1}*SharedItemsImports = 5 85 | _Common\_Common.projitems*{8be2d59d-e1f3-4902-9f8c-81cbf4b1a1b5}*SharedItemsImports = 5 86 | _Common\_Common.projitems*{98b203ba-0d08-4789-b857-e3143330ab64}*SharedItemsImports = 13 87 | _Common\_Common.projitems*{9c9e4913-482d-4176-b072-96bc08697e3d}*SharedItemsImports = 5 88 | _Common\_Common.projitems*{f3a942ec-d60a-44e0-900b-b673f73419c6}*SharedItemsImports = 5 89 | EndGlobalSection 90 | EndGlobal 91 | -------------------------------------------------------------------------------- /Zoryn.Mods.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | DO_NOT_SHOW 3 | Field, Property, Event, Method 4 | Field, Property, Event, Method 5 | UseVarWhenEvident 6 | UseVarWhenEvident 7 | UseVarWhenEvident 8 | ID 9 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy> 10 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy> 11 | <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy></Policy> 12 | <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="AaBb" /></Policy></Policy> 13 | True 14 | True 15 | True 16 | -------------------------------------------------------------------------------- /_Common/CommonHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using StardewModdingAPI; 4 | 5 | namespace Zoryn.Common; 6 | 7 | /// Provides common utility methods for interacting with the game code shared by my various mods. 8 | internal static class CommonHelper 9 | { 10 | /********* 11 | ** Public methods 12 | *********/ 13 | /**** 14 | ** File handling 15 | ****/ 16 | /// Remove one or more obsolete files from the mod folder, if they exist. 17 | /// The mod for which to delete files. 18 | /// The relative file path within the mod's folder. 19 | public static void RemoveObsoleteFiles(IMod mod, params string[] relativePaths) 20 | { 21 | string basePath = mod.Helper.DirectoryPath; 22 | 23 | foreach (string relativePath in relativePaths) 24 | { 25 | string fullPath = Path.Combine(basePath, relativePath); 26 | if (File.Exists(fullPath)) 27 | { 28 | try 29 | { 30 | File.Delete(fullPath); 31 | mod.Monitor.Log($"Removed obsolete file '{relativePath}'."); 32 | } 33 | catch (Exception ex) 34 | { 35 | mod.Monitor.Log($"Failed deleting obsolete file '{relativePath}':\n{ex}"); 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /_Common/_Common.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 98b203ba-0d08-4789-b857-e3143330ab64 7 | 8 | 9 | _Common 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /_Common/_Common.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 98b203ba-0d08-4789-b857-e3143330ab64 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | --------------------------------------------------------------------------------