LATE is a library for managing lasting effects, not instant effects.
Targets: Targets of effects. For now, players and mobs can be targets of effects.
Impacts: An elementary impact on target. Different effects can result in the same impact. In that case, their parameters and intensities are properly mixed to result in a single impact.
Effects: Combination of impacts, conditions and target. Many effects at once can be affected to a target, with different conditions (duration, area, equipment).
Conditions are only for stopping effect. LATE does not automatically start effects where condition are fulfilled. This would be far too difficult to continuously check for every possibility. Effect creation has to be triggered explicitely. Some helpers exist to start effects automatically on certain events.
Active effects are represented by Effect objects. Effect objects are created by calling late.new_effect method. Effects can also be automatically affected when using some items and blocks. In that case, they are defined in item or node definition.
Effects have a cycle of life involving four phases:
Effect starts in this phase.
It stops after raise seconds or if effect conditions are no longer fulfilled.
Intensity of effect grows from 0 to 1 during this phase.
Once raise phase is completed, effects enters the still phase.
Intensity is full and the phases lasts until one of the conditions stops being fulfilled.
When conditions are no longer fulfilled, effect enters fall phase.
This phase lasts fall seconds (if 0, effects gets to end phase instantly).
This is the terminal phase.
Effect will be deleted in next step.
Effect definition table may contain following fields:
idIdentifier. If given, should be unique for a target. If not given, an internal id is given.impactsImpacts effect has (pair of impact name / impact parameters);raiseTime (in seconds) it takes to raise to full intensity (default 0: immediate);fallTime (in seconds) it takes to fall, after end to no intensity (default 0: immediate);durationDuration (in seconds) the effect lasts (default: always);distanceFor effect associated to nodes, distance of action;stop_on_deathIf true, the effect stops at player death;hudHud defition (see Hud definition table section);
All fields are optional but an effect without impacts would do nothing.
Hud definition table (hud field of effect definition) may contain following fields:
iconTexture used to display effect in hud;colorColor of the hud background;labelText to be displayed;durationSet to false to hide duration (default true);
-- Run fast and make high jumps for 20 seconds
{
impacts = { jump=3, speed=10 },
fall = 2,
duration = 20,
hud = { color="yellow", label ="Jump fast!" },
}Of course, jump and speed impacts have to be defined (they are included in base impacts).
To affect a target with an effect, create a new effect using late.new_effect, giving the target and the effect definition.
Think about adding a duration or stop_on_death clause in effect definition to avoid permanent effect (unless expected).
Example :
-- Stuck player "toto" for 5 seconds
local player = minetest.get_player_by_name("toto")
if player then
late.new_effect(player, { duration=5, impacts = { speed=0 } })
endItems can have effects on players or mobs when:
- Equiped (in hand or in armor equipment): cloth, amulets, rings;
- Used (effect on self): potion, food;
- Used (on someone or something): magic wand, special weapon;
To create an item that have an effect when equiped, add to the item definition a field named effect_equip containing the effect definition.
Example:
-- Jump boots
minetest.register_tool("mymod:jump_boots", {
description = "Jump boots",
inventory_image = "mymod_boots.png",
effect_equip = { impacts = { jump=3 } },
})To make boots wearable as boots armor, refer to 3D Armor mod API.
To create an item that have an effect when used:
- Put the effect definition in item definition field
effect_use(for use on self) oreffect_use_on(for use on players or mobs); - Add a call to
late.on_use_tool_callbackin itemon_use; - Add an end condition to avoid creating permanent effect : a
durationclause orstop_on_death=trueclause;
Example:
-- Poison potion
minetest.register_tool("mymod:poison", {
description = "Poison potion",
inventory_image = "mymod_potion.png",
effect_use = { impacts = { damage={ 1, 2 } }, stop_on_death=true },
on_use = late.on_use_tool_callback,
})Effects can be triggered by the proximity of a specific node or being inside a specific node.
To create a node with effect:
- Add the node in
effect_triggergroup (effect_trigger=1in groups table); - Add either :
effect_nearfield in the node definition with adistancefield;effect_infield in the node definition;
Example:
-- Darkness 20 nodes around dark stone
minetest.register_node("mymod:dark_stone", {
description = "Dark stone",
tiles = {"default_stone.png"},
groups = { cracky = 3, stone = 1, effect_trigger = 1 },
effect_near = { impacts = { daylight=0 }, distance = 20 },
})function late.get_effect_by_id(target, id)Retrieves an effect affecting a target by it's id.
target: Target of the effect.
id: Identifier of the effect to retrieve.
Returns the Effect object if found, nil otherwise.
function late.on_use_tool_callback(itemstack, user, pointed_thing)Standard on_use tool callback to be added to tools with effects (see above).
Effect object represent a temporary (or permanent) effect on a target (player or mob).
function Effect:new(target, definition)Public API :
function late.new_effect(target, definition)Creates a new effect on a target.
target: Target to be affected by the effect.
definition: Effect defintion table.
Returns an Effect object if creation succeded, nil otherwise.
Possible cause of failure :
- Target is not suitable (neither a player nor a mob);
definition.id(optional) field contains a value that is already in use for the target (check first withlate.get_effect_by_idif you are using ids);
function Effect:start()Starts an effect or restart it.
If conditions are not fulfilled, it will fall in fall phase again during next step. So start/restart should be called only if condition are fulfilled again.
function Effect:restart()Same as start.
function Effect:stop()Stops an effect. Actually set it in fall phase, regardless of conditions.
function Effect:change_intensity(intensity)Change intensity of effect.
intensity: New intensity (between 0.0 and 1.0)
Developed for internal purpose but safe to use as public method.
function Effect:set_conditions(conditions)Sets or overrides condition(s) of an effect.
conditions Key / value table of conditions.
Developed for internal purpose but safe to use as public method.
function Effect:add_impact(type_name, params)Add a new impact to the effect.
type_name: Impact type name
params: Params for that impact (refer to the corresponding impact type definition)
function Effect:remove_impact(type_name)Remove an impact from effect.
type_name: Impact type name
function Effect:step(dtime)Performs a step calculation of effect.
dtime: Time since last step.
function late.register_condition_type(name, definition)Registers a condition type. Conditions are checked each step to determine if the effect should last or stop. Registering new condition types allows to extend the available types of conditions.
name: Name of the condition type.
definition: Definition table of the condition type.
definition table may contain following fields:
check(optional) = function(data, target, effect) A function called to check is a condition is fulfilled. Should return true if condition still fulfilled, false otherwise. This function is not called at each step, only when engine needs it. Function parameters:data: condition data (value of this condition field in effect definition)target: target affected,effect: Effect object instance.
step(optional) = function(data, target, effect) A function called at each step. Could be useful to prepare condition checking. Same parameters ascheckfunction.abm(optional) = function(pos, node, node_def) A function called by an ABM on nodes of the groupeeffect_trigger. This is used fornear_nodeandin_nodeconditions.
function late.register_impact_type(target_types, name, definition)Registers an impact type.
target_types: Target type or table of target types that can be affected by that impact type
name: Name of the impact type
definition: Definition table of the impact type
definition table may contain following fields:
varsInternal variables needed by the impact (variables will instantiated for each target) (optional);reset(optional) = function(impact) Function called when impact stops to reset normal target state (optional);update(optional) = function(impact) Function called when impact changes to apply impact on target;step(optional) = function(impact, dtime) Function called every global step (optional);
impactargument passed to reset, update and step functions is a table representing the impact instance concerned. Table fields are :
targetPlayer or mob ObjectRef affected by the impact;typeImpact type name;varsTable of impact variables (copied from impact type definition) indexed by their name;paramsTable of per effect params and intensity;changedTrue if impact changed since last step;
Except variables in vars, nothing should be changed by the functions.
In following helpers, valint stands for a pair of value / intensity.
Each effect corresponding to an impact gives one or more parameters to the impact and an effect intensity.
The impact is responsible of computing a single values from these parameters and intensity. LATE provides helpers to perform common combination operations.
function late.get_valints(params, index)Returns extacts value/intensity pairs from impact params table.
Impact params table contains params given by effects definition, plus an intensity field reflecting the corresponding effect intensity.
params: the impact.params field
index: index of the params field to be extracted
function late.append_valints(valints, extravalints)Appends a values and intensities list to another. Usefull to add extra values in further computation.
valints: List where extra valints will be append
extravalints: Extra valints to append
function late.multiply_valints(valints)Returns the result of a multiplication of values with intensities
valints: Value/Intensity list;
function late.sum_valints(valints)Returns the result of a sum of values with intensities
valints: Value/Intensity list
function late.superpose_valints(valints, base_value)Returns a ratio superposition (like if each ratio was a greyscale value and intensities where alpha chanel).
valints Value/Intensity list of ratios (values should go from 0 to 1)
base_value Base ratio value on which valints are superposed
function late.superpose_color_valints(valints, background_color)Returns a color superposition with alpha channel and intensity (actually, intensity is considered as a factor on alpha channel)
valints Value/Intensity list of colors
background_color Background color (default none)
function late.mix_color_valints(valints)Mix colors with intensity. Returns {r,g,b,a} table representing the resulting color.
valints List of colorstrings (value=) and intensities
function late.color_to_table(colorspec)Converts a colorspec to a {r,g,b,a} table. Returns the conversion result.
colorspec Can be a standard color name, a 32 bit integer or a table
function late.color_to_rgb_texture(colorspec)Converts a colorspec to a "#RRGGBB" string ready to use in textures.
colorspec Can be a standard color name, a 32 bit integer or a table
-- Impact on player speed
-- Params :
-- 1: Speed multiplier [0..infinite]. Default: 1
late.register_impact_type('player', 'speed', {
-- Reset function basically resets target speed to default value
reset = function(impact)
minetest.set_physics_override(impact.target, {speed = 1.0})
end,
-- Main function actually coding the impact
update = function(impact)
minetest.set_physics_override(impact.target, {
speed = late.multiply_valints(
late.get_valints(impact.params, 1))
})
end,
})late.get_storage_for_target(target)Retrieves or create the effects_api storage for a target.
target: Target
Returns storage associated with the target or nil if target not suitable.