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; class Farm { private Crops[,] crops; private Random r; private CropTypesHolder PresetCrops = new CropTypesHolder(); private int Update; private Astar astar = new Astar(); private PerlinNoise perlin = new PerlinNoise(); private Vector2 RainPosition; private Vector2 WindSpeed = new Vector2(0,0); private System.Drawing.Color[][] RainfallMap; private float[][] whiteNoise; private float[][] perlinNoise; private DayNightCycle Time; private float updatePerc = 0.10f; private float updateProgress = 0; private float nextUpdate = 0; private int productionUpdate = 0; //initializes the crops public void init(Vector2 Size, Vector2 housepos) { whiteNoise = PerlinNoise.GenerateWhiteNoise(100, 100); perlinNoise = PerlinNoise.GeneratePerlinNoise(whiteNoise, 1); PresetCrops.init(); r = new Random(); crops = new Crops[100, 100]; int dirtCount = 0; for (int i = 0; i < 99; i++) { for (int j = 0; j < 99; j++) { int x = 0; if (perlinNoise[i][j] > 0 && perlinNoise[i][j] < 0.15f) x = 0; else if (perlinNoise[i][j] >= 0.15f && perlinNoise[i][j] < 0.8f) x = 1; else if (perlinNoise[i][j] >= 0.8f) x = 2; crops[i, j] = new Crops(); crops[i, j].setStatus(x); crops[i, j].setOriginalStatus(); x = r.Next(1, 12); crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x)); crops[i, j].init(); if (crops[i, j].getStatus() == 2) { dirtCount++; } } } for (int i = 0; i < 99; i++) { for (int j = 0; j < 99; j++) { if (crops[i, j].getStatus() == 2) { if (!astar.isReachable(crops, new Vector2((int)i, (int)j), housepos)) { dirtCount--; } } } } if (dirtCount != 0) init(Size, housepos); RainPosition.X = r.Next(0, 1900); RainPosition.Y = r.Next(0, 1950); WindSpeed.X = GetRandomNumber(-1f, 1f) / 500; WindSpeed.Y = GetRandomNumber(-1f, 1f) / 500; RainfallMap = PerlinNoise.LoadImage("C:\\Users\\Joel\\source\\repos\\Oskars Repo\\Game1\\Content\\Rainfall.png"); //RainfallMap = PerlinNoise.LoadImage("C:/Users/oel/source/repos/Oscars Repo/Game1/Content/Rainfall.png"); } public Rectangle getRainPosition(int TileSize, int x, int y, Vector2 Size) { float xtrunc = RainPosition.X - (float)Math.Truncate(RainPosition.X); float ytrunc = RainPosition.Y - (float)Math.Truncate(RainPosition.Y); if (xtrunc > 0.5) xtrunc = xtrunc - 1; if (ytrunc > 0.5) ytrunc = ytrunc - 1; xtrunc = -xtrunc; ytrunc = -ytrunc; //return new Rectangle((int)(xtrunc * TileSize) + x * TileSize,(int)(ytrunc * TileSize) + y * TileSize, TileSize, TileSize); return new Rectangle((int)(xtrunc * TileSize) + x * TileSize, (int)(ytrunc * TileSize) + y * TileSize, TileSize, TileSize); } public Rectangle getDestinationRectangle(int x, int y, Vector2 Size) { Vector2 temp = new Vector2((int)Math.Round(x + RainPosition.X), y + (int)Math.Round(RainPosition.Y)); if (temp.X >= 1999 - Size.X - 1) temp.X = -(1999 - (int)Math.Round(RainPosition.X)); if (temp.Y >= 1999 - Size.Y - 1) temp.Y = -(1999 - (int)Math.Round(RainPosition.Y)); return new Rectangle((int)temp.X, (int)temp.Y, 1, 1); } public void drawWeatherInformation(SpriteBatch spriteBatch, SpriteFont Bold, Input input) { spriteBatch.DrawString(Bold, "WindSpeed: " + Math.Round(WindSpeed.X, 4), new Vector2(10, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 282), Color.Teal); spriteBatch.DrawString(Bold, " : ", new Vector2(153, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 282), Color.Teal); spriteBatch.DrawString(Bold, Math.Round(WindSpeed.Y, 4).ToString(), new Vector2(163, input.getSize().Y * (input.getTileSize() + input.getSpacing()) + 282), Color.Teal); } public void updateFarm(Vector2 Size) { Update++; if (Update == 30) { for (int i = 0; i < Size.X; i++) { for (int j = 0; j < Size.Y; j++) { Vector2 temp = new Vector2((int)Math.Round(i + RainPosition.X), j + (int)Math.Round(RainPosition.Y)); if (temp.X >= 1999 - Size.X - 1) temp.X = i + ((1999 - (int)Math.Round(RainPosition.X))); if (temp.Y >= 1999 - Size.Y - 1) temp.Y = i + ((1999 - (int)Math.Round(RainPosition.Y))); crops[i, j].updateCrop(Size, Time); crops[i, j].updateRainfall(RainfallMap[(int)Math.Round(temp.X)][(int)Math.Round(temp.Y)].GetBrightness()); } } Update = 0; } updateRainMapPosition(Size); if (productionUpdate == 60) { nextUpdate = updateProgress + updatePerc; for (int i = (int)(updateProgress * Size.X); i < nextUpdate * Size.X; i++) { for (int j = 0; j < Size.Y; j++) { if (crops[i, j].getStatus() > 1) { int x = getHighestProductionRate(i, j); crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x)); crops[i, j].updateProductionRate(); } } } updateProgress = updateProgress + updatePerc; if (updateProgress >= 1) { updateProgress = 0; } productionUpdate = 0; nextUpdate = 0; } productionUpdate++; } public void updateRainFall(Vector2 Size, DayNightCycle nTime) { Time = nTime; if (nTime.nDay()) { for (int i = 0; i < Size.X; i++) { for (int j = 0; j < Size.Y; j++) { crops[i, j].setPrevRainfall(); } } } } //Changes the properties of the tile when the tractor reaches this tile. public void setCropStatus(float xfloat, float yfloat) { int x = (int)xfloat; int y = (int)yfloat; if (crops[x, y].getStatus() >= 3) { crops[x, y].setStatus(2); } else if(crops[x, y].getStatus() == 0) { //do nothing } else if (crops[x, y].getStatus() == 2) { crops[x, y].setStatus(3); crops[x, y].setCropTimer(); } } public Crops getCrop(int x, int y) { return crops[x,y]; } public Crops[,] getCrops() { return crops; } private void updateRainMapPosition(Vector2 Size) { float x, y; x = WindSpeed.X + GetRandomNumber(-1f, 1f) / 20000; y = WindSpeed.Y + GetRandomNumber(-1f, 1f) / 20000; if (x <= 0.02f && x >= -0.02f) { WindSpeed.X = x; } if (y < 0.02f && y > -0.02f) { WindSpeed.Y = y; } if (WindSpeed.X > 0 && RainPosition.X < 2000) RainPosition.X = RainPosition.X + WindSpeed.X; else if (WindSpeed.X < 0 && RainPosition.X > 0) RainPosition.X = RainPosition.X + WindSpeed.X; if (WindSpeed.Y > 0 && RainPosition.Y < 2000) RainPosition.Y = RainPosition.Y + WindSpeed.Y; else if (WindSpeed.Y < 0 && RainPosition.Y > 0) RainPosition.Y = RainPosition.Y + WindSpeed.Y; if (Math.Round(RainPosition.X) == 1999 && WindSpeed.X > 0) RainPosition.X = 0; else if (Math.Round(RainPosition.X) == 1 && WindSpeed.X < 0) RainPosition.X = 1999; if (Math.Round(RainPosition.Y) == 1999 && WindSpeed.Y > 0) RainPosition.Y = 0; else if (Math.Round(RainPosition.Y) == 1 && WindSpeed.Y < 0) RainPosition.Y = 1999; } public void setNewHousePos(Vector2 pos, bool newState) { crops[(int)pos.X, (int)pos.Y].setHousePos(newState); } public CropTypes getPresetCropTypes(int Index) { return PresetCrops.getPresetCropTypes(Index); } public void setCropType(int x, int y, int Type) { crops[x, y].setCropType(Type, PresetCrops.getPresetCropTypes(Type)); } public void UpdatePreferedCrops(Vector2 Size) { for (int i = 0; i < Size.X; i++) { for (int j = 0; j < Size.X; j++) { if (crops[i, j].getStatus() == 2) { int x = getHighestProductionRate(i, j); crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x)); } } } } private int getHighestProductionRate(int x, int y) { int i = 6, holderIndex = 0; float holder = 0, SampleHolder = 0; do { holder = getProductionRate(x, y, i); if (SampleHolder < holder) { holderIndex = i; SampleHolder = holder; } i++; } while (i < 12); return holderIndex; } public Color getRainAmount(int x, int y, Color color, Vector2 Size) { Vector2 temp = new Vector2(x + (int)Math.Round(RainPosition.X), y + (int)Math.Round(RainPosition.Y)); if (temp.X >= 1999) temp.X = -(1999 - (int)Math.Round(temp.X)); if (temp.Y >= 1999) temp.Y = -(1999 - (int)Math.Round(temp.Y)); if (temp.X == -1) temp.X = 1999; if (temp.Y == -1) temp.Y = 1999; if (RainfallMap[(int)temp.X][(int)temp.Y].GetBrightness() < 0.45f) { return Color.FromNonPremultiplied(color.R, color.G, color.B, (int)(0)); } else { return Color.FromNonPremultiplied(color.R, color.G, color.B, (int)(255 * RainfallMap[(int)temp.X][(int)temp.Y].GetBrightness())); } } public float getProductionRate(int x, int y, int Type) { return crops[x, y]. getProductionRate(PresetCrops.getPresetCropTypes(Type)); } public float GetRandomNumber(double minimum, double maximum) { return (float)(Math.Round(r.NextDouble() * (maximum - minimum) + minimum, 2)); } }