public static PBEBattle LoadReplay(string path) { byte[] fileBytes = File.ReadAllBytes(path); using (var s = new MemoryStream(fileBytes)) using (var r = new EndianBinaryReader(s)) { byte[] hash; using (var md5 = MD5.Create()) { hash = md5.ComputeHash(fileBytes, 0, fileBytes.Length - 16); } for (int i = 0; i < 16; i++) { if (hash[i] != fileBytes[fileBytes.Length - 16 + i]) { throw new InvalidDataException(); } } ushort version = r.ReadUInt16(); PBEBattle b = null; int numEvents = r.ReadInt32(); for (int i = 0; i < numEvents; i++) { IPBEPacket packet = PBEPacketProcessor.CreatePacket(b, r.ReadBytes(r.ReadUInt16())); if (packet is PBEBattlePacket bp) { b = new PBEBattle(bp); } b.Events.Add(packet); } b.BattleState = PBEBattleState.Ended; b.OnStateChanged?.Invoke(b); return(b); } }
internal PBETeams(PBEBattle battle, PBETeamShell team1Shell, string team1TrainerName, PBETeamShell team2Shell, string team2TrainerName) { _team1 = new PBETeam(battle, 0, team1Shell, team1TrainerName); _team2 = new PBETeam(battle, 1, team2Shell, team2TrainerName); _team1.OpposingTeam = _team2; _team2.OpposingTeam = _team1; }
internal PBETeam(PBEBattle battle, byte id, PBETeamShell shell, string trainerName) { Battle = battle; Id = id; Party = new PBEList <PBEPokemon>(Battle.Settings.MaxPartySize); CreateParty(shell, trainerName); }
// Trainer battle internal PBETeam(PBEBattle battle, byte id, IReadOnlyList <PBETrainerInfo> ti, List <PBETrainer> allTrainers) { int count = ti.Count; if (!VerifyTrainerCount(battle.BattleFormat, count)) { throw new ArgumentException($"Illegal trainer count (Format: {battle.BattleFormat}, Team: {id}, Count: {count}"); } foreach (PBETrainerInfo t in ti) { if (!t.IsOkayForSettings(battle.Settings)) { throw new ArgumentOutOfRangeException(nameof(ti), "Team settings do not comply with battle settings."); } } Battle = battle; Id = id; var trainers = new PBETrainer[ti.Count]; for (int i = 0; i < ti.Count; i++) { trainers[i] = new PBETrainer(this, ti[i], allTrainers); } Trainers = new ReadOnlyCollection <PBETrainer>(trainers); }
internal PBETeams(PBEBattle battle) { _team1 = new PBETeam(battle, 0); _team2 = new PBETeam(battle, 1); _team1.OpposingTeam = _team2; _team2.OpposingTeam = _team1; }
public static PBEBattle LoadReplay(string path) { byte[] fileBytes = File.ReadAllBytes(path); using (var s = new MemoryStream(fileBytes)) using (var r = new EndianBinaryReader(s, encoding: EncodingType.UTF16)) { byte[] hash; using (var md5 = MD5.Create()) { hash = md5.ComputeHash(fileBytes, 0, fileBytes.Length - 16); } for (int i = 0; i < 16; i++) { if (hash[i] != fileBytes[fileBytes.Length - 16 + i]) { throw new InvalidDataException(); } } ushort version = r.ReadUInt16(); // Unused for now int seed = r.ReadInt32(); // Unused for now PBEBattle b = null; int numEvents = r.ReadInt32(); for (int i = 0; i < numEvents; i++) { IPBEPacket packet = PBEPacketProcessor.CreatePacket(b, r.ReadBytes(r.ReadUInt16())); if (packet is PBEBattlePacket bp) { b = new PBEBattle(bp); } else if (packet is PBEWildPkmnAppearedPacket wpap) { PBETrainer wildTrainer = b.Teams[1].Trainers[0]; foreach (PBEPkmnAppearedInfo info in wpap.Pokemon) { PBEBattlePokemon pkmn = wildTrainer.TryGetPokemon(info.Pokemon); // Process disguise and position now pkmn.FieldPosition = info.FieldPosition; if (info.IsDisguised) { pkmn.Status2 |= PBEStatus2.Disguised; pkmn.KnownCaughtBall = info.CaughtBall; pkmn.KnownGender = info.Gender; pkmn.KnownNickname = info.Nickname; pkmn.KnownShiny = info.Shiny; pkmn.KnownSpecies = info.Species; pkmn.KnownForm = info.Form; IPBEPokemonData pData = PBEDataProvider.Instance.GetPokemonData(info); pkmn.KnownType1 = pData.Type1; pkmn.KnownType2 = pData.Type2; } b.ActiveBattlers.Add(pkmn); } } b.Events.Add(packet); } b.BattleState = PBEBattleState.Ended; return(b); } }
// Wild battle internal PBETeams(PBEBattle battle, IReadOnlyList <PBETrainerInfo> ti, PBEWildInfo wi, out ReadOnlyCollection <PBETrainer> trainers) { var allTrainers = new List <PBETrainer>(); _team0 = new PBETeam(battle, 0, ti, allTrainers); _team1 = new PBETeam(battle, 1, wi, allTrainers); _team0.OpposingTeam = _team1; _team1.OpposingTeam = _team0; trainers = new ReadOnlyCollection <PBETrainer>(allTrainers); }
// Trainer battle internal PBETeams(PBEBattle battle, IReadOnlyList <PBETrainerInfo> ti0, IReadOnlyList <PBETrainerInfo> ti1, out PBETrainers trainers) { var allTrainers = new List <PBETrainer>(); _team0 = new PBETeam(battle, 0, ti0, allTrainers); _team1 = new PBETeam(battle, 1, ti1, allTrainers); _team0.OpposingTeam = _team1; _team1.OpposingTeam = _team0; trainers = new PBETrainers(allTrainers); }
// Remote battle internal PBETeams(PBEBattle battle, PBEBattlePacket packet, out ReadOnlyCollection <PBETrainer> trainers) { var allTrainers = new List <PBETrainer>(); _team0 = new PBETeam(battle, packet.Teams[0], allTrainers); _team1 = new PBETeam(battle, packet.Teams[1], allTrainers); _team0.OpposingTeam = _team1; _team1.OpposingTeam = _team0; trainers = new ReadOnlyCollection <PBETrainer>(allTrainers); }
public static PBEBattle LoadReplay(string path) { PBESettings settings = PBESettings.DefaultSettings; byte[] fileBytes = File.ReadAllBytes(path); using (var s = new MemoryStream(fileBytes)) using (var r = new BinaryReader(s)) { using (var md5 = MD5.Create()) { byte[] hash = md5.ComputeHash(fileBytes, 0, fileBytes.Length - 16); for (int i = 0; i < 16; i++) { if (hash[i] != fileBytes[fileBytes.Length - 16 + i]) { throw new InvalidDataException(); } } } ushort version = r.ReadUInt16(); var battle = new PBEBattle((PBEBattleFormat)r.ReadByte(), settings); battle.Teams[0].TrainerName = PBEUtils.StringFromBytes(r); var party = new PBEPokemonShell[r.ReadSByte()]; for (int i = 0; i < party.Length; i++) { party[i] = PBEPokemonShell.FromBytes(r, settings); } battle.Teams[0].CreateParty(party, ref battle.pkmnIdCounter); battle.Teams[1].TrainerName = PBEUtils.StringFromBytes(r); party = new PBEPokemonShell[r.ReadSByte()]; for (int i = 0; i < party.Length; i++) { party[i] = PBEPokemonShell.FromBytes(r, settings); } battle.Teams[1].CreateParty(party, ref battle.pkmnIdCounter); var packetProcessor = new PBEPacketProcessor(battle); INetPacket packet; do { byte[] buffer = r.ReadBytes(r.ReadInt16()); packet = packetProcessor.CreatePacket(buffer); battle.Events.Add(packet); } while (!(packet is PBEWinnerPacket)); return(battle); } }
// Wild battle internal PBETeam(PBEBattle battle, byte id, PBEWildInfo wi, List <PBETrainer> allTrainers) { int count = wi.Party.Count; if (!VerifyTrainerCount(battle.BattleFormat, count)) { throw new ArgumentException($"Illegal wild Pokémon count (Format: {battle.BattleFormat}, Count: {count}"); } if (!wi.IsOkayForSettings(battle.Settings)) { throw new ArgumentOutOfRangeException(nameof(wi), "Team settings do not comply with battle settings."); } Battle = battle; Id = id; Trainers = new ReadOnlyCollection <PBETrainer>(new[] { new PBETrainer(this, wi, allTrainers) }); }
// Remote battle internal PBETeam(PBEBattle battle, PBEBattlePacket.PBETeamInfo info, List <PBETrainer> allTrainers) { ReadOnlyCollection <PBEBattlePacket.PBETeamInfo.PBETrainerInfo> ti = info.Trainers; int count = ti.Count; if (!VerifyTrainerCount(battle.BattleFormat, count)) { throw new InvalidDataException(); } Battle = battle; Id = info.Id; var trainers = new PBETrainer[ti.Count]; for (int i = 0; i < trainers.Length; i++) { trainers[i] = new PBETrainer(this, ti[i], allTrainers); } Trainers = new ReadOnlyCollection <PBETrainer>(trainers); }
// Remote battle internal PBETeam(PBEBattle battle, PBEBattlePacket.PBETeamInfo info, List <PBETrainer> allTrainers) { ReadOnlyCollection <PBEBattlePacket.PBETeamInfo.PBETrainerInfo> ti = info.Trainers; int count = ti.Count; if (!VerifyTrainerCount(battle.BattleFormat, count)) { throw new InvalidDataException(); } Battle = battle; Id = info.Id; var trainers = new PBETrainer[ti.Count]; for (int i = 0; i < trainers.Length; i++) { trainers[i] = new PBETrainer(this, ti[i], allTrainers); } Trainers = new ReadOnlyCollection <PBETrainer>(trainers); CombinedName = GetCombinedName(); OpposingTeam = null !; // OpposingTeam is set in PBETeams after both are created }
public string AreSwitchesValid(params PBESwitchIn[] switches) { return(PBEBattle.AreSwitchesValid(this, switches)); }
public string SelectActionsIfValid(IReadOnlyCollection <PBETurnAction> actions) { return(PBEBattle.SelectActionsIfValid(this, actions)); }
// Client constructor internal PBETeam(PBEBattle battle, byte id) { Battle = battle; Id = id; Party = new List <PBEPokemon>(Battle.Settings.MaxPartySize); }
public string AreSwitchesValid(IReadOnlyCollection <PBESwitchIn> switches) { return(PBEBattle.AreSwitchesValid(this, switches)); }
// Will only be accurate for the host public override string ToString() { var sb = new StringBuilder(); sb.AppendLine($"{Nickname}/{Species} {GenderSymbol} Lv.{Level}"); sb.AppendLine($"HP: {HP}/{MaxHP} ({HPPercentage:P2})"); sb.Append($"Types: {PBELocalizedString.GetTypeName(Type1).English}"); if (Type2 != PBEType.None) { sb.Append($"/{PBELocalizedString.GetTypeName(Type2).English}"); } sb.AppendLine(); sb.Append($"Known types: {PBELocalizedString.GetTypeName(KnownType1).English}"); if (KnownType2 != PBEType.None) { sb.Append($"/{PBELocalizedString.GetTypeName(KnownType2).English}"); } sb.AppendLine(); sb.AppendLine($"Position: {Team.TrainerName}'s {FieldPosition}"); sb.AppendLine($"Status1: {Status1}"); if (Status1 == PBEStatus1.Asleep) { sb.AppendLine($"Sleep turns: {Status1Counter}/{SleepTurns}"); } else if (Status1 == PBEStatus1.BadlyPoisoned) { sb.AppendLine($"Toxic Counter: {Status1Counter}"); } sb.AppendLine($"Status2: {Status2}"); if (Status2.HasFlag(PBEStatus2.Confused)) { sb.AppendLine($"Confusion turns: {ConfusionCounter}/{ConfusionTurns}"); } if (Status2.HasFlag(PBEStatus2.Disguised)) { sb.AppendLine($"Disguised as: {DisguisedAsPokemon.Nickname}"); } if (Status2.HasFlag(PBEStatus2.Infatuated)) { sb.AppendLine($"Infatuated with: {InfatuatedWithPokemon.Nickname}"); } if (Status2.HasFlag(PBEStatus2.LeechSeed)) { sb.AppendLine($"Seeded position: {SeededTeam.TrainerName}'s {SeededPosition}"); } if (Status2.HasFlag(PBEStatus2.Substitute)) { sb.AppendLine($"Substitute HP: {SubstituteHP}"); } sb.AppendLine($"Stats: [A] {Attack}, [D] {Defense}, [SA] {SpAttack}, [SD] {SpDefense}, [S] {Speed}, [W] {Weight:0.0}"); PBEStat[] statChanges = GetChangedStats(); if (statChanges.Length > 0) { var statStrs = new List <string>(7); if (Array.IndexOf(statChanges, PBEStat.Attack) != -1) { statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(AttackChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Defense) != -1) { statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(DefenseChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1) { statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(SpAttackChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1) { statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(SpDefenseChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Speed) != -1) { statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(SpeedChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1) { statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(AccuracyChange, true):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1) { statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(EvasionChange, true):0.00}"); } sb.AppendLine($"Stat changes: {string.Join(", ", statStrs)}"); } sb.AppendLine($"Ability: {PBELocalizedString.GetAbilityName(Ability).English}"); sb.AppendLine($"Known ability: {(KnownAbility == PBEAbility.MAX ? "???" : PBELocalizedString.GetAbilityName(KnownAbility).English)}"); sb.AppendLine($"Item: {PBELocalizedString.GetItemName(Item).English}"); sb.AppendLine($"Known item: {(KnownItem == (PBEItem)ushort.MaxValue ? "???" : PBELocalizedString.GetItemName(KnownItem).English)}"); if (Moves.Contains(PBEMove.Frustration) || Moves.Contains(PBEMove.Return)) { sb.AppendLine($"Friendship: {Friendship} ({Friendship / byte.MaxValue:P2})"); } if (Moves.Contains(PBEMove.HiddenPower)) { sb.AppendLine($"{PBELocalizedString.GetMoveName(PBEMove.HiddenPower).English}: {PBELocalizedString.GetTypeName(IndividualValues.HiddenPowerType).English}:{IndividualValues.HiddenPowerBasePower}"); } sb.Append("Moves: "); for (int i = 0; i < Team.Battle.Settings.NumMoves; i++) { PBEBattleMoveset.PBEBattleMovesetSlot slot = Moves[i]; PBEMove move = slot.Move; if (i > 0) { sb.Append(", "); } sb.Append(PBELocalizedString.GetMoveName(slot.Move).English); if (move != PBEMove.None) { sb.Append($" ({slot.PP}/{slot.MaxPP})"); } } sb.AppendLine(); sb.Append("Known moves: "); for (int i = 0; i < Team.Battle.Settings.NumMoves; i++) { PBEBattleMoveset.PBEBattleMovesetSlot slot = KnownMoves[i]; PBEMove move = slot.Move; int pp = slot.PP; int maxPP = slot.MaxPP; if (i > 0) { sb.Append(", "); } sb.Append(move == PBEMove.MAX ? "???" : PBELocalizedString.GetMoveName(move).English); if (move != PBEMove.None && move != PBEMove.MAX) { sb.Append($" ({pp}{(maxPP == 0 ? ")" : $"/{maxPP})")}"); } }
// Host constructor internal PBETeam(PBEBattle battle, byte id, IEnumerable <PBEPokemonShell> party, ref byte pkmnIdCounter) { Battle = battle; Id = id; CreateParty(party, ref pkmnIdCounter); }
public string SelectSwitchesIfValid(IReadOnlyCollection <PBESwitchIn> switches) { return(PBEBattle.SelectSwitchesIfValid(this, switches)); }
public bool SelectSwitchesIfValid([NotNullWhen(false)] out string?invalidReason, params PBESwitchIn[] switches) { return(PBEBattle.SelectSwitchesIfValid(this, switches, out invalidReason)); }
public string SelectFleeIfValid() { return(PBEBattle.SelectFleeIfValid(this)); }
public string IsFleeValid() { return(PBEBattle.IsFleeValid(this)); }
public bool SelectFleeIfValid([NotNullWhen(false)] out string?invalidReason) { return(PBEBattle.SelectFleeIfValid(this, out invalidReason)); }
public bool IsFleeValid([NotNullWhen(false)] out string?invalidReason) { return(PBEBattle.IsFleeValid(this, out invalidReason)); }
public bool SelectActionsIfValid([NotNullWhen(false)] out string?invalidReason, params PBETurnAction[] actions) { return(PBEBattle.SelectActionsIfValid(this, actions, out invalidReason)); }
public string SelectActionsIfValid(params PBETurnAction[] actions) { return(PBEBattle.SelectActionsIfValid(this, actions)); }
public string SelectSwitchesIfValid(params PBESwitchIn[] switches) { return(PBEBattle.SelectSwitchesIfValid(this, switches)); }
public bool SelectSwitchesIfValid(IReadOnlyCollection <PBESwitchIn> switches, [NotNullWhen(false)] out string?invalidReason) { return(PBEBattle.SelectSwitchesIfValid(this, switches, out invalidReason)); }
public bool SelectActionsIfValid(IReadOnlyCollection <PBETurnAction> actions, [NotNullWhen(false)] out string?invalidReason) { return(PBEBattle.SelectActionsIfValid(this, actions, out invalidReason)); }