From 16d35e2d421ca3d713724eb1ebac1f4175935732 Mon Sep 17 00:00:00 2001 From: JoshuaNavarro Date: Fri, 16 Aug 2019 12:26:50 -0700 Subject: [PATCH] Got ores spawning on the farm, finished resource manager statistics, and made ore use proper health values. --- .../OreResourceInformation.cs | 36 +++- .../Framework/Objects/ObjectManager.cs | 9 + .../Framework/Objects/ResourceManager.cs | 169 +++++++++++++++--- .../Objects/Resources/OreVeins/OreVeinTile.cs | 54 ++++-- .../Framework/Utilities/LocationUtilities.cs | 25 +++ GeneralMods/Revitalize/ModCore.cs | 3 +- 6 files changed, 249 insertions(+), 47 deletions(-) diff --git a/GeneralMods/Revitalize/Framework/Objects/InformationFiles/OreResourceInformation.cs b/GeneralMods/Revitalize/Framework/Objects/InformationFiles/OreResourceInformation.cs index 2f4f8211..11ae1b8b 100644 --- a/GeneralMods/Revitalize/Framework/Objects/InformationFiles/OreResourceInformation.cs +++ b/GeneralMods/Revitalize/Framework/Objects/InformationFiles/OreResourceInformation.cs @@ -275,17 +275,43 @@ namespace Revitalize.Framework.Objects.InformationFiles return amount; } - /* + + /// + /// Checks to see if this resource can spawn in the quarry based off of RNG. + /// + /// public virtual bool shouldSpawnInQuarry() { - + double chance = Game1.random.NextDouble(); + chance = (chance - (this.spawnChanceLuckFactor * (Game1.player.LuckLevel + Game1.player.addedLuckLevel.Value))); + if (this.quarrySpawnChance >= chance) return true; + else return false; } - public virtual bool shouldSpawnInFarm() + /// + /// Checks to see if this resource should spawn on the farm based of of rng. + /// + /// + public virtual bool shouldSpawnOnFarm() { - + double chance = Game1.random.NextDouble(); + chance = (chance - (this.spawnChanceLuckFactor * (Game1.player.LuckLevel + Game1.player.addedLuckLevel.Value))); + if (this.farmSpawnChance >= chance) return true; + else return false; } - */ + + /// + /// Checks to see if this resource should spawn in the skull cavern based of of rng. + /// + /// + public virtual bool shouldSpawnInSkullCave() + { + double chance = Game1.random.NextDouble(); + chance = (chance - (this.spawnChanceLuckFactor * (Game1.player.LuckLevel + Game1.player.addedLuckLevel.Value))); + if (this.skullCaveSpawnChance >= chance) return true; + else return false; + } + /// /// Can this ore spawn at the given location? diff --git a/GeneralMods/Revitalize/Framework/Objects/ObjectManager.cs b/GeneralMods/Revitalize/Framework/Objects/ObjectManager.cs index 90b5bd10..21d7fd24 100644 --- a/GeneralMods/Revitalize/Framework/Objects/ObjectManager.cs +++ b/GeneralMods/Revitalize/Framework/Objects/ObjectManager.cs @@ -211,6 +211,15 @@ namespace Revitalize.Framework.Objects if (ObjectPools == null) ObjectPools = new Dictionary(); ObjectPools.Add(Manifest.UniqueID, new ObjectManager(Manifest)); } + + + /// + /// Cleans up all stored information. + /// + public void returnToTitleCleanUp() + { + + } } diff --git a/GeneralMods/Revitalize/Framework/Objects/ResourceManager.cs b/GeneralMods/Revitalize/Framework/Objects/ResourceManager.cs index 1cce6743..fa9c1504 100644 --- a/GeneralMods/Revitalize/Framework/Objects/ResourceManager.cs +++ b/GeneralMods/Revitalize/Framework/Objects/ResourceManager.cs @@ -24,6 +24,9 @@ namespace Revitalize.Framework.Objects /// A list of all of the ores held by the resource manager. /// public Dictionary ores; + /// + /// A list of all visited floors on the current visit to the mines. + /// public List visitedFloors; /// @@ -46,15 +49,43 @@ namespace Revitalize.Framework.Objects OreVeinObj testOre = new OreVeinObj(PyTKHelper.CreateOBJData("Omegasis.Revitalize.Resources.Ore.Test", TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), typeof(OreVeinTile), Color.White), new BasicItemInformation("Test Ore Vein", "Omegasis.Revitalize.Resources.Ore.Test", "A ore vein that is used for testing purposes.", "Revitalize.Ore", Color.Black, -300, 0, false, 350, Vector2.Zero, true, true, TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), new AnimationManager(TextureManager.GetExtendedTexture(ModCore.Manifest, "Resources.Ore", "Test"), new Animation(0, 0, 16, 16)), Color.White, false, null, null)); - /* - testOre.addComponent(new Vector2(0, 0), new OreVeinTile(PyTKHelper.CreateOBJData("Omegasis.Revitalize.Resources.Ore.Test", TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), typeof(OreVeinTile), Color.White), new BasicItemInformation("Test Ore Vein", "Omegasis.Revitalize.Resources.Ore.Test", "A ore vein that is used for testing purposes.", "Revitalize.Ore", Color.Black, -300, 0, false, 350, Vector2.Zero, true, true, TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), new AnimationManager(TextureManager.GetExtendedTexture(ModCore.Manifest, "Resources.Ore", "Test"), new Animation(0, 0, 16, 16)), Color.White, false, null, null), new InformationFiles.OreResourceInformation(new StardewValley.Object(211, 1), false, true, true, false, new List() + testOre.addComponent(new Vector2(0, 0), new OreVeinTile(PyTKHelper.CreateOBJData("Omegasis.Revitalize.Resources.Ore.Test", TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), typeof(OreVeinTile), Color.White), new BasicItemInformation("Test Ore Vein", "Omegasis.Revitalize.Resources.Ore.Test", "A ore vein that is used for testing purposes.", "Revitalize.Ore", Color.Black, -300, 0, false, 350, Vector2.Zero, true, true, TextureManager.GetTexture(ModCore.Manifest, "Resources.Ore", "Test"), new AnimationManager(TextureManager.GetExtendedTexture(ModCore.Manifest, "Resources.Ore", "Test"), new Animation(0, 0, 16, 16)), Color.White, false, null, null), + new InformationFiles.OreResourceInformation(new StardewValley.Object(211, 1), true, true, true, false, new List() { new IntRange(1,9) - }, new List(), 1, 5, 1, 10, 1d, 1d, 0, 0, 0, 0), new List())); + }, new List(), (i => i == 1), (i => i % 10 == 0), 1, 5, 1, 10, new IntRange(1, 3), new IntRange(1, 3), new IntRange(0, 0), new List() + { + new IntRange(0,0) + }, new List() + { + new IntRange(0,9999) + }, (i => i == -1), (i => i == -1), 1d, 1.0d, 0.10d, 1d, 1d, 0, 0, 0, 0), new List(),4)); + this.ores.Add("Omegasis.Revitalize.Resources.Ore.Test", testOre); - */ + + } + /// + /// Checks to see if a resource can be spawned here. + /// + /// + /// + /// + /// + public bool canResourceBeSpawnedHere(MultiTiledObject OBJ, GameLocation Location, Vector2 TilePosition) + { + return OBJ.canBePlacedHere(Location, TilePosition) && Location.isTileLocationTotallyClearAndPlaceable(TilePosition); + } + + + //~~~~~~~~~~~~~~~~~~~~~~~// + // World Ore Spawn Code // + //~~~~~~~~~~~~~~~~~~~~~~~// + + #region + + /// /// Spawns an ore vein at the given location if possible. /// @@ -100,23 +131,8 @@ namespace Revitalize.Framework.Objects } /// - /// Checks to see if a resource can be spawned here. + /// Spawns ore in the mine depending on a lot of given variables such as floor level and spawn chance. /// - /// - /// - /// - /// - public bool canResourceBeSpawnedHere(MultiTiledObject OBJ, GameLocation Location, Vector2 TilePosition) - { - return OBJ.canBePlacedHere(Location, TilePosition) && Location.isTileLocationTotallyClearAndPlaceable(TilePosition); - } - - - //~~~~~~~~~~~~~~~~~~~~~~~// - // Mine ore spawn code // - //~~~~~~~~~~~~~~~~~~~~~~~// - - #region public void spawnOreInMine() { int floorLevel = LocationUtilities.CurrentMineLevel(); @@ -211,16 +227,15 @@ namespace Revitalize.Framework.Objects } foreach (OreVeinObj ore in spawnableOreVeins) { - if (ore.resourceInfo.shouldSpawn()) + if ((ore.resourceInfo as OreResourceInformation).shouldSpawnInQuarry()) { - int amount = ore.resourceInfo.getNumberOfNodesToSpawn(); + int amount = (ore.resourceInfo as OreResourceInformation).getNumberOfNodesToSpawnQuarry(); List openTiles = this.getOpenQuarryTiles(ore); - //ModCore.log("Number of open tiles is: " + openTiles.Count); amount = Math.Min(amount, openTiles.Count); //Only spawn for as many open tiles or the amount of nodes to spawn. for (int i = 0; i < amount; i++) { int position = Game1.random.Next(openTiles.Count); - bool didSpawn = this.spawnOreVein(ore.info.id,Game1.getLocationFromName("Mountain"),openTiles[position]); + bool didSpawn = this.spawnOreVein(ore.info.id, Game1.getLocationFromName("Mountain"), openTiles[position]); if (didSpawn == false) { i--; //If the tile didn't spawn due to some odd reason ensure that the amount is spawned. @@ -238,7 +253,65 @@ namespace Revitalize.Framework.Objects { //Ore doesn't meet spawn chance. } - //ModCore.log("Spawned :" + amount + " pancake test ores!"); + } + + } + + /// + /// Spawns ore in the mountain farm every day. + /// + public void mountainFarmDayUpdate() + { + if (LocationUtilities.Farm_IsFarmHiltopFarm() == false) + { + ModCore.log("Farm is not hiltop farm!"); + return; + } + GameLocation farm = Game1.getFarm(); + + List spawnableOreVeins = new List(); + //Get a list of all of the ores that can spawn on this mine level. + foreach (KeyValuePair pair in this.ores) + { + if ((pair.Value.resourceInfo as OreResourceInformation).spawnsOnFarm) + { + spawnableOreVeins.Add(pair.Value); + ModCore.log("Found an ore that spawns on the farm!"); + } + } + foreach (OreVeinObj ore in spawnableOreVeins) + { + if ((ore.resourceInfo as OreResourceInformation).shouldSpawnOnFarm()) + { + int amount = (ore.resourceInfo as OreResourceInformation).getNumberOfNodesToSpawnFarm(); + List openTiles = this.getFarmQuarryOpenTiles(ore); + if (openTiles.Count == 0) + { + ModCore.log("No open farm tiles!"); + } + amount = Math.Min(amount, openTiles.Count); //Only spawn for as many open tiles or the amount of nodes to spawn. + for (int i = 0; i < amount; i++) + { + int position = Game1.random.Next(openTiles.Count); + bool didSpawn = this.spawnOreVein(ore.info.id, farm, openTiles[position]); + if (didSpawn == false) + { + i--; //If the tile didn't spawn due to some odd reason ensure that the amount is spawned. + openTiles.Remove(openTiles[position]); + //amount = Math.Min(amount, openTiles.Count); //Only spawn for as many open tiles or the amount of nodes to spawn. + ModCore.log("Did not spawn ore in the farm quarry!"); + } + else + { + ModCore.log("Spawned ore in the farm quarry!"); + openTiles.Remove(openTiles[position]); //Remove that tile from the list of open tiles. + } + } + } + else + { + //Ore doesn't meet spawn chance. + } } } @@ -251,11 +324,11 @@ namespace Revitalize.Framework.Objects { List tiles = new List(); Microsoft.Xna.Framework.Rectangle r = new Microsoft.Xna.Framework.Rectangle(106, 13, 21, 21); - for(int i = r.X; i <= r.X + r.Width; i++) + for (int i = r.X; i <= r.X + r.Width; i++) { - for(int j=r.Y;j<= r.Y + r.Height; j++) + for (int j = r.Y; j <= r.Y + r.Height; j++) { - if (this.isTileOpenForQuarryStone(i, j) && this.canResourceBeSpawnedHere(obj,Game1.getLocationFromName("Mountain"),new Vector2(i,j))) + if (this.isTileOpenForQuarryStone(i, j) && this.canResourceBeSpawnedHere(obj, Game1.getLocationFromName("Mountain"), new Vector2(i, j))) { tiles.Add(new Vector2(i, j)); } @@ -268,10 +341,42 @@ namespace Revitalize.Framework.Objects return tiles; } + /// + /// Gets all of the open tiles in the farm quarry. + /// + /// + /// + private List getFarmQuarryOpenTiles(MultiTiledObject obj) + { + List tiles = new List(); + Microsoft.Xna.Framework.Rectangle r = new Microsoft.Xna.Framework.Rectangle(5, 37, 22, 8); + GameLocation farm = Game1.getFarm(); + for (int i = r.X; i <= r.X + r.Width; i++) + { + for (int j = r.Y; j <= r.Y + r.Height; j++) + { + Vector2 pos = new Vector2(i, j); + if (farm.doesTileHavePropertyNoNull((int)pos.X, (int)pos.Y, "Type", "Back").Equals("Dirt") && this.canResourceBeSpawnedHere(obj, farm, new Vector2(i, j))) + { + tiles.Add(pos); + } + } + } + if (tiles.Count == 0) + { + //ModCore.log("Quarry is full! Can't spawn more resources!"); + } + return tiles; + } + #endregion + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + // SMAPI Events // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + #region /// /// What happens when the player warps maps. /// @@ -286,11 +391,17 @@ namespace Revitalize.Framework.Objects } } + /// + /// Triggers at the start of every new day to populate the world full of ores. + /// + /// + /// public void DailyResourceSpawn(object o, EventArgs NewDay) { + this.mountainFarmDayUpdate(); this.quarryDayUpdate(); } - + #endregion } } diff --git a/GeneralMods/Revitalize/Framework/Objects/Resources/OreVeins/OreVeinTile.cs b/GeneralMods/Revitalize/Framework/Objects/Resources/OreVeins/OreVeinTile.cs index f2302e73..3db63969 100644 --- a/GeneralMods/Revitalize/Framework/Objects/Resources/OreVeins/OreVeinTile.cs +++ b/GeneralMods/Revitalize/Framework/Objects/Resources/OreVeins/OreVeinTile.cs @@ -20,25 +20,29 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins /// public ResourceInformaton resourceInfo; public List extraDrops; + public int healthValue; + public OreVeinTile() : base() { } - public OreVeinTile(CustomObjectData PyTKData, BasicItemInformation Info,ResourceInformaton Resource,List ExtraDrops) : base(PyTKData, Info) + public OreVeinTile(CustomObjectData PyTKData, BasicItemInformation Info,ResourceInformaton Resource,List ExtraDrops,int Health) : base(PyTKData, Info) { - this.health = 3; + this.healthValue = Health; this.resourceInfo = Resource; this.extraDrops = ExtraDrops != null ? ExtraDrops : new List(); + this.setHealth(this.healthValue); } - public OreVeinTile(CustomObjectData PyTKData, BasicItemInformation Info, Vector2 TileLocation,ResourceInformaton Resource, List ExtraDrops) : base(PyTKData, Info, TileLocation) + public OreVeinTile(CustomObjectData PyTKData, BasicItemInformation Info, Vector2 TileLocation,ResourceInformaton Resource, List ExtraDrops,int Health) : base(PyTKData, Info, TileLocation) { - this.health = 3; + this.healthValue = Health; this.resourceInfo = Resource; this.extraDrops = ExtraDrops != null ? ExtraDrops : new List(); + this.setHealth(this.healthValue); } @@ -53,6 +57,24 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins return base.performDropDownAction(who); } + public override void actionOnPlayerEntry() + { + base.actionOnPlayerEntry(); + this.setHealth(this.healthValue); + } + + public override void updateWhenCurrentLocation(GameTime time, GameLocation environment) + { + base.updateWhenCurrentLocation(time, environment); + this.setHealth(this.healthValue); + } + + public override void DayUpdate(GameLocation location) + { + base.DayUpdate(location); + this.setHealth(this.healthValue); + } + //Checks for any sort of interaction IF and only IF there is a held object on this tile. public override bool checkForAction(Farmer who, bool justCheckingForActivity = false) { @@ -79,6 +101,12 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins //return false; } + /// + /// What happens when the player hits this with a tool. + /// + /// + /// + /// public override bool performToolAction(Tool t, GameLocation location) { @@ -89,7 +117,7 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins if (this.location != null) { this.location.playSound("hammer"); - //ModCore.log("Ore has this much health left: "+this.health); + ModCore.log("Ore has this much health left: "+this.healthValue); } return false; } @@ -101,6 +129,12 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins //return base.performToolAction(t, location); } + /// + /// What happens when an explosion occurs for this object. + /// + /// + /// + /// public override bool onExplosion(Farmer who, GameLocation location) { this.destoryVein(); @@ -117,8 +151,8 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins if (amount <= 0) return; else { - this.health -= amount; - if (this.health <= 0) + this.healthValue -= amount; + if (this.healthValue <= 0) { this.destoryVein(); } @@ -192,10 +226,9 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins return base.shiftRightClicked(who); } - public override Item getOne() { - OreVeinTile component = new OreVeinTile(this.data, this.info,this.resourceInfo,this.extraDrops); + OreVeinTile component = new OreVeinTile(this.data, this.info,this.resourceInfo,this.extraDrops,this.healthValue); component.containerObject = this.containerObject; component.offsetKey = this.offsetKey; return component; @@ -204,9 +237,6 @@ namespace Revitalize.Framework.Objects.Resources.OreVeins public override ICustomObject recreate(Dictionary additionalSaveData, object replacement) { //instead of using this.offsetkey.x use get additional save data function and store offset key there - - - Vector2 offsetKey = new Vector2(Convert.ToInt32(additionalSaveData["offsetKeyX"]), Convert.ToInt32(additionalSaveData["offsetKeyY"])); OreVeinTile self = Revitalize.ModCore.Serializer.DeserializeGUID(additionalSaveData["GUID"]); if (self == null) diff --git a/GeneralMods/Revitalize/Framework/Utilities/LocationUtilities.cs b/GeneralMods/Revitalize/Framework/Utilities/LocationUtilities.cs index 35ca6ab5..3c2ec81b 100644 --- a/GeneralMods/Revitalize/Framework/Utilities/LocationUtilities.cs +++ b/GeneralMods/Revitalize/Framework/Utilities/LocationUtilities.cs @@ -9,8 +9,24 @@ using StardewValley; namespace Revitalize.Framework.Utilities { + /// + /// Deals with helping with locational logic. + /// public class LocationUtilities { + + /// + /// The int value used by SDV to determine if a farm is a hilltop farm. + /// + public static int Farm_HilltopFarmNumber + { + get + { + return 3; + } + } + + /// /// Checks to see if the player is in the regular mine. /// @@ -100,5 +116,14 @@ namespace Revitalize.Framework.Utilities } return openTiles; } + + /// + /// Checks to see if the farm for the game is the hilltop farm. + /// + /// + public static bool Farm_IsFarmHiltopFarm() + { + return Game1.whichFarm == Farm_HilltopFarmNumber; + } } } diff --git a/GeneralMods/Revitalize/ModCore.cs b/GeneralMods/Revitalize/ModCore.cs index c4d79961..a9ba5a9a 100644 --- a/GeneralMods/Revitalize/ModCore.cs +++ b/GeneralMods/Revitalize/ModCore.cs @@ -220,7 +220,7 @@ namespace Revitalize //customObjects = new Dictionary(); ObjectGroups = new Dictionary(); - ObjectManager = new ObjectManager(); + ObjectManager = new ObjectManager(Manifest); Serializer = new Serializer(); ObjectsToDraw = new Dictionary(); @@ -257,6 +257,7 @@ namespace Revitalize private void GameLoop_ReturnedToTitle(object sender, StardewModdingAPI.Events.ReturnedToTitleEventArgs e) { Serializer.returnToTitle(); + ObjectManager = new ObjectManager(Manifest); } /// /// Must be enabled for the tabled to be placed????