Initial project sync

This commit is contained in:
wxm
2026-07-06 22:55:14 -07:00
commit 8cca00d0da
1066 changed files with 58585 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
class_name DefenseResolver
extends RefCounted
static func resolve_effective_defense(context: Dictionary, attack_tags: Array[StringName] = []) -> Dictionary:
var defense_state := StringName(str(context.get("defense_state", &"Vulnerable")))
# 背刺破格挡只作用于姿态本身的 Parrying,先降级再合并 effect 修饰符:
# 否则霸体(SuperArmor,优先级低于 Parrying)会先被格挡态吞掉、
# 再随背刺降级一起丢失,违反霸体「无击退、不打断」的承诺。
if defense_state == &"Parrying" and not bool(context.get("attack_from_front", true)):
defense_state = &"Vulnerable"
var modifiers := _defense_modifiers(context, attack_tags)
for modifier: Resource in modifiers:
var modified_state := StringName(str(modifier.get("defense_state")))
if not modified_state.is_empty():
defense_state = _stronger_defense_state(defense_state, modified_state)
var damage_mult := _damage_mult_for_state(defense_state, context)
var interrupts := defense_state != &"Invincible" and defense_state != &"SuperArmor" and defense_state != &"Parrying"
for modifier: Resource in modifiers:
damage_mult *= float(modifier.get("damage_mult"))
interrupts = interrupts and bool(modifier.get("interrupts"))
return {
"defense_state": defense_state,
"damage_mult": damage_mult,
"interrupts": interrupts,
}
static func _damage_mult_for_state(defense_state: StringName, context: Dictionary = {}) -> float:
match defense_state:
&"Invincible":
return 0.0
&"Parrying":
return _parry_damage_mult(context)
&"SuperArmor":
return 1.0
_:
return 1.0
static func _parry_damage_mult(context: Dictionary) -> float:
match StringName(str(context.get("block_judgement", &"perfect"))):
&"good":
return 0.2
&"bad":
return 0.4
&"miss":
return 1.0
return 0.0
static func _defense_modifiers(context: Dictionary, attack_tags: Array[StringName]) -> Array[Resource]:
var modifiers: Array[Resource] = []
if context.has("defense_modifiers"):
modifiers = _resource_array(context["defense_modifiers"])
else:
var container = context.get("effect_container", null)
if container != null and container.has_method("defense_modifiers"):
modifiers = _resource_array(container.call("defense_modifiers"))
var matched: Array[Resource] = []
for modifier: Resource in modifiers:
if _modifier_matches_attack_tags(modifier, attack_tags):
matched.append(modifier)
return matched
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 _modifier_matches_attack_tags(modifier: Resource, attack_tags: Array[StringName]) -> bool:
var required_tags := _string_name_array(modifier.get("required_attack_tags"))
return required_tags.is_empty() or _has_any(attack_tags, required_tags)
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 _has_any(values: Array[StringName], candidates: Array[StringName]) -> bool:
for value: StringName in values:
if candidates.has(value):
return true
return false
static func _stronger_defense_state(current_state: StringName, candidate_state: StringName) -> StringName:
return candidate_state if _defense_priority(candidate_state) > _defense_priority(current_state) else current_state
static func _defense_priority(defense_state: StringName) -> int:
match defense_state:
&"Invincible":
return 4
&"Parrying":
return 3
&"SuperArmor":
return 2
&"Vulnerable":
return 1
_:
return 0