using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; class Crops { private int Status; private int originalStatus; private int cropType = 0; private float Timer = 1; private int UpdateCrop; private float fullTimer = 1; private bool housePos = false; private Vector2 Size; private Random r = new Random(); private CropTypes DataSet; SoilProperties soilProperties = new SoilProperties(); private float ProductionRate; private float tempRain; private float prevpred; private DayNightCycle Time = new DayNightCycle(); private int previousDay = 0; public void updateCrop(Vector2 newSize, DayNightCycle nTime) { Time = nTime; if (UpdateCrop == 60) { degradeSoil(); UpdateCrop = 0; } if (Status == 3 && Timer != 1) { Timer = Timer - 1f * ProductionRate; } Size = newSize; UpdateCrop++; if (Timer < 1) { Timer = 1; } } public void updateProductionRate() { getProductionRate(DataSet); } public float getSpeedFactor(float tractorSpeed) { if (getCostOnMovement() == 1) return (1f * tractorSpeed); return (1f * tractorSpeed) / (getCostOnMovement() / 5.0f); } public SoilProperties getSoilProperties() { return soilProperties; } public void Fertilize(Fertilizer fertilizer) { soilProperties.Nitrogen += fertilizer.Nitrogen; soilProperties.Phosphorous += fertilizer.Phosphorus; soilProperties.Potassium += fertilizer.Potassium; if (soilProperties.Nitrogen > 42) soilProperties.Nitrogen = 42; if (soilProperties.Phosphorous > 42) soilProperties.Phosphorous = 42; if (soilProperties.Potassium > 19) soilProperties.Potassium = 19; } public bool isSaturated() { if (soilProperties.Nitrogen > 40 && (soilProperties.Phosphorous > 40 || soilProperties.Potassium > 17)) return true; if (soilProperties.Phosphorous > 40 && soilProperties.Potassium > 17) return true; return false; } public bool isSaturated(int threshold) { if (soilProperties.Nitrogen > 40 - threshold && (soilProperties.Phosphorous > 40 - threshold || soilProperties.Potassium > 17 - (threshold * 17/40))) return true; if (soilProperties.Phosphorous > 40 - threshold && soilProperties.Potassium > 17 - (threshold *17/40)) return true; return false; } public float getCropTimer() { return Timer; } public int getCropTimerBar(int tileSize) { int x = (int)((1 - ((float)Timer / fullTimer)) * (tileSize - tileSize / 3)); return x; } public void init() { soilProperties.setSoilProperties(); } // Changes the time required for the crops to be harvestable public void setCropTimer() { if (cropType == 1) // Barley { Timer = 300; fullTimer = Timer; } else if (cropType == 1) // Wheat { Timer = 600; fullTimer = Timer; } else if (cropType == 2) // Berries { Timer = 1200; fullTimer = Timer; } else // Fruit Trees { Timer = 2400; fullTimer = Timer; } } public int getCostOnMovement() { if (Status == 1) //grass { return 1; } else if (Status == 2) //dirt { return 8; } else { if (cropType == 0) { return 16; //Barley } if (cropType == 1) { return 16; //Barley } else if (cropType == 2) { return 16; //Cotton } else if (cropType == 3) { return 16; //Ground Nuts } else if (cropType == 4) { return 16; //Maize } else if (cropType == 5) { return 16; //Millets } else if (cropType == 6) { return 16; //Oil Seeds } else if (cropType == 7) { return 16; //Paddy } else if (cropType == 8) { return 16; //Pulses } else if (cropType == 9) { return 16; //Sugarcane } else if (cropType == 10) { return 16; //Wheat } else { return 16; //Tobacco } } } public void degradeSoil() { Random r = new Random(); if (soilProperties.Nitrogen > 4.0f) { soilProperties.Nitrogen = soilProperties.Nitrogen - ((soilProperties.NitrogenDegradeRate * (float)Math.Pow(ProductionRate, 2)) * (float)Math.Pow((r.NextDouble() + 0.5f), 2)); } if (soilProperties.Phosphorous > 0.1f) { soilProperties.Phosphorous = soilProperties.Phosphorous - ((soilProperties.PhosphorousDegradeRate * (float)Math.Pow(ProductionRate, 2)) * (float)Math.Pow((r.NextDouble() + 0.5f), 2)); } if (soilProperties.Potassium > 0.1f) { soilProperties.Potassium = soilProperties.Potassium - ((soilProperties.PotassiumDegradeRate * (float)Math.Pow(ProductionRate, 2)) * (float)Math.Pow((r.NextDouble() + 0.5f), 2)); } } public void updateRainfall(float Rain) { if (Rain >= 0.45f) { soilProperties.Rainfall = soilProperties.Rainfall + Rain * 4; } } public void setPrevRainfall() { soilProperties.prevRainfall = soilProperties.Rainfall; if (soilProperties.prevRainfall > 3616) soilProperties.prevRainfall = 3616; else if (soilProperties.prevRainfall < 236) soilProperties.prevRainfall = 236; soilProperties.Rainfall = 0; } public void setCropType(int Type, CropTypes nCropType) { if (Timer == fullTimer) { CropTypes temp = DataSet; DataSet = nCropType; cropType = Type; if (Status > 1) { soilProperties.Area = r.Next(nCropType.AreaMin, nCropType.AreaMax); if (temp != nCropType) updateMLModel(DataSet, 1.0f); } } } public int getStatus() { if (Status != 3) { return Status; } else { return Status; // + cropType; When unique crop textures have been added } } public int getCropType() { return cropType; } public void setStatus(int newStatus) { Status = newStatus; Timer = getCropTimer(); } public void setOriginalStatus() { originalStatus = Status; } public void setHousePos(bool state) { housePos = state; if (state) { Timer = 1; Status = 1; } else { Status = originalStatus; } } public bool getHousePos() { return housePos; } public bool belowCapacity() { return ((int)(soilProperties.Nitrogen + soilProperties.Potassium + soilProperties.Phosphorous)) < soilProperties.Capacity; } public Vector4 getColour() { float r, g, b, a; float productionRate, overhead; if (ProductionRate > 1.0f) { productionRate = 1.0f; overhead = ProductionRate - 1.0f; } else { productionRate = ProductionRate; overhead = 0.0f; } r = (1.0f - productionRate) * 4; g = 0.0f + productionRate; b = 0.0f + overhead * 3; a = 255; return new Vector4(r, g, b, a); } public float getProductionRate(CropTypes Sample) { float predProd = 1.0f; if (Status > 1 && Time.getDays() != previousDay) { predProd = updateMLModel(Sample, predProd); } prevpred = predProd; ProductionRate = 1; float min = 1.0f; if (DataSet != null) { //ProductionRate = ProductionRate + (ProductionRate * compareToDatset(soilProperties.Temperature, Sample.Temparature)); //ProductionRate = ProductionRate + (ProductionRate * compareToDatset(soilProperties.Moisture, Sample.Moisture)); //ProductionRate = ProductionRate + (ProductionRate * compareToDatset(soilProperties.Humidity, Sample.Humidity)); if (DataSet.soilType[0] != null) { if (Sample.soilType[0] == soilProperties.soilType) { ProductionRate = ProductionRate + 0.1f; } if (DataSet.soilType[1] != null) { if (Sample.soilType[1] == soilProperties.soilType) { ProductionRate = ProductionRate + 0.08f; } if (DataSet.soilType[2] != null) { if (Sample.soilType[2] == soilProperties.soilType) { ProductionRate = ProductionRate + 0.5f; } } } } min = Math.Min(compareToDatset(soilProperties.Phosphorous, Sample.Phosphorous), Math.Min(compareToDatset(soilProperties.Potassium, Sample.Potassium), compareToDatset(soilProperties.Nitrogen, Sample.Nitrogen))); ProductionRate = ProductionRate + (ProductionRate * min); if (ProductionRate < 0) { ProductionRate = 0; } ProductionRate = ProductionRate / 1.5f; } ProductionRate = (float)Math.Pow(ProductionRate, 2.5f); return ProductionRate * prevpred; } public float updateMLModel(CropTypes Sample, float predProd) { previousDay = Time.getDays(); bool correctSeason = false; foreach (string i in Sample.Season) { if (i == Time.getTimeOfYear() || i == "Whole Year") { correctSeason = true; break; } } if (correctSeason) { predProd = Game1.Sources.ML_Joel.Engine.PredictProductionwithRainfall(soilProperties, Time); predProd = (predProd / soilProperties.Area) / 2; } else predProd = 0.20f; return predProd; } public float getProductionRate() { return ProductionRate; } public float compareToDatset(float i, float j) { if (i < j) { return (i / j); } else { return (j / i); } } public void Inspect(int tileSize, int Spacing, SpriteFont Bold, SpriteBatch spriteBatch, string[] cropTypesNames) { spriteBatch.Begin(); if (housePos) { spriteBatch.DrawString(Bold, "Tiletype: House", new Vector2(240, Size.Y * (tileSize + Spacing) + 42), Color.Teal); } else if (Status == 0) { spriteBatch.DrawString(Bold, "Tiletype: Boulders", new Vector2(240, Size.Y * (tileSize + Spacing) + 42), Color.Teal); } else if (Status == 1) { spriteBatch.DrawString(Bold, "Tiletype: Grassfield", new Vector2(240, Size.Y * (tileSize + Spacing) + 42), Color.Teal); } else if (Status == 2) { spriteBatch.DrawString(Bold, "Tiletype: Soil", new Vector2(240, Size.Y * (tileSize + Spacing) + 42), Color.Teal); } else if (Status == 3) { int x = (int)(((float)Timer / fullTimer) * 100); x = 100 - x; spriteBatch.DrawString(Bold, "Tiletype: Crop ", new Vector2(240, Size.Y * (tileSize + Spacing) + 42), Color.Teal); spriteBatch.DrawString(Bold, "Completion: " + x + "%", new Vector2(240, Size.Y * (tileSize + Spacing) + 82), Color.Teal); } if (Status != 3) { spriteBatch.DrawString(Bold, "-------------", new Vector2(240, Size.Y * (tileSize + Spacing) + 82), Color.DarkRed); } if (Status > 1) { spriteBatch.DrawString(Bold, "Prefered Crop: " + cropTypesNames[cropType], new Vector2(240, Size.Y * (tileSize + Spacing) + 62), Color.Teal); } else { spriteBatch.DrawString(Bold, "None", new Vector2(240, Size.Y * (tileSize + Spacing) + 62), Color.Teal); } spriteBatch.DrawString(Bold, "Soil Properties:", new Vector2(240, Size.Y * (tileSize + Spacing) + 122), Color.DarkRed); spriteBatch.DrawString(Bold, "Soil Type: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 142), Color.DarkRed); spriteBatch.DrawString(Bold, soilProperties.soilType, new Vector2(370, Size.Y * (tileSize + Spacing) + 142), Color.Teal); spriteBatch.DrawString(Bold, "Temparature: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 162), Color.DarkRed); spriteBatch.DrawString(Bold, soilProperties.Temperature.ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 162), Color.Teal); spriteBatch.DrawString(Bold, "Moisture: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 182), Color.DarkRed); spriteBatch.DrawString(Bold, soilProperties.Moisture.ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 182), Color.Teal); spriteBatch.DrawString(Bold, "Humidity: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 202), Color.DarkRed); spriteBatch.DrawString(Bold, soilProperties.Humidity.ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 202), Color.Teal); spriteBatch.DrawString(Bold, "Phosphorous: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 222), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round(soilProperties.Phosphorous,1).ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 222), Color.Teal); spriteBatch.DrawString(Bold, "Potassium: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 242), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round(soilProperties.Potassium, 1).ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 242), Color.Teal); spriteBatch.DrawString(Bold, "Nitrogen: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 262), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round(soilProperties.Nitrogen, 1).ToString(), new Vector2(370, Size.Y * (tileSize + Spacing) + 262), Color.Teal); spriteBatch.DrawString(Bold, "Production Rate: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 282), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round((ProductionRate * 100), 1).ToString() + "%", new Vector2(370, Size.Y * (tileSize + Spacing) + 282), Color.Teal); spriteBatch.DrawString(Bold, "Last Years Rainfall: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 302), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round((soilProperties.prevRainfall), 1).ToString() + "mm", new Vector2(370, Size.Y * (tileSize + Spacing) + 302), Color.Teal); spriteBatch.DrawString(Bold, "Rainfall: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 322), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round((soilProperties.Rainfall), 1).ToString() + "mm", new Vector2(370, Size.Y * (tileSize + Spacing) + 322), Color.Teal); spriteBatch.DrawString(Bold, "Rain mm/s: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 342), Color.DarkRed); spriteBatch.DrawString(Bold, Math.Round((tempRain * 2), 2).ToString() + "mm", new Vector2(370, Size.Y * (tileSize + Spacing) + 342), Color.Teal); spriteBatch.DrawString(Bold, "Area: ", new Vector2(240, Size.Y * (tileSize + Spacing) + 362), Color.DarkRed); spriteBatch.DrawString(Bold, soilProperties.Area + "m^2", new Vector2(370, Size.Y * (tileSize + Spacing) + 362), Color.Teal); spriteBatch.End(); } }