gmtk24/scripts/Table.cs

194 lines
6.4 KiB
C#
Raw Permalink Normal View History

2024-08-19 20:32:19 +02:00
using Godot;
2024-08-20 16:17:44 +02:00
using System;
2024-08-19 20:32:19 +02:00
using System.Linq;
namespace Gmtk24 {
2024-08-19 22:27:26 +02:00
public partial class Table : Interactible {
[Export]
public Hud Hud;
2024-08-19 20:32:19 +02:00
[Export(PropertyHint.NodeType, "FuncGodotMap")]
public Node3D TrenchbroomMap;
[ExportCategory("Spawn Options")]
2024-08-20 01:20:14 +02:00
[Export]
2024-08-19 20:32:19 +02:00
public float RelativeScale = 0.05f;
[Export]
2024-08-20 01:20:52 +02:00
public Node3D SpawnPoint;
[Export(PropertyHint.LayersAvoidance)]
public uint BlockMask;
2024-08-20 02:29:32 +02:00
[Export(PropertyHint.LayersAvoidance)]
public uint GhostOnlyMask = 0b100000;
[Export(PropertyHint.LayersAvoidance)]
public uint PlaneOnlyLayer = 0b1000000;
[ExportCategory("Block Materials")]
2024-08-20 01:20:52 +02:00
[Export]
2024-08-19 20:32:19 +02:00
public ShaderMaterial BlockMaterial;
[Export]
2024-08-19 23:33:24 +02:00
public ShaderMaterial BlockHoverMaterial;
[Export]
2024-08-20 01:20:52 +02:00
public ShaderMaterial BlockGhostMaterial;
2024-08-19 20:32:19 +02:00
[ExportCategory("Scene Items")]
2024-08-19 23:33:24 +02:00
[Export]
public Orbit Orbit;
[Export]
public StaticBody3D Plane;
2024-08-19 23:33:24 +02:00
2024-08-20 01:20:52 +02:00
public BuildingBlock GhostBlock;
private Vector3 GhostBlockNormal;
2024-08-20 01:20:52 +02:00
2024-08-20 16:17:44 +02:00
public bool IsEnabled { get => Visible == true; }
2024-08-19 20:32:19 +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
Orbit.Hud = Hud;
2024-08-19 20:32:19 +02:00
Vector3 SpawnPos = Vector3.Zero;
if (SpawnPoint != null)
SpawnPos = SpawnPoint.GlobalPosition - GlobalPosition;
SpawnBlocks(SpawnPos);
2024-08-20 01:20:52 +02:00
Orbit.BlockRelease += OnBlockRelease;
Orbit.DraggingHeldBlock += OnBlockDrag;
Plane.CollisionLayer = PlaneOnlyLayer;
Plane.CollisionMask = PlaneOnlyLayer;
DisablePlane();
2024-08-19 20:32:19 +02:00
}
public void SpawnBlocks(Vector3 position) {
var rng = new RandomNumberGenerator();
var children = TrenchbroomMap.FindChildren("*_buildingblock");
foreach (StaticBody3D buildingBlockStaticBody in children.Cast<StaticBody3D>()) {
var baseBlock = new BuildingBlock.BaseBlock(buildingBlockStaticBody);
var block = new BuildingBlock() {
Base = baseBlock,
Material = BlockMaterial,
2024-08-19 23:33:24 +02:00
HoverMaterial = BlockHoverMaterial,
2024-08-19 20:32:19 +02:00
Position = position + Vector3.One * (rng.Randf() * 0.5f - 0.25f) + Vector3.Up * rng.Randf(),
2024-08-20 00:50:55 +02:00
PhysicalModeLayer = BlockMask,
2024-08-19 20:32:19 +02:00
RelativeScale = RelativeScale,
};
AddChild(block);
2024-08-20 00:50:55 +02:00
block.PickUp += OnBlockPickup;
2024-08-19 20:32:19 +02:00
}
}
2024-08-19 22:27:26 +02:00
2024-08-19 23:33:24 +02:00
public void Interact(InputEvent _) {
Orbit.SetEnabled(true);
}
2024-08-20 01:20:52 +02:00
public override void _Process(double delta) {
GhostBlockNormal = Vector3.Up;
2024-08-20 01:20:52 +02:00
if (GhostBlock != null) {
var res = Util.RaycastFromMouse(Orbit.Camera, 0b10100 | PlaneOnlyLayer);
2024-08-20 01:20:52 +02:00
if (res is RaycastResult results) {
2024-08-20 02:29:32 +02:00
Vector3 LocalPos = results.Position - GlobalPosition;
2024-08-20 15:58:22 +02:00
GhostBlockNormal = results.Normal;
Vector3 offset = GhostBlock.OffsetFrom(results.Normal, GhostOnlyMask);
LocalPos += offset;
2024-08-20 02:29:32 +02:00
GhostBlock.Position = LocalPos * Basis;
2024-08-20 01:20:52 +02:00
}
2024-08-20 02:47:18 +02:00
if (Orbit.HeldBlock != null)
GhostBlock.Rotation = Orbit.HeldBlock.Rotation;
2024-08-20 01:20:52 +02:00
}
}
2024-08-20 00:50:55 +02:00
public void OnBlockPickup(BuildingBlock block) {
Orbit.HoldBlock(block);
2024-08-20 01:20:52 +02:00
Vector3 LocalPos = Vector3.Zero;
GhostBlock = new BuildingBlock() {
Base = block.Base,
Material = BlockGhostMaterial,
PhysicalModeLayer = 0,
2024-08-20 02:29:32 +02:00
NonPhysicalModeLayer = GhostOnlyMask,
2024-08-20 01:20:52 +02:00
RelativeScale = RelativeScale,
Position = LocalPos,
Mode = BuildingBlock.BlockMode.NonPhysical,
};
AddChild(GhostBlock);
2024-08-20 01:39:05 +02:00
Hud.InteractionPaused = true;
2024-08-20 01:20:52 +02:00
}
public void OnBlockRelease(BuildingBlock block, uint typeUint) {
2024-08-20 01:39:05 +02:00
Hud.InteractionPaused = false;
BlockReleaseType type = (BlockReleaseType)typeUint;
DisablePlane();
2024-08-20 01:39:05 +02:00
block.Reparent(this);
2024-08-20 01:20:52 +02:00
switch (type) {
case BlockReleaseType.Throw: {
block.SetMode(BuildingBlock.BlockMode.Physical);
var normal = Orbit.Camera.ProjectRayNormal(Orbit.Camera.GetViewport().GetMousePosition());
var direction = normal * 10;
var res = Util.RaycastFromMouse(Orbit.Camera, 0b1111);
if (res is RaycastResult results) {
direction = (results.Position - block.GlobalPosition + Vector3.Up * 0.5f) * 3;
}
block.ApplyImpulse(direction);
break;
}
case BlockReleaseType.Place: {
2024-08-20 01:39:05 +02:00
block.SetMode(BuildingBlock.BlockMode.Placed);
block.Transform = GhostBlock.Transform;
2024-08-20 01:20:52 +02:00
break;
}
default: break;
}
2024-08-20 01:39:05 +02:00
if (GhostBlock != null) {
GhostBlock.QueueFree();
GhostBlock = null;
}
2024-08-20 00:50:55 +02:00
}
private void OnBlockDrag(BuildingBlock _) {
var offset = GhostBlock.OffsetFrom(GhostBlockNormal);
EnablePlane(GhostBlock.Position - offset, new Quaternion(Vector3.Up, GhostBlockNormal));
}
private void EnablePlane(Vector3 pos, Quaternion rot) {
Plane.Visible = true;
Plane.ProcessMode = ProcessModeEnum.Pausable;
Plane.Position = pos;
Plane.Quaternion = rot;
}
private void DisablePlane() {
Plane.Visible = false;
Plane.ProcessMode = ProcessModeEnum.Disabled;
}
2024-08-20 16:17:44 +02:00
public void DisableTable() {
Visible = false;
ProcessMode = ProcessModeEnum.Disabled;
}
public void SpawnTable(Vector3 position, Vector3 lookAt) {
if (IsEnabled)
return;
Visible = true;
ProcessMode = ProcessModeEnum.Pausable;
Position = position;
lookAt.Y = 0;
LookAt(lookAt);
Rotate(Vector3.Up, (float)Math.PI / 2);
}
2024-08-19 20:32:19 +02:00
}
2024-08-19 23:33:24 +02:00
}