gmtk24/scripts/Orbit.cs

171 lines
6.5 KiB
C#
Raw Permalink Normal View History

2024-08-19 23:33:24 +02:00
using Godot;
using System;
namespace Gmtk24 {
public partial class Orbit : Node3D {
2024-08-20 01:20:52 +02:00
[Signal]
public delegate void BlockReleaseEventHandler(BuildingBlock block, uint blockReleaseTypeUint);
[Signal]
public delegate void DraggingHeldBlockEventHandler(BuildingBlock block);
2024-08-20 01:20:52 +02:00
2024-08-20 15:58:22 +02:00
[ExportCategory("Camera")]
2024-08-19 23:33:24 +02:00
[Export(PropertyHint.Range, "0,10,0.1")]
public float MaxCameraDistance = 1f;
[Export(PropertyHint.Range, "0,10,0.1")]
public float MinCameraDistance = 0.1f;
2024-08-20 15:58:22 +02:00
[Export(PropertyHint.Range, "0,10,0.1")]
public float MinCameraHeight = 1.123f;
[Export(PropertyHint.Range, "0,10,0.1")]
public float MaxCameraHeight = 5f;
[Export(PropertyHint.Range, "0,10,0.1")]
public float CameraZoomTick = 0.1f;
2024-08-19 23:33:24 +02:00
[Export]
public Camera3D Camera;
2024-08-20 15:58:22 +02:00
[ExportCategory("Hand")]
2024-08-20 00:50:55 +02:00
[Export]
public Node3D Hand;
[Export]
public BuildingBlock HeldBlock { private set; get; }
2024-08-20 02:47:18 +02:00
[Export]
public float RotateAmt = (float)(Math.PI / 12);
[Export]
public float DragDistanceTreshold = 500f;
2024-08-19 23:33:24 +02:00
2024-08-20 15:58:22 +02:00
[ExportCategory("Debug")]
2024-08-19 23:33:24 +02:00
[Export]
public bool IsEnabled { private set; get; } = false;
2024-08-20 15:58:22 +02:00
public Hud Hud;
private float CurrentZoom = 1f;
private float CurrentHeight = 0;
2024-08-19 23:33:24 +02:00
private float CurrentYaw = 0;
private float CurrentPitch = 0;
2024-08-20 02:47:18 +02:00
private RandomNumberGenerator RNG = new RandomNumberGenerator();
private bool PlacingBlock = false;
private Vector2 PlacingMouse = Vector2.Zero;
private bool Dragging = false;
2024-08-19 23:33:24 +02:00
// Called when the node enters the scene tree for the first time.
public override void _Ready() {
2024-08-20 15:58:22 +02:00
CurrentPitch = -(float)Math.PI * 0.25f;
CurrentYaw = (float)Math.PI * 0.5f;
2024-08-19 23:33:24 +02:00
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta) {
2024-08-20 15:58:22 +02:00
if (Hud != null) {
var diff = MaxCameraHeight - MinCameraHeight;
CurrentHeight = (float)(Hud.CameraHeightSlider.Value / Hud.CameraHeightSlider.MaxValue * diff + MinCameraHeight);
}
Position = Vector3.Up * CurrentHeight;
Camera.Position = new Vector3(0, 0, CurrentZoom);
2024-08-19 23:33:24 +02:00
Quaternion = new Quaternion(Vector3.Up, CurrentYaw) * new Quaternion(Vector3.Right, CurrentPitch);
if (HeldBlock != null) {
2024-08-20 00:50:55 +02:00
HeldBlock.Position = HeldBlock.Position.Lerp(Vector3.Zero, 0.2f);
if (PlacingBlock) {
var distance = Camera.GetViewport().GetMousePosition().DistanceSquaredTo(PlacingMouse);
if (distance >= DragDistanceTreshold && !Dragging) {
Dragging = true;
EmitSignal(SignalName.DraggingHeldBlock, HeldBlock);
}
} else {
Dragging = false;
}
}
2024-08-19 23:33:24 +02:00
}
public void SetEnabled(bool enabled) {
IsEnabled = enabled;
Camera.Current = enabled;
if (IsEnabled)
Input.MouseMode = Input.MouseModeEnum.Visible;
else
Input.MouseMode = Input.MouseModeEnum.Captured;
2024-08-20 15:58:22 +02:00
Hud.CameraHeightContainer.Visible = enabled;
2024-08-19 23:33:24 +02:00
}
public override void _UnhandledInput(InputEvent @event) {
if (!IsEnabled)
return;
2024-08-20 16:49:13 +02:00
if (@event.IsAction("toggle_pause_menu") && HeldBlock == null) {
2024-08-20 14:28:35 +02:00
SetEnabled(false);
GetViewport().SetInputAsHandled();
}
2024-08-19 23:33:24 +02:00
if (@event.IsActionPressed("drag_orbit"))
Input.MouseMode = Input.MouseModeEnum.Captured;
if (@event.IsActionReleased("drag_orbit"))
Input.MouseMode = Input.MouseModeEnum.Visible;
if (Input.IsActionPressed("drag_orbit") && @event is InputEventMouseMotion mouseMotion) {
var cameraSensitivity = UserSettings.Singleton.GetCameraSpeedMultipliers();
var mouseMultiplier = 0.0003f;
CurrentYaw -= mouseMotion.ScreenRelative.X * mouseMultiplier * cameraSensitivity.X;
CurrentPitch -= mouseMotion.ScreenRelative.Y * mouseMultiplier * cameraSensitivity.Y;
CurrentPitch = Mathf.Clamp(CurrentPitch, -Mathf.Pi * 0.49f, 0);
}
2024-08-20 00:50:55 +02:00
if (HeldBlock != null) {
if (@event.IsActionPressed("release_block")) {
2024-08-20 01:20:52 +02:00
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Throw);
HeldBlock = null;
2024-08-20 00:50:55 +02:00
}
if (@event.IsAction("place_block")) {
if (@event.IsPressed()) {
PlacingBlock = true;
PlacingMouse = Camera.GetViewport().GetMousePosition();
} else if (PlacingBlock) {
EmitSignal(SignalName.BlockRelease, HeldBlock, (uint)BlockReleaseType.Place);
HeldBlock = null;
}
}
2024-08-20 02:47:18 +02:00
2024-08-20 14:28:35 +02:00
if (@event.IsActionPressed("rotate_block_right")) {
HeldBlock.RotateY(RotateAmt);
}
if (@event.IsActionPressed("rotate_block_left")) {
HeldBlock.RotateY(-RotateAmt);
}
2024-08-20 15:58:22 +02:00
} else {
if (@event.IsActionPressed("zoom_orbit_out")) {
CurrentZoom = Math.Clamp(CurrentZoom - CameraZoomTick, MinCameraDistance, MaxCameraDistance);
}
if (@event.IsActionPressed("zoom_orbit_in")) {
CurrentZoom = Math.Clamp(CurrentZoom + CameraZoomTick, MinCameraDistance, MaxCameraDistance);
}
2024-08-20 02:47:18 +02:00
}
2024-08-20 00:50:55 +02:00
}
public bool HoldBlock(BuildingBlock block) {
if (HeldBlock != null)
return false; // TODO
PlacingBlock = false;
2024-08-20 00:50:55 +02:00
HeldBlock = block;
2024-08-20 02:47:18 +02:00
bool wasPlaced = HeldBlock.Mode == BuildingBlock.BlockMode.Placed;
var oldLocalRot = HeldBlock.Quaternion;
2024-08-20 00:50:55 +02:00
HeldBlock.SetMode(BuildingBlock.BlockMode.NonPhysical);
HeldBlock.Reparent(Hand, true);
2024-08-20 02:47:18 +02:00
if (!wasPlaced)
HeldBlock.Quaternion = new Quaternion(Vector3.Up, RotateAmt * RNG.RandiRange(0, 100));
else
HeldBlock.Quaternion = oldLocalRot;
2024-08-20 00:50:55 +02:00
return true;
2024-08-19 23:33:24 +02:00
}
}
2024-08-20 01:20:52 +02:00
public enum BlockReleaseType {
Throw = 0,
Place = 1,
}
2024-08-19 23:33:24 +02:00
}