From 22f035f9e82add27c17709732b8828193b783e97 Mon Sep 17 00:00:00 2001 From: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Date: Tue, 7 May 2024 11:50:19 -0400 Subject: [PATCH] Standardizes & documents Attack Chain. Telekinesis cleanup (#10903) * https://github.com/tgstation/tgstation/pull/46391 * https://github.com/tgstation/tgstation/pull/49471 * https://github.com/tgstation/tgstation/pull/54475 * https://github.com/tgstation/tgstation/pull/54589 * https://github.com/tgstation/tgstation/pull/54642 * cleanup * 515 * woops --- beestation.dme | 5 +- .../{ => signals_atom}/signals_atom.dm | 26 --- .../signals_atom/signals_atom_attack.dm | 27 ++++ .../dcs/signals/signals_mob/signals_human.dm | 2 - .../dcs/signals/signals_mob/signals_mob.dm | 6 - .../signals/signals_mob/signals_mobattack.dm | 20 +++ .../signals_obj/signals_item/signals_item.dm | 8 - .../signals_item/signals_itemattack.dm | 19 +++ code/_onclick/click.dm | 149 +++++++++--------- code/_onclick/item_attack.dm | 100 ++++++++---- code/_onclick/observer.dm | 2 +- code/_onclick/other_mobs.dm | 14 +- code/_onclick/telekinesis.dm | 79 ++++++---- code/datums/components/buffer.dm | 4 +- code/datums/components/butchering.dm | 6 +- code/datums/components/deployable.dm | 2 +- code/datums/components/embedded.dm | 2 +- code/datums/components/storage/storage.dm | 10 +- code/datums/components/uplink.dm | 2 +- code/game/machinery/cell_charger.dm | 1 + code/game/objects/items/RPD.dm | 2 +- code/game/objects/items/robot/ai_upgrades.dm | 19 +-- code/game/objects/items/teleportation.dm | 2 +- code/game/objects/items/theft_tools.dm | 4 +- .../objects/structures/beds_chairs/chair.dm | 6 +- code/game/objects/structures/bedsheet_bin.dm | 1 + .../structures/crates_lockers/closets.dm | 3 +- code/game/objects/structures/extinguisher.dm | 7 +- code/game/objects/structures/fireaxe.dm | 7 +- code/game/objects/structures/tables_racks.dm | 4 +- code/game/objects/structures/window.dm | 1 + code/game/turfs/turf.dm | 2 +- .../antagonists/wizard/equipment/artefact.dm | 22 +-- code/modules/hydroponics/hydroitemdefines.dm | 22 +-- code/modules/mining/equipment/resonator.dm | 2 +- .../mob/living/silicon/silicon_defense.dm | 2 +- .../living/simple_animal/hostile/hostile.dm | 3 +- code/modules/mob/mob.dm | 3 + code/modules/paperwork/filingcabinet.dm | 6 +- code/modules/power/lighting/light.dm | 4 +- .../modules/power/lighting/light_construct.dm | 13 +- code/modules/power/singularity/boh_tear.dm | 12 +- code/modules/power/singularity/singularity.dm | 60 +++++-- code/modules/power/supermatter/supermatter.dm | 15 +- code/modules/power/tesla/energy_ball.dm | 17 +- code/modules/research/stock_parts.dm | 2 +- 46 files changed, 442 insertions(+), 283 deletions(-) rename code/__DEFINES/dcs/signals/{ => signals_atom}/signals_atom.dm (87%) create mode 100644 code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm create mode 100644 code/__DEFINES/dcs/signals/signals_mob/signals_mobattack.dm create mode 100644 code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_itemattack.dm diff --git a/beestation.dme b/beestation.dme index c7f5f129a5834..99c4fe7ff66d5 100644 --- a/beestation.dme +++ b/beestation.dme @@ -196,7 +196,8 @@ #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\dcs\signals\signals_area.dm" -#include "code\__DEFINES\dcs\signals\signals_atom.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_attack.dm" #include "code\__DEFINES\dcs\signals\signals_global.dm" #include "code\__DEFINES\dcs\signals\signals_lighting.dm" #include "code\__DEFINES\dcs\signals\signals_movable.dm" @@ -212,6 +213,7 @@ #include "code\__DEFINES\dcs\signals\signals_mob\signals_human.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_living.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_mob.dm" +#include "code\__DEFINES\dcs\signals\signals_mob\signals_mobattack.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_silicon.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_simplemob.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_xenobiology.dm" @@ -223,6 +225,7 @@ #include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_food.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_grenade.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_implant.dm" +#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_itemattack.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_item.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_organs.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_airlock.dm" diff --git a/code/__DEFINES/dcs/signals/signals_atom.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm similarity index 87% rename from code/__DEFINES/dcs/signals/signals_atom.dm rename to code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm index 18c0e97b8ed38..74d1457ccd7ce 100644 --- a/code/__DEFINES/dcs/signals/signals_atom.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm @@ -5,12 +5,6 @@ // /atom signals ///from base of atom/proc/Initialize(mapload): sent any time a new atom is created #define COMSIG_ATOM_CREATED "atom_created" -///! from base of atom/attackby(): (/obj/item, /mob/living, params) -#define COMSIG_PARENT_ATTACKBY "atom_attackby" - ///! Return this in response if you don't want afterattack to be called - #define COMPONENT_NO_AFTERATTACK 1 -///! from base of atom/attack_hulk(): (/mob/living/carbon/human) -#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" /// from base of atom/examine(): (/mob, list/examine_text) #define COMSIG_PARENT_EXAMINE "atom_examine" /// from base of atom/get_examine_name(): (/mob, list/overrides) @@ -20,8 +14,6 @@ #define EXAMINE_POSITION_BEFORE (1<<1) //End positions #define COMPONENT_EXNAME_CHANGED (1<<0) -//from base of atom/attack_basic_mob(): (/mob/user) -#define COMSIG_ATOM_ATTACK_BASIC_MOB "attack_basic_mob" /// from base of [/atom/proc/update_appearance]: (updates) #define COMSIG_ATOM_UPDATE_APPEARANCE "atom_update_appearance" @@ -133,24 +125,6 @@ /// called when an atom stops orbiting another atom: (atom) #define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" -///////////////// -/* Attack signals. They should share the returned flags, to standardize the attack chain. */ -/// tool_act -> pre_attack -> target.attackby (item.attack) -> afterattack - ///Ends the attack chain. If sent early might cause posterior attacks not to happen. - #define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0) - ///Skips the specific attack step, continuing for the next one to happen. - #define COMPONENT_SKIP_ATTACK (1<<1) - -///! from base of atom/attack_ghost(): (mob/dead/observer/ghost) -#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" -///! from base of atom/attack_hand(): (mob/user) -#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" -///! from base of atom/attack_paw(): (mob/user) -#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" - //works on all 3. - #define COMPONENT_NO_ATTACK_HAND 1 -///! from base of atom/animal_attack(): (/mob/user) -#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal" ///This signal return value bitflags can be found in __DEFINES/misc.dm ///called for each movable in a turf contents on /turf/attempt_z_impact(): (atom/movable/A, levels) #define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm new file mode 100644 index 0000000000000..91094391ed1d1 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm @@ -0,0 +1,27 @@ +// Atom attack signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +///from base of atom/attackby(): (/obj/item, /mob/living, params) +#define COMSIG_PARENT_ATTACKBY "atom_attackby" +///Return this in response if you don't want afterattack to be called + #define COMPONENT_NO_AFTERATTACK (1<<0) +///from base of atom/attack_hulk(): (/mob/living/carbon/human) +#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" +///from base of atom/animal_attack(): (/mob/user) +#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal" +//from base of atom/attack_basic_mob(): (/mob/user) +#define COMSIG_ATOM_ATTACK_BASIC_MOB "attack_basic_mob" + +/* Attack signals. They should share the returned flags, to standardize the attack chain. */ +/// tool_act -> pre_attack -> target.attackby (item.attack) -> afterattack + ///Ends the attack chain. If sent early might cause posterior attacks not to happen. + #define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0) + ///Skips the specific attack step, continuing for the next one to happen. + #define COMPONENT_SKIP_ATTACK (1<<1) +///from base of atom/attack_ghost(): (mob/dead/observer/ghost) +#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" +///from base of atom/attack_hand(): (mob/user) +#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" +///from base of atom/attack_paw(): (mob/user) +#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_human.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_human.dm index 4d951dcbfe563..9c57150679f92 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_human.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_human.dm @@ -3,8 +3,6 @@ // All signals send the source datum of the signal as the first argument // /mob/living/carbon/human signals -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //! from mob/living/carbon/human/UnarmedAttack(): (atom/target) -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //! from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) #define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //! Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) #define COMSIG_HUMAN_ATTACKED "carbon_attacked" //hit by something that checks shields. diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm index aa45c9cd1ce71..0ef03a089e156 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm @@ -34,17 +34,11 @@ #define COMSIG_MOB_RECEIVE_ARTIFACT "mob_receive_artifact" // #define COMPONENT_BLOCK_ARTIFACT 1 #define COMSIG_MOB_HUD_CREATED "mob_hud_created" //! from base of mob/create_mob_hud(): () -#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //! from base of #define COMSIG_MOB_ATTACK_HAND_TURF "mob_attack_hand_turf" //! from base of turf/attack_hand #define COMSIG_MOB_HAND_ATTACKED "mob_hand_attacked" //! from base of -#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //! from base of /obj/item/attack(): (mob/M, mob/user) - #define COMPONENT_ITEM_NO_ATTACK 1 -#define COMSIG_MOB_ITEM_ATTACKBY "mob_item_attackby" //! from base of /obj/item/attack(): (mob/user, src) #define COMSIG_MOB_EQUIPPED_ITEM "mob_equipped_item" //! from base of /item/equipped(): (/mob/user, /obj/item, slot) #define COMSIG_MOB_DROPPED_ITEM "mob_dropped_item" //! from base of /item/dropped(): (/mob/user, /obj/item, loc) #define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" //! from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone) -#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //! from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) -#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //! from base of mob/RangedAttack(): (atom/A, params) #define COMSIG_MOB_THROW "mob_throw" //! from base of /mob/throw_item(): (atom/target) #define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //! from base of /mob/update_sight(): () #define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/target) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mobattack.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mobattack.dm new file mode 100644 index 0000000000000..3748b57a5271d --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mobattack.dm @@ -0,0 +1,20 @@ +// Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +/* Attack signals. They should share the returned flags, to standardize the attack chain. */ + +///from base of atom/attack_hand(): (mob/user) +#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" +///from base of /obj/item/attack(): (mob/M, mob/user) +#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" +///from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) +#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" +///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, proxiumity_flag, click_parameters) +#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted" +///from base of mob/RangedAttack(): (atom/A, params) +#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" +///from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity) +#define COMSIG_HUMAN_EARLY_UNARMED_ATTACK "human_early_unarmed_attack" +///from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity) +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm index fbed54f2b0d97..2f74eb1b263fa 100644 --- a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm +++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm @@ -3,14 +3,6 @@ // All signals send the source datum of the signal as the first argument // /obj/item signals -#define COMSIG_ITEM_ATTACK "item_attack" //! from base of obj/item/attack(): (/mob/living/target, /mob/living/user) -#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //! from base of obj/item/attack_self(): (/mob) - #define COMPONENT_NO_INTERACT 1 -#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //! from base of obj/item/attack_obj(): (/obj, /mob) - #define COMPONENT_NO_ATTACK_OBJ 1 -#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //! from base of obj/item/pre_attack(): (atom/target, mob/user, params) - #define COMPONENT_NO_ATTACK 1 -#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //! from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, params) ///from base of obj/item/equipped(): (/mob/equipper, slot) #define COMSIG_ITEM_EQUIPPED "item_equip" ///from base of obj/item/on_grind(): ()) diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_itemattack.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_itemattack.dm new file mode 100644 index 0000000000000..dc127a0a0714f --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_itemattack.dm @@ -0,0 +1,19 @@ +// Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +/* Attack signals. They should share the returned flags, to standardize the attack chain. */ +///from base of obj/item/attack(): (/mob/living/target, /mob/living/user) +#define COMSIG_ITEM_ATTACK "item_attack" + +#define COMSIG_MOB_ITEM_ATTACKBY "item_attackby" +///from base of obj/item/attack_self(): (/mob) +#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" +///from base of obj/item/attack_obj(): (/obj, /mob) +#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" +///from base of obj/item/pre_attack(): (atom/target, mob/user, params) +#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" +///from base of obj/item/afterattack(): (atom/target, mob/user, params) +#define COMSIG_ITEM_AFTERATTACK "item_afterattack" +///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params) +#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 37ea04ee9d918..a13f706c0df79 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -29,15 +29,15 @@ adj += S.nextmove_adjust() next_move = world.time + ((num + adj)*mod) -/* - Before anything else, defer these calls to a per-mobtype handler. This allows us to - remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. - - Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however, - that's a lot of code duplication and is hard to maintain. - - Note that this proc can be overridden, and is in the case of screen objects. -*/ +/** + * Before anything else, defer these calls to a per-mobtype handler. This allows us to + * remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. + * + * Alternately, you could hardcode every mob's variation in a flat [/mob/proc/ClickOn] proc; however, + * that's a lot of code duplication and is hard to maintain. + * + * Note that this proc can be overridden, and is in the case of screen objects. + */ /atom/Click(location,control,params) if(flags_1 & INITIALIZED_1) SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) @@ -51,19 +51,19 @@ if(flags_1 & INITIALIZED_1) usr.MouseWheelOn(src, delta_x, delta_y, params) -/* - Standard mob ClickOn() - Handles exceptions: Buildmode, middle click, modified clicks, mech actions - - After that, mostly just check your state, check whether you're holding an item, - check whether you're adjacent to the target, then pass off the click to whoever - is receiving it. - The most common are: - * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves - * atom/attackby(item,user) - used only when adjacent - * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent - * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed -*/ +/** + * Standard mob ClickOn() + * Handles exceptions: Buildmode, middle click, modified clicks, mech actions + * + * After that, mostly just check your state, check whether you're holding an item, + * check whether you're adjacent to the target, then pass off the click to whoever + * is receiving it. + * The most common are: + * * [mob/proc/UnarmedAttack] (atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves + * * [atom/proc/attackby] (item,user) - used only when adjacent + * * [obj/item/proc/afterattack] (atom,user,adjacent,params) - used both ranged and adjacent + * * [mob/proc/RangedAttack] (atom,params) - used only ranged, only used for tk and laser eyes but could be changed + */ /mob/proc/ClickOn( atom/A, params ) if(world.time <= next_click) return @@ -161,7 +161,7 @@ else RangedAttack(A,params) -//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it +/// Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it /atom/proc/IsObscured() SHOULD_BE_PURE(TRUE) if(!isturf(loc)) //This only makes sense for things directly on turfs for now @@ -180,9 +180,11 @@ return TRUE return FALSE +/** + * A backwards depth-limited breadth-first-search to see if the target is + * logically "in" anything adjacent to us. + */ /atom/movable/proc/CanReach(atom/ultimate_target, obj/item/tool, view_only = FALSE) - // A backwards depth-limited breadth-first-search to see if the target is - // logically "in" anything adjacent to us. var/list/direct_access = DirectAccess() var/depth = 1 + (view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH) @@ -247,60 +249,61 @@ return qdel(dummy) -// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click) +/// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click) /mob/proc/DblClickOn(atom/A, params) return -/* - Translates into attack_hand, etc. - - Note: proximity_flag here is used to distinguish between normal usage (flag=1), - and usage when clicking on things telekinetically (flag=0). This proc will - not be called at ranged except with telekinesis. - - proximity_flag is not currently passed to attack_hand, and is instead used - in human click code to allow glove touches only at melee range. -*/ +/** + * Translates into [atom/proc/attack_hand], etc. + * + * Note: proximity_flag here is used to distinguish between normal usage (flag=1), + * and usage when clicking on things telekinetically (flag=0). This proc will + * not be called at ranged except with telekinesis. + * + * proximity_flag is not currently passed to attack_hand, and is instead used + * in human click code to allow glove touches only at melee range. + */ /mob/proc/UnarmedAttack(atom/A, proximity_flag) if(ismob(A)) changeNext_move(CLICK_CD_MELEE) return -/* - Ranged unarmed attack: - - This currently is just a default for all mobs, involving - laser eyes and telekinesis. You could easily add exceptions - for things like ranged glove touches, spitting alien acid/neurotoxin, - animals lunging, etc. -*/ +/** + * Ranged unarmed attack: + * + * This currently is just a default for all mobs, involving + * laser eyes and telekinesis. You could easily add exceptions + * for things like ranged glove touches, spitting alien acid/neurotoxin, + * animals lunging, etc. + */ /mob/proc/RangedAttack(atom/A, params) SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params) -/* - Restrained ClickOn - Used when you are handcuffed and click things. - Not currently used by anything but could easily be. -*/ +/** + * Restrained ClickOn + * + * Used when you are handcuffed and click things. + * Not currently used by anything but could easily be. + */ /mob/proc/RestrainedClickOn(atom/A) return /** - * Middle click - * *Mainly used for swapping hands - */ + * Middle click + * Mainly used for swapping hands + */ /mob/proc/MiddleClickOn(atom/A) . = SEND_SIGNAL(src, COMSIG_MOB_MIDDLECLICKON, A) if(. & COMSIG_MOB_CANCEL_CLICKON) return swap_hand() -/* - Shift click - For most mobs, examine. - This is overridden in ai.dm -*/ +/** + * Shift click + * For most mobs, examine. + * This is overridden in ai.dm + */ /mob/proc/ShiftClickOn(atom/A) A.ShiftClick(src) return @@ -310,11 +313,10 @@ user.examinate(src) return -/* - Ctrl click - For most objects, pull -*/ - +/** + * Ctrl click + * For most objects, pull + */ /mob/proc/CtrlClickOn(atom/A) A.CtrlClick(src) return @@ -343,10 +345,10 @@ A.CtrlClick(src) // this assumes you did CtrlClick instead of MiddleClick return -/* - Alt click - Unused except for AI -*/ +/** + * Alt click + * Unused except for AI + */ /mob/proc/AltClickOn(atom/A) . = SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, A) if(. & COMSIG_MOB_CANCEL_CLICKON) @@ -360,7 +362,7 @@ user.listed_turf = T user.set_stat_tab(T.name) -// Use this instead of /mob/proc/AltClickOn(atom/A) where you only want turf content listing without additional atom alt-click interaction +/// Use this instead of [/mob/proc/AltClickOn] where you only want turf content listing without additional atom alt-click interaction /atom/proc/AltClickNoInteract(mob/user, atom/A) var/turf/T = get_turf(A) if(T && user.TurfAdjacent(T)) @@ -370,10 +372,10 @@ /mob/proc/TurfAdjacent(turf/T) return T.Adjacent(src) -/* - Control+Shift click - Used for AI and Give code -*/ +/** + * Control+Shift click + * Used for AI and Give code + */ /mob/proc/CtrlShiftClickOn(atom/A) A.CtrlShiftClick(src) return @@ -408,7 +410,7 @@ LE.preparePixelProjectile(A, src, params) LE.fire() -// Simple helper to face what you clicked on, in case it should be needed in more than one place +/// Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(atom/A) if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y ) return @@ -481,8 +483,7 @@ click_turf.Click(click_turf, control, list2params(modifiers)) . = 1 -/* MouseWheelOn */ - +/// MouseWheelOn /mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params) SEND_SIGNAL(src, COMSIG_MOB_MOUSE_SCROLL_ON, A, delta_x, delta_y, params) if (!client) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 4f6d538f0b9ef..1478721cd627f 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -1,31 +1,59 @@ - +/** + * This is the proc that handles the order of an item_attack. + * + * The order of procs called is: + * * [/atom/proc/tool_act] on the target. If it returns TRUE, the chain will be stopped. + * * [/obj/item/proc/pre_attack] on src. If this returns TRUE, the chain will be stopped. + * * [/atom/proc/attackby] on the target. If it returns TRUE, the chain will be stopped. + * * [/obj/item/proc/afterattack]. The return value does not matter. + */ /obj/item/proc/melee_attack_chain(mob/user, atom/target, params) - if(!tool_attack_chain(user, target) && pre_attack(target, user, params)) - // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) - var/resolved = target.attackby(src, user, params) - if(!resolved && target && !QDELETED(src)) - afterattack(target, user, 1, params) - -//Checks if the item can work as a tool, calling the appropriate tool behavior on the target -/obj/item/proc/tool_attack_chain(mob/user, atom/target) - if(!tool_behaviour) - return FALSE - - return target.tool_act(user, src, tool_behaviour) + if(tool_behaviour && target.tool_act(user, src, tool_behaviour)) + return TRUE + if(pre_attack(target, user, params)) + return TRUE + if(target.attackby(src,user, params)) + return TRUE + if(QDELETED(src)) + stack_trace("An item got deleted while performing an item attack and did not stop melee_attack_chain.") + return TRUE + if(QDELETED(target)) + stack_trace("The target of an item attack got deleted and melee_attack_chain was not stopped.") + return TRUE + return afterattack(target, user, TRUE, params) -// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. +/// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. /obj/item/proc/attack_self(mob/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) - return + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_CANCEL_ATTACK_CHAIN) + return TRUE interact(user) +/** + * Called on the item before it hits something + * + * Arguments: + * * atom/A - The atom about to be hit + * * mob/living/user - The mob doing the htting + * * params - click params such as alt/shift etc + * + * See: [/obj/item/proc/melee_attack_chain] + */ /obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! - if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) - return FALSE - return TRUE //return FALSE to avoid calling attackby after this proc does stuff - -// No comment + if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_CANCEL_ATTACK_CHAIN) + return TRUE + return FALSE //return TRUE to avoid calling attackby after this proc does stuff + +/** + * Called on an object being hit by an item + * + * Arguments: + * * obj/item/W - The item hitting this atom + * * mob/user - The wielder of this item + * * params - click params such as alt/shift etc + * + * See: [/obj/item/proc/melee_attack_chain] + */ /atom/proc/attackby(obj/item/W, mob/user, params) if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) return TRUE @@ -52,10 +80,20 @@ return return I.attack(src, user) - +/** + * Called from [/mob/living/attackby] + * + * Arguments: + * * mob/living/M - The mob being hit by this item + * * mob/living/user - The mob hitting with this item + */ /obj/item/proc/attack(mob/living/M, mob/living/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK) + var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) + if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN) + return TRUE + if(signal_return & COMPONENT_SKIP_ATTACK) return + SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user) SEND_SIGNAL(M, COMSIG_MOB_ITEM_ATTACKBY, user, src) @@ -100,9 +138,9 @@ add_fingerprint(user) -//the equivalent of the standard version of attack() but for object targets. +/// The equivalent of the standard version of [/obj/item/proc/attack] but for object targets. /obj/item/proc/attack_obj(obj/O, mob/living/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_CANCEL_ATTACK_CHAIN) return if(item_flags & NOBLUDGEON) return @@ -110,6 +148,7 @@ user.do_attack_animation(O) O.attacked_by(src, user) +/// Called from [/obj/item/proc/attack_obj] and [/obj/item/proc/attack] if the attack succeeds /atom/proc/attacked_by() return @@ -150,8 +189,15 @@ else return ..() -// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. -// Click parameters is the params string from byond Click() code, see that documentation. +/** + * Last proc in the [/obj/item/proc/melee_attack_chain] + * + * Arguments: + * * atom/target - The thing that was hit + * * mob/user - The mob doing the hitting + * * proximity_flag - is 1 if this afterattack was called on something adjacent, in your square, or on your person. + * * click_parameters - is the params string from byond [/atom/proc/Click] code, see that documentation. + */ /obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, src, proximity_flag, click_parameters) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index deb9ec5137160..899255956d71c 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -47,7 +47,7 @@ // Oh by the way this didn't work with old click code which is why clicking shit didn't spam you /atom/proc/attack_ghost(mob/dead/observer/user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_CANCEL_ATTACK_CHAIN) return TRUE if(user.client) if(user.gas_scan && atmosanalyzer_scan(user, src)) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index e2a4f96ce9e32..21bd7205bf3f4 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -28,12 +28,12 @@ SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) A.attack_hand(src) -//Return TRUE to cancel other attack hand effects that respect it. +/// Return TRUE to cancel other attack hand effects that respect it. /atom/proc/attack_hand(mob/user) . = FALSE if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) add_fingerprint(user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_CANCEL_ATTACK_CHAIN) . = TRUE if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) . = _try_interact(user) @@ -95,14 +95,16 @@ /mob/living/carbon/human/RangedAttack(atom/A, mouseparams) . = ..() + if(.) + return if(gloves) var/obj/item/clothing/gloves/G = gloves if(istype(G) && G.Touch(A,0)) // for magic gloves - return + return TRUE if(isturf(A) && get_dist(src,A) <= 1) - src.Move_Pulled(A) - return + Move_Pulled(A) + return TRUE /* Animals & All Unspecified @@ -134,7 +136,7 @@ A.attack_paw(src) /atom/proc/attack_paw(mob/user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_CANCEL_ATTACK_CHAIN) return TRUE return FALSE diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 095fc5bb1f8ef..3d21335141266 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -4,52 +4,68 @@ This needs more thinking out, but I might as well. */ -/* - Telekinetic attack: - - By default, emulate the user's unarmed attack -*/ - #define TK_MAXRANGE 15 +/** + * Telekinesis attack act, happens when the TK user clicks on a non-adjacent target in range. + * + * * By default, emulates the user's unarmed attack. + * * Called indirectly by the `COMSIG_MOB_ATTACK_RANGED` signal. + * * Returns `COMPONENT_CANCEL_ATTACK_CHAIN` when it performs any action, to further acts on the attack chain. + */ /atom/proc/attack_tk(mob/user) if(user.stat || !tkMaxRangeCheck(user, src)) return new /obj/effect/temp_visual/telekinesis(get_turf(src)) - user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc add_hiddenprint(user) - return + user.UnarmedAttack(src, FALSE) // attack_hand, attack_paw, etc + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/attack_tk(mob/user) if(user.stat) return if(anchored) return ..() - attack_tk_grab(user) + return attack_tk_grab(user) +/obj/item/attack_tk(mob/user) + if(user.stat) + return + return attack_tk_grab(user) + +/** + * Telekinesis object grab act. + * + * * Called by `/obj/attack_tk()`. + * * Returns `COMPONENT_CANCEL_ATTACK_CHAIN` when it performs any action, to further acts on the attack chain. + */ /obj/proc/attack_tk_grab(mob/user) var/obj/item/tk_grab/O = new(src) O.tk_user = user - if(O.focus_object(src)) - user.put_in_active_hand(O) - add_hiddenprint(user) + if(!O.focus_object(src)) + return + user.put_in_active_hand(O) + add_hiddenprint(user) + return COMPONENT_CANCEL_ATTACK_CHAIN /mob/attack_tk(mob/user) return -/* - This is similar to item attack_self, but applies to anything - that you can grab with a telekinetic grab. - - It is used for manipulating things at range, for example, opening and closing closets. - There are not a lot of defaults at this time, add more where appropriate. -*/ - +/** + * Telekinesis item attack_self act. + * + * * This is similar to item attack_self, but applies to anything that you can grab with a telekinetic grab. + * * It is used for manipulating things at range, for example, opening and closing closets.. + * * Defined at the `/atom` level but only used at the `/obj/item` one. + * * Returns `COMPONENT_CANCEL_ATTACK_CHAIN` when it performs any action, to further acts on the attack chain. + */ /atom/proc/attack_self_tk(mob/user) return + /obj/item/attack_self_tk(mob/user) - attack_self(user) + if(attack_self(user)) + return COMPONENT_CANCEL_ATTACK_CHAIN /* @@ -109,25 +125,31 @@ /obj/item/tk_grab/attack_self(mob/user) if(!focus) return - if(QDELETED(focus)) + if(QDELING(focus)) qdel(src) return - focus.attack_self_tk(user) + if(focus.attack_self_tk(user) & COMPONENT_CANCEL_ATTACK_CHAIN) + . = TRUE update_icon() /obj/item/tk_grab/afterattack(atom/target, mob/living/carbon/user, proximity, params)//TODO: go over this . = ..() + if(.) + return + if(!target || !user) return if(!focus) focus_object(target) - return - else if(!check_if_focusable(focus)) + return TRUE + + if(!check_if_focusable(focus)) return if(target == focus) - target.attack_self_tk(user) + if(target.attack_self_tk(user) & COMPONENT_CANCEL_ATTACK_CHAIN) + . = TRUE update_icon() return @@ -142,16 +164,17 @@ if(!isturf(target) && isitem(focus) && target.Adjacent(focus)) apply_focus_overlay() var/obj/item/I = focus - I.melee_attack_chain(tk_user, target, params) //isn't copying the attack chain fun. we should do it more often. + . = I.melee_attack_chain(tk_user, target, params) //isn't copying the attack chain fun. we should do it more often. if(check_if_focusable(focus)) focus.do_attack_animation(target, null, focus) else - + . = TRUE apply_focus_overlay() focus.throw_at(target, 10, 1,user) user.changeNext_move(CLICK_CD_MELEE) update_icon() + /proc/tkMaxRangeCheck(mob/user, atom/target) var/d = get_dist(user, target) if(d > TK_MAXRANGE) diff --git a/code/datums/components/buffer.dm b/code/datums/components/buffer.dm index 09855e9dcac07..a5b4052792a3d 100644 --- a/code/datums/components/buffer.dm +++ b/code/datums/components/buffer.dm @@ -27,7 +27,7 @@ /datum/component/buffer/proc/intercept_attack(datum/source, atom/attack_target, mob/user, params) SIGNAL_HANDLER if ((SEND_SIGNAL(attack_target, COMSIG_PARENT_RECIEVE_BUFFER, user, target, parent) & COMPONENT_BUFFER_RECIEVED)) - return COMPONENT_NO_ATTACK + return COMPONENT_CANCEL_ATTACK_CHAIN return NONE /datum/component/buffer/proc/examine(datum/source, mob/user, list/examine_list) @@ -42,7 +42,7 @@ flush_buffer() if (user) to_chat(user, "You flush the buffer of [source]!") - return COMPONENT_NO_INTERACT + return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/buffer/proc/populate_buffer(datum/source, datum/buffer_entity) SIGNAL_HANDLER diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index ced03d367abaa..d281865081aa4 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -34,16 +34,16 @@ if(user.a_intent == INTENT_HARM && M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it? if(butchering_enabled && (can_be_blunt || source.is_sharp())) INVOKE_ASYNC(src, PROC_REF(startButcher), source, M, user) - return COMPONENT_ITEM_NO_ATTACK + return COMPONENT_CANCEL_ATTACK_CHAIN if(user.a_intent == INTENT_GRAB && ishuman(M) && source.is_sharp()) var/mob/living/carbon/human/H = M if(H.has_status_effect(/datum/status_effect/neck_slice)) user.show_message("[H]'s neck has already been already cut, you can't make the bleeding any worse!", 1, \ "Their neck has already been already cut, you can't make the bleeding any worse!") - return COMPONENT_ITEM_NO_ATTACK + return COMPONENT_CANCEL_ATTACK_CHAIN if((H.health <= H.crit_threshold || (user.pulling == H && user.grab_state >= GRAB_NECK) || H.IsSleeping())) // Only sleeping, neck grabbed, or crit, can be sliced. INVOKE_ASYNC(src, PROC_REF(startNeckSlice), source, H, user) - return COMPONENT_ITEM_NO_ATTACK + return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/butchering/proc/startButcher(obj/item/source, mob/living/M, mob/living/user) to_chat(user, "You begin to butcher [M]...") diff --git a/code/datums/components/deployable.dm b/code/datums/components/deployable.dm index f2b031c58b8c5..5202dbae3701c 100644 --- a/code/datums/components/deployable.dm +++ b/code/datums/components/deployable.dm @@ -58,7 +58,7 @@ /datum/component/deployable/proc/on_attack_self(datum/source, mob/user) SIGNAL_HANDLER INVOKE_ASYNC(src, PROC_REF(try_deploy), user, user.loc) - return COMPONENT_NO_INTERACT + return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/deployable/proc/on_afterattack(datum/source, atom/movable/target, mob/user, proximity_flag, params) SIGNAL_HANDLER diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 5bc4612806422..a8969ec2fecd2 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -251,7 +251,7 @@ return INVOKE_ASYNC(src, PROC_REF(pluckOut), user, 1, 2, "pulling out") - return COMPONENT_NO_ATTACK_HAND + return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/embedded/proc/checkRemoval(mob/living/carbon/victim, obj/item/I, mob/user) SIGNAL_HANDLER diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 53bba3c18a93a..b4ed7cb592bb4 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -185,7 +185,7 @@ if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) return FALSE - . = COMPONENT_NO_ATTACK + . = COMPONENT_CANCEL_ATTACK_CHAIN if(locked) var/atom/host = parent host.balloon_alert(M, "[host] is locked.") @@ -779,7 +779,7 @@ if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item user.active_storage.close(user) close(user) - . = COMPONENT_NO_ATTACK_HAND + . = COMPONENT_CANCEL_ATTACK_CHAIN return if(rustle_sound) @@ -788,18 +788,18 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket. - . = COMPONENT_NO_ATTACK_HAND + . = COMPONENT_CANCEL_ATTACK_CHAIN INVOKE_ASYNC(H, TYPE_PROC_REF(/mob, put_in_hands), A) H.l_store = null return if(H.r_store == A && !H.get_active_held_item()) - . = COMPONENT_NO_ATTACK_HAND + . = COMPONENT_CANCEL_ATTACK_CHAIN INVOKE_ASYNC(H, TYPE_PROC_REF(/mob, put_in_hands), A) H.r_store = null return if(A.loc == user) - . = COMPONENT_NO_ATTACK_HAND + . = COMPONENT_CANCEL_ATTACK_CHAIN if(locked) var/atom/host = parent host.balloon_alert(user, "[host] is locked.") diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index dc317f773a8db..85c49f68d8b67 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -141,7 +141,7 @@ if(user) INVOKE_ASYNC(src, PROC_REF(ui_interact), user) // an unlocked uplink blocks also opening the PDA or headset menu - return COMPONENT_NO_INTERACT + return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/uplink/ui_state(mob/user) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 7b21dff633dfa..bd0a164f12229 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -101,6 +101,7 @@ to_chat(user, "You telekinetically remove [charging] from [src].") removecell() + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/machinery/cell_charger/attack_ai(mob/user) return diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 2e1094c979931..00e48c6a8dba5 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -469,7 +469,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( attack_target = get_turf(attack_target) var/can_make_pipe = (isturf(attack_target) || is_type_in_typecache(attack_target, rpd_whitelist)) - . = FALSE + . = TRUE if((mode & DESTROY_MODE) && is_type_in_typecache(A, rpd_targets)) to_chat(user, "You start destroying a pipe...") diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm index 296af65198de6..322a4eefeb7a1 100644 --- a/code/game/objects/items/robot/ai_upgrades.dm +++ b/code/game/objects/items/robot/ai_upgrades.dm @@ -9,10 +9,10 @@ icon_state = "datadisk3" -/obj/item/malf_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user) - . = ..() - if(!istype(AI)) - return +/obj/item/malf_upgrade/pre_attack(atom/A, mob/living/user) + if(!isAI(A)) + return ..() + var/mob/living/silicon/ai/AI = A if(AI.malf_picker) AI.malf_picker.processing_time += 50 to_chat(AI, "[user] has attempted to upgrade you with combat software that you already possess. You gain 50 points to spend on Malfunction Modules instead.") @@ -24,7 +24,7 @@ message_admins("[ADMIN_LOOKUPFLW(user)] has upgraded [ADMIN_LOOKUPFLW(AI)] with a [src].") to_chat(user, "You upgrade [AI]. [src] is consumed in the process.") qdel(src) - + return TRUE //Lipreading /obj/item/surveillance_upgrade @@ -33,10 +33,10 @@ icon = 'icons/obj/module.dmi' icon_state = "datadisk3" -/obj/item/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user) - . = ..() - if(!istype(AI)) - return +/obj/item/surveillance_upgrade/pre_attack(atom/A, mob/living/user) + if(!isAI(A)) + return ..() + var/mob/living/silicon/ai/AI = A if(AI.eyeobj) AI.eyeobj.set_relay_speech(TRUE) to_chat(AI, "[user] has upgraded you with surveillance software!") @@ -45,3 +45,4 @@ log_game("[key_name(user)] has upgraded [key_name(AI)] with a [src].") message_admins("[ADMIN_LOOKUPFLW(user)] has upgraded [ADMIN_LOOKUPFLW(AI)] with a [src].") qdel(src) + return TRUE diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 9f67d17f582b5..d62d696dd7bcb 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -123,7 +123,7 @@ /obj/item/hand_tele/pre_attack(atom/target, mob/user, params) if(try_dispel_portal(target, user)) - return FALSE + return TRUE return ..() /obj/item/hand_tele/proc/try_dispel_portal(obj/effect/portal/target, mob/user) diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index e92289f30efa1..4e579bfddd7b9 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -127,8 +127,8 @@ item_state = "supermattersliver" pulseicon = "supermatter_sliver_pulse" -/obj/item/nuke_core/supermatter_sliver/attack_tk() // no TK dusting memes - return FALSE +/obj/item/nuke_core/supermatter_sliver/attack_tk(mob/user) // no TK dusting memes + return /obj/item/nuke_core/supermatter_sliver/can_be_pulled(user) // no drag memes return FALSE diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index b8cf038e37951..4c93ddb74d010 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -94,9 +94,9 @@ /obj/structure/chair/attack_tk(mob/user) if(!anchored || has_buckled_mobs() || !isturf(user.loc)) - ..() - else - setDir(turn(dir,-90)) + return ..() + setDir(turn(dir,-90)) + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/structure/chair/proc/handle_rotation(direction) handle_layer() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index b26314ec37c13..9648e4d4358a3 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -105,6 +105,7 @@ hidden = null add_fingerprint(user) + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/structure/bedsheetbin/attack_tk(mob/user) if(amount >= 1) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index e9fd7f1bbf230..71d88db88d179 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -461,7 +461,8 @@ // tk grab then use on self /obj/structure/closet/attack_self_tk(mob/user) - return attack_hand(user) + if(attack_hand(user)) + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/structure/closet/verb/verb_toggleopen() set src in view(1) diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 7c43db431012a..c8aa218581b37 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -93,15 +93,16 @@ /obj/structure/extinguisher_cabinet/attack_tk(mob/user) + . = COMPONENT_CANCEL_ATTACK_CHAIN if(stored_extinguisher) stored_extinguisher.forceMove(loc) to_chat(user, "You telekinetically remove [stored_extinguisher] from [src].") stored_extinguisher = null - opened = 1 + opened = TRUE playsound(loc, 'sound/machines/click.ogg', 15, 1, -3) update_icon() - else - toggle_cabinet(user) + return + toggle_cabinet(user) /obj/structure/extinguisher_cabinet/attack_paw(mob/user) diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 599157471090a..669026f47062d 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -133,13 +133,12 @@ return /obj/structure/fireaxecabinet/attack_tk(mob/user) + . = COMPONENT_CANCEL_ATTACK_CHAIN if(locked) to_chat(user, "The [name] won't budge!") return - else - open = !open - update_appearance() - return + open = !open + update_icon() /obj/structure/fireaxecabinet/update_icon() cut_overlays() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 115276a9dd3a8..ed8dec679fa57 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -114,8 +114,8 @@ user.stop_pulling() return ..() -/obj/structure/table/attack_tk() - return FALSE +/obj/structure/table/attack_tk(mob/user) + return /obj/structure/table/CanAllowThrough(atom/movable/mover, border_dir) . = ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 9c7374d0cec66..a033bd4b51f8b 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -150,6 +150,7 @@ user.visible_message("Something knocks on [src].") add_fingerprint(user) playsound(src, 'sound/effects/Glassknock.ogg', 50, 1) + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/structure/window/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) if(!can_be_reached(user)) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 760a3a6e2a0fe..7f4be91b18acf 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -204,7 +204,7 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists) else if(allow_z_travel) to_chat(user, "You can't float up and down when there is gravity!") . = ..() - if(SEND_SIGNAL(user, COMSIG_MOB_ATTACK_HAND_TURF, src) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(user, COMSIG_MOB_ATTACK_HAND_TURF, src) & COMPONENT_CANCEL_ATTACK_CHAIN) . = TRUE if(.) return diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index d34b0c0bee522..d5f5c07d10eff 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -131,16 +131,18 @@ ) /obj/tear_in_reality/attack_tk(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood) - if(insaneinthemembrane.sanity < 15) - return //they've already seen it and are about to die, or are just too insane to care - to_chat(C, "OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!") - insaneinthemembrane.sanity = 0 - for(var/lore in typesof(/datum/brain_trauma/severe)) - C.gain_trauma(lore) - addtimer(CALLBACK(src, PROC_REF(deranged), C), 100) + if(!iscarbon(user)) + return + . = COMPONENT_CANCEL_ATTACK_CHAIN + var/mob/living/carbon/jedi = user + var/datum/component/mood/insaneinthemembrane = jedi.GetComponent(/datum/component/mood) + if(insaneinthemembrane.sanity < 15) + return //they've already seen it and are about to die, or are just too insane to care + to_chat(jedi, "OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!") + insaneinthemembrane.sanity = 0 + for(var/lore in typesof(/datum/brain_trauma/severe)) + jedi.gain_trauma(lore) + addtimer(CALLBACK(src, PROC_REF(deranged), jedi), 10 SECONDS) /obj/tear_in_reality/proc/deranged(mob/living/carbon/C) if(!C || C.stat == DEAD) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 33852058545f3..c736d09979cc2 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -131,17 +131,17 @@ /obj/item/scythe/pre_attack(atom/A, mob/living/user, params) if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user)) return ..() - else - var/turf/user_turf = get_turf(user) - var/dir_to_target = get_dir(user_turf, get_turf(A)) - swiping = TRUE - var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90) - for(var/i in scythe_slash_angles) - var/turf/T = get_step(user_turf, turn(dir_to_target, i)) - for(var/obj/structure/spacevine/V in T) - if(user.Adjacent(V)) - melee_attack_chain(user, V) - swiping = FALSE + var/turf/user_turf = get_turf(user) + var/dir_to_target = get_dir(user_turf, get_turf(A)) + swiping = TRUE + var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90) + for(var/i in scythe_slash_angles) + var/turf/T = get_step(user_turf, turn(dir_to_target, i)) + for(var/obj/structure/spacevine/V in T) + if(user.Adjacent(V)) + melee_attack_chain(user, V) + swiping = FALSE + return TRUE // ************************************* // Nutrient defines for hydroponics diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index b5588e772ba9d..150ae9fdcab7e 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -56,7 +56,7 @@ /obj/item/resonator/pre_attack(atom/target, mob/user, params) if(check_allowed_items(target, 1)) CreateResonance(target, user) - return TRUE + . = ..() //resonance field, crushes rock, damages mobs /obj/effect/temp_visual/resonance diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index f07099a5fa73b..3fbe8f1a1bc92 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -67,7 +67,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /mob/living/silicon/attack_hand(mob/living/carbon/human/M) . = FALSE - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M) & COMPONENT_CANCEL_ATTACK_CHAIN) . = TRUE switch(M.a_intent) if ("help") diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index c4adc619b768c..b64402066fbed 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -507,8 +507,7 @@ if(ranged && ranged_cooldown <= world.time) GiveTarget(A) OpenFire(A) - ..() - + return ..() ////// AI Status /////// diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1b60348ca4ba4..c16509a666297 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -963,6 +963,9 @@ /mob/proc/can_interact_with(atom/A, treat_mob_as_adjacent) if(IsAdminGhost(src)) return TRUE + var/datum/dna/mob_dna = has_dna() + if(mob_dna?.check_mutation(TK) && tkMaxRangeCheck(src, A)) + return TRUE if(treat_mob_as_adjacent && src == A.loc) return TRUE return Adjacent(A) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index ba160f639105a..60e03f12459c5 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -81,11 +81,11 @@ /obj/structure/filingcabinet/attack_tk(mob/user) if(anchored) - attack_self_tk(user) - else - ..() + return attack_self_tk(user) + return ..() /obj/structure/filingcabinet/attack_self_tk(mob/user) + . = COMPONENT_CANCEL_ATTACK_CHAIN if(contents.len) if(prob(40 + contents.len * 5)) var/obj/item/I = pick(contents) diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index c9e9e1c2d2815..9e82edabda40a 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -621,8 +621,8 @@ to_chat(user, "You telekinetically remove the light [fitting].") // create a light tube/bulb item and put it in the user's hand - var/obj/item/light/L = drop_light_tube() - L.attack_tk(user) + var/obj/item/light/light_tube = drop_light_tube() + return light_tube.attack_tk(user) // break the light and make sparks if was on diff --git a/code/modules/power/lighting/light_construct.dm b/code/modules/power/lighting/light_construct.dm index fa5f81ca18724..96c23c8e7aaf4 100644 --- a/code/modules/power/lighting/light_construct.dm +++ b/code/modules/power/lighting/light_construct.dm @@ -54,11 +54,14 @@ add_fingerprint(user) /obj/structure/light_construct/attack_tk(mob/user) - if(cell) - to_chat(user, "You telekinetically remove [cell].") - cell.forceMove(drop_location()) - cell.attack_tk(user) - remove_cell() + if(!cell) + return + to_chat(user, "You telekinetically remove [cell].") + var/obj/item/stock_parts/cell/cell_reference = cell + cell = null + cell_reference.forceMove(drop_location()) + remove_cell() + return cell_reference.attack_tk(user) /obj/structure/light_construct/attackby(obj/item/W, mob/user, params) add_fingerprint(user) diff --git a/code/modules/power/singularity/boh_tear.dm b/code/modules/power/singularity/boh_tear.dm index 18b6b6e477614..ec5ef44fe2ddc 100644 --- a/code/modules/power/singularity/boh_tear.dm +++ b/code/modules/power/singularity/boh_tear.dm @@ -75,12 +75,14 @@ investigate_log("was created at [AREACOORD(T)].", INVESTIGATE_ENGINES) /obj/boh_tear/attack_tk(mob/living/user) - if(!istype(user)) + if(!isliving(user)) return - to_chat(user, "You don't feel like you are real anymore.") - user.dust_animation() - user.spawn_dust() - addtimer(CALLBACK(src, PROC_REF(consume), user), 5) + var/mob/living/jedi = user + to_chat(jedi, "You don't feel like you are real anymore.") + jedi.dust_animation() + jedi.spawn_dust() + addtimer(CALLBACK(src, PROC_REF(consume), jedi), 0.5 SECONDS) + return COMPONENT_CANCEL_ATTACK_CHAIN #undef BOH_TEAR_CONSUME_RANGE #undef BOH_TEAR_GRAV_PULL diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 2b85a17b9475f..e7d57f1962e6a 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -62,18 +62,58 @@ return ..() /obj/anomaly/singularity/attack_tk(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.visible_message("[C]'s head begins to collapse in on itself!", "Your head feels like it's collapsing in on itself! This was really not a good idea!", "You hear something crack and explode in gore.") - var/turf/T = get_turf(C) - for(var/i in 1 to 3) - C.apply_damage(30, BRUTE, BODY_ZONE_HEAD) - new /obj/effect/gibspawner/generic(T, C) - sleep(1) - C.ghostize() - var/obj/item/bodypart/head/rip_u = C.get_bodypart(BODY_ZONE_HEAD) + if(!iscarbon(user)) + return + . = COMPONENT_CANCEL_ATTACK_CHAIN + var/mob/living/carbon/jedi = user + jedi.visible_message( + "[jedi]'s head begins to collapse in on itself!", + "Your head feels like it's collapsing in on itself! This was really not a good idea!", + "You hear something crack and explode in gore." + ) + jedi.Stun(3 SECONDS) + new /obj/effect/gibspawner/generic(get_turf(jedi), jedi) + jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD) + if(QDELETED(jedi)) + return // damage was too much + if(jedi.stat == DEAD) + jedi.ghostize() + var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD) rip_u.dismember(BURN) //nice try jedi qdel(rip_u) + return + addtimer(CALLBACK(src, PROC_REF(carbon_tk_part_two), jedi), 0.1 SECONDS) + + +/obj/anomaly/singularity/proc/carbon_tk_part_two(mob/living/carbon/jedi) + if(QDELETED(jedi)) + return + new /obj/effect/gibspawner/generic(get_turf(jedi), jedi) + jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD) + if(QDELETED(jedi)) + return // damage was too much + if(jedi.stat == DEAD) + jedi.ghostize() + var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD) + if(rip_u) + rip_u.dismember(BURN) + qdel(rip_u) + return + addtimer(CALLBACK(src, PROC_REF(carbon_tk_part_three), jedi), 0.1 SECONDS) + + +/obj/anomaly/singularity/proc/carbon_tk_part_three(mob/living/carbon/jedi) + if(QDELETED(jedi)) + return + new /obj/effect/gibspawner/generic(get_turf(jedi), jedi) + jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD) + if(QDELETED(jedi)) + return // damage was too much + jedi.ghostize() + var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD) + if(rip_u) + rip_u.dismember(BURN) + qdel(rip_u) /obj/anomaly/singularity/ex_act(severity, target) switch(severity) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index f9a76a0002bfb..e26fb9848c3cd 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -652,13 +652,16 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) Consume(B) /obj/machinery/power/supermatter_crystal/attack_tk(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - to_chat(C, "That was a really dense idea.") - C.ghostize() - var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - rip_u.Remove(C) + if(!iscarbon(user)) + return + var/mob/living/carbon/jedi = user + to_chat(jedi, "That was a really dense idea.") + jedi.ghostize() + var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in jedi.internal_organs + if(rip_u) + rip_u.Remove(jedi) qdel(rip_u) + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/machinery/power/supermatter_crystal/attack_paw(mob/user) dust_mob(user, cause = "monkey attack") diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 17485bfb998de..f1a2d9f89c515 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -147,14 +147,17 @@ dust_mobs(AM) /obj/anomaly/energy_ball/attack_tk(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - to_chat(C, "That was a shockingly dumb idea.") - var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - C.ghostize(FALSE) + if(!iscarbon(user)) + return + var/mob/living/carbon/jedi = user + to_chat(jedi, "That was a shockingly dumb idea.") + var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in jedi.internal_organs + jedi.ghostize(jedi) + if(rip_u) qdel(rip_u) - C.investigate_log("had [C.p_their()] brain dusted by touching [src] with telekinesis.", INVESTIGATE_DEATHS) - C.death() + jedi.investigate_log("had [jedi.p_their()] brain dusted by touching [src] with telekinesis.", INVESTIGATE_DEATHS) + jedi.death() + return COMPONENT_CANCEL_ATTACK_CHAIN /obj/anomaly/energy_ball/proc/dust_mobs(atom/A) if(isliving(A)) diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index e16979c4ced27..d3d0d4224b9a5 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -31,7 +31,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi if(works_from_distance) user.Beam(attacked_machinery, icon_state = "rped_upgrade", time = 5) attacked_machinery.exchange_parts(user, src) - return FALSE + return TRUE var/obj/structure/frame/machine/attacked_frame = attacked_object