93 lines
2.7 KiB
GDScript
93 lines
2.7 KiB
GDScript
class_name Adventurer extends CharacterBody2D
|
|
|
|
const popup_template = preload("res://profile_popup.tscn")
|
|
var profile_popup
|
|
|
|
@onready var bt_player : BTPlayer = $BTPlayer
|
|
@export var movement_speed : float = 400.0
|
|
@onready var movement_target_position : Vector2 = global_position
|
|
@onready var nav_agent : NavigationAgent2D = $NavigationAgent2D
|
|
|
|
var data : AdventurerData = null
|
|
var interaction_target = null
|
|
var last_position : Vector2 = Vector2.ZERO
|
|
var stuck : bool = false
|
|
var stuck_time_remaining : float = 0
|
|
@onready var bubble : SpeechBubble = $SpeechBubble
|
|
@export var interaction_range : float = 75
|
|
@export var stop_range : float = 25
|
|
|
|
signal navigation_finished()
|
|
signal navigation_failed()
|
|
|
|
func _ready() -> void:
|
|
nav_agent.navigation_finished.connect(_on_nav_agent_finished)
|
|
pass
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if nav_agent.is_navigation_finished():
|
|
if interaction_target:
|
|
try_interact(interaction_target)
|
|
#If they have an interaction target within range
|
|
#clear the target
|
|
#try_interact
|
|
return
|
|
var curr_pos: Vector2 = global_position
|
|
var next_path_pos: Vector2 = nav_agent.get_next_path_position()
|
|
|
|
velocity = curr_pos.direction_to(next_path_pos) * movement_speed
|
|
move_and_slide()
|
|
#If they virtually didn't move
|
|
if !stuck:
|
|
if (global_position - last_position).length_squared() < 5:
|
|
stuck = true
|
|
stuck_time_remaining = 1
|
|
else:
|
|
if stuck_time_remaining > 0:
|
|
stuck_time_remaining -= delta
|
|
if stuck_time_remaining <= 0:
|
|
nav_agent.target_position = global_position
|
|
navigation_failed.emit()
|
|
last_position = global_position
|
|
|
|
func approach(pos : Vector2) -> void:
|
|
stuck = false
|
|
var rid = get_world_2d().get_navigation_map()
|
|
var point : Vector2 = NavigationServer2D.map_get_closest_point(rid, pos)
|
|
set_movement_target(point)
|
|
|
|
func approach_and_interact(obj : Interactable) -> void:
|
|
set_movement_target(obj.global_position)
|
|
nav_agent.target_desired_distance = interaction_range - 5
|
|
interaction_target = obj
|
|
|
|
func try_interact(obj : Interactable) -> void:
|
|
var df = obj.global_position - global_position
|
|
if df.length() > interaction_range:
|
|
approach_and_interact(obj)
|
|
else:
|
|
interact(obj)
|
|
interaction_target = null
|
|
|
|
func interact(obj : Interactable) -> void:
|
|
obj.interact(self)
|
|
|
|
func set_movement_target(target : Vector2) -> void:
|
|
nav_agent.target_position = target
|
|
|
|
func show_speech_bubble(bubble_type : String) -> void:
|
|
bubble.try_show_speech(bubble_type)
|
|
|
|
func _on_nav_agent_finished() -> void:
|
|
navigation_finished.emit()
|
|
|
|
|
|
func _on_mouse_entered() -> void:
|
|
profile_popup = popup_template.instantiate()
|
|
add_child(profile_popup)
|
|
profile_popup.setup(data.name, data.level, data.job, "Nothing")
|
|
|
|
|
|
func _on_mouse_exited() -> void:
|
|
profile_popup.queue_free()
|