class_name EnemyDef extends Resource ## Data-only description of a trash enemy. Behaviour is picked from a small set ## of readable, predictable movements -- players should be able to learn an ## enemy in one encounter. enum Move { ## Never moves. Pure turret. STATIC, ## Slides along a fixed heading, bouncing off the arena edges. DRIFT, ## Circles its spawn point at a fixed radius. ORBIT, ## Walks straight at the nearest player, slowly. APPROACH, ## Keeps a preferred distance from the nearest player. STRAFE, } @export var id: StringName = &"drone" @export var display_name: String = "Drone" @export var max_hp: int = 40 @export var radius: float = 14.0 @export var move: Move = Move.DRIFT @export var speed: float = 60.0 ## ORBIT radius, or STRAFE preferred distance. @export var move_param: float = 120.0 ## Ticks between direction re-evaluations for APPROACH/STRAFE, so enemies read ## as deliberate rather than twitchy. @export var retarget_interval: int = 30 ## How far this enemy notices a player, in world units. It also needs line of ## sight -- range alone would mean shooting through walls. @export var aggro_range: float = 420.0 ## Index the client renderer uses to pick a shape/colour. @export var visual: int = 0 @export var emitters: Array[BulletEmitter] = [] ## The emitter timeline wraps at this many ticks. @export var pattern_loop_ticks: int = 240 ## Never takes damage. Exists for the hub's practice target, whose whole job is ## to still be there tomorrow -- expressing that as a flag rather than as a ## large health pool means it cannot be worn down by a patient player, and ## keeps its health inside the u16 the snapshot sends. @export var indestructible: bool = false ## What this enemy may leave behind. Rolled once per entry on death, against ## the world's own RNG. Empty for anything that should drop nothing. @export var loot: Array[LootDrop] = []