public async Task SellAsync(CommandContext ctx) { if (this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar ambush) { throw new CommandFailedException("There is a chicken war running in this channel. No sells are allowed before the war finishes."); } var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken is null) { throw new CommandFailedException("You do not own a chicken!"); } long price = chicken.SellPrice; if (!await ctx.WaitForBoolReplyAsync($"{ctx.User.Mention}, are you sure you want to sell your chicken for {Formatter.Bold($"{price:n0}")} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}?")) { return; } using (DatabaseContext db = this.Database.CreateContext()) { await db.ModifyBankAccountAsync(ctx.User.Id, ctx.Guild.Id, v => v + price); db.Chickens.Remove(new DatabaseChicken { GuildId = ctx.Guild.Id, UserId = ctx.User.Id }); await db.SaveChangesAsync(); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{ctx.User.Mention} sold {Formatter.Bold(chicken.Name)} for {Formatter.Bold($"{price:n0}")} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}!"); }
private Chicken TryJoinInternal(CommandContext ctx, bool team2 = true) { if (!(this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar ambush)) { throw new CommandFailedException("There are no ambushes running in this channel."); } var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken is null) { throw new CommandFailedException("You do not own a chicken!"); } if (chicken.Stats.TotalVitality < 25) { throw new CommandFailedException($"{ctx.User.Mention}, your chicken is too weak for that action! Heal it using {Formatter.InlineCode("chicken heal")} command."); } if (ambush.Started) { throw new CommandFailedException("Ambush has already started, you can't join it."); } if (!ambush.AddParticipant(chicken, ctx.User, team2: team2)) { throw new CommandFailedException("Your chicken is already participating in the ambush."); } return(chicken); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("IDs of the upgrades to buy.")] params int[] ids) { if (ids is null || !ids.Any()) { throw new CommandFailedException("You need to specify the IDs of the upgrades you wish to purchase."); } if (this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar) { throw new CommandFailedException("There is a chicken war running in this channel. No sells are allowed before the war finishes."); } var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken is null) { throw new CommandFailedException($"You do not own a chicken in this guild! Use command {Formatter.InlineCode("chicken buy")} to buy a chicken (requires atleast 1000 {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"})."); } if (chicken.Stats.Upgrades.Any(u => ids.Contains(u.Id))) { throw new CommandFailedException("Your chicken already one of those upgrades!"); } using (DatabaseContext db = this.Database.CreateContext()) { foreach (int id in ids) { DatabaseChickenUpgrade upgrade = db.ChickenUpgrades.FirstOrDefault(u => u.Id == id); if (upgrade is null) { throw new CommandFailedException($"An upgrade with ID {Formatter.InlineCode(id.ToString())} does not exist! Use command {Formatter.InlineCode("chicken upgrades")} to view all available upgrades."); } if (!await ctx.WaitForBoolReplyAsync($"{ctx.User.Mention} are you sure you want to buy {Formatter.Bold(upgrade.Name)} for {Formatter.Bold($"{upgrade.Cost :n0}")} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}?")) { return; } if (!await db.TryDecreaseBankAccountAsync(ctx.User.Id, ctx.Guild.Id, upgrade.Cost)) { throw new CommandFailedException($"You do not have enough {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"} to buy that upgrade!"); } db.ChickensBoughtUpgrades.Add(new DatabaseChickenBoughtUpgrade { Id = upgrade.Id, GuildId = chicken.GuildId, UserId = chicken.OwnerId }); await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{ctx.User.Mention} upgraded his chicken with {Formatter.Bold(upgrade.Name)} (+{upgrade.Modifier}) {upgrade.UpgradesStat.ToShortString()}!"); } await db.SaveChangesAsync(); } }
public async Task InfoAsync(CommandContext ctx, [Description("User.")] DiscordMember member = null) { member = member ?? ctx.Member; var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, member.Id); if (chicken is null) { throw new CommandFailedException($"User {member.Mention} does not own a chicken in this guild! Use command {Formatter.InlineCode("chicken buy")} to buy a chicken (1000 {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"})."); } await ctx.RespondAsync(embed : chicken.ToDiscordEmbed(member)); }
private async Task TryBuyInternalAsync(CommandContext ctx, ChickenType type, string name) { if (string.IsNullOrWhiteSpace(name)) { throw new InvalidCommandUsageException("Name for your chicken is missing."); } if (name.Length < 2 || name.Length > 30) { throw new InvalidCommandUsageException("Name cannot be shorter than 2 and longer than 30 characters."); } if (!name.All(c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c))) { throw new InvalidCommandUsageException("Name cannot contain characters that are not letters or digits."); } if (!(Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id) is null)) { throw new CommandFailedException("You already own a chicken!"); } if (!await ctx.WaitForBoolReplyAsync($"{ctx.User.Mention}, are you sure you want to buy a chicken for {Formatter.Bold(Chicken.Price(type).ToString())} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}?")) { return; } using (DatabaseContext db = this.Database.CreateContext()) { if (!await db.TryDecreaseBankAccountAsync(ctx.User.Id, ctx.Guild.Id, Chicken.Price(type))) { throw new CommandFailedException($"You do not have enough {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"} to buy a chicken ({Chicken.Price(type)} needed)!"); } ChickenStats stats = Chicken.StartingStats[type]; db.Chickens.Add(new DatabaseChicken { GuildId = ctx.Guild.Id, MaxVitality = stats.BareMaxVitality, Name = name, Strength = stats.BareStrength, UserId = ctx.User.Id, Vitality = stats.BareVitality }); await db.SaveChangesAsync(); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{ctx.User.Mention} bought a chicken named {Formatter.Bold(name)}"); }
public async Task JoinAsync(CommandContext ctx, [RemainingText, Description("Team name to join.")] string team) { if (!(this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar war)) { throw new CommandFailedException("There are no chicken wars running in this channel."); } if (war.Started) { throw new CommandFailedException("War has already started, you can't join it."); } if (war.IsParticipating(ctx.User)) { throw new CommandFailedException("Your chicken is already participating in the war!"); } var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken is null) { throw new CommandFailedException("You do not own a chicken!"); } if (chicken.Stats.TotalVitality < 25) { throw new CommandFailedException($"{ctx.User.Mention}, your chicken is too weak to join the war! Heal it using {Formatter.BlockCode("chicken heal")} command."); } if (string.Compare(team, war.Team1Name, StringComparison.InvariantCultureIgnoreCase) == 0) { war.AddParticipant(chicken, ctx.User, team1: true); } else if (string.Compare(team, war.Team2Name, StringComparison.InvariantCultureIgnoreCase) == 0) { war.AddParticipant(chicken, ctx.User, team2: true); } else { throw new CommandFailedException($"No such team exists in this war. Teams that are active are {Formatter.Bold(war.Team1Name)} and {Formatter.Bold(war.Team1Name)}."); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{Formatter.Bold(chicken.Name)} joined the war team {Formatter.Bold(team)}."); }
public async Task JoinAsync(CommandContext ctx, [Description("Number 1 or 2 depending of team you wish to join.")] int team) { if (!(this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar war)) { throw new CommandFailedException("There are no chicken wars running in this channel."); } if (war.Started) { throw new CommandFailedException("War has already started, you can't join it."); } if (war.IsParticipating(ctx.User)) { throw new CommandFailedException("Your chicken is already participating in the war!"); } var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken is null) { throw new CommandFailedException("You do not own a chicken!"); } if (chicken.Stats.TotalVitality < 25) { throw new CommandFailedException($"{ctx.User.Mention}, your chicken is too weak to join the war! Heal it using {Formatter.BlockCode("chicken heal")} command."); } switch (team) { case 1: war.AddParticipant(chicken, ctx.User, team1: true); break; case 2: war.AddParticipant(chicken, ctx.User, team2: true); break; default: throw new CommandFailedException($"No such team exists in this war. Teams that are active are {Formatter.Bold(war.Team1Name)} and {Formatter.Bold(war.Team1Name)}."); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{Formatter.Bold(chicken.Name)} joined the war team {Formatter.Bold(team == 1 ? war.Team1Name : war.Team2Name)}."); }
public async Task FightAsync(CommandContext ctx, [Description("Name of the chicken to fight.")] string chickenName) { var chicken = Chicken.FromDatabase(this.Database, ctx.Guild.Id, chickenName); if (chicken is null) { throw new CommandFailedException("Couldn't find any chickens with that name!"); } try { await this.FightAsync(ctx, await ctx.Guild.GetMemberAsync(chicken.OwnerId)); } catch (NotFoundException) { using (DatabaseContext db = this.Database.CreateContext()) { db.Chickens.Remove(chicken.ToDatabaseChicken()); await db.SaveChangesAsync(); } throw new CommandFailedException("The user whose chicken you tried to fight is not currently in this guild. The chicken has been put to sleep."); } }
public async Task FightAsync(CommandContext ctx, [Description("Member whose chicken to fight.")] DiscordMember member) { if (this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar ambush) { throw new CommandFailedException("There is a chicken war running in this channel. No fights are allowed before the war finishes."); } if (member.Id == ctx.User.Id) { throw new CommandFailedException("You can't fight against your own chicken!"); } var chicken1 = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (chicken1 is null) { throw new CommandFailedException("You do not own a chicken!"); } if (chicken1.Stats.TotalVitality < 25) { throw new CommandFailedException($"{ctx.User.Mention}, your chicken is too weak to start a fight with another chicken! Heal it using {Formatter.InlineCode("chicken heal")} command."); } var chicken2 = Chicken.FromDatabase(this.Database, ctx.Guild.Id, member.Id); if (chicken2 is null) { throw new CommandFailedException("The specified user does not own a chicken!"); } if (Math.Abs(chicken1.Stats.TotalStrength - chicken2.Stats.TotalStrength) > 75) { throw new CommandFailedException("The strength difference is too big (75 max)! Please find a more suitable opponent."); } string header = $"{Formatter.Bold(chicken1.Name)} ({chicken1.Stats.ToShortString()}) {StaticDiscordEmoji.DuelSwords} {Formatter.Bold(chicken2.Name)} ({chicken2.Stats.ToShortString()}) {StaticDiscordEmoji.Chicken}\n\n"; Chicken winner = chicken1.Fight(chicken2); winner.Owner = winner.OwnerId == ctx.User.Id ? ctx.User : member; Chicken loser = winner == chicken1 ? chicken2 : chicken1; int gain = winner.DetermineStrengthGain(loser); winner.Stats.BareStrength += gain; winner.Stats.BareVitality -= gain; if (winner.Stats.TotalVitality == 0) { winner.Stats.BareVitality++; } loser.Stats.BareVitality -= 50; using (DatabaseContext db = this.Database.CreateContext()) { db.Chickens.Update(winner.ToDatabaseChicken()); if (loser.Stats.TotalVitality > 0) { db.Chickens.Update(loser.ToDatabaseChicken()); } else { db.Chickens.Remove(loser.ToDatabaseChicken()); } await db.ModifyBankAccountAsync(ctx.User.Id, ctx.Guild.Id, v => v + gain * 200); await db.SaveChangesAsync(); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, header + $"{StaticDiscordEmoji.Trophy} Winner: {Formatter.Bold(winner.Name)}\n\n" + $"{Formatter.Bold(winner.Name)} gained {Formatter.Bold(gain.ToString())} strength!\n" + (loser.Stats.TotalVitality > 0 ? $"{Formatter.Bold(loser.Name)} lost {Formatter.Bold("50")} HP!" : $"{Formatter.Bold(loser.Name)} died in the battle!") + $"\n\n{winner.Owner.Mention} won {gain * 200} {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credits"}." , important : true ); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("Whose chicken to ambush?")] DiscordMember member) { if (this.Shared.IsEventRunningInChannel(ctx.Channel.Id)) { if (this.Shared.GetEventInChannel(ctx.Channel.Id) is ChickenWar) { await this.JoinAsync(ctx); } else { throw new CommandFailedException("Another event is already running in the current channel."); } return; } var ambushed = Chicken.FromDatabase(this.Database, ctx.Guild.Id, member.Id); if (ambushed is null) { throw new CommandFailedException("Given user does not have a chicken in this guild!"); } var ambusher = Chicken.FromDatabase(this.Database, ctx.Guild.Id, ctx.User.Id); if (ambusher is null) { throw new CommandFailedException("You do not own a chicken!"); } if (ambusher.Stats.TotalStrength > ambushed.Stats.TotalStrength) { throw new CommandFailedException("You cannot start an ambush against a weaker chicken!"); } var ambush = new ChickenWar(ctx.Client.GetInteractivity(), ctx.Channel, "Ambushed chickens", "Evil ambushers"); this.Shared.RegisterEventInChannel(ambush, ctx.Channel.Id); try { ambush.AddParticipant(ambushed, member, team1: true); await this.JoinAsync(ctx); await this.InformAsync(ctx, StaticDiscordEmoji.Clock1, $"The ambush will start in 1 minute. Use command {Formatter.InlineCode("chicken ambush")} to make your chicken join the ambush, or {Formatter.InlineCode("chicken ambush help")} to help the ambushed chicken."); await Task.Delay(TimeSpan.FromMinutes(1)); if (ambush.Team2.Any()) { await ambush.RunAsync(); var sb = new StringBuilder(); using (DatabaseContext db = this.Database.CreateContext()) { foreach (Chicken chicken in ambush.Team1Won ? ambush.Team1 : ambush.Team2) { chicken.Stats.BareStrength += 5; chicken.Stats.BareVitality -= 10; db.Chickens.Update(chicken.ToDatabaseChicken()); sb.AppendLine($"{Formatter.Bold(chicken.Name)} gained 5 STR and lost 10 HP!"); } foreach (Chicken chicken in ambush.Team1Won ? ambush.Team2 : ambush.Team1) { chicken.Stats.BareVitality -= 50; if (chicken.Stats.TotalVitality > 0) { db.Chickens.Update(chicken.ToDatabaseChicken()); sb.AppendLine($"{Formatter.Bold(chicken.Name)} lost 50 HP!"); } else { db.Chickens.Remove(new DatabaseChicken { GuildId = ctx.Guild.Id, UserId = chicken.OwnerId }); sb.AppendLine($"{Formatter.Bold(chicken.Name)} died!"); } } await db.SaveChangesAsync(); } await this.InformAsync(ctx, StaticDiscordEmoji.Chicken, $"{Formatter.Bold(ambush.Team1Won ? ambush.Team1Name : ambush.Team2Name)} won!\n\n{sb.ToString()}"); } } finally { this.Shared.UnregisterEventInChannel(ctx.Channel.Id); } }