├── .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 |
--------------------------------------------------------------------------------