async def CoMWithFriends(self, ctx): """**Randomise**. Open an Inducement Skill Pack and randomly apply all Training cards across your opponents' teams.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def SoM3000(self, ctx): """Each team in the tournament receives a random stadium enhancement. Other stadium enhancement cards are ignored and may not be replaced.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def reaction(self, ctx, *card_name): """User reaction card USAGE: !reaction <card_name> <card_name>: name of the reaction card """ coach = CoachService.discord_user_to_coach(ctx.author) room = ctx.channel.name if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return get_coach_deck_for_room_or_raise(room, coach) card_name = " ".join(card_name).strip() card = CardService.get_card_from_coach(coach, card_name) if card and card.template.card_type == "Reaction": msg = [ f"**{coach.short_name()}** plays **{card.get('name')}**: {card.get('description')}" ] notification = f"Card **{card.get('name')}** removed from your collection" db.session.delete(card) db.session.expire(coach, ['cards']) reason = f"Reaction card {card.template.name} used in {room} tournament" tran = Transaction(description=reason, price=0) coach.make_transaction(tran) await self.send_message(ctx.channel, msg) await self.bank_notification(ctx, notification, coach) else: raise ValueError(f"Reaction card {card_name} was not found!!!") return
async def CoMLegendBuilder(self, ctx): """Roll a dice to select a random rookie player from your roster. Open a Temporary Legend Pack for your chosen mixed team and apply all possible skills and injuries from the Legend to the chosen rookie player.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def CoM2000(self, ctx): """**Randomise**. In the Deck Inducement phase, open an additional Inducement Skill Pack. Each Training Card in the pack must be applied to a random player on your team. This card is removed from your collection after use.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def CoM9000(self, ctx): """**Randomise**. Choose one Special Play card that is yet to be resolved. The chosen card must now be played as if it had the **Randomise** key word. In the Deck Inducement phase, open three additional Inducement Coaching Packs. Each Training Card in the pack must be applied to a random player on your team. This card is removed from your collection after use.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def CelebrityMasterChef(self, ctx): """All other teams in the tournament roll a D6. On a result of 1-3, they permanently lose a team re-roll for the entire tournament! Roll a D6. On a result of 4-6, you gain one team re-roll for the entire tournament! If multiple Celebrity Master Chefs are played, each team can only ever lose a maximum of one team re-roll across all instances of the card.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def CommentatorsCurse(self, ctx): """The most powerful force in the known universe… joins your team! Add a Human Ogre or Ogre Ogre called Biff Bobbord to your team and grant him +ST, +AG, Break Tackle, Piling On, Juggernaut and Block. All teams at the tournament (including your own) then roll a D6. On a result of 1-2, they must roll a Level 1 Curse for their team. If all teams succeed their 3+ roll, you must instead roll a Level 2 curse for your own team.""" me = CoachService.discord_user_to_coach(ctx.author) data = getattr(special_play, inspect.currentframe().f_code.co_name)(ctx.channel.name, me) await self.send_embed(data, ctx)
async def focus(self, ctx): """Reviews your deck and tells what the deck focus is""" me = CoachService.discord_user_to_coach(ctx.author) tourn = TournamentService.get_tournament_using_room(ctx.channel.name) deck = [ts.deck for ts in tourn.tournament_signups if ts.coach == me] if not deck: raise Exception( f"#{me.short_name()} is not signed into the tournament. Nice try!" ) focus = DeckService.focus(deck[0]) await ctx.send(f"Deck focus is {', '.join(focus)}")
async def list(self, ctx, all=None): """List details about coach's collection""" with db.session.no_autoflush: coach = CoachService.discord_user_to_coach(ctx.author) show_starter = True if all == "all" else False if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return all_cards = coach.active_cards() sp_msg = " (with Starter Pack)" if not show_starter: all_cards = [card for card in all_cards if not card.is_starter] sp_msg = "" msg = [ f"**Bank:** {coach.account.amount} coins\n", f"**Tournaments:**", *[ f'{t.tournament_id}. {t.name}, status: {t.status}, expected start: {t.expected_start_date}' for t in coach.tournaments ], f"\n**Collection**{sp_msg}:", "-" * 65 + "", PackHelper.format_pack(all_cards, show_hidden=True), "-" * 65 + "\n" ] if coach.duster: msg.append( f"**Dusting** - {coach.duster.type} - {coach.duster.status}" ) admin_in = Tournament.query.filter( Tournament.admin == coach.short_name(), Tournament.status.in_(("OPEN", "RUNNING"))).all() if admin_in: msg.append(f"**Tournament Admin:**") msg.extend([ f'{t.tournament_id}. {t.name}, status: {t.status}, channel: {t.discord_channel}' for t in admin_in ]) free_packs = coach.get_freepacks() if free_packs: msg.append(f"**Free Packs:**") msg.append((', ').join(free_packs)) await self.send_message(ctx.author, msg) await ctx.send("Info sent to PM")
async def resign(self, ctx, tournament_id: int): """Resigns coach from tournament USAGE: !resign <tournament_id> <tournament_id>: id of tournament from !complist """ coach = CoachService.discord_user_to_coach(ctx.author) if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return await resign(tournament_id, coach, ctx) return
async def newcoach(self, ctx): """Creates new coach account""" coach = CoachService.discord_user_to_coach(ctx.author) if coach: await ctx.send(f"**{ctx.author.mention}** account exists already") elif Coach.get_by_discord_id(ctx.author.id, deleted=True): await ctx.send( f"**{ctx.author.mention}** account is inactive, use the web page to activate it" ) else: coach = CoachService.new_coach(ctx.author, ctx.author.id) msg = f"**{ctx.author.mention}** account created\n" \ + f"**Bank:** {coach.account.amount} coins\n" \ + f"**Rules**: <{RULES_LINK}>" await ctx.send(msg)
async def done(self, ctx): """Confirms Special Play, Inducement and Blood Bowl phase""" coach = CoachService.discord_user_to_coach(ctx.author) room = ctx.channel.name if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return if TournamentService.get_phase(room) in [ Tourn.DB_PHASE, Tourn.LOCKED_PHASE ]: msg = "This command has no effect in this phase. Go and commit your deck!" elif TournamentService.confirm_phase(coach, room): msg = f"Phase confirmed for {coach.short_name()}" else: msg = "No deck found!" await ctx.send(msg)
async def genpacktemp(self, ctx, pack_type:str, subtype:str=None): """Generates special play or inducement packs. These packs are for one time use and are not assigned to coaches permanent collection""" if not check_gentemp_command(pack_type, subtype): raise discord.ext.commands.CommandError("Invalid usage!") coach = CoachService.discord_user_to_coach(ctx.author) if coach is None: await ctx.send(f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first.") return if pack_type in ["player", "positional", "legendary"]: pack = PackService.generate(pack_type, team=subtype) elif pack_type in ["training", "special", "skill", "coaching", "brawl","hc"]: pack = PackService.generate(pack_type) elif pack_type == "booster": pack_type = "booster_budget" if not subtype else f"booster_{subtype}" pack = PackService.generate(pack_type) title = f"**Temporary {PackService.description(pack)}**" description = "**Note**: This is one time pack only!!!" pieces = PackHelper.format_pack_to_pieces(pack.cards) efs = [] efs.append({ 'name': "Cards:", 'value': pieces['cards'], 'inline': False, }) for desc in pieces['descriptions']: efs.append({ 'name': desc['name'], 'value': desc['description'], 'inline': False, }) embed = { 'embed_title': title, 'embed_desc': description, 'thumbnail_url': 'https://cdn2.rebbl.net/images/cards/dice_small.png', 'embed_fields': efs, } await self.send_embed(embed, ctx)
async def ransom(self, ctx): """Pay ransom for the kidnapped player""" coach = CoachService.discord_user_to_coach(ctx.author) if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return reason = 'Ransom' amount = -5 tran = Transaction(description=reason, price=-1 * amount) coach.make_transaction(tran) msg = [ f"Bank for {coach.name} updated to **{coach.account.amount}** coins:\n", f"Note: {reason}\n", f"Change: {amount} coins" ] await self.send_message(ctx.channel, msg) await self.bank_notification( ctx, f"Your bank has been updated by **{amount}** coins - {reason}", coach) return
async def comp(self, ctx, *args): """Manages in-game competitions for tournaments. Needs to be run in the tournament discord channel USAGE: !comp list list all competitions for tournament !comp create ladder creates ladder comp for tournament if it does not exists !comp create 1on1 <competition_name> creates 1 on 1 comp with <competition_name> for tournament if it does not exists !comp create knockout <team_number> <name> creates knockout comp with <name> for <team_number> teams !comp ticket <competition_name> sends ticket to the <competition_name> to the coach issuing the command in the tournament room !comp start <competition_name> starts comp with <competition_name> for tournament """ room = ctx.channel.name args_len = len(args) if args_len == 0 \ or (args_len > 0 and args[0] not in ["list","create", "ticket", "start"]) \ or (args[0] == "create" and \ (args_len < 2 or args[1] not in ["ladder", "1on1","knockout"] or (args[1] == "1on1" and args_len == 2) \ or (args[1] == "knockout" and args_len < 4 and not represents_int(args[2])))) \ or (args[0] in ["ticket", "start"] and args_len < 2): raise ValueError("Incorrect arguments") tourn = TournamentService.get_tournament_using_room(room) if tourn.status != "RUNNING": await ctx.send("Tournament is not running!") return if args[0] == "create": if args[1] == "ladder": comp_name = tourn.ladder_room_name() comp = CompetitionService.create_imperium_ladder(comp_name) if args[1] == "1on1": comp_name = " ".join(args[2:]) comp_name = comp_name[:25] if len( comp_name) > 25 else comp_name comp = CompetitionService.create_imperium_rr(comp_name) if args[1] == "knockout": comp_name = " ".join(args[3:]) comp_name = comp_name[:25] if len( comp_name) > 25 else comp_name comp = CompetitionService.create_imperium_knockout( comp_name, int(args[2])) tourn.competitions.append(comp) db.session.commit() await ctx.send( f"Competition **{comp.name}** created in **{comp.league_name}**" ) return if args[0] == "list": msg = [] msg.append('{:25s} | {:25} | {:25}'.format("League", "Name", "Type")) msg.append(78 * "-") for comp in tourn.competitions: msg.append('{:25s} | {:25} | {:25}'.format( comp.league_name, comp.name, comp.type_str())) await self.send_message(ctx.channel, msg, block=True) # await ctx.send("\n".join(msg)) return if args[0] == "ticket": comp_name = " ".join(args[1:]) # get coach coach = CoachService.discord_user_to_coach(ctx.author) result = CompetitionService.ticket_competition( comp_name, coach, tourn) team_name = result['ResponseCreateCompetitionTicket'][ 'TicketInfos']['RowTeam']['Name'] await ctx.send( f"Ticket sent to **{team_name}** for competition **{comp_name}**" ) return if args[0] == "start": comp_name = " ".join(args[1:]) comp = Competition.query.filter_by(name=comp_name).one_or_none() if not comp: raise CompetitionError( f"Competition **{comp_name}** does not exist") result = CompetitionService.start_competition(comp) await ctx.send(f"Started competition **{comp_name}**") return
async def genpack(self, ctx, pack_type:str, subtype:str=None): """Generates packs""" if not check_gen_command(pack_type, subtype): raise discord.ext.commands.CommandError("Invalid usage!") coach = CoachService.discord_user_to_coach(ctx.author) if coach is None: await ctx.send(f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first.") return pp_count = db.session.query(Pck.id).filter_by(coach_id=coach.id, pack_type="player").count() if pack_type == "player": first = True if pp_count == 0 else False pack = PackService.generate(pack_type, team=subtype, first=first, coach=coach) elif pack_type in ["training","special", "hc"]: pack = PackService.generate(pack_type, coach=coach) elif pack_type == "booster": pack_type = "booster_budget" if not subtype else f"booster_{subtype}" pack = PackService.generate(pack_type, coach=coach) duster = coach.duster duster_on = False duster_txt = "" if pp_count > 0 and duster and duster.status == "COMMITTED": if (pack_type == "player" and duster.type == "Tryouts" or pack_type == "training" and duster.type == "Drills" or pack_type == "special" and duster.type == "Drills"): duster_on = True duster_txt = f" ({duster.type})" db.session.delete(duster) free_packs = coach.get_freepacks() if pack_type in ["player"] and not duster_on: if pack_type in free_packs: pack.price = 0 coach.remove_from_freepacks(pack_type) else: raise TransactionError( "You need to commit Tryouts or earn the pack through" + " Achievements to be able to generate this pack!" ) if pack_type in ["training", "special"] and not duster_on: raise TransactionError( "You need to commit Drills to be able to generate this pack!" ) if pack_type in ["booster_budget", "booster_premium"]: if pack_type in free_packs: pack.price = 0 coach.remove_from_freepacks(pack_type) tran = Transaction(pack=pack, price=pack.price, description=PackService.description(pack)) coach.make_transaction(tran) title = f"**{PackService.description(pack)}** for **{ctx.message.author.name}** - **{pack.price}** coins{duster_txt}" description = f"**Bank:** {coach.account.amount} coins" pieces = PackHelper.format_pack_to_pieces(pack.cards) await self.auto_cards(pack, ctx) CoachService.check_collect_three_legends_quest(coach) efs = [] efs.append({ 'name': "Cards:", 'value': pieces['cards'], 'inline': False, }) for desc in pieces['descriptions']: efs.append({ 'name': desc['name'], 'value': desc['description'], 'inline': False, }) embed = { 'embed_title': title, 'embed_desc': description, 'thumbnail_url': 'https://cdn2.rebbl.net/images/cards/dice_small.png', 'embed_fields': efs, } await self.send_embed(embed, ctx)