mirror of
https://github.com/Steffo99/patched-porobot.git
synced 2024-12-22 17:44:22 +00:00
Add CardType::Equipment and rewrite Telegram rendering code
This commit is contained in:
parent
933907cd5f
commit
140a35e6a4
2 changed files with 198 additions and 98 deletions
|
@ -9,6 +9,9 @@ pub enum CardType {
|
|||
/// A spell.
|
||||
Spell,
|
||||
|
||||
/// A equipment.
|
||||
Equipment,
|
||||
|
||||
/// An unit: either a minion, or a champion.
|
||||
///
|
||||
/// Champions have their [supertype](super::card::Card::supertype) set to `Champion`, and their [rarity](super::card::Card::rarity) set to [CardRarity::Champion](super::rarity::CardRarity::Champion) as well.
|
||||
|
@ -33,6 +36,7 @@ pub enum CardType {
|
|||
impl From<&CardType> for &'static str {
|
||||
fn from(r#type: &CardType) -> Self {
|
||||
match r#type {
|
||||
CardType::Equipment => "Equipment",
|
||||
CardType::Spell => "Spell",
|
||||
CardType::Unit => "Unit",
|
||||
CardType::Ability => "Ability",
|
||||
|
|
|
@ -23,118 +23,163 @@ use teloxide::utils::html::escape;
|
|||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
pub fn display_card(globals: &LocalizedGlobalsIndexes, card: &Card) -> String {
|
||||
let title = format!("<b><u>{}</u></b>\n", escape(&card.name),);
|
||||
|
||||
let stats = match &card.r#type {
|
||||
CardType::Spell => format!("{} mana\n\n", escape(&card.cost.to_string()),),
|
||||
let title: String = display_title(&card.name);
|
||||
let r#type: String = display_type(globals, card);
|
||||
let stats = display_stats(card);
|
||||
let subtypes: String = display_subtypes(&card.subtypes);
|
||||
|
||||
let header = format!("{} ({})\n{}\n{}\n", &title, &r#type, &stats, &subtypes);
|
||||
|
||||
let keywords = display_keywords(&card.keywords, &globals.keywords);
|
||||
let description = display_description(&card.localized_description_text);
|
||||
let levelup = display_levelup(&card.localized_levelup_text);
|
||||
|
||||
let body = format!("{}{}{}", &keywords, &description, &levelup);
|
||||
|
||||
let set = display_set(&card.set, &globals.sets);
|
||||
let regions = display_regions(&card.regions, &globals.regions);
|
||||
let flavor = display_flavor(&card.main_art().expect("Card to have at least one illustration").full_png, &card.localized_flavor_text);
|
||||
|
||||
let footer = format!("{}{}\n{}", &set, ®ions, &flavor);
|
||||
|
||||
format!("{}⸻\n\n{}⸻\n\n{}", &header, &body, &footer)
|
||||
}
|
||||
|
||||
/// Render a [Card]'s title in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_title(name: &str) -> String {
|
||||
format!("<b><u>{}</u></b>", escape(name))
|
||||
}
|
||||
|
||||
/// Render the [Card]'s in-game type in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_type(globals: &LocalizedGlobalsIndexes, card: &Card) -> String {
|
||||
match card.r#type {
|
||||
CardType::Spell => {
|
||||
"Spell".to_string()
|
||||
}
|
||||
CardType::Equipment => {
|
||||
CardKeyword::Equipment.localized(&globals.keywords).map(|l| l.name.clone()).unwrap_or_else(|| "EQUIPMENT".to_string())
|
||||
}
|
||||
CardType::Unit => {
|
||||
if card.supertype.eq(&CardSupertype::Champion) {
|
||||
"Champion".to_string()
|
||||
}
|
||||
else {
|
||||
"Unit".to_string()
|
||||
}
|
||||
}
|
||||
CardType::Ability => {
|
||||
if card.keywords.contains(&CardKeyword::Skill) {
|
||||
CardKeyword::Skill.localized(&globals.keywords).map(|l| l.name.clone()).unwrap_or_else(|| "SKILL".to_string())
|
||||
}
|
||||
else {
|
||||
"Ability".to_string() // Does this exist?
|
||||
}
|
||||
}
|
||||
CardType::Landmark => {
|
||||
CardKeyword::Landmark.localized(&globals.keywords).map(|l| l.name.clone()).unwrap_or_else(|| "LANDMARK".to_string())
|
||||
}
|
||||
CardType::Trap => {
|
||||
if card.keywords.contains(&CardKeyword::Trap) {
|
||||
CardKeyword::Trap.localized(&globals.keywords).map(|l| l.name.clone()).unwrap_or_else(|| "TRAP".to_string())
|
||||
}
|
||||
else if card.keywords.contains(&CardKeyword::Boon) {
|
||||
CardKeyword::Boon.localized(&globals.keywords).map(|l| l.name.clone()).unwrap_or_else(|| "Boon".to_string())
|
||||
}
|
||||
else {
|
||||
"Trigger".to_string() // Does this exist?
|
||||
}
|
||||
}
|
||||
CardType::Unsupported => {
|
||||
"UNKNOWN?".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn display_stats(card: &Card) -> String {
|
||||
match &card.r#type {
|
||||
CardType::Spell => format!("{} mana", escape(&card.cost.to_string())),
|
||||
CardType::Unit => format!(
|
||||
"{} mana {}|{}\n\n",
|
||||
"{} mana · {}|{}",
|
||||
escape(&card.cost.to_string()),
|
||||
escape(&card.attack.to_string()),
|
||||
escape(&card.health.to_string()),
|
||||
),
|
||||
CardType::Landmark => format!("{} mana\n\n", &card.cost),
|
||||
CardType::Landmark => format!("{} mana", &card.cost),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
let set = display_set(&card.set, &globals.sets);
|
||||
let regions = display_regions(&card.regions, &globals.regions);
|
||||
let r#type = display_types(&card.r#type, &card.supertype, &card.subtypes);
|
||||
|
||||
let breadcrumbs = format!("{} › {} › {}\n\n", &set, ®ions, &r#type);
|
||||
|
||||
let keywords = display_keywords(&card.keywords, &globals.keywords);
|
||||
|
||||
let description = display_description(&card.localized_description_text);
|
||||
let levelup = display_levelup(&card.localized_levelup_text);
|
||||
|
||||
let flavor = format!("<i>{}</i>\n", escape(&card.localized_flavor_text));
|
||||
|
||||
let artist = format!(
|
||||
r#"<a href="{}">Illustration</a> by {}"#,
|
||||
&card
|
||||
.main_art()
|
||||
.expect("Card to have at least one illustration")
|
||||
.full_png,
|
||||
escape(&card.artist_name)
|
||||
);
|
||||
|
||||
format!(
|
||||
"{}{}{}{}{}{}-----\n{}{}",
|
||||
&title, &breadcrumbs, &keywords, &stats, &description, &levelup, &flavor, &artist,
|
||||
)
|
||||
}
|
||||
|
||||
/// Render a [CardSet] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_set(set: &CardSet, hm: &LocalizedCardSetIndex) -> String {
|
||||
format!(
|
||||
"<i>{}</i>",
|
||||
set.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
)
|
||||
}
|
||||
|
||||
/// Render a slice of [CardRegion]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_regions(regions: &[CardRegion], hm: &LocalizedCardRegionIndex) -> String {
|
||||
regions
|
||||
.iter()
|
||||
.map(|region| {
|
||||
region
|
||||
.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
})
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
/// Render the [CardType], the [CardSupertype] and the [CardSubtype]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_types(r#type: &CardType, supertype: &CardSupertype, subtypes: &[CardSubtype]) -> String {
|
||||
let mut result = String::new();
|
||||
|
||||
result.push_str(
|
||||
match supertype {
|
||||
CardSupertype::Champion => "<i>Champion</i> › ",
|
||||
CardSupertype::Unsupported => "<i>Unknown</i> › ",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
|
||||
result.push_str(&format!("<i>{}</i>", escape(&String::from(r#type)),));
|
||||
|
||||
if !subtypes.is_empty() {
|
||||
result.push_str(&format!(
|
||||
" › {}",
|
||||
subtypes
|
||||
.iter()
|
||||
.map(|subtype| format!("<i>{}</i>", escape(subtype)))
|
||||
.join(", ")
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
/// Render the [CardSubtype]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_subtypes(subtypes: &[CardSubtype]) -> String {
|
||||
let result = subtypes
|
||||
.iter()
|
||||
.map(|s| titlecase(&s))
|
||||
.map(|s| escape(&s))
|
||||
.map(|s| format!("<i>{s}</i>"))
|
||||
.join(", ");
|
||||
|
||||
if result.is_empty() {
|
||||
result
|
||||
} else {
|
||||
result + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
/// Render a slice of [CardKeyword]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_keywords(keywords: &[CardKeyword], hm: &LocalizedCardKeywordIndex) -> String {
|
||||
format!(
|
||||
"{}\n",
|
||||
keywords
|
||||
.iter()
|
||||
.map(|keyword| keyword
|
||||
.localized(hm)
|
||||
.map(|o| format!("[<b>{}</b>]", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string()))
|
||||
.join(" ")
|
||||
)
|
||||
let result = keywords
|
||||
.iter()
|
||||
.filter(|keyword| match keyword {
|
||||
CardKeyword::Countdown => false,
|
||||
CardKeyword::OnPlay => false,
|
||||
CardKeyword::Landmark => false,
|
||||
CardKeyword::Shurima => false,
|
||||
CardKeyword::Noxus => false,
|
||||
CardKeyword::ClobberNoEmptySlotRequirement => false,
|
||||
CardKeyword::Nab => false,
|
||||
CardKeyword::Enlightened => false,
|
||||
CardKeyword::Invoke => false,
|
||||
CardKeyword::Drain => false,
|
||||
CardKeyword::LastBreath => false,
|
||||
CardKeyword::Demacia => false,
|
||||
CardKeyword::BandleCity => false,
|
||||
CardKeyword::Bilgewater => false,
|
||||
CardKeyword::Runeterra => false,
|
||||
CardKeyword::Recall => false,
|
||||
CardKeyword::Weakest => false,
|
||||
CardKeyword::Support => false,
|
||||
CardKeyword::Obliterate => false,
|
||||
CardKeyword::Imbue => false,
|
||||
CardKeyword::Targon => false,
|
||||
CardKeyword::ShadowIsles => false,
|
||||
CardKeyword::AuraVisualFakeKeyword => false,
|
||||
CardKeyword::Ionia => false,
|
||||
CardKeyword::PiltoverZaun => false,
|
||||
CardKeyword::SilenceIndividualKeyword => false,
|
||||
CardKeyword::Plunder => false,
|
||||
CardKeyword::Silenced => false,
|
||||
_ => true,
|
||||
})
|
||||
.map(|keyword| keyword
|
||||
.localized(hm)
|
||||
.map(|o| format!("[<b>{}</b>: {}]\n", escape(&o.name), escape(&o.description)))
|
||||
.unwrap_or_else(|| "[<b>UNKNOWN?</b>]\n".to_string()))
|
||||
.join("");
|
||||
|
||||
if result.is_empty() {
|
||||
result
|
||||
} else {
|
||||
result + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
/// Render a [Card::localized_description_text] in [Telegram Bot HTML].
|
||||
|
@ -159,6 +204,46 @@ fn display_levelup(levelup: &String) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Render a [CardSet] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_set(set: &CardSet, hm: &LocalizedCardSetIndex) -> String {
|
||||
format!(
|
||||
"<i>{}</i>",
|
||||
set.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "UNKNOWN?".to_string())
|
||||
)
|
||||
}
|
||||
|
||||
/// Render a slice of [CardRegion]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_regions(regions: &[CardRegion], hm: &LocalizedCardRegionIndex) -> String {
|
||||
let result = regions
|
||||
.iter()
|
||||
.map(|region| {
|
||||
region
|
||||
.localized(hm)
|
||||
.map(|o| format!("<u>{}</u>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "UNKNOWN?".to_string())
|
||||
})
|
||||
.join(", ");
|
||||
|
||||
if result.is_empty() {
|
||||
result
|
||||
} else {
|
||||
format!(" · {}", &result)
|
||||
}
|
||||
}
|
||||
|
||||
/// Render the flavor text of a [Card] in [Telegram Bot HTML], linking to the given art.
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_flavor(art_url: &str, localized_flavor_text: &str) -> String {
|
||||
format!("<a href=\"{}\"><i>{}</i></a>", &art_url, escape(localized_flavor_text))
|
||||
}
|
||||
|
||||
/// Render a [Deck] in [Telegram Bot HTML], with an optional `name`.
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
|
@ -205,7 +290,7 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: &str, name: &Option<&s
|
|||
let mut tags: Vec<&'static str> = vec![];
|
||||
|
||||
let regions = if let Some(regions) = deck.standard(index) {
|
||||
tags.push("#Standard_4_3");
|
||||
tags.push("#Standard_4_5");
|
||||
regions
|
||||
} else if let Some(regions) = deck.eternal(index) {
|
||||
tags.push("#Eternal");
|
||||
|
@ -245,3 +330,14 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: &str, name: &Option<&s
|
|||
None => format!("<code>{}</code>\n{}\n{}", &code, &tags, &cards),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// https://stackoverflow.com/a/38406885/4334568
|
||||
fn titlecase(s: &str) -> String {
|
||||
let s = s.to_lowercase();
|
||||
let mut c = s.chars();
|
||||
match c.next() {
|
||||
None => String::new(),
|
||||
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue