TinyAdventure/systems/BuildSystem.gd

96 lines
3.1 KiB
GDScript

class_name BuildSystem
extends Node
const CAMERA_SPEED = 4.0
@onready var build_preview = %BuildPreview
@onready var player = %Player
@onready var built_structures = %BuiltStructures
@onready var camera:Camera3D = %Camera
@export var build_item:Item = null
var camera_velocity:Vector3 = Vector3.ZERO
var is_active:bool = false
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func update_build_preview_item() -> void:
for child in build_preview.get_children():
if build_item == null or child.scene_file_path != build_item.scene.resource_path:
child.get_parent().remove_child(child)
child.queue_free()
if build_preview.get_child_count() == 0 and build_item != null:
build_preview.add_child(build_item.scene.instantiate())
func move_build_camera(delta):
var input_dir = Input.get_vector("walk_left", "walk_right", "walk_forward", "walk_back")
var direction = (camera.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
camera_velocity.x = direction.x * CAMERA_SPEED
camera_velocity.z = direction.z * CAMERA_SPEED
else:
camera_velocity.x = move_toward(camera_velocity.x, 0, CAMERA_SPEED)
camera_velocity.z = move_toward(camera_velocity.z, 0, CAMERA_SPEED)
camera_velocity.y = 0
camera.global_position = camera.global_position + camera_velocity * delta
func update_build_preview():
var mouse_view_coords = get_viewport().get_mouse_position() # / get_viewport().get_visible_rect().size
var mouse_ray_origin = camera.project_ray_origin(mouse_view_coords)
var mouse_ray_normal = camera.project_ray_normal(mouse_view_coords)
var world_space_state = camera.get_world_3d().direct_space_state
var ray_query:PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(mouse_ray_origin, mouse_ray_origin + mouse_ray_normal * 100)
var ray_result:Dictionary = world_space_state.intersect_ray(ray_query)
if not ray_result.is_empty() and Vector3.UP.dot(ray_result["normal"]) > 0.9:
var build_location:Vector3 = ray_result["position"]
build_location = Vector3(roundf(build_location.x * 4), build_location.y, roundf(build_location.z * 4)) * 0.25
build_preview.global_position = build_location
func _physics_process(_delta):
if not is_active:
return
update_build_preview_item()
#move_build_camera(delta)
update_build_preview()
if build_item != null and Input.is_action_just_pressed("interaction"):
var new_structure:Node3D = build_item.scene.instantiate()
new_structure.transform = build_preview.transform
built_structures.add_child(new_structure)
get_viewport().set_input_as_handled()
return
func _unhandled_input(_event: InputEvent) -> void:
if Input.is_action_just_pressed("toggle_build_mode"):
is_active = not is_active
get_viewport().set_input_as_handled()
return
if not is_active:
build_preview.hide()
return
build_preview.show()
if Input.is_action_just_pressed("rotate_clockwise"):
build_preview.global_basis = build_preview.basis.rotated(Vector3.UP, deg_to_rad(45))
if Input.is_action_just_pressed("rotate_counter_clockwise"):
build_preview.global_basis = build_preview.basis.rotated(Vector3.UP, -deg_to_rad(45))