예제 #1
0
 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);
         }
 }
예제 #2
0
 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;
 }
예제 #3
0
 internal PBETeam(PBEBattle battle, byte id, PBETeamShell shell, string trainerName)
 {
     Battle = battle;
     Id     = id;
     Party  = new PBEList <PBEPokemon>(Battle.Settings.MaxPartySize);
     CreateParty(shell, trainerName);
 }
예제 #4
0
        // 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);
        }
예제 #5
0
 internal PBETeams(PBEBattle battle)
 {
     _team1 = new PBETeam(battle, 0);
     _team2 = new PBETeam(battle, 1);
     _team1.OpposingTeam = _team2;
     _team2.OpposingTeam = _team1;
 }
예제 #6
0
 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);
         }
 }
예제 #7
0
        // 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);
        }
예제 #8
0
        // 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);
        }
예제 #9
0
        // 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);
        }
예제 #10
0
        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);
                }
        }
예제 #11
0
        // 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) });
        }
예제 #12
0
        // 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);
        }
예제 #13
0
        // 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
        }
예제 #14
0
 public string AreSwitchesValid(params PBESwitchIn[] switches)
 {
     return(PBEBattle.AreSwitchesValid(this, switches));
 }
예제 #15
0
 public string SelectActionsIfValid(IReadOnlyCollection <PBETurnAction> actions)
 {
     return(PBEBattle.SelectActionsIfValid(this, actions));
 }
예제 #16
0
 // Client constructor
 internal PBETeam(PBEBattle battle, byte id)
 {
     Battle = battle;
     Id     = id;
     Party  = new List <PBEPokemon>(Battle.Settings.MaxPartySize);
 }
예제 #17
0
 public string AreSwitchesValid(IReadOnlyCollection <PBESwitchIn> switches)
 {
     return(PBEBattle.AreSwitchesValid(this, switches));
 }
예제 #18
0
        // 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})")}");
                }
            }
예제 #19
0
 // Host constructor
 internal PBETeam(PBEBattle battle, byte id, IEnumerable <PBEPokemonShell> party, ref byte pkmnIdCounter)
 {
     Battle = battle;
     Id     = id;
     CreateParty(party, ref pkmnIdCounter);
 }
예제 #20
0
 public string SelectSwitchesIfValid(IReadOnlyCollection <PBESwitchIn> switches)
 {
     return(PBEBattle.SelectSwitchesIfValid(this, switches));
 }
예제 #21
0
 public bool SelectSwitchesIfValid([NotNullWhen(false)] out string?invalidReason, params PBESwitchIn[] switches)
 {
     return(PBEBattle.SelectSwitchesIfValid(this, switches, out invalidReason));
 }
예제 #22
0
 public string SelectFleeIfValid()
 {
     return(PBEBattle.SelectFleeIfValid(this));
 }
예제 #23
0
 public string IsFleeValid()
 {
     return(PBEBattle.IsFleeValid(this));
 }
예제 #24
0
 public bool SelectFleeIfValid([NotNullWhen(false)] out string?invalidReason)
 {
     return(PBEBattle.SelectFleeIfValid(this, out invalidReason));
 }
예제 #25
0
 public bool IsFleeValid([NotNullWhen(false)] out string?invalidReason)
 {
     return(PBEBattle.IsFleeValid(this, out invalidReason));
 }
예제 #26
0
 public bool SelectActionsIfValid([NotNullWhen(false)] out string?invalidReason, params PBETurnAction[] actions)
 {
     return(PBEBattle.SelectActionsIfValid(this, actions, out invalidReason));
 }
예제 #27
0
 public string SelectActionsIfValid(params PBETurnAction[] actions)
 {
     return(PBEBattle.SelectActionsIfValid(this, actions));
 }
예제 #28
0
 public string SelectSwitchesIfValid(params PBESwitchIn[] switches)
 {
     return(PBEBattle.SelectSwitchesIfValid(this, switches));
 }
예제 #29
0
 public bool SelectSwitchesIfValid(IReadOnlyCollection <PBESwitchIn> switches, [NotNullWhen(false)] out string?invalidReason)
 {
     return(PBEBattle.SelectSwitchesIfValid(this, switches, out invalidReason));
 }
예제 #30
0
 public bool SelectActionsIfValid(IReadOnlyCollection <PBETurnAction> actions, [NotNullWhen(false)] out string?invalidReason)
 {
     return(PBEBattle.SelectActionsIfValid(this, actions, out invalidReason));
 }