Beispiel #1
0
    public int GetCurrentStarsWinning()
    {
        if (levelID == 0)
        {
            return(0);
        }

        return(GameplayUtils.StarsWon(LivesRemoved, objetives));
    }
Beispiel #2
0
 public Game()
 {
     AIScore     = 0;
     playerScore = 0;
     draws       = 0;
     db          = new DBManager();
     util        = new Utilities();
     gameplay    = new GameplayUtils();
 }
Beispiel #3
0
    List <TowerType> GetTowersTypeToSwap(MinionTypeRepetition minionRepeated)
    {
        var targetType      = GameplayUtils.GetTargetTypeByMinionType(minionRepeated.type);
        var triggerToConsec = GetConsequenceByTargetType(targetType);


        var list = new List <TowerType>();

        foreach (var item in triggerToConsec.toBeReplaced)
        {
            TowerType t = (TowerType)Enum.Parse(typeof(TowerType), item);
            list.Add(t);
        }
        return(list);
    }
Beispiel #4
0
    void MinionWalkFinishedHandler(MinionType type)
    {
        //Debug.Log("MinionWalkFinishedHandler " + type.ToString());

        _minionWalkFinishedOrder.Add(type);
        if (_minionWalkFinishedOrder.Count < _swapJson.enableThreshold)
        {
            return;
        }

        var repeatedList = GetRepeatedMinionList(_minionWalkFinishedOrder);
        var minionRep    = IsAnyMinionAbuse(repeatedList);

        if (minionRep == null)
        {
            return;
        }

        var toBeReplacedList = GetTowersTypeToSwap(minionRep);
        var currentTowers    = _towerManager.GetLevelTowersByType(toBeReplacedList);

        if (currentTowers.Count == 0)
        {
            return;
        }
        var selected = currentTowers[UnityEngine.Random.Range(0, currentTowers.Count)];
        var newTower = GetNewTowerPrefab(GameplayUtils.GetTargetTypeByMinionType(minionRep.type));

        SwapTowers(selected, newTower);

        //If the code could arrive to this point, then a swap was made, so reset the list.
        _minionWalkFinishedOrder = new List <MinionType>();

        if (!_hasSeenTutorial)
        {
            _hasSeenTutorial = true;
            _lvlCanvasManager.EnableSwapTowerTutorial(selected.transform.position);
        }
    }
Beispiel #5
0
    public void InitButton(BaseMinionSkill.SkillType myType, Action <BaseMinionSkill.SkillType> callback, string parentName, GameManager gm)
    {
        _init          = true;
        _myType        = myType;
        _originalColor = img.color;
        _originalScale = img.rectTransform.sizeDelta;


        _buttonBackground.enabled = true;

        OnSkillButtonDown += callback;
        name = "skill_button_" + parentName[parentName.Length - 1];

        if (myType == BaseMinionSkill.SkillType.None)
        {
            img.gameObject.SetActive(false);
            _buttonBackground.enabled = false;
        }
        else
        {
            img.sprite = gm.LoadedAssets.GetSpriteByName(GameplayUtils.GetMinionTypeBySkill(_myType).ToString() + "_skill");
            img.gameObject.SetActive(true);
        }
    }
Beispiel #6
0
        /// <summary>
        /// post processing attributes to ensure ability to influence some statistics can increase other.
        /// In effect this produces "Final" attributes which are result of "Base" attributes plus "Changes"
        /// Attribute Process:
        /// Base - permanent attributes of the item/character, which are not recalculated often, but can be change in game
        /// Changes - modifiers applied to the base. Eg traits, effects, item bonuses...
        /// Final - AttributesProcessing function which ensures there is a way to post process special connections between tags.
        /// </summary>
        /// <param name="a"></param>
        /// <returns></returns>
        static public object AttributesProcessing(Attributes a, Character c, bool returnChangelog)
        {
            a.finalAttributes = new NetDictionary <DBReference <Tag>, FInt>();

            //from, to, how much change occurred. This is so that it can be later processed
            //for additional information on "extra info" popups
            //string -  ID of the skill or item which influenced change
            //Tag - attribute changed by the process
            //FInt - amount of the change
            List <Multitype <long, Tag, FInt, bool> > changelog = null;

            if (returnChangelog)
            {
                changelog = new List <Multitype <long, Tag, FInt, bool> >();
            }

            foreach (var pair in a.baseAttributes)
            {
                a.finalAttributes[pair.Key] = pair.Value;
            }

            Dictionary <Tag, FInt>  addons      = new Dictionary <Tag, FInt>();
            Dictionary <Tag, float> multipliers = new Dictionary <Tag, float>();

            if (c != null)
            {
                //this is a character therefore trigger passive skills which influence attributes
                //Process skills in slots
                foreach (var v in c.learnedSkills)
                {
                    foreach (var k in v.source.Get().skillSubskills)
                    {
                        if (k.trigger.triggerGroup == ETriggerGroupType.Passive)
                        {
                            Globals.CallFunction(k.activation.scriptName,
                                                 v.GetCurrentSkillAttributes()[k],
                                                 addons,
                                                 multipliers,
                                                 DescriptionInfoUtils.GetInfoID(v.source.Get().descriptionInfo),
                                                 changelog,
                                                 c);
                        }
                    }
                }

                //Process skills in effects on character
                foreach (var v in c.effects)
                {
                    foreach (var k in v.source.Get().skillSubskills)
                    {
                        if (k.trigger.triggerGroup == ETriggerGroupType.Passive)
                        {
                            Globals.CallFunction(k.activation.scriptName,
                                                 v.GetCurrentSkillAttributes()[k],
                                                 addons,
                                                 multipliers,
                                                 DescriptionInfoUtils.GetInfoID(v.source.Get().descriptionInfo),
                                                 changelog,
                                                 c);
                        }
                    }
                }

                //Process skills from items
                foreach (SkillInstance v in c.equipmentEffects)
                {
                    foreach (Subskill k in v.source.Get().skillSubskills)
                    {
                        if (k.trigger.triggerGroup == ETriggerGroupType.Passive)
                        {
//                             string itemID = null;
//                             foreach (var i in c.equipment)
//                             {
//                                 if (i != null &&
//                                     i.Get() != null &&
//                                     i.Get().skill == v)
//                                 {
//                                     itemID = i.Get().GetDescriptionInfo().GetInfoID().ToString();
//                                     break;
//                                 }
//                             }

                            Globals.CallFunction(k.activation.scriptName,
                                                 v.GetCurrentSkillAttributes()[k],
                                                 addons,
                                                 multipliers,
                                                 DescriptionInfoUtils.GetInfoID(v.source.Get().descriptionInfo),
                                                 changelog,
                                                 c);
                        }
                    }
                }
                foreach (var add in addons)
                {
                    if (a.finalAttributes.ContainsKey(add.Key))
                    {
                        a.finalAttributes[add.Key] += add.Value;
                    }
                    else
                    {
                        a.finalAttributes[add.Key] = add.Value;
                    }
                }
                foreach (var mul in multipliers)
                {
                    if (a.finalAttributes.ContainsKey(mul.Key))
                    {
                        a.finalAttributes[mul.Key] = a.finalAttributes[mul.Key] * mul.Value;
                    }
                }
            }

            //main attributes to secondary conversion
            //NOTE: attributes which gets processing should not be parent tags for any other tag as they are
            //add for this reason only at late stage

            Tag tag = Globals.GetInstanceFromDB <Tag>(TAG.WITS);

            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt wits = a.finalAttributes[tag];
                //use special function to calculate delay
                FInt delay;
                if (wits.ToFloat() <= 16f)
                {
                    delay = 4f - (wits / 4f);
                }
                else
                {
                    // - Sqrt( x/2 - 8) / 2
                    //delay 0 at wits 16,
                    //delay -1 at wits 24,    = sqrt(4) / 2
                    //delay -2 at wits 48,    = sqrt(16) / 2
                    //delay -3 at wits 88,    = sqrt(36) / 2
                    //delay -4 at wits 144,   = sqrt(64) / 2
                    //delay -5 at wits 216,   = sqrt(100) / 2
                    delay = (FInt)Mathf.Pow(wits.ToFloat() * 0.5f - 8f, 0.5f) * (-0.5f);
                }

                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.DELAY),
                                    delay, multipliers, changelog);
            }
            else
            {
                //write down without calculation if wits are not on character attribute list
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.DELAY),
                                    new FInt(4), multipliers, changelog);
            }

            tag = Globals.GetInstanceFromDB <Tag>(TAG.STRENGTH);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.PERSONAL_CARRY_LIMIT),
                                    GameplayUtils.GetCarryValue(value.ToInt()), multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_PHYSICAL),
                                    1f * value, multipliers, changelog);
            }

            tag = Globals.GetInstanceFromDB <Tag>(TAG.PERCEPTION);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_PHYSICAL),
                                    0.5f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.GATHERING),
                                    0.4f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.LUCK),
                                    0.2f * value, multipliers, changelog);
            }

            tag = Globals.GetInstanceFromDB <Tag>(TAG.INTELLIGENCE);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_MENTAL),
                                    1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RESEARCH),
                                    0.4f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.CRAFTING),
                                    0.2f * value, multipliers, changelog);
            }
            tag = Globals.GetInstanceFromDB <Tag>(TAG.WISDOM);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_MENTAL),
                                    0.5f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.LUCK),
                                    0.1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RITUALS),
                                    0.2f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.CRAFTING),
                                    0.4f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.GATHERING),
                                    0.2f * value, multipliers, changelog);
            }

            tag = Globals.GetInstanceFromDB <Tag>(TAG.MYSTICISM);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_SPIRIT),
                                    1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RESEARCH),
                                    0.2f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RITUALS),
                                    0.4f * value, multipliers, changelog);
            }
            tag = Globals.GetInstanceFromDB <Tag>(TAG.DESTINY);
            if (a.finalAttributes.ContainsKey(tag))
            {
                FInt value = a.finalAttributes[tag];
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.MAX_HEALTH_SPIRIT),
                                    .5f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.GATHERING),
                                    0.1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RESEARCH),
                                    0.1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag, (Tag)TAG.LUCK,
                                    0.4f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.RITUALS),
                                    0.1f * value, multipliers, changelog);
                SimpleApplyModifier(a.finalAttributes, tag,
                                    Globals.GetInstanceFromDB <Tag>(TAG.CRAFTING),
                                    0.1f * value, multipliers, changelog);
            }



            //Apply all values to their parents so that they can be sampled easy later
            //we are using presorted list which ensures that we will process leafs first, therefore
            //no parent would be processed before its child to ensure that parent can influence
            //its own parents including this bonus without double processing
            List <Tag> tags = DBTypeUtils <Tag> .GetParentSortedType();

            foreach (Tag t in tags)
            {
                if (a.finalAttributes.ContainsKey(t))
                {
                    FInt          bonus   = a.finalAttributes[t];
                    HashSet <Tag> parents = DBTypeUtils <Tag> .GetParentsOf(t);

                    foreach (Tag parent in parents)
                    {
                        if (parent == null)
                        {
                            Debug.LogError("[ERROR]" + parent);
                        }
                        if (a.finalAttributes.ContainsKey(parent))
                        {
                            a.finalAttributes[parent] += bonus;
                        }
                        else
                        {
                            a.finalAttributes[parent] = bonus;
                        }
                    }
                }
            }

            if (c != null)
            {
                c.MaxCarry = a.finalAttributes[(Tag)TAG.PERSONAL_CARRY_LIMIT];
            }

            a.ClampAndScaleHP();
            a.ClearDirty();


            return(changelog);
        }
        static public string SI_ShieldUpImproved(object info)
        {
            Multitype <NetCard, NetSkill, NetBattlefield> data = info as Multitype <NetCard, NetSkill, NetBattlefield>;

            if (data != null)
            {
                var  ns    = data.t1;
                var  bf    = data.t2;
                FInt value = ns.GetFloatAttribute("TAG-CA_SHIELD");
                if (value == FInt.ZERO)
                {
                    if (bf.ChallengeType == EChallengeType.TypePhysical)
                    {
                        value = ns.GetFloatAttribute("TAG-SHIELDING_PHYSICAL");
                    }
                    else if (bf.ChallengeType == EChallengeType.TypeMental)
                    {
                        value = ns.GetFloatAttribute("TAG-SHIELDING_MENTAL");
                    }
                    else if (bf.ChallengeType == EChallengeType.TypeMental)
                    {
                        value = ns.GetFloatAttribute("TAG-SHIELDING_SPIRIT");
                    }
                }

                FInt f = GameplayUtils.GetDamageFor(data.t1, data.t0);
                return((value + f).ToInt().ToString());
            }

            Multitype <SkillInstance, Subskill, ClientEntityCharacter> dInfo = info as Multitype <SkillInstance, Subskill, ClientEntityCharacter>;
            SkillInstance         si        = dInfo.t0;
            Subskill              ss        = dInfo.t1;
            ClientEntityCharacter character = dInfo.t2;
            var dataInWorld = si.GetCurrentSkillAttributes()[ss];

            if (dataInWorld.attributes != null && dataInWorld.attributes.Count > 0)
            {
                FInt extra = FInt.ZERO;

                string st = null;
                foreach (var v in ss.challengeTypes)
                {
                    if (character != null)
                    {
                        extra = GameplayUtils.GetDamageFor(si, ss, character, v);
                    }

                    FInt   value = dataInWorld.GetFInt("TAG-CA_SHIELD");
                    string color = "";

                    switch (v)
                    {
                    case EChallengeType.TypePhysical:
                        if (value == FInt.ZERO)
                        {
                            value = dataInWorld.GetFInt("TAG-SHIELDING_PHYSICAL");
                        }
                        color = "XML_COLOR-PHYSICAL";
                        break;

                    case EChallengeType.TypeMental:
                        if (value == FInt.ZERO)
                        {
                            value = dataInWorld.GetFInt("TAG-SHIELDING_MENTAL");
                        }
                        color = "XML_COLOR-MENTAL";
                        break;

                    case EChallengeType.TypeSpirit:
                        if (value == FInt.ZERO)
                        {
                            value = dataInWorld.GetFInt("TAG-SHIELDING_SPIRIT");
                        }
                        color = "XML_COLOR-SPIRITUAL";
                        break;
                    }

                    if (st == null)
                    {
                        st = "";
                    }
                    else
                    {
                        st += "|";
                    }

                    if (extra != FInt.ZERO)
                    {
                        st += ColorUtils.GetColorAsTextTag(color) +
                              extra +
                              ColorUtils.GetColorAsTextTag("XML_COLOR-NORMAL_FONT") +
                              " [+" + value + "]";
                    }
                    else
                    {
                        st += " [+" + value + "]";
                    }
                }
                return(st != null ? st : "");
            }

            return("");
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="bf">general battlefield information</param>
        /// <param name="q">queue element which is already executed which trigers this skill</param>
        /// <param name="stack">Items which are still in stack including "q", which most likely is first element</param>
        /// <param name="previousItems">Queue items which were already executed in order they were executed</param>
        /// <param name="random">random generator specific to this thread</param>
        /// <returns></returns>
        /// <summary>
        /// Basic damage
        /// </summary>
        static public object Act_Damage_Procedural(
            NetBattlefield bf,
            NetQueueItem q,
            List <NetQueueItem> stack,
            List <NetQueueItem> previousItems,
            MHRandom random)
        {
            NetSkill ns    = q.GetNetSkill(bf);
            NetCard  owner = bf.GetCardByID(ns.OwnerCardID);

            NetCard target = null;

            if (NetType.IsNullOrEmpty(q.Targets))
            {
                return(null);
            }

            int  flags   = ns.Flags;
            bool essence = (flags & (int)EActivatorBlocks.Essence) > 0;
            bool ancient = (flags & (int)EActivatorBlocks.Ancient) > 0;
            bool gray    = !ancient && !essence;

            FInt damage = GameplayUtils.GetDamageFor(ns, owner);
//             if ((flags & (int)SkillGenerator.EActivatorBlocks.Additive) > 0)
//             {
//
//                 if (essence)
//                 {
//                     //essence is estimated to be equal between additive and multiplicative at
//                     // value of 10  (A x 0.2 + 8) ~ (A = 10)
//                     damage = owner.GetSkillCastingAdditiveStrength(ns, SkillGenerator.ESSENCE_ADDITIVE_BASE);
//                 }
//                 else if(ancient)
//                 {
//                     //essence is estimated to be equal between additive and multiplicative at
//                     // value of 15  (A x 0.2 + 12) ~ (A = 15)
//                     damage = owner.GetSkillCastingAdditiveStrength(ns, SkillGenerator.ANCIENT_ADDITIVE_BASE);
//                 }
//                 else
//                 {
//                     //essence is estimated to be equal between additive and multiplicative at
//                     // value of 6  (A x 0.2 + 5) ~ (A = 6)
//                     damage = owner.GetSkillCastingAdditiveStrength(ns, SkillGenerator.GRAY_ADDITIVE_BASE);
//                 }
//             }
//             else
//             {
//                 damage = owner.GetSkillCastingStrength(ns);
//             }

            bool trueDamage   = (flags & (int)EActivatorBlocks.TrueDamage) > 0;
            bool poisonDamage = (flags & (int)EActivatorBlocks.PoisonDamage) > 0;
            bool lifeLeech    = (flags & (int)EActivatorBlocks.LifeLeech) > 0;
            bool shieldLeech  = (flags & (int)EActivatorBlocks.ShieldLeech) > 0;
            bool additive     = (flags & (int)EActivatorBlocks.Additive) > 0;

            int lifeLeeched   = 0;
            int shieldLeeched = 0;

            #region Primary targets
            foreach (var v in q.Targets.value)
            {
                target = bf.ConvertPositionIDToCard(v);
                if (target != null)
                {
                    FInt dmg = damage;
                    if (poisonDamage && target.IsWounded())
                    {
                        if (essence)
                        {
                            dmg *= 1.35f;
                        }
                        else
                        {
                            dmg *= 1.6f;
                        }
                    }

                    if (trueDamage)
                    {
                        if (essence)
                        {
                            target.ReciveTrueDamageEssence(dmg, bf, q, v);
                        }
                        else //no test for ancient
                        {
                            target.ReciveTrueDamageAncient(dmg, bf, q, v);
                        }
                    }
                    else
                    {
                        target.ReciveNormalDamage(dmg, bf, q, v);
                    }

                    if (lifeLeech)
                    {
                        if (essence)
                        {
                            lifeLeeched += (dmg * 0.4f).ToInt();
                        }
                        else
                        {
                            lifeLeeched += (dmg * 0.8f).ToInt();
                        }
                    }
                    if (shieldLeech)
                    {
                        if (essence)
                        {
                            shieldLeeched += (dmg * 0.5f).ToInt();
                        }
                        else
                        {
                            shieldLeeched += (dmg * 1.0f).ToInt();
                        }
                    }
                }
            }
            #endregion
            #region Secondary targets
            ////do splash if needed
            if (!NetType.IsNullOrEmpty(q.SecondaryTargets))
            {
                bool splashBonus = (flags & (int)EActivatorBlocks.AOE) > 0;

                if (gray || !splashBonus)
                {
                    damage *= 0.5f;
                }
                else
                {
                    //this is !gray && AOE
                    if (essence)
                    {
                        damage *= 0.75f;
                    }
                    if (ancient)
                    {
                        damage *= 1f;
                    }
                }

                //ancient damage is 100% splash

                foreach (var v in q.SecondaryTargets.value)
                {
                    target = bf.ConvertPositionIDToCard(v);
                    if (target != null)
                    {
                        FInt dmg = damage;
                        if (poisonDamage && target.IsWounded())
                        {
                            if (essence)
                            {
                                dmg *= 1.35f;
                            }
                            else
                            {
                                dmg *= 1.6f;
                            }
                        }

                        if (trueDamage)
                        {
                            if (essence)
                            {
                                target.ReciveTrueDamageEssence(dmg, bf, q, v);
                            }
                            else //no test for ancient
                            {
                                target.ReciveTrueDamageAncient(dmg, bf, q, v);
                            }
                        }
                        else
                        {
                            target.ReciveNormalDamage(dmg, bf, q, v);
                        }

                        if (lifeLeech)
                        {
                            if (essence)
                            {
                                lifeLeeched += (dmg * 0.4f).ToInt();
                            }
                            else
                            {
                                lifeLeeched += (dmg * 0.8f).ToInt();
                            }
                        }
                        if (shieldLeech)
                        {
                            if (essence)
                            {
                                shieldLeeched += (dmg * 0.5f).ToInt();
                            }
                            else
                            {
                                shieldLeeched += (dmg * 1.0f).ToInt();
                            }
                        }
                    }
                }
            }
            #endregion

            #region Leech
            if (lifeLeeched > 0)
            {
                FInt max = owner.GetCA_MAX_HEALTH();
                FInt cur = owner.GetCA_HEALTH();
                if (cur < max)
                {
                    if (lifeLeeched > max - cur)
                    {
                        owner.SetCA_HEALTH(max);
                    }
                    else
                    {
                        owner.SetCA_HEALTH(cur + lifeLeeched);
                    }
                }
            }
            if (shieldLeeched > 0)
            {
                FInt cur = owner.GetCA_SHIELD();
                owner.SetCA_SHIELD(cur + shieldLeeched);
            }
            #endregion


            return(null);
        }
        static public string SI_ProceduralDamage(object info)
        {
            Multitype <NetCard, NetSkill, NetBattlefield> data = info as Multitype <NetCard, NetSkill, NetBattlefield>;

            if (data != null)
            {
                return(GameplayUtils.GetDamageFor(data.t1, data.t0).ToString(false));
            }

            Multitype <SkillInstance, Subskill, ClientEntityCharacter> dInfo = info as Multitype <SkillInstance, Subskill, ClientEntityCharacter>;
            SkillInstance         si        = dInfo.t0;
            Subskill              ss        = dInfo.t1;
            ClientEntityCharacter character = dInfo.t2;

            var skillAttributes = si.GetCurrentSkillAttributes()[ss];
            int flags           = skillAttributes.GetFInt("ProceduralFlags").ToInt();

            string st = null;

            FInt  dmgBase = GameplayUtils.GetDamageFor(si, ss, null);
            float addBase = (flags & (int)EActivatorBlocks.Additive) > 0 ?  GameplayUtils.DamageNormalToAdditive(dmgBase) : 0f;

            var a = new FInt(addBase);

            if (ss.challengeTypes == null || character == null)
            {
                if (addBase > 0)
                {
                    st = "x" + dmgBase.ToString(true) + " [+" + a.ToString(true) + "]";
                }
                else
                {
                    st = "x" + dmgBase.ToString(true);
                }
            }
            else
            {
                foreach (var v in ss.challengeTypes)
                {
                    string color = "";
                    switch (v)
                    {
                    case EChallengeType.TypePhysical:
                        color = "XML_COLOR-PHYSICAL";
                        break;

                    case EChallengeType.TypeMental:
                        color = "XML_COLOR-MENTAL";
                        break;

                    case EChallengeType.TypeSpirit:
                        color = "XML_COLOR-SPIRITUAL";
                        break;
                    }

                    if (st == null)
                    {
                        st = "";
                    }
                    else
                    {
                        st += "|";
                    }

                    if (addBase > 0)
                    {
                        st += "x" + dmgBase.ToString(true) + "[+" + a.ToString(true) + "]" +
                              " ( " +
                              ColorUtils.GetColorAsTextTag(color) +
                              GameplayUtils.GetDamageFor(si, ss, character, v, true).ToString(false) +
                              ColorUtils.GetColorAsTextTag("XML_COLOR-NORMAL_FONT") +
                              " )";
                    }
                    else
                    {
                        st += "x" + dmgBase.ToString(true) +
                              " ( " +
                              ColorUtils.GetColorAsTextTag(color) +
                              GameplayUtils.GetDamageFor(si, ss, character, v).ToString(false) +
                              ColorUtils.GetColorAsTextTag("XML_COLOR-NORMAL_FONT") +
                              " )";
                    }
                }
            }
            return(st);
        }