nonsens
This commit is contained in:
parent
18dce569c0
commit
e98762df73
16 changed files with 333 additions and 93 deletions
|
|
@ -13,6 +13,18 @@
|
|||
<None Remove="Assemblies\**" />
|
||||
<None Remove="Classes\Rendering\Particles\explosion.cfx" />
|
||||
<EmbeddedResource Include="Classes\Rendering\Particles\explosion.cfx" />
|
||||
<None Update="Resources\Audio\in_custody0.mp3">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\Audio\missing0.mp3">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\Audio\missing1.mp3">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\ExplosionHole.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\NoiseTexture.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
@ -110,7 +122,7 @@
|
|||
<None Update="Resources\Garage.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\Audio\helicopter.mp3">
|
||||
<None Update="Resources\Audio\helicopter0.mp3">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Resources\Helicopter.png">
|
||||
|
|
|
|||
|
|
@ -11,12 +11,14 @@ using System.Threading;
|
|||
using AStar;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Concurrent;
|
||||
using NAudio.Wave;
|
||||
|
||||
namespace CityGame.Classes.Entities
|
||||
{
|
||||
public class Car : Entity
|
||||
{
|
||||
public int grid = 1;
|
||||
public bool mightSwitchLane = false;
|
||||
public long TimeUntilReroute = 5000;
|
||||
protected long RerouteTimePassed = 0;
|
||||
public static List<Car> Cars = new List<Car>();
|
||||
|
|
@ -41,10 +43,10 @@ namespace CityGame.Classes.Entities
|
|||
}
|
||||
public float Speed { get; set; } = 128;
|
||||
float currentSpeed = 0;
|
||||
public static ConcurrentDictionary<Tile, Car> OccupiedTilesFill = new ConcurrentDictionary<Tile, Car>();
|
||||
public static ConcurrentDictionary<Tile, Car> OccupiedTiles = new ConcurrentDictionary<Tile, Car>();
|
||||
public static ConcurrentDictionary<Tile, Car> OccupiedTilesFill2 = new ConcurrentDictionary<Tile, Car>();
|
||||
public static ConcurrentDictionary<Tile, Car> OccupiedTiles2 = new ConcurrentDictionary<Tile, Car>();
|
||||
public static ConcurrentDictionary<Tile, ConcurrentBag<Car>> OccupiedTilesFill = new ConcurrentDictionary<Tile, ConcurrentBag<Car>>();
|
||||
public static ConcurrentDictionary<Tile, ConcurrentBag<Car>> OccupiedTiles = new ConcurrentDictionary<Tile, ConcurrentBag<Car>>();
|
||||
public static ConcurrentDictionary<Tile, ConcurrentBag<Car>> OccupiedTilesFill2 = new ConcurrentDictionary<Tile, ConcurrentBag<Car>>();
|
||||
public static ConcurrentDictionary<Tile, ConcurrentBag<Car>> OccupiedTiles2 = new ConcurrentDictionary<Tile, ConcurrentBag<Car>>();
|
||||
protected string PNGFile = "NPCCar.png";
|
||||
protected ColoredRectangle debugRect;
|
||||
protected Tile lastTile;
|
||||
|
|
@ -101,6 +103,12 @@ namespace CityGame.Classes.Entities
|
|||
private float curveModePixelDuration;
|
||||
private int curveModeStartedAt;
|
||||
private bool pathfindingInProgress;
|
||||
LaneMode laneMode = LaneMode.Default;
|
||||
private long laneSwitchCooldown = 0;
|
||||
enum LaneMode
|
||||
{
|
||||
WrongLane = -1, Parked = 0, Default = 1
|
||||
}
|
||||
private async Task<Point[]> CalculatePathAsync(Point start, Point target, PathFinder pathfinder)
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
|
|
@ -110,18 +118,19 @@ namespace CityGame.Classes.Entities
|
|||
}
|
||||
public override async void Tick(long deltaTime)
|
||||
{
|
||||
//deltaTime /= 10;
|
||||
//deltaTime *= 500;
|
||||
Tuple<TileType, string>[] fullBlockTiles = new Tuple<TileType, string>[]
|
||||
visualX = X;
|
||||
visualY = Y;
|
||||
visualRotation = Rotation;
|
||||
UseVisualPosition = true;
|
||||
float r = Rotation;
|
||||
if (laneMode == LaneMode.WrongLane)
|
||||
{
|
||||
new Tuple<TileType, string>(TileType.Road, "4c"),
|
||||
new Tuple<TileType, string>(TileType.Road, "3c"),
|
||||
new Tuple<TileType, string>(TileType.Road, "1"),
|
||||
new Tuple<TileType, string>(TileType.Garage, null)
|
||||
};
|
||||
//if (this == MainWindow.Selected) Debug.WriteLine("Selected.");
|
||||
r = (r + 180) % 360;
|
||||
Vector2 offsetVector = new Vector2(0,-1).RotateBy(Rotation - 90) * MainWindow.TileSize / 3;
|
||||
visualX += offsetVector.X;
|
||||
visualY += offsetVector.Y;
|
||||
}
|
||||
Tile myTile = MainWindow.Grid[Point.X, Point.Y];
|
||||
bool fullBlock = fullBlockTiles.Any(x => (x.Item1 == myTile.Type || (x.Item1 == TileType.Road && (myTile.Type == TileType.Path || myTile.Type == TileType.Highway || myTile.Type == TileType.Bridge || myTile.Type == TileType.HighwayBridge))) && (x.Item2 == myTile.Pattern.PatternCode || x.Item2 is null));
|
||||
if (myTile.Type == TileType.Garage)
|
||||
{
|
||||
Rotation = ((Canvas)myTile.Element).Children[1].Rotation - 90;
|
||||
|
|
@ -163,16 +172,7 @@ namespace CityGame.Classes.Entities
|
|||
Path = null;
|
||||
NextTarget = 0;
|
||||
JourneyFinished(this);
|
||||
if (Math.Round(Rotation) == 0 || Math.Round(Rotation) == 90)
|
||||
{
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile)) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile) && fullBlock) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
}
|
||||
if (Math.Round(Rotation) == 180 || Math.Round(Rotation) == 270)
|
||||
{
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile)) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile) && fullBlock) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
}
|
||||
DoLaneBlockades();
|
||||
return;
|
||||
}
|
||||
if (X.CloselyEquals(nextTarget.X * MainWindow.TileSize) && Y.CloselyEquals(nextTarget.Y * MainWindow.TileSize))
|
||||
|
|
@ -189,30 +189,35 @@ namespace CityGame.Classes.Entities
|
|||
Tile targetTile = MainWindow.Grid[nextTarget.X, nextTarget.Y];
|
||||
Car blockingCar = null;
|
||||
|
||||
if (Math.Round(Rotation) == 0 || Math.Round(Rotation) == 90)
|
||||
DoLaneBlockades();
|
||||
if (Math.Round(r) == 0 || Math.Round(r) == 90)
|
||||
{
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile)) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile) && fullBlock) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
if (OccupiedTiles.ContainsKey(targetTile) && OccupiedTiles[targetTile] != this)
|
||||
if (OccupiedTiles.ContainsKey(targetTile) && OccupiedTiles[targetTile].Any(x => x != this))
|
||||
{
|
||||
SpeedMulti = 0;
|
||||
blockingCar = OccupiedTiles[targetTile];
|
||||
blockingCar = OccupiedTiles[targetTile].First(x => x != this);
|
||||
if (blockingCar is null) blockingCar = this;
|
||||
}
|
||||
}
|
||||
if (Math.Round(Rotation) == 180 || Math.Round(Rotation) == 270)
|
||||
if (Math.Round(r) == 180 || Math.Round(r) == 270)
|
||||
{
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile)) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile) && fullBlock) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
if (OccupiedTiles2.ContainsKey(targetTile) && OccupiedTiles2[targetTile] != this)
|
||||
if (OccupiedTiles2.ContainsKey(targetTile) && OccupiedTiles2[targetTile].Any(x => x != this))
|
||||
{
|
||||
SpeedMulti = 0;
|
||||
blockingCar = OccupiedTiles2[targetTile];
|
||||
blockingCar = OccupiedTiles2[targetTile].First(x => x != this);
|
||||
if (blockingCar is null) blockingCar = this;
|
||||
}
|
||||
}
|
||||
|
||||
laneSwitchCooldown -= (long)Speed * deltaTime;
|
||||
if (SpeedMulti == 0 && blockingCar is not null)
|
||||
{
|
||||
RerouteTimePassed += deltaTime;
|
||||
if (mightSwitchLane && laneSwitchCooldown <= 0)
|
||||
{
|
||||
laneMode = (LaneMode)((int)laneMode * -1);
|
||||
laneSwitchCooldown = MainWindow.TileSize * 3 * 1000;
|
||||
}
|
||||
if (RerouteTimePassed > TimeUntilReroute)
|
||||
{
|
||||
var resetFunc = MainWindow.UpdatePathfinding(targetTile, 0, 3);
|
||||
|
|
@ -221,6 +226,7 @@ namespace CityGame.Classes.Entities
|
|||
}
|
||||
else
|
||||
{
|
||||
if (laneSwitchCooldown <= 0) laneMode = LaneMode.Default;
|
||||
RerouteTimePassed = 0;
|
||||
}
|
||||
|
||||
|
|
@ -251,11 +257,11 @@ namespace CityGame.Classes.Entities
|
|||
}
|
||||
}
|
||||
|
||||
if (this is CriminalCar && SpeedMulti > 0 && deltaTime > 0) Debug.WriteLine("running");
|
||||
var possibleDistance = Speed * deltaTime / 1000 * SpeedMulti;
|
||||
var finalDistance = Math.Min(possibleDistance, travel.Length());
|
||||
Vector2 travelFinal = direction * finalDistance;
|
||||
|
||||
UseVisualPosition = false;
|
||||
if (curveMode != 0)
|
||||
{
|
||||
float rotationStart = MainWindow.TileSize * 1.25f;
|
||||
|
|
@ -265,8 +271,6 @@ namespace CityGame.Classes.Entities
|
|||
if (curveModePixelDuration <= rotationEnd) curveMode = 0;
|
||||
else
|
||||
{
|
||||
UseVisualPosition = true;
|
||||
|
||||
if (curveModePixelDuration < rotationStart && curveModePixelDuration > rotationEnd)
|
||||
{
|
||||
float percentage = (curveModePixelDuration - rotationEnd) / (rotationStart - rotationEnd);
|
||||
|
|
@ -284,15 +288,10 @@ namespace CityGame.Classes.Entities
|
|||
vRotDeg = (-45 * percentage2) * curveMode;
|
||||
}
|
||||
if (this == MainWindow.Selected) Debug.WriteLine(vRotDeg);
|
||||
visualX = X;
|
||||
visualY = Y;
|
||||
visualRotation = Rotation + vRotDeg;
|
||||
visualRotation += vRotDeg;
|
||||
}
|
||||
else
|
||||
{
|
||||
visualX = X;
|
||||
visualY = Y;
|
||||
visualRotation = Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -302,16 +301,33 @@ namespace CityGame.Classes.Entities
|
|||
}
|
||||
else
|
||||
{
|
||||
if (Math.Round(Rotation) == 0 || Math.Round(Rotation) == 90)
|
||||
{
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile)) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile) && fullBlock) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
}
|
||||
if (Math.Round(Rotation) == 180 || Math.Round(Rotation) == 270)
|
||||
{
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile)) OccupiedTilesFill2.TryAdd(myTile, this);
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile) && fullBlock) OccupiedTilesFill.TryAdd(myTile, this);
|
||||
}
|
||||
DoLaneBlockades();
|
||||
}
|
||||
}
|
||||
public void DoLaneBlockades()
|
||||
{
|
||||
Tuple<TileType, string>[] fullBlockTiles = new Tuple<TileType, string>[]
|
||||
{
|
||||
new Tuple<TileType, string>(TileType.Road, "4c"),
|
||||
new Tuple<TileType, string>(TileType.Road, "3c"),
|
||||
new Tuple<TileType, string>(TileType.Road, "1"),
|
||||
new Tuple<TileType, string>(TileType.Garage, null)
|
||||
};
|
||||
//if (this == MainWindow.Selected) Debug.WriteLine("Selected.");
|
||||
Tile myTile = MainWindow.Grid[Point.X, Point.Y];
|
||||
bool fullBlock = fullBlockTiles.Any(x => (x.Item1 == myTile.Type || (x.Item1 == TileType.Road && (myTile.Type == TileType.Path || myTile.Type == TileType.Highway || myTile.Type == TileType.Bridge || myTile.Type == TileType.HighwayBridge))) && (x.Item2 == myTile.Pattern.PatternCode || x.Item2 is null));
|
||||
if (laneMode == LaneMode.Parked) return;
|
||||
float r = Rotation;
|
||||
if (laneMode == LaneMode.WrongLane) r = (r + 180) % 360;
|
||||
if (Math.Round(r) == 0 || Math.Round(r) == 90)
|
||||
{
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile)) OccupiedTilesFill.WeirdAddToList(myTile, this);
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile) && fullBlock) OccupiedTilesFill2.WeirdAddToList(myTile, this);
|
||||
}
|
||||
if (Math.Round(r) == 180 || Math.Round(r) == 270)
|
||||
{
|
||||
if (!OccupiedTilesFill2.ContainsKey(myTile)) OccupiedTilesFill2.WeirdAddToList(myTile, this);
|
||||
if (!OccupiedTilesFill.ContainsKey(myTile) && fullBlock) OccupiedTilesFill.WeirdAddToList(myTile, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
89
CityGame/Classes/Entities/CriminalCar.cs
Normal file
89
CityGame/Classes/Entities/CriminalCar.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using CityGame.Classes.Rendering;
|
||||
using CityGame.Classes.World;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OrpticonGameHelper;
|
||||
using OrpticonGameHelper.Classes.Elements;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CityGame.Classes.Entities
|
||||
{
|
||||
public class CriminalCar : Car
|
||||
{
|
||||
public long CaughtTimer { get; set; }
|
||||
public bool GotAway { get; set; } = false;
|
||||
public bool Caught { get; set; } = false;
|
||||
public static List<Tile> targetTiles = new List<Tile>();
|
||||
public static List<CriminalCar> CCars = new List<CriminalCar>();
|
||||
public CriminalCar() : base()
|
||||
{
|
||||
CCars.Add(this);
|
||||
if (targetTiles.Count == 0)
|
||||
{
|
||||
for (int x = 0; x < MainWindow.Grid.GetLength(0); x++)
|
||||
{
|
||||
targetTiles.Add(MainWindow.Grid[x, 0]);
|
||||
targetTiles.Add(MainWindow.Grid[x, MainWindow.Grid.GetLength(1) - 1]);
|
||||
}
|
||||
for (int y = 0; y < MainWindow.Grid.GetLength(1); y++)
|
||||
{
|
||||
targetTiles.Add(MainWindow.Grid[0, y]);
|
||||
targetTiles.Add(MainWindow.Grid[MainWindow.Grid.GetLength(0) - 1, y]);
|
||||
}
|
||||
}
|
||||
grid = 2;
|
||||
//mightSwitchLane = true;
|
||||
Speed = 160;
|
||||
PNGFile = "CriminalCar.png";
|
||||
TimeUntilReroute = 1000;
|
||||
}
|
||||
public override OCanvas Render()
|
||||
{
|
||||
OCanvas canvas = base.Render();
|
||||
|
||||
return canvas;
|
||||
}
|
||||
public override void Tick(long deltaTime)
|
||||
{
|
||||
if (!Caught && !GotAway)
|
||||
{
|
||||
if (CaughtTimer >= 0)
|
||||
{
|
||||
if (Path is null || Path.Length == 0)
|
||||
{
|
||||
var myTile = MainWindow.Grid[(int)X / MainWindow.TileSize, (int)Y / MainWindow.TileSize];
|
||||
Target = MainWindow.FindNearestTile(myTile, MainWindow.Grids[grid], targetTiles.ToArray());
|
||||
if (Target is Tile tile && tile.X == myTile.X && tile.Y == myTile.Y)
|
||||
{
|
||||
GotAway = true;
|
||||
Window.FireSound("missing");
|
||||
Object.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
base.Tick(deltaTime);
|
||||
|
||||
if (Path is null || Path.Length == 0)
|
||||
{
|
||||
CaughtTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
CaughtTimer = 10000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((SourcedImage)Object.Children[0]).Source = Environment.CurrentDirectory + "\\Resources\\CaughtCar.png";
|
||||
Caught = true;
|
||||
Window.FireSound("in_custody");
|
||||
}
|
||||
}
|
||||
if(Caught)
|
||||
{
|
||||
DoLaneBlockades();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,13 +48,14 @@ namespace CityGame.Classes.Entities
|
|||
if (pipe.Exploded > 0) return false;
|
||||
Explosion x = new Explosion();
|
||||
pipe.canvas.Children.Add(x);
|
||||
Canvas.SetLeft(x, pipe.GetParticleOrigin().X);
|
||||
Canvas.SetTop(x, pipe.GetParticleOrigin().Y);
|
||||
Canvas.SetLeft(x, pipe.GetParticleOrigin().X - 8);
|
||||
Canvas.SetTop(x, pipe.GetParticleOrigin().Y - 8);
|
||||
x.RotationOrigin = new Microsoft.Xna.Framework.Point(MainWindow.TileSize / 2);
|
||||
x.Size = 16;
|
||||
x.MaxParticleDistance = 32;
|
||||
x.Emit();
|
||||
pipe.Exploded = 1;
|
||||
pipe.image.Source = pipe.image.Source.Replace("ManholeCover", "ExplosionHole");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using CityGame.Classes.Rendering;
|
||||
using AStar.Collections.MultiDimensional;
|
||||
using CityGame.Classes.Rendering;
|
||||
using CityGame.Classes.Rendering.Particles;
|
||||
using CityGame.Classes.World;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OrpticonGameHelper.Classes.Elements;
|
||||
|
||||
|
|
@ -8,9 +10,9 @@ namespace CityGame.Classes.Entities
|
|||
public class GasPipe : Entity
|
||||
{
|
||||
public long Exploded { get; set; }
|
||||
public long LastSmoke { get; set; }
|
||||
public Image image { get; set; }
|
||||
public OCanvas canvas { get; set; }
|
||||
public Explosion Smoke { get; set; }
|
||||
public GasPipe()
|
||||
{
|
||||
if (MainWindow.random.Next(0, 2) == 0) Rotation += 180;
|
||||
|
|
@ -32,31 +34,36 @@ namespace CityGame.Classes.Entities
|
|||
if (Exploded > 0)
|
||||
{
|
||||
Exploded += deltaTime;
|
||||
if(Smoke is null)
|
||||
LastSmoke += deltaTime;
|
||||
if (LastSmoke > 0 && Exploded < 6500)
|
||||
{
|
||||
LastSmoke -= 500;
|
||||
CreateSmoke();
|
||||
}
|
||||
Tile tile = MainWindow.Grid[(int)(X / MainWindow.TileSize), (int)(Y / MainWindow.TileSize)];
|
||||
Car.OccupiedTilesFill.WeirdAddToList(tile, null);
|
||||
Car.OccupiedTilesFill2.WeirdAddToList(tile, null);
|
||||
}
|
||||
}
|
||||
void CreateSmoke()
|
||||
Explosion CreateSmoke()
|
||||
{
|
||||
Explosion smoke = new Explosion();
|
||||
smoke.DirectionTendency = MainWindow.Wind;
|
||||
smoke.DirectionVariance = 22.5f;
|
||||
smoke.MinColor = Color.LightGray;
|
||||
smoke.MaxColor = Color.DarkGray;
|
||||
smoke.MinColor = new Color(225, 225, 225);
|
||||
smoke.MaxColor = new Color(30, 30, 30);
|
||||
smoke.MaxParticleDistance = MainWindow.TileSize * 3;
|
||||
smoke.EmissionTime = 3;
|
||||
smoke.EmissionTime = 6;
|
||||
smoke.ParticleCountMin = 1;
|
||||
smoke.ParticleCountMax = 2;
|
||||
smoke.Size = 16;
|
||||
smoke.RotationOrigin = new Microsoft.Xna.Framework.Point(MainWindow.TileSize / 2);
|
||||
smoke.EaseMovement = false;
|
||||
Smoke = smoke;
|
||||
Object.Children.Add(Smoke);
|
||||
Canvas.SetLeft(Smoke, GetParticleOrigin().X);
|
||||
Canvas.SetTop(Smoke, GetParticleOrigin().Y);
|
||||
Object.Children.Add(smoke);
|
||||
Canvas.SetLeft(smoke, GetParticleOrigin().X - 8);
|
||||
Canvas.SetTop(smoke, GetParticleOrigin().Y - 8);
|
||||
smoke.Emit().ContinueWith(t => CreateSmoke());
|
||||
return smoke;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace CityGame.Classes.Entities
|
|||
public PoliceCar() : base()
|
||||
{
|
||||
grid = 2;
|
||||
mightSwitchLane = true;
|
||||
PCars.Add(this);
|
||||
Speed = 192;
|
||||
PNGFile = "PoliceCar.png";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using CityGame.Classes.Entities;
|
||||
using CityGame.Classes.World;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Numerics;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
|
|
@ -45,5 +48,10 @@ namespace CityGame
|
|||
float rotatedY = v.X * sin + v.Y * cos;
|
||||
return new System.Numerics.Vector2(rotatedX, rotatedY);
|
||||
}
|
||||
public static void WeirdAddToList<T1, T2>(this ConcurrentDictionary<T1, ConcurrentBag<T2>> list, T1 myTile, T2 car)
|
||||
{
|
||||
if(!list.ContainsKey(myTile)) list.TryAdd(myTile, new ConcurrentBag<T2>());
|
||||
list[myTile].Add(car);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -69,5 +69,11 @@ namespace CityGame.Classes.Rendering
|
|||
{ "#fc4141", "#4141fc" },
|
||||
{ "#b80000", "#0000b8" }
|
||||
};
|
||||
public static Dictionary<string, string> CarToCaughtCar = new Dictionary<string, string>()
|
||||
{
|
||||
{ "#ff0000", "#00ff00" },
|
||||
{ "#fc4141", "#41fc41" },
|
||||
{ "#b80000", "#00b800" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
namespace CityGame.Classes.Rendering
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace CityGame.Classes.Rendering
|
||||
{
|
||||
public struct IntPoint
|
||||
{
|
||||
|
|
@ -13,6 +15,14 @@
|
|||
{
|
||||
return new IntPoint(a.X + b.X, a.Y + b.Y);
|
||||
}
|
||||
public static IntPoint operator -(IntPoint a, Vector2 b)
|
||||
{
|
||||
return new IntPoint(a.X - (int)b.X, a.Y - (int)b.Y);
|
||||
}
|
||||
public static IntPoint operator +(IntPoint a, Vector2 b)
|
||||
{
|
||||
return new IntPoint(a.X + (int)b.X, a.Y + (int)b.Y);
|
||||
}
|
||||
public static IntPoint operator *(IntPoint a, int b)
|
||||
{
|
||||
return new IntPoint(a.X * b, a.Y * b);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
{
|
||||
public enum TileType
|
||||
{
|
||||
Invalid = -100,
|
||||
|
||||
Skyscraper = 100,
|
||||
House = 101,
|
||||
Helipad = 102,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using OrpticonGameHelper;
|
|||
using OrpticonGameHelper.Classes.Elements;
|
||||
using static CityGame.Classes.Entities.Car;
|
||||
using OrpticonGameHelper.Classes.Misc;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CityGame
|
||||
{
|
||||
|
|
@ -78,9 +79,60 @@ namespace CityGame
|
|||
internal static Canvas GameCanvas = new OCanvas();
|
||||
Canvas CameraCanvas = new OCanvas();
|
||||
Canvas UICanvas = new OCanvas();
|
||||
public static Tile FindNearestTile(Tile startPoint, short[,] pfGrid, params Tile[] targets)
|
||||
{
|
||||
var t = FindNearestTarget(new IntPoint(startPoint.X, startPoint.Y), pfGrid, targets.Select(x => new IntPoint(x.X, x.Y)).ToArray());
|
||||
if (t.X == -1 && t.Y == -1) return new Tile { Type = TileType.Invalid };
|
||||
return Grid[t.X, t.Y];
|
||||
}
|
||||
public static Tile FindNearestTile(Tile startPoint, short[,] pfGrid, TileType targetTile)
|
||||
{
|
||||
var targets = new List<Tile>();
|
||||
for (int i = 0; i < Grid.Length; i++)
|
||||
{
|
||||
if (Grid[i % Grid.GetLength(0), i / Grid.GetLength(0)].Type == targetTile) targets.Add(Grid[i % Grid.GetLength(0), i / Grid.GetLength(0)]);
|
||||
}
|
||||
return FindNearestTile(startPoint, pfGrid, targets.ToArray());
|
||||
}
|
||||
public static IntPoint FindNearestTarget(IntPoint startPoint, short[,] pfGrid, params IntPoint[] targets)
|
||||
{
|
||||
var directions = new Vector2[] { new Vector2(0, 1), new Vector2(1, 0), new Vector2(0, -1), new Vector2(-1, 0) };
|
||||
IntPoint result = new IntPoint(0, 0);
|
||||
bool resultFound = false;
|
||||
var searchers = new List<IntPoint>();
|
||||
var processed = new List<IntPoint>();
|
||||
searchers.Add(startPoint);
|
||||
while (!resultFound)
|
||||
{
|
||||
if (searchers.Count == 0) return new IntPoint(-1, -1);
|
||||
var s = searchers.ToList();
|
||||
searchers = new List<IntPoint>();
|
||||
foreach (var searcher in s)
|
||||
{
|
||||
if (targets.Contains(searcher))
|
||||
{
|
||||
result = searcher;
|
||||
resultFound = true;
|
||||
break;
|
||||
}
|
||||
foreach (var direction in directions)
|
||||
{
|
||||
var p = searcher + direction;
|
||||
if (p.X < 0 || p.Y < 0) continue;
|
||||
if (p.X >= pfGrid.GetLength(1)) continue;
|
||||
if (p.Y >= pfGrid.GetLength(0)) continue;
|
||||
if (processed.Contains(p)) continue;
|
||||
if (pfGrid[p.Y, p.X] == 0) continue;
|
||||
processed.Add(p);
|
||||
searchers.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the pathfinding grids of all grid numbers includes in the "grids" parameter
|
||||
/// Updates the pathfinding grids of all grid numbers included in the "grids" parameter
|
||||
/// </summary>
|
||||
/// <param name="tile">The tile to update</param>
|
||||
/// <param name="value">The value to update the tile to</param>
|
||||
|
|
@ -163,16 +215,18 @@ namespace CityGame
|
|||
ImageConverter.ChangeColor("Error", "ErrorRed", new Dictionary<string, string> { { "#000000", "#ff0000" } });
|
||||
ImageConverter.ChangeColor("Car", "NPCCar", ColorConversionMaps.CarToNPCCar);
|
||||
ImageConverter.ChangeColor("Car", "PoliceCar", ColorConversionMaps.CarToPoliceCar);
|
||||
ImageConverter.ChangeColor("Car", "CaughtCar", ColorConversionMaps.CarToCaughtCar);
|
||||
ImageConverter.ChangeColor("Car", "CriminalCar", new Dictionary<string, string>());
|
||||
#endregion
|
||||
|
||||
LoadableContent.Add(ShaderLoader.Create());
|
||||
|
||||
int seed = 8;
|
||||
int seed = (int)(DateTime.Now.Ticks % int.MaxValue);
|
||||
|
||||
Noise.Seed = seed;
|
||||
|
||||
int mapHeight = 100;
|
||||
int mapWidth = 200;
|
||||
int mapHeight = 50;
|
||||
int mapWidth = 50;
|
||||
|
||||
float[,] lakeMap = Noise.Calc2D(mapWidth, mapHeight, 0.05f);
|
||||
|
||||
|
|
@ -194,6 +248,7 @@ namespace CityGame
|
|||
int minBlockWidth = 3;
|
||||
|
||||
int NPCCount = (int)Math.Ceiling(mapHeight * mapWidth / 100f);
|
||||
int CriminalCount = 1;
|
||||
//NPCCount = 1;
|
||||
//NPCCount = 0;
|
||||
//NPCCount /= 2;
|
||||
|
|
@ -310,6 +365,22 @@ namespace CityGame
|
|||
if (IntermediateGrid[x, y].Type == TileType.Park) changeTo = TileType.Path;
|
||||
if (x < doubleWidth - 1 && IntermediateGrid[x + 1, y].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
||||
if (y < doubleHeight - 1 && IntermediateGrid[x, y + 1].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
||||
var type = IntermediateGrid[x, y].Type;
|
||||
if (type == TileType.Bridge) bridgeTiles.Add(IntermediateGrid[x, y]);
|
||||
if (type == TileType.Road) roadTiles.Add(IntermediateGrid[x, y]);
|
||||
bool walkable = ((int)type) / 100 == 4;
|
||||
Grids[2][y, x] = (short)(walkable ? 1 : 0);
|
||||
if (type == TileType.Path) walkable = false;
|
||||
Grids[1][y, x] = (short)(walkable ? 1 : 0);
|
||||
}
|
||||
}
|
||||
bool checkBridges = true;
|
||||
if (checkBridges)
|
||||
{
|
||||
foreach (var tile in bridgeTiles)
|
||||
{
|
||||
IntPoint road = FindNearestTarget(new IntPoint(tile.X, tile.Y), Grids[1], roadTiles.Select(x => new IntPoint(x.X, x.Y)).ToArray());
|
||||
if (road.X == -1 && road.Y == -1) IntermediateGrid[tile.X, tile.Y].Type = TileType.Lake;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,9 +426,21 @@ namespace CityGame
|
|||
startPoint += step;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
for (int y = 0; y < doubleHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < doubleWidth; x++)
|
||||
{
|
||||
var type = IntermediateGrid[x, y].Type;
|
||||
bool walkable = ((int)type) / 100 == 4;
|
||||
Grids[2][y, x] = (short)(walkable ? 1 : 0);
|
||||
if (type == TileType.Path) walkable = false;
|
||||
Grids[1][y, x] = (short)(walkable ? 1 : 0);
|
||||
if (type == TileType.Road || type == TileType.Bridge) npcWalkable.Add(IntermediateGrid[x, y]);
|
||||
}
|
||||
}
|
||||
|
||||
Grid = IntermediateGrid;
|
||||
#endregion
|
||||
//for(int y = 0; y < mapHeight; y++)
|
||||
//{
|
||||
// for(int x = 0; x < mapWidth; x++)
|
||||
|
|
@ -400,20 +483,6 @@ namespace CityGame
|
|||
GameCanvas.Children.Add(image);
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < doubleHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < doubleWidth; x++)
|
||||
{
|
||||
var type = IntermediateGrid[x, y].Type;
|
||||
bool walkable = ((int)type) / 100 == 4;
|
||||
Grids[2][y, x] = (short)(walkable ? 1 : 0);
|
||||
if (type == TileType.Path) walkable = false;
|
||||
Grids[1][y, x] = (short)(walkable ? 1 : 0);
|
||||
if (type == TileType.Bridge) bridgeTiles.Add(IntermediateGrid[x, y]);
|
||||
if (type == TileType.Road) roadTiles.Add(IntermediateGrid[x, y]);
|
||||
if (type == TileType.Road || type == TileType.Bridge) npcWalkable.Add(IntermediateGrid[x, y]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kvp in Grids) WorldGrids.Add(kvp.Key, new WorldGrid(kvp.Value));
|
||||
InstantiatePathfinders();
|
||||
|
|
@ -436,7 +505,7 @@ namespace CityGame
|
|||
Entities.Add(new PoliceCar { X = x, Y = y });
|
||||
}
|
||||
var roads = SourcedImage.GetObjectsBySourceFile("Road1.png", "Road2.png", "Road2c.png", "Road3c.png", "Road4c.png");
|
||||
var pipeCount = NPCCount;
|
||||
var pipeCount = NPCCount * 2;
|
||||
var pipeRoads = roads.OrderBy(x => random.Next(0, roads.Count)).Take(pipeCount).ToArray();
|
||||
foreach (Image image in pipeRoads)
|
||||
{
|
||||
|
|
@ -464,19 +533,35 @@ namespace CityGame
|
|||
|
||||
Entities.Add(car);
|
||||
}
|
||||
for (int n = 0; n < CriminalCount; n++)
|
||||
{
|
||||
CriminalCar car = new CriminalCar();
|
||||
bool foundStartPoint = false;
|
||||
Tile startTile = Grid[0, 0];
|
||||
while(!foundStartPoint)
|
||||
{
|
||||
startTile = npcWalkable[random.Next(0, npcWalkable.Count)];
|
||||
if (startTile.X > doubleWidth / 3 && startTile.Y > doubleHeight / 3 && startTile.X < doubleWidth / 3 * 2 && startTile.Y < doubleHeight / 3 * 2) foundStartPoint = true;
|
||||
}
|
||||
|
||||
car.Point = new Point(startTile.X, startTile.Y);
|
||||
Entities.Add(car);
|
||||
}
|
||||
|
||||
SoundEffectListener = new AudioListener { Position = new Vector3(0, 0, 100) };
|
||||
|
||||
Show();
|
||||
}
|
||||
int swv;
|
||||
public bool PauseEntities = true;
|
||||
protected override Color SkyColor(long SpeedFactor)
|
||||
{
|
||||
return base.SkyColor(180);
|
||||
return Color.Gray;
|
||||
}
|
||||
protected override void Update(GameTime time)
|
||||
{
|
||||
MouseState state = Mouse.GetState();
|
||||
KeyboardState kstate = Keyboard.GetState();
|
||||
|
||||
if (state.MiddleButton == ButtonState.Pressed)
|
||||
{
|
||||
|
|
@ -522,12 +607,15 @@ namespace CityGame
|
|||
Selected.RunAction(select);
|
||||
}
|
||||
}
|
||||
if (kstate.IsKeyDown(Keys.Space)) PauseEntities = !PauseEntities;
|
||||
PauseParticles = PauseEntities;
|
||||
|
||||
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
foreach (Entity entity in Entities)
|
||||
{
|
||||
long deltaTime = milliseconds - entity.Time;
|
||||
deltaTime = (long)time.ElapsedGameTime.TotalMilliseconds;
|
||||
if (PauseEntities) deltaTime = 0;
|
||||
entity.Time = milliseconds;
|
||||
entity.Tick(deltaTime);
|
||||
entity.BaseTick(deltaTime);
|
||||
|
|
@ -542,9 +630,9 @@ namespace CityGame
|
|||
Canvas.SetTop(entity.Object, entity.VisualY);
|
||||
}
|
||||
Car.OccupiedTiles = Car.OccupiedTilesFill;
|
||||
Car.OccupiedTilesFill = new System.Collections.Concurrent.ConcurrentDictionary<Tile, Car>();
|
||||
Car.OccupiedTilesFill = new System.Collections.Concurrent.ConcurrentDictionary<Tile, System.Collections.Concurrent.ConcurrentBag<Car>>();
|
||||
Car.OccupiedTiles2 = Car.OccupiedTilesFill2;
|
||||
Car.OccupiedTilesFill2 = new System.Collections.Concurrent.ConcurrentDictionary<Tile, Car>();
|
||||
Car.OccupiedTilesFill2 = new System.Collections.Concurrent.ConcurrentDictionary<Tile, System.Collections.Concurrent.ConcurrentBag<Car>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
CityGame/Resources/Audio/in_custody0.mp3
Normal file
BIN
CityGame/Resources/Audio/in_custody0.mp3
Normal file
Binary file not shown.
BIN
CityGame/Resources/Audio/missing0.mp3
Normal file
BIN
CityGame/Resources/Audio/missing0.mp3
Normal file
Binary file not shown.
BIN
CityGame/Resources/Audio/missing1.mp3
Normal file
BIN
CityGame/Resources/Audio/missing1.mp3
Normal file
Binary file not shown.
BIN
CityGame/Resources/ExplosionHole.png
Normal file
BIN
CityGame/Resources/ExplosionHole.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 B |
Loading…
Add table
Add a link
Reference in a new issue