Cleaned up lots of code, and made a settings manager that managers paint and machine settings so far. Will be useful when I actually start implementing machines and stuff.

This commit is contained in:
2017-06-07 12:08:03 -07:00
parent 7f648aa602
commit d3aab3661a
18 changed files with 353 additions and 220 deletions

View File

@ -1,6 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Revitalize.Persistance;
using StardewModdingAPI;
using StardewValley;
using System;

View File

@ -22,13 +22,13 @@ using StardewValley.Locations;
using Revitalize.Menus;
using Microsoft.Xna.Framework.Input;
using xTile;
using Revitalize.Persistance;
using Revitalize.Draw;
using Revitalize.Aesthetics;
using Revitalize.Aesthetics.WeatherDebris;
using System.Reflection;
using StardewValley.Menus;
using Revitalize.Resources.DataNodes;
using Revitalize.Persistence;
namespace Revitalize
{
@ -46,9 +46,12 @@ namespace Revitalize
public static string key_binding="P";
public static string key_binding2 = "E";
public static string key_binding3 = "F";
public static bool useMenuFocus;
public static string path;
public static string contentPath;
public static List<LocalizedContentManager> modContent;
public static IModHelper modHelper;
const int range = 1;
public static MouseState mState;
@ -59,77 +62,52 @@ namespace Revitalize
bool gametick;
bool mapWipe;
public static bool hasLoadedTerrainList;
List<GameLoc> newLoc;
public static bool mapWipe;
public static bool hasLoadedTerrainList;
public static List<GameLoc> newLoc;
public static bool paintEnabled;
public static bool gameLoaded;
public static List<LocalizedContentManager> modContent;
public override void Entry(IModHelper helper)
{
//string first=StardewModdingAPI.Program.StardewAssembly.Location;
modHelper = helper;
string first = StardewModdingAPI.Constants.ExecutionPath;
contentPath= first.Remove(first.Length - 19, 19);
StardewModdingAPI.Events.ControlEvents.KeyPressed += ShopCall;
StardewModdingAPI.Events.ControlEvents.MouseChanged += ControlEvents_MouseChanged;
StardewModdingAPI.Events.GameEvents.UpdateTick +=gameMenuCall;
// StardewModdingAPI.Events.GameEvents.UpdateTick += BedCleanUpCheck;
StardewModdingAPI.Events.GameEvents.GameLoaded += GameEvents_GameLoaded;
StardewModdingAPI.Events.GameEvents.OneSecondTick += MapWipe;
StardewModdingAPI.Events.TimeEvents.DayOfMonthChanged += Util.ResetAllDailyBooleans;
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad;
StardewModdingAPI.Events.SaveEvents.BeforeSave += SaveEvents_BeforeSave;
StardewModdingAPI.Events.SaveEvents.AfterSave += SaveEvents_AfterSave;
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterSave;
StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick;
StardewModdingAPI.Events.GraphicsEvents.OnPreRenderHudEvent += GraphicsEvents_OnPreRenderHudEvent;
StardewModdingAPI.Events.GraphicsEvents.OnPostRenderHudEvent += draw;
//StardewModdingAPI.Events.TimeEvents.DayOfMonthChanged += Util.WaterAllCropsInAllLocations;
hasLoadedTerrainList = false;
path = Helper.DirectoryPath;
newLoc = new List<GameLoc>();
PlayerVariables.initializePlayerVariables();
Log.AsyncG("Revitalize: Running on API Version: " +StardewModdingAPI.Constants.ApiVersion);
useMenuFocus = true;
Lists.loadAllListsAtEntry();
if (File.Exists(Path.Combine(path, "xnb_node.cmd")))
{
paintEnabled = true;
Log.AsyncG("Revitalize: Paint Module Enabled");
}
else
{
paintEnabled = false;
Log.AsyncG("Revitalize: Paint Module Disabled");
SetUp.DuringEntry();
}
}
/// <summary>
/// Draw my weather debris system.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void draw(object sender, EventArgs e)
{
WeatherDebrisSystem.draw();
}
/// <summary>
/// Draw all modded huds like the magic meter.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GraphicsEvents_OnPreRenderHudEvent(object sender, EventArgs e)
{
if (gameLoaded == true)
@ -145,19 +123,20 @@ namespace Revitalize
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_AfterLoad(object sender, EventArgs e)
private void SaveEvents_AfterSave(object sender, EventArgs e)
{
Serialize.createDirectories();
SetUp.createDirectories();
Util.loadMapSwapData();
Serialize.restoreAllModObjects();
gameLoaded = true;
}//end of function;
private void SaveEvents_AfterSave(object sender, EventArgs e)
{
Serialize.createDirectories();
Serialize.restoreAllModObjects();
}
/// <summary>
/// Makes sure that any modded objects are not floating about the world to prevent the serializer from crashing.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_BeforeSave(object sender, EventArgs e)
{
Serialize.cleanUpInventory();
@ -179,7 +158,11 @@ namespace Revitalize
}
}
/// <summary>
/// Checks to see if certain mod objects have been interacted with, such as the Bag of Holding, or modded seeds.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ControlEvents_MouseChanged(object sender, EventArgsMouseStateChanged e)
{
@ -219,15 +202,10 @@ namespace Revitalize
private void GameEvents_GameLoaded(object sender, EventArgs e)
{
modContent = new List<LocalizedContentManager>();//new LocalizedContentManager(Game1.content.ServiceProvider, Game1.content.RootDirectory);
Dictionaries.initializeDictionaries();
Lists.initializeAllLists();
mapWipe = false;
SetUp.AfterGameHasLoaded();
}
public void MapWipe(object sender, EventArgs e)
{

View File

@ -1,6 +1,6 @@
using Microsoft.Xna.Framework;
using Revitalize.Objects;
using Revitalize.Persistance;
using Revitalize.Persistence;
using StardewModdingAPI;
using StardewValley;
using StardewValley.TerrainFeatures;

View File

@ -1,7 +1,7 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Revitalize.Objects;
using Revitalize.Persistance;
using Revitalize.Persistence;
using StardewModdingAPI;
using StardewValley;
using System;

View File

@ -1,7 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Revitalize.Persistance;
using Revitalize.Resources.DataNodes;
using StardewModdingAPI;
using StardewValley;

View File

@ -92,10 +92,15 @@ namespace Revitalize.Objects.Machines
//Extra stuff. May or may not be used.
public bool producePollution;
public bool consumeEnergy;
public bool doesOverrideGlobalConsumeEnergy;
public float currentEnergy;
public float MaxEnergy;

View File

@ -370,7 +370,7 @@ namespace Revitalize.Objects.Machines
this.heldObject.tileLocation = this.tileLocation;
this.heldObject.boundingBox.X = this.boundingBox.X;
this.heldObject.boundingBox.Y = this.boundingBox.Y;
Log.AsyncO(getDefaultBoundingBoxForType((dropIn as Spawner).Decoration_type));
// Log.AsyncO(getDefaultBoundingBoxForType((dropIn as Spawner).Decoration_type));
this.heldObject.performDropDownAction(who);
this.heldObject = null;
if (!probe)

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Persistance
namespace Revitalize.Persistence
{
public class MapSwapData
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Persistance
namespace Revitalize.Persistence
{
public class PlayerVariables
{

View File

@ -58,6 +58,12 @@
<Compile Include="Menus\CarpenterMenu.cs" />
<Compile Include="Menus\MenuComponents\ClickableComponentsExtended.cs" />
<Compile Include="Menus\MenuComponents\ClickableTextureComponentExpanded.cs" />
<Compile Include="Settings\MachineSettings.cs" />
<Compile Include="Settings\MagicSettings.cs" />
<Compile Include="Settings\PaintSettings.cs" />
<Compile Include="Settings\SettingsInterface.cs" />
<Compile Include="Settings\SettingsManager.cs" />
<Compile Include="SetUp.cs" />
<Compile Include="Utilities\MapUtilities.cs" />
<Compile Include="Magic\Alchemy\Menus\ExpandableItemGrabMenu.cs" />
<Compile Include="Magic\Alchemy\Objects\BagofHolding.cs" />
@ -87,8 +93,8 @@
<Compile Include="Menus\LightCustomizer.cs" />
<Compile Include="Objects\shopObject.cs" />
<Compile Include="Objects\SpriteFontObject.cs" />
<Compile Include="Persistance\MapSwapData.cs" />
<Compile Include="Persistance\PlayerVariables.cs" />
<Compile Include="Persistence\MapSwapData.cs" />
<Compile Include="Persistence\PlayerVariables.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\DataNodes\FarmOptionsDataNode.cs" />
<Compile Include="Resources\DataNodes\SeedDataNode.cs" />
@ -107,7 +113,6 @@
<ItemGroup>
<Folder Include="Aesthetics\Paint\Utilities\" />
<Folder Include="Locations\MapUtilities\" />
<Folder Include="Persistance\Configs\" />
<Folder Include="TerrainFeatures\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -6,7 +6,7 @@ using Revitalize.Magic.Alchemy;
using Revitalize.Magic.Alchemy.Objects;
using Revitalize.Objects;
using Revitalize.Objects.Machines;
using Revitalize.Persistance;
using Revitalize.Persistence;
using Revitalize.Resources;
using Revitalize.Resources.DataNodes;
using StardewModdingAPI;
@ -37,52 +37,7 @@ namespace Revitalize
public static string SerializerTrashPath;
public static void createDirectories()
{
DataDirectoryPath = Path.Combine(Class1.path, "PlayerData");
PlayerDataPath = Path.Combine(DataDirectoryPath, Game1.player.name);
InvPath = Path.Combine(PlayerDataPath, "Inventory");
objectsInWorldPath = Path.Combine(PlayerDataPath, "objects");
SerializerTrashPath = Path.Combine(Class1.path, "SerializerTrash");
// Log.AsyncC(TrackedTerrainDataPath);
if (!Directory.Exists(DataDirectoryPath))
{
Directory.CreateDirectory(DataDirectoryPath);
}
if (!Directory.Exists(PlayerDataPath))
{
Directory.CreateDirectory(PlayerDataPath);
}
if (!Directory.Exists(InvPath))
{
Directory.CreateDirectory(InvPath);
}
if (!Directory.Exists(objectsInWorldPath))
{
Directory.CreateDirectory(InvPath);
}
if (!Directory.Exists(SerializerTrashPath))
{
Directory.CreateDirectory(SerializerTrashPath);
}
foreach (GameLocation loc in Game1.locations)
{
if (!Directory.Exists(Path.Combine(objectsInWorldPath, loc.name)))
{
Directory.CreateDirectory(Path.Combine(objectsInWorldPath, loc.name));
}
}
}
public static string SettingsPath;
public static void cleanUpWorld()
{
@ -194,7 +149,7 @@ namespace Revitalize
}
catch (Exception e)
{
Serialize.createDirectories();
SetUp.createDirectories();
}
}
@ -219,8 +174,6 @@ namespace Revitalize
}
public static void ProcessDirectoryForCleanUp(string targetDirectory)
{
// Process the list of files found in the directory.
@ -334,14 +287,9 @@ namespace Revitalize
try
{
//parse from Json Style
cObj = pair.Value.parse.Invoke(data);
cObj.thisLocation = Game1.getLocationFromName(cObj.locationsName);
if (cObj.thisLocation == null)
{
Game1.player.addItemToInventory(cObj);
@ -362,10 +310,8 @@ namespace Revitalize
}
}
}
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
@ -403,7 +349,7 @@ namespace Revitalize
TextReader reader = null;
try
{
Log.AsyncC(filePath);
//Log.AsyncC(filePath);
reader = new StreamReader(filePath);
var fileContents = reader.ReadToEnd();
@ -433,13 +379,9 @@ namespace Revitalize
serializer.Serialize(writer, objectToWrite);
writer.Close();
// XElement school = doc.Element("School");
// school.Add(new XAttribute("ID", "ID_Value"));
}
public static bool WriteToXMLFileSafetyCheck(string filePath, Item objectToWrite, bool append = false)
@ -472,17 +414,10 @@ namespace Revitalize
continue;
}
}
Log.AsyncC("CHECK RESULTS " + false);
return false;
// XElement school = doc.Element("School");
// school.Add(new XAttribute("ID", "ID_Value"));
}
public static T ReadFromXMLFile<T>(string filePath) where T : new()
@ -542,8 +477,6 @@ namespace Revitalize
}
}
public static Item parseItemFromJson(string data)
{
@ -673,13 +606,8 @@ namespace Revitalize
public static Spawner parseSpawner(string data)
{
dynamic obj = JObject.Parse(data);
// Log.AsyncC(obj.thisType);
Spawner d = new Spawner(false);
d.price = obj.price;
@ -756,10 +684,6 @@ namespace Revitalize
// Log.AsyncM(e);
return null;
}
}
public static void serializeSpawner(Item d)
@ -774,13 +698,8 @@ namespace Revitalize
public static GiftPackage parseGiftPackage(string data)
{
dynamic obj = JObject.Parse(data);
// Log.AsyncC(obj.thisType);
GiftPackage d = new GiftPackage(false);
d.price = obj.price;
@ -860,10 +779,6 @@ namespace Revitalize
// Log.AsyncM(e);
return null;
}
}
public static void serializeGiftPackage(Item d)
{
@ -875,10 +790,6 @@ namespace Revitalize
dynamic obj = JObject.Parse(data);
// Log.AsyncC(obj.thisType);
ExtraSeeds d = new ExtraSeeds(false);
d.price = obj.price;
@ -955,10 +866,6 @@ namespace Revitalize
// Log.AsyncM(e);
return null;
}
}
public static void serializeExtraSeeds(Item d)
{
@ -990,11 +897,6 @@ namespace Revitalize
dynamic obj = JObject.Parse(data);
// Log.AsyncC(data);
// Log.AsyncC(obj.thisType);
Light d = new Light(false);
d.price = obj.price;
@ -1076,9 +978,6 @@ namespace Revitalize
return null;
}
}
public static void serializeLight(Item d)
{
@ -1094,11 +993,6 @@ namespace Revitalize
dynamic obj = JObject.Parse(data);
// Log.AsyncC(data);
// Log.AsyncC(obj.thisType);
SpriteFontObject d = new SpriteFontObject(false);
d.price = obj.price;
@ -1180,9 +1074,6 @@ namespace Revitalize
return null;
}
}
public static void serializeSpriteFontObject(Item d)
{
@ -1318,10 +1209,6 @@ namespace Revitalize
Log.AsyncM(e);
return null;
}
}
public static void serializeBagOfHolding(Item d)
{
@ -1329,21 +1216,10 @@ namespace Revitalize
// Serialize.WriteToJsonFile(Path.Combine(InvPath, d.Name + ".json"), (BagofHolding)d);
}
public static void serializeGeneric(Item d)
{
WriteToXMLFile<BagofHolding>(Path.Combine(InvPath, d.Name + ".json"),(BagofHolding)d);
// Serialize.WriteToJsonFile(Path.Combine(InvPath, d.Name + ".json"), (BagofHolding)d);
}
public static Quarry parseQuarry(string data)
{
dynamic obj = JObject.Parse(data);
// Log.AsyncC(obj.thisType);
Quarry d = new Quarry(false);
d.price = obj.price;
@ -1422,10 +1298,6 @@ namespace Revitalize
// Log.AsyncM(e);
return null;
}
}
public static void serializeQuarry(Item d)
{
@ -1440,11 +1312,6 @@ namespace Revitalize
{
dynamic obj = JObject.Parse(data);
// Log.AsyncC(obj.thisType);
shopObject d = new shopObject(false);
d.price = obj.price;
@ -1522,10 +1389,6 @@ namespace Revitalize
//Log.AsyncM(e);
return null;
}
}
public static void serializeShopObject(Item d)
{
@ -1600,8 +1463,6 @@ namespace Revitalize
WriteToJsonFile<List<TrackedTerrainDummyDataNode>>(Path.Combine(PlayerDataPath, "TrackedTerrainFeaturesList.json"), Lists.trackedTerrainFeaturesDummyList);
}
public static List<Item> parseInventoryList(JArray array)
{
@ -1630,8 +1491,6 @@ namespace Revitalize
}
public abstract class JsonCreationConverter<T> : JsonConverter
{
/// <summary>

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Revitalize;
using System.IO;
using StardewValley;
using Revitalize.Resources;
using Revitalize.Persistence;
using StardewModdingAPI;
namespace Revitalize
{
/// <summary>
/// A class used to set everything up at initialization time instead of having everything spaggetti codded about.
/// </summary>
class SetUp
{
public static void DuringEntry()
{
Class1.hasLoadedTerrainList = false;
Class1.path = Class1.modHelper.DirectoryPath;
Class1.newLoc = new List<GameLoc>();
PlayerVariables.initializePlayerVariables();
Log.AsyncG("Revitalize: Running on API Version: " + StardewModdingAPI.Constants.ApiVersion);
Lists.loadAllListsAtEntry();
Settings.SettingsManager.Initialize();
Settings.SettingsManager.LoadAllSettings();
Settings.SettingsManager.SaveAllSettings();
}
public static void AfterGameHasLoaded()
{
Class1.modContent = new List<LocalizedContentManager>();//new LocalizedContentManager(Game1.content.ServiceProvider, Game1.content.RootDirectory);
Dictionaries.initializeDictionaries();
Lists.initializeAllLists();
Class1.mapWipe = false;
}
/// <summary>
/// Create all the directories necessary to run this mod.
/// </summary>
public static void createDirectories()
{
Serialize.DataDirectoryPath = Path.Combine(Class1.path, "PlayerData");
Serialize.PlayerDataPath = Path.Combine(Serialize.DataDirectoryPath, Game1.player.name);
Serialize.InvPath = Path.Combine(Serialize.PlayerDataPath, "Inventory");
Serialize.objectsInWorldPath = Path.Combine(Serialize.PlayerDataPath, "objects");
Serialize.SerializerTrashPath = Path.Combine(Class1.path, "SerializerTrash");
// Log.AsyncC(TrackedTerrainDataPath);
if (!Directory.Exists(Serialize.DataDirectoryPath))
{
Directory.CreateDirectory(Serialize.DataDirectoryPath);
}
if (!Directory.Exists(Serialize.PlayerDataPath))
{
Directory.CreateDirectory(Serialize.PlayerDataPath);
}
if (!Directory.Exists(Serialize.InvPath))
{
Directory.CreateDirectory(Serialize.InvPath);
}
if (!Directory.Exists(Serialize.objectsInWorldPath))
{
Directory.CreateDirectory(Serialize.InvPath);
}
if (!Directory.Exists(Serialize.SerializerTrashPath))
{
Directory.CreateDirectory(Serialize.SerializerTrashPath);
}
foreach (GameLocation loc in Game1.locations)
{
if (!Directory.Exists(Path.Combine(Serialize.objectsInWorldPath, loc.name)))
{
Directory.CreateDirectory(Path.Combine(Serialize.objectsInWorldPath, loc.name));
}
}
}
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using Revitalize;
using StardewModdingAPI;
namespace Revitalize.Settings
{
class MachineSettings : SettingsInterface
{
public static bool doMachinesConsumePower;
public MachineSettings()
{
Initialize();
}
/// <summary>
/// Initializes defaults for this setting.
/// </summary>
public void Initialize()
{
doMachinesConsumePower = true;
}
/// <summary>
/// Loads the settings for this module.
/// </summary>
public void LoadSettings()
{
try
{
SettingsManager.machineSettings= Serialize.ReadFromJsonFile<MachineSettings>(Path.Combine(Serialize.SettingsPath, "MachineSettings" + ".json"));
}
catch (Exception e)
{
Log.AsyncR("Failed to load Machine Settings");
}
}
/// <summary>
/// Saves the settings for this module.
/// </summary>
public void SaveSettings()
{
Serialize.WriteToJsonFile(Path.Combine(Serialize.SettingsPath, "MachineSettings" + ".json"), (MachineSettings)SettingsManager.machineSettings);
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Settings
{
class MagicSettings : SettingsInterface
{
public void Initialize()
{
throw new NotImplementedException();
}
public void LoadSettings()
{
throw new NotImplementedException();
}
public void SaveSettings()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,44 @@
using StardewModdingAPI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Settings
{
class PaintSettings : SettingsInterface
{
public static bool PaintEnabled;
public PaintSettings()
{
this.Initialize();
}
public void Initialize()
{
if (File.Exists(Path.Combine(Class1.path, "xnb_node.cmd")))
{
PaintEnabled = true;
Log.AsyncG("Revitalize: Paint Module Enabled");
}
else
{
PaintEnabled = false;
Log.AsyncG("Revitalize: Paint Module Disabled");
}
}
public void LoadSettings()
{
// throw new NotImplementedException();
}
public void SaveSettings()
{
// throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Settings
{
interface SettingsInterface
{
void Initialize();
void LoadSettings();
void SaveSettings();
}
}

View File

@ -0,0 +1,55 @@
using StardewModdingAPI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Revitalize.Settings
{
class SettingsManager
{
public static MachineSettings machineSettings;
public static PaintSettings paintSettings;
public static List<SettingsInterface> SettingsList;
public static void Initialize()
{
Serialize.SettingsPath = Path.Combine(Class1.path, "Settings");
if (!Directory.Exists(Serialize.SettingsPath))
{
Directory.CreateDirectory(Serialize.SettingsPath);
}
SettingsList = new List<SettingsInterface>();
SettingsList.Add(machineSettings = new MachineSettings());
SettingsList.Add(paintSettings = new PaintSettings());
}
public static void SaveAllSettings()
{
foreach(var v in SettingsList)
{
v.SaveSettings();
}
}
public static void LoadAllSettings()
{
foreach(var v in SettingsList)
{
try
{
v.LoadSettings();
}
catch(Exception e)
{
Log.AsyncR(e);
}
}
}
}
}

View File

@ -1,6 +1,6 @@
using Microsoft.Xna.Framework;
using Revitalize.Objects;
using Revitalize.Persistance;
using Revitalize.Persistence;
using Revitalize.Resources;
using Revitalize.Resources.DataNodes;
using StardewModdingAPI;
@ -27,7 +27,7 @@ namespace Revitalize
public static void ResetAllDailyBooleans(object sender, EventArgsIntChanged e)
{
Serialize.createDirectories();
SetUp.createDirectories();
hasWateredAllCropsToday = false;
if (Lists.trackedTerrainFeatures != null)
{