예제 #1
0
        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));
        }
예제 #2
0
        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);
        }