Example #1
0
async def test_del_char() -> None:
    session = db.Session()
    guild_id = 555
    player_id = 111
    session.add(
        Character(
            guild=guild_id,
            player=player_id,
            name="name",
            race="race",
            attr_reason=5,
            disc_science=12,
        ))
    session.commit()
    cog = STA()
    context = MagicMock()
    context.author.id = player_id
    context.guild.id = guild_id
    context.guild.__bool__.return_value = True
    context.author.__bool__.return_value = True
    future: Future[bool] = asyncio.Future()
    future.set_result(True)
    context.send.return_value = future
    context.mock_add_spec(["guild", "author", "send"], spec_set=True)

    assert db.Session().query(Character).count() == 1
    await STA.del_char(cog, context)
    assert db.Session().query(Character).count() == 0

    assert context.mock_calls == [
        call.guild.__bool__(),
        call.send("Character deleted."),
    ]
Example #2
0
    async def trivia(self, ctx: Context) -> None:
        score = PlayerScore.get(ctx)

        response = "Answer the Question in 30 seconds!"
        await ctx.send(response)
        chosen_row = random.choice(self.questions)

        possible_answers = [chosen_row.answer] + random.sample(
            chosen_row.options, k=3)

        random.shuffle(possible_answers)

        await ctx.send(chosen_row.question)
        choices = random.sample(possible_answers, k=4)
        msg = "\n".join(f"{i+1}: {choice}" for i, choice in enumerate(choices))
        await ctx.send(msg)

        def check(match: Message) -> bool:
            return bool(match.content.isdigit() and match.author == ctx.author)

        try:
            guess = await self.bot.wait_for("message",
                                            check=check,
                                            timeout=30.0)
        except asyncio.TimeoutError:
            score.score = 0
            await ctx.send(
                f"Sorry, you took too long! The answer was {chosen_row.answer}.\n"
                f"Your high score is: {score.high_score}")
            db.Session().commit()
            return

        if choices[int(guess.content) - 1] == chosen_row.answer:
            score.score += 1
            new_high_score = False
            if score.score > score.high_score:
                score.high_score = score.score
                new_high_score = True

            await ctx.send(
                f"You are right! Your current score is: {score.score}\n"
                f"Your high score is: {score.high_score}")
            if new_high_score:
                await ctx.send("New high score \N{party popper}")
        else:
            score.score = 0
            await ctx.send(f'Oh no! The answer was: "{chosen_row.answer}".\n'
                           f"Your high score is: {score.high_score}")

        db.Session().commit()
Example #3
0
    async def set_stat(self, ctx: Context, stat: str, subcmd: str,
                       value: int) -> None:
        character = Character.get(ctx)

        stat_lower = stat.lower()
        if subcmd == "set":
            if stat_lower in ["det", "determination"]:
                character.determination = value
            elif stat_lower in ["stress", "str"]:
                character.stress = value
        else:
            if subcmd == "add":
                change = value
            elif subcmd == "sub":
                change = -value
            else:
                await ctx.send(f"Bad operation: {subcmd}")
                return

            if stat_lower in ["det", "determination"]:
                character.determination += change
            elif stat_lower in ["stress", "str"]:
                character.stress += change

        db.Session().commit()
        await self.player_embed(ctx)
Example #4
0
    async def sub_game_stat(self, ctx: Context, stat: str, diff: int) -> None:
        """
        Set a stat on the game state

        :param ctx: Game context
        :param stat: Stat name
        :param diff: Stat change
        """
        state = GameState.get_or_create(ctx)
        stat_l = stat.lower()

        if stat_l == "momentum":
            changed = state.sub_momentum(diff)
        elif stat_l == "threat":
            changed = state.sub_threat(diff)
        else:
            await ctx.send(f"Unknown stat: {stat}")
            return

        if not changed:
            await ctx.send(f"Not enough {stat} (Needed {diff})")

        db.Session().commit()

        await self.show_game(ctx, state, color=Colour.magenta())
Example #5
0
    async def set_disc(self, ctx: Context, disc: str, value: int) -> None:
        character = Character.get(ctx)
        try:
            character.set_discipline(disc, value)
        except AttributeError:
            await ctx.send(f"Unknown discipline: {disc}")
            return

        db.Session().commit()
        await self.player_embed(ctx)
Example #6
0
    async def set_attr(self, ctx: Context, stat: str, value: int) -> None:
        character = Character.get(ctx)
        try:
            character.set_attribute(stat, value)
        except AttributeError:
            await ctx.send(f"Unknown attribute: {stat}")
            return

        db.Session().commit()

        await self.player_embed(ctx)
Example #7
0
    async def del_char(self, ctx: Context, other_user: User = None) -> None:
        character = Character.get(ctx, other_user)

        if not character:
            await ctx.send("No character found")
            return

        session = db.Session()
        session.delete(character)
        session.commit()

        await ctx.send("Character deleted.")
Example #8
0
    def get_or_create(cls, context: Context) -> "GameState":
        state = cls.get(context)
        guild = context.guild
        if not guild:
            raise ValueError("Missing guild?!")

        if state is None:
            session = db.Session()
            state = GameState(guild=guild.id, momentum=0, threat=0)
            session.add(state)
            session.commit()

        return state
Example #9
0
    def get(cls, context: Context) -> Optional["GameState"]:
        """
        Get a game state

        :return: Current state
        """
        session = db.Session()
        guild = context.guild
        if not guild:
            raise ValueError("Missing guild?!")

        guild_id = guild.id
        state = session.query(cls).get(guild_id)
        if state is None:
            return None

        return cast(GameState, state)
Example #10
0
async def test_challenge_attribute_order(attr: str, disc: str) -> None:
    random.seed(1)
    cog = MagicMock()
    session = db.Session()
    guild_id = 555
    player_id = 111
    session.add(
        Character(
            guild=guild_id,
            player=player_id,
            name="name",
            race="race",
            attr_reason=5,
            disc_science=12,
        ))
    session.commit()
    context = MagicMock()
    context.author.id = player_id
    context.guild.id = guild_id
    context.guild.__bool__.return_value = True
    context.author.__bool__.return_value = True
    future: Future[bool] = asyncio.Future()
    future.set_result(True)
    context.send.return_value = future
    context.mock_add_spec(["guild", "author", "send"], spec_set=True)
    assert (await STA.challenge(cog, context, attr, disc, 1, 2)) is None
    msg = context.send.mock_calls[0]
    embed: Embed = msg.kwargs["embed"]
    file: File = msg.kwargs["file"]

    # This is done by send normally
    file.close()

    assert embed.author.name is Embed.Empty
    assert embed.title == "Challenge"
    assert embed.description == "Science (12) + Reason (5)"

    fields = cast(List[EmbedProxy], embed.fields)
    AssertEmbed(fields[0]).has_name("Difficulty: ").has_value("1")
    AssertEmbed(fields[1]).has_name("Successes: ").has_value("1")
    AssertEmbed(fields[2]).has_name("Complications: ").has_value("0")
    AssertEmbed(fields[3]).has_name("Rolls: ").has_value("[5, 19]")

    assert embed.image.url == "attachment://Green-alert.gif"
    assert file.filename == "Green-alert.gif"
Example #11
0
    async def gm_challenge(
        self,
        ctx: Context,
        attribute: str,
        attribute_value: int,
        discipline: str,
        discipline_value: int,
        difficulty: int,
        num_dice: int,
        focus: bool = False,
        do_threat: bool = False,
    ) -> None:
        challenge_value = attribute_value + discipline_value

        roll = ChallengeRoll.do_roll(
            num_dice,
            challenge_value,
            focus,
            discipline_value,
            attribute_value,
            discipline,
            attribute,
            difficulty,
        )

        embed = roll.embed

        game_state = GameState.get_or_create(ctx)
        old_threat = game_state.threat
        if do_threat and roll.successes > difficulty:
            threat = roll.successes - difficulty
            game_state.add_threat(threat)

        threat_diff = game_state.threat - old_threat
        if threat_diff:
            embed.add_field(name="Threat: ", value=f"+{threat_diff}")

        db.Session().commit()

        file = roll.get_img()

        embed.set_image(url=f"attachment://{file.filename}")

        await ctx.send(embed=embed, file=file)
Example #12
0
    def get(cls, ctx: Context) -> "PlayerScore":
        session = db.Session()
        guild = ctx.guild
        author = ctx.author
        if not guild:
            raise ValueError("Missing guild?!")

        if not author:
            raise ValueError("Missing author?!")

        guild_id = guild.id
        author_id = author.id
        state = cast(PlayerScore,
                     session.query(cls).get((guild_id, author_id)))
        if state is None:
            state = PlayerScore(guild=guild_id, player=author_id)
            session.add(state)
            session.commit()

        return state
Example #13
0
    def get(cls,
            ctx: Context,
            other_user: Optional[Union[User, Member]] = None) -> "Character":
        """
        Get a player's character

        :param ctx: Context
        :param other_user: Player's name
        :return: Player's character or None
        """
        guild = ctx.guild
        if not guild:
            raise ValueError("Unset guild?!")

        member: Union[User, Member]
        if other_user:
            member = other_user
        else:
            member = ctx.author

        return cast(Character,
                    db.Session().query(cls).get((guild.id, member.id)))
Example #14
0
    async def create_player(
        self,
        ctx: Context,
        name: str,
        race: str,
        control: int,
        daring: int,
        fitness: int,
        insight: int,
        presence: int,
        reason: int,
        command: int,
        conn: int,
        security: int,
        engineering: int,
        science: int,
        medicine: int,
        other_user: User = None,
    ) -> None:
        guild = ctx.guild
        if not guild:
            raise ValueError("Missing guild")

        member: Union[Member, User]
        if other_user:
            member = other_user
        else:
            member = ctx.author

        if not member:
            raise ValueError("Missing author")

        character = Character.get(ctx, member)

        if character:
            await ctx.send(
                f"{member.display_name} already has a Character ({character.name})."
            )
            return

        character = Character(
            name=name,
            race=race,
            attr_control=control,
            attr_fitness=fitness,
            attr_daring=daring,
            attr_insight=insight,
            attr_presence=presence,
            attr_reason=reason,
            disc_conn=conn,
            disc_command=command,
            disc_medicine=medicine,
            disc_science=science,
            disc_security=security,
            disc_engineering=engineering,
            player=member.id,
            guild=guild.id,
        )
        session = db.Session()
        session.add(character)
        session.commit()
        await ctx.send("Character created!")

        await self.player_embed(ctx, member)
Example #15
0
 async def sub_game(self, ctx: Context, stat: str, value: int) -> None:
     await self.sub_game_stat(ctx, stat, abs(value))
     db.Session().commit()
Example #16
0
 async def add_game(self, ctx: Context, stat: str, value: int) -> None:
     await self.add_game_stat(ctx, stat, value)
     db.Session().commit()