Files
Cinderwild/scripts/building/door.gd

62 lines
1.9 KiB
GDScript

extends "res://scripts/building/build_piece.gd"
## Wooden door: a wall-sized frame (snaps like a wall) with a hinged panel.
## E opens or closes it. The panel is an AnimatableBody3D so it pushes the
## player out of the way rather than trapping them.
const OPEN_ANGLE := 1.75 ## radians: swings toward -Z, away from where you stood to place it
var open := false
var _hinge: Node3D
var _panel: AnimatableBody3D
var _tween: Tween
func _visual_mesh() -> Mesh:
return ItemDB.mesh_for(String(def.get("mesh", item_id)) + "_frame") # (wood_door_frame, stone_door_frame)
func _build() -> void:
_hinge = Node3D.new()
_hinge.name = "Hinge"
_hinge.position = Vector3(-0.54, 0.0, 0.0)
add_child(_hinge)
_panel = AnimatableBody3D.new()
_panel.name = "Panel"
# Follow the hinge directly (sync_to_physics would only track the body's
# own motion, not its parent rotating).
_panel.sync_to_physics = false
_panel.collision_layer = 1 | BUILD_LAYER
_panel.set_meta("owner_piece", self)
_hinge.add_child(_panel)
var mi := MeshInstance3D.new()
mi.mesh = ItemDB.mesh_for("wood_door_panel")
mi.material_override = ItemDB.item_material()
_panel.add_child(mi)
var cs := CollisionShape3D.new()
var box := BoxShape3D.new()
box.size = Vector3(1.06, 1.86, 0.08)
cs.shape = box
cs.position = Vector3(0.54, 0.95, 0.0)
_panel.add_child(cs)
func interact_prompt(_player: Node) -> String:
return "Door [E] %s" % ("Close" if open else "Open")
func interact(player: Node) -> void:
Actions.toggle_door(player, self)
func set_open(on: bool, animate: bool = true) -> void:
open = on
var target := OPEN_ANGLE if on else 0.0
if _tween != null:
_tween.kill()
if animate and is_inside_tree():
_tween = create_tween()
_tween.tween_property(_hinge, "rotation:y", target, 0.45).set_trans(Tween.TRANS_SINE)
else:
_hinge.rotation.y = target
func save_extra() -> Dictionary:
return {"open": open}
func load_extra(d: Dictionary) -> void:
set_open(bool(d.get("open", false)), false)