gmtk24/scripts/BuildingBlock.cs

146 lines
4.9 KiB
C#
Raw Permalink Normal View History

2024-08-19 20:32:19 +02:00
using Godot;
using Godot.Collections;
namespace Gmtk24 {
2024-08-19 23:33:24 +02:00
public partial class BuildingBlock : Interactible {
2024-08-20 00:50:55 +02:00
[Signal]
public delegate void PickUpEventHandler(BuildingBlock block);
2024-08-19 20:32:19 +02:00
public BaseBlock Base;
public ShaderMaterial Material;
2024-08-19 23:33:24 +02:00
public ShaderMaterial HoverMaterial;
2024-08-19 20:32:19 +02:00
public float RelativeScale;
2024-08-20 00:50:55 +02:00
public uint PhysicalModeLayer;
public BlockMode Mode { private set; get; } = BlockMode.Physical;
2024-08-19 20:32:19 +02:00
2024-08-19 23:33:24 +02:00
private MeshInstance3D MeshInstance;
private ShaderMaterial[] NormalMaterialArr;
private ShaderMaterial[] HoverMaterialArr;
2024-08-19 20:32:19 +02:00
public BuildingBlock() {
Name = "BuildingBlock";
2024-08-20 00:50:55 +02:00
FreezeMode = FreezeModeEnum.Kinematic;
CanSleep = false;
2024-08-19 20:32:19 +02:00
}
public override void _Ready() {
base._Ready();
2024-08-20 00:50:55 +02:00
UpdatePhysics();
2024-08-19 23:33:24 +02:00
HoverMaterial ??= Material;
Hovered += OnHover;
2024-08-20 00:50:55 +02:00
Interacted += OnInteract;
2024-08-19 23:33:24 +02:00
MeshInstance = new MeshInstance3D() {
2024-08-19 20:32:19 +02:00
Mesh = Base.Mesh,
Scale = Vector3.One * RelativeScale,
};
2024-08-19 23:33:24 +02:00
AddChild(MeshInstance);
int count = MeshInstance.GetSurfaceOverrideMaterialCount();
NormalMaterialArr = new ShaderMaterial[count];
HoverMaterialArr = new ShaderMaterial[count];
2024-08-19 20:32:19 +02:00
2024-08-19 23:33:24 +02:00
for (int i = 0; i < MeshInstance.GetSurfaceOverrideMaterialCount(); i++) {
var replacedMaterial = MeshInstance.Mesh.SurfaceGetMaterial(i);
2024-08-19 20:32:19 +02:00
var transparency = replacedMaterial.Get("transparency");
if (((int)transparency) != 0) {
ShaderMaterial newMat = (ShaderMaterial)Material.Duplicate();
newMat.SetShaderParameter("texture_albedo_for_alpha", replacedMaterial.Get("albedo_texture"));
2024-08-19 23:33:24 +02:00
ShaderMaterial newHoverMat = (ShaderMaterial)HoverMaterial.Duplicate();
newHoverMat.SetShaderParameter("texture_albedo_for_alpha", replacedMaterial.Get("albedo_texture"));
NormalMaterialArr[i] = newMat;
HoverMaterialArr[i] = newHoverMat;
2024-08-19 20:32:19 +02:00
} else {
2024-08-19 23:33:24 +02:00
NormalMaterialArr[i] = Material;
2024-08-20 01:20:14 +02:00
HoverMaterialArr[i] = HoverMaterial;
2024-08-19 20:32:19 +02:00
}
2024-08-19 23:33:24 +02:00
MeshInstance.SetSurfaceOverrideMaterial(i, NormalMaterialArr[i]);
2024-08-19 20:32:19 +02:00
}
foreach (var shape in Base.Colliders) {
var bigPoints = ((ConvexPolygonShape3D)shape.Shape).Points;
var points = new Vector3[bigPoints.Length];
for (int i = 0; i < bigPoints.Length; i++) {
points[i] = bigPoints[i] * RelativeScale;
}
AddChild(new CollisionShape3D {
Shape = new ConvexPolygonShape3D {
Points = points,
},
});
}
}
2024-08-20 00:50:55 +02:00
public void SetMode(BlockMode mode) {
GD.Print(mode);
Mode = mode;
SetMaterial(false);
UpdatePhysics();
}
private void UpdatePhysics() {
if (Mode != BlockMode.NonPhysical) {
CollisionLayer = PhysicalModeLayer;
CollisionMask = PhysicalModeLayer;
if (Mode == BlockMode.Dragged) {
FreezeMode = FreezeModeEnum.Kinematic;
Freeze = true;
} else {
Freeze = false;
}
} else {
CollisionLayer = 0;
CollisionMask = 0;
FreezeMode = FreezeModeEnum.Static;
Freeze = true;
}
}
2024-08-19 23:33:24 +02:00
public void OnHover(bool hovered) {
2024-08-20 00:50:55 +02:00
if (Mode != BlockMode.NonPhysical) {
SetMaterial(hovered);
}
}
private void SetMaterial(bool hoverMaterial) {
2024-08-19 23:33:24 +02:00
for (int i = 0; i < MeshInstance.GetSurfaceOverrideMaterialCount(); i++) {
2024-08-20 00:50:55 +02:00
if (hoverMaterial)
2024-08-19 23:33:24 +02:00
MeshInstance.SetSurfaceOverrideMaterial(i, HoverMaterialArr[i]);
else
MeshInstance.SetSurfaceOverrideMaterial(i, NormalMaterialArr[i]);
}
}
2024-08-20 00:50:55 +02:00
public void OnInteract(InputEvent _) {
EmitSignal(SignalName.PickUp, this);
}
2024-08-19 20:32:19 +02:00
public struct BaseBlock {
public Mesh Mesh;
public Array<CollisionShape3D> Colliders;
public BaseBlock(StaticBody3D reference) {
Mesh = ((MeshInstance3D)reference.FindChild("*_mesh_instance")).Mesh;
Colliders = new Array<CollisionShape3D>();
foreach (var shape in reference.FindChildren("*_collision_shape")) {
Colliders.Add((CollisionShape3D)shape);
}
}
}
2024-08-20 00:50:55 +02:00
public enum BlockMode {
Physical,
Dragged,
NonPhysical,
}
2024-08-19 20:32:19 +02:00
}
}