public BattleEventArgs(BattleEventType type, ActiveMonster monster, int hpBefore, int hpAfter) { Type = type; Monster = monster; HPBefore = hpBefore; HPAfter = hpAfter; }
protected void HandleLockInBeginning(ActiveMonster current, MultiEffect lockInEffect, ActiveMonster opponent) { if (current.SelectedMove.Effects.Any(e => e.Type == MoveEffectType.CancelEnemyMove)) { OnSendMessage("{0}{1} can't move!", opponent.Trainer.MonNamePrefix, opponent.Monster.Name); } current.QueuedMove = current.SelectedMove; if (lockInEffect.Min == 2 && lockInEffect.Max == 5) { current.QueuedMoveLimit = new int[] { 2, 2, 2, 3, 3, 3, 4, 5 } }
protected bool HandleDisableEffect(ActiveMonster current, ActiveMonster opponent) { if (opponent.DisabledCount > 0) { messageBuffer.AppendLine("But, it failed!"); return(false); } else { Move[] enabled = opponent.Moves.Zip(opponent.CurrentPP, (move, pp) => new KeyValuePair <Move, int>(move, pp)).Where(p => p.Value > 0).Select(p => p.Key).ToArray(); if (enabled.Length <= 0) { messageBuffer.AppendLine("But, it failed!"); return(false); } else { Move disabledMove = enabled[Rng.Next(0, enabled.Length)]; for (int i = 0; i < opponent.Moves.Length; i++) { if (opponent.Moves[i] == disabledMove) { opponent.DisabledMoveIndex = i; break; } } MultiEffect disableEffect = (MultiEffect)current.SelectedMove.Effects.Where(e => e.Type == MoveEffectType.Disable).First(); opponent.DisabledCount = Rng.Next(disableEffect.Min, disableEffect.Max + 1); messageBuffer.AppendLine(string.Format("{0}{1}'s {2} was disabled!", opponent.Trainer.MonNamePrefix, opponent.Monster.Name, disabledMove.Name.ToUpper())); return(true); } } }
public BattleEventArgs(BattleEventType type, ActiveMonster monster, StatusCondition status) { Type = type; Monster = monster; Status = status; }
public BattleEventArgs(BattleEventType type, ActiveMonster monster, Move move) { Type = type; Monster = monster; Move = move; }
public BattleEventArgs(BattleEventType type, ActiveMonster monster) { Type = type; Monster = monster; }
public bool HandleStatusEffect(ActiveMonster current, Move move, ActiveMonster opponent, StatusEffect eff, bool hitOpponent) { if (eff.Type != MoveEffectType.Status) { return(false); } bool ret = false; if (Rng.Next(0, 256) < eff.Chance) { ActiveMonster[] mons = new ActiveMonster[] { current, opponent }; for (int i = 0; i < mons.Length; i++) { if (mons[i] == null) { continue; } Who who = i == 0 ? Who.Self : Who.Foe; if (eff.Who == Who.Foe && who == Who.Foe && opponent.SubstituteHP > 0) { if (move.Category == ElementCategory.Status) { messageBuffer.AppendLine(string.Format("It didn't affect {0}{1}.", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); } continue; } if (mons[i] != null && (eff.Who == who || eff.Who == Who.Both) && (i == 0 || hitOpponent)) { if (eff.Status == StatusCondition.Faint) { mons[i].Monster.CurrentHP = 0; ret = true; } else if (eff.Status == StatusCondition.Confusion) { if (mons[i].IsConfused) { messageBuffer.AppendLine(string.Format("{0}{1} is already confused!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); } else { messageBuffer.AppendLine(string.Format(eff.Message ?? "{0}{1} became confused!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); mons[i].ConfusedCount = Rng.Next(2, 6); ret = true; } } else if (eff.Status == StatusCondition.Flinch) { mons[i].Flinched = true; ret = true; } else if ((eff.Force || mons[i].Monster.Status == StatusCondition.None) && !mons[i].Species.IsImmuneToStatus(eff.Status)) { string message = eff.Message; if (mons[i].Monster.Status != StatusCondition.None && eff.Force && !string.IsNullOrEmpty(eff.ForceMessage)) { message = eff.ForceMessage; } mons[i].Monster.Status = eff.Status; ret = true; switch (eff.Status) { case StatusCondition.Paralysis: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} was paralyzed!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); mons[i].EffectiveStats.Speed = (int)(((decimal)mons[i].EffectiveStats.Speed) * 0.25m); break; case StatusCondition.Sleep: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} fell asleep!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); mons[i].Monster.SleepCounter = eff.TurnLimit > 0 ? eff.TurnLimit : Rng.Next(1, 8); break; case StatusCondition.Burn: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} was burned!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); mons[i].EffectiveStats.Attack = (int)(((decimal)mons[i].EffectiveStats.Attack) * 0.5m); break; case StatusCondition.BadlyPoisoned: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} was badly poisoned!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); break; case StatusCondition.Freeze: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} was frozen!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); break; default: messageBuffer.AppendLine(string.Format(message ?? "{0}{1} was {2}ed!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name, eff.Status.ToString().ToLower())); break; } } else if (move.Category == ElementCategory.Status) { messageBuffer.AppendLine(string.Format("It didn't affect {0}{1}.", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); } } } } return(ret); }
public bool HandleStatEffect(ActiveMonster current, ActiveMonster opponent, StatEffect eff, bool hitOpponent, bool showFailMessage = true) { bool ret = false; if (Rng.Next(0, 256) < eff.Chance) { ActiveMonster[] mons = new ActiveMonster[] { current, opponent }; for (int i = 0; i < mons.Length; i++) { if (mons[i] == null) { continue; } Who who = i == 0 ? Who.Self : Who.Foe; if (eff.Who == Who.Foe && who == Who.Foe && opponent.SubstituteHP > 0) { if (showFailMessage) { messageBuffer.AppendLine("But, it failed!"); } continue; } if (mons[i] != null && (eff.Who == who || eff.Who == Who.Both) && (i == 0 || hitOpponent)) { if (i == 1 && mons[i].ProtectStages) { if (showFailMessage) { messageBuffer.AppendLine("But, it failed!"); } } else if (eff.Temporary) { mons[i].EffectiveStats[eff.Stat] = (int)(((decimal)mons[i].EffectiveStats[eff.Stat]) * eff.Multiplier); } else if (eff.Condition == "defense-only") { bool worked = false; if (eff.Stat == StatType.Defense && mons[i].DefenseMultiplier == 1) { mons[i].DefenseMultiplier = (int)eff.Multiplier; worked = true; } else if (eff.Stat == StatType.Special && mons[i].SpecialDefenseMultiplier == 1) { mons[i].SpecialDefenseMultiplier = (int)eff.Multiplier; worked = true; } else { messageBuffer.AppendLine("But, it failed!"); } if (worked && !string.IsNullOrWhiteSpace(eff.Message)) { messageBuffer.AppendLine(string.Format(eff.Message, mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); } if (worked) { ret = true; } } else { if ((eff.Change > 0 && mons[i].StatStages[eff.Stat] >= 6) || (eff.Change < 0 && mons[i].StatStages[eff.Stat] <= -6)) { if (showFailMessage) { messageBuffer.AppendLine("Nothing happened!"); } } else { if (!string.IsNullOrWhiteSpace(eff.Message)) { messageBuffer.AppendLine(string.Format(eff.Message, mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name)); } if (eff.Stat == StatType.CritRatio) { mons[i].EffectiveStats.CritRatio = eff.Constant; } else { mons[i].StatStages[eff.Stat] += eff.Change; if (mons[i].StatStages[eff.Stat] > 6) { mons[i].StatStages[eff.Stat] = 6; } else if (mons[i].StatStages[eff.Stat] < -6) { mons[i].StatStages[eff.Stat] = -6; } messageBuffer.AppendLine(string.Format("{0}{1}'s {2} {3}{4}!", mons[i].Trainer.MonNamePrefix, mons[i].Monster.Name, eff.Stat.ToString().ToUpper(), eff.Change > 1 ? "greatly " : eff.Change < -1 ? "sharply " : "", eff.Change > 0 ? "rose" : "fell")); mons[i].Recalc(eff.Stat); } ret = true; } } } } } return(ret); }
protected void HandleDamageOverTime(ActiveMonster current, ActiveMonster opponent) { if (current.Monster.Status == StatusCondition.Poison || current.Monster.Status == StatusCondition.BadlyPoisoned) { OnSendMessage("{0}{1}'s hurt by poison!", current.Trainer.MonNamePrefix, current.Monster.Name); OnBattleEvent(new BattleEventArgs(BattleEventType.StatusAilment, current, StatusCondition.Poison)); int damage = (int)(((decimal)current.Monster.Stats.HP) / 16m); if (current.Monster.Status == StatusCondition.BadlyPoisoned) { damage = damage * current.BadlyPoisonedCount++; } int oldHP = current.Monster.CurrentHP; int newHP = Math.Max(0, current.Monster.CurrentHP - damage); OnBattleEvent(new BattleEventArgs(BattleEventType.MonHPChanged, current, oldHP, newHP)); current.Monster.CurrentHP = newHP; current.AccumulatedDamage += damage; OnSendDebugMessage("Did {0} damage to {1}{2}", damage, current.Trainer.MonNamePrefix, current.Monster.Name); } else if (current.Monster.Status == StatusCondition.Burn) { OnSendMessage("{0}{1}'s hurt by the burn!", current.Trainer.MonNamePrefix, current.Monster.Name); OnBattleEvent(new BattleEventArgs(BattleEventType.StatusAilment, current, StatusCondition.Burn)); int damage = (int)(((decimal)current.Monster.Stats.HP) / 16m); int oldHP = current.Monster.CurrentHP; int newHP = Math.Max(0, current.Monster.CurrentHP - damage); OnBattleEvent(new BattleEventArgs(BattleEventType.MonHPChanged, current, oldHP, newHP)); current.Monster.CurrentHP = newHP; current.AccumulatedDamage += damage; OnSendDebugMessage("Did {0} damage to {1}{2}", damage, current.Trainer.MonNamePrefix, current.Monster.Name); } if (current.IsSeeded) { int damage = (int)(((decimal)current.Monster.Stats.HP) / 16m); if (damage == 0) { damage = 1; } if (current.Monster.Status == StatusCondition.BadlyPoisoned) { damage = damage * current.BadlyPoisonedCount; } OnBattleEvent(new BattleEventArgs(BattleEventType.StatusAilment, current, StatusCondition.Seeded)); int oldHP = current.Monster.CurrentHP; int newHP = Math.Max(0, current.Monster.CurrentHP - damage); OnSendDebugMessage("Did {0} damage to {1}{2}", damage, current.Trainer.MonNamePrefix, current.Monster.Name); OnBattleEvent(new BattleEventArgs(BattleEventType.MonHPChanged, current, oldHP, newHP)); current.Monster.CurrentHP = newHP; oldHP = opponent.Monster.CurrentHP; int hpRestored = Math.Min(damage, opponent.Monster.Stats.HP - opponent.Monster.CurrentHP); OnBattleEvent(new BattleEventArgs(BattleEventType.MonHPChanged, opponent, oldHP, oldHP + hpRestored)); opponent.Monster.CurrentHP += hpRestored; OnSendDebugMessage("Restored {0} HP to {1}{2}", hpRestored, opponent.Trainer.MonNamePrefix, opponent.Monster.Name); OnSendMessage("LEECH SEED saps {0}{1}!", current.Trainer.MonNamePrefix, current.Monster.Name); } }
protected void HandleFainting(ActiveMonster current, bool isPlayer, ActiveMonster opponent) { if (current.Monster.CurrentHP == 0) { OnBattleEvent(new BattleEventArgs(BattleEventType.MonFainted, current)); current.Monster.Status = StatusCondition.Faint; OnSendMessage("{0}{1} fainted!", current.Trainer.MonNamePrefix, current.Monster.Name); if (!current.AnyMonstersRemaining) { current.Monster = null; if (isPlayer) { OnSendMessage("{0} is out of usable Pokémon! {0} blacked out!", current.Trainer.Name); } else { OnSendMessage("{0} defeated {1}!", this.Player.Name, current.Trainer.Name); } if (RewardMoney > 0) { OnSendMessage("{0} picked up ${1}!", isPlayer ? Foe.Name : Player.Name, RewardMoney); } return; } bool playerShifted = false; Monster playerNextMon = null; if (isPlayer) { Monster mon = PlayerChooseNextMon(current.Trainer, false); while (mon.CurrentHP <= 0) { OnSendMessage("There's no will to fight!"); mon = PlayerChooseNextMon(current.Trainer, false); } current.Monster = mon; } else { Monster aboutToUse = null; if (FoeChooseNextMon != null) { aboutToUse = FoeChooseNextMon(current.Trainer, false); } else { aboutToUse = current.Trainer.Party.Where(m => m != null && m.CurrentHP > 0 && m.Status != StatusCondition.Faint).FirstOrDefault(); } if (Shift) { OnSendMessage("{0} is about to use {1}!", current.Trainer.Name, aboutToUse.Name); OnSendMessage("Will {0} change Pokémon?", opponent.Trainer.Name); playerNextMon = PlayerChooseNextMon(opponent.Trainer, true); while (playerNextMon != null && playerNextMon != opponent.Monster && playerNextMon.CurrentHP <= 0) { OnSendMessage("There's no will to fight!"); playerNextMon = PlayerChooseNextMon(current.Trainer, true); } if (playerNextMon != null && playerNextMon != opponent.Monster) { playerShifted = true; } } if (current.Monster.CurrentHP <= 0) { current.Monster.Status = StatusCondition.Faint; } current.Monster = aboutToUse; } if (isPlayer) { OnSendMessage(GetPlayerSentOutText(), current.Monster.Name); } else { OnSendMessage("{0} sent out {1}!", current.Trainer.Name, current.Monster.Name); } OnBattleEvent(new BattleEventArgs(BattleEventType.MonSentOut, current)); if (playerShifted) { OnSendMessage(GetPlayerRecalledText(), opponent.Monster.Name); OnBattleEvent(new BattleEventArgs(BattleEventType.MonRecalled, opponent)); opponent.Monster = playerNextMon; OnSendMessage(GetPlayerSentOutText(), opponent.Monster.Name); OnBattleEvent(new BattleEventArgs(BattleEventType.MonSentOut, opponent)); } //cancel trapping move that isn't rage if (opponent.QueuedMove != null && opponent.QueuedMove.Effects.Any(e => e.Type == MoveEffectType.LockInMove && ((LockInEffect)e).ConstantDamage)) { opponent.QueuedMove = null; opponent.QueuedMoveDamage = -1; opponent.QueuedMoveLimit = -1; } } }