private bool AreTokenRequirementsMet(GenericShip targetShip)
        {
            List <Type> tokenRequirements = HostShip.GetWeaponAttackRequirement(this, isSilent: true);

            if (tokenRequirements.Count > 0)
            {
                foreach (Type tokenRequirement in tokenRequirements)
                {
                    if (tokenRequirement == typeof(BlueTargetLockToken))
                    {
                        List <GenericToken> waysToPay = new List <GenericToken>();

                        List <char>  letters         = ActionsHolder.GetTargetLocksLetterPairs(HostShip, targetShip);
                        GenericToken targetLockToken = HostShip.Tokens.GetToken(typeof(BlueTargetLockToken), letters.FirstOrDefault());
                        if (targetLockToken != null)
                        {
                            waysToPay.Add(targetLockToken);
                        }

                        HostShip.CallOnGenerateAvailableAttackPaymentList(waysToPay);

                        if (waysToPay.Count != 0)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        if (HostShip.Tokens.HasToken(tokenRequirement))
                        {
                            return(true);
                        }
                    }
                }
            }
            else
            {
                return(true);
            }

            return(false);
        }
        public virtual bool IsShotAvailable(GenericShip targetShip)
        {
            bool result = true;

            int MinRangeUpdated = WeaponInfo.MinRange;
            int MaxRangeUpdated = WeaponInfo.MaxRange;

            HostShip.CallUpdateWeaponRange(this, ref MinRangeUpdated, ref MaxRangeUpdated);

            if (!State.IsFaceup)
            {
                return(false);
            }

            if (State.UsesCharges && State.Charges == 0)
            {
                return(false);
            }

            ShotInfo shotInfo = new ShotInfo(HostShip, targetShip, this);
            int      range    = shotInfo.Range;

            if (!shotInfo.IsShotAvailable)
            {
                return(false);
            }

            if (range < MinRangeUpdated)
            {
                return(false);
            }
            if (range > MaxRangeUpdated)
            {
                return(false);
            }

            Type tokenRequirement = HostShip.GetWeaponAttackRequirement(this, isSilent: true);

            if (tokenRequirement == typeof(BlueTargetLockToken))
            {
                List <GenericToken> waysToPay = new List <GenericToken>();

                List <char>  letters         = ActionsHolder.GetTargetLocksLetterPairs(HostShip, targetShip);
                GenericToken targetLockToken = HostShip.Tokens.GetToken(typeof(BlueTargetLockToken), letters.FirstOrDefault());
                if (targetLockToken != null)
                {
                    waysToPay.Add(targetLockToken);
                }

                HostShip.CallOnGenerateAvailableAttackPaymentList(waysToPay);

                if (waysToPay.Count == 0)
                {
                    return(false);
                }
            }
            else if (tokenRequirement != null)
            {
                if (!HostShip.Tokens.HasToken(tokenRequirement))
                {
                    return(false);
                }
            }

            return(result);
        }