mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
[MIRROR] Standardizes attack chain signal returns and fixes a tk bug (#1409)
* Standardizes attack chain signal returns and fixes a tk bug (#54475) The attack chain is a bit of a mess, and the introduction of signals hasn't helped in simplifying it. In order to take a step into untangling this, I re-ordered the attack signals to no longer be by source type and instead to be grouped more modularly, as they are all members of the attack chain and function similarly. They all share the trait of potentially ending the attack chain via a return, but had several different names for it. I joined it into one. Additionally, fixed a tk bug reported by @ Timberpoes by adding a signal return check at the base of /mob/proc/RangedAttack Lastly, removed the async call of /datum/mutation/human/telekinesis/proc/on_ranged_attack, which was added as a lazy patch to appease the linter complaining about a sleep on a signal handler (namely in /obj/singularity/attack_tk). Fixed the problem using timers. Also cleaned some code here and there. * Standardizes attack chain signal returns and fixes a tk bug Co-authored-by: Rohesie <rohesie@gmail.com>
This commit is contained in:
@@ -149,14 +149,6 @@
|
||||
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
|
||||
///called when an atom stops orbiting another atom: (atom)
|
||||
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
|
||||
/////////////////
|
||||
///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"
|
||||
#define COMPONENT_NO_ATTACK_HAND (1<<0) //works on all 3.
|
||||
///from base of atom/set_opacity(): (new_opacity)
|
||||
#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity"
|
||||
|
||||
@@ -327,19 +319,9 @@
|
||||
#define COMPONENT_BLOCK_MAGIC (1<<0)
|
||||
///from base of mob/create_mob_hud(): ()
|
||||
#define COMSIG_MOB_HUD_CREATED "mob_hud_created"
|
||||
///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"
|
||||
#define COMPONENT_ITEM_NO_ATTACK (1<<0)
|
||||
|
||||
///from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
|
||||
#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage"
|
||||
///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 base of /mob/throw_item(): (atom/target)
|
||||
#define COMSIG_MOB_THROW "mob_throw"
|
||||
///from base of /mob/verb/examinate(): (atom/target)
|
||||
@@ -494,21 +476,6 @@
|
||||
|
||||
// /obj/item signals
|
||||
|
||||
///from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
|
||||
#define COMSIG_ITEM_ATTACK "item_attack"
|
||||
///from base of obj/item/attack_self(): (/mob)
|
||||
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self"
|
||||
#define COMPONENT_NO_INTERACT (1<<0)
|
||||
///from base of obj/item/attack_obj(): (/obj, /mob)
|
||||
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj"
|
||||
#define COMPONENT_NO_ATTACK_OBJ (1<<0)
|
||||
///from base of obj/item/pre_attack(): (atom/target, mob/user, params)
|
||||
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack"
|
||||
#define COMPONENT_NO_ATTACK (1<<0)
|
||||
///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"
|
||||
///from base of obj/item/equipped(): (/mob/equipper, slot)
|
||||
#define COMSIG_ITEM_EQUIPPED "item_equip"
|
||||
///from base of obj/item/dropped(): (mob/user)
|
||||
@@ -649,12 +616,6 @@
|
||||
|
||||
// /mob/living/carbon/human signals
|
||||
|
||||
///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"
|
||||
///from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby"
|
||||
///Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
|
||||
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
|
||||
///Whenever EquipRanked is called, called after job is set
|
||||
@@ -840,3 +801,38 @@
|
||||
// /datum/component/container_item
|
||||
/// (atom/container, mob/user) - returns bool
|
||||
#define COMSIG_CONTAINER_TRY_ATTACH "container_try_attach"
|
||||
|
||||
/* Attack signals. They should share the returned flags, to standardize the attack chain. */
|
||||
#define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0)
|
||||
///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"
|
||||
///from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
|
||||
#define COMSIG_ITEM_ATTACK "item_attack"
|
||||
///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"
|
||||
///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"
|
||||
|
||||
@@ -277,7 +277,8 @@
|
||||
* animals lunging, etc.
|
||||
*/
|
||||
/mob/proc/RangedAttack(atom/A, params)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params)
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/// 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)
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK_SELF, src) //SKYRAT EDIT ADDITION - GUNPOINT
|
||||
interact(user)
|
||||
@@ -37,7 +37,7 @@
|
||||
* 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)
|
||||
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
|
||||
|
||||
@@ -73,21 +73,21 @@
|
||||
* * 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)
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
|
||||
if(item_flags & NOBLUDGEON)
|
||||
return
|
||||
|
||||
if(force && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(item_flags & EYE_STAB && user.zone_selected == BODY_ZONE_PRECISE_EYES)
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
M = user
|
||||
if(eyestab(M,user))
|
||||
return
|
||||
return TRUE
|
||||
if(!force)
|
||||
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), TRUE, -1)
|
||||
else if(hitsound)
|
||||
@@ -104,11 +104,12 @@
|
||||
|
||||
log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
|
||||
|
||||
/// 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
|
||||
|
||||
@@ -48,7 +48,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))
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
if(proximity && istype(G) && G.Touch(A,1))
|
||||
return
|
||||
//This signal is needed to prevent gloves of the north star + hulk.
|
||||
if(SEND_SIGNAL(src, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, A, proximity) & COMPONENT_NO_ATTACK_HAND)
|
||||
if(SEND_SIGNAL(src, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, A, proximity) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A, proximity)
|
||||
A.attack_hand(src)
|
||||
@@ -35,7 +35,7 @@
|
||||
. = 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)
|
||||
@@ -82,14 +82,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
|
||||
@@ -135,7 +137,7 @@
|
||||
|
||||
|
||||
/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
|
||||
|
||||
|
||||
@@ -4,57 +4,74 @@
|
||||
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
|
||||
attack_tk_grab(user)
|
||||
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
|
||||
|
||||
|
||||
/*
|
||||
@@ -112,44 +129,53 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/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
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -198,7 +198,8 @@
|
||||
to_chat(user, "<span class='warning'>The acid on \the [parent_atom] burns your hand!</span>")
|
||||
playsound(parent_atom, 'sound/weapons/sear.ogg', 50, TRUE)
|
||||
user.update_damage_overlays()
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/// Handles searing the feet of whoever walks over this without protection. Only active if the parent is a turf.
|
||||
/datum/component/acid/proc/on_crossed(atom/parent_atom, mob/living/crosser)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
if(M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it?
|
||||
if(butchering_enabled && (can_be_blunt || source.get_sharpness()))
|
||||
INVOKE_ASYNC(src, .proc/startButcher, source, M, user)
|
||||
return COMPONENT_ITEM_NO_ATTACK
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
if(ishuman(M) && source.force && source.get_sharpness())
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -38,9 +38,9 @@
|
||||
if(H.has_status_effect(/datum/status_effect/neck_slice))
|
||||
user.show_message("<span class='warning'>[H]'s neck has already been already cut, you can't make the bleeding any worse!</span>", MSG_VISUAL, \
|
||||
"<span class='warning'>Their neck has already been already cut, you can't make the bleeding any worse!</span>")
|
||||
return COMPONENT_ITEM_NO_ATTACK
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
INVOKE_ASYNC(src, .proc/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, "<span class='notice'>You begin to butcher [M]...</span>")
|
||||
|
||||
@@ -276,7 +276,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
return
|
||||
var/fullness = eater.get_fullness() + 10 //The theoretical fullness of the person eating if they were to eat this
|
||||
|
||||
. = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN //Point of no return I suppose
|
||||
|
||||
if(eater == feeder)//If you're eating it yourself.
|
||||
if(!do_mob(feeder, eater, eat_time)) //Gotta pass the minimal eat time
|
||||
@@ -416,7 +416,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
if(bitecount == 0 || prob(50))
|
||||
L.manual_emote("nibbles away at \the [parent].")
|
||||
bitecount++
|
||||
. = COMPONENT_ITEM_NO_ATTACK
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
L.taste(owner.reagents) // why should carbons get all the fun?
|
||||
if(bitecount >= 5)
|
||||
var/satisfaction_text = pick("burps from enjoyment.", "yaps for more!", "woofs twice.", "looks at the area where \the [parent] was.")
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"<span class='notice'>You start to insert the [inserted_item.name] into \the [parent].</span>")
|
||||
|
||||
INVOKE_ASYNC(src, .proc/insert_item, inserted_item, user)
|
||||
return COMPONENT_ITEM_NO_ATTACK
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/** Begins the process of attempting to remove the stored item.
|
||||
*
|
||||
@@ -93,7 +93,7 @@
|
||||
"<span class='notice'>You start to rip into \the [parent].</span>")
|
||||
|
||||
INVOKE_ASYNC(src, .proc/begin_remove_item, user)
|
||||
return COMPONENT_ITEM_NO_ATTACK
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/** Inserts the item into the food, after a do_after.
|
||||
*
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
|
||||
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
|
||||
return FALSE
|
||||
. = COMPONENT_NO_ATTACK
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(locked)
|
||||
to_chat(M, "<span class='warning'>[parent] seems to be locked!</span>")
|
||||
return FALSE
|
||||
@@ -771,6 +771,7 @@
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
|
||||
SIGNAL_HANDLER_DOES_SLEEP
|
||||
|
||||
@@ -780,7 +781,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)
|
||||
@@ -789,23 +790,24 @@
|
||||
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
|
||||
H.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
|
||||
H.put_in_hands(A)
|
||||
H.r_store = null
|
||||
return
|
||||
|
||||
if(A.loc == user)
|
||||
. = COMPONENT_NO_ATTACK_HAND
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>[parent] seems to be locked!</span>")
|
||||
else
|
||||
show_to(user)
|
||||
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
var/mob/living/carbon/carbontarget
|
||||
var/obj/item/bodypart/affecting
|
||||
var/selected_zone = user.zone_selected
|
||||
. = COMPONENT_ITEM_NO_ATTACK
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
if(iscarbon(livingtarget))
|
||||
carbontarget = livingtarget
|
||||
|
||||
@@ -84,12 +84,12 @@ This component is used in vat growing to swab for microbiological samples which
|
||||
var/obj/item/I = parent
|
||||
I.update_icon()
|
||||
|
||||
return COMPONENT_NO_ATTACK
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(!can_swab(target))
|
||||
return NONE //Just do the normal attack.
|
||||
|
||||
|
||||
. = COMPONENT_NO_ATTACK //Point of no return. No more attacking after this.
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN //Point of no return. No more attacking after this.
|
||||
|
||||
if(LAZYLEN(swabbed_items))
|
||||
to_chat(user, "<span class='warning'>You cannot collect another sample on [parent]!</span>")
|
||||
|
||||
@@ -122,7 +122,8 @@
|
||||
if(user)
|
||||
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)
|
||||
return GLOB.inventory_state
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
source.do_attack_animation(target, ATTACK_EFFECT_SMASH)
|
||||
source.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
return visual_indicators[type][1]
|
||||
|
||||
///Triggers on COMSIG_MOB_ATTACK_RANGED. Usually handles stuff like picking up items at range.
|
||||
/datum/mutation/human/telekinesis/proc/on_ranged_attack(datum/source, atom/target)
|
||||
/datum/mutation/human/telekinesis/proc/on_ranged_attack(mob/source, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
INVOKE_ASYNC(target, /atom.proc/attack_tk, owner)
|
||||
return target.attack_tk(source)
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
INVOKE_ASYNC(victim, /mob.proc/emote, "scream")
|
||||
victim.Stun(0.5 SECONDS)
|
||||
limb.receive_damage(brute=rand(3,7))
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/datum/wound/blunt/receive_damage(wounding_type, wounding_dmg, wound_bonus)
|
||||
if(!victim || wounding_dmg < WOUND_MINIMUM_DAMAGE)
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
|
||||
removecell()
|
||||
|
||||
|
||||
/obj/machinery/cell_charger/attack_tk(mob/user)
|
||||
if(!charging)
|
||||
return
|
||||
@@ -101,6 +102,8 @@
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove [charging] from [src].</span>")
|
||||
|
||||
removecell()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/machinery/cell_charger/attack_ai(mob/user)
|
||||
return
|
||||
|
||||
@@ -177,10 +177,12 @@
|
||||
return
|
||||
return try_to_activate_door(user)
|
||||
|
||||
|
||||
/obj/machinery/door/attack_tk(mob/user)
|
||||
if(requiresID() && !allowed(null))
|
||||
return
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/door/proc/try_to_activate_door(mob/user)
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -113,11 +113,15 @@
|
||||
user.put_in_hands(charging)
|
||||
setCharging(null)
|
||||
|
||||
|
||||
/obj/machinery/recharger/attack_tk(mob/user)
|
||||
if(charging)
|
||||
charging.update_icon()
|
||||
charging.forceMove(drop_location())
|
||||
setCharging(null)
|
||||
if(!charging)
|
||||
return
|
||||
charging.update_icon()
|
||||
charging.forceMove(drop_location())
|
||||
setCharging(null)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/machinery/recharger/process(delta_time)
|
||||
if(machine_stat & (NOPOWER|BROKEN) || !anchored)
|
||||
|
||||
@@ -192,9 +192,11 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
return attack_self(M)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/pda/attack_self_tk(mob/user)
|
||||
to_chat(user, "<span class='warning'>The PDA's capacitive touch screen doesn't seem to respond!</span>")
|
||||
return
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/item/pda/interact(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
*/
|
||||
/obj/item/radio/intercom/attack_tk_grab(mob/user)
|
||||
interact(user)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/item/radio/intercom/attack_ai(mob/user)
|
||||
interact(user)
|
||||
|
||||
@@ -124,8 +124,10 @@
|
||||
inhand_icon_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
|
||||
|
||||
@@ -193,6 +193,8 @@
|
||||
timer = world.time + cooldown
|
||||
if(!quiet)
|
||||
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/**
|
||||
* Resets the request for battle.
|
||||
|
||||
@@ -89,11 +89,13 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/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()
|
||||
|
||||
@@ -393,8 +393,9 @@ LINEN BINS
|
||||
to_chat(user, "<span class='notice'>[hidden] falls out of [B]!</span>")
|
||||
hidden = null
|
||||
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
/obj/structure/bedsheetbin/attack_tk(mob/user)
|
||||
if(amount >= 1)
|
||||
amount--
|
||||
@@ -415,5 +416,5 @@ LINEN BINS
|
||||
hidden.forceMove(drop_location())
|
||||
hidden = null
|
||||
|
||||
|
||||
add_fingerprint(user)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
@@ -374,7 +374,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)
|
||||
|
||||
@@ -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, "<span class='notice'>You telekinetically remove [stored_extinguisher] from [src].</span>")
|
||||
stored_extinguisher = null
|
||||
opened = 1
|
||||
opened = TRUE
|
||||
playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3)
|
||||
update_icon()
|
||||
else
|
||||
toggle_cabinet(user)
|
||||
return
|
||||
toggle_cabinet(user)
|
||||
|
||||
|
||||
/obj/structure/extinguisher_cabinet/attack_paw(mob/user)
|
||||
|
||||
@@ -131,14 +131,15 @@
|
||||
toggle_lock(user)
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/fireaxecabinet/attack_tk(mob/user)
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The [name] won't budge!</span>")
|
||||
return
|
||||
else
|
||||
open = !open
|
||||
update_icon()
|
||||
return
|
||||
open = !open
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/structure/fireaxecabinet/update_overlays()
|
||||
. = ..()
|
||||
|
||||
@@ -88,8 +88,10 @@
|
||||
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, turf/target)
|
||||
. = ..()
|
||||
|
||||
@@ -130,11 +130,14 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/window/attack_tk(mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.visible_message("<span class='notice'>Something knocks on [src].</span>")
|
||||
add_fingerprint(user)
|
||||
playsound(src, knocksound, 50, TRUE)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/structure/window/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(!can_be_reached(user))
|
||||
|
||||
@@ -223,26 +223,29 @@
|
||||
else
|
||||
to_chat(human_user,"<span class='danger'>You pull your hand away from the hole as the eldritch energy flails trying to catch onto the existance itself!</span>")
|
||||
|
||||
|
||||
/obj/effect/broken_illusion/attack_tk(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
if(IS_HERETIC(human_user))
|
||||
to_chat(human_user,"<span class='boldwarning'>You know better than to tempt forces out of your control!</span>")
|
||||
return
|
||||
//a very elaborate way to suicide
|
||||
to_chat(human_user,"<span class='userdanger'>Eldritch energy lashes out, piercing your fragile mind, tearing it to pieces!</span>")
|
||||
human_user.ghostize()
|
||||
var/obj/item/bodypart/head/head = locate() in human_user.bodyparts
|
||||
if(head)
|
||||
head.dismember()
|
||||
qdel(head)
|
||||
else
|
||||
//a very elaborate way to suicide
|
||||
to_chat(human_user,"<span class='userdanger'>Eldritch energy lashes out, piercing your fragile mind, tearing it to pieces!</span>")
|
||||
human_user.ghostize()
|
||||
var/obj/item/bodypart/head/head = locate() in human_user.bodyparts
|
||||
if(head)
|
||||
head.dismember()
|
||||
qdel(head)
|
||||
else
|
||||
human_user.gib()
|
||||
human_user.gib()
|
||||
|
||||
var/datum/effect_system/reagents_explosion/explosion = new()
|
||||
explosion.set_up(1, get_turf(human_user), TRUE, 0)
|
||||
explosion.start()
|
||||
|
||||
var/datum/effect_system/reagents_explosion/explosion = new()
|
||||
explosion.set_up(1, get_turf(human_user), 1, 0)
|
||||
explosion.start()
|
||||
|
||||
/obj/effect/broken_illusion/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -119,17 +119,21 @@
|
||||
eat()
|
||||
return
|
||||
|
||||
|
||||
/obj/singularity/wizard/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, "<span class='userdanger'>OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!</span>")
|
||||
insaneinthemembrane.sanity = 0
|
||||
for(var/lore in typesof(/datum/brain_trauma/severe))
|
||||
C.gain_trauma(lore)
|
||||
addtimer(CALLBACK(src, /obj/singularity/wizard.proc/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, "<span class='userdanger'>OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!</span>")
|
||||
insaneinthemembrane.sanity = 0
|
||||
for(var/lore in typesof(/datum/brain_trauma/severe))
|
||||
jedi.gain_trauma(lore)
|
||||
addtimer(CALLBACK(src, /obj/singularity/wizard.proc/deranged, jedi), 10 SECONDS)
|
||||
|
||||
|
||||
/obj/singularity/wizard/proc/deranged(mob/living/carbon/C)
|
||||
if(!C || C.stat == DEAD)
|
||||
|
||||
@@ -685,10 +685,10 @@
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_BUMP)
|
||||
|
||||
/obj/item/clothing/gloves/gauntlets/proc/rocksmash(mob/living/carbon/human/H, atom/A, proximity)
|
||||
if(!istype(A, /turf/closed/mineral))
|
||||
return
|
||||
A.attackby(src, H)
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
if(!istype(A, /turf/closed/mineral))
|
||||
return
|
||||
A.attackby(src, H)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
///Bosses
|
||||
|
||||
@@ -62,7 +62,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")
|
||||
|
||||
@@ -504,12 +504,12 @@
|
||||
A.attack_animal(src)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/RangedAttack(atom/A, params) //Player firing
|
||||
if(ranged && ranged_cooldown <= world.time)
|
||||
target = A
|
||||
OpenFire(A)
|
||||
..()
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
////// AI Status ///////
|
||||
|
||||
@@ -79,13 +79,15 @@
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
|
||||
|
||||
|
||||
/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)
|
||||
@@ -96,6 +98,7 @@
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You find nothing in [src].</span>")
|
||||
|
||||
|
||||
/obj/structure/filingcabinet/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr)))
|
||||
return
|
||||
|
||||
@@ -94,12 +94,16 @@
|
||||
cell = null
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
/obj/structure/light_construct/attack_tk(mob/user)
|
||||
if(cell)
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove [cell].</span>")
|
||||
cell.forceMove(drop_location())
|
||||
cell.attack_tk(user)
|
||||
cell = null
|
||||
if(!cell)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove [cell].</span>")
|
||||
var/obj/item/stock_parts/cell/cell_reference = cell
|
||||
cell = null
|
||||
cell_reference.forceMove(drop_location())
|
||||
return cell_reference.attack_tk(user)
|
||||
|
||||
|
||||
/obj/structure/light_construct/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
@@ -730,8 +734,8 @@
|
||||
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove the light [fitting].</span>")
|
||||
// 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
|
||||
|
||||
@@ -39,10 +39,13 @@
|
||||
message_admins("A BoH tear has been created at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("was created at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
|
||||
/obj/singularity/boh_tear/attack_tk(mob/living/user)
|
||||
if(!istype(user))
|
||||
|
||||
/obj/singularity/boh_tear/attack_tk(mob/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
to_chat(user, "<span class='userdanger'>You don't feel like you are real anymore.</span>")
|
||||
user.dust_animation()
|
||||
user.spawn_dust()
|
||||
addtimer(CALLBACK(src, .proc/consume, user), 5)
|
||||
var/mob/living/jedi = user
|
||||
to_chat(jedi, "<span class='userdanger'>You don't feel like you are real anymore.</span>")
|
||||
jedi.dust_animation()
|
||||
jedi.spawn_dust()
|
||||
addtimer(CALLBACK(src, .proc/consume, jedi), 0.5 SECONDS)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
@@ -95,19 +95,61 @@
|
||||
/obj/singularity/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
|
||||
/obj/singularity/attack_tk(mob/user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='danger'>[C]'s head begins to collapse in on itself!</span>", "<span class='userdanger'>Your head feels like it's collapsing in on itself! This was really not a good idea!</span>", "<span class='hear'>You hear something crack and explode in gore.</span>")
|
||||
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(
|
||||
"<span class='danger'>[jedi]'s head begins to collapse in on itself!</span>",
|
||||
"<span class='userdanger'>Your head feels like it's collapsing in on itself! This was really not a good idea!</span>",
|
||||
"<span class='hear'>You hear something crack and explode in gore.</span>"
|
||||
)
|
||||
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(GLOBAL_PROC, .proc/carbon_tk_part_two, jedi), 0.1 SECONDS)
|
||||
|
||||
|
||||
/obj/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(GLOBAL_PROC, .proc/carbon_tk_part_three, jedi), 0.1 SECONDS)
|
||||
|
||||
|
||||
/obj/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/singularity/ex_act(severity, target)
|
||||
switch(severity)
|
||||
|
||||
@@ -850,14 +850,19 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
"<span class='hear'>You hear a loud crack as you are washed with a wave of heat.</span>")
|
||||
Consume(B)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/attack_tk(mob/user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
to_chat(C, "<span class='userdanger'>That was a really dense idea.</span>")
|
||||
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, "<span class='userdanger'>That was a really dense idea.</span>")
|
||||
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")
|
||||
|
||||
@@ -145,14 +145,19 @@
|
||||
/obj/singularity/energy_ball/Bumped(atom/movable/AM)
|
||||
dust_mobs(AM)
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/attack_tk(mob/user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
to_chat(C, "<span class='userdanger'>That was a shockingly dumb idea.</span>")
|
||||
var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs
|
||||
C.ghostize(0)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
var/mob/living/carbon/jedi = user
|
||||
to_chat(jedi, "<span class='userdanger'>That was a shockingly dumb idea.</span>")
|
||||
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.death()
|
||||
jedi.death()
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target)
|
||||
if (istype(target))
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
new /obj/effect/decal/cleanable/wrapping(get_turf(user))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/small_delivery/attack_self_tk(mob/user)
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
@@ -214,6 +215,8 @@
|
||||
new /obj/effect/decal/cleanable/wrapping(get_turf(user))
|
||||
unwrap_contents()
|
||||
qdel(src)
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/item/small_delivery/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -27,5 +27,4 @@
|
||||
/obj/item/clothing/gloves/butchering/proc/butcher_target(mob/user, atom/target, proximity)
|
||||
if(!isliving(target))
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, target, user) & COMPONENT_ITEM_NO_ATTACK)
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
return SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, target, user)
|
||||
|
||||
@@ -46,7 +46,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
|
||||
/obj/item/hilbertshotel/attack_tk(mob/user)
|
||||
to_chat(user, "<span class='notice'>\The [src] actively rejects your mind as the bluespace energies surrounding it disrupt your telekinesis.</span>")
|
||||
return
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user, mob/target)
|
||||
var/chosenRoomNumber
|
||||
|
||||
Reference in New Issue
Block a user