Re-refactors batons / Refactors attack chain force modifiers (#90809)

## About The Pull Request

Melee attack chain now has a list passed along with it,
`attack_modifiers`, which you can stick force modifiers to change the
resulting attack

This is basically a soft implementation of damage packets until a more
definitive pr, but one that only applies to item attack chain, and not
unarmed attacks.

This change was done to facilitate a baton refactor - batons no longer
hack together their own attack chain, and are now integrated straight
into the real attack chain. This refactor itself was done because batons
don't send any attack signals, which has been annoying in the past (for
swing combat).

## Changelog

🆑 Melbert
refactor: Batons have been refactored again. Baton stuns now properly
count as an attack, when before it was a nothing. Report any oddities,
particularly in regards to harmbatonning vs normal batonning.
refactor: The method of adjusting item damage mid-attack has been
refactored - some affected items include the Nullblade and knives.
Report any strange happenings with damage numbers.
refactor: A few objects have been moved to the new interaction chain -
records consoles, mawed crucible, alien weeds and space vines, hedges,
restaurant portals, and some mobs - to name a few.
fix: Spears only deal bonus damage against secure lockers, not all
closet types (including crates)
/🆑
This commit is contained in:
MrMelbert
2025-05-18 22:32:12 -05:00
committed by GitHub
parent 225300a189
commit 5261efb67f
483 changed files with 1088 additions and 1082 deletions
+43 -8
View File
@@ -332,14 +332,6 @@ GLOBAL_LIST_INIT(leg_zones, list(BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
/// Calculates the new armour value after armour penetration. Can return negative values, and those must be caught.
#define PENETRATE_ARMOUR(armour, penetration) (penetration == 100 ? 0 : 100 * (armour - penetration) / (100 - penetration))
/// Return values used in item/melee/baton/baton_attack.
/// Does a normal item attack.
#define BATON_DO_NORMAL_ATTACK 1
/// The attack has been stopped. Either because the user was clumsy or the attack was blocked.
#define BATON_ATTACK_DONE 2
/// The baton attack is still going. baton_effect() is called.
#define BATON_ATTACKING 3
// Defines for combo attack component
/// LMB Attack
#define LEFT_ATTACK "Left Attack"
@@ -377,3 +369,46 @@ GLOBAL_LIST_INIT(leg_zones, list(BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
#define JOULES_PER_DAMAGE (25 KILO JOULES)
/// Calculates the amount of burn force when applying this much energy to a mob via electrocution from an energy source.
#define ELECTROCUTE_DAMAGE(energy) (energy >= 1 KILO JOULES ? clamp(20 + round(energy / JOULES_PER_DAMAGE), 20, 195) + rand(-5,5) : 0)
// Attack chain attack_modifier modifiers
/// Sets the weapon's base force to this. Use carefully (as multiple overrides may collide). Set via [SET_ATTACK_FORCE]
#define FORCE_OVERRIDE "force_override"
/// Flat addition or subtration to the weapon's force. Set via [MODIFY_ATTACK_FORCE]
#define FORCE_MODIFIER "force_modifier"
/// Multiplication of the weapon's force. Applied AFTER [FORCE_MODIFIER]. Set via [MODIFY_ATTACK_FORCE_MULTIPLIER]
#define FORCE_MULTIPLIER "force_multiplier"
/// If set in modifiers, default messages ("You hit the thing with the thing") are silenced
#define SILENCE_DEFAULT_MESSAGES "silence_default_messages"
/// If set in modifiers, default hitsound is silenced
#define SILENCE_HITSOUND "silence_hitsound"
/// Used in attack chain to set the force of the attack without changing the base force of the item.
#define SET_ATTACK_FORCE(atk_mods, value) \
if(!islist(atk_mods)) { atk_mods = list() }; \
atk_mods[FORCE_OVERRIDE] = value;
/// Used in attack chain to add or remove force from the attack without changing the base force of the item.
#define MODIFY_ATTACK_FORCE(atk_mods, amount) \
if(!islist(atk_mods)) { atk_mods = list() }; \
atk_mods[FORCE_MODIFIER] += amount;
/// Used in attack chain to multiply the force of the attack without changing the base force of the item.
#define MODIFY_ATTACK_FORCE_MULTIPLIER(atk_mods, amount) \
if(!islist(atk_mods)) { atk_mods = list() }; \
if(!(FORCE_MULTIPLIER in atk_mods)) { atk_mods[FORCE_MULTIPLIER] = 1 }; \
atk_mods[FORCE_MULTIPLIER] *= amount;
/// Used in attack chain to prevent hitsounds on attack (to allow for custom sounds)
#define MUTE_ATTACK_HITSOUND(atk_mods) \
if(!islist(atk_mods)) { atk_mods = list() }; \
atk_mods[SILENCE_HITSOUND] = TRUE;
/// Used in attack chain to prevent default visible messages from being sent (to allow for custom messages)
#define HIDE_ATTACK_MESSAGES(atk_mods) \
if(!islist(atk_mods)) { atk_mods = list() }; \
atk_mods[SILENCE_DEFAULT_MESSAGES] = TRUE;
/// Calculates the final force of some item based on atk_mods
/// Needs to have support for force overrides and multipliers of 0 (hence why we ternaries are used over 'or's)
#define CALCULATE_FORCE(some_item, atk_mods) \
((((FORCE_OVERRIDE in atk_mods) ? atk_mods[FORCE_OVERRIDE] : some_item.force) + (atk_mods?[FORCE_MODIFIER] || 0)) * ((FORCE_MULTIPLIER in atk_mods) ? atk_mods[FORCE_MULTIPLIER] : 1))
@@ -194,7 +194,7 @@
#define COMSIG_TABLE_SLAMMED "table_slammed"
///from base of atom/attack_hand(): (mob/user, modifiers)
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand"
///from base of /obj/item/attack(): (mob/M, mob/user, list/modifiers)
///from base of /obj/item/attack(): (mob/M, mob/user, list/modifiers, list/attack_modifiers)
#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack"
///from base of mob/RangedAttack(): (atom/A, modifiers)
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged"
+4 -4
View File
@@ -133,7 +133,7 @@
#define COMSIG_ITEM_ON_GRIND "on_grind"
///from base of obj/item/on_juice(): ()
#define COMSIG_ITEM_ON_JUICE "on_juice"
///from /obj/machinery/hydroponics/attackby(obj/item/O, mob/user, list/modifiers) when an object is used as compost: (mob/user)
///from /obj/machinery/hydroponics/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers) when an object is used as compost: (mob/user)
#define COMSIG_ITEM_ON_COMPOSTED "on_composted"
///Called when an item is dried by a drying rack
#define COMSIG_ITEM_DRIED "item_dried"
@@ -461,7 +461,7 @@
/// Prevents click from happening.
#define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0)
///from base of /obj/item/attack(): (mob/living, mob/living, list/modifiers)
///from base of /obj/item/attack(): (mob/living, mob/living, list/modifiers, list/attack_modifiers)
#define COMSIG_ITEM_ATTACK "item_attack"
///from base of obj/item/attack_self(): (/mob)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self"
@@ -471,12 +471,12 @@
#define COMSIG_ITEM_ATTACK_ATOM "item_attack_atom"
///from base of obj/item/pre_attack(): (atom/target, mob/user, list/modifiers)
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack"
/// From base of [/obj/item/proc/pre_attack_secondary()]: (atom/target, mob/user, list/modifiers)
/// From base of [/obj/item/proc/pre_attack_secondary()]: (atom/target, mob/user, list/modifiers, list/attack_modifiers)
#define COMSIG_ITEM_PRE_ATTACK_SECONDARY "item_pre_attack_secondary"
#define COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN (1<<0)
#define COMPONENT_SECONDARY_CONTINUE_ATTACK_CHAIN (1<<1)
#define COMPONENT_SECONDARY_CALL_NORMAL_ATTACK_CHAIN (1<<2)
/// From base of [/obj/item/proc/attack_secondary()]: (atom/target, mob/user, list/modifiers)
/// From base of [/obj/item/proc/attack_secondary()]: (atom/target, mob/user, list/modifiers, list/attack_modifiers)
#define COMSIG_ITEM_ATTACK_SECONDARY "item_attack_secondary"
///from base of [obj/item/attack()]: (atom/target, mob/user, proximity_flag, list/modifiers)
#define COMSIG_ITEM_AFTERATTACK "item_afterattack"
+94 -70
View File
@@ -1,17 +1,31 @@
/**
* This is the proc that handles the order of an item_attack.
* THIS IS THE ROOT OF ALL EVIL (I mean the root of all item-on-atom interactions)
*
* The order of procs called is:
* * [/atom/proc/tool_act] on the target. If it returns ITEM_INTERACT_SUCCESS or ITEM_INTERACT_BLOCKING, 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.
* Implementation details
*
* [obj/item/proc/base_item_interaction] handles all non-combat interactions of an item with an atom.
* This calls [atom/proc/tool_act], among others.
*
* [obj/item/proc/pre_attack] is called before an attack is made, before we even check for block.
* Use pre attack to cancel attacks early based on conditions ("You cant attack with this unless you're a pacifist!")
* After pre-attack we go into [atom/proc/attackby] which is where individual atoms handle what happens when being hit
* Objects use [obj/item/proc/attack_atom], mobs use [obj/item/proc/attack].
* You GENERALLY should never override attack, like ever. (On-attack effects go in afterattack)
* Regardless, we go BACK to the atom to call [atom/proc/attacked_by], which is where the damage is actually applied.
* Finally we call [obj/item/proc/afterattack] after damage is dealt, to handle special item interacts after an attack occurs.
* Use afterattack for stuff like "My stick stuns when it hits people".
*
* Arguments
* * mob/living/user - The mob using src on something
* * atom/target - The atom being clicked on with src
* * list/modifiers - click params such as alt/shift and x/y, etc
* * list/attack_modifiers - attack modifiers such as force, damage type, etc. Only used in attacks
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, list/modifiers)
/obj/item/proc/melee_attack_chain(mob/user, atom/target, list/modifiers, list/attack_modifiers = list())
//Proxy replaces src cause it returns an atom that will attack the target on our behalf
var/obj/item/source_atom = get_proxy_attacker_for(target, user)
if(source_atom != src) //if we are someone else then call that attack chain else we can proceed with the usual stuff
return source_atom.melee_attack_chain(user, target, modifiers)
return source_atom.melee_attack_chain(user, target, modifiers, attack_modifiers)
var/is_right_clicking = LAZYACCESS(modifiers, RIGHT_CLICK)
@@ -25,9 +39,9 @@
var/pre_attack_result
if (is_right_clicking)
switch (pre_attack_secondary(target, user, modifiers))
switch (pre_attack_secondary(target, user, modifiers, attack_modifiers))
if (SECONDARY_ATTACK_CALL_NORMAL)
pre_attack_result = pre_attack(target, user, modifiers)
pre_attack_result = pre_attack(target, user, modifiers, attack_modifiers)
if (SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return TRUE
if (SECONDARY_ATTACK_CONTINUE_CHAIN)
@@ -35,7 +49,7 @@
else
CRASH("pre_attack_secondary must return an SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm")
else
pre_attack_result = pre_attack(target, user, modifiers)
pre_attack_result = pre_attack(target, user, modifiers, attack_modifiers)
if(pre_attack_result)
return TRUE
@@ -44,9 +58,9 @@
var/attackby_result
if (is_right_clicking)
switch (target.attackby_secondary(src, user, modifiers))
switch (target.attackby_secondary(src, user, modifiers, attack_modifiers))
if (SECONDARY_ATTACK_CALL_NORMAL)
attackby_result = target.attackby(src, user, modifiers)
attackby_result = target.attackby(src, user, modifiers, attack_modifiers)
if (SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return TRUE
if (SECONDARY_ATTACK_CONTINUE_CHAIN)
@@ -54,7 +68,7 @@
else
CRASH("attackby_secondary must return an SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm")
else
attackby_result = target.attackby(src, user, modifiers)
attackby_result = target.attackby(src, user, modifiers, attack_modifiers)
if (attackby_result)
// This means the attack failed or was handled for whatever reason
@@ -89,11 +103,12 @@
* * atom/target - The atom about to be hit
* * mob/living/user - The mob doing the htting
* * list/modifiers - click params such as alt/shift etc
*
* * attack_modifiers - attack modifiers such as force, damage type, etc
* See: [/obj/item/proc/melee_attack_chain]
*/
/obj/item/proc/pre_attack(atom/target, mob/living/user, list/modifiers) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, target, user, modifiers) & COMPONENT_CANCEL_ATTACK_CHAIN)
/obj/item/proc/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, target, user, modifiers, attack_modifiers) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
@@ -104,11 +119,12 @@
* * atom/target - The atom about to be hit
* * mob/living/user - The mob doing the htting
* * list/modifiers - click params such as alt/shift etc
* * list/attack_modifiers - attack modifiers such as force, damage type, etc
*
* See: [/obj/item/proc/melee_attack_chain]
*/
/obj/item/proc/pre_attack_secondary(atom/target, mob/living/user, list/modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK_SECONDARY, target, user, modifiers)
/obj/item/proc/pre_attack_secondary(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK_SECONDARY, target, user, modifiers, attack_modifiers)
if(signal_result & COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -124,12 +140,13 @@
* Arguments:
* * obj/item/attacking_item - The item hitting this atom
* * mob/user - The wielder of this item
* * params - click params such as alt/shift etc
* * list/modifiers - click params such as alt/shift etc
* * list/attack_modifiers - attack modifiers such as force, damage type, etc
*
* See: [/obj/item/proc/melee_attack_chain]
*/
/atom/proc/attackby(obj/item/attacking_item, mob/user, list/modifiers)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACKBY, attacking_item, user, modifiers) & COMPONENT_NO_AFTERATTACK)
/atom/proc/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACKBY, attacking_item, user, modifiers, attack_modifiers) & COMPONENT_NO_AFTERATTACK)
return TRUE
return FALSE
@@ -139,12 +156,13 @@
* Arguments:
* * obj/item/weapon - The item hitting this atom
* * mob/user - The wielder of this item
* * params - click params such as alt/shift etc
* * list/modifiers - click params such as alt/shift etc
* * list/attack_modifiers - attack modifiers such as force, damage type, etc
*
* See: [/obj/item/proc/melee_attack_chain]
*/
/atom/proc/attackby_secondary(obj/item/weapon, mob/user, list/modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ATOM_ATTACKBY_SECONDARY, weapon, user, modifiers)
/atom/proc/attackby_secondary(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ATOM_ATTACKBY_SECONDARY, weapon, user, modifiers, attack_modifiers)
if(signal_result & COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -154,12 +172,12 @@
return SECONDARY_ATTACK_CALL_NORMAL
/obj/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(..())
return TRUE
if(!(obj_flags & CAN_BE_HIT))
return FALSE
return attacking_item.attack_atom(src, user, modifiers)
return attacking_item.attack_atom(src, user, modifiers, attack_modifiers)
/mob/living/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
for(var/datum/surgery/operation as anything in surgeries)
@@ -172,14 +190,14 @@
return NONE
/mob/living/attackby(obj/item/attacking_item, mob/living/user, list/modifiers)
/mob/living/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(..())
return TRUE
user.changeNext_move(attacking_item.attack_speed)
return attacking_item.attack(src, user, modifiers)
return attacking_item.attack(src, user, modifiers, attack_modifiers)
/mob/living/attackby_secondary(obj/item/weapon, mob/living/user, list/modifiers)
var/result = weapon.attack_secondary(src, user, modifiers)
/mob/living/attackby_secondary(obj/item/weapon, mob/living/user, list/modifiers, list/attack_modifiers)
var/result = weapon.attack_secondary(src, user, modifiers, attack_modifiers)
// Normal attackby updates click cooldown, so we have to make up for it
if (result != SECONDARY_ATTACK_CALL_NORMAL)
@@ -196,10 +214,11 @@
* Arguments:
* * mob/living/target_mob - The mob being hit by this item
* * mob/living/user - The mob hitting with this item
* * params - Click params of this attack
* * modifiers - click modifiers such as alt/shift or x/y
* * attack_modifiers - attack modifiers such as force, damage type, etc
*/
/obj/item/proc/attack(mob/living/target_mob, mob/living/user, list/modifiers)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, target_mob, user, modifiers) || SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, target_mob, user, modifiers)
/obj/item/proc/attack(mob/living/target_mob, mob/living/user, list/modifiers, list/attack_modifiers)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, target_mob, user, modifiers, attack_modifiers) || SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, target_mob, user, modifiers, attack_modifiers)
if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
if(signal_return & COMPONENT_SKIP_ATTACK)
@@ -208,37 +227,39 @@
if(item_flags & NOBLUDGEON)
return FALSE
if(damtype != STAMINA && force && HAS_TRAIT(user, TRAIT_PACIFISM))
var/final_force = CALCULATE_FORCE(src, attack_modifiers)
if(damtype != STAMINA && final_force && HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, span_warning("You don't want to harm other living beings!"))
return FALSE
if(!force && !HAS_TRAIT(src, TRAIT_CUSTOM_TAP_SOUND))
playsound(src, 'sound/items/weapons/tap.ogg', get_clamped_volume(), TRUE, -1)
else if(hitsound)
playsound(src, hitsound, get_clamped_volume(), TRUE, extrarange = stealthy_audio ? SILENCED_SOUND_EXTRARANGE : -1, falloff_distance = 0)
if(!LAZYACCESS(attack_modifiers, SILENCE_HITSOUND))
if(!final_force && !HAS_TRAIT(src, TRAIT_CUSTOM_TAP_SOUND))
playsound(src, 'sound/items/weapons/tap.ogg', get_clamped_volume(), TRUE, -1)
else if(hitsound)
playsound(src, hitsound, get_clamped_volume(), TRUE, extrarange = stealthy_audio ? SILENCED_SOUND_EXTRARANGE : -1, falloff_distance = 0)
target_mob.lastattacker = user.real_name
target_mob.lastattackerckey = user.ckey
if(force && target_mob == user && user.client)
if(final_force && target_mob == user && user.client)
user.client.give_award(/datum/award/achievement/misc/selfouch, user)
if(get(src, /mob/living) == user) // telekinesis.
user.do_attack_animation(target_mob)
if(!target_mob.attacked_by(src, user))
if(!target_mob.attacked_by(src, user, modifiers, attack_modifiers))
return TRUE
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target_mob, user, modifiers)
SEND_SIGNAL(target_mob, COMSIG_ATOM_AFTER_ATTACKEDBY, src, user, modifiers)
afterattack(target_mob, user, modifiers)
log_combat(user, target_mob, "attacked", src.name, "(COMBAT MODE: [uppertext(user.combat_mode)]) (DAMTYPE: [uppertext(damtype)])")
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target_mob, user, modifiers, attack_modifiers)
SEND_SIGNAL(target_mob, COMSIG_ATOM_AFTER_ATTACKEDBY, src, user, modifiers, attack_modifiers)
afterattack(target_mob, user, modifiers, attack_modifiers)
if(final_force > 0)
log_combat(user, target_mob, "attacked", src.name, "(COMBAT MODE: [uppertext(user.combat_mode)]) (DAMTYPE: [uppertext(damtype)])")
add_fingerprint(user)
return FALSE // unhandled
/// The equivalent of [/obj/item/proc/attack] but for alternate attacks, AKA right clicking
/obj/item/proc/attack_secondary(mob/living/victim, mob/living/user, list/modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SECONDARY, victim, user, modifiers)
/obj/item/proc/attack_secondary(mob/living/victim, mob/living/user, list/modifiers, list/attack_modifiers)
var/signal_result = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SECONDARY, victim, user, modifiers, attack_modifiers)
if(signal_result & COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -249,8 +270,8 @@
return SECONDARY_ATTACK_CALL_NORMAL
/// The equivalent of the standard version of [/obj/item/proc/attack] but for non mob targets.
/obj/item/proc/attack_atom(atom/attacked_atom, mob/living/user, list/modifiers)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_ATOM, attacked_atom, user) | SEND_SIGNAL(user, COMSIG_LIVING_ATTACK_ATOM, attacked_atom)
/obj/item/proc/attack_atom(atom/attacked_atom, mob/living/user, list/modifiers, list/attack_modifiers)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_ATOM, attacked_atom, user, modifiers, attack_modifiers) | SEND_SIGNAL(user, COMSIG_LIVING_ATTACK_ATOM, attacked_atom, modifiers, attack_modifiers)
if(signal_return & COMPONENT_SKIP_ATTACK)
return TRUE
if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN)
@@ -260,30 +281,32 @@
user.changeNext_move(attack_speed)
if(get(src, /mob/living) == user) // telekinesis.
user.do_attack_animation(attacked_atom)
attacked_atom.attacked_by(src, user)
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, attacked_atom, user, modifiers)
SEND_SIGNAL(attacked_atom, COMSIG_ATOM_AFTER_ATTACKEDBY, src, user, modifiers)
afterattack(attacked_atom, user, modifiers)
attacked_atom.attacked_by(src, user, modifiers, attack_modifiers)
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, attacked_atom, user, modifiers, attack_modifiers)
SEND_SIGNAL(attacked_atom, COMSIG_ATOM_AFTER_ATTACKEDBY, src, user, modifiers, attack_modifiers)
afterattack(attacked_atom, user, modifiers, attack_modifiers)
return FALSE // unhandled
/// Called from [/obj/item/proc/attack_atom] and [/obj/item/proc/attack] if the attack succeeds
/atom/proc/attacked_by(obj/item/attacking_item, mob/living/user)
/atom/proc/attacked_by(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(!uses_integrity)
CRASH("attacked_by() was called on an object that doesn't use integrity!")
if(!attacking_item.force)
return
var/final_force = CALCULATE_FORCE(attacking_item, attack_modifiers)
if(final_force <= 0)
return 0
var/damage = take_damage(attacking_item.force, attacking_item.damtype, MELEE, 1, get_dir(src, user))
var/damage = take_damage(final_force, attacking_item.damtype, MELEE, 1, get_dir(src, user))
//only witnesses close by and the victim see a hit message.
user.visible_message(span_danger("[user] hits [src] with [attacking_item][damage ? "." : ", without leaving a mark!"]"), \
span_danger("You hit [src] with [attacking_item][damage ? "." : ", without leaving a mark!"]"), null, COMBAT_MESSAGE_RANGE)
log_combat(user, src, "attacked", attacking_item)
return damage
/area/attacked_by(obj/item/attacking_item, mob/living/user)
/area/attacked_by(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
CRASH("areas are NOT supposed to have attacked_by() called on them!")
/mob/living/attacked_by(obj/item/attacking_item, mob/living/user)
/mob/living/attacked_by(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
var/targeting = check_zone(user.zone_selected)
if(user != src)
@@ -293,7 +316,8 @@
targeting = get_random_valid_zone(targeting, zone_hit_chance)
var/targeting_human_readable = parse_zone_with_bodypart(targeting)
send_item_attack_message(attacking_item, user, targeting_human_readable, targeting)
if(!LAZYACCESS(attack_modifiers, SILENCE_DEFAULT_MESSAGES))
send_item_attack_message(attacking_item, user, targeting_human_readable, targeting)
var/armor_block = min(run_armor_check(
def_zone = targeting,
@@ -304,9 +328,9 @@
weak_against_armour = attacking_item.weak_against_armour,
), ARMOR_MAX_BLOCK)
var/damage = attacking_item.force
var/final_force = CALCULATE_FORCE(attacking_item, attack_modifiers)
if(mob_biotypes & MOB_ROBOTIC)
damage *= attacking_item.get_demolition_modifier(src)
final_force *= attacking_item.get_demolition_modifier(src)
var/wounding = attacking_item.wound_bonus
if((attacking_item.item_flags & SURGICAL_TOOL) && !user.combat_mode && body_position == LYING_DOWN && (LAZYLEN(surgeries) > 0))
@@ -314,20 +338,20 @@
if(user != src)
// This doesn't factor in armor, or most damage modifiers (physiology). Your mileage may vary
if(check_block(attacking_item, damage, "\the [attacking_item]", MELEE_ATTACK, attacking_item.armour_penetration, attacking_item.damtype))
return FALSE
if(check_block(attacking_item, final_force, "\the [attacking_item]", MELEE_ATTACK, attacking_item.armour_penetration, attacking_item.damtype))
return 0
SEND_SIGNAL(attacking_item, COMSIG_ITEM_ATTACK_ZONE, src, user, targeting)
if(damage <= 0)
return TRUE
if(final_force <= 0)
return 1 // Pretend like we did 1 damage so afterattack still runs
if(ishuman(src) || client) // istype(src) is kinda bad, but it's to avoid spamming the blackbox
SSblackbox.record_feedback("nested tally", "item_used_for_combat", 1, list("[attacking_item.force]", "[attacking_item.type]"))
SSblackbox.record_feedback("tally", "zone_targeted", 1, targeting_human_readable)
var/damage_done = apply_damage(
damage = damage,
damage = final_force,
damagetype = attacking_item.damtype,
def_zone = targeting,
blocked = armor_block,
@@ -340,7 +364,7 @@
attack_effects(damage_done, targeting, armor_block, attacking_item, user)
return TRUE
return damage_done
/**
* Called when we take damage, used to cause effects such as a blood splatter.
@@ -436,7 +460,7 @@
* * 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, list/modifiers)
/obj/item/proc/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
PROTECTED_PROC(TRUE)
return
@@ -32,14 +32,14 @@
/datum/component/alternative_sharpness/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK_SECONDARY, PROC_REF(on_secondary_attack))
/datum/component/alternative_sharpness/proc/on_secondary_attack(obj/item/source, atom/target, mob/user, list/modifiers)
/datum/component/alternative_sharpness/proc/on_secondary_attack(obj/item/source, atom/target, mob/user, list/modifiers, list/attack_modifiers)
SIGNAL_HANDLER
if (alt_attacking || (required_trait && !HAS_TRAIT(source, required_trait)))
return
alt_attacking = TRUE
source.force += force_mod
MODIFY_ATTACK_FORCE(attack_modifiers, force_mod)
base_sharpness = source.sharpness
source.sharpness = alt_sharpness
if (!isnull(verbs_continuous))
@@ -54,7 +54,6 @@
/datum/component/alternative_sharpness/proc/disable_alt_attack()
var/obj/item/weapon = parent
alt_attacking = FALSE
weapon.force -= force_mod
weapon.attack_verb_continuous = base_continuous
weapon.attack_verb_simple = base_simple
weapon.sharpness = base_sharpness
+6 -4
View File
@@ -3,6 +3,8 @@
* Not compatible with any other component or status effect which modifies attack damage
*/
/datum/component/focused_attacker
/// Current attack bonus
VAR_FINAL/current_gain
/// Amount of damage we gain per attack
var/gain_per_attack
/// Maximum amount by which we can increase our attack power
@@ -48,14 +50,14 @@
register_new_target(target)
/// Before an item attacks, try increasing its attack power
/datum/component/focused_attacker/proc/pre_item_attack(obj/item/weapon, atom/target, mob/user, list/modifiers)
/datum/component/focused_attacker/proc/pre_item_attack(obj/item/weapon, atom/target, mob/user, list/modifiers, list/attack_modifiers)
SIGNAL_HANDLER
if (target == last_target)
if (weapon.force - initial(weapon.force) < maximum_gain)
weapon.force += gain_per_attack
current_gain += gain_per_attack
MODIFY_ATTACK_FORCE(attack_modifiers, current_gain)
return
weapon.force = initial(weapon.force)
current_gain = 0
register_new_target(target)
/// Register a new target
+1 -1
View File
@@ -334,7 +334,7 @@
internals.forceMove(get_turf(src))
internals = null
/obj/item/trapdoor_remote/attackby(obj/item/assembly/trapdoor/assembly, mob/living/user, list/modifiers)
/obj/item/trapdoor_remote/attackby(obj/item/assembly/trapdoor/assembly, mob/living/user, list/modifiers, list/attack_modifiers)
. = ..()
if(. || !istype(assembly))
return
+1 -1
View File
@@ -232,7 +232,7 @@
QDEL_NULL(record)
return ..()
/obj/item/disk/holodisk/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/disk/holodisk/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/disk/holodisk))
var/obj/item/disk/holodisk/holodiskOriginal = item
if (holodiskOriginal.record)
+1 -1
View File
@@ -271,7 +271,7 @@
icon_state = inhand_icon_state = "[base_icon_state][HAS_TRAIT(src, TRAIT_WIELDED)]"
return ..()
/obj/item/staff/bostaff/attack(mob/target, mob/living/user, list/modifiers)
/obj/item/staff/bostaff/attack(mob/target, mob/living/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, span_warning("You club yourself over the head with [src]."))
+2 -2
View File
@@ -17,7 +17,7 @@
. += span_notice("This kit has enough ink for [uses] use\s.")
. += span_boldnotice("You can use a toner cartridge to refill this.")
/obj/item/tattoo_kit/attackby(obj/item/toner/ink_cart, mob/living/tattoo_artist, list/modifiers)
/obj/item/tattoo_kit/attackby(obj/item/toner/ink_cart, mob/living/tattoo_artist, list/modifiers, list/attack_modifiers)
. = ..()
if(!istype(ink_cart))
return
@@ -29,7 +29,7 @@
qdel(ink_cart)
balloon_alert(tattoo_artist, "added tattoo ink")
/obj/item/tattoo_kit/attack(mob/living/tattoo_holder, mob/living/tattoo_artist, list/modifiers)
/obj/item/tattoo_kit/attack(mob/living/tattoo_holder, mob/living/tattoo_artist, list/modifiers, list/attack_modifiers)
. = ..()
if(.)
return TRUE
+1 -1
View File
@@ -109,7 +109,7 @@
power_change()
return ITEM_INTERACT_SUCCESS
/obj/machinery/pdapainter/attackby(obj/item/O, mob/living/user, list/modifiers)
/obj/machinery/pdapainter/attackby(obj/item/O, mob/living/user, list/modifiers, list/attack_modifiers)
if(machine_stat & BROKEN)
if(O.tool_behaviour == TOOL_WELDER && !user.combat_mode)
if(!O.tool_start_check(user, amount=1))
+2 -2
View File
@@ -804,13 +804,13 @@
return attack_robot(user)
return _try_interact(user)
/obj/machinery/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
. = ..()
if(.)
return
update_last_used(user)
/obj/machinery/attackby_secondary(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/attackby_secondary(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
. = ..()
if(.)
return
+1 -1
View File
@@ -43,7 +43,7 @@
synced_bank_account = null
return ..()
/obj/machinery/computer/bank_machine/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/computer/bank_machine/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
var/value = 0
if(istype(weapon, /obj/item/stack/spacecash))
var/obj/item/stack/spacecash/inserted_cash = weapon
@@ -119,7 +119,7 @@
return ITEM_INTERACT_SUCCESS
return ..()
/obj/machinery/camera/attackby(obj/item/attacking_item, mob/living/user, list/modifiers)
/obj/machinery/camera/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(camera_construction_state != CAMERA_STATE_FINISHED || panel_open)
if(attacking_item.tool_behaviour == TOOL_ANALYZER)
if(!isXRay(TRUE)) //don't reveal it was already upgraded if was done via MALF AI Upgrade Camera Network ability
+1 -1
View File
@@ -41,7 +41,7 @@
update_appearance()
return ITEM_INTERACT_SUCCESS
/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(istype(W, /obj/item/stock_parts/power_store/cell) && !panel_open)
if(machine_stat & BROKEN)
to_chat(user, span_warning("[src] is broken!"))
+1 -1
View File
@@ -47,7 +47,7 @@
///Typecast of an inserted, scanned ID card inside the console, as bounties are held within the ID card.
var/obj/item/card/id/inserted_scan_id
/obj/machinery/computer/piratepad_control/civilian/attackby(obj/item/I, mob/living/user, list/modifiers)
/obj/machinery/computer/piratepad_control/civilian/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
if(isidcard(I))
if(id_insert(user, I, inserted_scan_id))
inserted_scan_id = I
@@ -110,7 +110,7 @@
return TRUE
return authenticated
/obj/machinery/computer/communications/attackby(obj/I, mob/user, list/modifiers)
/obj/machinery/computer/communications/attackby(obj/I, mob/user, list/modifiers, list/attack_modifiers)
if(isidcard(I))
attack_hand(user)
else
+1 -1
View File
@@ -172,7 +172,7 @@
genetic_damage_pulse()
return
/obj/machinery/computer/scan_consolenew/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/computer/scan_consolenew/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
// Store chromosomes in the console if there's room
if (istype(item, /obj/item/chromosome))
item.forceMove(src)
+1 -1
View File
@@ -11,7 +11,7 @@
log_silicon("\A [name] was created at [loc_name(src)].")
message_admins("\A [name] was created at [ADMIN_VERBOSEJMP(src)].")
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, list/modifiers)
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers)
if(istype(O, /obj/item/ai_module))
var/obj/item/ai_module/M = O
if(machine_stat & (NOPOWER|BROKEN|MAINT))
@@ -50,7 +50,7 @@
linked_techweb = tool.buffer
return TRUE
/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, list/modifiers)
/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers)
if(istype(O, /obj/item/disk/surgery))
user.visible_message(span_notice("[user] begins to load \the [O] in \the [src]..."), \
span_notice("You begin to load a surgery protocol from \the [O]..."), \
@@ -102,7 +102,7 @@
. = ..()
. += span_notice("There's [points] point\s on the card.")
/obj/item/card/mining_point_card/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/item/card/mining_point_card/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(!isidcard(attacking_item))
return ..()
var/obj/item/card/id/attacking_id = attacking_item
@@ -50,7 +50,7 @@
balloon_alert_to_viewers("id ejected")
playsound(src, 'sound/machines/terminal/terminal_insert_disc.ogg', 50, FALSE)
/obj/machinery/computer/prisoner/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/computer/prisoner/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
if(istype(weapon, /obj/item/card/id/advanced/prisoner))
id_insert(user, weapon)
return TRUE
@@ -20,11 +20,11 @@
pass_flags = PASSTABLE
projectiles_pass_chance = 100
/obj/machinery/computer/records/medical/attacked_by(obj/item/attacking_item, mob/living/user)
. = ..()
if(!istype(attacking_item, /obj/item/photo))
return
insert_new_record(user, attacking_item)
/obj/machinery/computer/records/medical/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!istype(tool, /obj/item/photo))
return NONE
insert_new_record(user, tool)
return ITEM_INTERACT_SUCCESS
/obj/machinery/computer/records/medical/ui_interact(mob/user, datum/tgui/ui)
. = ..()
@@ -66,11 +66,11 @@
qdel(target)
continue
/obj/machinery/computer/records/security/attacked_by(obj/item/attacking_item, mob/living/user)
. = ..()
if(!istype(attacking_item, /obj/item/photo))
return
insert_new_record(user, attacking_item)
/obj/machinery/computer/records/security/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!istype(tool, /obj/item/photo))
return NONE
insert_new_record(user, tool)
return ITEM_INTERACT_SUCCESS
/obj/machinery/computer/records/security/ui_interact(mob/user, datum/tgui/ui)
. = ..()
+1 -1
View File
@@ -81,7 +81,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
return
user.put_in_hands(defib.paddles)
/obj/machinery/defibrillator_mount/attackby(obj/item/item, mob/living/user, list/modifiers)
/obj/machinery/defibrillator_mount/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/defibrillator))
if(defib)
to_chat(user, span_warning("There's already a defibrillator in [src]!"))
+1 -1
View File
@@ -26,7 +26,7 @@
return
/obj/structure/barricade/attackby(obj/item/I, mob/living/user, list/modifiers)
/obj/structure/barricade/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode && bar_material == METAL)
if(atom_integrity < max_integrity)
if(!I.tool_start_check(user, amount=1))
+1 -1
View File
@@ -83,7 +83,7 @@
default_unfasten_wrench(user, tool)
return ITEM_INTERACT_SUCCESS
/obj/machinery/dish_drive/attackby(obj/item/dish, mob/living/user, list/modifiers)
/obj/machinery/dish_drive/attackby(obj/item/dish, mob/living/user, list/modifiers, list/attack_modifiers)
if(is_type_in_list(dish, collectable_items) && !user.combat_mode)
if(!user.transferItemToLoc(dish, src))
return
@@ -161,7 +161,7 @@
//we set drop to false to manually call it with an allowlist
dump_inventory_contents(list(occupant))
/obj/machinery/dna_infuser/attackby(obj/item/used, mob/user, list/modifiers)
/obj/machinery/dna_infuser/attackby(obj/item/used, mob/user, list/modifiers, list/attack_modifiers)
if(infusing)
return
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, used))//sent icon_state is irrelevant...
@@ -128,7 +128,7 @@
. = ..()
. += "You can use your tendril hammer arm to deliver a devastating blow against mining fauna, but only once every two seconds."
/obj/item/goliath_infuser_hammer/attack(mob/living/target, mob/living/carbon/human/user, list/modifiers)
/obj/item/goliath_infuser_hammer/attack(mob/living/target, mob/living/carbon/human/user, list/modifiers, list/attack_modifiers)
. = ..()
//If we're on cooldown, we'll do a normal attack.
+1 -1
View File
@@ -125,7 +125,7 @@
return
open_machine()
/obj/machinery/dna_scannernew/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/dna_scannernew/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, item))//sent icon_state is irrelevant...
update_appearance()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed
+1 -1
View File
@@ -1021,7 +1021,7 @@
update_appearance()
return TRUE
/obj/machinery/door/airlock/attackby(obj/item/C, mob/user, list/modifiers)
/obj/machinery/door/airlock/attackby(obj/item/C, mob/user, list/modifiers, list/attack_modifiers)
if(!HAS_SILICON_ACCESS(user))
if(isElectrified() && (C.obj_flags & CONDUCTS_ELECTRICITY) && shock(user, 75))
return
+1 -1
View File
@@ -367,7 +367,7 @@
try_to_crowbar(tool, user, forced_open)
return ITEM_INTERACT_SUCCESS
/obj/machinery/door/attackby(obj/item/weapon, mob/living/user, list/modifiers)
/obj/machinery/door/attackby(obj/item/weapon, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(weapon, /obj/item/access_key))
var/obj/item/access_key/key = weapon
return key.attempt_open_door(user, src)
+1 -1
View File
@@ -306,7 +306,7 @@
/obj/machinery/firealarm/attack_robot_secondary(mob/user)
return attack_hand_secondary(user)
/obj/machinery/firealarm/attackby(obj/item/tool, mob/living/user, list/modifiers)
/obj/machinery/firealarm/attackby(obj/item/tool, mob/living/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if(tool.tool_behaviour == TOOL_SCREWDRIVER && buildstage == FIRE_ALARM_BUILD_SECURED)
+2 -2
View File
@@ -62,7 +62,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26)
return ..()
//Don't want to render prison breaks impossible
/obj/machinery/flasher/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/flasher/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if (attacking_item.tool_behaviour == TOOL_WIRECUTTER)
if (bulb)
@@ -185,7 +185,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26)
if(vname == NAMEOF(src, flash_range))
proximity_monitor?.set_range(flash_range)
/obj/machinery/flasher/portable/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/flasher/portable/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if (attacking_item.tool_behaviour == TOOL_WRENCH)
attacking_item.play_tool_sound(src, 100)
+1 -1
View File
@@ -258,7 +258,7 @@ Possible to do for anyone motivated enough:
if(record_mode)
record_stop()
/obj/machinery/holopad/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/holopad/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", item))
return
+1 -1
View File
@@ -27,7 +27,7 @@
open_machine()
update_appearance()
/obj/machinery/hypnochair/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/hypnochair/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, item))
update_appearance()
return
+1 -1
View File
@@ -179,7 +179,7 @@
user.visible_message(span_warning("[user] attaches [src] to [target]."), span_notice("You attach [src] to [target]."))
attach_iv(target, user)
/obj/machinery/iv_drip/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/iv_drip/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(use_internal_storage)
return ..()
+2 -2
View File
@@ -75,7 +75,7 @@
balloon_alert(user, "saved to buffer")
return ITEM_INTERACT_SUCCESS
/obj/machinery/launchpad/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/launchpad/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
if(!stationary)
return ..()
@@ -312,7 +312,7 @@
closed = TRUE
update_indicator()
/obj/machinery/launchpad/briefcase/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/launchpad/briefcase/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/launchpad_remote))
var/obj/item/launchpad_remote/launch = item
if(launch.pad == WEAKREF(src)) //do not attempt to link when already linked
+1 -1
View File
@@ -54,7 +54,7 @@
O.throw_at(target, drive_range * power, power)
flick("mass_driver1", src)
/obj/machinery/mass_driver/attackby(obj/item/item, mob/living/user, list/modifiers)
/obj/machinery/mass_driver/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers)
if(is_wire_tool(item) && panel_open)
wires.interact(user)
+1 -1
View File
@@ -117,7 +117,7 @@
active_price = board.custom_cost
return
/obj/machinery/medical_kiosk/attackby(obj/item/O, mob/user, list/modifiers)
/obj/machinery/medical_kiosk/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, "[base_icon_state]_open", "[base_icon_state]_off", O))
return
else if(default_deconstruction_crowbar(O))
+1 -1
View File
@@ -143,7 +143,7 @@
if(default_deconstruction_crowbar(tool))
return TRUE
/obj/machinery/modular_shield_generator/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/modular_shield_generator/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(is_wire_tool(W) && panel_open)
wires.interact(user)
+1 -1
View File
@@ -115,7 +115,7 @@
return TRUE
return default_deconstruction_screwdriver(user, "navbeacon1","navbeacon0",tool)
/obj/machinery/navbeacon/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/navbeacon/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
var/turf/our_turf = loc
if(our_turf.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
return // prevent intraction when T-scanner revealed
+1 -1
View File
@@ -109,7 +109,7 @@
if(isopenturf(turf))
turf.atmos_spawn_air("[GAS_TRITIUM]=1;[TURF_TEMPERATURE(T20C)]")
/obj/machinery/nebula_shielding/radiation/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/nebula_shielding/radiation/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, initial(icon_state) + "_open", initial(icon_state), item))
return
@@ -486,7 +486,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
. = ..()
update_appearance()
/obj/machinery/newscaster/attackby(obj/item/attacking_item, mob/living/user, list/modifiers)
/obj/machinery/newscaster/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(attacking_item, /obj/item/paper))
if(!user.temporarilyRemoveItemFromInventory(attacking_item))
return
+1 -1
View File
@@ -151,7 +151,7 @@
ui = new(user, src, "PipeDispenser", name)
ui.open()
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter))
to_chat(usr, span_notice("You put [W] back into [src]."))
@@ -324,7 +324,7 @@ DEFINE_BITFIELD(turret_flags, list(
balloon_alert(user, "saved to multitool buffer")
return ITEM_INTERACT_SUCCESS
/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, list/modifiers)
/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(machine_stat & BROKEN)
if(I.tool_behaviour == TOOL_CROWBAR)
//If the turret is destroyed, you can remove it with a crowbar to
@@ -996,7 +996,7 @@ DEFINE_BITFIELD(turret_flags, list(
to_chat(user, span_notice("You link \the [multi_tool.buffer] with \the [src]."))
return ITEM_INTERACT_SUCCESS
/obj/machinery/turretid/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/turretid/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(machine_stat & BROKEN)
return
@@ -40,7 +40,7 @@
if(PTURRET_START_EXTERNAL_ARMOUR)
. += span_notice("The turret's armor needs to be <b>welded</b> in place, the armor looks like it could be <i>pried</i> off.")
/obj/machinery/porta_turret_construct/attackby(obj/item/used, mob/user, list/modifiers)
/obj/machinery/porta_turret_construct/attackby(obj/item/used, mob/user, list/modifiers, list/attack_modifiers)
//this is a bit unwieldy but self-explanatory
switch(build_step)
if(PTURRET_UNSECURED) //first step
@@ -45,7 +45,7 @@
balloon_alert(user, "saved to multitool buffer")
return ITEM_INTERACT_SUCCESS
/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user, list/modifiers)
/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(I.tool_behaviour == TOOL_WRENCH && !parent_turret.on)
if(parent_turret.raised)
return
@@ -72,8 +72,8 @@
return ..()
/obj/machinery/porta_turret_cover/attacked_by(obj/item/I, mob/user)
parent_turret.attacked_by(I, user)
/obj/machinery/porta_turret_cover/attacked_by(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
return parent_turret.attacked_by(I, user, modifiers)
/obj/machinery/porta_turret_cover/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers)
parent_turret.attack_alien(user, modifiers)
+1 -1
View File
@@ -26,7 +26,7 @@
QDEL_NULL(current_plate)
. = ..()
/obj/machinery/plate_press/attackby(obj/item/I, mob/living/user, list/modifiers)
/obj/machinery/plate_press/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
if(!is_operational)
to_chat(user, span_warning("[src] has to be on to do this!"))
return FALSE
+1 -3
View File
@@ -71,7 +71,7 @@
balloon_alert(user, "no quantum pad data found!")
return NONE
/obj/machinery/quantumpad/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/quantumpad/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, "qpad-idle-open", "qpad-idle", weapon))
return
@@ -242,5 +242,3 @@
failed.set_output(COMPONENT_SIGNAL)
return
attached_pad.doteleport(target_pad = attached_pad.linked_pad)
+1 -1
View File
@@ -83,7 +83,7 @@
update_appearance()
return ..()
/obj/machinery/recharger/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/recharger/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(!is_type_in_typecache(attacking_item, allowed_devices))
return ..()
+1 -1
View File
@@ -106,7 +106,7 @@
if (!(. & EMP_PROTECT_SELF))
open_machine()
/obj/machinery/recharge_station/attackby(obj/item/P, mob/user, list/modifiers)
/obj/machinery/recharge_station/attackby(obj/item/P, mob/user, list/modifiers, list/attack_modifiers)
if(state_open)
if(default_deconstruction_screwdriver(user, "borgdecon2", "borgcharger0", P))
return
+1 -1
View File
@@ -384,7 +384,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
to_chat(user, span_warning("You must open the maintenance panel first!"))
return TRUE
/obj/machinery/requests_console/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/requests_console/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
var/obj/item/card/id/ID = attacking_item.GetID()
if(ID)
message_verified_by = "[ID.registered_name] ([ID.assignment])"
+1 -1
View File
@@ -116,7 +116,7 @@
update_appearance() // Not applicable to all objects.
///Handles setting ownership and the betting itself.
/obj/machinery/roulette/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/roulette/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(machine_stat & MAINT && is_wire_tool(W))
wires.interact(user)
return
+1 -1
View File
@@ -145,7 +145,7 @@
return
set_scanline("passive")
/obj/machinery/scanner_gate/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/scanner_gate/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
var/obj/item/card/id/card = attacking_item.GetID()
if(card)
if(locked)
+2 -2
View File
@@ -236,7 +236,7 @@
set_anchored(FALSE)
/obj/machinery/shieldgen/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/shieldgen/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(istype(W, /obj/item/stack/cable_coil) && (machine_stat & BROKEN) && panel_open)
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
@@ -460,7 +460,7 @@
return
return default_deconstruction_crowbar(tool)
/obj/machinery/power/shieldwallgen/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/power/shieldwallgen/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
. = ..()
if(W.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
+2 -2
View File
@@ -202,7 +202,7 @@
default_unfasten_wrench(user, tool)
return ITEM_INTERACT_SUCCESS
/obj/machinery/space_heater/attackby(obj/item/I, mob/user, list/modifiers)
/obj/machinery/space_heater/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if(default_deconstruction_screwdriver(user, icon_state, icon_state, I))
@@ -402,7 +402,7 @@
. = TRUE
///Slightly modified to ignore the open_hatch - it's always open, we hacked it.
/obj/machinery/space_heater/improvised_chem_heater/attackby(obj/item/item, mob/user, list/modifiers)
/obj/machinery/space_heater/improvised_chem_heater/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
add_fingerprint(user)
if(default_deconstruction_crowbar(item))
return
+1 -1
View File
@@ -639,7 +639,7 @@
return TRUE
/obj/machinery/suit_storage_unit/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/machinery/suit_storage_unit/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
. = TRUE
var/obj/item/card/id/id = null
if(istype(weapon, /obj/item/stock_parts/card_reader) && can_install_card_reader(user))
+2 -2
View File
@@ -189,7 +189,7 @@
return TRUE
/obj/machinery/syndicatebomb/attackby(obj/item/I, mob/user, list/modifiers)
/obj/machinery/syndicatebomb/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(is_wire_tool(I) && open_panel)
wires.interact(user)
@@ -533,7 +533,7 @@
playsound(loc, 'sound/effects/bamf.ogg', 75, TRUE, 5)
/obj/item/bombcore/chemical/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/bombcore/chemical/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(I.tool_behaviour == TOOL_CROWBAR && beakers.len > 0)
I.play_tool_sound(src)
for (var/obj/item/B in beakers)
@@ -15,7 +15,7 @@
FREQ_CTF_BLUE,
)
/obj/machinery/telecomms/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/telecomms/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
var/icon_closed = initial(icon_state)
var/icon_open = "[initial(icon_state)]_o"
@@ -45,6 +45,6 @@
sleep(signal.data["slow"]) // simulate the network lag if necessary
signal.broadcast()
/obj/machinery/telecomms/allinone/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/machinery/telecomms/allinone/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
return attack_hand(user)
@@ -34,7 +34,7 @@
to_chat(user, span_warning("It seems that the blackbox is missing..."))
return
/obj/machinery/blackbox_recorder/attackby(obj/item/attacking_item, mob/living/user, list/modifiers)
/obj/machinery/blackbox_recorder/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(attacking_item, /obj/item/blackbox))
if(HAS_TRAIT(attacking_item, TRAIT_NODROP) || !user.transferItemToLoc(attacking_item, src))
to_chat(user, span_warning("[attacking_item] is stuck to your hand!"))
+2 -2
View File
@@ -52,7 +52,7 @@
if(is_ready())
teleport(AM)
/obj/machinery/teleport/hub/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/teleport/hub/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, "tele-o", "tele0", W))
if(power_station?.engaged)
power_station.engaged = 0 //hub with panel open is off, so the station must be informed.
@@ -179,7 +179,7 @@
balloon_alert(user, "data uploaded from buffer")
return ITEM_INTERACT_SUCCESS
/obj/machinery/teleport/station/attackby(obj/item/W, mob/user, list/modifiers)
/obj/machinery/teleport/station/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(default_deconstruction_screwdriver(user, "controller-o", "controller", W))
update_appearance()
return
@@ -81,7 +81,7 @@
if(mergeable_decal)
return TRUE
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, list/modifiers)
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if((istype(W, /obj/item/reagent_containers/cup) && !istype(W, /obj/item/rag)) || istype(W, /obj/item/reagent_containers/cup/glass))
if(src.reagents && W.reagents)
. = 1 //so the containers don't splash their content on the src while scooping.
@@ -537,7 +537,7 @@
ignite()
log_combat(hit_proj.firer, src, "used [hit_proj] to ignite")
/obj/effect/decal/cleanable/fuel_pool/attackby(obj/item/item, mob/user, list/modifiers)
/obj/effect/decal/cleanable/fuel_pool/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(item.ignition_effect(src, user))
ignite()
log_combat(user, src, "used [item] to ignite")
@@ -346,7 +346,7 @@
to_chat(user, span_warning("You hit [src] but bounce off it!"))
playsound(src.loc, 'sound/items/weapons/tap.ogg', 100, TRUE)
/obj/structure/foamedmetal/attackby(obj/item/W, mob/user, list/modifiers)
/obj/structure/foamedmetal/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
///A speed modifier for how fast the wall is build
var/platingmodifier = 1
if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
+2 -2
View File
@@ -9,8 +9,8 @@
blocks_emissive = EMISSIVE_BLOCK_GENERIC
uses_integrity = FALSE
/obj/effect/attackby(obj/item/weapon, mob/user, list/modifiers)
if(SEND_SIGNAL(weapon, COMSIG_ITEM_ATTACK_EFFECT, src, user, modifiers) & COMPONENT_NO_AFTERATTACK)
/obj/effect/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
if(SEND_SIGNAL(weapon, COMSIG_ITEM_ATTACK_EFFECT, src, user, modifiers, attack_modifiers) & COMPONENT_NO_AFTERATTACK)
return TRUE
// I'm not sure why these are snowflaked to early return but they are
+1 -1
View File
@@ -69,7 +69,7 @@
/obj/effect/portal/newtonian_move(inertia_angle, instant = FALSE, start_delay = 0, drift_force = 0, controlled_cap = null)
return TRUE
/obj/effect/portal/attackby(obj/item/W, mob/user, list/modifiers)
/obj/effect/portal/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(user && Adjacent(user))
teleport(user)
return TRUE
@@ -23,7 +23,7 @@
demoraliser = new(src, 7, TRUE, mood_category)
return ..()
/obj/structure/sign/poster/traitor/attackby(obj/item/tool, mob/user, list/modifiers)
/obj/structure/sign/poster/traitor/attackby(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers)
if (tool.tool_behaviour == TOOL_WIRECUTTER)
QDEL_NULL(demoraliser)
return ..()
@@ -17,7 +17,7 @@
department_grab.quirk_poster_department = quirk_poster_department
/// You can use any spraypaint can on a quirk poster to turn it into a contraband poster from the traitor objective
/obj/item/poster/quirk/attackby(obj/item/postertool, mob/user, list/modifiers)
/obj/item/poster/quirk/attackby(obj/item/postertool, mob/user, list/modifiers, list/attack_modifiers)
if(!is_special_character(user) || !HAS_TRAIT(user, TRAIT_POSTERBOY) || !istype(postertool, /obj/item/toy/crayon))
return ..()
balloon_alert(user, "converting poster...")
@@ -50,7 +50,7 @@
mood_buff = new(_host = src, range = 7, _ignore_if_not_on_turf = TRUE, department = quirk_poster_department)
return ..()
/obj/structure/sign/poster/quirk/attackby(obj/item/I, mob/user, list/modifiers)
/obj/structure/sign/poster/quirk/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if (I.tool_behaviour == TOOL_WIRECUTTER)
QDEL_NULL(mood_buff)
return ..()
+2 -2
View File
@@ -53,7 +53,7 @@
name = "[name] - [poster_structure.original_name]"
/obj/item/poster/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/poster/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(!istype(I, /obj/item/shard))
return ..()
@@ -172,7 +172,7 @@
desc = holi_data.poster_desc
icon_state = holi_data.poster_icon
/obj/structure/sign/poster/attackby(obj/item/tool, mob/user, list/modifiers)
/obj/structure/sign/poster/attackby(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers)
if(tool.tool_behaviour == TOOL_WIRECUTTER)
tool.play_tool_sound(src, 100)
if(ruined)
@@ -589,7 +589,7 @@
playsound(loc, 'sound/items/weapons/egloves.ogg', vol = 80, vary = TRUE)
end()
/obj/effect/constructing_effect/attackby(obj/item/weapon, mob/user, list/modifiers)
/obj/effect/constructing_effect/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers)
attacked(user)
/obj/effect/constructing_effect/attack_hand(mob/living/user, list/modifiers)
+1 -1
View File
@@ -134,7 +134,7 @@
. += span_notice("Its ink levels look [ink_level].")
/obj/item/airlock_painter/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/airlock_painter/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(istype(W, /obj/item/toner))
if(ink)
to_chat(user, span_warning("[src] already contains \a [ink]!"))
+1 -1
View File
@@ -79,7 +79,7 @@
pushed_over = FALSE
tacticool = AddComponent(/datum/component/tactical)
/obj/item/cardboard_cutout/attackby(obj/item/I, mob/living/user, list/modifiers)
/obj/item/cardboard_cutout/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(I, /obj/item/toy/crayon))
change_appearance(I, user)
return TRUE
+1 -1
View File
@@ -87,7 +87,7 @@
myhead.dismember()
return BRUTELOSS
/obj/item/chainsaw/attack(mob/living/target_mob, mob/living/user, list/modifiers)
/obj/item/chainsaw/attack(mob/living/target_mob, mob/living/user, list/modifiers, list/attack_modifiers)
if (target_mob.stat != DEAD)
return ..()
+2 -2
View File
@@ -336,7 +336,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.visible_message(span_suicide("[user] is huffing [src] as quickly as [user.p_they()] can! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer."))
return (TOXLOSS|OXYLOSS)
/obj/item/cigarette/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/cigarette/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(lit)
return ..()
@@ -897,7 +897,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
STOP_PROCESSING(SSobj, src)
QDEL_NULL(cig_smoke)
/obj/item/cigarette/pipe/attackby(obj/item/thing, mob/user, list/modifiers)
/obj/item/cigarette/pipe/attackby(obj/item/thing, mob/user, list/modifiers, list/attack_modifiers)
if(!istype(thing, /obj/item/food/grown))
return ..()
+1 -1
View File
@@ -208,7 +208,7 @@
skinhead.set_hairstyle("Skinhead", update = TRUE)
playsound(loc, 'sound/items/tools/welder2.ogg', 20, TRUE)
/obj/item/razor/attack(mob/target_mob, mob/living/user, list/modifiers)
/obj/item/razor/attack(mob/target_mob, mob/living/user, list/modifiers, list/attack_modifiers)
if(!ishuman(target_mob))
return ..()
var/mob/living/carbon/human/human_target = target_mob
+1 -1
View File
@@ -34,7 +34,7 @@
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
/obj/item/gavelblock/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/gavelblock/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(istype(I, /obj/item/gavelhammer))
playsound(loc, 'sound/items/gavel.ogg', 100, TRUE)
user.visible_message(span_warning("[user] strikes [src] with [I]."))
+1 -1
View File
@@ -64,7 +64,7 @@
return FALSE
return TRUE
/obj/structure/checkoutmachine/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/structure/checkoutmachine/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(!canwalk)
balloon_alert(user, "not ready to accept transactions!")
return
+1 -1
View File
@@ -95,7 +95,7 @@
else
return 0
/obj/item/holochip/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/holochip/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
..()
if(istype(I, /obj/item/holochip))
var/obj/item/holochip/H = I
+1 -1
View File
@@ -437,7 +437,7 @@
forceMove(defib)
defib.update_power()
/obj/item/shockpaddles/attack(mob/M, mob/living/user, list/modifiers)
/obj/item/shockpaddles/attack(mob/M, mob/living/user, list/modifiers, list/attack_modifiers)
if(busy)
return
defib?.update_power()
@@ -95,7 +95,7 @@
max_capacity = 1000
w_class = WEIGHT_CLASS_NORMAL
/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/target, mob/living/user, list/modifiers)
/obj/item/computer_disk/syndie_ai_upgrade/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
var/mob/living/silicon/ai/AI
if(isAI(target))
AI = target
@@ -91,7 +91,7 @@
crystal_lens = null
return ITEM_INTERACT_SUCCESS
/obj/item/laser_pointer/attackby(obj/item/attack_item, mob/user, list/modifiers)
/obj/item/laser_pointer/attackby(obj/item/attack_item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(attack_item, /obj/item/stock_parts/micro_laser))
if(diode)
balloon_alert(user, "already has a diode!")
@@ -76,7 +76,7 @@
//replace lights & stuff
return do_action(interacting_with, user) ? ITEM_INTERACT_SUCCESS : NONE
/obj/item/lightreplacer/attackby(obj/item/insert, mob/user, list/modifiers)
/obj/item/lightreplacer/attackby(obj/item/insert, mob/user, list/modifiers, list/attack_modifiers)
. = ..()
if(uses >= max_uses)
user.balloon_alert(user, "already full!")
@@ -37,7 +37,7 @@
return
return ..()
/obj/item/electropack/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/electropack/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(istype(W, /obj/item/clothing/head/helmet))
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user)
A.icon = 'icons/obj/devices/assemblies.dmi'
@@ -468,7 +468,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
tool.play_tool_sound(src, 10)
return TRUE
/obj/item/radio/headset/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/radio/headset/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(istype(W, /obj/item/encryptionkey))
if(keyslot && keyslot2)
to_chat(user, span_warning("The headset can't hold another key!"))
+1 -1
View File
@@ -27,7 +27,7 @@
icon_state = "swapper[linked_swapper ? "-linked" : null]"
return ..()
/obj/item/swapper/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/swapper/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(istype(I, /obj/item/swapper))
var/obj/item/swapper/other_swapper = I
if(other_swapper.linked_swapper)
@@ -33,7 +33,7 @@
. += span_info("The current CST (local) time is: [station_time_timestamp()].")
. += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss", NO_TIMEZONE)].")
/obj/item/table_clock/attackby(obj/item/attacking_item, mob/user, list/modifiers)
/obj/item/table_clock/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
. = ..()
if(attacking_item.force < 5 || broken)
return
@@ -84,7 +84,7 @@
else
soundloop.start()
/obj/item/taperecorder/attackby(obj/item/I, mob/user, list/modifiers)
/obj/item/taperecorder/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(!mytape && istype(I, /obj/item/tape))
if(!user.transferItemToLoc(I,src))
return
@@ -441,7 +441,7 @@ effective or pretty fucking useless.
return TRUE
/obj/machinery/porta_turret/syndicate/toolbox/attackby(obj/item/attacking_item, mob/living/user, list/modifiers)
/obj/machinery/porta_turret/syndicate/toolbox/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
if(!istype(attacking_item, /obj/item/wrench/combat))
return ..()
+1 -1
View File
@@ -206,7 +206,7 @@
/obj/item/dualsaber/purple
possible_colors = list("purple")
/obj/item/dualsaber/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/dualsaber/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(W.tool_behaviour == TOOL_MULTITOOL)
if(!hacked)
hacked = TRUE
+1 -1
View File
@@ -8,7 +8,7 @@
/obj/item/dyespray/attack_self(mob/user)
dye(user, user)
/obj/item/dyespray/pre_attack(atom/target, mob/living/user, list/modifiers)
/obj/item/dyespray/pre_attack(atom/target, mob/living/user, list/modifiers, list/attack_modifiers)
dye(target, user)
return ..()
+2 -2
View File
@@ -187,7 +187,7 @@
else
return ..()
/obj/item/extinguisher/attack_atom(obj/O, mob/living/user, list/modifiers)
/obj/item/extinguisher/attack_atom(obj/O, mob/living/user, list/modifiers, list/attack_modifiers)
if(AttemptRefill(O, user))
refilling = TRUE
return FALSE
@@ -322,7 +322,7 @@
user.visible_message(span_notice("[user] empties out \the [src] onto the floor using the release valve."), span_info("You quietly empty out \the [src] using its release valve."))
//firebot assembly
/obj/item/extinguisher/attackby(obj/O, mob/user, list/modifiers)
/obj/item/extinguisher/attackby(obj/O, mob/user, list/modifiers, list/attack_modifiers)
if(istype(O, /obj/item/bodypart/arm/left/robot) || istype(O, /obj/item/bodypart/arm/right/robot))
to_chat(user, span_notice("You add [O] to [src]."))
qdel(O)
+1 -1
View File
@@ -64,7 +64,7 @@ GLOBAL_DATUM(bridge_axe, /obj/item/fireaxe)
user.visible_message(span_suicide("[user] axes [user.p_them()]self from head to toe! It looks like [user.p_theyre()] trying to commit suicide!"))
return BRUTELOSS
/obj/item/fireaxe/afterattack(atom/target, mob/user, list/modifiers)
/obj/item/fireaxe/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
if(!HAS_TRAIT(src, TRAIT_WIELDED)) //destroys windows and grilles in one hit
return
if(target.resistance_flags & INDESTRUCTIBLE)
+1 -1
View File
@@ -119,7 +119,7 @@
update_appearance()
return TRUE
/obj/item/flamethrower/attackby(obj/item/W, mob/user, list/modifiers)
/obj/item/flamethrower/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
if(isigniter(W))
var/obj/item/assembly/igniter/I = W
if(I.secured)
+2 -2
View File
@@ -88,7 +88,7 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0)
new /mob/living/basic/chick(spawn_turf)
GLOB.chicks_from_eggs++
/obj/item/food/egg/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/food/egg/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/toy/crayon))
var/obj/item/toy/crayon/crayon = item
var/clr = crayon.crayon_color
@@ -282,7 +282,7 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0)
. = ..()
AddElement(/datum/element/love_food_buff, /datum/status_effect/food/speech/french)
/obj/item/food/omelette/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/food/omelette/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/kitchen/fork))
var/obj/item/kitchen/fork/fork = item
if(fork.forkload)
+1 -1
View File
@@ -373,7 +373,7 @@
if (can_stick)
. += span_notice("If you had a rod you could make <b>butter on a stick</b>.")
/obj/item/food/butter/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/food/butter/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(!istype(item, /obj/item/stack/rods) || !can_stick)
return ..()
var/obj/item/stack/rods/rods = item
+2 -2
View File
@@ -30,7 +30,7 @@
positive_result = TRUE,\
use_large_steam_sprite = TRUE)
/obj/item/food/pancakes/raw/attackby(obj/item/garnish, mob/living/user, list/modifiers)
/obj/item/food/pancakes/raw/attackby(obj/item/garnish, mob/living/user, list/modifiers, list/attack_modifiers)
var/newresult
if(istype(garnish, /obj/item/food/grown/berries))
newresult = /obj/item/food/pancakes/blueberry
@@ -117,7 +117,7 @@
ingredients_listed += "[ING.name], "
. += "It contains [contents.len?"[ingredients_listed]":"no ingredient, "]on top of a [initial(name)]."
/obj/item/food/pancakes/attackby(obj/item/item, mob/living/user, list/modifiers)
/obj/item/food/pancakes/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/food/pancakes))
var/obj/item/food/pancakes/pancake = item
if((contents.len >= PANCAKE_MAX_STACK) || ((pancake.contents.len + contents.len) > PANCAKE_MAX_STACK))
+2 -4
View File
@@ -14,7 +14,7 @@
/obj/item/sparkler/fire_act(exposed_temperature, exposed_volume)
light()
/obj/item/sparkler/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/sparkler/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
var/ignition_msg = item.ignition_effect(src, user)
if(ignition_msg)
light(user, ignition_msg)
@@ -75,7 +75,7 @@
/obj/item/grenade/firecracker/attack_self(mob/user) // You need to light it manually.
return
/obj/item/grenade/firecracker/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/grenade/firecracker/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
var/ignition_msg = item.ignition_effect(src, user)
if(ignition_msg && !active)
visible_message(ignition_msg)
@@ -117,5 +117,3 @@
update_mob()
explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2)
qdel(src)
@@ -217,7 +217,7 @@
else
. += span_notice("The wires are just dangling from it, you need some sort of <i> activating assembly</i>.")
/obj/item/sliced_pipe/attackby(obj/item/item, mob/user, list/modifiers)
/obj/item/sliced_pipe/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(!wires_are_in)
// here we can stuff in additional objects for a cooler effect
if(is_type_in_typecache(item, allowed) && contents.len < MAX_STUFFINGS)

Some files were not shown because too many files have changed in this diff Show More