예제 #1
0
        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);
            }
예제 #3
0
            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();
                }
            }
예제 #4
0
        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));
        }
예제 #5
0
            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)}");
            }
예제 #6
0
            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)}.");
            }
예제 #7
0
            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)}.");
            }
예제 #8
0
        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.");
            }
        }
예제 #9
0
        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);
                }
            }