Game now finally works somewhat properly
parent
4763de9827
commit
268f2c0ce1
|
@ -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
|
@ -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..."
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue