Compare commits

..

8 Commits

Author SHA1 Message Date
Yan Wittmann 4763de9827 Attempt #1 at fixing main 2025-01-11 17:43:13 +01:00
Yan Wittmann 238af1cc83 Merge branch 'working-map'
# Conflicts:
#	project/main-scenes/island.tscn
2025-01-11 17:40:50 +01:00
Yan Wittmann cd82cf5bdf Fixed up tilemap and content 2025-01-11 17:39:37 +01:00
2021587 2923738906 now its only the gameworld 2025-01-11 17:00:31 +01:00
2021587 8bbca6cef5 Revert "added game world"
This reverts commit 7304b48f3c.
2025-01-11 16:59:42 +01:00
2021587 7304b48f3c added game world 2025-01-11 16:59:08 +01:00
Yan Wittmann 9446c10556 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	project/assets/tilemap/tileset.tres
#	project/main-scenes/island.tscn
2025-01-11 16:15:03 +01:00
Yan Wittmann 731ff9ed12 Initial version of boat construction 2025-01-11 16:09:10 +01:00
25 changed files with 472 additions and 83 deletions

View File

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

File diff suppressed because one or more lines are too long

View File

@ -112,3 +112,4 @@ key_6={
textures/canvas_textures/default_texture_filter=0 textures/canvas_textures/default_texture_filter=0
renderer/rendering_method="gl_compatibility" renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility"
environment/defaults/default_clear_color=Color(0.356863, 0.431373, 0.882353, 1)

View File

@ -7,8 +7,8 @@ extends Camera2D
@export var max_speed: float = 500.0 @export var max_speed: float = 500.0
@export var inner_border_threshold: float = 0.0 # 60.0 @export var inner_border_threshold: float = 0.0 # 60.0
@export var outer_border_threshold: float = 0.0 # 40.0 @export var outer_border_threshold: float = 0.0 # 40.0
@export var min_position: Vector2 = Vector2(0, 0) @export var min_position: Vector2 = Vector2(874, 843)
@export var max_position: Vector2 = Vector2(1375, 660) @export var max_position: Vector2 = Vector2(4884, 4623)
var velocity: Vector2 = Vector2.ZERO var velocity: Vector2 = Vector2.ZERO
# #

View File

@ -8,6 +8,8 @@ enum Event {
CAMP_ADDED_ITEM, CAMP_ADDED_ITEM,
CAMP_TAKEN_ITEM, CAMP_TAKEN_ITEM,
CAMP_TAKE_ITEM_FAILED, CAMP_TAKE_ITEM_FAILED,
CAMP_BOAT_PART_DELIVERED,
CAMP_BOAT_COMPLETE,
SLEEP, SLEEP,
PLAYER_PICKED_UP_ITEM, PLAYER_PICKED_UP_ITEM,
PLAYER_DROPPED_ITEM, PLAYER_DROPPED_ITEM,
@ -60,11 +62,17 @@ static func populate_visual_log_create_label(event: TrackedEvent, container: Con
elif event_id == Event.SLEEP: elif event_id == Event.SLEEP:
text = "Player slept" text = "Player slept"
elif event_id == Event.PLAYER_PICKED_UP_ITEM: elif event_id == Event.PLAYER_PICKED_UP_ITEM:
text = "took" text = "Took"
elif event_id == Event.PLAYER_DROPPED_ITEM: elif event_id == Event.PLAYER_DROPPED_ITEM:
text = "dropped" text = "Dropped"
elif event_id == Event.PLAYER_USED_ITEM: elif event_id == Event.PLAYER_USED_ITEM:
text = "used" text = "Used"
elif event_id == Event.CAMP_BOAT_PART_DELIVERED:
text = "Boat construction"
elif event_id == Event.CAMP_BOAT_COMPLETE:
text = "Boat complete"
else:
text = "Something happened..."
var event_label: Label = Label.new() var event_label: Label = Label.new()
event_label.text = text event_label.text = text

View File

@ -39,7 +39,9 @@ func _process(delta: float) -> void:
world.camp_manager.sleep_effect() world.camp_manager.sleep_effect()
world.camp_manager.campfire_extinguish() world.camp_manager.campfire_extinguish()
if Input.is_action_just_pressed("force_game_tick"): if Input.is_action_just_pressed("force_game_tick"):
Task.print_behavior_tree_evaluation = true
_on_game_tick_timeout() _on_game_tick_timeout()
Task.print_behavior_tree_evaluation = false
if Input.is_action_pressed("force_game_tick_fast"): if Input.is_action_pressed("force_game_tick_fast"):
_on_game_tick_timeout() _on_game_tick_timeout()
if Input.is_action_just_pressed("key_6"): if Input.is_action_just_pressed("key_6"):
@ -53,7 +55,7 @@ func player_health_depleted():
func _on_game_tick_timeout() -> void: func _on_game_tick_timeout() -> void:
var timer_on_game_tick_timeout: PerformanceTimer = PerformanceTimer.new() var timer_on_game_tick_timeout: PerformanceTimer = PerformanceTimer.new()
timer_on_game_tick_timeout.display_name = "game tick duration" timer_on_game_tick_timeout.display_name = "frame"
tilemap_navigation.game_tick_start() tilemap_navigation.game_tick_start()
world.game_tick_start() world.game_tick_start()

View File

@ -33,12 +33,12 @@ var temperature_buff_timer: int = 0
var temperature_timer: int = 0 var temperature_timer: int = 0
var health: int = max_health var health: int = max_health
#
var inventory_slot: Vector2i = tilemap_types.EMPTY: var inventory_slot: Vector2i = tilemap_types.EMPTY:
set(value): set(value):
inventory_slot = value inventory_slot = value
update_board() update_board()
var player_memory: Dictionary = {}
func _ready() -> void: func _ready() -> void:
call_deferred("defer_ready") call_deferred("defer_ready")
@ -90,13 +90,15 @@ func pick_up_item(tilemap_pos: Vector2i) -> void:
var pick_up_item_type: Vector2i = game_manager.world.tilemap_interactive.tilemap.get_cell_atlas_coords(tilemap_pos) var pick_up_item_type: Vector2i = game_manager.world.tilemap_interactive.tilemap.get_cell_atlas_coords(tilemap_pos)
# check if tile will transform into another tile upon pickup # check if inventory contains item that needs to be transformed on dropping
# this should never be the case, as the pick up item operation should already reflect this transformation
var tile_drop_item: Vector2i = inventory_slot var tile_drop_item: Vector2i = inventory_slot
if tile_drop_item == tilemap_types.OBJECT_I_FILLED_BUSH: if tile_drop_item == tilemap_types.OBJECT_I_FILLED_BUSH:
tile_drop_item = tilemap_types.OBJECT_I_BERRY tile_drop_item = tilemap_types.OBJECT_I_BERRY
elif tile_drop_item == tilemap_types.OBJECT_I_TREE_FULL: elif tile_drop_item == tilemap_types.OBJECT_I_TREE_FULL:
tile_drop_item = tilemap_types.OBJECT_I_STICK tile_drop_item = tilemap_types.OBJECT_I_STICK
# check if tile will transform into another tile upon pickup
var tile_after_pickup_transform = null var tile_after_pickup_transform = null
if pick_up_item_type == tilemap_types.OBJECT_I_FILLED_BUSH: if pick_up_item_type == tilemap_types.OBJECT_I_FILLED_BUSH:
tile_after_pickup_transform = tilemap_types.OBJECT_I_EMPTY_BUSH tile_after_pickup_transform = tilemap_types.OBJECT_I_EMPTY_BUSH
@ -104,7 +106,6 @@ func pick_up_item(tilemap_pos: Vector2i) -> void:
elif pick_up_item_type == tilemap_types.OBJECT_I_TREE_FULL: elif pick_up_item_type == tilemap_types.OBJECT_I_TREE_FULL:
tile_after_pickup_transform = tilemap_types.OBJECT_I_TREE_CUT tile_after_pickup_transform = tilemap_types.OBJECT_I_TREE_CUT
pick_up_item_type = tilemap_types.OBJECT_I_STICK pick_up_item_type = tilemap_types.OBJECT_I_STICK
tile_drop_item = tilemap_types.OBJECT_I_STICK
# check if the inventory slot is empty # check if the inventory slot is empty
if inventory_slot == tilemap_types.EMPTY: if inventory_slot == tilemap_types.EMPTY:
@ -233,6 +234,7 @@ func tick_handle_food():
func game_tick() -> void: func game_tick() -> void:
behavior_tree.game_tick() behavior_tree.game_tick()
StepVisualization.add_circle_tileset(board_position, view_distance, StepVisualization.CircleType.PLAYER_VIEW)
tick_handle_temperature(get_current_temperature()) tick_handle_temperature(get_current_temperature())
tick_handle_food() tick_handle_food()

View File

@ -8,25 +8,25 @@ var behavior_tree: Task = null
func _ready() -> void: func _ready() -> void:
if get_child_count() == 0 or get_child_count() > 1: if get_child_count() == 0 or get_child_count() > 1:
push_error("This controller needs exactly one Task child, got " + str(get_child_count())) push_error("This controller needs exactly one Task child, got " + str(get_child_count()))
var child: Node = get_child(0) var child: Node = get_child(0)
if not (child is Task): if not (child is Task):
push_error("Child is not a task: " + child.name) push_error("Child is not a task: " + child.name)
behavior_tree = child as Task behavior_tree = child as Task
func populate_blackboard(): func populate_blackboard():
blackboard["world"] = game_manager.world blackboard["world"] = game_manager.world
blackboard["player"] = game_manager.player blackboard["player"] = game_manager.player
blackboard["camera"] = game_manager.camera blackboard["camera"] = game_manager.camera
blackboard["navigation"] = game_manager.tilemap_navigation blackboard["navigation"] = game_manager.tilemap_navigation
func game_tick() -> void: func game_tick() -> void:
print("game_tick:") populate_blackboard()
populate_blackboard() behavior_tree.internal_run(blackboard)
behavior_tree.internal_run(blackboard) if Task.print_behavior_tree_evaluation:
print(" ==> [active state=", blackboard["current_task"], "] [status=", behavior_tree.status, "] [blackboard=", blackboard, "]") print(" ==> [active state=", blackboard["current_task"], "] [status=", behavior_tree.status, "] [blackboard=", blackboard, "]")

View File

@ -2,6 +2,8 @@ class_name Task
extends Node extends Node
enum {FAILURE = -1, SUCCESS = 1, RUNNING = 0, SUCCESS_STOP = 2} enum {FAILURE = -1, SUCCESS = 1, RUNNING = 0, SUCCESS_STOP = 2}
static var print_behavior_tree_evaluation: bool = false
#
var status: int = FAILURE var status: int = FAILURE
var status_reason: String = "" var status_reason: String = ""
var tilemap_types: TileMapTileTypes = TileMapTileTypes.new() var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
@ -22,9 +24,11 @@ func internal_run(blackboard: Dictionary) -> void:
if running_child != null: if running_child != null:
extra_string = running_child.name extra_string = running_child.name
print(" -> ", human_readable(extra_string)) if print_behavior_tree_evaluation:
print(" -> ", human_readable(extra_string))
run(blackboard) run(blackboard)
print(" <- ", human_readable(extra_string)) if print_behavior_tree_evaluation:
print(" <- ", human_readable(extra_string))
func find_running_child() -> Task: func find_running_child() -> Task:

View File

@ -2,6 +2,11 @@ class_name TaskSelector
extends Task extends Task
func run(blackboard: Dictionary) -> void: func run(blackboard: Dictionary) -> void:
if get_children().size() == 0:
status = FAILURE
status_reason = "no children"
return
var running_child: Task = find_running_child() var running_child: Task = find_running_child()
for c in slice_at_child(running_child): for c in slice_at_child(running_child):
run_child(blackboard, c) run_child(blackboard, c)

View File

@ -2,6 +2,11 @@ class_name TaskSequence
extends Task extends Task
func run(blackboard: Dictionary) -> void: func run(blackboard: Dictionary) -> void:
if get_children().size() == 0:
status = FAILURE
status_reason = "no children"
return
var running_child: Task = find_running_child() var running_child: Task = find_running_child()
for c in slice_at_child(running_child): for c in slice_at_child(running_child):
run_child(blackboard, c) run_child(blackboard, c)

View File

@ -0,0 +1,13 @@
class_name TaskCheckBoatCompleted
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
if world.camp_manager.boat_items.size() >= world.camp_manager.required_boat_parts:
status = SUCCESS
status_reason = "Boat is completed with " + str(world.camp_manager.boat_items.size()) + " parts"
return
status = FAILURE
status_reason = "Boat is not completed, got only " + str(world.camp_manager.boat_items.size()) + " parts"

View File

@ -0,0 +1,20 @@
class_name TaskDeliverBoatPart
extends Task
func run(blackboard: Dictionary) -> void:
var world: World = blackboard["world"]
var player: PlayerManager = blackboard["player"]
if tilemap_types.is_part_of_collection(tilemap_types.OBJECT_COLLECTION_BOAT_PARTS, player.inventory_slot):
EventsTracker.track(EventsTracker.Event.CAMP_BOAT_PART_DELIVERED, {"item": player.inventory_slot})
world.camp_manager.boat_items.append(player.inventory_slot)
player.inventory_slot = tilemap_types.EMPTY
if world.camp_manager.boat_items.size() >= world.camp_manager.required_boat_parts:
EventsTracker.track(EventsTracker.Event.CAMP_BOAT_COMPLETE, {"item": tilemap_types.OBJECT_I_BOAT_WITH_ENGINE})
world.tilemap_interactive.set_cell(world.camp_manager.boat_build_location, tilemap_types.OBJECT_I_BOAT_WITH_ENGINE)
status = SUCCESS
status_reason = "Player delivered boat part"
return
status = FAILURE
status_reason = "Player does not have boat part to deliver"

View File

@ -0,0 +1,35 @@
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:
status = FAILURE
status_reason = "No boat parts found"
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:
status = FAILURE
status_reason = "No closest boat part found"
return
blackboard["closest_part"] = closest_part
var path: Array[Vector2i] = navigation.find_path_allow_neighbors(player.board_position, closest_part, player.view_distance)
if path.size() > 0:
blackboard["path"] = path
status_reason = "Found path to closest boat part"
status = SUCCESS
return
status = FAILURE
status_reason = "No path found to closest boat part " + str(closest_part)

View File

@ -0,0 +1,20 @@
class_name TaskGoToBoatLeaveLocation
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
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)

View File

@ -0,0 +1,20 @@
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
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)

View File

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

View File

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

View File

@ -0,0 +1,15 @@
class_name TaskPickupBoat
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:
status = FAILURE
status_reason = "Boat is not on the map"
return
player.pick_up_item(world.camp_manager.boat_build_location)
status = SUCCESS
status_reason = "Picked up boat"

View File

@ -0,0 +1,12 @@
class_name TaskPickupBoatPart
extends Task
func run(blackboard: Dictionary) -> void:
var player: PlayerManager = blackboard["player"]
var closest_part: Vector2i = blackboard["closest_part"]
player.pick_up_item(closest_part)
player.player_memory.erase("boat_part")
status = SUCCESS
status_reason = "Picked up boat part"

View File

@ -4,10 +4,13 @@ extends Node2D
static var game_manager: GameManager static var game_manager: GameManager
static var world: World static var world: World
# #
enum LineType { SEARCH_BASE, SEARCH_SELECTED } enum LineType { SEARCH_BASE, SEARCH_SELECTED, SEARCH_FAILED }
enum CircleType { PLAYER_VIEW }
# #
# Dictionary[Array[Vector2i], LineType] ([from, to], line_type) # Dictionary[Array[Vector2i], LineType] ([from, to], line_type)
static var draw_lines: Dictionary = {} static var draw_lines: Dictionary = {}
# Dictionary[Array[Vector2i], CircleType] ([center, radius], circle_type)
static var draw_circles: Dictionary = {}
static func add_line(from: Vector2i, to: Vector2i, line_type: LineType) -> void: static func add_line(from: Vector2i, to: Vector2i, line_type: LineType) -> void:
@ -20,8 +23,19 @@ static func add_line_tileset(from: Vector2i, to: Vector2i, line_type: LineType)
draw_lines[[from_tileset, to_tileset]] = line_type draw_lines[[from_tileset, to_tileset]] = line_type
static func add_circle(center: Vector2i, radius: int, circle_type: CircleType) -> void:
draw_circles[[center, radius]] = circle_type
static func add_circle_tileset(center: Vector2i, radius: int, circle_type: CircleType) -> void:
var center_tileset: Vector2i = world.tilemap_ground.cell_to_local(center)
radius *= world.tilemap_ground.tilemap.tile_set.tile_size.x
draw_circles[[center_tileset, radius]] = circle_type
func game_tick_start(): func game_tick_start():
draw_lines.clear() draw_lines.clear()
draw_circles.clear()
func game_tick_end(): func game_tick_end():
@ -29,7 +43,7 @@ func game_tick_end():
var label_font = Control.new().get_theme_default_font() var label_font = Control.new().get_theme_default_font()
@export var default_line_color: Color = Color("red") @export var default_color: Color = Color("red")
func _ready() -> void: func _ready() -> void:
@ -37,7 +51,6 @@ func _ready() -> void:
func _draw() -> void: func _draw() -> void:
# draw all draw_lines with their labels
for key in draw_lines.keys(): for key in draw_lines.keys():
var from: Vector2i = key[0] var from: Vector2i = key[0]
var to: Vector2i = key[1] var to: Vector2i = key[1]
@ -47,6 +60,13 @@ func _draw() -> void:
draw_line(from, to, Color("blue"), 1) draw_line(from, to, Color("blue"), 1)
elif line_type == LineType.SEARCH_SELECTED: elif line_type == LineType.SEARCH_SELECTED:
draw_line(from, to, Color("green"), 2) draw_line(from, to, Color("green"), 2)
elif line_type == LineType.SEARCH_FAILED:
draw_line(from, to, Color(255, 0, 0, 0.1), 1)
# var center: Vector2 = (from + to) / 2 for key in draw_circles.keys():
# draw_string(label_font, center, label, 0, -1, 12, text_color) 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)

View File

@ -1,6 +1,8 @@
class_name TileMapLayerAccess class_name TileMapLayerAccess
extends Node extends Node
var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
#
var tilemap: TileMapLayer = null var tilemap: TileMapLayer = null
var sid: int = 0 var sid: int = 0
@ -17,15 +19,15 @@ func get_cells_by_type(
if max_distance < 99999999: if max_distance < 99999999:
var filtered_tiles: Array[Vector2i] = [] var filtered_tiles: Array[Vector2i] = []
for tile in tiles_with_type: for tile in tiles_with_type:
if TilemapNavigation.manhattan_distance(center, tile, true) <= max_distance: if TilemapNavigation.is_within_radius(center, tile, max_distance, true):
filtered_tiles.append(tile) filtered_tiles.append(tile)
return filtered_tiles return filtered_tiles
return tiles_with_type return tiles_with_type
func get_cells_by_type_collection( func get_cells_by_type_collection(
atlas_coords: Array[Vector2i], atlas_coords: Array[Vector2i],
center: Vector2i = Vector2i(-1, -1), max_distance: int = 99999999 center: Vector2i = Vector2i(-1, -1), max_distance: int = 99999999
) -> Array[Vector2i]: ) -> Array[Vector2i]:
var tiles_with_type: Array[Vector2i] = [] var tiles_with_type: Array[Vector2i] = []
for coords in atlas_coords: for coords in atlas_coords:
@ -33,7 +35,7 @@ func get_cells_by_type_collection(
if max_distance < 99999999: if max_distance < 99999999:
var filtered_tiles: Array[Vector2i] = [] var filtered_tiles: Array[Vector2i] = []
for tile in tiles_with_type: for tile in tiles_with_type:
if TilemapNavigation.manhattan_distance(center, tile, true) <= max_distance: if TilemapNavigation.is_within_radius(center, tile, max_distance, true):
filtered_tiles.append(tile) filtered_tiles.append(tile)
return filtered_tiles return filtered_tiles
return tiles_with_type return tiles_with_type
@ -67,6 +69,8 @@ func get_cell(position: Vector2i) -> TileData:
func get_cell_atlas_coords(position: Vector2i) -> Vector2i: func get_cell_atlas_coords(position: Vector2i) -> Vector2i:
if not get_cell(position):
return tilemap_types.NO_TILE_FOUND
return tilemap.get_cell_atlas_coords(position) return tilemap.get_cell_atlas_coords(position)

View File

@ -10,7 +10,6 @@ const GROUND_WATER_SHALLOW: Vector2i = Vector2i(1, 0)
const GROUND_WATER_DEEP: Vector2i = Vector2i(2, 0) const GROUND_WATER_DEEP: Vector2i = Vector2i(2, 0)
const GROUND_SAND: Vector2i = Vector2i(3, 0) const GROUND_SAND: Vector2i = Vector2i(3, 0)
const GROUND_DOCK: Vector2i = Vector2i(3, 0) const GROUND_DOCK: Vector2i = Vector2i(3, 0)
const GROUND_SNOW: Vector2i = Vector2i(4,0)
# #
# objects, sid = 1 # objects, sid = 1
# NI = not interactive # NI = not interactive
@ -20,10 +19,10 @@ const OBJECT_NI_ROCK_1: Vector2i = Vector2i(2, 0)
# #
# I = interactive # I = interactive
# boat # boat
const OBJECT_I_BOAT_NO_ENIGNE: Vector2i = Vector2i(4, 4) const OBJECT_I_BOAT_NO_ENIGNE: Vector2i = Vector2i(0, 4)
const OBJECT_I_BOAT_WITH_ENGINE: Vector2i = Vector2i(6, 4) const OBJECT_I_BOAT_WITH_ENGINE: Vector2i = Vector2i(2, 4)
# boat parts # boat parts
const OBJECT_I_BOAT_PART_GENERIC: Vector2i = Vector2i(4584, 5234) const OBJECT_I_BOAT_PART_GENERIC: Vector2i = Vector2i(1, 1)
const OBJECT_I_BOAT_PART_ENGINE: Vector2i = Vector2i(0, 1) const OBJECT_I_BOAT_PART_ENGINE: Vector2i = Vector2i(0, 1)
const OBJECT_I_BOAT_PART_FUEL: Vector2i = Vector2i(1, 1) const OBJECT_I_BOAT_PART_FUEL: Vector2i = Vector2i(1, 1)
const OBJECT_I_BOAT_PART_ANCHOR: Vector2i = Vector2i(2, 1) const OBJECT_I_BOAT_PART_ANCHOR: Vector2i = Vector2i(2, 1)
@ -53,6 +52,7 @@ const OBJECT_COLLECTION_BOAT_PARTS: Array[Vector2i] = [ # @formatter:off
OBJECT_I_BOAT_PART_CHEST, OBJECT_I_BOAT_PART_GEARS, OBJECT_I_BOAT_PART_MEDIKIT, OBJECT_I_BOAT_PART_CHEST, OBJECT_I_BOAT_PART_GEARS, OBJECT_I_BOAT_PART_MEDIKIT,
OBJECT_I_BOAT_PART_PADDLE, OBJECT_I_BOAT_PART_GAS_STOVE OBJECT_I_BOAT_PART_PADDLE, OBJECT_I_BOAT_PART_GAS_STOVE
] # @formatter:on ] # @formatter:on
const OBJECT_COLLECTION_BOAT: Array[Vector2i] = [OBJECT_I_BOAT_NO_ENIGNE, OBJECT_I_BOAT_WITH_ENGINE]
# #
# temperature, sid = 2 # temperature, sid = 2
const TEMPERATURE_NORMAL: Vector2i = Vector2i(2, 0) const TEMPERATURE_NORMAL: Vector2i = Vector2i(2, 0)
@ -83,3 +83,6 @@ func player_sprite_from_direction(direction: Vector2i) -> Vector2i:
if direction == Vector2i(1, 0): if direction == Vector2i(1, 0):
return PLAYER_RIGHT return PLAYER_RIGHT
return PLAYER_DOWN return PLAYER_DOWN
func is_part_of_collection(collection: Array[Vector2i], item: Vector2i) -> bool:
return collection.find(item) != -1

View File

@ -32,15 +32,18 @@ func game_tick_end() -> void:
world.tilemap_nav_vis.set_cell(chosen_path[chosen_path.size() - 1], tilemap_types.NAVIGATION_TARGET) world.tilemap_nav_vis.set_cell(chosen_path[chosen_path.size() - 1], tilemap_types.NAVIGATION_TARGET)
func is_within_radius(position: Vector2i, center: Vector2i, radius: int, record: bool = false) -> bool: static func is_within_radius(position: Vector2i, center: Vector2i, radius: int, record: bool = false) -> bool:
return TilemapNavigation.manhattan_distance(position, center, record) <= radius var is_within: bool = TilemapNavigation.manhattan_distance(position, center) <= radius
static func manhattan_distance(a: Vector2i, b: Vector2i, record: bool = false) -> int:
var dist: int = abs(a.x - b.x) + abs(a.y - b.y)
if record: if record:
StepVisualization.add_line_tileset(a, b, StepVisualization.LineType.SEARCH_BASE) if is_within:
return dist StepVisualization.add_line_tileset(center, position, StepVisualization.LineType.SEARCH_BASE)
else:
StepVisualization.add_line_tileset(center, position, StepVisualization.LineType.SEARCH_FAILED)
return is_within
static func manhattan_distance(a: Vector2i, b: Vector2i) -> int:
return abs(a.x - b.x) + abs(a.y - b.y)
func manhattan_distance_closest(options: Array[Vector2i], target: Vector2i) -> Vector2i: func manhattan_distance_closest(options: Array[Vector2i], target: Vector2i) -> Vector2i:

View File

@ -6,9 +6,14 @@ var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
var game_manager: GameManager = null var game_manager: GameManager = null
var tilemap_interactive: TileMapLayerAccess = null var tilemap_interactive: TileMapLayerAccess = null
# #
var items: Array[Vector2i] = [] var camp_items: Array[Vector2i] = []
var camp: Vector2i = Vector2i(0, 0) var boat_items: Array[Vector2i] = []
var campfire: Vector2i = Vector2i(0, 0) 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
@export var required_boat_parts: int = 3
func setup() -> void: func setup() -> void:
@ -18,30 +23,45 @@ func setup() -> void:
camp = camp_locations[0] camp = camp_locations[0]
else: else:
push_error("No camp location found on tilemap") push_error("No camp location found on tilemap")
var firepit_locations: Array[Vector2i] = tilemap_interactive.get_cells_by_type_collection(tilemap_types.OBJECT_COLLECTION_FIREPIT) var firepit_locations: Array[Vector2i] = tilemap_interactive.get_cells_by_type_collection(tilemap_types.OBJECT_COLLECTION_FIREPIT)
if len(firepit_locations) > 0: if len(firepit_locations) > 0:
campfire = firepit_locations[0] campfire = firepit_locations[0]
else: else:
push_error("No firepit location found on tilemap") push_error("No firepit location found on tilemap")
var boat_build_locations: Array[Vector2i] = tilemap_interactive.get_cells_by_type(tilemap_types.OBJECT_I_BOAT_NO_ENIGNE)
if len(boat_build_locations) > 0:
boat_build_location = boat_build_locations[0]
else:
push_error("No boat build location found on tilemap")
var boat_leave_locations: Array[Vector2i] = tilemap_interactive.get_cells_by_type(tilemap_types.OBJECT_I_BOAT_WITH_ENGINE)
if len(boat_leave_locations) > 0:
boat_leave_location = boat_leave_locations[0]
tilemap_interactive.set_cell(boat_leave_location, tilemap_types.EMPTY)
else:
push_error("No boat leave location found on tilemap")
print("CampManager: camp=", camp, " campfire=", campfire) print("CampManager: camp=", camp, " campfire=", campfire)
tilemap_interactive.set_cell(campfire, tilemap_types.OBJECT_I_FIREPIT_OFF) tilemap_interactive.set_cell(campfire, tilemap_types.OBJECT_I_FIREPIT_OFF)
func camp_contains_item(item: Vector2i) -> bool: func camp_contains_item(item: Vector2i) -> bool:
return items.find(item) != -1 return camp_items.find(item) != -1
func camp_contains_item_collection(item: Array[Vector2i]) -> bool: func camp_contains_item_collection(item: Array[Vector2i]) -> bool:
for i in item: for i in item:
if items.find(i) == -1: if camp_items.find(i) == -1:
return false return false
return true return true
func camp_item_count(item: Vector2i) -> int: func camp_item_count(item: Vector2i) -> int:
var count: int = 0 var count: int = 0
for i in items: for i in camp_items:
if i == item: if i == item:
count += 1 count += 1
return count return count
@ -49,7 +69,7 @@ func camp_item_count(item: Vector2i) -> int:
func camp_item_collection_count(item: Array[Vector2i]) -> int: func camp_item_collection_count(item: Array[Vector2i]) -> int:
var count: int = 0 var count: int = 0
for i in items: for i in camp_items:
if item.find(i) != -1: if item.find(i) != -1:
count += 1 count += 1
return count return count
@ -62,9 +82,9 @@ 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(items.size()): for i in range(camp_items.size()):
if items[i] == item: if camp_items[i] == item:
items.remove_at(i) camp_items.remove_at(i)
taken += 1 taken += 1
if taken == count: if taken == count:
break break
@ -74,7 +94,7 @@ func camp_take_item(item: Vector2i, count: int = 1) -> bool:
func camp_add_item(item: Vector2i) -> void: func camp_add_item(item: Vector2i) -> void:
items.append(item) camp_items.append(item)
EventsTracker.track(EventsTracker.Event.CAMP_ADDED_ITEM, {"item": item, "count": 1, "new_count": camp_item_count(item)}) EventsTracker.track(EventsTracker.Event.CAMP_ADDED_ITEM, {"item": item, "count": 1, "new_count": camp_item_count(item)})