From 8e6f6498c9d871eb26e8a6370b98620e535a6071 Mon Sep 17 00:00:00 2001 From: hz Date: Sat, 8 Nov 2025 16:49:49 -0600 Subject: [PATCH] Giving character sleep requirements, when character gets tired it goes home and sleeps --- scenes/Grid/grid_character_controller.gd | 81 ++++++++++++++++++++++++ scenes/Grid/grid_field.tscn | 2 + 2 files changed, 83 insertions(+) diff --git a/scenes/Grid/grid_character_controller.gd b/scenes/Grid/grid_character_controller.gd index 1df0420..5def678 100644 --- a/scenes/Grid/grid_character_controller.gd +++ b/scenes/Grid/grid_character_controller.gd @@ -8,6 +8,8 @@ class_name GridCharacterController @export_range(0.1, 20.0, 0.1) var move_speed: float = 4.0 @export_range(0.0, 2.0, 0.01) var height_offset: float = 0.3 @export var home_marker_scene: PackedScene +@export_range(1.0, 16.0, 0.5) var sleep_requirement_hours: float = 8.0 +@export var day_night_controller_path: NodePath var _grid_manager: GridPlaneManager = null var _camera: Camera3D = null @@ -15,6 +17,13 @@ var _current_cell: Vector2i = Vector2i(-1, -1) var _target_position: Vector3 var _is_moving: bool = false var _home_instance: Node3D = null +var _day_night_controller: DayNightController = null +var _last_time_hours: float = 0.0 +var _awake_accum_hours: float = 0.0 +var _sleep_accum_hours: float = 0.0 +var _is_sleeping: bool = false +var _sleep_pending_return: bool = false +var _awake_duration_hours: float = 0.0 func _ready() -> void: set_physics_process(true) @@ -24,6 +33,13 @@ func _ready() -> void: _grid_manager.grid_layout_changed.connect(_on_grid_layout_changed) _move_to_cell(start_cell, true) _spawn_home() + _update_awake_duration() + if _day_night_controller: + _last_time_hours = _day_night_controller.get_time_of_day_hours() + else: + _last_time_hours = 0.0 + _is_sleeping = false + _sleep_pending_return = false func _physics_process(delta: float) -> void: if not _is_moving: @@ -33,6 +49,8 @@ func _physics_process(delta: float) -> void: if distance <= 0.01: global_position = _target_position _is_moving = false + if _sleep_pending_return and _current_cell == start_cell: + _enter_sleep_state() return var step: float = move_speed * delta var move_vector: Vector3 = direction.normalized() * min(step, distance) @@ -41,12 +59,16 @@ func _physics_process(delta: float) -> void: func _unhandled_input(event: InputEvent) -> void: if Engine.is_editor_hint(): return + if _is_sleeping or _sleep_pending_return: + return if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: _move_to_mouse_click() func _move_to_mouse_click() -> void: if not _grid_manager or not _camera: return + if _is_sleeping or _sleep_pending_return: + return var viewport: Viewport = get_viewport() if viewport == null: return @@ -66,6 +88,8 @@ func _move_to_cell(cell: Vector2i, instant: bool = false) -> void: if instant: global_position = _target_position _is_moving = false + if _sleep_pending_return and cell == start_cell: + _enter_sleep_state() else: _is_moving = true @@ -103,6 +127,11 @@ func _resolve_references() -> void: _camera = get_node_or_null(camera_path) as Camera3D if not _home_instance and home_marker_scene: _spawn_home() + if day_night_controller_path != NodePath(): + _day_night_controller = get_node_or_null(day_night_controller_path) as DayNightController + else: + _day_night_controller = get_node_or_null("../DirectionalLight3D") as DayNightController + _connect_day_night() func _spawn_home() -> void: if not home_marker_scene or not _grid_manager: @@ -135,3 +164,55 @@ func _update_home_position() -> void: var local_center := _grid_manager.cell_to_world(start_cell) var world_center := _grid_manager.to_global(local_center) _home_instance.global_position = world_center + Vector3.UP * 0.01 + +func _connect_day_night() -> void: + if _day_night_controller and not _day_night_controller.is_connected("time_changed", Callable(self, "_on_time_changed")): + _day_night_controller.time_changed.connect(_on_time_changed) + _update_awake_duration() + +func _update_awake_duration() -> void: + var total_hours := sleep_requirement_hours + 1.0 + if _day_night_controller: + total_hours = _day_night_controller.get_day_length_hours() + _awake_duration_hours = max(total_hours - sleep_requirement_hours, 0.1) + +func _on_time_changed(current_hours: float) -> void: + if _day_night_controller == null: + return + var delta := _compute_time_delta(current_hours) + _last_time_hours = current_hours + if _is_sleeping: + _sleep_accum_hours += delta + if _sleep_accum_hours >= sleep_requirement_hours: + _exit_sleep_state() + else: + if _sleep_pending_return: + return + _awake_accum_hours += delta + if _awake_accum_hours >= _awake_duration_hours: + _begin_sleep_cycle() + +func _compute_time_delta(current_hours: float) -> float: + var day_length := _day_night_controller.get_day_length_hours() if _day_night_controller else 24.0 + var delta := current_hours - _last_time_hours + if delta < 0.0: + delta += day_length + return delta + +func _begin_sleep_cycle() -> void: + if _sleep_pending_return or _is_sleeping: + return + _sleep_pending_return = true + _sleep_accum_hours = 0.0 + _move_to_cell(start_cell) + +func _enter_sleep_state() -> void: + _sleep_pending_return = false + _is_sleeping = true + _sleep_accum_hours = 0.0 + +func _exit_sleep_state() -> void: + _is_sleeping = false + _sleep_pending_return = false + _sleep_accum_hours = 0.0 + _awake_accum_hours = 0.0 diff --git a/scenes/Grid/grid_field.tscn b/scenes/Grid/grid_field.tscn index 534a952..dc268b8 100644 --- a/scenes/Grid/grid_field.tscn +++ b/scenes/Grid/grid_field.tscn @@ -113,8 +113,10 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0.3, -4.5) script = ExtResource("5_n4d0h") grid_manager_path = NodePath("..") camera_path = NodePath("../Camera3D") +start_cell = Vector2i(0, 0) move_speed = 5.0 home_marker_scene = ExtResource("7_1vmu7") +day_night_controller_path = NodePath("../DirectionalLight3D") [node name="Mesh" type="MeshInstance3D" parent="GridCharacter"] material_override = SubResource("StandardMaterial3D_character")