datums
This commit is contained in:
@@ -32,8 +32,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
|
||||
1. `/datum/var/list/datum_components` (private)
|
||||
* Lazy associated list of type -> component/list of components.
|
||||
1. `/datum/component/var/enabled` (protected, boolean)
|
||||
* If the component is enabled. If not, it will not react to signals
|
||||
1. `/datum/var/list/comp_lookup` (private)
|
||||
* Lazy associated list of signal -> registree/list of registrees
|
||||
1. `/datum/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
|
||||
1. `/datum/var/signal_enabled` (protected, boolean)
|
||||
* If the datum is signal enabled. If not, it will not react to signals
|
||||
* `FALSE` by default, set to `TRUE` when a signal is registered
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How duplicate component types are handled when added to the datum.
|
||||
@@ -45,14 +49,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
* Definition of a duplicate component type
|
||||
* `null` means exact match on `type` (default)
|
||||
* Any other type means that and all subtypes
|
||||
1. `/datum/component/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
|
||||
1. `/datum/component/var/datum/parent` (protected, read-only)
|
||||
* The datum this component belongs to
|
||||
* Never `null` in child procs
|
||||
1. `report_signal_origin` (protected, boolean)
|
||||
* If `TRUE`, will invoke the callback when signalled with the signal type as the first argument.
|
||||
* `FALSE` by default.
|
||||
1. `report_signal_origin` (protected, boolean)
|
||||
* If `TRUE`, will invoke the callback when signalled with the signal type as the first argument.
|
||||
* `FALSE` by default.
|
||||
|
||||
### Procs
|
||||
|
||||
@@ -88,6 +90,14 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final)
|
||||
* Handles most of the actual signaling procedure
|
||||
* Will runtime if used on datums with an empty component list
|
||||
1. `/datum/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
|
||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||
* Makes the datum listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is received `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
1. `/datum/component/New(datum/parent, ...)` (private, final)
|
||||
* Runs internal setup for the component
|
||||
* Extra arguments are passed to `Initialize()`
|
||||
@@ -121,13 +131,5 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
1. `/datum/component/proc/UnregisterFromParent` (abstract, no-sleep)
|
||||
* Counterpart to `RegisterWithParent()`
|
||||
* Used to unregister the signals that should only be on the `parent` object
|
||||
1. `/datum/component/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
|
||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is received `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
|
||||
### See/Define signals and their arguments in __DEFINES\components.dm
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/datum/component
|
||||
var/enabled = FALSE
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
var/dupe_type
|
||||
var/list/signal_procs
|
||||
var/datum/parent
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
@@ -10,7 +8,7 @@
|
||||
var/list/arguments = args.Copy(2)
|
||||
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
||||
qdel(src, TRUE, TRUE)
|
||||
CRASH("Incompatible [type] assigned to a [P.type]!")
|
||||
CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]")
|
||||
|
||||
_JoinParent(P)
|
||||
|
||||
@@ -57,15 +55,11 @@
|
||||
return
|
||||
|
||||
/datum/component/Destroy(force=FALSE, silent=FALSE)
|
||||
enabled = FALSE
|
||||
var/datum/P = parent
|
||||
if(!force)
|
||||
if(!force && parent)
|
||||
_RemoveFromParent()
|
||||
if(!silent)
|
||||
SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
|
||||
SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
parent = null
|
||||
for(var/target in signal_procs)
|
||||
UnregisterSignal(target, signal_procs[target])
|
||||
return ..()
|
||||
|
||||
/datum/component/proc/_RemoveFromParent()
|
||||
@@ -89,7 +83,7 @@
|
||||
/datum/component/proc/UnregisterFromParent()
|
||||
return
|
||||
|
||||
/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
if(QDELETED(src) || QDELETED(target))
|
||||
return
|
||||
|
||||
@@ -122,9 +116,9 @@
|
||||
else // Many other things have registered here
|
||||
lookup[sig_type][src] = TRUE
|
||||
|
||||
enabled = TRUE
|
||||
signal_enabled = TRUE
|
||||
|
||||
/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
var/list/lookup = target.comp_lookup
|
||||
if(!signal_procs || !signal_procs[target] || !lookup)
|
||||
return
|
||||
@@ -174,15 +168,15 @@
|
||||
/datum/proc/_SendSignal(sigtype, list/arguments)
|
||||
var/target = comp_lookup[sigtype]
|
||||
if(!length(target))
|
||||
var/datum/component/C = target
|
||||
if(!C.enabled)
|
||||
var/datum/C = target
|
||||
if(!C.signal_enabled)
|
||||
return NONE
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
return CB.InvokeAsync(arglist(arguments))
|
||||
. = NONE
|
||||
for(var/I in target)
|
||||
var/datum/component/C = I
|
||||
if(!C.enabled)
|
||||
var/datum/C = I
|
||||
if(!C.signal_enabled)
|
||||
continue
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
. |= CB.InvokeAsync(arglist(arguments))
|
||||
@@ -232,6 +226,7 @@
|
||||
CRASH("[nt]: Invalid dupe_type ([dt])!")
|
||||
else
|
||||
new_comp = nt
|
||||
nt = new_comp.type
|
||||
|
||||
args[1] = src
|
||||
|
||||
@@ -281,10 +276,11 @@
|
||||
var/datum/old_parent = parent
|
||||
PreTransfer()
|
||||
_RemoveFromParent()
|
||||
parent = null
|
||||
SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
|
||||
/datum/proc/TakeComponent(datum/component/target)
|
||||
if(!target)
|
||||
if(!target || target.parent == src)
|
||||
return
|
||||
if(target.parent)
|
||||
target.RemoveComponent()
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
magic = _magic
|
||||
holy = _holy
|
||||
|
||||
/datum/component/anti_magic/proc/on_equip(mob/equipper, slot)
|
||||
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/can_protect, TRUE)
|
||||
|
||||
/datum/component/anti_magic/proc/on_drop(mob/user)
|
||||
/datum/component/anti_magic/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOB_RECEIVE_MAGIC)
|
||||
|
||||
/datum/component/anti_magic/proc/can_protect(_magic, _holy, list/protection_sources)
|
||||
/datum/component/anti_magic/proc/can_protect(datum/source, _magic, _holy, list/protection_sources)
|
||||
if((_magic && magic) || (_holy && holy))
|
||||
protection_sources += parent
|
||||
return COMPONENT_BLOCK_MAGIC
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
for(var/I in other_archdrops)
|
||||
_archdrops[I] += other_archdrops[I]
|
||||
|
||||
/datum/component/archaeology/proc/Dig(obj/item/I, mob/living/user)
|
||||
/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user)
|
||||
if(dug)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
return
|
||||
@@ -72,7 +72,7 @@
|
||||
if(callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/component/archaeology/proc/SingDig(S, current_size)
|
||||
/datum/component/archaeology/proc/SingDig(datum/source, S, current_size)
|
||||
switch(current_size)
|
||||
if(STAGE_THREE)
|
||||
if(prob(30))
|
||||
@@ -84,7 +84,7 @@
|
||||
if(current_size >= STAGE_FIVE && prob(70))
|
||||
gets_dug()
|
||||
|
||||
/datum/component/archaeology/proc/BombDig(severity, target)
|
||||
/datum/component/archaeology/proc/BombDig(datum/source, severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
var/obj/item/typecast = upgrade_item
|
||||
upgrade_name = initial(typecast.name)
|
||||
|
||||
/datum/component/armor_plate/proc/examine(mob/user)
|
||||
/datum/component/armor_plate/proc/examine(datum/source, mob/user)
|
||||
//upgrade_item could also be typecast here instead
|
||||
if(ismecha(parent))
|
||||
if(amount)
|
||||
@@ -45,7 +45,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It can be strengthened with up to [maxamount] [upgrade_name].</span>")
|
||||
|
||||
/datum/component/armor_plate/proc/applyplate(obj/item/I, mob/user, params)
|
||||
/datum/component/armor_plate/proc/applyplate(datum/source, obj/item/I, mob/user, params)
|
||||
if(!istype(I,upgrade_item))
|
||||
return
|
||||
if(amount >= maxamount)
|
||||
@@ -72,7 +72,7 @@
|
||||
to_chat(user, "<span class='info'>You strengthen [O], improving its resistance against melee attacks.</span>")
|
||||
|
||||
|
||||
/datum/component/armor_plate/proc/dropplates(force)
|
||||
/datum/component/armor_plate/proc/dropplates(datum/source, force)
|
||||
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))
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
|
||||
|
||||
/datum/component/caltrop/proc/Crossed(atom/movable/AM)
|
||||
/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM)
|
||||
var/atom/A = parent
|
||||
if(!A.has_gravity())
|
||||
return
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
target_turf = target
|
||||
START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
|
||||
|
||||
/datum/component/chasm/proc/Entered(atom/movable/AM)
|
||||
/datum/component/chasm/proc/Entered(datum/source, atom/movable/AM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
drop_stuff(AM)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/action)
|
||||
update_parent(index)
|
||||
|
||||
/datum/component/construction/proc/examine(mob/user)
|
||||
/datum/component/construction/proc/examine(datum/source, mob/user)
|
||||
if(desc)
|
||||
to_chat(user, desc)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
else
|
||||
update_parent(index)
|
||||
|
||||
/datum/component/construction/proc/action(obj/item/I, mob/living/user)
|
||||
/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user)
|
||||
return check_step(I, user)
|
||||
|
||||
/datum/component/construction/proc/update_index(diff)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
var/first_dir // This only stores the dir arg from init
|
||||
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color))
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
first_dir = _dir
|
||||
description = _description
|
||||
@@ -38,13 +38,14 @@
|
||||
remove()
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
|
||||
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)
|
||||
if(!_icon || !_icon_state)
|
||||
return FALSE
|
||||
// It has to be made from an image or dir breaks because of a byond bug
|
||||
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
|
||||
pic = new(temp_image)
|
||||
pic.color = _color
|
||||
pic.alpha = _alpha
|
||||
return TRUE
|
||||
|
||||
/datum/component/decal/proc/apply(atom/thing)
|
||||
@@ -59,16 +60,16 @@
|
||||
if(isitem(master))
|
||||
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/component/decal/proc/rotate_react(old_dir, new_dir)
|
||||
/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
remove()
|
||||
pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/clean_react(strength)
|
||||
/datum/component/decal/proc/clean_react(datum/source, strength)
|
||||
if(strength >= cleanable)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/decal/proc/examine(mob/user)
|
||||
to_chat(user, description)
|
||||
/datum/component/decal/proc/examine(datum/source, mob/user)
|
||||
to_chat(user, description)
|
||||
@@ -32,7 +32,7 @@
|
||||
blood_splatter_appearances[index] = pic
|
||||
return TRUE
|
||||
|
||||
/datum/component/decal/blood/proc/get_examine_name(mob/user, list/override)
|
||||
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
|
||||
var/atom/A = parent
|
||||
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
|
||||
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
|
||||
|
||||
/datum/component/earhealing/proc/equippedChanged(mob/living/carbon/user, slot)
|
||||
/datum/component/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
|
||||
if (slot == SLOT_EARS && istype(user))
|
||||
if (!wearer)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
valid_slots = _valid_slots
|
||||
callback = CALLBACK(src, .proc/reducebang)
|
||||
|
||||
/datum/component/wearertargeting/earprotection/proc/reducebang(list/reflist)
|
||||
/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist)
|
||||
reflist[1]--
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
|
||||
|
||||
/datum/component/edit_complainer/proc/var_edit_react(list/arguments)
|
||||
/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments)
|
||||
var/atom/movable/master = parent
|
||||
master.say(pick(say_lines))
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
flags = _flags
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
|
||||
|
||||
/datum/component/empprotection/proc/getEmpFlags(severity)
|
||||
/datum/component/empprotection/proc/getEmpFlags(datum/source, severity)
|
||||
return flags
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/datum/component/footstep
|
||||
var/steps = 0
|
||||
var/volume
|
||||
var/e_range
|
||||
|
||||
/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
volume = volume_
|
||||
e_range = e_range_
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep)
|
||||
|
||||
/datum/component/footstep/proc/play_footstep()
|
||||
var/turf/open/T = get_turf(parent)
|
||||
if(!istype(T))
|
||||
return
|
||||
var/mob/living/LM = parent
|
||||
var/v = volume
|
||||
var/e = e_range
|
||||
if(!T.footstep || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing)
|
||||
return
|
||||
if(iscarbon(LM))
|
||||
var/mob/living/carbon/C = LM
|
||||
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
|
||||
return
|
||||
if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK)
|
||||
v /= 2
|
||||
e -= 5
|
||||
steps++
|
||||
if(steps >= 6)
|
||||
steps = 0
|
||||
if(steps % 2)
|
||||
return
|
||||
if(!LM.has_gravity(T) && steps != 0) // don't need to step as often when you hop around
|
||||
return
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
@@ -1,8 +1,20 @@
|
||||
/datum/component/forced_gravity
|
||||
var/gravity = 1
|
||||
var/gravity
|
||||
var/ignore_space = FALSE //If forced gravity should also work on space turfs
|
||||
|
||||
/datum/component/forced_gravity/Initialize(forced_value = 1)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
gravity = forced_value
|
||||
RegisterSignal(COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check)
|
||||
if(isturf(parent))
|
||||
RegisterSignal(COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
|
||||
|
||||
gravity = forced_value
|
||||
|
||||
/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs)
|
||||
if(!ignore_space && isspaceturf(location))
|
||||
return
|
||||
gravs += gravity
|
||||
|
||||
/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
|
||||
return gravity_check(parent, gravs)
|
||||
@@ -40,7 +40,7 @@
|
||||
fibers = null
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/clean_act(strength)
|
||||
/datum/component/forensics/proc/clean_act(datum/source, strength)
|
||||
if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
|
||||
wipe_fingerprints()
|
||||
if(strength >= CLEAN_STRENGTH_BLOOD)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
expire_time = world.time + expire_in
|
||||
QDEL_IN(src, expire_in)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_COLLIDE, .proc/try_infect_collide)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/try_infect_collide)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/try_infect_crossed)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, .proc/try_infect_attack_zone)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/try_infect_attack)
|
||||
@@ -22,20 +22,20 @@
|
||||
RegisterSignal(parent, COMSIG_FOOD_EATEN, .proc/try_infect_eat)
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean)
|
||||
|
||||
/datum/component/infective/proc/try_infect_eat(mob/living/eater, mob/living/feeder)
|
||||
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
|
||||
for(var/V in diseases)
|
||||
eater.ForceContractDisease(V)
|
||||
try_infect(feeder, BODY_ZONE_L_ARM)
|
||||
|
||||
/datum/component/infective/proc/clean(clean_strength)
|
||||
/datum/component/infective/proc/clean(datum/source, clean_strength)
|
||||
if(clean_strength >= min_clean_strength)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/infective/proc/try_infect_buckle(mob/M, force)
|
||||
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
|
||||
if(isliving(M))
|
||||
try_infect(M)
|
||||
|
||||
/datum/component/infective/proc/try_infect_collide(atom/A)
|
||||
/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
|
||||
var/atom/movable/P = parent
|
||||
if(P.throwing)
|
||||
//this will be handled by try_infect_impact_zone()
|
||||
@@ -43,19 +43,19 @@
|
||||
if(isliving(A))
|
||||
try_infect(A)
|
||||
|
||||
/datum/component/infective/proc/try_infect_impact_zone(mob/living/target, hit_zone)
|
||||
/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
|
||||
try_infect(target, hit_zone)
|
||||
|
||||
/datum/component/infective/proc/try_infect_attack_zone(mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
try_infect(user, BODY_ZONE_L_ARM)
|
||||
try_infect(target, hit_zone)
|
||||
|
||||
/datum/component/infective/proc/try_infect_attack(mob/living/target, mob/living/user)
|
||||
/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user)
|
||||
if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone
|
||||
try_infect(target)
|
||||
try_infect(user, BODY_ZONE_L_ARM)
|
||||
|
||||
/datum/component/infective/proc/try_infect_equipped(mob/living/L, slot)
|
||||
/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
|
||||
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()
|
||||
@@ -69,7 +69,7 @@
|
||||
var/obj/item/I = parent
|
||||
I.permeability_coefficient = old_permeability
|
||||
|
||||
/datum/component/infective/proc/try_infect_crossed(atom/movable/M)
|
||||
/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/M)
|
||||
if(isliving(M))
|
||||
try_infect(M, BODY_ZONE_PRECISE_L_FOOT)
|
||||
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/on_attack)
|
||||
|
||||
/datum/component/jousting/proc/on_equip(mob/user, slot)
|
||||
/datum/component/jousting/proc/on_equip(datum/source, mob/user, slot)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE)
|
||||
current_holder = user
|
||||
|
||||
/datum/component/jousting/proc/on_drop(mob/user)
|
||||
/datum/component/jousting/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
current_holder = null
|
||||
current_direction = NONE
|
||||
current_tile_charge = 0
|
||||
|
||||
/datum/component/jousting/proc/on_attack(mob/living/target, mob/user)
|
||||
/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user)
|
||||
if(user != current_holder)
|
||||
return
|
||||
var/current = current_tile_charge
|
||||
@@ -58,7 +58,7 @@
|
||||
if(length(msg))
|
||||
user.visible_message("<span class='danger'>[msg]!</span>")
|
||||
|
||||
/datum/component/jousting/proc/mob_move(newloc, dir)
|
||||
/datum/component/jousting/proc/mob_move(datum/source, newloc, dir)
|
||||
if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled))))
|
||||
return
|
||||
if(dir != current_direction)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
var/knockoff_chance = 100 //Chance to knockoff
|
||||
var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed
|
||||
var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed
|
||||
var/datum/component/redirect/disarm_redirect
|
||||
|
||||
/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
|
||||
if(!isitem(parent))
|
||||
@@ -33,7 +32,7 @@
|
||||
|
||||
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(mob/living/carbon/human/H,slot)
|
||||
/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot)
|
||||
if(!istype(H))
|
||||
return
|
||||
if(slots_knockoffable && !(slot in slots_knockoffable))
|
||||
@@ -41,5 +40,5 @@
|
||||
return
|
||||
RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
|
||||
|
||||
/datum/component/knockoff/proc/OnDropped(mob/living/M)
|
||||
/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M)
|
||||
UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
|
||||
@@ -1,23 +1,34 @@
|
||||
/datum/component/magnetic_catch/Initialize()
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSS, .proc/uncross_react)
|
||||
else
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXIT, .proc/exit_react)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/crossed_react)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/uncrossed_react)
|
||||
for(var/i in get_turf(parent))
|
||||
if(i == parent)
|
||||
continue
|
||||
RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
|
||||
else
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/entered_react)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/exited_react)
|
||||
for(var/i in parent)
|
||||
RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
|
||||
|
||||
/datum/component/magnetic_catch/proc/uncross_react(atom/movable/thing)
|
||||
if(!thing.throwing || thing.throwing.thrower)
|
||||
return
|
||||
qdel(thing.throwing)
|
||||
return COMPONENT_MOVABLE_BLOCK_UNCROSS
|
||||
/datum/component/magnetic_catch/proc/examine(datum/source, mob/user)
|
||||
to_chat(user, "It has been installed with inertia dampening to prevent coffee spills.")
|
||||
|
||||
/datum/component/magnetic_catch/proc/exit_react(atom/movable/thing, atom/newloc)
|
||||
if(!thing.throwing || thing.throwing.thrower)
|
||||
return
|
||||
qdel(thing.throwing)
|
||||
return COMPONENT_ATOM_BLOCK_EXIT
|
||||
/datum/component/magnetic_catch/proc/crossed_react(datum/source, atom/movable/thing)
|
||||
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
|
||||
|
||||
/datum/component/magnetic_catch/proc/examine(mob/user)
|
||||
to_chat(user, "It has been installed with inertia dampening to prevent coffee spills.")
|
||||
/datum/component/magnetic_catch/proc/uncrossed_react(datum/source, atom/movable/thing)
|
||||
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
|
||||
|
||||
/datum/component/magnetic_catch/proc/entered_react(datum/source, atom/movable/thing, atom/oldloc)
|
||||
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
|
||||
|
||||
/datum/component/magnetic_catch/proc/exited_react(datum/source, atom/movable/thing, atom/newloc)
|
||||
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
|
||||
|
||||
/datum/component/magnetic_catch/proc/throw_react(datum/source, list/arguments)
|
||||
return COMPONENT_CANCEL_THROW
|
||||
@@ -27,8 +27,13 @@
|
||||
max_amount = max(0, max_amt)
|
||||
show_on_examine = _show_on_examine
|
||||
disable_attackby = _disable_attackby
|
||||
|
||||
if(allowed_types)
|
||||
allowed_typecache = typecacheof(allowed_types)
|
||||
if(ispath(allowed_types) && allowed_types == /obj/item/stack)
|
||||
allowed_typecache = GLOB.typecache_stack
|
||||
else
|
||||
allowed_typecache = typecacheof(allowed_types)
|
||||
|
||||
precondition = _precondition
|
||||
after_insert = _after_insert
|
||||
|
||||
@@ -44,7 +49,7 @@
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
|
||||
/datum/component/material_container/proc/OnExamine(mob/user)
|
||||
/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
|
||||
if(show_on_examine)
|
||||
for(var/I in materials)
|
||||
var/datum/material/M = materials[I]
|
||||
@@ -52,7 +57,7 @@
|
||||
if(amt)
|
||||
to_chat(user, "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>")
|
||||
|
||||
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
|
||||
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
|
||||
var/list/tc = allowed_typecache
|
||||
if(disable_attackby)
|
||||
return
|
||||
@@ -242,24 +247,25 @@
|
||||
//For spawning mineral sheets; internal use only
|
||||
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
|
||||
if(!M.sheet_type)
|
||||
return FALSE
|
||||
if(sheet_amt > 0)
|
||||
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
new M.sheet_type(get_turf(parent), MAX_STACK_SIZE)
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
|
||||
var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(parent), sheet_amt)
|
||||
if(target)
|
||||
s.forceMove(target)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
return count
|
||||
return FALSE
|
||||
return 0
|
||||
if(sheet_amt <= 0)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
target = get_turf(parent)
|
||||
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
new M.sheet_type(target, MAX_STACK_SIZE)
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
if(sheet_amt >= 1)
|
||||
new M.sheet_type(target, sheet_amt)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
return count
|
||||
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
|
||||
if(materials[id])
|
||||
|
||||
+102
-71
@@ -1,3 +1,6 @@
|
||||
#define MINOR_INSANITY_PEN 5
|
||||
#define MAJOR_INSANITY_PEN 10
|
||||
|
||||
/datum/component/mood
|
||||
var/mood //Real happiness
|
||||
var/sanity = 100 //Current sanity
|
||||
@@ -5,25 +8,32 @@
|
||||
var/mood_level = 5 //To track what stage of moodies they're on
|
||||
var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets
|
||||
var/datum/mood_event/list/mood_events = list()
|
||||
var/mob/living/owner
|
||||
var/datum/looping_sound/reverse_bear_trap/slow/soundloop //Insanity ticking
|
||||
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
|
||||
var/holdmyinsanityeffect = 0 //before we edit our sanity lets take a look
|
||||
var/obj/screen/mood/screen_obj
|
||||
|
||||
/datum/component/mood/Initialize()
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
START_PROCESSING(SSmood, src)
|
||||
owner = parent
|
||||
soundloop = new(list(owner), FALSE, TRUE)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
|
||||
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
|
||||
RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/update_beauty)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
|
||||
var/mob/living/owner = parent
|
||||
if(owner.hud_used)
|
||||
modify_hud()
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
hud.show_hud(hud.hud_version)
|
||||
|
||||
/datum/component/mood/Destroy()
|
||||
STOP_PROCESSING(SSmood, src)
|
||||
QDEL_NULL(soundloop)
|
||||
unmodify_hud()
|
||||
return ..()
|
||||
|
||||
/datum/component/mood/proc/print_mood()
|
||||
/datum/component/mood/proc/print_mood(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
|
||||
msg += "<span class='notice'>My mental status: </span>" //Long term
|
||||
switch(sanity)
|
||||
@@ -67,8 +77,8 @@
|
||||
var/datum/mood_event/event = mood_events[i]
|
||||
msg += event.description
|
||||
else
|
||||
msg += "<span class='nicegreen'>Nothing special has happened to me lately!<span>\n"
|
||||
to_chat(owner, msg)
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
|
||||
to_chat(user || parent, msg)
|
||||
|
||||
/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed
|
||||
mood = 0
|
||||
@@ -104,41 +114,25 @@
|
||||
|
||||
|
||||
/datum/component/mood/proc/update_mood_icon()
|
||||
var/mob/living/owner = parent
|
||||
if(owner.client && owner.hud_used)
|
||||
if(sanity < 25)
|
||||
owner.hud_used.mood.icon_state = "mood_insane"
|
||||
screen_obj.icon_state = "mood_insane"
|
||||
else
|
||||
owner.hud_used.mood.icon_state = "mood[mood_level]"
|
||||
screen_obj.icon_state = "mood[mood_level]"
|
||||
|
||||
/datum/component/mood/process() //Called on SSmood process
|
||||
switch(sanity)
|
||||
if(SANITY_INSANE to SANITY_CRAZY)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 3)
|
||||
update_mood_icon()
|
||||
if(prob(7))
|
||||
owner.playsound_local(null, pick(CREEPY_SOUNDS), 40, 1)
|
||||
soundloop.start()
|
||||
if(SANITY_INSANE to SANITY_UNSTABLE)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 2)
|
||||
if(prob(3))
|
||||
owner.playsound_local(null, pick(CREEPY_SOUNDS), 20, 1)
|
||||
soundloop.stop()
|
||||
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 1)
|
||||
soundloop.stop()
|
||||
if(SANITY_DISTURBED to INFINITY)
|
||||
owner.clear_fullscreen("depression")
|
||||
soundloop.stop()
|
||||
var/mob/living/owner = parent
|
||||
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
DecreaseSanity(0.2, 0)
|
||||
DecreaseSanity(0.2)
|
||||
if(2)
|
||||
DecreaseSanity(0.125, 25)
|
||||
DecreaseSanity(0.125, SANITY_CRAZY)
|
||||
if(3)
|
||||
DecreaseSanity(0.075, 50)
|
||||
DecreaseSanity(0.075, SANITY_UNSTABLE)
|
||||
if(4)
|
||||
DecreaseSanity(0.025, 75)
|
||||
DecreaseSanity(0.025, SANITY_DISTURBED)
|
||||
if(5)
|
||||
IncreaseSanity(0.1)
|
||||
if(6)
|
||||
@@ -146,42 +140,60 @@
|
||||
if(7)
|
||||
IncreaseSanity(0.20)
|
||||
if(8)
|
||||
IncreaseSanity(0.25, 125)
|
||||
IncreaseSanity(0.25, SANITY_GREAT)
|
||||
if(9)
|
||||
IncreaseSanity(0.4, 125)
|
||||
IncreaseSanity(0.4, SANITY_GREAT)
|
||||
|
||||
if(insanity_effect != holdmyinsanityeffect)
|
||||
if(insanity_effect > holdmyinsanityeffect)
|
||||
owner.crit_threshold += (insanity_effect - holdmyinsanityeffect)
|
||||
else
|
||||
owner.crit_threshold -= (holdmyinsanityeffect - insanity_effect)
|
||||
|
||||
if(owner.has_trait(TRAIT_DEPRESSION))
|
||||
if(prob(0.05))
|
||||
add_event("depression", /datum/mood_event/depression)
|
||||
clear_event("jolly")
|
||||
add_event(null, "depression", /datum/mood_event/depression)
|
||||
clear_event(null, "jolly")
|
||||
if(owner.has_trait(TRAIT_JOLLY))
|
||||
if(prob(0.05))
|
||||
add_event("jolly", /datum/mood_event/jolly)
|
||||
clear_event("depression")
|
||||
add_event(null, "jolly", /datum/mood_event/jolly)
|
||||
clear_event(null, "depression")
|
||||
|
||||
var/area/A = get_area(owner)
|
||||
if(A)
|
||||
update_beauty(A)
|
||||
holdmyinsanityeffect = insanity_effect
|
||||
|
||||
HandleNutrition(owner)
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, limit = 0)
|
||||
if(sanity < limit) //This might make KevinZ stop fucking pinging me.
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
|
||||
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
|
||||
IncreaseSanity(0.5)
|
||||
else
|
||||
sanity = max(0, sanity - amount)
|
||||
sanity = max(minimum, sanity - amount)
|
||||
if(sanity < SANITY_UNSTABLE)
|
||||
if(sanity < SANITY_CRAZY)
|
||||
insanity_effect = (MAJOR_INSANITY_PEN)
|
||||
else
|
||||
insanity_effect = (MINOR_INSANITY_PEN)
|
||||
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, limit = 99)
|
||||
if(sanity > limit)
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
|
||||
if(sanity > maximum)
|
||||
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
|
||||
else
|
||||
sanity = min(limit, sanity + amount)
|
||||
sanity = min(maximum, sanity + amount)
|
||||
if(sanity > SANITY_CRAZY)
|
||||
if(sanity > SANITY_UNSTABLE)
|
||||
insanity_effect = 0
|
||||
else
|
||||
insanity_effect = MINOR_INSANITY_PEN
|
||||
|
||||
/datum/component/mood/proc/add_event(category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
|
||||
/datum/component/mood/proc/add_event(datum/source, category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
|
||||
var/datum/mood_event/the_event
|
||||
if(mood_events[category])
|
||||
the_event = mood_events[category]
|
||||
if(the_event.type != type)
|
||||
clear_event(category)
|
||||
clear_event(null, category)
|
||||
else
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
return 0 //Don't have to update the event.
|
||||
the_event = new type(src, param)
|
||||
|
||||
@@ -189,9 +201,9 @@
|
||||
update_mood()
|
||||
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, category), the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
/datum/component/mood/proc/clear_event(category)
|
||||
/datum/component/mood/proc/clear_event(datum/source, category)
|
||||
var/datum/mood_event/event = mood_events[category]
|
||||
if(!event)
|
||||
return 0
|
||||
@@ -200,22 +212,41 @@
|
||||
qdel(event)
|
||||
update_mood()
|
||||
|
||||
/datum/component/mood/proc/update_beauty(area/A)
|
||||
if(A.outdoors) //if we're outside, we don't care.
|
||||
clear_event("area_beauty")
|
||||
return FALSE
|
||||
switch(A.beauty)
|
||||
if(-INFINITY to BEAUTY_LEVEL_HORRID)
|
||||
add_event("area_beauty", /datum/mood_event/horridroom)
|
||||
if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD)
|
||||
add_event("area_beauty", /datum/mood_event/badroom)
|
||||
if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_MEH)
|
||||
add_event("area_beauty", /datum/mood_event/mehroom)
|
||||
if(BEAUTY_LEVEL_MEH to BEAUTY_LEVEL_DECENT)
|
||||
clear_event("area_beauty")
|
||||
if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD)
|
||||
add_event("area_beauty", /datum/mood_event/decentroom)
|
||||
if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT)
|
||||
add_event("area_beauty", /datum/mood_event/goodroom)
|
||||
if(BEAUTY_LEVEL_GREAT to INFINITY)
|
||||
add_event("area_beauty", /datum/mood_event/greatroom)
|
||||
/datum/component/mood/proc/modify_hud(datum/source)
|
||||
var/mob/living/owner = parent
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
screen_obj = new
|
||||
hud.infodisplay += screen_obj
|
||||
RegisterSignal(hud, COMSIG_PARENT_QDELETED, .proc/unmodify_hud)
|
||||
RegisterSignal(screen_obj, COMSIG_CLICK, .proc/hud_click)
|
||||
|
||||
/datum/component/mood/proc/unmodify_hud(datum/source)
|
||||
if(!screen_obj)
|
||||
return
|
||||
var/mob/living/owner = parent
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
if(hud && hud.infodisplay)
|
||||
hud.infodisplay -= screen_obj
|
||||
QDEL_NULL(screen_obj)
|
||||
|
||||
/datum/component/mood/proc/hud_click(datum/source, location, control, params, mob/user)
|
||||
print_mood(user)
|
||||
|
||||
|
||||
/datum/component/mood/proc/HandleNutrition(mob/living/L)
|
||||
switch(L.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
add_event(null, "nutrition", /datum/mood_event/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
add_event(null, "nutrition", /datum/mood_event/wellfed)
|
||||
if( NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
add_event(null, "nutrition", /datum/mood_event/fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
clear_event(null, "nutrition")
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
add_event(null, "nutrition", /datum/mood_event/hungry)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
add_event(null, "nutrition", /datum/mood_event/starving)
|
||||
|
||||
#undef MINOR_INSANITY_PEN
|
||||
#undef MAJOR_INSANITY_PEN
|
||||
|
||||
@@ -90,12 +90,12 @@
|
||||
|
||||
/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, list/arguments)
|
||||
if(new_nanites)
|
||||
adjust_nanites(new_nanites.nanite_volume)
|
||||
adjust_nanites(null, new_nanites.nanite_volume)
|
||||
else
|
||||
adjust_nanites(arguments[1]) //just add to the nanite volume
|
||||
adjust_nanites(null, arguments[1]) //just add to the nanite volume
|
||||
|
||||
/datum/component/nanites/process()
|
||||
adjust_nanites(regen_rate)
|
||||
adjust_nanites(null, regen_rate)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_process()
|
||||
@@ -105,7 +105,7 @@
|
||||
next_sync = world.time + NANITE_SYNC_DELAY
|
||||
|
||||
//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/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
|
||||
/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
|
||||
var/list/programs_to_remove = programs.Copy()
|
||||
var/list/programs_to_add = source.programs.Copy()
|
||||
for(var/X in programs)
|
||||
@@ -122,7 +122,7 @@
|
||||
qdel(X)
|
||||
for(var/X in programs_to_add)
|
||||
var/datum/nanite_program/SNP = X
|
||||
add_program(SNP.copy())
|
||||
add_program(null, SNP.copy())
|
||||
|
||||
/datum/component/nanites/proc/cloud_sync()
|
||||
if(!cloud_id)
|
||||
@@ -131,9 +131,9 @@
|
||||
if(backup)
|
||||
var/datum/component/nanites/cloud_copy = backup.nanites
|
||||
if(cloud_copy)
|
||||
sync(cloud_copy)
|
||||
sync(null, cloud_copy)
|
||||
|
||||
/datum/component/nanites/proc/add_program(datum/nanite_program/new_program, datum/nanite_program/source_program)
|
||||
/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
if(NP.unique && NP.type == new_program.type)
|
||||
@@ -149,10 +149,10 @@
|
||||
/datum/component/nanites/proc/consume_nanites(amount, force = FALSE)
|
||||
if(!force && safety_threshold && (nanite_volume - amount < safety_threshold))
|
||||
return FALSE
|
||||
adjust_nanites(-amount)
|
||||
adjust_nanites(null, -amount)
|
||||
return (nanite_volume > 0)
|
||||
|
||||
/datum/component/nanites/proc/adjust_nanites(amount)
|
||||
/datum/component/nanites/proc/adjust_nanites(datum/source, amount)
|
||||
nanite_volume = CLAMP(nanite_volume + amount, 0, max_nanites)
|
||||
if(nanite_volume <= 0) //oops we ran out
|
||||
qdel(src)
|
||||
@@ -168,39 +168,39 @@
|
||||
nanite_percent = CLAMP(CEILING(nanite_percent, 10), 10, 100)
|
||||
holder.icon_state = "nanites[nanite_percent]"
|
||||
|
||||
/datum/component/nanites/proc/on_emp(severity)
|
||||
/datum/component/nanites/proc/on_emp(datum/source, severity)
|
||||
nanite_volume *= (rand(0.60, 0.90)) //Lose 10-40% of nanites
|
||||
adjust_nanites(-(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
if(prob(40/severity))
|
||||
cloud_id = 0
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_emp(severity)
|
||||
|
||||
/datum/component/nanites/proc/on_shock(shock_damage)
|
||||
/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
|
||||
nanite_volume *= (rand(0.45, 0.80)) //Lose 20-55% of nanites
|
||||
adjust_nanites(-(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_shock(shock_damage)
|
||||
|
||||
/datum/component/nanites/proc/on_minor_shock()
|
||||
adjust_nanites(-(rand(5, 15))) //Lose 5-15 flat nanite volume
|
||||
/datum/component/nanites/proc/on_minor_shock(datum/source)
|
||||
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/on_death(gibbed)
|
||||
/datum/component/nanites/proc/on_death(datum/source, gibbed)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_death(gibbed)
|
||||
|
||||
/datum/component/nanites/proc/on_hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
/datum/component/nanites/proc/on_hear(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
|
||||
/datum/component/nanites/proc/receive_signal(code, source = "an unidentified source")
|
||||
/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source")
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.receive_signal(code, source)
|
||||
@@ -209,7 +209,7 @@
|
||||
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes))
|
||||
qdel(src) //bodytype no longer sustains nanites
|
||||
|
||||
/datum/component/nanites/proc/check_access(obj/O)
|
||||
/datum/component/nanites/proc/check_access(datum/source, obj/O)
|
||||
for(var/datum/nanite_program/triggered/access/access_program in programs)
|
||||
if(access_program.activated)
|
||||
return O.check_access_list(access_program.access)
|
||||
@@ -217,19 +217,19 @@
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/datum/component/nanites/proc/set_volume(amount)
|
||||
/datum/component/nanites/proc/set_volume(datum/source, amount)
|
||||
nanite_volume = CLAMP(amount, 0, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_max_volume(amount)
|
||||
/datum/component/nanites/proc/set_max_volume(datum/source, amount)
|
||||
max_nanites = max(1, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_cloud(amount)
|
||||
/datum/component/nanites/proc/set_cloud(datum/source, amount)
|
||||
cloud_id = CLAMP(amount, 0, 100)
|
||||
|
||||
/datum/component/nanites/proc/set_safety(amount)
|
||||
/datum/component/nanites/proc/set_safety(datum/source, amount)
|
||||
safety_threshold = CLAMP(amount, 0, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_regen(amount)
|
||||
/datum/component/nanites/proc/set_regen(datum/source, amount)
|
||||
regen_rate = amount
|
||||
|
||||
/datum/component/nanites/proc/confirm_nanites()
|
||||
@@ -243,10 +243,10 @@
|
||||
nanite_data["safety_threshold"] = safety_threshold
|
||||
nanite_data["stealth"] = stealth
|
||||
|
||||
/datum/component/nanites/proc/get_programs(list/nanite_programs)
|
||||
/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
|
||||
nanite_programs |= programs
|
||||
|
||||
/datum/component/nanites/proc/nanite_scan(mob/user, full_scan)
|
||||
/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
|
||||
if(!full_scan)
|
||||
if(!stealth)
|
||||
to_chat(user, "<span class='notice'><b>Nanites Detected</b></span>")
|
||||
@@ -268,7 +268,7 @@
|
||||
to_chat(user, "<span class='info'><b>[NP.name]</b> | [NP.activated ? "Active" : "Inactive"]</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/component/nanites/proc/nanite_ui_data(list/data, scan_level)
|
||||
/datum/component/nanites/proc/nanite_ui_data(datum/source, list/data, scan_level)
|
||||
data["has_nanites"] = TRUE
|
||||
data["nanite_volume"] = nanite_volume
|
||||
data["regen_rate"] = regen_rate
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/atom/A = parent
|
||||
A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint)
|
||||
|
||||
/datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
if(!istype(spraycan) || user.a_intent == INTENT_HARM)
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/datum/component/rad_insulation // Yes, this really is just a component to add some vars
|
||||
/datum/component/rad_insulation
|
||||
var/amount // Multiplier for radiation strength passing through
|
||||
var/protects // Does this protect things in its contents from being affected?
|
||||
var/contamination_proof // Can this object be contaminated?
|
||||
|
||||
/datum/component/rad_insulation/Initialize(_amount=RAD_MEDIUM_INSULATION, _protects=TRUE, _contamination_proof=TRUE)
|
||||
/datum/component/rad_insulation/Initialize(_amount=RAD_MEDIUM_INSULATION, protects=TRUE, contamination_proof=TRUE)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
if(protects) // Does this protect things in its contents from being affected?
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_PROBE, .proc/rad_probe_react)
|
||||
if(contamination_proof) // Can this object be contaminated?
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_CONTAMINATING, .proc/rad_contaminating)
|
||||
if(_amount != 1) // If it's 1 it wont have any impact on radiation passing through anyway
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_WAVE_PASSING, .proc/rad_pass)
|
||||
|
||||
amount = _amount
|
||||
protects = _protects
|
||||
contamination_proof = _contamination_proof
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_probe_react(datum/source)
|
||||
return COMPONENT_BLOCK_RADIATION
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_contaminating(datum/source, strength)
|
||||
return COMPONENT_BLOCK_CONTAMINATION
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_pass(datum/source, datum/radiation_wave/wave, width)
|
||||
wave.intensity = wave.intensity*(1-((1-amount)/width)) // The further out the rad wave goes the less it's affected by insulation (larger width)
|
||||
@@ -58,7 +58,7 @@
|
||||
else
|
||||
strength = max(strength, arguments[1])
|
||||
|
||||
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
|
||||
/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing)
|
||||
var/atom/master = parent
|
||||
var/list/out = list()
|
||||
if(get_dist(master, user) <= 1)
|
||||
@@ -74,7 +74,7 @@
|
||||
out += "."
|
||||
to_chat(user, out.Join())
|
||||
|
||||
/datum/component/radioactive/proc/rad_attack(atom/movable/target, mob/living/user)
|
||||
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
|
||||
radiation_pulse(parent, strength/20)
|
||||
target.rad_act(strength/2)
|
||||
strength -= strength / hl3_release_date
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
This component allows machines to connect remotely to a material container
|
||||
(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful
|
||||
fallback to a local material storage in case remote storage is unavailable, and
|
||||
handles linking back and forth.
|
||||
*/
|
||||
|
||||
/datum/component/remote_materials
|
||||
// Three possible states:
|
||||
// 1. silo exists, materials is parented to silo
|
||||
// 2. silo is null, materials is parented to parent
|
||||
// 3. silo is null, materials is null
|
||||
var/obj/machinery/ore_silo/silo
|
||||
var/datum/component/material_container/mat_container
|
||||
var/category
|
||||
var/allow_standalone
|
||||
var/local_size = INFINITY
|
||||
|
||||
/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE)
|
||||
if (!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.category = category
|
||||
src.allow_standalone = allow_standalone
|
||||
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
|
||||
|
||||
var/turf/T = get_turf(parent)
|
||||
if (force_connect || (mapload && is_station_level(T.z)))
|
||||
addtimer(CALLBACK(src, .proc/LateInitialize))
|
||||
else if (allow_standalone)
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/proc/LateInitialize()
|
||||
silo = GLOB.ore_silo_default
|
||||
if (silo)
|
||||
silo.connected += src
|
||||
mat_container = silo.GetComponent(/datum/component/material_container)
|
||||
else
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/Destroy()
|
||||
if (silo)
|
||||
silo.connected -= src
|
||||
silo.updateUsrDialog()
|
||||
silo = null
|
||||
mat_container = null
|
||||
else if (mat_container)
|
||||
// specify explicitly in case the other component is deleted first
|
||||
var/atom/P = parent
|
||||
mat_container.retrieve_all(P.drop_location())
|
||||
return ..()
|
||||
|
||||
/datum/component/remote_materials/proc/_MakeLocal()
|
||||
silo = null
|
||||
mat_container = parent.AddComponent(/datum/component/material_container,
|
||||
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC),
|
||||
local_size,
|
||||
FALSE,
|
||||
/obj/item/stack)
|
||||
|
||||
/datum/component/remote_materials/proc/set_local_size(size)
|
||||
local_size = size
|
||||
if (!silo && mat_container)
|
||||
mat_container.max_amount = size
|
||||
|
||||
// called if disconnected by ore silo UI or destruction
|
||||
/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo)
|
||||
if (!old_silo || silo != old_silo)
|
||||
return
|
||||
silo = null
|
||||
mat_container = null
|
||||
if (allow_standalone)
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
if (istype(I, /obj/item/multitool))
|
||||
var/obj/item/multitool/M = I
|
||||
if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
|
||||
if (silo == M.buffer)
|
||||
to_chat(user, "<span class='notice'>[parent] is already connected to [silo].</span>")
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
if (silo)
|
||||
silo.connected -= src
|
||||
silo.updateUsrDialog()
|
||||
else if (mat_container)
|
||||
mat_container.retrieve_all()
|
||||
qdel(mat_container)
|
||||
silo = M.buffer
|
||||
silo.connected += src
|
||||
silo.updateUsrDialog()
|
||||
mat_container = silo.GetComponent(/datum/component/material_container)
|
||||
to_chat(user, "<span class='notice'>You connect [parent] to [silo] from the multitool's buffer.</span>")
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
else if (silo && istype(I, /obj/item/stack))
|
||||
if (silo.remote_attackby(parent, user, I))
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/datum/component/remote_materials/proc/on_hold()
|
||||
return silo && silo.holds["[get_area(parent)]/[category]"]
|
||||
|
||||
/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
|
||||
if (silo)
|
||||
silo.silo_log(M || parent, action, amount, noun, mats)
|
||||
|
||||
/datum/component/remote_materials/proc/format_amount()
|
||||
if (mat_container)
|
||||
return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
|
||||
else
|
||||
return "0 / 0"
|
||||
@@ -26,11 +26,11 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_unbuckle(mob/living/M, force = FALSE)
|
||||
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
|
||||
restore_position(M)
|
||||
unequip_buckle_inhands(M)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(mob/living/M, force = FALSE)
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
|
||||
handle_vehicle_offsets()
|
||||
|
||||
/datum/component/riding/proc/handle_vehicle_layer()
|
||||
@@ -46,7 +46,7 @@
|
||||
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
|
||||
directional_vehicle_layers["[dir]"] = layer
|
||||
|
||||
/datum/component/riding/proc/vehicle_moved()
|
||||
/datum/component/riding/proc/vehicle_moved(datum/source)
|
||||
var/atom/movable/AM = parent
|
||||
for(var/i in AM.buckled_mobs)
|
||||
ride_check(i)
|
||||
|
||||
@@ -77,16 +77,16 @@
|
||||
remove_verbs()
|
||||
. = ..()
|
||||
|
||||
/datum/component/simple_rotation/proc/ExamineMessage(mob/user)
|
||||
/datum/component/simple_rotation/proc/ExamineMessage(datum/source, mob/user)
|
||||
if(rotation_flags & ROTATION_ALTCLICK)
|
||||
to_chat(user, "<span class='notice'>Alt-click to rotate it clockwise.</span>")
|
||||
|
||||
/datum/component/simple_rotation/proc/HandRot(mob/user, rotation = default_rotation_direction)
|
||||
/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
|
||||
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
|
||||
return
|
||||
BaseRot(user, rotation)
|
||||
|
||||
/datum/component/simple_rotation/proc/WrenchRot(obj/item/I, mob/living/user)
|
||||
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
|
||||
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
|
||||
return
|
||||
if(istype(I,/obj/item/wrench))
|
||||
|
||||
@@ -3,15 +3,31 @@
|
||||
|
||||
/datum/component/redirect
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
var/list/signals
|
||||
var/datum/callback/turfchangeCB
|
||||
|
||||
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback, flags=NONE)
|
||||
/datum/component/redirect/Initialize(list/_signals, flags=NONE)
|
||||
//It's not our job to verify the right signals are registered here, just do it.
|
||||
if(!LAZYLEN(signals) || !istype(_callback))
|
||||
warning("signals are [list2params(signals)], callback is [_callback]]")
|
||||
if(!LAZYLEN(_signals))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(flags & REDIRECT_TRANSFER_WITH_TURF && isturf(parent))
|
||||
RegisterSignal(parent, COMSIG_TURF_CHANGE, .proc/turf_change)
|
||||
RegisterSignal(parent, signals, _callback)
|
||||
// If they also want to listen to the turf change then we need to set it up so both callbacks run
|
||||
if(_signals[COMSIG_TURF_CHANGE])
|
||||
turfchangeCB = _signals[COMSIG_TURF_CHANGE]
|
||||
if(!istype(turfchangeCB))
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("Redirect components must be given instanced callbacks, not proc paths.")
|
||||
_signals[COMSIG_TURF_CHANGE] = CALLBACK(src, .proc/turf_change)
|
||||
|
||||
signals = _signals
|
||||
|
||||
/datum/component/redirect/proc/turf_change(path, new_baseturfs, flags, list/transfers)
|
||||
/datum/component/redirect/RegisterWithParent()
|
||||
for(var/signal in signals)
|
||||
RegisterSignal(parent, signal, signals[signal])
|
||||
|
||||
/datum/component/redirect/UnregisterFromParent()
|
||||
UnregisterSignal(parent, signals)
|
||||
|
||||
/datum/component/redirect/proc/turf_change(datum/source, path, new_baseturfs, flags, list/transfers)
|
||||
transfers += src
|
||||
return turfchangeCB?.InvokeAsync(arglist(args))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
callback = _callback
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
|
||||
|
||||
/datum/component/slippery/proc/Slip(atom/movable/AM)
|
||||
/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
|
||||
var/mob/victim = AM
|
||||
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback)
|
||||
callback.Invoke(victim)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/datum/component/spooky/Initialize()
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
|
||||
|
||||
/datum/component/spooky/proc/spectral_attack(mob/living/carbon/C, mob/user)
|
||||
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
|
||||
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))
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/datum/component/squeak
|
||||
var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1)
|
||||
var/list/override_squeak_sounds
|
||||
var/squeak_chance = 100
|
||||
var/volume = 30
|
||||
|
||||
// This is so shoes don't squeak every step
|
||||
var/steps = 0
|
||||
var/step_delay = 1
|
||||
|
||||
// This is to stop squeak spam from inhand usage
|
||||
var/last_use = 0
|
||||
var/use_delay = 20
|
||||
|
||||
/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
|
||||
if(isitem(parent))
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
if(istype(parent, /obj/item/clothing/shoes))
|
||||
RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
|
||||
|
||||
override_squeak_sounds = custom_sounds
|
||||
if(chance_override)
|
||||
squeak_chance = chance_override
|
||||
if(volume_override)
|
||||
volume = volume_override
|
||||
if(isnum(step_delay_override))
|
||||
step_delay = step_delay_override
|
||||
if(isnum(use_delay_override))
|
||||
use_delay = use_delay_override
|
||||
|
||||
/datum/component/squeak/proc/play_squeak()
|
||||
if(prob(squeak_chance))
|
||||
if(!override_squeak_sounds)
|
||||
playsound(parent, pickweight(default_squeak_sounds), volume, 1, -1)
|
||||
else
|
||||
playsound(parent, pickweight(override_squeak_sounds), volume, 1, -1)
|
||||
|
||||
/datum/component/squeak/proc/step_squeak()
|
||||
if(steps > step_delay)
|
||||
play_squeak()
|
||||
steps = 0
|
||||
else
|
||||
steps++
|
||||
|
||||
/datum/component/squeak/proc/play_squeak_crossed(atom/movable/AM)
|
||||
if(isitem(AM))
|
||||
var/obj/item/I = AM
|
||||
if(I.item_flags & ABSTRACT)
|
||||
return
|
||||
else if(istype(AM, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = AM
|
||||
if(P.original != parent)
|
||||
return
|
||||
var/atom/current_parent = parent
|
||||
if(isturf(current_parent.loc))
|
||||
play_squeak()
|
||||
|
||||
/datum/component/squeak/proc/use_squeak()
|
||||
if(last_use + use_delay < world.time)
|
||||
last_use = world.time
|
||||
play_squeak()
|
||||
|
||||
/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react, TRUE)
|
||||
|
||||
/datum/component/squeak/proc/on_drop(datum/source, mob/user)
|
||||
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)
|
||||
//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)
|
||||
//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()
|
||||
@@ -42,7 +42,7 @@
|
||||
var/turf/currentturf = get_turf(src)
|
||||
to_chat(get(parent, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
|
||||
var/turf/targetturf = relocate()
|
||||
log_game("[parent] has been moved out of bounds in [AREACOORD(currentturf)]. Moving it to [AREACOORD(targetturf)].")
|
||||
log_game("[parent] has been moved out of bounds in [loc_name(currentturf)]. Moving it to [loc_name(targetturf)].")
|
||||
if(inform_admins)
|
||||
message_admins("[parent] has been moved out of bounds in [ADMIN_VERBOSEJMP(currentturf)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
|
||||
|
||||
@@ -65,17 +65,17 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/component/stationloving/proc/check_deletion(force) // TRUE = interrupt deletion, FALSE = proceed with deletion
|
||||
/datum/component/stationloving/proc/check_deletion(datum/source, force) // TRUE = interrupt deletion, FALSE = proceed with deletion
|
||||
|
||||
var/turf/T = get_turf(parent)
|
||||
|
||||
if(inform_admins && force)
|
||||
message_admins("[parent] has been !!force deleted!! in [ADMIN_VERBOSEJMP(T)].")
|
||||
log_game("[parent] has been !!force deleted!! in [AREACOORD(T)].")
|
||||
log_game("[parent] has been !!force deleted!! in [loc_name(T)].")
|
||||
|
||||
if(!force && !allow_death)
|
||||
var/turf/targetturf = relocate()
|
||||
log_game("[parent] has been destroyed in [AREACOORD(T)]. Moving it to [AREACOORD(targetturf)].")
|
||||
log_game("[parent] has been destroyed in [loc_name(T)]. Moving it to [loc_name(targetturf)].")
|
||||
if(inform_admins)
|
||||
message_admins("[parent] has been destroyed in [ADMIN_VERBOSEJMP(T)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
|
||||
return TRUE
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
var/datum/component/storage/slave = i
|
||||
slave.refresh_mob_views()
|
||||
|
||||
/datum/component/storage/concrete/emp_act(severity)
|
||||
/datum/component/storage/concrete/emp_act(datum/source, severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/atom/real_location = real_location()
|
||||
@@ -90,13 +90,13 @@
|
||||
slaves -= S
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/proc/on_contents_del(atom/A)
|
||||
/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A)
|
||||
var/atom/real_location = parent
|
||||
if(A in real_location)
|
||||
usr = null
|
||||
remove_from_storage(A, null)
|
||||
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(disassembled)
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled)
|
||||
if(drop_all_on_deconstruct)
|
||||
do_quick_empty()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user)
|
||||
var/atom/A = parent
|
||||
if(A == W)
|
||||
if(A == W) //don't put yourself into yourself.
|
||||
return
|
||||
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding))
|
||||
matching -= A
|
||||
@@ -30,7 +30,7 @@
|
||||
for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
|
||||
ladder.ActivateAlmonds()
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [AREACOORD(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].")
|
||||
qdel(A)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -89,12 +89,13 @@
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
|
||||
RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
|
||||
RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_PRE_THROW, .proc/close_all)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all)
|
||||
|
||||
RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click)
|
||||
RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
|
||||
@@ -118,6 +119,7 @@
|
||||
return
|
||||
var/obj/item/I = parent
|
||||
modeswitch_action = new(I)
|
||||
RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger)
|
||||
if(I.obj_flags & IN_INVENTORY)
|
||||
var/mob/M = I.loc
|
||||
if(!istype(M))
|
||||
@@ -143,14 +145,24 @@
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
return master? master.real_location() : null
|
||||
|
||||
/datum/component/storage/proc/attack_self(mob/M)
|
||||
/datum/component/storage/proc/canreach_react(datum/source, list/next)
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!master)
|
||||
return
|
||||
. = COMPONENT_BLOCK_REACH
|
||||
next += master.parent
|
||||
for(var/i in master.slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
next += slave.parent
|
||||
|
||||
/datum/component/storage/proc/attack_self(datum/source, mob/M)
|
||||
if(locked)
|
||||
to_chat(M, "<span class='warning'>[parent] seems to be locked!</span>")
|
||||
return FALSE
|
||||
if((M.get_active_held_item() == parent) && allow_quick_empty)
|
||||
quick_empty(M)
|
||||
|
||||
/datum/component/storage/proc/preattack_intercept(obj/O, mob/M, params)
|
||||
/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
|
||||
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
|
||||
return FALSE
|
||||
. = COMPONENT_NO_ATTACK
|
||||
@@ -263,7 +275,7 @@
|
||||
remove_from_storage(I, _target)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/set_locked(new_state)
|
||||
/datum/component/storage/proc/set_locked(datum/source, new_state)
|
||||
locked = new_state
|
||||
if(locked)
|
||||
close_all()
|
||||
@@ -371,11 +383,11 @@
|
||||
close(M)
|
||||
. = TRUE //returns TRUE if any mobs actually got a close(M) call
|
||||
|
||||
/datum/component/storage/proc/emp_act(severity)
|
||||
/datum/component/storage/proc/emp_act(datum/source, severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(severity)
|
||||
master.emp_act(source, severity)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
|
||||
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
|
||||
@@ -405,7 +417,7 @@
|
||||
return FALSE
|
||||
return master._removal_reset(thing)
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(atom/movable/thing)
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
|
||||
_removal_reset(thing)
|
||||
refresh_mob_views()
|
||||
|
||||
@@ -447,7 +459,7 @@
|
||||
return FALSE
|
||||
|
||||
//This proc is called when you want to place an item into the storage item.
|
||||
/datum/component/storage/proc/attackby(obj/item/I, mob/M, params)
|
||||
/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params)
|
||||
if(istype(I, /obj/item/hand_labeler))
|
||||
var/obj/item/hand_labeler/labeler = I
|
||||
if(labeler.mode)
|
||||
@@ -476,13 +488,13 @@
|
||||
return real_location.contents.Copy()
|
||||
|
||||
//Abuses the fact that lists are just references, or something like that.
|
||||
/datum/component/storage/proc/signal_return_inv(list/interface, recursive = TRUE)
|
||||
/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE)
|
||||
if(!islist(interface))
|
||||
return FALSE
|
||||
interface |= return_inv(recursive)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/mousedrop_onto(atom/over_object, mob/M)
|
||||
/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
|
||||
set waitfor = FALSE
|
||||
. = COMPONENT_NO_MOUSEDROP
|
||||
var/atom/A = parent
|
||||
@@ -519,7 +531,7 @@
|
||||
if(force || M.CanReach(parent, view_only = TRUE))
|
||||
show_to(M)
|
||||
|
||||
/datum/component/storage/proc/mousedrop_receive(atom/movable/O, mob/M)
|
||||
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
|
||||
if(isitem(O))
|
||||
var/obj/item/I = O
|
||||
if(iscarbon(M) || isdrone(M))
|
||||
@@ -540,7 +552,7 @@
|
||||
if(real_location == I.loc)
|
||||
return FALSE //Means the item is already in the storage item
|
||||
if(locked)
|
||||
if(M)
|
||||
if(M && !stop_messages)
|
||||
host.add_fingerprint(M)
|
||||
to_chat(M, "<span class='warning'>[host] seems to be locked!</span>")
|
||||
return FALSE
|
||||
@@ -618,18 +630,18 @@
|
||||
var/obj/O = parent
|
||||
O.update_icon()
|
||||
|
||||
/datum/component/storage/proc/signal_insertion_attempt(obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
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(obj/item/I, mob/M, silent = FALSE)
|
||||
/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE)
|
||||
return can_be_inserted(I, silent, M)
|
||||
|
||||
/datum/component/storage/proc/show_to_ghost(mob/dead/observer/M)
|
||||
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
|
||||
return user_show_to_mob(M, TRUE)
|
||||
|
||||
/datum/component/storage/proc/signal_show_attempt(mob/showto, force = FALSE)
|
||||
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
|
||||
return user_show_to_mob(showto, force)
|
||||
|
||||
/datum/component/storage/proc/on_check()
|
||||
@@ -638,14 +650,14 @@
|
||||
/datum/component/storage/proc/check_locked()
|
||||
return locked
|
||||
|
||||
/datum/component/storage/proc/signal_take_type(type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
|
||||
/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
|
||||
if(!force)
|
||||
if(check_adjacent)
|
||||
if(!user || !user.CanReach(destination) || !user.CanReach(parent))
|
||||
return FALSE
|
||||
var/list/taking = typecache_filter_list(contents(), typecacheof(type))
|
||||
if(length(taking) > amount)
|
||||
taking.Cut(amount)
|
||||
if(taking.len > amount)
|
||||
taking.len = amount
|
||||
if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item.
|
||||
for(var/i in taking)
|
||||
if(remove_from_storage(i, destination))
|
||||
@@ -659,7 +671,7 @@
|
||||
var/atom/real_location = real_location()
|
||||
return max(0, max_items - real_location.contents.len)
|
||||
|
||||
/datum/component/storage/proc/signal_fill_type(type, amount = 20, force = FALSE)
|
||||
/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
|
||||
var/atom/real_location = real_location()
|
||||
if(!force)
|
||||
amount = min(remaining_space_items(), amount)
|
||||
@@ -668,7 +680,7 @@
|
||||
CHECK_TICK
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/on_attack_hand(mob/user)
|
||||
/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
|
||||
var/atom/A = parent
|
||||
if(!attack_hand_interact)
|
||||
return
|
||||
@@ -701,25 +713,25 @@
|
||||
else
|
||||
show_to(user)
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(mob/user)
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
var/atom/A = parent
|
||||
update_actions()
|
||||
for(var/mob/M in range(1, A))
|
||||
if(M.active_storage == src)
|
||||
close(M)
|
||||
|
||||
/datum/component/storage/proc/signal_take_obj(atom/movable/AM, new_loc, force = FALSE)
|
||||
/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE)
|
||||
if(!(AM in real_location()))
|
||||
return FALSE
|
||||
return remove_from_storage(AM, new_loc)
|
||||
|
||||
/datum/component/storage/proc/signal_quick_empty(atom/loctarget)
|
||||
/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget)
|
||||
return do_quick_empty(loctarget)
|
||||
|
||||
/datum/component/storage/proc/signal_hide_attempt(mob/target)
|
||||
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
|
||||
return hide_from(target)
|
||||
|
||||
/datum/component/storage/proc/on_alt_click(mob/user)
|
||||
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
|
||||
if(!isliving(user) || user.incapacitated() || !quickdraw || locked || !user.CanReach(parent))
|
||||
return
|
||||
var/obj/item/I = locate() in real_location()
|
||||
@@ -731,6 +743,10 @@
|
||||
return
|
||||
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)
|
||||
gather_mode_switch(source.owner)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
/datum/component/storage/proc/gather_mode_switch(mob/user)
|
||||
collection_mode = (collection_mode+1)%3
|
||||
switch(collection_mode)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm)
|
||||
|
||||
/datum/component/swarming/proc/join_swarm(atom/movable/AM)
|
||||
/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM)
|
||||
GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM)
|
||||
if(!other_swarm)
|
||||
return
|
||||
@@ -20,7 +20,7 @@
|
||||
other_swarm.swarm()
|
||||
other_swarm.swarm_members |= src
|
||||
|
||||
/datum/component/swarming/proc/leave_swarm(atom/movable/AM)
|
||||
/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM)
|
||||
GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM)
|
||||
if(!other_swarm || !(other_swarm in swarm_members))
|
||||
return
|
||||
|
||||
@@ -68,14 +68,14 @@
|
||||
else
|
||||
QDEL_IN(fakefire, 50)
|
||||
|
||||
/datum/component/thermite/proc/clean_react(strength)
|
||||
/datum/component/thermite/proc/clean_react(datum/source, strength)
|
||||
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
|
||||
qdel(src)
|
||||
|
||||
/datum/component/thermite/proc/flame_react(exposed_temperature, exposed_volume)
|
||||
/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
|
||||
thermite_melt()
|
||||
|
||||
/datum/component/thermite/proc/attackby_react(obj/item/thing, mob/user, params)
|
||||
/datum/component/thermite/proc/attackby_react(datum/source, obj/item/thing, mob/user, params)
|
||||
if(thing.is_hot())
|
||||
thermite_melt(user)
|
||||
@@ -84,7 +84,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
gamemode = _gamemode
|
||||
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
|
||||
|
||||
/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user)
|
||||
/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
if(!active)
|
||||
return //no hitting everyone/everything just to try to slot tcs in!
|
||||
if(istype(I, /obj/item/stack/telecrystal))
|
||||
@@ -101,7 +101,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
/datum/component/uplink/proc/interact(mob/user)
|
||||
/datum/component/uplink/proc/interact(datum/source, mob/user)
|
||||
if(locked)
|
||||
return
|
||||
active = TRUE
|
||||
@@ -201,28 +201,28 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
/datum/component/uplink/proc/implant_activation()
|
||||
var/obj/item/implant/implant = parent
|
||||
locked = FALSE
|
||||
interact(implant.imp_in)
|
||||
interact(null, implant.imp_in)
|
||||
|
||||
/datum/component/uplink/proc/implanting(list/arguments)
|
||||
/datum/component/uplink/proc/implanting(datum/source, list/arguments)
|
||||
var/mob/user = arguments[2]
|
||||
owner = "[user.key]"
|
||||
|
||||
/datum/component/uplink/proc/old_implant(list/arguments, obj/item/implant/new_implant)
|
||||
/datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant)
|
||||
// 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/component/uplink/uplink)
|
||||
/datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink)
|
||||
uplink.telecrystals += telecrystals
|
||||
return COMPONENT_DELETE_NEW_IMPLANT
|
||||
|
||||
// PDA signal responses
|
||||
|
||||
/datum/component/uplink/proc/new_ringtone(mob/living/user, new_ring_text)
|
||||
/datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text)
|
||||
var/obj/item/pda/master = parent
|
||||
if(trim(lowertext(new_ring_text)) != trim(lowertext(master.lock_code))) //why is the lock code stored on the pda?
|
||||
return
|
||||
locked = FALSE
|
||||
interact(user)
|
||||
interact(null, user)
|
||||
to_chat(user, "The PDA softly beeps.")
|
||||
user << browse(null, "window=pda")
|
||||
master.mode = 0
|
||||
@@ -230,22 +230,22 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
|
||||
// Radio signal responses
|
||||
|
||||
/datum/component/uplink/proc/new_frequency(list/arguments)
|
||||
/datum/component/uplink/proc/new_frequency(datum/source, list/arguments)
|
||||
var/obj/item/radio/master = parent
|
||||
var/frequency = arguments[1]
|
||||
if(frequency != master.traitor_frequency)
|
||||
return
|
||||
locked = FALSE
|
||||
if(ismob(master.loc))
|
||||
interact(master.loc)
|
||||
interact(null, master.loc)
|
||||
|
||||
// Pen signal responses
|
||||
|
||||
/datum/component/uplink/proc/pen_rotation(degrees, mob/living/carbon/user)
|
||||
/datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user)
|
||||
var/obj/item/pen/master = parent
|
||||
if(degrees != master.traitor_unlock_degrees)
|
||||
return
|
||||
locked = FALSE
|
||||
master.degrees = 0
|
||||
interact(user)
|
||||
interact(null, user)
|
||||
to_chat(user, "<span class='warning'>Your pen makes a clicking noise, before quickly rotating back to 0 degrees!</span>")
|
||||
@@ -0,0 +1,15 @@
|
||||
/datum/component/waddling
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
|
||||
/datum/component/waddling/Initialize()
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Waddle)
|
||||
|
||||
/datum/component/waddling/proc/Waddle()
|
||||
var/mob/living/L = parent
|
||||
if(L.incapacitated() || L.lying)
|
||||
return
|
||||
animate(L, pixel_z = 4, time = 0)
|
||||
animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2)
|
||||
animate(pixel_z = 0, transform = matrix(), time = 0)
|
||||
@@ -12,13 +12,13 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
|
||||
/datum/component/wearertargeting/proc/on_equip(mob/equipper, slot)
|
||||
/datum/component/wearertargeting/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
if((slot in valid_slots) && istype(equipper, mobtype))
|
||||
RegisterSignal(equipper, signals, callback, TRUE)
|
||||
else
|
||||
UnregisterSignal(equipper, signals)
|
||||
|
||||
/datum/component/wearertargeting/proc/on_drop(mob/user)
|
||||
/datum/component/wearertargeting/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, signals)
|
||||
|
||||
/datum/component/wearertargeting/Destroy()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
S.intensity = intensity
|
||||
S.lube_flags = lube_flags
|
||||
|
||||
/datum/component/wet_floor/proc/dry(strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
||||
/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
||||
for(var/i in time_left_list)
|
||||
if(text2num(i) <= strength)
|
||||
time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
|
||||
@@ -120,8 +120,8 @@
|
||||
if(O.obj_flags & FROZEN)
|
||||
O.make_unfrozen()
|
||||
add_wet(TURF_WET_WATER, max_time_left())
|
||||
dry(TURF_WET_ICE)
|
||||
dry(ALL, FALSE, decrease)
|
||||
dry(null, TURF_WET_ICE)
|
||||
dry(null, ALL, FALSE, decrease)
|
||||
check()
|
||||
last_process = world.time
|
||||
|
||||
|
||||
Reference in New Issue
Block a user