93 lines
3.1 KiB
GDScript
93 lines
3.1 KiB
GDScript
class_name EffectInstance
|
|
extends RefCounted
|
|
|
|
var definition: Resource
|
|
var remaining := 0.0
|
|
var stacks := 1
|
|
var source: Variant = &"-"
|
|
|
|
|
|
static func create(next_definition: Resource, next_source: Variant = &"-") -> RefCounted:
|
|
var script: Script = load("res://resources/effects/effect_instance.gd")
|
|
var instance: RefCounted = script.new()
|
|
instance.definition = next_definition
|
|
instance.remaining = float(next_definition.get("duration"))
|
|
if StringName(str(next_definition.get("duration_type"))) == &"until_event":
|
|
instance.remaining = 1.0
|
|
instance.source = next_source
|
|
return instance
|
|
|
|
|
|
func is_expired() -> bool:
|
|
return remaining <= 0.0 and StringName(str(definition.get("duration_type"))) != &"infinite"
|
|
|
|
|
|
func tick_time(delta: float) -> void:
|
|
var duration_type := StringName(str(definition.get("duration_type")))
|
|
if duration_type == &"seconds":
|
|
remaining -= delta
|
|
|
|
|
|
func tick_beats(beats: float) -> void:
|
|
var duration_type := StringName(str(definition.get("duration_type")))
|
|
if duration_type == &"beats":
|
|
remaining -= beats
|
|
|
|
|
|
func tick_event(event_name: StringName, context: Dictionary = {}) -> void:
|
|
if not matches_event_context(context):
|
|
return
|
|
var duration_type := StringName(str(definition.get("duration_type")))
|
|
if duration_type == &"actions" and event_name == &"on_action_start":
|
|
remaining -= 1.0
|
|
elif duration_type == &"hits" and event_name == &"on_hit":
|
|
remaining -= 1.0
|
|
elif duration_type == &"hurts" and event_name == &"on_hurt":
|
|
remaining -= 1.0
|
|
elif duration_type == &"measures" and event_name == &"on_measure_start":
|
|
remaining -= 1.0
|
|
elif duration_type == &"until_event" and event_name == StringName(str(definition.get("until_event"))):
|
|
remaining = 0.0
|
|
|
|
|
|
func matches_event_context(context: Dictionary = {}) -> bool:
|
|
var action_tags := _event_action_tags(context)
|
|
var required_tags := _string_name_array(definition.get("required_event_action_tags"))
|
|
if not required_tags.is_empty() and not _has_any(action_tags, required_tags):
|
|
return false
|
|
var blocked_tags := _string_name_array(definition.get("blocked_event_action_tags"))
|
|
if not blocked_tags.is_empty() and _has_any(action_tags, blocked_tags):
|
|
return false
|
|
return true
|
|
|
|
|
|
func _event_action_tags(context: Dictionary) -> Array[StringName]:
|
|
if context.has("action_tags"):
|
|
return _string_name_array(context["action_tags"])
|
|
var action: Resource = context.get("action", null) as Resource
|
|
if action != null:
|
|
return _string_name_array(action.get("action_tags"))
|
|
var result = context.get("result", {})
|
|
if result is Dictionary:
|
|
if result.has("action_tags"):
|
|
return _string_name_array(result["action_tags"])
|
|
var result_action: Resource = result.get("action", null) as Resource
|
|
if result_action != null:
|
|
return _string_name_array(result_action.get("action_tags"))
|
|
return []
|
|
|
|
|
|
func _string_name_array(value: Variant) -> Array[StringName]:
|
|
var result: Array[StringName] = []
|
|
if value is Array:
|
|
for item: Variant in value:
|
|
result.append(StringName(str(item)))
|
|
return result
|
|
|
|
|
|
func _has_any(values: Array[StringName], candidates: Array[StringName]) -> bool:
|
|
for value: StringName in values:
|
|
if candidates.has(value):
|
|
return true
|
|
return false
|