public int GetCurrentStarsWinning() { if (levelID == 0) { return(0); } return(GameplayUtils.StarsWon(LivesRemoved, objetives)); }
public Game() { AIScore = 0; playerScore = 0; draws = 0; db = new DBManager(); util = new Utilities(); gameplay = new GameplayUtils(); }
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); }
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); } }
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); } }
/// <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); }