Solarus quests  1.1
Quest maker's reference
Enemy

Table of Contents

An enemy is a bad guy that hurts the hero when touching him.

This type of map entity can be declared in the map data file. It can also be created dynamically with map:create_enemy().

Overview

Enemies can exist in various breeds. Each breed corresponds to a model of enemy with its the behavior, its sprites and its movements.

The script file enemies/XXXX.lua defines the enemy breed XXXX. This script is executed every time an enemy of that model is created. The corresponding Lua enemy object is passed as parameter of that script. Use the Lua notation "..." to get this parameter and store it into a regular variable.

Here is a basic example of script for the enemy breed "tentacle", a simple model of enemy that just follows the hero.

-- First, we put the parameter into a variable called "enemy".
-- (In Lua, the notation "..." refers to the parameter(s) of the script.)
local enemy = ...

-- Called when the enemy was just created on the map.
function enemy:on_created()

  -- Define the properties of this enemy.
  self:set_life(1)
  self:set_damage(2)
  self:create_sprite("enemies/tentacle")
  self:set_size(16, 16)
  self:set_origin(8, 13)
end

-- Called when the enemy should start or restart its movement
-- (for example if the enemy has just been created or was just hurt).
function enemy:on_restarted()

  -- Create a movement that walks toward the hero.
  local m = sol.movement.create("target")
  m:set_speed(32)
  self:start_movement(m)
end

Such a script is all what you need to define a model of enemy. The engine handles for you the detection of collisions with the hero or his weapons, hurts the hero or the enemy when appropriate, removes the enemy when it gets killed, etc. But you can customize everything using the API described on this page, like what kind of attacks can hurt the enemy. You can also make complex enemies composed of several sprites, and set different behavior to each sprite. This is very useful to program a boss.

Timers are handy to script some repeated behavior on enemies, like performing a particular attack every 5 seconds. Create your timers from the enemy:on_restarted() event. Timers of an enemy are automatically destroyed when the enemy is hurt or immobilized, so that they don't get triggered during these special states. They are also destroyed when you call enemy:restart(). When enemy:on_restarted() is called, you are guaranteed that no timers exist on your enemy. Thus, it is safe to create them there.

Basic enemies often have the same behavior. To avoid duplication of code, you can factorize some code into a generic file and call it from each enemy breed script with require(), sol.main.do_file() or sol.main.load_file().

Methods inherited from map entity

Enemies are particular map entities. Therefore, they inherit all methods from the type map entity.

See Methods of all entity types to know these methods.

Methods of the type enemy

The following methods are specific to enemies.

enemy:get_breed()

Returns the breed (the model) of this enemy.

  • Return value (string): The enemy's breed.

enemy:get_life()

Returns the current life of this enemy.

  • Return value (number): Number of health points of the enemy.

enemy:set_life(life)

Sets the current life of this enemy.

The default value is 1.

  • life (number): Number of health points to set. A value of 0 kills the enemy.

enemy:add_life(life)

Adds some life to the enemy.

  • life (number): Number of health points to add.
Remarks
Equivalent to enemy:set_life(enemy:get_life() + life)

enemy:remove_life(life)

Removes some life from the enemy.

  • life (number): Number of health points to remove.
Remarks
Equivalent to enemy:set_life(enemy:get_life() - life)

enemy:get_damage()

Returns the number of life points that the enemy removes from the hero when touching him. This number will be divided by the level of resistance ability of the player (his tunic).

  • Return value (number): Damage inflicted to the hero.

enemy:set_damage(damage)

Sets the number of life points that the enemy removes from the hero when touching him. This number will be divided by the level of resistance ability of the player (his tunic).

The default value is 1.

  • damage (number): Damage inflicted to the hero.

enemy:get_magic_damage()

Returns the number of magic points that the enemy removes from the hero when touching him.

  • Return value (number): Magic damage inflicted to the hero.

enemy:set_magic_damage(magic_damage)

Sets the number of magic points that the enemy removes from the hero when touching him.

The default value is 0.

  • magic_damage (number): Magic damage inflicted to the hero.

enemy:is_pushed_back_when_hurt()

Returns whether the enemy is pushed away when it is hurt.

  • Return value (boolean): true if the enemy is pushed away when hurt.

enemy:set_pushed_back_when_hurt([pushed_back_when_hurt])

Sets whether the enemy should be pushed away when it is hurt.

The default value is true.

  • pushed_back_when_hurt (boolean, optional): true to make the enemy pushed away when hurt. No value means true.

enemy:get_push_hero_on_sword()

Returns whether the hero is pushed away when he hits this enemy with his sword.

  • Return value (boolean): true if the hero is pushed away when hitting this enemy with his sword.

enemy:set_push_hero_on_sword([push_hero_on_sword])

Sets whether the hero should be pushed away when he hits this enemy with his sword.

The default value is false.

  • push_hero_on_sword (boolean, optional): true to push the hero away when hitting this enemy with his sword. No value means true.

enemy:get_can_hurt_hero_running()

Returns whether this enemy can hurt the hero even when the hero is running.

  • Return value (boolean): true if the hero can be hurt by this enemy even when running.

enemy:set_can_hurt_hero_running([can_hurt_hero_running])

Sets whether this enemy can hurt the hero even when the hero is running.

The default value is false.

  • can_hurt_hero_running (boolean, optional): true so that the hero can be hurt by this enemy even when running. No value means true.

enemy:get_hurt_style()

Returns the style of sounds and animations to play when this enemy is hurt.

  • Return value (string): "normal", "monster" or "boss".

enemy:set_hurt_style(hurt_style)

Sets the style of sounds and animations to play when this enemy is hurt. The default values are "normal" for usual enemies and "boss" for bosses and minibosses.

  • hurt_style (string): "normal", "monster" or "boss".

enemy:get_can_attack()

Returns whether this enemy can currently attack the hero.

  • Return value (boolean): true if the enemy can currently attack the hero.

enemy:set_can_attack([can_attack])

Sets whether this enemy can currently attack the hero.

When the enemy restarts after being hurt, can_attack is always set to true.

  • can_attack (boolean, optional): true to allow the enemy to attack the hero. No value means true.

enemy:get_minimum_shield_needed()

Returns the level of protection (if any) that stops attacks from this enemy.

If the player has a protection ability greater than or equal to this value, he will stop attacks from this enemy if he is facing the direction of the enemy. The special value of 0 means that attacks cannot be stopped with the protection ability. Returns the required level of protection to stop attacks from this enemy.

  • Return value (number): The level of protection that stops attacks from this enemy. A value of 0 means that the hero cannot stop the attacks.

enemy:set_minimum_shield_needed(minimum_shield_needed)

Sets a level of protection that stops attacks from this enemy.

If the player has a protection ability greater than or equal to this value, he will stop attacks from this enemy if he is facing the direction of the enemy. The special value of 0 means that attacks cannot be stopped with the protection ability. The default value is 0.

  • minimum_shield_needed (number): The level of protection that stops attacks from this enemy. A value of 0 means that the hero cannot stop the attacks.

enemy:set_attack_consequence(attack, consequence)

Sets how this enemy reacts when it receives an attack.

Recall that enemies may have several sprites. This attack consequence applies to all sprites of the enemy, unless the ones that you override with enemy:set_attack_consequence_sprite().

  • attack (string): Name of an attack against the enemy: "sword", "thrown_item", "explosion", "arrow", "hookshot", "boomerang" or "fire".
  • consequence (number or string): Indicates what happens when this enemy receives the attack. It may be:
    • A positive integer: The enemy is hurt and loses this number of life points.
    • "ignored": Nothing happens. The weapon (if any) traverses the enemy.
    • "protected": The enemy stops the attack. A attack failure sound is played.
    • "immobilize": The enemy is immobilized for a few seconds.
    • "custom": Event enemy:on_custom_attack_received() is called.

enemy:set_attack_consequence_sprite(sprite, attack, consequence):

Sets how this enemy reacts when one of its sprites receives an attack. This method overrides for a particular sprite the attack consequences defined by enemy:set_attack_consequence().

  • sprite (sprite): A sprite of this enemy.
  • attack (string): Name of an attack against the enemy: "sword", "thrown_item", "explosion", "arrow", "hookshot", "boomerang" or "fire".
  • consequence (number or string): Indicates what happens when this sprite receives the attack. The possible values are the same as in enemy:set_attack_consequence().

enemy:set_default_attack_consequences()

Restores the default attack consequences for this enemy and its sprites.

enemy:set_default_attack_consequences_sprite(sprite)

Restores the default attack consequences for a particular sprite of this enemy.

  • sprite (sprite): A sprite of this enemy.

enemy:set_invincible()

Makes this enemy ignore all attacks.

Equivalent to calling lua_api_enemy_set_attack_consequence(attack, "ignored") for each attack.

enemy:set_invincible_sprite(sprite)

Makes a sprite of this enemy ignore all attacks.

Equivalent to calling lua_api_enemy_set_attack_consequence_sprite(sprite, attack, "ignored") for each attack.

  • sprite (sprite): A sprite of this enemy.

enemy:has_layer_independent_collisions()

Returns whether this enemy can detect collisions with entities even if they are not on the same layer.

By default, enemies can only have collisions with entities on the same layer.

  • Return value (boolean): true if this enemy can detect collisions even with entities on other layers.

enemy:set_layer_independent_collisions([independent])

Sets whether this enemy can detect collisions with entities even if they are not on the same layer.

By default, enemies can only have collisions with entities on the same layer. If you set this property to true, this enemy will be able to hurt the hero even from a different layer.

  • independent (boolean, optional): true to make this enemy detect collisions even with entities on other layers. No value means true.

enemy:set_treasure([item_name, [variant, [savegame_variable]]])

Sets the pickable treasure that will drop this enemy when killed.

  • item_name (string, optional): Name of an equipment item. nil or no value means no item.
  • variant (number, optional): Variant of this equipment item (1 means the first variant). The default value is 1.
  • savegame_variable (string, optional): Name of the boolean value that stores in the savegame whether the treasure dropped is found. nil or no value means that the treasure is not saved.

enemy:is_traversable()

Returns whether this enemy is traversed by other entities.

  • Return value (boolean): true if this enemy is traversable.

enemy:set_traversable([traversable])

Sets whether this enemy can be traversed by other entities.

By default, the enemy is traversable. For example, if you want to prevent the hero to pass without killing the enemy, you can use this function to make the enemy become an obstacle. But make sure that the enemy's sprite is greater than its bounding box, otherwise, the enemy cannot touch the hero (and hurt him) anymore.

  • traversable (boolean, optional): true to make this enemy traversable. No value means true.

enemy:get_obstacle_behavior()

Returns how the enemy behaves with obstacles.

  • Return value (string): "normal", "flying" or "swimming".

enemy:set_obstacle_behavior(obstacle_behavior)

Sets how this enemy should behave with obstacles. The default value is "normal". "swimming" allow the enemy to traverse water. "flying" allows the enemy to traverse holes, water and lava.

  • obstacle_behavior (string): "normal", "flying" or "swimming".

enemy:set_size(width, height)

Sets the size of the bounding box of this enemy.

The default value is 16x16 pixels. This is the effective size used to detect obstacles when moving, but the sprite of the enemy may be larger, especially for a boss.

  • width (number): Width of the enemy in pixels.
  • height (number): Height of the enemy in pixels.

enemy:set_origin(origin_x, origin_y)

Sets the origin point of this enemy, relative to the top-left corner of its bounding box.

This origin point property allows entities of different sizes to have comparable reference points that can be used by the engine. Indeed, when two enemies overlap, the engine needs to determine which one has to be displayed first (it is always the one with the lowest Y coordinate). Sometimes, the engine also needs to compute an angle between two entities, for example to push away an enemy that was just hit. Using the top-left corner of their bounding box would not give the correct angle (unless both entities had the same size).

The origin point is also the point of synchronization of an entity with its sprites (because again, an entity that has a given size may have sprites with different sizes).

The default values is 0x0 and should be changed for most enemies. See entity:get_origin() for more explanations about the origin point.

  • origin_x (number): X coordinate of the origin point in pixels, relative to the top-left corner of the enemy's bounding box.
  • origin_y (number): Y coordinate of the origin point in pixels, relative to the top-left corner of the enemy's bounding box.

enemy:restart()

Restarts this enemy.

This plays animation "walking" on its sprites, destroys any timer of the enemy and calls the event enemy:on_restarted().

enemy:hurt(life_points)

Hurts this enemy if possible.

The enemy is not hurt if he is currently invulnerable (for example because he is already in the process of being hurt).

  • life_points (number): Number of life points to remove from the enemy.

enemy:immobilize()

Immobilizes this enemy for a while if possible.

After a few seconds, the enemy shakes and then restarts.

enemy:get_sprite()

Returns the sprite of this enemy, as created by enemy:create_sprite().

  • Return value (sprite): The first sprite created for this enemy.
Remarks
If the enemy has several sprites, the first one created is returned. For the other sprites, you cannot use this function. However, you can just store the return values of your calls to enemy:create_sprite().

enemy:create_sprite(sprite_name)

Creates a sprite for this enemy.

  • sprite_name (string): Name of the animation set of the sprite to create.
  • Return value (sprite): The sprite created.
Remarks
If you don't create a sprite, your enemy will be invisible.

enemy:remove_sprite([sprite])

Removes and destroys a sprite of this enemy.

The sprite must have been created before by enemy:create_sprite().

  • sprite (sprite): The sprite to remove. The default value is the first sprite that was created.

enemy:create_enemy(properties)

Creates another enemy on the map, specifying its coordinates as relative to the current enemy.

This function is similar to map:create_enemy() but the coordinates are relative to the current enemy, and the layer is the one of the current enemy by default.

  • properties (table): A table that describes all properties of the enemy to create. Its key-value pairs must be:
    • name (string, optional): Name identifying the entity. No value means no name.
    • layer (number, optional): Layer on the map (0: low, 1: intermediate, 2: high). No value means the same layer as the current enemy.
    • x (number, optional): X coordinate on the map, relative to the current enemy. The default value is 0.
    • y (number, optional): Y coordinate on the map, relative to the current enemy. The default value is 0.
    • direction (number, optional): Initial direction of the enemy, between 0 (East) and 3 (South). The default value is 3.
    • breed (string): Model of enemy to create.
    • rank (number, optional): 0 for a normal enemy (default), 1 for a miniboss, 2 for a boss.
    • savegame_variable (string, optional): Name of the boolean value that stores in the savegame whether this enemy is dead. No value means that the enemy is not saved. If the enemy is saved and was already killed, then no enemy is created. Instead, its pickable treasure is created if it is a saved one.
    • treasure_name (string, optional): Kind of pickable treasure to drop when the enemy is killed (the name of an equipment item). If this value is not set, or corresponds to a non obtainable item, then the enemy won't drop anything.
    • treasure_variant (number, optional): Variant of the treasure (because some equipment items may have several variants). The default value is 1 (the first variant).
    • treasure_savegame_variable (string, optional): Name of the boolean value that stores in the savegame whether the pickable treasure of this enemy was obtained. No value means that the state of the treasure is not saved. If the treasure is saved and the player already has it, then the enemy won't drop anything.
  • Return value (enemy or pickable treasure): The enemy created, except when it is a saved enemy that is already dead. In this case, if the enemy dropped a saved treasure that is not obtained yet, this pickable treasure is created and returned. Otherwise, nil is returned.

Events inherited from map entity

Events are callback methods automatically called by the engine if you define them.

Enemies are particular map entities. Therefore, they inherit all events from the type map entity.

See Events of all entity types to know these events.

Events of the type enemy

The following events are specific to enemies.

enemy:on_update()

Called at each cycle while this enemy is alive.

Remarks
As this function is called at each cycle, it is recommended to use other solutions when possible, like timers and other events.

enemy:on_suspended(suspended)

Called when the map has just been suspended or resumed.

The map is suspended by the engine in a few cases, like when the game is paused or when the camera is being moved by a script. When this happens, all map entities stop moving and most sprites stop their animation.

  • suspended (boolean): true if the map was just suspended, false if it was resumed.

enemy:on_created()

called when this enemy has just been created on the map.

enemy:on_enabled()

called when this enemy has just been enabled.

enemy:on_disabled()

called when this enemy has just been disabled.

enemy:on_restarted()

Called when this enemy should start or restart its movement and timers because something happened. For example, the enemy has just been created, or it was just hurt or immobilized, or you called enemy:restart(). If your enemy should move, this is the right place to create its movement.

Timers associated to the enemy were automatically destroyed. Thus, you should also recreate them from this event.

enemy:on_pre_draw()

Called just before the enemy is drawn on the map. You may display additional things below the enemy.

enemy:on_post_draw()

Called just after the enemy is drawn on the map. You may display additional things above the enemy.

enemy:on_collision_enemy(other_enemy, other_sprite, my_sprite)

Called when a sprite of this enemy overlaps another enemy's sprite.

  • other_enemy (enemy): Another enemy.
  • other_sprite (sprite): A sprite of that other enemy.
  • my_sprite (sprite): A sprite of the current enemy.

enemy:on_custom_attack_received(attack, sprite)

Called when this enemy receives an attack with a custom effect.

This function is called if you consequence of the attack to "custom". You have to define what happens, for example hurting the enemy, making a special reaction, etc.

  • attack (string): The attack that was received: "sword", "thrown_item", "explosion", "arrow", "hookshot", "boomerang" or "fire".
  • sprite (sprite): The sprite of this enemy that receives the attack, or nil if the attack does not come from a pixel-precise collision.

enemy:on_hurt(attack, life_lost)

Called when this enemy was just hurt.

  • The attack that was received: "sword", "thrown_item", "explosion", "arrow", "hookshot", "boomerang" or "fire".
  • life_lost (number): The number of life points just lost by the enemy.

enemy:on_dying()

Called when the enemy's life comes to 0.

When the life comes to 0, the movement of the enemy is stopped, its timers are stopped too, the dying animation starts and a sound is played. The details of the dying animation and the sound played depend on the hurt style property. If the hurt style is "enemy" or "monster", any sprite you created on the enemy is automatically removed and replaced by sprite "enemies/enemy_killed". If the hurt style is "boss", your sprites continue to exist and to play animation "hurt", while explosions appear on the enemy.

In both cases, the enemy will be removed from the map when the dying animation ends.

enemy:on_dead()

Called when the enemy's dying animation is finished.

At this point, the enemy no longer exists on the map. In other words, enemy:exists() returns false, trying to get the enemy from its name returns nil, and functions like map:get_entities(prefix) won't find this enemy.

This means that you can safely use map:has_entities(prefix) from enemy:on_dead() to detect when all enemies with a common prefix are dead.

enemy:on_immobilized():

Called when the enemy is immobilized.