Game now finally works somewhat properly

pull/7/head
Yan Wittmann 2025-01-11 19:05:03 +01:00
parent 4763de9827
commit 268f2c0ce1
21 changed files with 160 additions and 46 deletions

View File

@ -24,7 +24,7 @@ texture = ExtResource("1_ukrsa")
3:2/4 = 4
0:0/0 = 0
0:0/0/custom_data_0 = true
0:0/0/custom_data_2 = 4
0:0/0/custom_data_2 = 2
3:1/next_alternative_id = 4
3:1/0 = 0
3:1/0/custom_data_0 = true
@ -33,6 +33,8 @@ texture = ExtResource("1_ukrsa")
5:3/0 = 0
5:3/0/custom_data_0 = true
4:0/0 = 0
4:0/0/custom_data_0 = true
4:0/0/custom_data_2 = 3
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_x77e4"]
texture = ExtResource("2_15xge")

File diff suppressed because one or more lines are too long

View File

@ -14,6 +14,7 @@ enum Event {
PLAYER_PICKED_UP_ITEM,
PLAYER_DROPPED_ITEM,
PLAYER_USED_ITEM,
GAME_STATE_WIN,
};
#
static var events: Array[TrackedEvent] = []
@ -71,6 +72,8 @@ static func populate_visual_log_create_label(event: TrackedEvent, container: Con
text = "Boat construction"
elif event_id == Event.CAMP_BOAT_COMPLETE:
text = "Boat complete"
elif event_id == Event.GAME_STATE_WIN:
text = "Game won"
else:
text = "Something happened..."

View File

@ -67,10 +67,17 @@ func _on_game_tick_timeout() -> void:
EventsTracker.populate_visual_log(%RecentEventsLog, self)
update_bars()
handle_result_game_state(player.behavior_tree.blackboard)
timer_on_game_tick_timeout.stop()
func handle_result_game_state(blackboard: Dictionary) -> void:
if blackboard.has("game_state_win"):
EventsTracker.track(EventsTracker.Event.GAME_STATE_WIN)
game_ticker.stop()
func update_bars() -> void:
if health_bar != null:
health_bar.max_value = player.max_health

View File

@ -3,12 +3,11 @@ extends Node
@export var max_health: int = 100
# food system
@export var max_food: int = 100
@export var max_food: int = 250
@export var food_damage: int = 1
@export var food_addon_per_berry: int = 100
@export var food_critical_threshold: int = 50
# temperature
@export var temperature_set_buff_value: int = 50
@export var temperature_set_buff_value: int = 250
@export var temperature_damage: int = 1
@export var temperature_endure: int = 50
# viewing

View File

@ -17,6 +17,12 @@ func _ready() -> void:
behavior_tree = child as Task
initialize_blackboard()
func initialize_blackboard() -> void:
blackboard["cached_paths"] = {}
func populate_blackboard():
blackboard["world"] = game_manager.world

View File

@ -19,7 +19,7 @@ func _ready() -> void:
func internal_run(blackboard: Dictionary) -> void:
blackboard["current_task"] = self
var running_child: Task = find_running_child()
var running_child: Task = find_running_child()
var extra_string: String = ""
if running_child != null:
extra_string = running_child.name
@ -89,3 +89,31 @@ func human_readable(addon: String = "") -> String:
ret += " [" + clear_status + "]"
return ret
# SECTION: utility
func find_closest_item(blackboard: Dictionary, item_types: Array[Vector2i], memory_key: String, max_distance: int = -1) -> Dictionary:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
var navigation: TilemapNavigation = blackboard["navigation"]
var result: Dictionary = {"status": FAILURE, "status_reason": "", "closest_item": null}
var items: Array[Vector2i] = world.tilemap_interactive.get_cells_by_type_collection(
item_types, player.board_position, max_distance if max_distance > -1 else player.view_distance)
if len(items) == 0:
result.status_reason = "No items of type " + str(item_types) + " found"
return result
var closest_item: Vector2i = navigation.manhattan_distance_closest(items, player.board_position)
player.player_memory[memory_key] = closest_item
StepVisualization.add_line_tileset(player.board_position, closest_item, StepVisualization.LineType.SEARCH_SELECTED)
if closest_item == tilemap_types.NO_TILE_FOUND:
result.status_reason = "No closest item of type " + str(item_types) + " found"
return result
result.status = SUCCESS
result.closest_item = closest_item
return result

View File

@ -19,6 +19,7 @@ func run(blackboard: Dictionary) -> void:
player.walk_along(path)
if navigation.has_arrived(player.board_position, path):
blackboard["cached_paths"] = {}
status = SUCCESS
status_reason = "already arrived at destination"
return

View File

@ -19,6 +19,7 @@ func run(blackboard: Dictionary) -> void:
player.walk_along(path)
if navigation.has_arrived(player.board_position, path):
blackboard["cached_paths"] = {}
status = SUCCESS
status_reason = "already arrived at destination"
return

View File

@ -19,6 +19,7 @@ func run(blackboard: Dictionary) -> void:
player.walk_along(path)
if navigation.has_arrived(player.board_position, path):
blackboard["cached_paths"] = {}
status = SUCCESS
status_reason = "already arrived at destination"
return

View File

@ -2,29 +2,25 @@ class_name TaskFindClosestBoatPart
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
var navigation: TilemapNavigation = blackboard["navigation"]
var parts: Array[Vector2i] = world.tilemap_interactive.get_cells_by_type_collection(
tilemap_types.OBJECT_COLLECTION_BOAT_PARTS, player.board_position, player.view_distance)
if len(parts) == 0:
if tilemap_types.is_part_of_collection(tilemap_types.OBJECT_COLLECTION_BOAT_PARTS, player.inventory_slot):
status = FAILURE
status_reason = "No boat parts found"
status_reason = "Player already has boat part"
return
var closest_part: Vector2i = navigation.manhattan_distance_closest(parts, player.board_position)
player.player_memory["boat_part"] = closest_part
StepVisualization.add_line_tileset(player.board_position, closest_part, StepVisualization.LineType.SEARCH_SELECTED)
if closest_part == tilemap_types.NO_TILE_FOUND:
var result: Dictionary = find_closest_item(blackboard, tilemap_types.OBJECT_COLLECTION_BOAT_PARTS, "boat_part")
if result.status == FAILURE:
status = FAILURE
status_reason = "No closest boat part found"
status_reason = result.status_reason
return
var closest_part: Vector2i = result.closest_item
blackboard["closest_part"] = closest_part
var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, closest_part, player.view_distance)
var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_boat_part", closest_part, player.view_distance)
if path.size() > 0:
blackboard["path"] = path
status_reason = "Found path to closest boat part"

View File

@ -3,18 +3,15 @@ extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
var navigation: TilemapNavigation = blackboard["navigation"]
var target: Vector2i = world.camp_manager.boat_leave_location
var target: Vector2i = world.camp_manager.boat_leave_location
var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_boat_leave", target)
StepVisualization.add_line_tileset(player.board_position, target, StepVisualization.LineType.SEARCH_SELECTED)
var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, target, player.view_distance)
if path.size() > 0:
blackboard["path"] = path
status_reason = "Found path to boat leave location"
status = SUCCESS
return
status = FAILURE
status_reason = "No path found to boat leave location " + str(target)
else:
status = FAILURE
status_reason = "No path found to boat leave location " + str(target)

View File

@ -2,19 +2,24 @@ class_name TaskGoToBoatLocation
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
var navigation: TilemapNavigation = blackboard["navigation"]
var target: Vector2i = world.camp_manager.boat_build_location
var result: Dictionary = find_closest_item(blackboard, tilemap_types.OBJECT_COLLECTION_BOAT, "boat_building_location", TileMapLayerAccess.ANY_DISTANCE)
if result.status == FAILURE:
status = FAILURE
status_reason = result.status_reason
return
# var target: Vector2i = world.camp_manager.boat_build_location
var target: Vector2i = result.closest_item
var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_boat", target)
StepVisualization.add_line_tileset(player.board_position, target, StepVisualization.LineType.SEARCH_SELECTED)
var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, target, player.view_distance)
if path.size() > 0:
blackboard["path"] = path
status_reason = "Found path to boat build location"
status = SUCCESS
return
status = FAILURE
status_reason = "No path found to boat build location " + str(target)
else:
status = FAILURE
status_reason = "No path found to boat build location " + str(target)

View File

@ -0,0 +1,12 @@
class_name TaskWinningSequence
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
world.tilemap_interactive.set_cell(world.camp_manager.boat_leave_location, player.inventory_slot)
EventsTracker.track(EventsTracker.Event.PLAYER_USED_ITEM, {"item": player.inventory_slot})
player.inventory_slot = tilemap_types.EMPTY
blackboard["game_state_win"] = true

View File

@ -7,7 +7,9 @@ func run(blackboard: Dictionary) -> void:
var navigation: TilemapNavigation = blackboard["navigation"]
var warm_tiles: Array[Vector2i] = world.tilemap_temperature.get_cells_by_type(
tilemap_types.TEMPERATURE_NORMAL, player.board_position, player.view_distance)
tilemap_types.TEMPERATURE_NORMAL,
player.board_position, player.view_distance,
false)
if len(warm_tiles) == 0:
status = FAILURE
status_reason = "No warm tiles found"

View File

@ -3,13 +3,14 @@ extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
var world: World = blackboard["world"]
if world.camp_manager.boat_build_location == tilemap_types.EMPTY:
var result: Dictionary = find_closest_item(blackboard, tilemap_types.OBJECT_COLLECTION_BOAT, "boat_building_location", TileMapLayerAccess.ANY_DISTANCE)
if result.status == FAILURE:
status = FAILURE
status_reason = "Boat is not on the map"
status_reason = result.status_reason
return
player.pick_up_item(world.camp_manager.boat_build_location)
player.pick_up_item(result.closest_item)
status = SUCCESS
status_reason = "Picked up boat"

View File

@ -4,9 +4,10 @@ extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
var tilemap_navigation: TilemapNavigation = blackboard["navigation"]
var navigation: TilemapNavigation = blackboard["navigation"]
var path: Array[Vector2i] = tilemap_navigation.find_path_allow_neighbors(player.board_position, world.tilemap_mouse_position(), player.view_distance)
# var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, world.tilemap_mouse_position(), player.view_distance)
var path: Array[Vector2i] = navigation.cached_path_allow_neighbors(blackboard, "path_to_boat_part", world.tilemap_mouse_position(), player.view_distance * 1.4)
if len(path) == 0:
status = FAILURE

View File

@ -13,18 +13,22 @@ func setup() -> void:
func get_cells_by_type(
atlas_coords: Vector2i,
center: Vector2i = Vector2i(-1, -1), max_distance: int = 99999999
center: Vector2i = Vector2i(-1, -1), max_distance: int = 99999999,
record: bool = true
) -> Array[Vector2i]:
var tiles_with_type: Array[Vector2i] = tilemap.get_used_cells_by_id(sid, atlas_coords)
if max_distance < 99999999:
var filtered_tiles: Array[Vector2i] = []
for tile in tiles_with_type:
if TilemapNavigation.is_within_radius(center, tile, max_distance, true):
if TilemapNavigation.is_within_radius(center, tile, max_distance, record):
filtered_tiles.append(tile)
return filtered_tiles
return tiles_with_type
const ANY_DISTANCE: int = 99999999
func get_cells_by_type_collection(
atlas_coords: Array[Vector2i],
center: Vector2i = Vector2i(-1, -1), max_distance: int = 99999999

View File

@ -94,6 +94,45 @@ func has_arrived(position: Vector2i, path: Array[Vector2i]) -> bool:
return path.size() > 0 and path[path.size() - 1] == position
func path_still_valid(require_on_path: Vector2i, require_close_end: Vector2i, path: Array[Vector2i]) -> bool:
# check if:
# - player is on the path
# - target is close to the last position in the path (<= 1 step away)
# - all positions are still walkable
if not require_on_path == tilemap_types.NO_TILE_FOUND and not path.has(require_on_path):
return false
if not require_close_end == tilemap_types.NO_TILE_FOUND and (path.size() == 0 or not is_within_radius(require_close_end, path[path.size() - 1], 1)):
return false
for pos in path:
if not world.is_walkable(pos):
return false
return true
func cached_path_allow_neighbors(blackboard: Dictionary, path_key: String, target: Vector2i, max_radius: int = -1) -> Array[Vector2i]:
var player: PlayerManager = blackboard["player"]
if blackboard["cached_paths"].has(path_key):
# clear ALL other that are not the current path
for key in blackboard["cached_paths"].keys():
if key != path_key:
blackboard["cached_paths"].erase(key)
# check if the path is still valid
if path_still_valid(player.board_position, target, blackboard["cached_paths"][path_key]):
return blackboard["cached_paths"][path_key]
else:
blackboard["cached_paths"].erase(path_key)
StepVisualization.add_line_tileset(player.board_position, target, StepVisualization.LineType.SEARCH_SELECTED)
var path: Array[Vector2i] = find_path_allow_neighbors(player.board_position, target, max_radius)
if path.size() > 0:
blackboard["cached_paths"][path_key] = path
return path
func find_path(start_position: Vector2i, end_position: Vector2i, max_radius: int = -1) -> Array[Vector2i]:
var path: Array[Vector2i] = _find_path_internal(start_position, end_position, max_radius)
if path.size() > 0:

View File

@ -56,6 +56,11 @@ func tilemap_mouse_position() -> Vector2i:
func find_item_drop_location(center_pos: Vector2i) -> Vector2i:
for x in range(center_pos.x - 1, center_pos.x + 1):
for y in range(center_pos.y - 1, center_pos.y + 1):
var check_pos: Vector2i = Vector2i(x, y)
if not tilemap_interactive.get_cell(check_pos) and is_walkable(check_pos):
return check_pos
for x in range(center_pos.x - 2, center_pos.x + 2):
for y in range(center_pos.y - 2, center_pos.y + 2):
var check_pos: Vector2i = Vector2i(x, y)

View File

@ -13,7 +13,7 @@ var campfire: Vector2i = tilemap_types.EMPTY
var boat_build_location: Vector2i = tilemap_types.EMPTY
var boat_leave_location: Vector2i = tilemap_types.EMPTY
@export var required_boat_parts: int = 3
@export var required_boat_parts: int = 6
func setup() -> void: