349 lines
10 KiB
C#
349 lines
10 KiB
C#
using System;
|
|
using System.Text;
|
|
using Godot;
|
|
using RobotAndDonkey.Game.Board;
|
|
using RobotAndDonkey.Game.Cards;
|
|
using RobotAndDonkey.Game.Data;
|
|
using RobotAndDonkey.Game.GameState;
|
|
using RobotAndDonkey.Game.Modifiers;
|
|
using RobotAndDonkey.Game.Pois;
|
|
|
|
public partial class Tooltip : Control
|
|
{
|
|
public override void _Ready()
|
|
{
|
|
Instance = this;
|
|
|
|
m_Label = GetNode<RichTextLabel>("RichText");
|
|
m_Label.BbcodeEnabled = true;
|
|
m_Label.AutowrapMode = TextServer.AutowrapMode.Word;
|
|
m_Label.ScrollActive = true;
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
UpdateGamepadScroll((float)delta);
|
|
}
|
|
|
|
private void UpdateGamepadScroll(float delta)
|
|
{
|
|
if (m_Label == null || !Visible)
|
|
return;
|
|
|
|
var axis = Input.GetActionStrength("tooltip_scroll_down") - Input.GetActionStrength("tooltip_scroll_up");
|
|
|
|
if (Mathf.Abs(axis) < 0.1f)
|
|
return;
|
|
|
|
var vbar = m_Label.GetVScrollBar();
|
|
if (vbar == null)
|
|
return;
|
|
|
|
vbar.Value += axis * GamepadScrollSpeed * delta;
|
|
}
|
|
|
|
public void Describe(Cell cell)
|
|
{
|
|
Begin();
|
|
AppendCell(cell);
|
|
Commit();
|
|
}
|
|
|
|
public void Describe(Card card)
|
|
{
|
|
Begin();
|
|
AppendCard(card);
|
|
Commit();
|
|
}
|
|
|
|
private void Begin()
|
|
{
|
|
m_Builder.Clear();
|
|
}
|
|
|
|
private void Commit()
|
|
{
|
|
if (m_Label == null)
|
|
return;
|
|
|
|
m_Label.Text = m_Builder.ToString();
|
|
m_Label.ScrollToLine(0);
|
|
}
|
|
|
|
private static string WrapColor(string text, string colorHex)
|
|
{
|
|
return $"[color={colorHex}]{text}[/color]";
|
|
}
|
|
|
|
private void AppendTitle(string title, string subtitle = null)
|
|
{
|
|
m_Builder.Append(WrapColor($"[b]{title}[/b]", ColorTitle));
|
|
|
|
if (!string.IsNullOrEmpty(subtitle))
|
|
{
|
|
m_Builder.Append(' ');
|
|
m_Builder.Append(WrapColor(subtitle, ColorSubtitle));
|
|
}
|
|
|
|
m_Builder.Append('\n');
|
|
}
|
|
|
|
private void AppendSectionHeader(string title)
|
|
{
|
|
m_Builder.Append('\n');
|
|
m_Builder.Append(WrapColor($"[b]{title}[/b]", ColorHeader));
|
|
m_Builder.Append('\n');
|
|
}
|
|
|
|
private void AppendKeyValue(string key, string value)
|
|
{
|
|
m_Builder.Append(WrapColor($"{key}: ", ColorLabel)).Append(WrapColor(value, ColorText)).Append('\n');
|
|
}
|
|
|
|
private void AppendBlankLine()
|
|
{
|
|
m_Builder.Append('\n');
|
|
}
|
|
|
|
private void AppendCell(Cell cell)
|
|
{
|
|
var subtitle = cell.Hex.ToString();
|
|
AppendTitle("Cell", subtitle);
|
|
|
|
var surfaceColor = GetCellColor(cell.Type);
|
|
AppendKeyValue("Surface", WrapColor(cell.Type.ToString(), surfaceColor));
|
|
m_Builder.Append(WrapColor(GetCellDescription(cell.Type), ColorText));
|
|
m_Builder.Append('\n');
|
|
|
|
if (cell.Poi != null)
|
|
{
|
|
Main.Instance.Music.Play(cell.Poi);
|
|
AppendPoi(cell.Poi);
|
|
}
|
|
else
|
|
{
|
|
Main.Instance.Music.Play(cell.Type);
|
|
}
|
|
|
|
AppendModifiers("Cell", cell);
|
|
}
|
|
|
|
public static string GetCellDescription(ECellType cellType)
|
|
{
|
|
return cellType switch
|
|
{
|
|
ECellType.Grass => "Plain and simple terrain, suitable for most tasks.",
|
|
ECellType.Dry => $"Resting replenishes {WrapColor($"{Balancing.Instance.DryRestEnergyMalus} less energy", ColorBad)} and interacting costs {WrapColor($"{Balancing.Instance.DryInteractEnergyMalus} more energy", ColorBad)}.",
|
|
ECellType.Fertile => $"Replenish {WrapColor($"{Balancing.Instance.FertileRestEnergyReplenish} more energy", ColorGood)} while resting here.",
|
|
ECellType.Mud => $"Movement is very difficult and costs {WrapColor($"{Balancing.Instance.MudMoveEnergyCost} more energy", ColorBad)}.",
|
|
ECellType.Blocked => "Can't walk here, try jumping or flying.",
|
|
ECellType.Rocky => "When entering, programs have a high risk of race conditions.",
|
|
_ => throw new ArgumentOutOfRangeException(nameof(cellType), cellType, null)
|
|
};
|
|
}
|
|
|
|
private string GetCellColor(ECellType type)
|
|
{
|
|
return type switch
|
|
{
|
|
ECellType.Grass => "#9ccc65",
|
|
ECellType.Dry => "#ffcc80",
|
|
ECellType.Fertile => "#a5d6a7",
|
|
ECellType.Mud => "#8d6e63",
|
|
ECellType.Blocked => "#b0bec5",
|
|
ECellType.Rocky => "#b39ddb",
|
|
_ => ColorText
|
|
};
|
|
}
|
|
|
|
private void AppendPoi(Poi poi)
|
|
{
|
|
switch (poi)
|
|
{
|
|
case Avatar:
|
|
AppendRobot(Main.Instance.CoreLoop.Robot);
|
|
break;
|
|
|
|
case Shed shed:
|
|
{
|
|
var summary = $"Requested {shed.Requested}\n" + $"Received {shed.Received}\n" + $"Remaining {shed.Remaining}";
|
|
AppendPoiBlock("Shed", summary, poi);
|
|
break;
|
|
}
|
|
|
|
case Crate crate:
|
|
AppendPoiBlock("Crate", $"Contains {crate.Amount} goods", poi);
|
|
break;
|
|
|
|
case Tower tower:
|
|
AppendPoiBlock("Tower", tower.Active ? WrapColor("Active", ColorBad) : WrapColor("Disabled", ColorGood), poi);
|
|
break;
|
|
|
|
case Donkey:
|
|
AppendPoiBlock("Donkey", string.Empty, poi);
|
|
break;
|
|
|
|
default:
|
|
AppendPoiBlock(poi.GetType().Name, string.Empty, poi);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void AppendPoiBlock(string title, string body, Poi poi)
|
|
{
|
|
AppendSectionHeader(title);
|
|
m_Builder.Append("[indent]\n");
|
|
|
|
if (!string.IsNullOrWhiteSpace(body))
|
|
{
|
|
m_Builder.Append(WrapColor(body, ColorText));
|
|
m_Builder.Append("\n\n");
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(poi.Tooltip))
|
|
{
|
|
m_Builder.Append(WrapColor(poi.Tooltip, ColorText));
|
|
m_Builder.Append('\n');
|
|
|
|
var tooltipModifiers = poi.TooltipModifiers;
|
|
if (tooltipModifiers.Length > 0)
|
|
{
|
|
AppendSectionHeader("Related:");
|
|
foreach (var modifier in tooltipModifiers)
|
|
AppendModifier(modifier);
|
|
}
|
|
}
|
|
|
|
m_Builder.Append("[/indent]\n");
|
|
}
|
|
|
|
private void AppendRobot(RobotAndDonkey.Game.Robots.Robot robot)
|
|
{
|
|
AppendSectionHeader(Main.Instance.CoreLoop.Robot.Type.ToString());
|
|
m_Builder.Append("[indent]\n");
|
|
|
|
AppendKeyValue("Programs", robot.ProgramCount.ToString());
|
|
AppendCurrency(robot.Currency);
|
|
|
|
AppendModifiers("Robot", robot);
|
|
|
|
m_Builder.Append("[/indent]\n");
|
|
}
|
|
|
|
private void AppendCurrency(Currency currency)
|
|
{
|
|
AppendKeyValue("Remaining energy", currency.Energy.ToString());
|
|
AppendKeyValue("Good carried", $"{currency.Carry}/{currency.MaxCarry}");
|
|
AppendKeyValue("Completed deliveries", currency.Delivery.ToString());
|
|
AppendKeyValue("Tape length", currency.TapeLength.ToString());
|
|
AppendKeyValue("Hand size", currency.HandSize.ToString());
|
|
}
|
|
|
|
private void AppendCard(Card card)
|
|
{
|
|
var rarityColor = GetRarityColor(card.Rarity);
|
|
var rarityText = WrapColor(card.Rarity.ToString(), rarityColor);
|
|
var subtitle = $"\n{rarityText} {card.CardType}";
|
|
|
|
AppendTitle(card.Name, subtitle);
|
|
|
|
AppendSectionHeader("Costs");
|
|
m_Builder.Append("[indent]\n");
|
|
AppendKeyValue("Shop", card.ShopCost.ToString());
|
|
AppendKeyValue("Play", card.PlayCost.ToString());
|
|
m_Builder.Append("[/indent]\n");
|
|
|
|
if (!string.IsNullOrWhiteSpace(card.ToolTip))
|
|
{
|
|
AppendSectionHeader("Effect");
|
|
m_Builder.Append("[indent]\n");
|
|
m_Builder.Append(WrapColor(card.ToolTip, ColorText));
|
|
m_Builder.Append('\n');
|
|
|
|
var tooltipModifiers = card.TooltipModifiers;
|
|
if (tooltipModifiers.Length > 0)
|
|
{
|
|
AppendSectionHeader("Related:");
|
|
foreach (var modifier in tooltipModifiers)
|
|
AppendModifier(modifier);
|
|
}
|
|
|
|
m_Builder.Append("[/indent]\n");
|
|
}
|
|
|
|
AppendModifiers("Card", card);
|
|
}
|
|
|
|
private string GetRarityColor(ERarity rarity)
|
|
{
|
|
return rarity switch
|
|
{
|
|
ERarity.Common => "#FFFFFF",
|
|
ERarity.Magic => "#4CFF4C",
|
|
ERarity.Uncommon => "#4C99FF",
|
|
ERarity.Rare => "#CC4CFF",
|
|
ERarity.Legendary => "#FF8033",
|
|
_ => ColorText
|
|
};
|
|
}
|
|
|
|
private void AppendModifiers(string entityName, Entity entity)
|
|
{
|
|
if (entity.Modifiers.Count == 0)
|
|
return;
|
|
|
|
AppendSectionHeader($"{entityName} modifiers");
|
|
m_Builder.Append("[indent]\n");
|
|
foreach (var modifier in entity.Modifiers)
|
|
AppendModifier(modifier);
|
|
m_Builder.Append("[/indent]\n");
|
|
}
|
|
|
|
private void AppendModifier(Modifier modifier)
|
|
{
|
|
var debuffed = modifier.DebuffSources.Count > 0;
|
|
var header = $"{modifier.Id} [{modifier.Duration}]";
|
|
|
|
if (debuffed)
|
|
{
|
|
m_Builder.Append(WrapColor($"[s]{header}[/s]", ColorMuted));
|
|
}
|
|
else
|
|
{
|
|
m_Builder.Append(WrapColor(header, ColorModifier));
|
|
}
|
|
|
|
m_Builder.Append('\n');
|
|
|
|
if (!string.IsNullOrWhiteSpace(modifier.ToolTip))
|
|
{
|
|
m_Builder.Append(WrapColor(modifier.ToolTip, ColorText));
|
|
m_Builder.Append('\n');
|
|
}
|
|
|
|
if (debuffed)
|
|
{
|
|
m_Builder.Append(WrapColor(" (Debuffed)", ColorMuted));
|
|
m_Builder.Append('\n');
|
|
}
|
|
}
|
|
|
|
public static Tooltip Instance { get; private set; }
|
|
|
|
private const string ColorTitle = "#ffd65c";
|
|
private const string ColorSubtitle = "#aaaaaa";
|
|
private const string ColorHeader = "#a5d6ff";
|
|
private const string ColorLabel = "#cccccc";
|
|
private const string ColorText = "#ffffff";
|
|
private const string ColorGood = "#a5d6a7";
|
|
private const string ColorBad = "#ef9a9a";
|
|
private const string ColorMuted = "#9e9e9e";
|
|
private const string ColorModifier = "#ffcc80";
|
|
|
|
private readonly StringBuilder m_Builder = new();
|
|
|
|
[Export]
|
|
public float GamepadScrollSpeed = 800f;
|
|
|
|
private RichTextLabel m_Label;
|
|
} |