Fixes several attack chain call sites (#27553)

This commit is contained in:
warriorstar-orion
2024-12-06 17:20:12 -05:00
committed by GitHub
parent 9a17eccd0d
commit d23c808e47
6 changed files with 53 additions and 19 deletions
@@ -61,7 +61,7 @@
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS)
RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(alert_admins_on_destroy))
/obj/item/melee/saber/attack(mob/living/target, mob/living/user)
/obj/item/melee/saber/attack__legacy__attackchain(mob/living/target, mob/living/user)
if(user.a_intent != INTENT_HELP || !ishuman(target))
return ..()
if(!COOLDOWN_FINISHED(src, slap_cooldown))
@@ -308,7 +308,7 @@
return
applying_meds = TRUE
for(var/obj/item/reagent_containers/P in contents)
if(P.attack(M, user))
if(P.attack__legacy__attackchain(M, user))
applying_meds = FALSE
else
applying_meds = FALSE
@@ -357,7 +357,7 @@
C.visible_message("<span class='danger'>[C] [rapid_intake_message]</span>")
if(do_mob(C, C, 100)) // 10 seconds
for(var/obj/item/reagent_containers/pill/P in contents)
P.attack(C, C)
P.attack__legacy__attackchain(C, C)
C.visible_message("<span class='danger'>[C] [rapid_post_instake_message]</span>")
return
@@ -560,7 +560,7 @@
var/threat = C.assess_threat(src)
var/prev_intent = a_intent
a_intent = INTENT_HELP
baton.attack(C, src)
baton.attack__legacy__attackchain(C, src)
a_intent = prev_intent
baton_delayed = TRUE
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
@@ -263,7 +263,7 @@
var/threat = C.assess_threat(src)
var/prev_intent = a_intent
a_intent = harmbaton ? INTENT_HARM : INTENT_HELP
baton.attack(C, src)
baton.attack__legacy__attackchain(C, src)
a_intent = prev_intent
baton_delayed = TRUE
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
@@ -211,7 +211,7 @@
if(S)
H.drop_item()
H.put_in_active_hand(S)
S.attack(H, H)
S.attack__legacy__attackchain(H, H)
qdel(src)
else
..()
+47 -13
View File
@@ -22,6 +22,7 @@ class AttackChainCall:
var_type: p | None
call_name: str
source_info: any
legacy: bool
def make_error_message(self):
return f"{self.proc_decl.type_path}/{self.proc_decl.name}(...) calls {self.call_name}(...) on var {self.var_type}/{self.var_name}"
@@ -66,7 +67,7 @@ class AttackChainCallWalker:
return None
def add_attack_call(self, var_name, chain_call, source_info):
def add_attack_call(self, var_name, chain_call, source_info, legacy):
var_type = self.get_var_type(var_name)
CALLS[var_type].add(
AttackChainCall(
@@ -75,6 +76,7 @@ class AttackChainCallWalker:
self.get_var_type(var_name),
chain_call,
source_info,
legacy=legacy,
)
)
@@ -83,15 +85,22 @@ class AttackChainCallWalker:
def visit_Expr(self, node, source_info):
if node.kind == NodeKind.CALL:
legacy = False
record = False
if "__legacy__attackchain" in node.name.name:
if node.expr:
if node.expr.kind == NodeKind.IDENTIFIER:
self.add_attack_call(
str(node.expr), node.name.name, source_info
)
elif node.expr.kind == NodeKind.CONSTANT:
if not node.expr.constant.val:
self.add_attack_call("src", node.name.name, source_info)
legacy = True
record = True
elif node.name.name in NEW_PROCS:
legacy = False
record = True
if record and node.expr:
if node.expr.kind == NodeKind.IDENTIFIER:
self.add_attack_call(
str(node.expr), node.name.name, source_info, legacy
)
elif node.expr.kind == NodeKind.CONSTANT:
if not node.expr.constant.val:
self.add_attack_call("src", node.name.name, source_info, legacy)
# Ignored types will never be part of the attack chain.
@@ -117,10 +126,21 @@ IGNORED_TYPES = [
ASSISTED_TYPES = [
p("/atom"),
p("/mob"),
p("/mob/living"),
p("/obj"),
p("/obj/item"),
]
NEW_PROCS = [
"activate_self",
"after_attack",
"attack_by",
"attack",
"attacked",
"interact_with_atom",
"item_interaction",
]
if __name__ == "__main__":
print("check_legacy_attack_chain started")
@@ -131,6 +151,7 @@ if __name__ == "__main__":
CALLS = defaultdict(set)
SETTING_CACHE = dict()
LEGACY_PROCS = dict()
MODERN_PROCS = dict()
BAD_TREES = dict()
PROCS = dict()
@@ -153,6 +174,7 @@ if __name__ == "__main__":
LEGACY_PROCS[pth] = {
x for x in td.proc_names(modified=True) if "__legacy__attackchain" in x
}
MODERN_PROCS[pth] = {x for x in td.proc_names(modified=True) if x in NEW_PROCS}
for proc_decl in td.proc_decls():
walker = AttackChainCallWalker(td, proc_decl)
proc_decl.walk(walker)
@@ -170,11 +192,23 @@ if __name__ == "__main__":
exit_code = 1
print(f"new_attack_chain on {pth} but related type {cursor} is not")
cursor = cursor.parent
if pth in CALLS:
exit_code = 1
print("Call sites requiring migration:")
if pth in CALLS and any([x.legacy for x in CALLS[pth]]):
print("Legacy sites requiring migration:")
for call in CALLS[pth]:
print(call.format_error())
if call.legacy:
print(call.format_error())
elif pth not in ASSISTED_TYPES:
if MODERN_PROCS[pth]:
exit_code = 1
print(f"new_attack_chain not on {pth} using new procs:")
for proc in sorted(MODERN_PROCS[pth]):
print(f"\t{proc}")
if pth in CALLS and any([not x.legacy for x in CALLS[pth]]):
exit_code = 1
print("Unexpected new call sites:")
for call in CALLS[pth]:
if not call.legacy:
print(call.format_error())
end = time.time()
print(f"check_legacy_attack_chain tests completed in {end - start:.2f}s\n")