def embed(state: PicViewState): url = MonsterImage.picture(state.monster) animated = state.monster.has_animation fields = [ EmbedField( 'Extra Links', Box( Box(Text('Animation:'), LinkedText('(MP4)', MonsterImage.video(state.monster)), Text('|'), LinkedText('(GIF)', MonsterImage.gif(state.monster)), delimiter=' ') if animated else None, Box(Text('Orb Skin:'), LinkedText('Regular', MonsterImage.orb_skin(state.monster)), Text('|'), LinkedText( 'Color Blind', MonsterImage.orb_skin_colorblind(state.monster)), delimiter=' ') if state.monster.orb_skin_id else None, )) ] return EmbedView( EmbedMain(color=state.color, title=MonsterHeader.long_v2(state.monster).to_markdown(), url=puzzledragonx(state.monster)), embed_footer=pad_info_footer_with_state(state), embed_fields=fields, embed_body_image=EmbedBodyImage(url), )
def _get_short_desc(prev_index: int, awakening: "AwakeningModel"): emoji_text = get_awakening_emoji(awakening.awoken_skill_id, awakening.name) return Box( Text(emoji_text), Text('[Same as {} awakening]'.format(ORDINAL_WORDS[prev_index])), delimiter=' ' )
def stats_header(cls, m: "MonsterModel", previous_evolutions, query_settings: QuerySettings): voice_emoji = get_awakening_emoji( 63) if m.awakening_count(63) and not m.is_equip else '' multiboost_emoji = None if m.awakening_count( 30) and query_settings.cardmode == CardModeModifier.coop: multiboost_emoji = get_emoji('misc_multiboost') plus_emoji = get_emoji('plus_297') if cls.get_plus_status(previous_evolutions, query_settings.cardplus) != 297: plus_emoji = get_emoji('plus_0') lb_emoji = get_emoji('lv110') if m.limit_mult > 0 and query_settings.cardlevel == CardLevelModifier.lv120: lb_emoji = get_emoji('lv120') header = Box(Text(voice_emoji), Text(plus_emoji), Text(multiboost_emoji) if multiboost_emoji else None, Text('Stats'), Text('({}, +{}%)'.format(lb_emoji, m.limit_mult)) if m.limit_mult else None, delimiter=' ') return header
def _get_stat_text(stat, lb_stat, icon): return Box( Text(str(stat)), Text("({})".format(lb_stat)) if lb_stat else None, Text(icon) if icon else None, delimiter=' ' )
def short_with_emoji(m: "MonsterModel", link=True, prefix=None): msg = f"{m.monster_no_na} - {m.name_en}" return Box(prefix, Text(get_attribute_emoji_by_monster(m)), LinkedText(msg, puzzledragonx(m)) if link else Text(msg), Text(MonsterHeader.jp_suffix(m, False)), delimiter=' ')
def super_awakenings_row(m: "MonsterModel"): normal_awakenings = len(m.awakenings) - m.superawakening_count super_awakenings_emojis = [_get_awakening_text(a) for a in m.awakenings[normal_awakenings:]] return Box( Text(get_emoji('sa_questionmark')), *[Text(e) for e in super_awakenings_emojis], delimiter=' ') if len(super_awakenings_emojis) > 0 else None
def embed(cls, state: IdViewState): m = state.monster fields = [ EmbedField( '/'.join(['{}'.format(t.name) for t in m.types]), Box(IdView.all_awakenings_row(m, state.transform_base), IdView.killers_row(m, state.transform_base))), EmbedField( 'Inheritable' if m.is_inheritable else 'Not inheritable', IdView.misc_info(m, state.true_evo_type_raw, state.acquire_raw, state.base_rarity), inline=True), EmbedField(IdView.stats_header(m).to_markdown(), IdView.stats(m), inline=True), EmbedField( IdView.active_skill_header(m, state.transform_base).to_markdown(), Text(m.active_skill.desc if m.active_skill else 'None')), EmbedField( IdView.leader_skill_header(m).to_markdown(), Text(m.leader_skill.desc if m.leader_skill else 'None')), evos_embed_field(state) ] return EmbedView(EmbedMain(color=state.color, title=MonsterHeader.long_maybe_tsubaki( m, state.alt_monsters[0].monster.monster_id == cls.TSUBAKI).to_markdown(), url=puzzledragonx(m)), embed_thumbnail=EmbedThumbnail(MonsterImage.icon(m)), embed_footer=embed_footer_with_state(state), embed_fields=fields)
def embed(cls, state: TransformInfoViewState): base_mon = state.base_mon transformed_mon = state.transformed_mon lsmultiplier = state.query_settings.lsmultiplier fields = [ EmbedField( '/'.join(['{}'.format(t.name) for t in transformed_mon.types]), Box( Box(get_emoji(cls.up_emoji_name), cls.normal_awakenings_row(transformed_mon) if len(transformed_mon.awakenings) != 0 else Box( Text('No Awakenings')), delimiter=' '), TransformInfoView.base_info(base_mon), cls.killers_row(base_mon, base_mon)), ), EmbedField(BoldText(transformat('Card info')), TransformInfoView.card_info(base_mon, transformed_mon, state.acquire_raw), inline=True), EmbedField(BoldText('Stats -> ' + transformat('Transform')), TransformInfoView.stats(base_mon, transformed_mon), inline=True), EmbedField( transformat( TransformInfoView.transform_active_header( transformed_mon).to_markdown()), Box( Text( cls.active_skill_text(transformed_mon.active_skill, state.awoken_skill_map)), TransformInfoView.base_active_header( base_mon).to_markdown(), Text( cls.active_skill_text(base_mon.active_skill, state.awoken_skill_map)))), EmbedField( transformat( TransformInfoView.leader_header(transformed_mon, False, lsmultiplier, base_mon).to_markdown()), Box( Text(transformed_mon.leader_skill.desc if transformed_mon. leader_skill else 'None'), TransformInfoView.leader_header(base_mon, True, lsmultiplier, base_mon).to_markdown(), Text(base_mon.leader_skill.desc if base_mon. leader_skill else 'None'))) ] return EmbedView(EmbedMain(color=state.color, title=MonsterHeader.fmt_id_header( transformed_mon, False, state.is_jp_buffed).to_markdown(), url=puzzledragonx(transformed_mon)), embed_thumbnail=EmbedThumbnail( MonsterImage.icon(transformed_mon)), embed_footer=embed_footer_with_state(state), embed_fields=fields)
def get_stat_block(bi_stat_set: ButtonInfoStatSet): return BlockText( Box( Text('Base: {}'.format(int(round(bi_stat_set.main)))), Text('Subattr: {}'.format(int(round(bi_stat_set.sub)))), Text('Total: {}'.format(int(round(bi_stat_set.total)))) ) )
def killers_row(m: "MonsterModel", transform_base): killers_text = 'Any' if 'Any' in m.killers else \ ' '.join(_killer_latent_emoji(k) for k in transform_base.killers) available_killer_text = 'Available killers:' if m == transform_base else 'Avail. killers (pre-xform):' return Box(BoldText(available_killer_text), Text('[{} slots]'.format(m.latent_slots)), Text(killers_text), delimiter=' ')
def get_awoken_skill_description(awoken_skill: "AwokenSkillModel"): emoji_text = get_awakening_emoji(awoken_skill.awoken_skill_id, awoken_skill.name) desc = awoken_skill.desc_en return Box(Text(emoji_text), BoldText(awoken_skill.name_en), Text(desc), delimiter=' ')
def get_description(definition, timestamp, success): if success: if timestamp == UNKNOWN_EDIT_TIMESTAMP: return Text('No last-updated date recorded') else: return Text('Last Updated {}'.format(timestamp)) else: return definition
def stats_header(m: "MonsterModel"): voice = get_awakening_emoji(63) if m.awakening_count(63) and not m.is_equip else '' header = Box( Text(voice), Text('Stats'), Text('(LB, +{}%)'.format(m.limit_mult)) if m.limit_mult else None, delimiter=' ' ) return header
def killers_row(m: "MonsterModel", transform_base): killers = m.killers if m==transform_base else transform_base.killers killers_text = 'Any' if 'Any' in killers else \ ' '.join(_killer_latent_emoji(k) for k in killers) return Box( BoldText('Available killers:'), Text('\N{DOWN-POINTING RED TRIANGLE}' if m!=transform_base else ''), Text('[{} slots]'.format(m.latent_slots if m==transform_base \ else transform_base.latent_slots)), Text(killers_text), delimiter=' ' )
def misc_info(m: "MonsterModel", true_evo_type_raw: str, acquire_raw: str, base_rarity: str): rarity = Box( LabeledText('Rarity', str(m.rarity)), Text('({})'.format(LabeledText('Base', str(base_rarity)).to_markdown())), Text("" if m.orb_skin_id is None else "(Orb Skin)"), delimiter=' ' ) cost = LabeledText('Cost', str(m.cost)) acquire = BoldText(acquire_raw) if acquire_raw else None valid_true_evo_types = ("Reincarnated", "Assist", "Pixel", "Super Reincarnated") true_evo_type = BoldText(true_evo_type_raw) if true_evo_type_raw in valid_true_evo_types else None return Box(rarity, cost, acquire, true_evo_type)
def embed(state: LeaderSkillViewState): lls = state.l_mon.leader_skill rls = state.r_mon.leader_skill return EmbedView(embed_main=EmbedMain( title=ls_multiplier_text(lls, rls), description=Box( BoldText( MonsterHeader.name(state.l_mon, link=True, show_jp=True)), Text(lls.desc if lls else 'None'), BoldText( MonsterHeader.name(state.r_mon, link=True, show_jp=True)), Text(rls.desc if rls else 'None')), color=state.color), embed_footer=embed_footer_with_state(state))
def embed(state: TransformInfoViewState): base_mon = state.base_mon transformed_mon = state.transformed_mon fields = [ EmbedField( '/'.join(['{}'.format(t.name) for t in transformed_mon.types]), Box( Box(TRANSFORM_EMOJI, IdView.normal_awakenings_row(transformed_mon) if len(transformed_mon.awakenings) != 0 else Box( Text('No Awakenings')), delimiter=' '), base_info(base_mon), IdView.killers_row(base_mon, base_mon)), ), EmbedField(BoldText(transformat('Card info')), card_info(base_mon, transformed_mon, state.acquire_raw), inline=True), EmbedField(BoldText('Stats -> ' + transformat('Transform')), stats(base_mon, transformed_mon), inline=True), EmbedField( transformat( transform_active_header(transformed_mon).to_markdown()), Box( Text(transformed_mon.active_skill.desc if transformed_mon. active_skill else 'None'), base_active_header(base_mon).to_markdown(), Text(base_mon.active_skill.desc if base_mon. active_skill else 'None'))), EmbedField( transformat( leader_header(transformed_mon, False).to_markdown()), Box( Text(transformed_mon.leader_skill.desc if transformed_mon. leader_skill else 'None'), leader_header(base_mon, True).to_markdown(), Text(base_mon.leader_skill.desc if base_mon. leader_skill else 'None'))) ] return EmbedView(EmbedMain( color=state.color, title=MonsterHeader.long_v2(transformed_mon).to_markdown(), url=puzzledragonx(transformed_mon)), embed_thumbnail=EmbedThumbnail( MonsterImage.icon(transformed_mon)), embed_footer=embed_footer_with_state(state), embed_fields=fields)
def embed(cls, state: OtherInfoViewState): m: "MonsterModel" = state.monster return EmbedView( EmbedMain( color=state.color, title=MonsterHeader.fmt_id_header( state.monster, state.alt_monsters[0].monster.monster_id == cls.TSUBAKI, state.is_jp_buffed).to_markdown(), url=puzzledragonx(m)), embed_footer=embed_footer_with_state(state), embed_fields=[ EmbedField( "Stats at +297:", Box( # need to put these on the same line to get around discord's insane # whitespace margins around code blocks Text(statsbox(m, plus=297) + 'Stats at +0:'), Text(statsbox(m, plus=0)), LabeledText("JP Name", m.name_ja), LinksView.linksbox(m), LabeledText("JP Added", str(m.reg_date)) if m.reg_date else None, LabeledText("Series", m.series.name_en), Box(LabeledText("Sell MP", '{:,}'.format(m.sell_mp)), LabeledText("Buy MP", '{:,}'.format(m.buy_mp)) if m.buy_mp else None, delimiter=' '), Box( LabeledText("Sell Gold", '{:,}'.format(m.sell_gold))), Box(LabeledText( "XP to Max", '{:.1f}'.format(m.exp / 1000000).rstrip('0').rstrip('.') + 'M' if m.exp >= 1000000 else '{:,}'.format(m.exp)), LabeledText("Max Level", str(m.level)), delimiter=' '), Box(LabeledText("Weighted Stats", str(m.stats()[3])), Text('LB {} (+{}%)'.format( m.stats(lv=110)[3], m.limit_mult)) if m.limit_mult > 0 else None, delimiter=' | '), LabeledText("Fodder EXP", '{:,}'.format(m.fodder_exp)), Box(LabeledText("Rarity", str(m.rarity)), LabeledText("Cost", str(m.cost)), delimiter=' '))), cls.evos_embed_field(state) ])
def all_awakenings_row(m: "MonsterModel"): if len(m.awakenings) == 0: return Box(Text('No Awakenings')) return Box( IdView.normal_awakenings_row(m), IdView.super_awakenings_row(m) )
def long_maybe_tsubaki(m: "MonsterModel", is_tsubaki): """Returns long_v2 as well as an `!` if the monster is Tsubaki To celebrate 1000 issues/PRs in our main Tsubaki repo, we added this easter egg! Yay! """ return Text('[{}] {}{}{}'.format(m.monster_no_na, m.name_en, '!' if is_tsubaki else '', MonsterHeader.jp_suffix(m)))
def embed(state: IdViewState): m = state.monster fields = [ EmbedField( '/'.join(['{}'.format(t.name) for t in m.types]), Box( IdView.all_awakenings_row(m), IdView.killers_row(m, state.transform_base) ) ), EmbedField( 'Inheritable' if m.is_inheritable else 'Not inheritable', IdView.misc_info(m, state.true_evo_type_raw, state.acquire_raw, state.base_rarity), inline=True ), EmbedField( IdView.stats_header(m).to_markdown(), IdView.stats(m), inline=True ), EmbedField( IdView.active_skill_header(m).to_markdown(), Text(m.active_skill.desc if m.active_skill else 'None') ), EmbedField( IdView.leader_skill_header(m).to_markdown(), Text(m.leader_skill.desc if m.leader_skill else 'None') ), EmbedField( "Alternate Evos", HighlightableLinks( links=[LinkedText(str(m.monster_no_na), puzzledragonx(m)) for m in state.alt_monsters], highlighted=next(i for i, mon in enumerate(state.alt_monsters) if m.monster_id == mon.monster_id) ) ) ] return EmbedView( EmbedMain( color=state.color, title=MonsterHeader.long_v2(m).to_markdown(), url=puzzledragonx(m)), embed_thumbnail=EmbedThumbnail(MonsterImage.icon(m)), embed_footer=pad_info_footer_with_state(state), embed_fields=fields)
def base_info(m: "MonsterModel"): return Box( Box('\N{DOWN-POINTING RED TRIANGLE}', IdView.normal_awakenings_row(m) if len(m.awakenings) != 0 else Box( Text('No Awakenings')), delimiter=' '), IdView.super_awakenings_row(m), # the transform base of the base is the same IdView.killers_row(m, m))
def embed(state: LeaderSkillSingleViewState): ls = state.mon.leader_skill return EmbedView( embed_main=EmbedMain( title=createSingleMultiplierText(ls), description=Box( BoldText(MonsterHeader.name(state.mon, link=True, show_jp=True)), Text(ls.desc if ls else 'None')), color=state.color), embed_footer=embed_footer_with_state(state))
def fmt_id_header(cls, m: "MonsterModel", is_tsubaki=False, is_jp_buffed=False, use_emoji=False): return Text('{}{} {}'.strip().format( get_attribute_emoji_by_monster(m) if use_emoji else '', '\N{EARTH GLOBE AMERICAS}' if m.server_priority == Server.NA else '', cls.long_maybe_tsubaki(m, is_tsubaki, bool(is_jp_buffed))))
def card_info(base_mon: "MonsterModel", transformed_mon: "MonsterModel", acquire_raw): rarity = Box(LabeledText( 'Rarity', '{} -> {}'.format(base_mon.rarity, transformed_mon.rarity)), Text("" if base_mon.orb_skin_id is None else "(Orb Skin)"), delimiter=' ') cost = LabeledText('Cost', '{} -> {}'.format(base_mon.cost, transformed_mon.cost)) acquire = BoldText(acquire_raw) if acquire_raw else None return Box(rarity, cost, acquire)
def get_awoken_skill_description(awoken_skill: "AwokenSkillModel", show_help: bool = False, token_map: dict = None): if token_map is None: token_map = {} emoji_text = get_awakening_emoji(awoken_skill.awoken_skill_id, awoken_skill.name) if not show_help: desc = awoken_skill.desc_en else: if awoken_skill.awoken_skill_id not in token_map: desc = "No modifiers found. Please contact Tsubaki admins for support." else: tokens = token_map[awoken_skill.awoken_skill_id] tokens: set desc = ', '.join('`{}`'.format(token) for token in list(tokens)) return Box(Text(emoji_text), BoldText(awoken_skill.name_en), Text(desc), delimiter=' ')
def embed(state: LeaderSkillSingleViewState): ls = state.mon.leader_skill return EmbedView(embed_main=EmbedMain( title=ls_single_multiplier_text(ls), description=Box( BoldText( MonsterHeader.box_with_emoji( state.mon, query_settings=state.query_settings)), Text(ls.desc if ls else 'None')), color=state.query_settings.embedcolor), embed_footer=embed_footer_with_state(state))
def embed(cls, state: OtherInfoViewState): m: "MonsterModel" = state.monster return EmbedView( EmbedMain(color=state.color, title=MonsterHeader.long_maybe_tsubaki( state.monster, state.alt_monsters[0].monster.monster_id == cls.TSUBAKI).to_markdown(), url=puzzledragonx(m)), embed_footer=embed_footer_with_state(state), embed_fields=[ EmbedField( "Stats at +297:", Box( Text(statsbox(m)), LabeledText("JP Name", m.name_ja), LinksView.linksbox(m), LabeledText("History", m.history_us) if m.history_us else None, LabeledText("Series", m.series.name_en), Box(LabeledText("Sell MP", '{:,}'.format(m.sell_mp)), LabeledText("Buy MP", '{:,}'.format(m.buy_mp)) if m.buy_mp else None, delimiter=' '), Box(LabeledText( "XP to Max", '{:.1f}'.format(m.exp / 1000000).rstrip('0').rstrip('.') + 'M' if m.exp >= 1000000 else '{:,}'.format(m.exp)), LabeledText("Max Level", str(m.level)), delimiter=' '), Box(LabeledText("Weighted Stats", str(m.stats()[3])), Text('LB {} (+{}%)'.format( m.stats(lv=110)[3], m.limit_mult)) if m.limit_mult > 0 else None, delimiter=' | '), LabeledText("Fodder EXP", '{:,}'.format(m.fodder_exp)), Box(LabeledText("Rarity", str(m.rarity)), LabeledText("Cost", str(m.cost)), delimiter=' '))), evos_embed_field(state) ])
def embed(cls, state: IdViewState): m = state.monster fields = [ EmbedField( '/'.join(['{}'.format(t.name) for t in m.types]), Box(IdView.all_awakenings_row(m, state.transform_base), cls.killers_row(m, state.transform_base))), EmbedField( 'Inheritable' if m.is_inheritable else 'Not inheritable', IdView.misc_info(m, state.true_evo_type_raw, state.acquire_raw, state.base_rarity), inline=True), EmbedField(IdView.stats_header(m, state.previous_evolutions, state.query_settings).to_markdown(), IdView.stats(m, state.previous_evolutions, state.query_settings), inline=True), EmbedField( cls.active_skill_header( m, state.previous_transforms).to_markdown(), Text( cls.active_skill_text(m.active_skill, state.awoken_skill_map))), EmbedField( cls.leader_skill_header(m, state.query_settings.lsmultiplier, state.transform_base).to_markdown(), Text(m.leader_skill.desc if m.leader_skill else 'None')), cls.evos_embed_field(state) ] return EmbedView( EmbedMain(color=state.query_settings.embedcolor, title=MonsterHeader.menu_title( m, is_tsubaki=state.alt_monsters[0].monster.monster_id == cls.TSUBAKI, is_jp_buffed=state.is_jp_buffed).to_markdown(), url=MonsterLink.header_link(m, state.query_settings)), embed_thumbnail=EmbedThumbnail(MonsterImage.icon(m.monster_id)), embed_footer=embed_footer_with_state(state), embed_fields=fields)
def all_awakenings_row(cls, m: "MonsterModel", transform_base): if len(m.awakenings) == 0: return Box(Text('No Awakenings')) return Box( Box(get_emoji(cls.up_emoji_name) if m != transform_base else '', cls.normal_awakenings_row(m), delimiter=' '), Box('\N{DOWN-POINTING RED TRIANGLE}', IdView.all_awakenings_row(transform_base, transform_base), delimiter=' ') if m != transform_base else None, cls.super_awakenings_row(m), )