From a91bdf793b516700b61517b82b39830e5ee85171 Mon Sep 17 00:00:00 2001 From: hz Date: Sun, 9 Nov 2025 20:19:20 -0600 Subject: [PATCH] Adding hunger mechanic --- scenes/Grid/grid_character_controller.gd | 53 +++++++++++++++++++----- scenes/Grid/water_display.gd | 20 ++++++--- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/scenes/Grid/grid_character_controller.gd b/scenes/Grid/grid_character_controller.gd index f723ed3..d83f55b 100644 --- a/scenes/Grid/grid_character_controller.gd +++ b/scenes/Grid/grid_character_controller.gd @@ -15,6 +15,10 @@ class_name GridCharacterController @export_range(0.0, 200.0, 0.5) var movement_water_usage_ml_per_meter: float = 2.0 @export_range(50.0, 2000.0, 50.0) var low_water_threshold_ml: float = 400.0 @export_range(100.0, 2000.0, 25.0) var bladder_capacity_ml: float = 750.0 +@export_range(200.0, 6000.0, 50.0) var max_food_kcal: float = 2000.0 +@export_range(0.0, 5.0, 0.1) var passive_food_usage_kcal_per_minute: float = 1.5 +@export_range(0.0, 200.0, 0.5) var movement_food_usage_kcal_per_meter: float = 1.0 +@export_range(50.0, 1000.0, 25.0) var low_food_threshold_kcal: float = 300.0 @export var vitals_display_path: NodePath var _grid_manager: GridPlaneManager = null @@ -35,8 +39,10 @@ var _bladder_level_ml: float = 0.0 var _needs_water: bool = false var _needs_bathroom: bool = false var _returning_home_for_needs: bool = false +var _food_level_kcal: float = 0.0 +var _needs_food: bool = false -signal vitals_changed(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool) +signal vitals_changed(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool, food_level: float, needs_food: bool) func get_water_level() -> float: return _water_level_ml @@ -50,6 +56,12 @@ func is_water_low() -> bool: func is_bladder_full() -> bool: return _needs_bathroom +func get_food_level() -> float: + return _food_level_kcal + +func is_food_low() -> bool: + return _needs_food + func _ready() -> void: set_physics_process(true) set_process_unhandled_input(true) @@ -60,6 +72,7 @@ func _ready() -> void: _spawn_home() _water_level_ml = max_water_ml _bladder_level_ml = 0.0 + _food_level_kcal = max_food_kcal _update_awake_duration() if _day_night_controller: _last_time_hours = _day_night_controller.get_time_of_day_hours() @@ -67,7 +80,7 @@ func _ready() -> void: _last_time_hours = 0.0 _is_sleeping = false _sleep_pending_return = false - emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom) + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) func _physics_process(delta: float) -> void: if not _is_moving: @@ -82,7 +95,7 @@ func _physics_process(delta: float) -> void: var step: float = move_speed * delta var move_vector: Vector3 = direction.normalized() * min(step, distance) global_position += move_vector - emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom) + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) func _unhandled_input(event: InputEvent) -> void: if Engine.is_editor_hint(): @@ -197,7 +210,7 @@ func _update_home_position() -> void: _home_instance.global_position = world_center + Vector3.UP * 0.01 func _should_ignore_player_input() -> bool: - return _is_sleeping or _sleep_pending_return or _needs_water or _needs_bathroom + return _is_sleeping or _sleep_pending_return or _needs_water or _needs_bathroom or _needs_food func _handle_arrival_at_current_cell() -> void: if _current_cell == start_cell: @@ -211,6 +224,8 @@ func _on_arrived_home() -> void: if _needs_water: _fill_water() _needs_water = false + if _needs_food: + _eat_food() _returning_home_for_needs = false if _sleep_pending_return: _enter_sleep_state() @@ -283,14 +298,14 @@ func _apply_passive_water_usage(delta_hours: float) -> void: if delta_hours <= 0.0: return var minutes := delta_hours * 60.0 - var amount := minutes * passive_water_usage_ml_per_minute - _consume_water(amount) + _consume_water(minutes * passive_water_usage_ml_per_minute) + _consume_food(minutes * passive_food_usage_kcal_per_minute) func _apply_movement_water_usage(distance: float) -> void: if distance <= 0.0: return - var usage := movement_water_usage_ml_per_meter * distance - _consume_water(usage) + _consume_water(movement_water_usage_ml_per_meter * distance) + _consume_food(movement_food_usage_kcal_per_meter * distance) func _consume_water(amount: float) -> void: if amount <= 0.0: @@ -307,16 +322,32 @@ func _consume_water(amount: float) -> void: if not _returning_home_for_needs and not _sleep_pending_return: _returning_home_for_needs = true _request_home_return() - emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom) + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) + +func _consume_food(amount: float) -> void: + if amount <= 0.0: + return + _food_level_kcal = max(_food_level_kcal - amount, 0.0) + if _food_level_kcal <= low_food_threshold_kcal: + _needs_food = true + if not _returning_home_for_needs and not _sleep_pending_return: + _returning_home_for_needs = true + _request_home_return() + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) func _fill_water() -> void: _water_level_ml = max_water_ml - emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom) + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) func _empty_bladder() -> void: _bladder_level_ml = 0.0 _needs_bathroom = false - emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom) + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) + +func _eat_food() -> void: + _food_level_kcal = max_food_kcal + _needs_food = false + emit_signal("vitals_changed", _water_level_ml, _bladder_level_ml, _needs_water, _needs_bathroom, _food_level_kcal, _needs_food) func _request_home_return() -> void: if _is_sleeping: diff --git a/scenes/Grid/water_display.gd b/scenes/Grid/water_display.gd index 2961bf2..75723ce 100644 --- a/scenes/Grid/water_display.gd +++ b/scenes/Grid/water_display.gd @@ -4,6 +4,7 @@ class_name WaterDisplay @export var character_path: NodePath @export var show_bladder: bool = true +@export var show_food: bool = true @export var show_water: bool = true var _character: GridCharacterController = null @@ -13,11 +14,11 @@ func _ready() -> void: _resolve_character() if _character: _character.vitals_changed.connect(_on_vitals_changed) - _on_vitals_changed(_character.get_water_level(), _character.get_bladder_level(), _character.is_water_low(), _character.is_bladder_full()) + _on_vitals_changed(_character.get_water_level(), _character.get_bladder_level(), _character.is_water_low(), _character.is_bladder_full(), _character.get_food_level(), _character.is_food_low()) func _process(_delta: float) -> void: if Engine.is_editor_hint(): - _update_text(0.0, 0.0, false, false) + _update_text(0.0, 0.0, false, false, 0.0, false) func _resolve_character() -> void: if character_path != NodePath(): @@ -25,13 +26,20 @@ func _resolve_character() -> void: else: _character = get_parent() as GridCharacterController -func _on_vitals_changed(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool) -> void: - _update_text(water_level, bladder_level, needs_water, needs_bathroom) +func _on_vitals_changed(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool, food_level: float, needs_food: bool) -> void: + _update_text(water_level, bladder_level, needs_water, needs_bathroom, food_level, needs_food) -func _update_text(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool) -> void: +func _update_text(water_level: float, bladder_level: float, needs_water: bool, needs_bathroom: bool, food_level: float, needs_food: bool) -> void: var parts: Array[String] = [] if show_water: parts.append("Water: %4d ml%s" % [int(water_level), " !" if needs_water else ""]) if show_bladder: parts.append("Bladder: %4d ml%s" % [int(bladder_level), " !" if needs_bathroom else ""]) - text = " | ".join(parts) + if show_food: + parts.append("Food: %4d kcal%s" % [int(food_level), " !" if needs_food else ""]) + if show_food and parts.size() >= 3: + var first_line := " | ".join(parts.slice(0, 2)) + var second_line := " | ".join(parts.slice(2, parts.size())) + text = first_line + "\n" + second_line + else: + text = " | ".join(parts)