extends CharacterBody2D class_name Player @export var SPEED := 4 var last_direction = 0 var interaction_location: Vector2i var _interaction_options: InteractionWheel var _interacting := false var _attempting_build: Building var _build_placement: Sprite2D var _in_menu := false var _skills := Skills.new() @onready var sprite: AnimatedSprite2D = $Sprite @onready var interaction_timer: Timer = $InteractionTimer const INTERACTION_BAR = preload("res://scene/interaction_bar.tscn") const BUILD_MENU = preload("res://scene/build_menu.tscn") const BUILDING_BASE = preload("res://data/buildings/building_base.tscn") func _physics_process(delta: float) -> void: var input_direction := Input.get_vector("move_left", "move_right", "move_up", "move_down") if not _in_menu else Vector2.ZERO velocity = input_direction * SPEED / delta move_and_slide() if input_direction: if _interaction_options: _interaction_options.queue_free() _on_interation_options_closed() sprite.play("walk") last_direction = input_direction.angle() + PI / 2 rotation = last_direction interaction_location = Grid.world_to_grid(position) + Vector2i(input_direction.round()) Grid.set_selected_tile(interaction_location) else: sprite.stop() if _build_placement: _build_placement.position = Grid.grid_to_world_center(interaction_location) _build_placement.self_modulate = Color(0, 1, 0, 0.5) if Grid.get_location_data(interaction_location).is_buildable() else Color(1, 0, 0, 0.4) func _input(event: InputEvent) -> void: if event.is_action_pressed("interact"): var interact_data: CellData = Grid.get_location_data(interaction_location) if _attempting_build and interact_data.is_buildable(): _build() elif not _interacting and interact_data.is_interactable(): if interact_data.has_resource(): if interact_data.get_resource().can_harvest(_skills): var interaction = INTERACTION_BAR.instantiate() interaction.interaction_finished.connect(_on_interaction_finished) interaction.grid_position = interaction_location _interacting = true add_sibling(interaction) else: # TODO add toast message print("Research needed") elif interact_data.has_building(): _in_menu = interact_data.get_building().interact(_on_interaction_finished) if event.is_action_pressed("build"): var build_menu = BUILD_MENU.instantiate() build_menu.build.connect(_on_build_menu_build) add_sibling(build_menu) _in_menu = true func _on_interaction_finished() -> void: _interacting = false _in_menu = false func _on_build_menu_build(building: Building) -> void: print("Building: %s" % building.name) _in_menu = false _attempting_build = building _build_placement = Sprite2D.new() _build_placement.texture = _attempting_build.atlas_texture _build_placement.self_modulate = Color(1, 0, 0, 0.4) add_sibling(_build_placement) func _build() -> void: ResourceManager.use_resources(_attempting_build.cost) var build: BuildingBase = BUILDING_BASE.instantiate() add_sibling(build) build.initialize(_attempting_build, interaction_location) Grid.change_location_building(interaction_location, build) if not ResourceManager.has_resources(_attempting_build.cost): _attempting_build = null _build_placement.queue_free() _build_placement = null func _on_interation_options_closed() -> void: _interaction_options = null func _unhandled_input(event): if event is InputEventMouseButton: match event.button_index: MOUSE_BUTTON_WHEEL_DOWN: $Camera2D.zoom -= Vector2(0.01, 0.01) MOUSE_BUTTON_WHEEL_UP: $Camera2D.zoom += Vector2(0.01, 0.01)