Skip to content

Commit

Permalink
Fixes several attack chain call sites (ParadiseSS13#27553)
Browse files Browse the repository at this point in the history
  • Loading branch information
warriorstar-orion authored Dec 6, 2024
1 parent 9a17ecc commit d23c808
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 18 deletions.
2 changes: 1 addition & 1 deletion code/game/objects/items/weapons/melee/melee_misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/weapons/storage/firstaid.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/simple_animal/bot/ed209bot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/simple_animal/bot/secbot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/surgery/organs/organ_internal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
..()
Expand Down
58 changes: 46 additions & 12 deletions tools/ci/check_legacy_attack_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down Expand Up @@ -66,7 +67,7 @@ def get_var_type(self, name):

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(
Expand All @@ -75,6 +76,7 @@ def add_attack_call(self, var_name, chain_call, source_info):
self.get_var_type(var_name),
chain_call,
source_info,
legacy=legacy,
)
)

Expand All @@ -83,15 +85,22 @@ def visit_Var(self, node, source_info):

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.
Expand All @@ -117,10 +126,21 @@ def visit_Expr(self, node, source_info):
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")
Expand All @@ -131,6 +151,7 @@ def visit_Expr(self, node, source_info):
CALLS = defaultdict(set)
SETTING_CACHE = dict()
LEGACY_PROCS = dict()
MODERN_PROCS = dict()
BAD_TREES = dict()
PROCS = dict()

Expand All @@ -153,6 +174,7 @@ def visit_Expr(self, node, source_info):
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)
Expand All @@ -170,11 +192,23 @@ def visit_Expr(self, node, source_info):
exit_code = 1
print(f"new_attack_chain on {pth} but related type {cursor} is not")
cursor = cursor.parent
if pth in CALLS:
if pth in CALLS and any([x.legacy for x in CALLS[pth]]):
print("Legacy sites requiring migration:")
for call in CALLS[pth]:
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("Call sites requiring migration:")
print("Unexpected new call sites:")
for call in CALLS[pth]:
print(call.format_error())
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")
Expand Down

0 comments on commit d23c808

Please sign in to comment.