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