extends CharacterBody2D # TODO: rewrite NPC to use state machine # TODO: create class_name which is used to inherit common attributes to mainship and npc ship class_name NPCShip @export var destination_timer : Timer @export var faction = "Enemy" @export var bounty_min : int = 20 @export var bounty_max : int = 30 @export var bounty : PackedScene @onready var ship = get_tree().current_scene.get_node("MainShip") @onready var engine = $"Engine" @onready var hull = $"Hull" @onready var debug_label = $DebugLabel @onready var target_snap = $TargetSnap @onready var healthbar = $Zalupa/ZalupaTwo/Health @onready var shield = $Shield var state = "idle" var shooting = false var allow_shooting = true signal destroyed func _ready(): destination_timer.timeout.connect(switchdestination) target_snap.mouse_entered.connect(get_tree().current_scene.addtargetlist.bind(self)) target_snap.mouse_exited.connect(get_tree().current_scene.removetargetlist.bind(self)) destroyed.connect(get_tree().current_scene.enemydestroyed) shield.material = material material.set_shader_parameter("color",modulate) func _physics_process(_delta): match state: "idle": idlestate() "chase": chasestate() "maintaindistance": maintaindistancestate() "runaway": runawaystate() var format = {"HP" : "%0.2f" % hull.hp, "SC" : "%0.2f" % shield.capacity} healthbar.text = "{HP} HS + {SC} SC".format(format) if hull.hp <= 0: destroy() if Vector2.ZERO.distance_to(global_position) > 5800: destroy(true) func switchdestination(): engine.destination_angle = randi_range(0, 360) func idlestate(): shooting = false if global_position.distance_to(ship.global_position) <= 512 and ship.allow_shooting: state = "chase" func chasestate(): engine.destination_angle = rad_to_deg(global_position.angle_to_point(ship.global_position)) shooting = true if abs(engine.destination_difference) <= 5 else false if global_position.distance_to(ship.global_position) > 512 or !ship.allow_shooting: state = "idle" if hull.hp < hull.max_hp * 0.2: state = "runaway" if global_position.distance_to(ship.global_position) <= 128: state = "maintaindistance" func maintaindistancestate(): engine.destination_angle += 1 shooting = true if abs(engine.destination_difference) <= 5 else false if global_position.distance_to(ship.global_position) > 128: state = "chase" if !ship.allow_shooting: state = "idle" func runawaystate(): shooting = false engine.destination_angle = rad_to_deg(global_position.angle_to_point(ship.global_position)) - 180 if global_position.distance_to(ship.global_position) > 1024 or !ship.allow_shooting: state = "idle" func destroy(silent : bool = false): hull.hp = hull.max_hp hull.fuel = hull.max_fuel shield.capacity = shield.max_capacity state = "idle" var bounty_inst = bounty.instantiate() get_tree().current_scene.add_child(bounty_inst) bounty_inst.global_position = global_position bounty_inst.amount = randi_range(bounty_min, bounty_max) bounty_inst.text.text = str(bounty_inst.amount) + " MU" global_position = Vector2(randi_range(-4096, 4096), randi_range(-4096, 4096)) if !silent: destroyed.emit(self)