public FormationUnit ReplaceUnit(MonsterData data, FormationUnit oldUnit, GameObject newObject, bool roll = false, float carryHp = 0) { #region Companion var companionRecord = Companions.Find(record => record.TargetUnit == oldUnit || record.CompanionUnit == oldUnit); if (companionRecord != null) { Companions.Remove(companionRecord); if (companionRecord.CompanionUnit == oldUnit) { foreach (var buff in companionRecord.CompanionComponent.Buffs) { companionRecord.TargetUnit.Character.RemoveSourceBuff(buff, BuffSourceType.Adventure); } companionRecord.TargetUnit.OverlaySlot.UpdateOverlay(); } } #endregion FormationUnit newUnit = Instantiate(newObject).GetComponent <FormationUnit>(); newUnit.Initialize(new Monster(data), oldUnit.Rank, Team.Monsters); newUnit.transform.SetParent(oldUnit.transform.parent, false); newUnit.transform.position = oldUnit.transform.position; newUnit.Party = oldUnit.Party; newUnit.Party.Units[newUnit.Party.Units.IndexOf(oldUnit)] = newUnit; newUnit.Formation = oldUnit.Formation; RaidSceneManager.TorchMeter.ApplyBuffsForUnit(newUnit); oldUnit.OverlaySlot.LockOnUnit(newUnit); oldUnit.RankSlot.PutInSlot(newUnit); if (carryHp != 0) { newUnit.Character.Health.ValueRatio = carryHp; } newUnit.CombatInfo.PrepareForBattle(oldUnit.CombatInfo.CombatId, newUnit.Character as Monster, true); DarkestSoundManager.ExecuteNarration("change_monster_class", NarrationPlace.Raid, oldUnit.Character.Class, newUnit.Character.Class); if (!newUnit.RankSlot.Ranks.facingRight) { newUnit.InstantFlip(); } newUnit.ResetAnimations(); if (roll) { for (int i = 0; i < Round.OrderedUnits.Count; i++) { if (Round.OrderedUnits[i] == oldUnit) { Round.OrderedUnits[i] = newUnit; } } } else { Round.OrderedUnits.RemoveAll(unit => unit == oldUnit); } if (SharedHealth.IsActive && data.SharedHealth != null) { SharedHealth.SharedUnits.Remove(oldUnit); SharedHealth.SharedUnits.Add(newUnit); newUnit.Character[AttributeType.HitPoints, true] = SharedHealth.Health; } Destroy(oldUnit.gameObject); #region Companion Check if (data.Companion != null) { var companion = newUnit.Formation.party.Units.Find(unit => unit.Character.Class == data.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit, companion)); foreach (var buff in data.Companion.Buffs) { newUnit.Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.OverlaySlot.UpdateOverlay(); } } for (int i = 0; i < newUnit.Party.Units.Count; i++) { if (newUnit.Party.Units[i] != newUnit && newUnit.Party.Units[i].Character.IsMonster) { var monster = newUnit.Party.Units[i].Character as Monster; if (monster.Data.Companion != null) { var companion = newUnit.Party.Units.Find(unit => unit.Character.Class == monster.Data.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit.Party.Units[i], companion)); foreach (var buff in monster.Data.Companion.Buffs) { newUnit.Party.Units[i].Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.Party.Units[i].OverlaySlot.UpdateOverlay(); } } } } #endregion return(newUnit); }
public abstract bool SelectTarget(FormationUnit performer, MonsterBrainDecision decision);
public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect) { return(ApplyInstant(performer, target, effect)); }
public void ApplyIndependent(FormationUnit target) { SubEffects.ForEach(sub => sub.Apply(null, target, this)); }
public override bool SelectTarget(FormationUnit performer, MonsterBrainDecision decision) { if (!(SpecificCombatSkillId == "" || SpecificCombatSkillId == decision.SelectedSkill.Id)) { return(false); } if (decision.SelectedSkill.TargetRanks.IsSelfFormation && !IsFriendlyTargetDesire) { return(false); } if (!(decision.SelectedSkill.TargetRanks.IsSelfFormation || decision.SelectedSkill.TargetRanks.IsSelfTarget) && !IsEnemyTargetDesire) { return(false); } var availableTargets = new List <FormationUnit>(decision.TargetInfo.Targets); if (Parameters[TargetSelectParameter.CanTargetDeathsDoor].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetDeathsDoor].Value) { availableTargets.RemoveAll(unit => unit.Character.AtDeathsDoor); } } if (Parameters[TargetSelectParameter.CanTargetLastHero].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetLastHero].Value) { availableTargets.RemoveAll(unit => performer.CombatInfo.LastCombatSkillTarget == unit.CombatInfo.CombatId); } } if (Parameters[TargetSelectParameter.CanTargetNotOverstressed].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetNotOverstressed].Value) { availableTargets.RemoveAll(unit => !unit.Character.IsOverstressed); } } if (Parameters[TargetSelectParameter.CanTargetAfflicted].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetAfflicted].Value) { availableTargets.RemoveAll(unit => unit.Character.IsAfflicted); } } if (Parameters[TargetSelectParameter.CanTargetVirtued].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetVirtued].Value) { availableTargets.RemoveAll(unit => unit.Character.IsVirtued); } } if (availableTargets.Count > 0) { decision.TargetInfo.Targets.Clear(); if (decision.SelectedSkill.TargetRanks.IsMultitarget) { decision.TargetInfo.Targets.AddRange(availableTargets); return(true); } else { float lowestRes = float.MaxValue; FormationUnit lowestResTarget = null; foreach (var target in availableTargets) { if (target.Character[ResistanceType].ModifiedValue < lowestRes) { lowestRes = target.Character[ResistanceType].ModifiedValue; lowestResTarget = target; } } decision.TargetInfo.Targets.Add(lowestResTarget); availableTargets.Remove(lowestResTarget); if (decision.SelectedSkill.ExtraTargetsChance > 0 && availableTargets.Count > 0 && RandomSolver.CheckSuccess(decision.SelectedSkill.ExtraTargetsChance)) { lowestRes = 500f; lowestResTarget = null; foreach (var target in availableTargets) { if (target.Character[ResistanceType].ModifiedValue < lowestRes) { lowestRes = target.Character[ResistanceType].ModifiedValue; lowestResTarget = target; } } if (lowestResTarget != null) { decision.TargetInfo.Targets.Add(lowestResTarget); } return(true); } return(true); } } return(false); }
public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } if (StatAddBuffs.Count == 0 && StatMultBuffs.Count == 0) { return(false); } if (effect.BooleanParams[EffectBoolParams.CurioResult].HasValue) { if (effect.BooleanParams[EffectBoolParams.CurioResult].Value) { ApplyBuff(target, effect); RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Buff); target.OverlaySlot.UpdateOverlay(); return(true); } else { float debuffChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; debuffChance -= target.Character.GetSingleAttribute(AttributeType.Debuff).ModifiedValue; if (performer != null && performer.Character is Hero) { debuffChance += performer.Character.GetSingleAttribute(AttributeType.DebuffChance).ModifiedValue; } debuffChance = performer == target ? 1 : Mathf.Clamp(debuffChance, 0, 0.95f); if (RandomSolver.CheckSuccess(debuffChance)) { ApplyBuff(target, effect); RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Debuff); target.OverlaySlot.UpdateOverlay(); return(true); } RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.DebuffResist); return(false); } } else { if (IsPositive()) { ApplyBuff(target, effect); RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Buff); target.OverlaySlot.UpdateOverlay(); return(true); } else { float debuffChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; debuffChance -= target.Character.GetSingleAttribute(AttributeType.Debuff).ModifiedValue; if (performer != null && performer.Character is Hero) { debuffChance += performer.Character.GetSingleAttribute(AttributeType.DebuffChance).ModifiedValue; } debuffChance = performer == target ? 1 : Mathf.Clamp(debuffChance, 0, 0.95f); if (RandomSolver.CheckSuccess(debuffChance)) { ApplyBuff(target, effect); RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Debuff); target.OverlaySlot.UpdateOverlay(); return(true); } RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.DebuffResist); return(false); } } }
public void ShowPopupMessage(FormationUnit unit, PopupMessageType type, string parameter = "", float ripOffset = 0) { PopupMessage popupMessage = Instantiate(popupText.gameObject).GetComponent<PopupMessage>(); popupMessage.RectTransform.SetParent(eventRect, false); Spine.Bone bone = unit.CurrentState.Skeleton.FindBone("fxhead") ?? unit.CurrentState.Skeleton.FindBone("fxskill"); switch(type) { case PopupMessageType.DeathBlow: popupMessage.SetColor(PopupColors["pop_text_deathblow"], PopupColors["pop_text_outline_deathblow"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_deathblow")); popupMessage.SetRotation(new Vector3(0, 0, 8)); break; case PopupMessageType.DeathsDoor: bone = unit.CurrentState.Skeleton.FindBone("fxchest"); popupMessage.SetColor(PopupColors["pop_text_death_avoided"], PopupColors["pop_text_outline_death_avoided"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_death_avoided")); popupMessage.SetIcon("poptext_death_avoided"); popupMessage.SetRotation(new Vector3(0, 0, 8)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/combat/deaths_door"); break; case PopupMessageType.HeartAttack: popupMessage.SetColor(PopupColors["pop_text_heart_attack"], PopupColors["pop_text_outline_heart_attack"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_heart_attack")); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/heart_attack"); break; case PopupMessageType.RetreatFailed: popupMessage.SetColor(PopupColors["pop_text_heart_attack"], PopupColors["pop_text_outline_heart_attack"]); popupMessage.SetMessage(LocalizationManager.GetString("retreat_fail_announcement")); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/combat/retreat_fail"); break; case PopupMessageType.Miss: popupMessage.SetColor(PopupColors["pop_text_miss"], PopupColors["pop_text_outline_miss"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_miss")); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); break; case PopupMessageType.Dodge: popupMessage.SetColor(PopupColors["pop_text_miss"], PopupColors["pop_text_outline_miss"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_dodge")); popupMessage.SetRotation(new Vector3(0, 0, 4)); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); break; case PopupMessageType.ZeroDamage: popupMessage.SetColor(PopupColors["pop_text_no_damage"], PopupColors["pop_text_outline_no_damage"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_no_damage")); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); break; case PopupMessageType.Damage: popupMessage.SetColor(PopupColors["pop_text_damage"], PopupColors["pop_text_outline_damage"]); popupMessage.SetMessage(parameter); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); popupMessage.SkillMessage.fontSize = 70; break; case PopupMessageType.CritDamage: popupMessage.SetColor(PopupColors["pop_text_crit_damage"], PopupColors["pop_text_outline_crit_damage"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_crittxt") + "\n" + parameter); popupMessage.SetOffset(new Vector3(0, ripOffset, 0)); popupMessage.SkillMessage.fontSize = 72; break; case PopupMessageType.Stress: popupMessage.SetColor(PopupColors["pop_text_stress_damage"], PopupColors["pop_text_outline_stress_damage"]); popupMessage.SetMessage(parameter); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/stress_up"); popupMessage.SkillMessage.fontSize = 70; break; case PopupMessageType.StressHeal: popupMessage.SetColor(PopupColors["pop_text_stress_reduce"], PopupColors["pop_text_outline_stress_reduce"]); popupMessage.SetMessage(parameter); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/stress_down"); popupMessage.SkillMessage.fontSize = 70; break; case PopupMessageType.Heal: popupMessage.SetColor(PopupColors["pop_text_heal"], PopupColors["pop_text_outline_heal"]); popupMessage.SetMessage(parameter); popupMessage.SkillMessage.fontSize = 70; break; case PopupMessageType.CritHeal: popupMessage.SetColor(PopupColors["pop_text_heal_crit"], PopupColors["pop_text_outline_heal_crit"]); popupMessage.SetMessage(parameter); popupMessage.SkillMessage.fontSize = 72; break; case PopupMessageType.Pass: popupMessage.SetColor(PopupColors["pop_text_pass"], PopupColors["pop_text_outline_pass"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_pass")); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/pass"); break; case PopupMessageType.Tagged: popupMessage.SetColor(PopupColors["pop_text_tagged"], PopupColors["pop_text_outline_tagged"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_tagged")); popupMessage.SetIcon("poptext_tagged"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/marked"); break; case PopupMessageType.Untagged: popupMessage.SetColor(PopupColors["pop_text_tagged"], PopupColors["pop_text_outline_tagged"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_untagged")); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/marked"); popupMessage.SetRotation(new Vector3(0, 0, 6)); break; case PopupMessageType.Bleed: popupMessage.SetColor(PopupColors["pop_text_bleed"], PopupColors["pop_text_outline_bleed"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_bleed")); popupMessage.SetIcon("poptext_bleed"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/bleed_onset"); break; case PopupMessageType.Poison: popupMessage.SetColor(PopupColors["pop_text_poison"], PopupColors["pop_text_outline_poison"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_poison")); popupMessage.SetIcon("poptext_poison"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/poison_onset"); break; case PopupMessageType.Buff: popupMessage.SetColor(PopupColors["pop_text_buff"], PopupColors["pop_text_outline_buff"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_buff")); popupMessage.SetIcon("poptext_buff"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/buff"); break; case PopupMessageType.Debuff: popupMessage.SetColor(PopupColors["pop_text_debuff"], PopupColors["pop_text_outline_debuff"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_debuff")); popupMessage.SetIcon("poptext_debuff"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/debuff"); break; case PopupMessageType.Stunned: popupMessage.SetColor(PopupColors["pop_text_stun"], PopupColors["pop_text_outline_stun"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_stun")); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/stun_onset"); break; case PopupMessageType.Unstun: popupMessage.SetColor(PopupColors["pop_text_stun_clear"], PopupColors["pop_text_outline_stun_clear"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_stun")); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/stun_off"); break; case PopupMessageType.Cured: popupMessage.SetColor(PopupColors["pop_text_cured"], PopupColors["pop_text_outline_cured"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_cured")); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/cured"); break; case PopupMessageType.BleedResist: if(unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_bleed_resist"], PopupColors["pop_text_outline_bleed_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_bleed_resist")); popupMessage.SetIcon("poptext_bleed_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.PoisonResist: if (unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_poison_resist"], PopupColors["pop_text_outline_poison_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_blight_resist")); popupMessage.SetIcon("poptext_poison_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.StunResist: if (unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_stun_resist"], PopupColors["pop_text_outline_stun_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_stun_resist")); popupMessage.SetIcon("poptext_stun_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.MoveResist: if (unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_move_resist"], PopupColors["pop_text_outline_move_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_move_resist")); popupMessage.SetIcon("poptext_move_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.DebuffResist: if (unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_debuff_resist"], PopupColors["pop_text_outline_debuff_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_debuff_resist")); popupMessage.SetIcon("poptext_debuff_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.DiseaseResist: if (unit.Character.DisplayModifier != null && unit.Character.DisplayModifier.DisabledPopups.Contains("resist")) { Destroy(popupMessage.gameObject); return; } popupMessage.SetColor(PopupColors["pop_text_disease_resist"], PopupColors["pop_text_outline_disease_resist"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_disease_resist")); popupMessage.SetIcon("poptext_disease_resist"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/resist"); break; case PopupMessageType.Disease: popupMessage.SetColor(PopupColors["pop_text_disease_resist"], PopupColors["pop_text_outline_disease_resist"]); popupMessage.SetMessage(parameter); popupMessage.SetOffset(new Vector3(0, 70, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/quirk_neg"); break; case PopupMessageType.PositiveQuirk: popupMessage.SetColor(PopupColors["notable"], Color.black); popupMessage.SetMessage(parameter); popupMessage.SetOffset(new Vector3(0, 70, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/quirk_pos"); break; case PopupMessageType.NegativeQuirk: popupMessage.SetColor(PopupColors["harmful"], Color.black); popupMessage.SetMessage(parameter); popupMessage.SetOffset(new Vector3(0, 70, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/quirk_neg"); break; case PopupMessageType.QuirkRemoved: popupMessage.SetColor(PopupColors["notable"], Color.black); popupMessage.SetMessage(parameter + LocalizationManager.GetString("curio_announcement_purge_format")); popupMessage.SetOffset(new Vector3(0, 70, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/char/quirk_pos"); break; case PopupMessageType.DiseaseCured: popupMessage.SetMessage(string.Format(LocalizationManager.GetString("str_ui_disease_cured"), parameter)); popupMessage.SetColor(PopupColors["pop_text_disease_resist"], PopupColors["pop_text_outline_disease_resist"]); popupMessage.SetIcon("poptext_disease_resist"); popupMessage.SetOffset(new Vector3(0, 30, 0)); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/cured"); break; case PopupMessageType.Guard: popupMessage.SetColor(PopupColors["pop_text_guard"], PopupColors["pop_text_outline_guard"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_guard")); popupMessage.SetIcon("poptext_guard"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/guard"); break; case PopupMessageType.Riposte: popupMessage.SetColor(PopupColors["pop_text_riposte"], PopupColors["pop_text_outline_riposte"]); popupMessage.SetMessage(LocalizationManager.GetString("str_ui_riposte")); popupMessage.SetIcon("poptext_riposte"); FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/riposte_enabled"); break; } Vector3 screenPosition = RaidSceneManager.DungeonPositionToScreen( unit.RectTransform.TransformPoint(bone.WorldX, bone.WorldY, 0)); popupMessage.RectTransform.position = new Vector3(screenPosition.x, screenPosition.y, 0); popupMessage.FollowXBone(bone, unit); popupMessage.gameObject.SetActive(true); }
public void SkillExecuted() { ActionType = CampUsageResultType.Wait; SelectedTarget = null; }
public void ScrollClosed() { SelectedTarget = null; gameObject.SetActive(false); }
public static HeroActionInfo CalculateSkillPotential(FormationUnit performerUnit, FormationUnit targetUnit, CombatSkill skill) { var target = targetUnit.Character; var performer = performerUnit.Character; if (skill.Category == SkillCategory.Heal || skill.Category == SkillCategory.Support) { HeroActionInfo.UpdateInfo(false, 0, 0, 0, 0); return(HeroActionInfo); } else { ApplyConditions(performerUnit, targetUnit, skill); float accuracy = skill.Accuracy + performer.Accuracy; float hitChance = Mathf.Clamp(accuracy - target.Dodge, 0, 0.95f); if (skill.CanMiss == false) { hitChance = 1; } else if (target.BattleModifiers != null && target.BattleModifiers.CanBeMissed == false) { hitChance = 1; } float initialMinDamage = performer is Hero ? performer.MinDamage * (1 + skill.DamageMod) : skill.DamageMin * performer.DamageMod; float initialMaxDamage = performer is Hero ? performer.MaxDamage * (1 + skill.DamageMod) : skill.DamageMax * performer.DamageMod; int minDamage = Mathf.CeilToInt(initialMinDamage * (1 - target.Protection)); if (minDamage < 0) { minDamage = 0; } int maxDamage = Mathf.CeilToInt(initialMaxDamage * (1 - target.Protection)); if (maxDamage < 0) { maxDamage = 0; } if (target.BattleModifiers != null && target.BattleModifiers.CanBeDamagedDirectly == false) { minDamage = 0; maxDamage = 0; } float critChance = 0; if (skill.IsCritValid) { critChance = performer.GetSingleAttribute(AttributeType.CritChance).ModifiedValue + skill.CritMod; } RemoveConditions(performerUnit); RemoveConditions(targetUnit); HeroActionInfo.UpdateInfo(true, hitChance, critChance, minDamage, maxDamage); return(HeroActionInfo); } }
public static void RemoveConditions(FormationUnit targetUnit) { targetUnit.Character.ApplyAllBuffRules(RaidSceneManager.Rules.GetIdleUnitRules(targetUnit)); targetUnit.Character.RemoveConditionalBuffs(); }
public static void ExecuteSkill(FormationUnit performerUnit, FormationUnit targetUnit, CombatSkill skill, SkillArtInfo artInfo) { SkillResult.Skill = skill; SkillResult.ArtInfo = artInfo; var target = targetUnit.Character; var performer = performerUnit.Character; ApplyConditions(performerUnit, targetUnit, skill); if (skill.Move != null && !performerUnit.CombatInfo.IsImmobilized) { if (skill.Move.Pullforward > 0) { performerUnit.Pull(skill.Move.Pullforward, false); } else if (skill.Move.Pushback > 0) { performerUnit.Push(skill.Move.Pushback, false); } } if (skill.Category == SkillCategory.Heal || skill.Category == SkillCategory.Support) { #region Heal if (skill.Heal != null) { float initialHeal = RandomSolver.Next(skill.Heal.MinAmount, skill.Heal.MaxAmount + 1) * (1 + performer.GetSingleAttribute(AttributeType.HpHealPercent).ModifiedValue); if (skill.IsCritValid) { float critChance = performer[AttributeType.CritChance].ModifiedValue + skill.CritMod / 100; if (RandomSolver.CheckSuccess(critChance)) { int critHeal = target.Heal(initialHeal * 1.5f, true); targetUnit.OverlaySlot.healthBar.UpdateHealth(target); SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critHeal, SkillResultType.CritHeal)); ApplyEffects(performerUnit, targetUnit, skill); if (targetUnit.Character.IsMonster == false) { DarkestDungeonManager.Data.Effects["crit_heal_stress_heal"].ApplyIndependent(targetUnit); } return; } } int heal = target.Heal(initialHeal, true); targetUnit.OverlaySlot.healthBar.UpdateHealth(target); SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, heal, SkillResultType.Heal)); ApplyEffects(performerUnit, targetUnit, skill); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Utility)); ApplyEffects(performerUnit, targetUnit, skill); } #endregion } else { #region Damage float accuracy = skill.Accuracy + performer.Accuracy; float hitChance = Mathf.Clamp(accuracy - target.Dodge, 0, 0.95f); float roll = (float)RandomSolver.NextDouble(); if (target.BattleModifiers != null && target.BattleModifiers.CanBeHit == false) { roll = float.MaxValue; } if (roll > hitChance) { if (!(skill.CanMiss == false || (target.BattleModifiers != null && target.BattleModifiers.CanBeMissed == false))) { if (roll > Mathf.Min(accuracy, 0.95f)) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Miss)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Dodge)); } ApplyEffects(performerUnit, targetUnit, skill); return; } } float initialDamage = performer is Hero? Mathf.Lerp(performer.MinDamage, performer.MaxDamage, (float)RandomSolver.NextDouble()) * (1 + skill.DamageMod) : Mathf.Lerp(skill.DamageMin, skill.DamageMax, (float)RandomSolver.NextDouble()) * performer.DamageMod; int damage = Mathf.CeilToInt(initialDamage * (1 - target.Protection)); if (damage < 0) { damage = 0; } if (target.BattleModifiers != null && target.BattleModifiers.CanBeDamagedDirectly == false) { damage = 0; } if (skill.IsCritValid) { float critChance = performer.GetSingleAttribute(AttributeType.CritChance).ModifiedValue + skill.CritMod; if (RandomSolver.CheckSuccess(critChance)) { int critDamage = target.TakeDamage(damage * 1.5f); targetUnit.OverlaySlot.healthBar.UpdateHealth(target); if (target.HasZeroHealth) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, true, SkillResultType.Crit)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, SkillResultType.Crit)); } ApplyEffects(performerUnit, targetUnit, skill); if (targetUnit.Character.IsMonster == false) { DarkestDungeonManager.Data.Effects["Stress 2"].ApplyIndependent(targetUnit); } return; } } damage = target.TakeDamage(damage); targetUnit.OverlaySlot.healthBar.UpdateHealth(target); if (target.HasZeroHealth) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, true, SkillResultType.Hit)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, SkillResultType.Hit)); } ApplyEffects(performerUnit, targetUnit, skill); return; #endregion } }
public static MonsterBrainDecision UseMonsterBrain(FormationUnit performer, string combatSkillOverride = null) { if (performer.Character.IsMonster) { var monster = performer.Character as Monster; if (combatSkillOverride == null) { var skillDesires = new List <SkillSelectionDesire>(monster.Brain.SkillDesireSet); var monsterBrainDecision = new MonsterBrainDecision(BrainDecisionType.Pass); while (skillDesires.Count != 0) { SkillSelectionDesire desire = RandomSolver.ChooseByRandom(skillDesires); if (desire != null && desire.SelectSkill(performer, monsterBrainDecision)) { var cooldown = monster.Brain.SkillCooldowns.Find(cd => cd.SkillId == monsterBrainDecision.SelectedSkill.Id); if (cooldown != null) { performer.CombatInfo.SkillCooldowns.Add(cooldown.Copy()); } RaidSceneManager.BattleGround.LastSkillUsed = monsterBrainDecision.SelectedSkill.Id; return(monsterBrainDecision); } else { skillDesires.Remove(desire); } } return(new MonsterBrainDecision(BrainDecisionType.Pass)); } else { var availableSkill = monster.Data.CombatSkills.Find(skill => skill.Id == combatSkillOverride); if (availableSkill != null && BattleSolver.IsSkillUsable(performer, availableSkill)) { var monsterBrainDecision = new MonsterBrainDecision(BrainDecisionType.Pass); monsterBrainDecision.Decision = BrainDecisionType.Perform; monsterBrainDecision.SelectedSkill = availableSkill; monsterBrainDecision.TargetInfo.Targets = GetSkillAvailableTargets(performer, monsterBrainDecision.SelectedSkill); monsterBrainDecision.TargetInfo.Type = monsterBrainDecision.SelectedSkill.TargetRanks.IsSelfTarget ? SkillTargetType.Self : monsterBrainDecision.SelectedSkill.TargetRanks.IsSelfFormation ? SkillTargetType.Party : SkillTargetType.Enemy; var availableTargetDesires = new List <TargetSelectionDesire>(monster.Brain.TargetDesireSet); while (availableTargetDesires.Count > 0) { TargetSelectionDesire desire = RandomSolver.ChooseByRandom(availableTargetDesires); if (desire.SelectTarget(performer, monsterBrainDecision)) { return(monsterBrainDecision); } else { availableTargetDesires.Remove(desire); } } return(new MonsterBrainDecision(BrainDecisionType.Pass)); } return(new MonsterBrainDecision(BrainDecisionType.Pass)); } } else { var hero = performer.Character as Hero; var availableSkills = hero.Mode == null ? new List <CombatSkill>(hero.CurrentCombatSkills).FindAll(skill => skill != null && IsSkillUsable(performer, skill)) : new List <CombatSkill>(hero.CurrentCombatSkills).FindAll(skill => skill.ValidModes.Contains(hero.CurrentMode.Id) && skill != null && IsSkillUsable(performer, skill)); if (availableSkills.Count != 0) { var monsterBrainDecision = new MonsterBrainDecision(BrainDecisionType.Pass); monsterBrainDecision.Decision = BrainDecisionType.Perform; monsterBrainDecision.SelectedSkill = availableSkills[RandomSolver.Next(availableSkills.Count)]; monsterBrainDecision.TargetInfo.Targets = GetSkillAvailableTargets(performer, monsterBrainDecision.SelectedSkill); monsterBrainDecision.TargetInfo.Type = monsterBrainDecision.SelectedSkill.TargetRanks.IsSelfTarget ? SkillTargetType.Self : monsterBrainDecision.SelectedSkill.TargetRanks.IsSelfFormation ? SkillTargetType.Party : SkillTargetType.Enemy; var availableTargets = new List <FormationUnit>(monsterBrainDecision.TargetInfo.Targets); if (availableTargets.Count > 0) { monsterBrainDecision.TargetInfo.Targets.Clear(); if (monsterBrainDecision.SelectedSkill.TargetRanks.IsMultitarget) { monsterBrainDecision.TargetInfo.Targets.AddRange(availableTargets); return(monsterBrainDecision); } else { int index = RandomSolver.Next(availableTargets.Count); monsterBrainDecision.TargetInfo.Targets.Add(availableTargets[index]); availableTargets.RemoveAt(index); return(monsterBrainDecision); } } return(new MonsterBrainDecision(BrainDecisionType.Pass)); } return(new MonsterBrainDecision(BrainDecisionType.Pass)); } }
public static bool IsPerformerSkillTargetable(CombatSkill skill, BattleFormation allies, BattleFormation enemies, FormationUnit performer) { if (skill.TargetRanks.IsSelfTarget) { if (skill.Heal != null && performer.CombatInfo.BlockedHealUnitIds.Contains(performer.CombatInfo.CombatId)) { return(false); } if (skill.IsBuffSkill && performer.CombatInfo.BlockedBuffUnitIds.Contains(performer.CombatInfo.CombatId)) { return(false); } return(true); } if (skill.TargetRanks.IsSelfFormation) { if (skill.IsSelfValid) { if (skill.Heal != null) { if (performer.CombatInfo.BlockedHealUnitIds.Contains(performer.CombatInfo.CombatId) == false) { return(true); } } else if (skill.IsBuffSkill) { if (performer.CombatInfo.BlockedBuffUnitIds.Contains(performer.CombatInfo.CombatId) == false) { return(true); } } else { return(true); } } for (int i = 0; i < allies.party.Units.Count; i++) { if (skill.Heal != null && performer.CombatInfo.BlockedHealUnitIds. Contains(allies.party.Units[i].CombatInfo.CombatId)) { continue; } if (skill.IsBuffSkill && performer.CombatInfo.BlockedBuffUnitIds. Contains(allies.party.Units[i].CombatInfo.CombatId)) { continue; } if (allies.party.Units[i] != performer && skill.TargetRanks.IsTargetableUnit(allies.party.Units[i])) { return(true); } } } else { for (int i = 0; i < enemies.party.Units.Count; i++) { if (skill.TargetRanks.IsTargetableUnit(enemies.party.Units[i])) { return(true); } } } return(false); }
public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } if (target.Party.Units.Count < 2) { return(false); } if (IsPartyShuffle) { foreach (var unit in target.Party.Units) { float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; moveChance -= unit.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue; if (performer != null && performer.Character is Hero) { moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue; } moveChance = Mathf.Clamp(moveChance, 0, 0.95f); if (RandomSolver.CheckSuccess(moveChance)) { var shuffleTargets = unit.Party.Units.FindAll(shuffle => shuffle != unit); var shuffleRoll = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)]; if (shuffleRoll.Rank < unit.Rank) { unit.Pull(unit.Rank - shuffleRoll.Rank); } else { unit.Push(shuffleRoll.Rank - unit.Rank); } return(true); } } return(true); } else { float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; moveChance -= target.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue; if (performer != null && performer.Character is Hero) { moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue; } moveChance = Mathf.Clamp(moveChance, 0, 0.95f); if (RandomSolver.CheckSuccess(moveChance)) { var shuffleTargets = target.Party.Units.FindAll(unit => unit != target); var shuffleRoll = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)]; if (shuffleRoll.Rank < target.Rank) { target.Pull(target.Rank - shuffleRoll.Rank); } else { target.Push(shuffleRoll.Rank - target.Rank); } return(true); } RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.MoveResist); return(false); } }
public bool IsTargetableUnit(FormationUnit unit) { return(Ranks.Exists(r => r >= unit.Rank && r <= unit.Rank + unit.Size - 1)); }
public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } if (StatAddBuffs.Count == 0 && StatMultBuffs.Count == 0) { return(false); } if (effect.BooleanParams[EffectBoolParams.CurioResult].HasValue) { if (effect.BooleanParams[EffectBoolParams.CurioResult].Value) { ApplyBuff(target, effect); return(true); } else { float debuffChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; debuffChance -= target.Character.GetSingleAttribute(AttributeType.Debuff).ModifiedValue; if (performer != null && performer.Character is Hero) { debuffChance += performer.Character.GetSingleAttribute(AttributeType.DebuffChance).ModifiedValue; } debuffChance = Mathf.Clamp(debuffChance, 0, 0.95f); if (performer == target) { debuffChance = 1; } if (RandomSolver.CheckSuccess(debuffChance)) { ApplyBuff(target, effect); return(true); } return(false); } } else { if (IsPositive()) { ApplyBuff(target, effect); return(true); } else { float debuffChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; debuffChance -= target.Character.GetSingleAttribute(AttributeType.Debuff).ModifiedValue; if (performer != null && performer.Character is Hero) { debuffChance += performer.Character.GetSingleAttribute(AttributeType.DebuffChance).ModifiedValue; } debuffChance = Mathf.Clamp(debuffChance, 0, 0.95f); if (performer == target) { debuffChance = 1; } if (RandomSolver.CheckSuccess(debuffChance)) { ApplyBuff(target, effect); return(true); } return(false); } } }
public CompanionRecord(FormationUnit target, FormationUnit companion) { TargetUnit = target; CompanionUnit = companion; }
public override void ApplyTargetConditions(FormationUnit performer, FormationUnit target, FormationUnit primaryTarget, Effect effect) { if ((TargetStatus == StatusType.None && TargetMonsterType == MonsterType.None) == false) { if (primaryTarget == null) { return; } if (TargetMonsterType != MonsterType.None) { if (primaryTarget.Character.IsMonster == false) { return; } if (!((Monster)primaryTarget.Character).Types.Contains(TargetMonsterType)) { return; } } if (TargetStatus != StatusType.None) { if (!primaryTarget.Character.GetStatusEffect(TargetStatus).IsApplied) { return; } } ApplyConditional(target); } }
public CaptureRecord(FormationUnit prisoner, FormationUnit captor, bool removeFromParty) { PrisonerUnit = prisoner; CaptorUnit = captor; RemoveFromParty = removeFromParty; }
public void FollowXBone(Spine.Bone bone, FormationUnit unit) { followBone = true; targetBone = bone; targetUnit = unit; }
public ControlRecord(FormationUnit prisoner, FormationUnit controller, int duration) { PrisonerUnit = prisoner; ControllUnit = controller; DurationLeft = duration; }
public void Apply(FormationUnit performer, FormationUnit target, SkillResult skillResult) { if (BooleanParams[EffectBoolParams.ApplyOnce].HasValue) { if (BooleanParams[EffectBoolParams.ApplyOnce].Value) { if (skillResult.AppliedEffects.Contains(this)) { return; } } } if (BooleanParams[EffectBoolParams.OnMiss] == false) { if (skillResult.Current.Type == SkillResultType.Miss || skillResult.Current.Type == SkillResultType.Dodge) { return; } } if (BooleanParams[EffectBoolParams.CanApplyAfterDeath] == false) { if (skillResult.Current.IsZeroed) { return; } } switch (TargetType) { case EffectTargetType.Performer: foreach (var subEffect in SubEffects) { subEffect.Apply(performer, performer, this); } break; case EffectTargetType.Target: foreach (var subEffect in SubEffects) { subEffect.Apply(performer, target, this); } break; case EffectTargetType.PerformersOther: foreach (var unit in performer.Party.Units) { if (unit != performer) { foreach (var subEffect in SubEffects) { subEffect.Apply(performer, unit, this); } } } break; case EffectTargetType.TargetGroup: foreach (var unit in target.Party.Units) { foreach (var subEffect in SubEffects) { subEffect.Apply(performer, unit, this); } } break; case EffectTargetType.Global: if (IntegerParams[EffectIntParams.Torch].HasValue) { if (IntegerParams[EffectIntParams.Torch] < 0) { RaidSceneManager.TorchMeter.DecreaseTorch(-IntegerParams[EffectIntParams.Torch].Value); } else { RaidSceneManager.TorchMeter.IncreaseTorch(IntegerParams[EffectIntParams.Torch].Value); } } foreach (var subEffect in SubEffects) { subEffect.Apply(performer, target, this); } break; } skillResult.AppliedEffects.Add(this); }
protected override bool IsValidTarget(FormationUnit target) { return(target.Character.HealthRatio < HpRatioThreshold); }
public override bool SelectTarget(FormationUnit performer, MonsterBrainDecision decision) { if (decision.SelectedSkill.Effects.Find(effect => effect.SubEffects.Find(subeffect => subeffect is CaptureEffect) != null) == null) { return(false); } if (!(SpecificCombatSkillId == "" || SpecificCombatSkillId == decision.SelectedSkill.Id)) { return(false); } if (decision.SelectedSkill.TargetRanks.IsSelfFormation && !IsFriendlyTargetDesire) { return(false); } if (!(decision.SelectedSkill.TargetRanks.IsSelfFormation || decision.SelectedSkill.TargetRanks.IsSelfTarget) && !IsEnemyTargetDesire) { return(false); } var availableTargets = new List <FormationUnit>(decision.TargetInfo.Targets); if (Parameters[TargetSelectParameter.CanTargetDeathsDoor].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetDeathsDoor].Value) { availableTargets.RemoveAll(unit => unit.Character.AtDeathsDoor); } } if (Parameters[TargetSelectParameter.CanTargetLastHero].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetLastHero].Value) { availableTargets.RemoveAll(unit => performer.CombatInfo.LastCombatSkillTarget == unit.CombatInfo.CombatId); } } if (Parameters[TargetSelectParameter.CanTargetNotOverstressed].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetNotOverstressed].Value) { availableTargets.RemoveAll(unit => !unit.Character.IsOverstressed); } } if (Parameters[TargetSelectParameter.CanTargetAfflicted].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetAfflicted].Value) { availableTargets.RemoveAll(unit => unit.Character.IsAfflicted); } } if (Parameters[TargetSelectParameter.CanTargetVirtued].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetVirtued].Value) { availableTargets.RemoveAll(unit => unit.Character.IsVirtued); } } if (availableTargets.Count > 0) { decision.TargetInfo.Targets.Clear(); if (decision.SelectedSkill.TargetRanks.IsMultitarget) { decision.TargetInfo.Targets.AddRange(availableTargets); return(true); } else { int index = Random.Range(0, availableTargets.Count); decision.TargetInfo.Targets.Add(availableTargets[index]); return(true); } } return(false); }
public abstract bool CheckBonusInitiative(FormationUnit performer);
public override bool SelectTarget(FormationUnit performer, MonsterBrainDecision decision) { if (!(SpecificCombatSkillId == "" || SpecificCombatSkillId == decision.SelectedSkill.Id)) { return(false); } if (decision.SelectedSkill.TargetRanks.IsSelfFormation && !IsFriendlyTargetDesire) { return(false); } if (!(decision.SelectedSkill.TargetRanks.IsSelfFormation || decision.SelectedSkill.TargetRanks.IsSelfTarget) && !IsEnemyTargetDesire) { return(false); } var availableTargets = new List <FormationUnit>(decision.TargetInfo.Targets). FindAll(target => target.Character.Class == AllyBaseClass); if (Parameters[TargetSelectParameter.CanTargetDeathsDoor].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetDeathsDoor].Value) { availableTargets.RemoveAll(unit => unit.Character.AtDeathsDoor); } } if (Parameters[TargetSelectParameter.CanTargetLastHero].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetLastHero].Value) { availableTargets.RemoveAll(unit => performer.CombatInfo.LastCombatSkillTarget == unit.CombatInfo.CombatId); } } if (Parameters[TargetSelectParameter.CanTargetNotOverstressed].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetNotOverstressed].Value) { availableTargets.RemoveAll(unit => !unit.Character.IsOverstressed); } } if (Parameters[TargetSelectParameter.CanTargetAfflicted].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetAfflicted].Value) { availableTargets.RemoveAll(unit => unit.Character.IsAfflicted); } } if (Parameters[TargetSelectParameter.CanTargetVirtued].HasValue) { if (!Parameters[TargetSelectParameter.CanTargetVirtued].Value) { availableTargets.RemoveAll(unit => unit.Character.IsVirtued); } } if (availableTargets.Count > 0) { decision.TargetInfo.Targets.Clear(); if (decision.SelectedSkill.TargetRanks.IsMultitarget) { decision.TargetInfo.Targets.AddRange(availableTargets); return(true); } else { int index = Random.Range(0, availableTargets.Count); decision.TargetInfo.Targets.Add(availableTargets[index]); availableTargets.RemoveAt(index); if (decision.SelectedSkill.ExtraTargetsChance > 0 && availableTargets.Count > 0 && RandomSolver.CheckSuccess(decision.SelectedSkill.ExtraTargetsChance)) { int sideTargetIndex = Random.Range(0, availableTargets.Count); decision.TargetInfo.Targets.Add(availableTargets[sideTargetIndex]); return(true); } return(true); } } return(false); }
public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } if (effect.IntegerParams[EffectIntParams.Chance].HasValue) { if (!RandomSolver.CheckSuccess((float)effect.IntegerParams[EffectIntParams.Chance].Value / 100)) { return(false); } } List <int> summonPool = new List <int>(); List <float> chancePool = new List <float>(SummonChances); for (int i = 0; i < SummonMonsters.Count; i++) { summonPool.Add(i); } for (int i = 0; i < SummonCount; i++) { if (summonPool.Count == 0) { break; } int rolledIndex = RandomSolver.ChooseRandomIndex(chancePool); int summonIndex = summonPool[rolledIndex]; if (SummonLimits.Count > 0) { if (SummonLimits[summonIndex] <= performer.Party.Units.FindAll(unit => unit.Character.Name == SummonMonsters[summonIndex]).Count) { i--; summonPool.RemoveAt(rolledIndex); chancePool.RemoveAt(rolledIndex); continue; } } if (performer.Formation.AvailableSummonSpace < DarkestDungeonManager.Data.Monsters[SummonMonsters[summonIndex]].Size) { i--; summonPool.RemoveAt(rolledIndex); chancePool.RemoveAt(rolledIndex); continue; } MonsterData summonData = DarkestDungeonManager.Data.Monsters[SummonMonsters[summonIndex]]; GameObject summonObject = Resources.Load("Prefabs/Monsters/" + summonData.TypeId) as GameObject; bool rollInitiative = SummonRollInitiatives.Count > 0; if (SummonRanks.Count > 0) { RaidSceneManager.BattleGround.SummonUnit(summonData, summonObject, SummonRanks[summonIndex]. Ranks[RandomSolver.Next(SummonRanks[summonIndex].Ranks.Count)], rollInitiative, CanSpawnLoot); } else { RaidSceneManager.BattleGround.SummonUnit(summonData, summonObject, 1, rollInitiative, CanSpawnLoot); } } return(true); }
public override void Apply(FormationUnit performer, FormationUnit target, Effect effect) { ApplyInstant(performer, target, effect); }
public void SummonUnit(MonsterData monsterData, GameObject unitObject, int targetRank, bool initiativeRoll, bool canSpawnLoot) { FormationUnit newUnit = Instantiate(unitObject).GetComponent <FormationUnit>(); newUnit.Initialize(new Monster(monsterData), targetRank, Team.Monsters); newUnit.transform.SetParent(MonsterParty.transform, false); newUnit.RectTransform.position = MonsterFormation.rankHolder.rankMarkSlots[targetRank - 1].transform.position; newUnit.Party = MonsterParty; newUnit.Formation = MonsterFormation; newUnit.CombatInfo.PrepareForBattle(PickId(), newUnit.Character as Monster, canSpawnLoot); RaidSceneManager.TorchMeter.ApplyBuffsForUnit(newUnit); if (!MonsterFormation.ranks.facingRight) { newUnit.InstantFlip(); } newUnit.ResetAnimations(); if (newUnit.Formation.AvailableFreeSpace >= newUnit.Size) { newUnit.Formation.SpawnUnit(newUnit, targetRank); if (initiativeRoll) { Round.InsertInitiativeRoll(newUnit); } #region Spawn Check if (monsterData.Spawn != null) { for (int i = 0; i < monsterData.Spawn.Effects.Count; i++) { for (int j = 0; j < monsterData.Spawn.Effects[i].SubEffects.Count; j++) { monsterData.Spawn.Effects[i].SubEffects[j].ApplyInstant(newUnit, newUnit, monsterData.Spawn.Effects[i]); } } newUnit.OverlaySlot.UpdateOverlay(); } #endregion #region Companion Check if (monsterData.Companion != null) { var companion = newUnit.Formation.party.Units.Find(unit => unit.Character.Class == monsterData.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit, companion)); foreach (var buff in monsterData.Companion.Buffs) { newUnit.Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.OverlaySlot.UpdateOverlay(); } } for (int i = 0; i < newUnit.Party.Units.Count; i++) { if (newUnit.Party.Units[i] != newUnit && newUnit.Party.Units[i].Character.IsMonster) { var monster = newUnit.Party.Units[i].Character as Monster; if (monster.Data.Companion != null) { var companion = newUnit.Party.Units.Find(unit => unit.Character.Class == monster.Data.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit.Party.Units[i], companion)); foreach (var buff in monster.Data.Companion.Buffs) { newUnit.Party.Units[i].Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.Party.Units[i].OverlaySlot.UpdateOverlay(); } } } } #endregion } else if (newUnit.Formation.AvailableSummonSpace >= newUnit.Size) { var purgingCandidates = new List <FormationUnit>(newUnit.Formation.party.Units); purgingCandidates.Sort((x, y) => { if (Mathf.Abs(x.Rank - targetRank) == Mathf.Abs(y.Rank - targetRank)) { return(0); } if (Mathf.Abs(x.Rank - targetRank) < Mathf.Abs(y.Rank - targetRank)) { return(1); } else { return(-1); } }); for (int i = purgingCandidates.Count - 1; i >= 0; i--) { if (purgingCandidates[i].Character.IsMonster && purgingCandidates[i].Character.BattleModifiers.CanBeSummonRank) { RaidSceneManager.Instanse.SummonPurging(purgingCandidates[i]); if (newUnit.Formation.AvailableFreeSpace >= newUnit.Size) { newUnit.Formation.SpawnUnit(newUnit, targetRank); if (initiativeRoll) { Round.InsertInitiativeRoll(newUnit); } #region Spawn Check if (monsterData.Spawn != null) { for (int k = 0; k < monsterData.Spawn.Effects.Count; k++) { for (int j = 0; j < monsterData.Spawn.Effects[k].SubEffects.Count; j++) { monsterData.Spawn.Effects[k].SubEffects[j].ApplyInstant(newUnit, newUnit, monsterData.Spawn.Effects[k]); } } newUnit.OverlaySlot.UpdateOverlay(); } #endregion #region Companion Check if (monsterData.Companion != null) { var companion = newUnit.Formation.party.Units.Find(unit => unit.Character.Class == monsterData.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit, companion)); foreach (var buff in monsterData.Companion.Buffs) { newUnit.Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.OverlaySlot.UpdateOverlay(); } } for (int j = 0; j < newUnit.Party.Units.Count; j++) { if (newUnit.Party.Units[j] != newUnit && newUnit.Party.Units[j].Character.IsMonster) { var monster = newUnit.Party.Units[j].Character as Monster; if (monster.Data.Companion != null) { var companion = newUnit.Party.Units.Find(unit => unit.Character.Class == monster.Data.Companion.MonsterClass); if (companion != null) { Companions.Add(new CompanionRecord(newUnit.Party.Units[j], companion)); foreach (var buff in monster.Data.Companion.Buffs) { newUnit.Party.Units[j].Character.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Adventure, 3)); } newUnit.Party.Units[j].OverlaySlot.UpdateOverlay(); } } } } #endregion return; } } } ReturnId(newUnit.CombatInfo.CombatId); Debug.LogError("Not enough summon space for " + newUnit.name); Destroy(newUnit.gameObject); } else { ReturnId(newUnit.CombatInfo.CombatId); Debug.LogError("Not enough summon space for " + newUnit.name); Destroy(newUnit.gameObject); } }