Compare commits
8 Commits
f27f1b944a
...
4763de9827
Author | SHA1 | Date |
---|---|---|
|
4763de9827 | |
|
238af1cc83 | |
|
cd82cf5bdf | |
|
2923738906 | |
|
8bbca6cef5 | |
|
7304b48f3c | |
|
9446c10556 | |
|
731ff9ed12 |
|
@ -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
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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, "]")
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
|
@ -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"
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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"
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)})
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue