225 lines
8.8 KiB
C#
225 lines
8.8 KiB
C#
#if UNITY_EDITOR
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using YachtDice.Modifiers.Definition;
|
|
|
|
namespace YachtDice.Modifiers.Editor
|
|
{
|
|
public static class ModifierDefinitionValidator
|
|
{
|
|
[MenuItem("YachtDice/Validate All Modifier Definitions")]
|
|
public static void ValidateAll()
|
|
{
|
|
string[] guids = AssetDatabase.FindAssets("t:ModifierDefinitionSO");
|
|
|
|
if (guids.Length == 0)
|
|
{
|
|
Debug.Log("[ModifierValidator] No ModifierDefinitionSO assets found.");
|
|
return;
|
|
}
|
|
|
|
var errorCount = 0;
|
|
var warnCount = 0;
|
|
var usedIds = new Dictionary<string, string>(); // id -> asset path
|
|
|
|
foreach (var t in guids)
|
|
{
|
|
var path = AssetDatabase.GUIDToAssetPath(t);
|
|
var def = AssetDatabase.LoadAssetAtPath<ModifierDefinition>(path);
|
|
|
|
if (def == null)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] Failed to load asset at {path}");
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
// ── Id checks ────────────────────────────────────────
|
|
|
|
if (string.IsNullOrWhiteSpace(def.Id))
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: Id is empty.", def);
|
|
errorCount++;
|
|
}
|
|
else if (usedIds.TryGetValue(def.Id, out string existingPath))
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: Duplicate Id '{def.Id}' (also used by {existingPath}).", def);
|
|
errorCount++;
|
|
}
|
|
else
|
|
{
|
|
usedIds[def.Id] = path;
|
|
}
|
|
|
|
// ── Economy checks ───────────────────────────────────
|
|
|
|
if (def.ShopPrice < 0)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: ShopPrice is negative ({def.ShopPrice}).", def);
|
|
errorCount++;
|
|
}
|
|
|
|
if (def.SellPrice < 0)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: SellPrice is negative ({def.SellPrice}).", def);
|
|
errorCount++;
|
|
}
|
|
|
|
if (def.SellPrice > def.ShopPrice && def.ShopPrice > 0)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: SellPrice ({def.SellPrice}) > ShopPrice ({def.ShopPrice}). Infinite money exploit?", def);
|
|
warnCount++;
|
|
}
|
|
|
|
// ── Durability checks ────────────────────────────────
|
|
|
|
if (def.HasLimitedUses && def.MaxUses <= 0)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: HasLimitedUses is true but MaxUses is {def.MaxUses}.", def);
|
|
errorCount++;
|
|
}
|
|
|
|
if (!def.HasLimitedUses && def.MaxUses > 0)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: HasLimitedUses is false but MaxUses is {def.MaxUses}. Ignored at runtime.", def);
|
|
warnCount++;
|
|
}
|
|
|
|
if (def.MaxStacks < 1)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: MaxStacks must be >= 1 (is {def.MaxStacks}).", def);
|
|
errorCount++;
|
|
}
|
|
|
|
// ── Behavior checks ──────────────────────────────────
|
|
|
|
if (def.Behaviors == null || def.Behaviors.Count == 0)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: No behaviors assigned. Modifier will do nothing.", def);
|
|
warnCount++;
|
|
continue;
|
|
}
|
|
|
|
for (int b = 0; b < def.Behaviors.Count; b++)
|
|
{
|
|
var behavior = def.Behaviors[b];
|
|
|
|
if (behavior == null)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: Behavior slot [{b}] is null.", def);
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
// Check for null conditions
|
|
if (behavior.Conditions != null)
|
|
{
|
|
for (int c = 0; c < behavior.Conditions.Count; c++)
|
|
{
|
|
if (behavior.Conditions[c] == null)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: Behavior '{behavior.name}' has null condition at slot [{c}].", behavior);
|
|
warnCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for null or empty effects
|
|
if (behavior.Effects == null || behavior.Effects.Count == 0)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: Behavior '{behavior.name}' has no effects.", behavior);
|
|
warnCount++;
|
|
}
|
|
else
|
|
{
|
|
for (int e = 0; e < behavior.Effects.Count; e++)
|
|
{
|
|
if (behavior.Effects[e] == null)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] {path}: Behavior '{behavior.name}' has null effect at slot [{e}].", behavior);
|
|
errorCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── Display checks ───────────────────────────────────
|
|
|
|
if (string.IsNullOrWhiteSpace(def.DisplayName))
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: DisplayName is empty.", def);
|
|
warnCount++;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(def.Description))
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] {path}: Description is empty.", def);
|
|
warnCount++;
|
|
}
|
|
}
|
|
|
|
string summary = $"[ModifierValidator] Validated {guids.Length} modifier(s): {errorCount} error(s), {warnCount} warning(s).";
|
|
|
|
if (errorCount > 0)
|
|
Debug.LogError(summary);
|
|
else if (warnCount > 0)
|
|
Debug.LogWarning(summary);
|
|
else
|
|
Debug.Log(summary);
|
|
}
|
|
|
|
[MenuItem("YachtDice/Validate Modifier Catalog")]
|
|
public static void ValidateCatalog()
|
|
{
|
|
string[] guids = AssetDatabase.FindAssets("t:ModifierCatalogSO");
|
|
|
|
if (guids.Length == 0)
|
|
{
|
|
Debug.LogWarning("[ModifierValidator] No ModifierCatalogSO asset found. Create one via Create > YachtDice/Modifiers/Catalog.");
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < guids.Length; i++)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
|
var catalog = AssetDatabase.LoadAssetAtPath<ModifierCatalog>(path);
|
|
|
|
if (catalog == null)
|
|
{
|
|
Debug.LogError($"[ModifierValidator] Failed to load catalog at {path}");
|
|
continue;
|
|
}
|
|
|
|
if (catalog.All == null || catalog.All.Count == 0)
|
|
{
|
|
Debug.LogWarning($"[ModifierValidator] Catalog at {path} is empty.");
|
|
continue;
|
|
}
|
|
|
|
int nullCount = 0;
|
|
var catalogIds = new HashSet<string>();
|
|
|
|
for (int j = 0; j < catalog.All.Count; j++)
|
|
{
|
|
if (catalog.All[j] == null)
|
|
{
|
|
nullCount++;
|
|
Debug.LogError($"[ModifierValidator] Catalog {path}: Null entry at index [{j}].", catalog);
|
|
continue;
|
|
}
|
|
|
|
string id = catalog.All[j].Id;
|
|
if (!catalogIds.Add(id))
|
|
{
|
|
Debug.LogError($"[ModifierValidator] Catalog {path}: Duplicate modifier Id '{id}' in catalog.", catalog);
|
|
}
|
|
}
|
|
|
|
Debug.Log($"[ModifierValidator] Catalog {path}: {catalog.All.Count} entries, {nullCount} null.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|