Aetheria/Assets/Scripts/Gameplay/ActionBarSlot.cs
soul bc05417450 Command seam fixes: the player's switches, ping and stance flips are PilotCommand presses; triggers, switches and ping are internal
ActivatedBehavior replaces IActivatedBehavior so Activate/Deactivate can be internal under Unity's C# 9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:33:20 +02:00

210 lines
No EOL
6.6 KiB
C#

using System;
using MessagePack;
using Newtonsoft.Json;
using TMPro;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.UI;
public class ActionBarSlot : MonoBehaviour
{
public TextMeshProUGUI Label;
public RawImage Icon;
public TextMeshProUGUI InputLabel;
public Image InputIcon;
public TextMeshProUGUI QuantityRemaining;
public Image Fill;
public ObservablePointerEnterTrigger PointerEnterTrigger;
public ObservablePointerExitTrigger PointerExitTrigger;
private ActionBarBinding binding;
public ActionBarBinding Binding
{
get => binding;
set
{
binding = value;
if (binding == null)
{
Fill.fillAmount = 0;
Label.gameObject.SetActive(false);
QuantityRemaining.gameObject.SetActive(false);
Icon.gameObject.SetActive(false);
}
}
}
private void Update()
{
Binding?.Update();
}
public SavedActionBarBinding Save()
{
return Binding switch
{
ActionBarConsumableBinding actionBarConsumableBinding => new SavedActionBarConsumableBinding
{
Target = actionBarConsumableBinding.Entity.ItemManager.ItemData.RefOf(actionBarConsumableBinding.Target)
},
ActionBarGearBinding actionBarGearBinding => new SavedActionBarGearBinding
{
EquipmentIndex = actionBarGearBinding.Entity.Equipment.IndexOf(actionBarGearBinding.Item),
BehaviorIndex = Array.IndexOf(actionBarGearBinding.Item.Behaviors, actionBarGearBinding.Behavior)
},
ActionBarWeaponGroupBinding actionBarWeaponGroupBinding => new SavedActionBarWeaponGroupBinding
{
Group = actionBarWeaponGroupBinding.Group
},
_ => null
};
}
public void Restore(SavedActionBarBinding binding, Entity entity)
{
Binding = binding switch
{
SavedActionBarConsumableBinding savedActionBarConsumableBinding =>
new ActionBarConsumableBinding(
entity,
this,
entity.ItemManager.ItemData.Get(savedActionBarConsumableBinding.Target)),
SavedActionBarGearBinding savedActionBarGearBinding =>
new ActionBarGearBinding(
entity,
this,
entity.Equipment[savedActionBarGearBinding.EquipmentIndex],
entity.Equipment[savedActionBarGearBinding.EquipmentIndex]
.Behaviors[savedActionBarGearBinding.BehaviorIndex] as ActivatedBehavior),
SavedActionBarWeaponGroupBinding savedActionBarWeaponGroupBinding =>
new ActionBarWeaponGroupBinding(entity, this, savedActionBarWeaponGroupBinding.Group),
_ => null
};
}
}
public abstract class ActionBarBinding
{
public Entity Entity { get; }
protected ActionBarSlot Slot { get; }
public abstract void Activate();
public abstract void Deactivate();
public abstract void Update();
public ActionBarBinding(Entity entity, ActionBarSlot slot)
{
Entity = entity;
Slot = slot;
}
}
public class ActionBarConsumableBinding : ActionBarBinding
{
public ConsumableItemData Target;
public ActionBarConsumableBinding(Entity entity, ActionBarSlot slot, ConsumableItemData target) : base(entity, slot)
{
Target = target;
Slot.QuantityRemaining.gameObject.SetActive(true);
var data = Target;
if(!string.IsNullOrEmpty(data.Icon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.texture = EngineAssets.Load<Texture2D>(data.Icon);
}
else Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
Entity.Command.Use(Target);
}
public override void Deactivate()
{
}
public override void Update()
{
Slot.QuantityRemaining.text = $"{Entity.CountItemsInCargo(Entity.ItemManager.ItemData.RefOf<ItemData>(Target).Key)}";
var instance = Entity.FindActiveConsumable(Target);
if (instance == null) Slot.Fill.fillAmount = 0;
else Slot.Fill.fillAmount = instance.RemainingDuration / instance.Data.Duration;
}
}
public class ActionBarGearBinding : ActionBarBinding
{
public EquippedItem Item { get; }
public ActivatedBehavior Behavior { get; }
public bool Active;
public ActionBarGearBinding(Entity entity, ActionBarSlot slot, EquippedItem item, ActivatedBehavior behavior) : base(entity, slot)
{
Item = item;
var data = Entity.ItemManager.GetData(item.EquippableItem);
Behavior = behavior;
Slot.QuantityRemaining.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Label.gameObject.SetActive(false);
if (!string.IsNullOrEmpty(Item.Data.ActionBarIcon))
Slot.Icon.texture = EngineAssets.Load<Texture2D>(Item.Data.ActionBarIcon);
else if (data is WeaponItemData weaponItemData)
Slot.Icon.texture = ActionGameManager.Instance.Settings.GetIcon(weaponItemData.WeaponType).texture;
else Slot.Icon.texture = ActionGameManager.Instance.Settings.GetIcon(data.HardpointType).texture;
}
// The press and the let-go are each one trigger edge, applied at the next step; Active is the slot's display.
public override void Activate()
{
Active = true;
Entity.Command.Pull(Behavior);
}
public override void Deactivate()
{
Active = false;
Entity.Command.Release(Behavior);
}
public override void Update()
{
Slot.Fill.fillAmount = Active ? 1 : 0;
}
}
[MessagePackObject]
public class ActionBarWeaponGroupBinding : ActionBarBinding
{
[Key(0)] public int Group;
public ActionBarWeaponGroupBinding(Entity entity, ActionBarSlot slot, int group) : base(entity, slot)
{
Group = group;
slot.Label.gameObject.SetActive(true);
slot.Label.text = $"G{Group+1}";
Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
foreach (var weapon in Entity.WeaponGroups[Group].weapons)
{
Entity.Command.Pull(weapon);
}
}
public override void Deactivate()
{
foreach (var weapon in Entity.WeaponGroups[Group].weapons)
{
Entity.Command.Release(weapon);
}
}
public override void Update()
{
}
}