Пример #1
0
    async def on_pm_command(self, ctx, game, player, args):
        command = args[0]
        can_do, reason = self.can_do_action(game)
        if not can_do:
            return await ctx.send(f'You cannot use your action today. {reason}')

        if command == 'noaction':
            for action in game.night_actions:
                if action['player'].user.id == player.user.id:
                    game.night_actions.remove(action)

            game.night_actions.add_action({
                'action': None,
                'player': player,
                'priority': 0
            })
            return await ctx.send('You decided to stay home tonight.')

        game.night_actions.add_action({
            'action': self.action,
            'player': player,
            'priority': self.action_priority,
            'target': player,
            'can_block': self.can_block,
            'can_transport': self.can_transport,
            'can_visit': False
        })
        await ctx.send('You have decided to {} tonight.'.format(self.action))

        if len(game.players.filter(action_only=True)) == len(game.night_actions):
            try:
                if not game.phase == Phase.STANDBY:
                    await game.increment_phase()
            except Exception as exc:
                raise PhaseChangeError(None, *exc.args)
Пример #2
0
    async def startgame(self,
                        ctx: CustomContext,
                        r_setup: typing.Optional[str] = None):
        """
        Starts the game.
        To view a list of available setups, use the `setupinfo` command.
        """
        game = ctx.game

        if game.has_started:
            await ctx.send("Game has already started!")
            return

        if game.setup and len(game.players) != game.setup.total_players:
            return await ctx.send('Custom setup used needs {} players.'.format(
                game.setup.total_players))

        if game.setup is None:
            try:
                game.phase = Phase.STANDBY
                found_setup = await game.find_setup(r_setup)
            except ValueError as err:  # pylint: disable=broad-except
                return await ctx.send(err)
            finally:
                game.phase = Phase.PREGAME
            game.setup = found_setup

        # set to standby so people can't join while the bot is sending rolepms
        game.phase = Phase.STANDBY
        await ctx.send(f'Chose the setup **{game.setup.name}**. '
                       'Randing roles...')

        no_dms = await game.setup.assign_roles(game)
        await ctx.send('Sent all role PMs!')

        if len(no_dms) > 0:
            no_dms = [*map(lambda usr: usr.name, no_dms)]
            await ctx.send(
                f"I couldn't DM {', '.join(no_dms)}."
                f" Use the {self.bot.global_prefix}rolepm command to receive your PM."
            )

        # flags
        flags = {
            flag_name: game.setup.flags[flag_name]
            for flag_name in Setup.all_flags
        }

        if "night_start" in flags and flags['night_start']:
            game.cycle = 1
            game.phase = Phase.DAY
        try:
            await game.increment_phase()
        except Exception as exc:
            raise PhaseChangeError(None, *exc.args)
Пример #3
0
    async def update(self):
        if not self.has_started or self.phase == Phase.STANDBY:
            return

        curr_t = datetime.now()
        phase_end = self.phase_end_at
        if phase_end is not None and curr_t > phase_end:
            if self.phase == Phase.DAY:
                # no lynch achieved
                await self.channel.send('Nobody was lynched')
            try:
                await self.increment_phase()
            except Exception as exc:
                raise PhaseChangeError(None, *exc.args)
Пример #4
0
    async def on_pm_command(self, ctx, game, player, args):
        command = args.pop(0)

        can_do, reason = self.can_do_action(game)
        if not can_do:
            return await ctx.send(f'You cannot use your action today. {reason}')

        if command == 'noaction':
            for action in game.night_actions:
                if action['player'].user.id == player.user.id:
                    game.night_actions.remove(action)

            game.night_actions.add_action({
                'action': None,
                'player': player,
                'priority': 0
            })
            if len(game.players.filter(action_only=True)) == len(game.night_actions):
                if not game.phase == Phase.STANDBY:
                    await game.increment_phase()
            return await ctx.send('You decided to stay home tonight.')

        targets = []
        if len(args) < 2:
            return await ctx.send('You have to specifiy 2 targets.')

        for arg in args[0:2]:
            if not arg.isdigit():
                return await ctx.send('Pick a valid number from the playerlist.')
            num = int(arg)
            if num > len(game.players):
                return await ctx.send(f'There are only {len(game.players)} playing.')
            target = game.players[num - 1]
            targets.append(target)

        for target in targets:
            can_target, reason = self.can_target(player, target)
            if not can_target:
                return await ctx.send(reason)

        target1, target2 = targets
        if target1 == target2:
            return await ctx.send('Pick 2 distinct targets.')

        for action in game.night_actions:
            if action['player'].user.id == player.user.id:
                game.night_actions.remove(action)

        game.night_actions.add_action({
            'action': self.action,
            'player': player,
            'target': targets,
            'priority': self.action_priority,
            'can_block': self.can_block,
            'can_transport': self.can_transport,
            'can_visit': self.can_visit
        })
        await ctx.send(f'You are {self.action_gerund} {" and ".join(map(lambda p: p.user.name, targets))} tonight.')

        if len(game.players.filter(action_only=True)) == len(game.night_actions):
            try:
                if not game.phase == Phase.STANDBY:
                    await game.increment_phase()
            except Exception as exc:
                raise PhaseChangeError(None, *exc.args)
Пример #5
0
    async def on_pm_command(self, ctx, game, player, args):
        command = args.pop(0)
        can_do, reason = self.can_do_action(game)
        if not can_do:
            return await ctx.send(f'You cannot use your action today. {reason}'
                                  )

        args = ' '.join(args)

        if command == 'noaction':
            for action in game.night_actions:
                if action['player'].user.id == player.user.id:
                    game.night_actions.remove(action)

            game.night_actions.add_action({
                'action': None,
                'player': player,
                'priority': 0
            })
            if len(game.players.filter(action_only=True)) == len(
                    game.night_actions):
                if not game.phase == Phase.STANDBY:
                    await game.increment_phase()
            return await ctx.send('You decided to stay home tonight.')

        if not args.isdigit():
            return await ctx.send('Pick a valid number from the playerlist.')

        num = int(args)
        if num > len(game.players):
            return await ctx.send(
                f'There are only {len(game.players)} playing.')
        target_pl = game.players[num - 1]
        target = target_pl.user

        if target_pl is None:
            return await ctx.send('Invalid input')
        can_target, reason = self.can_target(player, target_pl)
        if not can_target:
            return await ctx.send(reason)

        for action in game.night_actions:
            if action['player'].user.id == player.user.id:
                game.night_actions.remove(action)

        # special godfather stuff
        if self.name == 'Godfather' and len(
                game.players.filter(role='Goon', is_alive=True)) > 0:
            goon = game.players.filter(role='Goon')[0]
            for action in game.night_actions:
                if action['player'].role.name == 'Goon':
                    game.night_actions.remove(action)

            game.night_actions.add_action({
                'action': self.action,
                'player': goon,
                'target': target_pl,
                'priority': self.action_priority,
                'can_block': self.can_block,
                'can_transport': self.can_transport,
                'can_visit': self.can_visit
            })

        game.night_actions.add_action({
            'action': self.action,
            'player': player,
            'target': target_pl,
            'priority': self.action_priority,
            'can_block': self.can_block,
            'can_transport': self.can_transport,
            'can_visit': self.can_visit
        })
        await ctx.send(f'You are {self.action_gerund} {target} tonight.')

        if len(game.players.filter(action_only=True)) == len(
                game.night_actions):
            try:
                if not game.phase == Phase.STANDBY:
                    await game.increment_phase()
            except Exception as exc:
                raise PhaseChangeError(None, *exc.args)
Пример #6
0
    async def on_pm_command(self, ctx, game, player, args):
        if self.ignited:
            # already ignited last time, let's remove everything now
            self.doused.clear()
            self.ignited = False
        command = args.pop(0)
        can_do, reason = self.can_do_action(command)
        if not can_do:
            return await ctx.send(f'You cannot use your action today. {reason}')

        args = ' '.join(args)

        if command == 'noaction':
            for action in game.night_actions:
                if action['player'].user.id == player.user.id:
                    game.night_actions.remove(action)

            for action in game.night_actions:
                if action['player'].user.id == player.user.id:
                    game.night_actions.remove(action)

            game.night_actions.add_action({
                'action': None,
                'player': player,
                'priority': 0
            })
            if len(game.players.filter(action_only=True)) == len(game.night_actions):
                await game.increment_phase()
            return await ctx.send('You decided to stay home tonight.')

        if command == 'ignite':
            for target in self.doused:
                if not target.is_alive:
                    continue
                game.night_actions.add_action({
                    'action': 'ignite',
                    'player': player,
                    'target': target,
                    'priority': Priority.ARSONIST,
                    'can_block': False,
                    'can_transport': False
                })
            self.ignited = True
            await ctx.send('You are igniting your doused targets today.')
            total_actions = len(game.players.filter(action_only=True))
            expected_total = total_actions + len(self.doused) - 1
            if expected_total == len(game.night_actions):
                try:
                    await game.increment_phase()
                except Exception as exc:
                    raise PhaseChangeError(None, *exc.args)
            return

        if not args.isdigit():
            return await ctx.send('Pick a valid number from the playerlist.')

        num = int(args)
        if num > len(game.players):
            return await ctx.send(f'There are only {len(game.players)} playing.')
        target_pl = game.players[num - 1]
        target = target_pl.user

        if target_pl is None:
            return await ctx.send('Invalid input')
        can_target, reason = self.can_target(player, target_pl)
        if not can_target:
            return await ctx.send(reason)

        for action in game.night_actions:
            if action['player'].user.id == player.user.id:
                game.night_actions.remove(action)

        game.night_actions.add_action({
            'action': 'douse',
            'player': player,
            'target': target_pl,
            'priority': Priority.ARSONIST,
            'can_block': True,
            'can_transport': True
        })
        await ctx.send(f'You are dousing {target} tonight.')

        if len(game.players.filter(action_only=True)) == len(game.night_actions):
            try:
                await game.increment_phase()
            except Exception as exc:
                raise PhaseChangeError(None, *exc.args)