using System; using System.Collections.Generic; using System.ComponentModel; using Godot; using Godot.Bridge; using Godot.NativeInterop; [ScriptPath("res://Scripts/Puzzles/Sukoban.cs")] public partial class Sukoban : Node2D { [Signal] public delegate void OnCompletionEventHandler(); [Export(PropertyHint.None, "")] private Entity entity; [Export(PropertyHint.None, "")] private CratePush[] crates; [Export(PropertyHint.None, "")] private PuzzleButton[] buttons; [Export(PropertyHint.None, "")] private RichTextLabel help; [Export(PropertyHint.None, "")] private SaveFile.Flags flag; [Export(PropertyHint.None, "")] private StringName mapFlag = "None"; [Export(PropertyHint.None, "")] private CapacitorShot entityFrom; [Export(PropertyHint.None, "")] private bool noFlag; private Vector2 startCam; private Entity caller; public static Sukoban instance; public override void _Process(double delta) { if (entityFrom != null && !GodotObject.IsInstanceValid(entity) && GodotObject.IsInstanceValid(entityFrom.entity)) { entity = entityFrom.entity; } if (instance == null || Main.inEvent != null) { return; } RichTextLabel richTextLabel = help; if (richTextLabel != null && richTextLabel.Text.Length < 1) { help.Text = "[center][color=gray]" + Texts.common[54]; } if (Input.IsActionJustPressed(Main.keys[6])) { Audio.PlaySound(Audio.commonSounds[0]); Stop(); return; } PuzzleButton[] array = buttons; if (array == null || array.Length == 0) { return; } for (int i = 0; i < buttons.Length; i++) { if (!buttons[i].active) { return; } } Stop(panCamera: false); if (flag > SaveFile.Flags.IsInDW && !noFlag) { SaveFile.AddFlag(flag); } EmitSignal(SignalName.OnCompletion); } public void Stop(bool panCamera = true) { instance = null; if (help != null) { help.Text = ""; } Vector2 globalPosition = CameraController.instance.GlobalPosition; CameraController.instance.follow = null; Player.instance.lockMenu = false; if (caller == null) { caller = Player.instance; } if (panCamera) { Main.inEvent = Coroutine.Start(CameraController.PanToObj(globalPosition, caller, 100f, fixedRate: false)); } Player.AssumeControl(caller, playParticle: false, updateCamera: false); } private void Reset() { entity.GlobalPosition = entity.startPos; for (int i = 0; i < crates.Length; i++) { crates[i].GlobalPosition = crates[i].start; } } public void Start() { caller = Player.instance.controlling; if (SaveFile.HasFlag(flag) || Room.current.tempFlags.Contains(mapFlag)) { TextSystem.GetText("SukobanDone"); return; } Reset(); startCam = CameraController.instance.GlobalPosition; Party.StopMoving(); if (Player.instance.controlling == Player.instance) { Party.LookAt(Vector2.Up); } else { Player.instance.controlling.LookAt(Vector2.Up); } instance = this; Audio.PlaySound("snd_puzzle_start.wav"); CameraController.instance.follow = null; Player.instance.lockMenu = true; Main.inEvent = Coroutine.Start(CameraController.Pan(startCam, base.GlobalPosition, 100f, fixedRate: false)); Player.AssumeControl(entity, playParticle: false, updateCamera: false); } }