Exemple #1
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        float poisonChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                             (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        poisonChance -= target.Character.GetSingleAttribute(AttributeType.Poison).ModifiedValue;
        if (performer != null && performer.Character is Hero)
        {
            poisonChance += performer.Character.GetSingleAttribute(AttributeType.PoisonChance).ModifiedValue;
        }

        poisonChance = Mathf.Clamp(poisonChance, 0, 0.95f);
        if (RandomSolver.CheckSuccess(poisonChance))
        {
            var poisonStatus = (PoisonStatusEffect)target.Character.GetStatusEffect(StatusType.Poison);
            var newDot       = new DamageOverTimeInstanse
            {
                TickDamage  = DotPoison,
                TicksAmount = effect.IntegerParams[EffectIntParams.Duration] ?? 3
            };
            newDot.TicksLeft = newDot.TicksAmount;
            poisonStatus.AddInstanse(newDot);
            return(true);
        }
        return(false);
    }
Exemple #2
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null || target.Character is Hero == false)
        {
            return(false);
        }

        float diseaseTriggerChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                                     (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        if (!RandomSolver.CheckSuccess(diseaseTriggerChance))
        {
            return(false);
        }

        float diseaseChance = 1 - target.Character.GetSingleAttribute(AttributeType.Disease).ModifiedValue;

        if (RandomSolver.CheckSuccess(diseaseChance))
        {
            var hero = (Hero)target.Character;
            if (IsRandom == false && Disease != null)
            {
                if (hero.AddQuirk(Disease))
                {
                    return(true);
                }
            }
            else
            {
                hero.AddRandomDisease();
                return(true);
            }
        }
        return(false);
    }
Exemple #3
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        if (!performer.Character.IsMonster)
        {
            return(false);
        }

        if (((Monster)performer.Character).Data.ControllerCaptor == null)
        {
            return(false);
        }

        float debuffChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                             (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        debuffChance -= target.Character.GetSingleAttribute(AttributeType.Debuff).ModifiedValue;
        debuffChance  = performer == target ? 1 : Mathf.Clamp(debuffChance, 0, 0.95f);

        if (RandomSolver.CheckSuccess(debuffChance))
        {
            RaidSceneManager.BattleGround.ControlUnit(target, performer, Duration);
            return(true);
        }
        return(false);
    }
Exemple #4
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        var stunStatus = (StunStatusEffect)target.Character.GetStatusEffect(StatusType.Stun);

        if (stunStatus.IsApplied)
        {
            return(true);
        }

        float stunChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                           (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        stunChance -= target.Character.GetSingleAttribute(AttributeType.Stun).ModifiedValue;
        if (performer != null && performer.Character is Hero)
        {
            stunChance += performer.Character.GetSingleAttribute(AttributeType.StunChance).ModifiedValue;
        }

        stunChance = Mathf.Clamp(stunChance, 0, 0.95f);
        if (RandomSolver.CheckSuccess(stunChance))
        {
            stunStatus.StunApplied = true;
            target.SetHalo("stunned");
            target.Character[StatusType.Guard].ResetStatus();
            return(true);
        }
        return(false);
    }
    protected virtual bool ChooseTargets(List <FormationUnit> availableTargets, MonsterBrainDecision decision)
    {
        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);
    }
Exemple #6
0
    public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        if (target.Character is Hero == false)
        {
            return(false);
        }

        if (effect.IntegerParams[EffectIntParams.Chance].HasValue)
        {
            if (!RandomSolver.CheckSuccess((float)effect.IntegerParams[EffectIntParams.Chance].Value / 100))
            {
                return(false);
            }
        }

        float initialDamage = StressAmount;

        if (performer != null)
        {
            initialDamage *= (1 + performer.Character.GetSingleAttribute(AttributeType.StressDmgPercent).ModifiedValue);
        }

        int damage = Mathf.RoundToInt(initialDamage * (1 +
                                                       target.Character.GetSingleAttribute(AttributeType.StressDmgReceivedPercent).ModifiedValue));

        if (damage < 1)
        {
            damage = 1;
        }

        target.Character.Stress.IncreaseValue(damage);
        if (target.Character.IsOverstressed)
        {
            if (target.Character.IsVirtued)
            {
                target.Character.Stress.CurrentValue = Mathf.Clamp(target.Character.Stress.CurrentValue, 0, 100);
            }
            else if (!target.Character.IsAfflicted && target.Character.IsOverstressed)
            {
                RaidSceneManager.Instanse.AddResolveCheck(target);
            }

            if (Mathf.Approximately(target.Character.Stress.CurrentValue, 200))
            {
                RaidSceneManager.Instanse.AddHeartAttackCheck(target);
            }
        }

        target.OverlaySlot.UpdateOverlay();
        RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Stress, damage.ToString());
        target.SetHalo("afflicted");
        return(true);
    }
    public void ProvideActivity()
    {
        foreach (var treatmentSlot in TreatmentSlots)
        {
            switch (treatmentSlot.Status)
            {
            case ActivitySlotStatus.Caretaken:
                treatmentSlot.Status = ActivitySlotStatus.Available;
                treatmentSlot.Hero   = null;
                break;

            case ActivitySlotStatus.Blocked:
            case ActivitySlotStatus.Checkout:
                treatmentSlot.Hero.Status = HeroStatus.Available;
                treatmentSlot.Status      = ActivitySlotStatus.Available;
                treatmentSlot.Hero        = null;
                break;

            case ActivitySlotStatus.Paid:
                if (treatmentSlot.TargetDiseaseQuirk != null)
                {
                    if (RandomSolver.CheckSuccess(CureAllChance))
                    {
                        var cured = treatmentSlot.Hero.RemoveDiseases();
                        if (cured.Count == 0)
                        {
                            Debug.LogError("Sanitarium treament diseases not found.");
                        }
                        else
                        {
                            LogActivity(ActivityType.RemoveAllDiseases,
                                        treatmentSlot.Hero, cured.Select(info => info.Quirk.Id).ToArray());
                        }
                    }
                    else
                    {
                        if (treatmentSlot.Hero.RemoveQuirk(treatmentSlot.TargetDiseaseQuirk) == null)
                        {
                            Debug.LogError("Sanitarium treament disease not found.");
                        }
                        else
                        {
                            LogActivity(ActivityType.RemoveDisease,
                                        treatmentSlot.Hero, new string[] { treatmentSlot.TargetDiseaseQuirk });
                        }
                    }
                }
                treatmentSlot.Hero.Status = HeroStatus.Available;
                treatmentSlot.Status      = ActivitySlotStatus.Available;
                treatmentSlot.Hero        = null;
                break;

            default:
                break;
            }
        }
    }
    public override bool ApplyQueued(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);
            }
        }

        float initialHeal = HealAmount;

        if (performer != null)
        {
            initialHeal *= (1 + performer.Character.GetSingleAttribute(AttributeType.HpHealPercent).ModifiedValue);
        }

        if (performer != null && RandomSolver.CheckSuccess(performer.Character.Crit))
        {
            int critHeal = target.Character.Heal(initialHeal * 1.5f, true);
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.CritHeal, critHeal.ToString());
            if (target.Character is Hero)
            {
                FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/heal_ally_crit");
            }
            else
            {
                FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/heal_enemy_crit");
            }

            target.OverlaySlot.UpdateOverlay();
            return(true);
        }
        else
        {
            int heal = target.Character.Heal(initialHeal, true);
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Heal, heal.ToString());
            if (target.Character is Hero)
            {
                FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/heal_ally");
            }
            else
            {
                FMODUnity.RuntimeManager.PlayOneShot("event:/general/status/heal_enemy");
            }

            target.OverlaySlot.UpdateOverlay();
            return(true);
        }
    }
Exemple #9
0
    public void RestockBonus(List <int> rosterIds, Estate estate, string bonusClass, int bonusAmount)
    {
        EventHeroes.Clear();
        GraveIndexes.Clear();

        #region Clear unrecruited heroes
        if (EventHeroes.Count > 0)
        {
            for (int i = 0; i < EventHeroes.Count; i++)
            {
                if (rosterIds.Contains(EventHeroes[i].RosterId))
                {
                    Debug.LogError("Same id returned while restocking heroes.");
                }
                else
                {
                    rosterIds.Add(EventHeroes[i].RosterId);
                }

                estate.HeroPurchases.Remove(EventHeroes[i].RosterId);
            }
        }
        #endregion

        #region Create bonus recruits
        for (int i = 0; i < bonusAmount; i++)
        {
            RecruitUpgrade experienceUpgrade = null;

            if (CurrentRecruitMaxLevel > 0)
            {
                for (int j = 0; j <= RecruitExperienceUpgrades.Count - 1; j++)
                {
                    if (RecruitExperienceUpgrades[j].Level <= CurrentRecruitMaxLevel &&
                        RandomSolver.CheckSuccess(RecruitExperienceUpgrades[j].Chance))
                    {
                        experienceUpgrade = RecruitExperienceUpgrades[j];
                        break;
                    }
                }
            }
            int    id        = rosterIds[Random.Range(0, rosterIds.Count)];
            string heroClass = DarkestDungeonManager.Data.HeroClasses[bonusClass].StringId;
            string heroName  = LocalizationManager.GetString("hero_name_" + Random.Range(0, 556).ToString());
            var    newHero   = experienceUpgrade == null ?
                               new Hero(id, heroClass, heroName) :
                               new Hero(id, heroClass, heroName, experienceUpgrade);
            EventHeroes.Add(newHero);
            rosterIds.Remove(id);
            GeneratePurchaseInfo(newHero, estate);
        }
        #endregion
    }
    public void Apply(Unit caster, Unit target, Spell spell, ArenaManager world)
    {
        int amount = 0;

        amount += RandomSolver.Next(minValue, maxValue);

        if (amount < 1)
        {
            amount = 1;
        }

        int initialDamage = amount;

        caster.Character.parameters.Copy(world.SpellInfo.parameters);
        for (int i = 0; i < Modifiers.Count; i++)
        {
            Modifiers[i].ModifySpell(caster, target, world.SpellInfo, spell, world);
        }

        initialDamage = (int)(initialDamage * world.SpellInfo.parameters[ParameterType.DamageDealing].FinalValue);

        bool isCrit = RandomSolver.CheckSuccess(world.SpellInfo.parameters[ParameterType.CritChance].FinalValue);

        if (isCrit)
        {
            initialDamage = (int)(initialDamage * caster.Character.parameters[ParameterType.CritDamageMultiplier].FinalValue);
        }

        amount = initialDamage;
        Buff absorbBuff;

        for (int i = target.character.AbsorbEffects.Count - 1; i >= 0; i--)
        {
            amount = target.character.AbsorbEffects[i](target, world, amount, out absorbBuff);
            if (amount != 0)
            {
                target.character.Buffs.Remove(absorbBuff);
            }
            else
            {
                return;
            }
        }

        target.Character.health.Decrease((ushort)amount);

        if (caster.id == world.PlayerUnit.id)
        {
            GameObject damageEvent = MonoBehaviour.Instantiate(Resources.Load("Prefabs/UI/DamageEvent")) as GameObject;
            damageEvent.GetComponent <UnitDamageUIEvent>().Initialize(initialDamage, target, isCrit, ArenaManager.PlayerInterface);
        }
    }
    protected override bool ChooseTargets(List <FormationUnit> availableTargets, MonsterBrainDecision decision)
    {
        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);
        }

        var hero = target.Character as Hero;

        if (hero == null)
        {
            return(false);
        }

        if (effect.IntegerParams[EffectIntParams.Chance].HasValue)
        {
            if (!RandomSolver.CheckSuccess((float)effect.IntegerParams[EffectIntParams.Chance].Value / 100))
            {
                return(false);
            }
        }

        float initialHeal = StressHealAmount;

        if (performer != null)
        {
            initialHeal *= (1 + performer.Character.GetSingleAttribute(AttributeType.StressHealPercent).ModifiedValue);
        }

        int heal = Mathf.RoundToInt(initialHeal * (1 +
                                                   target.Character.GetSingleAttribute(AttributeType.StressHealReceivedPercent).ModifiedValue));

        if (heal < 1)
        {
            heal = 1;
        }

        target.Character.Stress.DecreaseValue(heal);
        if (Mathf.RoundToInt(hero.Stress.CurrentValue) == 0 && hero.IsAfflicted)
        {
            hero.RevertTrait();
        }
        target.OverlaySlot.stressBar.UpdateStress(target.Character.Stress.ValueRatio);
        RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.StressHeal, heal.ToString());
        target.SetHalo("heroic");
        return(true);
    }
Exemple #13
0
    public void FinishBattle()
    {
        StallingRoundNumber = 0;
        var darkenessLoot = DarkestDungeonManager.Data.LootDatabase.DarknessLoot["battle"];

        for (int i = darkenessLoot.Count - 1; i >= 0; i--)
        {
            if (darkenessLoot[i].DarknessLevel == RaidSceneManager.TorchMeter.CurrentRange.Min)
            {
                if (RandomSolver.CheckSuccess(darkenessLoot[i].Chance))
                {
                    for (int j = 0; j < darkenessLoot[i].Codes.Count; j++)
                    {
                        BattleLoot.Add(new LootDefinition()
                        {
                            Code = darkenessLoot[i].Codes[j], Count = 1
                        });
                    }
                }
                break;
            }
        }
        for (int i = 0; i < HeroParty.Units.Count; i++)
        {
            var hero = (Hero)HeroParty.Units[i].Character;
            if (hero.HeroClass.ExtraBattleLoot != null)
            {
                BattleLoot.Add(hero.HeroClass.ExtraBattleLoot);
            }
        }

        HeroFormation.RectTransform.SetParent(Rect.parent, false);
        RaidSceneManager.DungeonCamera.target = HeroFormation.ranks.RectTransform;
        MonsterFormation.overlay.ResetOverlay();
        MonsterParty.DeleteFormation();
        MonsterFormation.gameObject.SetActive(false);
        ResetIds();
        backdrop.Deactivate();
        Round.OrderedUnits.Clear();
        RaidSceneManager.TorchMeter.ClearModifier();

        if (SharedHealth.IsActive)
        {
            SharedHealth.Reset();
        }
    }
Exemple #14
0
    public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null || target.Character is Hero == false)
        {
            return(false);
        }

        float diseaseTriggerChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                                     (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        if (!RandomSolver.CheckSuccess(diseaseTriggerChance))
        {
            return(false);
        }

        float diseaseChance = 1 - target.Character.GetSingleAttribute(AttributeType.Disease).ModifiedValue;

        if (RandomSolver.CheckSuccess(diseaseChance))
        {
            var hero = (Hero)target.Character;
            if (IsRandom == false && Disease != null)
            {
                if (hero.AddQuirk(Disease))
                {
                    target.SetHalo("disease");
                    RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Disease,
                                                                 LocalizationManager.GetString("str_quirk_name_" + Disease.Id));
                    return(true);
                }
                return(false);
            }
            else
            {
                var disease = hero.AddRandomDisease();
                RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Disease,
                                                             LocalizationManager.GetString("str_quirk_name_" + disease.Id));
                target.SetHalo("disease");
                return(true);
            }
        }
        else
        {
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.DiseaseResist);
            return(false);
        }
    }
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        var hero = target.Character as Hero;

        if (hero == null)
        {
            return(false);
        }

        if (effect.IntegerParams[EffectIntParams.Chance].HasValue)
        {
            if (!RandomSolver.CheckSuccess((float)effect.IntegerParams[EffectIntParams.Chance].Value / 100))
            {
                return(false);
            }
        }

        float initialHeal = StressHealAmount;

        if (performer != null)
        {
            initialHeal *= (1 + performer.Character.GetSingleAttribute(AttributeType.StressHealPercent).ModifiedValue);
        }

        int heal = Mathf.RoundToInt(initialHeal * (1 +
                                                   target.Character.GetSingleAttribute(AttributeType.StressHealReceivedPercent).ModifiedValue));

        if (heal < 1)
        {
            heal = 1;
        }

        target.Character.Stress.DecreaseValue(heal);
        if (Mathf.RoundToInt(hero.Stress.CurrentValue) == 0 && hero.IsAfflicted)
        {
            hero.RevertTrait();
        }
        target.OverlaySlot.UpdateOverlay();
        return(true);
    }
Exemple #16
0
    public override int Fuse(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(0);
        }

        if (target.Character is Hero == false)
        {
            return(0);
        }

        if (effect.IntegerParams[EffectIntParams.Chance].HasValue)
        {
            if (!RandomSolver.CheckSuccess((float)effect.IntegerParams[EffectIntParams.Chance].Value / 100))
            {
                return(0);
            }
        }

        float initialDamage = StressAmount;

        if (performer != null)
        {
            initialDamage *= (1 + performer.Character.GetSingleAttribute(AttributeType.StressDmgPercent).ModifiedValue);
        }

        int damage = Mathf.RoundToInt(initialDamage * (1 +
                                                       target.Character.GetSingleAttribute(AttributeType.StressDmgReceivedPercent).ModifiedValue));

        if (damage < 1)
        {
            damage = 1;
        }

        return(damage);
    }
Exemple #17
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        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))
        {
            target.Push(PushParam);
            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);
            }
        }

        float initialHeal = HealAmount;

        if (performer != null)
        {
            initialHeal *= (1 + performer.Character.GetSingleAttribute(AttributeType.HpHealPercent).ModifiedValue);
        }

        if (performer != null && RandomSolver.CheckSuccess(performer.Character.Crit))
        {
            int critHeal = target.Character.Heal(initialHeal * 1.5f, true);
            target.OverlaySlot.healthBar.UpdateHealth(target.Character);
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.CritHeal, critHeal.ToString());
        }
        else
        {
            int heal = target.Character.Heal(initialHeal, true);
            target.OverlaySlot.healthBar.UpdateHealth(target.Character);
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.Heal, heal.ToString());
        }
        return(true);
    }
Exemple #19
0
    public void ProvideActivity()
    {
        foreach (var activitySlot in ActivitySlots)
        {
            switch (activitySlot.Status)
            {
            case ActivitySlotStatus.Caretaken:
            case ActivitySlotStatus.Crierd:
                activitySlot.Status = ActivitySlotStatus.Available;
                activitySlot.Hero   = null;
                break;

            case ActivitySlotStatus.Blocked:
            case ActivitySlotStatus.Checkout:
                activitySlot.Hero.Status = HeroStatus.Available;
                activitySlot.Status      = ActivitySlotStatus.Available;
                activitySlot.Hero        = null;
                break;

            case ActivitySlotStatus.Paid:
                activitySlot.Hero.GetPairedAttribute(AttributeType.Stress).DecreaseValue(StressHealAmount);
                if (RandomSolver.CheckSuccess(SideEffectChance))
                {
                    var effect = RandomSolver.ChooseByRandom <TownEffect>(SideEffects);
                    switch (effect.Type)
                    {
                    case TownEffectType.GoMissing:
                        var missingEffect = effect as MissingTownEffect;
                        var duration      = RandomSolver.ChooseByRandom <MissingDuration>(missingEffect.Durations);

                        LogActivity(ActivityEffectType.Missing, activitySlot.Hero, "None");

                        activitySlot.Hero.Status          = HeroStatus.Missing;
                        activitySlot.Hero.MissingDuration = duration.Duration;
                        activitySlot.Status = ActivitySlotStatus.Available;
                        activitySlot.Hero   = null;
                        break;

                    case TownEffectType.ActivityLock:
                        activitySlot.Status = ActivitySlotStatus.Blocked;
                        LogActivity(ActivityEffectType.Lock, activitySlot.Hero, "None");
                        break;

                    case TownEffectType.AddQuirk:
                        var addQuirkEffect = effect as AddQuirkTownEffect;
                        var activityQuirk  = RandomSolver.ChooseByRandom <TownActivityQuirk>(addQuirkEffect.QuirkSet);
                        if (activityQuirk != null)
                        {
                            var quirk = DarkestDungeonManager.Data.Quirks[activityQuirk.QuirkName];
                            if (activitySlot.Hero.AddQuirk(quirk))
                            {
                                LogActivity(ActivityEffectType.AddQuirk, activitySlot.Hero, quirk.Id);
                            }
                        }
                        activitySlot.Hero.Status = HeroStatus.Available;
                        activitySlot.Status      = ActivitySlotStatus.Available;
                        activitySlot.Hero        = null;
                        break;

                    case TownEffectType.AddTrinket:
                        if (activitySlot.Hero.LeftTrinket != null || activitySlot.Hero.RightTrinket != null)
                        {
                            var trinket = DarkestDungeonManager.Campaign.Estate.NomadWagon.GenerateTrinket();
                            DarkestDungeonManager.Campaign.RealmInventory.AddTrinket(trinket);
                            LogActivity(ActivityEffectType.AddTrinket, activitySlot.Hero, trinket.Id);
                        }
                        activitySlot.Hero.Status = HeroStatus.Available;
                        activitySlot.Status      = ActivitySlotStatus.Available;
                        activitySlot.Hero        = null;
                        break;

                    case TownEffectType.RemoveTrinket:
                        if (activitySlot.Hero.LeftTrinket != null && activitySlot.Hero.RightTrinket != null)
                        {
                            if (Random.value > 0.5f)
                            {
                                LogActivity(ActivityEffectType.RemoveTrinket,
                                            activitySlot.Hero, activitySlot.Hero.LeftTrinket.Id);
                                activitySlot.Hero.Unequip(TrinketSlot.Left);
                            }
                            else
                            {
                                LogActivity(ActivityEffectType.RemoveTrinket,
                                            activitySlot.Hero, activitySlot.Hero.RightTrinket.Id);
                                activitySlot.Hero.Unequip(TrinketSlot.Right);
                            }
                        }
                        else if (activitySlot.Hero.LeftTrinket != null)
                        {
                            LogActivity(ActivityEffectType.RemoveTrinket,
                                        activitySlot.Hero, activitySlot.Hero.LeftTrinket.Id);
                            activitySlot.Hero.Unequip(TrinketSlot.Left);
                        }
                        else if (activitySlot.Hero.RightTrinket != null)
                        {
                            LogActivity(ActivityEffectType.RemoveTrinket,
                                        activitySlot.Hero, activitySlot.Hero.RightTrinket.Id);
                            activitySlot.Hero.Unequip(TrinketSlot.Right);
                        }
                        activitySlot.Hero.Status = HeroStatus.Available;
                        activitySlot.Status      = ActivitySlotStatus.Available;
                        activitySlot.Hero        = null;
                        break;

                    case TownEffectType.ApplyBuff:
                        var addBuffTownEffect = effect as AddBuffTownEffect;
                        var activityBuff      = RandomSolver.ChooseByRandom <TownActivityBuff>(addBuffTownEffect.BuffSets);
                        if (activityBuff != null)
                        {
                            foreach (var buffName in activityBuff.BuffNames)
                            {
                                var buff = DarkestDungeonManager.Data.Buffs[buffName];
                                if (!activitySlot.Hero.ContainsBuff(buff, BuffSourceType.Estate))
                                {
                                    activitySlot.Hero.AddBuff(new BuffInfo(buff, BuffDurationType.Raid, BuffSourceType.Estate));
                                }
                            }
                            LogActivity(ActivityEffectType.AddBuff, activitySlot.Hero, activityBuff.BuffNames[0]);
                        }
                        activitySlot.Hero.Status = HeroStatus.Available;
                        activitySlot.Status      = ActivitySlotStatus.Available;
                        activitySlot.Hero        = null;
                        break;

                    case TownEffectType.ChangeCurrency:
                        var changeCurrencyEffect = effect as CurrencyTownEffect;
                        var change = RandomSolver.ChooseByRandom <TownActivityCurrency>(changeCurrencyEffect.Changes);
                        if (change != null)
                        {
                            if (change.Amount > 0)
                            {
                                LogActivity(ActivityEffectType.CurrencyGained,
                                            activitySlot.Hero, change.Amount.ToString());
                                DarkestDungeonManager.Campaign.Estate.AddGold(change.Amount);
                            }
                            else
                            {
                                LogActivity(ActivityEffectType.CurrencyLost,
                                            activitySlot.Hero, Mathf.Abs(change.Amount).ToString());
                                DarkestDungeonManager.Campaign.Estate.RemoveGold(-change.Amount);
                            }
                        }
                        activitySlot.Hero.Status = HeroStatus.Available;
                        activitySlot.Status      = ActivitySlotStatus.Available;
                        activitySlot.Hero        = null;
                        break;
                    }
                }
                else
                {
                    LogActivity(ActivityEffectType.Nothing, activitySlot.Hero, "None");
                    activitySlot.Hero.Status = HeroStatus.Available;
                    activitySlot.Status      = ActivitySlotStatus.Available;
                    activitySlot.Hero        = null;
                }
                break;

            default:
                break;
            }
        }
    }
    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.UpdateOverlay();
                        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.UpdateOverlay();

                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.UpdateOverlay();

                    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.UpdateOverlay();
            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);

            #endregion
        }
    }
    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 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 ExecuteProgress()
    {
        foreach (var eventEntry in EventModifiers.EventData)
        {
            switch (eventEntry.Type)
            {
            case TownEventDataType.IdleBuff:
                for (int i = 0; i < Heroes.Count; i++)
                {
                    if (Heroes[i].Status == HeroStatus.Available)
                    {
                        Heroes[i].AddBuff(new BuffInfo(DarkestDungeonManager.Data.Buffs[eventEntry.StringData],
                                                       BuffDurationType.IdleTownVisit, BuffSourceType.Estate));
                    }
                }
                break;

            case TownEventDataType.IdleResolve:
                for (int i = 0; i < Heroes.Count; i++)
                {
                    if (Heroes[i].Class == eventEntry.StringData)
                    {
                        for (int j = 0; j < eventEntry.NumberData; j++)
                        {
                            Heroes[i].Resolve.AddExperience(Heroes[i].Resolve.NextLevelXP - Heroes[i].Resolve.CurrentXP);
                        }

                        Heroes[i].UpdateResolve();
                    }
                }
                break;

            case TownEventDataType.InActivityBuff:
                for (int i = 0; i < Heroes.Count; i++)
                {
                    if (Heroes[i].Status == HeroStatus.Abbey || Heroes[i].Status == HeroStatus.Tavern)
                    {
                        for (int j = 0; j < eventEntry.NumberData; j++)
                        {
                            Heroes[i].AddBuff(new BuffInfo(DarkestDungeonManager.Data.Buffs[eventEntry.StringData],
                                                           BuffDurationType.IdleTownVisit, BuffSourceType.Estate));
                        }
                    }
                }
                break;

            default:
                break;
            }
        }

        TriggeredEvent  = null;
        GuaranteedEvent = null;
        EventModifiers.Reset();
        Estate.ExecuteProgress();

        var possibleEvents = DarkestDungeonManager.Data.EventDatabase.Events.FindAll(townEvent => townEvent.IsPossible);

        if (possibleEvents.Count > 0 && EventsOption.Frequency.Count > 3 && RandomSolver.CheckSuccess(EventsOption.Frequency[3]))
        {
            TriggeredEvent = RandomSolver.ChooseBySingleRandom(possibleEvents);
            for (int i = 0; i < DarkestDungeonManager.Data.EventDatabase.Events.Count; i++)
            {
                DarkestDungeonManager.Data.EventDatabase.Events[i].EventTriggered(false);
            }

            TriggeredEvent.EventTriggered(true);
            EventModifiers.IncludeEvent(TriggeredEvent);

            if (TriggeredEvent.Id == "plot_quest_town_invasion_0")
            {
                DarkestSoundManager.PlayOneShot("event:/town/town_event_display_bandit_incursion");
            }
            else if (TriggeredEvent.Tone == TownEventTone.Bad)
            {
                DarkestSoundManager.PlayOneShot("event:/town/town_event_display_bad");
            }
            else if (TriggeredEvent.Tone == TownEventTone.Good)
            {
                DarkestSoundManager.PlayOneShot("event:/town/town_event_display_good");
            }
            else
            {
                DarkestSoundManager.PlayOneShot("event:/town/town_event_display_neutral");
            }
        }

        GenerateQuests();
        SearchMissingHeroes();
    }
Exemple #24
0
    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);
    }
Exemple #25
0
    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);
        }
    }
Exemple #26
0
    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);
    }
Exemple #27
0
    public void RestockHeroes(List <int> rosterIds, Estate estate)
    {
        var heroClasses = DarkestDungeonManager.Data.HeroClasses.Keys.ToList();

        Heroes.AddRange(EventHeroes);
        EventHeroes.Clear();
        GraveIndexes.Clear();
        #region Clear unrecruited heroes
        if (Heroes != null && Heroes.Count > 0)
        {
            for (int i = 0; i < Heroes.Count; i++)
            {
                if (rosterIds.Contains(Heroes[i].RosterId))
                {
                    Debug.LogError("Same id returned while restocking heroes.");
                }
                else
                {
                    rosterIds.Add(Heroes[i].RosterId);
                }

                estate.HeroPurchases.Remove(Heroes[i].RosterId);
            }
        }
        #endregion
        #region Create new recruits
        Heroes = new List <Hero>();
        if (DarkestDungeonManager.RaidManager.Quest != null && DarkestDungeonManager.RaidManager.Quest.Goal.Id == "tutorial_final_room")
        {
            for (int i = 0; i < firstHeroClasses.Length; i++)
            {
                int id      = rosterIds[Random.Range(0, rosterIds.Count)];
                var newHero = new Hero(id, firstHeroClasses[i],
                                       LocalizationManager.GetString("hero_name_" + Random.Range(0, 556).ToString()));
                Heroes.Add(newHero);
                rosterIds.Remove(id);
                GeneratePurchaseInfo(newHero, estate);
            }
        }
        else
        {
            for (int i = 0; i < RecruitSlots; i++)
            {
                RecruitUpgrade experienceUpgrade = null;

                if (CurrentRecruitMaxLevel > 0)
                {
                    for (int j = 0; j <= RecruitExperienceUpgrades.Count - 1; j++)
                    {
                        if (RecruitExperienceUpgrades[j].Level <= CurrentRecruitMaxLevel &&
                            RandomSolver.CheckSuccess(RecruitExperienceUpgrades[j].Chance))
                        {
                            experienceUpgrade = RecruitExperienceUpgrades[j];
                            break;
                        }
                    }
                }
                int    id        = rosterIds[Random.Range(0, rosterIds.Count)];
                string heroClass = heroClasses[Random.Range(0, DarkestDungeonManager.Data.HeroClasses.Count)];
                string heroName  = LocalizationManager.GetString("hero_name_" + Random.Range(0, 556).ToString());
                var    newHero   = experienceUpgrade == null ?
                                   new Hero(id, heroClass, heroName) :
                                   new Hero(id, heroClass, heroName, experienceUpgrade);
                Heroes.Add(newHero);
                rosterIds.Remove(id);
                GeneratePurchaseInfo(newHero, estate);
            }
        }
        #endregion
        #region Add recruits for minimum of one party
        int abominations = DarkestDungeonManager.Campaign.Heroes.FindAll(hero =>
                                                                         hero.Class == "abomination").Count + Heroes.FindAll(hero => hero.Class == "abomination").Count;
        int additionalHeroes = 4 - DarkestDungeonManager.Campaign.Heroes.Count - Heroes.Count + abominations;
        if (abominations > 3)
        {
            return;
        }
        for (int i = 0; i < additionalHeroes; i++)
        {
            RecruitUpgrade experienceUpgrade = null;

            if (CurrentRecruitMaxLevel > 0)
            {
                for (int j = 0; j <= RecruitExperienceUpgrades.Count - 1; j++)
                {
                    if (RecruitExperienceUpgrades[j].Level <= CurrentRecruitMaxLevel &&
                        RandomSolver.CheckSuccess(RecruitExperienceUpgrades[j].Chance))
                    {
                        experienceUpgrade = RecruitExperienceUpgrades[j];
                        break;
                    }
                }
            }
            int    id        = rosterIds[Random.Range(0, rosterIds.Count)];
            string heroClass = "abomination";
            while (heroClass == "abomination")
            {
                heroClass = heroClasses[Random.Range(0, DarkestDungeonManager.Data.HeroClasses.Count)];
            }

            string heroName = LocalizationManager.GetString("hero_name_" + Random.Range(0, 556).ToString());
            var    newHero  = experienceUpgrade == null ?
                              new Hero(id, heroClass, heroName) :
                              new Hero(id, heroClass, heroName, experienceUpgrade);
            Heroes.Add(newHero);
            rosterIds.Remove(id);
            GeneratePurchaseInfo(newHero, estate);
        }
        #endregion
    }
Exemple #28
0
    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);
    }
Exemple #29
0
    void OnTriggerEnter2D(Collider2D other)
    {
        if (isPartyInside)
        {
            return;
        }
        isPartyInside = true;
        if (Area != null)
        {
            if (Area.Type == AreaType.Curio)
            {
                DarkestSoundManager.ExecuteNarration("curio", NarrationPlace.Raid);
            }

            if (Area.Knowledge == Knowledge.Hidden)
            {
                RaidSceneManager.TorchMeter.DecreaseTorch(6);
            }
            else
            {
                RaidSceneManager.TorchMeter.DecreaseTorch(1);
            }

            RaidSceneManager.Raid.EnteredSector(Area as HallSector);

            RaidSceneManager.Raid.CurrentLocation      = Area;
            RaidSceneManager.HallwayView.CurrentSector = this;

            if (Area.Type == AreaType.Battle)
            {
                #region Battle Checks
                RaidSceneManager.MapPanel.SetCurrentIndicator(Area as HallSector);
                if (!Area.BattleEncounter.Cleared)
                {
                    if (RaidSceneManager.Raid.Dungeon.SharedMash != null)
                    {
                        if (RaidSceneManager.TorchMeter.CurrentRange.RangeType == TorchRangeType.Out)
                        {
                            if (!RaidSceneManager.Raid.Dungeon.SharedMashExecutionIds.Contains(0))
                            {
                                RaidSceneManager.Raid.Dungeon.SharedMashExecutionIds.Add(0);
                                if (RandomSolver.CheckSuccess((float)RaidSceneManager.Raid.Dungeon.
                                                              SharedMash.HallEncounters[0].Chance / 100))
                                {
                                    Area.BattleEncounter = new BattleEncounter(RaidSceneManager.Raid.Dungeon.
                                                                               SharedMash.HallEncounters[0].MonsterSet);
                                }
                            }
                        }

                        if (RaidSceneManager.Inventory.PercentageFull >= 0.65f)
                        {
                            if (!RaidSceneManager.Raid.Dungeon.SharedMashExecutionIds.Contains(1))
                            {
                                RaidSceneManager.Raid.Dungeon.SharedMashExecutionIds.Add(1);
                                if (RandomSolver.CheckSuccess((float)RaidSceneManager.Raid.Dungeon.
                                                              SharedMash.HallEncounters[1].Chance / 100))
                                {
                                    Area.BattleEncounter = new BattleEncounter(RaidSceneManager.Raid.Dungeon.
                                                                               SharedMash.HallEncounters[1].MonsterSet);
                                }
                            }
                        }
                    }

                    RaidSceneManager.Instanse.EncounterMonsters(this);
                }
                #endregion
            }
            else if (Area.Type == AreaType.Door)
            {
                Area.Knowledge = Knowledge.Completed;
                return;
            }

            #region Force Curio Tag
            if (Area.Type == AreaType.Curio && (Area.Knowledge == Knowledge.Hidden || Area.Knowledge == Knowledge.Scouted))
            {
                Curio curio = Area.Prop as Curio;
                if (curio.IsQuestCurio == false)
                {
                    foreach (var triggeredHero in RaidSceneManager.Formations.heroes.party.Units)
                    {
                        if (triggeredHero.Character.Trait != null)
                        {
                            if (triggeredHero.Character.Trait.CurioTag == "All" ||
                                curio.Tags.Contains(triggeredHero.Character.Trait.CurioTag))
                            {
                                if (RandomSolver.CheckSuccess(triggeredHero.Character.Trait.TagChance))
                                {
                                    triggeredHero.OverlaySlot.UnitSelected();
                                    if (!(Prop as RaidCurio).Investigated)
                                    {
                                        RaidSceneManager.Instanse.ActivateCurio(this, triggeredHero.Character.Trait);
                                    }
                                    break;
                                }
                            }
                        }
                        var hero = triggeredHero.Character as Hero;
                        foreach (var triggerQuirk in hero.Quirks)
                        {
                            if (triggerQuirk.Quirk.CurioTag == "All" || curio.Tags.Contains(triggerQuirk.Quirk.CurioTag))
                            {
                                if (RandomSolver.CheckSuccess(triggerQuirk.Quirk.CurioTagChance))
                                {
                                    triggeredHero.OverlaySlot.UnitSelected();
                                    if (!(Prop as RaidCurio).Investigated)
                                    {
                                        RaidSceneManager.Instanse.ActivateCurio(this, triggerQuirk.Quirk);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            #endregion

            if (Area.Knowledge != Knowledge.Completed)
            {
                if (Area.Type == AreaType.Hunger)
                {
                    Area.Knowledge = Knowledge.Completed;

                    if (RaidSceneManager.Raid.HungerCooldown <= 0)
                    {
                        RaidSceneManager.Instanse.ActivateHunger(this);
                    }

                    RaidSceneManager.Raid.ResetHungerCooldown();
                }
                else if (Area.Type == AreaType.Empty)
                {
                    Area.Knowledge = Knowledge.Completed;
                    RaidSceneManager.Raid.HungerCooldown--;
                }
                else if (Area.Knowledge == Knowledge.Hidden || Area.Knowledge == Knowledge.Scouted)
                {
                    Area.Knowledge = Knowledge.Visited;
                    RaidSceneManager.Raid.HungerCooldown--;
                }
            }

            RaidSceneManager.MapPanel.SetCurrentIndicator(Area as HallSector);
            RaidSceneManager.MapPanel.OnHallSectorEnter(Area as HallSector);
            RaidSceneManager.MapPanel.FocusTarget();
        }
    }
Exemple #30
0
    public void SpawnEncounter(BattleEncounter encounter, bool campfireSurprise)
    {
        MonsterFormation.LoadParty(encounter);
        for (int i = 0; i < MonsterParty.Units.Count; i++)
        {
            var monster = MonsterParty.Units[i].Character as Monster;
            MonsterParty.Units[i].CombatInfo.PrepareForBattle(PickId(), monster, true);
            if (monster.TorchlightModifier != null)
            {
                RaidSceneManager.TorchMeter.Modify(monster.TorchlightModifier);
            }
            RaidSceneManager.TorchMeter.ApplyBuffsForUnit(MonsterParty.Units[i]);
            if (monster.Data.BattleBackdrop != null)
            {
                backdrop.Activate(monster.Data.BattleBackdrop);
            }
            #region Spawn Check
            if (monster.Data.Spawn != null)
            {
                for (int k = 0; k < monster.Data.Spawn.Effects.Count; k++)
                {
                    for (int j = 0; j < monster.Data.Spawn.Effects[k].SubEffects.Count; j++)
                    {
                        monster.Data.Spawn.Effects[k].SubEffects[j].ApplyInstant(MonsterParty.Units[i],
                                                                                 MonsterParty.Units[i], monster.Data.Spawn.Effects[k]);
                    }
                }
                MonsterParty.Units[i].OverlaySlot.UpdateOverlay();
            }
            #endregion
        }
        var shared = MonsterParty.Units.Find(unit => unit.Character.SharedHealth != null);
        if (shared != null)
        {
            SharedHealth.Initialize(MonsterParty.Units, shared.Character.SharedHealth);
        }
        MonsterFormation.overlay.UpdateOverlay();

        SurpriseStatus = SurpriseStatus.Nothing;

        if (MonsterFormation.AlwaysSurprises() || campfireSurprise)
        {
            SurpriseStatus = SurpriseStatus.HeroesSurprised;
        }
        else if (MonsterFormation.AlwaysBeSurprised())
        {
            SurpriseStatus = SurpriseStatus.MonstersSurprised;
        }
        else
        {
            if (MonsterFormation.CanBeSurprised())
            {
                float monstersSurprised = 0.1f + RaidSceneManager.TorchMeter.CurrentRange.MonstersSurprised;
                for (int i = 0; i < HeroParty.Units.Count; i++)
                {
                    monstersSurprised += HeroParty.Units[i].Character[AttributeType.MonsterSurpirseChance].ModifiedValue;
                }
                monstersSurprised = Mathf.Clamp(monstersSurprised, 0, 0.65f);
                if (RandomSolver.CheckSuccess(monstersSurprised))
                {
                    SurpriseStatus = SurpriseStatus.MonstersSurprised;
                }
            }

            if (MonsterFormation.CanSurprise() && SurpriseStatus == SurpriseStatus.Nothing)
            {
                float heroesSurprised = 0.1f + RaidSceneManager.TorchMeter.CurrentRange.HeroesSurprised;
                for (int i = 0; i < HeroParty.Units.Count; i++)
                {
                    heroesSurprised += HeroParty.Units[i].Character[AttributeType.PartySurpriseChance].ModifiedValue;
                }
                heroesSurprised = Mathf.Clamp(heroesSurprised, 0, 0.65f);
                if (RandomSolver.CheckSuccess(heroesSurprised))
                {
                    SurpriseStatus = SurpriseStatus.HeroesSurprised;
                }
            }
        }
        Round.StartBattle(this);
    }