using System; using Cirno.Scripts; using Cirno.Scripts.Utils; using Godot; using Godot.Collections; namespace Cirno._3D.TrenchBroom.EntityScripts.Solid; [Tool] public partial class FuncMove : AnimatableBody3D, IActivable { [Export] public string TargetName { get; private set; } [Export] public Array MovePos { get; set; } = [Vector3.Zero, Vector3.Zero]; [Export] public Vector3 MoveRot { get; set; } = Vector3.Zero; [Export] public float Speed { get; set; } = 3.0f; public enum MoveStates { READY, MOVE } private MoveStates _state = MoveStates.READY; private float _moveProgress = 0.0f; private float _moveProgressTarget = 0.0f; public void _func_godot_apply_properties(Dictionary props) { TargetName = props["targetname"].AsString(); MovePos[1] = QuakeTools.IdVecToGodotVec(props["move_pos"]) * QuakeTools.InverseScale; if (props["move_rot"].Obj is Vector3 rotVec) { MoveRot = new Vector3(Mathf.DegToRad(rotVec.X), Mathf.DegToRad(rotVec.Y), Mathf.DegToRad(rotVec.Z)); } Speed = props["speed"].AsSingle(); // if (props.TryGetValue("activationtype", out var type)) // { // var t = Enum.TryParse(type, true, out ActivationType activationType); // if (t) // { // ActivationType = activationType; // } // } // TODO: Oneshot } public void MoveForward() { _moveProgressTarget = 1.0f; } public void Use() { MoveForward(); } public void MoveReverse() { _moveProgressTarget = 0.0f; } public bool Activate(ActivationType activationType = ActivationType.Toggle) { switch (activationType) { case ActivationType.Toggle: case ActivationType.Use: Toggle(); break; case ActivationType.Enable: case ActivationType.Open: MoveForward(); break; case ActivationType.Disable: case ActivationType.Close: MoveReverse(); break; case ActivationType.Destroy: break; default: throw new ArgumentOutOfRangeException(nameof(activationType), activationType, null); } return true; } public void Toggle() { if (_moveProgressTarget > 0.0) { MoveReverse(); } else { MoveForward(); } } public FuncMove() { AddToGroup("func_move"); SyncToPhysics = false; } public override void _Ready() { if (Engine.IsEditorHint()) return; if (!string.IsNullOrWhiteSpace(TargetName)) { this.AddToGroup(TargetName); } MovePos[0] = Position; MovePos[1] += MovePos[0]; if (Speed > 0.0f) { Speed = 1.0f / Speed; } } public override void _PhysicsProcess(double delta) { if (Engine.IsEditorHint()) return; if (_moveProgress == _moveProgressTarget) { return; } if (_moveProgress < _moveProgressTarget) { _moveProgress = Mathf.Min(_moveProgress + (float)(Speed * delta), _moveProgressTarget); } else if (_moveProgress > _moveProgressTarget) { _moveProgress = Mathf.Max(_moveProgress - (float)(Speed * delta), _moveProgressTarget); } if (MovePos[0] != MovePos[1]) { Position = MovePos[0].Lerp(MovePos[1], _moveProgress); } if (MoveRot != Vector3.Zero) { Rotation = Vector3.Zero.Lerp(MoveRot, _moveProgress); } } }