Files
DepthsOfGreed/Assets/Scripts/HandbookUI/HandbookTowerEntry.cs
T

109 lines
5.3 KiB
C#

using UnityEngine;
namespace DepthsOfGreed.HandbookUI
{
public enum HandbookTowerCategory { Munition, Energie, Spezial }
public enum BuildMenuGroup { Physisch, Energie, Anlagen, Einsaetze }
[CreateAssetMenu(menuName = "Depths of Greed/Handbuch/Turmtyp", fileName = "NeuerTurmtyp")]
public sealed class HandbookTowerEntry : ScriptableObject
{
[Header("Name und Kategorie")]
[Tooltip("Stabile ID für die Gameplay-Anbindung. Nach Zuordnung nicht ändern.")]
public string id;
public string displayName;
[InspectorName("Waffentechnik / Basisfarbe")] public HandbookTowerCategory category;
[InspectorName("Buchkategorie")] public BuildMenuGroup menuGroup;
public BuildUse use;
[Header("Kaufpreis")]
[Tooltip("Energie-Kaufpreis. 0 wird in der Preisanzeige ausgeblendet.")]
[Min(0)] public int energyCost;
[Tooltip("Gedärme-Kaufpreis. 0 wird in der Preisanzeige ausgeblendet. Beide Ressourcen können gemeinsam erforderlich sein.")]
[Min(0)] public int entrailsCost;
[Header("Texte im Handbuch")]
public string summary;
[TextArea(3, 8)] public string description;
[Header("Grafiken und Prefabs")]
[Tooltip("Bild im Bau-, Index- und Upgrademenü.")]
public Sprite icon;
[Tooltip("Grafik, die während der Platzierung dem Mauszeiger folgt.")]
public Sprite previewSprite;
[Tooltip("Grafik des unbeweglichen Unterteils. Wird vom Platzierungsprototyp genutzt.")]
public Sprite baseSprite;
[Tooltip("Vorbereitetes Unterteil als GameObject. Noch nicht vom Platzierungsprototyp verwendet.")]
public GameObject basePrefab;
[Tooltip("Vollständiges Objekt für die spätere Gameplay-Anbindung.")]
public GameObject gameplayPrefab;
[Header("Platzierung und Platzbedarf")]
public BuildRegion region;
public BaseShape baseShape;
[Tooltip("Kreis, der die gesamte Basis umschließt. Muss vollständig in die Baufläche passen.")]
[Min(0.001f)] public float baseRadius = 0.36f;
public Vector2 baseSize = new Vector2(0.5f, 0.5f);
[Tooltip("Abstandskreis: darf andere Abstandskreise nicht überlappen.")]
[Min(0.001f)] public float placementRadius = 0.6f;
public bool allowPlayerRotation;
public bool blocksMovement, requirePathValidation;
[Header("Mengenlimits und Einsatzdauer")]
public bool countsTowardWallLimit = true;
[Tooltip("0 = kein zusätzliches Limit für diesen Typ.")]
[Min(0)] public int maxPerType;
[Min(0)] public float deploymentCooldown, lifetimeSeconds;
[Min(0)] public int contactUses;
[Header("Kampf, Verbrauch und Sonderfunktion")]
public CombatDefinition combat = new CombatDefinition();
[Header("Kellerversorgung und Turmmagazin")]
public TowerSupplyDefinition supply = new TowerSupplyDefinition();
[Header("Angreifbarkeit und Haltbarkeit")]
public bool targetableByEnemies, destroyableByDamage;
[Min(0)] public float maxHealth;
public bool removeOnFloorLoss = true;
[Header("Verbesserungen")]
public bool upgradeable = true;
public UpgradeDefinition[] upgrades = new UpgradeDefinition[0];
[Header("Vorläufige Werte und Designnotizen")]
public bool provisional = true;
[HideInInspector] public int dataVersion;
public float sourceCostRating;
public int sourceBalanceScore;
[TextArea(3, 12)] public string designNotes;
public CombatDefinition CreateCombatSnapshot(int level)
{
var result = JsonUtility.FromJson<CombatDefinition>(JsonUtility.ToJson(combat));
for (int i = 0; i < Mathf.Min(Mathf.Max(0, level), upgrades.Length); i++)
{
var u = upgrades[i]; result.damagePerHit *= u.damageMultiplier; result.continuousDamagePerSecond *= u.damageMultiplier; result.attacksPerSecond *= u.fireRateMultiplier; result.range *= u.rangeMultiplier;
result.effectStrength *= u.effectMultiplier; result.knockbackDistance *= u.effectMultiplier;
result.energyGeneratedPerSecond *= u.effectMultiplier; result.energyCapacityBonus *= u.effectMultiplier;
result.repairHealthPerSecond *= u.effectMultiplier; result.corpsesCollectedPerSecond *= u.effectMultiplier;
result.slowFraction = Mathf.Clamp01(result.slowFraction * u.effectMultiplier);
}
return result;
}
private void OnValidate()
{
baseRadius = Mathf.Max(0.001f, baseRadius);
placementRadius = Mathf.Max(baseRadius, placementRadius);
energyCost = Mathf.Max(0, energyCost);
entrailsCost = Mathf.Max(0, entrailsCost);
baseSize = new Vector2(Mathf.Max(0.01f, baseSize.x), Mathf.Max(0.01f, baseSize.y));
if (use == BuildUse.Ability) countsTowardWallLimit = false;
if (category == HandbookTowerCategory.Munition) menuGroup = BuildMenuGroup.Physisch;
else if (category == HandbookTowerCategory.Energie) menuGroup = BuildMenuGroup.Energie;
else if ((int)menuGroup < 2) menuGroup = use == BuildUse.Structure ? BuildMenuGroup.Anlagen : BuildMenuGroup.Einsaetze;
}
}
}