extends CharacterBody3D var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") var grabbable : bool = false var shootable : bool = true var weakpoint : bool = false var rootnode : bool = true var waitingfor : int = 0 @export var HP : float = 3 @export var weakpoint_damage : float = 5.0 @export var runner : bool = false @export var physics_push_force : float = 1.5 var movement_speed: float = 8.0 var movement_delta: float var path_point_margin: float = 1 var current_path_index: int = 0 var current_path_point: Vector3 var current_path: PackedVector3Array @onready var default_3d_map_rid: RID = get_world_3d().get_navigation_map() var startpos : Vector3 var forth : bool = false var headoffset : Vector3 var headbone : int var pissed : bool = false @export var min_player_distance : float = 4.0 @export var min_ally_distance : float = 6.0 var runtarget : Vector3 @export var player : Node # Called when the node enters the scene tree for the first time. func _ready(): headoffset = Vector3(0,0.2,0) headbone = $CharacterArmature/Skeleton3D.find_bone("Head") $CharacterArmature.rotation_degrees.y = 180 rotation_degrees.y += 180 player.enemies.append(self) $AnimationPlayer.play("Idle") pissed = true func _physics_process(delta): if pissed and player.global_transform.origin.distance_to(runtarget) > 4: runtarget = player.global_transform.origin if current_path.is_empty() and NavigationServer3D.map_is_active(default_3d_map_rid): if runner: set_movement_target($waypoint.global_transform.origin) elif pissed and global_transform.origin.distance_to(runtarget) > 4: set_movement_target(runtarget) $chase_timer.start(1.5) move_and_slide() for i in get_slide_collision_count(): var slaminto = get_slide_collision(i) if slaminto.get_collider() is RigidBody3D: slaminto.get_collider().apply_central_impulse(-slaminto.get_normal() * physics_push_force) if !current_path.is_empty(): if !runner and global_transform.origin.distance_to(player.global_transform.origin) <= min_player_distance: clearpath() $chase_timer.start(1.5) if global_transform.origin.distance_to(current_path_point) <= path_point_margin: current_path_index += 1 if current_path_index >= current_path.size(): clearpath() if runner: if !forth: set_movement_target(startpos) forth = true elif forth: set_movement_target($waypoint.global_transform.origin) forth = false else: $chase_timer.start(1.5) """for bud in player.enemies: if bud.get_instance_id() != get_instance_id() and bud.global_position.distance_to(global_position) <= min_ally_distance and bud.global_position.distance_to(player.global_position) < global_position.distance_to(player.global_position): clearpath() $queue_timer.start(3)""" if !current_path.is_empty() and HP > 0: $Head.position = headoffset + $CharacterArmature/Skeleton3D.get_bone_global_pose(headbone).origin if len(current_path) > 0: current_path_point = current_path[current_path_index] var direction = global_transform.origin.direction_to(current_path_point) var acceleration = 8.0 velocity.x = lerp(velocity.x, direction.x * movement_speed, acceleration * delta) velocity.z = lerp(velocity.z, direction.z * movement_speed, acceleration * delta) global_transform = global_transform.interpolate_with(global_transform.looking_at(Vector3(current_path_point.x,global_position.y,current_path_point.z)), 0.2) elif current_path.is_empty() or waitingfor != 0: velocity.x = 0 velocity.z = 0 if HP > 0: var velocityclamp = 0.25 if abs(velocity.x) + abs(velocity.z) > (velocityclamp * 2): $AnimationPlayer.play("Run") else: $AnimationPlayer.play("Idle") else: velocity = Vector3(0,0,0) if not is_on_floor(): velocity.y -= gravity * delta func deal_damage(damage): print(str(damage)+" damage taken, "+str(HP)+" HP left") HP = HP - damage if HP <= 0: print("death") $AnimationPlayer.play("Death") func set_movement_target(target_position: Vector3): var start_position: Vector3 = global_transform.origin current_path = NavigationServer3D.map_get_path( default_3d_map_rid, start_position, target_position, true ) if not current_path.is_empty(): current_path_index = 0 current_path_point = current_path[0] func clearpath(): current_path = [] current_path_index = 0 current_path_point = global_transform.origin func _on_animation_player_animation_finished(anim_name): if anim_name == "Idle": $AnimationPlayer.play("Idle") if anim_name == "Run": $AnimationPlayer.play("Run") if anim_name == "Death": delete_me() """set_collision_layer_value(1, false) $Head.set_collision_layer_value(1, false)""" func delete_me(): player.enemies.erase(self) get_parent().remove_child(self) queue_free() func _on_chase_timer_timeout(): if player.global_transform.origin.distance_to(runtarget) > 4: runtarget = player.global_transform.origin if global_transform.origin.distance_to(runtarget) > 4: set_movement_target(runtarget) print("updating runtarget to "+str(runtarget)) $chase_timer.start(1.5) func _on_queue_timer_timeout(): $queue_timer.stop() _on_chase_timer_timeout()