[MIRROR] Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking (#430)

* Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking (#52761)

Adds SIGNAL_HANDLER, a macro that sets SHOULD_NOT_SLEEP(TRUE). This should ideally be required on all new signal callbacks.

Adds BLOCKING_SIGNAL_HANDLER, a macro that does nothing except symbolize "this is an older signal that didn't necessitate a code rewrite". It should not be allowed for new work.

This comes from discussion around #52735, which yields by calling input, and (though it sets the return type beforehand) will not properly return the flag to prevent attack from slapping.

To fix 60% of the yielding cases, WrapAdminProcCall no longer waits for another admin's proc call to finish. I'm not an admin, so I don't know how many behinds this has saved, but if this is problematic for admins I can just make it so that it lets you do it anyway. I'm not sure what the point of this babysitting was anyway.

Requested by @optimumtact.
Changelog

cl
admin: Calling a proc while another admin is calling one will no longer wait for the first to finish. You will simply just have to call it again.
/cl

* Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking

Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
This commit is contained in:
SkyratBot
2020-08-19 20:17:28 -04:00
committed by GitHub
co-authored by Jared-Fogle
parent d129e6973c
commit e65a48e91f
166 changed files with 906 additions and 20 deletions
+6
View File
@@ -29,15 +29,21 @@
expire = _expire
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
SIGNAL_HANDLER
if(!(allowed_slots & slot)) //Check that the slot is valid for antimagic
UnregisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC)
return
RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/protect, TRUE)
/datum/component/anti_magic/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
UnregisterSignal(user, COMSIG_MOB_RECEIVE_MAGIC)
/datum/component/anti_magic/proc/protect(datum/source, mob/user, _magic, _holy, _psychic, chargecost, self, list/protection_sources)
SIGNAL_HANDLER
if(((_magic && magic) || (_holy && holy) || (_psychic && psychic)) && (!self || blocks_self))
protection_sources += parent
reaction?.Invoke(user, chargecost)
+6
View File
@@ -26,6 +26,8 @@
_archdrops[I] += other_archdrops[I]
/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER
if(dug)
to_chat(user, "<span class='warning'>Looks like someone has dug here already!</span>")
return
@@ -73,6 +75,8 @@
callback.Invoke()
/datum/component/archaeology/proc/SingDig(datum/source, S, current_size)
SIGNAL_HANDLER
switch(current_size)
if(STAGE_THREE)
if(prob(30))
@@ -85,6 +89,8 @@
gets_dug()
/datum/component/archaeology/proc/BombDig(datum/source, severity, target)
SIGNAL_HANDLER
switch(severity)
if(3)
return
+8
View File
@@ -32,6 +32,8 @@
upgrade_name = initial(typecast.name)
/datum/component/armor_plate/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
//upgrade_item could also be typecast here instead
if(ismecha(parent))
if(amount)
@@ -48,6 +50,8 @@
examine_list += "<span class='notice'>It can be strengthened with up to [maxamount] [upgrade_name].</span>"
/datum/component/armor_plate/proc/applyplate(datum/source, obj/item/I, mob/user, params)
SIGNAL_HANDLER
if(!istype(I,upgrade_item))
return
if(amount >= maxamount)
@@ -75,11 +79,15 @@
/datum/component/armor_plate/proc/dropplates(datum/source, force)
SIGNAL_HANDLER
if(ismecha(parent)) //items didn't drop the plates before and it causes erroneous behavior for the time being with collapsible helmets
for(var/i in 1 to amount)
new upgrade_item(get_turf(parent))
/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays)
SIGNAL_HANDLER
if(amount)
var/overlay_string = "ripley-g"
if(amount >= 3)
+8
View File
@@ -13,6 +13,8 @@
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet)
/datum/component/art/proc/apply_moodlet(mob/M, impress)
SIGNAL_HANDLER
M.visible_message("<span class='notice'>[M] stops and looks intently at [parent].</span>", \
"<span class='notice'>You stop to take in [parent].</span>")
switch(impress)
@@ -27,13 +29,19 @@
/datum/component/art/proc/on_other_examine(datum/source, mob/M)
SIGNAL_HANDLER
apply_moodlet(M, impressiveness)
/datum/component/art/proc/on_obj_examine(datum/source, mob/M)
SIGNAL_HANDLER
var/obj/O = parent
apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity))
/datum/component/art/proc/on_attack_hand(datum/source, mob/M)
SIGNAL_HANDLER_DOES_SLEEP
to_chat(M, "<span class='notice'>You start examining [parent]...</span>")
if(!do_after(M, 20, target = parent))
return
+4
View File
@@ -28,11 +28,15 @@
UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
/datum/component/bane/proc/speciesCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag || !is_species(target, speciestype))
return
activate(source, target, user)
/datum/component/bane/proc/mobCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag || !istype(target, mobtype))
return
activate(source, target, user)
+4
View File
@@ -16,12 +16,16 @@
enter_area(null, A)
/datum/component/beauty/proc/enter_area(datum/source, area/A)
SIGNAL_HANDLER
if(A.outdoors)
return
A.totalbeauty += beauty
A.update_beauty()
/datum/component/beauty/proc/exit_area(datum/source, area/A)
SIGNAL_HANDLER
if(A.outdoors)
return
A.totalbeauty -= beauty
+2
View File
@@ -34,6 +34,8 @@
update_regex()
/datum/component/beetlejuice/proc/say_react(datum/source, mob/speaker,message)
SIGNAL_HANDLER
if(!speaker || speaker == parent || !message || !active)
return
var/found = R.Find(message)
+4
View File
@@ -23,6 +23,8 @@
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/onItemAttack)
/datum/component/butchering/proc/onItemAttack(obj/item/source, mob/living/M, mob/living/user)
SIGNAL_HANDLER
if(user.a_intent != INTENT_HARM)
return
if(M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it?
@@ -122,6 +124,8 @@
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/onCrossed)
/datum/component/butchering/recycler/proc/onCrossed(datum/source, mob/living/L)
SIGNAL_HANDLER
if(!istype(L))
return
var/obj/machinery/recycler/eater = parent
+2
View File
@@ -15,6 +15,8 @@
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM)
SIGNAL_HANDLER
if(!prob(probability))
return
+2
View File
@@ -29,6 +29,8 @@
START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
/datum/component/chasm/proc/Entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
START_PROCESSING(SSobj, src)
drop_stuff(AM)
+4
View File
@@ -20,6 +20,8 @@
update_parent(index)
/datum/component/construction/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
if(desc)
examine_list += desc
@@ -30,6 +32,8 @@
update_parent(index)
/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER_DOES_SLEEP
return check_step(I, user)
/datum/component/construction/proc/update_index(diff)
@@ -3,6 +3,8 @@
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button)
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
SIGNAL_HANDLER
var/datum/hud/H = user.hud_used
var/obj/screen/craft/C = new()
C.icon = H.ui_style
@@ -312,6 +314,8 @@
qdel(DL)
/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user)
SIGNAL_HANDLER_DOES_SLEEP
if(user == parent)
ui_interact(user)
@@ -31,6 +31,8 @@
return ..()
/datum/component/deadchat_control/proc/deadchat_react(mob/source, message)
SIGNAL_HANDLER
message = lowertext(message)
if(!inputs[message])
return
@@ -97,10 +99,14 @@
deltimer(timerid)
/datum/component/deadchat_control/proc/orbit_begin(atom/source, atom/orbiter)
SIGNAL_HANDLER
RegisterSignal(orbiter, COMSIG_MOB_DEADSAY, .proc/deadchat_react)
orbiters |= orbiter
/datum/component/deadchat_control/proc/orbit_stop(atom/source, atom/orbiter)
SIGNAL_HANDLER
if(orbiter in orbiters)
UnregisterSignal(orbiter, COMSIG_MOB_DEADSAY)
orbiters -= orbiter
+10
View File
@@ -59,11 +59,15 @@
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/component/decal/proc/late_update_icon(atom/source)
SIGNAL_HANDLER
if(source && istype(source))
source.update_icon()
UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE)
/datum/component/decal/proc/apply_overlay(atom/source, list/overlay_list)
SIGNAL_HANDLER
overlay_list += pic
/datum/component/decal/proc/remove(atom/thing)
@@ -74,6 +78,8 @@
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
SIGNAL_HANDLER
if(old_dir == new_dir)
return
remove()
@@ -81,9 +87,13 @@
apply()
/datum/component/decal/proc/clean_react(datum/source, clean_types)
SIGNAL_HANDLER
if(clean_types & cleanable)
qdel(src)
return TRUE
/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
examine_list += description
+2
View File
@@ -33,6 +33,8 @@
return TRUE
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
SIGNAL_HANDLER
var/atom/A = parent
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
+9
View File
@@ -66,6 +66,8 @@ Behavior that's still missing from this component that original food items had t
owner.reagents.add_reagent(rid, amount)
/datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
if(!(food_flags & FOOD_IN_CONTAINER))
switch (bitecount)
if (0)
@@ -78,9 +80,13 @@ Behavior that's still missing from this component that original food items had t
examine_list += "[parent] was bitten multiple times!"
/datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user)
SIGNAL_HANDLER
return TryToEat(M, user)
/datum/component/edible/proc/TryToEatTurf(datum/source, mob/user)
SIGNAL_HANDLER
return TryToEat(user, user)
///All the checks for the act of eating itself and
@@ -230,6 +236,9 @@ Behavior that's still missing from this component that original food items had t
///Ability to feed food to puppers
/datum/component/edible/proc/UseByAnimal(datum/source, mob/user)
SIGNAL_HANDLER
var/atom/owner = parent
if(!isdog(user))
@@ -19,5 +19,7 @@
RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments)
SIGNAL_HANDLER
var/atom/movable/master = parent
master.say(pick(say_lines))
+8
View File
@@ -157,6 +157,8 @@
/// Called every time a carbon with a harmful embed moves, rolling a chance for the item to cause pain. The chance is halved if the carbon is crawling or walking.
/datum/component/embedded/proc/jostleCheck()
SIGNAL_HANDLER
var/mob/living/carbon/victim = parent
var/chance = jostle_chance
if(victim.m_intent == MOVE_INTENT_WALK || !(victim.mobility_flags & MOBILITY_STAND))
@@ -182,6 +184,8 @@
/// Called when a carbon with an object embedded/stuck to them inspects themselves and clicks the appropriate link to begin ripping the item out. This handles the ripping attempt, descriptors, and dealing damage, then calls safe_remove()
/datum/component/embedded/proc/ripOut(datum/source, obj/item/I, obj/item/bodypart/limb)
SIGNAL_HANDLER_DOES_SLEEP
if(I != weapon || src.limb != limb)
return
var/mob/living/carbon/victim = parent
@@ -203,6 +207,8 @@
/// This proc handles the final step and actual removal of an embedded/stuck item from a carbon, whether or not it was actually removed safely.
/// Pass TRUE for to_hands if we want it to go to the victim's hands when they pull it out
/datum/component/embedded/proc/safeRemove(to_hands)
SIGNAL_HANDLER_DOES_SLEEP
var/mob/living/carbon/victim = parent
limb.embedded_objects -= weapon
UnregisterSignal(weapon, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) // have to do it here otherwise we trigger weaponDeleted()
@@ -218,6 +224,8 @@
/// Something deleted or moved our weapon while it was embedded, how rude!
/datum/component/embedded/proc/weaponDeleted()
SIGNAL_HANDLER
var/mob/living/carbon/victim = parent
limb.embedded_objects -= weapon
+2
View File
@@ -8,4 +8,6 @@
RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
/datum/component/empprotection/proc/getEmpFlags(datum/source, severity)
SIGNAL_HANDLER
return flags
+16
View File
@@ -36,20 +36,30 @@
always_delete = _always_delete
/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
SIGNAL_HANDLER
check_if_detonate(I)
/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
SIGNAL_HANDLER
check_if_detonate(hit_atom)
/datum/component/explodable/proc/explodable_bump(datum/source, atom/A)
SIGNAL_HANDLER
check_if_detonate(A)
///Called when you use this object to attack sopmething
/datum/component/explodable/proc/explodable_attack(datum/source, atom/movable/target, mob/living/user)
SIGNAL_HANDLER
check_if_detonate(target)
///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants.
/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone)
SIGNAL_HANDLER
if(!def_zone)
return
if(damagetype != BURN) //Don't bother if it's not fire.
@@ -59,9 +69,13 @@
detonate()
/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot)
SIGNAL_HANDLER
RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMGE, .proc/explodable_attack_zone, TRUE)
/datum/component/explodable/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
UnregisterSignal(user, COMSIG_MOB_APPLY_DAMGE)
/// Checks if we're hitting the zone this component is covering
@@ -103,6 +117,8 @@
/// Expldoe and remove the object
/datum/component/explodable/proc/detonate()
SIGNAL_HANDLER
var/atom/A = parent
var/log = TRUE
if(light_impact_range < 1)
+4
View File
@@ -66,6 +66,8 @@
return T
/datum/component/footstep/proc/play_simplestep()
SIGNAL_HANDLER
var/turf/open/T = prepare_step()
if(!T)
return
@@ -87,6 +89,8 @@
playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range)
/datum/component/footstep/proc/play_humanstep()
SIGNAL_HANDLER
if(HAS_TRAIT(parent, TRAIT_SILENT_FOOTSTEPS))
return
var/turf/open/T = prepare_step()
+2
View File
@@ -52,6 +52,8 @@
return TRUE
/datum/component/forensics/proc/clean_act(datum/source, clean_types)
SIGNAL_HANDLER
if(clean_types & CLEAN_TYPE_FINGERPRINTS)
wipe_fingerprints()
. = TRUE
+8
View File
@@ -36,15 +36,21 @@ GLOBAL_LIST_EMPTY(GPS_list)
///Called on COMSIG_ITEM_ATTACK_SELF
/datum/component/gps/item/proc/interact(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(user)
ui_interact(user)
///Called on COMSIG_PARENT_EXAMINE
/datum/component/gps/item/proc/on_examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
examine_list += "<span class='notice'>Alt-click to switch it [tracking ? "off":"on"].</span>"
///Called on COMSIG_ATOM_EMP_ACT
/datum/component/gps/item/proc/on_emp_act(datum/source, severity)
SIGNAL_HANDLER
emped = TRUE
var/atom/A = parent
A.cut_overlay("working")
@@ -61,6 +67,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
///Calls toggletracking
/datum/component/gps/item/proc/on_AltClick(datum/source, mob/user)
SIGNAL_HANDLER
toggletracking(user)
///Toggles the tracking for the gps
+12
View File
@@ -65,6 +65,8 @@
UnregisterSignal(parent, list(COMSIG_LIVING_START_PULL, COMSIG_MOVABLE_BUMP))
/datum/component/gunpoint/proc/check_bump(atom/B, atom/A)
SIGNAL_HANDLER
var/mob/living/T = A
if(T && T == target)
var/mob/living/shooter = parent
@@ -74,6 +76,8 @@
qdel(src)
/datum/component/gunpoint/proc/check_shove(mob/living/carbon/shooter, mob/shooter_again, mob/living/T)
SIGNAL_HANDLER
if(T == target && (shooter.a_intent == INTENT_DISARM || shooter.a_intent == INTENT_GRAB))
shooter.visible_message("<span class='danger'>[shooter] bumps into [target] and fumbles [shooter.p_their()] aim!</span>", \
"<span class='danger'>You bump into [target] and fumble your aim!</span>", target)
@@ -94,10 +98,14 @@
damage_mult = GUNPOINT_MULT_STAGE_3
/datum/component/gunpoint/proc/check_deescalate()
SIGNAL_HANDLER
if(!can_see(parent, target, GUNPOINT_SHOOTER_STRAY_RANGE - 1))
cancel()
/datum/component/gunpoint/proc/trigger_reaction()
SIGNAL_HANDLER_DOES_SLEEP
SEND_SIGNAL(target, COMSIG_CLEAR_MOOD_EVENT, "gunpoint")
if(point_of_no_return)
return
@@ -122,6 +130,8 @@
qdel(src)
/datum/component/gunpoint/proc/cancel()
SIGNAL_HANDLER
var/mob/living/shooter = parent
shooter.visible_message("<span class='danger'>[shooter] breaks [shooter.p_their()] aim on [target]!</span>", \
"<span class='danger'>You are no longer aiming [weapon] at [target].</span>", target)
@@ -130,6 +140,8 @@
qdel(src)
/datum/component/gunpoint/proc/flinch(attacker, damage, damagetype, def_zone)
SIGNAL_HANDLER_DOES_SLEEP
var/mob/living/shooter = parent
var/flinch_chance = 50
+2
View File
@@ -12,6 +12,8 @@
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
/datum/component/heirloom/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
if(user.mind == owner)
examine_list += "<span class='notice'>It is your precious [family_name] family heirloom. Keep it safe!</span>"
else if(isobserver(user))
+4
View File
@@ -28,9 +28,13 @@
qdel(parent)
/datum/component/hot_ice/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
SIGNAL_HANDLER
if(exposed_temperature > T0C + 100)
hot_ice_melt()
/datum/component/hot_ice/proc/attackby_react(datum/source, obj/item/thing, mob/user, params)
SIGNAL_HANDLER
if(thing.get_temperature())
hot_ice_melt(user)
+6
View File
@@ -19,14 +19,20 @@
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/igniter/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag)
return
do_igniter(target)
/datum/component/igniter/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
SIGNAL_HANDLER
do_igniter(target)
/datum/component/igniter/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
SIGNAL_HANDLER
do_igniter(target)
/datum/component/igniter/proc/do_igniter(atom/target)
+20
View File
@@ -33,11 +33,15 @@
RegisterSignal(parent, COMSIG_GIBS_STREAK, .proc/try_infect_streak)
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
SIGNAL_HANDLER
for(var/V in diseases)
eater.ForceContractDisease(V)
try_infect(feeder, BODY_ZONE_L_ARM)
/datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder)
SIGNAL_HANDLER
for(var/disease in diseases)
drinker.ForceContractDisease(disease)
var/appendage_zone = feeder.held_items.Find(source)
@@ -45,15 +49,21 @@
try_infect(feeder, appendage_zone)
/datum/component/infective/proc/clean(datum/source, clean_types)
SIGNAL_HANDLER
if(clean_types & required_clean_types)
qdel(src)
return TRUE
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
SIGNAL_HANDLER
if(isliving(M))
try_infect(M)
/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
SIGNAL_HANDLER
var/atom/movable/P = parent
if(P.throwing)
//this will be handled by try_infect_impact_zone()
@@ -62,9 +72,13 @@
try_infect(A)
/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
SIGNAL_HANDLER
try_infect(target, hit_zone)
/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
SIGNAL_HANDLER
try_infect(user, BODY_ZONE_L_ARM)
try_infect(target, hit_zone)
@@ -74,6 +88,8 @@
try_infect(user, BODY_ZONE_L_ARM)
/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
SIGNAL_HANDLER
var/old_permeability
if(isitem(parent))
//if you are putting an infective item on, it obviously will not protect you, so set its permeability high enough that it will never block ContactContractDisease()
@@ -88,10 +104,14 @@
I.permeability_coefficient = old_permeability
/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/M)
SIGNAL_HANDLER
if(isliving(M))
try_infect(M, BODY_ZONE_PRECISE_L_FOOT)
/datum/component/infective/proc/try_infect_streak(datum/source, list/directions, list/output_diseases)
SIGNAL_HANDLER
output_diseases |= diseases
/datum/component/infective/proc/try_infect(mob/living/L, target_zone)
+8
View File
@@ -23,16 +23,22 @@
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/on_attack)
/datum/component/jousting/proc/on_equip(datum/source, mob/user, slot)
SIGNAL_HANDLER
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE)
current_holder = user
/datum/component/jousting/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
current_holder = null
current_direction = NONE
current_tile_charge = 0
/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user)
SIGNAL_HANDLER
if(user != current_holder)
return
var/current = current_tile_charge
@@ -59,6 +65,8 @@
user.visible_message("<span class='danger'>[msg]!</span>")
/datum/component/jousting/proc/mob_move(datum/source, newloc, dir)
SIGNAL_HANDLER
if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled))))
return
if(dir != current_direction)
+6
View File
@@ -27,16 +27,22 @@
/// triggered after an item attacks something
/datum/component/knockback/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag)
return
do_knockback(target, user, get_dir(source, target))
/// triggered after a hostile simplemob attacks something
/datum/component/knockback/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
SIGNAL_HANDLER
do_knockback(target, attacker, get_dir(attacker, target))
/// triggered after a projectile hits something
/datum/component/knockback/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
SIGNAL_HANDLER
do_knockback(target, null, angle2dir(Angle))
+6
View File
@@ -19,6 +19,8 @@
src.slots_knockoffable = slots_knockoffable
/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone)
SIGNAL_HANDLER
var/obj/item/I = parent
var/mob/living/carbon/human/wearer = I.loc
if(!istype(wearer))
@@ -33,6 +35,8 @@
wearer.visible_message("<span class='warning'>[attacker] knocks off [wearer]'s [I.name]!</span>","<span class='userdanger'>[attacker] knocks off your [I.name]!</span>")
/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot)
SIGNAL_HANDLER
if(!istype(H))
return
if(slots_knockoffable && !(slot in slots_knockoffable))
@@ -41,4 +45,6 @@
RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M)
SIGNAL_HANDLER
UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
+4
View File
@@ -52,6 +52,8 @@
* user: The mob who is wielding the attacking object.
*/
/datum/component/label/proc/OnAttackby(datum/source, obj/item/attacker, mob/user)
SIGNAL_HANDLER
// If the attacking object is not a hand labeler or its mode is 1 (has a label ready to apply), return.
// The hand labeler should be off (mode is 0), in order to remove a label.
var/obj/item/hand_labeler/labeler = attacker
@@ -73,6 +75,8 @@
* examine_list: The current list of text getting passed from the parent's normal examine() proc.
*/
/datum/component/label/proc/Examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
examine_list += "<span class='notice'>It has a label with some words written on it. Use a hand labeler to remove it.</span>"
/// Applies a label to the name of the parent in the format of: "parent_name (label)"
+6
View File
@@ -20,14 +20,20 @@
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag)
return
do_lifesteal(user, target)
/datum/component/lifesteal/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
SIGNAL_HANDLER
do_lifesteal(attacker, target)
/datum/component/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
SIGNAL_HANDLER
do_lifesteal(firer, target)
/datum/component/lifesteal/proc/do_lifesteal(atom/heal_target, atom/damage_target)
+12
View File
@@ -16,19 +16,31 @@
RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
/datum/component/magnetic_catch/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
examine_list += "It has been installed with inertia dampening to prevent coffee spills."
/datum/component/magnetic_catch/proc/crossed_react(datum/source, atom/movable/thing)
SIGNAL_HANDLER
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
/datum/component/magnetic_catch/proc/uncrossed_react(datum/source, atom/movable/thing)
SIGNAL_HANDLER
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
/datum/component/magnetic_catch/proc/entered_react(datum/source, atom/movable/thing, atom/oldloc)
SIGNAL_HANDLER
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
/datum/component/magnetic_catch/proc/exited_react(datum/source, atom/movable/thing, atom/newloc)
SIGNAL_HANDLER
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
/datum/component/magnetic_catch/proc/throw_react(datum/source, list/arguments)
SIGNAL_HANDLER
return COMPONENT_CANCEL_THROW
+10
View File
@@ -43,9 +43,13 @@
UnregisterSignal(parent, COMSIG_MOB_DEATH)
/datum/component/manual_blinking/proc/restart()
SIGNAL_HANDLER
START_PROCESSING(SSdcs, src)
/datum/component/manual_blinking/proc/pause()
SIGNAL_HANDLER
STOP_PROCESSING(SSdcs, src)
/datum/component/manual_blinking/process()
@@ -63,6 +67,8 @@
warn_grace = TRUE
/datum/component/manual_blinking/proc/check_added_organ(mob/who_cares, obj/item/organ/O)
SIGNAL_HANDLER
var/obj/item/organ/eyes/new_eyes = O
if(istype(new_eyes,/obj/item/organ/eyes))
@@ -70,6 +76,8 @@
START_PROCESSING(SSdcs, src)
/datum/component/manual_blinking/proc/check_removed_organ(mob/who_cares, obj/item/organ/O)
SIGNAL_HANDLER
var/obj/item/organ/eyes/bye_beyes = O // oh come on, that's pretty good
if(istype(bye_beyes, /obj/item/organ/eyes))
@@ -77,6 +85,8 @@
STOP_PROCESSING(SSdcs, src)
/datum/component/manual_blinking/proc/check_emote(mob/living/carbon/user, datum/emote/emote)
SIGNAL_HANDLER
if(emote.type in valid_emotes)
warn_grace = FALSE
warn_dying = FALSE
@@ -43,9 +43,13 @@
UnregisterSignal(parent, COMSIG_MOB_DEATH)
/datum/component/manual_breathing/proc/restart()
SIGNAL_HANDLER
START_PROCESSING(SSdcs, src)
/datum/component/manual_breathing/proc/pause()
SIGNAL_HANDLER
STOP_PROCESSING(SSdcs, src)
/datum/component/manual_breathing/process()
@@ -65,6 +69,8 @@
warn_grace = TRUE
/datum/component/manual_breathing/proc/check_added_organ(mob/who_cares, obj/item/organ/O)
SIGNAL_HANDLER
var/obj/item/organ/eyes/new_lungs = O
if(istype(new_lungs,/obj/item/organ/lungs))
@@ -72,6 +78,8 @@
START_PROCESSING(SSdcs, src)
/datum/component/manual_breathing/proc/check_removed_organ(mob/who_cares, obj/item/organ/O)
SIGNAL_HANDLER
var/obj/item/organ/lungs/old_lungs = O
if(istype(old_lungs, /obj/item/organ/lungs))
@@ -79,6 +87,8 @@
STOP_PROCESSING(SSdcs, src)
/datum/component/manual_breathing/proc/check_emote(mob/living/carbon/user, datum/emote/emote)
SIGNAL_HANDLER
if(emote.type == next_breath_type)
if(next_breath_type == /datum/emote/inhale)
next_breath_type = /datum/emote/exhale
@@ -46,6 +46,8 @@
materials[M] = 0
/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
SIGNAL_HANDLER
if(show_on_examine)
for(var/I in materials)
var/datum/material/M = I
@@ -55,6 +57,8 @@
/// Proc that allows players to fill the parent with mats
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER
var/list/tc = allowed_typecache
if(disable_attackby)
return
+2
View File
@@ -22,6 +22,8 @@
UnregisterSignal(parent, list(COMSIG_PROJECTILE_ON_HIT))
/datum/component/mirv/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
SIGNAL_HANDLER_DOES_SLEEP
do_shrapnel(firer, target)
/datum/component/mirv/proc/do_shrapnel(mob/firer, atom/target)
+16
View File
@@ -38,6 +38,8 @@
return ..()
/datum/component/mood/proc/register_job_signals(datum/source, job)
SIGNAL_HANDLER
if(job in list("Research Director", "Scientist", "Roboticist"))
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT_RND, .proc/add_event) //Mood events that are only for RnD members
@@ -237,6 +239,8 @@
insanity_effect = newval
/datum/component/mood/proc/add_event(datum/source, category, type, ...) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
SIGNAL_HANDLER
var/datum/mood_event/the_event
if(!istext(category))
category = REF(category)
@@ -260,6 +264,8 @@
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
/datum/component/mood/proc/clear_event(datum/source, category)
SIGNAL_HANDLER
if(!istext(category))
category = REF(category)
var/datum/mood_event/event = mood_events[category]
@@ -281,6 +287,8 @@
/datum/component/mood/proc/modify_hud(datum/source)
SIGNAL_HANDLER
var/mob/living/owner = parent
var/datum/hud/hud = owner.hud_used
screen_obj = new
@@ -290,6 +298,8 @@
RegisterSignal(screen_obj, COMSIG_CLICK, .proc/hud_click)
/datum/component/mood/proc/unmodify_hud(datum/source)
SIGNAL_HANDLER
if(!screen_obj)
return
var/mob/living/owner = parent
@@ -299,6 +309,8 @@
QDEL_NULL(screen_obj)
/datum/component/mood/proc/hud_click(datum/source, location, control, params, mob/user)
SIGNAL_HANDLER
if(user != parent)
return
print_mood(user)
@@ -343,6 +355,8 @@
add_event(null, "charge", /datum/mood_event/supercharged)
/datum/component/mood/proc/check_area_mood(datum/source, area/A)
SIGNAL_HANDLER
update_beauty(A)
if(A.mood_bonus)
add_event(null, "area", /datum/mood_event/area, A.mood_bonus, A.mood_message)
@@ -373,6 +387,8 @@
///Called when parent is ahealed.
/datum/component/mood/proc/on_revive(datum/source, full_heal)
SIGNAL_HANDLER
if(!full_heal)
return
remove_temp_moods()
+46
View File
@@ -121,10 +121,14 @@
/datum/component/nanites/proc/delete_nanites()
SIGNAL_HANDLER
qdel(src)
//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status)
/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
SIGNAL_HANDLER
var/list/programs_to_remove = programs.Copy()
var/list/programs_to_add = source.programs.Copy()
for(var/X in programs)
@@ -157,6 +161,8 @@
NP.software_error()
/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
SIGNAL_HANDLER
for(var/X in programs)
var/datum/nanite_program/NP = X
if(NP.unique && NP.type == new_program.type)
@@ -176,6 +182,8 @@
return (nanite_volume > 0)
/datum/component/nanites/proc/adjust_nanites(datum/source, amount)
SIGNAL_HANDLER
nanite_volume = clamp(nanite_volume + amount, 0, max_nanites)
if(nanite_volume <= 0) //oops we ran out
qdel(src)
@@ -192,6 +200,8 @@
holder.icon_state = "nanites[nanite_percent]"
/datum/component/nanites/proc/on_emp(datum/source, severity)
SIGNAL_HANDLER
nanite_volume *= (rand(60, 90) * 0.01) //Lose 10-40% of nanites
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
if(prob(40/severity))
@@ -202,6 +212,8 @@
/datum/component/nanites/proc/on_shock(datum/source, shock_damage, siemens_coeff = 1, flags = NONE)
SIGNAL_HANDLER
if(flags & SHOCK_ILLUSION || shock_damage < 1)
return
@@ -213,35 +225,49 @@
NP.on_shock(shock_damage)
/datum/component/nanites/proc/on_minor_shock(datum/source)
SIGNAL_HANDLER
adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_minor_shock()
/datum/component/nanites/proc/check_stealth(datum/source)
SIGNAL_HANDLER
return stealth
/datum/component/nanites/proc/on_death(datum/source, gibbed)
SIGNAL_HANDLER
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_death(gibbed)
/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source")
SIGNAL_HANDLER
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.receive_signal(code, source)
/datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source")
SIGNAL_HANDLER
for(var/X in programs)
if(istype(X, /datum/nanite_program/comm))
var/datum/nanite_program/comm/NP = X
NP.receive_comm_signal(comm_code, comm_message, comm_source)
/datum/component/nanites/proc/check_viable_biotype()
SIGNAL_HANDLER
if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)))
qdel(src) //bodytype no longer sustains nanites
/datum/component/nanites/proc/check_access(datum/source, obj/O)
SIGNAL_HANDLER
for(var/datum/nanite_program/access/access_program in programs)
if(access_program.activated)
return O.check_access_list(access_program.access)
@@ -250,15 +276,23 @@
return FALSE
/datum/component/nanites/proc/set_volume(datum/source, amount)
SIGNAL_HANDLER
nanite_volume = clamp(amount, 0, max_nanites)
/datum/component/nanites/proc/set_max_volume(datum/source, amount)
SIGNAL_HANDLER
max_nanites = max(1, max_nanites)
/datum/component/nanites/proc/set_cloud(datum/source, amount)
SIGNAL_HANDLER
cloud_id = clamp(amount, 0, 100)
/datum/component/nanites/proc/set_cloud_sync(datum/source, method)
SIGNAL_HANDLER
switch(method)
if(NANITE_CLOUD_TOGGLE)
cloud_active = !cloud_active
@@ -268,12 +302,18 @@
cloud_active = TRUE
/datum/component/nanites/proc/set_safety(datum/source, amount)
SIGNAL_HANDLER
safety_threshold = clamp(amount, 0, max_nanites)
/datum/component/nanites/proc/set_regen(datum/source, amount)
SIGNAL_HANDLER
regen_rate = amount
/datum/component/nanites/proc/confirm_nanites()
SIGNAL_HANDLER
return TRUE //yup i exist
/datum/component/nanites/proc/get_data(list/nanite_data)
@@ -285,6 +325,8 @@
nanite_data["stealth"] = stealth
/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
SIGNAL_HANDLER
nanite_programs |= programs
/datum/component/nanites/proc/add_research()
@@ -301,6 +343,8 @@
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_NANITES = research_value))
/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
SIGNAL_HANDLER
if(!full_scan)
if(!stealth)
to_chat(user, "<span class='notice'><b>Nanites Detected</b></span>")
@@ -324,6 +368,8 @@
return TRUE
/datum/component/nanites/proc/nanite_ui_data(datum/source, list/data, scan_level)
SIGNAL_HANDLER
data["has_nanites"] = TRUE
data["nanite_volume"] = nanite_volume
data["regen_rate"] = regen_rate
+6
View File
@@ -41,6 +41,8 @@
* We do the prob() at the beginning to A. add some tension for /when/ it will strike, and B. (more importantly) ameliorate the fact that we're checking up to 5 turfs's contents each time
*/
/datum/component/omen/proc/check_accident(atom/movable/our_guy)
SIGNAL_HANDLER_DOES_SLEEP
if(!prob(15))
return
for(var/t in get_adjacent_open_turfs(our_guy))
@@ -53,6 +55,8 @@
/// If we get knocked down, see if we have a really bad slip and bash our head hard
/datum/component/omen/proc/check_slip(mob/living/our_guy, amount)
SIGNAL_HANDLER
if(amount <= 0 || prob(50)) // 50% chance to bonk our head
return
@@ -68,6 +72,8 @@
/// Hijack the mood system to see if we get the blessing mood event to cancel the omen
/datum/component/omen/proc/check_bless(mob/living/our_guy, category)
SIGNAL_HANDLER
if(category != "blessing")
return
to_chat(our_guy, "<span class='nicegreen'>You feel a horrible omen lifted off your shoulders!</span>")
+2
View File
@@ -118,6 +118,8 @@
/datum/component/orbiter/proc/orbiter_move_react(atom/movable/orbiter, atom/oldloc, direction)
SIGNAL_HANDLER
if(orbiter.loc == get_turf(parent))
return
end_orbit(orbiter)
+2
View File
@@ -13,6 +13,8 @@
A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint)
/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
SIGNAL_HANDLER
if(!istype(spraycan) || user.a_intent == INTENT_HARM)
return
. = COMPONENT_NO_AFTERATTACK
+4
View File
@@ -28,6 +28,8 @@
RegisterSignal(parent, COMSIG_OBJ_ATTEMPT_CHARGE_CHANGE, .proc/change_cost)
/datum/component/payment/proc/attempt_charge(datum/source, atom/movable/target, extra_fees = 0)
SIGNAL_HANDLER
if(!cost) //In case a free variant of anything is made it'll skip charging anyone.
return
if(!ismob(target))
@@ -66,6 +68,8 @@
playsound(src, 'sound/effects/cashregister.ogg', 20, TRUE)
/datum/component/payment/proc/change_cost(datum/source, new_cost)
SIGNAL_HANDLER
if(!isnum(new_cost))
CRASH("change_cost called with variable new_cost as not a number.")
cost = new_cost
+18
View File
@@ -98,6 +98,8 @@
* The arguments really don't matter, this proc is triggered by COMSIG_PELLET_CLOUD_INIT which is only for this really, it's just a big mess of the state vars we need for doing the stuff over here.
*/
/datum/component/pellet_cloud/proc/create_casing_pellets(obj/item/ammo_casing/shell, atom/target, mob/living/user, fired_from, randomspread, spread, zone_override, params, distro)
SIGNAL_HANDLER_DOES_SLEEP
shooter = user
var/targloc = get_turf(target)
if(!zone_override)
@@ -125,6 +127,8 @@
* Note that grenades have extra handling for someone throwing themselves/being thrown on top of it, while landmines do not (obviously, it's a landmine!). See [/datum/component/pellet_cloud/proc/handle_martyrs]
*/
/datum/component/pellet_cloud/proc/create_blast_pellets(obj/O, mob/living/lanced_by)
SIGNAL_HANDLER_DOES_SLEEP
var/atom/A = parent
if(isgrenade(parent)) // handle_martyrs can reduce the radius and thus the number of pellets we produce if someone dives on top of a frag grenade
@@ -198,6 +202,8 @@
///One of our pellets hit something, record what it was and check if we're done (terminated == num_pellets)
/datum/component/pellet_cloud/proc/pellet_hit(obj/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone)
SIGNAL_HANDLER
pellets -= P
terminated++
hits++
@@ -287,6 +293,8 @@
/// Look alive, we're armed! Now we start watching to see if anyone's covering us
/datum/component/pellet_cloud/proc/grenade_armed(obj/item/nade)
SIGNAL_HANDLER
if(ismob(nade.loc))
shooter = nade.loc
LAZYINITLIST(bodies)
@@ -296,11 +304,15 @@
/// Someone dropped the grenade, so set them to the shooter in case they're on top of it when it goes off
/datum/component/pellet_cloud/proc/grenade_dropped(obj/item/nade, mob/living/slick_willy)
SIGNAL_HANDLER
shooter = slick_willy
grenade_moved()
/// Our grenade has moved, reset var/list/bodies so we're "on top" of any mobs currently on the tile
/datum/component/pellet_cloud/proc/grenade_moved()
SIGNAL_HANDLER
LAZYCLEARLIST(bodies)
for(var/mob/living/L in get_turf(parent))
RegisterSignal(L, COMSIG_PARENT_QDELETING, .proc/on_target_qdel, override=TRUE)
@@ -308,10 +320,14 @@
/// Someone who was originally "under" the grenade has moved off the tile and is now eligible for being a martyr and "covering" it
/datum/component/pellet_cloud/proc/grenade_uncrossed(datum/source, atom/movable/AM)
SIGNAL_HANDLER
bodies -= AM
/// Our grenade or landmine or caseless shell or whatever tried deleting itself, so we intervene and nullspace it until we're done here
/datum/component/pellet_cloud/proc/nullspace_parent()
SIGNAL_HANDLER
var/atom/movable/AM = parent
AM.moveToNullspace()
queued_delete = TRUE
@@ -319,6 +335,8 @@
/// Someone who was originally "under" the grenade has moved off the tile and is now eligible for being a martyr and "covering" it
/datum/component/pellet_cloud/proc/on_target_qdel(atom/target)
SIGNAL_HANDLER
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
targets_hit -= target
LAZYREMOVE(bodies, target)
@@ -99,6 +99,8 @@
///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize()
/datum/component/plumbing/proc/create_overlays(atom/movable/AM, list/overlays)
SIGNAL_HANDLER
if(tile_covered || !use_overlays)
return
@@ -135,6 +137,8 @@
///we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff
/datum/component/plumbing/proc/disable()
SIGNAL_HANDLER
if(!active)
return
@@ -183,6 +187,8 @@
/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move
/datum/component/plumbing/proc/toggle_active(obj/O, new_state)
SIGNAL_HANDLER
if(new_state)
enable()
else
@@ -229,6 +235,8 @@
net.add_plumber(P, opposite_dir)
/datum/component/plumbing/proc/hide(atom/movable/AM, intact)
SIGNAL_HANDLER
tile_covered = intact
AM.update_icon()
+4
View File
@@ -13,9 +13,13 @@
RegisterSignal(parent, list(COMSIG_ITEM_SPLIT_PROFIT, COMSIG_ITEM_SPLIT_PROFIT_DRY), .proc/return_ratio)
/datum/component/pricetag/proc/Unwrapped()
SIGNAL_HANDLER
qdel(src) //Once it leaves it's wrapped container, the object in question should lose it's pricetag component.
/datum/component/pricetag/proc/split_profit(item_value)
SIGNAL_HANDLER
var/price = item_value
if(price)
var/adjusted_value = price*(profit_ratio/100)
+2
View File
@@ -22,6 +22,8 @@
///Called on COMSIG_ITEM_ATTACK_SELF. Allows you to change the warcry.
/datum/component/wearertargeting/punchcooldown/proc/changewarcry(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7)
if(!QDELETED(src) && !QDELETED(user) && !user.Adjacent(parent))
return
+6
View File
@@ -15,11 +15,17 @@
amount = _amount
/datum/component/rad_insulation/proc/rad_probe_react(datum/source)
SIGNAL_HANDLER
return COMPONENT_BLOCK_RADIATION
/datum/component/rad_insulation/proc/rad_contaminating(datum/source, strength)
SIGNAL_HANDLER
return COMPONENT_BLOCK_CONTAMINATION
/datum/component/rad_insulation/proc/rad_pass(datum/source, datum/radiation_wave/wave, width)
SIGNAL_HANDLER
wave.intensity = wave.intensity*(1-((1-amount)/width)) // The further out the rad wave goes the less it's affected by insulation (larger width)
return COMPONENT_RAD_WAVE_HANDLED
+6
View File
@@ -68,6 +68,8 @@
strength = max(strength, _strength)
/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing)
SIGNAL_HANDLER
var/atom/master = parent
var/list/out = list()
if(get_dist(master, user) <= 1)
@@ -85,6 +87,8 @@
to_chat(user, "<span class ='warning'>[out.Join()]</span>")
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
SIGNAL_HANDLER
radiation_pulse(parent, strength/20)
target.rad_act(strength/2)
if(!hl3_release_date)
@@ -92,6 +96,8 @@
strength -= strength / hl3_release_date
/datum/component/radioactive/proc/rad_clean(datum/source, clean_types)
SIGNAL_HANDLER
if(QDELETED(src))
return
+4
View File
@@ -51,6 +51,8 @@
* Since all of these involve attackby, we require mega proc. Handles Invocation, Sacrificing, And Selection of Sects.
*/
/datum/component/religious_tool/proc/AttemptActions(datum/source, obj/item/the_item, mob/living/user)
SIGNAL_HANDLER_DOES_SLEEP
/**********Sect Selection**********/
if(!SetGlobalToLocal())
if(!(operation_flags & RELIGION_TOOL_SECTSELECT))
@@ -126,6 +128,8 @@
* Appends to examine so the user knows it can be used for religious purposes.
*/
/datum/component/religious_tool/proc/on_examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
var/can_i_see = FALSE
if(isobserver(user))
can_i_see = TRUE
@@ -86,11 +86,15 @@ handles linking back and forth.
_MakeLocal()
/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
SIGNAL_HANDLER
if (silo && istype(I, /obj/item/stack))
if (silo.remote_attackby(parent, user, I))
return COMPONENT_NO_AFTERATTACK
/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I)
SIGNAL_HANDLER
if(!I.multitool_check_buffer(user, I))
return COMPONENT_BLOCK_TOOL_ATTACK
var/obj/item/multitool/M = I
+10
View File
@@ -34,6 +34,8 @@
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
SIGNAL_HANDLER
var/atom/movable/AM = parent
restore_position(M)
unequip_buckle_inhands(M)
@@ -41,6 +43,8 @@
qdel(src)
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
SIGNAL_HANDLER
var/atom/movable/movable_parent = parent
handle_vehicle_offsets(movable_parent.dir)
@@ -58,6 +62,8 @@
directional_vehicle_layers["[dir]"] = layer
/datum/component/riding/proc/vehicle_moved(datum/source, dir)
SIGNAL_HANDLER
var/atom/movable/movable_parent = parent
if (isnull(dir))
dir = movable_parent.dir
@@ -67,6 +73,8 @@
handle_vehicle_layer(dir)
/datum/component/riding/proc/vehicle_turned(datum/source, _old_dir, new_dir)
SIGNAL_HANDLER
vehicle_moved(source, new_dir)
/datum/component/riding/proc/ride_check(mob/living/M)
@@ -238,6 +246,8 @@
H.add_movespeed_modifier(/datum/movespeed_modifier/human_carry)
/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target)
SIGNAL_HANDLER
var/mob/living/carbon/human/H = parent
if(H.a_intent == INTENT_DISARM && (target in H.buckled_mobs))
force_dismount(target)
+6
View File
@@ -99,15 +99,21 @@
. = ..()
/datum/component/simple_rotation/proc/ExamineMessage(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
if(rotation_flags & ROTATION_ALTCLICK)
examine_list += "<span class='notice'>Alt-click to rotate it clockwise.</span>"
/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
SIGNAL_HANDLER
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
return
BaseRot(user, rotation)
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
return
BaseRot(user,default_rotation_direction)
+4
View File
@@ -15,12 +15,16 @@
RegisterSignal(parent, COMSIG_ITEM_WEARERCROSSED, .proc/Slip_on_wearer)
/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
SIGNAL_HANDLER
var/mob/victim = AM
if(istype(victim) && !victim.is_flying() && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback)
callback.Invoke(victim)
/datum/component/slippery/proc/Slip_on_wearer(datum/source, atom/movable/AM, mob/living/crossed)
SIGNAL_HANDLER
if(!(crossed.mobility_flags & MOBILITY_STAND) && !crossed.buckle_lying)
Slip(source, AM)
+2
View File
@@ -19,6 +19,8 @@
RegisterSignal(S, COMSIG_MOVABLE_MOVED, .proc/free_prisoner)
/datum/component/soulstoned/proc/free_prisoner()
SIGNAL_HANDLER
var/mob/living/simple_animal/S = parent
if(S.loc != container)
qdel(src)
+2
View File
@@ -29,6 +29,8 @@
/datum/component/spawner/proc/stop_spawning(force)
SIGNAL_HANDLER
STOP_PROCESSING(SSprocessing, src)
for(var/mob/living/simple_animal/L in spawned_mobs)
if(L.nest == src)
+6
View File
@@ -40,15 +40,21 @@
master.item_flags &= ~ITEM_SLOT_POCKETS
/datum/component/spill/proc/equip_react(obj/item/source, mob/equipper, slot)
SIGNAL_HANDLER
if(slot == ITEM_SLOT_LPOCKET || slot == ITEM_SLOT_RPOCKET)
RegisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN, .proc/knockdown_react, TRUE)
else
UnregisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN)
/datum/component/spill/proc/drop_react(obj/item/source, mob/dropper)
SIGNAL_HANDLER
UnregisterSignal(dropper, COMSIG_LIVING_STATUS_KNOCKDOWN)
/datum/component/spill/proc/knockdown_react(mob/living/fool)
SIGNAL_HANDLER
var/obj/item/master = parent
fool.dropItemToGround(master)
if(droptext)
+2
View File
@@ -5,6 +5,8 @@
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(ishuman(user)) //this weapon wasn't meant for mortals.
var/mob/living/carbon/human/U = user
if(!istype(U.dna.species, /datum/species/skeleton))
+16
View File
@@ -41,6 +41,8 @@
use_delay = use_delay_override
/datum/component/squeak/proc/play_squeak()
SIGNAL_HANDLER
if(prob(squeak_chance))
if(!override_squeak_sounds)
playsound(parent, pickweight(default_squeak_sounds), volume, TRUE, -1)
@@ -48,6 +50,8 @@
playsound(parent, pickweight(override_squeak_sounds), volume, TRUE, -1)
/datum/component/squeak/proc/step_squeak()
SIGNAL_HANDLER
if(steps > step_delay)
play_squeak()
steps = 0
@@ -55,6 +59,8 @@
steps++
/datum/component/squeak/proc/play_squeak_crossed(datum/source, atom/movable/AM)
SIGNAL_HANDLER
if(isitem(AM))
var/obj/item/I = AM
if(I.item_flags & ABSTRACT)
@@ -74,22 +80,32 @@
play_squeak()
/datum/component/squeak/proc/use_squeak()
SIGNAL_HANDLER
if(last_use + use_delay < world.time)
last_use = world.time
play_squeak()
/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot)
SIGNAL_HANDLER
RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react, TRUE)
/datum/component/squeak/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING)
// Disposal pipes related shit
/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/holder, obj/machinery/disposal/source)
SIGNAL_HANDLER
//We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted
RegisterSignal(holder, COMSIG_ATOM_DIR_CHANGE, .proc/holder_dir_change)
/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir)
SIGNAL_HANDLER
//If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall
if(old_dir != new_dir)
play_squeak()
+11
View File
@@ -25,6 +25,8 @@
inform_admins = inform_admins
/datum/component/stationloving/proc/relocate()
SIGNAL_HANDLER
var/targetturf = find_safe_turf()
if(!targetturf)
if(GLOB.blobstart.len > 0)
@@ -39,6 +41,8 @@
return targetturf
/datum/component/stationloving/proc/check_in_bounds()
SIGNAL_HANDLER
if(in_bounds())
return
else
@@ -49,9 +53,13 @@
message_admins("[parent] has been moved out of bounds in [ADMIN_VERBOSEJMP(currentturf)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
/datum/component/stationloving/proc/check_soul_imbue()
SIGNAL_HANDLER
return disallow_soul_imbue
/datum/component/stationloving/proc/check_mark_retrieval()
SIGNAL_HANDLER
return COMPONENT_BLOCK_MARK_RETRIEVAL
/datum/component/stationloving/proc/in_bounds()
@@ -75,6 +83,9 @@
/datum/component/stationloving/proc/check_deletion(datum/source, force) // TRUE = interrupt deletion, FALSE = proceed with deletion
SIGNAL_HANDLER
var/turf/T = get_turf(parent)
if(inform_admins && force)
+2
View File
@@ -44,6 +44,8 @@ It has a punishment variable that is what happens to the parent when they leave
* * PUNISHMENT_TELEPORT: finds a safe turf if possible, or a completely random one if not.
*/
/datum/component/stationstuck/proc/punish()
SIGNAL_HANDLER
var/mob/living/L = parent
if(message)
var/span = punishment == PUNISHMENT_TELEPORT ? "danger" : "userdanger"
+58
View File
@@ -170,6 +170,8 @@
return master? master.real_location() : null
/datum/component/storage/proc/canreach_react(datum/source, list/next)
SIGNAL_HANDLER
var/datum/component/storage/concrete/master = master()
if(!master)
return
@@ -180,12 +182,16 @@
next += slave.parent
/datum/component/storage/proc/on_move()
SIGNAL_HANDLER
var/atom/A = parent
for(var/mob/living/L in can_see_contents())
if(!L.CanReach(A))
hide_from(L)
/datum/component/storage/proc/attack_self(datum/source, mob/M)
SIGNAL_HANDLER_DOES_SLEEP
if(locked)
to_chat(M, "<span class='warning'>[parent] seems to be locked!</span>")
return FALSE
@@ -193,6 +199,8 @@
quick_empty(M)
/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
SIGNAL_HANDLER_DOES_SLEEP
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
return FALSE
. = COMPONENT_NO_ATTACK
@@ -308,6 +316,8 @@
return TRUE
/datum/component/storage/proc/set_locked(datum/source, new_state)
SIGNAL_HANDLER
locked = new_state
if(locked)
close_all()
@@ -410,12 +420,16 @@
hide_from(M)
/datum/component/storage/proc/close_all()
SIGNAL_HANDLER
. = FALSE
for(var/mob/M in can_see_contents())
close(M)
. = TRUE //returns TRUE if any mobs actually got a close(M) call
/datum/component/storage/proc/emp_act(datum/source, severity)
SIGNAL_HANDLER
if(emp_shielded)
return
var/datum/component/storage/concrete/master = master()
@@ -450,6 +464,8 @@
return master._removal_reset(thing)
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
SIGNAL_HANDLER
_removal_reset(thing)
refresh_mob_views()
@@ -463,6 +479,8 @@
return master.remove_from_storage(AM, new_location)
/datum/component/storage/proc/refresh_mob_views()
SIGNAL_HANDLER
var/list/seeing = can_see_contents()
for(var/i in seeing)
show_to(i)
@@ -492,6 +510,8 @@
//This proc is called when you want to place an item into the storage item.
/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params)
SIGNAL_HANDLER
if(istype(I, /obj/item/hand_labeler))
var/obj/item/hand_labeler/labeler = I
if(labeler.mode)
@@ -521,12 +541,16 @@
//Abuses the fact that lists are just references, or something like that.
/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE)
SIGNAL_HANDLER
if(!islist(interface))
return FALSE
interface |= return_inv(recursive)
return TRUE
/datum/component/storage/proc/topic_handle(datum/source, user, href_list)
SIGNAL_HANDLER
if(href_list["show_valid_pocket_items"])
handle_show_valid_items(source, user)
@@ -534,6 +558,8 @@
to_chat(user, "<span class='notice'>[source] can hold: [can_hold_description]</span>")
/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
SIGNAL_HANDLER_DOES_SLEEP
set waitfor = FALSE
. = COMPONENT_NO_MOUSEDROP
if(!ismob(M))
@@ -573,6 +599,8 @@
show_to(M)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
SIGNAL_HANDLER
if(isitem(O))
var/obj/item/I = O
if(iscarbon(M) || isdrone(M))
@@ -678,26 +706,40 @@
O.update_icon()
/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
SIGNAL_HANDLER
if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent))
return FALSE
return handle_item_insertion(I, silent, M)
/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE)
SIGNAL_HANDLER
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
SIGNAL_HANDLER
return user_show_to_mob(M, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
SIGNAL_HANDLER
return user_show_to_mob(showto, force)
/datum/component/storage/proc/on_check()
SIGNAL_HANDLER
return TRUE
/datum/component/storage/proc/check_locked()
SIGNAL_HANDLER
return locked
/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
SIGNAL_HANDLER
if(!force)
if(check_adjacent)
if(!user || !user.CanReach(destination) || !user.CanReach(parent))
@@ -719,6 +761,8 @@
return max(0, max_items - real_location.contents.len)
/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
SIGNAL_HANDLER_DOES_SLEEP
var/atom/real_location = real_location()
if(!force)
amount = min(remaining_space_items(), amount)
@@ -731,6 +775,8 @@
return TRUE
/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
var/atom/A = parent
if(!attack_hand_interact)
return
@@ -764,22 +810,32 @@
show_to(user)
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
SIGNAL_HANDLER
update_actions()
for(var/mob/M in can_see_contents() - user)
close(M)
/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE)
SIGNAL_HANDLER
if(!(AM in real_location()))
return FALSE
return remove_from_storage(AM, new_loc)
/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget)
SIGNAL_HANDLER
return do_quick_empty(loctarget)
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
SIGNAL_HANDLER
return hide_from(target)
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(!isliving(user) || !user.CanReach(parent) || user.incapacitated())
return
if(locked)
@@ -804,6 +860,8 @@
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
SIGNAL_HANDLER
gather_mode_switch(source.owner)
return COMPONENT_ACTION_BLOCK_TRIGGER
+8
View File
@@ -34,14 +34,20 @@
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/summoning/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
if(!proximity_flag)
return
do_spawn_mob(get_turf(target), user)
/datum/component/summoning/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
SIGNAL_HANDLER
do_spawn_mob(get_turf(target), attacker)
/datum/component/summoning/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
SIGNAL_HANDLER
do_spawn_mob(get_turf(target), firer)
/datum/component/summoning/proc/do_spawn_mob(atom/spawn_location, summoner)
@@ -65,4 +71,6 @@
spawn_location.visible_message("<span class='danger'>[L] [spawn_text].</span>")
/datum/component/summoning/proc/on_spawned_death(mob/killed, gibbed)
SIGNAL_HANDLER
spawned_mobs -= killed
@@ -31,6 +31,8 @@
*
*/
/datum/component/surgery_initiator/proc/initiate_surgery_moment(datum/source, atom/target, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(!isliving(target))
return
var/mob/living/livingtarget = target
+4
View File
@@ -23,6 +23,8 @@
return ..()
/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM)
SIGNAL_HANDLER
var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming)
if(!other_swarm)
return
@@ -32,6 +34,8 @@
other_swarm.swarm_members |= src
/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM)
SIGNAL_HANDLER
var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming)
if(!other_swarm || !(other_swarm in swarm_members))
return
+8
View File
@@ -63,11 +63,15 @@
///Store the thrownthing datum for later use
/datum/component/tackler/proc/registerTackle(mob/living/carbon/user, datum/thrownthing/TT)
SIGNAL_HANDLER
tackle = TT
tackle.thrower = user
///See if we can tackle or not. If we can, leap!
/datum/component/tackler/proc/checkTackle(mob/living/carbon/user, atom/A, params)
SIGNAL_HANDLER
if(!user.in_throw_mode || user.get_active_held_item() || user.pulling || user.buckled || user.incapacitated())
return
@@ -140,6 +144,8 @@
* Finally, we return a bitflag to [COMSIG_MOVABLE_IMPACT] that forces the hitpush to false so that we don't knock them away.
*/
/datum/component/tackler/proc/sack(mob/living/carbon/user, atom/hit)
SIGNAL_HANDLER_DOES_SLEEP
if(!tackling || !tackle)
return
@@ -452,6 +458,8 @@
///Check to see if we hit a table, and if so, make a big mess!
/datum/component/tackler/proc/checkObstacle(mob/living/carbon/owner)
SIGNAL_HANDLER
if(!tackling)
return
+4
View File
@@ -20,6 +20,8 @@
return ..()
/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot)
SIGNAL_HANDLER
if(allowed_slot && slot != allowed_slot)
unmodify()
return
@@ -32,6 +34,8 @@
I.layer = ABOVE_MOB_LAYER
/datum/component/tactical/proc/unmodify(obj/item/source, mob/user)
SIGNAL_HANDLER
var/obj/item/master = source || parent
if(!user)
if(!ismob(master.loc))
+2
View File
@@ -17,6 +17,8 @@
RegisterSignal(parent, list(COMSIG_MOVABLE_PRE_MOVE), .proc/checkTether)
/datum/component/tether/proc/checkTether(mob/mover, newloc)
SIGNAL_HANDLER
if (get_dist(mover,newloc) > max_dist)
to_chat(mover, "<span class='userdanger'>The [tether_name] runs out of slack and prevents you from moving!</span>")
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
+6
View File
@@ -80,14 +80,20 @@
qdel(src)
/datum/component/thermite/proc/clean_react(datum/source, strength)
SIGNAL_HANDLER
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
qdel(src)
return TRUE
/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
SIGNAL_HANDLER
if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
thermite_melt()
/datum/component/thermite/proc/attackby_react(datum/source, obj/item/thing, mob/user, params)
SIGNAL_HANDLER
if(thing.get_temperature())
thermite_melt(user)
+14
View File
@@ -89,6 +89,8 @@
/// Triggered on equip of the item containing the component
/datum/component/two_handed/proc/on_equip(datum/source, mob/user, slot)
SIGNAL_HANDLER
if(require_twohands && slot == ITEM_SLOT_HANDS) // force equip the item
wield(user)
if(!user.is_holding(parent) && wielded && !require_twohands)
@@ -96,6 +98,8 @@
/// Triggered on drop of item containing the component
/datum/component/two_handed/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
if(require_twohands)
unwield(user, show_message=TRUE)
if(wielded)
@@ -105,6 +109,8 @@
/// Triggered on attack self of the item containing the component
/datum/component/two_handed/proc/on_attack_self(datum/source, mob/user)
SIGNAL_HANDLER
if(wielded)
unwield(user)
else if(user.is_holding(parent))
@@ -248,6 +254,8 @@
* Updates the icon using icon_wielded if set
*/
/datum/component/two_handed/proc/on_update_icon(datum/source)
SIGNAL_HANDLER
if(icon_wielded && wielded)
var/obj/item/parent_item = parent
if(parent_item)
@@ -258,12 +266,16 @@
* on_moved Triggers on item moved
*/
/datum/component/two_handed/proc/on_moved(datum/source, mob/user, dir)
SIGNAL_HANDLER
unwield(user)
/**
* on_swap_hands Triggers on swapping hands, blocks swap if the other hand is busy
*/
/datum/component/two_handed/proc/on_swap_hands(mob/user, obj/item/held_item)
SIGNAL_HANDLER
if(!held_item)
return
if(held_item == parent)
@@ -273,6 +285,8 @@
* on_sharpen Triggers on usage of a sharpening stone on the item
*/
/datum/component/two_handed/proc/on_sharpen(obj/item/item, amount, max_amount)
SIGNAL_HANDLER
if(!item)
return COMPONENT_BLOCK_SHARPEN_BLOCKED
if(sharpened_increase)
+20
View File
@@ -94,6 +94,8 @@
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
SIGNAL_HANDLER
if(!active)
return //no hitting everyone/everything just to try to slot tcs in!
if(istype(I, /obj/item/stack/telecrystal))
@@ -112,6 +114,8 @@
return
/datum/component/uplink/proc/interact(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(locked)
return
active = TRUE
@@ -225,25 +229,35 @@
// Implant signal responses
/datum/component/uplink/proc/implant_activation()
SIGNAL_HANDLER_DOES_SLEEP
var/obj/item/implant/implant = parent
locked = FALSE
interact(null, implant.imp_in)
/datum/component/uplink/proc/implanting(datum/source, list/arguments)
SIGNAL_HANDLER
var/mob/user = arguments[2]
owner = "[user.key]"
/datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant)
SIGNAL_HANDLER
// It kinda has to be weird like this until implants are components
return SEND_SIGNAL(new_implant, COMSIG_IMPLANT_EXISTING_UPLINK, src)
/datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink)
SIGNAL_HANDLER
uplink.telecrystals += telecrystals
return COMPONENT_DELETE_NEW_IMPLANT
// PDA signal responses
/datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text)
SIGNAL_HANDLER_DOES_SLEEP
var/obj/item/pda/master = parent
if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code)))
if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code)))
@@ -258,11 +272,15 @@
return COMPONENT_STOP_RINGTONE_CHANGE
/datum/component/uplink/proc/check_detonate()
SIGNAL_HANDLER
return COMPONENT_PDA_NO_DETONATE
// Radio signal responses
/datum/component/uplink/proc/new_frequency(datum/source, list/arguments)
SIGNAL_HANDLER_DOES_SLEEP
var/obj/item/radio/master = parent
var/frequency = arguments[1]
if(frequency != unlock_code)
@@ -276,6 +294,8 @@
// Pen signal responses
/datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user)
SIGNAL_HANDLER_DOES_SLEEP
var/obj/item/pen/master = parent
previous_attempts += degrees
if(length(previous_attempts) > PEN_ROTATIONS)
@@ -13,10 +13,14 @@
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
/datum/component/wearertargeting/proc/on_equip(datum/source, mob/equipper, slot)
SIGNAL_HANDLER
if((slot in valid_slots) && istype(equipper, mobtype))
RegisterSignal(equipper, signals, proctype, TRUE)
else
UnregisterSignal(equipper, signals)
/datum/component/wearertargeting/proc/on_drop(datum/source, mob/user)
SIGNAL_HANDLER
UnregisterSignal(user, signals)
+4
View File
@@ -97,6 +97,8 @@
parent.LoadComponent(/datum/component/slippery, intensity, lube_flags, CALLBACK(src, .proc/AfterSlip))
/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
SIGNAL_HANDLER
for(var/i in time_left_list)
if(text2num(i) <= strength)
time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
@@ -137,6 +139,8 @@
highest_strength = max(highest_strength, text2num(i))
/datum/component/wet_floor/proc/is_wet()
SIGNAL_HANDLER
. = 0
for(var/i in time_left_list)
. |= text2num(i)