using System; using System.Linq; using Encompass; using isometricparkfna.Messages; using isometricparkfna.Components; namespace isometricparkfna.Engines { [Receives(typeof(GameRateMessage), typeof(TogglePauseMessage))] [Sends(typeof(SpawnContractMessage), typeof(TickMessage))] [Reads(typeof(AreaComponent), typeof(BudgetComponent), typeof(BudgetLineComponent), typeof(ContractStatusComponent), typeof(TreeDeltaComponent))] [Writes(typeof(BudgetComponent))] public class SimulationBridgeEngine : Engine { public Simulation simulation; private int ticksToSend; private Random random_generator; public SimulationBridgeEngine(Simulation simulation) { this.simulation = simulation; this.random_generator = new Random(); } public int addTick() { this.ticksToSend++; return ticksToSend; } public override void Update(double dt) { foreach (ref readonly var entity in ReadEntities()) { ref readonly var budgetComponent = ref GetComponent(entity); SetComponent(entity, new BudgetComponent { currentBudget = this.simulation.latestBudget, priorBudget = this.simulation.previousBudget }); } foreach (ref readonly var message in ReadMessages()) { this.simulation.paused = message.paused; if (message.rate != null) { this.simulation.setRate(message.rate ?? 0); } } foreach (ref readonly var message in ReadMessages()) { this.simulation.paused = !this.simulation.paused; } decimal new_contract_amount = 0M; foreach (ref readonly var entity in ReadEntities()) { ref readonly var budgetComponent = ref GetComponent(entity); var status = GetComponent(entity).status; // SetComponent(entity, new BudgetComponent{currentBudget = this.simulation.latestBudget, // priorBudget = this.simulation.previousBudget}); switch (budgetComponent.category) { case "Contracts": if (status == ContractStatus.Accepted) { new_contract_amount += budgetComponent.amount; } break; } } if (this.ticksToSend > 0) { Logging.Trace(String.Format("{0} ticks to send in update", this.ticksToSend)); } for (int i = ticksToSend; i > 0; i--) { SendMessage(new TickMessage { }); //For now: SendMessage(new SpawnContractMessage { //max_squares = 100, name = string.Format("#logging_company.capitalizeAll# {0}", this.simulation.DateTime.ToShortDateString()) }); foreach (ref readonly var entity in ReadEntities()) { var status = GetComponent(entity).status; var area = GetComponent(entity); var delta = GetComponent(entity); if (status == ContractStatus.Accepted) { var removed = 0; var tree_squares = area.squares.Where((square) => simulation.map.cells[(int)square.X][(int)square.Y].hasTree); var to_remove = -delta.deltaTrees; //calculate the probability in order to get the expected number of removed trees var expected = to_remove; var trials = tree_squares.Count(); double probability = ((double)expected / (double)trials) / 12; foreach (var square in tree_squares) { var cell = simulation.map.cells[(int)square.X][(int)square.Y]; if (cell.hasTree && random_generator.NextDouble() < probability) { cell.removeTree(); removed++; } if (removed >= to_remove) { // break; } } } } } this.ticksToSend = 0; simulation.contracts = new_contract_amount; } } }