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);
|
2024-08-20 15:16:57 +02:00
|
|
|
[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);
|
2024-08-20 15:16:57 +02:00
|
|
|
[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();
|
|
|
|
|
2024-08-20 15:16:57 +02:00
|
|
|
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);
|
2024-08-20 15:16:57 +02:00
|
|
|
if (HeldBlock != null) {
|
2024-08-20 00:50:55 +02:00
|
|
|
HeldBlock.Position = HeldBlock.Position.Lerp(Vector3.Zero, 0.2f);
|
2024-08-20 15:16:57 +02:00
|
|
|
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
|
|
|
|
2024-08-20 01:28:22 +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
|
|
|
}
|
2024-08-20 15:16:57 +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 01:28:22 +02:00
|
|
|
}
|
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
|
|
|
|
|
2024-08-20 15:16:57 +02:00
|
|
|
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
|
|
|
}
|