I patched together some version of this using nested dictionaries:
var abilities: Dictionary = {
AbilityData.Trigger.BEFORE_ATTACK : {},
AbilityData.Trigger.ON_ATTACK : {},
AbilityData.Trigger.ON_HIT : {},
AbilityData.Trigger.ON_KILL : {},
AbilityData.Trigger.ON_DEATH : {},
AbilityData.Trigger.ON_JUMP : {},
AbilityData.Trigger.PASSIVE : {}
}
with each value being another key:value pair of { "ability_id": <ability-node> }
so I can keep a reference to the Ability node and use dictionary functions like .has() to check if a character has a specific ability:
func has_ability(ability_data: AbilityData) -> bool:
if abilities[ability_data.trigger_type].has(ability_data.id):
return true
return false
Then when a trigger fires, it calls this (I omitted the return code):
// Activates all abilities with the specified trigger type. Returns an array containing each ability that was activated this way.
//trigger_type is an enum
//data is just a resource containing things like position, target, ability owner, etc
func trigger(trigger_type: AbilityData.Trigger, data: AbilityActivationData) -> Array[Ability]:
var abilities_to_activate: Dictionary = abilities.get(trigger_type)
// Loops through the list of Ability nodes.
for ability in abilities_to_activate.values():
ability.activate(data)
abilities_activated.append(ability)
This seems to work, but it still gives me that tickling sensation that it could be a little cleaner.
It depends entirely on the company you work for. Even then, I wouldn’t exactly describe the work as “chill”