public void ProcessExpedition(ExpeditionData data, uint currentRoundNumber) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (currentRoundNumber < data.StartingRound || currentRoundNumber > data.EndingRound) { return; // already processed } decimal militaryPower = this.CalculateCurrentExpeditionPower(data, PowerType.Military); // increase defense and range decimal sciencePower = this.CalculateCurrentExpeditionPower(data, PowerType.Science); // increases rare findings per turn decimal laborPower = this.CalculateCurrentExpeditionPower(data, PowerType.Labour); // increase range & findings per turn decimal rangeDelta = this.CalculateRangeIncrease(militaryPower, laborPower); data.CurrentRange += rangeDelta; // calculate new findings - depending on passing turn and total range var explorableResources = ResourceInfo.KnownResources.Where(r => r.FindingProbability > 0.0m && r.BaseFindSize > 0.0m); foreach (var explorableResource in explorableResources) { var finding = this.CalculateFindingSize(explorableResource, militaryPower, sciencePower, laborPower, data.CurrentRange); data.DiscoveredResources.Add(finding); } // calculate endangerment (if any) depending on passing turn (& range) decimal dangerLevel = this.CalculateDangerLevel(data.CurrentRange, data.StartingRound, currentRoundNumber); // fight var enemyForces = this.GenerateOpposingForce(dangerLevel); if (enemyForces.AnyOne()) { FightOutcome outcome = this._fightLogic.CalculateFight(enemyForces, data.RemainingUnits); if (outcome.JunkProduced.Value > 0) { data.DiscoveredResources.Add(outcome.JunkProduced); } // reduce units if (outcome.RazedDefenders.AnyOne()) { data.RemainingUnits.Substract(outcome.RazedDefenders); } } // left at least one worker and stop expedition at that point if (!data.RemainingUnits.AnyOne()) { this._unitLogic.AddWorkers(data.RemainingUnits, 1); data.EndingRound = currentRoundNumber; } }
private decimal CalculateCurrentExpeditionPower(ExpeditionData data, PowerType powerType) { switch (powerType) { case PowerType.Military: return(this._unitLogic.GetMilitaryPower(data.RemainingUnits, MilitarySide.Both)); case PowerType.Science: return(this._unitLogic.GetSciencePower(data.RemainingUnits)); case PowerType.Labour: return(this._unitLogic.GetLabourPower(data.RemainingUnits)); case PowerType.Electric: throw new NotSupportedException("Power.Electric does not apply to Expedition calculations."); default: throw new ArgumentOutOfRangeException(nameof(powerType), powerType, null); } }