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
|
|
|
}
|
|
|
|
}
|