195 lines
6.6 KiB
GDScript
195 lines
6.6 KiB
GDScript
class_name PlayerManager
|
|
extends Node
|
|
|
|
@onready var inventory_label: Label = %InventoryLabel
|
|
|
|
@export var food_damage: int = 1
|
|
@export var temperature_damage: int = 1
|
|
@export var temperature_endure: int = 50
|
|
@export var view_distance: int = 50
|
|
|
|
var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
|
|
#
|
|
var game_manager: GameManager = null
|
|
var board_position: Vector2i = Vector2i(8, 10)
|
|
|
|
@onready var behavior_tree: BehaviorTree = $BehaviorTree
|
|
|
|
var food: int = 0
|
|
# var water: int = 0
|
|
var temperature_timer: int = 0
|
|
var health: int = 0
|
|
#
|
|
var inventory_slot: Vector2i = tilemap_types.EMPTY
|
|
|
|
|
|
func _ready() -> void:
|
|
call_deferred("defer_ready")
|
|
|
|
|
|
func defer_ready() -> void:
|
|
behavior_tree.game_manager = game_manager
|
|
update_board()
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if Input.is_action_just_pressed("key_3"):
|
|
game_manager.camera.go_to_zooming(game_manager.world.tilemap_player.cell_to_local(board_position), 2)
|
|
if Input.is_action_just_pressed("key_5"):
|
|
pick_up_item(Vector2i(5, 8))
|
|
pick_up_item(Vector2i(9, 9))
|
|
update_board()
|
|
if Input.is_action_just_pressed("key_4"):
|
|
var nearest: Vector2i = find_nearest_object([game_manager.world.tilemap_types.OBJECT_I_TREE_1])
|
|
# nearest.x = nearest.x - 1
|
|
walk_towards(nearest)
|
|
update_board()
|
|
|
|
|
|
# SECTION: board access/mangement
|
|
|
|
func update_board() -> void:
|
|
game_manager.world.tilemap_player.clear_cells()
|
|
game_manager.world.tilemap_player.set_cell(board_position, tilemap_types.PLAYER)
|
|
if inventory_slot and inventory_slot != tilemap_types.EMPTY:
|
|
inventory_label.text = str(inventory_slot)
|
|
else:
|
|
inventory_label.text = "empty"
|
|
|
|
|
|
# SECTION: inventory system
|
|
|
|
func pick_up_item(tilemap_pos: Vector2i) -> void:
|
|
var pick_up_cell: TileData = game_manager.world.tilemap_interactive.get_cell(tilemap_pos)
|
|
if not pick_up_cell:
|
|
push_warning("Player trying to pick up item that does not exist at ", tilemap_pos)
|
|
return
|
|
|
|
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
|
|
var tile_after_pickup_transform = null
|
|
var tile_drop_item: Vector2i = inventory_slot
|
|
if tilemap_types.OBJECT_I_FILLED_BUSH == pick_up_item_type:
|
|
tile_after_pickup_transform = tilemap_types.OBJECT_I_EMPTY_BUSH
|
|
pick_up_item_type = tilemap_types.OBJECT_I_BERRY
|
|
tile_drop_item = tilemap_types.OBJECT_I_BERRY
|
|
|
|
# check if the inventory slot is empty
|
|
if inventory_slot == tilemap_types.EMPTY:
|
|
inventory_slot = pick_up_item_type
|
|
if tile_after_pickup_transform:
|
|
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_after_pickup_transform)
|
|
else:
|
|
game_manager.world.tilemap_interactive.clear_cell(tilemap_pos)
|
|
print("Picked up item: ", pick_up_item_type)
|
|
else:
|
|
# inventory is full, swap the item
|
|
print("Inventory is full. Swapping item: ", inventory_slot, " with item: ", pick_up_item_type)
|
|
if tile_after_pickup_transform:
|
|
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_after_pickup_transform)
|
|
var drop_location: Vector2i = game_manager.world.find_item_drop_location(tilemap_pos)
|
|
if drop_location != tilemap_types.EMPTY:
|
|
game_manager.world.tilemap_interactive.set_cell(drop_location, tile_drop_item)
|
|
else:
|
|
push_warning("Could not find valid drop position for ", inventory_slot)
|
|
else:
|
|
game_manager.world.tilemap_interactive.set_cell(tilemap_pos, tile_drop_item)
|
|
inventory_slot = pick_up_item_type
|
|
|
|
|
|
# SECTION: player movement
|
|
|
|
func walk_towards(position: Vector2i) -> void:
|
|
var path: Array[Vector2i] = game_manager.world.find_path(board_position, position)
|
|
walk_along(path)
|
|
|
|
|
|
func walk_along(path: Array[Vector2i]) -> void:
|
|
if len(path) > 1:
|
|
var next_position: Vector2i = path[1]
|
|
var direction: Vector2i = find_direction(board_position, next_position)
|
|
move_player(direction)
|
|
else:
|
|
push_warning("walk_along path is empty")
|
|
|
|
|
|
func move_player(direction: Vector2i) -> void:
|
|
var new_position: Vector2 = board_position + direction
|
|
if game_manager.world.is_walkable(new_position):
|
|
board_position = new_position
|
|
else:
|
|
push_warning("Player trying to move to non-walkable position, prevented ", new_position)
|
|
|
|
|
|
func find_nearest_object(object_collection: Array[Vector2i]) -> Vector2i:
|
|
var object_positions: Array[Vector2i] = []
|
|
|
|
for obj in object_collection:
|
|
object_positions.append_array(game_manager.world.tilemap_interactive.get_cells_by_type(obj))
|
|
|
|
if object_positions.size() == 0:
|
|
push_warning("No " + str(object_collection) + " found!")
|
|
return tilemap_types.NO_TILE_FOUND
|
|
|
|
var closest_object: Vector2i = tilemap_types.NO_TILE_FOUND
|
|
var shortest_distance: float = 99999999
|
|
|
|
for position in object_positions:
|
|
var distance: float = game_manager.world.manhattan_distance(board_position, position)
|
|
if closest_object == tilemap_types.NO_TILE_FOUND or distance < shortest_distance:
|
|
closest_object = position
|
|
shortest_distance = distance
|
|
|
|
print("Find nearest " + str(object_collection) + " at:", closest_object)
|
|
return closest_object
|
|
|
|
|
|
func find_direction(pos_a: Vector2i, pos_b: Vector2i) -> Vector2i:
|
|
var direction: Vector2i = Vector2i(0, 0)
|
|
if pos_a.x < pos_b.x:
|
|
direction.x = 1
|
|
elif pos_a.x > pos_b.x:
|
|
direction.x = -1
|
|
|
|
if pos_a.y < pos_b.y:
|
|
direction.y = 1
|
|
elif pos_a.y > pos_b.y:
|
|
direction.y = -1
|
|
|
|
return direction
|
|
|
|
|
|
# SECTION: game tick
|
|
|
|
func tick_handle_temperature(cell_temperature: int):
|
|
if cell_temperature == 0:
|
|
temperature_timer = 0
|
|
elif temperature_timer > temperature_endure:
|
|
temperature_timer += cell_temperature
|
|
health -= temperature_damage
|
|
|
|
|
|
func tick_handle_food():
|
|
if food <= 0:
|
|
health -= food_damage
|
|
|
|
|
|
func game_tick() -> void:
|
|
behavior_tree.game_tick()
|
|
|
|
var player_positon_array: Array[Vector2i] = game_manager.world.tilemap_player.get_cells_by_type(tilemap_types.PLAYER)
|
|
if len(player_positon_array) > 0:
|
|
var player_positon: Vector2i = player_positon_array[0]
|
|
var cell_temperature: int = game_manager.world.tilemap_temperature.get_custom_data(player_positon, "temperature", 0) as int
|
|
tick_handle_temperature(cell_temperature)
|
|
else:
|
|
push_error("No player found on tilemap")
|
|
|
|
tick_handle_food()
|
|
|
|
if health < 0:
|
|
game_manager.player_health_depleted()
|
|
|
|
update_board()
|