using Godot; using SupaLidlGame.Extensions; namespace SupaLidlGame.Entities; public partial class DynamicDoor : StaticBody2D { [Export] public string MapStateKey { get; set; } [Export] public Godot.Collections.Array VisibleOnToggle { get; set; } [Export] public Godot.Collections.Array Rebake { get; set; } [Export] public bool DefaultState { get; set; } private AnimationPlayer _animPlayer; public override void _Ready() { _animPlayer = GetNode("AnimationPlayer"); var globalState = this.GetGlobalState(); globalState.MapState.MapStateBoolChanged += OnMapStateChanged; SetAnimations(false); RefreshMapState((bool)globalState.MapState[MapStateKey]); } public virtual void OnMapStateChanged(string key, bool value) { GD.Print("Map state changed"); if (key == MapStateKey) { SetAnimations(true); RefreshMapState(value); } } private async void RefreshMapState(bool value) { if (value) { Open(); } else { Close(); } await ToSignal(_animPlayer, AnimationPlayer.SignalName.AnimationFinished); if (Rebake is not null) { foreach (var navmesh in Rebake) { // rebake navmesh so NPCs can correctly travel conditionally GD.Print("Dynamic door updated; rebaking navmeshes..."); if (!navmesh.IsBaking()) { navmesh.BakeNavigationPolygon(); } } } } public virtual void Open() { _animPlayer?.TryPlay("open"); //this.GetWorld().CurrentPlayer.Camera.Shake(1, 0.5f); } public virtual void Close() { _animPlayer?.TryPlay("close"); //this.GetWorld().CurrentPlayer.Camera.Shake(2, 0.25f); } public void SetAnimations(bool isEnabled) { if (VisibleOnToggle is null) { GD.PushWarning($"DynamicDoor {GetPath()} has no VisibleOnToggle " + "array. Set this to empty array to disable this warning."); return; } foreach (var animKey in _animPlayer.GetAnimationList()) { var anim = _animPlayer.GetAnimation(animKey); for (int i = 0; i < anim.GetTrackCount(); i++) { foreach (var nodePath in VisibleOnToggle) { if (anim.TrackGetPath(i) == nodePath) { anim.TrackSetEnabled(i, isEnabled); } } } } } }