using System; using System.Linq; using Cirno.Scripts.Utils; using Godot; using Godot.Collections; namespace Cirno.Scripts.Interactables; [Tool] public partial class Switch3D : Interactable3D { [Export] public string TargetGroup { get; protected set; } [Export] public Node Target { get; set; } [Export] public Array Targets { get; private set; } = []; [Export] public ActivationType ActivationType { get; set; } = ActivationType.Toggle; [Signal] public delegate void OnActivatedEventHandler(ActivationType activationType, bool success); private AudioStreamPlayer _activationSound; private AudioStreamPlayer _denySound; private readonly string _activationSoundName = "ActivationSound"; private readonly string _denySoundName = "DenySound"; public override void _Ready() { if (Engine.IsEditorHint()) return; _activationSound = GetNodeOrNull(_activationSoundName); _denySound = GetNodeOrNull(_denySoundName); } public virtual void _func_godot_apply_properties(Dictionary props) { TargetGroup = props["target"].AsString(); if (props.TryGetValue("key", out var prop)) { RequirementKeys = [prop.AsString()]; } if (props.TryGetValue("activationtype", out var type)) { var t = Enum.TryParse(type.AsString(), true, out ActivationType activationType); if (t) { ActivationType = activationType; } } //TargetFunc = props["targetfunc"]; //TargetName = props["targetname"]; } public override bool Activate(ActivationType activationType = ActivationType.Toggle) { var activationTypeToUse = activationType is ActivationType.Use ? ActivationType : activationType; if (!MeetsRequirements()) { _denySound?.Play(); return false; } // Compatibility for old single system bool success = ActivateTarget(Target, activationTypeToUse); if (!string.IsNullOrWhiteSpace(TargetGroup)) { success |= ActivationHelper.UseTargets(this, TargetGroup, activationTypeToUse); } var result = Targets.Aggregate(success, (current, target) => current | ActivateTarget(target, activationTypeToUse)); if (result) { _activationSound?.Play(); } else { _denySound?.Play(); } EmitSignal(SignalName.OnActivated, (int)activationTypeToUse, result); return result; } private bool ActivateTarget(Node target, ActivationType activationType = ActivationType.Toggle) { if (target is not IActivable activable) return false; activable.Activate(activationType); return true; } // private void UseTargets(Node activator, string target) // { // GD.Print($"Trying to use targets called: {target}"); // var targetList = activator.GetTree().GetNodesInGroup(target); // foreach (var t in targetList) // { // //string f; // GD.Print($"Trying to use {t.Name}"); // if (t is IActivable activable) // { // GD.Print($"Activating {t.Name}"); // activable.Toggle(); // } // } // } }