Merge branch 'master' into upstream-merge-38649

This commit is contained in:
deathride58
2018-07-06 01:34:12 -04:00
committed by GitHub
837 changed files with 15447 additions and 7458 deletions
+16 -9
View File
@@ -46,10 +46,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* `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 recieves that signal
* 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.
### Procs
@@ -61,6 +64,11 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Returns a reference to a component whose type MATCHES component_type if that component exists in the datum, null otherwise
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
1. `SEND_SIGNAL(target, sigtype, ...)` (public, final)
* Use to send signals to target datum
* Extra arguments are to be specified in the signal definition
* Returns a bitflag with signal specific information assembled from all activated components
* Arguments are packaged in a list and handed off to _SendSignal()
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
* Creates an instance of `component_type` in the datum and passes `...` to its `Initialize()` call
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
@@ -71,23 +79,22 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
* Called on a component's `parent` after a signal recieved causes it to activate. `src` is the parameter
* Called on a component's `parent` after a signal received causes it to activate. `src` is the parameter
* Will only be called if a component's callback returns `TRUE`
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
* Properly transfers ownership of a component from one datum to another
* Signals `COMSIG_COMPONENT_REMOVING` on the parent
* Called on the datum you want to own the component with another datum's component
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
* Call to send a signal to the components of the target datum
* Extra arguments are to be specified in the signal definition
* Returns a bitflag with signal specific information assembled from all activated components
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/component/New(datum/parent, ...)` (private, final)
* Runs internal setup for the component
* Extra arguments are passed to `Initialize()`
1. `/datum/component/Initialize(...)` (abstract, no-sleep)
* Called by `New()` with the same argments excluding `parent`
* Component does not exist in `parent`'s `datum_components` list yet, although `parent` is set and may be used
* Signals will not be recieved while this function is running
* Signals will not be received while this function is running
* Component may be deleted after this function completes without being attached
* Do not call `qdel(src)` from this function
1. `/datum/component/Destroy(force(bool), silent(bool))` (virtual, no-sleep)
@@ -108,10 +115,10 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Clears `parent` and removes the component from it's component list
1. `/datum/component/proc/_JoinParent` (private, final)
* Tries to add the component to it's `parent`s `datum_components` list
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
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 recieved `proc_ref` will be called on the component, along with associated arguments
* 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
+56 -29
View File
@@ -56,10 +56,10 @@
if(!force)
_RemoveFromParent()
if(!silent)
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
parent = null
SSdcs.UnregisterSignal(src, signal_procs)
LAZYCLEARLIST(signal_procs)
for(var/target in signal_procs)
UnregisterSignal(target, signal_procs[target])
return ..()
/datum/component/proc/_RemoveFromParent()
@@ -78,34 +78,69 @@
if(!dc.len)
P.datum_components = null
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src))
/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src) || QDELETED(target))
return
var/list/procs = signal_procs
if(!procs)
procs = list()
signal_procs = procs
signal_procs = procs = list()
if(!procs[target])
procs[target] = list()
var/list/lookup = target.comp_lookup
if(!lookup)
target.comp_lookup = lookup = list()
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
proc_or_callback = CALLBACK(src, proc_or_callback)
var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types)
for(var/sig_type in sig_types)
if(!override && procs[sig_type])
if(!override && procs[target][sig_type])
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
if(sig_type[1] == "!")
SSdcs.RegisterSignal(src, sig_type)
procs[target][sig_type] = proc_or_callback
procs[sig_type] = proc_or_callback
if(!lookup[sig_type]) // Nothing has registered here yet
lookup[sig_type] = src
else if(lookup[sig_type] == src) // We already registered here
continue
else if(!length(lookup[sig_type])) // One other thing registered here
lookup[sig_type] = list(lookup[sig_type]=TRUE)
lookup[sig_type][src] = TRUE
else // Many other things have registered here
lookup[sig_type][src] = TRUE
enabled = TRUE
/datum/component/proc/HasSignal(sig_type)
return signal_procs[sig_type] != null
/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
var/list/lookup = target.comp_lookup
if(!signal_procs || !signal_procs[target] || !lookup)
return
if(!islist(sig_type_or_types))
sig_type_or_types = list(sig_type_or_types)
for(var/sig in sig_type_or_types)
switch(length(lookup[sig]))
if(2)
lookup[sig] = (lookup[sig]-src)[1]
if(1)
stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup")
if(src in lookup[sig])
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
if(0)
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
else
lookup[sig] -= src
/datum/component/proc/UnregisterSignal(sig_type_or_types)
signal_procs -= sig_type_or_types
signal_procs[target] -= sig_type_or_types
if(!signal_procs[target].len)
signal_procs -= target
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
return
@@ -125,28 +160,20 @@
current_type = type2parent(current_type)
. += current_type
/datum/proc/SendSignal(sigtype, ...)
var/list/comps = datum_components
if(!comps)
return NONE
var/list/arguments = args.Copy(2)
var/target = comps[/datum/component]
/datum/proc/_SendSignal(sigtype, list/arguments)
var/target = comp_lookup[sigtype]
if(!length(target))
var/datum/component/C = target
if(!C.enabled)
return NONE
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
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)
continue
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
continue
var/datum/callback/CB = C.signal_procs[src][sigtype]
. |= CB.InvokeAsync(arglist(arguments))
/datum/proc/GetComponent(c_type)
@@ -228,7 +255,7 @@
new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal
if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
SendSignal(COMSIG_COMPONENT_ADDED, new_comp)
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp)
return new_comp
return old_comp
@@ -243,7 +270,7 @@
var/datum/old_parent = parent
PreTransfer()
_RemoveFromParent()
old_parent.SendSignal(COMSIG_COMPONENT_REMOVING, src)
SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src)
/datum/proc/TakeComponent(datum/component/target)
if(!target)
+3 -3
View File
@@ -15,9 +15,9 @@
archdrops[i][ARCH_PROB] = 100
stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null probability value in [i].")
callback = _callback
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig)
RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/Dig)
RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/BombDig)
RegisterSignal(parent, COMSIG_ATOM_SING_PULL, .proc/SingDig)
/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original)
var/list/other_archdrops = A.archdrops
+3 -3
View File
@@ -9,9 +9,9 @@
if(!isobj(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/applyplate)
RegisterSignal(COMSIG_PARENT_PREQDELETED, .proc/dropplates)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/applyplate)
RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, .proc/dropplates)
if(_maxamount)
maxamount = _maxamount
+2 -2
View File
@@ -5,8 +5,8 @@
if(!ismovableatom(parent))
return COMPONENT_INCOMPATIBLE
beauty = beautyamount
RegisterSignal(COMSIG_ENTER_AREA, .proc/enter_area)
RegisterSignal(COMSIG_EXIT_AREA, .proc/exit_area)
RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/enter_area)
RegisterSignal(parent, COMSIG_EXIT_AREA, .proc/exit_area)
var/area/A = get_area(parent)
if(!A || A.outdoors)
return
+1 -1
View File
@@ -12,7 +12,7 @@
probability = _probability
flags = _flags
RegisterSignal(list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
/datum/component/caltrop/proc/Crossed(atom/movable/AM)
var/atom/A = parent
+1 -1
View File
@@ -23,7 +23,7 @@
))
/datum/component/chasm/Initialize(turf/target)
RegisterSignal(list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered)
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered)
target_turf = target
START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
+8 -8
View File
@@ -4,7 +4,7 @@
/datum/component/cleaning/Initialize()
if(!ismovableatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(list(COMSIG_MOVABLE_MOVED), .proc/Clean)
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Clean)
/datum/component/cleaning/proc/Clean()
var/atom/movable/AM = parent
@@ -12,13 +12,13 @@
if(!isturf(tile))
return
tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/I = A
I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(ismob(I.loc))
var/mob/M = I.loc
M.regenerate_icons()
@@ -26,14 +26,14 @@
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(cleaned_human.shoes)
cleaned_human.shoes.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
to_chat(cleaned_human, "<span class='danger'>[AM] cleans your face!</span>")
+2 -2
View File
@@ -15,8 +15,8 @@
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/action)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/action)
update_parent(index)
/datum/component/construction/proc/examine(mob/user)
+3 -3
View File
@@ -12,11 +12,11 @@
cleanable = _cleanable
if(_dir) // If no dir is assigned at start then it follows the atom's dir
RegisterSignal(COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
if(_cleanable)
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
if(_description)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
apply()
/datum/component/decal/Destroy()
+1 -1
View File
@@ -5,7 +5,7 @@
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
RegisterSignal(COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
var/obj/item/I = parent
+1 -1
View File
@@ -7,7 +7,7 @@
/datum/component/earhealing/Initialize()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
RegisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
/datum/component/earhealing/proc/equippedChanged(mob/living/carbon/user, slot)
if (slot == SLOT_EARS && istype(user))
+1 -1
View File
@@ -16,7 +16,7 @@
)
say_lines = text || default_lines
RegisterSignal(COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
/datum/component/edit_complainer/proc/var_edit_react(list/arguments)
var/atom/movable/master = parent
+1 -1
View File
@@ -5,7 +5,7 @@
if(!istype(parent, /atom))
return COMPONENT_INCOMPATIBLE
flags = _flags
RegisterSignal(list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
/datum/component/empprotection/proc/getEmpFlags(severity)
return flags
+8
View File
@@ -0,0 +1,8 @@
/datum/component/forced_gravity
var/gravity = 1
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
+1 -1
View File
@@ -21,7 +21,7 @@
blood_DNA = new_blood_DNA
fibers = new_fibers
check_blood()
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
/datum/component/forensics/proc/wipe_fingerprints()
fingerprints = null
+9 -9
View File
@@ -12,15 +12,15 @@
if(expire_in)
expire_time = world.time + expire_in
QDEL_IN(src, expire_in)
RegisterSignal(COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle)
RegisterSignal(COMSIG_MOVABLE_COLLIDE, .proc/try_infect_collide)
RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/try_infect_crossed)
RegisterSignal(COMSIG_ITEM_ATTACK_ZONE, .proc/try_infect_attack_zone)
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/try_infect_attack)
RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/try_infect_equipped)
RegisterSignal(COMSIG_MOVABLE_IMPACT_ZONE, .proc/try_infect_impact_zone)
RegisterSignal(COMSIG_FOOD_EATEN, .proc/try_infect_eat)
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean)
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle)
RegisterSignal(parent, COMSIG_MOVABLE_COLLIDE, .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)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/try_infect_equipped)
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, .proc/try_infect_impact_zone)
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)
for(var/V in diseases)
+5 -15
View File
@@ -13,31 +13,21 @@
var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to.
var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever.
var/mob/current_holder
var/datum/component/redirect/listener
var/current_timerid
/datum/component/jousting/Initialize()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop)
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack)
/datum/component/jousting/Destroy()
QDEL_NULL(listener)
return ..()
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
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)
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE)
current_holder = user
if(!listener)
listener = user.AddComponent(/datum/component/redirect, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move))
else
user.TakeComponent(listener)
if(QDELING(listener))
listener = null
/datum/component/jousting/proc/on_drop(mob/user)
QDEL_NULL(listener)
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
current_holder = null
current_direction = NONE
current_tile_charge = 0
+5 -12
View File
@@ -8,8 +8,8 @@
/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_ITEM_EQUIPPED,.proc/OnEquipped)
RegisterSignal(COMSIG_ITEM_DROPPED,.proc/OnDropped)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED,.proc/OnEquipped)
RegisterSignal(parent, COMSIG_ITEM_DROPPED,.proc/OnDropped)
src.knockoff_chance = knockoff_chance
@@ -37,16 +37,9 @@
if(!istype(H))
return
if(slots_knockoffable && !(slot in slots_knockoffable))
if(disarm_redirect)
QDEL_NULL(disarm_redirect)
UnregisterSignal(H, COMSIG_HUMAN_DISARM_HIT)
return
if(!disarm_redirect)
disarm_redirect = H.AddComponent(/datum/component/redirect,list(COMSIG_HUMAN_DISARM_HIT),CALLBACK(src,.proc/Knockoff))
RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
/datum/component/knockoff/proc/OnDropped(mob/living/M)
if(disarm_redirect)
QDEL_NULL(disarm_redirect)
/datum/component/knockoff/Destroy()
QDEL_NULL(disarm_redirect)
. = ..()
UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
+23
View File
@@ -0,0 +1,23 @@
/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)
/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/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/examine(mob/user)
to_chat(user, "It has been installed with inertia dampening to prevent coffee spills.")
+3 -3
View File
@@ -32,8 +32,8 @@
precondition = _precondition
after_insert = _after_insert
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/OnExamine)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
var/list/possible_mats = list()
for(var/mat_type in subtypesof(/datum/material))
@@ -58,7 +58,7 @@
return
if(user.a_intent != INTENT_HELP)
return
if(I.flags_1 & ABSTRACT_1)
if(I.item_flags & ABSTRACT)
return
if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc)))
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
+3 -3
View File
@@ -14,9 +14,9 @@
START_PROCESSING(SSmood, src)
owner = parent
soundloop = new(list(owner), FALSE, TRUE)
RegisterSignal(COMSIG_ADD_MOOD_EVENT, .proc/add_event)
RegisterSignal(COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
RegisterSignal(COMSIG_ENTER_AREA, .proc/update_beauty)
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)
/datum/component/mood/Destroy()
STOP_PROCESSING(SSmood, src)
+7 -7
View File
@@ -1,8 +1,8 @@
//Thing meant for allowing datums and objects to access a NTnet network datum.
/datum/proc/ntnet_recieve(datum/netdata/data)
/datum/proc/ntnet_receive(datum/netdata/data)
return
/datum/proc/ntnet_recieve_broadcast(datum/netdata/data)
/datum/proc/ntnet_receive_broadcast(datum/netdata/data)
return
/datum/proc/ntnet_send(datum/netdata/data, netid)
@@ -15,7 +15,7 @@
var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually.
var/network_name = "" //text
var/list/networks_connected_by_id = list() //id = datum/ntnet
var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_recieve. NOT RECOMMENDED.
var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_receive. NOT RECOMMENDED.
/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing!
hardware_id = "[SSnetworks.get_next_HID()]"
@@ -31,12 +31,12 @@
SSnetworks.unregister_interface(src)
return ..()
/datum/component/ntnet_interface/proc/__network_recieve(datum/netdata/data) //Do not directly proccall!
parent.SendSignal(COMSIG_COMPONENT_NTNET_RECIEVE, data)
/datum/component/ntnet_interface/proc/__network_receive(datum/netdata/data) //Do not directly proccall!
SEND_SIGNAL(parent, COMSIG_COMPONENT_NTNET_RECEIVE, data)
if(differentiate_broadcast && data.broadcast)
parent.ntnet_recieve_broadcast(data)
parent.ntnet_receive_broadcast(data)
else
parent.ntnet_recieve(data)
parent.ntnet_receive(data)
/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall!
// Process data before sending it
+1 -1
View File
@@ -2,7 +2,7 @@
var/current_paint
/datum/component/spraycan_paintable/Initialize()
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/Repaint)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/Repaint)
/datum/component/spraycan_paintable/Destroy()
RemoveCurrentCoat()
+3 -3
View File
@@ -19,10 +19,10 @@
can_contaminate = _can_contaminate
if(istype(parent, /atom))
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/rad_examine)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/rad_examine)
if(istype(parent, /obj/item))
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/rad_attack)
RegisterSignal(COMSIG_ITEM_ATTACK_OBJ, .proc/rad_attack)
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/rad_attack)
RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, .proc/rad_attack)
else
CRASH("Something that wasn't an atom was given /datum/component/radioactive")
return
+5 -5
View File
@@ -22,9 +22,9 @@
/datum/component/riding/Initialize()
if(!ismovableatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle)
RegisterSignal(COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle)
RegisterSignal(COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle)
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)
restore_position(M)
@@ -193,7 +193,7 @@
/datum/component/riding/human/Initialize()
. = ..()
RegisterSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee)
RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee)
/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target)
var/mob/living/carbon/human/AM = parent
@@ -307,7 +307,7 @@
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "offhand"
w_class = WEIGHT_CLASS_HUGE
flags_1 = ABSTRACT_1 | DROPDEL_1 | NOBLUDGEON_1
item_flags = ABSTRACT | DROPDEL | NOBLUDGEON
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/mob/living/carbon/rider
var/mob/living/parent
+21 -3
View File
@@ -45,10 +45,10 @@
default_rotation_direction = ROTATION_CLOCKWISE
if(src.rotation_flags & ROTATION_ALTCLICK)
RegisterSignal(COMSIG_CLICK_ALT, .proc/HandRot)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/ExamineMessage)
RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/HandRot)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/ExamineMessage)
if(src.rotation_flags & ROTATION_WRENCH)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/WrenchRot)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/WrenchRot)
if(src.rotation_flags & ROTATION_VERBS)
var/atom/movable/AM = parent
@@ -59,6 +59,24 @@
if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE)
AM.verbs += /atom/movable/proc/simple_rotate_counterclockwise
/datum/component/simple_rotation/proc/remove_verbs()
if(parent)
var/atom/movable/AM = parent
AM.verbs -= /atom/movable/proc/simple_rotate_flip
AM.verbs -= /atom/movable/proc/simple_rotate_clockwise
AM.verbs -= /atom/movable/proc/simple_rotate_counterclockwise
/datum/component/simple_rotation/Destroy()
remove_verbs()
QDEL_NULL(can_user_rotate)
QDEL_NULL(can_be_rotated)
QDEL_NULL(after_rotation)
. = ..()
/datum/component/simple_rotation/RemoveComponent()
remove_verbs()
. = ..()
/datum/component/simple_rotation/proc/ExamineMessage(mob/user)
if(rotation_flags & ROTATION_ALTCLICK)
to_chat(user, "<span class='notice'>Alt-click to rotate it clockwise.</span>")
+5 -2
View File
@@ -1,3 +1,6 @@
// This should only be used by non components trying to listen to a signal
// If you use this inside a component I will replace your eyes with lemons ~ninjanomnom
/datum/component/redirect
dupe_mode = COMPONENT_DUPE_ALLOWED
@@ -7,8 +10,8 @@
warning("signals are [list2params(signals)], callback is [_callback]]")
return COMPONENT_INCOMPATIBLE
if(flags & REDIRECT_TRANSFER_WITH_TURF && isturf(parent))
RegisterSignal(COMSIG_TURF_CHANGE, .proc/turf_change)
RegisterSignal(signals, _callback)
RegisterSignal(parent, COMSIG_TURF_CHANGE, .proc/turf_change)
RegisterSignal(parent, signals, _callback)
/datum/component/redirect/proc/turf_change(path, new_baseturfs, flags, list/transfers)
transfers += src
+1 -1
View File
@@ -7,7 +7,7 @@
intensity = max(_intensity, 0)
lube_flags = _lube_flags
callback = _callback
RegisterSignal(list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
/datum/component/slippery/proc/Slip(atom/movable/AM)
var/mob/victim = AM
+1 -1
View File
@@ -2,7 +2,7 @@
var/too_spooky = TRUE //will it spawn a new instrument?
/datum/component/spooky/Initialize()
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/spectral_attack)
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
/datum/component/spooky/proc/spectral_attack(mob/living/carbon/C, mob/user)
if(ishuman(user)) //this weapon wasn't meant for mortals.
+4 -4
View File
@@ -24,10 +24,10 @@
if(use_delay_override)
use_delay = use_delay_override
RegisterSignal(list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_COLLIDE, COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ), .proc/play_squeak)
RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/play_squeak_turf)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
RegisterSignal(COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_COLLIDE, COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ), .proc/play_squeak)
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_turf)
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
/datum/component/squeak/proc/play_squeak()
if(prob(squeak_chance))
+3 -3
View File
@@ -7,9 +7,9 @@
/datum/component/stationloving/Initialize(inform_admins = FALSE, allow_death = FALSE)
if(!ismovableatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(list(COMSIG_MOVABLE_Z_CHANGED), .proc/check_in_bounds)
RegisterSignal(list(COMSIG_PARENT_PREQDELETED), .proc/check_deletion)
RegisterSignal(list(COMSIG_ITEM_IMBUE_SOUL), .proc/check_soul_imbue)
RegisterSignal(parent, list(COMSIG_MOVABLE_Z_CHANGED), .proc/check_in_bounds)
RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED), .proc/check_deletion)
RegisterSignal(parent, list(COMSIG_ITEM_IMBUE_SOUL), .proc/check_soul_imbue)
src.inform_admins = inform_admins
src.allow_death = allow_death
check_in_bounds() // Just in case something is being created outside of station/centcom
@@ -14,8 +14,8 @@
/datum/component/storage/concrete/Initialize()
. = ..()
RegisterSignal(COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
RegisterSignal(COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct)
RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct)
/datum/component/storage/concrete/Destroy()
var/atom/real_location = real_location()
@@ -2,7 +2,7 @@
var/atom/A = parent
if((istype(W, /obj/item/storage/backpack/holding) || count_by_type(W.GetAllContents(), /obj/item/storage/backpack/holding)))
var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed")
if(safety == "Abort" || !in_range(A, user) || !A || !W || user.incapacitated())
if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user)))
return
var/turf/loccheck = get_turf(A)
if(is_reebe(loccheck.z))
@@ -14,6 +14,7 @@
to_chat(user, "<span class='danger'>The Bluespace interfaces of the two devices catastrophically malfunction!</span>")
qdel(W)
playsound(loccheck,'sound/effects/supermatter.ogg', 200, 1)
user.gib(TRUE, TRUE, TRUE)
for(var/turf/T in range(6,loccheck))
if(istype(T, /turf/open/space/transit))
continue
@@ -54,12 +54,18 @@
/datum/component/storage/concrete/pockets/pocketprotector
max_items = 3
max_w_class = WEIGHT_CLASS_TINY
var/atom/original_parent
/datum/component/storage/concrete/pockets/pocketprotector/Initialize()
original_parent = parent
. = ..()
can_hold = typecacheof(list( //Same items as a PDA
/obj/item/pen,
/obj/item/toy/crayon,
/obj/item/lipstick,
/obj/item/flashlight/pen,
/obj/item/clothing/mask/cigarette))
/obj/item/clothing/mask/cigarette))
/datum/component/storage/concrete/pockets/pocketprotector/real_location()
// if the component is reparented to a jumpsuit, the items still go in the protector
return original_parent
@@ -20,7 +20,7 @@
allow_quick_gather = TRUE
allow_quick_empty = TRUE
click_gather = TRUE
max_w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills
max_combined_w_class = 800
max_items = 400
display_numerical_stacking = TRUE
@@ -29,5 +29,5 @@
. = ..()
if(!I.get_part_rating())
if (!stop_messages)
to_chat(M, "<span class='warning'>[parent] only accepts machine par ts!</span>")
to_chat(M, "<span class='warning'>[parent] only accepts machine parts!</span>")
return FALSE
+39 -40
View File
@@ -67,38 +67,38 @@
closer = new(null, src)
orient2hud()
RegisterSignal(COMSIG_CONTAINS_STORAGE, .proc/on_check)
RegisterSignal(COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
RegisterSignal(COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt)
RegisterSignal(COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt)
RegisterSignal(COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert)
RegisterSignal(COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type)
RegisterSignal(COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type)
RegisterSignal(COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked)
RegisterSignal(COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj)
RegisterSignal(COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty)
RegisterSignal(COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt)
RegisterSignal(COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all)
RegisterSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv)
RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check)
RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt)
RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt)
RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert)
RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type)
RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type)
RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked)
RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj)
RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty)
RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt)
RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all)
RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/attackby)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby)
RegisterSignal(COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
RegisterSignal(COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand)
RegisterSignal(COMSIG_ATOM_EMP_ACT, .proc/emp_act)
RegisterSignal(COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
RegisterSignal(COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
RegisterSignal(COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand)
RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act)
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(COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
RegisterSignal(COMSIG_ITEM_PICKUP, .proc/signal_on_pickup)
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(COMSIG_MOVABLE_THROW, .proc/close_all)
RegisterSignal(parent, COMSIG_MOVABLE_THROW, .proc/close_all)
RegisterSignal(COMSIG_CLICK_ALT, .proc/on_alt_click)
RegisterSignal(COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
RegisterSignal(COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_recieve)
RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click)
RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive)
update_actions()
@@ -125,11 +125,13 @@
modeswitch_action.Grant(M)
/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master)
if(!istype(new_master))
if(new_master == src || (!isnull(new_master) && !istype(new_master)))
return FALSE
master.on_slave_unlink(src)
if(master)
master.on_slave_unlink(src)
master = new_master
master.on_slave_link(src)
if(master)
master.on_slave_link(src)
return TRUE
/datum/component/storage/proc/master()
@@ -149,7 +151,7 @@
quick_empty(M)
/datum/component/storage/proc/preattack_intercept(obj/O, mob/M, params)
if(!isitem(O) || !click_gather || O.SendSignal(COMSIG_CONTAINS_STORAGE))
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
return FALSE
. = COMPONENT_NO_ATTACK
if(locked)
@@ -466,7 +468,7 @@
if(recursive)
for(var/i in ret.Copy())
var/atom/A = i
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
return ret
/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS!
@@ -517,19 +519,19 @@
if(force || M.CanReach(parent, view_only = TRUE))
show_to(M)
/datum/component/storage/proc/mousedrop_recieve(atom/movable/O, mob/M)
/datum/component/storage/proc/mousedrop_receive(atom/movable/O, mob/M)
if(isitem(O))
var/obj/item/I = O
if(iscarbon(M) || isdrone(M))
var/mob/living/L = M
if(!L.incapacitated() && I == L.get_active_held_item())
if(!I.SendSignal(COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert.
if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert.
handle_item_insertion(I, FALSE, L)
//This proc return 1 if the item can be picked up and 0 if it can't.
//Set the stop_messages to stop it from printing messages
/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M)
if(!istype(I) || (I.flags_1 & ABSTRACT_1))
if(!istype(I) || (I.item_flags & ABSTRACT))
return FALSE //Not an item
if(I == parent)
return FALSE //no paradoxes for you
@@ -573,7 +575,7 @@
if(!stop_messages)
to_chat(M, "<span class='warning'>[IP] cannot hold [I] as it's a storage item of the same size!</span>")
return FALSE //To prevent the stacking of same sized storage items.
if(I.flags_1 & NODROP_1) //SHOULD be handled in unEquip, but better safe than sorry.
if(I.item_flags & NODROP) //SHOULD be handled in unEquip, but better safe than sorry.
to_chat(M, "<span class='warning'>\the [I] is stuck to your hand, you can't put it in \the [host]!</span>")
return FALSE
var/datum/component/storage/concrete/master = master()
@@ -639,10 +641,7 @@
/datum/component/storage/proc/signal_take_type(type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
if(!force)
if(check_adjacent)
if(user)
if(!user.CanReach(destination) || !user.CanReach(parent))
return FALSE
else if(!destination.CanReachStorage(parent))
if(!user || !user.CanReach(destination) || !user.CanReach(parent))
return FALSE
var/list/taking = typecache_filter_list(contents(), typecacheof(type))
if(length(taking) > amount)
+2 -2
View File
@@ -8,8 +8,8 @@
offset_x = rand(-max_x, max_x)
offset_y = rand(-max_y, max_y)
RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/join_swarm)
RegisterSignal(COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm)
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)
GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM)
+4 -4
View File
@@ -34,9 +34,9 @@
overlay = mutable_appearance('icons/effects/effects.dmi', "thermite")
master.add_overlay(overlay)
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/attackby_react)
RegisterSignal(COMSIG_ATOM_FIRE_ACT, .proc/flame_react)
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby_react)
RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, .proc/flame_react)
/datum/component/thermite/Destroy()
var/turf/master = parent
@@ -60,7 +60,7 @@
if(amount >= 50)
var/burning_time = max(100, 100-amount)
master = master.ScrapeAway()
master = master.Melt()
master.burn_tile()
if(user)
master.add_hiddenprint(user)
+250
View File
@@ -0,0 +1,250 @@
GLOBAL_LIST_EMPTY(uplinks)
/**
* Uplinks
*
* All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.'
* Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink.
* You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it.
**/
/datum/component/uplink
dupe_mode = COMPONENT_DUPE_UNIQUE
var/name = "syndicate uplink"
var/active = FALSE
var/lockable = TRUE
var/locked = TRUE
var/allow_restricted = TRUE
var/telecrystals
var/selected_cat
var/owner = null
var/datum/game_mode/gamemode
var/datum/uplink_purchase_log/purchase_log
var/list/uplink_items
var/hidden_crystals = 0
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
if(istype(parent, /obj/item/implant))
RegisterSignal(parent, COMSIG_IMPLANT_ACTIVATED, .proc/implant_activation)
RegisterSignal(parent, COMSIG_IMPLANT_IMPLANTING, .proc/implanting)
RegisterSignal(parent, COMSIG_IMPLANT_OTHER, .proc/old_implant)
RegisterSignal(parent, COMSIG_IMPLANT_EXISTING_UPLINK, .proc/new_implant)
else if(istype(parent, /obj/item/pda))
RegisterSignal(parent, COMSIG_PDA_CHANGE_RINGTONE, .proc/new_ringtone)
else if(istype(parent, /obj/item/radio))
RegisterSignal(parent, COMSIG_RADIO_NEW_FREQUENCY, .proc/new_frequency)
else if(istype(parent, /obj/item/pen))
RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation)
GLOB.uplinks += src
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
if(_owner)
owner = _owner
LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
if(GLOB.uplink_purchase_logs_by_key[owner])
purchase_log = GLOB.uplink_purchase_logs_by_key[owner]
else
purchase_log = new(owner, src)
lockable = _lockable
active = _enabled
gamemode = _gamemode
telecrystals = starting_tc
if(!lockable)
active = TRUE
locked = FALSE
/datum/component/uplink/InheritComponent(datum/component/uplink/U)
lockable |= U.lockable
active |= U.active
if(!gamemode)
gamemode = U.gamemode
telecrystals += U.telecrystals
if(purchase_log && U.purchase_log)
purchase_log.MergeWithAndDel(U.purchase_log)
/datum/component/uplink/Destroy()
GLOB.uplinks -= src
gamemode = null
return ..()
/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE)
if(!silent)
to_chat(user, "<span class='notice'>You slot [TC] into [parent] and charge its internal uplink.</span>")
var/amt = TC.amount
telecrystals += amt
TC.use(amt)
/datum/component/uplink/proc/set_gamemode(_gamemode)
gamemode = _gamemode
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
/datum/component/uplink/proc/OnAttackBy(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))
LoadTC(user, I)
for(var/category in uplink_items)
for(var/item in uplink_items[category])
var/datum/uplink_item/UI = uplink_items[category][item]
var/path = UI.refund_path || UI.item
var/cost = UI.refund_amount || UI.cost
if(I.type == path && UI.refundable && I.check_uplink_validity())
telecrystals += cost
purchase_log.total_spent -= cost
to_chat(user, "<span class='notice'>[I] refunded.</span>")
qdel(I)
return
/datum/component/uplink/proc/interact(mob/user)
if(locked)
return
active = TRUE
if(user)
ui_interact(user)
// an unlocked uplink blocks also opening the PDA or headset menu
return COMPONENT_NO_INTERACT
/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
active = TRUE
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state)
ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input.
ui.set_style("syndicate")
ui.open()
/datum/component/uplink/ui_data(mob/user)
if(!user.mind)
return
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
data["categories"] = list()
for(var/category in uplink_items)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
if(category == selected_cat)
for(var/item in uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(I.limited_stock == 0)
continue
if(I.restricted_roles.len)
var/is_inaccessible = 1
for(var/R in I.restricted_roles)
if(R == user.mind.assigned_role)
is_inaccessible = 0
if(is_inaccessible)
continue
cat["items"] += list(list(
"name" = I.name,
"cost" = I.cost,
"desc" = I.desc,
))
data["categories"] += list(cat)
return data
/datum/component/uplink/ui_act(action, params)
if(!active)
return
switch(action)
if("buy")
var/item = params["item"]
var/list/buyable_items = list()
for(var/category in uplink_items)
buyable_items += uplink_items[category]
if(item in buyable_items)
var/datum/uplink_item/I = buyable_items[item]
MakePurchase(usr, I)
. = TRUE
if("lock")
active = FALSE
locked = TRUE
telecrystals += hidden_crystals
hidden_crystals = 0
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
return TRUE
/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U)
if(!istype(U))
return
if (!user || user.incapacitated())
return
if(telecrystals < U.cost || U.limited_stock == 0)
return
telecrystals -= U.cost
U.purchase(user, src)
if(U.limited_stock > 0)
U.limited_stock -= 1
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]"))
return TRUE
// Implant signal responses
/datum/component/uplink/proc/implant_activation()
var/obj/item/implant/implant = parent
locked = FALSE
interact(implant.imp_in)
/datum/component/uplink/proc/implanting(list/arguments)
var/mob/user = arguments[2]
owner = "[user.key]"
/datum/component/uplink/proc/old_implant(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)
uplink.telecrystals += telecrystals
return COMPONENT_DELETE_NEW_IMPLANT
// PDA signal responses
/datum/component/uplink/proc/new_ringtone(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)
to_chat(user, "The PDA softly beeps.")
user << browse(null, "window=pda")
master.mode = 0
return COMPONENT_STOP_RINGTONE_CHANGE
// Radio signal responses
/datum/component/uplink/proc/new_frequency(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)
// Pen signal responses
/datum/component/uplink/proc/pen_rotation(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)
to_chat(user, "<span class='warning'>Your pen makes a clicking noise, before quickly rotating back to 0 degrees!</span>")
+9 -13
View File
@@ -1,7 +1,6 @@
// A dummy parent type used for easily making components that target an item's wearer rather than the item itself.
/datum/component/wearertargeting
var/datum/component/mobhook
var/list/valid_slots = list()
var/list/signals = list()
var/datum/callback/callback = CALLBACK(GLOBAL_PROC, .proc/pass)
@@ -10,17 +9,14 @@
/datum/component/wearertargeting/Initialize()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/checkMobHook)
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
/datum/component/wearertargeting/Destroy()
QDEL_NULL(mobhook)
return ..()
/datum/component/wearertargeting/proc/checkMobHook(mob/user, slot)
if ((slot in valid_slots) && istype(user, mobtype))
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, signals, callback)
/datum/component/wearertargeting/proc/on_equip(mob/equipper, slot)
if((slot in valid_slots) && istype(equipper, mobtype))
RegisterSignal(equipper, signals, callback, TRUE)
else
QDEL_NULL(mobhook)
UnregisterSignal(equipper, signals)
/datum/component/wearertargeting/proc/on_drop(mob/user)
UnregisterSignal(user, signals)
+2 -2
View File
@@ -26,8 +26,8 @@
if(!isopenturf(parent))
return COMPONENT_INCOMPATIBLE
add_wet(strength, duration_minimum, duration_add, duration_maximum)
RegisterSignal(COMSIG_TURF_IS_WET, .proc/is_wet)
RegisterSignal(COMSIG_TURF_MAKE_DRY, .proc/dry)
RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet)
RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry)
permanent = _permanent
if(!permanent)
START_PROCESSING(SSwet_floors, src)