tool extends KinematicBody2D class_name Enemy signal died signal got_damage export var num_of_hits := 3 export var walking_speed := 20.0 export var attack_cool_down := .1 export var patroler = true export var idle_interval := .5 export var idle_time := .2 export var dont_fall_patrol = true export var gravity = 500.0 var _velocity := Vector2.ZERO var _is_idle := false var _is_alive := true var _triggerd := false var _damage_enabled := true var _player_ref:Player = null; var _genesis_position:Vector2; func _get_configuration_warning() -> String: var warnings = PoolStringArray() var children = get_children() var warning_sections := { "animation_player": true, "collision_shape": true, "sprite": true, "raycast_left": dont_fall_patrol, "raycast_right": dont_fall_patrol, "area_2d": true } for child in children: if child.name == 'CollisionShape2D': warning_sections.collision_shape = false; elif child.name == 'Sprite': warning_sections.sprite = false; elif child.name == 'Area2D': warning_sections.area_2d = false; elif child.name == 'RayCastLeft': warning_sections.raycast_left = false; elif child.name == 'RayCastRight': warning_sections.raycast_right = false; elif child.name == 'AnimationPlayer': warning_sections.animation_player = not ( $AnimationPlayer.has_animation("walk") and $AnimationPlayer.has_animation("die") and $AnimationPlayer.has_animation("idle") and $AnimationPlayer.has_animation("hit") ) if warning_sections.collision_shape: warnings.append(name + " Needs to have a CollisionShape2D Child") if warning_sections.area_2d: warnings.append(name + " Needs to have an Area2D Child") if warning_sections.raycast_left: warnings.append(name + " With dont-fall mode Needs to have a RayCastLeft Child") if warning_sections.raycast_right: warnings.append(name + " With dont-fall mode Needs to have a RayCastRight Child") if warning_sections.sprite: warnings.append(name + " Needs to have aa Sprite Child") if warning_sections.animation_player: warnings.append(name + " Needs to have an AnimationPlayer Child witt 'walk', 'idle', 'die', 'hit' animations") return warnings.join('\n') func _ready() -> void: add_to_group("Enemies") _genesis_position = position func _physics_process(delta: float) -> void: if Engine.editor_hint: return if not _is_alive: return if not _damage_enabled: _velocity.y += gravity * delta _velocity = move_and_slide(_velocity, Vector2.UP) return if not _is_idle and not _triggerd: if patroler: if is_on_wall(): $Sprite.scale = Vector2($Sprite.scale.x * -1, 1) elif dont_fall_patrol and is_on_floor(): var pit_direction = _get_pit_direction() if not pit_direction == 0: $Sprite.scale = Vector2(pit_direction * -1, 1) $AnimationPlayer.play("walk") _velocity.y += gravity * delta _velocity.x = $Sprite.scale.x * walking_speed _velocity = move_and_slide(_velocity, Vector2.UP) pass func take_damage(from_direction:int, damage: int = 1)->void: num_of_hits -= 1 if num_of_hits <= 0: _is_alive = false _damage_enabled = false $AnimationPlayer.play("die") else: _damage_enabled = false $AnimationPlayer.play("hit") $Sprite.scale = Vector2(from_direction * -1, 1) _velocity.x = 100 * from_direction _velocity.y = -50 func on_animation_hit_ended(): _damage_enabled = true func _get_pit_direction()->int: if not $RayCastLeft.is_colliding(): return -1 elif not $RayCastRight.is_colliding(): return 1 return 0 func _alerted()->bool: return false