Esempio n. 1
0
    async def _lookup_search3(self, ctx, entities, query, query_type=None):
        """
        :type ctx: discord.ext.commands.Context
        :param entities: A dict mapping entitlements entity types to the entities themselves.
        :type entities: dict[str, list[T]]
        :type query: str
        :param str query_type: The type of the object being queried for (default entity type if only one dict key)
        :rtype: T
        :raises: RequiresLicense if an entity that requires a license is selected
        """
        # sanity checks
        if len(entities) == 0:
            raise ValueError("At least 1 entity type must be passed in")
        if query_type is None and len(entities) != 1:
            raise ValueError("Query type must be passed for multiple entity types")
        elif query_type is None:
            query_type = list(entities.keys())[0]

        # this may take a while, so type
        await ctx.trigger_typing()

        # get licensed objects, mapped by entity type
        available_ids = {k: await self.bot.ddb.get_accessible_entities(ctx, ctx.author.id, k) for k in entities}

        # the selection display key
        def selectkey(e):
            the_entity, the_etype = e
            if the_entity.homebrew:
                return f"{the_entity.name} ({HOMEBREW_EMOJI})"
            elif can_access(the_entity, available_ids[the_etype]):
                return the_entity.name
            return f"{the_entity.name}\\*"

        # get the object
        choices = []
        for entity_entitlement_type, es in entities.items():
            for entity in es:
                choices.append((entity, entity_entitlement_type))  # entity, entity type

        result, metadata = await search_and_select(
            ctx, choices, query, lambda e: e[0].name, return_metadata=True,
            selectkey=selectkey
        )

        # get the entity
        entity, entity_entitlement_type = result

        # log the query
        await self._add_training_data(
            query_type, query, entity.name, metadata=metadata, srd=entity.is_free,
            could_view=can_access(entity, available_ids[entity_entitlement_type])
        )

        # display error if not srd
        if not can_access(entity, available_ids[entity_entitlement_type]):
            raise errors.RequiresLicense(entity, available_ids[entity_entitlement_type] is not None)
        return entity
Esempio n. 2
0
 def selectkey(e):
     the_entity, the_etype = e
     if the_entity.homebrew:
         return f"{the_entity.name} ({HOMEBREW_EMOJI})"
     elif can_access(the_entity, available_ids[the_etype]):
         return the_entity.name
     return f"{the_entity.name}\\*"
Esempio n. 3
0
async def run_action(ctx, embed, args, caster, action, targets, combat):
    """
    Runs an action: adds title, handles -f and -thumb args, commits combat, runs automation, edits embed.

    :type ctx: discord.ext.commands.Context
    :type embed: discord.Embed
    :type args: utils.argparser.ParsedArguments
    :type caster: cogs5e.models.character.Character
    :type action: cogs5e.models.sheet.action.Action
    :type targets: list of str or list of cogs5e.models.sheet.statblock.StatBlock
    :type combat: None or cogs5e.models.initiative.Combat
    :rtype: cogs5e.models.automation.AutomationResult or None
    """
    await ctx.trigger_typing()

    # entitlements: ensure runner has access to grantor entity
    source_feature = action.gamedata.source_feature
    available_entity_e10s = await ctx.bot.ddb.get_accessible_entities(
        ctx, ctx.author.id, source_feature.entitlement_entity_type)
    if not lookuputils.can_access(source_feature, available_entity_e10s):
        raise RequiresLicense(source_feature, available_entity_e10s
                              is not None)

    if not args.last('h', type_=bool):
        name = caster.get_title_name()
    else:
        name = "An unknown creature"

    if args.last('title') is not None:
        embed.title = args.last('title') \
            .replace('[name]', name) \
            .replace('[aname]', action.name)
    else:
        embed.title = f'{name} uses {action.name}!'

    if action.automation is not None:
        return await _run_common(ctx, embed, args, caster, action, targets,
                                 combat)

    # else, show action description and note that it can't be automated
    if action.snippet:
        embed.description = action.snippet
    else:
        embed.description = "Unknown action effect."
    embed.set_footer(text="No action automation found.")
    return None
Esempio n. 4
0
    async def add_action_field(title, action_source):
        nonlocal non_automated_count, non_e10s_count  # eh
        action_texts = []
        for action in sorted(action_source, key=lambda a: a.name):
            has_automation = action.gamedata is not None
            has_e10s = True
            # entitlement stuff
            if has_automation:
                source_feature = action.gamedata.source_feature
                if source_feature.entitlement_entity_type not in e10s_map:
                    e10s_map[
                        source_feature.
                        entitlement_entity_type] = await ctx.bot.ddb.get_accessible_entities(
                            ctx, ctx.author.id,
                            source_feature.entitlement_entity_type)
                source_feature_type_e10s = e10s_map[
                    source_feature.entitlement_entity_type]
                has_e10s = lookuputils.can_access(source_feature,
                                                  source_feature_type_e10s)
                if not has_e10s:
                    non_e10s_count += 1
                    source_names.add(source_feature.source)

            if verbose:
                name = f"**{action.name}**" if has_automation and has_e10s else f"***{action.name}***"
                action_texts.append(
                    f"{name}: {action.build_str(caster=caster, snippet=True)}")
            elif has_automation:
                name = f"**{action.name}**" if has_e10s else f"***{action.name}***"
                action_texts.append(
                    f"**{name}**: {action.build_str(caster=caster, snippet=False)}"
                )

            # count these for extra display
            if not has_automation:
                non_automated_count += 1
        if not action_texts:
            return
        action_text = '\n'.join(action_texts)
        fields.append({'name': title, 'value': action_text})