41 lines
1.4 KiB
C#
41 lines
1.4 KiB
C#
|
|
using Godot;
|
||
|
|
|
||
|
|
namespace Theriapolis.GodotHost.Scenes.Widgets;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Drop target for ability assignment. Per GODOT_PORTING_GUIDE.md §7.2:
|
||
|
|
/// accepts any drag payload tagged "ability_value" and emits
|
||
|
|
/// <see cref="Dropped"/> with the payload so the step orchestrates the
|
||
|
|
/// state change centrally. Visual content (the AbilityToken when filled,
|
||
|
|
/// or a placeholder dash when empty) is set by the step on every refresh.
|
||
|
|
///
|
||
|
|
/// Each slot owns exactly one ability id (STR/DEX/CON/INT/WIS/CHA). On
|
||
|
|
/// click of a filled slot, returns the value to the pool (synthesised
|
||
|
|
/// slot→pool payload) — matches the React prototype's "click to unbind"
|
||
|
|
/// affordance from <c>steps.jsx</c>.
|
||
|
|
/// </summary>
|
||
|
|
public partial class AbilitySlot : PanelContainer
|
||
|
|
{
|
||
|
|
[Signal] public delegate void DroppedEventHandler(Godot.Collections.Dictionary payload);
|
||
|
|
|
||
|
|
[Export] public string Ability { get; set; } = "STR";
|
||
|
|
|
||
|
|
public override void _Ready()
|
||
|
|
{
|
||
|
|
CustomMinimumSize = new Vector2(56, 56);
|
||
|
|
MouseFilter = MouseFilterEnum.Stop;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override bool _CanDropData(Vector2 atPosition, Variant data)
|
||
|
|
{
|
||
|
|
if (data.VariantType != Variant.Type.Dictionary) return false;
|
||
|
|
var d = data.AsGodotDictionary();
|
||
|
|
return d.ContainsKey("kind") && d["kind"].AsString() == "ability_value";
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void _DropData(Vector2 atPosition, Variant data)
|
||
|
|
{
|
||
|
|
EmitSignal(SignalName.Dropped, data);
|
||
|
|
}
|
||
|
|
}
|