TowerGame/scripts/building_components/building.gd

113 lines
3.1 KiB
GDScript

extends Node3D
class_name Building
@export_category("Defence")
@export var max_hp: int = 100
@export_category("Stacking")
@export var can_stack: bool = true
@export var can_be_stacked_on: bool = true
@export var stack_position: Vector3 = Vector3(0,2,0)
@onready var build_position: Vector3 = global_position
@onready var nav_obstacle: NavObstable = $NavObstacle
@onready var consumer: Consumer = $Consumer
@onready var producer: Producer = $Producer
@onready var collision_shape: CollisionShape3D = $CollisionShape3D
signal functional_changed(functional: bool)
enum BuildState {
UNPLACED,
BUILDING,
READY,
DESTROYED
}
const PLACEMENT_POSITION_OK: int = 0b0001
const PLACEMENT_FOUNDATION_REQUIRED: int = 0b0010
const PLACEMENT_PART_ADDED: int = 0b0100
const PLACEMENT_COMPLETED: int = 0b1000
var hp: int = max_hp
var stacked_buildings: Array[Building] = []
var build_state: BuildState = BuildState.READY:
set(state):
build_state = state
functional_changed.emit(is_functional())
func _ready() -> void:
if nav_obstacle != null:
functional_changed.connect(func(enable:bool): nav_obstacle.enabled = enable)
if consumer != null:
functional_changed.connect(func(enable:bool): consumer.enabled = enable)
if producer != null:
functional_changed.connect(func(enable:bool): producer.enabled = enable)
if collision_shape != null:
functional_changed.connect(func(enable:bool): collision_shape.disabled = !enable)
func _process(delta: float) -> void:
if build_state == BuildState.UNPLACED:
global_position = global_position.lerp(build_position, 0.4)
var debug_text: String = ""
debug_text += "State: %s\n" % build_state
if consumer != null:
var consumer_state: String
if consumer.enabled:
consumer_state = "OK"
else:
consumer_state = "Off"
debug_text += "Input: %s \nStorage: %d\n" % [consumer_state, consumer.storage_total]
if producer != null:
var producer_state = "OK"
if !producer.enabled:
producer_state = "Off"
elif !producer.can_produce():
producer_state = "Blocked"
debug_text += "Output: %s\n" % producer_state
$Label3D.text = debug_text
func is_functional() -> bool:
return build_state == BuildState.READY
func _start_placement() -> void:
build_state = BuildState.UNPLACED
func _end_placement() -> void:
build_state = BuildState.READY
func _placement_select_building(building: Building, confirmed: bool) -> int:
while !building.stacked_buildings.is_empty():
building = building.stacked_buildings[0]
var stack_ok: bool = can_stack and building.can_be_stacked_on
var ret: int = 0
if stack_ok:
build_position = building.global_position + building.stack_position
ret |= PLACEMENT_POSITION_OK
if confirmed and stack_ok:
global_position = build_position
building.stacked_buildings.append(self)
ret |= PLACEMENT_COMPLETED
return ret
func _placement_select_position(pos: Vector3, confirmed: bool) -> int:
var ret: int = 0
ret |= PLACEMENT_POSITION_OK
build_position = Vector3(roundf(pos.x), ceilf(pos.y-0.01), roundf(pos.z))
if confirmed:
build_state = BuildState.BUILDING
ret |= PLACEMENT_COMPLETED
return ret