Ui/Punchboard/PbShowcase.razor

The file is a UI panel component that showcases various game features, including a round progress bar, player statistics, and collectible cards. It allows users to interact with mock elements to demonstrate UI functionality.

@namespace CitySim.Punchboard
@using Sandbox
@using Sandbox.UI
@inherits PanelComponent

<root class="pb-showcase">
	<div class="pb-sc-scroll">
		<div class="pb-sc-title">@(GameText.Get("ui.pb_showcase.punchboard_components"))</div>
		<div class="pb-sc-note">@(GameText.Get("ui.pb_showcase.a_live_catalogue_every_component_below_takes_plain_parameters_and_has_no"))</div>

		<div class="pb-sc-row">
			<PbPanel Title=@(GameText.Get("ui.pb_showcase.round_bar")) Kind=@(PbPanelKind.Raised)>
<ChildContent>
				<div class="pb-sc-line">
					<div class="pb-sc-col"><span class="pb-sc-caption">@(GameText.Get("ui.pb_showcase.round"))</span><span class="pb-sc-big">@($"{round} / 8")</span><PbRoundTrack Total=@(8) Current=@round /></div>
					<PbDial Fill=@Fraction Text=@Seconds Alert=@(Seconds.ToInt() <= 5) />
					<div class="pb-sc-col"><span class="pb-sc-caption">@(GameText.Get("ui.pb_showcase.phase"))</span><span class="pb-sc-big">@(GameText.Get("ui.round_bar.build"))</span></div>
				</div>
			</ChildContent>
</PbPanel>

			<PbPanel Title=@(GameText.Get("ui.plotter_showcase.resources"))>
<ChildContent>
				<div class="pb-sc-line">
					<PbStat Icon="🪙" [email protected]() Tone=@(PbTone.Accent) Label=@(GameText.Get("ui.resource_panel.coins")) />
					<PbStat Icon="★" [email protected]() Tone=@(PbTone.Red) Label=@(GameText.Get("ui.pb_showcase.points")) />
				</div>
				<div class="pb-sc-line">
					<PbButton Text=@(GameText.Get("ui.pb_showcase.1_coin")) Size=@(PbSize.Small) Kind=@(PbButtonKind.Tertiary) Clicked=@(() => { coins++; }) />
					<PbButton Text=@(GameText.Get("ui.pb_showcase.3_points")) Size=@(PbSize.Small) Kind=@(PbButtonKind.Secondary) Clicked=@(() => { points += 3; }) />
				</div>
			</ChildContent>
</PbPanel>

			<PbPanel Title=@(GameText.Get("ui.pb_showcase.players"))>
<ChildContent>
				<div class="pb-sc-line"><PbMeeple Tint=@(new Color( 0.85f, 0.28f, 0.23f )) /><span class="pb-sc-name">@(GameText.Get("ui.pb_showcase.you"))</span></div>
				<div class="pb-sc-line"><PbMeeple Tint=@(new Color( 0.23f, 0.61f, 0.72f )) /><span class="pb-sc-name">@(GameText.Get("ui.pb_showcase.maya"))</span></div>
				<div class="pb-sc-line"><PbMeeple Tint=@(new Color( 0.94f, 0.72f, 0.23f )) /><span class="pb-sc-name">@(GameText.Get("ui.pb_showcase.bot_ben"))</span></div>
			</ChildContent>
</PbPanel>

			<PbPanel Title=@(GameText.Get("ui.pb_showcase.effects"))>
<ChildContent>
				<div class="pb-sc-line">
					<PbSlot Icon="🏛" Count=@(2) TooltipText=@(GameText.Get("ui.pb_showcase.bank_2")) />
					<PbSlot Icon="🎭" TooltipText=@(GameText.Get("cards.museum.name")) />
					<PbSlot Icon="🌿" TooltipText=@(GameText.Get("cards.gardeners_guild.name")) />
					<PbSlot Empty=@true />
				</div>
			</ChildContent>
</PbPanel>
		</div>

		<div class="pb-sc-row">
			<PbPanel Title=@(GameText.Get("ui.pb_showcase.buttons"))>
<ChildContent>
				<div class="pb-sc-line">
					<PbButton Text=@(GameText.Get("ui.pb_showcase.primary")) />
					<PbButton Text=@(GameText.Get("ui.plotter_showcase.secondary")) Kind=@(PbButtonKind.Secondary) />
					<PbButton Text=@(GameText.Get("ui.pb_showcase.tertiary")) Kind=@(PbButtonKind.Tertiary) />
					<PbButton Text=@(GameText.Get("ui.pb_showcase.ghost")) Kind=@(PbButtonKind.Ghost) />
					<PbButton Text=@(GameText.Get("ui.pb_showcase.danger")) Kind=@(PbButtonKind.Danger) />
				</div>
				<div class="pb-sc-line">
					<PbButton Text=@(GameText.Get("ui.pb_showcase.small")) Size=@(PbSize.Small) />
					<PbButton Text=@(GameText.Get("ui.plotter_showcase.disabled")) Disabled=@true />
					<PbButton Text=@(ready ? GameText.Get("ui.pb_showcase.ready") : GameText.Get("ui.lobby_panel.ready_2")) Toggled=@ready Clicked=@(() => { ready = !ready; }) />
					<PbButton Text=@(GameText.Get("ui.pb_showcase.big")) Size=@(PbSize.Big) />
				</div>
			</ChildContent>
</PbPanel>

			<PbPanel Title=@(GameText.Get("ui.hud.settings"))>
<ChildContent>
				<PbToggle Label=@(GameText.Get("ui.settings_panel.reduce_screen_shake")) Value=@shake ValueChanged=@((Action<bool>)(v => { shake = v; })) />
				<PbToggle Label=@(GameText.Get("ui.settings_panel.reduce_flashing")) Value=@flashing ValueChanged=@((Action<bool>)(v => { flashing = v; })) />
				<PbTabs Items=@tabs Selected=@tab SelectedChanged=@((Action<int>)(i => { tab = i; })) />
				<PbMeter Label=@(GameText.Get("ui.pb_showcase.hand")) Text="3 / 5" Value=@(0.6f) />
				<PbMeter Label=@(GameText.Get("ui.pb_showcase.park_tiles")) Text=@(GameText.Get("ui.pb_showcase.6_tiles")) Value=@(0.6f) Tone=@(PbTone.Good) />
			</ChildContent>
</PbPanel>

			<PbPanel Title=@(GameText.Get("ui.pb_showcase.tags_and_rarity"))>
<ChildContent>
				<div class="pb-sc-line">
					@foreach ( var tag in Enum.GetValues<PbTag>() )
					{
						<PbTagPill Tag=@tag />
					}
				</div>
				<div class="pb-sc-line">
					@foreach ( var rarity in Enum.GetValues<PbRarity>() )
					{
						<PbRarityMarker Rarity=@rarity />
					}
				</div>
			</ChildContent>
</PbPanel>

			<PbTooltipCard Title=@(GameText.Get("cards.cafe.name")) Rarity=@(PbRarity.Uncommon) Tags=@(new[] { PbTag.Trade, PbTag.Culture }) Text=@(GameText.Get("ui.pb_showcase.pays_1_coin_per_adjacent_house_or_shop_max_3")) Live=@(GameText.Get("ui.pb_showcase.income_sample")) />
		</div>

		<div class="pb-sc-row">
			<PbBanner Caption=@(GameText.Get("ui.pb_showcase.round_sample")) Title=@(GameText.Get("ui.pb_showcase.market")) />
			<PbBanner Caption=@(GameText.Get("ui.pb_showcase.goal_claimed")) Title=@(GameText.Get("ui.pb_showcase.neighbourhood_5")) Tone=@(PbTone.Teal) />
			<PbButton Text=@(GameText.Get("ui.pb_showcase.open_dialog")) Kind=@(PbButtonKind.Secondary) Clicked=@(() => { modal = true; }) />
		</div>

		<div class="pb-sc-hand">
			<PbHand>
<ChildContent>
				@for ( var i = 0; i < cards.Length; i++ )
				{
					var index = i;
					var card = cards[i];
					<PbCard [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
						HotKey=@((index + 1).ToString()) Compact=@true Selected=@(selected == index) Clicked=@(() => { selected = selected == index ? -1 : index; }) />
				}
			</ChildContent>
</PbHand>
		</div>
	</div>

	<PbModal Open=@modal Title=@(GameText.Get("ui.pb_showcase.end_of_game")) Dismissed=@(() => { modal = false; })>
		<ChildContent><div class="pb-sc-name">@(GameText.Get("ui.pb_showcase.maya_wins_with_58_vp"))</div></ChildContent>
		<Actions>
			<PbButton Text=@(GameText.Get("ui.end_panel.main_menu")) Kind=@(PbButtonKind.Secondary) Clicked=@(() => { modal = false; }) />
			<PbButton Text=@(GameText.Get("ui.end_panel.play_again")) Clicked=@(() => { modal = false; }) />
		</Actions>
	</PbModal>
</root>

@code
{
	record CardInfo( string Title, string Icon, PbRarity Rarity, PbTag[] Tags, string Text, Color Accent );

	readonly CardInfo[] cards =
	{
		new( GameText.Get("cards.house.name"), "🏠", PbRarity.Common, new[] { PbTag.Home }, GameText.Get("ui.pb_showcase.payout_1_coin_if_a_shop_is_within_2_tiles_place_1_vp_per_adjacent_home_b"), new Color( 0.85f, 0.28f, 0.23f ) ),
		new( GameText.Get("cards.park.name"), "🌳", PbRarity.Common, new[] { PbTag.Nature }, GameText.Get("cards.wild_garden.rules"), new Color( 0.29f, 0.65f, 0.39f ) ),
		new( GameText.Get("cards.cafe.name"), "☕", PbRarity.Uncommon, new[] { PbTag.Trade, PbTag.Culture }, GameText.Get("ui.pb_showcase.1_coin_per_adjacent_house_or_shop_max_3"), new Color( 0.64f, 0.41f, 0.78f ) ),
		new( GameText.Get("cards.bank.name"), "🏛", PbRarity.Rare, new[] { PbTag.Trade }, GameText.Get("ui.pb_showcase.2_coins_at_every_payout_stackable_max_3"), new Color( 0.94f, 0.72f, 0.23f ) ),
		new( GameText.Get("cards.monument.name"), "★", PbRarity.Legendary, new[] { PbTag.Culture }, GameText.Get("ui.pb_showcase.6_vp_at_game_end"), new Color( 0.9f, 0.6f, 0f ) ),
	};

	readonly List<string> tabs = new() { GameText.Get("ui.pb_showcase.audio"), GameText.Get("ui.pb_showcase.video"), GameText.Get("ui.pb_showcase.input") };

	int round = 3;
	int coins = 9;
	int points = 24;
	int selected = 1;
	int tab;
	bool ready;
	bool shake = true;
	bool flashing;
	bool modal;

	float Fraction => 1f - (Time.Now % 30f) / 30f;
	string Seconds => MathF.Ceiling( 30f - Time.Now % 30f ).ToString();

	protected override int BuildHash()
	{
		var a = HashCode.Combine( round, coins, points, selected, tab, ready, shake, flashing );
		return HashCode.Combine( a, modal, (int)(Time.Now * 2f) );
	}
}