Commit Description:
Change image for each contract.
Commit Description:
Change image for each contract.
File last commit:
Show/Diff file:
Action:
isometric-park-fna/Engines/Spawners/ContractSpawner.cs
139 lines | 4.9 KiB | text/x-csharp | CSharpLexer
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Encompass;
using JM.LinqFaster;
using TraceryNet;
using isometricparkfna.Messages;
using isometricparkfna.Components;
namespace isometricparkfna.Spawners {
[Receives(typeof(SpawnContractMessage))]
[Reads(typeof(AreaComponent), typeof(ContractStatusComponent))]
class ContractSpawner : Spawner<SpawnContractMessage>
{
private Random random_generator;
public const int DEFAULT_MIN_SQUARES = 10;
public const int DEFAULT_SQUARES = 25;
public const int CONTRACT_MINIMUM = 50;
public const int CONTRACT_MAXIMUM = 250;
private int MapWidth;
private int MapHeight;
private Simulation simulation;
private Grammar grammar;
public ContractSpawner(int mapWidth, int mapHeight, Simulation simulation, Grammar grammar)
{
this.random_generator = new Random();
this.MapWidth = mapWidth;
this.MapHeight = mapHeight;
this.simulation = simulation;
this.grammar = grammar;
}
private Vector2[] CreateArea(int start_x, int start_y, int max_size, HashSet<Vector2> occupied_squares)
{
var squares = new List<Vector2>(new[] { new Vector2(start_x, start_y) });
var squares_to_add = new HashSet<Vector2>();
var attempts = 0;
var maxAttempts = max_size * 10;
while (squares.Count < max_size)
{
foreach (var square in squares)
{
foreach (var new_square in new[] {new Vector2(square.X + 1, square.Y),
new Vector2(square.X, square.Y + 1),
new Vector2(square.X - 1, square.Y),
new Vector2(square.X, square.Y - 1)})
{
if (random_generator.NextDouble() < 0.5
&& !squares.Contains(new_square)
&& !occupied_squares.Contains(new_square)
&& MathUtils.Between(new_square.X, 0, this.MapWidth)
&& MathUtils.Between(new_square.Y, 0, this.MapHeight)
)
{
squares_to_add.Add(new_square);
}
attempts += 1;
}
}
var remaining = max_size - squares.Count;
squares.AddRange(squares_to_add.Take(remaining));
squares_to_add.Clear();
if (attempts >= maxAttempts && squares.Count < max_size)
{
Logging.Warning(string.Format("Failed to generate enough squares. {0} were requested, only {1} were found ({2} attempts)", max_size, squares.Count, attempts));
break;
}
}
return squares.ToArray();
}
protected override void Spawn(in SpawnContractMessage message)
{
//for now:
var occupied = new List<Vector2>();
foreach (var (entity, status) in ReadEntities<AreaComponent>().SelectWhereF((e) => (e, GetComponent<ContractStatusComponent>(e)),
(e) => (e.Item2.status != ContractStatus.Expired))
)
{
var entitySquares = GetComponent<AreaComponent>(entity).squares;
occupied.AddRange(entitySquares);
}
var start_x = random_generator.Next(0, 50);
var start_y = random_generator.Next(0, 50);
var image_index = random_generator.Next(1, 7);
int max_squares = (message.max_squares == 0) ? DEFAULT_SQUARES : message.max_squares;
int min_squares = (message.min_squares == null) ? DEFAULT_MIN_SQUARES : (int)message.min_squares;
Vector2[] squares = (message.squares == null) ? CreateArea(start_x, start_y, max_squares, new HashSet<Vector2>(occupied)) : message.squares;
if (squares.Length > min_squares)
{
var contract = CreateEntity();
int contract_amount = random_generator.Next(CONTRACT_MINIMUM, CONTRACT_MAXIMUM);
var deltaTrees = random_generator.Next(-20, 3);
// AddComponent
AddComponent(contract, new AreaComponent { squares = squares });
AddComponent(contract, new NameComponent { DisplayName = this.grammar.Flatten(message.name) });
AddComponent(contract, new SelectedComponent { selected = false });
AddComponent(contract, new ContractStatusComponent { status = ContractStatus.Proposed, date = this.simulation.DateTime });
AddComponent(contract, new TreeDeltaComponent { deltaTrees = deltaTrees });
AddComponent(contract, new BudgetLineComponent
{
category = "Contracts",
//Round to the nearest $5
amount = (decimal)((contract_amount / 5) * 5)
});
AddComponent(contract, new ImageComponent {ImageIndex = image_index});
AddComponent(contract, new WindowTypeComponent { type = Window.Contract});
AddComponent(contract, new VisibilityComponent { visible = false});
}
}
}
}