public void InitServices() { this.services = new ServiceCollection() .AddLogging() .AddSingleton <IDiceUtility, MockDice>() // Always rolls sixes on d6; always rolls 99 on d100 .BuildServiceProvider(); this.weapon = new BeamBatterySystem(3, "(All arcs)"); this.weaponAllocation = new GameUnitFireAllocation(); this.distanceGraph = new FormationDistanceGraph(); this.totalDummy = new TestDummyActor(this.services); this.phaseDummy = new TestDummyPhaseActor(this.services); this.engine = new EventHandlingEngine(); this.phaseEvent = new FiringPhaseEvent(1, 1, this.distanceGraph) as GamePhaseEvent; this.attackEvent = new WeaponAttackEvent(new TargetingData(), new AttackData(this.weapon, this.weaponAllocation)); }
protected override IList <GameEvent> ReceiveAttackEvent(GameEvent arg) { var result = new List <GameEvent>(); var evt = arg as AttackEvent ?? throw ReceiverArgumentMismatch(nameof(arg), arg.GetType(), MethodBase.GetCurrentMethod().Name, typeof(AttackEvent)); // Unit can act if: // a) Attack is assigned to this Unit's Formation // b) Attack has a valid reference to a target Formation if (evt.TargetingData == null || evt.TargetingData.Source.FormationId != this.unitFormationInfo.FormationId) { return(null); } var unit = this.unitFormationInfo.GetUnitReference(); var applicableWeaponAllocations = new List <GameUnitFireAllocation>(); foreach (var allocation in unit.FireAllocation.Where(a => a.Volley == evt.Volley)) { if (allocation.Priority.ToLowerInvariant() == evt.TargetingData.FirePriority.ToLowerInvariant()) { if ((allocation.FireMode ?? TargetingData.DefaultFireType).ToLowerInvariant() == evt.TargetingData.FireType.ToLowerInvariant()) { applicableWeaponAllocations.Add(allocation); } } } foreach (var allocation in applicableWeaponAllocations) { if (allocation.FireConId != 0) { var allocatedFireCon = unit.Electronics.Where(s => s.Id == allocation.FireConId).FirstOrDefault() ?? throw new InvalidOperationException("FireAllocation instance has an invalid System ID assigned for its Fire Control"); if (allocatedFireCon.Status != UnitSystemStatus.Operational) { var statusMsg = $"[{this.UnitId}]{this.UnitName} fire allocation {allocation.ToString()} has no effect -- " + $"fire control [{allocatedFireCon.Id}]{allocatedFireCon.SystemName} is {allocatedFireCon.Status.ToString()}"; this.Logger.LogInformation(statusMsg); result.Add(new UnitStatusEvent() { Description = $"UnitStatus: [{this.UnitId}]{this.UnitName}", Message = statusMsg, Exchange = evt.Exchange, Volley = evt.Volley }); continue; } } // TODO: Multiple fire allocations with the same FireCon in the same Volley should be illegal. TargetingData newTargeting = TargetingData.Clone(evt.TargetingData); newTargeting.Target.UnitActor = this; newTargeting.TargetUnitPercentileRoll = this.DiceUtility.RollPercentile(); foreach (var weaponId in allocation.WeaponIDs) { var weapon = unit.Weapons.Where(w => w.Id == weaponId).FirstOrDefault(); if (weapon.CanFire()) { AttackData attackData = new AttackData(weapon, allocation); WeaponAttackEvent weaponAttack = new WeaponAttackEvent(newTargeting, attackData, percentileRoll: newTargeting.TargetUnitPercentileRoll, exchange: evt.Exchange, volley: evt.Volley); result.Add(weaponAttack); } } } return(result); }