82 lines
2.8 KiB
GDScript
82 lines
2.8 KiB
GDScript
class_name ActionRuleResolver
|
|
extends RefCounted
|
|
|
|
|
|
static func can_execute(context: Dictionary, action: Resource) -> bool:
|
|
if action == null:
|
|
return false
|
|
var life_state := _context_axis(context, "life_state", &"Alive")
|
|
if life_state != &"Alive":
|
|
return false
|
|
var allowed_ground := _string_name_array(action.get("allowed_ground_states"))
|
|
if not allowed_ground.is_empty() and not allowed_ground.has(_context_axis(context, "ground_state", &"Grounded")):
|
|
return false
|
|
var allowed_phases := _string_name_array(action.get("allowed_action_phases"))
|
|
if not allowed_phases.is_empty() and not allowed_phases.has(_context_axis(context, "action_phase", &"Neutral")):
|
|
return false
|
|
if not _passes_effect_rule_modifiers(context, action):
|
|
return false
|
|
return true
|
|
|
|
|
|
static func can_move_freely(context: Dictionary) -> bool:
|
|
if _context_axis(context, "life_state", &"Alive") != &"Alive":
|
|
return false
|
|
if _context_axis(context, "action_phase", &"Neutral") != &"Neutral":
|
|
return false
|
|
for modifier: Resource in _action_rule_modifiers(context):
|
|
if bool(modifier.get("block_movement")):
|
|
return false
|
|
return true
|
|
|
|
|
|
static func _context_axis(context: Dictionary, key: String, fallback: StringName) -> StringName:
|
|
if context.has(key):
|
|
return StringName(str(context[key]))
|
|
return fallback
|
|
|
|
|
|
static 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
|
|
|
|
|
|
static func _passes_effect_rule_modifiers(context: Dictionary, action: Resource) -> bool:
|
|
var action_tags := _string_name_array(action.get("action_tags"))
|
|
for modifier: Resource in _action_rule_modifiers(context):
|
|
var blocked_tags := _string_name_array(modifier.get("blocked_action_tags"))
|
|
if not blocked_tags.is_empty() and _has_any(action_tags, blocked_tags):
|
|
return false
|
|
var allowed_tags := _string_name_array(modifier.get("allowed_action_tags"))
|
|
if not allowed_tags.is_empty() and not _has_any(action_tags, allowed_tags):
|
|
return false
|
|
return true
|
|
|
|
|
|
static func _action_rule_modifiers(context: Dictionary) -> Array[Resource]:
|
|
if context.has("action_rule_modifiers"):
|
|
return _resource_array(context["action_rule_modifiers"])
|
|
var container = context.get("effect_container", null)
|
|
if container != null and container.has_method("action_rule_modifiers"):
|
|
return _resource_array(container.call("action_rule_modifiers"))
|
|
return []
|
|
|
|
|
|
static func _resource_array(value: Variant) -> Array[Resource]:
|
|
var result: Array[Resource] = []
|
|
if value is Array:
|
|
for item: Variant in value:
|
|
if item is Resource:
|
|
result.append(item)
|
|
return result
|
|
|
|
|
|
static func _has_any(values: Array[StringName], candidates: Array[StringName]) -> bool:
|
|
for value: StringName in values:
|
|
if candidates.has(value):
|
|
return true
|
|
return false
|