コード例 #1
0
ファイル: Player.cs プロジェクト: ThePeterLuu/Ninja-Simulator
        public double Attack(StrikingDummy target, WeaponSkills weaponSkill)
        {
            var animationLocked = QueuedEffects.ContainsKey(Skills.StatusEffects.AnimationLocked);

            if (GcdDuration > 0 || animationLocked)
            {
                return(0);
            }

            var potency = WeaponLibrary.WeaponPotencies(weaponSkill, LastSkills);
            var damage  = FormulaLibrary.WeaponSkills(potency, Weapon.WeaponDamage, GetDexterity(), Det, CalculateMultiplier(target, DamageType.Slashing));

            if (StatusEffects.ContainsKey(Skills.StatusEffects.Duality))
            {
                damage *= 2;
                StatusEffects.Remove(Skills.StatusEffects.Duality);
            }
            else
            {
                damage = (damage * CalculateCritChance() * FormulaLibrary.CritDmg(Crt)) +
                         (damage * (1 - CalculateCritChance()));
            }

            WeaponLibrary.QueueEffect(this, target, weaponSkill);
            var gcdMultiplier = StatusEffects.ContainsKey(Skills.StatusEffects.Huton) ? 0.85 : 1.00;

            GcdDuration = (int)TimeSpan.FromSeconds(FormulaLibrary.Gcd(Sks, gcdMultiplier)).TotalMilliseconds;
            LastSkills.Push(weaponSkill);

            return(damage);
        }
コード例 #2
0
        public static void QueueEffect(Player player, StrikingDummy strikingDummy, WeaponSkills weaponSkill)
        {
            WeaponSkills lastSkill;
            player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });

            switch (weaponSkill)
            {
                case WeaponSkills.ShadowFang:
                    if (player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                    {
                        strikingDummy.QueuedEffects.Add(StatusEffects.ShadowFang, new EffectSnapshot
                        {
                            Duration = 585,
                            CritChance = player.CalculateCritChance(),
                            Crt = player.Crt,
                            Det = player.Det,
                            Multiplier = player.CalculateDamageOverTimeMultiplier(DamageType.Physical, strikingDummy),
                            Dex = player.GetDexterity(),
                            Potency = 40,
                            Target = strikingDummy,
                            WeaponDamage = player.Weapon.WeaponDamage
                        });
                    }
                    break;
                case WeaponSkills.Mutilate:
                    strikingDummy.QueuedEffects.Add(StatusEffects.Mutilate, new EffectSnapshot
                    {
                        Duration = 400,
                        CritChance = player.CalculateCritChance(),
                        Crt = player.Crt,
                        Det = player.Det,
                        Multiplier = player.CalculateDamageOverTimeMultiplier(DamageType.Physical, strikingDummy),
                        Dex = player.GetDexterity(),
                        Potency = 30,
                        Target = strikingDummy,
                        WeaponDamage = player.Weapon.WeaponDamage
                    });
                    break;
                case WeaponSkills.DancingEdge:
                    lastSkill = player.LastSkills.Pop();
                    if (lastSkill == WeaponSkills.GustSlash && player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                    {
                        strikingDummy.QueuedEffects.Add(StatusEffects.DancingEdge, new EffectSnapshot { Duration = 395, Target = strikingDummy });
                    }
                    player.LastSkills.Push(lastSkill);
                    break;
                case WeaponSkills.ArmorCrush:
                    lastSkill = player.LastSkills.Pop();
                    if (lastSkill == WeaponSkills.GustSlash && player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                    {
                        player.QueuedEffects.Add(StatusEffects.ArmorCrush, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    }
                    player.LastSkills.Push(lastSkill);
                    break;
            }
        }
コード例 #3
0
ファイル: Battle.cs プロジェクト: Koarth/Simulator-of-Light
        public Battle(IActor[] actors, int length = 180, int num_enemies = 1)
        {
            Actors      = actors;
            Friendlies  = actors;
            FightLength = length * 1000;
            _logger.Debug("Fight length: {0}", FightLength);

            Time       = 0;
            TickOffset = new Random().Next(0, 3000);
            _logger.Debug("Tick offset: {0}", TickOffset);

            foreach (IActor actor in actors)
            {
                _logger.Debug("Actor added: [{0}] {1}", actor.JobID.ToString(), actor.Name);
            }

            // Initialize enemies.
            Enemies = new ITarget[num_enemies];
            for (int i = 0; i < num_enemies; i++)
            {
                Enemies[i] = new StrikingDummy();
                _logger.Debug("Enemy added: {0}", Enemies[i].Name);
            }

            Targets = Friendlies.ToList().Concat(Enemies.ToList()).ToArray();

            EventQueue = new IntervalHeap <BattleEvent>();
            EventLog   = new ArrayList <CombatLogEvent>();

            // Add the inital Actor decisions to the queue.  These should drive the rest of the
            // simulation.
            foreach (IActor actor in Actors)
            {
                EventQueue.Add(new BattleEvent(BattleEventType.ACTOR_READY, Time, actor));
            }

            // Event to signal the end of the fight.
            EventQueue.Add(new BattleEvent(BattleEventType.FIGHT_COMPLETE, FightLength));

            // Event to signal the next Aura tick.
            EventQueue.Add(new BattleEvent(BattleEventType.AURA_TICK, Time + TickOffset));

            if (TickOffset > 1500)
            {
                EventQueue.Add(new BattleEvent(BattleEventType.REGEN_TICK, 1500 - TickOffset));
            }
            else
            {
                EventQueue.Add(new BattleEvent(BattleEventType.REGEN_TICK, TickOffset + 1500));
            }
        }
コード例 #4
0
        public static void QueueEffect(Player player, StrikingDummy strikingDummy, WeaponSkills weaponSkill)
        {
            player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = Game.GetGlobalAnimationLockDurationMs(), Target = player });

            switch (weaponSkill)
            {
                case WeaponSkills.HeavyThrust:
                    player.QueuedEffects.Add(StatusEffects.HeavyThrust, new EffectSnapshot { Duration = 1289, Target = player });
                    break;
                case WeaponSkills.Disembowel:
                    if (player.LastSkills.Peek() == WeaponSkills.ImpulseDrive)
                    {
                        strikingDummy.QueuedEffects.Add(StatusEffects.Disembowel, new EffectSnapshot { Duration = 1651, Target = strikingDummy });
                    }
                    break;
                case WeaponSkills.ChaosThrust:
                    var lastSkill = player.LastSkills.Pop();
                    if (lastSkill == WeaponSkills.Disembowel && player.LastSkills.Peek() == WeaponSkills.ImpulseDrive)
                    {
                        strikingDummy.QueuedEffects.Add(StatusEffects.ChaosThrust, new EffectSnapshot
                        {
                            Duration = 1651,
                            CritChance = player.CalculateCritChance(),
                            Crt = player.Crt,
                            Det = player.Det,
                            Multiplier = player.CalculateDamageOverTimeMultiplier(),
                            Str = player.GetStrength(),
                            Potency = 35,
                            Target = strikingDummy,
                            WeaponDamage = player.Weapon.WeaponDamage
                        });
                    }
                    player.LastSkills.Push(lastSkill);
                    break;
                case WeaponSkills.Phlebotomize:
                    strikingDummy.QueuedEffects.Add(StatusEffects.Phlebotomize, new EffectSnapshot
                    {
                        Duration = 1111,
                        CritChance = player.CalculateCritChance(),
                        Crt = player.Crt,
                        Det = player.Det,
                        Multiplier = player.CalculateDamageOverTimeMultiplier(),
                        Str = player.GetStrength(),
                        Potency = 30,
                        Target = strikingDummy,
                        WeaponDamage = player.Weapon.WeaponDamage
                    });
                    break;
            }
        }
コード例 #5
0
ファイル: Player.cs プロジェクト: ThePeterLuu/Ninja-Simulator
        public bool UseBuffSpell(StrikingDummy target, Spells spell, bool verbose = false)
        {
            if (GcdDuration <= 0)
            {
                throw new Exception($"Warning! Using off-gcd ability { spell } when GCD is available! Remaining cooldown on { spell }: { Cooldowns[spell]}");
            }

            if (Cooldowns.ContainsKey(spell) || QueuedEffects.ContainsKey(Skills.StatusEffects.AnimationLocked))
            {
                return(false);
            }

            SpellLibrary.QueueEffect(this, spell, target, verbose);
            Cooldowns.Add(spell, SpellLibrary.SpellCooldowns(spell));
            return(true);
        }
コード例 #6
0
        public MainPage()
        {
            IGearsetDAO dao = new GearsetDAOJsonImpl();

            var set = dao.GetEquipmentSetByName("WHMGear");

            PlayerCharacter actor = new PlayerCharacter("Kirima Yaeger", CharacterClan.HYUR_MIDLANDER, JobID.WHM, set);
            StrikingDummy   dummy = new StrikingDummy();

            ITarget[] targets    = new ITarget[] { dummy };
            ITarget[] friendlies = new ITarget[] { actor };

            var decision = actor.DecideAction(1234, friendlies, targets);


            Application.Current.Exit();
        }
コード例 #7
0
ファイル: Player.cs プロジェクト: ThePeterLuu/Ninja-Simulator
        // -- Methods

        public double AutoAttack(StrikingDummy target)
        {
            if (AutoAttackDuration > 0)
            {
                return(0);
            }

            var damage = FormulaLibrary.AutoAttack(Weapon.AutoAttack, GetDexterity(), Det, Weapon.Delay, CalculateMultiplier(target, DamageType.Slashing));

            damage = (damage * CalculateCritChance() * FormulaLibrary.CritDmg(Crt)) +
                     (damage * (1 - CalculateCritChance()));

            AutoAttackDuration = StatusEffects.ContainsKey(Skills.StatusEffects.Huton) ?
                                 (int)(TimeSpan.FromSeconds(Weapon.Delay).TotalMilliseconds * 0.85) :
                                 (int)TimeSpan.FromSeconds(Weapon.Delay).TotalMilliseconds;

            return(damage);
        }
コード例 #8
0
        public static void QueueEffect(Player player, StrikingDummy strikingDummy, WeaponSkills weaponSkill)
        {
            WeaponSkills lastSkill;

            player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
            });

            switch (weaponSkill)
            {
            case WeaponSkills.ShadowFang:
                if (player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                {
                    strikingDummy.QueuedEffects.Add(StatusEffects.ShadowFang, new EffectSnapshot
                    {
                        Duration     = 585,
                        CritChance   = player.CalculateCritChance(),
                        Crt          = player.Crt,
                        Det          = player.Det,
                        Multiplier   = player.CalculateDamageOverTimeMultiplier(DamageType.Physical, strikingDummy),
                        Dex          = player.GetDexterity(),
                        Potency      = 40,
                        Target       = strikingDummy,
                        WeaponDamage = player.Weapon.WeaponDamage
                    });
                }
                break;

            case WeaponSkills.Mutilate:
                strikingDummy.QueuedEffects.Add(StatusEffects.Mutilate, new EffectSnapshot
                {
                    Duration     = 400,
                    CritChance   = player.CalculateCritChance(),
                    Crt          = player.Crt,
                    Det          = player.Det,
                    Multiplier   = player.CalculateDamageOverTimeMultiplier(DamageType.Physical, strikingDummy),
                    Dex          = player.GetDexterity(),
                    Potency      = 30,
                    Target       = strikingDummy,
                    WeaponDamage = player.Weapon.WeaponDamage
                });
                break;

            case WeaponSkills.DancingEdge:
                lastSkill = player.LastSkills.Pop();
                if (lastSkill == WeaponSkills.GustSlash && player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                {
                    strikingDummy.QueuedEffects.Add(StatusEffects.DancingEdge, new EffectSnapshot {
                        Duration = 395, Target = strikingDummy
                    });
                }
                player.LastSkills.Push(lastSkill);
                break;

            case WeaponSkills.ArmorCrush:
                lastSkill = player.LastSkills.Pop();
                if (lastSkill == WeaponSkills.GustSlash && player.LastSkills.Peek() == WeaponSkills.SpinningEdge)
                {
                    player.QueuedEffects.Add(StatusEffects.ArmorCrush, new EffectSnapshot {
                        Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                    });
                }
                player.LastSkills.Push(lastSkill);
                break;
            }
        }
コード例 #9
0
        public static void QueueEffect(Player player, Spells spell, StrikingDummy target, bool verbose)
        {
            switch (spell)
            {
            case Spells.DreamWithinADream:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Mug:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.InternalRelease:
                player.QueuedEffects.Add(StatusEffects.InternalRelease, new EffectSnapshot {
                    Duration = 650, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.BloodForBlood:
                player.QueuedEffects.Add(StatusEffects.BloodForBlood, new EffectSnapshot {
                    Duration = 650, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Duality:
                player.QueuedEffects.Add(StatusEffects.Duality, new EffectSnapshot {
                    Duration = 650, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.DexterityPotion:
                player.QueuedEffects.Add(StatusEffects.DexterityPotion, new EffectSnapshot {
                    Duration = 949, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = 1334, Target = player
                });
                break;

            case Spells.Jugulate:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.TrickAttack:
                target.QueuedEffects.Add(StatusEffects.TrickAttack, new EffectSnapshot {
                    Duration = 955, Target = target
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.FumaShuriken:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = 500 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Raiton:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = 1000 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.PrePullSuiton:
                player.QueuedEffects.Add(StatusEffects.Suiton, new EffectSnapshot {
                    Duration = 1000, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Suiton:
                player.QueuedEffects.Add(StatusEffects.Suiton, new EffectSnapshot {
                    Duration = 2500, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = 1500 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Kassatsu:
                player.QueuedEffects.Add(StatusEffects.Kassatsu, new EffectSnapshot {
                    Duration = 1000, Target = player
                });
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            case Spells.Delay:
                player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot {
                    Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player
                });
                break;

            default:
                throw new Exception($"Unknown spell { spell }!");
            }

            if (verbose)
            {
                var animationLockDuration = player.QueuedEffects[StatusEffects.AnimationLocked].Duration;
                var remainingGCD          = player.GcdDuration;
                if (animationLockDuration > remainingGCD)
                {
                    Console.WriteLine($"Warning! GCD clipped by { spell } at { GameEngine.GetFormattedGameTime() } by { animationLockDuration - remainingGCD } milliseconds!");
                }
            }
        }
コード例 #10
0
        public static void QueueEffect(Player player, Spells spell, StrikingDummy target, bool verbose)
        {
            switch (spell)
            {
                case Spells.DreamWithinADream:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Mug:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.InternalRelease:
                    player.QueuedEffects.Add(StatusEffects.InternalRelease, new EffectSnapshot { Duration = 650, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.BloodForBlood:
                    player.QueuedEffects.Add(StatusEffects.BloodForBlood, new EffectSnapshot { Duration = 650, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Duality:
                    player.QueuedEffects.Add(StatusEffects.Duality, new EffectSnapshot { Duration = 650, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.DexterityPotion:
                    player.QueuedEffects.Add(StatusEffects.DexterityPotion, new EffectSnapshot { Duration = 949, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = 1334, Target = player });
                    break;
                case Spells.Jugulate:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.TrickAttack:
                    target.QueuedEffects.Add(StatusEffects.TrickAttack, new EffectSnapshot { Duration = 955, Target = target });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.FumaShuriken:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = 500 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Raiton:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = 1000 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.PrePullSuiton:
                    player.QueuedEffects.Add(StatusEffects.Suiton, new EffectSnapshot { Duration = 1000, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Suiton:
                    player.QueuedEffects.Add(StatusEffects.Suiton, new EffectSnapshot { Duration = 2500, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = 1500 + GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Kassatsu:
                    player.QueuedEffects.Add(StatusEffects.Kassatsu, new EffectSnapshot { Duration = 1000, Target = player });
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                case Spells.Delay:
                    player.QueuedEffects.Add(StatusEffects.AnimationLocked, new EffectSnapshot { Duration = GameEngine.GetGlobalAnimationLockDurationMs(), Target = player });
                    break;
                default:
                    throw new Exception($"Unknown spell { spell }!");
            }

            if (verbose)
            {
                var animationLockDuration = player.QueuedEffects[StatusEffects.AnimationLocked].Duration;
                var remainingGCD = player.GcdDuration;
                if (animationLockDuration > remainingGCD)
                {
                    Console.WriteLine($"Warning! GCD clipped by { spell } at { GameEngine.GetFormattedGameTime() } by { animationLockDuration - remainingGCD } milliseconds!");
                }
            }
        }
コード例 #11
0
ファイル: Player.cs プロジェクト: ThePeterLuu/Ninja-Simulator
        public double UseDamageSpell(StrikingDummy target, Spells spell, bool verbose = false)
        {
            if (GcdDuration <= 0 && spell != Spells.PrePullSuiton)
            {
                var remainingCd = Cooldowns.ContainsKey(spell) ? Cooldowns[spell] : 0;
                throw new Exception($"Warning! Using off-gcd ability { spell } when GCD is available! Remaining cooldown on { spell }: { remainingCd }");
            }

            if (Cooldowns.ContainsKey(spell) || QueuedEffects.ContainsKey(Skills.StatusEffects.AnimationLocked))
            {
                return(0);
            }

            if (spell == Spells.FumaShuriken ||
                spell == Spells.Raiton ||
                spell == Spells.Suiton)
            {
                if (Cooldowns.ContainsKey(Spells.FumaShuriken) ||
                    Cooldowns.ContainsKey(Spells.Raiton) ||
                    Cooldowns.ContainsKey(Spells.Suiton))
                {
                    return(0);
                }
            }

            if (spell == Spells.TrickAttack)
            {
                if (!StatusEffects.ContainsKey(Skills.StatusEffects.Suiton))
                {
                    throw new Exception($"Warning! Cannot use TA without Suiton active!");
                }
                if (verbose)
                {
                    Console.WriteLine("Suiton removed after TA cast!");
                }
                StatusEffects.Remove(Skills.StatusEffects.Suiton);
            }

            var potency    = SpellLibrary.SpellPotencies(spell);
            var multiplier = CalculateMultiplier(target, SpellLibrary.SpellDamageType(spell));
            var damage     = FormulaLibrary.WeaponSkills(potency, Weapon.WeaponDamage, GetDexterity(), Det, multiplier);

            var guaranteeCrit = false;

            if (spell == Spells.FumaShuriken ||
                spell == Spells.Raiton ||
                spell == Spells.Suiton)
            {
                if (StatusEffects.ContainsKey(Skills.StatusEffects.Kassatsu))
                {
                    guaranteeCrit = true;
                    StatusEffects.Remove(Skills.StatusEffects.Kassatsu);
                }
            }

            if (guaranteeCrit)
            {
                damage *= FormulaLibrary.CritDmg(Crt);
            }
            else
            {
                damage = (damage * CalculateCritChance() * FormulaLibrary.CritDmg(Crt)) +
                         (damage * (1 - CalculateCritChance()));
            }

            SpellLibrary.QueueEffect(this, spell, target, verbose);

            if (spell == Spells.FumaShuriken)
            {
                Cooldowns.Add(spell, 500 + SpellLibrary.SpellCooldowns(spell));
            }
            else if (spell == Spells.Raiton)
            {
                Cooldowns.Add(spell, 1000 + SpellLibrary.SpellCooldowns(spell));
            }
            else if (spell == Spells.Suiton)
            {
                Cooldowns.Add(spell, 1500 + SpellLibrary.SpellCooldowns(spell));
            }
            else if (spell == Spells.PrePullSuiton)
            {
                Cooldowns.Add(Spells.Suiton, SpellLibrary.SpellCooldowns(Spells.Suiton));
            }
            else
            {
                Cooldowns.Add(spell, SpellLibrary.SpellCooldowns(spell));
            }

            return(damage);
        }