Campfire and sleep mechanic

pull/7/head
Yan Wittmann 2025-01-12 16:28:36 +01:00
parent cd01fd24a2
commit 0becddf3d2
12 changed files with 215 additions and 13 deletions

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=39 format=4 uid="uid://b88asko1ugyd2"] [gd_scene load_steps=44 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/global/GameManager.gd" id="1_eeg2d"]
[ext_resource type="Script" path="res://scripts/tilemap/World.gd" id="1_k0rw8"] [ext_resource type="Script" path="res://scripts/tilemap/World.gd" id="1_k0rw8"]
@ -38,6 +38,11 @@
[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/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/TaskPlannedExploration.gd" id="35_tfcwq"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/exploration/TaskRandomWalking.gd" id="36_0tfae"] [ext_resource type="Script" path="res://scripts/player/tree/impl/exploration/TaskRandomWalking.gd" id="36_0tfae"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/game/camp/TaskWantsToSleep.gd" id="36_i5odk"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/game/inventory/TaskInventoryContainsStick.gd" id="38_2qm2u"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/game/camp/TaskCampContainsEnoughSticksToLightCampfire.gd" id="38_rf71d"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/game/camp/TaskPutInventoryContentInCamp.gd" id="39_8rirr"]
[ext_resource type="Script" path="res://scripts/player/tree/impl/game/camp/TaskCampSleep.gd" id="39_nbuyx"]
[node name="Island-scene" type="Node2D"] [node name="Island-scene" type="Node2D"]
script = ExtResource("1_eeg2d") script = ExtResource("1_eeg2d")
@ -92,6 +97,12 @@ theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 14 theme_override_font_sizes/font_size = 14
text = "Temp" text = "Temp"
[node name="TempResistance" 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 = "Resist."
[node name="BarContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer"] [node name="BarContainer" type="VBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer"]
layout_mode = 2 layout_mode = 2
@ -148,6 +159,24 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="TemperatureResistanceBar" 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="TemperatureResistanceLabel" type="Label" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer/StatsContainer/BarContainer/TemperatureResistanceBar"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="InventoryDisplayContainer" type="HBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer"] [node name="InventoryDisplayContainer" type="HBoxContainer" parent="Camera2D/CanvasLayer/TopLeftContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 0 size_flags_horizontal = 0
@ -388,6 +417,51 @@ script = ExtResource("10_4v1m1")
[node name="TaskPickupTheBerry" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_NextFood"] [node name="TaskPickupTheBerry" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Food/sl_PickMostRelevantFoodSource/sq_NextFood"]
script = ExtResource("15_ccdxl") script = ExtResource("15_ccdxl")
[node name="sq_Sleep" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival"]
script = ExtResource("9_i67mw")
[node name="TaskWantsToSleep" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep"]
script = ExtResource("36_i5odk")
[node name="sl_GoToSleepFindBestOption" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep"]
script = ExtResource("7_1jajd")
[node name="sq_GoddaShreep" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption"]
script = ExtResource("9_i67mw")
[node name="TaskCampContainsEnoughSticksToLightCampfire" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_GoddaShreep"]
script = ExtResource("38_rf71d")
[node name="TaskCampSleep" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_GoddaShreep"]
script = ExtResource("39_nbuyx")
[node name="sq_BringStickToCamp" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption"]
script = ExtResource("9_i67mw")
[node name="TaskInventoryContainsStick" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_BringStickToCamp"]
script = ExtResource("38_2qm2u")
[node name="TaskFindCamp" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_BringStickToCamp"]
script = ExtResource("21_cseat")
[node name="GoToWhileRunningSuccessStop" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_BringStickToCamp"]
script = ExtResource("10_4v1m1")
[node name="TaskPutInventoryContentInCamp" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_BringStickToCamp"]
script = ExtResource("39_8rirr")
[node name="sq_DoesNotHaveStick" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption"]
script = ExtResource("9_i67mw")
[node name="TaskFindClosestStick" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_DoesNotHaveStick"]
script = ExtResource("19_1orqu")
[node name="GoToWhileRunningSuccessStop" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_DoesNotHaveStick"]
script = ExtResource("10_4v1m1")
[node name="TaskPickupStick" type="Node" parent="PlayerManager/BehaviorTree/sl_Root/sl_BaseSurvival/sq_Sleep/sl_GoToSleepFindBestOption/sq_DoesNotHaveStick"]
script = ExtResource("20_uw2ce")
[node name="sl_Exploration" type="Node" parent="PlayerManager/BehaviorTree/sl_Root"] [node name="sl_Exploration" type="Node" parent="PlayerManager/BehaviorTree/sl_Root"]
script = ExtResource("7_1jajd") script = ExtResource("7_1jajd")

View File

@ -61,7 +61,7 @@ static func populate_visual_log_create_label(event: TrackedEvent, container: Con
elif event_id == Event.CAMP_ADDED_ITEM: elif event_id == Event.CAMP_ADDED_ITEM:
text = "Camp added item" text = "Camp added item"
elif event_id == Event.CAMP_TAKEN_ITEM: elif event_id == Event.CAMP_TAKEN_ITEM:
text = "Camp taken item" text = "Camp taken item x" + str(params["count"])
elif event_id == Event.CAMP_TAKE_ITEM_FAILED: elif event_id == Event.CAMP_TAKE_ITEM_FAILED:
text = "Could not take item from camp" text = "Could not take item from camp"
elif event_id == Event.SLEEP: elif event_id == Event.SLEEP:

View File

@ -11,7 +11,7 @@ var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
@onready var health_bar: ProgressBar = %HealthBar @onready var health_bar: ProgressBar = %HealthBar
@onready var food_bar: ProgressBar = %FoodBar @onready var food_bar: ProgressBar = %FoodBar
@onready var temperature_bar: ProgressBar = %TemperatureBar @onready var temperature_bar: ProgressBar = %TemperatureBar
@onready var temperature_layer: Node2D = $Tileset/TemperatureLayer @onready var temperature_resistance_bar: ProgressBar = %TemperatureResistanceBar
var tilemap_navigation: TilemapNavigation = TilemapNavigation.new() var tilemap_navigation: TilemapNavigation = TilemapNavigation.new()
@ -90,15 +90,18 @@ func update_bars() -> void:
food_bar.value = clamp(player.food, 0, player.max_food) food_bar.value = clamp(player.food, 0, player.max_food)
%FoodLabel.text = str(food_bar.value) + "/" + str(player.max_food) %FoodLabel.text = str(food_bar.value) + "/" + str(player.max_food)
if temperature_resistance_bar != null:
temperature_resistance_bar.max_value = player.temperature_set_buff_value
temperature_resistance_bar.value = clamp(player.temperature_buff_timer, 0, player.temperature_set_buff_value)
%TemperatureResistanceLabel.text = str(temperature_resistance_bar.value) + "/" + str(player.temperature_set_buff_value)
if temperature_bar != null: if temperature_bar != null:
temperature_bar.max_value = player.temperature_set_buff_value temperature_bar.max_value = player.temperature_endure
temperature_bar.value = clamp(player.temperature_buff_timer, 0, player.temperature_set_buff_value) # invert the value to show the time left
%TemperatureLabel.text = str(temperature_bar.value) + "/" + str(player.temperature_set_buff_value) var countdown: int = player.temperature_endure - player.temperature_timer
temperature_bar.value = clamp(countdown, 0, player.temperature_endure)
%TemperatureLabel.text = str(temperature_bar.value) + "/" + str(player.temperature_endure)
func toggle_temperature_layer() -> void: func toggle_temperature_layer() -> void:
if temperature_layer != null: world.tilemap_temperature.tilemap.visible = not world.tilemap_temperature.tilemap.visible
temperature_layer.visible = not temperature_layer.visible
print("TemperatureLayer visibility:", temperature_layer.visible)
else:
print("TemperatureLayer is null!")

View File

@ -0,0 +1,13 @@
class_name TaskCampContainsEnoughSticksToLightCampfire
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
if world.camp_manager.camp_contains_enough_sticks_to_light_campfire():
status = SUCCESS
status_reason = "Camp contains enough sticks to light campfire"
return
status = FAILURE
status_reason = "Camp does not contain enough sticks to light campfire"

View File

@ -0,0 +1,24 @@
class_name TaskCampSleep
extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
var world: World = blackboard["world"]
if not world.camp_manager.is_sleep_active and world.camp_manager.is_sundown():
world.camp_manager.campfire_light()
world.camp_manager.sleep_effect()
player.health = player.max_health
status = RUNNING
status_reason = "Sleeping"
return
if world.camp_manager.is_sleep_active:
player.food += 1
status = RUNNING
status_reason = "Still sleeping"
return
world.camp_manager.campfire_extinguish()
status = SUCCESS
status_reason = "Slept"

View File

@ -8,7 +8,7 @@ func run(blackboard: Dictionary) -> void:
blackboard["location_camp"] = world.camp_manager.camp blackboard["location_camp"] = world.camp_manager.camp
var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, world.camp_manager.camp, 99999999) var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_camp", world.camp_manager.camp, 99999999)
if path.size() > 0: if path.size() > 0:
blackboard["path"] = path blackboard["path"] = path
status = SUCCESS status = SUCCESS

View File

@ -0,0 +1,25 @@
class_name TaskGoCloseToCamp
extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
var world: World = blackboard["world"]
var navigation: TilemapNavigation = blackboard["navigation"]
# allow a radius of the player view distance / 1.5 to find a camp
var camp: Vector2i = world.camp_manager.camp
if TilemapNavigation.manhattan_distance(player.board_position, camp) < player.view_distance / 1.5:
blackboard["path"] = []
status = SUCCESS
status_reason = "Player is close to camp"
return
var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_camp", camp, 99999999)
if path.size() > 0:
blackboard["path"] = path
status = FAILURE
status_reason = "Found path to camp"
return
status = FAILURE
status_reason = "No path found to camp " + str(camp)

View File

@ -0,0 +1,16 @@
class_name TaskPutInventoryContentInCamp
extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
var world: World = blackboard["world"]
if player.inventory_slot != tilemap_types.EMPTY:
world.camp_manager.camp_add_item(player.inventory_slot)
player.inventory_slot = tilemap_types.EMPTY
status = SUCCESS
status_reason = "Put inventory content in camp"
return
status = FAILURE
status_reason = "Player has no inventory content"

View File

@ -0,0 +1,13 @@
class_name TaskWantsToSleep
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
if world.camp_manager.is_sundown():
status = SUCCESS
status_reason = "It is sundown " + str(world.camp_manager.time_of_day)
return
status = FAILURE
status_reason = "It is not sundown " + str(world.camp_manager.time_of_day)

View File

@ -0,0 +1,13 @@
class_name TaskInventoryContainsStick
extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
if player.inventory_slot == tilemap_types.OBJECT_I_STICK:
status = SUCCESS
status_reason = "Player has stick"
return
status = FAILURE
status_reason = "Player does not have stick"

View File

@ -124,6 +124,7 @@ func cached_path_allow_neighbors(blackboard: Dictionary, path_key: String, targe
if path_still_valid(player.board_position, target, blackboard["cached_paths"][path_key]): if path_still_valid(player.board_position, target, blackboard["cached_paths"][path_key]):
return blackboard["cached_paths"][path_key] return blackboard["cached_paths"][path_key]
else: else:
print("Cached path is invalid, recalculating for ", target, " ", path_key)
blackboard["cached_paths"].erase(path_key) blackboard["cached_paths"].erase(path_key)
StepVisualization.add_line_tileset(player.board_position, target, StepVisualization.LineType.SEARCH_SELECTED) StepVisualization.add_line_tileset(player.board_position, target, StepVisualization.LineType.SEARCH_SELECTED)

View File

@ -60,6 +60,14 @@ func game_tick_end() -> void:
EventsTracker.track(EventsTracker.Event.TIME_SUNDOWN) EventsTracker.track(EventsTracker.Event.TIME_SUNDOWN)
func is_sundown() -> bool:
return time_of_day >= day_length
func camp_contains_enough_sticks_to_light_campfire() -> bool:
return camp_item_count(tilemap_types.OBJECT_I_STICK) >= 2
func camp_contains_item(item: Vector2i) -> bool: func camp_contains_item(item: Vector2i) -> bool:
return camp_items.find(item) != -1 return camp_items.find(item) != -1
@ -94,7 +102,7 @@ func camp_take_item(item: Vector2i, count: int = 1) -> bool:
return false return false
var taken: int = 0 var taken: int = 0
for i in range(camp_items.size()): for i in range(camp_items.size() - 1, -1, -1):
if camp_items[i] == item: if camp_items[i] == item:
camp_items.remove_at(i) camp_items.remove_at(i)
taken += 1 taken += 1
@ -125,11 +133,23 @@ func campfire_extinguish() -> void:
tilemap_interactive.set_cell(campfire, tilemap_types.OBJECT_I_FIREPIT_OFF) tilemap_interactive.set_cell(campfire, tilemap_types.OBJECT_I_FIREPIT_OFF)
EventsTracker.track(EventsTracker.Event.CAMPFIRE_EXTINGUISHED) EventsTracker.track(EventsTracker.Event.CAMPFIRE_EXTINGUISHED)
var is_sleep_active: bool = false
func sleep_effect() -> void: func sleep_effect() -> void:
if is_sleep_active:
return
is_sleep_active = true
EventsTracker.track(EventsTracker.Event.SLEEP) EventsTracker.track(EventsTracker.Event.SLEEP)
game_manager.camera.go_to_zooming(game_manager.world.tilemap_player.cell_to_local(camp), 3) game_manager.camera.go_to_zooming(game_manager.world.tilemap_player.cell_to_local(camp), 3)
var tween_in: Tween = game_manager.world.get_tree().create_tween() var tween_in: Tween = game_manager.world.get_tree().create_tween()
tween_in.tween_method(game_manager.camera.set_vignette_intensity, 0.0, 1.0, 2.0).set_delay(0.5) tween_in.tween_method(game_manager.camera.set_vignette_intensity, 0.0, 1.0, 2.0).set_delay(0.5)
var tween_out: Tween = game_manager.world.get_tree().create_tween() var tween_out: Tween = game_manager.world.get_tree().create_tween()
tween_out.tween_method(game_manager.camera.set_vignette_intensity, 1.0, 0.0, 2.0).set_delay(4.0) tween_out.tween_method(game_manager.camera.set_vignette_intensity, 1.0, 0.0, 2.0).set_delay(4.0)
await game_manager.world.get_tree().create_timer(6.0).timeout
print("Sleep effect done")
is_sleep_active = false
time_of_day = 0