protected virtual Validation Validate(ColossoFighter User) { List <string> log = new List <string>(); if (!User.IsAlive) { return(new Validation(false, log)); } if (User.HasCondition(Condition.Stun)) { log.Add($"{User.Name} can't move."); return(new Validation(false, log)); } if (User.HasCondition(Condition.Sleep)) { log.Add($"{User.Name} is asleep!"); return(new Validation(false, log)); } if (User.HasCondition(Condition.Flinch)) { log.Add($"{User.Name} can't move."); User.RemoveCondition(Condition.Flinch); return(new Validation(false, log)); } if (User.HasCondition(Condition.ItemCurse) && !User.IsImmuneToItemCurse && Global.RandomNumber(0, 3) == 0) { log.Add($"{User.Name} can't move."); return(new Validation(false, log)); } return(new Validation(true, log)); }
protected override Validation Validate(ColossoFighter user) { var log = new List <string>(); var t = base.Validate(user); if (!t.IsValid) { return(t); } log.AddRange(t.Log); //Psy Seal: //PPCost > 1 is, because Items are right now implemented as Psynergy with PPCost 1 if (PpCost > 1 && user.HasCondition(Condition.Seal)) { log.Add($"{user.Name}'s Psynergy is sealed!"); return(new Validation(false, log)); } if (user.Stats.PP < PpCost) { log.Add($"{user.Name} has not enough PP to cast {Name}."); return(new Validation(false, log)); } var targets = GetTarget(user); if (!Effects.Any(i => i is ReviveEffect || i is MysticCallEffect) && targets.TrueForAll(i => !i.IsAlive)) { log.Add( $"{user.Name} wants to {(PpCost == 1 ? "use" : "cast")} {Name}, but {(targets.Count == 1 ? "the target is" : "all the targets are")} down."); if (user.Moves.FirstOrDefault(m => m is Defend) != null) { log.AddRange(user.Moves.FirstOrDefault(m => m is Defend).Use(user)); } return(new Validation(false, log)); } user.Stats.PP -= (int)PpCost; log.Add($"{Emote} {user.Name} {(PpCost == 1 ? "uses" : "casts")} {Name}!"); return(new Validation(true, log)); }
protected override List <string> InternalUse(ColossoFighter user) { if (user.Weapon != null) { Emote = user.Weapon.Icon; } var enemy = GetTarget(user).First(); var log = new List <string> { $"{Emote} {user.Name} attacks!" }; if (!enemy.IsAlive) { log.Add($"{enemy.Name} is down already!"); if (user.Moves.FirstOrDefault(m => m is Defend) != null) { log.AddRange(user.Moves.FirstOrDefault(m => m is Defend).Use(user)); } return(log); } var chanceToMiss = 16; if (user.HasCondition(Condition.Delusion)) { chanceToMiss = 2; } if (!enemy.HasCondition(Condition.Delusion) && enemy.Stats.Spd > 0 && Global.RandomNumber(0, chanceToMiss) == 0) { log.Add($"{enemy.Name} dodges the blow!"); return(log); } var weaponUnleashed = user.Weapon is { IsUnleashable : true } && Global.RandomNumber(0, 100) <= user.UnleashRate;
protected override Validation Validate(ColossoFighter User) { List <string> log = new List <string>(); var t = base.Validate(User); if (!t.isValid) { return(t); } log.AddRange(t.log); //Psy Seal: //PPCost > 1 is, because Items are right now implemented as Psynergy with PPCost 1 if (PPCost > 1 && User.HasCondition(Condition.Seal)) { log.Add($"{User.name}'s Psynergy is sealed!"); return(new Validation(false, log)); } if (User.stats.PP < PPCost) { log.Add($"{User.name} has not enough PP to cast {this.name}."); return(new Validation(false, log)); } List <ColossoFighter> targets = GetTarget(User); if (!effects.Any(i => i is ReviveEffect) && targets.TrueForAll(i => !i.IsAlive)) { log.Add($"{User.name} wants to {(PPCost == 1 ? "use" : "cast")} {name}, but {(targets.Count == 1 ? "the target is" : "all the targets are")} down."); return(new Validation(false, log)); } User.stats.PP -= (int)PPCost; log.Add($"{emote} {User.name} {(PPCost == 1 ? "uses" : "casts")} {this.name}!"); return(new Validation(true, log)); }
public override List <string> Apply(ColossoFighter user, ColossoFighter target) { var log = new List <string>(); if (!target.IsAlive) { return(log); } if (target.HasCondition(Condition.Key) || target.HasCondition(Condition.Trap) || target.HasCondition(Condition.Decoy)) { log.Add($"A magical barrier is protecting {target.Name}."); return(log); } if (!target.IsAlive) { return(log); } var baseDmg = Global.RandomNumber(0, 4); var dmg = AttackBased ? Math.Max(0, (user.Stats.Atk * user.MultiplyBuffs("Attack") - target.Stats.Def * target.IgnoreDefense * target.MultiplyBuffs("Defense")) / 2) : (int)Power; var elMult = 1 + (user.ElStats.GetPower(Element) * user.MultiplyBuffs("Power") - target.ElStats.GetRes(Element) * target.MultiplyBuffs("Resistance")) / (AttackBased ? 400 : 200); elMult = Math.Max(0.5, elMult); elMult = Math.Max(0, elMult); var prctdmg = (uint)(target.Stats.MaxHP * PercentageDamage / 100); var realDmg = (uint)((baseDmg + dmg + AddDamage) * DmgMult * elMult * target.DefensiveMult * user.OffensiveMult + prctdmg); var punctuation = "!"; if (target.ElStats.GetRes(Element) == target.ElStats.HighestRes()) { punctuation = "."; } if (target.ElStats.GetRes(Element) == target.ElStats.LowestRes()) { punctuation = "!!!"; if (user is PlayerFighter k) { k.BattleStats.AttackedWeakness++; } } realDmg = Math.Max(1, realDmg); log.AddRange(target.DealDamage(realDmg, punctuation)); user.DamageDoneThisTurn += realDmg; if (user is PlayerFighter p) { p.BattleStats.DamageDealt += realDmg; if (!target.IsAlive) { p.BattleStats.Kills++; } } if (target.IsAlive && target.HasCondition(Condition.Counter)) { var counterAtk = target.Stats.Atk * target.MultiplyBuffs("Attack"); var counterDef = user.Stats.Def * user.MultiplyBuffs("Defense") * user.IgnoreDefense; uint counterDamage = (uint)Global.RandomNumber(0, 4); if (counterDef < counterAtk) { counterDamage += (uint)((counterAtk - counterDef) * user.DefensiveMult / 2); } log.Add($"{target.Name} strikes back!"); log.AddRange(user.DealDamage(counterDamage)); } return(log); }
protected override List <string> InternalUse(ColossoFighter User) { if (User.Weapon != null) { emote = User.Weapon.Icon; } var enemy = GetTarget(User).First(); var log = new List <string> { $"{emote} {User.Name} attacks!" }; if (!enemy.IsAlive) { log.Add($"{enemy.Name} is down already!"); return(log); } int chanceToMiss = 16; if (User.HasCondition(Condition.Delusion)) { chanceToMiss = 2; } if (Global.Random.Next(0, chanceToMiss) == 0) { log.Add($"{enemy.Name} dodges the blow!"); return(log); } bool weaponUnleashed = User.Weapon != null && User.Weapon.IsUnleashable && Global.Random.Next(0, 100) <= User.unleashRate; if (weaponUnleashed) { log.Add($"{User.Weapon.IconDisplay} {User.Name}'s {User.Weapon.Name} lets out a howl! {User.Weapon.Unleash.UnleashName}!"); User.Weapon.Unleash.Effects .Where(e => e.timeToActivate == IEffect.TimeToActivate.beforeDamge) .ToList() .ForEach(e => log.AddRange(e.Apply(User, enemy))); } if (!enemy.IsAlive) { return(log); } var atk = User.Stats.Atk * User.MultiplyBuffs("Attack"); var def = enemy.Stats.Def * enemy.MultiplyBuffs("Defense") * enemy.ignoreDefense; uint damage = (uint)Global.Random.Next(0, 4); if (def < atk) { damage = (uint)((atk - def) / 2); } damage += User.addDamage; damage = (uint)(damage * User.offensiveMult); var element = Element.none; if (User.Weapon != null) { element = User.Weapon.DamageAlignment; } if (weaponUnleashed) { element = User.Weapon.Unleash.UnleashAlignment; } //var elMult = 1 + Math.Max(0.0, (int)User.elstats.GetPower(element) * User.MultiplyBuffs("Power") - (int)enemy.elstats.GetRes(element) * enemy.MultiplyBuffs("Resistance")) / 400; var elMult = 1 + (User.ElStats.GetPower(element) * User.MultiplyBuffs("Power") - enemy.ElStats.GetRes(element) * enemy.MultiplyBuffs("Resistance")) / 400; var punctuation = "!"; if (enemy.ElStats.GetRes(element) == enemy.ElStats.HighestRes()) { punctuation = "."; } damage = (uint)(damage * elMult); damage = (uint)(damage * enemy.defensiveMult); if (enemy.ElStats.GetRes(element) == enemy.ElStats.LeastRes()) { punctuation = "!!!"; if (User is PlayerFighter p) { p.battleStats.AttackedWeakness++; } } if (element == Psynergy.Element.none) { punctuation = "!"; } User.addDamage = 0; if (!weaponUnleashed && Global.Random.Next(0, 8) == 0) { log.Add("Critical!!"); damage = (uint)(damage * 1.25 + Global.Random.Next(5, 15)); } damage = Math.Max(1, damage); log.AddRange(enemy.DealDamage(damage, punctuation)); User.damageDoneThisTurn += damage; if (weaponUnleashed) { User.Weapon.Unleash.Effects .Where(e => e.timeToActivate == IEffect.TimeToActivate.afterDamage) .ToList() .ForEach(e => log.AddRange(e.Apply(User, enemy))); } if (enemy.IsAlive && enemy.HasCondition(Condition.Counter)) { var counterAtk = enemy.Stats.Atk * enemy.MultiplyBuffs("Attack"); var counterDef = User.Stats.Def * User.MultiplyBuffs("Defense") * User.ignoreDefense; uint CounterDamage = (uint)Global.Random.Next(0, 4); if (def < atk) { CounterDamage = (uint)((counterAtk - counterDef) * User.defensiveMult / 2); } log.Add($"{enemy.Name} strikes back!"); log.AddRange(User.DealDamage(CounterDamage)); } if (User is PlayerFighter player) { player.battleStats.DamageDealt += damage; if (!enemy.IsAlive) { player.battleStats.KillsByHand++; player.battleStats.Kills++; player.battleStats.HighestDamage = Math.Max(player.battleStats.HighestDamage, damage); } } return(log); }
public override bool InternalValidSelection(ColossoFighter User) { return(User.stats.PP >= PPCost && !(PPCost > 1 && User.HasCondition(Condition.Seal))); }
public override bool InternalValidSelection(ColossoFighter user) { return(user.Stats.PP >= PpCost && !(PpCost > 1 && user.HasCondition(Condition.Seal))); }