PotatoPlan/Game1/Sources/Crops/Farm.cs

350 lines
11 KiB
C#
Raw Normal View History

using System;
2020-06-15 01:45:16 +02:00
using System.IO;
using System.Reflection;
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;
2020-05-06 22:37:04 +02:00
private CropTypesHolder PresetCrops = new CropTypesHolder();
2020-05-07 13:53:07 +02:00
private int Update;
2020-05-10 21:16:24 +02:00
private Astar astar = new Astar();
2020-05-11 01:16:01 +02:00
private PerlinNoise perlin = new PerlinNoise();
2020-05-23 20:37:11 +02:00
private Vector2 RainPosition;
2020-05-23 20:55:45 +02:00
private Vector2 WindSpeed = new Vector2(0,0);
2020-05-23 20:37:11 +02:00
private System.Drawing.Color[][] RainfallMap;
2020-05-11 01:16:01 +02:00
private float[][] whiteNoise;
private float[][] perlinNoise;
2020-05-24 21:22:17 +02:00
private DayNightCycle Time;
private float updatePerc = 0.01f;
2020-05-24 22:22:09 +02:00
private float updateProgress = 0;
2020-05-24 23:10:51 +02:00
private float nextUpdate = 0;
2020-05-24 22:22:09 +02:00
private int productionUpdate = 0;
2020-06-15 01:45:16 +02:00
private string path_base = FindPath();
2020-05-11 01:16:01 +02:00
2020-05-03 13:05:05 +02:00
//initializes the crops
2020-05-06 16:22:30 +02:00
public void init(Vector2 Size, Vector2 housepos)
{
2020-05-11 01:16:01 +02:00
whiteNoise = PerlinNoise.GenerateWhiteNoise(100, 100);
perlinNoise = PerlinNoise.GeneratePerlinNoise(whiteNoise, 1);
2020-05-06 22:37:04 +02:00
PresetCrops.init();
r = new Random();
2020-05-03 13:05:05 +02:00
crops = new Crops[100, 100];
2020-05-10 23:56:52 +02:00
int dirtCount = 0;
2020-05-07 21:46:33 +02:00
for (int i = 0; i < 99; i++)
{
2020-05-07 21:46:33 +02:00
for (int j = 0; j < 99; j++)
{
2020-05-11 01:16:01 +02:00
int x = 0;
2020-05-23 20:37:11 +02:00
2020-05-11 01:54:47 +02:00
if (perlinNoise[i][j] > 0 && perlinNoise[i][j] < 0.15f)
2020-05-11 01:16:01 +02:00
x = 0;
2020-05-11 01:54:47 +02:00
else if (perlinNoise[i][j] >= 0.15f && perlinNoise[i][j] < 0.8f)
2020-05-11 01:16:01 +02:00
x = 1;
2020-05-11 01:54:47 +02:00
else if (perlinNoise[i][j] >= 0.8f)
2020-05-11 01:16:01 +02:00
x = 2;
crops[i, j] = new Crops();
2020-05-05 16:27:45 +02:00
crops[i, j].setStatus(x);
crops[i, j].setOriginalStatus();
2020-05-25 10:59:17 +02:00
x = r.Next(1, 12);
2020-05-07 01:55:52 +02:00
crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x));
2020-05-06 16:22:30 +02:00
crops[i, j].init();
2020-05-10 23:56:52 +02:00
if (crops[i, j].getStatus() == 2)
{
dirtCount++;
}
}
}
2020-05-10 21:16:24 +02:00
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--;
}
}
}
}
2020-05-11 00:04:59 +02:00
if (dirtCount != 0)
2020-05-10 21:16:24 +02:00
init(Size, housepos);
2020-05-23 20:37:11 +02:00
RainPosition.X = r.Next(0, 1900);
RainPosition.Y = r.Next(0, 1950);
2020-06-15 00:59:39 +02:00
float coef = GetRandomNumber(-1f, 1f);
if (coef < 0)
coef = -1.0f;
else
coef = 1.0f;
WindSpeed.X = GetRandomNumber(0.9f, 1f) / 50 * coef;
WindSpeed.Y = GetRandomNumber(0.9f, 1f) / 50 * coef;
2020-06-15 01:45:16 +02:00
RainfallMap = PerlinNoise.LoadImage(System.IO.Path.Combine(path_base, "Content/Rainfall.png"));
}
2020-05-24 18:49:23 +02:00
public Rectangle getRainPosition(int TileSize, int x, int y, Vector2 Size)
2020-05-23 20:37:11 +02:00
{
2020-05-24 16:26:04 +02:00
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);
2020-05-24 13:21:17 +02:00
}
2020-05-24 16:26:04 +02:00
public Rectangle getDestinationRectangle(int x, int y, Vector2 Size)
2020-05-24 13:21:17 +02:00
{
2020-05-24 18:49:23 +02:00
Vector2 temp = new Vector2((int)Math.Round(x + RainPosition.X), y + (int)Math.Round(RainPosition.Y));
2020-05-24 17:08:41 +02:00
if (temp.X >= 1999 - Size.X - 1)
2020-05-24 21:00:24 +02:00
temp.X = -(1999 - (int)Math.Round(RainPosition.X));
2020-05-24 17:08:41 +02:00
if (temp.Y >= 1999 - Size.Y - 1)
2020-05-24 21:00:24 +02:00
temp.Y = -(1999 - (int)Math.Round(RainPosition.Y));
2020-05-24 18:49:23 +02:00
return new Rectangle((int)temp.X, (int)temp.Y, 1, 1);
2020-05-24 13:21:17 +02:00
}
public void drawWeatherInformation(SpriteBatch spriteBatch, SpriteFont Bold, Input input)
{
2020-05-24 21:00:24 +02:00
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);
2020-05-23 20:37:11 +02:00
}
2020-05-24 21:00:24 +02:00
public void updateFarm(Vector2 Size)
{
2020-05-07 13:53:07 +02:00
Update++;
if (Update == 30)
{
2020-05-07 13:53:07 +02:00
for (int i = 0; i < Size.X; i++)
{
2020-05-07 13:53:07 +02:00
for (int j = 0; j < Size.Y; j++)
{
2020-05-24 18:49:23 +02:00
Vector2 temp = new Vector2((int)Math.Round(i + RainPosition.X), j + (int)Math.Round(RainPosition.Y));
2020-05-24 17:08:41 +02:00
if (temp.X >= 1999 - Size.X - 1)
2020-05-24 18:49:23 +02:00
temp.X = i + ((1999 - (int)Math.Round(RainPosition.X)));
2020-05-24 17:08:41 +02:00
if (temp.Y >= 1999 - Size.Y - 1)
2020-05-24 21:00:24 +02:00
temp.Y = i + ((1999 - (int)Math.Round(RainPosition.Y)));
2020-05-25 10:59:17 +02:00
crops[i, j].updateCrop(Size, Time);
crops[i, j].updateRainfall(RainfallMap[(int)Math.Round(temp.X)][(int)Math.Round(temp.Y)].GetBrightness());
2020-05-07 13:53:07 +02:00
}
}
2020-05-23 20:37:11 +02:00
2020-05-07 13:53:07 +02:00
Update = 0;
}
2020-05-25 10:59:17 +02:00
updateRainMapPosition(Size);
if (productionUpdate == 2)
2020-05-24 22:22:09 +02:00
{
2020-05-24 23:10:51 +02:00
nextUpdate = updateProgress + updatePerc;
for (int i = (int)(updateProgress * Size.X); i < nextUpdate * Size.X; i++)
2020-05-24 22:22:09 +02:00
{
for (int j = 0; j < Size.Y; j++)
{
2020-05-25 10:59:17 +02:00
if (crops[i, j].getStatus() > 1)
{
int x = getHighestProductionRate(i, j);
crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x));
crops[i, j].updateProductionRate();
}
2020-05-24 22:22:09 +02:00
}
}
updateProgress = updateProgress + updatePerc;
2020-05-24 23:10:51 +02:00
if (updateProgress >= 1)
2020-05-24 22:22:09 +02:00
{
updateProgress = 0;
}
productionUpdate = 0;
2020-05-24 23:10:51 +02:00
nextUpdate = 0;
2020-05-24 22:22:09 +02:00
}
productionUpdate++;
}
2020-05-24 21:22:17 +02:00
public void updateRainFall(Vector2 Size, DayNightCycle nTime)
2020-05-24 21:00:24 +02:00
{
2020-05-24 21:22:17 +02:00
Time = nTime;
if (nTime.nDay())
2020-05-24 21:00:24 +02:00
{
for (int i = 0; i < Size.X; i++)
{
for (int j = 0; j < Size.Y; j++)
{
crops[i, j].setPrevRainfall();
}
}
}
}
2020-05-23 20:37:11 +02:00
2020-05-03 13:05:05 +02:00
//Changes the properties of the tile when the tractor reaches this tile.
2020-05-06 16:22:30 +02:00
public void setCropStatus(float xfloat, float yfloat)
{
2020-05-06 16:22:30 +02:00
int x = (int)xfloat;
int y = (int)yfloat;
2020-05-07 01:55:52 +02:00
if (crops[x, y].getStatus() >= 3)
{
2020-05-05 16:27:45 +02:00
crops[x, y].setStatus(2);
}
2020-05-05 16:27:45 +02:00
else if(crops[x, y].getStatus() == 0)
{
//do nothing
}
2020-05-05 16:27:45 +02:00
else if (crops[x, y].getStatus() == 2)
{
2020-05-10 01:38:08 +02:00
2020-05-05 16:27:45 +02:00
crops[x, y].setStatus(3);
crops[x, y].setCropTimer();
2020-05-03 13:05:05 +02:00
}
}
public Crops getCrop(int x, int y)
{
return crops[x,y];
}
public Crops[,] getCrops()
{
return crops;
}
2020-05-24 16:26:04 +02:00
private void updateRainMapPosition(Vector2 Size)
2020-05-23 20:37:11 +02:00
{
2020-06-15 00:59:39 +02:00
double x, y;
2020-05-25 11:07:58 +02:00
x = WindSpeed.X + GetRandomNumber(-1f, 1f) / 20000;
y = WindSpeed.Y + GetRandomNumber(-1f, 1f) / 20000;
2020-05-24 21:00:24 +02:00
if (x <= 0.02f && x >= -0.02f)
2020-05-23 20:37:11 +02:00
{
2020-06-15 00:59:39 +02:00
WindSpeed.X = (float)x;
2020-05-23 20:37:11 +02:00
}
if (y < 0.02f && y > -0.02f)
{
2020-06-15 00:59:39 +02:00
WindSpeed.Y = (float)y;
2020-05-23 20:37:11 +02:00
}
2020-05-24 16:26:04 +02:00
if (WindSpeed.X > 0 && RainPosition.X < 2000)
2020-05-23 20:37:11 +02:00
RainPosition.X = RainPosition.X + WindSpeed.X;
2020-05-24 16:26:04 +02:00
else if (WindSpeed.X < 0 && RainPosition.X > 0)
2020-05-23 20:37:11 +02:00
RainPosition.X = RainPosition.X + WindSpeed.X;
2020-05-24 16:26:04 +02:00
if (WindSpeed.Y > 0 && RainPosition.Y < 2000)
2020-05-23 20:37:11 +02:00
RainPosition.Y = RainPosition.Y + WindSpeed.Y;
2020-05-24 16:26:04 +02:00
else if (WindSpeed.Y < 0 && RainPosition.Y > 0)
2020-05-23 20:37:11 +02:00
RainPosition.Y = RainPosition.Y + WindSpeed.Y;
2020-05-24 16:26:04 +02:00
if (Math.Round(RainPosition.X) == 1999 && WindSpeed.X > 0)
2020-05-24 18:49:23 +02:00
RainPosition.X = 0;
2020-05-24 16:26:04 +02:00
else if (Math.Round(RainPosition.X) == 1 && WindSpeed.X < 0)
RainPosition.X = 1999;
2020-05-24 21:00:24 +02:00
if (Math.Round(RainPosition.Y) == 1999 && WindSpeed.Y > 0)
2020-05-24 18:49:23 +02:00
RainPosition.Y = 0;
2020-05-24 21:00:24 +02:00
else if (Math.Round(RainPosition.Y) == 1 && WindSpeed.Y < 0)
RainPosition.Y = 1999;
2020-05-23 20:37:11 +02:00
}
2020-05-05 16:27:45 +02:00
public void setNewHousePos(Vector2 pos, bool newState)
{
crops[(int)pos.X, (int)pos.Y].setHousePos(newState);
}
2020-05-06 22:37:04 +02:00
public CropTypes getPresetCropTypes(int Index)
{
2020-05-24 23:10:51 +02:00
return PresetCrops.getPresetCropTypes(Index);
}
public void setCropType(int x, int y, int Type)
{
crops[x, y].setCropType(Type, PresetCrops.getPresetCropTypes(Type));
}
2020-05-07 21:46:33 +02:00
public void UpdatePreferedCrops(Vector2 Size)
{
for (int i = 0; i < Size.X; i++)
{
for (int j = 0; j < Size.X; j++)
{
2020-05-24 22:22:09 +02:00
if (crops[i, j].getStatus() == 2)
2020-05-10 19:21:52 +02:00
{
int x = getHighestProductionRate(i, j);
crops[i, j].setCropType(x, PresetCrops.getPresetCropTypes(x));
}
2020-05-07 21:46:33 +02:00
}
}
}
private int getHighestProductionRate(int x, int y)
{
2020-05-25 00:03:26 +02:00
int i = 6, holderIndex = 0;
2020-05-07 21:46:33 +02:00
float holder = 0, SampleHolder = 0;
do
{
2020-05-07 21:46:33 +02:00
holder = getProductionRate(x, y, i);
if (SampleHolder < holder)
{
holderIndex = i;
2020-05-07 21:46:33 +02:00
SampleHolder = holder;
}
i++;
} while (i < 12);
return holderIndex;
}
2020-05-24 16:26:04 +02:00
public Color getRainAmount(int x, int y, Color color, Vector2 Size)
2020-05-23 20:37:11 +02:00
{
2020-05-24 16:26:04 +02:00
Vector2 temp = new Vector2(x + (int)Math.Round(RainPosition.X), y + (int)Math.Round(RainPosition.Y));
2020-05-24 18:49:23 +02:00
if (temp.X >= 1999)
temp.X = -(1999 - (int)Math.Round(temp.X));
2020-05-24 21:00:24 +02:00
if (temp.Y >= 1999)
temp.Y = -(1999 - (int)Math.Round(temp.Y));
2020-05-24 16:51:29 +02:00
if (temp.X == -1)
temp.X = 1999;
2020-05-24 21:00:24 +02:00
if (temp.Y == -1)
temp.Y = 1999;
if (RainfallMap[(int)temp.X][(int)temp.Y].GetBrightness() < 0.45f)
2020-05-24 16:26:04 +02:00
{
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()));
}
2020-05-23 20:37:11 +02:00
}
public float getProductionRate(int x, int y, int Type)
{
2020-05-25 00:03:32 +02:00
return crops[x, y]. getProductionRate(PresetCrops.getPresetCropTypes(Type));
2020-05-06 22:37:04 +02:00
}
2020-05-23 20:55:45 +02:00
public float GetRandomNumber(double minimum, double maximum)
{
return (float)(Math.Round(r.NextDouble() * (maximum - minimum) + minimum, 2));
}
2020-06-15 01:45:16 +02:00
private static string FindPath()
{
string path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).ToString();
while (true)
{
path = Directory.GetParent(path).ToString();
if (path.EndsWith("\\Game1"))
{
return path;
}
}
}
}