internal static bool SelectSwitchesIfValid(PBETrainer trainer, IReadOnlyCollection <PBESwitchIn> switches, [NotNullWhen(false)] out string?invalidReason) { if (!AreSwitchesValid(trainer, switches, out invalidReason)) { return(false); } trainer.SwitchInsRequired = 0; foreach (PBESwitchIn s in switches) { trainer.SwitchInQueue.Add((trainer.GetPokemon(s.PokemonId), s.Position)); } if (trainer.Battle.Trainers.All(t => t.SwitchInsRequired == 0)) { trainer.Battle.BattleState = PBEBattleState.ReadyToRunSwitches; } return(true); }
public static PBEBattle LoadReplay(string path, PBEPacketProcessor packetProcessor) { 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 !; // The first packet should be a PBEBattlePacket int numEvents = r.ReadInt32(); if (numEvents < 1) { throw new InvalidDataException(); } for (int i = 0; i < numEvents; i++) { IPBEPacket packet = packetProcessor.CreatePacket(r.ReadBytes(r.ReadUInt16()), b); if (packet is PBEBattlePacket bp) { if (i != 0) { throw new InvalidDataException(); } b = new PBEBattle(bp); } else { if (i == 0) { throw new InvalidDataException(); } if (packet is PBEWildPkmnAppearedPacket wpap) { PBETrainer wildTrainer = b.Teams[1].Trainers[0]; foreach (PBEPkmnAppearedInfo info in wpap.Pokemon) { PBEBattlePokemon pkmn = wildTrainer.GetPokemon(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); } }
internal static bool SelectActionsIfValid(PBETrainer trainer, IReadOnlyCollection <PBETurnAction> actions, [NotNullWhen(false)] out string?invalidReason) { if (!AreActionsValid(trainer, actions, out invalidReason)) { return(false); } trainer.ActionsRequired.Clear(); foreach (PBETurnAction action in actions) { PBEBattlePokemon pkmn = trainer.GetPokemon(action.PokemonId); if (action.Decision == PBETurnDecision.Fight && pkmn.GetMoveTargets(action.FightMove) == PBEMoveTarget.RandomFoeSurrounding) { switch (trainer.Battle.BattleFormat) { case PBEBattleFormat.Single: case PBEBattleFormat.Rotation: { action.FightTargets = PBETurnTarget.FoeCenter; break; } case PBEBattleFormat.Double: { action.FightTargets = trainer.Battle._rand.RandomBool() ? PBETurnTarget.FoeLeft : PBETurnTarget.FoeRight; break; } case PBEBattleFormat.Triple: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { action.FightTargets = trainer.Battle._rand.RandomBool() ? PBETurnTarget.FoeCenter : PBETurnTarget.FoeRight; } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { PBETeam oppTeam = trainer.Team.OpposingTeam; int r; // Keep randomly picking until a non-fainted foe is selected roll: r = trainer.Battle._rand.RandomInt(0, 2); if (r == 0) { if (oppTeam.IsSpotOccupied(PBEFieldPosition.Left)) { action.FightTargets = PBETurnTarget.FoeLeft; } else { goto roll; } } else if (r == 1) { if (oppTeam.IsSpotOccupied(PBEFieldPosition.Center)) { action.FightTargets = PBETurnTarget.FoeCenter; } else { goto roll; } } else { if (oppTeam.IsSpotOccupied(PBEFieldPosition.Right)) { action.FightTargets = PBETurnTarget.FoeRight; } else { goto roll; } } } else { action.FightTargets = trainer.Battle._rand.RandomBool() ? PBETurnTarget.FoeLeft : PBETurnTarget.FoeCenter; } break; } default: throw new InvalidDataException(nameof(trainer.Battle.BattleFormat)); } } pkmn.TurnAction = action; } if (trainer.Battle.Trainers.All(t => t.ActionsRequired.Count == 0)) { trainer.Battle.BattleState = PBEBattleState.ReadyToRunTurn; } return(true); }