Files
Fruitomation/Assets/Scripts/UI/BasicUpgradeButton.cs
2026-04-21 21:02:06 +01:00

175 lines
5.6 KiB
C#

using System.Text.RegularExpressions;
using System.Collections.Generic;
using Fruitomation.Game;
using UnityEngine.UI;
using UnityEngine;
using System.Linq;
using System;
using PashaBibko.Pacore.Attributes;
namespace Fruitomation.UI
{
public enum UpgradeState
{
Unlocked,
Unlockable,
Viewable,
Hidden,
}
public class BasicUpgradeButton : MonoBehaviour
{
[Serializable] private class LineInfo
{
public RectTransform[] LinePoints;
}
[Header("Settings")]
[SerializeField] private BasicUpgrade Upgrade;
[SerializeField] private bool DrawDefaultLines;
[SerializeField] private CurrencyAmount Cost;
[SerializeField] private bool BigText;
[Header("References")]
[SerializeField] private BasicUpgradeButton[] RequiredUpgrades;
[SerializeField] private Material LineMaterial;
[Header("Lines")]
[SerializeField] private LineInfo[] Lines;
private (LineRenderer, BasicUpgradeButton, LineInfo)[] UpgradeLines;
[Header("Read Only")]
[SerializeField, InspectorReadOnly] private UpgradeState State = UpgradeState.Hidden;
[SerializeField, InspectorReadOnly] private Button AttachedButton;
[SerializeField, InspectorReadOnly] private Text AttachedText;
private void Awake()
{
const int TEXT_SCALAR = 5;
AttachedText = gameObject.GetComponentInChildren<Text>();
AttachedText.transform.localScale = new Vector3(1f / TEXT_SCALAR, 1f / TEXT_SCALAR, 1f);
AttachedText.fontSize = BigText ? 50 * TEXT_SCALAR : 35 * TEXT_SCALAR;
AttachedButton = GetComponent<Button>();
AttachedButton.onClick.AddListener(OnButtonClicked);
/* Stops null reference */
RequiredUpgrades ??= Array.Empty<BasicUpgradeButton>();
List<(LineRenderer, BasicUpgradeButton, LineInfo)> lines = new();
if (DrawDefaultLines)
{
foreach (BasicUpgradeButton required in RequiredUpgrades)
{
GameObject go = new("LineRenderer(Script Spawned)");
go.transform.SetParent(transform);
RectTransform rt = go.AddComponent<RectTransform>();
rt.anchoredPosition = new Vector2();
LineRenderer lr = go.AddComponent<LineRenderer>();
lr.material = LineMaterial;
lr.widthMultiplier = 0.1f;
lr.positionCount = 2;
lines.Add((lr, required, null));
}
}
else
{
foreach (LineInfo line in Lines)
{
GameObject go = new("LineRenderer(Script Spawned)");
go.transform.SetParent(transform);
RectTransform rt = go.AddComponent<RectTransform>();
rt.anchoredPosition = new Vector2();
LineRenderer lr = go.AddComponent<LineRenderer>();
lr.material = LineMaterial;
lr.widthMultiplier = 0.1f;
lines.Add((lr, null, line));
}
}
UpgradeLines = lines.ToArray();
}
private void OnButtonClicked()
{
UpgradeManager.Unlock(Upgrade);
}
private bool IsUnlockable =>
RequiredUpgrades.Length == 0 ||
RequiredUpgrades.All(required => required.IsUnlocked);
private bool IsViewable =>
RequiredUpgrades.Length == 0 ||
RequiredUpgrades.Any(required => required.IsUnlockable);
private void Update()
{
foreach ((LineRenderer lr, BasicUpgradeButton button, LineInfo info) in UpgradeLines)
{
if (DrawDefaultLines)
{
lr.SetPosition(0, transform.position);
lr.SetPosition(1, button.transform.position);
}
else
{
lr.positionCount = info.LinePoints.Length;
int index = 0;
foreach (RectTransform point in info.LinePoints)
{
lr.SetPosition(index++, point.position);
}
}
}
if (UpgradeManager.Is(Upgrade))
{
State = UpgradeState.Unlocked;
}
else if (IsUnlockable)
{
State = UpgradeState.Unlockable;
}
else if (IsViewable)
{
State = UpgradeState.Viewable;
}
else
{
State = UpgradeState.Hidden;
}
AttachedButton.interactable = State == UpgradeState.Unlockable;
// https://stackoverflow.com/questions/27040325/c-sharp-regex-to-convert-camelcase-to-sentence-case
string formatted = Regex.Replace(Upgrade.ToString(), "[A-Z]", " $0")[1..];
AttachedText.text = State switch
{
UpgradeState.Hidden => "???",
UpgradeState.Viewable => $"{formatted}",
UpgradeState.Unlockable => $"{formatted}\n{Cost.AsString()}",
UpgradeState.Unlocked => $"{formatted}\nUnlocked",
var _ => throw new ArgumentOutOfRangeException()
};
}
private bool IsUnlocked => State == UpgradeState.Unlocked;
}
}