Solarus quests
1.6
Quest maker's reference
|
This module provides a datatype state
that represents a custom state allowing advanced customization of the hero.
Custom states can be used to precisely control everything that can happen to the hero in particular situations.
The engine provides a number of built-in states like "free"
, "frozen"
, "hurt"
, "swimming"
, "pushing"
and more (see hero:get_state() for the whole list). In every state, the hero can or cannot do specific actions (like moving), and can react or ignore other entities.
Most of the time, you don't need custom states. Custom states are for advanced users who want more control. Remember that in any built-in state, you can already customize the essential features like sprites and movements. More often that not, the "frozen"
built-in state is enough to make a lot of things, like cutscenes.
Sometimes however, you may want more advanced customization. For instance, if the built-in "swimming"
state does not fit your needs, you can make a custom state instead with your own swimming implementation. Or sometimes, you just want a completely new behavior that is not covered by any existing built-in state.
The hero always has only one current state. It can either be a built-in state or a custom state.
To make a custom state, first create a custom state object with sol.state.create(). Then, use some of the many methods and events documented below, and finally start your state on the hero with hero:start_state(state).
After this operation, the current state string of the hero (as returned by hero:get_state()) is "custom"
, and no longer a usual built-in state like "free"
, "frozen"
, "swimming"
, etc. You can then use hero:get_state_object() to retrieve the actual custom state object that you created.
When your state finishes, because you or the engine started another state (built-in or custom), it is your responsibility to clean things that you may have done on objects other than the state. For instance, if you added a sprite to the hero for your custom state, maybe you want to remove it when the state finishes. The event state:on_finished() is the appropriate place to do so, because it is called no matter who is changing the state.
This short example is a state that allows the hero to move, but keeps his sprites direction fixed.
local state = sol.state.create() -- Create a custom state object. state:set_can_control_movement(true) -- Set up its properties. state:set_can_control_direction(false) hero:start_state(state) -- Associate it to the hero.
There are other ways to implement such a feature, but custom states make this easier.
Creates a custom state but does not start it yet.
description
(string, optional): An optional description of your state. The engine does nothing special with this description, but it may help you distinguish states.Returns the description of this state.
nil
if no description was set.Sets the description of this state.
The engine does nothing special with this description, but it may help you distinguish states.
description
(string or nil): The description to set, or nil
to set no description.Returns the entity controlled by this state.
nil
if the state is not associated to an entity yet.Returns the map of the entity controlled by this state.
nil
if the state is not associated to an entity yet.Returns the game of the entity controlled by this state.
nil
if the state is not associated to an entity yet.Returns whether this state is started, that is, if it was activated on an entity (see hero:start_state()) and is not finished yet.
true
if the state is started.Returns whether the entity is visible during this state.
true
if the entity is visible during this state, false
if it is hidden.Returns whether the entity should be visible during this state.
visible
(boolean, optional): true
to make the entity visible during this state, false
to hide it. No value means true
.Returns the draw function of this state.
See state:set_draw_override() for more details.
nil
if the draw function was not overridden.Changes how this entity is drawn during this state.
You can use this to replace the built-in draw implementation of the engine by your own function, if the default behavior does not fit your needs. To do so, your function can either call map:draw_visual() or draw on camera:get_surface().
draw_override
(function or nil): The draw function, or nil
to restore the built-in drawing. Your function will receive the following parameters:state
(state): The custom state of the entity to draw.camera
(camera): Camera where the entity is drawn.Returns whether the player controls the direction of entity's sprites during this state.
true
if the player controls the sprites direction.Sets whether the player controls the direction of entity's sprites during this state.
The default value is true
. If you set this to false
, then the entity's sprites no longer automatically take the direction pressed by the player.
can_control_direction
(boolean): true
to let the player control the sprites direction. No value means true
.Returns whether the player controls the movement of the entity during this state.
true
if the player controls the movement.Sets whether the player controls the movement of the entity during this state.
The default value is true
. If this setting is true
, a movement is automatically created on the entity and this movement reacts to the player's input. If you set this to false
, then the entity has no automatic movement during this state.
can_control_movement
(boolean): true
to let the player control the movement.Sets whether the entity can traverse other entities in this state.
By default, this depends on the other entities: for example, sensors can be traversed by default while doors cannot unless they are open.
entity_type
(string, optional): A type of entity. See entity:get_type() for the possible values. If not specified, the setting will be applied to all entity types for which you don't override this setting.traversable
(boolean, function or nil
): Whether the entity controlled by this state can traverse the other entity type. This can be:true
to allow your entity to traverse entities of the specified type, false
otherwise.true
if you allow your entity to traverse the other entity. When your entity has a movement, this function will be called every time it is about to overlap an entity of the specified type.nil:
Clears any previous setting for this entity type and therefore restores the default value.Returns whether the entity can traverse the given kind of ground during this state.
ground
(string): A kind of ground. See map:get_ground() for the possible values.true
if the ground can be traversed during this state.Sets whether the entity can traverse the given kind of ground during this state.
By default, this depends on the the ground: for example, the "grass"
ground can be traversed by default while the "low wall"
ground cannot.
ground
(string): A kind of ground. See map:get_ground() for the possible values.traversable
(boolean): Whether the entity can traverse this kind of ground during this state.Returns whether the entity is affected by gravity during this state.
If yes, the entity will fall to the lower layer when the ground below it is "empty"
.
true
if the entity is affected by gravity during this state.Sets whether the entity is affected by gravity during this state.
If yes, the entity will fall to the lower layer when the ground below it is "empty"
.
The default value is true
. You should typically set this to false
when the entity is jumping of flying.
gravity_enabled
(boolean): true
to make the entity affected by gravity during this state.Returns whether the given kind of ground affects the entity during this state.
ground
(string): A kind of ground. See map:get_ground() for the possible values.true
if this ground affects the entity during this state.Sets whether a kind of ground affects the entity during this state.
ground
(string): A kind of ground. See map:get_ground() for the possible values.affected
(boolean): true
to make this ground affect the entity during this state.Returns whether this state remembers the last solid position of the entity as a place to come back to later if it falls into bad ground like holes or lava.
true
if solid positions in this state are considered as places to come back to when falling into bad grounds.Sets whether this state remembers the last solid position of the entity as a place to come back to later if it falls into bad ground like holes or lava.
The default value is true
.
can_come_from_bad_ground
(boolean): true
if solid positions in this state should be considered as places to come back to when falling into bad grounds.Returns whether the entity can be hurt during this state.
true
if the entity can be hurt during this state.nil
parameter.Sets whether the entity can be hurt during this state.
The default value is true
.
can_be_hurt
(boolean or function): Whether the entity controlled by this state can be hurt. You can pass a function if you want to decide this depending at the last moment, for example depending on the attacker. In this case, your function should accept the following parameters and return value:state
(state): The current state itself.attacker
(entity or nil): the attacker entity, or nil
if the attack does not come from an entity.true
to allow your entity to get hurt by this attacker.Returns whether the entity can swing the sword during this state.
true
if the entity can use the sword.Sets whether the entity can swing the sword during this state.
The default value is true
.
can_use_sword
(boolean): true
to allow to use the sword.Returns whether the entity can cut another entity with the sword during this state.
true
if the entity can cut a destructible entity during this state.nil
parameter.Sets whether the entity can cut another entity with the sword during this state.
When the sword sprite overlaps a destructible object that destructible:get_can_be_cut() can be cut, this setting decides if the destructible will actually be cut.
The default value is true
.
can_cut
(boolean or function): Whether the sword can cut another entity during this state. You can pass a function if you want to decide this at the last moment, for example depending on the exact position of the entity about to be cut. In this case, your function should support the following parameters and return value:state
(state): The current state itself.entity
(entity or nil): the entity that would be cut, or nil
if there is no entity about to be cut.true
to allow to cut the entity with the sword.Returns whether the entity can stop attacks with the shield during this state.
true
if the entity can stop attacks with the shield.Sets whether the entity can stop attacks with the shield during this state.
The default value is true
.
can_use_shield
(boolean): true
if the entity can stop attacks with the shield.Returns whether an equipment item can be used during this state.
item_id
(string, optional): Name of the item to test, or nil
to mean items in general.true
if the player can use an equipment item during this state.Sets whether an equipment item can be used during this state.
The default value is true
.
item_id
(string, optional): Name of the item to allow or disallow, or nil
to mean items in general.can_use_item
(boolean): true
to allow the player to use an equipment item during this state.Returns whether the entity can interact with the entities it is facing.
true
if interactions are allowed in this state.Sets whether the entity can interact with the entities it is facing.
If true
, when the action game command is pressed while facing an entity that reacts to interactions (like an NPC), then an interaction will occur.
The default value is true
.
can_interact
(boolean): true
to allow to interact in this state.Returns whether the entity can grab the obstacles it is facing.
true
if grab is allowed in this state.Sets whether the entity can start grabbing the obstacles it is facing.
If true
, the entity will go to state "grabbing"
when the action command is pressed while facing an obstacle.
The default value is true
.
can_grab
(boolean): true
to allow to grab in this state.Returns whether the entity can try to push the obstacles it is facing.
true
if pushing is allowed in this state.Sets whether the entity can start pushing the obstacles it is facing.
If true
, the entity will go to state "pushing"
when it reaches an obstacle and continues to move toward this obstacle for a configurable delay. This does not mean that the obstacle being pushed will actually move (blocks can move when being pushed, but other entities usually cannot).
The default value is true
.
can_push
(boolean): true
to allow to push in this state.Returns the delay before pushing when moving towards an obstacle during this state.
Sets the delay before pushing when moving towards an obstacle during this state.
This only has an effect if state:get_can_push() is true
.
The default value is 1000
ms.
pushing_delay
(number): The pushing delay in milliseconds (0
for no delay).Returns whether pickable treasures can be picked during this state.
true
if pickable treasures can be picked during this state.Sets whether pickable treasures can be picked during this state.
The default value is true
.
can_pick_treasure
(boolean): true
to allow the entity to pick treasures during this state.Returns whether the entity can take teletransporters during this state.
true
if the entity can take teletransporter during this state.Sets whether the entity can take teletransporters during this state.
The default value is true
.
can_use_teletransporter
(boolean): true
to allow the entity to take teletransporters during this state.Returns whether the entity can activate switches during this state.
true
if the entity can activate switches during this state.Sets whether the entity can activate switches during this state.
The default value is true
.
can_use_switch
(boolean): true
to allow the entity to activate switches during this state.Returns whether the entity can take streams during this state.
true
if the entity can take stream during this state.Sets whether the entity can take streams during this state.
The default value is true
.
can_use_stream
(boolean): true
to allow the entity to take streams during this state.Returns whether the entity can take stairs during this state.
true
if the entity can take stairs during this state.Sets whether the entity can take stairs during this state.
The default value is true
.
can_use_stairs
(boolean): true
to allow the entity to take stairs during this state.Returns whether the entity can activate jumpers during this state.
true
if the entity can take jumpers during this state.Sets whether the entity can take jumpers during this state.
The default value is true
.
can_use_jumper
(boolean): true
to allow the entity to take jumpers during this state.Returns the delay before jumping when taking a jumper during this state.
0
means no delay).Sets the delay before jumping when taking a jumper during this state.
This only has an effect if state:get_can_use_jumper() is true
.
The default value is 200
ms.
jumper_delay
(number): The jump delay in milliseconds (0
for no delay).Returns what happens during this state to an object that was carried the previous state.
"throw"
(default): The carried object is automatically thrown."remove"
: The carried object is silently destroyed."keep"
: The carried object continues to be carried.Sets what happens during this state to an object that was carried the previous state.
action
(string): One of:"throw"
(default): The carried object is automatically thrown."remove"
: The carried object is silently destroyed."keep"
: The carried object continues to be carried.Events are callback methods automatically called by the engine if you define them. In the case of states, they are only called on an active state.
Called when this state starts.
previous_state_name
(string or nil): Name of the state that was active before. See hero:get_state() for the possible values. This value is nil
if there was no state before (only possible for the first state of an entity).previous_state
(state or nil): Custom state object that was active before, if it was a custom one, nil
otherwise.Called when this state finishes.
next_state_name
(string or nil): Name of the state that is about to be active after yours. See hero:get_state() for the possible values. This value is nil
if there is no state after yours (only possible if the entity is being removed).next_state
(state or nil): Custom state object about to start, if it is a custom one, nil
otherwise.Called at each cycle of the main loop while this state is active.
Called just before the entity is drawn on the map during this state.
You may display additional things below the entity. To do so, you can either call map:draw_visual() or draw on camera:get_surface().
camera
(camera): The camera where this entity is being drawn.Called just after the entity is drawn on the map during this state.
You may display additional things above the entity. To do so, you can either call map:draw_visual() or draw on camera:get_surface().
camera
(camera): The camera where this entity is being drawn.Called when the entity has just been suspended or resumed.
The entity is suspended by the engine in a few cases, like when the game is paused or when a dialog is active. When this happens, all map entities stop moving and most sprites stop their animation.
suspended
(boolean): true
if the entity was just suspended, false
if it was resumed.Called when a map starts (when the player enters it) during this state.
map
(map): The new map.destination
(destination): The destination entity from where the hero arrives on the map, or nil
if he used another way than a destination entity (like the side of the map or direct coordinates).Called when the map stops (when the player leaves it) during this state.
When a map begins during this state, called when the opening transition effect finishes.
map
(map): The map.destination
(destination): The destination entity from where the hero arrived on the map, or nil
if he used another way than a destination entity (like the side of the map or direct coordinates).Called when the coordinates of the entity controlled by this state have just changed.
x
(number): The new X coordinate of the entity.y
(number): The new Y coordinate of the entity.layer
(number): The new layer of the entity.Called when the kind of ground on the map below the entity controlled by this state has changed. It may change because the entity is moving, or when because another entity changes it.
ground_below
(string): The kind of ground at the ground point of the entity controlled by this state. nil
means empty, that is, there is no ground at this point on the current layer.Called when the movement of the entity was stopped because of an obstacle during this state.
When an obstacle is reached, this event is called instead of state:on_position_changed().
movement
(movement): The movement of the entity.Called when a movement is started on the entity controlled by this state.
movement
(movement): The movement that was just started on the entity.Called when some characteristics of the entity's movement (like the speed or the angle) have just changed during this state.
movement
(movement): The movement of the entity.Called when the movement of the entity controlled by this state is finished (if there is an end).
Called when the entity has just attacked an enemy during this state, even if the attack was not successful.
enemy
(enemy): The attacked enemy.enemy_sprite
(sprite): Sprite of the enemy that received the attack, or nil
if the attack does not come from a pixel-precise collision test.attack
(string): How the enemy was attacked. See enemy:set_attack_consequence() for the possible values.consequence
(number, string or function): How the enemy reacted to the attack. See enemy:set_attack_consequence() for the possible values.Called when the user presses a keyboard key during this state.
key
(string): Name of the raw key that was pressed.modifiers
(table): A table whose keys indicate what modifiers were down during the event. Possible table keys are "shift"
, "control"
and "alt"
. Table values are `true.true
, the event won't be propagated to other objects. If you return false
or nothing, the event will continue its propagation to the commands.Called when the user releases a keyboard key during this state.
key
(string): Name of the raw key that was released.true
, the event won't be propagated to other objects. If you return false
or nothing, the event will continue its propagation to the commands.Called when the user enters text during this state.
character
(string): A utf-8 string representing the character that was pressed.true
, the event won't be propagated to other objects. If you return false
or nothing, the event will continue its propagation to the commands.Called when the user presses a joypad button during this state.
button
(number): Index of the button that was pressed.true
, the event won't be propagated to other objects.Called when the user releases a joypad button during this state.
button
(number): Index of the button that was released.true
, the event won't be propagated to other objects.Called when the user moves a joypad axis during this state.
axis
(number): Index of the axis that was moved. Usually, 0
is an horizontal axis and 1
is a vertical axis.state
(number): The new state of the axis that was moved. -1
means left or up, 0
means centered and 1
means right or down.true
, the event won't be propagated to other objects.Called when the user moves a joypad hat during this state.
hat
(number): Index of the hat that was moved.direction8
(number): The new direction of the hat. -1
means that the hat is centered. 0
to 7
indicates that the hat is in one of the eight main directions.true
, the event won't be propagated to other objects.Called when the player presses a game command (a keyboard key or a joypad action mapped to a built-in game behavior) during this state. You can use this event to override the normal built-in behavior of the game command.
command
(string): Name of the built-in game command that was pressed. Possible commands are "action"
, "attack"
, "pause"
, "item_1"
, "item_2"
, "right"
, "up"
, "left"
and "down"
.true
, the event won't be propagated to other objects (you are overriding the built-in behavior of pressing this game command).Called when the player released a game command (a keyboard key or a joypad action mapped to a built-in game behavior). during this state. You can use this event to override the normal built-in behavior of the game command.
command
(string): Name of the built-in game command that was released. Possible commands are "action"
, "attack"
, "pause"
, "item_1"
, "item_2"
, "right"
, "up"
, "left"
and "down"
.true
, the event won't be propagated to other objects (you are overriding the built-in behavior of releasing this game command).Called when the user presses a mouse button during this state.
button
(string): Name of the mouse button that was pressed. Possible values are "left"
, "middle"
, "right"
, "x1"
and "x2"
.x
(integer): The x position of the mouse in quest size coordinates.y
(integer): The y position of the mouse in quest size coordinates.true
, the event won't be propagated to other objects.Called when the user releases a mouse button during this state.
button
(string): Name of the mouse button that was released. Possible values are "left"
, "middle"
, "right"
, "x1"
and "x2"
.x
(integer): The x position of the mouse in quest size coordinates.y
(integer): The y position of the mouse in quest size coordinates.true
, the event won't be propagated to other objects.Called when the user presses a finger during this state.
finger
(integer): ID of the finger that was pressed.x
(integer): The x position of the finger in quest size coordinates.y
(integer): The y position of the finger in quest size coordinates.pressure
(number): The pressure of the finger, normalized between 0 and 1.true
, the event won't be propagated to other objects.Called when the user releases a finger during this state.
finger
(integer): ID of the finger that was pressed.x
(integer): The x position of the finger in quest size coordinates.y
(integer): The y position of the finger in quest size coordinates.pressure
(number): The pressure of the finger, normalized between 0 and 1.true
, the event won't be propagated to other objects.Called when the user moves a finger during this state.
finger
(integer): ID of the finger that was pressed.x
(integer): The x position of the finger in quest size coordinates.y
(integer): The y position of the finger in quest size coordinates.dx
(integer): The horizontal distance moved by finger in quest size coordinates.dy
(integer): The vertical distance moved by finger in quest size coordinates.pressure
(number): The pressure of the finger, normalized between 0 and 1.true
, the event won't be propagated to other objects.