cirnogodot/3D/TrenchBroom/EntityScripts/Solid/FuncMove.cs
2025-06-28 13:59:12 +02:00

157 lines
No EOL
3.8 KiB
C#

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<Vector3> 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<string, Variant> 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);
}
}
}