Files
trail-into-darkness/Packages/com.jovian.encounter-system/Editor/EncounterLinkDrawer.cs
2026-04-19 12:46:44 +02:00

83 lines
3.5 KiB
C#

using Jovian.EncounterSystem;
using UnityEditor;
using UnityEngine;
namespace Jovian.EncounterSystem.Editor {
/// <summary>Table object-field + encounter dropdown picker. Changing tables clears the id.</summary>
[CustomPropertyDrawer(typeof(EncounterLink))]
public class EncounterLinkDrawer : PropertyDrawer {
private const string NonePlaceholder = "<none>";
private const string EmptyTablePlaceholder = "<select a table first>";
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
var tableProp = property.FindPropertyRelative("table");
var idProp = property.FindPropertyRelative("internalId");
EditorGUI.BeginProperty(position, label, property);
var lineHeight = EditorGUIUtility.singleLineHeight;
var spacing = EditorGUIUtility.standardVerticalSpacing;
var tableRect = new Rect(position.x, position.y, position.width, lineHeight);
var encounterRect = new Rect(position.x, position.y + lineHeight + spacing, position.width, lineHeight);
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(tableRect, tableProp, label);
var tableChanged = EditorGUI.EndChangeCheck();
using(new EditorGUI.IndentLevelScope()) {
var table = tableProp.objectReferenceValue as EncounterTable;
if(table == null || table.encounters == null || table.encounters.Count == 0) {
using(new EditorGUI.DisabledScope(true)) {
EditorGUI.Popup(encounterRect, "Encounter", 0, new[] { EmptyTablePlaceholder });
}
if(tableChanged) {
idProp.stringValue = string.Empty;
}
}
else {
DrawEncounterPicker(encounterRect, table, idProp, tableChanged);
}
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return EditorGUIUtility.singleLineHeight * 2 + EditorGUIUtility.standardVerticalSpacing;
}
private static void DrawEncounterPicker(Rect rect, EncounterTable table, SerializedProperty idProp, bool tableChanged) {
var count = table.encounters.Count;
var ids = new string[count + 1];
var names = new string[count + 1];
ids[0] = string.Empty;
names[0] = NonePlaceholder;
var currentIndex = 0;
for(int i = 0; i < count; i++) {
var encounter = table.encounters[i];
var id = encounter?.EncounterDefinition?.internalId ?? string.Empty;
var name = encounter?.EncounterDefinition?.name;
ids[i + 1] = id;
names[i + 1] = string.IsNullOrEmpty(name)
? $"<unnamed> ({encounter?.GetType().Name ?? "null"})"
: name;
if(!tableChanged && id == idProp.stringValue && !string.IsNullOrEmpty(id)) {
currentIndex = i + 1;
}
}
if(tableChanged) {
idProp.stringValue = string.Empty;
currentIndex = 0;
}
var newIndex = EditorGUI.Popup(rect, "Encounter", currentIndex, names);
if(newIndex != currentIndex) {
idProp.stringValue = ids[newIndex];
}
}
}
}