Attack2D

Inherits: RefCounted < Object

A basic interface for timed/consecutive Projectile2D spawning.


Description

The Attack2D class is an intermediary state machine designed to assist you in the common task of spawning projectiles. It helps you manage the complete lifecycle of your projectile-based attacks; from charging, to windup, to recovery. In short, use it to delegate the fire rate of your weapons as well as the delay and offset of your attacks.

As a whole, the Attack2D state machine is composed of four phases:

  • Charge.
  • Anticipation.
  • Main.
  • Recovery.

Note: Any attack phase with duration of 0 seconds or below margin will be skipped.

Note: Unlike projectiles, assigning custom methods to your attacks will overwrite its “normal” methods. If you want to keep its default functionanily you will have to invoke these “normal functions” inside your custom methods, like this:

extends Node2D

@onready var projectile_manager: ProjectileManager2D = $ProjectileManager2D


func _ready() -> void:
	projectile_manager.get_attack(0).set_on_recovery_enter(custom_recovery_enter).set_on_recovery_exit(custom_recovery_exit).set_on_recovery_update(custom_recovery_update)


# As with Projectiles, your Attack methods must follow a defined pattern:
func custom_recovery_enter(attack: Attack2D) -> void:
	attack.recovery_enter()	# Calling the default behavior for recovery phase start
	print("Hi from recovery start")


func custom_recovery_exit(attack: Attack2D) -> void:
	attack.recovery_exit()	# Calling the default behavior for recovery phase end
	print("Goodbye from recovery end")


func custom_recovery_update(attack: Attack2D, delta: float) -> void:
	attack.recovery_update(delta)	# Calling the default behavior for recovery phase update
	print("Greetings from recovery update")

Tutorials


Properties



Methods



Signals

direct_projectile_request(_projectile: Projectile2D, _pi: PackedInfo)

Emitted on ONE_BY_ONE requests.

The most straightway call with the ProjectileProcessor2D. Directly requests the creation of one new projectiles, intentionally skipping projectiles with multiple instances.


modifier_requested(_attack_modifier: Attack2DModifier)

Emitted an Attack2D request the application of an Attack2DModifier.

Directly requests modifier addition to the ProjectileProcessor2D.


projectile_requested(_projectile: Projectile2D, _position: Vector2, _destination: Vector2, _target: Node2D, move_method: Callable, start_method: Callable, collision_method: Callable, expired_method: Callable)

Emitted when an Attack2D request the creation of any new Projectile2Ds.

Directly requests the creation of new projectiles to the ProjectileProcessor2D.



Enumerations

enum AttackChargeTrigger :


enum AttackChargeType :


enum AttackState :

  • AttackState ATTACK_CHARGE = 0

  • Preparation phase before the attack even begins.

  • AttackState ATTACK_ANTICIPATE = 1

  • Wind-up phase before the main attack.

  • AttackState ATTACK_MAIN = 2

  • Active phase where projectiles are spawned.

  • AttackState ATTACK_RECOVERY = 3

  • Cooldown phase after the attack completes.


enum ExecutionType :

  • ExecutionType MANDATORY = 0

  • Once an attack starts, it cannot be stopped.

  • ExecutionType AS_REQUESTED = 1

  • Multi-instance attacks can be interrupted between shots.


enum InstancesSpawnType :


enum OnInterruptedExecutionContinuation :



Property Descriptions

float accumulated_charge = 0

Collective time accumulation for DISCRETE charged attacks.


float attack_anticipate_time = 0

Duration of the anticipation phase in seconds.


float attack_charge_time = 0

Duration of the charge phase in seconds.


float attack_duration_time = 0

Duration of the main attack phase in seconds.


Dictionary[StringName, Attack2DModifier] attack_modifiers = {}

Dictionary of all modifiers affecting this attack.


Vector2 attack_offset = Vector2.ZERO

Added distance to projectile position on creation.


float attack_recovery_time = 0

Duration of the recovery phase in seconds.


ProjectileManager2D caller

Entity that initiated the attack.

Used for flexible position and direction references.


bool can_reload = true

If true the attack can reload its remaining shoots.


AttackChargeTrigger charge_trigger = 0

Charge completion condition.


AttackChargeType charge_type = 0

Charge accumulation tracking method.


OnInterruptedExecutionContinuation continuation_type = 0

ONE_BY_ONE attacks behavior when resuming interrupted attacks.


float current_state_lifetime = -1

Remaining lifetime of the current attack phase in seconds.


AttackState current_state = 0

Current phase of the attack lifecycle.

Determines which callbacks and methods are executed.


ExecutionType execution_type = 0

ONE_BY_ONE attacks continuation condition.


Dictionary[StringName, Variant] global_properties = {}

This dictionary is shared between all attacks created by its original blueprint.

If you change its values, you will change them in all their attacks.


Dictionary[StringName, Variant] individual_properties = {}

This dictionary is independent in all attacks created by its original blueprint.

Modifying it will only affect this attack instance.


bool instance_attack_modifiers = false

If true the attack_modifiers dictionary will be independent in all attack copies made by your ProjectileManager2Ds instead of being shared among all of them.

This may seem like the optimal behavior but it is recommended to set it to false.


int instances = 0

Fixed Projectile instances on request.


bool is_active = false

Variable state for weapon update validation.


bool is_linked = false

If true the attack itself is connected with the ProjectileProcessor2D and can request projectiles and modify attacks.


bool is_under_uninterrupted_request = false

If true the original caller has requested new projectiles on every frame without a break.


float margin = 0

Minimum duration for attack phases.

Attack phases below this duration will be skipped.


Callable on_anticipate_enter

Attack custom anticipate phase enter callback.


Callable on_anticipate_exit

Attack custom anticipate phase exit callback.


Callable on_anticipate_update

Attack custom anticipate phase update callback.


Callable on_charge_enter

Attack custom charge phase enter callback.


Callable on_charge_exit

Attack custom charge phase exit callback.


Callable on_charge_update

Attack custom charge phase update callback.


Callable on_completed

Attack custom completion callback.


Callable on_main_enter

Attack custom main phase enter callback.


Callable on_main_exit

Attack custom main phase exit callback.


Callable on_main_update

Attack custom main phase update callback.


Callable on_recovery_enter

Attack custom recovery phase enter callback.


Callable on_recovery_exit

Attack custom recovery phase exit callback.


Callable on_recovery_update

Attack custom recovery phase update callback.


Callable on_start

Attack custom start callback.


bool override_attack_duration = false

If true overrides the attack_duration_time property with its assign projectile spawn_interval value.


bool override_direction = false

If true the attack ignores the given requested destinations and uses its own ProjectileManager2D Node right direction instead. See Transform2D.x.


bool override_position = false

If true the attack ignores the given spawn positions and uses its own ProjectileManager2D Node global position instead.


PackedInfo pi

Projectile spawn parameters.


Projectile2D projectile

Reference to the requested projectile.

Defines what gets spawned during the attack.


int remaining_shots = 0

Current attack repetitions until expiration.

Only available on ONE_BY_ONE executions.


bool requested_interaction = false

If true the original caller has requested the creation of more projectiles on this frame.


AttackBlueprint2D resource

Fixed attack blueprint.


InstancesSpawnType spawn_type = 0

Determines the spawning method of projectiles with multiple instances and with timed spawn intervals:

  • ALL_AT_ONCE: All projectile instances spawn simultaneously.
  • ONE_BY_ONE: Projectile instances spawn sequentially with delays.

float sub_frame_excess = 0

Remnant for attacks with lifetimes below framerate.

Only available on ONE_BY_ONE executions.



Method Descriptions

void _init(_resource: AttackBlueprint2D = null, proj_caller: Node2D = null)

Initializes a new attack instance from the values of the given AttackBlueprint2D _resource parameter.


Attack2D 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 attack_1: Attack2D = projectile_manager.get_attack(0)
var attack_2: Attack2D = projectile_manager.get_attack(0).clone()

attack_1.add_global_property("RECOIL", 11.5)
print(attack_1.global_properties["RECOIL"]) # Prints (11.5)
print(attack_2.global_properties["RECOIL"]) # Also prints (11.5)


Attack2D 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 attack_1: Attack2D = projectile_manager.get_attack(0)
var attack_2: Attack2D = projectile_manager.get_attack(0).clone()

attack_1.add_individual_property("DURABILITY", 100)
print(attack_1.individual_properties.get("DURABILITY", -1)) # Prints (100)
print(attack_2.individual_properties.get("DURABILITY", -1)) # Prints (-1.0) because "DURABILITY" does not exist here


bool add_modifier(modifier: Attack2DModifier)

Returns true if modifier was successfully added.

If valid, modifier gets added to attack_modifiers and emits the modifier_requested signal.

It is strongly recommended to use your ProjectileManager2D add_attack_modifier method instead.

var attack: Attack2D = projectile_manager.get_attack(0)
attack.add_modifier(Attack2DModifier.new("ATTACK_BUFF", 1.0))


void anticipate_enter()

Default behavior for anticipate phase start.


void anticipate_exit()

Default behavior for anticipate phase end.


void anticipate_update(_delta: float)

Default behavior for anticipate phase update.


void assign(_projectile: Projectile2D, _caller: ProjectileManager2D, _pi: PackedInfo = pi)

Set up an attack essential parameters.


bool change_state(state: AttackState)

Transitions to new state attack phase.

Also calls its appropriate enter callbacks.


void charge_enter()

Default behavior for charge phase start.


void charge_exit()

Default behavior for charge phase end.


void charge_update(_delta: float)

Default behavior for charge phase update.


Attack2D clone()

Returns an identical copy of the attack.


void copy(base: Attack2D)

Copies all properties from the base attack.


void direct_request(_projectile: Projectile2D = projectile, _pi: PackedInfo = pi)

Requests the creation of new projectiles through the direct_projectile_request signal.


void disable()

Interrupts/completes the attack sequence.

Calls on_completed callback.


float get_current_state_duration()

Returns duration of the current attack phase, whatever it may be.


bool is_charge_completed()

Returns true if the charge phase is completed.

Depends on charge_trigger setting.


Connects all attack signals to the given ProjectileProcessor2D instance.


void main_enter()

Default behavior for main phase start.

Sets up projectile spawning on ALL_AT_ONCE executions.


void main_exit()

Default behavior for main phase end.


void main_update(_delta: float)

Default behavior for main phase update.

Handles projectile spawning on ONE_BY_ONE executions.


void recovery_enter()

Default behavior for recovery phase start.


void recovery_exit()

Default behavior for recovery phase end.

Completes the attack.


void recovery_update(_delta: float)

Default behavior for recovery phase update.


void reload(proj: Projectile2D)

Sets proj as its projectile and proj.instances as its remaining_shots on ONE_BY_ONE executions.


bool remove_modifier(modifier_name: StringName)

Returns true if the modifier with key modifier_name was successfully removed.

Removes a modifier by name from attack_modifiers and calls its exit() method.

It is strongly recommended to use your ProjectileManager2D remove_attack_modifier method instead.

var attack: Attack2D = projectile_manager.get_attack(0)
attack.remove_modifier("ATTACK_BUFF")

void request_projectile(_projectile: Projectile2D = projectile)

Requests the creation of new projectiles through the projectile_requested signal.


void reset()

Resets the attack to its initial state using its blueprint.

Clears all runtime modifications and custom properties.


Attack2D set_on_anticipate_enter(method: Callable)

Returns itself for method chaining.

Sets on_anticipate_enter callback.


Attack2D set_on_anticipate_exit(method: Callable)

Returns itself for method chaining.

Sets on_anticipate_exit callback.


Attack2D set_on_anticipate_update(method: Callable)

Returns itself for method chaining.

Sets on_anticipate_update callback.


Attack2D set_on_charge_enter(method: Callable)

Returns itself for method chaining.

Sets on_charge_enter callback.


Attack2D set_on_charge_exit(method: Callable)

Returns itself for method chaining.

Sets on_charge_exit callback.


Attack2D set_on_charge_update(method: Callable)

Returns itself for method chaining.

Sets on_charge_update callback.


Attack2D set_on_completed(method: Callable)

Returns itself for method chaining.

Sets on_completed callback.


Attack2D set_on_main_enter(method: Callable)

Returns itself for method chaining.

Sets on_main_enter callback.


Attack2D set_on_main_exit(method: Callable)

Returns itself for method chaining.

Sets on_main_exit callback.


Attack2D set_on_main_update(method: Callable)

Returns itself for method chaining.

Sets on_main_update callback.


Attack2D set_on_recovery_enter(method: Callable)

Returns itself for method chaining.

Sets on_recovery_enter callback.


Attack2D set_on_recovery_exit(method: Callable)

Returns itself for method chaining.

Sets on_recovery_exit callback.


Attack2D set_on_recovery_update(method: Callable)

Returns itself for method chaining.

Sets on_recovery_update callback.


Attack2D set_on_start(method: Callable)

Returns itself for method chaining.

Sets on_start callback.


Attack2D set_property(property: StringName, value: Variant)

Returns itself for method chaining.

Assigns value to the given attack property. If the attack property does not exist or the given value's type doesn't match, nothing happens.

var attack: Attack2D = projectile_manager.get_attack(0)
attack.set_property("attack_duration_time", 2.5)
print(attack.attack_duration_time) # Prints (2.5)

void start()

Validates and initiates the attack phases sequence.


bool update_lifetime(_delta: float, local_margin: float = 0)

Updates the current attack phase lifetime.

Returns true as long as the current phase remains active.


bool update(_delta: float)

Updates the attack state machine.

Returns true as long as the attack itself remains active.


bool validate_attack()

Returns true if the attack can be executed.

A valid attack requires direct processor connection and a valid projectile.