public async Task Challenge(SocketUser battler1) { if (battler1.Id == Context.User.Id) { // } else if (BattleContext.GetBattleContext(Context.User) != null) { await Context.Channel.SendMessageAsync($"{Context.User.Username} is already participating in a battle."); } else if (BattleContext.GetBattleContext(battler1) != null) { await Context.Channel.SendMessageAsync($"{battler1.Username} is already participating in a battle."); } else { PBESettings settings = PBESettings.DefaultSettings; PBEPokemonShell[] team0Party, team1Party; // Completely Randomized Pokémon team0Party = PBEUtils.CreateCompletelyRandomTeam(settings, true); team1Party = PBEUtils.CreateCompletelyRandomTeam(settings, true); var battle = new PBEBattle(PBEBattleFormat.Single, settings, team0Party, team1Party); battle.Teams[0].TrainerName = Context.User.Username; battle.Teams[1].TrainerName = battler1.Username; var battleContext = new BattleContext(battle, Context.User, battler1, Context.Channel); } }
private async Task MainAsync(string[] args) { Utils.InitFemaleSpriteLookup(); ReplaySaver.RemoveOldReplays(); PBEUtils.InitEngine(string.Empty); _client = new DiscordSocketClient(); _commands = new CommandService(new CommandServiceConfig { DefaultRunMode = RunMode.Async }); await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), null); _client.Log += LogMessage; _client.MessageReceived += CommandMessageReceived; _client.ReactionAdded += OnReactionAdded; _client.ChannelDestroyed += OnChannelDeleted; _client.LeftGuild += OnLeftGuild; _client.UserLeft += OnUserLeft; _client.Connected += OnConnected; _client.Disconnected += OnDisconnected; _client.GuildMemberUpdated += OnGuildMemberUpdated; await _client.LoginAsync(TokenType.Bot, args[0]); // Token is passed in as args[0] await _client.StartAsync(); await Task.Delay(-1); }
public void SaveReplay(string path) { if (BattleState != PBEBattleState.Ended) { throw new InvalidOperationException($"{nameof(BattleState)} must be {PBEBattleState.Ended} to save a replay."); } var bytes = new List <byte>(); bytes.AddRange(BitConverter.GetBytes(CurrentReplayVersion)); bytes.Add((byte)BattleFormat); bytes.AddRange(PBEUtils.StringToBytes(Teams[0].TrainerName)); bytes.Add((byte)Teams[0].Party.Count); bytes.AddRange(Teams[0].Party.SelectMany(p => p.Shell.ToBytes())); bytes.AddRange(PBEUtils.StringToBytes(Teams[1].TrainerName)); bytes.Add((byte)Teams[1].Party.Count); bytes.AddRange(Teams[1].Party.SelectMany(p => p.Shell.ToBytes())); foreach (INetPacket packet in Events) { bytes.AddRange(packet.Buffer); } using (var md5 = MD5.Create()) { bytes.AddRange(md5.ComputeHash(bytes.ToArray())); } File.WriteAllBytes(path, bytes.ToArray()); }
internal PBEPlayerJoinedPacket(ReadOnlyCollection <byte> buffer, BinaryReader r, PBEBattle battle) { Buffer = buffer; IsMe = r.ReadBoolean(); BattleId = r.ReadInt32(); TrainerName = PBEUtils.StringFromBytes(r); }
private async Task MainAsync(string[] args) { PBEUtils.CreateDatabaseConnection(string.Empty); _client = new DiscordSocketClient(new DiscordSocketConfig { WebSocketProvider = Discord.Net.Providers.WS4Net.WS4NetProvider.Instance }); _commands = new CommandService(new CommandServiceConfig { DefaultRunMode = RunMode.Async }); _services = new ServiceCollection() .AddSingleton(_client) .AddSingleton(_commands) .BuildServiceProvider(); await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); _client.Log += LogMessage; _client.MessageReceived += CommandMessageReceived; _client.ReactionAdded += ReactionListener.Client_ReactionAdded; await _client.LoginAsync(TokenType.Bot, args[0]); // Token is passed in as args[0] await _client.StartAsync(); await Task.Delay(-1); }
protected override void OnClientConnected(Player client) { // Set new player's info client.Index = (byte)(Clients.Count() - 1); client.PlayerName = PBEUtils.Sample(new string[] { "Sasha", "Nikki", "Lara", "Violet", "Naomi", "Rose", "Sabrina", "Nicole" }); // Send all already connected players to this client foreach (Player player in Clients) { player.Send(new PBEPlayerJoinedPacket(player == client, client.Index, client.PlayerName)); if (player != client) { client.Send(new PBEPlayerJoinedPacket(false, player.Index, player.PlayerName)); } } Console.WriteLine($"Client connected ({client.Id} {client.Index} {client.PlayerName})"); if (battlers == null && Clients.Count() == 2) { Console.WriteLine("Two players connected!"); state = ServerState.WaitingForParties; Console.WriteLine("Waiting for parties..."); battlers = Clients.OrderBy(c => c.Index).Take(2).ToArray(); battle.Teams[0].TrainerName = battlers[0].PlayerName; battle.Teams[1].TrainerName = battlers[1].PlayerName; SendTo(battlers, new PBEPartyRequestPacket()); } }
private void DetermineTurnOrder() { _turnOrder.Clear(); IEnumerable <PBEPokemon> pkmnSwitchingOut = ActiveBattlers.Where(p => p.TurnAction.Decision == PBETurnDecision.SwitchOut); IEnumerable <PBEPokemon> pkmnFighting = ActiveBattlers.Where(p => p.TurnAction.Decision == PBETurnDecision.Fight); // Switching happens first: _turnOrder.AddRange(GetActingOrder(pkmnSwitchingOut, true)); // Moves: sbyte GetPrio(PBEPokemon p) { PBEMoveData mData = PBEMoveData.Data[p.TurnAction.FightMove]; return((sbyte)PBEUtils.Clamp(mData.Priority + (p.Ability == PBEAbility.Prankster && mData.Category == PBEMoveCategory.Status ? 1 : 0), sbyte.MinValue, sbyte.MaxValue)); } foreach (sbyte priority in pkmnFighting.Select(p => GetPrio(p)).Distinct().OrderByDescending(p => p)) { PBEPokemon[] pkmnWithThisPriority = pkmnFighting.Where(p => GetPrio(p) == priority).ToArray(); if (pkmnWithThisPriority.Length > 0) { Debug.WriteLine("Priority {0} bracket...", priority); _turnOrder.AddRange(GetActingOrder(pkmnWithThisPriority, false)); } } }
internal PBEPokemon(BinaryReader r, PBETeam team) { Team = team; Id = r.ReadByte(); Species = OriginalSpecies = KnownSpecies = (PBESpecies)r.ReadUInt32(); var pData = PBEPokemonData.GetData(Species); KnownType1 = Type1 = pData.Type1; KnownType2 = Type2 = pData.Type2; KnownWeight = Weight = pData.Weight; Nickname = KnownNickname = PBEUtils.StringFromBytes(r); Level = r.ReadByte(); Friendship = r.ReadByte(); Shiny = KnownShiny = r.ReadBoolean(); Ability = OriginalAbility = (PBEAbility)r.ReadByte(); KnownAbility = PBEAbility.MAX; Nature = (PBENature)r.ReadByte(); Gender = KnownGender = (PBEGender)r.ReadByte(); Item = OriginalItem = (PBEItem)r.ReadUInt16(); KnownItem = (PBEItem)ushort.MaxValue; EffortValues = new PBEEffortValues(Team.Battle.Settings, r); IndividualValues = new PBEIndividualValues(Team.Battle.Settings, r); SetStats(); HP = MaxHP; HPPercentage = 1D; OriginalMoveset = new PBEMoveset(Species, Level, Team.Battle.Settings, r); Moves = new PBEBattleMoveset(OriginalMoveset); KnownMoves = new PBEBattleMoveset(Team.Battle.Settings); TransformBackupMoves = new PBEBattleMoveset(Team.Battle.Settings); Team.Party.Add(this); }
internal static PBEPokemonShell FromBytes(BinaryReader r) { var pkmn = new PBEPokemonShell { Species = (PBESpecies)r.ReadUInt32(), Nickname = PBEUtils.StringFromBytes(r), Level = r.ReadByte(), Friendship = r.ReadByte(), Shiny = r.ReadBoolean(), Ability = (PBEAbility)r.ReadByte(), Nature = (PBENature)r.ReadByte(), Gender = (PBEGender)r.ReadByte(), Item = (PBEItem)r.ReadUInt16(), EVs = r.ReadBytes(6), IVs = r.ReadBytes(6) }; byte numMoves = r.ReadByte(); pkmn.Moves = new PBEMove[numMoves]; for (int i = 0; i < numMoves; i++) { pkmn.Moves[i] = (PBEMove)r.ReadUInt16(); } pkmn.PPUps = r.ReadBytes(numMoves); return(pkmn); }
public static PBELocalizedString GetNatureName(PBENature nature) { if (nature >= PBENature.MAX) { throw new ArgumentOutOfRangeException(nameof(nature)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(queryId, "NatureNames", (byte)nature))[0])); }
public static PBELocalizedString GetMoveName(PBEMove move) { if (move >= PBEMove.MAX) { throw new ArgumentOutOfRangeException(nameof(move)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "MoveNames", (ushort)move))[0])); }
public static PBELocalizedString GetGenderName(PBEGender gender) { if (gender >= PBEGender.MAX) { throw new ArgumentOutOfRangeException(nameof(gender)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "GenderNames", (byte)gender))[0])); }
public static PBELocalizedString GetSpeciesName(PBESpecies species) { if (species <= 0 || species >= PBESpecies.MAX) { throw new ArgumentOutOfRangeException(nameof(species)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "SpeciesNames", (ushort)species))[0])); }
public static PBELocalizedString GetStatName(PBEStat stat) { if (!Enum.IsDefined(typeof(PBEStat), stat)) { throw new ArgumentOutOfRangeException(nameof(stat)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "StatNames", (byte)stat))[0])); }
public static PBELocalizedString GetTypeName(PBEType type) { if (type >= PBEType.MAX) { throw new ArgumentOutOfRangeException(nameof(type)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "TypeNames", (byte)type))[0])); }
public static PBELocalizedString GetItemName(PBEItem item) { if (!Enum.IsDefined(typeof(PBEItem), item)) { throw new ArgumentOutOfRangeException(nameof(item)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "ItemNames", (ushort)item))[0])); }
public static PBELocalizedString GetAbilityName(PBEAbility ability) { if (ability >= PBEAbility.MAX) { throw new ArgumentOutOfRangeException(nameof(ability)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(QueryId, "AbilityNames", (byte)ability))[0])); }
public static PBELocalizedString GetMoveDescription(PBEMove move) { if (move >= PBEMove.MAX || !Enum.IsDefined(typeof(PBEMove), move)) { throw new ArgumentOutOfRangeException(nameof(move)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(queryId, "MoveDescriptions", (ushort)move))[0])); }
internal void ToBytes(List <byte> bytes) { PBEUtils.StringToBytes(bytes, TrainerName); bytes.Add((byte)Party.Count); for (int i = 0; i < (sbyte)Party.Count; i++) { Party[i].ToBytes(bytes); } }
public void SaveReplay() { if (IsDisposed) { throw new ObjectDisposedException(null); } // "12-30-2020 11-59-59 PM - Team 1 vs Team 2.pbereplay" SaveReplay(PBEUtils.ToSafeFileName(new string(string.Format("{0} - {1} vs {2}", DateTime.Now.ToLocalTime(), Teams[0].TrainerName, Teams[1].TrainerName).Take(200).ToArray())) + ".pbereplay"); }
/// <summary>Deals damage to <paramref name="victim"/> and broadcasts the HP changing and substitute damage.</summary> /// <param name="culprit">The Pokémon responsible for the damage.</param> /// <param name="victim">The Pokémon receiving the damage.</param> /// <param name="hp">The amount of HP <paramref name="victim"/> will try to lose.</param> /// <param name="ignoreSubstitute">Whether the damage should ignore <paramref name="victim"/>'s <see cref="PBEStatus2.Substitute"/>.</param> /// <param name="ignoreSturdy">Whether the damage should ignore <paramref name="victim"/>'s <see cref="PBEAbility.Sturdy"/>, <see cref="PBEItem.FocusBand"/>, or <see cref="PBEItem.FocusSash"/>.</param> /// <returns>The amount of damage dealt.</returns> private ushort DealDamage(PBEPokemon culprit, PBEPokemon victim, int hp, bool ignoreSubstitute, bool ignoreSturdy = false) { if (hp < 1) { hp = 1; } if (!ignoreSubstitute && victim.Status2.HasFlag(PBEStatus2.Substitute)) { ushort oldHP = victim.SubstituteHP; victim.SubstituteHP = (ushort)Math.Max(0, victim.SubstituteHP - hp); ushort damageAmt = (ushort)(oldHP - victim.SubstituteHP); BroadcastStatus2(victim, culprit, PBEStatus2.Substitute, PBEStatusAction.Damage); return(damageAmt); } else { ushort oldHP = victim.HP; double oldPercentage = victim.HPPercentage; victim.HP = (ushort)Math.Max(0, victim.HP - hp); bool sturdyHappened = false, focusBandHappened = false, focusSashHappened = false; if (!ignoreSturdy && victim.HP == 0) { // TODO: Endure if (oldHP == victim.MaxHP && victim.Ability == PBEAbility.Sturdy && !culprit.HasCancellingAbility()) { sturdyHappened = true; victim.HP = 1; } else if (victim.Item == PBEItem.FocusBand && PBEUtils.RandomBool(10, 100)) { focusBandHappened = true; victim.HP = 1; } else if (oldHP == victim.MaxHP && victim.Item == PBEItem.FocusSash) { focusSashHappened = true; victim.HP = 1; } } victim.HPPercentage = (double)victim.HP / victim.MaxHP; BroadcastPkmnHPChanged(victim, oldHP, oldPercentage); if (sturdyHappened) { BroadcastAbility(victim, culprit, PBEAbility.Sturdy, PBEAbilityAction.Damage); BroadcastEndure(victim); } else if (focusBandHappened) { BroadcastItem(victim, culprit, PBEItem.FocusBand, PBEItemAction.Damage); } else if (focusSashHappened) { BroadcastItem(victim, culprit, PBEItem.FocusSash, PBEItemAction.Consumed); } return((ushort)(oldHP - victim.HP)); } }
private ushort CalculateDamage(PBEPokemon user, PBEPokemon target, PBEMove move, PBEType moveType, PBEMoveCategory moveCategory, double basePower, bool criticalHit) { ushort damage; double a = 0, d = 0; bool unawareA = user != target && target.Ability == PBEAbility.Unaware && !user.HasCancellingAbility(); bool unawareD = user != target && user.Ability == PBEAbility.Unaware && !target.HasCancellingAbility(); // Verified: A target with Mold Breaker will accept more damage from a user with Unaware switch (move) { case PBEMove.FoulPlay: { double aMod = unawareA ? 1 : GetStatChangeModifier(criticalHit ? Math.Max((sbyte)0, target.AttackChange) : target.AttackChange, false); a = CalculateAttack(user, target, moveType, target.Attack * aMod); double dMod = unawareD ? 1 : GetStatChangeModifier(criticalHit ? Math.Min((sbyte)0, target.DefenseChange) : target.DefenseChange, false); d = CalculateDefense(user, target, target.Defense * dMod); break; } case PBEMove.Psyshock: case PBEMove.Psystrike: case PBEMove.SecretSword: { double aMod = unawareA ? 1 : GetStatChangeModifier(criticalHit ? Math.Max((sbyte)0, user.SpAttackChange) : user.SpAttackChange, false); a = CalculateSpAttack(user, target, moveType, user.SpAttack * aMod); double dMod = unawareD ? 1 : GetStatChangeModifier(criticalHit ? Math.Min((sbyte)0, target.DefenseChange) : target.DefenseChange, false); d = CalculateDefense(user, target, target.Defense * dMod); break; } default: { if (moveCategory == PBEMoveCategory.Physical) { double aMod = unawareA ? 1 : GetStatChangeModifier(criticalHit ? Math.Max((sbyte)0, user.AttackChange) : user.AttackChange, false); a = CalculateAttack(user, target, moveType, user.Attack * aMod); double dMod = unawareD ? 1 : GetStatChangeModifier(criticalHit ? Math.Min((sbyte)0, target.DefenseChange) : target.DefenseChange, false); d = CalculateDefense(user, target, target.Defense * dMod); } else if (moveCategory == PBEMoveCategory.Special) { double aMod = unawareA ? 1 : GetStatChangeModifier(criticalHit ? Math.Max((sbyte)0, user.SpAttackChange) : user.SpAttackChange, false); a = CalculateSpAttack(user, target, moveType, user.SpAttack * aMod); double dMod = unawareD ? 1 : GetStatChangeModifier(criticalHit ? Math.Min((sbyte)0, target.SpDefenseChange) : target.SpDefenseChange, false); d = CalculateSpDefense(user, target, target.SpDefense * dMod); } break; } } damage = (ushort)((2 * user.Level / 5) + 2); damage = (ushort)(damage * a * basePower / d); damage /= 50; damage += 2; return((ushort)(damage * (100 - PBEUtils.RandomInt(0, 15)) / 100)); }
public PBEPlayerJoinedPacket(bool isMe, int battleId, string trainerName) { var bytes = new List <byte>(); bytes.AddRange(BitConverter.GetBytes(Code)); bytes.Add((byte)((IsMe = isMe) ? 1 : 0)); bytes.AddRange(BitConverter.GetBytes(BattleId = battleId)); bytes.AddRange(PBEUtils.StringToBytes(TrainerName = trainerName)); Buffer = BitConverter.GetBytes((short)bytes.Count).Concat(bytes); }
internal void FromBytes(BinaryReader r) { TrainerName = PBEUtils.StringFromBytes(r); sbyte amt = r.ReadSByte(); for (int i = 0; i < amt; i++) { new PBEPokemon(r, this); } }
public static PBELocalizedString GetSpeciesName(PBESpecies species) { uint speciesId = (ushort)species; if (!Enum.IsDefined(typeof(PBESpecies), speciesId)) { throw new ArgumentOutOfRangeException(nameof(species)); } return(new PBELocalizedString(PBEUtils.QueryDatabase <SearchResult>(string.Format(queryId, "SpeciesNames", speciesId))[0])); }
public static void Test() { Console.WriteLine("----- Pokémon Battle Engine Test -----"); var settings = new PBESettings { NumMoves = 12 }; PBEPokemonShell[] team0Party, team1Party; // Completely Randomized Pokémon team0Party = PBEUtils.CreateCompletelyRandomTeam(settings, true); team1Party = PBEUtils.CreateCompletelyRandomTeam(settings, true); // Predefined Pokémon /*team0Party = new PBEPokemonShell[] * { * PBECompetitivePokemonShells.Zoroark_VGC, * PBECompetitivePokemonShells.Volcarona_VGC, * PBECompetitivePokemonShells.Vaporeon_VGC, * PBECompetitivePokemonShells.Thundurus_VGC, * PBECompetitivePokemonShells.Vanilluxe_VGC, * PBECompetitivePokemonShells.Chandelure_VGC * }; * team1Party = new PBEPokemonShell[] * { * PBECompetitivePokemonShells.Arceus_Uber, * PBECompetitivePokemonShells.Darkrai_Uber, * PBECompetitivePokemonShells.Kyurem_White_Uber, * PBECompetitivePokemonShells.Latias_VGC, * PBECompetitivePokemonShells.Metagross_VGC, * PBECompetitivePokemonShells.Victini_Uber * };*/ var battle = new PBEBattle(PBEBattleFormat.Double, settings, team0Party, team1Party); battle.Teams[0].TrainerName = "Team 1"; battle.Teams[1].TrainerName = "Team 2"; battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; battle.OnStateChanged += Battle_OnStateChanged; try { writer = new StreamWriter(new FileStream(LogFile, FileMode.Create, FileAccess.Write)); } catch (Exception e) { Console.WriteLine($"Cannot open \"{LogFile}\" for writing."); Console.WriteLine(e.Message); return; } oldWriter = Console.Out; Console.SetOut(writer); battle.Begin(); }
public PBEPlayerJoinedPacket(byte[] buffer, PBEBattle battle) { Buffer = buffer; using (var r = new BinaryReader(new MemoryStream(buffer))) { r.ReadInt16(); // Skip Code IsMe = r.ReadBoolean(); BattleId = r.ReadInt32(); TrainerName = PBEUtils.StringFromBytes(r); } }
public static void Main(string[] args) { if (args.Length != 3) { PrintUsage(); } else { PBEUtils.InitEngine(string.Empty); new BattleServer(args); } }
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); } }
internal PBEIllusionPacket(ReadOnlyCollection <byte> buffer, BinaryReader r, PBEBattle battle) { Buffer = buffer; Pokemon = (PBEFieldPosition)r.ReadByte(); PokemonTeam = battle.Teams[r.ReadByte()]; ActualGender = (PBEGender)r.ReadByte(); ActualNickname = PBEUtils.StringFromBytes(r); ActualShiny = r.ReadBoolean(); ActualSpecies = (PBESpecies)r.ReadUInt16(); ActualType1 = (PBEType)r.ReadByte(); ActualType2 = (PBEType)r.ReadByte(); ActualWeight = r.ReadDouble(); }