Refactored the attack proc (#19908)

Refactored the attack proc signature.
Added signals and components for the attack proc.
Added signals and components for the attackby proc.
Adjusted some leftover attackby procs signatures.
Added grep test to ensure people don't keep adding attack/attackby procs
with the wrong signature.
This commit is contained in:
Fluffy
2024-10-06 21:30:00 +00:00
committed by GitHub
parent b79b7c5177
commit 9636363e60
121 changed files with 878 additions and 663 deletions
@@ -836,7 +836,7 @@
w_class = WEIGHT_CLASS_TINY
icon_state = "ore_glass"
/obj/item/shapesand/attack() //can't be used to actually bludgeon things
/obj/item/shapesand/attack(mob/living/target_mob, mob/living/user, target_zone) //can't be used to actually bludgeon things
return 1
/obj/item/shapesand/afterattack(atom/A, mob/living/user)
+2 -2
View File
@@ -108,8 +108,8 @@
return TRUE
return ..()
/obj/item/reagent_containers/attack(mob/M, mob/user, def_zone)
if(can_operate(M) && do_surgery(M, user, src))
/obj/item/reagent_containers/attack(mob/living/target_mob, mob/living/user, target_zone)
if(can_operate(target_mob) && do_surgery(target_mob, user, src))
return
if(!reagents.total_volume && user.a_intent == I_HURT)
return ..()
@@ -66,8 +66,8 @@
if(reagents && reagents.total_volume)
AddOverlays(overlay_image('icons/obj/bloodpack.dmi', "[icon_state][get_filling_state()]", color = reagents.get_color()))
/obj/item/reagent_containers/blood/attack(mob/living/carbon/human/M as mob, mob/living/carbon/human/user as mob, var/target_zone)
if(user == M && (MODE_VAMPIRE in user.mind?.antag_datums))
/obj/item/reagent_containers/blood/attack(mob/living/target_mob, mob/living/user, target_zone)
if(user == target_mob && (MODE_VAMPIRE in user.mind?.antag_datums))
var/datum/vampire/vampire = user.mind.antag_datums[MODE_VAMPIRE]
if (being_feed)
to_chat(user, SPAN_NOTICE("You are already feeding on \the [src]."))
@@ -77,7 +77,7 @@
being_feed = TRUE
vampire_marks = TRUE
if (!LAZYLEN(src.other_DNA))
LAZYADD(src.other_DNA, M.dna.unique_enzymes)
LAZYADD(src.other_DNA, target_mob.dna.unique_enzymes)
src.other_DNA_type = "saliva"
while (do_after(user, 25, 5))
@@ -165,7 +165,7 @@
filling.color = R.get_color()
AddOverlays(filling)
/obj/item/reagent_containers/hypospray/borghypo/service/attack(var/mob/M, var/mob/user)
/obj/item/reagent_containers/hypospray/borghypo/service/attack(mob/living/target_mob, mob/living/user, target_zone)
return
/obj/item/reagent_containers/hypospray/borghypo/service/afterattack(var/obj/target, var/mob/user, var/proximity)
@@ -24,15 +24,15 @@
If it's empty, you can crush it on your forehead by selecting your head and clicking on yourself with harm intent. \
You can also crush cans on other people's foreheads as well."
/obj/item/reagent_containers/food/drinks/cans/attack(mob/living/M, mob/user, var/target_zone)
if(iscarbon(M) && !reagents.total_volume && user.a_intent == I_HURT && target_zone == BP_HEAD)
if(M == user)
/obj/item/reagent_containers/food/drinks/cans/attack(mob/living/target_mob, mob/living/user, target_zone)
if(iscarbon(target_mob) && !reagents.total_volume && user.a_intent == I_HURT && target_zone == BP_HEAD)
if(target_mob == user)
user.visible_message(SPAN_WARNING("[user] crushes the can of [src.name] on [user.get_pronoun("his")] forehead!"), SPAN_NOTICE("You crush the can of [src.name] on your forehead."))
else
user.visible_message(SPAN_WARNING("[user] crushes the can of [src.name] on [M]'s forehead!"), SPAN_NOTICE("You crush the can of [src.name] on [M]'s forehead."))
M.apply_damage(2,DAMAGE_BRUTE,BP_HEAD) // ouch.
playsound(M,'sound/items/soda_crush.ogg', rand(10,50), TRUE)
var/obj/item/trash/can/crushed_can = new /obj/item/trash/can(M.loc)
user.visible_message(SPAN_WARNING("[user] crushes the can of [src.name] on [target_mob]'s forehead!"), SPAN_NOTICE("You crush the can of [src.name] on [target_mob]'s forehead."))
target_mob.apply_damage(2,DAMAGE_BRUTE,BP_HEAD) // ouch.
playsound(target_mob,'sound/items/soda_crush.ogg', rand(10,50), TRUE)
var/obj/item/trash/can/crushed_can = new /obj/item/trash/can(target_mob.loc)
crushed_can.icon_state = icon_state
qdel(src)
user.put_in_hands(crushed_can)
@@ -596,13 +596,13 @@
pickup_sound = 'sound/items/pickup/shoes.ogg'
reagents_to_add = list(/singleton/reagent/drink/bochbrew = 30)
/obj/item/reagent_containers/food/drinks/cans/boch/attack(mob/living/M, mob/user, var/target_zone) // modified can reaction; have you ever seen someone crush a plastic bottle on their head?
if(iscarbon(M) && !reagents.total_volume && user.a_intent == I_HURT && target_zone == BP_HEAD)
if(M == user)
/obj/item/reagent_containers/food/drinks/cans/boch/attack(mob/living/target_mob, mob/living/user, target_zone) // modified can reaction; have you ever seen someone crush a plastic bottle on their head?
if(iscarbon(target_mob) && !reagents.total_volume && user.a_intent == I_HURT && target_zone == BP_HEAD)
if(target_mob == user)
user.visible_message(SPAN_WARNING("[user] smacks the bottle of [src.name] against [user.get_pronoun("his")] forehead!"), SPAN_NOTICE("You smack the bottle of [src.name] on your forehead."))
else
user.visible_message(SPAN_WARNING("[user] smacks the bottle of [src.name] against [M]'s forehead!"), SPAN_NOTICE("You whack the bottle of [src.name] on [M]'s forehead."))
M.apply_damage(2,DAMAGE_BRUTE,BP_HEAD) // quoth the copy-paste code, 'ouch.'
user.visible_message(SPAN_WARNING("[user] smacks the bottle of [src.name] against [target_mob]'s forehead!"), SPAN_NOTICE("You whack the bottle of [src.name] on [target_mob]'s forehead."))
target_mob.apply_damage(2,DAMAGE_BRUTE,BP_HEAD) // quoth the copy-paste code, 'ouch.'
return TRUE
. = ..()
@@ -76,7 +76,7 @@ If you add a drink with an empty icon sprite, ensure it is in the same folder, e
atom_flags |= ATOM_FLAG_OPEN_CONTAINER
shaken = 0
/obj/item/reagent_containers/food/drinks/attack(mob/M as mob, mob/user as mob, def_zone)
/obj/item/reagent_containers/food/drinks/attack(mob/living/target_mob, mob/living/user, target_zone)
if(force && !(atom_flags & ITEM_FLAG_NO_BLUDGEON) && user.a_intent == I_HURT)
return ..()
return 0
@@ -148,12 +148,12 @@
return
..()
/obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user, var/hit_zone)
/obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target_mob, mob/living/user, target_zone)
var/blocked = ..()
if(user.a_intent != I_HURT)
return
if(target == user) //A check so you don't accidentally smash your brains out while trying to get your drink on.
if(target_mob == user) //A check so you don't accidentally smash your brains out while trying to get your drink on.
var/confirm = alert("Do you want to smash the bottle on yourself?","Hit yourself?","No", "Yeah!", "Splash Reagents")
if(confirm == "No")
return 1 //prevents standard_splash_mob on return
@@ -165,24 +165,24 @@
// You are going to knock someone out for longer if they are not wearing a helmet.
var/weaken_duration = 0
if(blocked < 100)
weaken_duration = smash_duration + min(0, force - target.get_blocked_ratio(hit_zone, DAMAGE_BRUTE) * 100 + 10)
weaken_duration = smash_duration + min(0, force - target_mob.get_blocked_ratio(target_zone, DAMAGE_BRUTE) * 100 + 10)
var/mob/living/carbon/human/H = target
if(istype(H) && H.headcheck(hit_zone))
var/obj/item/organ/affecting = H.get_organ(hit_zone) //headcheck should ensure that affecting is not null
var/mob/living/carbon/human/H = target_mob
if(istype(H) && H.headcheck(target_zone))
var/obj/item/organ/affecting = H.get_organ(target_zone) //headcheck should ensure that affecting is not null
user.visible_message(SPAN_DANGER("[user] smashes [src] into [H]'s [affecting.name]!"))
if(weaken_duration)
target.apply_effect(min(weaken_duration, 5), WEAKEN, blocked) // Never weaken more than a flash!
target_mob.apply_effect(min(weaken_duration, 5), WEAKEN, blocked) // Never weaken more than a flash!
else
user.visible_message(SPAN_DANGER("\The [user] smashes [src] into [target]!"))
user.visible_message(SPAN_DANGER("\The [user] smashes [src] into [target_mob]!"))
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
//The reagents in the bottle splash all over the target_mob, thanks for the idea Nodrak
if(reagents)
user.visible_message(SPAN_NOTICE("The contents of \the [src] splash all over [target]!"))
reagents.splash(target, reagents.total_volume)
user.visible_message(SPAN_NOTICE("The contents of \the [src] splash all over [target_mob]!"))
reagents.splash(target_mob, reagents.total_volume)
//Finally, smash the bottle. This kills (qdel) the bottle.
var/obj/item/broken_bottle/B = smash(target.loc, target)
var/obj/item/broken_bottle/B = smash(target_mob.loc, target_mob)
user.put_in_active_hand(B)
return blocked
@@ -1,8 +1,8 @@
/obj/item/reagent_containers/food/snacks/breadslice/attackby(obj/item/W as obj, mob/user)
/obj/item/reagent_containers/food/snacks/breadslice/attackby(obj/item/attacking_item, mob/user, params)
if(istype(W,/obj/item/reagent_containers/food/snacks))
if(istype(attacking_item,/obj/item/reagent_containers/food/snacks))
var/obj/item/reagent_containers/food/snacks/csandwich/S = new(get_turf(src))
S.attackby(W,user)
S.attackby(attacking_item,user)
qdel(src)
..()
@@ -214,10 +214,10 @@
is_liquid = TRUE
//Custard + blowtorch = creme brulee
/obj/item/reagent_containers/food/snacks/custard/attackby(obj/item/W, mob/living/user)
/obj/item/reagent_containers/food/snacks/custard/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
if(W.iswelder())
var/obj/item/weldingtool/welder = W
if(attacking_item.iswelder())
var/obj/item/weldingtool/welder = attacking_item
if(welder.isOn())
new /obj/item/reagent_containers/food/snacks/creme_brulee(src)
to_chat(user, "You apply the flame to the sugary custard, caramelizing it.")
@@ -46,12 +46,12 @@
bitesize = 6
reagents_to_add = list(/singleton/reagent/kois = 12, /singleton/reagent/toxin/phoron = 16)
/obj/item/reagent_containers/food/snacks/koiskebab2/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/reagent_containers/food/snacks/friedkois))
/obj/item/reagent_containers/food/snacks/koiskebab2/attackby(obj/item/attacking_item, mob/user, params)
if(istype(attacking_item,/obj/item/reagent_containers/food/snacks/friedkois))
new /obj/item/reagent_containers/food/snacks/koiskebab3(src)
to_chat(user, "You add fried K'ois to the kebab.")
qdel(src)
qdel(W)
qdel(attacking_item)
/obj/item/reagent_containers/food/snacks/koiskebab3
name = "k'ois on a stick"
@@ -131,22 +131,22 @@
return
. = ..()
// Used for turning other food into sushi.
/obj/item/reagent_containers/food/snacks/friedegg/attackby(obj/item/attacking_item, var/mob/user)
/obj/item/reagent_containers/food/snacks/friedegg/attackby(obj/item/attacking_item, mob/user, params)
if((locate(/obj/structure/table) in loc) && istype(attacking_item, /obj/item/reagent_containers/food/snacks/boiledrice))
new /obj/item/reagent_containers/food/snacks/sushi(get_turf(src), attacking_item, src)
return
. = ..()
/obj/item/reagent_containers/food/snacks/tofu/attackby(obj/item/attacking_item, var/mob/user)
/obj/item/reagent_containers/food/snacks/tofu/attackby(obj/item/attacking_item, mob/user, params)
if((locate(/obj/structure/table) in loc) && istype(attacking_item, /obj/item/reagent_containers/food/snacks/boiledrice))
new /obj/item/reagent_containers/food/snacks/sushi(get_turf(src), attacking_item, src)
return
. = ..()
/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/attacking_item, var/mob/user)
/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/attacking_item, mob/user, params)
if((locate(/obj/structure/table) in loc) && istype(attacking_item, /obj/item/reagent_containers/food/snacks/boiledrice))
new /obj/item/reagent_containers/food/snacks/sushi(get_turf(src), attacking_item, src)
return
. = ..()
/obj/item/reagent_containers/food/snacks/cutlet/attackby(obj/item/attacking_item, var/mob/user)
/obj/item/reagent_containers/food/snacks/cutlet/attackby(obj/item/attacking_item, mob/user, params)
if((locate(/obj/structure/table) in loc) && istype(attacking_item, /obj/item/reagent_containers/food/snacks/boiledrice))
new /obj/item/reagent_containers/food/snacks/sushi(get_turf(src), attacking_item, src)
return
@@ -46,10 +46,10 @@
possible_transfer_amounts = list(5, 10, 15, 30)
time = 0
/obj/item/reagent_containers/hypospray/attack(var/mob/M, var/mob/user, target_zone)
/obj/item/reagent_containers/hypospray/attack(mob/living/target_mob, mob/living/user, target_zone)
. = ..()
if(isliving(M))
var/mob/living/L = M
if(isliving(target_mob))
var/mob/living/L = target_mob
var/inj_time = time
var/mod_time = L.can_inject(user, TRUE, target_zone, armorcheck)
if(!mod_time)
@@ -60,7 +60,7 @@
inj_time *= mod_time
user.visible_message(SPAN_WARNING("\The [user] is trying to inject \the [L] with \the [src]!"), SPAN_NOTICE("You are trying to inject \the [L] with \the [src]."))
if(do_mob(user, L, inj_time))
inject(M, user, M.Adjacent(user))
inject(target_mob, user, target_mob.Adjacent(user))
/obj/item/reagent_containers/hypospray/update_icon()
ClearOverlays()
@@ -133,7 +133,7 @@
spent = FALSE
update_icon()
/obj/item/reagent_containers/hypospray/autoinjector/attack(var/mob/M, var/mob/user, target_zone)
/obj/item/reagent_containers/hypospray/autoinjector/attack(mob/living/target_mob, mob/living/user, target_zone)
if(is_open_container())
to_chat(user, SPAN_NOTICE("You must secure the reagents inside \the [src] before using it!"))
return FALSE
@@ -107,13 +107,13 @@
if(!proximity)
return
/obj/item/reagent_containers/inhaler/attack(mob/M as mob, mob/user as mob)
/obj/item/reagent_containers/inhaler/attack(mob/living/target_mob, mob/living/user, target_zone)
if(is_open_container())
to_chat(user,SPAN_NOTICE("You must secure the reagents inside \the [src] before using it!"))
return FALSE
else
inject(M, user, M.Adjacent(user))
inject(target_mob, user, target_mob.Adjacent(user))
. = ..()
/obj/item/reagent_containers/inhaler/attack_self(mob/user as mob)
@@ -126,12 +126,12 @@
stored_cartridge = null
update_icon()
/obj/item/personal_inhaler/attack(mob/living/M as mob, mob/user as mob)
/obj/item/personal_inhaler/attack(mob/living/target_mob, mob/living/user, target_zone)
var/mob/living/carbon/human/H = M
var/mob/living/carbon/human/H = target_mob
if (!istype(H))
to_chat(user,SPAN_WARNING("You can't find a way to use \the [src] on \the [M]!"))
to_chat(user,SPAN_WARNING("You can't find a way to use \the [src] on \the [H]!"))
return
if(!stored_cartridge)
@@ -144,10 +144,10 @@
if (((user.is_clumsy()) || (user.mutations & DUMB)) && prob(10))
to_chat(user,SPAN_DANGER("Your hand slips from clumsiness!"))
if(M.eyes_protected(src, FALSE))
eyestab(M,user)
user.visible_message(SPAN_NOTICE("[user] accidentally sticks \the [src] in [M]'s eye!"),
SPAN_NOTICE("You accidentally stick the [src] in [M]'s eye!"))
if(H.eyes_protected(src, FALSE))
eyestab(H,user)
user.visible_message(SPAN_NOTICE("[user] accidentally sticks \the [src] in [H]'s eye!"),
SPAN_NOTICE("You accidentally stick the [src] in [H]'s eye!"))
return
@@ -161,29 +161,29 @@
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
user.do_attack_animation(H)
if(user == M)
if(user == H)
user.visible_message(SPAN_NOTICE("[user] sticks \the [src] in their mouth and presses the injection button."),
SPAN_NOTICE("You stick \the [src] in your mouth and press the injection button."))
else
user.visible_message(SPAN_WARNING("[user] attempts to administer \the [src] to [M]..."),
SPAN_NOTICE("You attempt to administer \the [src] to [M]..."))
if (!do_after(user, 1 SECONDS, M))
to_chat(user,SPAN_NOTICE("You and \the [M] need to be standing still in order to inject \the [src]."))
user.visible_message(SPAN_WARNING("[user] attempts to administer \the [src] to [H]..."),
SPAN_NOTICE("You attempt to administer \the [src] to [H]..."))
if (!do_after(user, 1 SECONDS, H))
to_chat(user,SPAN_NOTICE("You and \the [H] need to be standing still in order to inject \the [src]."))
return
user.visible_message(SPAN_NOTICE("[user] sticks \the [src] in [M]'s mouth and presses the injection button."),
SPAN_NOTICE("You stick \the [src] in [M]'s mouth and press the injection button."))
user.visible_message(SPAN_NOTICE("[user] sticks \the [src] in [H]'s mouth and presses the injection button."),
SPAN_NOTICE("You stick \the [src] in [H]'s mouth and press the injection button."))
if(M.reagents)
if(H.reagents)
var/contained = stored_cartridge.reagentlist()
var/temp = stored_cartridge.reagents.get_temperature()
var/trans = stored_cartridge.reagents.trans_to_mob(M, transfer_amount, CHEM_BREATHE, bypass_checks = TRUE)
admin_inject_log(user, M, src, contained, temp, trans)
playsound(M.loc, 'sound/items/stimpack.ogg', 50, 1)
var/trans = stored_cartridge.reagents.trans_to_mob(H, transfer_amount, CHEM_BREATHE, bypass_checks = TRUE)
admin_inject_log(user, H, src, contained, temp, trans)
playsound(H.loc, 'sound/items/stimpack.ogg', 50, 1)
if(eject_when_empty)
to_chat(user,SPAN_NOTICE("\The [stored_cartridge] automatically ejects from \the [src]."))
stored_cartridge.forceMove(user.loc)
@@ -23,38 +23,38 @@
if(!icon_state)
icon_state = "pill[rand(1, 20)]"
/obj/item/reagent_containers/pill/attack(mob/M as mob, mob/user as mob, def_zone)
/obj/item/reagent_containers/pill/attack(mob/living/target_mob, mob/living/user, target_zone)
//TODO: replace with standard_feed_mob() call.
if(M == user)
if(!M.can_eat(src))
if(target_mob == user)
if(!target_mob.can_eat(src))
return
M.visible_message("<b>[M]</b> swallows a pill.", SPAN_NOTICE("You swallow \the [src]."), null, 2)
target_mob.visible_message("<b>[target_mob]</b> swallows a pill.", SPAN_NOTICE("You swallow \the [src]."), null, 2)
if(reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
reagents.trans_to_mob(target_mob, reagents.total_volume, CHEM_INGEST)
qdel(src)
return 1
else if(istype(M, /mob/living/carbon/human))
if(!M.can_force_feed(user, src))
else if(istype(target_mob, /mob/living/carbon/human))
if(!target_mob.can_force_feed(user, src))
return
user.visible_message(SPAN_WARNING("[user] attempts to force [M] to swallow \the [src]!"))
user.visible_message(SPAN_WARNING("[user] attempts to force [target_mob] to swallow \the [src]!"))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(!do_mob(user, M))
if(!do_mob(user, target_mob))
return
user.visible_message(SPAN_WARNING("[user] forces [M] to swallow \the [src]."))
user.visible_message(SPAN_WARNING("[user] forces [target_mob] to swallow \the [src]."))
var/contained = reagentlist()
M.attack_log +="\[[time_stamp()]\] <font color='orange'>Has been fed [name] by [key_name(user)] Reagents: [contained]</font>"
user.attack_log += "\[[time_stamp()]\] <span class='warning'>Fed [name] to [key_name(M)] Reagents: [contained]</span>"
msg_admin_attack("[key_name_admin(user)] fed [key_name_admin(M)] with [name] Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(M))
target_mob.attack_log +="\[[time_stamp()]\] <font color='orange'>Has been fed [name] by [key_name(user)] Reagents: [contained]</font>"
user.attack_log += "\[[time_stamp()]\] <span class='warning'>Fed [name] to [key_name(target_mob)] Reagents: [contained]</span>"
msg_admin_attack("[key_name_admin(user)] fed [key_name_admin(target_mob)] with [name] Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(target_mob))
if(reagents.total_volume)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
reagents.trans_to_mob(target_mob, reagents.total_volume, CHEM_INGEST)
qdel(src)
return 1
@@ -61,24 +61,24 @@
if(!trans_dest && !user.loc)
return
/obj/item/reagent_containers/toothbrush/attack(atom/target as obj|turf|area, mob/user as mob , flag)
if(isliving(target))
var/mob/living/M = target
/obj/item/reagent_containers/toothbrush/attack(mob/living/target_mob, mob/living/user, target_zone)
if(isliving(target_mob))
var/mob/living/M = target_mob
if(ishuman(M))
if(!reagents.total_volume)
to_chat(user, SPAN_WARNING("The [initial(name)] is dry!"))
else if(reagents.total_volume)
if(user.zone_sel.selecting == BP_MOUTH && !(M.wear_mask && M.wear_mask.item_flags & ITEM_FLAG_AIRTIGHT))
user.do_attack_animation(src)
user.visible_message(SPAN_WARNING("[user] is trying to brush \the [target]'s teeth \the [src]!"))
user.visible_message(SPAN_WARNING("[user] is trying to brush \the [target_mob]'s teeth \the [src]!"))
playsound(loc, 'sound/effects/toothbrush.ogg', 15, 1)
if(do_after(user, 30))
user.visible_message(SPAN_WARNING("[user] has brushed \the [target]'s teeth with \the [src]!"))
user.visible_message(SPAN_WARNING("[user] has brushed \the [target_mob]'s teeth with \the [src]!"))
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BREATHE)
reagents.trans_to_mob(target_mob, amount_per_transfer_from_this, CHEM_BREATHE)
update_icon()
else
wipe_down(target, user)
wipe_down(target_mob, user)
return
return ..()