Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.0 kB
6
Indexable
Never
extends CharacterBody2D

# Additional import
var CorpseScene = preload("res://Scenes/Corpse.tscn")

# Punching Variables
enum State {IDLE, MOVING, PUNCHING}
var state = State.IDLE
var punch_key = ""
var punch_damage = 10
var stamina_cost = 5
var bodies_in_hitbox = []
var hitbox_collision_shape
var punch_timer = 0 

var walk_speed = 30
var run_speed = 100
var current_speed = walk_speed
var follow_distance = 300
var minimum_distance = 26  # Adjust this value as needed
var player_follow = false
var player = null
var current_dir = "none"
var last_dir = "down"
var animated_sprite
var linear_velocity = Vector2.ZERO
var running = false

# Attributes
var maxHealth = 100
var currentHealth
var minHealth = 0
var maxStamina = 100
var currentStamina
var minStamina = 0

var hitbox

func _ready():
	add_to_group("npc")
	animated_sprite = get_node("AnimatedSprite2D")
	$healthbar.max_value = maxHealth
	currentHealth = maxHealth
	$healthbar.value = currentHealth
	$staminabar.max_value = maxStamina
	currentStamina = maxStamina
	$staminabar.value = currentStamina
	set_motion_mode(MOTION_MODE_FLOATING)
	hitbox = get_node("npc_hitbox")
	hitbox_collision_shape = hitbox.get_node("CollisionShape2D")
	$PunchTimer.connect("timeout", self._on_punch_timer_timeout)
	


func _physics_process(delta):
	update_running_state()
	if state != State.PUNCHING:
		move_and_slide()
	if player_follow:
		follow_player(delta)
		linear_velocity = velocity
		move_and_slide()
	else:
		velocity = Vector2.ZERO
	update_animation()
	
	punch_timer += delta
	if player in bodies_in_hitbox and punch_timer >= 1:
		perform_punch()
		punch_timer = 0


func follow_player(delta):
	var distance = global_position.distance_to(player.global_position)
	var target_velocity = Vector2.ZERO

	if distance <= follow_distance:
		target_velocity = (player.global_position - global_position).normalized() * current_speed
		if distance < minimum_distance:
			target_velocity = Vector2.ZERO

	velocity = velocity.lerp(target_velocity, 3 * delta)



func update_running_state():
	if currentStamina > 20:
		running = true
		current_speed = run_speed
	else:
		running = false
		current_speed = walk_speed

func take_damage(damage, attacker_position):
	if currentStamina > 0:
		currentStamina -= damage
		update_stamina_bar()
	else:
		currentHealth -= damage
		update_health_bar()

	if currentHealth <= 0:
		die()

func die():
	animated_sprite.play("dead")
	set_physics_process(false)
	$CollisionShape2D.disabled = true

	await get_tree().create_timer(15).timeout
	queue_free()
	$CollisionShape2D.disabled = false

func create_corpse():
	var corpse = CorpseScene.instance()
	corpse.global_position = get_node("npc").global_position
	corpse.currentHealth = 0
	corpse.take_damage = null
	corpse.sprite_resource = animated_sprite.frames
	get_parent().add_child(corpse)

	await get_tree().create_timer(15).timeout

func update_health_bar():
	$healthbar.value = currentHealth

func update_stamina_bar():
	$staminabar.value = currentStamina

func update_animation():
	if state == State.PUNCHING:
		return

	var anim_name = ""
	var state = "walk"

	if running:
		state = "run"

	if velocity.length() < 10:  # Add this threshold
		anim_name = "idle_" + last_dir
	else:
		if abs(velocity.x) > abs(velocity.y):  # Change this line
			if velocity.x > 0:
				last_dir = "right"
			else:
				last_dir = "left"
		else:
			if velocity.y > 0:
				last_dir = "down"
			else:
				last_dir = "up"
		anim_name = state + "_" + last_dir

	if animated_sprite.animation != anim_name:
		animated_sprite.play(anim_name)


		
func perform_punch():
	if currentStamina > 0:
		state = State.PUNCHING
		play_punch_anim() 
		for body in bodies_in_hitbox:
			if body.has_method("take_damage"):
				body.take_damage(punch_damage, global_position)
		currentStamina -= stamina_cost
		state = State.IDLE
		if state != State.PUNCHING:
			currentStamina -= punch_damage
			update_stamina_bar()

		if currentHealth <= 0:
			die()

func play_punch_anim():
	if randi() % 2 == 0:
		punch_key = "rpunch"
	else:
		punch_key = "lpunch"

	animated_sprite.play(punch_key + "_" + last_dir)
	# No connection line here

func _process(_delta):
	if state == State.PUNCHING and not animated_sprite.playing:
		_on_punch_anim_finished()


func _on_punch_anim_finished():
	state = State.IDLE



func _on_detectionarea_body_entered(body):
	if body.is_in_group("player"):
		player = body
		player_follow = true
		set_physics_process(true)
		print("Following player")

func _on_detectionarea_body_exited(body):
	if body.is_in_group("player"):
		player = null
		player_follow = false
		print("Not following player")

func enemy():
	pass

func _on_npc_hitbox_body_entered(body):
	if body.is_in_group("player"):
		bodies_in_hitbox.append(body)
		print("npc hitbox")
		$PunchTimer.start()

func _on_npc_hitbox_body_exited(body):
	if body.is_in_group("player"):
		bodies_in_hitbox.erase(body)
		print("npc out hitbox")
		$PunchTimer.stop()

func _on_punch_timer_timeout():
	perform_punch()