diff --git a/BetterShippingBox/BetterShippingBox.csproj b/BetterShippingBox/BetterShippingBox.csproj index fe85bb1..b3b2460 100644 --- a/BetterShippingBox/BetterShippingBox.csproj +++ b/BetterShippingBox/BetterShippingBox.csproj @@ -10,7 +10,10 @@ 4 - C:\Users\Kylindra\Source\SDVMods\_releases + + + $(MSBuildProjectName) + $(SolutionDir)\_releases AnyCPU @@ -30,6 +33,9 @@ x86 + + x86 + @@ -45,11 +51,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/BetterShippingBox/BetterShippingBox/BetterShippingBox.cs b/BetterShippingBox/BetterShippingBox/BetterShippingBox.cs index 5259404..c701796 100644 --- a/BetterShippingBox/BetterShippingBox/BetterShippingBox.cs +++ b/BetterShippingBox/BetterShippingBox/BetterShippingBox.cs @@ -16,7 +16,7 @@ public override void Entry(IModHelper helper) private void MenuEvents_OnMenuChanged(object sender, EventArgsClickableMenuChanged e) { - if (e.NewMenu is ItemGrabMenu && (e.NewMenu as ItemGrabMenu).shippingBin) + if ((e.NewMenu is ItemGrabMenu menu) && (menu.shippingBin)) { Game1.activeClickableMenu = new BetterShippingMenu(); } diff --git a/BetterShippingBox/packages.config b/BetterShippingBox/packages.config index d601731..f749d09 100644 --- a/BetterShippingBox/packages.config +++ b/BetterShippingBox/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/ClimateDataExamin/App.config b/ClimateDataExamin/App.config deleted file mode 100644 index 88fa402..0000000 --- a/ClimateDataExamin/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ClimateDataExamin/ClimateDataExaminer.csproj b/ClimateDataExamin/ClimateDataExaminer.csproj deleted file mode 100644 index df7efc5..0000000 --- a/ClimateDataExamin/ClimateDataExaminer.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - - - Debug - AnyCPU - {696260C4-50B9-4EE6-BCAD-B2DD085BE40E} - Exe - ClimateDataExamin - ClimateDataExamin - v4.5.2 - 512 - true - - - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - - Always - - - - \ No newline at end of file diff --git a/ClimateDataExamin/Extensions.cs b/ClimateDataExamin/Extensions.cs deleted file mode 100644 index aae0637..0000000 --- a/ClimateDataExamin/Extensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace ClimateDataExaminer -{ - public static class TwilightExtensions - { - public static string GetRandomItem(this string[] array, Random r) - { - int l = array.Length; - - return array[r.Next(l)]; - } - - public static bool Contains(this T[] array, T val) - { - foreach (T i in array) - { - if (val.Equals(i)) - return true; - } - - return false; - } - - public static bool IsBetween(this int val, int lowBound, int highBound) - { - if (val > lowBound && val < highBound) - return true; - - return false; - } - - public static bool IsBetweenInc(this int val, int lowBound, int highBound) - { - if (val >= lowBound && val <= highBound) - return true; - - return false; - } - } -} diff --git a/ClimateDataExamin/FerngillClimate.cs b/ClimateDataExamin/FerngillClimate.cs deleted file mode 100644 index 5909f88..0000000 --- a/ClimateDataExamin/FerngillClimate.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Generic; - -namespace ClimateDataExaminer -{ - public class FerngillClimate - { - public bool AllowRainInWinter; - public List ClimateSequences; - - //constructor - public FerngillClimate() - { - ClimateSequences = new List(); - } - - //constructor - public FerngillClimate(List fCTS) - { - ClimateSequences = new List(); - foreach (FerngillClimateTimeSpan CTS in fCTS) - this.ClimateSequences.Add(new FerngillClimateTimeSpan(CTS)); - } - - //climate access functions - public FerngillClimateTimeSpan GetClimateForDate(SDVDate Target) - { - foreach (FerngillClimateTimeSpan s in ClimateSequences) - { - SDVDate BeginDate = new SDVDate(s.BeginSeason, s.BeginDay); - SDVDate EndDate = new SDVDate(s.EndSeason, s.EndDay); - - if (Target.IsBetweenInc(BeginDate, EndDate)) - return s; - } - - return default(FerngillClimateTimeSpan); - } - } -} - diff --git a/ClimateDataExamin/FerngillClimateTimeSpan.cs b/ClimateDataExamin/FerngillClimateTimeSpan.cs deleted file mode 100644 index 41751bd..0000000 --- a/ClimateDataExamin/FerngillClimateTimeSpan.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace ClimateDataExaminer -{ - public class FerngillClimateTimeSpan - { - public string BeginSeason; - public string EndSeason; - public int BeginDay; - public int EndDay; - public List WeatherChances; - - public FerngillClimateTimeSpan() - { - this.WeatherChances = new List(); - } - - public FerngillClimateTimeSpan(string BeginSeason, string EndSeason, int BeginDay, int EndDay, List wp) - { - this.BeginSeason = BeginSeason; - this.EndSeason = EndSeason; - - this.BeginDay = BeginDay; - this.EndDay = EndDay; - this.WeatherChances = new List(); - - foreach (WeatherParameters w in wp) - { - this.WeatherChances.Add(new WeatherParameters(w)); - } - - } - - public FerngillClimateTimeSpan(FerngillClimateTimeSpan CTS) - { - this.WeatherChances = new List(); - foreach (WeatherParameters w in CTS.WeatherChances) - this.WeatherChances.Add(new WeatherParameters(w)); - } - - public void AddWeatherChances(WeatherParameters wp) - { - if (this.WeatherChances is null) - WeatherChances = new List(); - - WeatherChances.Add(new WeatherParameters(wp)); - } - - public double RetrieveOdds(MersenneTwister dice, string weather, int day) - { - double Odd = 0; - - List wp = (List)this.WeatherChances.Where(w => w.WeatherType == weather); - - if (wp.Count == 0) - return 0; - - Odd = wp[0].BaseValue + (wp[0].ChangeRate * day); - RangePair range = new RangePair(wp[0].VariableLowerBound, wp[0].VariableHigherBound); - Odd = Odd + range.RollInRange(dice); - - //sanity check. - if (Odd < 0) Odd = 0; - if (Odd > 1) Odd = 1; - - return Odd; - } - - public double RetrieveTemp(MersenneTwister dice, string temp, int day) - { - double Temp = 0; - List wp = (List)this.WeatherChances.Where(w => w.WeatherType == temp); - - if (wp.Count == 0) - return 0; - - Temp = wp[0].BaseValue + (wp[0].ChangeRate * day); - RangePair range = new RangePair(wp[0].VariableLowerBound, wp[0].VariableHigherBound); - Temp = Temp + range.RollInRange(dice); - - return Temp; - } - } -} diff --git a/ClimateDataExamin/MersenneTwister.cs b/ClimateDataExamin/MersenneTwister.cs deleted file mode 100644 index 0e61ab1..0000000 --- a/ClimateDataExamin/MersenneTwister.cs +++ /dev/null @@ -1,578 +0,0 @@ -#region License -// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com) -/* - * This license governs use of the accompanying software. If you use the software, you - * accept this license. If you do not accept the license, do not use the software. - * - * 1. Definitions - * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the - * same meaning here as under U.S. copyright law. - * A "contribution" is the original software, or any additions or changes to the software. - * A "contributor" is any person that distributes its contribution under this license. - * "Licensed patents" are a contributor's patent claims that read directly on its contribution. - * - * 2. Grant of Rights - * (A) Copyright Grant- Subject to the terms of this license, including the license conditions - * and limitations in section 3, each contributor grants you a non-exclusive, worldwide, - * royalty-free copyright license to reproduce its contribution, prepare derivative works - * of its contribution, and distribute its contribution or any derivative works that you create. - * (B) Patent Grant- Subject to the terms of this license, including the license conditions and - * limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free - * license under its licensed patents to make, have made, use, sell, offer for sale, import, - * and/or otherwise dispose of its contribution in the software or derivative works of the - * contribution in the software. - * - * 3. Conditions and Limitations - * (A) No Trademark License- This license does not grant you rights to use any contributors' - * name, logo, or trademarks. - * (B) If you bring a patent claim against any contributor over patents that you claim are - * infringed by the software, your patent license from such contributor to the software - * ends automatically. - * (C) If you distribute any portion of the software, you must retain all copyright, patent, - * trademark, and attribution notices that are present in the software. - * (D) If you distribute any portion of the software in source code form, you may do so only under - * this license by including a complete copy of this license with your distribution. If you - * distribute any portion of the software in compiled or object code form, you may only do so - * under a license that complies with this license. - * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no - * express warranties, guarantees or conditions. You may have additional consumer rights under - * your local laws which this license cannot change. To the extent permitted under your local laws, - * the contributors exclude the implied warranties of merchantability, fitness for a particular - * purpose and non-infringement. - * - */ - -// Adapted from: - -/* C# Version Copyright (C) 2001-2004 Akihilo Kramot (Takel). */ -/* C# porting from a C-program for MT19937, originaly coded by */ -/* Takuji Nishimura and Makoto Matsumoto, considering the suggestions by */ -/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ -/* This library is free software under the Artistic license: */ -/* */ -/* You can find the original C-program at */ -/* http://www.math.keio.ac.jp/~matumoto/mt.html */ -/* */ - -// and: - -///////////////////////////////////////////////////////////////////////////// -// C# Version Copyright (c) 2003 CenterSpace Software, LLC // -// // -// This code is free software under the Artistic license. // -// // -// CenterSpace Software // -// 2098 NW Myrtlewood Way // -// Corvallis, Oregon, 97330 // -// USA // -// http://www.centerspace.net // -///////////////////////////////////////////////////////////////////////////// - -// and, of course: - -/* - A C-program for MT19937, with initialization improved 2002/2/10. - Coded by Takuji Nishimura and Makoto Matsumoto. - This is a faster version by taking Shawn Cokus's optimization, - Matthe Bellew's simplification, Isaku Wada's real version. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ -#endregion - -using System; - -namespace ClimateDataExaminer -{ -#pragma warning disable IDE1006 // Naming Styles - /// - /// Generates pseudo-random numbers using the Mersenne Twister algorithm. - /// - /// - /// See - /// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html for details - /// on the algorithm. - /// - public class MersenneTwister : Random - { - /// - /// Creates a new pseudo-random number generator with a given seed. - /// - /// A value to use as a seed. - public MersenneTwister(Int32 seed) - { - unchecked - { - init((UInt32)seed); - } - } - - /// - /// Creates a new pseudo-random number generator with a default seed. - /// - /// - /// new (). - /// is used for the seed. - /// - public MersenneTwister() - : this(new Random().Next()) /* a default initial seed is used */ - { } - - /// - /// Creates a pseudo-random number generator initialized with the given array. - /// - /// The array for initializing keys. - public MersenneTwister(Int32[] initKey) - { - if (initKey == null) - { - throw new ArgumentNullException("initKey"); - } - - UInt32[] initArray = new UInt32[initKey.Length]; - - for (int i = 0; i < initKey.Length; ++i) - { - initArray[i] = (UInt32)initKey[i]; - } - - init(initArray); - } - - /// - /// Returns the next pseudo-random . - /// - /// A pseudo-random value. - //[CLSCompliant(false)] - public virtual UInt32 NextUInt32() - { - return GenerateUInt32(); - } - - /// - /// Returns the next pseudo-random - /// up to . - /// - /// - /// The maximum value of the pseudo-random number to create. - /// - /// - /// A pseudo-random value which is at most . - /// - //[CLSCompliant(false)] - public virtual UInt32 NextUInt32(UInt32 maxValue) - { - return (UInt32)(GenerateUInt32() / ((Double)UInt32.MaxValue / maxValue)); - } - - /// - /// Returns the next pseudo-random at least - /// and up to . - /// - /// The minimum value of the pseudo-random number to create. - /// The maximum value of the pseudo-random number to create. - /// - /// A pseudo-random value which is at least - /// and at most . - /// - /// - /// If >= . - /// - //[CLSCompliant(false)] - public virtual UInt32 NextUInt32(UInt32 minValue, UInt32 maxValue) /* throws ArgumentOutOfRangeException */ - { - if (minValue >= maxValue) - { - throw new ArgumentOutOfRangeException(); - } - - return (UInt32)(GenerateUInt32() / ((Double)UInt32.MaxValue / (maxValue - minValue)) + minValue); - } - - /// - /// Returns the next pseudo-random . - /// - /// A pseudo-random value. - public override Int32 Next() - { - return Next(Int32.MaxValue); - } - - /// - /// Returns the next pseudo-random up to . - /// - /// The maximum value of the pseudo-random number to create. - /// - /// A pseudo-random value which is at most . - /// - /// - /// When < 0. - /// - public override Int32 Next(Int32 maxValue) - { - if (maxValue <= 1) - { - if (maxValue < 0) - { - throw new ArgumentOutOfRangeException(); - } - - return 0; - } - - return (Int32)(NextDouble() * maxValue); - } - - /// - /// Returns the next pseudo-random - /// at least - /// and up to . - /// - /// The minimum value of the pseudo-random number to create. - /// The maximum value of the pseudo-random number to create. - /// A pseudo-random Int32 value which is at least and at - /// most . - /// - /// If >= . - /// - public override Int32 Next(Int32 minValue, Int32 maxValue) - { - if (maxValue <= minValue) - { - throw new ArgumentOutOfRangeException(); - } - - if (maxValue == minValue) - { - return minValue; - } - - return Next(maxValue - minValue) + minValue; - } - - /// - /// Fills a buffer with pseudo-random bytes. - /// - /// The buffer to fill. - /// - /// If == . - /// - public override void NextBytes(Byte[] buffer) - { - // [codekaizen: corrected this to check null before checking length.] - if (buffer == null) - { - throw new ArgumentNullException(); - } - - Int32 bufLen = buffer.Length; - - for (Int32 idx = 0; idx < bufLen; ++idx) - { - buffer[idx] = (Byte)Next(256); - } - } - - /// - /// Returns the next pseudo-random value. - /// - /// A pseudo-random double floating point value. - /// - /// - /// There are two common ways to create a double floating point using MT19937: - /// using and dividing by 0xFFFFFFFF + 1, - /// or else generating two double words and shifting the first by 26 bits and - /// adding the second. - /// - /// - /// In a newer measurement of the randomness of MT19937 published in the - /// journal "Monte Carlo Methods and Applications, Vol. 12, No. 5-6, pp. 385 – 393 (2006)" - /// entitled "A Repetition Test for Pseudo-Random Number Generators", - /// it was found that the 32-bit version of generating a double fails at the 95% - /// confidence level when measuring for expected repetitions of a particular - /// number in a sequence of numbers generated by the algorithm. - /// - /// - /// Due to this, the 53-bit method is implemented here and the 32-bit method - /// of generating a double is not. If, for some reason, - /// the 32-bit method is needed, it can be generated by the following: - /// - /// (Double)NextUInt32() / ((UInt64)UInt32.MaxValue + 1); - /// - /// - /// - public override Double NextDouble() - { - return compute53BitRandom(0, InverseOnePlus53BitsOf1s); - } - - /// - /// Returns a pseudo-random number greater than or equal to zero, and - /// either strictly less than one, or less than or equal to one, - /// depending on the value of the given parameter. - /// - /// - /// If , the pseudo-random number returned will be - /// less than or equal to one; otherwise, the pseudo-random number returned will - /// be strictly less than one. - /// - /// - /// If is , - /// this method returns a double-precision pseudo-random number greater than - /// or equal to zero, and less than or equal to one. - /// If is , this method - /// returns a double-precision pseudo-random number greater than or equal to zero and - /// strictly less than one. - /// - public Double NextDouble(Boolean includeOne) - { - return includeOne ? compute53BitRandom(0, Inverse53BitsOf1s) : NextDouble(); - } - - /// - /// Returns a pseudo-random number greater than 0.0 and less than 1.0. - /// - /// A pseudo-random number greater than 0.0 and less than 1.0. - public Double NextDoublePositive() - { - return compute53BitRandom(0.5, Inverse53BitsOf1s); - } - - /// - /// Returns a pseudo-random number between 0.0 and 1.0. - /// - /// - /// A single-precision floating point number greater than or equal to 0.0, - /// and less than 1.0. - /// - public Single NextSingle() - { - return (Single)NextDouble(); - } - - /// - /// Returns a pseudo-random number greater than or equal to zero, and either strictly - /// less than one, or less than or equal to one, depending on the value of the - /// given boolean parameter. - /// - /// - /// If , the pseudo-random number returned will be - /// less than or equal to one; otherwise, the pseudo-random number returned will - /// be strictly less than one. - /// - /// - /// If is , this method returns a - /// single-precision pseudo-random number greater than or equal to zero, and less - /// than or equal to one. If is , - /// this method returns a single-precision pseudo-random number greater than or equal to zero and - /// strictly less than one. - /// - public Single NextSingle(Boolean includeOne) - { - return (Single)NextDouble(includeOne); - } - - /// - /// Returns a pseudo-random number greater than 0.0 and less than 1.0. - /// - /// A pseudo-random number greater than 0.0 and less than 1.0. - public Single NextSinglePositive() - { - return (Single)NextDoublePositive(); - } - - /// - /// Generates a new pseudo-random . - /// - /// A pseudo-random . - //[CLSCompliant(false)] - protected UInt32 GenerateUInt32() - { - UInt32 y; - - /* _mag01[x] = x * MatrixA for x=0,1 */ - if (_mti >= N) /* generate N words at one time */ - { - Int16 kk = 0; - - for (; kk < N - M; ++kk) - { - y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask); - _mt[kk] = _mt[kk + M] ^ (y >> 1) ^ _mag01[y & 0x1]; - } - - for (; kk < N - 1; ++kk) - { - y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask); - _mt[kk] = _mt[kk + (M - N)] ^ (y >> 1) ^ _mag01[y & 0x1]; - } - - y = (_mt[N - 1] & UpperMask) | (_mt[0] & LowerMask); - _mt[N - 1] = _mt[M - 1] ^ (y >> 1) ^ _mag01[y & 0x1]; - - _mti = 0; - } - - y = _mt[_mti++]; - y ^= temperingShiftU(y); - y ^= temperingShiftS(y) & TemperingMaskB; - y ^= temperingShiftT(y) & TemperingMaskC; - y ^= temperingShiftL(y); - - return y; - } - - /* Period parameters */ - private const Int32 N = 624; - private const Int32 M = 397; - private const UInt32 MatrixA = 0x9908b0df; /* constant vector a */ - private const UInt32 UpperMask = 0x80000000; /* most significant w-r bits */ - private const UInt32 LowerMask = 0x7fffffff; /* least significant r bits */ - - /* Tempering parameters */ - private const UInt32 TemperingMaskB = 0x9d2c5680; - private const UInt32 TemperingMaskC = 0xefc60000; - - private static UInt32 temperingShiftU(UInt32 y) - - { - return (y >> 11); - } - - private static UInt32 temperingShiftS(UInt32 y) - { - return (y << 7); - } - - private static UInt32 temperingShiftT(UInt32 y) - { - return (y << 15); - } - - private static UInt32 temperingShiftL(UInt32 y) - { - return (y >> 18); - } - - private readonly UInt32[] _mt = new UInt32[N]; /* the array for the state vector */ - private Int16 _mti; - - private static readonly UInt32[] _mag01 = { 0x0, MatrixA }; - - private void init(UInt32 seed) - { - unchecked - { - _mt[0] = seed & 0xffffffffU; - - for (_mti = 1; _mti < N; _mti++) - { - _mt[_mti] = (uint)(1812433253U * (_mt[_mti - 1] ^ (_mt[_mti - 1] >> 30)) + _mti); - // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. - // In the previous versions, MSBs of the seed affect - // only MSBs of the array _mt[]. - // 2002/01/09 modified by Makoto Matsumoto - _mt[_mti] &= 0xffffffffU; - // for >32 bit machines - } - } - } - - private void init(UInt32[] key) - { - Int32 i, j, k; - init(19650218U); - - Int32 keyLength = key.Length; - i = 1; j = 0; - k = (N > keyLength ? N : keyLength); - - for (; k > 0; k--) - { - _mt[i] = (uint)((_mt[i] ^ ((_mt[i - 1] ^ (_mt[i - 1] >> 30)) * 1664525U)) + key[j] + j); /* non linear */ - _mt[i] &= 0xffffffffU; // for WORDSIZE > 32 machines - i++; j++; - if (i >= N) { _mt[0] = _mt[N - 1]; i = 1; } - if (j >= keyLength) j = 0; - } - - for (k = N - 1; k > 0; k--) - { - _mt[i] = (uint)((_mt[i] ^ ((_mt[i - 1] ^ (_mt[i - 1] >> 30)) * 1566083941U)) - i); /* non linear */ - _mt[i] &= 0xffffffffU; // for WORDSIZE > 32 machines - i++; - - if (i < N) - { - continue; - } - - _mt[0] = _mt[N - 1]; i = 1; - } - - _mt[0] = 0x80000000U; // MSB is 1; assuring non-zero initial array - } - - - // 9007199254740991.0 is the maximum double value which the 53 significand - // can hold when the exponent is 0. - private const Double FiftyThreeBitsOf1s = 9007199254740991.0; - // Multiply by inverse to (vainly?) try to avoid a division. - private const Double Inverse53BitsOf1s = 1.0 / FiftyThreeBitsOf1s; - private const Double OnePlus53BitsOf1s = FiftyThreeBitsOf1s + 1; - private const Double InverseOnePlus53BitsOf1s = 1.0 / OnePlus53BitsOf1s; - - private Double compute53BitRandom(Double translate, Double scale) - { - // get 27 pseudo-random bits - UInt64 a = (UInt64)GenerateUInt32() >> 5; - // get 26 pseudo-random bits - UInt64 b = (UInt64)GenerateUInt32() >> 6; - - // shift the 27 pseudo-random bits (a) over by 26 bits (* 67108864.0) and - // add another pseudo-random 26 bits (+ b). - return ((a * 67108864.0 + b) + translate) * scale; - - // What about the following instead of the above? Is the multiply better? - // Why? (Is it the FMUL instruction? Does this count in .Net? Will the JITter notice?) - //return BitConverter.Int64BitsToDouble((a << 26) + b)); - } - } -#pragma warning restore IDE1006 // Naming Styles -} \ No newline at end of file diff --git a/ClimateDataExamin/Program.cs b/ClimateDataExamin/Program.cs deleted file mode 100644 index f695179..0000000 --- a/ClimateDataExamin/Program.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using Newtonsoft.Json; -using System.IO; -using System.Text; - -namespace ClimateDataExaminer -{ - class Program - { - private readonly static JsonSerializerSettings JsonSettings = new JsonSerializerSettings - { - Formatting = Formatting.Indented, - ObjectCreationHandling = ObjectCreationHandling.Replace, // avoid issue where default ICollection values are duplicated each time the config is loaded - }; - - static void Main(string[] args) - { - FerngillClimate OurClimate = ReadJsonFile("enhanced.json"); - StringBuilder outputString = new StringBuilder(); - - Console.WriteLine("Parsing Data.."); - outputString.AppendLine("Parsing Data.."); - - //the goal of this is to produce a write up per time span of outputs. - //Example: Time Span is Season: X K to Y Z - // - //Weather Parameters [1..n]: Type 'K', Equation: XD + Y , Variability: -A to +B - // Effective Range: [-C to +E] - - Console.WriteLine($"Settings: Allow Rain in Winter set to {OurClimate.AllowRainInWinter}"); - outputString.AppendLine($"Settings: Allow Rain in Winter set to {OurClimate.AllowRainInWinter}"); - - foreach (FerngillClimateTimeSpan span in OurClimate.ClimateSequences) - { - //pull the time span. - Console.WriteLine($"Time Span is Season {span.BeginSeason} {span.BeginDay} to " + - $"{span.EndSeason} {span.EndDay}"); - Console.WriteLine(); - - outputString.AppendLine($"Time Span is Season {span.BeginSeason} {span.BeginDay} to " + - $"{span.EndSeason} {span.EndDay}"); - outputString.AppendLine(); - - //verify the span is valid - if (SDVDate.LesserThan(span.EndSeason, span.EndDay, span.BeginSeason, span.BeginDay)) - { - Console.WriteLine("INVALID SPAN. The Ending date must be equal or greater than the beginning date."); - outputString.AppendLine("INVALID SPAN. The Ending date must be equal or greater than the beginning date."); - continue; - } - - //pull the parameters - for (int i = 0; i < span.WeatherChances.Count; i++) - { - Console.Write($"Weather Parameters {i}: Type {span.WeatherChances[i].WeatherType}, "); - Console.WriteLine($" Equation: {span.WeatherChances[i].ChangeRate}x + {span.WeatherChances[i].BaseValue} "); - Console.WriteLine($"Varibility: {span.WeatherChances[i].VariableLowerBound} to {span.WeatherChances[i].VariableHigherBound}"); - - outputString.Append($"Weather Parameters {i}: Type {span.WeatherChances[i].WeatherType}, "); - outputString.AppendLine($" Equation: {span.WeatherChances[i].ChangeRate}x + {span.WeatherChances[i].BaseValue} "); - outputString.AppendLine($"Varibility: {span.WeatherChances[i].VariableLowerBound} to {span.WeatherChances[i].VariableHigherBound}"); - - //calc effective range - double min = 9000; - double max = -9000; - int start = span.BeginDay; - int end = span.EndDay; - - if (span.BeginSeason != span.EndSeason) - { - for (int j = span.BeginDay; j <= 28; j++) - { - double val = span.WeatherChances[i].ChangeRate * j + span.WeatherChances[i].BaseValue; - double lVal = val + span.WeatherChances[i].VariableLowerBound; - double hVal = val + span.WeatherChances[i].VariableHigherBound; - - Console.WriteLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - outputString.AppendLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - - if (lVal < min) - min = lVal; - if (hVal > max) - max = hVal; - - } - - for (int j = 1; j <= span.EndDay; j++) - { - double val = span.WeatherChances[i].ChangeRate * j + span.WeatherChances[i].BaseValue; - double lVal = val + span.WeatherChances[i].VariableLowerBound; - double hVal = val + span.WeatherChances[i].VariableHigherBound; - Console.WriteLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - outputString.AppendLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - - if (lVal < min) - min = lVal; - if (hVal > max) - max = hVal; - } - } - else - { - for (int j = start; j <= end; j++) - { - double val = span.WeatherChances[i].ChangeRate * j + span.WeatherChances[i].BaseValue; - double lVal = val + span.WeatherChances[i].VariableLowerBound; - double hVal = val + span.WeatherChances[i].VariableHigherBound; - Console.WriteLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - outputString.AppendLine($"Testing: Generated Value for day [{j}] is {lVal} and {hVal}"); - - if (lVal < min) - min = lVal; - if (hVal > max) - max = hVal; - } - } - - - Console.WriteLine($" Effective Range: [{min.ToString("F2")} to {max.ToString("F2")}]"); - Console.WriteLine(); - - outputString.AppendLine($" Effective Range: [{min.ToString("F2")} to {max.ToString("F2")}]"); - outputString.AppendLine(); - } - } - - File.WriteAllText(@"output.txt", outputString.ToString()); - Console.ReadLine(); - - } - - public static TModel ReadJsonFile(string fullPath) - where TModel : class - { - // validate - if (string.IsNullOrWhiteSpace(fullPath)) - throw new ArgumentException("The file path is empty or invalid.", nameof(fullPath)); - - // read file - string json; - try - { - json = File.ReadAllText(fullPath); - } - catch (Exception ex) when (ex is DirectoryNotFoundException || ex is FileNotFoundException) - { - return null; - } - - // deserialise model - return JsonConvert.DeserializeObject(json, JsonSettings); - } - } -} diff --git a/ClimateDataExamin/Properties/AssemblyInfo.cs b/ClimateDataExamin/Properties/AssemblyInfo.cs deleted file mode 100644 index 924e33f..0000000 --- a/ClimateDataExamin/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ClimateDataExamin")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ClimateDataExamin")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("696260c4-50b9-4ee6-bcad-b2dd085be40e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ClimateDataExamin/RangePair.cs b/ClimateDataExamin/RangePair.cs deleted file mode 100644 index 1e5bf04..0000000 --- a/ClimateDataExamin/RangePair.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace ClimateDataExaminer -{ - /// - /// generic pair struct - /// - public struct RangePair - { - /// - /// Lower bound - /// - public double LowerBound; - - /// - /// Higher bound - /// - public double HigherBound; - - /// - /// Constructor - /// - /// Lower bound - /// Higher bound - public RangePair(double l, double h) - { - this.LowerBound = l; - this.HigherBound = h; - } - - /// - /// Basic constructor - /// - /// The value for this pair - public RangePair(double r) - { - this.LowerBound = this.HigherBound = r; - } - - /// - /// Returns an item in range between Lower and Higher Bound - /// - /// The random object - /// Number in range - public double RollInRange(MersenneTwister d) - { - if (HigherBound == LowerBound) - return LowerBound; - - return (d.NextDoublePositive() * (HigherBound - LowerBound) + LowerBound); - } - } -} diff --git a/ClimateDataExamin/SDVDate.cs b/ClimateDataExamin/SDVDate.cs deleted file mode 100644 index 2a4e916..0000000 --- a/ClimateDataExamin/SDVDate.cs +++ /dev/null @@ -1,322 +0,0 @@ -using System; - -namespace ClimateDataExaminer -{ - public class SDVDate - { - public string Season { get; set; } - public int Day { get; set; } - - public static string[] Seasons = new string[] - { - "spring", - "summer", - "fall", - "winter" - }; - - public SDVDate(string s, int d) - { - s = s.ToLower(); - - if (!Seasons.Contains(s)) - throw new ArgumentOutOfRangeException("The season must be one of the four seasons"); - - if (d > 28) - throw new ArgumentOutOfRangeException("The day can be no larger than 28"); - - Season = s; - Day = d; - } - - public override bool Equals(object obj) - { - if (obj is SDVDate i) - { - if (i.Season == Season && i.Day == Day) - return true; - } - - return false; - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public static bool operator ==(SDVDate s1, SDVDate s2) - { - if (s1.Season == s2.Season && s1.Day == s2.Day) - return true; - else - return false; - } - - public static SDVDate operator -(SDVDate s1, int s2) - { - int day = s1.Day - s2; - string season = s1.Season; - while (day < 1) - { - season = SDVDate.GetPrevSeason(season); - day += 28; - } - - return new SDVDate(season, day); - } - - public static SDVDate operator +(SDVDate s1, int s2) - { - int day = s1.Day + s2; - string season = s1.Season; - while (day > 28) - { - season = SDVDate.GetNextSeason(season); - day -= 28; - } - - return new SDVDate(season, day); - } - - public static bool operator !=(SDVDate s1, SDVDate s2) - { - if (s1.Season == s2.Season && s1.Day == s2.Day) - return false; - else - return true; - } - - public static bool NotEquals(SDVDate s1, string s2, int d2) - { - return (s1 != new SDVDate(s2, d2)); - } - - public static bool Equals(SDVDate s1, string s2, int d2) - { - return (s1 == new SDVDate(s2, d2)); - } - - public static bool GreaterThan(SDVDate s1, string s2, int d2) - { - return (s1 > new SDVDate(s2, d2)); - } - - public static bool GreaterOrEqualsThan(SDVDate s1, string s2, int d2) - { - return (s1 >= new SDVDate(s2, d2)); - } - - public static bool LesserThan(SDVDate s1, string s2, int d2) - { - return (s1 < new SDVDate(s2, d2)); - } - - public static bool LesserOrEqualsThan(SDVDate s1, string s2, int d2) - { - return (s1 <= new SDVDate(s2, d2)); - } - - public static bool NotEquals(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1,d1) != new SDVDate(s2, d2)); - } - - public static bool Equals(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1, d1) == new SDVDate(s2, d2)); - } - - public static bool GreaterThan(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1,d1) > new SDVDate(s2, d2)); - } - - public static bool GreaterOrEqualsThan(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1,d1) >= new SDVDate(s2, d2)); - } - - public static bool LesserThan(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1,d1) < new SDVDate(s2, d2)); - } - - public static bool LesserOrEqualsThan(string s1, int d1, string s2, int d2) - { - return (new SDVDate(s1,d1) <= new SDVDate(s2, d2)); - } - - public static bool operator >(SDVDate s1, SDVDate s2) - { - //handle same season first. - if (s1.Season == s2.Season && s1.Day > s2.Day) - return true; - else if (s1.Season == s2.Season && !(s1.Day > s2.Day)) - return false; - - //handle different season - if (s1.Season == "winter" && s2.Season != "winter") - return true; - - if (s1.Season == "fall" && (s2.Season == "summer" || s2.Season == "spring")) - return true; - - if (s1.Season == "summer" && s2.Season == "spring") - return true; - - return false; - } - - public static bool operator <(SDVDate s1, SDVDate s2) - { - //handle same season first. - if (s1.Season == s2.Season && s1.Day < s2.Day) - return true; - else if (s1.Season == s2.Season && !(s1.Day < s2.Day)) - return false; - - //handle different season - if (s1.Season == "spring" && (s2.Season != "spring")) - return true; - - if (s1.Season == "summer" && (s2.Season == "fall" || s2.Season == "winter")) - return true; - - if (s1.Season == "fall" && s2.Season == "winter") - return true; - - return false; - } - - public static bool operator <=(SDVDate s1, SDVDate s2) - { - //handle same season first. - if (s1.Season == s2.Season && s1.Day <= s2.Day) - return true; - else if (s1.Season == s2.Season && !(s1.Day <= s2.Day)) - return false; - - //handle different season - if (s1.Season == "spring" && (s2.Season != "spring")) - return true; - - if (s1.Season == "summer" && (s2.Season == "fall" || s2.Season == "winter")) - return true; - - if (s1.Season == "fall" && s2.Season == "winter") - return true; - - return false; - } - - public static bool operator >=(SDVDate s1, SDVDate s2) - { - if (s1.Season == s2.Season && s1.Day >= s2.Day) - return true; - else if (s1.Season == s2.Season && !(s1.Day >= s2.Day)) - return false; - - //handle different season - if (s1.Season == "winter" && s2.Season != "winter") - return true; - - if (s1.Season == "fall" && (s2.Season == "summer" || s2.Season == "spring")) - return true; - - if (s1.Season == "summer" && s2.Season == "spring") - return true; - - return false; - } - - public bool IsBetween(SDVDate lower, SDVDate higher) - { - if (this > lower && this < higher) - return true; - else - return false; - } - - public bool IsBetweenInc(SDVDate lower, SDVDate higher) - { - if (this >= lower && this <= higher) - return true; - else - return false; - } - - public static SDVDate GetNextDay(SDVDate current) - { - int day = 1; - string season = "spring"; - - if (current.Day == 28) - { - day = 1; - season = SDVDate.GetNextSeason(current.Season); - } - else - { - season = current.Season; - day = current.Day + 1; - } - - return new SDVDate(season, day); - } - - public static SDVDate GetNextDay(string season, int day) - { - if (day == 28) - { - day = 1; - season = SDVDate.GetNextSeason(season); - } - else - { - day = day + 1; - } - - return new SDVDate(season, day); - } - - - public static string GetNextSeason(string currentSeason) - { - for (int i = 0; i < Seasons.Length; i++) - { - if (Seasons[i] == currentSeason) - { - if (i + 1 < Seasons.Length) - return Seasons[i + 1]; - else - return Seasons[0]; - } - } - - return "Error"; - } - - public static string GetPrevSeason(string currentSeason) - { - for (int i = 0; i < Seasons.Length; i++) - { - if (Seasons[i] == currentSeason) - { - if (i - 1 >= 0) - return Seasons[i - 1]; - else - return Seasons[Seasons.Length - 1]; - } - } - - return "Error"; - } - - public override string ToString() - { - return $"{Season} {Day}"; - } - - } -} diff --git a/ClimateDataExamin/WeatherParameters.cs b/ClimateDataExamin/WeatherParameters.cs deleted file mode 100644 index c6ac2ad..0000000 --- a/ClimateDataExamin/WeatherParameters.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace ClimateDataExaminer -{ - public class WeatherParameters - { - public string WeatherType; - public double BaseValue; - public double ChangeRate; - public double VariableLowerBound; - public double VariableHigherBound; - - public WeatherParameters() - { - - } - - public WeatherParameters(string wType, double bValue, double cRate, double vLowerBound, double vHigherBound) - { - this.WeatherType = wType; - this.BaseValue = bValue; - this.ChangeRate = cRate; - this.VariableLowerBound = vLowerBound; - this.VariableHigherBound = vHigherBound; - } - - public WeatherParameters(WeatherParameters c) - { - this.WeatherType = c.WeatherType; - this.BaseValue = c.BaseValue; - this.ChangeRate = c.ChangeRate; - this.VariableLowerBound = c.VariableLowerBound; - this.VariableHigherBound = c.VariableHigherBound; - } - } -} diff --git a/ClimateDataExamin/enhanced.json b/ClimateDataExamin/enhanced.json deleted file mode 100644 index 34971b1..0000000 --- a/ClimateDataExamin/enhanced.json +++ /dev/null @@ -1,584 +0,0 @@ -{ - "AllowRainInWinter": true, - "ClimateSequences": [ - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.69, - "ChangeRate": -0.0375, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.25, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.025, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 1.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.49, - "ChangeRate": -0.14, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.15, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.275, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 0.95, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 1.05, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.24, - "ChangeRate": -0.0005, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3925, - "ChangeRate": -0.0075, - "VariableLowerBound": -0.14, - "VariableHigherBound": 0.14 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 0.805, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 0.875, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.2, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.4, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.82, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.2, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.62, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": -0.12, - "ChangeRate": 0.0183, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": -0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 27.0, - "ChangeRate": -0.25, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 57.0, - "ChangeRate": -1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.44, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.62, - "ChangeRate": -0.056, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.026, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 21.0, - "ChangeRate": -0.78, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 23.0, - "ChangeRate": -0.64, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.02, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3, - "ChangeRate": 0.035, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.2, - "ChangeRate": 0.05, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.494, - "ChangeRate": 0.0424, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 1.4932, - "ChangeRate": 0.044, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 15.75, - "ChangeRate": -0.65017, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 10.0, - "ChangeRate": -0.358, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": -1.85, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.65, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": -0.005, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.2, - "ChangeRate": 0.014, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -2.5, - "ChangeRate": -0.05, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 0.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.03, - "ChangeRate": 0.0051, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.58, - "ChangeRate": 0.006, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.05, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.44, - "ChangeRate": -0.012, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -24.0, - "ChangeRate": 1.0, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -1.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 1.0 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.52, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": -0.17, - "ChangeRate": 0.012, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": ".5", - "ChangeRate": 0.014, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -16.0, - "ChangeRate": 0.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -2.9, - "ChangeRate": 0.056, - "VariableLowerBound": -2.0, - "VariableHigherBound": 3.5 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - } - ] -} \ No newline at end of file diff --git a/ClimateDataExamin/monsoon.json b/ClimateDataExamin/monsoon.json deleted file mode 100644 index 5f0feaa..0000000 --- a/ClimateDataExamin/monsoon.json +++ /dev/null @@ -1,492 +0,0 @@ -{ - "AllowRainInWinter": false, - "ClimateSequences": [ - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 1, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.25, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.025, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 1.5, - "ChangeRate": 1.125, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 3.0, - "ChangeRate": 1.18, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3925, - "ChangeRate": 0.0075, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 4.25, - "ChangeRate": 0.805, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 3.0, - "ChangeRate": 1.05, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.4, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.82, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.62, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": -0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 27.0, - "ChangeRate": -0.25, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 57.0, - "ChangeRate": -1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.62, - "ChangeRate": -0.056, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.026, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 21.0, - "ChangeRate": -0.78, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 23.0, - "ChangeRate": -0.64, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.02, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3, - "ChangeRate": 0.035, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.2, - "ChangeRate": 0.05, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 2.0222, - "ChangeRate": 0.0722, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": -1.85, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -2.5, - "ChangeRate": -0.05, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 0.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 2.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.03, - "ChangeRate": 0.0051, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -24.0, - "ChangeRate": 1.0, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -1.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 1.0 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -16.0, - "ChangeRate": 0.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -2.9, - "ChangeRate": 0.056, - "VariableLowerBound": -2.0, - "VariableHigherBound": 2.5 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - } - ] -} \ No newline at end of file diff --git a/ClimateDataExamin/normal.json b/ClimateDataExamin/normal.json deleted file mode 100644 index 2dbd7c9..0000000 --- a/ClimateDataExamin/normal.json +++ /dev/null @@ -1,542 +0,0 @@ -{ - "AllowRainInWinter": false, - "ClimateSequences": [ - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.85, - "ChangeRate": -0.04, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.25, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.025, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 1.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.49, - "ChangeRate": -0.14, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.15, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.275, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 0.95, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 1.05, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.24, - "ChangeRate": -0.0005, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3925, - "ChangeRate": -0.0075, - "VariableLowerBound": -0.14, - "VariableHigherBound": 0.14 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 2.0, - "ChangeRate": 0.805, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 4.0, - "ChangeRate": 0.875, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.2, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.4, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.82, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.2, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.62, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": -0.12, - "ChangeRate": 0.0183, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": -0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 27.0, - "ChangeRate": -0.25, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 57.0, - "ChangeRate": -1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.44, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.62, - "ChangeRate": -0.056, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.026, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 21.0, - "ChangeRate": -0.78, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 23.0, - "ChangeRate": -0.64, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.02, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3, - "ChangeRate": 0.035, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.2, - "ChangeRate": 0.05, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.494, - "ChangeRate": 0.0444, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 2.0222, - "ChangeRate": 0.0722, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": -1.85, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.75, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -2.5, - "ChangeRate": -0.05, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 0.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 2.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.03, - "ChangeRate": 0.0051, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.58, - "ChangeRate": 0.006, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -24.0, - "ChangeRate": 1.0, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -1.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 1.0 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.58, - "ChangeRate": 0.006, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -16.0, - "ChangeRate": 0.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -2.9, - "ChangeRate": 0.056, - "VariableLowerBound": -2.0, - "VariableHigherBound": 2.5 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - } - ] -} \ No newline at end of file diff --git a/ClimateDataExamin/packages.config b/ClimateDataExamin/packages.config deleted file mode 100644 index c809207..0000000 --- a/ClimateDataExamin/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/ClimateDataExamin/wet.json b/ClimateDataExamin/wet.json deleted file mode 100644 index 24725cf..0000000 --- a/ClimateDataExamin/wet.json +++ /dev/null @@ -1,492 +0,0 @@ -{ - "AllowRainInWinter": false, - "ClimateSequences": [ - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 1, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.85, - "ChangeRate": -0.02, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.25, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.025, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 1.5, - "ChangeRate": 1.125, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 3.0, - "ChangeRate": 1.18, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "spring", - "EndSeason": "spring", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.75, - "ChangeRate": -0.011, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3925, - "ChangeRate": 0.0075, - "VariableLowerBound": -0.08, - "VariableHigherBound": 0.08 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 4.25, - "ChangeRate": 0.805, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 3.0, - "ChangeRate": 1.05, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.35, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.45, - "ChangeRate": -0.0025, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.4, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.82, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.45, - "ChangeRate": -0.0025, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 24.0, - "ChangeRate": 0.1, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 28.0, - "ChangeRate": 0.62, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "summer", - "EndSeason": "summer", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.45, - "ChangeRate": -0.0025, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.8, - "ChangeRate": -0.0065, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 27.0, - "ChangeRate": -0.25, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 57.0, - "ChangeRate": -1.25, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.64, - "ChangeRate": -0.001, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "storm", - "BaseValue": 0.62, - "ChangeRate": -0.056, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.05, - "ChangeRate": 0.026, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 21.0, - "ChangeRate": -0.78, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 23.0, - "ChangeRate": -0.64, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.001, - "ChangeRate": 0.02, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 10, - "EndDay": 19, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.55, - "ChangeRate": 0.0, - "VariableLowerBound": -0.02, - "VariableHigherBound": 0.02 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 0.3, - "ChangeRate": 0.035, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.2, - "ChangeRate": 0.05, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "fall", - "EndSeason": "fall", - "BeginDay": 20, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.544, - "ChangeRate": 0.0444, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "storm", - "BaseValue": 0.1, - "ChangeRate": 0.0, - "VariableLowerBound": -0.1, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "debris", - "BaseValue": 2.0222, - "ChangeRate": 0.0722, - "VariableLowerBound": 0.0, - "VariableHigherBound": 0.1 - }, - { - "WeatherType": "lowtemp", - "BaseValue": 25.0, - "ChangeRate": -1.11, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 29.0, - "ChangeRate": -1.3522, - "VariableLowerBound": -4.0, - "VariableHigherBound": 4.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.55, - "ChangeRate": -1.85, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 1, - "EndDay": 9, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.85, - "ChangeRate": 0.0, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -2.5, - "ChangeRate": -0.05, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": 0.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 2.0 - }, - { - "WeatherType": "fog", - "BaseValue": 0.03, - "ChangeRate": 0.0051, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 10, - "EndDay": 18, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.63, - "ChangeRate": 0.006, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -24.0, - "ChangeRate": 1.0, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -1.0, - "ChangeRate": -0.1579, - "VariableLowerBound": -4.0, - "VariableHigherBound": 1.0 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - }, - { - "BeginSeason": "winter", - "EndSeason": "winter", - "BeginDay": 19, - "EndDay": 28, - "WeatherChances": [ - { - "WeatherType": "rain", - "BaseValue": 0.63, - "ChangeRate": 0.006, - "VariableLowerBound": -0.07, - "VariableHigherBound": 0.07 - }, - { - "WeatherType": "lowtemp", - "BaseValue": -16.0, - "ChangeRate": 0.5, - "VariableLowerBound": -3.0, - "VariableHigherBound": 3.0 - }, - { - "WeatherType": "hightemp", - "BaseValue": -2.9, - "ChangeRate": 0.056, - "VariableLowerBound": -2.0, - "VariableHigherBound": 2.5 - }, - { - "WeatherType": "fog", - "BaseValue": -0.2, - "ChangeRate": 0.028, - "VariableLowerBound": -0.04, - "VariableHigherBound": 0.04 - } - ] - } - ] -} \ No newline at end of file diff --git a/ClimatesOfFerngill/Assets/Assets.7z b/ClimatesOfFerngill/Assets/Assets.7z new file mode 100644 index 0000000..865eaa6 Binary files /dev/null and b/ClimatesOfFerngill/Assets/Assets.7z differ diff --git a/ClimatesOfFerngill/Assets/MoonPhases.png b/ClimatesOfFerngill/Assets/MoonPhases.png new file mode 100644 index 0000000..4deec5d Binary files /dev/null and b/ClimatesOfFerngill/Assets/MoonPhases.png differ diff --git a/ClimatesOfFerngill/Assets/ThickerFog.png b/ClimatesOfFerngill/Assets/ThickerFog.png new file mode 100644 index 0000000..f688f05 Binary files /dev/null and b/ClimatesOfFerngill/Assets/ThickerFog.png differ diff --git a/ClimatesOfFerngill/Assets/WeatherIcons.png b/ClimatesOfFerngill/Assets/WeatherIcons.png new file mode 100644 index 0000000..bb886e5 Binary files /dev/null and b/ClimatesOfFerngill/Assets/WeatherIcons.png differ diff --git a/ClimatesOfFerngill/Assets/WeatherIcons2.png b/ClimatesOfFerngill/Assets/WeatherIcons2.png new file mode 100644 index 0000000..703dec0 Binary files /dev/null and b/ClimatesOfFerngill/Assets/WeatherIcons2.png differ diff --git a/ClimatesOfFerngill/Assets/climatesheet2.png b/ClimatesOfFerngill/Assets/climatesheet2.png deleted file mode 100644 index 9fc9309..0000000 Binary files a/ClimatesOfFerngill/Assets/climatesheet2.png and /dev/null differ diff --git a/ClimatesOfFerngill/ClimatesOfFerngill.csproj b/ClimatesOfFerngill/ClimatesOfFerngill.csproj index 4daa47e..2bb9a98 100644 --- a/ClimatesOfFerngill/ClimatesOfFerngill.csproj +++ b/ClimatesOfFerngill/ClimatesOfFerngill.csproj @@ -38,7 +38,15 @@ x86 + + ..\packages\Enums.NET.2.3.1\lib\net45\Enums.NET.dll + + + D:\GalaxyClient\Games\Stardew Valley\Mods\PyTK\PyTK.dll + False + + @@ -48,23 +56,33 @@ - - - + + + + + + + + + + + + - - + - + - + - + + + @@ -95,17 +113,26 @@ - + + Always + + + Always + + + Always + + Always - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/ClimatesOfFerngill/ClimatesOfFerngillApi.cs b/ClimatesOfFerngill/ClimatesOfFerngillApi.cs new file mode 100644 index 0000000..26661f0 --- /dev/null +++ b/ClimatesOfFerngill/ClimatesOfFerngillApi.cs @@ -0,0 +1,51 @@ +namespace ClimatesOfFerngillRebuild +{ + internal class ClimatesOfFerngillApi + { + private SDVMoon Termina; + private WeatherConditions CurrentConditions; + private WeatherConfig ModConfig; + private StaminaDrain StaminaManager; + + //Constructor + internal ClimatesOfFerngillApi(SDVMoon moon, WeatherConditions cond, StaminaDrain manager, WeatherConfig config) + { + Termina = moon; + CurrentConditions = cond; + StaminaManager = manager; + ModConfig = config; + } + + MoonPhase GetCurrentMoonPhase() + { + return Termina.CurrentPhase; + } + + bool IsFarmerSick() + { + return StaminaManager.IsSick(); + } + + CurrentWeather GetWeatherConditions() + { + return CurrentConditions.GetCurrentConditions(); + } + + bool IsFoggyOutside() + { + foreach (ISDVWeather w in CurrentConditions.GetWeatherMatchingType("Fog")) + { + if (w.IsWeatherVisible) + return true; + } + + return false; + } + + bool HasPrecip() + { + return CurrentConditions.HasPrecip(); + } + + } +} diff --git a/ClimatesOfFerngill/ClimatesOfFerngillRebuild.cs b/ClimatesOfFerngill/ClimatesOfFerngillRebuild.cs index 729a577..0d9a73d 100644 --- a/ClimatesOfFerngill/ClimatesOfFerngillRebuild.cs +++ b/ClimatesOfFerngill/ClimatesOfFerngillRebuild.cs @@ -3,53 +3,28 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using System.Text; - using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; - using StardewValley; using StardewValley.Locations; using StardewValley.Menus; using StardewValley.Objects; using StardewValley.TerrainFeatures; - using StardewModdingAPI; using StardewModdingAPI.Events; using StardewModdingAPI.Utilities; -using SFarmer = StardewValley.Farmer; using TwilightShards.Stardew.Common; using TwilightShards.Common; using Microsoft.Xna.Framework.Graphics; +using EnumsNET; +using PyTK.CustomTV; #endregion namespace ClimatesOfFerngillRebuild { public class ClimatesOfFerngill : Mod { - public static Dictionary ForceDays = new Dictionary - { - { new SDate(1,"spring"), Game1.weather_sunny }, - { new SDate(2, "spring"), Game1.weather_sunny }, - { new SDate(3, "spring"), Game1.weather_rain }, - { new SDate(4, "spring"), Game1.weather_sunny }, - { new SDate(13, "spring"), Game1.weather_festival }, - { new SDate(24, "spring"), Game1.weather_festival }, - { new SDate(1, "summer"), Game1.weather_sunny }, - { new SDate(11, "summer"), Game1.weather_festival }, - { new SDate(13, "summer"), Game1.weather_lightning }, - { new SDate(25, "summer", 25), Game1.weather_lightning }, - { new SDate(26, "summer", 26), Game1.weather_lightning }, - { new SDate(28, "summer", 28), Game1.weather_festival }, - { new SDate(1,"fall"), Game1.weather_sunny }, - { new SDate(16,"fall"), Game1.weather_festival }, - { new SDate(27,"fall"), Game1.weather_festival }, - { new SDate(1,"winter"), Game1.weather_sunny }, - { new SDate(8, "winter"), Game1.weather_festival }, - { new SDate(25, "winter"), Game1.weather_festival } - }; - /// The options file private WeatherConfig WeatherOpt { get; set; } @@ -57,67 +32,53 @@ public class ClimatesOfFerngill : Mod private MersenneTwister Dice; /// The current weather conditions - private WeatherConditions CurrentWeather; + private WeatherConditions Conditions; /// The climate for the game private FerngillClimate GameClimate; - /// - /// This is used to display icons on the menu - /// + /// This is used to display icons on the menu private Sprites.Icons OurIcons { get; set; } - private StringBuilder DebugOutput; - private CustomWeather WeatherCntrl; + + /// The moon object private SDVMoon OurMoon; //for stamina management private StaminaDrain StaminaMngr; private int TicksOutside; private int TicksTotal; - - //for events private int ExpireTime; private List CropList; - - //queued string private HUDMessage queuedMsg; - /// - /// This is used to allow the menu to revert back to a previous menu - /// + /// This is used to allow the menu to revert back to a previous menu private IClickableMenu PreviousMenu; - - //tv overloading - private static FieldInfo Field = typeof(GameLocation).GetField("afterQuestion", BindingFlags.Instance | BindingFlags.NonPublic); - private static FieldInfo TVChannel = typeof(TV).GetField("currentChannel", BindingFlags.Instance | BindingFlags.NonPublic); - private static FieldInfo TVScreen = typeof(TV).GetField("screen", BindingFlags.Instance | BindingFlags.NonPublic); - private static FieldInfo TVScreenOverlay = typeof(TV).GetField("screenOverlay", BindingFlags.Instance | BindingFlags.NonPublic); - private static MethodInfo TVMethod = typeof(TV).GetMethod("getWeatherChannelOpening", BindingFlags.Instance | BindingFlags.NonPublic); - private static MethodInfo TVMethodOverlay = typeof(TV).GetMethod("setWeatherOverlay", BindingFlags.Instance | BindingFlags.NonPublic); - private static GameLocation.afterQuestionBehavior Callback; - private static TV Target; - public static Texture2D fadeToBlackRect; - + private Descriptions DescriptionEngine; + private Rectangle RWeatherIcon; private Color nightColor = new Color((int)byte.MaxValue, (int)byte.MaxValue, 0); - private bool Disabled = false; + private int[] SeedsForDialogue; + public bool IsEclipse { get; set; } + public int ResetTicker { get; set; } + + private bool IsFestivalDay => Utility.isFestivalDay(SDate.Now().Day, SDate.Now().Season); /// Main mod function. /// The helper. public override void Entry(IModHelper helper) { + RWeatherIcon = new Rectangle(); WeatherOpt = helper.ReadConfig(); Dice = new MersenneTwister(); - CurrentWeather = new WeatherConditions(); - WeatherCntrl = new CustomWeather(); DebugOutput = new StringBuilder(); - OurMoon = new SDVMoon(Dice); + OurMoon = new SDVMoon(WeatherOpt, Dice); OurIcons = new Sprites.Icons(Helper.Content); CropList = new List(); + Conditions = new WeatherConditions(OurIcons, Dice, Helper.Translation, Monitor, WeatherOpt); StaminaMngr = new StaminaDrain(WeatherOpt, Helper.Translation, Monitor); - fadeToBlackRect = new Texture2D(Game1.graphics.GraphicsDevice, 12, 8, false, SurfaceFormat.Color); - + SeedsForDialogue = new int[] { Dice.Next(), Dice.Next() }; + DescriptionEngine = new Descriptions(Helper.Translation, Dice, WeatherOpt, Monitor); queuedMsg = null; Vector2 snowPos = Vector2.Zero; TicksOutside = 0; @@ -145,6 +106,8 @@ public override void Entry(IModHelper helper) MenuEvents.MenuChanged += MenuEvents_MenuChanged; GameEvents.UpdateTick += CheckForChanges; SaveEvents.AfterReturnToTitle += ResetMod; + SaveEvents.AfterLoad += SaveEvents_AfterLoad; + GraphicsEvents.OnPostRenderGuiEvent += DrawOverMenus; GraphicsEvents.OnPreRenderHudEvent += DrawPreHudObjects; GraphicsEvents.OnPostRenderHudEvent += DrawObjects; LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; @@ -153,11 +116,49 @@ public override void Entry(IModHelper helper) //console commands helper.ConsoleCommands - .Add("weather_settommorowweather", helper.Translation.Get("console-text.desc_tmrweather"), TmrwWeatherChangeFromConsole) - .Add("weather_setweather", helper.Translation.Get("console-text.desc_setweather"), WeatherChangeFromConsole) - .Add("debug_changecondt", "Changes conditions. Debug function.", DebugChgCondition) - .Add("debug_staminaforce", "Forces stamina drain level. Debug function", DebugStaForce) - .Add("debug_weatherstatus", "Prints an overly detailed weahter status screen out.", DebugWeather); + .Add("weather_settommorow", helper.Translation.Get("console-text.desc_tmrweather"), TomorrowWeatherChangeFromConsole) + .Add("weather_changeweather", helper.Translation.Get("console-text.desc_setweather"), WeatherChangeFromConsole) + .Add("world_solareclipse", "Starts the solar eclipse.", SolarEclipseEvent_CommandFired); + } + } + + private void SolarEclipseEvent_CommandFired(string command, string[] args) + { + IsEclipse = true; + Game1.globalOutdoorLighting = .5f; //force lightning change. + Game1.currentLocation.switchOutNightTiles(); + Game1.ambientLight = nightColor; + Monitor.Log("Setting the eclipse event to true"); + } + + private void SaveEvents_AfterLoad(object sender, EventArgs e) + { + CustomTVMod.changeAction("weather", DisplayWeather); + } + + public void DisplayWeather(TV tv, TemporaryAnimatedSprite sprite, StardewValley.Farmer who, string answer) + { + TemporaryAnimatedSprite BackgroundSprite = new TemporaryAnimatedSprite(Game1.mouseCursors, new Rectangle(497, 305, 42, 28), 9999f, 1, 999999, tv.getScreenPosition(), false, false, (float)((double)(tv.boundingBox.Bottom - 1) / 10000.0 + 9.99999974737875E-06), 0.0f, Color.White, tv.getScreenSizeModifier(), 0.0f, 0.0f, 0.0f, false); + TemporaryAnimatedSprite WeatherSprite = DescriptionEngine.GetWeatherOverlay(Conditions, tv); + + string OnScreenText = ""; + + if (BackgroundSprite is null) + Monitor.Log("Background Sprite is null"); + if (WeatherSprite is null) + Monitor.Log("Weather Sprite is null"); + + OnScreenText += DescriptionEngine.GenerateTVForecast(Conditions, OurMoon); + + CustomTVMod.showProgram(BackgroundSprite, OnScreenText, CustomTVMod.endProgram, WeatherSprite); + } + + private void DrawOverMenus(object sender, EventArgs e) + { + //revised this so it properly draws over the canon moon. :v + if (Game1.showingEndOfNightStuff && Game1.activeClickableMenu is ShippingMenu menu && !Game1.wasRainingYesterday) + { + Game1.spriteBatch.Draw(OurIcons.MoonSource, new Vector2((float)(Game1.viewport.Width - 80 * Game1.pixelZoom), (float)Game1.pixelZoom), OurIcons.GetNightMoonSprite(SDVMoon.GetLunarPhaseForDay(SDate.Now().AddDays(-1))), Color.LightBlue, 0.0f, Vector2.Zero, (float)Game1.pixelZoom * 1.5f, SpriteEffects.None, 1f); } } @@ -165,7 +166,7 @@ private void DebugWeather(string arg1, string[] arg2) { //print a complete weather status. string retString = ""; - retString += $"Weather for {SDate.Now()} is {CurrentWeather.ToString()}. {Environment.NewLine} Moon Phase {OurMoon.ToString()}"; + retString += $"Weather for {SDate.Now()} is {Conditions.ToString()}. Moon Phase is {OurMoon.ToString()}. {Environment.NewLine} System flags: isRaining {Game1.isRaining} isSnowing {Game1.isSnowing} isDebrisWeather: {Game1.isDebrisWeather} isLightning {Game1.isLightning}, with tommorow's set weather being {Game1.weatherForTomorrow}"; Monitor.Log(retString); } @@ -175,12 +176,7 @@ private void DrawPreHudObjects(object sender, EventArgs e) return; if (Game1.currentLocation.IsOutdoors) - CurrentWeather.DrawFog(); - - if (Game1.currentLocation.isOutdoors && !(Game1.currentLocation is Desert) && - CurrentWeather.UnusualWeather == SpecialWeather.Blizzard) - WeatherCntrl.DrawBlizzard(); - + Conditions.DrawWeathers(); } /// @@ -190,20 +186,34 @@ private void DrawPreHudObjects(object sender, EventArgs e) /// Parameters private void LocationEvents_CurrentLocationChanged(object sender, EventArgsCurrentLocationChanged e) { - if (CurrentWeather.IsFogVisible()) + if (IsEclipse) { + Game1.globalOutdoorLighting = .5f; + Game1.currentLocation.switchOutNightTiles(); + Game1.ambientLight = nightColor; + if (!Game1.currentLocation.isOutdoors && Game1.currentLocation is DecoratableLocation) { var loc = Game1.currentLocation as DecoratableLocation; foreach (Furniture f in loc.furniture) { - if (WeatherOpt.Verbose) - Monitor.Log($"Iterating through {f.name}"); + if (f.furniture_type == Furniture.window) + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + } + } + } + if (Conditions.HasWeather(CurrentWeather.Fog)) + { + if (!Game1.currentLocation.isOutdoors && Game1.currentLocation is DecoratableLocation) + { + var loc = Game1.currentLocation as DecoratableLocation; + foreach (Furniture f in loc.furniture) + { if (f.furniture_type == Furniture.window) { - if (WeatherOpt.Verbose) Monitor.Log($"Attempting to remove the light for {f.name}"); - Helper.Reflection.GetPrivateMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + //if (WeatherOpt.Verbose) Monitor.Log($"Attempting to remove the light for {f.name}"); + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); } } } @@ -220,13 +230,13 @@ private void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged if (GameClimate is null) Monitor.Log("GameClimate is null"); if (e.NewMenu is null) - Monitor.Log("e.NewMenu is null"); + Monitor.Log("e.NewMenu is null"); if (e.NewMenu is DialogueBox box) { bool stormDialogue = false; double odds = Dice.NextDoublePositive(), stormOdds = GameClimate.GetStormOdds(SDate.Now().AddDays(1), Dice, DebugOutput); - List lines = Helper.Reflection.GetPrivateValue>(box, "dialogues"); + List lines = Helper.Reflection.GetField>(box, "dialogues").GetValue(); if (lines.FirstOrDefault() == Game1.content.LoadString("Strings\\StringsFromCSFiles:Object.cs.12822")) { if (WeatherOpt.Verbose) @@ -253,8 +263,6 @@ private void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged lines.Add(Game1.content.LoadString("Strings\\StringsFromCSFiles:Object.cs.12822")); } } - - TryHookTelevision(); } /// @@ -264,7 +272,7 @@ private void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged /// private void OnEndOfDay(object sender, EventArgs e) { - if (CurrentWeather.UnusualWeather == SpecialWeather.Frost) + if (Conditions.HasWeather(CurrentWeather.Frost) && WeatherOpt.AllowCropDeath) { Farm f = Game1.getFarm(); int count = 0, maxCrops = (int)Math.Floor(SDVUtilities.CropCountInFarm(f) * WeatherOpt.DeadCropPercentage); @@ -276,7 +284,7 @@ private void OnEndOfDay(object sender, EventArgs e) if (tf.Value is HoeDirt curr && curr.crop != null) { - if (Dice.NextDouble() <= (WeatherOpt.CropResistance / 2)) + if (Dice.NextDouble() > WeatherOpt.CropResistance) { CropList.Add(tf.Key); count++; @@ -292,135 +300,27 @@ private void OnEndOfDay(object sender, EventArgs e) hd.crop.dead = true; } - queuedMsg = new HUDMessage(Helper.Translation.Get("hud-text.desc_frost_killed"), Color.SeaGreen, 5250f, true) + queuedMsg = new HUDMessage(Helper.Translation.Get("hud-text.desc_frost_killed", new { deadCrops = count }), Color.SeaGreen, 5250f, true) { whatType = 2 }; } } + if (IsEclipse) + IsEclipse = false; + //moon works after frost does OurMoon.HandleMoonAtSleep(Game1.getFarm(), Helper.Translation); } - #region TVOverride - public void TryHookTelevision() - { - if (Game1.currentLocation != null && Game1.currentLocation is DecoratableLocation && Game1.activeClickableMenu != null && Game1.activeClickableMenu is DialogueBox) - { - Callback = (GameLocation.afterQuestionBehavior)Field.GetValue(Game1.currentLocation); - if (Callback != null && Callback.Target.GetType() == typeof(TV)) - { - Field.SetValue(Game1.currentLocation, new GameLocation.afterQuestionBehavior(InterceptCallback)); - Target = (TV)Callback.Target; - } - } - } - - public void InterceptCallback(SFarmer who, string answer) - { - if (answer != "Weather") - { - Callback(who, answer); - return; - } - TVChannel.SetValue(Target, 2); - TVScreen.SetValue(Target, new TemporaryAnimatedSprite(Game1.mouseCursors, new Rectangle(413, 305, 42, 28), 150f, 2, 999999, Target.getScreenPosition(), false, false, (float)((double)(Target.boundingBox.Bottom - 1) / 10000.0 + 9.99999974737875E-06), 0.0f, Color.White, Target.getScreenSizeModifier(), 0.0f, 0.0f, 0.0f, false)); - Game1.drawObjectDialogue(Game1.parseText((string)TVMethod.Invoke(Target, null))); - Game1.afterDialogues = NextScene; - } - - public void NextScene() - { - TVScreen.SetValue(Target, new TemporaryAnimatedSprite(Game1.mouseCursors, new Rectangle(497, 305, 42, 28), 9999f, 1, 999999, Target.getScreenPosition(), false, false, (float)((double)(Target.boundingBox.Bottom - 1) / 10000.0 + 9.99999974737875E-06), 0.0f, Color.White, Target.getScreenSizeModifier(), 0.0f, 0.0f, 0.0f, false)); - Game1.drawObjectDialogue(Game1.parseText(GetWeatherForecast())); - TVMethodOverlay.Invoke(Target, null); - Game1.afterDialogues = Target.proceedToNextScene; - } - #endregion - /// /// This function gets the forecast of the weather for the TV. /// /// A string describing the weather public string GetWeatherForecast() { - string tvText = " "; - - //The TV should display: Alerts, today's weather, Tomorrow's weather, alerts. - - // Something such as "Today, the high is 12C, with low 8C. It'll be a very windy day. Tomorrow, it'll be rainy." - // since we don't predict weather in advance yet. (I don't want to rearchitecture it yet.) - // That said, the TV channel starts with Tomorrow, so we need to keep that in mind. - - tvText = Helper.Translation.Get("tv.opening-desc"); - - if (Game1.timeOfDay < 1800) //don't display today's weather - { - if (WeatherOpt.Verbose) - Monitor.Log("Triggering weather"); - - //why was this not done seperately? Will proc tommorow - //does.. Game1.isFestival() work the way I think it does...? - if (Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason)) - { - tvText += Helper.Translation.Get("tv.desc-festival", - new { festival = SDVUtilities.GetFestivalName(), Temperature = CurrentWeather.GetTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation) }); - } - else - { - if (CurrentWeather.IsFogVisible()) - { - if (!CurrentWeather.IsDarkFog()) - { - tvText += Helper.Translation.Get("tv.desc-todayFog", new - { - temperature = CurrentWeather.GetTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation), - weathercondition = CurrentWeather.GetDescText(CurrentWeather.TodayWeather, SDate.Now(), Dice, Helper.Translation), - time = CurrentWeather.GetFogEndTime().ToString() - }); - } - else - { - tvText += Helper.Translation.Get("tv.desc-todayDFog", new - { - temperature = CurrentWeather.GetTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation), - weathercondition = CurrentWeather.GetDescText(CurrentWeather.TodayWeather, SDate.Now(), Dice, Helper.Translation), - time = CurrentWeather.GetFogEndTime().ToString() - }); - } - - } - else - { - tvText += Helper.Translation.Get("tv.desc-today", new - { - temperature = CurrentWeather.GetTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation), - weathercondition = CurrentWeather.GetDescText(CurrentWeather.TodayWeather, SDate.Now(), Dice, Helper.Translation) - }); - } - } - } - - //Tomorrow weather - if (Utility.isFestivalDay(SDate.Now().Day + 1, SDate.Now().Season)) - { - tvText += Helper.Translation.Get("tv.desc-festival", new - { - festival = SDVUtilities.GetTomorrowFestivalName(), - temperature = CurrentWeather.GetTomorrowTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation) - }); - } - else - { - tvText += Helper.Translation.Get("tv.desc-tomorrow", new - { - temperature = CurrentWeather.GetTomorrowTemperatureString(WeatherOpt.ShowBothScales, Helper.Translation), - weathercondition = CurrentWeather.GetDescText(CurrentWeather.TomorrowWeather, SDate.Now().AddDays(1), Dice, Helper.Translation) - }); - } - - return tvText; + return DescriptionEngine.GenerateTVForecast(Conditions, OurMoon); } /// @@ -433,7 +333,15 @@ private void CheckForChanges(object sender, EventArgs e) if (!Context.IsWorldReady) return; - CurrentWeather.MoveFog(); + if (IsEclipse && ResetTicker > 0) + { + Game1.globalOutdoorLighting = .5f; + Game1.ambientLight = nightColor; + Game1.currentLocation.switchOutNightTiles(); + ResetTicker = 0; + } + + Conditions.MoveWeathers(); if (Game1.isEating) { @@ -461,32 +369,63 @@ private void TenMinuteUpdate(object sender, EventArgsIntChanged e) if (!Game1.hasLoadedGame) return; - CurrentWeather.UpdateFog(e.NewInt, WeatherOpt.Verbose, Monitor); + Conditions.TenMinuteUpdate(); - if (CurrentWeather.IsFogVisible()) + if (IsEclipse) { + Game1.globalOutdoorLighting = .5f; + Game1.ambientLight = nightColor; + Game1.currentLocation.switchOutNightTiles(); + ResetTicker = 1; + if (!Game1.currentLocation.isOutdoors && Game1.currentLocation is DecoratableLocation) { var loc = Game1.currentLocation as DecoratableLocation; foreach (Furniture f in loc.furniture) { - if (WeatherOpt.Verbose) - Monitor.Log($"Iterating through {f.name}"); + if (f.furniture_type == Furniture.window) + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + } + } + if ((Game1.farmEvent == null && Game1.random.NextDouble() < (0.25 - Game1.dailyLuck / 2.0)) + && ((WeatherOpt.SpawnMonsters && Game1.spawnMonstersAtNight) || (WeatherOpt.SpawnMonstersAllFarms))) + { + Monitor.Log("Spawning a monster, or attempting to.", LogLevel.Debug); + if (Game1.random.NextDouble() < 0.25) + { + if (this.Equals(Game1.currentLocation)) + { + Game1.getFarm().spawnFlyingMonstersOffScreen(); + return; + } + } + else + { + Game1.getFarm().spawnGroundMonsterOffScreen(); + } + } + + } + + if (Conditions.HasWeather(CurrentWeather.Fog)) + { + if (!Game1.currentLocation.isOutdoors && Game1.currentLocation is DecoratableLocation) + { + var loc = Game1.currentLocation as DecoratableLocation; + foreach (Furniture f in loc.furniture) + { //Yes, *add* lights removes them. No, don't ask me why. if (f.furniture_type == Furniture.window) { - if (WeatherOpt.Verbose) Monitor.Log($"Attempting to remove the light for {f.name}"); - Helper.Reflection.GetPrivateMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + //if (WeatherOpt.Verbose) Monitor.Log($"Attempting to remove the light for {f.name}"); + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); } } } } - if (Game1.currentLocation.isOutdoors && - (CurrentWeather.UnusualWeather == SpecialWeather.Thundersnow || - CurrentWeather.UnusualWeather == SpecialWeather.DryLightning) - && Game1.timeOfDay < 2400) + if (Game1.currentLocation.isOutdoors && Conditions.HasWeather(CurrentWeather.Lightning) && Game1.timeOfDay < 2400) Utility.performLightningUpdate(); //queued messages clear @@ -499,7 +438,7 @@ private void TenMinuteUpdate(object sender, EventArgsIntChanged e) //frost works at night, heatwave works during the day if (Game1.timeOfDay == 1700) { - if (WeatherConditions.IsHeatwave(CurrentWeather.UnusualWeather)) + if (Conditions.HasWeather(CurrentWeather.Heatwave)) { ExpireTime = 2000; Farm f = Game1.getFarm(); @@ -507,7 +446,6 @@ private void TenMinuteUpdate(object sender, EventArgsIntChanged e) foreach (KeyValuePair tf in f.terrainFeatures) { - if (count >= maxCrops) break; @@ -524,10 +462,10 @@ private void TenMinuteUpdate(object sender, EventArgsIntChanged e) if (CropList.Count > 0) { - if (!WeatherOpt.AllowCropDeath) - SDVUtilities.ShowMessage(Helper.Translation.Get("hud-text.desc_heatwave_dry")); - else + if (WeatherOpt.AllowCropDeath) SDVUtilities.ShowMessage(Helper.Translation.Get("hud-text.desc_heatwave_kill")); + else + SDVUtilities.ShowMessage(Helper.Translation.Get("hud-text.desc_heatwave_dry")); } } } @@ -553,7 +491,7 @@ private void TenMinuteUpdate(object sender, EventArgsIntChanged e) } float oldStamina = Game1.player.stamina; - Game1.player.stamina += StaminaMngr.TenMinuteTick(CurrentWeather.UnusualWeather, TicksOutside, TicksTotal, Dice, CurrentWeather.TodayWeather, CurrentWeather.IsFogVisible()); + Game1.player.stamina += StaminaMngr.TenMinuteTick(Conditions, TicksOutside, TicksTotal, Dice); if (Game1.player.stamina <= 0) SDVUtilities.FaintPlayer(); @@ -582,13 +520,58 @@ private void DrawObjects(object sender, EventArgs e) //determine icon offset if (!Game1.eventUp) { - Game1.spriteBatch.Draw(OurIcons.source, weatherMenu.position + new Vector2(116f, 68f), new Rectangle?(new Rectangle(134 + 12 * CurrentWeather.GetWeatherIcon(), 60, 12, 8)), Color.White, 0.0f, Vector2.Zero, 4f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, .1f); + if ((int)Conditions.CurrentWeatherIcon != (int)WeatherIcon.IconError) + { + RWeatherIcon = new Rectangle(0 + 12 * (int)Conditions.CurrentWeatherIcon, SDVTime.IsNight ? 8 : 0, 12, 8); + } + + if ((int)Conditions.CurrentWeatherIcon == (int)WeatherIcon.IconBloodMoon) + { + RWeatherIcon = new Rectangle(144, 8, 12, 8); + } + + if ((int)Conditions.CurrentWeatherIcon == (int)WeatherIcon.IconError) + { + RWeatherIcon = new Rectangle(144, 0, 12, 8); + } + + + Game1.spriteBatch.Draw(OurIcons.WeatherSource, weatherMenu.position + new Vector2(116f, 68f), RWeatherIcon, Color.White, 0.0f, Vector2.Zero, 4f, SpriteEffects.None, .1f); } - } + + //redraw mouse cursor + if (Game1.activeClickableMenu == null && Game1.mouseCursor > -1 && (Mouse.GetState().X != 0 || Mouse.GetState().Y != 0) && (Game1.getOldMouseX() != 0 || Game1.getOldMouseY() != 0)) + { + if ((double)Game1.mouseCursorTransparency <= 0.0 || !Utility.canGrabSomethingFromHere(Game1.getOldMouseX() + Game1.viewport.X, Game1.getOldMouseY() + Game1.viewport.Y, Game1.player) || Game1.mouseCursor == 3) + { + if (Game1.player.ActiveObject != null && Game1.mouseCursor != 3 && !Game1.eventUp) + { + if ((double)Game1.mouseCursorTransparency > 0.0 || Game1.options.showPlacementTileForGamepad) + { + Game1.player.ActiveObject.drawPlacementBounds(Game1.spriteBatch, Game1.currentLocation); + if ((double)Game1.mouseCursorTransparency > 0.0) + { + bool flag = Utility.playerCanPlaceItemHere(Game1.currentLocation, Game1.player.CurrentItem, Game1.getMouseX() + Game1.viewport.X, Game1.getMouseY() + Game1.viewport.Y, Game1.player) || Utility.isThereAnObjectHereWhichAcceptsThisItem(Game1.currentLocation, Game1.player.CurrentItem, Game1.getMouseX() + Game1.viewport.X, Game1.getMouseY() + Game1.viewport.Y) && Utility.withinRadiusOfPlayer(Game1.getMouseX() + Game1.viewport.X, Game1.getMouseY() + Game1.viewport.Y, 1, Game1.player); + Game1.player.CurrentItem.drawInMenu(Game1.spriteBatch, new Vector2((float)(Game1.getMouseX() + Game1.tileSize / 4), (float)(Game1.getMouseY() + Game1.tileSize / 4)), flag ? (float)((double)Game1.dialogueButtonScale / 75.0 + 1.0) : 1f, flag ? 1f : 0.5f, 0.999f); + } + } + } + else if (Game1.mouseCursor == 0 && Game1.isActionAtCurrentCursorTile) + Game1.mouseCursor = Game1.isInspectionAtCurrentCursorTile ? 5 : 2; + } + if (!Game1.options.hardwareCursor) + Game1.spriteBatch.Draw(Game1.mouseCursors, new Vector2((float)Game1.getMouseX(), (float)Game1.getMouseY()), new Microsoft.Xna.Framework.Rectangle?(Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, Game1.mouseCursor, 16, 16)), Color.White * Game1.mouseCursorTransparency, 0.0f, Vector2.Zero, (float)Game1.pixelZoom + Game1.dialogueButtonScale / 150f, SpriteEffects.None, 1f); + Game1.wasMouseVisibleThisFrame = (double)Game1.mouseCursorTransparency > 0.0; + } + Game1.mouseCursor = 0; + if (Game1.isActionAtCurrentCursorTile || Game1.activeClickableMenu != null) + return; + Game1.mouseCursorTransparency = 1f; + } private void ResetMod(object sender, EventArgs e) { - CurrentWeather.Reset(); + Conditions.Reset(); ExpireTime = 0; CropList.Clear(); DebugOutput.Clear(); @@ -605,17 +588,26 @@ private void HandleNewDay(object sender, EventArgs e) Monitor.Log("DebugOutput is null!"); if (OurMoon == null) Monitor.Log("OurMoon is null"); - if (CurrentWeather == null) + if (Conditions == null) Monitor.Log("CurrentWeather is null"); if (StaminaMngr == null) Monitor.Log("StaminaMngr is null"); if (GameClimate is null) Monitor.Log("GameClimate is null"); + if (Dice.NextDouble() < WeatherOpt.EclipseChance && WeatherOpt.EclipseOn && OurMoon.CurrentPhase == MoonPhase.FullMoon && + SDate.Now().DaysSinceStart > 2) + { + IsEclipse = true; + Game1.addHUDMessage(new HUDMessage("It looks like a rare solar eclipse will darken the sky all day!")); + Conditions.BlockFog = true; + } + + SeedsForDialogue[0] = Dice.Next(); + SeedsForDialogue[1] = Dice.Next(); CropList.Clear(); //clear the crop list DebugOutput.Clear(); - OurMoon.UpdateForNewDay(); - CurrentWeather.OnNewDay(); + Conditions.OnNewDay(); UpdateWeatherOnNewDay(); SetTommorowWeather(); OurMoon.HandleMoonAfterWake(Helper.Translation); @@ -647,13 +639,10 @@ private void SetTommorowWeather() return; } - if (CheckForForceDay(SDate.Now().AddDays(1))) + if (ForceDays.CheckForForceDay(DescriptionEngine, SDate.Now().AddDays(1),Monitor, WeatherOpt.Verbose)) { if (WeatherOpt.Verbose) Monitor.Log($"The game will force tomorrow. Aborting processing.", LogLevel.Trace); - - //if (WeatherOpt.Verbose) Monitor.Log(DebugOutput.ToString()); - CurrentWeather.TomorrowWeather = Game1.weatherForTomorrow; //this also needs to be set, self. return; } @@ -693,17 +682,20 @@ private void SetTommorowWeather() if (WeatherOpt.Verbose) Monitor.Log($"Weather result is {Result}"); + if (!Conditions.IsTodayTempSet) + throw new NullReferenceException("Today's temperatures have not been set!"); + //now parse the result. if (Result == "rain") { //snow applies first - double MidPointTemp = CurrentWeather.GetTodayHigh() - - ((CurrentWeather.GetTodayHigh() - CurrentWeather.GetTodayLow()) / 2); + double MidPointTemp = Conditions.TodayHigh - + ((Conditions.TodayHigh - Conditions.TodayLow) / 2); - if ((CurrentWeather.GetTodayHigh() <= 2 || MidPointTemp <= 0) && Game1.currentSeason != "spring") + if ((Conditions.TodayHigh <= 2 || MidPointTemp <= 0) && Game1.currentSeason != "spring") { if (WeatherOpt.Verbose) - Monitor.Log($"Snow is enabled, with the High for the day being: {CurrentWeather.TodayTemps.HigherBound}" + + Monitor.Log($"Snow is enabled, with the High for the day being: {Conditions.TodayHigh}" + $" and the calculated midpoint temperature being {MidPointTemp}"); Game1.weatherForTomorrow = Game1.weather_snow; @@ -726,18 +718,12 @@ private void SetTommorowWeather() Game1.weatherForTomorrow = Game1.weather_rain; } - //apply dry lightning check - if (CurrentWeather.UnusualWeather == SpecialWeather.DryLightningAndHeatwave || CurrentWeather.UnusualWeather == SpecialWeather.DryLightning) - Game1.isLightning = true; - - //tracking time! - //Snow fall on Fall 28, if the flag is set. + //tracking time! - Snow fall on Fall 28, if the flag is set. if (Game1.dayOfMonth == 28 && Game1.currentSeason == "fall" && WeatherOpt.SnowOnFall28) { - CurrentWeather.ResetTodayTemps(2, -1); + Conditions.ForceTodayTemps(2, -1); Game1.weatherForTomorrow = Game1.weather_snow; } - } if (Result == "debris") @@ -751,9 +737,7 @@ private void SetTommorowWeather() } if (WeatherOpt.Verbose) - Monitor.Log($"We've set the weather for Tomorrow. It is: {Game1.weatherForTomorrow}"); - - CurrentWeather.TomorrowWeather = Game1.weatherForTomorrow; //would help if I updated this! + Monitor.Log($"We've set the weather for Tomorrow. It is: {DescriptionEngine.DescribeInGameWeather(Game1.weatherForTomorrow)}"); } private void UpdateWeatherOnNewDay() @@ -763,20 +747,19 @@ private void UpdateWeatherOnNewDay() //Set Temperature for today and tommorow. Get today's conditions. // If tomorrow is set, move it to today, and autoregen tomorrow. - CurrentWeather.GetTodayWeather(); + // *201711 Due to changes in the object, it auto attempts to update today from tomorrow. + Conditions.SetTodayWeather(); - if (CurrentWeather.TomorrowTemps == null) - CurrentWeather.SetTodayTemps(GameClimate.GetTemperatures(SDate.Now(), Dice, DebugOutput)); - else - CurrentWeather.SetTodayTemps(CurrentWeather.TomorrowTemps); + if (!Conditions.IsTomorrowTempSet) + Conditions.SetTodayTemps(GameClimate.GetTemperatures(SDate.Now(), Dice, DebugOutput)); - CurrentWeather.SetTmrwTemps(GameClimate.GetTemperatures(SDate.Now().AddDays(1), Dice, DebugOutput)); + Conditions.SetTomorrowTemps(GameClimate.GetTemperatures(SDate.Now().AddDays(1), Dice, DebugOutput)); if (WeatherOpt.Verbose) Monitor.Log($"Updated the temperature for tommorow and today. Setting weather for today... ", LogLevel.Trace); //if today is a festival or wedding, do not go further. - if (Utility.isFestivalDay(SDate.Now().Day, SDate.Now().Season) || CurrentWeather.TodayWeather == Game1.weather_wedding) + if (Conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Festival | CurrentWeather.Wedding)) { if (WeatherOpt.Verbose) Monitor.Log("It is a wedding or festival today. Not attempting to run special weather or fog."); @@ -784,112 +767,11 @@ private void UpdateWeatherOnNewDay() //if (WeatherOpt.Verbose) Monitor.Log(DebugOutput.ToString()); return; } - - //now, update today's weather for fog and other special weathers. - double fogChance = GameClimate.GetClimateForDate(SDate.Now()) - .RetrieveOdds(Dice, "fog", SDate.Now().Day, DebugOutput); - - //fogChance = 1; //for testing purposes - double fogRoll = Dice.NextDoublePositive(); - - if (fogRoll < fogChance && CurrentWeather.TodayWeather != Game1.weather_debris) - { - if (WeatherOpt.Verbose) - Monitor.Log("Executing fog analysis.. "); - - CurrentWeather.InitFog(Dice, WeatherOpt); - - if (WeatherOpt.Verbose) - Monitor.Log($"With roll {fogRoll.ToString("N3")} against {fogChance}, there will be fog today until {CurrentWeather.GetFogEndTime()}. Whether or not this is dark: {CurrentWeather.IsDarkFog()}"); - } - - //now special weathers - //there are three main special weathers. Blizard, only during snow; Dry Lightning, which is lightning minus rain; - // Thundersnow - - // Conditions: Blizzard - occurs in weather_snow in "winter" - // Dry Lightning - occurs in weather_clear in any season if temps are >24C. - // Thundersnow - as Blizzard, but really rare. - - // And now, with stamina enabled, time to reenable heatwaves and frosts - - if (WeatherOpt.Verbose) - Monitor.Log("Testing for special weathers - first, blizzard and thundrsnow"); - - if (CurrentWeather.TodayWeather == Game1.weather_snow) - { - double blizRoll = Dice.NextDoublePositive(); - if (blizRoll <= WeatherOpt.BlizzardOdds) - { - CurrentWeather.UnusualWeather = SpecialWeather.Blizzard; - if (WeatherOpt.Verbose) - Monitor.Log($"With roll {blizRoll.ToString("N3")} against {WeatherOpt.BlizzardOdds}, there will be blizzards today"); - } - } - - //Dry Lightning is also here for such like the dry and arid climates - // which have so low rain chances they may never storm. - if (CurrentWeather.TodayWeather == Game1.weather_snow) - { - double oddsRoll = Dice.NextDoublePositive(); - - if (oddsRoll <= WeatherOpt.ThundersnowOdds) - { - CurrentWeather.UnusualWeather = SpecialWeather.Thundersnow; - if (WeatherOpt.Verbose) - Monitor.Log($"With roll {oddsRoll.ToString("N3")} against {WeatherOpt.ThundersnowOdds}, there will be thundersnow today"); - } - } - - if (WeatherOpt.Verbose) - Monitor.Log("Testing for special weathers - dry lightning and heatwave"); - - if (CurrentWeather.TodayWeather == Game1.weather_sunny) - { - double oddsRoll = Dice.NextDoublePositive(); - - if (oddsRoll <= WeatherOpt.DryLightning && CurrentWeather.GetTodayHigh() >= WeatherOpt.DryLightningMinTemp) - { - CurrentWeather.UnusualWeather = SpecialWeather.DryLightning; - if (WeatherOpt.Verbose) - Monitor.Log($"With roll {oddsRoll.ToString("N3")} against {WeatherOpt.DryLightning}, there will be dry lightning today."); - } - - if (CurrentWeather.GetTodayHigh() > WeatherOpt.TooHotOutside && WeatherOpt.HazardousWeather) - { - if (CurrentWeather.UnusualWeather == SpecialWeather.DryLightning) - CurrentWeather.UnusualWeather = SpecialWeather.DryLightningAndHeatwave; - else - CurrentWeather.UnusualWeather = SpecialWeather.Heatwave; - } - } - - if (WeatherOpt.Verbose) - Monitor.Log("Testing for special weathers - frost."); - - if (CurrentWeather.GetTodayLow() < WeatherOpt.TooColdOutside && !Game1.IsWinter) + + if (Conditions.TestForSpecialWeather(GameClimate.GetClimateForDate(SDate.Now()).RetrieveOdds(Dice, "fog", SDate.Now().Day, DebugOutput))) { - if (WeatherOpt.HazardousWeather) - { - CurrentWeather.UnusualWeather = SpecialWeather.Frost; - } - } - - } - - private bool CheckForForceDay(SDate Target) - { - foreach (KeyValuePair entry in ForceDays) - { - if (entry.Key.Day == Target.Day && entry.Key.Season == Target.Season) - { - if (WeatherOpt.Verbose) - Monitor.Log($"Setting {entry.Value}"); - Game1.weatherForTomorrow = entry.Value; - return true; - } + Monitor.Log("Special weather created!"); } - return false; } /* ************************************************************** @@ -897,79 +779,6 @@ private bool CheckForForceDay(SDate Target) * ************************************************************** */ - /// - /// This function changes the weather (Console Command) - /// - /// The command used - /// The console command parameters - private void DebugChgCondition(string arg1, string[] arg2) - { - if (arg2.Length < 1) - return; - - string ChosenWeather = arg2[0]; - - switch (ChosenWeather) - { - case "blizzard": - WeatherChangeFromConsole("blah", new string[] { "snow" }); - CurrentWeather.UnusualWeather = SpecialWeather.Blizzard; - break; - case "reset": - WeatherChangeFromConsole("blah", new string[] { "sunny" }); - CurrentWeather.UnusualWeather = SpecialWeather.None; - CurrentWeather.ResetFog(); - break; - case "thundersnow": - WeatherChangeFromConsole("blah", new string[] { "snow" }); - CurrentWeather.UnusualWeather = SpecialWeather.Thundersnow; - break; - case "drylightning": - WeatherChangeFromConsole("blah", new string[] { "sunny" }); - CurrentWeather.UnusualWeather = SpecialWeather.DryLightning; - break; - case "fogblizzard": - CurrentWeather.InitFog(Dice, WeatherOpt); - CurrentWeather.SetFogExpirTime(new SDVTime(1900)); - WeatherChangeFromConsole("blah", new string[] { "snow" }); - CurrentWeather.UnusualWeather = SpecialWeather.Blizzard; - break; - case "fulldayfog": - CurrentWeather.InitFog(Dice, WeatherOpt); - CurrentWeather.SetFogExpirTime(new SDVTime(2400)); - break; - case "fog": - CurrentWeather.ResetFog(); - CurrentWeather.InitFog(Dice, WeatherOpt, false); - CurrentWeather.SetFogExpirTime(new SDVTime(1900)); - break; - case "clearfog": - CurrentWeather.ResetFog(); - break; - case "darkfog": - CurrentWeather.InitFog(Dice, WeatherOpt); - CurrentWeather.ForceDarkFog(); - CurrentWeather.SetFogExpirTime(new SDVTime(1900)); - break; - case "heatwave": - CurrentWeather.UnusualWeather = SpecialWeather.Heatwave; - break; - case "frost": - CurrentWeather.UnusualWeather = SpecialWeather.Frost; - break; - } - } - - /// - /// This function changes the weather (Console Command) - /// - /// The command used - /// The console command parameters - private void DebugStaForce(string arg1, string[] arg2) - { - StaminaMngr.MakeSick(); - } - /// /// This function changes the weather (Console Command) /// @@ -988,34 +797,62 @@ private void WeatherChangeFromConsole(string arg1, string[] arg2) Game1.isSnowing = Game1.isLightning = Game1.isDebrisWeather = false; Game1.isRaining = true; Game1.debrisWeather.Clear(); + Conditions.GetWeatherMatchingType("Blizzard").First().EndWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); Monitor.Log(Helper.Translation.Get("console-text.weatherset_rain"), LogLevel.Info); break; case "storm": Game1.isSnowing = Game1.isDebrisWeather = false; Game1.isLightning = Game1.isRaining = true; Game1.debrisWeather.Clear(); + Conditions.GetWeatherMatchingType("Blizzard").First().EndWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); Monitor.Log(Helper.Translation.Get("console-text.weatherset_storm"), LogLevel.Info); break; case "snow": Game1.isRaining = Game1.isLightning = Game1.isDebrisWeather = false; Game1.isSnowing = true; Game1.debrisWeather.Clear(); + Conditions.GetWeatherMatchingType("Blizzard").First().EndWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); Monitor.Log(Helper.Translation.Get("console-text.weatherset_snow"), LogLevel.Info); break; case "debris": Game1.isSnowing = Game1.isLightning = Game1.isRaining = false; + Conditions.GetWeatherMatchingType("Blizzard").First().EndWeather(); + Conditions.GetWeatherMatchingType("Fog").First().EndWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); Game1.isDebrisWeather = true; Game1.populateDebrisWeatherArray(); Monitor.Log(Helper.Translation.Get("console-text.weatherset_debris", LogLevel.Info)); break; case "sunny": + Conditions.GetWeatherMatchingType("Blizzard").First().EndWeather(); + Conditions.GetWeatherMatchingType("Fog").First().EndWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); Game1.isSnowing = Game1.isLightning = Game1.isRaining = Game1.isRaining = false; Monitor.Log(Helper.Translation.Get("console-text.weatherset_sun", LogLevel.Info)); break; + case "blizzard": + Game1.isRaining = Game1.isLightning = Game1.isDebrisWeather = false; + Game1.isSnowing = true; + Game1.debrisWeather.Clear(); + Conditions.GetWeatherMatchingType("Blizzard").First().CreateWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().EndWeather(); + Monitor.Log(Helper.Translation.Get("console-text.weatherset_snow"), LogLevel.Info); + break; + case "whiteout": + Game1.isRaining = Game1.isLightning = Game1.isDebrisWeather = false; + Game1.isSnowing = true; + Game1.debrisWeather.Clear(); + Conditions.GetWeatherMatchingType("Blizzard").First().CreateWeather(); + Conditions.GetWeatherMatchingType("WhiteOut").First().CreateWeather(); + Monitor.Log(Helper.Translation.Get("console-text.weatherset_snow"), LogLevel.Info); + break; } Game1.updateWeatherIcon(); - CurrentWeather.GetTodayWeather(); + Conditions.SetTodayWeather(); } /// @@ -1023,7 +860,7 @@ private void WeatherChangeFromConsole(string arg1, string[] arg2) /// /// The command used /// The console command parameters - private void TmrwWeatherChangeFromConsole(string arg1, string[] arg2) + private void TomorrowWeatherChangeFromConsole(string arg1, string[] arg2) { if (arg2.Length < 1) return; @@ -1113,10 +950,12 @@ private void ToggleMenu() /// private void ShowMenu() { + string MenuText = DescriptionEngine.GenerateMenuPopup(Conditions, OurMoon); + // show menu this.PreviousMenu = Game1.activeClickableMenu; - Game1.activeClickableMenu = new WeatherMenu(Monitor, this.Helper.Reflection, OurIcons, Helper.Translation, CurrentWeather, - OurMoon, WeatherOpt, 160, Dice); + Game1.activeClickableMenu = new WeatherMenu(Monitor, this.Helper.Reflection, OurIcons, Helper.Translation, Conditions, + OurMoon, WeatherOpt, MenuText); } /// diff --git a/ClimatesOfFerngill/CustomWeather.cs b/ClimatesOfFerngill/CustomWeather.cs index b1dc9d1..e50391e 100644 --- a/ClimatesOfFerngill/CustomWeather.cs +++ b/ClimatesOfFerngill/CustomWeather.cs @@ -4,15 +4,10 @@ namespace ClimatesOfFerngillRebuild { - public class CustomWeather + public class CustomWeatherOld { private Vector2 snowPos; //snow elements - public CustomWeather() - { - - } - public void DrawBlizzard() { snowPos = Game1.updateFloatingObjectPositionForMovement(snowPos, new Vector2(Game1.viewport.X, Game1.viewport.Y), diff --git a/ClimatesOfFerngill/DaMoon/MoonPhase.cs b/ClimatesOfFerngill/DaMoon/MoonPhase.cs new file mode 100644 index 0000000..09b3bbf --- /dev/null +++ b/ClimatesOfFerngill/DaMoon/MoonPhase.cs @@ -0,0 +1,28 @@ +using StardewValley; +using System; +using StardewModdingAPI; +using StardewValley.TerrainFeatures; +using TwilightShards.Common; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using StardewValley.Locations; +using System.Linq; +using StardewModdingAPI.Utilities; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + public enum MoonPhase + { + NewMoon, + WaxingCrescent, + FirstQuarter, + WaxingGibbeous, + FullMoon, + WaningGibbeous, + ThirdQuarter, + WaningCrescent, + BloodMoon, + ErrorPhase + } +} diff --git a/ClimatesOfFerngill/SDVMoon.cs b/ClimatesOfFerngill/DaMoon/SDVMoon.cs similarity index 77% rename from ClimatesOfFerngill/SDVMoon.cs rename to ClimatesOfFerngill/DaMoon/SDVMoon.cs index d9897da..9475236 100644 --- a/ClimatesOfFerngill/SDVMoon.cs +++ b/ClimatesOfFerngill/DaMoon/SDVMoon.cs @@ -1,5 +1,6 @@ using StardewValley; using System; +using StardewModdingAPI.Utilities; using StardewModdingAPI; using StardewValley.TerrainFeatures; using TwilightShards.Common; @@ -7,30 +8,18 @@ using Microsoft.Xna.Framework; using StardewValley.Locations; using System.Linq; +using TwilightShards.Stardew.Common; namespace ClimatesOfFerngillRebuild { - public enum MoonPhase - { - NewMoon, - WaxingCrescent, - FirstQuarter, - WaxingGibbeous, - FullMoon, - WaningGibbeous, - ThirdQuarter, - WaningCrescent, - ErrorPhase - } - public class SDVMoon { //encapsulated members private MersenneTwister Dice; + private WeatherConfig ModConfig; //internal trackers - internal MoonPhase CurrPhase; - private static int cycleLength = 16; + private static int cycleLength = 14; //chances for various things private double CropGrowthChance; @@ -43,9 +32,10 @@ public class SDVMoon internal readonly int[] beachItems = new int[] { 393, 397, 392, 394 }; internal readonly int[] moonBeachItems = new int[] { 393, 394, 560, 586, 587, 589, 397 }; - public SDVMoon(MersenneTwister rng) + public SDVMoon(WeatherConfig config, MersenneTwister rng) { Dice = rng; + ModConfig = config; //set chances. CropGrowthChance = .09; @@ -53,38 +43,61 @@ public SDVMoon(MersenneTwister rng) BeachRemovalChance = .09; BeachSpawnChance = .35; GhostChance = .02; - CurrPhase = SDVMoon.GetLunarPhase(); } - public void UpdateForNewDay() + + public override string ToString() { - CurrPhase = SDVMoon.GetLunarPhase(); + return DescribeMoonPhase() + " on day " + GetDayOfCycle(); } - public void Reset() + public MoonPhase CurrentPhase => GetLunarPhase(); + + public MoonPhase GetLunarPhase() { - CurrPhase = MoonPhase.ErrorPhase; + //divide it by the cycle. + int currentCycle = (int)Math.Floor(SDate.Now().DaysSinceStart / (double)cycleLength); + int currentDay = GetDayOfCycle(SDate.Now()); + + MoonPhase ret = SDVMoon.GetLunarPhase(currentDay); + + if (ret == MoonPhase.FullMoon) + { + if (Dice.NextDoublePositive() <= ModConfig.BadMoonRising) + return MoonPhase.BloodMoon; + } + + return ret; } - public override string ToString() + private int GetDayOfCycle() { - return DescribeMoonPhase(); + return SDVMoon.GetDayOfCycle(SDate.Now()); } - public static MoonPhase GetLunarPhase() + private static int GetDayOfCycle(SDate Today) { - return SDVMoon.GetLunarPhase((int)Game1.stats.daysPlayed); - } + return Today.DaysSinceStart % cycleLength; + } - public static MoonPhase GetLunarPhase(int day) + /// + /// This function returns the lunar phase for an arbitary day. + /// + /// The day you are examining for. + /// + public static MoonPhase GetLunarPhaseForDay(SDate Today) { //divide it by the cycle. - int currentCycle = (int)Math.Floor(day / (double)cycleLength); - int currentDay = day - (cycleLength * currentCycle); - //int currentDay = day - ((int)(Math.Floor(day / (double)cycleLength)) * cycleLength); + int currentCycle = (int)Math.Floor(Today.DaysSinceStart / (double)cycleLength); + int currentDay = GetDayOfCycle(Today); + return SDVMoon.GetLunarPhase(currentDay); + } + + private static MoonPhase GetLunarPhase(int day) + { //Day 0 and 16 are the New Moon, so Day 8 must be the Full Moon. Day 4 is 1Q, Day 12 is 3Q. Coorespondingly.. - switch (currentDay) + switch (day) { case 0: return MoonPhase.NewMoon; @@ -96,21 +109,19 @@ public static MoonPhase GetLunarPhase(int day) return MoonPhase.FirstQuarter; case 5: case 6: - case 7: return MoonPhase.WaxingGibbeous; - case 8: + case 7: return MoonPhase.FullMoon; + case 8: case 9: + return MoonPhase.WaningGibbeous; case 10: + return MoonPhase.ThirdQuarter; case 11: - return MoonPhase.WaningGibbeous; case 12: - return MoonPhase.ThirdQuarter; case 13: - case 14: - case 15: return MoonPhase.WaningCrescent; - case 16: + case 14: return MoonPhase.NewMoon; default: return MoonPhase.ErrorPhase; @@ -126,10 +137,13 @@ public void HandleMoonAtSleep(Farm f, ITranslationHelper Helper) if (f == null) return; + if (Dice.NextDoublePositive() < .20) + return; + int cropsAffected = 0; //moon processing - if (SDVMoon.GetLunarPhase() == MoonPhase.FullMoon) + if (CurrentPhase == MoonPhase.FullMoon) { foreach (var TF in f.terrainFeatures) { @@ -165,10 +179,10 @@ public void HandleMoonAtSleep(Farm f, ITranslationHelper Helper) } if (cropsAffected > 0) - Game1.addHUDMessage(new HUDMessage(Helper.Get("moon-text.fullmoon_eff"))); + Game1.addHUDMessage(new HUDMessage(Helper.Get("moon-text.fullmoon_eff", new { cropsAffected = cropsAffected }))); } - if (SDVMoon.GetLunarPhase() == MoonPhase.NewMoon) + if (CurrentPhase == MoonPhase.NewMoon) { if (f != null) { @@ -186,17 +200,23 @@ public void HandleMoonAtSleep(Farm f, ITranslationHelper Helper) } if (cropsAffected > 0) - Game1.addHUDMessage(new HUDMessage(Helper.Get("moon-text.newmoon_eff"))); + Game1.addHUDMessage(new HUDMessage(Helper.Get("moon-text.newmoon_eff", new { cropsAffected = cropsAffected }))); } } public void HandleMoonAfterWake(ITranslationHelper Helper) { + if (Game1.getLocationFromName("Beach") is null) + throw new Exception("... Please reinstall your game"); + Beach b = Game1.getLocationFromName("Beach") as Beach; int itemsChanged = 0; - + + if (Dice.NextDoublePositive() < .20) + return; + //new moon processing - if (SDVMoon.GetLunarPhase() == MoonPhase.NewMoon) + if (CurrentPhase == MoonPhase.NewMoon) { List> entries = (from o in b.objects where beachItems.Contains(o.Value.parentSheetIndex) @@ -216,7 +236,7 @@ where beachItems.Contains(o.Value.parentSheetIndex) } //full moon processing - if (SDVMoon.GetLunarPhase() == MoonPhase.FullMoon) + if (CurrentPhase == MoonPhase.FullMoon) { int parentSheetIndex = 0; Rectangle rectangle = new Rectangle(65, 11, 25, 12); @@ -225,8 +245,15 @@ where beachItems.Contains(o.Value.parentSheetIndex) //get the item ID to spawn parentSheetIndex = moonBeachItems.GetRandomItem(Dice); - if (Dice.NextDouble() < .0001) - parentSheetIndex = 392; //rare chance + if (Dice.NextDouble() <= .0001) + parentSheetIndex = 392; //rare chance for a Nautlius Shell. + + else if (Dice.NextDouble() > .0001 && Dice.NextDouble() <= .45) + parentSheetIndex = 589; + + else if (Dice.NextDouble() > .45 && Dice.NextDouble() <= .62) + parentSheetIndex = 60; + if (Dice.NextDouble() < BeachSpawnChance) { @@ -271,7 +298,7 @@ public static string DescribeMoonPhase(MoonPhase mp, ITranslationHelper Helper) private string DescribeMoonPhase() { - switch (this.CurrPhase) + switch (this.CurrentPhase) { case MoonPhase.ErrorPhase: return "Phase Error"; @@ -300,7 +327,7 @@ public bool CheckForGhostSpawn() { if (Game1.timeOfDay > Game1.getTrulyDarkTime() && Game1.currentLocation.isOutdoors && Game1.currentLocation is Farm) { - if (CurrPhase is MoonPhase.FullMoon && Dice.NextDouble() < GhostChance) + if (CurrentPhase is MoonPhase.FullMoon && Dice.NextDouble() < GhostChance) { return true; } diff --git a/ClimatesOfFerngill/Descriptions.cs b/ClimatesOfFerngill/Descriptions.cs new file mode 100644 index 0000000..5c6e423 --- /dev/null +++ b/ClimatesOfFerngill/Descriptions.cs @@ -0,0 +1,392 @@ +using Microsoft.Xna.Framework; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; +using StardewValley.Objects; +using System; +using System.Collections.Generic; +using System.Linq; +using TwilightShards.Common; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + class Descriptions + { + private ITranslationHelper Helper; + private MersenneTwister OurDice; + private WeatherConfig ModConfig; + private IMonitor Output; + + public Descriptions(ITranslationHelper Translaton, MersenneTwister mDice, WeatherConfig wc, IMonitor log) + { + Helper = Translaton; + OurDice = mDice; + ModConfig = wc; + Output = log; + } + + internal string GetDescOfDay(SDate date) + { + return Helper.Get("date" + GeneralFunctions.FirstLetterToUpper(date.Season) + date.Day); + } + + internal string DescribeInGameWeather(int weather) + { + if (weather == Game1.weather_debris) + return Helper.Get("weather_wind"); + if (weather == Game1.weather_festival) + return Helper.Get("weather_festival"); + if (weather == Game1.weather_lightning) + return Helper.Get("weather_lightning"); + if (weather == Game1.weather_rain) + return Helper.Get("weather_rainy"); + if (weather == Game1.weather_snow) + return Helper.Get("weather_snow"); + if (weather == Game1.weather_sunny) + return Helper.Get("weather_sunny"); + if (weather == Game1.weather_wedding) + return Helper.Get("weather_wedding"); + + return "ERROR"; + } + + private string GetTemperatureString(double temp) + { + if (ModConfig.ShowBothScales) + { + //Temp = "34 C (100 F)" + return $"{temp.ToString("N1")} C ({GeneralFunctions.ConvCtF(temp).ToString("N1")} F)"; + } + else + { + return $"{temp.ToString("N1")} C"; + } + } + + internal string UpperSeason(string season) + { + if (season == "spring") return "Spring"; + if (season == "winter") return "Winter"; + if (season == "fall") return "Fall"; + if (season == "summer") return "Summer"; + + return "error"; + } + + internal string GenerateMenuPopup(WeatherConditions Current, SDVMoon Moon) + { + string text = ""; + + if (SDate.Now().Season == "spring" && SDate.Now().Day == 1) + text = Helper.Get("weather-menu.openingS1D1", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; + else if (SDate.Now().Season == "winter" && SDate.Now().Day == 28) + text = Helper.Get("weather-menu.openingS4D28", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; + else + text = Helper.Get("weather-menu.opening", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; + + if (Current.ContainsCondition(CurrentWeather.Heatwave)) + { + text += Helper.Get("weather-menu.condition.heatwave") + Environment.NewLine; + } + + if (Current.ContainsCondition(CurrentWeather.Frost)) + { + text += Helper.Get("weather-menu.condition.frost") + Environment.NewLine; + } + + ISDVWeather CurrentFog = Current.GetWeatherMatchingType("Fog").First(); + string fogString = ""; + + // If the fog is visible, we don't need to display fog information. However, if it's in the morning, + // and we know evening fog is likely, we should display the message it's expected + // That said, if it's not, we need to pull the fog information down, assuming it's been reset. This checks that the fog end + // time is *before* now. To avoid nested trinary statements.. + if (SDVTime.CurrentTime < CurrentFog.WeatherExpirationTime && Current.GenerateEveningFog && CurrentFog.WeatherBeginTime < new SDVTime(1200)) + fogString = Helper.Get("weather-menu.expectedFog"); + if (CurrentFog.WeatherBeginTime > SDVTime.CurrentTime && Current.GenerateEveningFog) + fogString = Helper.Get("weather-menu.fogFuture", + new + { + fogTime = CurrentFog.WeatherBeginTime.ToString(), + endFog = CurrentFog.WeatherExpirationTime.ToString() + }); + + //Current Conditions. + text += Helper.Get("weather-menu.current", new + { + todayCondition = Current.HasWeather(CurrentWeather.Fog) ? Helper.Get("weather-menu.fog", new { condition = GetBasicWeather(Current, Game1.currentSeason), fogTime = CurrentFog.IsWeatherVisible ? CurrentFog.WeatherExpirationTime.ToString() : "" }) : GetBasicWeather(Current, Game1.currentSeason), + + todayHigh = GetTemperatureString(Current.TodayHigh), + todayLow = GetTemperatureString(Current.TodayLow), + fogString = fogString + }) + Environment.NewLine; + + //Tomorrow weather + text += Helper.Get("weather-menu.tomorrow", + new { + tomorrowCondition = GetBasicWeather(Game1.weatherForTomorrow, Game1.currentSeason), + tomorrowLow = GetTemperatureString(Current.TomorrowLow), + tomorrowHigh = GetTemperatureString(Current.TomorrowHigh) + }) + Environment.NewLine; + + return text; + } + + internal string GenerateTVForecast(WeatherConditions Current, SDVMoon Moon) + { + //assemble params + var talkParams = new Dictionary + { + { "location", GetRandomLocation() }, + { "descWeather", GetWeather(Current, Game1.currentSeason) }, + { "festival", SDVUtilities.GetFestivalName(SDate.Now()) }, + { "festivalTomorrow", SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) }, + { "fogTime", Current.GetFogTime().ToString() }, + { "todayHigh", GetTemperatureString(Current.TodayHigh) }, + { "todayLow", GetTemperatureString(Current.TodayLow) }, + { "tomorrowWeather", GetWeather(Game1.weatherForTomorrow, Game1.currentSeason, true) }, + { "tomorrowHigh", GetTemperatureString(Current.TomorrowHigh) }, + { "tomorrowLow", GetTemperatureString(Current.TomorrowLow) }, + { "condWarning", GetCondWarning(Current) }, + { "condString", GetCondWarning(Current) }, + { "eveningFog", GetEveningFog(Current) } + }; + + //select the weather string for the TV. + SDVTimePeriods CurrentPeriod = SDVTime.CurrentTimePeriod; //get the current time period + int nRandom = OurDice.Next(2); + + //first, check for special conditions -fog, festival, wedding + if (Current.HasWeather(CurrentWeather.Fog)) + { + return Helper.Get($"weat-loc.fog.{nRandom}", talkParams); + } + + //festival today + else if (Current.HasWeather(CurrentWeather.Festival)) + { + return Helper.Get("weat-fesToday.0", talkParams); + } + + //festival tomorrow + else if (SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) != "") + { + return Helper.Get("weat-fesTomorrow.0", talkParams); + } + + //wedding today + else if (Current.HasWeather(CurrentWeather.Wedding)) + { + return Helper.Get("weat-wedToday.0", talkParams); + } + + //wedding tomrrow + else if (Game1.countdownToWedding == 1) + { + talkParams["tomrrowWeather"] = Helper.Get($"weat-{Game1.currentSeason}.sunny.{nRandom}"); + return Helper.Get("weat-wedTomorrow.0", talkParams); + } + + if (OurDice.NextDoublePositive() > .45) + { + if (CurrentPeriod == SDVTimePeriods.Morning) + return Helper.Get($"weat-morn.{nRandom}", talkParams); + else if (CurrentPeriod == SDVTimePeriods.Afternoon) + return Helper.Get($"weat-afternoon.{nRandom}", talkParams); + else if (CurrentPeriod == SDVTimePeriods.Evening) + return Helper.Get($"weat-evening.{nRandom}", talkParams); + else if (CurrentPeriod == SDVTimePeriods.Night) + return Helper.Get($"weat-night.{nRandom}", talkParams); + else if (CurrentPeriod == SDVTimePeriods.Midnight) + return Helper.Get($"weat-midnight.{nRandom}", talkParams); + else if (CurrentPeriod == SDVTimePeriods.LateNight) + return Helper.Get($"weat-latenight.{nRandom}", talkParams); + } + else + { + //ye olde generic! + return Helper.Get($"weat-loc.{nRandom}", talkParams); + } + + return ""; + } + + private string GetEveningFog(WeatherConditions Current) + { + if (Current.GenerateEveningFog) + { + var fList = Current.GetWeatherMatchingType("Fog"); + foreach (ISDVWeather weat in fList) + { + if (weat is FerngillFog fWeat) + { + if (Current.GetWeatherMatchingType("Fog").First().IsWeatherVisible && (SDVTime.CurrentTime > new SDVTime(1200))) + return Helper.Get("weather-condition.fog", new { fogTime = fWeat.WeatherExpirationTime.ToString() }); + else + { + if (fWeat.WeatherBeginTime != fWeat.WeatherExpirationTime) + return Helper.Get("weather-condition.evenFog", new { startTime = fWeat.WeatherBeginTime.ToString(), endTime = fWeat.WeatherExpirationTime.ToString() }); + else + return ""; + } + } + } + return ""; + } + else + return ""; + } + + private string GetCondWarning(WeatherConditions Current) + { + int rNumber = OurDice.Next(2); + if (Current.ContainsCondition(CurrentWeather.Heatwave)) + return Helper.Get($"weather-condition.heatwave.{rNumber}"); + + if (Current.ContainsCondition(CurrentWeather.Frost)) + return Helper.Get($"weather-condition.frost.{rNumber}"); + + if (Current.ContainsCondition(CurrentWeather.WhiteOut)) + return Helper.Get($"weather-condition.whiteout.{rNumber}"); + + return ""; + } + + private string GetWeather(int weather, string season, bool TomorrowWeather = false) + { + int rNumber = OurDice.Next(2); + + if (weather == Game1.weather_debris) + return Helper.Get($"weat-{season}.debris.{rNumber}"); + else if (weather == Game1.weather_festival || weather == Game1.weather_wedding || weather == Game1.weather_sunny && SDVTime.CurrentIntTime < Game1.getModeratelyDarkTime() && !TomorrowWeather) + return Helper.Get($"weat-{season}.sunny_daytime.{rNumber}"); + else if (weather == Game1.weather_festival || weather == Game1.weather_wedding || weather == Game1.weather_sunny && SDVTime.CurrentIntTime >= Game1.getModeratelyDarkTime() && !TomorrowWeather) + return Helper.Get($"weat-{season}.sunny_nighttime.{rNumber}"); + else if (weather == Game1.weather_festival || weather == Game1.weather_wedding || weather == Game1.weather_sunny && TomorrowWeather) + return Helper.Get($"weat-{season}.sunny_daytime.{rNumber}"); + else if (weather == Game1.weather_lightning) + return Helper.Get($"weat-{season}.stormy.{rNumber}"); + else if (weather == Game1.weather_rain) + return Helper.Get($"weat-{season}.rainy.{rNumber}"); + else if (weather == Game1.weather_snow) + return Helper.Get($"weat-{season}.snow.{rNumber}"); + + return "ERROR"; + } + + private string GetBasicWeather(int weather, string season) + { + int rNumber = OurDice.Next(2); + + if (weather == Game1.weather_debris) + return Helper.Get($"weather_wind"); + else if (weather == Game1.weather_festival || weather == Game1.weather_wedding) + return Helper.Get($"weather_sunny"); + else if (weather == Game1.weather_lightning) + return Helper.Get($"weather_lightning"); + else if (weather == Game1.weather_rain) + return Helper.Get($"weather_rainy"); + else if (weather == Game1.weather_snow) + return Helper.Get($"weather_snow"); + else if (weather == Game1.weather_sunny) + return Helper.Get($"weather_sunny"); + + return "ERROR"; + } + + private string GetBasicWeather(WeatherConditions Weather, string season) + { + if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconBlizzard || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWhiteOut) + return Helper.Get($"weather_blizzard"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSpringDebris || Weather.CurrentWeatherIconBasic == WeatherIcon.IconDebris) + return Helper.Get($"weather_wind"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconDryLightning) + return Helper.Get($"weather_drylightning"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime < Game1.getModeratelyDarkTime()) + return Helper.Get($"weather_sunny_daytime"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime >= Game1.getModeratelyDarkTime()) + return Helper.Get($"weather_sunny_nighttime"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconStorm) + return Helper.Get($"weather_lightning"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSnow) + return Helper.Get($"weather_snow"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconRain) + return Helper.Get($"weather_rainy"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconThunderSnow) + return Helper.Get($"weather_thundersnow"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding) + return Helper.Get($"weather_wedding"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival) + return Helper.Get($"weather_festival"); + return "ERROR"; + } + + private string GetWeather(WeatherConditions Weather, string season) + { + int rNumber = OurDice.Next(2); + + if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconBlizzard || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWhiteOut) + return Helper.Get($"weat-{season}.blizzard.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSpringDebris || Weather.CurrentWeatherIconBasic == WeatherIcon.IconDebris) + return Helper.Get($"weat-{season}.debris.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconDryLightning) + return Helper.Get($"weat-{season}.drylightning.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding || Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival || Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime < Game1.getModeratelyDarkTime()) + return Helper.Get($"weat-{season}.sunny_daytime.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding || Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival && SDVTime.CurrentIntTime >= Game1.getModeratelyDarkTime()) + return Helper.Get($"weat-{season}.sunny_nighttime.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconStorm) + return Helper.Get($"weat-{season}.stormy.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSnow) + return Helper.Get($"weat-{season}.snow.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconRain) + return Helper.Get($"weat-{season}.rainy.{rNumber}"); + else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconThunderSnow) + return Helper.Get($"weat-{season}.thundersnow.{rNumber}"); + + return "ERROR"; + } + + private string GetRandomLocation() + { + return Helper.Get("fern-loc." + OurDice.Next(12)); + } + + internal TemporaryAnimatedSprite GetWeatherOverlay(WeatherConditions Current, TV tv) + { + Rectangle placement = new Rectangle(413, 333, 13, 13); + + switch (Current.CurrentWeatherIconBasic) + { + case WeatherIcon.IconSunny: + case WeatherIcon.IconWedding: + case WeatherIcon.IconDryLightning: + placement = new Rectangle(413, 333, 13, 13); + break; + case WeatherIcon.IconRain: + placement = new Rectangle(465, 333, 13, 13); + break; + case WeatherIcon.IconDebris: + placement = (Game1.currentSeason.Equals("fall") ? new Rectangle(413, 359, 13, 13) : new Rectangle(465, 346, 13, 13)); + break; + case WeatherIcon.IconSpringDebris: + placement = new Rectangle(465, 359, 13, 13); + break; + case WeatherIcon.IconStorm: + placement = new Rectangle(413, 346, 13, 13); + break; + case WeatherIcon.IconFestival: + placement = new Rectangle(413, 372, 13, 13); + break; + case WeatherIcon.IconSnow: + case WeatherIcon.IconBlizzard: + case WeatherIcon.IconWhiteOut: + placement = new Rectangle(465, 346, 13, 13); + break; + } + + return new TemporaryAnimatedSprite(Game1.mouseCursors, placement, 100f, 4, 999999, tv.getScreenPosition() + new Vector2(3f, 3f) * tv.getScreenSizeModifier(), false, false, (float)((double)(tv.boundingBox.Bottom - 1) / 10000.0 + 1.99999994947575E-05), 0.0f, Color.White, tv.getScreenSizeModifier(), 0.0f, 0.0f, 0.0f, false); + } + } +} diff --git a/ClimatesOfFerngill/FerngillFog.cs b/ClimatesOfFerngill/FerngillFog.cs deleted file mode 100644 index 5f28270..0000000 --- a/ClimatesOfFerngill/FerngillFog.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ClimatesOfFerngill/README.md b/ClimatesOfFerngill/README.md index f28c2c2..2b16e5e 100644 --- a/ClimatesOfFerngill/README.md +++ b/ClimatesOfFerngill/README.md @@ -1,12 +1,19 @@ # Climates of Ferngill (Rebuild) You Can (Not) Have Weather -Current Version (4 November 2017): v1.2 rc1 +Current Version (4 Feburary 2018): 1.3 ## What's New - Fog! - Blizzards, Thundersnow - A more customizable weather system +- More descriptive and varied weather reports + +## Requirements + +- SMAPI 2.3+ +- Stardew Valley 1.2.33+ +- PyTK 0.7.0+ ## Overview @@ -33,13 +40,14 @@ Every ten minutes, the mod checks to see if you've been outside for a certain pe *Special Weathers: Thundersnow, Blizzard (NB: While you incur a stamina penalty for being sick in fog, it deliberately does not trigger this.) -The penalties are cumulative - that is, they add up to the final multiplier. +The penalties are **cumulative** - that is, they add up to the final multiplier. *Lightning : +100% ( 1) *Thundersnow: +100% (1) *Thundersnow (nighttime): +50% (.5) *Foggy: +50% (.5) *Foggy (nightime) +25% (.25) *Blizzard: +125% (1.25) +*Blizzard: **White Out**+225% (2.25) *Blizzard (nighttime) +50% (.5) *Frost (nightime): +125% (1.25) - this is not during the winter. During winter, the frost penalty is untriggered. *Heatwave (daytime): +125% (1.25) @@ -49,7 +57,7 @@ The calculated number is then rounded __down__ For example, therefore, if you're outduring a storm, with the base of 2, you only take a stamina penalty of 2. But if it's also a heatwave, your penatly is now (+1+1.25)=*2.25 or 4.5. So a penalty of 4. If you're out in a blizzard during the day, it's *1.25 or 2.5 rounded down to 2. If you're out in that blizzard at night, another .5 (1.25+.5) is added making it 1.75 or 3.5 rounded down to 3. -(This does mean a foggy blizzard at night is (+.5+.25+1.25+.5 or *2.25), and if you somehow get this in fall, would be *3.5) +(This does mean a foggy blizzard at night is (+.5+.25+1.25+.5 or *2.25), and if you somehow get this in fall, would be *3.5. And somehow, if you get a whiteout, it would be *3.25 and *4.5!) ## Known Issues @@ -57,7 +65,112 @@ If you're out in a blizzard during the day, it's *1.25 or 2.5 rounded down to 2. ## Wishlist +## Acknowledgements +- eemie for the moon sprites +- Prismuth for the fog sprite +- Pathoschild for ideas +- ChefRude for testing and the night icon sprites (as well as better fog textures) + ## Changelog +v1.3 +- custom popup text on first and last day of the year + +v1.3beta8 + - updated descriptors for (sunny, at night) + - updated evening fog descriptor to not show the fog beginning once started + - added special descriptors for the easter egg. + - some differnation done on current descriptors + - fixed some issues lingering with fog lines not spacing correctly + - refined some of the text to read more cleanly + - added conversion chance for snow in spring if it's cold enough + +v1.3beta7 + - Updated the console command code to be more.. proper. + - Added a easter egg blizzard mode. + +v1.3beta6 + - ISDVWeather now implements a EndWeather + - Console commands can now arbitarily trigger blizzards + - Fog code cleaned up to remove old code + - Sprites cleaned up to remove old sprite code. + - Festival text fixes + +v1.3beta5 +- fog text fixes (remove duplicate fog text, evening fog properly display) + +v1.3beta4 +- text fixes (fog Time not appearing, temperature string incomplete) +- modified the menu screen to work properly over fog. + +v1.3beta3 +- .. somehow the text fixes didn't take? +- cleaned up various elements of the code - no longer attempts to IAssetEditor +- fixes the spring wind icon not appearing on the TV. + +v1.3beta2 +- text fixes: spring wind may not display properly on the TV +- fix for the mouse not properly redrawing + +v1.3beta1 +- merged in the solar eclipse mod. +- text fixes +- added in weather popup +- solar eclipse will now only trigger on full moons and will prohibit fog formation. +- updated manifest to require PyTK to prevent any issues with it not loading before this mod. + +v1.3alpha41 +- fixes tv icon +- text fixes + +-v1.3alpha40 +- reimplemented the text for the TV. +- fixed the heatwave icons +- fixed stamina issue with getting sick more than once +- fixed a bug where frost kills didn't respect allow crop death + +v1.3alpha29 +- moved to PyTK +- thanks to ChefRude's new neight icons, we now have night icons! +- refined the mod's definition of night to be TrulyDarkTime +- made the stamina drain mesages more descriptive to the reason induced +- fixed some weather status icons to properly appear + +v1.3alpha28 + - evening fog will now respect the fact it's windy and stay away + - some of the debug output updated to be more useful + +v1.3alpha27 +- The weather icon is working, and the pointer properly draws over it now +- fixed the cold repeating itself +- fog fade in/out is slowed down +- easter egg removed + +v1.3alpha3 +- easter egg added - the desert has snow in real time Dec 15 til Jan 4. +- a new fade in/out method of fog has been added, and the lighting system should work normally + +v1.3alpha2 +- Architecture change - now uses an interface to streamline adding new weathers to draw mechanics +- Fog can now also be at night also. + +v1.2rc2-2 (v1.3-beta1) +- refactoring +- began push to improve TV text +- new fog texture +- now reuses CustomTV to make sure it's compatible with stuff like DailyNews +- #%@%@%@@@@%@%@@%@%@ + +v1.2rc2 (v1.3-beta1) +- fog is now properly dark and either way, the fog fades over time. +- fall climates in normal and enhanced from Fall 19 to Fall 28 produced way too much fog +- frosts now get full resistance on crops +- the frost death message will now tell you how many died +- stamina system overhauled that you won't get sick from something you can't suffer from events at the time. +- bad moon rising: blood moons will appear. +- new sprites, thanks to eemie, that more closely match the vanilla ones! +- lunar events now have a 20% chance to not trigger +- stamina system now factors in luck and a few other things. + v1.1.12p5 - overhauled stamina system to correct an odd error. See writeup for more details. - updated the console command to actually update the internal tracker. :v @@ -99,11 +212,6 @@ v1.1.12 beta - added stamina drains back in - heatwaves and frosts are back in, and now it triggers during certain times. -##Requirements - -- Stardew Valley: 1.2.33+ -- SMAPI: 1.15.4+ - ## Config Options - `ClimateType` - set to weather that has a corresponding file in `data\weather\`. Packaged with the mod is @@ -157,8 +265,20 @@ over a certain value.). Valid 0-1, but it's recommended that this is kept low. D - 'DeadCropPercentage' - The amount of crops that a heatwave and frost can kill. (Note: Frost will kill more than heatwaves). Default: '.1' Valid range is 0 to 1. - - 'CropResistance' - This represents the resistance an averagecrop has to heatwaves. Frosts have half this resistance. Default: '.4' Valid Range is 0 to 1. + - 'CropResistance' - This represents the resistance an average crop has to heatwaves and frosts. Default: '.4' Valid Range is 0 to 1. - 'DarkFogChance' - This controls the chance of the darker fog appearing. Default is set to '.0875' (or a 1/8th chance if it's foggy it'll be dark fog.) Valid Range is 0 to 1. - - 'ChanceOfGettingSick' - Controls the chance you'll get sick when conditions are matched. Default is set to '.7' for (70% chance). Valid Range is 0 to 1. \ No newline at end of file + - 'ChanceOfGettingSick' - Controls the chance you'll get sick when conditions are matched. Default is set to '.7' for (70% chance). Valid Range is 0 to 1. + + - 'Use12HourTime' - Tells it whether or not to use 12hour time or not in displays. Defaults to false. Valid: true, false + + - 'BadMoonRising' - Chance of a blood moon on a full moon. Default: .004 (.4%). Valid Range is 0 to 1. + + - 'EclipseOn' - Whether or not the eclipse is enabled. Defaults to true. (NOTE: Will not trigger until at least Spring 2, and must be a full moon.) (valid: true, false) + + - 'EclipseChance' - The chance of an eclipse every full moon. Defaults to .015 (1.5%) Valid Range is 0 to 1. + + - 'SpawnMonsters' - Controls if monsters spawn on your wilderness farm. Default: true. Valid: true, false + + - 'SpawnMonstersAllFarms' - Controls if monsters spawn on all farms. Default: false. Valid: true, false \ No newline at end of file diff --git a/ClimatesOfFerngill/README.txt b/ClimatesOfFerngill/README.txt new file mode 100644 index 0000000..f28c2c2 --- /dev/null +++ b/ClimatesOfFerngill/README.txt @@ -0,0 +1,164 @@ +# Climates of Ferngill (Rebuild) You Can (Not) Have Weather + +Current Version (4 November 2017): v1.2 rc1 + +## What's New + +- Fog! +- Blizzards, Thundersnow +- A more customizable weather system + +## Overview + +This mod does the following: + +- Alters the weather via a custom method that can read custom files +- Adds in several custom weathers - Thundersnow! Blizzards! Dry Lightning! +- Changes the rain totem to occasionally spawm storms as well. +- Adds a moon overhead, which will act on the world +- Adds a weather menu option, which will display information about the weather +- Changes the text for the TV weather channel +- Going out in storms, blizzards, frosts and heatwaves is now more perilous, as it drains your stamina. Thankfully, + a 'Muscle Remedy' has been found to cure even the hardiest flu + +## Stamina System + +__Very Important: Read this before you alter StaminaDrain in the config!__ + +Rather than a fixed penalty for certain conditions, this now calculates a multiplier based on the conditions prevailing. + +Every ten minutes, the mod checks to see if you've been outside for a certain percentage of the last 10 minutes. By default, it's set to 65%. (This percentage is calculated by counting the ticks you've been outside and the total number in the span to account for time change mods). Then, it generates a random number and tests it against a chance to get sick. By default, this is 70%. In addition, this must be during certain weather conditions: +*Temperature: Frost or Heatwave (as defined in the config file, see the readme for more information) +*Weathers: Lightning +*Special Weathers: Thundersnow, Blizzard +(NB: While you incur a stamina penalty for being sick in fog, it deliberately does not trigger this.) + +The penalties are cumulative - that is, they add up to the final multiplier. +*Lightning : +100% ( 1) +*Thundersnow: +100% (1) +*Thundersnow (nighttime): +50% (.5) +*Foggy: +50% (.5) +*Foggy (nightime) +25% (.25) +*Blizzard: +125% (1.25) +*Blizzard (nighttime) +50% (.5) +*Frost (nightime): +125% (1.25) - this is not during the winter. During winter, the frost penalty is untriggered. +*Heatwave (daytime): +125% (1.25) + +The calculated number is then rounded __down__ + +For example, therefore, if you're outduring a storm, with the base of 2, you only take a stamina penalty of 2. But if it's also a heatwave, your penatly is now (+1+1.25)=*2.25 or 4.5. So a penalty of 4. +If you're out in a blizzard during the day, it's *1.25 or 2.5 rounded down to 2. If you're out in that blizzard at night, another .5 (1.25+.5) is added making it 1.75 or 3.5 rounded down to 3. + +(This does mean a foggy blizzard at night is (+.5+.25+1.25+.5 or *2.25), and if you somehow get this in fall, would be *3.5) + +## Known Issues + +## To Do + +## Wishlist + +## Changelog +v1.1.12p5 + - overhauled stamina system to correct an odd error. See writeup for more details. + - updated the console command to actually update the internal tracker. :v + - possiblity of all day fog (.1%) added to fog time + +v1.1.12p4 + - the hud overdraw code is now disabled on festival days + - the hud overdraw code that was unneccesary was removed + - it should properly not darken on inventory menu (and others, by using the right event) + - error fixed on normal and enhanced climates during the second week of spring + - corrected an incorrect filter causing wind to never be added + +v1.1.12p3 +- Text tweaks to make it flow properly +- The TV and popup will have some lines about fog now +- The popup will scroll. +- The probability of dark fog will be lowered to 8.75% and configurable in the settings option. It will also now default to having day 1 not having dark fog (probably hard coded to prevent option bloat) +- Cleaned up some of the code, removed some debug spam +- Rain Totems override chance isn't just the first one now, although that means if you get it to set a Storm totem, the next use might override it.. +- fixed issue where festival name would never appear in the popup, and the wrong text was called for the TV. +- fixed issue where summer drylightning tried to call for thundersnow (!) +- added fog icons to the weather hud, as well as a blizzard one +- the window will be dark while it is foggy outside +- fixed a path display error in Linux +- fixed the path being capitlization inspecific +- the mouse will draw over the icon again, and the weather icon darkens properly + when menus draw. + - No longer darkens for dialogue when it shouldn't. +- fixed fog and snow drawing over hud code. + +v1.1.12p2 +- removed fog testing code. + +v1.1.12p1 +- replaced the totem detection code to make it a bit more tolerant of fault + +v1.1.12 beta +- fixed an issue with festivals +- added stamina drains back in +- heatwaves and frosts are back in, and now it triggers during certain times. + +##Requirements + +- Stardew Valley: 1.2.33+ +- SMAPI: 1.15.4+ + +## Config Options + +- `ClimateType` - set to weather that has a corresponding file in `data\weather\`. Packaged with the mod is +`normal`, `extended`, `arid`, `dry`, `wet`, `monsoon`. Default: `normal`. + +- `ThundersnowOdds` - This controls the odds of thundersnow. (Custom weather available during the snow.) Valid: 0-1, but it's +recommended that this is kept low. Default: `.001` (.1%) + +- `BlizzardOdds` - This controls the odds of blizzards (Custom weather available during the snow.). Valid 0-1, but it's +recommended that this is kept low. Default: `.08` (8%) + +- `DryLightning` - This controls the odds of dry lightning (Custom weather available during any clear day, as long as the temperature is +over a certain value.). Valid 0-1, but it's recommended that this is kept low. Default: `.1` (10%) + +- `DryLightningMinTemp` - This controls the minimum temperature to trigger the DryLightning event. + Defaults to `34`. Values are in Celsius. (34 C is 93.2 F) + +- 'TooColdOutside' - This controls the temperature required (the *low* temperature required) to trigger the Frost event. Note this is a Spring and Fall event, and will potentially kill crops + Defaults to '-3'. Values are in Celsius (1 C is 33.8 F). + NOTE: Frosts trigger at dark + +- 'TooHotOutside' - This controls the temperature required (the *high* temperature required) to trigger the Heatwave event. + Defaults to '39'. Values are in Celsius (39 C is 102.2 F) + NOTE : Heatwaves taper off at night. + +- `SnowOnFall28` - If set to true, this will force snow fall and appropriate temperatures on Fall 28. Default: `false`, + Valid: `true` or `false` + +- `StormTotemChange` - Usage of the rain totem will now spawn storms with the same odds as spawning storms on + rainy days. Default: `true`. Valid: `true` or `false`. + +- `Verbose` - This makes the mod noisy to provide a lot of debug options. Default: `false`. Valid: `true` or `false`. + +- `AllowStormsSpringYear1` - Default: `false`. Normally, you can't get storms in Spring Y1. This keeps that valid. Valid: `true` or + `false` + +- `DisplayBothScales` - Default: `false`. This will display both known scales. Set to `true`, if you want to see Farenheit as well. + +- `HazardousWeather` - Default: `false`. This turns on hazardous weather. It's normally turned off. Right now, it only turns on the heatwave and frost events + IMPORTANT NOTE: This only enables the stamina drain on them, and the dewatering of the heatwave. Frost's crop death will remain disabled, + as well not watering the plants in time for a heatwave. + +- `AllowCropDeath` - Default: `false`. Normally, hazardous weather won't kill crops, just stop them growing. This reenables crop death.' + +- 'AffectedOutside' - The percentage outside you need to be within a 10 minute span to be affected by stamina events. + Defaults to '.65', valid values are between 0 and 1. To turn stamina drains off entirely, set it to 0. + + - 'SickMoreThanOnce' - By default, the false means you can only get sick once a day. Set it to true to be affected by multiple colds. + + - 'StaminaDrain' - This is an int containing the default stamina drain for hazardous events. See the writeup (soon) for more information. Default is '2'. Valid range is any number between foo and bar.' + + - 'DeadCropPercentage' - The amount of crops that a heatwave and frost can kill. (Note: Frost will kill more than heatwaves). Default: '.1' Valid range is 0 to 1. + + - 'CropResistance' - This represents the resistance an averagecrop has to heatwaves. Frosts have half this resistance. Default: '.4' Valid Range is 0 to 1. + + - 'DarkFogChance' - This controls the chance of the darker fog appearing. Default is set to '.0875' (or a 1/8th chance if it's foggy it'll be dark fog.) Valid Range is 0 to 1. + + - 'ChanceOfGettingSick' - Controls the chance you'll get sick when conditions are matched. Default is set to '.7' for (70% chance). Valid Range is 0 to 1. \ No newline at end of file diff --git a/ClimatesOfFerngill/SpecialWeather.cs b/ClimatesOfFerngill/SpecialWeather.cs index fad25ef..3ed41a1 100644 --- a/ClimatesOfFerngill/SpecialWeather.cs +++ b/ClimatesOfFerngill/SpecialWeather.cs @@ -1,6 +1,6 @@ namespace ClimatesOfFerngillRebuild { - public enum SpecialWeather + public enum SpecialWeatherOLD { None = 0, Thundersnow = 1, diff --git a/ClimatesOfFerngill/Sprites.cs b/ClimatesOfFerngill/Sprites.cs index bba0b52..b194796 100644 --- a/ClimatesOfFerngill/Sprites.cs +++ b/ClimatesOfFerngill/Sprites.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework; +using EnumsNET; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; using StardewModdingAPI; @@ -7,7 +8,7 @@ namespace ClimatesOfFerngillRebuild { - internal class Sprites + public class Sprites { /// Sprites used to draw a letter. public static class Letter @@ -22,15 +23,46 @@ public static class Letter /// Sprites used for drawing various weather stuff public class Icons { - public Texture2D source; + public Texture2D WeatherSource; + public Texture2D MoonSource; + public Texture2D FogTexture; public static Texture2D source2; public Icons(IContentHelper helper) { - source = helper.Load(Path.Combine("Assets","climatesheet2.png")); + WeatherSource = helper.Load(Path.Combine("Assets","WeatherIcons2.png")); + MoonSource = helper.Load(Path.Combine("Assets", "MoonPhases.png")); + FogTexture = helper.Load(Path.Combine("Assets", "ThickerFog.png")); source2 = Game1.mouseCursors; } + public Rectangle GetNightMoonSprite(MoonPhase currPhase) + { + switch (currPhase) + { + case MoonPhase.BloodMoon: + return Icons.BloodMoon; + case MoonPhase.NewMoon: + return Icons.NewMoon; + case MoonPhase.WaxingCrescent: + return Icons.WaxingCrescent2; + case MoonPhase.FirstQuarter: + return Icons.FirstQuarter; + case MoonPhase.WaxingGibbeous: + return Icons.WaxingGibbeous; + case MoonPhase.FullMoon: + return Icons.FullMoon; + case MoonPhase.WaningGibbeous: + return Icons.WaningGibbeous; + case MoonPhase.ThirdQuarter: + return Icons.ThirdQuarter; + case MoonPhase.WaningCrescent: + return Icons.WaningCrescent2; + } + + return Icons.NewMoon; + } + public Rectangle GetMoonSprite(MoonPhase moon) { if (moon == MoonPhase.FirstQuarter) @@ -42,60 +74,76 @@ public Rectangle GetMoonSprite(MoonPhase moon) if (moon == MoonPhase.ThirdQuarter) return Icons.ThirdQuarter; if (moon == MoonPhase.WaningCrescent) - return Icons.WaningCrescent; - if (moon == MoonPhase.WaningGibbeous) - return Icons.WaningGibbeous; + return Icons.WaningCrescent1; if (moon == MoonPhase.WaxingCrescent) - return Icons.WaxingCrescent; + return Icons.WaxingCrescent1; + if (moon == MoonPhase.WaningGibbeous) + return Icons.WaningGibbeous; if (moon == MoonPhase.WaxingGibbeous) return Icons.WaxingGibbeous; return Icons.NewMoon; } - public Rectangle GetWeatherSprite(int weather) + public Rectangle GetWeatherSprite(CurrentWeather condition) { - if (weather == Game1.weather_debris) + if (condition.HasFlag(CurrentWeather.Blizzard)) + return Icons.WeatherBlizzard; + + if (condition.HasFlag(CurrentWeather.Wind)) return Icons.WeatherWindy; - if (weather == Game1.weather_festival) + + if (condition.HasFlag(CurrentWeather.Festival)) return Icons.WeatherFestival; - if (weather == Game1.weather_sunny) + + if (condition.HasFlag(CurrentWeather.Sunny) && !condition.HasFlag(CurrentWeather.Lightning)) return Icons.WeatherSunny; - if (weather == Game1.weather_wedding) + + if (condition.HasFlag(CurrentWeather.Sunny) && condition.HasFlag(CurrentWeather.Lightning)) + return Icons.WeatherDryLightning; + + if (condition.HasFlag(CurrentWeather.Wedding)) return Icons.WeatherWedding; - if (weather == Game1.weather_snow) + + if (condition.HasFlag(CurrentWeather.Snow) && !condition.HasFlag(CurrentWeather.Lightning)) return Icons.WeatherSnowy; - if (weather == Game1.weather_rain) + + if (condition.HasFlag(CurrentWeather.Snow) && condition.HasFlag(CurrentWeather.Lightning)) + return Icons.WeatherThundersnow; + + if (condition.HasFlag(CurrentWeather.Rain)) return Icons.WeatherRainy; return Icons.WeatherSunny; } - // These are the positions of each sprite on the sheet. - public static readonly Rectangle NewMoon = new Rectangle(24, 120, 37, 35); - public static readonly Rectangle WaxingCrescent = new Rectangle(60, 120, 37, 34); - public static readonly Rectangle FirstQuarter = new Rectangle(174, 117, 38, 36); - public static readonly Rectangle WaxingGibbeous = new Rectangle(254, 118, 36, 33); - - public static readonly Rectangle FullMoon = new Rectangle(25, 156, 37, 33); - public static readonly Rectangle WaningCrescent = new Rectangle(255, 156, 36, 33); - public static readonly Rectangle ThirdQuarter = new Rectangle(174, 157, 37, 30); - public static readonly Rectangle WaningGibbeous = new Rectangle(99, 153, 37, 35); - - public static readonly Rectangle WeatherSunny = new Rectangle(24, 196, 40, 37); - public static readonly Rectangle WeatherRainy = new Rectangle(63, 197, 35, 36); - public static readonly Rectangle WeatherStormy = new Rectangle(96, 196, 41, 42); - public static readonly Rectangle WeatherSnowy = new Rectangle(137, 196, 39, 35); - public static readonly Rectangle WeatherWindy = new Rectangle(180, 198, 35, 31); - public static readonly Rectangle WeatherWedding = new Rectangle(221, 196, 37, 35); - public static readonly Rectangle WeatherFestival = new Rectangle(260, 198, 42, 38); - - /// A down arrow for scrolling content. - public static readonly Rectangle DownArrow = new Rectangle(12, 76, 40, 44); - - /// An up arrow for scrolling content. - public static readonly Rectangle UpArrow = new Rectangle(76, 72, 40, 44); - + // These are the positions of each sprite on their sheet. + public static readonly Rectangle NewMoon = new Rectangle(7, 23, 34, 36); + public static readonly Rectangle WaxingCrescent1 = new Rectangle(53, 22, 38, 38); + public static readonly Rectangle WaxingCrescent2 = new Rectangle(101, 20, 38, 40); + public static readonly Rectangle WaxingCrescent3 = new Rectangle(151, 23, 35, 38); + public static readonly Rectangle FirstQuarter = new Rectangle(198, 21, 38, 41); + public static readonly Rectangle FullMoon = new Rectangle(5, 86, 37, 38); + public static readonly Rectangle ThirdQuarter = new Rectangle(54, 86, 36, 38); + public static readonly Rectangle WaningCrescent1 = new Rectangle(104, 89, 32, 34); + public static readonly Rectangle WaningCrescent2 = new Rectangle(149, 87, 38, 37); + public static readonly Rectangle WaningCrescent3 = new Rectangle(208, 89, 33, 35); + public static readonly Rectangle WaxingGibbeous = new Rectangle(262, 91, 34, 33); + public static readonly Rectangle WaningGibbeous = new Rectangle(257, 22, 36, 39); + public static readonly Rectangle BloodMoonIntensifies = new Rectangle(312, 30, 41, 39); + public static readonly Rectangle BloodMoon = new Rectangle(317, 90, 37, 37); + + //Weather + public static readonly Rectangle WeatherSunny = new Rectangle(1, 32, 39, 38); + public static readonly Rectangle WeatherRainy = new Rectangle(40, 32, 35, 40); + public static readonly Rectangle WeatherStormy = new Rectangle(77, 32, 39, 40); + public static readonly Rectangle WeatherSnowy = new Rectangle(116, 32, 38, 41); + public static readonly Rectangle WeatherWindy = new Rectangle(155, 30, 42, 44); + public static readonly Rectangle WeatherWedding = new Rectangle(198, 32, 37, 38); + public static readonly Rectangle WeatherFestival = new Rectangle(235, 32, 47, 45); + public static readonly Rectangle WeatherBlizzard = new Rectangle(281, 32, 40, 42); + public static readonly Rectangle WeatherDryLightning = new Rectangle(321,32,33,39); + public static readonly Rectangle WeatherThundersnow = new Rectangle(355,31,39,40); } public static Texture2D Pixel => LazyPixel.Value; diff --git a/ClimatesOfFerngill/StaminaDrain.cs b/ClimatesOfFerngill/StaminaDrain.cs index a628d5e..e5a4517 100644 --- a/ClimatesOfFerngill/StaminaDrain.cs +++ b/ClimatesOfFerngill/StaminaDrain.cs @@ -3,6 +3,7 @@ using TwilightShards.Stardew.Common; using TwilightShards.Common; using System; +using EnumsNET; using System.Collections.Generic; namespace ClimatesOfFerngillRebuild @@ -12,12 +13,14 @@ internal class StaminaDrain private WeatherConfig Config; private ITranslationHelper Helper; private bool FarmerSick; - private bool SickToday; + public bool FarmerHasBeenSick; private IMonitor Monitor; + private readonly int FROST = 1; + private readonly int HEATWAVE = 2; + public StaminaDrain(WeatherConfig Options, ITranslationHelper SHelper, IMonitor mon) { - SickToday = false; Config = Options; Helper = SHelper; Monitor = mon; @@ -28,15 +31,24 @@ public bool IsSick() return this.FarmerSick; } - public void MakeSick() + public void MakeSick(int reason = 0) { FarmerSick = true; - SDVUtilities.ShowMessage(Helper.Get("hud-text.desc_sick")); + FarmerHasBeenSick = true; + if (reason == FROST) + { + SDVUtilities.ShowMessage(Helper.Get("hud-text.desc_freeze")); + } + else if (reason == HEATWAVE) + { + SDVUtilities.ShowMessage(Helper.Get("hud-text.desc_exhaust")); + } + else + SDVUtilities.ShowMessage(Helper.Get("hud-text.desc_sick")); } public void OnNewDay() { - SickToday = false; FarmerSick = false; } @@ -48,34 +60,30 @@ public void ClearDrain() public void Reset() { - SickToday = false; FarmerSick = false; } public bool FarmerCanGetSick() { - if (FarmerSick) - { - if (Config.Verbose) - Monitor.Log("Farmer is already sick, returning false"); + if (FarmerSick && !Config.SickMoreThanOnce) return false; - } - if (SickToday && !Config.SickMoreThanOnce) + if (!Config.SickMoreThanOnce && FarmerHasBeenSick) return false; return true; } - public int TenMinuteTick(SpecialWeather conditions, int ticksOutside, int ticksTotal, MersenneTwister Dice, int weather, bool IsFoggy) + public int TenMinuteTick(WeatherConditions conditions, int ticksOutside, int ticksTotal, MersenneTwister Dice) { double amtOutside = ticksOutside / (double)ticksTotal, totalMulti = 0; int staminaAffect = 0; + int sickReason = 0; var condList = new List(); - if (Config.Verbose) + /* if (Config.Verbose) Monitor.Log($"Ticks: {ticksOutside}/{ticksTotal} with percentage {amtOutside.ToString("N3")} against" + - $" target {Config.AffectedOutside}"); + $" target {Config.AffectedOutside}"); */ //Logic: At all times, if the today danger is not null, we should consider processing. //However: If it's frost, only at night. If it's a heatwave, only during the day. @@ -83,65 +91,91 @@ public int TenMinuteTick(SpecialWeather conditions, int ticksOutside, int ticksT //If it's frost or heatwave during the appropriate time.. you can get sick //First, update the sick status - if (amtOutside >= Config.AffectedOutside && ((Dice.NextDoublePositive() >= Config.ChanceOfGettingSick) || this.FarmerSick)) + bool farmerCaughtCold = false; + double sickOdds = Config.ChanceOfGettingSick - Game1.dailyLuck; + + //weee. + if (Game1.player.hat?.which == 28 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Lightning)) + sickOdds -= (Dice.NextDoublePositive() / 5.0) - .1; + + if (Game1.player.hat?.which == 25 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard)) + sickOdds -= .22; + + if (Game1.player.hat?.which == 4 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight) + sickOdds -= .11; + + farmerCaughtCold = (Dice.NextDoublePositive() <= sickOdds); + + if (amtOutside >= Config.AffectedOutside && farmerCaughtCold || this.FarmerSick) { //check if it's a valid condition - if (ValidConditions(weather, conditions) && FarmerCanGetSick()) + if (FarmerCanGetSick()) { - this.MakeSick(); + if (conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Blizzard | CurrentWeather.Lightning) || (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) | (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)) + { + if ((conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)) + sickReason = HEATWAVE; + else if (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) + sickReason = FROST; - if (Config.Verbose) - Monitor.Log("Making the farmer sick"); + this.MakeSick(sickReason); + } } //test status - if (Config.Verbose) - Monitor.Log($"Status update. Farmer Sick: {FarmerSick} and Valid Conditions: {ValidConditions(weather, conditions)}"); + /*if (Config.Verbose) + Monitor.Log($"Status update. Farmer Sick: {FarmerSick} and Valid Conditions: {conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Blizzard | CurrentWeather.Lightning) || (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) | (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)}"); */ //now that we've done that, go through the various conditions - if (this.FarmerSick && (weather == Game1.weather_lightning || conditions == SpecialWeather.Thundersnow)) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Lightning)) { totalMulti += 1; condList.Add("Lightning or Thundersnow"); } - if (this.FarmerSick && IsFoggy) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Fog)) { totalMulti += .5; condList.Add("Fog"); } - if (this.FarmerSick && IsFoggy && SDVTime.IsNight) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Fog) && SDVTime.IsNight) { totalMulti += .25; condList.Add("Night Fog"); } - if (this.FarmerSick && conditions == SpecialWeather.Blizzard) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && !conditions.GetCurrentConditions().HasFlag(CurrentWeather.WhiteOut)) { totalMulti += 1.25; condList.Add("Blizzard"); } - if (this.FarmerSick && WeatherConditions.IsFrost(conditions) && SDVTime.IsNight) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && conditions.GetCurrentConditions().HasFlag(CurrentWeather.WhiteOut)) + { + totalMulti += 2.25; + condList.Add("White Out"); + } + + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) { totalMulti += 1.25; condList.Add("Night Frost"); } - if (this.FarmerSick && conditions == SpecialWeather.Thundersnow && SDVTime.IsNight) + if (this.FarmerSick && conditions.GetCurrentConditions().HasAllFlags(CurrentWeather.Lightning | CurrentWeather.Snow) && SDVTime.IsNight) { totalMulti += .5; condList.Add("Night Thundersnow"); } - if (this.FarmerSick && conditions == SpecialWeather.Blizzard && SDVTime.IsNight) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && SDVTime.IsNight) { totalMulti += .5; condList.Add("Night Blizzard"); } - if (this.FarmerSick && WeatherConditions.IsHeatwave(conditions) && !SDVTime.IsNight) + if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight) { totalMulti += 1.25; condList.Add("Day Heatwave"); @@ -166,16 +200,11 @@ public int TenMinuteTick(SpecialWeather conditions, int ticksOutside, int ticksT } } condString += " ]"; - - Monitor.Log($"[{Game1.timeOfDay}] Conditions for the drain are {condString} for a total multipler of {totalMulti} for a total drain of {staminaAffect}"); + /* + Monitor.Log($"[{Game1.timeOfDay}] Conditions for the drain are {condString} for a total multipler of {totalMulti} for a total drain of {staminaAffect}"); */ } return staminaAffect; } - - private bool ValidConditions(int weather, SpecialWeather conditions) - { - return weather == Game1.weather_lightning || conditions == SpecialWeather.Blizzard || WeatherConditions.IsFrost(conditions) || WeatherConditions.IsHeatwave(conditions) || conditions == SpecialWeather.Thundersnow; - } } } diff --git a/ClimatesOfFerngill/WeatherConditions.cs b/ClimatesOfFerngill/WeatherConditions.cs deleted file mode 100644 index e6c25d9..0000000 --- a/ClimatesOfFerngill/WeatherConditions.cs +++ /dev/null @@ -1,535 +0,0 @@ -using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI; -using StardewModdingAPI.Utilities; -using StardewValley; -using TwilightShards.Common; -using TwilightShards.Stardew.Common; - -namespace ClimatesOfFerngillRebuild -{ - public class WeatherConditions - { - //STATIC MEMBERS - public static bool IsHeatwave(SpecialWeather cond) => (cond == SpecialWeather.DryLightningAndHeatwave || cond == SpecialWeather.Heatwave); - public static bool IsFrost(SpecialWeather cond) => (cond == SpecialWeather.Frost); - - //Instance Members - public RangePair TodayTemps { get; private set; } - public int TodayWeather; - public RangePair TomorrowTemps { get; private set; } - public int TomorrowWeather; - public SpecialWeather UnusualWeather; - - // Things needed for internal fog stuff. - private bool AmbientFog { get; set; } - private Rectangle FogSource = new Microsoft.Xna.Framework.Rectangle(640, 0, 64, 64); - private bool FogTypeDark { get; set; } - private Color FogColor { get; set; } - private float FogAlpha { get; set; } - private Vector2 FogPosition { get; set; } - private SDVTime FogExpirTime { get; set; } - - //access control members - public bool IsFogVisible() => (AmbientFog); - public void SetTodayTemps(RangePair a) => TodayTemps = new RangePair(a, EnforceHigherOverLower: true); - public void SetTmrwTemps(RangePair a) => TomorrowTemps = new RangePair(a, EnforceHigherOverLower: true); - public bool IsDarkFog() => (IsFogVisible() && FogTypeDark); - public void SetFogExpirTime(SDVTime t) => FogExpirTime = t; - public SDVTime GetFogEndTime() => (FogExpirTime ?? new SDVTime(0600)); - public bool IsDangerousWeather() => (UnusualWeather != SpecialWeather.None); - - public void ForceDarkFog() => FogTypeDark = true; - public double GetTodayHigh() => TodayTemps.HigherBound; - public double GetTodayLow() => TodayTemps.LowerBound; - public double GetTodayHighF() => ConvCtF(TodayTemps.HigherBound); - public double GetTodayLowF() => ConvCtF(TodayTemps.LowerBound); - public double GetTmrwHigh() => TomorrowTemps.HigherBound; - public double GetTmrwLow() => TomorrowTemps.LowerBound; - public double GetTmrwHighF() => ConvCtF(TomorrowTemps.HigherBound); - public double GetTmrwLowF() => ConvCtF(TomorrowTemps.LowerBound); - private double ConvCtF(double temp) => ((temp * 1.8) + 32); - - public void ResetTodayTemps(double high, double low) - { - TodayTemps.HigherBound = high; - TodayTemps.LowerBound = low; - } - - public WeatherConditions() - { - UnusualWeather = SpecialWeather.None; - FogExpirTime = new SDVTime(600); - } - - public void OnNewDay() - { - TodayWeather = 0; - TomorrowWeather = 0; - UnusualWeather = SpecialWeather.None; - TodayTemps = null; - TomorrowTemps = null; - FogExpirTime = new SDVTime(600); - } - - public void Reset() - { - TodayTemps = null; - TomorrowTemps = null; - TodayWeather = 0; - TomorrowWeather = 0; - UnusualWeather = SpecialWeather.None; - FogTypeDark = false; - AmbientFog = false; - FogAlpha = 0f; - FogExpirTime = new SDVTime(0600); - } - - private static string DescCond(SpecialWeather UW) - { - if (UW == SpecialWeather.None) - return "None"; - if (UW == SpecialWeather.Thundersnow) - return "Thundersnow"; - if (UW == SpecialWeather.Blizzard) - return "Blizzard"; - if (UW == SpecialWeather.DryLightning) - return "DryLightning"; - if (UW == SpecialWeather.Frost) - return "Frost"; - if (UW == SpecialWeather.Heatwave) - return "Heatwave"; - if (UW == SpecialWeather.DryLightningAndHeatwave) - return "DryLightningAndHeatwave"; - - return "ERR"; - } - - private static string DescWeather(int weather) - { - if (weather == Game1.weather_wedding) - return "Wedding"; - if (weather == Game1.weather_festival) - return "Festival"; - if (weather == Game1.weather_sunny) - return "Sunny"; - if (weather == Game1.weather_debris) - return "Debris"; - if (weather == Game1.weather_rain) - return "Rain"; - if (weather == Game1.weather_lightning) - return "Lightning"; - if (weather == Game1.weather_snow) - return "Snowy"; - - else - return "ERR"; - } - - public override string ToString() - { - string ret = ""; - ret += $"Low for today is {TodayTemps.LowerBound} with the high being {TodayTemps.HigherBound}. The current special condition is {WeatherConditions.DescCond(UnusualWeather)} with standard weather being {WeatherConditions.DescWeather(TodayWeather)}."; - - if (IsFogVisible()) - { - ret += $"Fog is visible until {FogExpirTime} and it is dark fog: {IsDarkFog()}"; - } - - ret += $"Weather set for tommorow is {WeatherConditions.DescWeather(TomorrowWeather)} with high {TomorrowTemps.HigherBound} and low {TomorrowTemps.LowerBound}"; - - return ret; - } - - - public int GetWeatherIcon() - { - int icon = 1; - - switch (TodayWeather) - { - case Game1.weather_wedding: - icon = 0; - break; - case Game1.weather_festival: - icon = 1; - break; - case Game1.weather_sunny: - icon = 2; - break; - case Game1.weather_rain: - icon = 4; - break; - case Game1.weather_lightning: - icon = 5; - break; - case Game1.weather_debris: - if (Game1.currentSeason == "spring") - icon = 3; - else - icon = 6; - break; - case Game1.weather_snow: - icon = 7; - break; - } - - if (IsFogVisible() && TodayWeather == Game1.weather_sunny) - icon = 9; - - if (IsFogVisible() && TodayWeather == Game1.weather_rain) - icon = 10; - - if (IsFogVisible() && TodayWeather == Game1.weather_snow) - icon = 11; - - if (UnusualWeather == SpecialWeather.Blizzard) - icon = 8; - - return icon; - } - - // FOG SECTION. - - /// - /// This resets the fog to null. - /// - public void ResetFog() - { - FogTypeDark = false; - AmbientFog = false; - FogAlpha = 0f; - FogExpirTime = new SDVTime(0600); - } - - public void InitFog(MersenneTwister Dice, WeatherConfig WeatherOpt, bool FogTypeDark = false) - { - this.FogColor = Color.White * 1.5f; - this.FogAlpha = 1f; - this.FogTypeDark = FogTypeDark; - this.AmbientFog = true; - - if (Dice.NextDoublePositive() < WeatherOpt.DarkFogChance && - (SDate.Now().Day != 1 && SDate.Now().Year != 1 && SDate.Now().Season != "spring")) - { - FogTypeDark = true; - Game1.outdoorLight = new Color(214, 210, 208); - } - else - { - Game1.outdoorLight = new Color(180, 155, 110); - } - - double FogTimer = Dice.NextDoublePositive(); - this.FogExpirTime = new SDVTime(1200); //default - - if (FogTimer > .75 && FogTimer <= .90) - { - FogExpirTime = new SDVTime(1120); - } - else if (FogTimer > .55 && FogTimer <= .75) - { - FogExpirTime = new SDVTime(1030); - } - else if (FogTimer > .30 && FogTimer <= .55) - { - FogExpirTime = new SDVTime(930); - } - else if (FogTimer <= .30) - { - FogExpirTime = new SDVTime(820); - } - - this.FogExpirTime = FogExpirTime; - - - if (Dice.NextDoublePositive() <= .001) - FogExpirTime = new SDVTime(2400); //all day fog! - } - - public void UpdateFog(int time, bool debug, IMonitor Monitor) - { - if (IsFogVisible()) - { - if (FogTypeDark) - { - if (time == (FogExpirTime - 30).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-30 minutes"); - Game1.outdoorLight = new Color(190, 188, 186); - } - - if (time == (FogExpirTime - 20).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-20 minutes"); - Game1.outdoorLight = new Color(159, 156, 151); - } - - if (time == (FogExpirTime - 10).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-10 minutes"); - Game1.outdoorLight = new Color(110, 109, 107); - } - } - else - { - if (time == (FogExpirTime - 30).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-30 minutes"); - Game1.outdoorLight = new Color(168, 142, 99); - } - - if (time == (FogExpirTime - 20).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-20 minutes"); - Game1.outdoorLight = new Color(117, 142, 99); - - } - - if (time == (FogExpirTime - 10).ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-10 minutes"); - Game1.outdoorLight = new Color(110, 109, 107); - } - } - - //it helps if you implement the fog cutoff! - if (time >= FogExpirTime.ReturnIntTime()) - { - if (debug) Monitor.Log("Now at T-0 minutes"); - this.AmbientFog = false; - this.FogTypeDark = false; - Game1.outdoorLight = Color.White; - FogAlpha = 0f; //fixes it lingering. - } - } - } - - public void DrawFog() - { - if (IsFogVisible()) - { - Vector2 position = new Vector2(); - float num1 = -64 * Game1.pixelZoom + (int)(FogPosition.X % (double)(64 * Game1.pixelZoom)); - while (num1 < (double)Game1.graphics.GraphicsDevice.Viewport.Width) - { - float num2 = -64 * Game1.pixelZoom + (int)(FogPosition.Y % (double)(64 * Game1.pixelZoom)); - while ((double)num2 < Game1.graphics.GraphicsDevice.Viewport.Height) - { - position.X = (int)num1; - position.Y = (int)num2; - Game1.spriteBatch.Draw(Game1.mouseCursors, position, new Microsoft.Xna.Framework.Rectangle? - (FogSource), FogAlpha > 0.0 ? FogColor * FogAlpha : Color.Black * 0.95f, 0.0f, Vector2.Zero, Game1.pixelZoom + 1f / 1000f, SpriteEffects.None, 1f); - num2 += 64 * Game1.pixelZoom; - } - num1 += 64 * Game1.pixelZoom; - } - } - } - - public void MoveFog() - { - if (AmbientFog) - { - this.FogPosition = Game1.updateFloatingObjectPositionForMovement(FogPosition, - new Vector2(Game1.viewport.X, Game1.viewport.Y), Game1.previousViewportPosition, -1f); - FogPosition = new Vector2((FogPosition.X + 0.5f) % (64 * Game1.pixelZoom), - (FogPosition.Y + 0.5f) % (64 * Game1.pixelZoom)); - } - } - - public void GetTodayWeather() - { - if (Game1.isRaining && !Game1.isSnowing && !Game1.isLightning && !Game1.isDebrisWeather) - TodayWeather = Game1.weather_rain; - - if (Game1.isRaining && !Game1.isSnowing && Game1.isLightning && !Game1.isDebrisWeather) - TodayWeather = Game1.weather_lightning; - - if (!Game1.isRaining && Game1.isSnowing && !Game1.isLightning && !Game1.isDebrisWeather) - TodayWeather = Game1.weather_snow; - - if (!Game1.isRaining && !Game1.isSnowing && !Game1.isLightning && !Game1.isDebrisWeather) - TodayWeather = Game1.weather_sunny; - - if (!Game1.isRaining && !Game1.isSnowing && !Game1.isLightning && Game1.isDebrisWeather) - TodayWeather = Game1.weather_debris; - - if (Utility.isFestivalDay(SDate.Now().Day, SDate.Now().Season)) - TodayWeather = Game1.weather_festival; - - if (Game1.weddingToday) - TodayWeather = Game1.weather_wedding; - } - - ///DESCRIPTION SECTION - - /// - /// This returns a description for use in the weather menu - /// - /// The weather being looked at - /// The date of the day - /// Randomizer object - /// Translation Helper - /// The string describing the weather - public string GetDescText(int weather, SDate Date, MersenneTwister Dice, ITranslationHelper Helper) - { - string retString = ""; - - switch (Date.Season) - { - case "spring": - if (weather == Game1.weather_sunny) - retString = Helper.Get("weather-desc.spring_sunny1"); - if (weather == Game1.weather_debris) - retString = Helper.Get("weather-desc.spring_debris1"); - if (weather == Game1.weather_rain) - retString = Helper.Get("weather-desc.spring_rainy1"); - if (weather == Game1.weather_lightning) - retString = Helper.Get("weather-desc.spring_stormy1"); - if (weather == Game1.weather_snow) - retString = Helper.Get("weather-desc.spring_snowy1"); - if (weather == Game1.weather_wedding) - retString = Helper.Get("weather-desc.spring_wedding1"); - if (weather == Game1.weather_festival) - retString = Helper.Get("weather-desc.spring_festival1"); - break; - case "summer": - if (weather == Game1.weather_sunny) - retString = Helper.Get("weather-desc.summer_sunny1"); - if (weather == Game1.weather_debris) - retString = Helper.Get("weather-desc.summer_debris1"); - if (weather == Game1.weather_rain) - retString = Helper.Get("weather-desc.summer_rainy1"); - if (weather == Game1.weather_lightning) - retString = Helper.Get("weather-desc.summer_stormy1"); - if (weather == Game1.weather_snow) - retString = Helper.Get("weather-desc.summer_snowy1"); - if (weather == Game1.weather_wedding) - retString = Helper.Get("weather-desc.summer_wedding1"); - if (weather == Game1.weather_festival) - retString = Helper.Get("weather-desc.summer_festival1"); - break; - case "fall": - if (weather == Game1.weather_sunny) - retString = Helper.Get("weather-desc.fall_sunny1"); - if (weather == Game1.weather_debris) - retString = Helper.Get("weather-desc.fall_debris1"); - if (weather == Game1.weather_rain) - retString = Helper.Get("weather-desc.fall_rainy1"); - if (weather == Game1.weather_lightning) - retString = Helper.Get("weather-desc.fall_stormy1"); - if (weather == Game1.weather_snow) - retString = Helper.Get("weather-desc.fall_snowy1"); - if (weather == Game1.weather_wedding) - retString = Helper.Get("weather-desc.fall_wedding1"); - if (weather == Game1.weather_festival) - retString = Helper.Get("weather-desc.fall_festival1"); - break; - case "winter": - if (weather == Game1.weather_sunny) - retString = Helper.Get("weather-desc.winter_sunny1"); - if (weather == Game1.weather_debris) - retString = Helper.Get("weather-desc.winter_debris1"); - if (weather == Game1.weather_rain) - retString = Helper.Get("weather-desc.winter_rainy1"); - if (weather == Game1.weather_lightning) - retString = Helper.Get("weather-desc.winter_stormy1"); - if (weather == Game1.weather_snow) - retString = Helper.Get("weather-desc.winter_snowy1"); - if (weather == Game1.weather_wedding) - retString = Helper.Get("weather-desc.winter_wedding1"); - if (weather == Game1.weather_festival) - retString = Helper.Get("weather-desc.winter_festival1"); - break; - default: - retString = ""; - break; - } - - return retString; - } - - public string GetHazardousText(ITranslationHelper Helper, SDate Date, MersenneTwister Dice) - { - string retString = ""; - switch (UnusualWeather) - { - case SpecialWeather.Blizzard: - retString = Helper.Get("weather-desc.winter_blizzard1"); - break; - case SpecialWeather.Thundersnow: - retString = Helper.Get("weather-desc.winter_thundersnow1"); - break; - case SpecialWeather.DryLightning: - if (Date.Season != "summer") - retString = Helper.Get("weather-desc.summer_drylightning1"); - else - retString = Helper.Get("weather-desc.nonsummer_drylightning1"); - break; - case SpecialWeather.Frost: - if (Date.Season == "spring") - retString = Helper.Get("weather-desc.spring_frost1"); - else if (Date.Season == "fall") - retString = Helper.Get("weather-desc.fall_frost1"); - break; - case SpecialWeather.Heatwave: - retString = Helper.Get("weather-desc.summer_heatwave1"); - break; - case SpecialWeather.DryLightningAndHeatwave: - retString = Helper.Get("weather-desc.summer_litheatwave1"); - break; - default: - retString = ""; - break; - } - - return retString; - } - - public string GetTemperatureString(bool Scales, ITranslationHelper Helper) - { - string Temperature = ""; - - if (Scales) - Temperature = Helper.Get("weather-menu.temp_bothscales", new - { - highTempC = this.GetTodayHigh().ToString("N1"), - lowTempC = this.GetTodayLow().ToString("N1"), - highTempF = this.GetTodayHighF().ToString("N1"), - lowTempF = this.GetTodayLowF().ToString("N1"), - }); - else - Temperature = Helper.Get("weather-menu.temp_onlyscales", new - { - highTempC = this.GetTodayHigh().ToString("N1"), - lowTempC = this.GetTodayLow().ToString("N1") - }); - - return Temperature; - } - - public string GetTomorrowTemperatureString(bool Scales, ITranslationHelper Helper) - { - string Temperature = ""; - - if (Scales) - Temperature = Helper.Get("weather-menu.temp_bothscales", new - { - highTempC = this.GetTmrwHigh().ToString("N1"), - lowTempC = this.GetTmrwLow().ToString("N1"), - highTempF = this.GetTmrwHighF().ToString("N1"), - lowTempF = this.GetTmrwLowF().ToString("N1"), - }); - else - Temperature = Helper.Get("weather-menu.temp_onlyscales", new - { - highTempC = this.GetTmrwHigh().ToString("N1"), - lowTempC = this.GetTmrwLow().ToString("N1") - }); - - return Temperature; - } - } -} diff --git a/ClimatesOfFerngill/WeatherConfig.cs b/ClimatesOfFerngill/WeatherConfig.cs index 30163d7..4362b56 100644 --- a/ClimatesOfFerngill/WeatherConfig.cs +++ b/ClimatesOfFerngill/WeatherConfig.cs @@ -27,6 +27,12 @@ public class WeatherConfig public double CropResistance { get; set; } public double DarkFogChance { get; set; } public double ChanceOfGettingSick { get; set; } + public bool Use12HourTime { get; set; } + public double BadMoonRising { get; set; } + public bool EclipseOn { get; set; } + public double EclipseChance { get; set; } + public bool SpawnMonsters { get; set; } + public bool SpawnMonstersAllFarms { get; set; } public bool Verbose { get; set; } @@ -45,15 +51,18 @@ public WeatherConfig() DryLightningMinTemp = 34; //34 C, or 93.2 F HazardousWeather = false; //normally, hazardous weather is turned off TooHotOutside = 39; //At this temp, it's too hot outside, and you can have a heatwave. 39 C or 102.2 F default - TooColdOutside = 1; //At this temp, it's too cold outside, and you have a hard frost. 1 C or 33.8 F default + TooColdOutside = 1; //At this temp, it's too cold outside, and you have a hard frost. 1 C or 33.8 F default\ + AllowCropDeath = false; //even if you turn hazardous weather on, it won't enable crop death. SnowOnFall28 = false; //default setting - since if true, it will force StormTotemChange = true; //rain totems may spawn storms instead of rain totems. AllowStormsSpringYear1 = false; //default setting - maintains the fact that starting players may not ShowBothScales = true; //default setting. DeadCropPercentage = .1; //default setting - CropResistance = .4; //default settting + CropResistance = .75; //default settting DarkFogChance = .0875; //default setting + Use12HourTime = false; //default setting + BadMoonRising = .004; //default setting // be able to deal with lightning strikes @@ -65,6 +74,12 @@ public WeatherConfig() //general mod options Verbose = true; + + //eclipse stuff + EclipseOn = true; + EclipseChance = .015; + SpawnMonsters = true; + SpawnMonstersAllFarms = false; } } } diff --git a/ClimatesOfFerngill/FerngillClimate.cs b/ClimatesOfFerngill/WeatherData/FerngillClimate.cs similarity index 100% rename from ClimatesOfFerngill/FerngillClimate.cs rename to ClimatesOfFerngill/WeatherData/FerngillClimate.cs diff --git a/ClimatesOfFerngill/FerngillClimateTimeSpan.cs b/ClimatesOfFerngill/WeatherData/FerngillClimateTimeSpan.cs similarity index 95% rename from ClimatesOfFerngill/FerngillClimateTimeSpan.cs rename to ClimatesOfFerngill/WeatherData/FerngillClimateTimeSpan.cs index 98c9ed8..781c32f 100644 --- a/ClimatesOfFerngill/FerngillClimateTimeSpan.cs +++ b/ClimatesOfFerngill/WeatherData/FerngillClimateTimeSpan.cs @@ -37,6 +37,11 @@ public FerngillClimateTimeSpan(string BeginSeason, string EndSeason, int BeginDa public FerngillClimateTimeSpan(FerngillClimateTimeSpan CTS) { + this.BeginSeason = CTS.BeginSeason; + this.EndSeason = CTS.EndSeason; + this.BeginDay = CTS.BeginDay; + this.EndDay = CTS.EndDay; + this.WeatherChances = new List(); foreach (WeatherParameters w in CTS.WeatherChances) this.WeatherChances.Add(new WeatherParameters(w)); diff --git a/ClimatesOfFerngill/WeatherParameters.cs b/ClimatesOfFerngill/WeatherData/WeatherParameters.cs similarity index 100% rename from ClimatesOfFerngill/WeatherParameters.cs rename to ClimatesOfFerngill/WeatherData/WeatherParameters.cs diff --git a/ClimatesOfFerngill/WeatherMenu.cs b/ClimatesOfFerngill/WeatherMenu.cs index 42acdd6..7593b20 100644 --- a/ClimatesOfFerngill/WeatherMenu.cs +++ b/ClimatesOfFerngill/WeatherMenu.cs @@ -8,10 +8,6 @@ using StardewValley; using StardewValley.Menus; using Pathoschild.Stardew.UIF; -using System.Linq; -using StardewModdingAPI.Utilities; -using TwilightShards.Stardew.Common; -using TwilightShards.Common; namespace ClimatesOfFerngillRebuild { @@ -34,30 +30,9 @@ internal class WeatherMenu : IClickableMenu /// The aspect ratio of the page background. private readonly Vector2 AspectRatio = new Vector2(Sprites.Letter.Sprite.Width, Sprites.Letter.Sprite.Height); - /// The spacing around the scroll buttons. - private readonly int ScrollButtonGutter = 15; - /// To da Moon, Princess! private SDVMoon OurMoon; - /// The amount to scroll long content on each up/down scroll. - private readonly int ScrollAmount; - - /// The clickable 'scroll up' icon. - private readonly ClickableTextureComponent ScrollUpButton; - - /// The clickable 'scroll down' icon. - private readonly ClickableTextureComponent ScrollDownButton; - - /// The maximum pixels to scroll. - private int MaxScroll; - - /// The number of pixels to scroll. - private int CurrentScroll; - - /// The dice object. - private MersenneTwister Dice; - /// The current weather status private WeatherConditions CurrentWeather; @@ -70,6 +45,9 @@ internal class WeatherMenu : IClickableMenu /// Whether the game's draw mode has been validated for compatibility. private bool ValidatedDrawMode; + /// The text for the weather menu + private string MenuText; + /********* ** Public methods *********/ @@ -78,23 +56,17 @@ internal class WeatherMenu : IClickableMenu ****/ /// Construct an instance. /// Encapsulates logging and monitoring. - public WeatherMenu(IMonitor monitor, IReflectionHelper reflectionHelper, Sprites.Icons Icon, ITranslationHelper Helper, WeatherConditions weat, SDVMoon Termina, - WeatherConfig ModCon, int scroll, MersenneTwister Dice) + public WeatherMenu(IMonitor monitor, IReflectionHelper reflectionHelper, Sprites.Icons Icon, ITranslationHelper Helper, WeatherConditions weat, SDVMoon Termina, WeatherConfig ModCon, string text) { // save data + this.MenuText = text; this.Monitor = monitor; this.Reflection = reflectionHelper; this.Helper = Helper; this.CurrentWeather = weat; - this.ScrollAmount = scroll; this.IconSheet = Icon; this.OurMoon = Termina; this.OurConfig = ModCon; - this.Dice = Dice; - - // add scroll buttons - this.ScrollUpButton = new ClickableTextureComponent(Rectangle.Empty, Sprites.Icons.source2, Sprites.Icons.UpArrow, 1); - this.ScrollDownButton = new ClickableTextureComponent(Rectangle.Empty, Sprites.Icons.source2, Sprites.Icons.DownArrow, 1); // update layout this.UpdateLayout(); @@ -104,16 +76,6 @@ public WeatherMenu(IMonitor monitor, IReflectionHelper reflectionHelper, Sprites ** Events ****/ - /// The method invoked when the player scrolls the mouse wheel on the lookup UI. - /// The scroll direction. - public override void receiveScrollWheelAction(int direction) - { - if (direction > 0) // positive number scrolls content up - this.ScrollUp(); - else - this.ScrollDown(); - } - /// The method invoked when the player left-clicks on the lookup UI. /// The X-position of the cursor. /// The Y-position of the cursor. @@ -160,18 +122,6 @@ public override void receiveGamePadButton(Buttons button) ** Methods ****/ - /// Scroll up the menu content by the specified amount (if possible). - public void ScrollUp() - { - this.CurrentScroll -= this.ScrollAmount; - } - - /// Scroll down the menu content by the specified amount (if possible). - public void ScrollDown() - { - this.CurrentScroll += this.ScrollAmount; - } - /// Handle a left-click from the player's mouse or controller. /// The x-position of the cursor. /// The y-position of the cursor. @@ -182,13 +132,6 @@ public void HandleLeftClick(int x, int y) this.exitThisMenu(); } - public string FirstCharToUpper(string input) - { - if (String.IsNullOrEmpty(input)) - throw new ArgumentException("ARGH!"); - return input.First().ToString().ToUpper() + input.Substring(1); - } - /// Render the UI. /// The sprite batch being drawn. public override void draw(SpriteBatch spriteBatch) @@ -196,9 +139,9 @@ public override void draw(SpriteBatch spriteBatch) // disable when game is using immediate sprite sorting if (!this.ValidatedDrawMode) { - IPrivateField sortModeField = - this.Reflection.GetPrivateField(Game1.spriteBatch, "spriteSortMode", required: false) // XNA - ?? this.Reflection.GetPrivateField(Game1.spriteBatch, "_sortMode"); // MonoGame + IReflectedField sortModeField = + this.Reflection.GetField(Game1.spriteBatch, "spriteSortMode", required: false) // XNA + ?? this.Reflection.GetField(Game1.spriteBatch, "_sortMode"); // MonoGame if (sortModeField.GetValue() == SpriteSortMode.Immediate) { this.Monitor.Log("Aborted the weather draw because the game's current rendering mode isn't compatible with the mod's UI. This only happens in rare cases (e.g. the Stardew Valley Fair).", LogLevel.Warn); @@ -226,167 +169,43 @@ public override void draw(SpriteBatch spriteBatch) // and I kinda want to have this where I can understand what it's for float spaceWidth = DrawHelper.GetSpaceWidth(font); + // draw background // (This uses a separate sprite batch because it needs to be drawn before the // foreground batch, and we can't use the foreground batch because the background is // outside the clipping area.) - using (SpriteBatch backgroundBatch = new SpriteBatch(Game1.graphics.GraphicsDevice)) + //spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null); + spriteBatch.DrawSprite(Sprites.Letter.Sheet, Sprites.Letter.Sprite, x, y, scale: width / (float)Sprites.Letter.Sprite.Width); + //spriteBatch.End(); + + // begin draw + + // draw weather icon + spriteBatch.Draw(IconSheet.WeatherSource, new Vector2(x + leftOffset, y + topOffset), IconSheet.GetWeatherSprite(CurrentWeather.GetCurrentConditions()), Color.White); + leftOffset += 72; + string weatherString = ""; + + // draw text as sent from outside the menu + float wrapWidth = this.width - leftOffset - gutter; { - backgroundBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null); - backgroundBatch.DrawSprite(Sprites.Letter.Sheet, Sprites.Letter.Sprite, x, y, scale: width / (float)Sprites.Letter.Sprite.Width); - backgroundBatch.End(); - } + Vector2 textSize = spriteBatch.DrawTextBlock(font, MenuText, new Vector2(x + leftOffset, y + topOffset), wrapWidth); + topOffset += textSize.Y; + topOffset += lineHeight; - // draw foreground - // (This uses a separate sprite batch to set a clipping area for scrolling.) - using (SpriteBatch contentBatch = new SpriteBatch(Game1.graphics.GraphicsDevice)) - { - // begin draw - GraphicsDevice device = Game1.graphics.GraphicsDevice; - device.ScissorRectangle = new Rectangle(x + gutter, y + gutter, (int)contentWidth, (int)contentHeight); - contentBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, new RasterizerState { ScissorTestEnable = true }); - - // scroll view - this.CurrentScroll = Math.Max(0, this.CurrentScroll); // don't scroll past top - this.CurrentScroll = Math.Min(this.MaxScroll, this.CurrentScroll); // don't scroll past bottom - topOffset -= this.CurrentScroll; // scrolled down == move text up - - // draw weather icon - contentBatch.Draw(IconSheet.source, new Vector2(x + leftOffset, y + topOffset), - IconSheet.GetWeatherSprite(CurrentWeather.TodayWeather), Color.White); - leftOffset += 72; - string weatherString = ""; - - // draw fields - float wrapWidth = this.width - leftOffset - gutter; - { - // draw high and low - { - Vector2 descSize = contentBatch.DrawTextBlock(font, Helper.Get("weather-menu.opening", new { season = Game1.currentSeason, day = Game1.dayOfMonth }), - new Vector2(x + leftOffset, y + topOffset), wrapWidth); - topOffset += descSize.Y; - if (CurrentWeather.IsFogVisible()) - { - //fog display - string fogString = ""; - - switch (Game1.currentSeason) - { - case "spring": - if (CurrentWeather.IsDarkFog()) - fogString = Helper.Get("weather-desc.spring_dfog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - else - fogString = Helper.Get("weather-desc.spring_fog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - break; - case "summer": - if (CurrentWeather.IsDarkFog()) - fogString = Helper.Get("weather-desc.summer_dfog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - else - fogString = Helper.Get("weather-desc.summer_fog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - break; - case "fall": - if (CurrentWeather.IsDarkFog()) - fogString = Helper.Get("weather-desc.fall_dfog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - else - fogString = Helper.Get("weather-desc.fall_fog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - break; - case "winter": - if (CurrentWeather.IsDarkFog()) - fogString = Helper.Get("weather-desc.winter_dfog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - else - fogString = Helper.Get("weather-desc.winter_fog", new { time = CurrentWeather.GetFogEndTime().ToString() }); - break; - default: - fogString = "ERROR"; - break; - } - - Vector2 fogSize = contentBatch.DrawTextBlock(font, fogString, new Vector2(x + leftOffset, y + topOffset), wrapWidth); - topOffset += fogSize.Y; - } - - topOffset += lineHeight; - //build the temperature display - string Temperature = CurrentWeather.GetTemperatureString(OurConfig.ShowBothScales, Helper); - - //Output today's weather - - if (CurrentWeather.TodayWeather != Game1.weather_festival) - { - weatherString = Helper.Get("weather-menu.fore_today_notFest", - new { currentConditions = CurrentWeather.GetDescText(CurrentWeather.TodayWeather, SDate.Now(), Dice, Helper), - Temperature = Temperature }); - } - else - { - weatherString = Helper.Get("weather-menu.fore_today_festival", - new { festival = SDVUtilities.GetFestivalName(), Temperature = Temperature }); - } - - Vector2 nameSize = contentBatch.DrawTextBlock(font, weatherString, new Vector2(x + leftOffset, y + topOffset), wrapWidth); - topOffset += nameSize.Y; - topOffset += lineHeight; - - - //Output Tomorrow's weather - if (!(Utility.isFestivalDay(Game1.dayOfMonth +1, Game1.currentSeason))) - { - weatherString = Helper.Get("weather-menu.fore_tomorrow_notFest", new - { - currentConditions = CurrentWeather.GetDescText(CurrentWeather.TomorrowWeather, SDate.Now().AddDays(1), Dice, Helper), - Temperature = Temperature - }); - } - else - { - weatherString = Helper.Get("weather-menu.fore_tomorrow_festival", - new { festival = SDVUtilities.GetTomorrowFestivalName(), Temperature = Temperature }); - } - - Vector2 tomSize = contentBatch.DrawTextBlock(font, weatherString, new Vector2(x + leftOffset, y + topOffset), wrapWidth); - - topOffset += tomSize.Y; - } - - // draw spacer - topOffset += lineHeight; - - if (CurrentWeather.IsDangerousWeather()) - { - weatherString = Helper.Get("weather-menu.dangerous_condition", - new { condition = CurrentWeather.GetHazardousText(Helper,SDate.Now(), Dice) }); - Vector2 statusSize = contentBatch.DrawTextBlock(font, weatherString, new Vector2(x + leftOffset, y + topOffset), wrapWidth, - bold: true); - topOffset += statusSize.Y; - topOffset += lineHeight; - } - - } - - //draw moon info - contentBatch.Draw(IconSheet.source, new Vector2(x + 15, y + topOffset), - IconSheet.GetMoonSprite(OurMoon.CurrPhase), Color.White); - - weatherString = Helper.Get("moon-desc.desc_moonphase", - new { moonPhase = SDVMoon.DescribeMoonPhase(OurMoon.CurrPhase, Helper)}); + } - Vector2 moonText = contentBatch.DrawTextBlock(font, - weatherString, new Vector2(x + leftOffset, y + topOffset), wrapWidth); + //draw moon info + spriteBatch.Draw(IconSheet.MoonSource, new Vector2(x + 15, y + topOffset), + IconSheet.GetMoonSprite(OurMoon.CurrentPhase), Color.White); - topOffset += lineHeight; //stop moon from being cut off. + weatherString = Helper.Get("moon-desc.desc_moonphase", + new { moonPhase = SDVMoon.DescribeMoonPhase(OurMoon.CurrentPhase, Helper)}); - // update max scroll - this.MaxScroll = Math.Max(0, (int)(topOffset - contentHeight + this.CurrentScroll)); + Vector2 moonText = spriteBatch.DrawTextBlock(font, + weatherString, new Vector2(x + leftOffset, y + topOffset), wrapWidth); - // draw scroll icons - if (this.MaxScroll > 0 && this.CurrentScroll > 0) - this.ScrollUpButton.draw(contentBatch); - if (this.MaxScroll > 0 && this.CurrentScroll < this.MaxScroll) - this.ScrollDownButton.draw(spriteBatch); + topOffset += lineHeight; //stop moon from being cut off. - // end draw - contentBatch.End(); - } this.drawMouse(Game1.spriteBatch); } @@ -409,7 +228,7 @@ private void UpdateLayout() // update up/down buttons int x = this.xPositionOnScreen; int y = this.yPositionOnScreen; - int gutter = this.ScrollButtonGutter; + int gutter = 16; float contentHeight = this.height - gutter * 2; } diff --git a/ClimatesOfFerngill/Weathers/CurrentWeather.cs b/ClimatesOfFerngill/Weathers/CurrentWeather.cs new file mode 100644 index 0000000..907afd3 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/CurrentWeather.cs @@ -0,0 +1,25 @@ +using System; + +namespace ClimatesOfFerngillRebuild +{ + /// + /// This enum tracks weathers added to the system as well as the current weather. + /// + [Flags] + public enum CurrentWeather + { + Unset = 0, + Sunny = 2, + Rain = 4, + Snow = 8, + Wind = 16, + Festival = 32, + Wedding = 64, + Lightning = 128, + Blizzard = 256, + Fog = 512, + Frost = 1024, + Heatwave = 2048, + WhiteOut = 4096 + } +} diff --git a/ClimatesOfFerngill/Weathers/FerngillBlizzard.cs b/ClimatesOfFerngill/Weathers/FerngillBlizzard.cs new file mode 100644 index 0000000..3783e44 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/FerngillBlizzard.cs @@ -0,0 +1,153 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using StardewValley.Locations; +using System; +using TwilightShards.Common; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + /// This tracks blizzard details + internal class FerngillBlizzard : ISDVWeather + { + /// This is for the second snow overlay. + private Vector2 snowPos; + public event EventHandler OnUpdateStatus; + private bool IsBlizzard { get; set; } + public bool IsWeatherVisible => IsBlizzard; + private SDVTime ExpirTime; + private SDVTime BeginTime; + + private MersenneTwister Dice; + private WeatherConfig ModConfig; + + public string WeatherType => "Blizzard"; + public void SetWeatherExpirationTime(SDVTime t) => ExpirTime = t; + public void SetWeatherBeginTime(SDVTime t) => BeginTime = t; + + public SDVTime WeatherExpirationTime => (ExpirTime ?? new SDVTime(0600)); + public SDVTime WeatherBeginTime => (BeginTime ?? new SDVTime(0600)); + public bool WeatherInProgress => (SDVTime.CurrentTime >= BeginTime && SDVTime.CurrentTime <= ExpirTime); + + public FerngillBlizzard(MersenneTwister Dice, WeatherConfig config) + { + ExpirTime = new SDVTime(2600); + BeginTime = new SDVTime(0600); + this.Dice = Dice; + this.ModConfig = config; + } + + /* work on creating various buff code here */ + public void UpdateStatus(string weather, bool status) + { + if (OnUpdateStatus == null) return; + + WeatherNotificationArgs args = new WeatherNotificationArgs(weather, status); + OnUpdateStatus(this, args); + } + + public void OnNewDay() + { + IsBlizzard = false; + } + + public void Reset() + { + IsBlizzard = false; + } + + public void SetWeatherTime(SDVTime begin, SDVTime end) + { + BeginTime = new SDVTime(begin); + ExpirTime = new SDVTime(end); + } + + public void CreateWeather() + { + //Blizzards opt to mostly being all day. + BeginTime = new SDVTime(0600); + ExpirTime = new SDVTime(2800); + if (Dice.NextDouble() >= .5 && Dice.NextDouble() < .8) + { + ExpirTime = new SDVTime(Game1.getModeratelyDarkTime()); + } + if (Dice.NextDouble() >= .8 && Dice.NextDouble() < .95) + { + ExpirTime = new SDVTime((BeginTime.ReturnIntTime() + 1000)); + } + if (Dice.NextDouble() >= .95) + { + ExpirTime = new SDVTime((BeginTime.ReturnIntTime() + 500)); + } + + if (SDVTime.CurrentTime >= BeginTime) + { + IsBlizzard = true; + UpdateStatus(WeatherType, true); + } + } + + public void EndWeather() + { + if (IsWeatherVisible) + { + IsBlizzard = false; + ExpirTime = new SDVTime(SDVTime.CurrentIntTime - 10); + UpdateStatus(WeatherType, false); + } + } + + public void UpdateWeather() + { + if (!IsWeatherVisible) + { + return; + } + + if (SDVTime.CurrentTime >= WeatherExpirationTime) + { + IsBlizzard = false; + UpdateStatus(WeatherType, false); + } + } + + public void MoveWeather() + { + + } + + public override string ToString() + { + return $"Blizzard Weather from {BeginTime} to {ExpirTime}. Visible: {IsWeatherVisible}. "; + } + + public void DrawWeather() + { + if (IsWeatherVisible && !(Game1.currentLocation is Desert)) + { + snowPos = Game1.updateFloatingObjectPositionForMovement(snowPos, new Vector2(Game1.viewport.X, Game1.viewport.Y), + Game1.previousViewportPosition, -1f); + snowPos.X = snowPos.X % (16 * Game1.pixelZoom); + Vector2 position = new Vector2(); + float num1 = -16 * Game1.pixelZoom + snowPos.X % (16 * Game1.pixelZoom); + while ((double)num1 < Game1.viewport.Width) + { + float num2 = -16 * Game1.pixelZoom + snowPos.Y % (16 * Game1.pixelZoom); + while (num2 < (double)Game1.viewport.Height) + { + position.X = (int)num1; + position.Y = (int)num2; + Game1.spriteBatch.Draw(Game1.mouseCursors, position, new Microsoft.Xna.Framework.Rectangle? + (new Microsoft.Xna.Framework.Rectangle + (368 + (int)((Game1.currentGameTime.TotalGameTime.TotalMilliseconds + 150) % 1200.0) / 75 * 16, 192, 16, 16)), + Color.White * Game1.options.snowTransparency, 0.0f, Vector2.Zero, + Game1.pixelZoom + 1f / 1000f, SpriteEffects.None, 1f); + num2 += 16 * Game1.pixelZoom; + } + num1 += 16 * Game1.pixelZoom; + } + } + } + } +} \ No newline at end of file diff --git a/ClimatesOfFerngill/Weathers/FerngillFog.cs b/ClimatesOfFerngill/Weathers/FerngillFog.cs new file mode 100644 index 0000000..63d361e --- /dev/null +++ b/ClimatesOfFerngill/Weathers/FerngillFog.cs @@ -0,0 +1,343 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; +using System; +using System.Diagnostics; +using TwilightShards.Common; +using TwilightShards.Stardew.Common; +using static ClimatesOfFerngillRebuild.Sprites; + +namespace ClimatesOfFerngillRebuild +{ + /// This tracks fog details + internal class FerngillFog : ISDVWeather + { + public event EventHandler OnUpdateStatus; + + public static Rectangle FogSource = new Rectangle(0, 0, 64, 64); + private Color FogColor = Color.White * 1.25f; + + internal Icons Sheet; + + /// The Current Fog Type + internal FogType CurrentFogType { get; set; } + + private bool VerboseDebug { get; set; } + private IMonitor Monitor { get; set; } + + /// The alpha attribute of the fog. + private float FogAlpha { get; set; } + + /// Fog Position. For drawing. + private Vector2 FogPosition { get; set; } + + /// Sets the expiration time of the fog + private SDVTime ExpirTime { get; set; } + private SDVTime BeginTime { get; set; } + + public bool IsWeatherVisible => (CurrentFogType != FogType.None); + + public string WeatherType => "Fog"; + + /// Returns the expiration time of fog. Note that this doesn't sanity check if the fog is even visible. + public SDVTime WeatherExpirationTime => (ExpirTime ?? new SDVTime(0600)); + public SDVTime WeatherBeginTime => (BeginTime ?? new SDVTime(0600)); + public bool WeatherInProgress + { + get + { + if (BeginTime is null || ExpirTime is null) + return false; + if (BeginTime is null) + Console.WriteLine("BeginTime is null"); + if (ExpirTime is null) + Console.WriteLine("ExpirTime is null"); + if (SDVTime.CurrentTime is null) + Console.WriteLine("CURRENT TIME IS NULL."); + if (WeatherBeginTime is null) + Console.WriteLine("WBT is null"); + if (WeatherExpirationTime is null) + Console.WriteLine("WET is null"); + + return (SDVTime.CurrentTime >= WeatherBeginTime && SDVTime.CurrentTime <= WeatherExpirationTime); + } + } + + /// Sets the fog expiration time. + /// The time for the fog to expire + public void SetWeatherExpirationTime(SDVTime t) => ExpirTime = t; + public void SetWeatherBeginTime(SDVTime t) => BeginTime = t; + public SDVTimePeriods FogTimeSpan { get; set;} + private MersenneTwister Dice { get; set; } + private WeatherConfig ModConfig { get; set; } + private bool FadeOutFog { get; set; } + private bool FadeInFog { get; set; } + private Stopwatch FogElapsed { get; set; } + + /// Default constructor. + internal FerngillFog(Icons Sheet, bool Verbose, IMonitor Monitor, MersenneTwister Dice, WeatherConfig config, SDVTimePeriods FogPeriod) + { + this.Sheet = Sheet; + CurrentFogType = FogType.None; + ExpirTime = null; + VerboseDebug = Verbose; + this.Monitor = Monitor; + this.Dice = Dice; + this.ModConfig = config; + this.FogTimeSpan = FogPeriod; + FogElapsed = new Stopwatch(); + } + + /// This function resets the fog for a new day. + public void OnNewDay() + { + Reset(); + } + + /// This function resets the fog. + public void Reset() + { + CurrentFogType = FogType.None; + BeginTime = null; + ExpirTime = null; + FogAlpha = 0f; + FadeOutFog = false; + FadeInFog = false; + FogElapsed.Reset(); + } + + /// Returns a string describing the fog type. + /// The type of the fog being looked at. + /// The fog type + internal static string DescFogType(FogType CurrentFogType) + { + switch (CurrentFogType) + { + case FogType.None: + return "None"; + case FogType.Blinding: + return "Blinding"; + case FogType.Dark: + return "Dark"; + case FogType.Normal: + return "Normal"; + default: + return "ERROR"; + } + } + + /// This function creates the fog + public void CreateWeather() + { + this.FogAlpha = 1f; + //First, let's determine the type. + //... I am a dumb foxgirl. A really dumb one. + if (Dice.NextDoublePositive() < ModConfig.DarkFogChance && SDate.Now().Day != 1 && SDate.Now().Year != 1 && SDate.Now().Season != "spring") + CurrentFogType = FogType.Dark; + else if (Dice.NextDoublePositive() <= .001) + CurrentFogType = FogType.Blinding; + else + CurrentFogType = FogType.Normal; + + //now determine the fog expiration time + double FogChance = Dice.NextDoublePositive(); + + /* + * So we should rarely have full day fog, and it should on average burn off around 9am. + * So, the strongest odds should be 820 to 930, with sharply falling off odds until 1200. And then + * so, extremely rare odds for until 7pm and even rarer than midnight. + */ + + if (FogTimeSpan == SDVTimePeriods.Morning) + { + BeginTime = new SDVTime(0600); + if (FogChance > 0 && FogChance < .25) + this.ExpirTime = new SDVTime(830); + else if (FogChance >= .25 && FogChance < .32) + this.ExpirTime = new SDVTime(900); + else if (FogChance >= .32 && FogChance < .41) + this.ExpirTime = new SDVTime(930); + else if (FogChance >= .41 && FogChance < .55) + this.ExpirTime = new SDVTime(950); + else if (FogChance >= .55 && FogChance < .7) + this.ExpirTime = new SDVTime(1040); + else if (FogChance >= .7 && FogChance < .8) + this.ExpirTime = new SDVTime(1120); + else if (FogChance >= .8 && FogChance < .9) + this.ExpirTime = new SDVTime(1200); + else if (FogChance >= .9 && FogChance < .95) + this.ExpirTime = new SDVTime(1220); + else if (FogChance >= .95 && FogChance < .98) + this.ExpirTime = new SDVTime(1300); + else if (FogChance >= .98 && FogChance < .99) + this.ExpirTime = new SDVTime(1910); + else if (FogChance >= .99) + this.ExpirTime = new SDVTime(2400); + } + else + { + BeginTime = new SDVTime(Game1.getStartingToGetDarkTime()); + BeginTime.AddTime(Dice.Next(-15, 90)); + + ExpirTime = new SDVTime(BeginTime); + ExpirTime.AddTime(Dice.Next(120, 310)); + + BeginTime.ClampToTenMinutes(); + ExpirTime.ClampToTenMinutes(); + } + + if (SDVTime.CurrentTime >= BeginTime) + UpdateStatus(WeatherType, true); + } + + public void EndWeather() + { + if (IsWeatherVisible) + { + ExpirTime = new SDVTime(SDVTime.CurrentTime - 10); + CurrentFogType = FogType.None; + UpdateStatus(WeatherType, false); + } + } + + public void SetWeatherTime(SDVTime begin, SDVTime end) + { + BeginTime = new SDVTime(begin); + ExpirTime = new SDVTime(end); + } + + public override string ToString() + { + return $"Fog Weather from {BeginTime} to {ExpirTime}. Visible: {IsWeatherVisible}. Alpha: {FogAlpha}."; + } + + public void UpdateWeather() + { + if (WeatherBeginTime is null || WeatherExpirationTime is null) + return; + + if (WeatherInProgress && !IsWeatherVisible) + { + CurrentFogType = FogType.Normal; + FadeInFog = true; + FogElapsed.Start(); + UpdateStatus(WeatherType, true); + } + + if (WeatherExpirationTime <= SDVTime.CurrentTime && IsWeatherVisible) + { + FadeOutFog = true; + FogElapsed.Start(); + UpdateStatus(WeatherType, false); + } + } + + internal void SetEveningFog() + { + SDVTime STime, ETime; + STime = new SDVTime(Game1.getStartingToGetDarkTime()); + STime.AddTime(Dice.Next(-25, 80)); + + ETime = new SDVTime(STime); + ETime.AddTime(Dice.Next(120, 310)); + + STime.ClampToTenMinutes(); + ETime.ClampToTenMinutes(); + this.SetWeatherTime(STime, ETime); + } + + public void DrawWeather() + { + if (IsWeatherVisible) + { + if (CurrentFogType != FogType.Blinding) + { + //Game1.outdoorLight = fogLight; + Texture2D fogTexture = null; + Vector2 position = new Vector2(); + float num1 = -64* Game1.pixelZoom + (int)(FogPosition.X % (double)(64 * Game1.pixelZoom)); + while (num1 < (double)Game1.graphics.GraphicsDevice.Viewport.Width) + { + float num2 = -64 * Game1.pixelZoom + (int)(FogPosition.Y % (double)(64 * Game1.pixelZoom)); + while ((double)num2 < Game1.graphics.GraphicsDevice.Viewport.Height) + { + position.X = (int)num1; + position.Y = (int)num2; + + fogTexture = Sheet.FogTexture; + + if (Game1.isStartingToGetDarkOut()) + { + FogColor = Color.LightBlue; + } + + Game1.spriteBatch.Draw(fogTexture, position, new Microsoft.Xna.Framework.Rectangle? + (FogSource), FogAlpha > 0.0 ? FogColor * FogAlpha : Color.Black * 0.95f, 0.0f, Vector2.Zero, Game1.pixelZoom + 1f / 1000f, SpriteEffects.None, 1f); + num2 += 64 * Game1.pixelZoom; + } + num1 += 64 * Game1.pixelZoom; + } + } + } + } + + public void UpdateStatus(string weather, bool status) + { + if (OnUpdateStatus == null) return; + + WeatherNotificationArgs args = new WeatherNotificationArgs(weather, status); + OnUpdateStatus(this, args); + } + + public string FogDescription(double fogRoll, double fogChance) + { + return $"With roll {fogRoll.ToString("N3")} against {fogChance}, there will be fog today from {WeatherBeginTime} to {WeatherExpirationTime} with type {CurrentFogType}"; + } + + public void MoveWeather() + { + float FogFadeTime = 2690f; + if (FadeOutFog) + { + // we want to fade out the fog over 3 or so seconds, so we need to process a fade from 100% to 45% + // So, 3000ms for 55% or 54.45 repeating. But this is super fast.... + // let's try 955ms.. or 1345.. + // or 2690.. so no longer 3s. :< + FogAlpha = 1 - (FogElapsed.ElapsedMilliseconds / FogFadeTime); + + if (FogAlpha <= 0) + { + FogAlpha = 0; + CurrentFogType = FogType.None; + FadeOutFog = false; + FogElapsed.Stop(); + FogElapsed.Reset(); + } + } + + if (FadeInFog) + { + //as above, but the reverse. + FogAlpha = (FogElapsed.ElapsedMilliseconds / FogFadeTime); + if (FogAlpha >= 1) + { + FogAlpha = 1; + FadeInFog = false; + FogElapsed.Stop(); + FogElapsed.Reset(); + } + } + + if (IsWeatherVisible) + { + //Game1.outdoorLight = fogLight; + this.FogPosition = Game1.updateFloatingObjectPositionForMovement(FogPosition, + new Vector2(Game1.viewport.X, Game1.viewport.Y), Game1.previousViewportPosition, -1f); + FogPosition = new Vector2((FogPosition.X + 0.5f) % (64 * Game1.pixelZoom), + (FogPosition.Y + 0.5f) % (64 * Game1.pixelZoom)); + } + } + } +} \ No newline at end of file diff --git a/ClimatesOfFerngill/Weathers/FerngillWhiteOut.cs b/ClimatesOfFerngill/Weathers/FerngillWhiteOut.cs new file mode 100644 index 0000000..3da7c40 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/FerngillWhiteOut.cs @@ -0,0 +1,177 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using StardewValley.Locations; +using System; +using TwilightShards.Common; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + /// This tracks white out details + internal class FerngillWhiteOut : ISDVWeather + { + /// This is for the second snow overlay. + private Vector2 snowPos; + private Vector2 snowPos2; + public event EventHandler OnUpdateStatus; + private bool IsWhiteout { get; set; } + public bool IsWeatherVisible => IsWhiteout; + private SDVTime ExpirTime; + private SDVTime BeginTime; + + private MersenneTwister Dice; + private WeatherConfig ModConfig; + + public string WeatherType => "WhiteOut"; + public void SetWeatherExpirationTime(SDVTime t) => ExpirTime = t; + public void SetWeatherBeginTime(SDVTime t) => BeginTime = t; + + public SDVTime WeatherExpirationTime => (ExpirTime ?? new SDVTime(0600)); + public SDVTime WeatherBeginTime => (BeginTime ?? new SDVTime(0600)); + public bool WeatherInProgress => (SDVTime.CurrentTime >= BeginTime && SDVTime.CurrentTime <= ExpirTime); + + public FerngillWhiteOut(MersenneTwister Dice, WeatherConfig config) + { + ExpirTime = new SDVTime(2600); + BeginTime = new SDVTime(0600); + this.Dice = Dice; + this.ModConfig = config; + } + + public void UpdateStatus(string weather, bool status) + { + if (OnUpdateStatus == null) return; + + WeatherNotificationArgs args = new WeatherNotificationArgs(weather, status); + OnUpdateStatus(this, args); + } + + public void OnNewDay() + { + IsWhiteout = false; + } + + public void Reset() + { + IsWhiteout = false; + } + + public void SetWeatherTime(SDVTime begin, SDVTime end) + { + BeginTime = new SDVTime(begin); + ExpirTime = new SDVTime(end); + } + + public void CreateWeather() + { + BeginTime = new SDVTime(0600); + ExpirTime = new SDVTime(2800); + if (Dice.NextDouble() >= .5 && Dice.NextDouble() < .8) + { + ExpirTime = new SDVTime(Game1.getModeratelyDarkTime()); + } + if (Dice.NextDouble() >= .8 && Dice.NextDouble() < .95) + { + ExpirTime = new SDVTime((BeginTime.ReturnIntTime() + 1000)); + } + if (Dice.NextDouble() >= .95) + { + ExpirTime = new SDVTime((BeginTime.ReturnIntTime() + 500)); + } + + if (SDVTime.CurrentTime >= BeginTime) + { + IsWhiteout = true; + UpdateStatus(WeatherType, true); + } + } + + public void EndWeather() + { + if (IsWeatherVisible) + { + IsWhiteout = false; + ExpirTime = new SDVTime(SDVTime.CurrentIntTime - 10); + UpdateStatus(WeatherType, false); + } + } + + public void UpdateWeather() + { + if (!IsWeatherVisible) + { + return; + } + + if (SDVTime.CurrentTime >= WeatherExpirationTime) + { + IsWhiteout = false; + UpdateStatus(WeatherType, false); + } + } + + public void MoveWeather() + { + + } + + public override string ToString() + { + return $"White Out Weather from {BeginTime} to {ExpirTime}. Visible: {IsWeatherVisible}. "; + } + + public void DrawWeather() + { + if (IsWeatherVisible && !(Game1.currentLocation is Desert)) + { + snowPos = Game1.updateFloatingObjectPositionForMovement(snowPos, new Vector2(Game1.viewport.X, Game1.viewport.Y), + Game1.previousViewportPosition, -1f); + snowPos.X = snowPos.X % (16 * Game1.pixelZoom); + Vector2 position = new Vector2(); + float num1 = -16 * Game1.pixelZoom + snowPos.X % (16 * Game1.pixelZoom); + while ((double)num1 < Game1.viewport.Width) + { + float num2 = -12 * Game1.pixelZoom + snowPos.Y % (12 * Game1.pixelZoom); + while (num2 < (double)Game1.viewport.Height) + { + position.X = (int)num1; + position.Y = (int)num2; + Game1.spriteBatch.Draw(Game1.mouseCursors, position, new Microsoft.Xna.Framework.Rectangle? + (new Microsoft.Xna.Framework.Rectangle + (368 + (int)((Game1.currentGameTime.TotalGameTime.TotalMilliseconds + 225) % 1200.0) / 75 * 16, 192, 16, 16)), + Color.White * Game1.options.snowTransparency, 0.0f, Vector2.Zero, + Game1.pixelZoom + 1f / 1000f, SpriteEffects.None, 1f); + num2 += 16 * Game1.pixelZoom; + } + num1 += 16 * Game1.pixelZoom; + } + } + + if (IsWeatherVisible && !(Game1.currentLocation is Desert)) + { + snowPos2 = Game1.updateFloatingObjectPositionForMovement(snowPos2, new Vector2(Game1.viewport.X, Game1.viewport.Y), + Game1.previousViewportPosition, -1f); + snowPos2.X = snowPos2.X % (12 * Game1.pixelZoom); + Vector2 position = new Vector2(); + float num1 = -12 * Game1.pixelZoom + snowPos2.X % (12 * Game1.pixelZoom); + while ((double)num1 < Game1.viewport.Width) + { + float num2 = -8 * Game1.pixelZoom + snowPos2.Y % (8 * Game1.pixelZoom); + while (num2 < (double)Game1.viewport.Height) + { + position.X = (int)num1; + position.Y = (int)num2; + Game1.spriteBatch.Draw(Game1.mouseCursors, position, new Microsoft.Xna.Framework.Rectangle? + (new Microsoft.Xna.Framework.Rectangle + (368 + (int)((Game1.currentGameTime.TotalGameTime.TotalMilliseconds + 125) % 1200.0) / 75 * 16, 192, 16, 16)), + Color.White * Game1.options.snowTransparency, 0.0f, Vector2.Zero, + Game1.pixelZoom + 1f / 1000f, SpriteEffects.None, 1f); + num2 += 16 * Game1.pixelZoom; + } + num1 += 16 * Game1.pixelZoom; + } + } + } + } +} \ No newline at end of file diff --git a/ClimatesOfFerngill/Weathers/FogType.cs b/ClimatesOfFerngill/Weathers/FogType.cs new file mode 100644 index 0000000..adb9cf9 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/FogType.cs @@ -0,0 +1,16 @@ +namespace ClimatesOfFerngillRebuild +{ + /************************************************************************ + * Weather enums. + ******************************************************************************/ + /// + /// This enum is for what fog is currently on screen. + /// + internal enum FogType + { + None = 0, + Normal = 1, + Dark = 2, + Blinding = 3 + } +} \ No newline at end of file diff --git a/ClimatesOfFerngill/Weathers/ForceDays.cs b/ClimatesOfFerngill/Weathers/ForceDays.cs new file mode 100644 index 0000000..469205d --- /dev/null +++ b/ClimatesOfFerngill/Weathers/ForceDays.cs @@ -0,0 +1,46 @@ +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; +using System.Collections.Generic; + +namespace ClimatesOfFerngillRebuild +{ + internal class ForceDays + { + private static Dictionary _forceDays = new Dictionary + { + { new SDate(1,"spring"), Game1.weather_sunny }, + { new SDate(2, "spring"), Game1.weather_sunny }, + { new SDate(3, "spring"), Game1.weather_rain }, + { new SDate(4, "spring"), Game1.weather_sunny }, + { new SDate(13, "spring"), Game1.weather_festival }, + { new SDate(24, "spring"), Game1.weather_festival }, + { new SDate(1, "summer"), Game1.weather_sunny }, + { new SDate(11, "summer"), Game1.weather_festival }, + { new SDate(13, "summer"), Game1.weather_lightning }, + { new SDate(25, "summer", 25), Game1.weather_lightning }, + { new SDate(26, "summer", 26), Game1.weather_lightning }, + { new SDate(28, "summer", 28), Game1.weather_festival }, + { new SDate(1,"fall"), Game1.weather_sunny }, + { new SDate(16,"fall"), Game1.weather_festival }, + { new SDate(27,"fall"), Game1.weather_festival }, + { new SDate(1,"winter"), Game1.weather_sunny }, + { new SDate(8, "winter"), Game1.weather_festival }, + { new SDate(25, "winter"), Game1.weather_festival } + }; + + public static bool CheckForForceDay(Descriptions Desc, SDate Target, IMonitor mon, bool verbose) + { + foreach (KeyValuePair entry in ForceDays._forceDays) + { + if (entry.Key.Day == Target.Day && entry.Key.Season == Target.Season) + { + if (verbose) mon.Log($"Setting a forced value for tommorow: {Desc.DescribeInGameWeather(entry.Value)} for {entry.Key.Season} {entry.Key.Day}"); + Game1.weatherForTomorrow = entry.Value; + return true; + } + } + return false; + } + } +} diff --git a/ClimatesOfFerngill/Weathers/ISDVWeather.cs b/ClimatesOfFerngill/Weathers/ISDVWeather.cs new file mode 100644 index 0000000..0aef57c --- /dev/null +++ b/ClimatesOfFerngill/Weathers/ISDVWeather.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + interface ISDVWeather + { + //event handlers + event EventHandler OnUpdateStatus; + void UpdateStatus(string weather, bool status); + + //members + bool IsWeatherVisible { get; } + bool WeatherInProgress { get; } + SDVTime WeatherExpirationTime { get; } + SDVTime WeatherBeginTime { get; } + void SetWeatherBeginTime(SDVTime t); + void SetWeatherExpirationTime(SDVTime t); + void SetWeatherTime(SDVTime begin, SDVTime end); + string WeatherType { get; } + + //these functions control the weather over the date + void OnNewDay(); + void Reset(); + + //these functions are used to draw, update and create the weather + void DrawWeather(); + void UpdateWeather(); + void CreateWeather(); + void MoveWeather(); + void EndWeather(); + } +} diff --git a/ClimatesOfFerngill/Weathers/IWeatherEvent.cs b/ClimatesOfFerngill/Weathers/IWeatherEvent.cs new file mode 100644 index 0000000..f42a1dc --- /dev/null +++ b/ClimatesOfFerngill/Weathers/IWeatherEvent.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClimatesOfFerngillRebuild +{ + interface IWeatherEvent + { + event EventHandler OnUpdateStatus; + void UpdateStatus(string weather, bool status); + } +} diff --git a/ClimatesOfFerngill/Weathers/WeatherConditions.cs b/ClimatesOfFerngill/Weathers/WeatherConditions.cs new file mode 100644 index 0000000..3e18f92 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/WeatherConditions.cs @@ -0,0 +1,993 @@ +using EnumsNET; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; +using System.Collections.Generic; +using System.Linq; +using TwilightShards.Common; +using static ClimatesOfFerngillRebuild.Sprites; +using System; +using TwilightShards.Stardew.Common; + +namespace ClimatesOfFerngillRebuild +{ + /// + /// This class tracks the current the current weather of the game + /// + public class WeatherConditions + { + ///Game configuration options + private WeatherConfig ModConfig; + + ///pRNG object + private MersenneTwister Dice; + + ///SMAPI logger + private IMonitor Monitor; + + /// The translation interface + private ITranslationHelper Translation; + + /// Track today's temperature + private RangePair TodayTemps; + + /// Track tomorrow's temperature + private RangePair TomorrowTemps; + + /// Track current conditions + private CurrentWeather CurrentConditionsN { get; set; } + + internal List CurrentWeathers { get; set; } + + private bool HasSetEveningFog {get; set;} + + public bool GenerateEveningFog { get; set; } + + private bool FogCreationProhibited { get; set; } + + private SDVTime MorningFogExpir { get; set; } + + /// ************************************************************************* + /// ACCESS METHODS + /// ************************************************************************* + public CurrentWeather GetCurrentConditions() + { + return CurrentConditionsN; + } + + public void DrawWeathers() + { + foreach (ISDVWeather weather in CurrentWeathers) + weather.DrawWeather(); + } + + public void MoveWeathers() + { + foreach (ISDVWeather weather in CurrentWeathers) + weather.MoveWeather(); + } + + public string FogDescription(double fogRoll, double fogChance) + { + string desc = ""; + foreach (ISDVWeather weather in CurrentWeathers) + { + if (weather.WeatherType == "Fog") + { + FerngillFog fog = (FerngillFog)weather; + desc += fog.FogDescription(fogRoll, fogChance); + } + } + + return desc; + } + + public void CreateWeather(string Type, bool IsMorningFog = false) + { + foreach (ISDVWeather weather in CurrentWeathers) + { + if (weather.WeatherType == Type) + weather.CreateWeather(); + + if (Type == "Fog" && IsMorningFog) + { + MorningFogExpir = weather.WeatherExpirationTime; + } + } + } + + public void TenMinuteUpdate() + { + foreach (ISDVWeather weather in CurrentWeathers) + { + weather.UpdateWeather(); + } + + if (SDVTime.CurrentTimePeriod == SDVTimePeriods.Afternoon && GenerateEveningFog && !HasSetEveningFog && (!IsFestivalToday && !IsWeddingToday)) + { + //Get fog instance + FerngillFog ourFog = (FerngillFog)this.GetWeatherMatchingType("Fog").First(); + if (!ourFog.WeatherInProgress) + { + ourFog.SetEveningFog(); + HasSetEveningFog = true; + } + } + } + + internal List GetWeatherMatchingType(string type) + { + List Weathers = new List(); + foreach (ISDVWeather weather in CurrentWeathers) + { + if (weather.WeatherType == type) + Weathers.Add(weather); + } + + return Weathers; + } + + /// Rather than track the weather seprately, always get it from the game. + public CurrentWeather TommorowForecast => ConvertToCurrentWeather(Game1.weatherForTomorrow); + + public bool IsTodayTempSet => TodayTemps != null; + public bool IsTomorrowTempSet => TomorrowTemps != null; + public bool IsFestivalToday => CurrentConditionsN.HasFlag(CurrentWeather.Festival); + public bool IsWeddingToday => CurrentConditionsN.HasFlag(CurrentWeather.Wedding); + + /// This returns the high for today + public double TodayHigh => TodayTemps.HigherBound; + + /// This returns the high for tomorrow + public double TomorrowHigh => TomorrowTemps.HigherBound; + + /// This returns the low for today + public double TodayLow => TodayTemps.LowerBound; + + /// This returns the low for tomorrow + public double TomorrowLow => TomorrowTemps.LowerBound; + + public void AddWeather(CurrentWeather newWeather) + { + //sanity remove these once weather is set. + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Unset); + + //Some flags are contradictoary. Fix that here. + if (newWeather == CurrentWeather.Rain) + { + //unset debris, sunny, snow and blizzard, if it's raining. + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Sunny); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Snow); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Blizzard); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Wind); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Sunny) + { + //unset debris, rain, snow and blizzard, if it's sunny. + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Rain); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Snow); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Blizzard); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Wind); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Wind) + { + //unset sunny, rain, snow and blizzard, if it's debris. + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Rain); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Snow); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Blizzard); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Sunny); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Snow) + { + //unset debris, sunny, snow and blizzard, if it's raining. + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Sunny); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Rain); + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Wind); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Frost) + { + CurrentConditionsN.RemoveFlags(CurrentWeather.Heatwave); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Heatwave) + { + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Frost); + + CurrentConditionsN |= newWeather; + } + + else if (newWeather == CurrentWeather.Wedding || newWeather == CurrentWeather.Festival) + { + CurrentConditionsN = newWeather; //Clear *everything else* if it's a wedding or festival. + } + + else + CurrentConditionsN |= newWeather; + } + + internal void ForceEveningFog() + { + //Get fog instance + List fogWeather = this.GetWeatherMatchingType("Fog"); + foreach (ISDVWeather weat in fogWeather) + { + SDVTime BeginTime, ExpirTime; + BeginTime = new SDVTime(Game1.getStartingToGetDarkTime()); + BeginTime.AddTime(Dice.Next(-15, 90)); + + ExpirTime = new SDVTime(BeginTime); + ExpirTime.AddTime(Dice.Next(120, 310)); + + BeginTime.ClampToTenMinutes(); + ExpirTime.ClampToTenMinutes(); + weat.SetWeatherTime(BeginTime, ExpirTime); + } + } + + /// Syntatic Sugar for Enum.HasFlag(). Done so if I choose to rewrite how it's accessed, less rewriting of invoking functions is needed. + /// The weather being checked. + /// If the weather is present + public bool HasWeather(CurrentWeather checkWeather) + { + return CurrentConditionsN.HasFlag(checkWeather); + } + + public void ClearFog() => CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Fog); + + public bool HasPrecip() + { + if (CurrentConditionsN.HasAnyFlags(CurrentWeather.Snow | CurrentWeather.Rain | CurrentWeather.Blizzard)) + return true; + + return false; + } + + public WeatherIcon CurrentWeatherIcon + { + get + { + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Rain)) + return WeatherIcon.IconRain; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning))) + return WeatherIcon.IconStorm; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Sunny))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Wind))) + return WeatherIcon.IconDryLightningWind; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Snow))) + return WeatherIcon.IconThunderSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Snow)) + return WeatherIcon.IconSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard))) + return WeatherIcon.IconBlizzard; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard | CurrentWeather.WhiteOut))) + return WeatherIcon.IconWhiteOut; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Festival)) + return WeatherIcon.IconFestival; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Wedding)) + return WeatherIcon.IconWedding; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Sunny)) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Unset)) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Lightning)) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Wind)) { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Lightning))) + return WeatherIcon.IconThunderSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Lightning))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Sunny))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Heatwave))) + return WeatherIcon.IconRain; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Heatwave | CurrentWeather.Fog))) + return WeatherIcon.IconRainFog; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning | CurrentWeather.Heatwave))) + return WeatherIcon.IconStorm; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Fog))) + return WeatherIcon.IconStormFog; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Heatwave | CurrentWeather.Sunny))) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Wind))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Heatwave | CurrentWeather.Wind))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + //The more complex ones. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Sunny | CurrentWeather.Frost))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Frost))) + return WeatherIcon.IconStorm; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard | CurrentWeather.WhiteOut))) + return WeatherIcon.IconWhiteOut; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Frost))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Wind | CurrentWeather.Frost))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Frost))) + return WeatherIcon.IconRain; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Frost))) + return WeatherIcon.IconSnow; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Frost))) + return WeatherIcon.IconBlizzard; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Frost | CurrentWeather.WhiteOut))) + return WeatherIcon.IconBlizzard; + + //And now for fog. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Fog | CurrentWeather.Sunny))) + return WeatherIcon.IconSunnyFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Fog))) + return WeatherIcon.IconStormFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Fog))) + return WeatherIcon.IconSunnyFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Fog))) + return WeatherIcon.IconRainFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Fog))) + return WeatherIcon.IconSnowFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Fog))) + return WeatherIcon.IconBlizzardFog; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Frost | CurrentWeather.Fog))) + return WeatherIcon.IconSunnyFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Frost | CurrentWeather.Fog))) + return WeatherIcon.IconRainFog; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard | CurrentWeather.WhiteOut | CurrentWeather.Fog))) + return WeatherIcon.IconWhiteOutFog; + + Console.WriteLine($"Error. Current conditions are: {CurrentConditionsN}"); + + return WeatherIcon.IconError; + } + } + + public bool BlockFog { get; set; } + + public WeatherIcon CurrentWeatherIconBasic + { + get + { + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Rain)) + return WeatherIcon.IconRain; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning))) + return WeatherIcon.IconStorm; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Sunny))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Wind))) + return WeatherIcon.IconDryLightningWind; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Snow))) + return WeatherIcon.IconThunderSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Snow)) + return WeatherIcon.IconSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard))) + return WeatherIcon.IconBlizzard; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.WhiteOut))) + return WeatherIcon.IconWhiteOut; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Festival)) + return WeatherIcon.IconFestival; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Wedding)) + return WeatherIcon.IconWedding; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Sunny)) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Unset)) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Lightning)) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)CurrentWeather.Wind)) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Lightning))) + return WeatherIcon.IconThunderSnow; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Lightning))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Sunny))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Heatwave))) + return WeatherIcon.IconRain; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Heatwave | CurrentWeather.Fog))) + return WeatherIcon.IconRain; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning | CurrentWeather.Heatwave))) + return WeatherIcon.IconStorm; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Fog))) + return WeatherIcon.IconStorm; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Heatwave | CurrentWeather.Sunny))) + return WeatherIcon.IconSunny; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave))) + return WeatherIcon.IconDryLightning; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Wind))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Heatwave | CurrentWeather.Wind))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + + //The more complex ones. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Sunny | CurrentWeather.Frost))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Frost))) + return WeatherIcon.IconStorm; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Frost))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Wind | CurrentWeather.Frost))) + { + if (SDate.Now().Season == "spring") return WeatherIcon.IconSpringDebris; + else return WeatherIcon.IconDebris; + } + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Frost))) + return WeatherIcon.IconRain; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Frost))) + return WeatherIcon.IconSnow; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Frost))) + return WeatherIcon.IconBlizzard; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Frost | CurrentWeather.WhiteOut))) + return WeatherIcon.IconWhiteOut; + + //And now for fog. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Fog | CurrentWeather.Sunny))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Fog))) + return WeatherIcon.IconStorm; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Fog))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Fog))) + return WeatherIcon.IconRain; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Snow | CurrentWeather.Fog))) + return WeatherIcon.IconSnow; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Fog))) + return WeatherIcon.IconBlizzard; + + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Sunny | CurrentWeather.Frost | CurrentWeather.Fog))) + return WeatherIcon.IconSunny; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Rain | CurrentWeather.Frost | CurrentWeather.Fog))) + return WeatherIcon.IconRain; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditionsN, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Fog | CurrentWeather.WhiteOut))) + return WeatherIcon.IconWhiteOut; + + Console.WriteLine($"Error. Current conditions are: {CurrentConditionsN}"); + + return WeatherIcon.IconError; + } + } + + /// ****************************************************************************** + /// CONSTRUCTORS + /// ****************************************************************************** + + /// + /// Default Constructor + /// + /// pRNG + /// SMAPI log object + /// Game configuration + public WeatherConditions(Icons Sheets, MersenneTwister Dice, ITranslationHelper Translation, IMonitor monitor, WeatherConfig Config) + { + this.Monitor = monitor; + this.ModConfig = Config; + this.Dice = Dice; + this.Translation = Translation; + CurrentConditionsN = CurrentWeather.Unset; + CurrentWeathers = new List + { + new FerngillFog(Sheets, Config.Verbose, monitor, Dice, Config, SDVTimePeriods.Morning), + new FerngillWhiteOut(Dice, Config), + new FerngillBlizzard(Dice, Config) + }; + + foreach (ISDVWeather weather in CurrentWeathers) + weather.OnUpdateStatus += ProcessWeatherChanges; + } + + private void ProcessWeatherChanges(object sender, WeatherNotificationArgs e) + { + if (e.Weather == "WhiteOut") + { + if (e.Present) + { + CurrentConditionsN = CurrentConditionsN | CurrentWeather.WhiteOut; + } + else + { + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.WhiteOut); + } + } + + if (e.Weather == "Fog") + { + if (e.Present) + { + CurrentConditionsN = CurrentConditionsN | CurrentWeather.Fog; + } + else + { + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Fog); + } + } + + if (e.Weather == "Blizzard") + { + + if (e.Present) + CurrentConditionsN = CurrentConditionsN | CurrentWeather.Blizzard; + else + CurrentConditionsN = CurrentConditionsN.RemoveFlags(CurrentWeather.Blizzard); + } + } + + public bool ContainsCondition(CurrentWeather cond) + { + if (CurrentConditionsN.HasFlag(cond)) + { + return true; + } + + return false; + } + + /// ****************************************************************************** + /// PROCESSING + /// ****************************************************************************** + internal void ForceTodayTemps(double high, double low) + { + if (TodayTemps is null) + TodayTemps = new RangePair(); + + TodayTemps.HigherBound = high; + TodayTemps.LowerBound = low; + } + + /// This function resets the weather for a new day. + public void OnNewDay() + { + foreach (ISDVWeather weather in CurrentWeathers) + weather.OnNewDay(); + + FogCreationProhibited = false; + CurrentConditionsN = CurrentWeather.Unset; + TodayTemps = TomorrowTemps; //If Tomorrow is null, should just allow it to be null. + TomorrowTemps = null; + MorningFogExpir = new SDVTime(600); + } + + /// This function resets the weather object to basic. + public void Reset() + { + foreach (ISDVWeather weather in CurrentWeathers) + weather.Reset(); + + FogCreationProhibited = false; + TodayTemps = null; + TomorrowTemps = null; + CurrentConditionsN = CurrentWeather.Unset; + MorningFogExpir = new SDVTime(600); + } + + public SDVTime GetFogTime() + { + foreach (ISDVWeather weather in CurrentWeathers) + { + if (weather is FerngillFog f) + { + if (f.IsWeatherVisible) + return f.WeatherExpirationTime; + else + return new SDVTime(600); + } + } + + return new SDVTime(600); + } + + /// This sets the temperatures from outside for today + /// The RangePair that contains the generated temperatures + public void SetTodayTemps(RangePair a) => TodayTemps = new RangePair(a, EnforceHigherOverLower: true); + + /// This sets the temperatures from outside for tomorrow + /// The RangePair that contains the generated temperatures + public void SetTomorrowTemps(RangePair a) => TomorrowTemps = new RangePair(a, EnforceHigherOverLower: true); + + /// *************************************************************************** + /// Utility functions + /// *************************************************************************** + + /// This function converts from the game weather back to the CurrentWeather enum. Intended primarily for use with tommorow's forecasted weather. + internal static CurrentWeather ConvertToCurrentWeather(int weather) + { + if (weather == Game1.weather_rain) + return CurrentWeather.Rain; + else if (weather == Game1.weather_festival) + return CurrentWeather.Festival; + else if (weather == Game1.weather_wedding) + return CurrentWeather.Wedding; + else if (weather == Game1.weather_debris) + return CurrentWeather.Wind; + else if (weather == Game1.weather_snow) + return CurrentWeather.Snow; + else if (weather == Game1.weather_lightning) + return CurrentWeather.Rain | CurrentWeather.Lightning; + + //default return. + return CurrentWeather.Sunny; + } + + internal void SetTodayWeather() + { + CurrentConditionsN = CurrentWeather.Unset; //reset the flag. + + if (!Game1.isDebrisWeather && !Game1.isRaining && !Game1.isSnowing) + AddWeather(CurrentWeather.Sunny); + + if (Game1.isRaining) + AddWeather(CurrentWeather.Rain); + if (Game1.isDebrisWeather) + AddWeather(CurrentWeather.Wind); + if (Game1.isLightning) + AddWeather(CurrentWeather.Lightning); + if (Game1.isSnowing) + AddWeather(CurrentWeather.Snow); + + if (Utility.isFestivalDay(SDate.Now().Day, SDate.Now().Season)) + AddWeather(CurrentWeather.Festival); + + if (Game1.weddingToday) + AddWeather(CurrentWeather.Wedding); + + //check current weathers. + foreach (ISDVWeather weat in CurrentWeathers) + { + if (weat.WeatherType == "Fog" && weat.IsWeatherVisible) + CurrentConditionsN |= CurrentWeather.Fog; + if (weat.WeatherType == "Blizzard" && weat.IsWeatherVisible) + CurrentConditionsN |= CurrentWeather.Blizzard; + if (weat.WeatherType == "WhiteOut" && weat.IsWeatherVisible) + CurrentConditionsN |= CurrentWeather.WhiteOut; + } + } + + /// Force for wedding only to match vanilla behavior. + internal void ForceWeddingOnly() => CurrentConditionsN = CurrentWeather.Wedding; + + /// Force for festival only to match vanilla behavior. + internal void ForceFestivalOnly() => CurrentConditionsN = CurrentWeather.Festival; + + /// Gets a quick string describing the current weather. + /// A quick ID of the weather + private string GetWeatherType() + { + return WeatherConditions.GetWeatherType(CurrentConditionsN); + } + + /// Gets a quick string describing the weather. Meant primarily for use within the class. + /// A quick ID of the weather + private static string GetWeatherType(CurrentWeather CurrentConditions) + { + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Rain)) + return "rainy"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Rain | CurrentWeather.Lightning))) + return "stormy"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Lightning)) + return "drylightning"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Snow)) + return "snowy"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Snow | CurrentWeather.Blizzard))) + return "blizzard"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Festival)) + return "festival"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Wedding)) + return "wedding"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Sunny)) + return "sunny"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Unset)) + return "unset"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)CurrentWeather.Wind)) + return "windy"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Snow))) + return "thundersnow"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Sunny))) + return "drylightningheatwavesunny"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Heatwave | CurrentWeather.Wind))) + return "drylightningheatwavewindy"; + + //The more complex ones. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Frost | CurrentWeather.Sunny))) + return "drylightningwithfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Frost))) + return "stormswithfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Sunny | CurrentWeather.Frost))) + return "sunnyfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Sunny | CurrentWeather.Frost | CurrentWeather.Fog))) + return "sunnyfrostfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Rain | CurrentWeather.Frost | CurrentWeather.Fog))) + return "rainyfrostfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Wind | CurrentWeather.Frost))) + return "windyfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Rain | CurrentWeather.Frost))) + return "rainyfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Snow | CurrentWeather.Frost))) + return "snowyfrost"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Frost))) + return "blizzardfrost"; + + //And now for fog. + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Fog | CurrentWeather.Sunny))) + return "drylightningwithfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Lightning | CurrentWeather.Rain | CurrentWeather.Fog))) + return "stormswithfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Sunny | CurrentWeather.Fog))) + return "sunnyfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Rain | CurrentWeather.Fog))) + return "rainyfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Snow | CurrentWeather.Fog))) + return "snowyfog"; + if (GeneralFunctions.ContainsOnlyMatchingFlags(CurrentConditions, (int)(CurrentWeather.Blizzard | CurrentWeather.Snow | CurrentWeather.Fog))) + return "blizzardfog"; + + return $"ERROR. Dumping raw data: {CurrentConditions}"; + } + + ///This function returns the current condition (pulled from the translation helper.) + internal string DescribeConditions() + { + switch (GetWeatherType()) + { + case "rainy": + return Translation.Get("weather_rainy"); + case "stormy": + return Translation.Get("weather_lightning"); + case "drylightning": + return Translation.Get("weather_drylightning"); + case "snowy": + return Translation.Get("weather_snow"); + case "blizzard": + return Translation.Get("weather_blizzard"); + case "wedding": + return Translation.Get("weather_wedding"); + case "festival": + return Translation.Get("weather_festival"); + case "unset": + return Translation.Get("weather_unset"); + case "windy": + return Translation.Get("weather_wind"); + case "thundersnow": + return Translation.Get("weather_thundersnow"); + case "heatwave": + return Translation.Get("weather_heatwave"); + case "drylightningheatwave": + return Translation.Get("weather_drylightningheatwave"); + case "drylightningheatwavesunny": + return Translation.Get("weather_drylightningheatwavesunny"); + case "drylightningheatwavewindy": + return Translation.Get("weather_drylightningheatwavewindy"); + case "drylightningwithfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_drylightning") }); + case "stormswithfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_lightning") }); + case "sunnyfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_sunny") }); + case "windyfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_wind") }); + case "rainyfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_rainy") }); + case "snowyfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_snow") }); + case "blizzardfrost": + return Translation.Get("weather_frost", new { condition = Translation.Get("weather_blizzard") }); + case "drylightningwithfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_drylightning") + " " + Translation.Get("weather_sunny") }); + case "stormswithfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_lightning") }); + case "sunnyfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_sunny") }); + case "rainyfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_rainy") }); + case "snowyfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_snow") }); + case "blizzardfog": + return Translation.Get("weather_fog", new { condition = Translation.Get("weather_blizzard") }); + default: + return "ERROR"; + } + } + + /// + /// This function returns a description of the object. A very important note that this is meant for debugging, and as such does not do localization. + /// + /// A string describing the object. + public override string ToString() + { + string ret = ""; + ret += $"Low for today is {TodayTemps?.LowerBound.ToString("N3")} with the high being {TodayTemps?.HigherBound.ToString("N3")}. The current conditions are {GetWeatherType()}."; + + foreach (ISDVWeather weather in CurrentWeathers) + ret += weather.ToString() + Environment.NewLine; + + ret += $"Weather set for tommorow is {WeatherConditions.GetWeatherType(WeatherConditions.ConvertToCurrentWeather(Game1.weatherForTomorrow))} with high {TomorrowTemps?.HigherBound.ToString("N3")} and low {TomorrowTemps?.LowerBound.ToString("N3")}. Evening fog generated {GenerateEveningFog} "; + + return ret; + } + + internal bool TestForSpecialWeather(double fogChance) + { + bool specialWeatherTriggered = false; + // Conditions: Blizzard - occurs in weather_snow in "winter" + // Dry Lightning - occurs if it's sunny in any season if temps exceed 25C. + // Frost and Heatwave check against the configuration. + // Thundersnow - as Blizzard, but really rare. + // Fog - per climate, although night fog in winter is double normal chance + + //GenerateEveningFog = (Dice.NextDouble() < (Game1.currentSeason == "winter" ? fogChance * 2 : fogChance)) && !this.GetCurrentConditions().HasFlag(CurrentWeather.Wind); + GenerateEveningFog = true; + + if (BlockFog) + GenerateEveningFog = false; + + double fogRoll = Dice.NextDoublePositive(); + + if (fogRoll < fogChance && !this.GetCurrentConditions().HasFlag(CurrentWeather.Wind) && !BlockFog) + { + this.CreateWeather("Fog", true); + + if (ModConfig.Verbose) + Monitor.Log($"{FogDescription(fogRoll, fogChance)}"); + + specialWeatherTriggered = true; + } + + if (this.HasWeather(CurrentWeather.Snow)) + { + double blizRoll = Dice.NextDoublePositive(); + if (blizRoll <= ModConfig.BlizzardOdds) + { + this.CreateWeather("Blizzard"); + if (ModConfig.Verbose) + Monitor.Log($"With roll {blizRoll.ToString("N3")} against {ModConfig.BlizzardOdds}, there will be blizzards today"); + if (Dice.NextDoublePositive() < .05) + { + this.CreateWeather("WhiteOut"); + } + } + + specialWeatherTriggered = true; + } + + //Dry Lightning is also here for such like the dry and arid climates + // which have so low rain chances they may never storm. + if (this.HasWeather(CurrentWeather.Snow)) + { + double oddsRoll = Dice.NextDoublePositive(); + + if (oddsRoll <= ModConfig.ThundersnowOdds) + { + this.AddWeather(CurrentWeather.Lightning); + if (ModConfig.Verbose) + Monitor.Log($"With roll {oddsRoll.ToString("N3")} against {ModConfig.ThundersnowOdds}, there will be thundersnow today"); + + specialWeatherTriggered = true; + } + } + + if (!(this.HasPrecip())) + { + double oddsRoll = Dice.NextDoublePositive(); + + if (oddsRoll <= ModConfig.DryLightning && this.TodayHigh >= ModConfig.DryLightningMinTemp) + { + this.AddWeather(CurrentWeather.Lightning); + if (ModConfig.Verbose) + Monitor.Log($"With roll {oddsRoll.ToString("N3")} against {ModConfig.DryLightning}, there will be dry lightning today."); + + specialWeatherTriggered = true; + } + + if (this.TodayHigh > ModConfig.TooHotOutside && ModConfig.HazardousWeather) + { + this.AddWeather(CurrentWeather.Heatwave); + specialWeatherTriggered = true; + } + } + + if (this.TodayLow < ModConfig.TooColdOutside && !Game1.IsWinter) + { + if (ModConfig.HazardousWeather) + { + this.AddWeather(CurrentWeather.Frost); + specialWeatherTriggered = true; + } + } + + //test for spring conversion.- 50% chance + if (this.HasWeather(CurrentWeather.Rain) && this.HasWeather(CurrentWeather.Frost) && Game1.currentSeason == "spring" && Dice.NextDoublePositive() <= .5) + { + CurrentConditionsN.RemoveFlags(CurrentWeather.Rain); + CurrentConditionsN |= CurrentWeather.Snow; + Game1.isRaining = false; + Game1.isSnowing = true; + specialWeatherTriggered = true; + } + + + return specialWeatherTriggered; + } + } +} diff --git a/ClimatesOfFerngill/Weathers/WeatherIcon.cs b/ClimatesOfFerngill/Weathers/WeatherIcon.cs new file mode 100644 index 0000000..bd06ea1 --- /dev/null +++ b/ClimatesOfFerngill/Weathers/WeatherIcon.cs @@ -0,0 +1,31 @@ +using System; + +namespace ClimatesOfFerngillRebuild +{ + public enum WeatherIcon + { + IconWedding = 0, + IconFestival = 1, + IconSunny = 2, + IconSpringDebris = 3, + IconRain = 4, + IconStorm = 5, + IconDebris = 6, + IconSnow = 7, + IconBlizzard = 8, + IconSunnyFog = 9, + IconRainFog = 10, + IconSnowFog = 11, + IconError = 12, + IconStormFog = 13, + IconThunderSnowFog = 14, + IconDryLightningFog = 15, + IconBlizzardFog = 16, + IconThunderSnow = 17, + IconDryLightning = 18, + IconDryLightningWind = 19, + IconWhiteOut = 20, + IconWhiteOutFog = 21, + IconBloodMoon = 99 + } +} diff --git a/ClimatesOfFerngill/Weathers/WeatherNotificationArgs.cs b/ClimatesOfFerngill/Weathers/WeatherNotificationArgs.cs new file mode 100644 index 0000000..76afbff --- /dev/null +++ b/ClimatesOfFerngill/Weathers/WeatherNotificationArgs.cs @@ -0,0 +1,16 @@ +using System; + +namespace ClimatesOfFerngillRebuild +{ + public class WeatherNotificationArgs : EventArgs + { + public bool Present { get; private set; } + public string Weather { get; private set; } + + public WeatherNotificationArgs(string weather, bool present) + { + Weather = weather; + Present = present; + } + } +} diff --git a/ClimatesOfFerngill/data/weather/enhanced.json b/ClimatesOfFerngill/data/weather/enhanced.json index 6842d07..bc30317 100644 --- a/ClimatesOfFerngill/data/weather/enhanced.json +++ b/ClimatesOfFerngill/data/weather/enhanced.json @@ -390,7 +390,7 @@ "WeatherChances": [ { "WeatherType": "rain", - "BaseValue": 0.494, + "BaseValue": -0.494, "ChangeRate": 0.0424, "VariableLowerBound": -0.07, "VariableHigherBound": 0.07 @@ -405,7 +405,7 @@ { "WeatherType": "debris", "BaseValue": 1.4932, - "ChangeRate": 0.044, + "ChangeRate": -0.044, "VariableLowerBound": 0.0, "VariableHigherBound": 0.1 }, diff --git a/ClimatesOfFerngill/data/weather/normal.json b/ClimatesOfFerngill/data/weather/normal.json index b8fb573..5ca561a 100644 --- a/ClimatesOfFerngill/data/weather/normal.json +++ b/ClimatesOfFerngill/data/weather/normal.json @@ -390,7 +390,7 @@ "WeatherChances": [ { "WeatherType": "rain", - "BaseValue": 0.494, + "BaseValue": -0.494, "ChangeRate": 0.0444, "VariableLowerBound": -0.07, "VariableHigherBound": 0.07 @@ -405,7 +405,7 @@ { "WeatherType": "debris", "BaseValue": 2.0222, - "ChangeRate": 0.0722, + "ChangeRate": -0.0722, "VariableLowerBound": 0.0, "VariableHigherBound": 0.1 }, diff --git a/ClimatesOfFerngill/i18n/default.json b/ClimatesOfFerngill/i18n/default.json index a65b977..deed0ea 100644 --- a/ClimatesOfFerngill/i18n/default.json +++ b/ClimatesOfFerngill/i18n/default.json @@ -7,23 +7,251 @@ "console-text.weatherset_snow": "The weather is now snow", "console-text.weatherset_debris": "The weather is now debris", "console-text.weatherset_sun": "The weather is now sunny", - "console-text.weatherset-tmrwrain": "The weather set for tommorow is: rain", - "console-text.weatherset-tmrwstorm": "The weather set for tommorow is: storm", - "console-text.weatherset-tmrwsnow": "The weather set for tommorow is: snow", - "console-text.weatherset-tmrwdebris": "The weather set for tommorow is: debris", - "console-text.weatherset-tmrwfestival": "The weather set for tommorow is: festival", - "console-text.weatherset-tmrwsun": "The weather set for tommorow is: sunny", - "console-text.weatherset-tmrwwedding": "The weather set for tommorow is: wedding", + "console-text.weatherset-tmrwrain": "The weather set for tomorrow is: rain", + "console-text.weatherset-tmrwstorm": "The weather set for tomorrow is: storm", + "console-text.weatherset-tmrwsnow": "The weather set for tomorrow is: snow", + "console-text.weatherset-tmrwdebris": "The weather set for tomorrow is: debris", + "console-text.weatherset-tmrwfestival": "The weather set for tomorrow is: festival", + "console-text.weatherset-tmrwsun": "The weather set for tomorrow is: sunny", + "console-text.weatherset-tmrwwedding": "The weather set for tomorrow is: wedding", //HUD Messages "hud-text.desc_stormtotem": "You hear a roll of thunder...", "hud-text.desc_sick": "You have caught a cold...!", + "hud-text.desc_exhaust": "The hotter temperatures outside are wearing you out more than normal.", + "hud-text.desc_freeze": "The freezing temperatures outside are making you sleepy, wearing you out.", "hud-text.desc_flu": "You have caught the flu and better take some medicine soon!", - "hud-text.desc_frost_killed": "Some of your crops died in the night due to the cold..!", + "hud-text.desc_frost_killed": "{{deadCrops}} crops died in the night due to the cold..!", "hud-text.desc_heatwave_dry": "The extreme heat has caused some of your crops to become dry....!", "hud-text.desc_heatwave_kill": "The extreme heat has caused some of your crops to dry out. If you don't water them, they'll die!", "hud-text.desc_heatwave_cropdeath": "Some of the crops have died due to lack of water!", - "hud-text.desc_cold_removed": "You feel the medicine clearing your sickness", + "hud-text.desc_cold_removed": "You feel the medicine clearing your sickness and soothing your exhaustion", + + //Ferngill Locations + "fern-loc.0": "Castle Village", + "fern-loc.1": "Basket Town", + "fern-loc.2": "Pine Mesa City", + "fern-loc.3": "Point Break", + "fern-loc.4": "Minister Valley", + "fern-loc.5": "Grampleton", + "fern-loc.6": "Zuzu City", + "fern-loc.7": "Fort Josa", + "fern-loc.8": "Chestervale", + "fern-loc.9": "Fern Island", + "fern-loc.10": "Tanker Grove", + "fern-loc.11": "Pathos Isle", + + //Weather - Generic Strings + "weat-loc.0": ".. concludes the weather in {{location}}.#Now for Pelican Town, expect {{descWeather}}, with a high of {{todayHigh}} and low {{todayLow}}. {{condWarning}}{{eveningFog}} #Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-loc.1": "Now for Pelican Town, expect {{descWeather}}, with a high of {{todayHigh}} and low {{todayLow}}. {{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-loc.2": "The weather for Stardew Valley will be {{todayWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + "weat-loc.fog.0": ".. concludes the weather in {{location}}.#Now for Pelican Town, the valley will be blanked in fog until about {{fogTime}}, then expect {{descWeather}}, with a high of {{todayHigh}} and low {{todayLow}}. {{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-loc.fog.1": "Now for Pelican Town, fog will continue to blanket the region until roughly {{fogTime}}, then expect {{descWeather}}, with a high of {{todayHigh}} and low {{todayLow}}. {{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}.", + "weat-loc.fog.2": "Fog will be blanketing Stardew Valley until an anticipated {{fogTime}}, giving way to {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + //Weather - Morning Strings + "weat-morn.0": "Good morning to all our viewers. Today, expect {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-morn.1": "Another day is beginning, so expect {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-morn.2": ".. and that was Yari with the traffic.#Now, starting out weather for Pelican Town... expect {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + //Weather - Afternoon Strings + "weat-afternoon.0": "As morning gives way to afternoon, the weather will continue to be {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-afternoon.1": "The weather continues to be {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, expect {{tomorrowWeather}} withwith a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-afternoon.2": "The weather is currently {{descWeather}} with a high of {{todayHigh}} and low {{todayLow}}.{{condWarning}}{{eveningFog}}#Tomorrow, anticipate {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + //Weather - Evening Strings + "weat-evening.0": "The sun sets over the studio, bringing a close to today.#{{condString}}{{eveningFog}}Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-evening.1": "{{condString}}{{eveningFog}}Tomorrow, expect {{tomorrowWeather}} with high: {{tomorrowHigh}} and low: {{tomorrowLow}}", + "weat-evening.2": "{{condString}}{{eveningFog}}Tomorrow, anticipate {{tomorrowWeather}} with high: {{tomorrowHigh}} and low: {{tomorrowLow}}", + + //Weather - Night + "weat-night.0": "{{condString}}{{eveningFog}Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}.", + "weat-night.1": "{{condString}}{{eveningFog}}Tomorrow, it should be {{tomorrowWeather}} with high: {{tomorrowHigh}} and low: {{tomorrowLow}}", + "weat-night.2": "{{condString}}{{eveningFog}}For tomorrow, expect {{tomorrowWeather}} with high: {{tomorrowHigh}} and low: {{tomorrowLow}}", + + //Weather - Midnight + "weat-midnight.0": "As the witching hour reigns, the weather for tomorrow is {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}.", + "weat-midnight.1": "... concludes the weather for {{location}}#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}.", + "weat-midnight.2": "And the latest updates are in from the KOZU Weather Desk...#For Pelican Town, and the surronding region, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + //Weather - Late Night + "weat-latenight.0": "For the fellow insomniacs, here is the predicted weather for today. Expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + "weat-latenight.1": "And now for the amazing all in one iridium sheemed pufferchick approved Farming Tool from Nexus Co!#..The informerical continues...", + "weat-latenight.2": "For the early commuters, the weather for today is {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low of {{tomorrowLow}}", + + //Weather - Festivals Today + "weat-fesToday.0": "Today, in Stardew Valley, for the {{festival}}, expect {{descWeather}}.#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low {{tomorrowLow}}", + + //And Tomorrow + "weat-fesTomorrow.0": "Today, expect {{descWeather}} with high:{{todayHigh}} and low:{{todayLow}}#Tommorow, for the {{festivalTomorrow}}, expect {{tomorrowWeather}}", + + //Weather - Wedding Today + "weat-wedToday.0": "Today, in Stardew Valley, for the wedding, expect {{weather}}.#Tomorrow, expect {{tomorrowWeather}} with a high of {{tomorrowHigh}} and low {{tomorrowLow}}", + + //And Tomorrow + "weat-wedTomorrow.0": "Today, expect {{weather}} with high:{{high}} and low:{{low}}#Tommorow, for the wedding, expect {{tomorrowWeather}}", + + //Weather - Condition Strings + "weather-condition.heatwave.0": "RWS: A heatwave is expected for the Stardew Valley area out to Zuzu City. Please keep hydrated! ", + "weather-condition.heatwave.1": "RWS: A heatwave is expected for areas bordering the Gem Sea. ", + "weather-condition.heatwave.2": "RWS: A heatwave is in progress for areas bordering the Gem Sea. ", + + "weather-condition.frost.0": "RWS: An unsesaonal frost is expected from areas south and east of Minister Valley, including Stardew Valley. Please keep bundled up! ", + "weather-condition.frost.1": "RWS: A frost is expected for areas bordering the Gem Sea. Expect early crop death, as well as possible hypothermia. ", + "weather-condition.frost.2": "RWS: An overnight frost is expected for areas bordering the Gem Sea. ", + + "weather-condition.whiteout.0": "RWS: An extreme blizzard is sweeping over the region, whiting out the region. ", + "weather-condition.whiteout.1": "RWS: A howling blizzard is expected throughout the valley. Do not travel if at all possible. ", + "weather-condition.whiteout.2": "RWS: Expect near zero visiblity outside as a blizzard passes through. ", + + //this is the night string + "weather-condition.frost.night": "Forecasters are already seeing the temperatures dip dangerously low, and you should expect frosts outside tonight. ", + "weather-condition.evenFog": "Fog is predicted this evening from {{startTime}} to {{endTime}}. ", + + //Weather Descriptions - Spring + "weat-spring.sunny_daytime.0": "a beautiful sunny day", + "weat-spring.sunny_daytime.1": "a good day to enjoy the sun on a warm spring morning", + "weat-spring.sunny_daytime.2": "it's another day for planting those gardens", + + "weat-spring.sunny_nighttime.0": "a clear spring night", + "weat-spring.sunny_nighttime.1": "a cold and beautiful sky viewing night", + "weat-spring.sunny_nighttime.2": "the rest of the day in a chilly night", + + "weat-spring.rainy.0": "rain to fall down", + "weat-spring.rainy.1": "a gentle downpour of preciptation to nourish all of those flowers", + "weat-spring.rainy.2": "a good day to stay inside and read, as the rain drenches the town", + + "weat-spring.stormy.0": "the spring storms are blowing off the Gem Sea.", + "weat-spring.stormy.1": "the storms blowing through the valley are expected to be all day", + "weat-spring.stormy.2": "expect lightning and thunder all day", + + "weat-spring.debris.0": "the pollen to be blowing, so be careful if you're allergic", + "weat-spring.debris.1": "a front blowing through is blowing fircely", + "weat-spring.debris.2": "a stiff wind will be blowing pollen all day", + + "weat-spring.snow.0": "a late snow will be running through the valley", + "weat-spring.snow.1": "a possibly unpleasent surprise with snow throughout the day", + "weat-spring.snow.2": "the white stuff will be coming down", + + "weat-spring.blizzard.0": "an unusual blizzard is blowing through the valley", + "weat-spring.blizzard.1": "a late blizzard will make travel trecherous", + "weat-spring.blizzard.2": "the weather will be severe, with blizzards blowing throughout the area", + + "weat-spring.drythunder.0": "there will be thunder and lightning today, but no rain", + "weat-spring.drythunder.1": "due to the lack of moisture, the lightning will not include rain", + "weat-spring.drythunder.2": "expect lightning and thunder but no rain", + + "weat-spring.thundersnow.0": "a rare and out of season thunder snow will be in the valley", + "weat-spring.thundersnow.1": "a rare and out of season thunder snow will be in the valley", + "weat-spring.thundersnow.2": "a rare and out of season thunder snow will be in the valley", + + //Weather Descriptions - Summer + "weat-summer.sunny_daytime.0": "a hot sunny day", + "weat-summer.sunny_daytime.1": "a good day to enjoy the sun", + "weat-summer.sunny_daytime.2": "a bright cheery day", + + "weat-summer.sunny_nighttime.0": "a warm summer night", + "weat-summer.sunny_nighttime.1": "to enjoy a warm clear night", + "weat-summer.sunny_nighttime.2": "a great night to stargaze", + + "weat-summer.rainy.0": "a rain falling down", + "weat-summer.rainy.1": "a rain providing a relief from the sun", + "weat-summer.rainy.2": "a good day to stay inside and read, as the rain drenches the town", + + "weat-summer.stormy.0": "more summer storms blowing off the Gem Sea. Make sure to batten those hatches down!", + "weat-summer.stormy.1": "that the storms blowing through the valley will last all day", + "weat-summer.stormy.2": "lightning and thunder all day", + + "weat-summer.snow.0": "a freak snow will be running through the valley", + "weat-summer.snow.1": "an amazing surprise with snow throughout the day", + "weat-summer.snow.2": "a totallly unexpected occurance with snow predicted", + + "weat-summer.blizzard.0": "a freak blizzard is blowing through the valley", + "weat-summer.blizzard.1": "an amazing blizzard will make travel trecherous. Local viewers blame wizards.", + "weat-summer.blizzard.2": "the weather will be severe, with blizzards blowing throughout the area .. in summer", + + "weat-summer.drythunder.0": "there will be thunder and lightning today, but no rain", + "weat-summer.drythunder.1": "due to the lack of moisture, the lightning today will not include rain. Areas are expected to watch for wildfires.", + "weat-summer.drythunder.2": "expect lightning and thunder but no rain", + + "weat-summer.thundersnow.0": "a rare and out of season thunder snow will be in the valley", + "weat-summer.thundersnow.1": "a rare and out of season thunder snow will be in the valley", + "weat-summer.thundersnow.2": "a rare and out of season thunder snow will be in the valley", + + //Weather Descriptions - Fall + "weat-fall.sunny_daytime.0": "a cool sunny day", + "weat-fall.sunny_daytime.1": "a good day to enjoy the sun on a chilly fall morning", + "weat-fall.sunny_daytime.2": "a bright cheery day", + + "weat-fall.sunny_nighttime.0": "a chilly clear night", + "weat-fall.sunny_nighttime.1": "a chilly night", + "weat-fall.sunny_nighttime.2": "a good night to sit out on the porch", + + "weat-fall.rainy.0": "a rain falling down", + "weat-fall.rainy.1": "a sign of the advancing rain on the valley", + "weat-fall.rainy.2": "a good day to stay inside and read, as the rain drenches the town", + + "weat-fall.stormy.0": "the fall storms are blowing off the Gem Sea", + "weat-fall.stormy.1": "the storms blowing through the valley are expected to come in waves all day", + "weat-fall.stormy.2": "expect lightning and thunder all day", + + "weat-fall.debris.0": "the leaves are blowing today, so try not to jump in the piles people are sweeping!", + "weat-fall.debris.1": "a front blowing through is blowing fircely", + "weat-fall.debris.2": "a stiff wind will be blowing leaves around all day", + + "weat-fall.snow.0": "an early snow will be running through the valley", + "weat-fall.snow.1": "a presage of winter with snow throughout the day", + "weat-fall.snow.2": "a totallly unexpected occurance with snow predicted", + + "weat-fall.blizzard.0": "an early blizzard is blowing through the valley", + "weat-fall.blizzard.1": "an early blizzard will make travel trecherous", + "weat-fall.blizzard.2": "the weather will be severe, with blizzards blowing throughout the area", + + "weat-fall.drythunder.0": "there will be thunder and lightning, but no rain", + "weat-fall.drythunder.1": "due to the lack of moisture, the lightning will not include rain.", + "weat-fall.drythunder.2": "expect lightning and thunder but no rain", + + "weat-fall.thundersnow.0": "an extremely early thunder snow will be in the valley", + "weat-fall.thundersnow.1": "a rare thunder snow will be in the valley", + "weat-fall.thundersnow.2": "an almost unheard of thunder snow will be in the valley", + + //Weather Descriptions - Winter + "weat-winter.sunny_daytime.0": "a cool sunny day", + "weat-winter.sunny_daytime.1": "a good day to enjoy the sun on a chilly winter morning", + "weat-winter.sunny_daytime.2": "a bright winter cheery day", + + "weat-winter.sunny_nighttime.0": "a frigid sunny night", + "weat-winter.sunny_nighttime.1": "a good day to drink hot chocolate from inside", + "weat-winter.sunny_nighttime.2": "a frozen cloudless night", + + "weat-winter.rainy.0": "an unusually warm day sees rain pouring down", + "weat-winter.rainy.1": "a sign of the advancing rain on the valley", + "weat-winter.rainy.2": "a good day to stay inside to avoid the chilly rain pouring down", + + "weat-winter.stormy.0": "the winter storms are blowing from Zuzu City eastward", + "weat-winter.stormy.1": "the storms blowing through the valley are expected to come in consistent bands all day", + "weat-winter.stormy.2": "expect lightning and thunder all day, on top of the cold.", + + "weat-winter.debris.0": "the snow is blowing around", + "weat-winter.debris.1": "a front blowing through is blowing fircely, so watch out for snow drifts.", + "weat-winter.debris.2": "a stiff wind will be blowing snow around all day", + + "weat-winter.snow.0": "snow will be running through the valley", + "weat-winter.snow.1": "snow throughout the day stretching from the sea to the city", + "weat-winter.snow.2": "snow drifting down, blanketing the region in curtain of white", + + "weat-winter.blizzard.0": "a blizzard is blowing through the valley", + "weat-winter.blizzard.1": "a blizzard will make travel trecherous", + "weat-winter.blizzard.2": "the weather will be severe, with blizzards blowing throughout the area", + + "weat-winter.drythunder.0": "there will be thunder and lightning, but no moisture", + "weat-winter.drythunder.1": "due to the lack of moisture, there will be only thunder and lightning.", + "weat-winter.drythunder.2": "expect lightning and thunder but no preciptation today", + + "weat-winter.thundersnow.0": "a thunder snow will be in the valley", + "weat-winter.thundersnow.1": "a rare thunder snow will be in the valley", + "weat-winter.thundersnow.2": "expect thunder in the snow", //Lunar Messages "moon-text.phase-full": "Full Moon", @@ -38,84 +266,155 @@ "moon-text.hud_message_full": "It's a full moon! The beaches may have more items, but the ghosts may be about.", "moon-text.hud_message_new": "It's a new moon! The beaches may have less items than normal...", - "moon-text.fullmoon_eff": "The powers of the full moon have helped your crops grow..", - "moon-text.newmoon_eff": "The powers of the new moon have caused a few of your crops to grow more slower...", + "moon-text.fullmoon_eff": "The powers of the full moon have helped {{cropsAffected}} crops grow..", + "moon-text.newmoon_eff": "The powers of the new moon have caused {{cropsAffected}} crops to grow more slower...", "moon-desc.desc_moonphase": "Current Moon Phase: {{moonPhase}}", //Weather Menu strings - "weather-menu.opening": "This is Kylie from KWWX Radio. It is {{season}} {{day}}, and here is your weather report.", - "weather-menu.temp_bothscales": "a high of {{highTempC}} C ({{highTempF}} F) with a low of {{lowTempC}} C ({{lowTempF}} F)", - "weather-menu.temp_onlyscales": "a high of {{highTempC}} C with a low of {{lowTempC}} C", - "weather-menu.fore_today_notFest": "Today's weather is {{currentConditions}} with {{Temperature}}", - "weather-menu.fore_today_festival": "Today is the {{festival}}. It will be a sunny day with {{Temperature}}", - "weather-menu.fore_tomorrow_notFest": "Tomorrow's weather will be {{currentConditions}} with {{Temperature}}", - "weather-menu.fore_tomorrow_festival": "Tomorrow will be the {{festival}}. It's expected to be a sunny day with {{Temperature}}", - - //Weather description - "weather-desc.spring_fog": "A lukewarm fog will blanket the Valley until {{time}}.", - "weather-desc.summer_fog": "A warm fog will blanket the Valley until {{time}}.", - "weather-desc.fall_fog": "A chilly fog will blanket the Valley until {{time}}.", - "weather-desc.winter_fog": "A cold fog will blanket the Valley until {{time}}.", - "weather-desc.spring_dfog": "A lukewarm thick fog will blanket the Valley until {{time}}.", - "weather-desc.summer_dfog": "A warm thick fog will blanket the Valley until {{time}} ", - "weather-desc.fall_dfog": "A chilly thick fog will blanket the Valley until {{time}}", - "weather-desc.winter_dfog": "A cold thick fog will blanket the Valley until {{time}}.", - - "weather-desc.spring_sunny1": "a nice warm sunny day outside", - "weather-desc.spring_sunny2": "a warm bright day outside", - "weather-desc.spring_rainy1": "a relaxing spring shower", - "weather-desc.spring_rainy2": "a gently soaking rain", - "weather-desc.spring_stormy1": "a early shower that will soon sprout flowers", - "weather-desc.spring_stormy2": "a rumbly wet day outside", - "weather-desc.spring_snowy1": "a very late snow", - "weather-desc.spring_snowy2": "a late blast of winter", - "weather-desc.spring_debris1": "a chill wind", - "weather-desc.spring_debris2": "a warm but chilly wind is blowing through", - "weather-desc.spring_wedding1": "a nice spring Stardew Valley wedding", - "weather-desc.spring_wedding2": "a nice spring Stardew Valley wedding", - - "weather-desc.summer_sunny1": "hot sun", - "weather-desc.summer_sunny2": "a relentless warming sun", - "weather-desc.summer_rainy1": "warm showers", - "weather-desc.summer_rainy2": "hot showers to cool down the valley", - "weather-desc.summer_stormy1": "summertime thunderstorms", - "weather-desc.summer_stormy2": "thunderstorms are sweeping through the valley", - "weather-desc.summer_snowy1": "a freak occurance of snow", - "weather-desc.summer_snowy2": "a unusual once-in-a-lifetime snowfall is passing through the region", - "weather-desc.summer_debris1": "a hot wind", - "weather-desc.summer_debris2": "a wind blowing through today will bring some small relief from the heat", - "weather-desc.summer_wedding1": "a warm summer Stardew Valley wedding", - "weather-desc.summer_wedding2": "a clear ideal summer Stardew Valley wedding", - - "weather-desc.fall_sunny1": "a cool autumn day", - "weather-desc.fall_rainy1": "chilly showers", - "weather-desc.fall_stormy1": "a blustery thundery day ", - "weather-desc.fall_snowy1": "an early snow", - "weather-desc.fall_debris1": "a day full of whirling leaves", - "weather-desc.fall_wedding1": "a cool pleasent Stardew Valley wedding", - - "weather-desc.winter_sunny1": "a cold sunny day", - "weather-desc.winter_rainy1": "too warm for snow, a freezing rain", - "weather-desc.winter_stormy1": "a rare winter thunderstorm ", - "weather-desc.winter_snowy1": "cold snow", - "weather-desc.winter_debris1": "full of drifting flurries of snow", - "weather-desc.winter_wedding1": "a snowy winter Stardew Valley wedding ", - - "weather-desc.winter_blizzard1": "Blizzards are passing through, reducing visibility severely. Stay safe", - "weather-desc.winter_thundersnow1": "Rare Thundersnow across the valley and outlying Zuzu City today.", - "weather-desc.summer_drylightning1": "Abnormally dry conditions mean that there will be lighting with no rain across the valley.", - "weather-desc.nonsummer_drylightning1": "Unusual dry conditions are passing through the valley, which means we can expect lightning but no rain", - "weather-desc.fall_frost1": "An unseasonably early frost is expected across Raven's Rock through Stardew Valley.", - "weather-desc.spring_frost1": "An unseasonably late frost is expected across Stardew Valley through Point Drake.", - "weather-desc.summer_heatwave1": "A massive heatwave is boiling through the region. Stay hydrated.", - "weather-desc.summer_litheatwave1": "Massive heatwave is boiling through the region with dry lightning throughout the day. Stay hydrated and watch for lightning", - "weather-menu.dangerous_condition": "FRCS Alert: A dangerous condition has been observed for the Zuzu City and Pelican Town areas: {{condition}}", - - //TV strings - "tv.opening-desc": "...concludes the weather for Zuzu City.#Now, for Stardew Valley, ", - "tv.desc-today": "Today's temperature will be {{temperature}}, with {{weathercondition}}.#", - "tv.desc-todayFog": "currently, fog blankets the area until {{time}}. The day will become {{weathercondition}} with {{temperature}} for the rest of the day.#", - "tv.desc-todayDFog": "currently, thick fog blankets the area until {{time}}. The day will become {{weathercondition}} with {{temperature}} for the rest of the day.#", - "tv.desc-tomorrow": "Tomorrow's weather will be {{weathercondition}} with {{temperature}}", - "tv.desc-festival": "It will be a sunny day for the {{festival}} in Pelican Town, with {{temperature}}" + "weather-menu.opening": "This is Kylie from KZAM Radio, broadcasting on 92.5 out of Point Drake. It is the {{descDay}}, and here is the weather report for Stardew Valley:", + "weather-menu.openingS1D1": "This is Kylie from KZAM Radio, broadcasting on 92.5 out of Point Drake. It is the beginning of the year, the {{descDay}}, and here is the weather report for Stardew Valley:", + "weather-menu.openingS4D28": "This is Kylie from KZAM Radio, broadcasting on 92.5 out of Point Drake. It is the end of the year, the {{descDay}}, and here is the weather report for Stardew Valley:", + "weather-menu.condition.frost": "RWS Warning: Frost tonight.", + "weather-menu.condition.heatwave": "RWS Warning: Heatwave expected through the day.", + "weather-menu.current": "Current Conditions: {{todayCondition}}. High: {{todayHigh}} with Low: {{todayLow}}.{{fogString}}", + "weather-menu.fog": "Fog present until {{fogTime}}.", + "weather-menu.expectedFog": " Evening fog is expected as well.", + "weather-menu.fogFuture": " Expected fog later at about {{fogTime}} to {{endFog}}.", + "weather-menu.tomorrow": "Tomorrow's Forecast: {{tomorrowCondition}}. High: {{tomorrowHigh}} with Low: {{tomorrowLow}}.", + + //basic conditions + "weather_sunny_daytime": "Sunny", + "weather_sunny_nighttime": "Clear", + "weather_sunny": "Sunny", + "weather_whiteout": "White Out", + "weather_wind": "Windy", + "weather_lightning": "Stormy", + "weather_snow": "Snowy", + "weather_rainy": "Rainy", + "weather_festival": "Festival", + "weather_wedding": "Wedding", + "weather_drylightning": "Dry Lightning", + "weather_blizzard": "Blizzard", + "weather_frost": "Frost with {{condition}}", + "weather_heatwave": "Heatwave", + "weather_drylightningheatwave": "Dry Lightning with Heatwave", + "weather_drylightningheatwavesunny": "Dry Lightning with Heatwave and sun", + "weather_drylightningheatwavewindy": "Dry Lightning with Heatwave and wind", + "weather_thundersnow": "Thundersnow", + "weather_fog": "Fog with {{condition}} expected", + "weather_unset": "Unset", + + //ordinal strings + "dateSpring1": "1st of Spring", + "dateSpring2": "2nd of Spring", + "dateSpring3": "3rd of Spring", + "dateSpring4": "4th of Spring", + "dateSpring5": "5th of Spring", + "dateSpring6": "6th of Spring", + "dateSpring7": "7th of Spring", + "dateSpring8": "8th of Spring", + "dateSpring9": "9th of Spring", + "dateSpring10": "10th of Spring", + "dateSpring11": "11th of Spring", + "dateSpring12": "12th of Spring", + "dateSpring13": "13th of Spring", + "dateSpring14": "14th of Spring", + "dateSpring15": "15th of Spring", + "dateSpring16": "16th of Spring", + "dateSpring17": "17th of Spring", + "dateSpring18": "18th of Spring", + "dateSpring19": "19th of Spring", + "dateSpring20": "20th of Spring", + "dateSpring21": "21st of Spring", + "dateSpring22": "22nd of Spring", + "dateSpring23": "23rd of Spring", + "dateSpring24": "24th of Spring", + "dateSpring25": "25th of Spring", + "dateSpring26": "26th of Spring", + "dateSpring27": "27th of Spring", + "dateSpring28": "28th of Spring", + "dateSummer1": "1st of Summer", + "dateSummer2": "2nd of Summer", + "dateSummer3": "3rd of Summer", + "dateSummer4": "4th of Summer", + "dateSummer5": "5th of Summer", + "dateSummer6": "6th of Summer", + "dateSummer7": "7th of Summer", + "dateSummer8": "8th of Summer", + "dateSummer9": "9th of Summer", + "dateSummer10": "10th of Summer", + "dateSummer11": "11th of Summer", + "dateSummer12": "12th of Summer", + "dateSummer13": "13th of Summer", + "dateSummer14": "14th of Summer", + "dateSummer15": "15th of Summer", + "dateSummer16": "16th of Summer", + "dateSummer17": "17th of Summer", + "dateSummer18": "18th of Summer", + "dateSummer19": "19th of Summer", + "dateSummer20": "20th of Summer", + "dateSummer21": "21st of Summer", + "dateSummer22": "22nd of Summer", + "dateSummer23": "23rd of Summer", + "dateSummer24": "24th of Summer", + "dateSummer25": "25th of Summer", + "dateSummer26": "26th of Summer", + "dateSummer27": "27th of Summer", + "dateSummer28": "28th of Summer", + "dateFall1": "1st of Fall", + "dateFall2": "2nd of Fall", + "dateFall3": "3rd of Fall", + "dateFall4": "4th of Fall", + "dateFall5": "5th of Fall", + "dateFall6": "6th of Fall", + "dateFall7": "7th of Fall", + "dateFall8": "8th of Fall", + "dateFall9": "9th of Fall", + "dateFall10": "10th of Fall", + "dateFall11": "11th of Fall", + "dateFall12": "12th of Fall", + "dateFall13": "13th of Fall", + "dateFall14": "14th of Fall", + "dateFall15": "15th of Fall", + "dateFall16": "16th of Fall", + "dateFall17": "17th of Fall", + "dateFall18": "18th of Fall", + "dateFall19": "19th of Fall", + "dateFall20": "20th of Fall", + "dateFall21": "21st of Fall", + "dateFall22": "22nd of Fall", + "dateFall23": "23rd of Fall", + "dateFall24": "24th of Fall", + "dateFall25": "25th of Fall", + "dateFall26": "26th of Fall", + "dateFall27": "27th of Fall", + "dateFall28": "28th of Fall", + "dateWinter1": "1st of Winter", + "dateWinter2": "2nd of Winter", + "dateWinter3": "3rd of Winter", + "dateWinter4": "4th of Winter", + "dateWinter5": "5th of Winter", + "dateWinter6": "6th of Winter", + "dateWinter7": "7th of Winter", + "dateWinter8": "8th of Winter", + "dateWinter9": "9th of Winter", + "dateWinter10": "10th of Winter", + "dateWinter11": "11th of Winter", + "dateWinter12": "12th of Winter", + "dateWinter13": "13th of Winter", + "dateWinter14": "14th of Winter", + "dateWinter15": "15th of Winter", + "dateWinter16": "16th of Winter", + "dateWinter17": "17th of Winter", + "dateWinter18": "18th of Winter", + "dateWinter19": "19th of Winter", + "dateWinter20": "20th of Winter", + "dateWinter21": "21st of Winter", + "dateWinter22": "22nd of Winter", + "dateWinter23": "23rd of Winter", + "dateWinter24": "24th of Winter", + "dateWinter25": "25th of Winter", + "dateWinter26": "26th of Winter", + "dateWinter27": "27th of Winter", + "dateWinter28": "28th of Winter" } \ No newline at end of file diff --git a/ClimatesOfFerngill/manifest.json b/ClimatesOfFerngill/manifest.json index c94f975..f7bec22 100644 --- a/ClimatesOfFerngill/manifest.json +++ b/ClimatesOfFerngill/manifest.json @@ -1,14 +1,16 @@ { "Name": "Climates of Ferngill [Rebuild]", "Author": "KoihimeNakamura", - "Version": { - "MajorVersion": 1, - "MinorVersion": 2, - "PatchVersion": 0, - "Build": "rc-20171104" - }, + "Version": "1.3.0", "Description": "Create a unique climate system with custom weathers, as well as add weather related events and commands.", "UniqueID": "KoihimeNakamura.ClimatesOfFerngill", "EntryDll": "ClimatesOfFerngill.dll", - "MinimumApiVersion": "2.0" -} \ No newline at end of file + "MinimumApiVersion": "2.3", + "Dependencies": [ + { + "UniqueID": "Platonymous.Toolkit", + "MinimumVersion": "0.7.0" + } + ], + "UpdateKeys": [ "Nexus:604" ] +} \ No newline at end of file diff --git a/ClimatesOfFerngill/packages.config b/ClimatesOfFerngill/packages.config index d601731..90cb933 100644 --- a/ClimatesOfFerngill/packages.config +++ b/ClimatesOfFerngill/packages.config @@ -1,4 +1,5 @@  - + + \ No newline at end of file diff --git a/CustomizableCartRedux/CustomizableCartRedux.cs b/CustomizableCartRedux/CustomizableCartRedux.cs index a8661a6..fd4fb2d 100644 --- a/CustomizableCartRedux/CustomizableCartRedux.cs +++ b/CustomizableCartRedux/CustomizableCartRedux.cs @@ -4,8 +4,11 @@ using StardewValley; using StardewModdingAPI.Events; using StardewValley.Locations; +using System.Linq; using StardewModdingAPI.Utilities; using Microsoft.Xna.Framework; +using SObject = StardewValley.Object; +using StardewValley.Objects; namespace CustomizableCartRedux { @@ -25,6 +28,9 @@ private void SetCartSpawn(object Sender, EventArgs e) double randChance = r.NextDouble(), dayChance = 0; Forest f = Game1.getLocationFromName("Forest") as Forest; + if (f is null) + throw new Exception("The Forest is not loaded. Please verify your game is properly installed."); + //get the day DayOfWeek day = GetDayOfWeek(SDate.Now()); switch (day) @@ -112,7 +118,7 @@ private void SetCartSpawn(object Sender, EventArgs e) new Rectangle(23 * Game1.tileSize + 85 * Game1.pixelZoom, 10 * Game1.tileSize + 26 * Game1.pixelZoom, 26 * Game1.pixelZoom, 12 * Game1.pixelZoom) }; - f.travelingMerchantStock = Utility.getTravelingMerchantStock(); + f.travelingMerchantStock = GetTravelingMerchantStock(OurConfig.AmountOfItems); foreach (Rectangle travelingMerchantBound in f.travelingMerchantBounds) { Utility.clearObjectsInArea(travelingMerchantBound, f); @@ -127,6 +133,114 @@ private void SetCartSpawn(object Sender, EventArgs e) } } + private Dictionary GetTravelingMerchantStock(int numStock) + { + Dictionary dictionary = new Dictionary(); + Random r = new Random((int)((long)Game1.uniqueIDForThisGame + (long)Game1.stats.DaysPlayed)); + for (int index1 = 0; index1 < (numStock - 2); ++index1) + { + int index2 = r.Next(2, 790); + string[] strArray; + do + { + do + { + index2 = (index2 + 1) % 790; + } + while (!Game1.objectInformation.ContainsKey(index2) || Utility.isObjectOffLimitsForSale(index2)); + strArray = Game1.objectInformation[index2].Split('/'); + } + while (!strArray[3].Contains('-') || Convert.ToInt32(strArray[1]) <= 0 || (strArray[3].Contains("-13") || strArray[3].Equals("Quest")) || (strArray[0].Equals("Weeds") || strArray[3].Contains("Minerals") || strArray[3].Contains("Arch"))); + + + dictionary.Add((Item)new SObject(index2, 1, false, -1, 0), new int[2] + { + Math.Max(r.Next(1, 11) * 100, Convert.ToInt32(strArray[1]) * r.Next(3, 6)), + r.NextDouble() < 0.1 ? 5 : 1 + }); + } + dictionary.Add((Item)GetRandomFurniture(r, (List)null, 0, 1613), new int[2] + { + r.Next(1, 11) * 250, + 1 + }); + if (Utility.getSeasonNumber(Game1.currentSeason) < 2) + dictionary.Add((Item)new SObject(347, 1, false, -1, 0), new int[2] + { + 1000, + r.NextDouble() < 0.1 ? 5 : 1 + }); + else if (r.NextDouble() < 0.4) + dictionary.Add((Item)new SObject(Vector2.Zero, 136, false), new int[2] + { + 4000, + 1 + }); + if (r.NextDouble() < 0.25) + dictionary.Add((Item)new SObject(433, 1, false, -1, 0), new int[2] + { + 2500, + 1 + }); + return dictionary; + } + + private Furniture GetRandomFurniture(Random r, List stock, int lowerIndexBound = 0, int upperIndexBound = 1462) + { + Dictionary dictionary = Game1.content.Load>("Data\\Furniture"); + int num; + do + { + num = r.Next(lowerIndexBound, upperIndexBound); + if (stock != null) + { + foreach (Item obj in stock) + { + if (obj is Furniture && obj.parentSheetIndex == num) + num = -1; + } + } + } + while (IsFurnitureOffLimitsForSale(num) || !dictionary.ContainsKey(num)); + Furniture furniture = new Furniture(num, Vector2.Zero); + int maxValue = int.MaxValue; + furniture.stack = maxValue; + return furniture; + } + + private static bool IsFurnitureOffLimitsForSale(int index) + { + switch (index) + { + case 1680: + case 1733: + case 1669: + case 1671: + case 1541: + case 1545: + case 1554: + case 1402: + case 1466: + case 1468: + case 131: + case 1226: + case 1298: + case 1299: + case 1300: + case 1301: + case 1302: + case 1303: + case 1304: + case 1305: + case 1306: + case 1307: + case 1308: + return true; + default: + return false; + } + } + private DayOfWeek GetDayOfWeek(SDate Target) { switch (Target.Day % 7) diff --git a/CustomizableCartRedux/CustomizableCartRedux.csproj b/CustomizableCartRedux/CustomizableCartRedux.csproj index 1b19aa8..1bb584a 100644 --- a/CustomizableCartRedux/CustomizableCartRedux.csproj +++ b/CustomizableCartRedux/CustomizableCartRedux.csproj @@ -58,11 +58,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/CustomizableCartRedux/manifest.json b/CustomizableCartRedux/manifest.json index de638d5..45269f6 100644 --- a/CustomizableCartRedux/manifest.json +++ b/CustomizableCartRedux/manifest.json @@ -4,8 +4,8 @@ "Version": { "MajorVersion": 1, "MinorVersion": 1, - "PatchVersion": 0, - "Build": "20170917" + "PatchVersion": 1, + "Build": "" }, "Description": "Allows you to alter the chances of the traveling cart appearing. Credit to Yyeahdude for the original idea.", "UniqueID": "KoihimeNakamura.CCR", diff --git a/CustomizableCartRedux/packages.config b/CustomizableCartRedux/packages.config index d601731..f749d09 100644 --- a/CustomizableCartRedux/packages.config +++ b/CustomizableCartRedux/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/TwilightCore/Properties/AssemblyInfo.cs b/QuestOverhaul/Properties/AssemblyInfo.cs similarity index 89% rename from TwilightCore/Properties/AssemblyInfo.cs rename to QuestOverhaul/Properties/AssemblyInfo.cs index 2347640..fd718f5 100644 --- a/TwilightCore/Properties/AssemblyInfo.cs +++ b/QuestOverhaul/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("TwilightCore")] +[assembly: AssemblyTitle("QuestOverhaul")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TwilightCore")] +[assembly: AssemblyProduct("QuestOverhaul")] [assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +20,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("d316f761-a80b-4ccb-936d-1327f7aa63b5")] +[assembly: Guid("92e332e1-533e-42ca-b3ef-1e5bcfdd857b")] // Version information for an assembly consists of the following four values: // diff --git a/QuestOverhaul/USDVP.cs b/QuestOverhaul/USDVP.cs new file mode 100644 index 0000000..0f8119d --- /dev/null +++ b/QuestOverhaul/USDVP.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; +using StardewModdingAPI; +using StardewModdingAPI.Events; +using StardewValley; +using System; +using TwilightShards.Common; +using StardewValley.Quests; +using TwilightShards.Stardew.Common; +using SObject = StardewValley.Object; +using StardewValley.Menus; +using System.Collections.Specialized; +using StardewValley.Monsters; +using System.Collections.Generic; +using StardewValley.TerrainFeatures; +using System.Linq; + +namespace TwilightShards.USDVP +{ + public class USDVP : Mod + { + public override void Entry(IModHelper Helper) + { + SaveEvents.AfterLoad += GameEvents_OneSecondTick; + + } + + private void SaveEvents_BeforeSave(object sender, EventArgs e) + { + //resolve bug 3 (issue 46) + foreach (GameLocation location in Game1.locations) + { + for (int index = location.terrainFeatures.Count - 1; index >= 0; --index) + { + KeyValuePair keyValuePair = location.terrainFeatures.ElementAt>(index); + if (!location.isTileOnMap(keyValuePair.Key)) + { + SerializableDictionary terrainFeatures = location.terrainFeatures; + keyValuePair = location.terrainFeatures.ElementAt>(index); + Vector2 key = keyValuePair.Key; + terrainFeatures.Remove(key); + } + } + } + } + + private void GameEvents_OneSecondTick(object sender, EventArgs e) + { + if (!Context.IsWorldReady) + return; + + Monitor.Log("Running fixes...."); + for (int index = 0; index < Game1.player.questLog.Count; index++) + { + //resolve bug 1 (issue 44) + if (Game1.player.questLog[index].id == 15 && Game1.player.questLog[index] is SlayMonsterQuest ourQuest) + { + //check to see what hte monster actually is + if (ourQuest.monster.name != "Green Slime") + { + ourQuest.monsterName = "Green Slime"; + ourQuest.numberToKill = 10; + ourQuest.monster = new Monster("Green Slime", Vector2.Zero); + ourQuest.questTitle = "Initation"; + ourQuest.questDescription = "If you can slay 10 slimes, you'll have earned your place in the Adventurer's Guild."; + ourQuest.actualTarget = null; + ourQuest.targetMessage = null; + + } + } + } + } + } +} diff --git a/TwilightCore/TwilightCore.csproj b/QuestOverhaul/USDVP.csproj similarity index 68% rename from TwilightCore/TwilightCore.csproj rename to QuestOverhaul/USDVP.csproj index 960e2df..62cf787 100644 --- a/TwilightCore/TwilightCore.csproj +++ b/QuestOverhaul/USDVP.csproj @@ -1,19 +1,22 @@  + + $(MSBuildProjectName) + $(SolutionDir)\_releases + Debug AnyCPU - {D316F761-A80B-4CCB-936D-1327F7AA63B5} + {92E332E1-533E-42CA-B3EF-1E5BCFDD857B} Library Properties - TwilightCore - TwilightCore - v4.5 + USDVP + USDVP + v4.6.1 512 - true @@ -45,28 +48,22 @@ - - - - - - - - - - + - + + + + - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/QuestOverhaul/i18n/default.json b/QuestOverhaul/i18n/default.json new file mode 100644 index 0000000..c1860fa --- /dev/null +++ b/QuestOverhaul/i18n/default.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/QuestOverhaul/manifest.json b/QuestOverhaul/manifest.json new file mode 100644 index 0000000..149fd50 --- /dev/null +++ b/QuestOverhaul/manifest.json @@ -0,0 +1,14 @@ +{ + "Name": "USDVP", + "Author": "KoihimeNakamura", + "Version": { + "MajorVersion": 0, + "MinorVersion": 1, + "PatchVersion": 0, + "Build": "alpha-201801" + }, + "Description": "Patches various bugs in the game.", + "UniqueID": "KoihimeNakamura.USDVP", + "EntryDll": "USDVP.dll", + "MinimumApiVersion": "2.0" +} \ No newline at end of file diff --git a/QuestOverhaul/packages.config b/QuestOverhaul/packages.config new file mode 100644 index 0000000..33db9a9 --- /dev/null +++ b/QuestOverhaul/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index b7fb22e..8301cc3 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ documentation, licenses, and release notes. May have other related projects that * **[Customizable Cart Redux](https://rd.nexusmods.com/stardewvalley/mods/1402)** ([source](CustomizableCartRedux)) _Lets you customize when the cart appears, and how many items it has._ + +* **Quest Overhaul** ([source](QuestOverhaul)) + _This will overhaul the quest system, with more to come._ * **Tree Overhaul** ([source](TreeOverhaul)) _This is the source code for the unofficial patch I am maintaining to make it compatibile with 2.0_ @@ -15,7 +18,7 @@ documentation, licenses, and release notes. May have other related projects that _Creates a different climate system. This is a relatively basic approach, and may have more features in the future. It works by creating a base chance and a value that can increase (or decrease) as the month passes for weather._ * **[Solar Eclipse Event](http://www.nexusmods.com/stardewvalley/mods/897)** ([source](SolarEclipseEvent)) - _This adds the possibility of a solar eclipse to your game! Configurable chance. Also will spawn monsters if you have a wilderness farm in line with the same percentages as the base game._ + _This adds the possibility of a solar eclipse to your game! Configurable chance. Also will spawn monsters if you have a wilderness farm in line with the same percentages as the base game._ * **[Time Reminder](http://www.nexusmods.com/stardewvalley/mods/1000)** ([source](TimeReminder)) _Alerts you of system time after a configurable number of minutes._ diff --git a/SDVModTests/Properties/AssemblyInfo.cs b/SDVModTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 3740e22..0000000 --- a/SDVModTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TwilightCoreTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TwilightCoreTests")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("34ce4599-9236-4dd7-8c41-235e82a2b860")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SDVModTests/SDVMod Tests.csproj b/SDVModTests/SDVMod Tests.csproj deleted file mode 100644 index a3f0200..0000000 --- a/SDVModTests/SDVMod Tests.csproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - - Debug - AnyCPU - {34CE4599-9236-4DD7-8C41-235E82A2B860} - Library - Properties - TwilightCoreTests - TwilightCoreTests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - - - - - - - - - - - - - - - - - - {D316F761-A80B-4CCB-936D-1327F7AA63B5} - TwilightCore - - - - - - - False - - - False - - - False - - - False - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/SDVModTests/packages.config b/SDVModTests/packages.config deleted file mode 100644 index fc2bbdd..0000000 --- a/SDVModTests/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/SolarEclipseEvent/SolarEclipse.cs b/SolarEclipseEvent/SolarEclipse.cs index 2b0b496..425b3c7 100644 --- a/SolarEclipseEvent/SolarEclipse.cs +++ b/SolarEclipseEvent/SolarEclipse.cs @@ -14,24 +14,38 @@ public class SolarEclipseEvent : Mod public bool GameLoaded { get; set; } public bool IsEclipse { get; set; } public int ResetTicker { get; set; } + public bool Disabled { get; set; } private Color nightColor = new Color((int) byte.MaxValue, (int) byte.MaxValue, 0); public override void Entry(IModHelper helper) { + Disabled = false; + if (this.Helper.ModRegistry.IsLoaded("KoihimeNakamura.ClimatesOfFerngill")) + { + IManifest manifest = this.Helper.ModRegistry.Get("KoihimeNakamura.ClimatesOfFerngill"); + if (manifest.Version.IsNewerThan("1.3.0-beta1")) { + Disabled = true; + Monitor.Log("Disabled due to version 1.3.0+ of Climates of Ferngill loaded", LogLevel.Alert); + } + } + Config = Helper.ReadConfig(); - helper.ConsoleCommands - .Add("world_solareclipse", "Starts the solar eclipse.", SolarEclipseEvent_CommandFired); + if (!Disabled) + { + helper.ConsoleCommands + .Add("world_solareclipse", "Starts the solar eclipse.", SolarEclipseEvent_CommandFired); - SaveEvents.AfterLoad += SaveEvents_AfterLoad; - SaveEvents.BeforeSave += SaveEvents_BeforeSave; - TimeEvents.AfterDayStarted += TimeEvents_AfterDayStarted; - TimeEvents.TimeOfDayChanged += TimeEvents_TimeOfDayChanged; - GameEvents.UpdateTick += GameEvents_UpdateTick; - LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; + SaveEvents.AfterLoad += SaveEvents_AfterLoad; + SaveEvents.BeforeSave += SaveEvents_BeforeSave; + TimeEvents.AfterDayStarted += TimeEvents_AfterDayStarted; + TimeEvents.TimeOfDayChanged += TimeEvents_TimeOfDayChanged; + GameEvents.UpdateTick += GameEvents_UpdateTick; + LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; - ResetTicker = 0; + ResetTicker = 0; + } } private void GameEvents_UpdateTick(object sender, EventArgs e) @@ -71,7 +85,7 @@ private void LocationEvents_CurrentLocationChanged(object sender, EventArgsCurre foreach (Furniture f in loc.furniture) { if (f.furniture_type == Furniture.window) - Helper.Reflection.GetPrivateMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); } } } @@ -92,7 +106,7 @@ private void TimeEvents_TimeOfDayChanged(object sender, EventArgsIntChanged e) foreach (Furniture f in loc.furniture) { if (f.furniture_type == Furniture.window) - Helper.Reflection.GetPrivateMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); + Helper.Reflection.GetMethod(f, "addLights").Invoke(new object[] { Game1.currentLocation }); } } diff --git a/SolarEclipseEvent/SolarEclipseEvent.csproj b/SolarEclipseEvent/SolarEclipseEvent.csproj index 5721107..724a571 100644 --- a/SolarEclipseEvent/SolarEclipseEvent.csproj +++ b/SolarEclipseEvent/SolarEclipseEvent.csproj @@ -61,11 +61,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/SolarEclipseEvent/manifest.json b/SolarEclipseEvent/manifest.json index bb804d4..01d97bc 100644 --- a/SolarEclipseEvent/manifest.json +++ b/SolarEclipseEvent/manifest.json @@ -1,12 +1,7 @@ { "Name": "Solar Eclipse Event", "Author": "KoihimeNakamura", - "Version": { - "MajorVersion": 1, - "MinorVersion": 3, - "PatchVersion": 0, - "Build": "20170917" - }, + "Version": "1.3.1", "Description": "Adds a solar eclipse event", "UniqueID": "KoihimeNakamura.SolarEclipseEvent", "EntryDll": "SolarEclipseEvent.dll" diff --git a/SolarEclipseEvent/packages.config b/SolarEclipseEvent/packages.config index e5f436c..028670c 100644 --- a/SolarEclipseEvent/packages.config +++ b/SolarEclipseEvent/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/StardewMods.sln b/StardewMods.sln index b24f072..05fdf3d 100644 --- a/StardewMods.sln +++ b/StardewMods.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.16 +VisualStudioVersion = 15.0.27004.2009 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SolarEclipseEvent", "SolarEclipseEvent\SolarEclipseEvent.csproj", "{B932C1FD-CAC3-4A8C-8119-8D156F8CEB96}" EndProject @@ -17,10 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".metadata", ".metadata", "{ stardewvalley.targets = stardewvalley.targets EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwilightCore", "TwilightCore\TwilightCore.csproj", "{D316F761-A80B-4CCB-936D-1327F7AA63B5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClimateDataExaminer", "ClimateDataExamin\ClimateDataExaminer.csproj", "{696260C4-50B9-4EE6-BCAD-B2DD085BE40E}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TreeOverhaul", "TreeOverhaul\TreeOverhaul.csproj", "{2CDC5732-A8E9-44C4-A9E0-8B6EF3B859EE}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClimatesOfFerngill", "ClimatesOfFerngill\ClimatesOfFerngill.csproj", "{251AC91D-397E-42AF-925D-3C7D1A9C72D5}" @@ -31,14 +27,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterShippingBox", "Better EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TwilightCoreShared", "TwilightCoreShared\TwilightCoreShared.shproj", "{01DA90D0-EEC8-427B-9409-3168A8089F20}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestOverhaul", "QuestOverhaul\QuestOverhaul.csproj", "{92E332E1-533E-42CA-B3EF-1E5BCFDD857B}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution TwilightCoreShared\TwilightCoreShared.projitems*{01da90d0-eec8-427b-9409-3168a8089f20}*SharedItemsImports = 13 TwilightCoreShared\TwilightCoreShared.projitems*{251ac91d-397e-42af-925d-3c7d1a9c72d5}*SharedItemsImports = 4 TwilightCoreShared\TwilightCoreShared.projitems*{288636be-8ae8-4c50-a07d-18223377bf98}*SharedItemsImports = 4 - TwilightCoreShared\TwilightCoreShared.projitems*{92e332e1-533e-42ca-b3ef-1e5bcfdd857b}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,14 +46,6 @@ Global {3F10D072-54FD-47FA-B0AA-47A5A6F80931}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F10D072-54FD-47FA-B0AA-47A5A6F80931}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F10D072-54FD-47FA-B0AA-47A5A6F80931}.Release|Any CPU.Build.0 = Release|Any CPU - {D316F761-A80B-4CCB-936D-1327F7AA63B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D316F761-A80B-4CCB-936D-1327F7AA63B5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D316F761-A80B-4CCB-936D-1327F7AA63B5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D316F761-A80B-4CCB-936D-1327F7AA63B5}.Release|Any CPU.Build.0 = Release|Any CPU - {696260C4-50B9-4EE6-BCAD-B2DD085BE40E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {696260C4-50B9-4EE6-BCAD-B2DD085BE40E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {696260C4-50B9-4EE6-BCAD-B2DD085BE40E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {696260C4-50B9-4EE6-BCAD-B2DD085BE40E}.Release|Any CPU.Build.0 = Release|Any CPU {2CDC5732-A8E9-44C4-A9E0-8B6EF3B859EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CDC5732-A8E9-44C4-A9E0-8B6EF3B859EE}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CDC5732-A8E9-44C4-A9E0-8B6EF3B859EE}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -77,10 +62,6 @@ Global {4BE4E38A-4011-4CC9-8CD0-380BD8B417F0}.Debug|Any CPU.Build.0 = Debug|Any CPU {4BE4E38A-4011-4CC9-8CD0-380BD8B417F0}.Release|Any CPU.ActiveCfg = Release|Any CPU {4BE4E38A-4011-4CC9-8CD0-380BD8B417F0}.Release|Any CPU.Build.0 = Release|Any CPU - {92E332E1-533E-42CA-B3EF-1E5BCFDD857B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92E332E1-533E-42CA-B3EF-1E5BCFDD857B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92E332E1-533E-42CA-B3EF-1E5BCFDD857B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92E332E1-533E-42CA-B3EF-1E5BCFDD857B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TimeReminder/TimeReminder.cs b/TimeReminder/TimeReminder.cs index e33b05a..bb71750 100644 --- a/TimeReminder/TimeReminder.cs +++ b/TimeReminder/TimeReminder.cs @@ -1,7 +1,10 @@ -using StardewModdingAPI; +using Microsoft.Xna.Framework; +using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; +using StardewValley.TerrainFeatures; using System; +using System.Collections.Generic; namespace TimeReminder { diff --git a/TimeReminder/TimeReminder.csproj b/TimeReminder/TimeReminder.csproj index 28f8777..71d5762 100644 --- a/TimeReminder/TimeReminder.csproj +++ b/TimeReminder/TimeReminder.csproj @@ -63,11 +63,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/TimeReminder/packages.config b/TimeReminder/packages.config index d601731..f749d09 100644 --- a/TimeReminder/packages.config +++ b/TimeReminder/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/TreeOverhaul/TreeOverhaul.cs b/TreeOverhaul/TreeOverhaul.cs index f4a23bf..0d3c206 100644 --- a/TreeOverhaul/TreeOverhaul.cs +++ b/TreeOverhaul/TreeOverhaul.cs @@ -26,7 +26,7 @@ public override void Entry(IModHelper helper) { TimeEvents.AfterDayStarted += Events_NewDay; treeOverhaulConfig = helper.ReadConfig(); - this.Monitor.Log(GetType().Name + " has loaded"); + this.Monitor.Log(GetType().Name + " has loaded", LogLevel.Trace); } public void Events_NewDay(object sender, EventArgs e) diff --git a/TreeOverhaul/TreeOverhaul.csproj b/TreeOverhaul/TreeOverhaul.csproj index 720b8eb..6b4e125 100644 --- a/TreeOverhaul/TreeOverhaul.csproj +++ b/TreeOverhaul/TreeOverhaul.csproj @@ -59,12 +59,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - +