def stats(base_mon: "MonsterModel", transformed_mon: "MonsterModel"): base_hp, base_atk, base_rcv, base_weighted = base_mon.stats() tf_hp, tf_atk, tf_rcv, tf_weighed = transformed_mon.stats() return Box(LabeledText('HP', _get_tf_stat_diff_text(base_hp, tf_hp)), LabeledText('ATK', _get_tf_stat_diff_text(base_atk, tf_atk)), LabeledText('RCV', _get_tf_stat_diff_text(base_rcv, tf_rcv)))
def base_active_header(m: "MonsterModel"): return Box(BASE_EMOJI, BoldText('Base'), IdView.active_skill_header(m, m), delimiter=' ')
def normal_awakenings_row(m: "MonsterModel"): normal_awakenings = len(m.awakenings) - m.superawakening_count normal_awakenings_emojis = [ _get_awakening_text(a) for a in m.awakenings[:normal_awakenings] ] return Box(*[Text(e) for e in normal_awakenings_emojis], delimiter=' ')
def embed(state, props: ExperienceCurveViewProps): regular = get_normal_exp_difference(props.monster, props.low, props.high, props.offset) lb = get_lb_exp_difference(props.monster, props.low, props.high, props.offset) slb = get_slb_exp_difference(props.monster, props.low, props.high, props.offset) is_light = props.monster.full_damage_attr.value == 3 return EmbedView( EmbedMain( color=state.color, title=MonsterHeader.fmt_id_header(props.monster, use_emoji=True), url=puzzledragonx(props.monster), description=Text(f'lv{props.low} -> lv{props.high} (' + (trunc_humanize(props.monster.exp_curve) if props.monster.exp_curve else "no") + f' curve)'), ), embed_thumbnail=EmbedThumbnail(MonsterImage.icon(props.monster)), embed_fields=[ EmbedField(title='Exact', body=Box( LabeledText("Reg", humanize_number(regular)), LabeledText("LB", humanize_number(lb)), LabeledText("SLB", humanize_number(slb)), LabeledText("Net", humanize_number(regular + lb + slb))), inline=True), EmbedField(title='Approx', body=Box( LabeledText("Reg", trunc_humanize(regular)), LabeledText("LB", trunc_humanize(lb)), LabeledText("SLB", trunc_humanize(slb)), LabeledText("Net", trunc_humanize(regular + lb + slb))), inline=True), EmbedField( title='Resources', body=Box( LabeledText( "Globes " + emoji_cache.get_emoji( f'orb_{props.monster.full_damage_attr.name.lower()}' ), str( get_total_needed( props.monster, props.low, props.high, props.offset, ceil(1.5 * GLOBE_EXP[ props.monster.full_damage_attr.value]), is_light))), LabeledText( "TA2", str( get_total_needed(props.monster, props.low, props.high, props.offset, TA2_EXP, is_light))), LabeledText( "TA3", str( get_total_needed(props.monster, props.low, props.high, props.offset, TA3_EXP, is_light))), ), inline=True) ], embed_footer=embed_footer_with_state(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 linksbox(m): return Box(LinkedText('YouTube', youtube_search(m)), LinkedText('Skyozora', skyozora(m)), LinkedText('PDX', puzzledragonx(m)), LinkedText('Ilmina', ilmina(m)), delimiter=' | ')
def leader_skill_header(m: "MonsterModel"): return Box(BoldText('Leader Skill'), BoldText(createMultiplierText(m.leader_skill)), delimiter=' ')
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 base_info(cls, m: "MonsterModel"): return Box( Box(get_emoji(cls.down_emoji_name), cls.normal_awakenings_row(m) if len(m.awakenings) != 0 else Box(Text('No Awakenings')), delimiter=' '), cls.super_awakenings_row(m))
def base_active_header(cls, m: "MonsterModel"): return Box(get_emoji(cls.down_emoji_name), BoldText('Base'), cls.active_skill_header(m, []), delimiter=' ')
def _get_tf_stat_diff_text(stat, tf_stat): return Box(Text(str(stat)), Text('-> {}'.format(tf_stat)), delimiter=' ')
def short_with_emoji(m: "MonsterModel", link=True): msg = f"{m.monster_no_na} - {m.name_en}" return Box(Text(get_attribute_emoji_by_monster(m)), LinkedText(msg, puzzledragonx(m)) if link else Text(msg), Text(MonsterHeader.jp_suffix(m, False)), delimiter=' ')
def embed(cls, state: ButtonInfoViewState): is_coop = state.display_options.players == ButtonInfoOptions.coop is_desktop = state.display_options.device == ButtonInfoOptions.desktop max_110 = state.display_options.max_level == ButtonInfoOptions.limit_break monster = state.monster info = state.info fields = [ EmbedField( # this block does not change if the lv110/lv120 toggle is clicked ButtonInfoView.get_max_level_text(monster, True), Box( Text('Without Latents'), # avoid whitespace after code block Box(get_stat_block(info.coop if is_coop else info.solo), Text('With Latents (Atk+)'), delimiter=''), get_stat_block( info.coop_latent if is_coop else info.solo_latent)), inline=True), EmbedField( 'Lv. 120', Box( Text('Without Latents'), # avoid whitespace after code block Box(get_stat_block( info.coop_slb if is_coop else info.solo_slb), Text('With Latents (Atk++)'), delimiter=''), get_stat_block(info.coop_slb_latent if is_coop else info. solo_slb_latent)), inline=True) if monster.limit_mult != 0 else None, EmbedField( ButtonInfoView.get_common_buttons_title_text(monster, max_110), Box( Text( '*Inherits are assumed to be the max possible level (up to 110) and +297.*' ), # janky, but python gives DeprecationWarnings when using \* in a regular string Text(r'*\* = on-color stat bonus applied*'), Text('Card Button Damage'), # done this way to not have the whitespace after code block Box(BlockText(info.get_card_btn_str(is_coop, max_110)), Text('Team Button Contribution'), delimiter=''), BlockText(info.get_team_btn_str(is_coop, max_110)))) if is_desktop else None, EmbedField( ButtonInfoView.get_common_buttons_title_text(monster, max_110), Box( Text( '*Inherits are assumed to be the max possible level (up to 110) and +297.*' ), # janky, but python gives DeprecationWarnings when using \* in a regular string Text(r'*\* = on-color stat bonus applied*'))) if not is_desktop else None, EmbedField('Card Button Damage', BlockText( get_mobile_btn_str( info.get_card_btn_str(is_coop, max_110))), inline=True) if not is_desktop else None, EmbedField('Team Button Contribution', BlockText( get_mobile_btn_str( info.get_team_btn_str(is_coop, max_110))), inline=True) if not is_desktop else None, cls.evos_embed_field(state) ] return EmbedView(EmbedMain( color=state.query_settings.embedcolor, description='(Co-op mode)' if is_coop else '(Singleplayer mode)'), embed_author=EmbedAuthor( MonsterHeader.menu_title(monster).to_markdown(), MonsterLink.header_link(monster, state.query_settings), MonsterImage.icon(monster.monster_id)), 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 linksbox(m): return Box(LinkedText('YouTube', MonsterLink.youtube_search(m)), LinkedText('Skyozora', MonsterLink.skyozora(m)), LinkedText('PADIndex', MonsterLink.padindex(m)), LinkedText('Ilmina', MonsterLink.ilmina(m)), delimiter=' | ')