Llhth-h-hno message
d61f56d5Add on Nov 19, 2025History
extends CharacterBody2D

var player 
var energy = 10
var damage = 1
@export var speed = 300
@export var teach_mode = false

var direction := Vector2.ZERO
var save_direction := Vector2.ZERO

var can_attack = true
var can_move = true
var can_roll = true
var Invincible = false
var can_use_props = true
var can_use_skill = true
var alive = true

@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D

signal mc_attack(kind)
signal health_update(heal,up)
signal energy_update(energy,up)
signal energy_warning

func attack():
	if $"../Gaming_UI".open_bag == false and $"../Gaming_UI".paused == false :
		if randi_range(0, 1) == 0 :
			$audio/AudioStreamPlayer_sword.play()
		else :
			$audio/AudioStreamPlayer_sword2.play()
		use_sword()
		mc_attack.emit("norm")

func dash_attack():
	if $"../Gaming_UI".open_bag == false and $"../Gaming_UI".paused == false :
		if randi_range(0, 1) == 0 :
			$audio/AudioStreamPlayer_sword.play()
		else :
			$audio/AudioStreamPlayer_sword2.play()
		jab_sword()
		mc_attack.emit("jab")
		

func _ready() -> void:
	call_deferred("ui_update")

func use_sword():
		speed = 30
		animated_sprite.play("attack")
		$leg.play("attack")
		can_attack = false
		#can_move = false
		$sword.attacking = true
		$sword/AnimationPlayer.play("wave_positive")
		$sword.show()	
		
		$attack_p.start()
		var mouse_ps = get_global_mouse_position()
		if mouse_ps.x < position.x:
			animated_sprite.flip_h = true
			$leg.flip_h = true
			$sword.scale.x = -1

		else :
			animated_sprite.flip_h = false
			$leg.flip_h = false
			$sword.scale.x = 1
func jab_sword():
		speed = 800
		animated_sprite.play("dash_attack")
		can_attack = false
		#can_move = false
		$sword.attacking = true
		$sword/AnimationPlayer.play("wave_positive")
		$sword.show()
		
		$attack_p.start()
		var mouse_ps = get_global_mouse_position()
		if mouse_ps.x < position.x:
			animated_sprite.flip_h = true
			$leg.flip_h = true
			$sword.scale.x = -1

		else :
			animated_sprite.flip_h = false
			$leg.flip_h = false
			$sword.scale.x = 1

func _physics_process(delta: float) -> void:
	#---------------------------------------
	Main.player_position = position
	#-------------------------------------direction
	
	if $AnimatedSprite2D.animation != "roll" and $AnimatedSprite2D.animation != "dash_attack":
		direction = Input.get_vector("left","right","up","down")
	
	if direction != Vector2.ZERO :
		save_direction = direction
	
	#-----------------------------------------------------
	if can_move  and Main.player_health > 0:
		if $AnimatedSprite2D.animation != "roll":
			position += direction * speed * delta
		else :
			position += save_direction * speed * delta
		move_and_slide()
#-------------------------idel
	if direction == Vector2.ZERO and $AnimatedSprite2D.animation != "attack" and $AnimatedSprite2D.animation != "roll" and Main.player_health > 0:
		animated_sprite.play("idel")
		$leg.play("idel")
#-------------------------run 
	if direction != Vector2.ZERO  and $AnimatedSprite2D.animation != "roll" and $AnimatedSprite2D.animation != "attack" and $AnimatedSprite2D.animation != "dash_attack" and Main.player_health > 0:
		if $AnimatedSprite2D.animation != "attack" and $AnimatedSprite2D.animation != "dash_attack":
			animated_sprite.play("run")
		
			if Input.is_action_pressed("left"):
				animated_sprite.flip_h = true
				$leg.flip_h = true
				$sword.scale.x = -1
			
			if Input.is_action_pressed("right"):
				animated_sprite.flip_h = false
				$leg.flip_h = false
				$sword.scale.x = 1
		$leg.play("run")	
	#---------------------attack
	
	if Input.is_action_pressed("attack") and can_attack and $"../Gaming_UI".open_bag == false and Main.player_health > 0:
		if $AnimatedSprite2D.animation != "roll" :
			call_deferred("attack")
		elif $AnimatedSprite2D.animation == "roll"  and $AnimatedSprite2D.frame <= 4:
			if energy >= 2.5: 
				energy -= 2.5
				energy_update.emit(energy,false)
				call_deferred("dash_attack")
			else :
				energy_warning.emit()
		
	#-------------------use_props
	if Input.is_action_pressed("throw_bomb") and can_use_props == true and "bomb" in Main.bag and $"../Gaming_UI".open_bag == false and Main.player_health > 0:
		can_use_props = false
		$use_props.start()
		var curve = $"..".mc_curve.instantiate()
		$"..".add_child(curve)
		curve.global_position = %player.global_position
		curve.throw("bomb",(get_global_mouse_position()-global_position).normalized())
		$"../Gaming_UI/bomb_button/AnimationPlayer".play("cd")
		Main.bag["bomb"] -= 1
		Main.bag_update("bomb")
		ui_update()

	if Input.is_action_pressed("throw_health_posion") and can_use_props == true and "health_posion" in Main.bag and $"../Gaming_UI".open_bag == false:
		can_use_props = false
		$use_props.start()
		var curve = $"..".mc_curve.instantiate()
		$"..".add_child(curve)
		curve.global_position = %player.global_position
		curve.throw("health_posion",(get_global_mouse_position()-global_position).normalized())
		$"../Gaming_UI/health_posion_button/AnimationPlayer".play("cd")
		Main.bag["health_posion"] -= 1
		Main.bag_update("health_posion")
		ui_update()
	#------------------dash
	if Input.is_action_pressed("roll") and can_roll == true and $AnimatedSprite2D.animation != "attack" and $AnimatedSprite2D.animation != "roll" and $AnimatedSprite2D.animation != "dash_attack" and $"../Gaming_UI".open_bag == false and Main.player_health > 0:
		if energy >= 2.5 :
			$audio/AudioStreamPlayer_dash.play()
			$dustFX.emitting = true
			energy -= 2.5
			energy_update.emit(energy,false)
			speed = 500
			animated_sprite.play("roll")
			$leg.play("roll")
			can_roll = false
			Invincible = true
			$InvincibleTime.start()
			$dashTime.start()
		else :
			energy_warning.emit()
	#------------------skill
	if Input.is_action_pressed("skill") and can_attack and $AnimatedSprite2D.animation != "roll" and can_use_skill == true and Main.equipped_gem != "" and $"../Gaming_UI".open_bag == false and Main.player_health > 0:
		can_use_skill = false
		if Main.gem_half_cd == true :
			$skill_cd.wait_time = 4
		if Main.skill_uncd == true and randi()%10 <=2:
			$skill_cd.wait_time = 0.1
		$skill_cd.start()
		$"../Gaming_UI/skill_button/AnimationPlayer".play("cd")
		if Main.gem_half_cd == true :
			$"../Gaming_UI/skill_button/AnimationPlayer".speed_scale = 2
		var skill_times = 1
		if Main.add_skill_times == true :
			skill_times +=1
		if Main.coin_skill_up == true and "coin" in Main.bag:
			skill_times += int(Main.bag["coin"]/20)
		
		for i in range(skill_times):
			$"..".call_deferred(str(Main.gem_skill))
			$skill_interval.start()
			await $skill_interval.timeout

func ui_update() :
		health_update.emit(Main.player_health,true)
		energy_update.emit(energy,false)
		$"../Gaming_UI".props_button_update()
		$"../Gaming_UI".skill_button_update()

func _on_attack_p_timeout() -> void:
	can_attack = true

func _on_animated_sprite_2d_animation_finished() -> void:
	if animated_sprite.animation == "attack" or animated_sprite.animation == "roll" or animated_sprite.animation == "dash_attack":
		reset_speed ()
		$sword.rotation = 0
		if direction != Vector2.ZERO :
			animated_sprite.play("idel")
			$leg.play("idel")
		else :
			animated_sprite.play("run")
			$leg.play("run")
			reset_speed ()
	can_move = true
	reset_speed ()
func reset_speed () :
	speed = 300
func hit(damage,back):
	var fb = Main.skill_feedback[back].instantiate()
	$"../..".add_child(fb)
	fb.global_position = $AnimatedSprite2D.global_position	
	fb.rotation = randi()%360
	
	if Invincible == false :
		if alive == true and teach_mode == false:
			$audio/AudioStreamPlayer_hit.play()
			$"../Gaming_UI/hitted_fx/AnimationPlayer".play("new_animation")
			$hitted.play("new_animation")
			$"..".shake(3)
			Main.player_health -= damage
		if Main.player_health <= 0 and alive == true:
			alive = false
			$pointer.hide()
			Main.player_health = 0
			$"..".death()
			animated_sprite.play("died")
			$dieFX.emitting = true
		health_update.emit(Main.player_health,false)

func HP_up():
	$HP_up_fx.emitting = true

func _on_invincible_time_timeout() -> void:
	
	Invincible = false

func _on_dash_time_timeout() -> void:
	speed = 300
	can_roll = true

func _on_energy_up_timeout() -> void:
	if energy < 10 :
		energy += 0.1
		energy_update.emit(energy,true)

func _on_use_props_timeout() -> void:
	can_use_props = true

func _on_skill_cd_timeout() -> void:
	can_use_skill = true