Ui/CardPresentation.cs

A static class that provides utility methods for presenting card information in the game UI.

using CitySim.Cards;
using CitySim.Match;

namespace CitySim;

/// <summary>Reviewed, non-authoritative summaries of the subjects mentioned by each card's rules.</summary>
public static class CardPresentation
{
    /// <summary>Card-face artwork, separate from compact rule and board glyphs.</summary>
    public static string Artwork(CardDef card, bool mature = false) => card == null ? null
        : $"ui/cards/{(card.Id == "sapling" && mature ? "forest" : card.Id)}.png";

    static InteractionTarget T(string label, InteractionKind kind, bool own = false) => new(label,kind,own);
    public static IReadOnlyList<InteractionTarget> Targets(CardDef card) => CoreTargets(card)
        .Concat(card.Effects.Any(e=>e.Rule=="beside-road-vp") ? new[]{T(GameText.Get("ui.card_presentation.roads"),InteractionKind.Road)}:Array.Empty<InteractionTarget>())
        .Concat(card.Id=="orchard" ? new[]{T(GameText.Get("ui.card_presentation.nature"),InteractionKind.Nature)}:Array.Empty<InteractionTarget>()).ToArray();
    static IReadOnlyList<InteractionTarget> CoreTargets(CardDef card) => card.Id switch
    {
        "house" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home), T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop)],
        "apartment" => [T(GameText.Get("ui.card_presentation.home_tags"),InteractionKind.Home), T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop)],
        "cottage" => [T(GameText.Get("ui.card_presentation.parks"),InteractionKind.Park), T(GameText.Get("ui.card_presentation.lakes"),InteractionKind.Lake)],
        "shop" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home)],
        "farm" or "orchard" => [T(GameText.Get("ui.card_presentation.farms_orchards"),InteractionKind.Farm), .. (card.Id == "orchard" ? new[] { T(GameText.Get("ui.card_presentation.parks"),InteractionKind.Park) } : Array.Empty<InteractionTarget>())],
        "park" or "wild-garden" or "fountain" or "sapling" => [T(GameText.Get("ui.card_presentation.nature"),InteractionKind.Nature)],
        "street" or "avenue" or "roundabout" or "skyscraper" => [T(GameText.Get("ui.card_presentation.buildings"),InteractionKind.Building)],
        "lake" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home),T(GameText.Get("ui.card_presentation.nature"),InteractionKind.Nature)],
        "tax-office" or "school" or "airport" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home,card.Id is "tax-office" or "school")],
        "market" => [T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop,true)],
        "contractor" => [T(GameText.Get("ui.card_presentation.house"),InteractionKind.House), T(GameText.Get("ui.card_presentation.shop"),InteractionKind.Shop)],
        "cafe" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home), T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop), T(GameText.Get("ui.card_presentation.parks"),InteractionKind.Park), T(GameText.Get("ui.card_presentation.lakes"),InteractionKind.Lake)],
        "factory" or "stadium" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home), T(GameText.Get("ui.card_presentation.cafes"),InteractionKind.Cafe)],
        "town-hall" => [T(GameText.Get("ui.card_presentation.civic"),InteractionKind.Civic,true)],
        "museum" or "tourist-office" => [T(GameText.Get("ui.card_presentation.culture"),InteractionKind.Culture,true)],
        "chamber-of-commerce" => [T(GameText.Get("ui.card_presentation.trade"),InteractionKind.Trade,true)],
        "warehouse" or "builders-yard" or "depot" => [T(GameText.Get("ui.card_presentation.roads"),InteractionKind.Road,card.Id == "depot")],
        "hospital" => [T(GameText.Get("ui.card_presentation.emergencies"),InteractionKind.None)],
        "granary" => [T(GameText.Get("ui.card_presentation.farms_orchards"),InteractionKind.Farm,true)],
        "industrial-estate" => [T(GameText.Get("ui.card_presentation.industry"),InteractionKind.Industry,true)],
        "housing-authority" => [T(GameText.Get("ui.card_presentation.home"),InteractionKind.Home,true)],
        "eco-council" => [T(GameText.Get("ui.card_presentation.nature"),InteractionKind.Nature,true), T(GameText.Get("ui.card_presentation.industry_2"),InteractionKind.Industry,true)],
        "gardeners-guild" => [T(GameText.Get("ui.card_presentation.parks"),InteractionKind.Park)],
        "architects-studio" or "ribbon-cutting" or "renovation" => [T(GameText.Get("ui.card_presentation.buildings"),InteractionKind.Building)],
        "rush-hour" => [T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop,true)],
        "central-station" => [T(GameText.Get("ui.card_presentation.shops"),InteractionKind.Shop,true), T(GameText.Get("ui.card_presentation.markets"),InteractionKind.Market,true)],
        "land-claim" => [T(GameText.Get("ui.card_presentation.empty_tile"),InteractionKind.None)],
        "senate" => [T(GameText.Get("ui.card_presentation.tagged_buildings"),InteractionKind.Tagged,true)],
        _ => []
    };
    public static string Interactions(CardDef card) => string.Join(" · ",Targets(card).Select(target => target.Label));

    public static string Rules(CardDef card) => GameText.Resolve(card.Rules);
    public static string Limit(CardDef card) => card.OwnershipLimit > 0 ? GameText.Get("ui.card_presentation.limit", card.OwnershipLimit) : "";

    public static string Requirement(CardDef card) => card.Id == "street" ? GameText.Get("ui.card_presentation.place_by_a_road_or_board_edge") : card.NeedsRoad ? GameText.Get("ui.card_presentation.requires_road") : "";
}