From cd01fd24a24703a3d79d48a4870ada237df07572 Mon Sep 17 00:00:00 2001 From: Yan Wittmann Date: Sun, 12 Jan 2025 15:04:17 +0100 Subject: [PATCH] Made UI more modular --- project/main-scenes/island.tscn | 101 +++++++++++++++--- project/scripts/global/EventsTracker.gd | 3 + project/scripts/global/GameManager.gd | 14 +-- project/scripts/player/PlayerManager.gd | 3 +- .../exploration/TaskPlannedExploration.gd | 7 +- .../TaskCheckFoodBaseThreshold.gd | 13 +++ project/scripts/tilemap/StepVisualization.gd | 28 ++--- project/scripts/tilemap/World.gd | 7 ++ .../scripts/tilemap/objects/CampManager.gd | 12 +++ 9 files changed, 149 insertions(+), 39 deletions(-) create mode 100644 project/scripts/player/tree/impl/game/base_survival/TaskCheckFoodBaseThreshold.gd diff --git a/project/main-scenes/island.tscn b/project/main-scenes/island.tscn index 3892ac5..3647335 100644 --- a/project/main-scenes/island.tscn +++ b/project/main-scenes/island.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=38 format=4 uid="uid://b88asko1ugyd2"] +[gd_scene load_steps=39 format=4 uid="uid://b88asko1ugyd2"] [ext_resource type="Script" path="res://scripts/global/GameManager.gd" id="1_eeg2d"] [ext_resource type="Script" path="res://scripts/tilemap/World.gd" id="1_k0rw8"] @@ -35,6 +35,7 @@ [ext_resource type="Script" path="res://scripts/player/tree/impl/game/boat/TaskGoToBoatLeaveLocation.gd" id="26_vy1mu"] [ext_resource type="Script" path="res://scripts/player/tree/impl/game/boat/TaskWinningSequence.gd" id="27_4etxm"] [ext_resource type="Script" path="res://scripts/player/tree/impl/game/inventory/TaskPickupBoat.gd" id="27_tmoaj"] +[ext_resource type="Script" path="res://scripts/player/tree/impl/game/base_survival/TaskCheckFoodBaseThreshold.gd" id="35_dnm3y"] [ext_resource type="Script" path="res://scripts/player/tree/impl/exploration/TaskPlannedExploration.gd" id="35_tfcwq"] [ext_resource type="Script" path="res://scripts/player/tree/impl/exploration/TaskRandomWalking.gd" id="36_0tfae"] @@ -58,11 +59,44 @@ grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 4 -[node name="VBoxContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer"] -offset_right = 40.0 -offset_bottom = 40.0 +[node name="TopLeftContainer" type="MarginContainer" parent="Camera2D/CanvasLayer"] +offset_right = 204.0 +offset_bottom = 122.0 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 -[node name="HealthBar" type="ProgressBar" parent="Camera2D/CanvasLayer/VBoxContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer"] +layout_mode = 2 + +[node name="StatsContainer" type="HBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer"] +layout_mode = 2 + +[node name="LabelsContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer"] +layout_mode = 2 + +[node name="Hp" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/LabelsContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 14 +text = "Health" + +[node name="Food" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/LabelsContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 14 +text = "Food" + +[node name="Temp" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/LabelsContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 14 +text = "Temp" + +[node name="BarContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer"] +layout_mode = 2 + +[node name="HealthBar" type="ProgressBar" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer"] +unique_name_in_owner = true self_modulate = Color(0.788235, 0.0901961, 0.00392157, 1) custom_minimum_size = Vector2(150, 20) layout_mode = 2 @@ -70,7 +104,8 @@ tooltip_text = " " show_percentage = false -[node name="HealthLabel" type="Label" parent="Camera2D/CanvasLayer/VBoxContainer/HealthBar"] +[node name="HealthLabel" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer/HealthBar"] +unique_name_in_owner = true layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -78,13 +113,16 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="FoodBar" type="ProgressBar" parent="Camera2D/CanvasLayer/VBoxContainer"] +[node name="FoodBar" type="ProgressBar" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer"] +unique_name_in_owner = true self_modulate = Color(0.168627, 0.552941, 0.152941, 1) custom_minimum_size = Vector2(0, 20) layout_mode = 2 +size_flags_horizontal = 3 show_percentage = false -[node name="FoodLabel" type="Label" parent="Camera2D/CanvasLayer/VBoxContainer/FoodBar"] +[node name="FoodLabel" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer/FoodBar"] +unique_name_in_owner = true layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -92,14 +130,17 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="TemperatureBar" type="ProgressBar" parent="Camera2D/CanvasLayer/VBoxContainer"] +[node name="TemperatureBar" type="ProgressBar" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer"] +unique_name_in_owner = true self_modulate = Color(0.0235294, 0.0392157, 1, 1) custom_minimum_size = Vector2(0, 20) layout_mode = 2 +size_flags_horizontal = 3 max_value = 50.0 show_percentage = false -[node name="TemperatureLabel" type="Label" parent="Camera2D/CanvasLayer/VBoxContainer/TemperatureBar"] +[node name="TemperatureLabel" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer/TemperatureBar"] +unique_name_in_owner = true layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -107,23 +148,23 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="Camera2D/CanvasLayer/VBoxContainer"] +[node name="InventoryDisplayContainer" type="HBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer"] layout_mode = 2 size_flags_horizontal = 0 size_flags_vertical = 4 -[node name="TemperatureLabel" type="Label" parent="Camera2D/CanvasLayer/VBoxContainer/HBoxContainer"] +[node name="HeightLabel" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/InventoryDisplayContainer"] layout_mode = 2 theme_override_font_sizes/font_size = 32 -[node name="InventoryContentRect" type="TextureRect" parent="Camera2D/CanvasLayer/VBoxContainer/HBoxContainer"] +[node name="InventoryContentRect" type="TextureRect" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/InventoryDisplayContainer"] unique_name_in_owner = true layout_mode = 2 texture = ExtResource("4_o8ona") expand_mode = 2 stretch_mode = 5 -[node name="MarginContainer" type="MarginContainer" parent="Camera2D/CanvasLayer"] +[node name="BottomLeftContainer" type="MarginContainer" parent="Camera2D/CanvasLayer"] anchors_preset = 12 anchor_top = 1.0 anchor_right = 1.0 @@ -134,7 +175,7 @@ grow_vertical = 0 theme_override_constants/margin_left = 5 theme_override_constants/margin_bottom = 5 -[node name="RecentEventsLog" type="VBoxContainer" parent="Camera2D/CanvasLayer/MarginContainer"] +[node name="RecentEventsLog" type="VBoxContainer" parent="Camera2D/CanvasLayer/BottomLeftContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 0 @@ -317,6 +358,36 @@ script = ExtResource("10_4v1m1") [node name="TaskPickupBoatPart" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_Boat/sq_PickUpBoatPart"] script = ExtResource("26_hx2yd") +[node name="sl_BaseSurvival" type="Node" parent="PlayerManager/BehaviorTree/sl_Root"] +script = ExtResource("7_1jajd") + +[node name="sq_Food" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival"] +script = ExtResource("9_i67mw") + +[node name="TaskCheckFoodBaseThreshold" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food"] +script = ExtResource("35_dnm3y") + +[node name="sl_PickMostRelevantFoodSource" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food"] +script = ExtResource("7_1jajd") + +[node name="sq_FoodInInventory" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource"] +script = ExtResource("9_i67mw") + +[node name="TaskEatFoodFromInventory" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_FoodInInventory"] +script = ExtResource("10_70s0w") + +[node name="sq_NextFood" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource"] +script = ExtResource("9_i67mw") + +[node name="TaskFindClosestFood" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_NextFood"] +script = ExtResource("13_60fwc") + +[node name="GoToWhileRunningSuccessStop" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_NextFood"] +script = ExtResource("10_4v1m1") + +[node name="TaskPickupTheBerry" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_NextFood"] +script = ExtResource("15_ccdxl") + [node name="sl_Exploration" type="Node" parent="PlayerManager/BehaviorTree/sl_Root"] script = ExtResource("7_1jajd") diff --git a/project/scripts/global/EventsTracker.gd b/project/scripts/global/EventsTracker.gd index 985e48f..959463a 100644 --- a/project/scripts/global/EventsTracker.gd +++ b/project/scripts/global/EventsTracker.gd @@ -18,6 +18,7 @@ enum Event { NEW_EXPLORATION_GOAL, EXPLORATION_GOAL_REACHED, TEMPERATURE_COLD, + TIME_SUNDOWN, }; # static var events: Array[TrackedEvent] = [] @@ -83,6 +84,8 @@ static func populate_visual_log_create_label(event: TrackedEvent, container: Con text = "Exploration goal reached " + str(params["goal"]) elif event_id == Event.TEMPERATURE_COLD: text = "Temperature is cold: -" + str(params["temperature"]) + elif event_id == Event.TIME_SUNDOWN: + text = "The sun is setting..." else: text = "Something happened..." diff --git a/project/scripts/global/GameManager.gd b/project/scripts/global/GameManager.gd index b1e9978..3bdcd8e 100644 --- a/project/scripts/global/GameManager.gd +++ b/project/scripts/global/GameManager.gd @@ -8,9 +8,9 @@ var tilemap_types: TileMapTileTypes = TileMapTileTypes.new() @onready var camera: CameraController = $Camera2D as CameraController @onready var game_ticker: Timer = $GameTick # -@onready var health_bar: ProgressBar = $Camera2D/CanvasLayer/VBoxContainer/HealthBar -@onready var food_bar: ProgressBar = $Camera2D/CanvasLayer/VBoxContainer/FoodBar -@onready var temperature_bar: ProgressBar = $Camera2D/CanvasLayer/VBoxContainer/TemperatureBar +@onready var health_bar: ProgressBar = %HealthBar +@onready var food_bar: ProgressBar = %FoodBar +@onready var temperature_bar: ProgressBar = %TemperatureBar @onready var temperature_layer: Node2D = $Tileset/TemperatureLayer var tilemap_navigation: TilemapNavigation = TilemapNavigation.new() @@ -82,18 +82,18 @@ func update_bars() -> void: if health_bar != null: health_bar.max_value = player.max_health health_bar.value = clamp(player.health, 0, player.max_health) - $Camera2D/CanvasLayer/VBoxContainer/HealthBar/HealthLabel.text = str(health_bar.value) + "/" + str(player.max_health) - $Camera2D/CanvasLayer/VBoxContainer/HealthBar/HealthLabel.add_theme_color_override("font_color", Color(1, 1, 1)) + %HealthLabel.text = str(health_bar.value) + "/" + str(player.max_health) + %HealthLabel.add_theme_color_override("font_color", Color(1, 1, 1)) if food_bar != null: food_bar.max_value = player.max_food food_bar.value = clamp(player.food, 0, player.max_food) - $Camera2D/CanvasLayer/VBoxContainer/FoodBar/FoodLabel.text = str(food_bar.value) + "/" + str(player.max_food) + %FoodLabel.text = str(food_bar.value) + "/" + str(player.max_food) if temperature_bar != null: temperature_bar.max_value = player.temperature_set_buff_value temperature_bar.value = clamp(player.temperature_buff_timer, 0, player.temperature_set_buff_value) - $Camera2D/CanvasLayer/VBoxContainer/TemperatureBar/TemperatureLabel.text = str(temperature_bar.value) + "/" + str(player.temperature_set_buff_value) + %TemperatureLabel.text = str(temperature_bar.value) + "/" + str(player.temperature_set_buff_value) func toggle_temperature_layer() -> void: diff --git a/project/scripts/player/PlayerManager.gd b/project/scripts/player/PlayerManager.gd index 748c2a7..ba5f9b5 100644 --- a/project/scripts/player/PlayerManager.gd +++ b/project/scripts/player/PlayerManager.gd @@ -6,6 +6,7 @@ extends Node @export var max_food: int = 250 @export var food_damage: int = 1 @export var food_critical_threshold: int = 50 +@export var food_base_threshold: int = 150 # temperature @export var temperature_set_buff_value: int = 250 @export var temperature_damage: int = 1 @@ -233,7 +234,7 @@ func tick_handle_food(): func game_tick() -> void: behavior_tree.game_tick() - StepVisualization.add_circle_tileset(board_position, view_distance, StepVisualization.CircleType.PLAYER_VIEW) + StepVisualization.add_circle_tileset(board_position, view_distance / 1.2, StepVisualization.CircleType.PLAYER_VIEW) tick_handle_temperature(get_current_temperature()) tick_handle_food() diff --git a/project/scripts/player/tree/impl/exploration/TaskPlannedExploration.gd b/project/scripts/player/tree/impl/exploration/TaskPlannedExploration.gd index dbf99ad..04dd4b1 100644 --- a/project/scripts/player/tree/impl/exploration/TaskPlannedExploration.gd +++ b/project/scripts/player/tree/impl/exploration/TaskPlannedExploration.gd @@ -31,6 +31,7 @@ func run(blackboard: Dictionary) -> void: var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "exploration_goal", current_goal) if path.size() == 0: + current_goal = tilemap_types.NO_TILE_FOUND status = Task.FAILURE status_reason = "No path found" return @@ -49,7 +50,7 @@ func find_new_goal(world: World, player: PlayerManager, navigation: TilemapNavig var best_goal: Vector2i = tilemap_types.NO_TILE_FOUND var best_distance: float = 0 - for i in range(4): + for i in range(3): var goal_consideration: Vector2i = determine_an_interesting_goal(world) if goal_consideration == tilemap_types.NO_TILE_FOUND: continue @@ -80,8 +81,8 @@ func determine_an_interesting_goal(world: World) -> Vector2i: var last_walkable: Vector2i = Vector2i(0, 0) var iterations_no_walkable: int = 0 - for i in range(5000): - var check_position: Vector2i = camp_position + (direction * i).floor() + for i in range(2500): + var check_position: Vector2i = camp_position + (direction * i * 2).floor() if not world.is_walkable(check_position): iterations_no_walkable += 1 else: diff --git a/project/scripts/player/tree/impl/game/base_survival/TaskCheckFoodBaseThreshold.gd b/project/scripts/player/tree/impl/game/base_survival/TaskCheckFoodBaseThreshold.gd new file mode 100644 index 0000000..1ac9471 --- /dev/null +++ b/project/scripts/player/tree/impl/game/base_survival/TaskCheckFoodBaseThreshold.gd @@ -0,0 +1,13 @@ +class_name TaskCheckFoodBaseThreshold +extends Task + +func run(blackboard: Dictionary) -> void: + var player: PlayerManager = blackboard["player"] + + if player.food > player.food_base_threshold: + status = FAILURE + status_reason = "Player food is not base threshold (" + str(player.food) + " > " + str(player.food_critical_threshold) + ")" + return + + status = SUCCESS + status_reason = "Player food is base threshold (" + str(player.food) + " <= " + str(player.food_critical_threshold) + ")" diff --git a/project/scripts/tilemap/StepVisualization.gd b/project/scripts/tilemap/StepVisualization.gd index 917061e..90b9615 100644 --- a/project/scripts/tilemap/StepVisualization.gd +++ b/project/scripts/tilemap/StepVisualization.gd @@ -5,7 +5,7 @@ static var game_manager: GameManager static var world: World # enum LineType { SEARCH_BASE, SEARCH_SELECTED, SEARCH_FAILED } -enum CircleType { PLAYER_VIEW, GOAL_CONSIDERATION, GOAL } +enum CircleType { PLAYER_VIEW, GOAL_CONSIDERATION, GOAL, BOAT_PART } # # Dictionary[Array[Vector2i], LineType] ([from, to], line_type) static var draw_lines: Dictionary = {} @@ -51,6 +51,20 @@ func _ready() -> void: func _draw() -> void: + for key in draw_circles.keys(): + var center: Vector2i = key[0] + var radius: int = key[1] + var circle_type: CircleType = draw_circles[key] + + if circle_type == CircleType.PLAYER_VIEW: + draw_circle(center, radius, Color("green"), false, 2, true) + elif circle_type == CircleType.GOAL_CONSIDERATION: + draw_circle(center, radius, Color("yellow"), false, 2, true) + elif circle_type == CircleType.GOAL: + draw_circle(center, radius, Color("orange"), false, 2, true) + elif circle_type == CircleType.BOAT_PART: + draw_circle(center, radius, Color(255, 0, 0, 0.5), false, 1, true) + for key in draw_lines.keys(): var from: Vector2i = key[0] var to: Vector2i = key[1] @@ -62,15 +76,3 @@ func _draw() -> void: draw_line(from, to, Color("green"), 2) elif line_type == LineType.SEARCH_FAILED: draw_line(from, to, Color(255, 0, 0, 0.1), 1) - - for key in draw_circles.keys(): - var center: Vector2i = key[0] - var radius: int = key[1] - var circle_type: CircleType = draw_circles[key] - - if circle_type == CircleType.PLAYER_VIEW: - draw_circle(center, radius, Color("green"), false, 2, true) - elif circle_type == CircleType.GOAL_CONSIDERATION: - draw_circle(center, radius, Color("yellow"), false, 2, true) - elif circle_type == CircleType.GOAL: - draw_circle(center, radius, Color("red"), false, 2, true) diff --git a/project/scripts/tilemap/World.gd b/project/scripts/tilemap/World.gd index d1d4def..d368491 100644 --- a/project/scripts/tilemap/World.gd +++ b/project/scripts/tilemap/World.gd @@ -79,6 +79,7 @@ func is_walkable(position: Vector2i) -> bool: func game_tick_start() -> void: step_visualizer.game_tick_start() + camp_manager.game_tick_start() # refill empty bushes var empty_bushes: Array[Vector2i] = tilemap_interactive.get_cells_by_type(tilemap_types.OBJECT_I_EMPTY_BUSH) @@ -92,6 +93,12 @@ func game_tick_start() -> void: if randf() < 0.01: tilemap_interactive.set_cell(tree, tilemap_types.OBJECT_I_TREE_FULL) + # mark all boat parts on the map + var boat_parts: Array[Vector2i] = tilemap_interactive.get_cells_by_type_collection(tilemap_types.OBJECT_COLLECTION_BOAT_PARTS) + for part in boat_parts: + StepVisualization.add_circle_tileset(part, 1, StepVisualization.CircleType.BOAT_PART) + func game_tick_end() -> void: step_visualizer.game_tick_end() + camp_manager.game_tick_end() diff --git a/project/scripts/tilemap/objects/CampManager.gd b/project/scripts/tilemap/objects/CampManager.gd index aa13947..d156ead 100644 --- a/project/scripts/tilemap/objects/CampManager.gd +++ b/project/scripts/tilemap/objects/CampManager.gd @@ -12,6 +12,9 @@ var camp: Vector2i = tilemap_types.EMPTY var campfire: Vector2i = tilemap_types.EMPTY var boat_build_location: Vector2i = tilemap_types.EMPTY var boat_leave_location: Vector2i = tilemap_types.EMPTY +# +var time_of_day: int = 0 +var day_length: int = 2000 @export var required_boat_parts: int = 6 @@ -48,6 +51,15 @@ func setup() -> void: tilemap_interactive.set_cell(campfire, tilemap_types.OBJECT_I_FIREPIT_OFF) +func game_tick_start() -> void: + time_of_day += 1 + + +func game_tick_end() -> void: + if time_of_day == day_length: + EventsTracker.track(EventsTracker.Event.TIME_SUNDOWN) + + func camp_contains_item(item: Vector2i) -> bool: return camp_items.find(item) != -1