示例#1
0
        public static List <Option> PythonOptions(this Controller c, int gameId)
        {
            if (c.Choice != null)
            {
                if (c.Choice.ChoiceType == ChoiceType.GENERAL)
                {
                    return(c.Choice.Choices.Select(p => new Option(gameId, p, c.Game.IdEntityDic[p].Card.Name)).ToList());
                }

                throw new NotImplementedException();
            }

            int           controllerId = c.Id;
            List <Option> allOptions   = ManagedObjects.OptionBuffers[gameId];

            allOptions.Add(new Option(gameId, EndTurn));

            #region PlayCardTasks
            int  mana            = c.RemainingMana;
            int  zonePosRange    = c.BoardZone.Count;
            bool?spellCostHealth = null;

            Character[] allTargets      = null;
            Minion[]    friendlyMinions = null;
            Minion[]    enemyMinions    = null;
            Minion[]    allMinions      = null;
            Character[] allFriendly     = null;
            Character[] allEnemies      = null;

            ReadOnlySpan <IPlayable> handSpan = c.HandZone.GetSpan();
            for (int i = 0; i < handSpan.Length; i++)
            {
                if (!handSpan[i].ChooseOne || c.ChooseBoth)
                {
                    GetPlayCardTasks(handSpan[i]);
                }
                else
                {
                    IPlayable[] playables = handSpan[i].ChooseOnePlayables;
                    for (int j = 1; j < 3; j++)
                    {
                        GetPlayCardTasks(handSpan[i], playables[j - 1], j);
                    }
                }
            }
            #endregion

            #region HeroPowerTask
            HeroPower power         = c.Hero.HeroPower;
            Card      heroPowerCard = power.Card;
            if (!power.IsExhausted && mana >= power.Cost &&
                !c.HeroPowerDisabled && !heroPowerCard.HideStat)
            {
                if (heroPowerCard.ChooseOne)
                {
                    if (c.ChooseBoth)
                    {
                        allOptions.Add(new Option(gameId, API.Option.Types.PlayerTaskType.HeroPower, source: power));
                    }
                    else
                    {
                        allOptions.Add(new Option(gameId, API.Option.Types.PlayerTaskType.HeroPower, subOption: 1, source: power));
                        allOptions.Add(new Option(gameId, API.Option.Types.PlayerTaskType.HeroPower, subOption: 2, source: power));
                    }
                }
                else
                {
                    if (heroPowerCard.IsPlayableByCardReq(c))
                    {
                        Character[] targets = GetTargets(heroPowerCard);
                        if (targets != null)
                        {
                            for (int i = 0; i < targets.Length; i++)
                            {
                                allOptions.Add(new Option(gameId, API.Option.Types.PlayerTaskType.HeroPower,
                                                          0, Option.getPosition(targets[i], controllerId),
                                                          source: power, target: targets[i]));
                            }
                        }
                        else
                        {
                            allOptions.Add(new Option(gameId, API.Option.Types.PlayerTaskType.HeroPower, source: power));
                        }
                    }
                }
            }
            #endregion

            #region MinionAttackTasks
            Minion[] attackTargets             = null;
            bool     isOpHeroValidAttackTarget = false;
            var      boardSpan = c.BoardZone.GetSpan();
            for (int j = 0; j < boardSpan.Length; j++)
            {
                Minion minion = boardSpan[j];

                if (minion.IsExhausted && (!minion.HasCharge || minion.NumAttacksThisTurn != 0))
                {
                    continue;
                }
                if (minion.IsFrozen || minion.AttackDamage == 0 || minion.CantAttack || minion.Untouchable)
                {
                    continue;
                }

                GenerateAttackTargets();

                for (int i = 0; i < attackTargets.Length; i++)
                {
                    allOptions.Add(new Option(gameId, MinionAttack, j + 1,
                                              Option.getEnemyPosition(attackTargets[i]), source: minion, target: attackTargets[i]));
                }

                if (isOpHeroValidAttackTarget && !(minion.CantAttackHeroes || minion.AttackableByRush))
                {
                    allOptions.Add(new Option(gameId, MinionAttack, j + 1, Option.OP_HERO_POSITION,
                                              source: minion, target: c.Opponent.Hero));
                }
            }
            #endregion

            #region HeroAttackTaskts
            Hero hero = c.Hero;

            if ((!hero.IsExhausted || (hero.ExtraAttacksThisTurn > 0 && hero.ExtraAttacksThisTurn >= hero.NumAttacksThisTurn)) &&
                hero.AttackDamage > 0 && !hero.IsFrozen)
            {
                GenerateAttackTargets();

                for (int i = 0; i < attackTargets.Length; i++)
                {
                    allOptions.Add(new Option(gameId, HeroAttack, 0,
                                              Option.getEnemyPosition(attackTargets[i]), source: hero, target: attackTargets[i]));
                }

                if (isOpHeroValidAttackTarget && !hero.CantAttackHeroes)
                {
                    allOptions.Add(new Option(gameId, HeroAttack, 0, Option.OP_HERO_POSITION,
                                              source: hero, target: c.Opponent.Hero));
                }
            }
            #endregion

            return(allOptions);

            #region local functions
            void GetPlayCardTasks(in IPlayable playable, in IPlayable chooseOnePlayable = null, int subOption = -1)
            {
                Card card = chooseOnePlayable?.Card ?? playable.Card;

                if (!spellCostHealth.HasValue)
                {
                    spellCostHealth = c.ControllerAuraEffects[GameTag.SPELLS_COST_HEALTH] == 1;
                }

                bool healthCost = (playable.AuraEffects?.CardCostHealth ?? false) ||
                                  (spellCostHealth.Value && playable.Card.Type == CardType.SPELL);

                if (!healthCost && (playable.Cost > mana || playable.Card.HideStat))
                {
                    return;
                }

                // check PlayableByPlayer
                switch (playable.Card.Type)
                {
                //	REQ_MINION_CAP
                case CardType.MINION when c.BoardZone.IsFull:
                    return;

                case CardType.SPELL:
                {
                    if (card.IsSecret)
                    {
                        if (c.SecretZone.IsFull)                                 // REQ_SECRET_CAP
                        {
                            return;
                        }
                        if (c.SecretZone.Any(p => p.Card.AssetId == card.AssetId))                                 // REQ_UNIQUE_SECRET
                        {
                            return;
                        }
                    }

                    if (card.IsQuest && c.SecretZone.Quest != null)
                    {
                        return;
                    }
                    break;
                }
                }

                {
                    if (!card.IsPlayableByCardReq(c))
                    {
                        return;
                    }

                    Character[] targets = GetTargets(card);

                    int sourcePosition = playable.ZonePosition;

                    // Card doesn't require any targets
                    if (targets == null)
                    {
                        if (playable is Minion)
                        {
                            for (int i = 0; i <= zonePosRange; i++)
                            {
                                allOptions.Add(new Option(gameId, PlayCard, sourcePosition, i + 1, subOption,
                                                          source: playable));
                            }
                        }
                        else
                        {
                            allOptions.Add(new Option(gameId, PlayCard, sourcePosition, -1, subOption,
                                                      source: playable));
                        }
                    }
                    else
                    {
                        if (targets.Length == 0)
                        {
                            if (card.MustHaveTargetToPlay)
                            {
                                return;
                            }

                            if (playable is Minion)
                            {
                                for (int i = 0; i <= zonePosRange; i++)
                                {
                                    allOptions.Add(new Option(gameId, PlayCard, sourcePosition, i + 1, subOption,
                                                              source: playable));
                                }
                            }
                            else
                            {
                                allOptions.Add(new Option(gameId, PlayCard, sourcePosition, -1, subOption,
                                                          source: playable));
                            }
                        }
                        else
                        {
                            for (int j = 0; j < targets.Length; j++)
                            {
                                ICharacter target = targets[j];
                                if (playable is Minion)
                                {
                                    //for (int i = 0; i <= zonePosRange; i++)
                                    //    allOptions.Add(PlayCardTask.Any(c, playable, target, i, subOption,
                                    //        true));
                                    continue;
                                }
                                else
                                {
                                    allOptions.Add(new Option(gameId, PlayCard, sourcePosition,
                                                              Option.getPosition(target, controllerId), subOption,
                                                              source: playable, target: target));
                                }
                            }
                        }
                    }
                }
            }

            // Returns null if targeting is not required
            // Returns 0 Array if there is no available target
            Character[] GetTargets(Card card)
            {
                // Check it needs additional validation
                if (!card.TargetingAvailabilityPredicate?.Invoke(c, card) ?? false)
                {
                    return(null);
                }

                Character[] targets;

                switch (card.TargetingType)
                {
                case TargetingType.None:
                    return(null);

                case TargetingType.All:
                    if (allTargets == null)
                    {
                        if (c.Opponent.Hero.HasStealth)
                        {
                            allTargets    = new Character[GetFriendlyMinions().Length + GetEnemyMinions().Length + 1];
                            allTargets[0] = c.Hero;
                            Array.Copy(GetAllMinions(), 0, allTargets, 1, allMinions.Length);
                        }
                        else
                        {
                            allTargets    = new Character[GetFriendlyMinions().Length + GetEnemyMinions().Length + 2];
                            allTargets[0] = c.Hero;
                            allTargets[1] = c.Opponent.Hero;
                            Array.Copy(GetAllMinions(), 0, allTargets, 2, allMinions.Length);
                        }
                    }
                    targets = allTargets;
                    break;

                case TargetingType.FriendlyCharacters:
                    if (allFriendly == null)
                    {
                        allFriendly    = new Character[GetFriendlyMinions().Length + 1];
                        allFriendly[0] = c.Hero;
                        Array.Copy(friendlyMinions, 0, allFriendly, 1, friendlyMinions.Length);
                    }
                    targets = allFriendly;
                    break;

                case TargetingType.EnemyCharacters:
                    if (allEnemies == null)
                    {
                        if (!c.Opponent.Hero.HasStealth)
                        {
                            allEnemies    = new Character[GetEnemyMinions().Length + 1];
                            allEnemies[0] = c.Opponent.Hero;
                            Array.Copy(enemyMinions, 0, allEnemies, 1, enemyMinions.Length);
                        }
                        else
                        {
                            allEnemies = GetEnemyMinions();
                        }
                    }
                    targets = allEnemies;
                    break;

                case TargetingType.AllMinions:
                    targets = GetAllMinions();
                    break;

                case TargetingType.FriendlyMinions:
                    targets = GetFriendlyMinions();
                    break;

                case TargetingType.EnemyMinions:
                    targets = GetEnemyMinions();
                    break;

                case TargetingType.Heroes:
                    targets = !c.Opponent.Hero.HasStealth
                                                        ? new[] { c.Hero, c.Opponent.Hero }
                                                        : new[] { c.Hero };
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // Filtering for target_if_available
                TargetingPredicate p = card.TargetingPredicate;

                if (p != null)
                {
                    if (card.Type == CardType.SPELL || card.Type == CardType.HERO_POWER)
                    {
                        Character[] buffer = new Character[targets.Length];
                        int         i      = 0;
                        for (int j = 0; j < targets.Length; ++j)
                        {
                            if (!p(targets[j]) || targets[j].CantBeTargetedBySpells)
                            {
                                continue;
                            }
                            buffer[i] = targets[j];
                            i++;
                        }

                        if (i != targets.Length)
                        {
                            Character[] result = new Character[i];
                            Array.Copy(buffer, result, i);
                            return(result);
                        }
                        return(buffer);
                    }
                    else
                    {
                        if (!card.TargetingAvailabilityPredicate?.Invoke(c, card) ?? false)
                        {
                            return(null);
                        }

                        Character[] buffer = new Character[targets.Length];
                        int         i      = 0;
                        for (int j = 0; j < targets.Length; ++j)
                        {
                            if (!p(targets[j]))
                            {
                                continue;
                            }
                            buffer[i] = targets[j];
                            i++;
                        }

                        if (i != targets.Length)
                        {
                            Character[] result = new Character[i];
                            Array.Copy(buffer, result, i);
                            return(result);
                        }
                        return(buffer);
                    }
                }
                else if (card.Type == CardType.SPELL || card.Type == CardType.HERO_POWER)
                {
                    Character[] buffer = new Character[targets.Length];
                    int         i      = 0;
                    for (int j = 0; j < targets.Length; ++j)
                    {
                        if (targets[j].CantBeTargetedBySpells)
                        {
                            continue;
                        }
                        buffer[i] = targets[j];
                        i++;
                    }

                    if (i != targets.Length)
                    {
                        Character[] result = new Character[i];
                        Array.Copy(buffer, result, i);
                        return(result);
                    }
                    return(buffer);
                }

                return(targets);

                Minion[] GetFriendlyMinions()
                {
                    return(friendlyMinions ?? (friendlyMinions = c.BoardZone.GetAll()));
                }

                Minion[] GetAllMinions()
                {
                    if (allMinions != null)
                    {
                        return(allMinions);
                    }

                    allMinions = new Minion[GetEnemyMinions().Length + GetFriendlyMinions().Length];
                    Array.Copy(enemyMinions, allMinions, enemyMinions.Length);
                    Array.Copy(friendlyMinions, 0, allMinions, enemyMinions.Length, friendlyMinions.Length);

                    return(allMinions);
                }
            }

            void GenerateAttackTargets()
            {
                if (attackTargets != null)
                {
                    return;
                }

                Minion[] eMinions = GetEnemyMinions();
                //var taunts = new Minion[eMinions.Length];
                Minion[] taunts = null;
                int      tCount = 0;

                for (int i = 0; i < eMinions.Length; i++)
                {
                    if (eMinions[i].HasTaunt)
                    {
                        if (taunts == null)
                        {
                            taunts = new Minion[eMinions.Length];
                        }
                        taunts[tCount] = eMinions[i];
                        tCount++;
                    }
                }

                if (tCount > 0)
                {
                    var targets = new Minion[tCount];
                    Array.Copy(taunts, targets, tCount);
                    attackTargets             = targets;
                    isOpHeroValidAttackTarget = false;                      // some brawls allow taunt heros and c should be fixed
                    return;
                }
                attackTargets = eMinions;

                isOpHeroValidAttackTarget =
                    !c.Opponent.Hero.IsImmune && !c.Opponent.Hero.HasStealth;
            }

            Minion[] GetEnemyMinions()
            {
                return(enemyMinions ?? (enemyMinions = c.Opponent.BoardZone.GetAll(p => !p.HasStealth && !p.IsImmune)));
            }

            #endregion
        }
示例#2
0
        internal Card(string id, int assetId, Tag[] tags,
                      Dictionary <PlayReq, int> playRequirements, string[] entourage, Tag[] refTags)
        {
            Id               = id;
            AssetId          = assetId;
            Entourage        = entourage;
            PlayRequirements = playRequirements;
            var tagDict    = new Dictionary <GameTag, int>();
            var refTagDict = new Dictionary <GameTag, int>();

            #region Preprocessing tags.
            foreach (Tag tag in tags)
            {
                if (tag.TagValue.HasIntValue)
                {
                    tagDict.Add(tag.GameTag, tag.TagValue);
                    switch (tag.GameTag)
                    {
                    case GameTag.COST:
                        Cost = tag.TagValue;
                        break;

                    case GameTag.ATK:
                        ATK = tag.TagValue;
                        break;

                    case GameTag.HEALTH:
                        Health = tag.TagValue;
                        break;

                    case GameTag.OVERLOAD:
                        HasOverload = true;
                        Overload    = tag.TagValue;
                        break;

                    case GameTag.SPELLPOWER:
                        SpellPower = tag.TagValue;
                        break;

                    case GameTag.CHOOSE_ONE:
                        ChooseOne = true;
                        break;

                    case GameTag.COMBO:
                        Combo = true;
                        break;

                    case GameTag.TAUNT:
                        Taunt = true;
                        break;

                    case GameTag.CHARGE:
                        Charge = true;
                        break;

                    case GameTag.STEALTH:
                        Stealth = true;
                        break;

                    case GameTag.POISONOUS:
                        Poisonous = true;
                        break;

                    case GameTag.DIVINE_SHIELD:
                        DivineShield = true;
                        break;

                    case GameTag.WINDFURY:
                        Windfury = true;
                        break;

                    case GameTag.LIFESTEAL:
                        LifeSteal = true;
                        break;

                    case GameTag.ECHO:
                        Echo = true;
                        break;

                    case GameTag.RUSH:
                        Rush = true;
                        break;

                    case GameTag.CANT_BE_TARGETED_BY_SPELLS:
                        CantBeTargetedBySpells = true;
                        break;

                    case GameTag.CANT_ATTACK:
                        CantAttack = true;
                        break;

                    case GameTag.MODULAR:
                        Modular = true;
                        break;

                    case GameTag.SECRET:
                        IsSecret = true;
                        break;

                    case GameTag.QUEST:
                        IsQuest = true;
                        break;

                    case GameTag.DEATHRATTLE:
                        Deathrattle = true;
                        break;

                    case GameTag.UNTOUCHABLE:
                        Untouchable = true;
                        break;

                    case GameTag.HIDE_STATS:
                        HideStat = true;
                        break;

                    case GameTag.RECEIVES_DOUBLE_SPELLDAMAGE_BONUS:
                        ReceivesDoubleSpelldamageBonus = true;
                        break;

                    case GameTag.FREEZE:
                        Freeze = true;
                        break;

                    case GameTag.CARDRACE:
                        Race = (Race)(int)tag.TagValue;
                        break;

                    case GameTag.CLASS:
                        Class = (CardClass)(int)tag.TagValue;
                        break;

                    case GameTag.CARDTYPE:
                        Type = (CardType)(int)tag.TagValue;
                        break;
                    }
                }
                else if
                (tag.TagValue.HasBoolValue)
                {
                    tagDict.Add(tag.GameTag, tag.TagValue ? 1 : 0);
                }
                else if
                (tag.TagValue.HasStringValue)
                {
                    switch (tag.GameTag)
                    {
                    case GameTag.CARDNAME:
                        Name = tag.TagValue;
                        break;

                    case GameTag.CARDTEXT:
                        Text = tag.TagValue;
                        break;
                    }
                }
            }
            foreach (Tag tag in refTags)
            {
                if (refTagDict.ContainsKey(tag.GameTag))
                {
                    continue;
                }

                if (tag.TagValue.HasIntValue)
                {
                    refTagDict.Add(tag.GameTag, tag.TagValue);
                }
                else if (tag.TagValue.HasBoolValue)
                {
                    refTagDict.Add(tag.GameTag, tag.TagValue ? 1 : 0);
                }
            }
            #endregion

            #region Preprocessing requirements
            int  characterType = 0;
            int  friendlyCheck = 0;
            bool needsTarget   = false;
            foreach (KeyValuePair <PlayReq, int> requirement in playRequirements)
            {
                switch (requirement.Key)
                {
                case PlayReq.REQ_TARGET_TO_PLAY:
                    MustHaveTargetToPlay = true;
                    needsTarget          = true;
                    break;

                case PlayReq.REQ_DRAG_TO_PLAY:                          // TODO
                case PlayReq.REQ_NONSELF_TARGET:
                case PlayReq.REQ_TARGET_IF_AVAILABLE:
                    needsTarget = true;
                    break;

                case PlayReq.REQ_MINION_TARGET:
                    characterType = 1;
                    break;

                case PlayReq.REQ_FRIENDLY_TARGET:
                    friendlyCheck = 1;
                    break;

                case PlayReq.REQ_ENEMY_TARGET:
                    friendlyCheck = -1;
                    break;

                case PlayReq.REQ_HERO_TARGET:
                    characterType = -1;
                    break;

                case PlayReq.REQ_TARGET_WITH_RACE:
                    TargetingPredicate += TargetingPredicates.ReqTargetWithRace(requirement.Value);
                    break;

                case PlayReq.REQ_FROZEN_TARGET:
                    TargetingPredicate += TargetingPredicates.ReqFrozenTarget;
                    break;

                case PlayReq.REQ_DAMAGED_TARGET:
                    TargetingPredicate += TargetingPredicates.ReqDamagedTarget;
                    break;

                case PlayReq.REQ_UNDAMAGED_TARGET:
                    TargetingPredicate += TargetingPredicates.ReqUndamagedTarget;
                    break;

                case PlayReq.REQ_TARGET_MAX_ATTACK:
                    TargetingPredicate += TargetingPredicates.ReqTargetMaxAttack(requirement.Value);
                    break;

                case PlayReq.REQ_TARGET_MIN_ATTACK:
                    TargetingPredicate += TargetingPredicates.ReqTargetMinAttack(requirement.Value);
                    break;

                case PlayReq.REQ_MUST_TARGET_TAUNTER:
                    TargetingPredicate += TargetingPredicates.ReqMustTargetTaunter;
                    break;

                case PlayReq.REQ_STEALTHED_TARGET:
                    TargetingPredicate += TargetingPredicates.ReqStealthedTarget;
                    break;

                case PlayReq.REQ_TARGET_WITH_DEATHRATTLE:
                    TargetingPredicate += TargetingPredicates.ReqTargetWithDeathrattle;
                    break;

                case PlayReq.REQ_LEGENDARY_TARGET:
                    TargetingPredicate += TargetingPredicates.ReqLegendaryTarget;
                    break;

                case PlayReq.REQ_TARGET_FOR_COMBO:
                    needsTarget = true;
                    TargetingAvailabilityPredicate += TargetingPredicates.ReqTargetForCombo;
                    break;

                case PlayReq.REQ_TARGET_IF_AVAILABE_AND_ELEMENTAL_PLAYED_LAST_TURN:
                    needsTarget = true;
                    TargetingAvailabilityPredicate += TargetingPredicates.ElementalPlayedLastTurn;
                    break;

                case PlayReq.REQ_TARGET_IF_AVAILABLE_AND_DRAGON_IN_HAND:
                    needsTarget = true;
                    TargetingAvailabilityPredicate += TargetingPredicates.DragonInHand;
                    break;

                case PlayReq.REQ_TARGET_IF_AVAILABLE_AND_MINIMUM_FRIENDLY_MINIONS:
                    needsTarget = true;
                    TargetingAvailabilityPredicate += TargetingPredicates.MinimumFriendlyMinions(requirement.Value);
                    break;

                case PlayReq.REQ_TARGET_IF_AVAILABLE_AND_MINIMUM_FRIENDLY_SECRETS:
                    needsTarget = true;
                    TargetingAvailabilityPredicate += TargetingPredicates.MinimumFriendlySecrets(requirement.Value);
                    break;

                case PlayReq.REQ_TARGET_IF_AVAILABLE_AND_NO_3_COST_CARD_IN_DECK:
                    // TODO
                    TargetingType = TargetingType.AllMinions;
                    break;

                case PlayReq.REQ_NUM_MINION_SLOTS:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqNumMinionSlots;
                    break;

                case PlayReq.REQ_MINIMUM_ENEMY_MINIONS:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqMinimumEnemyMinions(requirement.Value);
                    break;

                case PlayReq.REQ_MINIMUM_TOTAL_MINIONS:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqMinimumTotalMinions(requirement.Value);
                    break;

                case PlayReq.REQ_HAND_NOT_FULL:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqHandNotFull;
                    break;

                case PlayReq.REQ_WEAPON_EQUIPPED:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqWeaponEquipped;
                    break;

                case PlayReq.REQ_ENTIRE_ENTOURAGE_NOT_IN_PLAY:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqEntireEntourageNotInPlay(assetId);
                    break;

                case PlayReq.REQ_FRIENDLY_MINION_DIED_THIS_GAME:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqFriendlyMinionDiedThisGame;
                    break;

                case PlayReq.REQ_MUST_PLAY_OTHER_CARD_FIRST:
                    PlayAvailabilityPredicate += c => false;
                    break;

                //	REQ_STEADY_SHOT
                //	REQ_MINION_OR_ENEMY_HERO	//	Steady Shot
                //	REQ_MINION_SLOT_OR_MANA_CRYSTAL_SLOT	//	Jade Blossom
                case PlayReq.REQ_SECRET_ZONE_CAP_FOR_NON_SECRET:
                    PlayAvailabilityPredicate += TargetingPredicates.ReqSecretZoneCapForNonSecret;
                    break;
                }
            }

            if (needsTarget)
            {
                if (characterType > 0)
                {
                    if (friendlyCheck == 0)
                    {
                        TargetingType = TargetingType.AllMinions;
                    }
                    else if (friendlyCheck == 1)
                    {
                        TargetingType = TargetingType.FriendlyMinions;
                    }
                    else
                    {
                        TargetingType = TargetingType.EnemyMinions;
                    }
                }
                else if (characterType == 0)
                {
                    if (friendlyCheck == 0)
                    {
                        TargetingType = TargetingType.All;
                    }
                    else if (friendlyCheck == 1)
                    {
                        TargetingType = TargetingType.FriendlyCharacters;
                    }
                    else
                    {
                        TargetingType = TargetingType.EnemyCharacters;
                    }
                }
                else
                {
                    TargetingType = TargetingType.Heroes;
                }
            }
            #endregion

            Tags    = tagDict;
            RefTags = refTagDict;
            // spell damage information add ...
            if (Text != null && (Text.Contains("$") || tagDict.ContainsKey(GameTag.AFFECTED_BY_SPELL_POWER)))
            {
                Text += " @spelldmg";
                IsAffectedBySpellDamage = true;
            }
        }