Untitled
unknown
plain_text
a year ago
6.2 kB
9
Indexable
Never
extends CharacterBody2D # Additional import var DamageLabelScene = load("res://Scenes/DamageLabel.tscn") var CorpseScene = preload("res://Scenes/Corpse.tscn") # Punching Variables enum State {IDLE, MOVING, PUNCHING} var state = State.IDLE var punch_key = "" var punch_damage = randi_range(7, 12) var stamina_cost = 5 var bodies_in_hitbox = [] var hitbox_collision_shape var punch_cooldown = 1.0 var punch_timer = 0.0 var walk_speed = 55 var run_speed = 80 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) velocity = linear_velocity move_and_slide() else: velocity = Vector2.ZERO update_animation() punch_timer += delta if player in bodies_in_hitbox and punch_timer >= punch_cooldown: check_punch_condition() punch_timer = 0 func check_punch_condition(): if state != State.PUNCHING and player in bodies_in_hitbox and punch_timer >= punch_cooldown: 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 linear_velocity = linear_velocity.lerp(target_velocity, 8 * delta) func update_running_state(): if currentStamina > 20: running = true current_speed = run_speed else: running = false current_speed = walk_speed @warning_ignore("unused_parameter") func take_damage(damage, attacker_position): if currentStamina > 0: currentStamina -= damage update_stamina_bar() else: currentHealth -= damage update_health_bar() var damage_label = DamageLabelScene.instantiate() damage_label.text = str(damage) damage_label.modulate = Color.WHITE var x_offset = randf_range(-10, 10) # Adjust the range as needed damage_label.position = Vector2(x_offset, -50) add_child(damage_label) var tween = get_tree().create_tween() tween.tween_property(damage_label, "position:y", damage_label.position.y - 100, 1) tween.tween_property(damage_label, "modulate:a", 0, 1) if currentHealth <= 0: die() func die(): animated_sprite.play("dead") set_physics_process(false) 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 = "" @warning_ignore("shadowed_variable") 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(): print("perform_punch called") if currentStamina > 0: punch_damage = randi_range(7, 12) play_punch_anim() await get_tree().create_timer(1.0).timeout # Add a delay to wait for the punch animation to finish for body in bodies_in_hitbox: if body.has_method("take_damage"): body.take_damage(punch_damage, global_position) # Pass the player's global_position currentStamina -= stamina_cost state = State.IDLE func play_punch_anim(): print("play_punch_anim called") if randi() % 2 == 0: punch_key = "rpunch" else: punch_key = "lpunch" animated_sprite.play(punch_key + "_" + last_dir) func _process(_delta): if state == State.PUNCHING and not animated_sprite.is_playing(): _on_punch_anim_finished() func _on_punch_anim_finished(): if state == State.PUNCHING: state = State.IDLE animated_sprite.disconnect("animation_finished", self, "_on_punch_anim_finished") for body in bodies_in_hitbox: if body.has_method("take_damage"): body.take_damage(punch_damage, global_position) # Pass the player's global_position 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") if not $PunchTimer.is_stopped(): $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() func _on_animated_sprite_2d_animation_finished(): if state == State.PUNCHING: state = State.IDLE