Пример #1
0
        public override bool IsActionEffectAvailable()
        {
            bool result = false;

            if (Combat.AttackStep == CombatStep.Attack)
            {
                if (Combat.ChosenWeapon.GetType() == typeof(Ship.PrimaryWeaponClass))
                {
                    if (Combat.Attacker.GetType() != typeof(Ship.TIEFighter.Howlrunner))
                    {
                        Ship.GenericShip Howlrunner = null;
                        foreach (var friendlyShip in Combat.Attacker.Owner.Ships)
                        {
                            if (friendlyShip.Value.GetType() == typeof(Ship.TIEFighter.Howlrunner))
                            {
                                Howlrunner = friendlyShip.Value;
                                break;
                            }
                        }
                        if (Howlrunner != null)
                        {
                            Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(Howlrunner, Combat.Attacker);
                            if (positionInfo.Range == 1)
                            {
                                result = true;
                            }
                        }
                    }
                }
            }

            return(result);
        }
Пример #2
0
        public override bool AnotherShipCanBeSelected(Ship.GenericShip anotherShip)
        {
            bool result = false;

            if (isEnemyAllowed)
            {
                Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Selection.ThisShip, anotherShip);
                int range = distanceInfo.Range;

                if ((range >= minRange) && (range <= maxRange))
                {
                    Game.UI.HideNextButton();
                    TargetShip = anotherShip;
                    MovementTemplates.ShowRange(Selection.ThisShip, anotherShip);
                    finishAction.Invoke();
                    Phases.FinishSubPhase(this.GetType());
                    callBack();
                }
                else
                {
                    Messages.ShowErrorToHuman("Ship is outside of range");
                    RevertSubPhase();
                }
            }
            else
            {
                Messages.ShowErrorToHuman("Enemy ship cannot be selected");
                RevertSubPhase();
            }
            return(result);
        }
Пример #3
0
        public override bool IsActionEffectAvailable()
        {
            bool result = false;

            if (Combat.AttackStep == (RerollType == RerollTypeEnum.AttackDice ? CombatStep.Attack : CombatStep.Defence))
            {
                var friendlyShip = RerollType == RerollTypeEnum.AttackDice ? Combat.Attacker : Combat.Defender;

                if (CanReRollWithWeaponClass())
                {
                    if (CanUseOwnAbility || friendlyShip != Host)
                    {
                        if (friendlyShip.Owner == Host.Owner)
                        {
                            Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(Host, friendlyShip);
                            if (positionInfo.Range <= MaxFriendlyShipRange)
                            {
                                result = true;
                            }
                        }
                    }
                }
            }

            return(result);
        }
Пример #4
0
        public void CanPerformAttack(ref bool result, List <string> stringList)
        {
            bool shipIsProtected = false;

            if (Selection.AnotherShip.ShipId != HostShip.ShipId)
            {
                if (Selection.AnotherShip.Owner.PlayerNo == HostShip.Owner.PlayerNo)
                {
                    Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(Selection.AnotherShip, HostShip);
                    if (positionInfo.Range <= 1)
                    {
                        if (!Selection.ThisShip.ShipsBumped.Contains(HostShip))
                        {
                            if (Combat.ChosenWeapon.IsShotAvailable(HostShip))
                            {
                                shipIsProtected = true;
                            }
                        }
                    }
                }
            }

            if (shipIsProtected)
            {
                if (Roster.GetPlayer(Phases.CurrentPhasePlayer).GetType() == typeof(Players.HumanPlayer))
                {
                    stringList.Add("Biggs DarkLighter: You cannot attack target ship");
                }
                result = false;
            }
        }
Пример #5
0
        public void CanPerformTargetLock(ref bool result, GenericShip attacker, GenericShip defender)
        {
            bool abilityIsActive = false;

            if (defender.ShipId != HostShip.ShipId)
            {
                if (defender.Owner.PlayerNo == HostShip.Owner.PlayerNo)
                {
                    Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(attacker, HostShip);
                    if (positionInfo.Range >= attacker.TargetLockMinRange && positionInfo.Range <= attacker.TargetLockMaxRange)
                    {
                        abilityIsActive = true;
                    }
                }
            }

            if (abilityIsActive)
            {
                if (Roster.GetPlayer(Phases.CurrentPhasePlayer).GetType() == typeof(Players.HumanPlayer))
                {
                    Messages.ShowErrorToHuman("Captain Kagi: You cannot target lock that ship");
                }
                result = false;
            }
        }
Пример #6
0
            public void CanPerformAttack(ref bool result, GenericShip attacker, GenericShip defender)
            {
                bool abilityIsActive = false;

                if (defender.ShipId != this.ShipId)
                {
                    if (defender.Owner.PlayerNo == this.Owner.PlayerNo)
                    {
                        Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(defender, this);
                        if (positionInfo.Range <= 1)
                        {
                            if (!attacker.ShipsBumped.Contains(this))
                            {
                                if (Combat.ChosenWeapon.IsShotAvailable(this))
                                {
                                    abilityIsActive = true;
                                }
                            }
                        }
                    }
                }

                if (abilityIsActive)
                {
                    if (Roster.GetPlayer(Phases.CurrentPhasePlayer).GetType() == typeof(Players.HumanPlayer))
                    {
                        Messages.ShowErrorToHuman("Biggs DarkLighter: You cannot attack target ship");
                    }
                    result = false;
                }
            }
Пример #7
0
        private List <Ship.GenericShip> GenerateListOfExceptions()
        {
            List <Ship.GenericShip> exceptShips = new List <Ship.GenericShip>();

            if (Selection.ThisShip != null)
            {
                if (targetsAllowed.Contains(TargetTypes.This))
                {
                    exceptShips.Add(Selection.ThisShip);
                }

                foreach (var ship in Roster.AllShips)
                {
                    if ((targetsAllowed.Contains(TargetTypes.OtherFriendly) && ship.Value.Owner.PlayerNo == Selection.ThisShip.Owner.PlayerNo) || (targetsAllowed.Contains(TargetTypes.Enemy) && ship.Value.Owner.PlayerNo != Selection.ThisShip.Owner.PlayerNo))
                    {
                        Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Selection.ThisShip, ship.Value);
                        if ((distanceInfo.Range < minRange) || (distanceInfo.Range > maxRange))
                        {
                            exceptShips.Add(ship.Value);
                        }
                    }
                }
            }

            return(exceptShips);
        }
Пример #8
0
        private void SaturationSalvoDamage(object sender, System.EventArgs e)
        {
            var allShips = Roster.AllShips.Select(x => x.Value).ToList();

            foreach (GenericShip ship in allShips)
            {
                if (ship.ShipId == Combat.Defender.ShipId)
                {
                    continue;
                }

                Board.ShipDistanceInformation shotInfo = new Board.ShipDistanceInformation(Combat.Defender, ship);

                if (shotInfo.Range == 1 && ship.Agility < (Combat.ChosenWeapon as GenericUpgrade).Cost)
                {
                    Triggers.RegisterTrigger(new Trigger()
                    {
                        Name         = ship.ShipId + ": Saturation Salvo Damage Check",
                        TriggerType  = TriggerTypes.OnAbilityDirect,
                        TriggerOwner = ship.Owner.PlayerNo,
                        EventHandler = StartSaturationSalvoCheckSubPhase,
                        Sender       = ship
                    });
                }
            }

            Triggers.ResolveTriggers(TriggerTypes.OnAbilityDirect, Triggers.FinishTrigger);
        }
Пример #9
0
 private bool FilterTargets(GenericShip ship)
 {
     //Filter other friendly ships range 1
     Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Host, ship);
     return(ship.Owner.PlayerNo != Host.Owner.PlayerNo &&
            ship != Host &&
            distanceInfo.Range == 1);
 }
Пример #10
0
        public virtual bool IsShotAvailable(Ship.GenericShip targetShip)
        {
            bool result = true;

            if (isDiscarded)
            {
                return(false);
            }

            int range;

            if (!CanShootOutsideArc)
            {
                Board.ShipShotDistanceInformation shotInfo = new Board.ShipShotDistanceInformation(Host, targetShip, this);
                range = shotInfo.Range;

                if (!shotInfo.InShotAngle)
                {
                    return(false);
                }
            }
            else
            {
                Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Host, targetShip);
                range = distanceInfo.Range;
            }

            if (range < MinRange)
            {
                return(false);
            }
            if (range > MaxRange)
            {
                return(false);
            }

            if (RequiresTargetLockOnTargetToShoot)
            {
                if (!Actions.HasTargetLockOn(Host, targetShip))
                {
                    return(false);
                }
            }

            if (RequiresFocusToShoot)
            {
                if (!Host.HasToken(typeof(Tokens.FocusToken)))
                {
                    return(false);
                }
            }

            return(result);
        }
Пример #11
0
 private void CheckDrawTheirFireAbility()
 {
     if (Combat.Defender.Owner.PlayerNo == Host.Owner.PlayerNo && Combat.Defender.ShipId != Host.ShipId)
     {
         Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Combat.Defender, Host);
         if (distanceInfo.Range == 1 && Combat.DiceRollAttack.CriticalSuccesses > 0)
         {
             RegisterDrawTheirFireAbility();
         }
     }
 }
Пример #12
0
 private void RegisterJanOrsAbility()
 {
     if (Combat.Attacker.Owner.PlayerNo == HostShip.Owner.PlayerNo && Combat.Attacker.ShipId != HostShip.ShipId)
     {
         Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Combat.Attacker, HostShip);
         if (distanceInfo.Range < 4)
         {
             RegisterAbilityTrigger(TriggerTypes.OnAttackStart, AskJanOrsAbility);
         }
     }
 }
Пример #13
0
 private void CheckSelflessnessAbility()
 {
     if (Combat.Defender.Owner.PlayerNo == HostShip.Owner.PlayerNo && Combat.Defender.ShipId != HostShip.ShipId)
     {
         Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Combat.Defender, HostShip);
         if (distanceInfo.Range == 1 && Combat.DiceRollAttack.RegularSuccesses > 0)
         {
             RegisterAbilityTrigger(TriggerTypes.OnTryDamagePrevention, UseSelflessnessAbility);
         }
     }
 }
Пример #14
0
 private void CheckAbility(GenericShip ship)
 {
     if (!IsAbilityUsed && ship.Owner.PlayerNo == HostShip.Owner.PlayerNo && ship.AssignedManeuver.ColorComplexity == Movement.ManeuverColor.White)
     {
         Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(HostShip, ship);
         if (distanceInfo.Range < 3)
         {
             ShipToRemoveStress = ship;
             RegisterAbilityTrigger(TriggerTypes.OnShipMovementFinish, AskKananJarrusAbility);
         }
     }
 }
Пример #15
0
        private void CheckPilotAbility()
        {
            bool IsDifferentPlayer = (HostShip.Owner.PlayerNo != Combat.Attacker.Owner.PlayerNo);
            bool HasFocusTokens    = HostShip.HasToken(typeof(Tokens.FocusToken));

            Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(HostShip, Combat.Attacker);

            if (IsDifferentPlayer && HasFocusTokens && distanceInfo.Range < 3)
            {
                RegisterAbilityTrigger(TriggerTypes.OnAttackStart, AskDecreaseAttack);
            }
        }
Пример #16
0
 private void RegisterScavengerCraneAbility(GenericShip destroyedShip, bool isFled)
 {
     Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(HostShip, destroyedShip);
     if (distanceInfo.Range <= 2)
     {
         var recoverableUpgrades = GetRecoverableUpgrades();
         if (recoverableUpgrades.Length > 0)
         {
             RegisterAbilityTrigger(TriggerTypes.OnShipIsDestroyed, AskUseScavengerCrane);
         }
     }
 }
Пример #17
0
 private void CheckCarnorJaxRestriction(GenericShip ship, ActionsList.GenericAction action, ref bool isAllowed)
 {
     if (ship.Owner != HostShip.Owner && action.TokensSpend.Any(token => token == typeof(FocusToken) || token == typeof(EvadeToken)))
     {
         Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(ship, HostShip);
         if (positionInfo.Range <= 1)
         {
             Messages.ShowErrorToHuman("Carnor Jax: Cannot perform focus or evade actions, or spend focus or evade tokens");
             isAllowed = false;
         }
     }
 }
Пример #18
0
 private void CaptainYorrPilotAbility(GenericShip ship, System.Type tokenType)
 {
     if (tokenType == typeof(Tokens.StressToken) && ship.Owner == HostShip.Owner && ship != HostShip && HostShip.TokenCount(typeof(Tokens.StressToken)) <= 2)
     {
         Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(ship, HostShip);
         if (positionInfo.Range <= 2)
         {
             TargetShip = ship;
             RegisterAbilityTrigger(TriggerTypes.OnBeforeTokenIsAssigned, ShowDecision);
         }
     }
 }
Пример #19
0
        public bool IsShotAvailable(GenericShip targetShip)
        {
            bool result = true;

            int range;

            if (Combat.ChosenWeapon.GetType() == GetType())
            {
                Board.ShipShotDistanceInformation shotInfo = new Board.ShipShotDistanceInformation(Host, targetShip, this);
                range = shotInfo.Range;
                if (!CanShootOutsideArc)
                {
                    //TODO: Change to munitions arc
                    if (!shotInfo.InShotAngle)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                if (!CanShootOutsideArc)
                {
                    Board.ShipShotDistanceInformation shotInfo = new Board.ShipShotDistanceInformation(Host, targetShip, this);
                    range = shotInfo.Range;

                    //TODO: Change to munitions arc
                    if (!shotInfo.InShotAngle)
                    {
                        return(false);
                    }
                }
                else
                {
                    Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Host, targetShip);
                    range = distanceInfo.Range;
                }
            }

            if (range < MinRange)
            {
                return(false);
            }
            if (range > MaxRange)
            {
                return(false);
            }

            return(result);
        }
Пример #20
0
        private void AssaultMissilesHitEffect()
        {
            var ships = Roster.AllShips.Select(x => x.Value).ToList();

            foreach (Ship.GenericShip ship in ships)
            {
                // null refs?
                if (ship.Model == null || Combat.Defender == null || Combat.Defender.Model == null)
                {
                    continue;
                }

                // Defending ship shouldn't suffer additional damage
                if (ship.Model == Combat.Defender.Model)
                {
                    continue;
                }

                Board.ShipDistanceInformation shotInfo = new Board.ShipDistanceInformation(Combat.Defender, ship);

                if (shotInfo.Range == 1)
                {
                    //Messages.ShowErrorToHuman(string.Format("{0} is within range 1 of {1}; assault missile deals 1 damage!", ship.PilotName, Combat.Defender.PilotName));

                    var diceRoll = new DiceRoll(DiceKind.Attack, 0, DiceRollCheckType.Combat);
                    diceRoll.AddDice(DieSide.Success);
                    var hitDie = diceRoll.DiceList [0];
                    ship.AssignedDamageDiceroll.DiceList.Add(hitDie);

                    Triggers.RegisterTrigger(new Trigger()
                    {
                        Name         = "Suffer Assault Missile Damage",
                        TriggerType  = TriggerTypes.OnDamageIsDealt,
                        TriggerOwner = ship.Owner.PlayerNo,
                        EventHandler = ship.SufferDamage,
                        Skippable    = true,
                        EventArgs    = new DamageSourceEventArgs()
                        {
                            Source     = "Assault Missile",
                            DamageType = DamageTypes.CardAbility
                        }
                    });
                }
            }

            Triggers.ResolveTriggers(TriggerTypes.OnDamageIsDealt, Triggers.FinishTrigger);
        }
Пример #21
0
        private void AssignIonTokens()
        {
            shipsToAssignIon = new List <GenericShip>();

            var ships = Roster.AllShips.Select(x => x.Value).ToList();

            foreach (GenericShip ship in ships)
            {
                Board.ShipDistanceInformation shotInfo = new Board.ShipDistanceInformation(Combat.Defender, ship);
                if (shotInfo.Range == 1)
                {
                    shipsToAssignIon.Add(ship);
                }
            }

            AssignIonTokensRecursive();
        }
Пример #22
0
 private void UseEpsilonLeaderAbility(object sender, System.EventArgs e)
 {
     Selection.ThisShip = this;
     Ship.GenericShip EpsilonLeader = Selection.ThisShip;
     // remove a stress from friendly ships at range 1
     foreach (var friendlyShip in EpsilonLeader.Owner.Ships)
     {
         Ship.GenericShip friendlyShipDefined       = friendlyShip.Value;
         Board.ShipDistanceInformation positionInfo = new Board.ShipDistanceInformation(EpsilonLeader, friendlyShipDefined);
         if (positionInfo.Range == 1)
         {
             // remove 1 stress token if it exists
             friendlyShipDefined.RemoveToken(typeof(Tokens.StressToken));
         }
     }
     Triggers.FinishTrigger();
 }
Пример #23
0
        private void TrySelectShipByRange(Ship.GenericShip ship)
        {
            Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Selection.ThisShip, ship);
            int range = distanceInfo.Range;

            if ((range >= minRange) && (range <= maxRange))
            {
                TargetShip = ship;
                Game.UI.HideNextButton();
                MovementTemplates.ShowRange(Selection.ThisShip, ship);
                finishAction.Invoke();
            }
            else
            {
                Messages.ShowErrorToHuman("Ship is outside of range");
                RevertSubPhase();
            }
        }
Пример #24
0
        private void TrySelectShipByRange(Ship.GenericShip ship)
        {
            Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Selection.ThisShip, ship);
            int range = distanceInfo.Range;

            if ((range >= minRange) && (range <= maxRange))
            {
                TargetShip = ship;
                UI.HideNextButton();
                MovementTemplates.ShowRange(Selection.ThisShip, ship);
                TargetShipIsSelected();
            }
            else
            {
                Messages.ShowErrorToHuman("Ship is outside of range");
                CancelShipSelection();
            }
        }
Пример #25
0
        public override bool IsActionEffectAvailable()
        {
            bool result = true;

            foreach (var friendlyShip in Host.Owner.Ships)
            {
                if (friendlyShip.Value.ShipId != Host.ShipId)
                {
                    Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Host, friendlyShip.Value);
                    if (distanceInfo.Range < 3)
                    {
                        result = false;
                        break;
                    }
                }
            }

            return(result);
        }
Пример #26
0
        public Dictionary <GenericShip, float> GetEnemyShipsAndDistance(GenericShip thisShip, bool ignoreCollided = false, bool inArcAndRange = false)
        {
            Dictionary <GenericShip, float> results = new Dictionary <GenericShip, float>();

            foreach (var shipHolder in Roster.GetPlayer(Roster.AnotherPlayer(thisShip.Owner.PlayerNo)).Ships)
            {
                if (!shipHolder.Value.IsDestroyed)
                {
                    if (ignoreCollided)
                    {
                        if (thisShip.LastShipCollision != null)
                        {
                            if (thisShip.LastShipCollision.ShipId == shipHolder.Value.ShipId)
                            {
                                continue;
                            }
                        }
                        if (shipHolder.Value.LastShipCollision != null)
                        {
                            if (shipHolder.Value.LastShipCollision.ShipId == thisShip.ShipId)
                            {
                                continue;
                            }
                        }
                    }

                    if (inArcAndRange)
                    {
                        Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(thisShip, shipHolder.Value);
                        if ((distanceInfo.Range > 3))
                        {
                            continue;
                        }
                    }

                    float distance = Vector3.Distance(thisShip.GetCenter(), shipHolder.Value.GetCenter());
                    results.Add(shipHolder.Value, distance);
                }
            }
            results = results.OrderBy(n => n.Value).ToDictionary(n => n.Key, n => n.Value);

            return(results);
        }
Пример #27
0
        public override bool IsActionEffectAvailable()
        {
            bool result = false;

            if (Combat.AttackStep == CombatStep.Defence && Combat.ShotInfo.InArc)
            {
                Board.ShipDistanceInformation shipDistance = new Board.ShipDistanceInformation(Combat.Attacker, Combat.Defender);
                if (shipDistance.Range == 1)
                {
                    Board.ShipShotDistanceInformation shotInfo = new Board.ShipShotDistanceInformation(Combat.Defender, Combat.Attacker, Combat.Defender.PrimaryWeapon);
                    if (shotInfo.InArc)
                    {
                        result = true;
                    }
                }
            }

            return(result);
        }
Пример #28
0
        protected bool FilterTargetsByRange(GenericShip ship, int minRange, int maxRange)
        {
            bool result = true;

            if ((Phases.CurrentSubPhase as SelectShipSubPhase) == null || (Phases.CurrentSubPhase as SelectShipSubPhase).CanMeasureRangeBeforeSelection)
            {
                Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Selection.ThisShip, ship);
                if (distanceInfo.Range < minRange)
                {
                    return(false);
                }
                if (distanceInfo.Range > maxRange)
                {
                    return(false);
                }
            }

            return(result);
        }
Пример #29
0
        private void DoSplashDamage(Action callback)
        {
            Messages.ShowInfo("\"Harpooned!\" condition deals splash damage");

            var ships = Roster.AllShips.Select(x => x.Value).ToList();

            foreach (GenericShip ship in ships)
            {
                // Defending ship shouldn't suffer additional damage
                if (ship.ShipId == Combat.Defender.ShipId)
                {
                    continue;
                }

                Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(Combat.Defender, ship);

                if (distanceInfo.Range == 1)
                {
                    var diceRoll = new DiceRoll(DiceKind.Attack, 0, DiceRollCheckType.Combat);
                    diceRoll.AddDice(DieSide.Success);
                    var hitDie = diceRoll.DiceList[0];
                    ship.AssignedDamageDiceroll.DiceList.Add(hitDie);

                    Triggers.RegisterTrigger(new Trigger()
                    {
                        Name         = "Suffer \"Harpooned!\" condition damage",
                        TriggerType  = TriggerTypes.OnDamageIsDealt,
                        TriggerOwner = ship.Owner.PlayerNo,
                        EventHandler = ship.SufferDamage,
                        Skippable    = true,
                        EventArgs    = new DamageSourceEventArgs()
                        {
                            Source     = "\"Harpooned!\" condition",
                            DamageType = DamageTypes.CardAbility
                        }
                    });
                }
            }

            Triggers.ResolveTriggers(TriggerTypes.OnDamageIsDealt, callback);
        }
Пример #30
0
        private void CheckAbility(GenericShip ship, Type tokenType)
        {
            if (IsAbilityUsed)
            {
                return;
            }
            if (tokenType != typeof(StressToken))
            {
                return;
            }
            if (ship.Owner.PlayerNo != HostShip.Owner.PlayerNo)
            {
                return;
            }

            Board.ShipDistanceInformation distanceInfo = new Board.ShipDistanceInformation(HostShip, ship);
            if (distanceInfo.Range < 3)
            {
                ShipToRemoveStress = ship;
                RegisterAbilityTrigger(TriggerTypes.OnShipMovementFinish, AskInspiringRecruitAbility);
            }
        }