TimedModifier
Inherits: RefCounted < Object
Inherited By: Attack2DModifier, Projectile2DModifier
Base class for All Projectiles limited duration class modifiers.
Description
The TimedModifier base class manages temporary effects applied to All Projectiles main classes. It handles:
- Lifetime tracking and expiration.
- Stacking of multiple instances of the same modifier.
- Callback execution for application, update, and removal.
- Custom property management for both shared and instance-specific values.
- Validation of modifier application.
Its main purpose is to provide an easy interface to help you create your own Projectile/Attacks buffs, debuffs, or other temporary effects.
Tutorials
Properties
Methods
void | _init |
TimedModifier | add_global_property |
TimedModifier | add_individual_property |
TimedModifier | clone |
void | copy |
void | disable |
void | enter |
void | exit |
TimedModifier | set_property |
bool | update_lifetime |
void | update |
Property Descriptions
Array[TimedModifier] copies = []
Array containing all instances of this modifier applied to the same target.
float duration = 1.0
Original modifier duration in seconds.
Dictionary[StringName, Variant] global_properties = {}
This dictionary is shared between all cloned instances.
If you change its values, you will change them in all cloned modifiers.
Dictionary[StringName, Variant] individual_properties = {}
This dictionary is independent between all cloned instances.
Modifying it will only affect this modifier instance.
bool is_active = false
Variable state for modifier update validation.
bool is_permanent = false
If true
the modifier never expires and remains active indefinitely.
float lifetime = 1.0
Remaining lifetime in seconds.
StringName name
Unique identifier. Used to distinguish between different modifiers regardless of type.
Callable on_enter
Modifier custom application callback.
Callable on_exit
Modifier custom expiration callback.
Callable on_update
Modifier custom update callback.
Callable on_validation
Modifier custom validation callback.
int stacks = 0
Current number of times this modifier has been applied to the same target.
RefCounted target
- void set_target(value: RefCounted)
- RefCounted get_target()
Object currently being affected by this modifier.
bool use_custom_update_method = false
If true
the modifier uses a custom update method.
Method Descriptions
void _init(_name: StringName = StringName(), _duration: float = 1.0, _on_enter: Callable = Calllable(), _on_exit: Callable = Calllable(), _on_update: Callable = Calllable(), _on_validation: Callable = Calllable())
Initializes a new modifier from the given values.
Takes the following arguments:
_name
: Modifier global identifier.
_duration
: Active time span of the modifier in seconds.
_on_enter
: Optional Callable to overwrite the set on_enter modifier property.
_on_exit
: Optional Callable to overwrite the set on_exit modifier property.
_on_update
: Optional Callable to overwrite both on_update modifier property.
_on_validation
: Optional Callable to overwrite the set on_validation modifier property.
Each Callable argument follows a define pattern and must take a set number of parameters and return a specific value.
-
The
_on_enter
callable returnsvoid
and takes the following parameters:modifier
: A representation of the modifier itself.target
: A representation of the object that the modifier is targeting, whether it is a Projectile or an Attack.extends Node2D @onready var projectile_caller = $ProjectileCaller2D func _process(_delta): if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): var destination = get_global_mouse_position() projectile_caller.request_projectile(0, position, destination) # In this example the "on_projectile_buff_enter" function is passed as a Callable in the optional "_on_enter" parameter. func _input(event): if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: projectile_caller.add_projectile_modifier(0, Projectile2DModifier.new("PROJ_BUFF", 1.0, on_projectile_buff_enter, on_projectile_buff_exit)) # This function will be called when the modifier is applied. func on_projectile_buff_enter(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances += 2 proj.proj_spread = Projectile2D.ProjectileSpread.ANGULAR proj.angular_spread = 90 func on_projectile_buff_exit(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances -= 2 proj.proj_spread = proj.resource.proj_spread proj.angular_spread = proj.resource.angular_spread
-
The
_on_exit
callable returnsvoid
and takes the following parameters:modifier
: A representation of the modifier itself.target
: A representation of the object that the modifier is targeting, whether it is a Projectile or an Attack.extends Node2D @onready var projectile_caller = $ProjectileCaller2D func _process(_delta): if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): var destination = get_global_mouse_position() projectile_caller.request_projectile(0, position, destination) # In this example the "on_projectile_buff_exit" function is passed as a Callable in the optional "_on_exit" parameter. func _input(event): if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: projectile_caller.add_projectile_modifier(0, Projectile2DModifier.new("PROJ_BUFF", 1.0, on_projectile_buff_enter, on_projectile_buff_exit)) func on_projectile_buff_enter(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances += 2 proj.proj_spread = Projectile2D.ProjectileSpread.ANGULAR proj.angular_spread = 90 # This function will be called when the modifier is expired. func on_projectile_buff_exit(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances -= 2 proj.proj_spread = proj.resource.proj_spread proj.angular_spread = proj.resource.angular_spread
-
The
_on_update
callable returnsvoid
and takes the following parameters:modifier
: A representation of the modifier itself.target
: A representation of the object that the modifier is targeting, whether it is a Projectile or an Attack.delta
: The time elapsed in seconds since the previous call to _on_update.extends Node2D @onready var projectile_caller = $ProjectileCaller2D func _process(_delta): if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): var destination = get_global_mouse_position() projectile_caller.request_projectile(0, position, destination) # In this example the "on_projectile_buff_update" function is passed as a Callable in the optional "_on_update" parameter. func _input(event): if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: projectile_caller.add_projectile_modifier(0, Projectile2DModifier.new("PROJ_BUFF", 1.0, Callable(), Callable(), on_projectile_buff_update)) #on_projectile_buff_enter, on_projectile_buff_exit)) # This function will be called on every frame. func on_projectile_buff_update(_modifier: Projectile2DModifier, proj: Projectile2D, delta: float) -> void: print("Projectile buff is active!")
-
The
_on_validation
callable must return abool
(as an element representing whether the modifier can be applied or not) and take the following two parameters:modifier
: A representation of the modifier itself.target
: A representation of the object that the modifier is targeting, whether it is a Projectile or an Attack.extends Node2D @onready var projectile_caller = $ProjectileCaller2D func _process(_delta): if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): var destination = get_global_mouse_position() projectile_caller.request_projectile(0, position, destination) # In this example the "refresh_projectile_validation" function is passed as a Callable in the optional "_on_validation" parameter. if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT): projectile_caller.add_projectile_modifier(0, Projectile2DModifier.new("PROJ_BUFF", 1.0, on_projectile_buff_enter, on_projectile_buff_exit, Callable(), refresh_projectile_validation)) func on_projectile_buff_enter(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances += 2 proj.proj_spread = Projectile2D.ProjectileSpread.ANGULAR proj.angular_spread = 90 func on_projectile_buff_exit(_modifier: Projectile2DModifier, proj: Projectile2D) -> void: proj.instances -= 2 proj.proj_spread = proj.resource.proj_spread proj.angular_spread = proj.resource.angular_spread # This function will determine whether or not the modifier is applied. func refresh_projectile_validation(_modifier: Projectile2DModifier, _proj: Projectile2D) -> bool: if (_proj.projectile_modifiers.has(_modifier.name)): _proj.projectile_modifiers[_modifier.name].lifetime = _modifier.duration return false return true
TimedModifier add_global_property(property: StringName, value: Variant)
Returns itself for method chaining.
Adds a new element at the global_properties dictionary, with the given value
at the given key property
.
var mod_1: Projectile2DModifier = Projectile2DModifier.new("PROJECTILE_BUFF", 1.0)
var mod_2: Projectile2DModifier = mod_1.clone()
mod_1.add_global_property("FREQUENCY", 0.2)
print(mod_1.global_properties["FREQUENCY"]) # Prints (0.2)
print(mod_2.global_properties["FREQUENCY"]) # Also prints (0.2)
TimedModifier add_individual_property(property: StringName, value: Variant)
Returns itself for method chaining.
Adds a new element at the individual_properties dictionary, with the given value
at the given key property
.
var mod_1: Projectile2DModifier = Projectile2DModifier.new("PROJECTILE_BUFF", 1.0)
var mod_2: Projectile2DModifier = mod_1.clone()
mod_1.add_individual_property("STALL", 10.0)
print(mod_1.individual_properties.get("STALL", -1)) # Prints (10.0)
print(mod_2.individual_properties.get("STALL", -1)) # Prints (-1.0) because "STALL" does not exist here
TimedModifier clone()
Returns an identical copy of the modifier.
void copy(base: TimedModifier)
Copies all properties from the base
modifier.
void disable()
Disables the modifier and cleans up physics resources.
Note: This method does not deactivates the modifier. Call the exit method for that.
void enter()
Default behavior for modifiers start.
Activates the modifier on its target, executes the enter callback if any, and increments the stack count.
void exit()
Default behavior for modifiers end.
Deactivates the modifier, executes the exit callback if any, and disables the modifier.
TimedModifier set_property(property: StringName, value: Variant)
Returns itself for method chaining.
Assigns value
to the given projectile property
. If the projectile property does not exist or the given value
's type doesn't match, nothing happens.
var modifier: Projectile2DModifier = Projectile2DModifier.new("PROJECTILE_BUFF", 1.0)
modifier.set_property("lifetime", 10.0)
print(modifier.lifetime) # Prints (10.0)
bool update_lifetime(delta: float)
Returns true
as long as the modifier remains active.
void update(delta: float)
Default update method. Can be overridden for custom update behavior.