499 lines
16 KiB
C#
499 lines
16 KiB
C#
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();
|
|
}
|
|
}
|