148 lines
4.4 KiB
GDScript
148 lines
4.4 KiB
GDScript
class_name Player
|
|
extends CharacterBody2D
|
|
|
|
const WEAPON_SWORD = preload("res://scenes/weapons/weapon_sword.tscn")
|
|
|
|
@export var camera: Camera2D
|
|
@export var main_ui: MainUI
|
|
|
|
var weapon: WeaponBase
|
|
|
|
@onready var sprite_2d: Sprite2D = $Sprite2D
|
|
|
|
var player_stats: PlayerStats = PlayerStats.new()
|
|
var modifiers: Array[PlayerStatsModifier] = []
|
|
var dead: bool = false
|
|
var death_anim_done: bool = false
|
|
var god_mode: bool = false
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event.is_action_pressed("active"):
|
|
weapon.do_active()
|
|
|
|
|
|
func _ready() -> void:
|
|
camera.position = global_position
|
|
main_ui.player_ui.update_hp()
|
|
GlobalConst.sig_debug_god_mode.connect(toggle_god_mode)
|
|
if not weapon:
|
|
weapon = WEAPON_SWORD.instantiate()
|
|
add_child(weapon)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if dead:
|
|
return
|
|
var input_direction = Input.get_vector("left", "right", "up", "down")
|
|
var move_speed = player_stats.get_final("move_speed", modifiers)
|
|
velocity = input_direction * move_speed
|
|
move_and_slide()
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
camera.position_smoothing_enabled = true
|
|
camera.position = global_position
|
|
if dead and !death_anim_done:
|
|
death_animation(delta)
|
|
|
|
|
|
func take_damage(value: float) -> void:
|
|
if dead or god_mode:
|
|
return
|
|
player_stats.current_health -= value
|
|
player_stats.current_health = clampf(
|
|
player_stats.current_health, -1.0, player_stats.get_final("max_health", modifiers)
|
|
)
|
|
var current_hp = player_stats.get_final("current_health", modifiers)
|
|
var max_hp = player_stats.get_final("max_health", modifiers)
|
|
GlobalConst.sig_debug_stats_set.emit("current_health", "%f" % current_hp)
|
|
GlobalConst.sig_debug_stats_set.emit("max_hp", "%f" % max_hp)
|
|
|
|
var dm = preload("res://scenes/damage_numbers.tscn").instantiate()
|
|
dm.damage_taken = value
|
|
dm.player_damage = false
|
|
add_child(dm)
|
|
GlobalConst.sig_on_player_hp_change.emit(current_hp, max_hp)
|
|
main_ui.player_ui.update_hp()
|
|
if player_stats.current_health <= 0:
|
|
die()
|
|
|
|
|
|
func die():
|
|
dead = true
|
|
remove_from_group("damagable")
|
|
get_tree().call_group("enemy", "cheer")
|
|
GlobalConst.sig_stop_spawning.emit(true)
|
|
sprite_2d.z_index += 10
|
|
get_taunted()
|
|
|
|
|
|
func death_animation(delta: float):
|
|
# Engine.time_scale = clampf(lerpf(Engine.time_scale, 0.25, 0.5), 0.25, 0.9*delta)
|
|
camera.zoom = lerp(camera.zoom, Vector2(8, 8), 0.99 * delta)
|
|
rotation_degrees = lerpf(rotation_degrees, 90, 0.99 * delta)
|
|
if rotation_degrees > 88:
|
|
main_ui.pause_ui.toggle_pause_ui()
|
|
death_anim_done = true
|
|
|
|
|
|
func get_taunted():
|
|
var taunting_enemies: Array[EnemyBase] = []
|
|
for body in get_tree().get_nodes_in_group(GlobalConst.GROUP_ENEMY):
|
|
print_debug("starting taunt: %s" % global_position.distance_to(body.global_position))
|
|
if global_position.distance_to(body.global_position) < 1000.0:
|
|
taunting_enemies.append(body)
|
|
print_debug("getting taunted by %s enemies" % len(taunting_enemies))
|
|
for i in range(taunting_enemies.size()):
|
|
var angle = (TAU / taunting_enemies.size()) * i
|
|
var target_pos = Vector2(cos(angle), sin(angle)) * 50
|
|
var new_target = Marker2D.new()
|
|
print_debug("getting taunted by %s" % taunting_enemies[i])
|
|
new_target.position = target_pos
|
|
add_child(new_target)
|
|
taunting_enemies[i].target = new_target
|
|
|
|
|
|
func toggle_god_mode(value: bool):
|
|
god_mode = value
|
|
|
|
|
|
func add_xp(amount: float) -> void:
|
|
player_stats.current_xp += amount
|
|
main_ui.player_ui.update_xp()
|
|
_check_level_up()
|
|
|
|
|
|
func _check_level_up() -> void:
|
|
var required_for_level = player_stats.xp_required_for_level()
|
|
if player_stats.current_xp >= required_for_level:
|
|
player_stats.current_level += 1
|
|
player_stats.current_xp -= required_for_level
|
|
_trigger_level_up()
|
|
|
|
|
|
func _trigger_level_up() -> void:
|
|
var choice_count = 3
|
|
var choices: Array[LevelUpChoice] = []
|
|
main_ui.level_up_ui.clear()
|
|
for i in range(choice_count):
|
|
# TODO: implement fortune
|
|
var mod = GlobalConst.draw_random_mod(1.0)
|
|
var l_choice = preload("res://scenes/managers/ui/level_up_choice.tscn").instantiate()
|
|
l_choice.mod = mod
|
|
l_choice.player = self
|
|
main_ui.level_up_ui.add_choice(l_choice)
|
|
Engine.time_scale = 0.0
|
|
main_ui.level_up_ui.visible = true
|
|
|
|
|
|
func _on_pickup_area_area_entered(area: Area2D) -> void:
|
|
var body: Node2D = area.get_parent()
|
|
if body.is_in_group(GlobalConst.GROUP_XP_ORB):
|
|
add_xp(body.value)
|
|
GlobalConst.sig_debug_stats_set.emit("player_xp", "%s" % player_stats.current_xp)
|
|
body.queue_free()
|
|
elif body.is_in_group(GlobalConst.GROUP_PICKUP):
|
|
body.pickup()
|