P3 alpha: wolf moon every 7th night, the alpha breaks wooden doors, iron-banded door, broken-door repair, alpha pelt and cloak (protocol 7)
This commit is contained in:
@@ -1,17 +1,28 @@
|
||||
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.
|
||||
## 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.
|
||||
##
|
||||
## An alpha wolf can break a closed wooden door (bash()): after DOOR_HP worth
|
||||
## of blows the panel gives way and hangs open, and the door shows as broken
|
||||
## until you repair it (E, two wood). An iron-banded door (items.json
|
||||
## place.sturdy) can't be broken. The frame stays either way, so whatever it
|
||||
## holds up keeps standing.
|
||||
|
||||
const OPEN_ANGLE := 1.75 ## radians: swings toward -Z, away from where you stood to place it
|
||||
const DOOR_HP := 100.0
|
||||
const REPAIR_COST := {"wood": 2}
|
||||
|
||||
var open := false
|
||||
var broken := false
|
||||
var door_hp := DOOR_HP
|
||||
var _hinge: Node3D
|
||||
var _panel: AnimatableBody3D
|
||||
var _panel_shape: CollisionShape3D
|
||||
var _tween: Tween
|
||||
|
||||
func _visual_mesh() -> Mesh:
|
||||
return ItemDB.mesh_for(String(def.get("mesh", item_id)) + "_frame") # (wood_door_frame, stone_door_frame)
|
||||
return ItemDB.mesh_for(String(def.get("mesh", item_id)) + "_frame") # (wood_door_frame, stone_doorway_frame...)
|
||||
|
||||
func _build() -> void:
|
||||
_hinge = Node3D.new()
|
||||
@@ -27,23 +38,38 @@ func _build() -> void:
|
||||
_panel.set_meta("owner_piece", self)
|
||||
_hinge.add_child(_panel)
|
||||
var mi := MeshInstance3D.new()
|
||||
mi.mesh = ItemDB.mesh_for("wood_door_panel")
|
||||
mi.mesh = ItemDB.mesh_for(String(def.place.get("panel", "wood_door_panel")))
|
||||
mi.material_override = ItemDB.item_material()
|
||||
_panel.add_child(mi)
|
||||
var cs := CollisionShape3D.new()
|
||||
_panel_shape = 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)
|
||||
_panel_shape.shape = box
|
||||
_panel_shape.position = Vector3(0.54, 0.95, 0.0)
|
||||
_panel.add_child(_panel_shape)
|
||||
|
||||
## Iron-banded: nothing breaks it.
|
||||
func sturdy() -> bool:
|
||||
return bool(def.place.get("sturdy", false))
|
||||
|
||||
## Shut and in one piece (something trying to get in has to get past it).
|
||||
func blocks() -> bool:
|
||||
return not open and not broken
|
||||
|
||||
func interact_prompt(_player: Node) -> String:
|
||||
if broken:
|
||||
return "Broken door [E] Repair (2 wood)"
|
||||
return "Door [E] %s" % ("Close" if open else "Open")
|
||||
|
||||
func interact(player: Node) -> void:
|
||||
Actions.toggle_door(player, self)
|
||||
if broken:
|
||||
Actions.repair_door(player, self)
|
||||
else:
|
||||
Actions.toggle_door(player, self)
|
||||
|
||||
func set_open(on: bool, animate: bool = true) -> void:
|
||||
if broken:
|
||||
on = true # (it hangs open off one hinge)
|
||||
open = on
|
||||
var target := OPEN_ANGLE if on else 0.0
|
||||
if _tween != null:
|
||||
@@ -54,8 +80,46 @@ func set_open(on: bool, animate: bool = true) -> void:
|
||||
else:
|
||||
_hinge.rotation.y = target
|
||||
|
||||
## A blow from something trying to get in. Returns "hit", "held" (iron
|
||||
## bands), "broke" (this blow broke it) or "" (open or already broken).
|
||||
func bash(damage: float) -> String:
|
||||
if not blocks():
|
||||
return ""
|
||||
if sturdy():
|
||||
return "held"
|
||||
door_hp -= damage
|
||||
if door_hp > 0.0:
|
||||
return "hit"
|
||||
set_broken(true)
|
||||
return "broke"
|
||||
|
||||
## Broken: the panel hangs open, askew, and stops anything. Repaired: shut
|
||||
## and whole again.
|
||||
func set_broken(on: bool) -> void:
|
||||
broken = on
|
||||
if on:
|
||||
door_hp = 0.0
|
||||
set_open(true, false)
|
||||
_hinge.rotation = Vector3(0.0, OPEN_ANGLE + 0.35, 0.18)
|
||||
_panel_shape.disabled = true
|
||||
else:
|
||||
door_hp = DOOR_HP
|
||||
_hinge.rotation = Vector3.ZERO
|
||||
_panel_shape.disabled = false
|
||||
set_open(false, false)
|
||||
|
||||
func save_extra() -> Dictionary:
|
||||
return {"open": open}
|
||||
return {"open": open, "broken": broken}
|
||||
|
||||
func load_extra(d: Dictionary) -> void:
|
||||
set_open(bool(d.get("open", false)), false)
|
||||
set_broken(bool(d.get("broken", false)))
|
||||
if not broken:
|
||||
set_open(bool(d.get("open", false)), false)
|
||||
|
||||
## A server telling us this door's state: swing it if it only opened or
|
||||
## closed, snap it if it broke or was mended.
|
||||
func net_state(d: Dictionary) -> void:
|
||||
if bool(d.get("broken", false)) != broken:
|
||||
load_extra(d)
|
||||
elif not broken:
|
||||
set_open(bool(d.get("open", false)))
|
||||
|
||||
Reference in New Issue
Block a user