private void UpdatePlanets(Duration time) { foreach (var planet in Galaxy.Planets) { if (planet.Settlement != null) { BuildStuff(planet, time); UpdatePopulation(planet, time); } } void BuildStuff(Planet populatedPlanet, Duration time) { Settlement settlement = populatedPlanet.Settlement !; var resources = time.YearFraction * settlement.Population.Civilians / 1000; var output = settlement.BuildQueue.Build((int)resources); resources -= output.ConsumedResources; foreach (var item in output.CompletedItems) { item.ItemToBuild.Complete(Galaxy, populatedPlanet, settlement, msg => Notify(settlement.OwnerId, msg)); } } void UpdatePopulation(Planet populatedPlanet, Duration time) { Settlement settlement = populatedPlanet.Settlement !; Player? owner = GetPlayer(settlement.OwnerId); if (owner != null) { settlement.Population += Rules.CalculatePopulationGrowth(populatedPlanet, owner, time); } } }
private void ExecuteAssaultOrders() { var assaultGroups = Galaxy.Fleets .Where(f => f.Passengers.Marines > 0) .Where(f => f.Waypoints?.Any() != true) .GroupBy(f => f.Position) .ToArray(); foreach (var group in assaultGroups) { var location = group.Key; var planet = Galaxy.Planets.SingleOrDefault(p => p.Position == location); if (planet?.Settlement != null) { DeployMarines(planet, group); } } void DeployMarines(Planet planet, IEnumerable <Fleet> fleets) { if (planet.Settlement == null) { return; } var assaultGroups = fleets .Where(f => f.OwnerId != planet.Settlement.OwnerId) .GroupBy(f => f.OwnerId); // 1) Unload reinforcements if attack is imminent if (assaultGroups.Any()) { var reinforcements = fleets.Where(f => f.OwnerId == planet.Settlement.OwnerId); foreach (var def in reinforcements) { planet.Settlement.Population += def.Passengers; Galaxy.Fleets.Remove(def); } } // 2) Attackers attack foreach (var group in assaultGroups) { int attackerId = group.Key; var assaultForce = new Population(); foreach (var att in group) { assaultForce += att.Passengers; Galaxy.Fleets.Remove(att); } ResolveGroundCombat(planet, assaultForce, attackerId); } } void ResolveGroundCombat(Planet planet, Population assaultForce, int attackerId) { Settlement settlement = planet.Settlement !; Player defender = GetPlayer(settlement.OwnerId) !; Player attacker = GetPlayer(attackerId) !; var defenseForce = settlement.Population; defenseForce.Civilians /= 10; var defenseValue = ForceValue(defenseForce); var attackValue = ForceValue(assaultForce); if (attackValue > defenseValue) { var killRate = 0.75 * defenseValue / attackValue; assaultForce -= CalculateCasualties(assaultForce, killRate); settlement.Population -= defenseForce; settlement.Population += assaultForce; settlement.OwnerId = attacker.Id; var defenderMsg = $"Our settlement on Planet #{planet.Id} was overrun by {attacker.Name} forces."; Notify(defender.Id, defenderMsg, Mood.Bad); var attackerMsg = $"We have conquered the {defender.Name} settlement on Planet #{planet.Id}"; Notify(attacker.Id, attackerMsg, Mood.Good); // TODO: Add history entry for defeated player? } else { var killRate = 0.75 * attackValue / defenseValue; settlement.Population -= CalculateCasualties(defenseForce, killRate); var defenderMsg = $"We have successfully defended our settlement on Planet #{planet.Id} from attacking {attacker.Name} forces."; Notify(defender.Id, defenderMsg, Mood.Good); var attackerMsg = $"Our assault on the {defender.Name} settlement on Planet #{planet.Id} failed."; Notify(attacker.Id, attackerMsg, Mood.Bad); }