using System.Collections.Generic;
using UnityEngine;
namespace Luneraria.View
{
///
/// A tower (Grenzwacht, Bastion, Kernwacht) or an Ancient (Mondherz) of the G2 set. Shows the
/// authoritative building HP as one of five looks, like scripts/luneraria/view/lune_tower_view.gd
/// and lune_ancient_view.gd: intact, lightly and heavily damaged, collapsing, ruin. The view never
/// decides anything; HP comes from the core (U2C binds it).
///
public sealed class LuneBuildingView : MonoBehaviour
{
public enum Look { Intact, Light, Heavy, Destroying, Ruin }
/// HP fractions where the look changes (the same bands for towers and Ancients).
public const float LightBelow = .605f;
public const float HeavyBelow = .305f;
public string BuildingId = "";
public int Team;
/// outer, inner, base or core.
public string Tier = "";
public Look Current = Look.Intact;
readonly Dictionary _parts = new Dictionary();
public bool IsAncient { get { return Tier == "core"; } }
void Collect()
{
if (_parts.Count > 0)
return;
Transform model = transform.childCount > 0 ? transform.GetChild(0) : transform;
foreach (Transform part in model)
_parts[part.name] = part;
}
/// Look for an HP fraction; a destroyed building shows its ruin.
public static Look LookFor(float hp, float maxHp)
{
float fraction = Mathf.Clamp01(hp / Mathf.Max(1f, maxHp));
if (hp <= 0f)
return Look.Ruin;
if (fraction < HeavyBelow)
return Look.Heavy;
if (fraction < LightBelow)
return Look.Light;
return Look.Intact;
}
/// Part visibility of a look (Godot _enter of the tower and Ancient views).
public void Show(Look look)
{
Collect();
Current = look;
bool standing = look != Look.Ruin;
if (IsAncient)
{
foreach (KeyValuePair part in _parts)
{
string key = part.Key;
bool visible;
if (key.StartsWith("Ruin"))
visible = !standing;
else if (key == "Crest_A")
visible = standing && Team == 0;
else if (key == "Crest_B")
visible = standing && Team != 0;
else if (key == "Dais" || key == "Pedestal")
visible = true;
else
visible = standing;
part.Value.gameObject.SetActive(visible);
}
return;
}
bool damagedTop = look == Look.Heavy || look == Look.Destroying;
Set("Upper", standing && !damagedTop);
Set("Upper_Damaged", standing && damagedTop);
Set("Debris", look == Look.Heavy || look == Look.Destroying);
Set("Lower", standing);
Set("Ruin", !standing);
foreach (KeyValuePair part in _parts)
{
string key = part.Key;
if (key == "Crystal" || key == "Ring" || key.StartsWith("Shard") || key.StartsWith("Banner") || key.StartsWith("Pennant"))
part.Value.gameObject.SetActive(standing);
}
}
void Set(string key, bool visible)
{
if (_parts.TryGetValue(key, out Transform part))
part.gameObject.SetActive(visible);
}
}
}