Ports new Brain Traumas from /tg/. Does not include the shitty creeper antag or Wizard Traumas, i'm porting wizard traumas later. Also adds the Desynchronizer and changes the way some heaRing args are handled.
842 lines
26 KiB
Plaintext
842 lines
26 KiB
Plaintext
/atom
|
|
layer = TURF_LAYER
|
|
plane = GAME_PLANE
|
|
var/level = 2
|
|
var/article // If non-null, overrides a/an/some in all cases
|
|
|
|
var/flags_1 = NONE
|
|
var/interaction_flags_atom = NONE
|
|
var/datum/reagents/reagents = null
|
|
|
|
//This atom's HUD (med/sec, etc) images. Associative list.
|
|
var/list/image/hud_list = null
|
|
//HUD images that this atom can provide.
|
|
var/list/hud_possible
|
|
|
|
//Value used to increment ex_act() if reactionary_explosions is on
|
|
var/explosion_block = 0
|
|
|
|
var/list/atom_colours //used to store the different colors on an atom
|
|
//its inherent color, the colored paint applied on it, special color effect etc...
|
|
|
|
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
|
var/list/remove_overlays // a very temporary list of overlays to remove
|
|
var/list/add_overlays // a very temporary list of overlays to add
|
|
|
|
var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
|
|
|
var/datum/proximity_monitor/proximity_monitor
|
|
var/buckle_message_cooldown = 0
|
|
var/fingerprintslast
|
|
|
|
var/list/filter_data //For handling persistent filters
|
|
|
|
var/datum/component/orbiter/orbiters
|
|
|
|
var/rad_flags = NONE // Will move to flags_1 when i can be arsed to
|
|
var/rad_insulation = RAD_NO_INSULATION
|
|
|
|
var/icon/blood_splatter_icon
|
|
var/list/fingerprints
|
|
var/list/fingerprintshidden
|
|
var/list/blood_DNA
|
|
var/list/suit_fibers
|
|
|
|
/atom/New(loc, ...)
|
|
//atom creation method that preloads variables at creation
|
|
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
|
GLOB._preloader.load(src)
|
|
|
|
if(datum_flags & DF_USE_TAG)
|
|
GenerateTag()
|
|
|
|
var/do_initialize = SSatoms.initialized
|
|
if(do_initialize != INITIALIZATION_INSSATOMS)
|
|
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
|
|
if(SSatoms.InitAtom(src, args))
|
|
//we were deleted
|
|
return
|
|
|
|
//Called after New if the map is being loaded. mapload = TRUE
|
|
//Called from base of New if the map is not being loaded. mapload = FALSE
|
|
//This base must be called or derivatives must set initialized to TRUE
|
|
//must not sleep
|
|
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
|
|
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
|
|
|
//Note: the following functions don't call the base for optimization and must copypasta:
|
|
// /turf/Initialize
|
|
// /turf/open/space/Initialize
|
|
|
|
/atom/proc/Initialize(mapload, ...)
|
|
if(flags_1 & INITIALIZED_1)
|
|
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
|
flags_1 |= INITIALIZED_1
|
|
|
|
//atom color stuff
|
|
if(color)
|
|
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
|
|
|
|
if (light_power && light_range)
|
|
update_light()
|
|
|
|
if (opacity && isturf(loc))
|
|
var/turf/T = loc
|
|
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
|
|
|
|
if (canSmoothWith)
|
|
canSmoothWith = typelist("canSmoothWith", canSmoothWith)
|
|
|
|
ComponentInitialize()
|
|
|
|
return INITIALIZE_HINT_NORMAL
|
|
|
|
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
|
/atom/proc/LateInitialize()
|
|
return
|
|
|
|
// Put your AddComponent() calls here
|
|
/atom/proc/ComponentInitialize()
|
|
return
|
|
|
|
/atom/Destroy()
|
|
if(alternate_appearances)
|
|
for(var/K in alternate_appearances)
|
|
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
|
|
AA.remove_from_hud(src)
|
|
|
|
if(reagents)
|
|
qdel(reagents)
|
|
|
|
LAZYCLEARLIST(overlays)
|
|
LAZYCLEARLIST(priority_overlays)
|
|
|
|
QDEL_NULL(light)
|
|
|
|
return ..()
|
|
|
|
/atom/proc/handle_ricochet(obj/item/projectile/P)
|
|
return
|
|
|
|
/atom/proc/CanPass(atom/movable/mover, turf/target)
|
|
return !density
|
|
|
|
/atom/proc/onCentCom()
|
|
var/turf/T = get_turf(src)
|
|
if(!T)
|
|
return FALSE
|
|
|
|
if(is_reserved_level(T.z))
|
|
for(var/A in SSshuttle.mobile)
|
|
var/obj/docking_port/mobile/M = A
|
|
if(M.launch_status == ENDGAME_TRANSIT)
|
|
for(var/place in M.shuttle_areas)
|
|
var/area/shuttle/shuttle_area = place
|
|
if(T in shuttle_area)
|
|
return TRUE
|
|
|
|
if(!is_centcom_level(T.z))//if not, don't bother
|
|
return FALSE
|
|
|
|
//Check for centcom itself
|
|
if(istype(T.loc, /area/centcom))
|
|
return TRUE
|
|
|
|
//Check for centcom shuttles
|
|
for(var/A in SSshuttle.mobile)
|
|
var/obj/docking_port/mobile/M = A
|
|
if(M.launch_status == ENDGAME_LAUNCHED)
|
|
for(var/place in M.shuttle_areas)
|
|
var/area/shuttle/shuttle_area = place
|
|
if(T in shuttle_area)
|
|
return TRUE
|
|
|
|
/atom/proc/onSyndieBase()
|
|
var/turf/T = get_turf(src)
|
|
if(!T)
|
|
return FALSE
|
|
|
|
if(!is_centcom_level(T.z))//if not, don't bother
|
|
return FALSE
|
|
|
|
if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership) || istype(T.loc, /area/shuttle/assault_pod))
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
|
|
if(does_attack_animation)
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
log_combat(user, src, "punched", "hulk powers")
|
|
user.do_attack_animation(src, ATTACK_EFFECT_SMASH)
|
|
|
|
/atom/proc/CheckParts(list/parts_list)
|
|
for(var/A in parts_list)
|
|
if(istype(A, /datum/reagent))
|
|
if(!reagents)
|
|
reagents = new()
|
|
reagents.reagent_list.Add(A)
|
|
reagents.conditional_update()
|
|
else if(ismovableatom(A))
|
|
var/atom/movable/M = A
|
|
if(isliving(M.loc))
|
|
var/mob/living/L = M.loc
|
|
L.transferItemToLoc(M, src)
|
|
else
|
|
M.forceMove(src)
|
|
|
|
//common name
|
|
/atom/proc/update_multiz(prune_on_fail = FALSE)
|
|
return FALSE
|
|
|
|
/atom/proc/assume_air(datum/gas_mixture/giver)
|
|
qdel(giver)
|
|
return null
|
|
|
|
/atom/proc/remove_air(amount)
|
|
return null
|
|
|
|
/atom/proc/return_air()
|
|
if(loc)
|
|
return loc.return_air()
|
|
else
|
|
return null
|
|
|
|
/atom/proc/check_eye(mob/user)
|
|
return
|
|
|
|
/atom/proc/Bumped(atom/movable/AM)
|
|
set waitfor = FALSE
|
|
|
|
// Convenience procs to see if a container is open for chemistry handling
|
|
/atom/proc/is_open_container()
|
|
return is_refillable() && is_drainable()
|
|
|
|
/atom/proc/is_injectable(allowmobs = TRUE)
|
|
return reagents && (reagents.reagents_holder_flags & (INJECTABLE | REFILLABLE))
|
|
|
|
/atom/proc/is_drawable(allowmobs = TRUE)
|
|
return reagents && (reagents.reagents_holder_flags & (DRAWABLE | DRAINABLE))
|
|
|
|
/atom/proc/is_refillable()
|
|
return reagents && (reagents.reagents_holder_flags & REFILLABLE)
|
|
|
|
/atom/proc/is_drainable()
|
|
return reagents && (reagents.reagents_holder_flags & DRAINABLE)
|
|
|
|
|
|
/atom/proc/AllowDrop()
|
|
return FALSE
|
|
|
|
/atom/proc/CheckExit()
|
|
return TRUE
|
|
|
|
/atom/proc/HasProximity(atom/movable/AM as mob|obj)
|
|
return
|
|
|
|
/atom/proc/emp_act(severity)
|
|
var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
|
|
if(!(protection & EMP_PROTECT_WIRES) && istype(wires))
|
|
wires.emp_pulse()
|
|
return protection // Pass the protection value collected here upwards
|
|
|
|
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
|
|
. = P.on_hit(src, 0, def_zone)
|
|
|
|
//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it.
|
|
// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first.
|
|
/atom/proc/shove_act(mob/living/target, mob/living/user)
|
|
return FALSE
|
|
|
|
/atom/proc/in_contents_of(container)//can take class or object instance as argument
|
|
if(ispath(container))
|
|
if(istype(src.loc, container))
|
|
return TRUE
|
|
else if(src in container)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/atom/proc/get_examine_name(mob/user)
|
|
. = "\a [src]"
|
|
var/list/override = list(gender == PLURAL ? "some" : "a", " ", "[name]")
|
|
if(article)
|
|
. = "[article] [src]"
|
|
override[EXAMINE_POSITION_ARTICLE] = article
|
|
|
|
var/should_override = FALSE
|
|
|
|
if(SEND_SIGNAL(src, COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED)
|
|
should_override = TRUE
|
|
|
|
|
|
if(blood_DNA && !istype(src, /obj/effect/decal))
|
|
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
|
|
should_override = TRUE
|
|
|
|
if(should_override)
|
|
. = override.Join("")
|
|
|
|
///Generate the full examine string of this atom (including icon for goonchat)
|
|
/atom/proc/get_examine_string(mob/user, thats = FALSE)
|
|
return "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
|
|
|
|
/atom/proc/examine(mob/user)
|
|
. = list("[get_examine_string(user, TRUE)].")
|
|
|
|
if(desc)
|
|
. += desc
|
|
|
|
if(reagents)
|
|
if(reagents.reagents_holder_flags & TRANSPARENT)
|
|
. += "It contains:"
|
|
if(length(reagents.reagent_list))
|
|
if(user.can_see_reagents()) //Show each individual reagent
|
|
for(var/datum/reagent/R in reagents.reagent_list)
|
|
. += "[R.volume] units of [R.name]"
|
|
else //Otherwise, just show the total volume
|
|
var/total_volume = 0
|
|
for(var/datum/reagent/R in reagents.reagent_list)
|
|
total_volume += R.volume
|
|
. += "[total_volume] units of various reagents"
|
|
else
|
|
. += "Nothing."
|
|
else if(reagents.reagents_holder_flags & AMOUNT_VISIBLE)
|
|
if(reagents.total_volume)
|
|
. += "<span class='notice'>It has [reagents.total_volume] unit\s left.</span>"
|
|
else
|
|
. += "<span class='danger'>It's empty.</span>"
|
|
|
|
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
|
|
|
/atom/proc/relaymove(mob/user)
|
|
if(buckle_message_cooldown <= world.time)
|
|
buckle_message_cooldown = world.time + 50
|
|
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
|
|
return
|
|
|
|
/atom/proc/prevent_content_explosion()
|
|
return FALSE
|
|
|
|
/atom/proc/contents_explosion(severity, target)
|
|
return //For handling the effects of explosions on contents that would not normally be effected
|
|
|
|
/atom/proc/ex_act(severity, target)
|
|
set waitfor = FALSE
|
|
contents_explosion(severity, target)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target)
|
|
|
|
/atom/proc/blob_act(obj/structure/blob/B)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_BLOB_ACT, B)
|
|
return
|
|
|
|
/atom/proc/fire_act(exposed_temperature, exposed_volume)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume)
|
|
return
|
|
|
|
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
|
|
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...).
|
|
addtimer(CALLBACK(src, .proc/hitby_react, AM), 2)
|
|
|
|
/atom/proc/hitby_react(atom/movable/AM)
|
|
if(AM && isturf(AM.loc))
|
|
step(AM, turn(AM.dir, 180))
|
|
|
|
/atom/proc/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
|
|
return
|
|
|
|
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
|
/mob/living/proc/get_blood_dna_list()
|
|
var/blood_id = get_blood_id()
|
|
if(!(blood_id =="blood" || blood_id == "jellyblood"))
|
|
return
|
|
return list("ANIMAL DNA" = "Y-")
|
|
|
|
/mob/living/carbon/get_blood_dna_list()
|
|
var/blood_id = get_blood_id()
|
|
if(!(blood_id =="blood" || blood_id == "jellyblood"))
|
|
return
|
|
var/list/blood_dna = list()
|
|
if(dna)
|
|
blood_dna[dna.unique_enzymes] = dna.blood_type
|
|
else
|
|
blood_dna["UNKNOWN DNA"] = "X*"
|
|
return blood_dna
|
|
|
|
/mob/living/carbon/alien/get_blood_dna_list()
|
|
return list("UNKNOWN DNA" = "X*")
|
|
|
|
//to add a mob's dna info into an object's blood_DNA list.
|
|
/atom/proc/transfer_mob_blood_dna(mob/living/L)
|
|
// Returns 0 if we have that blood already
|
|
var/new_blood_dna = L.get_blood_dna_list()
|
|
if(!new_blood_dna)
|
|
return FALSE
|
|
LAZYINITLIST(blood_DNA) //if our list of DNA doesn't exist yet, initialise it.
|
|
var/old_length = blood_DNA.len
|
|
blood_DNA |= new_blood_dna
|
|
if(blood_DNA.len == old_length)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
//to add blood dna info to the object's blood_DNA list
|
|
/atom/proc/transfer_blood_dna(list/blood_dna, list/datum/disease/diseases)
|
|
LAZYINITLIST(blood_DNA)
|
|
var/old_length = blood_DNA.len
|
|
blood_DNA |= blood_dna
|
|
if(blood_DNA.len > old_length)
|
|
return TRUE
|
|
//some new blood DNA was added
|
|
|
|
//to add blood from a mob onto something, and transfer their dna info
|
|
/atom/proc/add_mob_blood(mob/living/M)
|
|
var/list/blood_dna = M.get_blood_dna_list()
|
|
if(!blood_dna)
|
|
return FALSE
|
|
return add_blood_DNA(blood_dna, M.diseases)
|
|
|
|
//to add blood onto something, with blood dna info to include.
|
|
/atom/proc/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
return FALSE
|
|
|
|
/obj/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
return transfer_blood_dna(blood_dna, diseases)
|
|
|
|
/obj/item/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
add_blood_overlay()
|
|
|
|
/obj/item/proc/add_blood_overlay()
|
|
if(!blood_DNA.len)
|
|
return
|
|
if(initial(icon) && initial(icon_state))
|
|
blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
|
|
blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
|
|
blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
|
|
blood_splatter_icon.Blend(blood_DNA_to_color(), ICON_MULTIPLY)
|
|
add_overlay(blood_splatter_icon)
|
|
|
|
/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
. = ..()
|
|
transfer_blood = rand(2, 4)
|
|
|
|
/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
|
|
if(!B)
|
|
B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
|
|
B.transfer_blood_dna(blood_dna, diseases) //give blood info to the blood decal.
|
|
return TRUE //we bloodied the floor
|
|
|
|
/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
|
|
if(head)
|
|
head.add_blood_DNA(blood_dna, diseases)
|
|
update_inv_head()
|
|
else if(wear_mask)
|
|
wear_mask.add_blood_DNA(blood_dna, diseases)
|
|
update_inv_wear_mask()
|
|
if(wear_neck)
|
|
wear_neck.add_blood_DNA(blood_dna, diseases)
|
|
update_inv_neck()
|
|
if(wear_suit)
|
|
wear_suit.add_blood_DNA(blood_dna, diseases)
|
|
update_inv_wear_suit()
|
|
else if(w_uniform)
|
|
w_uniform.add_blood_DNA(blood_dna, diseases)
|
|
update_inv_w_uniform()
|
|
if(gloves)
|
|
var/obj/item/clothing/gloves/G = gloves
|
|
G.add_blood_DNA(blood_dna, diseases)
|
|
else
|
|
transfer_blood_dna(blood_dna, diseases)
|
|
bloody_hands = rand(2, 4)
|
|
update_inv_gloves() //handles bloody hands overlays and updating
|
|
return TRUE
|
|
|
|
/atom/proc/blood_DNA_to_color()
|
|
var/list/colors = list()//first we make a list of all bloodtypes present
|
|
for(var/bloop in blood_DNA)
|
|
if(colors[blood_DNA[bloop]])
|
|
colors[blood_DNA[bloop]]++
|
|
else
|
|
colors[blood_DNA[bloop]] = 1
|
|
|
|
var/final_rgb = BLOOD_COLOR_HUMAN //a default so we don't have white blood graphics if something messed up
|
|
|
|
if(colors.len)
|
|
var/sum = 0 //this is all shitcode, but it works; trust me
|
|
final_rgb = bloodtype_to_color(colors[1])
|
|
sum = colors[colors[1]]
|
|
if(colors.len > 1)
|
|
var/i = 2
|
|
while(i <= colors.len)
|
|
var/tmp = colors[colors[i]]
|
|
final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum))
|
|
sum += tmp
|
|
i++
|
|
|
|
return final_rgb
|
|
|
|
/atom/proc/clean_blood()
|
|
if(islist(blood_DNA))
|
|
blood_DNA = null
|
|
return TRUE
|
|
|
|
/atom/proc/wash_cream()
|
|
return TRUE
|
|
|
|
/atom/proc/isinspace()
|
|
if(isspaceturf(get_turf(src)))
|
|
return TRUE
|
|
else
|
|
return FALSE
|
|
|
|
/atom/proc/handle_fall()
|
|
return
|
|
|
|
/atom/proc/singularity_act()
|
|
return
|
|
|
|
/atom/proc/singularity_pull(obj/singularity/S, current_size)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_SING_PULL, S, current_size)
|
|
|
|
/atom/proc/acid_act(acidpwr, acid_volume)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume)
|
|
|
|
/atom/proc/emag_act()
|
|
return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
|
|
|
|
/atom/proc/rad_act(strength)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength)
|
|
|
|
/atom/proc/narsie_act()
|
|
SEND_SIGNAL(src, COMSIG_ATOM_NARSIE_ACT)
|
|
|
|
/atom/proc/ratvar_act()
|
|
SEND_SIGNAL(src, COMSIG_ATOM_RATVAR_ACT)
|
|
|
|
/atom/proc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
|
return FALSE
|
|
|
|
/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode)
|
|
return FALSE
|
|
|
|
/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user)
|
|
if(GetComponent(/datum/component/storage))
|
|
return component_storage_contents_dump_act(src_object, user)
|
|
return FALSE
|
|
|
|
/atom/proc/component_storage_contents_dump_act(datum/component/storage/src_object, mob/user)
|
|
var/list/things = src_object.contents()
|
|
var/datum/progressbar/progress = new(user, things.len, src)
|
|
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
|
while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress)))
|
|
stoplag(1)
|
|
qdel(progress)
|
|
to_chat(user, "<span class='notice'>You dump as much of [src_object.parent]'s contents into [STR.insert_preposition]to [src] as you can.</span>")
|
|
STR.orient2hud(user)
|
|
src_object.orient2hud(user)
|
|
if(user.active_storage) //refresh the HUD to show the transfered contents
|
|
user.active_storage.close(user)
|
|
user.active_storage.show_to(user)
|
|
return TRUE
|
|
|
|
/atom/proc/get_dumping_location(obj/item/storage/source,mob/user)
|
|
return null
|
|
|
|
//This proc is called on the location of an atom when the atom is Destroy()'d
|
|
/atom/proc/handle_atom_del(atom/A)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_CONTENTS_DEL, A)
|
|
|
|
//called when the turf the atom resides on is ChangeTurfed
|
|
/atom/proc/HandleTurfChange(turf/T)
|
|
for(var/a in src)
|
|
var/atom/A = a
|
|
A.HandleTurfChange(T)
|
|
|
|
//the vision impairment to give to the mob whose perspective is set to that atom (e.g. an unfocused camera giving you an impaired vision when looking through it)
|
|
/atom/proc/get_remote_view_fullscreens(mob/user)
|
|
return
|
|
|
|
//the sight changes to give to the mob whose perspective is set to that atom (e.g. A mob with nightvision loses its nightvision while looking through a normal camera)
|
|
/atom/proc/update_remote_sight(mob/living/user)
|
|
return
|
|
|
|
|
|
//Hook for running code when a dir change occurs
|
|
/atom/proc/setDir(newdir, ismousemovement=FALSE)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir)
|
|
dir = newdir
|
|
|
|
/atom/proc/mech_melee_attack(obj/mecha/M)
|
|
return
|
|
|
|
//If a mob logouts/logins in side of an object you can use this proc
|
|
/atom/proc/on_log(login)
|
|
if(loc)
|
|
loc.on_log(login)
|
|
|
|
|
|
/*
|
|
Atom Colour Priority System
|
|
A System that gives finer control over which atom colour to colour the atom with.
|
|
The "highest priority" one is always displayed as opposed to the default of
|
|
"whichever was set last is displayed"
|
|
*/
|
|
|
|
|
|
/*
|
|
Adds an instance of colour_type to the atom's atom_colours list
|
|
*/
|
|
/atom/proc/add_atom_colour(coloration, colour_priority)
|
|
if(!atom_colours || !atom_colours.len)
|
|
atom_colours = list()
|
|
atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently.
|
|
if(!coloration)
|
|
return
|
|
if(colour_priority > atom_colours.len)
|
|
return
|
|
atom_colours[colour_priority] = coloration
|
|
update_atom_colour()
|
|
|
|
|
|
/*
|
|
Removes an instance of colour_type from the atom's atom_colours list
|
|
*/
|
|
/atom/proc/remove_atom_colour(colour_priority, coloration)
|
|
if(!atom_colours)
|
|
atom_colours = list()
|
|
atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently.
|
|
if(colour_priority > atom_colours.len)
|
|
return
|
|
if(coloration && atom_colours[colour_priority] != coloration)
|
|
return //if we don't have the expected color (for a specific priority) to remove, do nothing
|
|
atom_colours[colour_priority] = null
|
|
update_atom_colour()
|
|
|
|
|
|
/*
|
|
Resets the atom's color to null, and then sets it to the highest priority
|
|
colour available
|
|
*/
|
|
/atom/proc/update_atom_colour()
|
|
if(!atom_colours)
|
|
atom_colours = list()
|
|
atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently.
|
|
color = null
|
|
for(var/C in atom_colours)
|
|
if(islist(C))
|
|
var/list/L = C
|
|
if(L.len)
|
|
color = L
|
|
return
|
|
else if(C)
|
|
color = C
|
|
return
|
|
|
|
/atom/vv_edit_var(var_name, var_value)
|
|
if(!GLOB.Debug2)
|
|
flags_1 |= ADMIN_SPAWNED_1
|
|
. = ..()
|
|
switch(var_name)
|
|
if("color")
|
|
add_atom_colour(color, ADMIN_COLOUR_PRIORITY)
|
|
|
|
/atom/vv_get_dropdown()
|
|
. = ..()
|
|
. += "---"
|
|
var/turf/curturf = get_turf(src)
|
|
if (curturf)
|
|
.["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
|
.["Modify Transform"] = "?_src_=vars;[HrefToken()];modtransform=[REF(src)]"
|
|
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]"
|
|
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]"
|
|
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]"
|
|
|
|
/atom/proc/drop_location()
|
|
var/atom/L = loc
|
|
if(!L)
|
|
return null
|
|
return L.AllowDrop() ? L : L.drop_location()
|
|
|
|
/atom/Entered(atom/movable/AM, atom/oldLoc)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc)
|
|
|
|
/atom/Exit(atom/movable/AM, atom/newLoc)
|
|
. = ..()
|
|
if(SEND_SIGNAL(src, COMSIG_ATOM_EXIT, AM, newLoc) & COMPONENT_ATOM_BLOCK_EXIT)
|
|
return FALSE
|
|
|
|
/atom/Exited(atom/movable/AM, atom/newLoc)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, newLoc)
|
|
|
|
/atom/proc/return_temperature()
|
|
return
|
|
|
|
// Tool behavior procedure. Redirects to tool-specific procs by default.
|
|
// You can override it to catch all tool interactions, for use in complex deconstruction procs.
|
|
// Just don't forget to return ..() in the end.
|
|
/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type)
|
|
switch(tool_type)
|
|
if(TOOL_CROWBAR)
|
|
return crowbar_act(user, I)
|
|
if(TOOL_MULTITOOL)
|
|
return multitool_act(user, I)
|
|
if(TOOL_SCREWDRIVER)
|
|
return screwdriver_act(user, I)
|
|
if(TOOL_WRENCH)
|
|
return wrench_act(user, I)
|
|
if(TOOL_WIRECUTTER)
|
|
return wirecutter_act(user, I)
|
|
if(TOOL_WELDER)
|
|
return welder_act(user, I)
|
|
if(TOOL_ANALYZER)
|
|
return analyzer_act(user, I)
|
|
|
|
// Tool-specific behavior procs. To be overridden in subtypes.
|
|
/atom/proc/crowbar_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/multitool_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
|
|
SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I)
|
|
|
|
/atom/proc/wrench_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/wirecutter_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/welder_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/analyzer_act(mob/living/user, obj/item/I)
|
|
return
|
|
|
|
/atom/proc/GenerateTag()
|
|
return
|
|
|
|
// Generic logging helper
|
|
/atom/proc/log_message(message, message_type, color=null, log_globally=TRUE)
|
|
if(!log_globally)
|
|
return
|
|
|
|
var/log_text = "[key_name(src)] [message] [loc_name(src)]"
|
|
switch(message_type)
|
|
if(LOG_ATTACK)
|
|
log_attack(log_text)
|
|
if(LOG_SAY)
|
|
log_say(log_text)
|
|
if(LOG_WHISPER)
|
|
log_whisper(log_text)
|
|
if(LOG_EMOTE)
|
|
log_emote(log_text)
|
|
if(LOG_DSAY)
|
|
log_dsay(log_text)
|
|
if(LOG_PDA)
|
|
log_pda(log_text)
|
|
if(LOG_CHAT)
|
|
log_chat(log_text)
|
|
if(LOG_COMMENT)
|
|
log_comment(log_text)
|
|
if(LOG_TELECOMMS)
|
|
log_telecomms(log_text)
|
|
if(LOG_OOC)
|
|
log_ooc(log_text)
|
|
if(LOG_ADMIN)
|
|
log_admin(log_text)
|
|
if(LOG_ADMIN_PRIVATE)
|
|
log_admin_private(log_text)
|
|
if(LOG_ASAY)
|
|
log_adminsay(log_text)
|
|
if(LOG_OWNERSHIP)
|
|
log_game(log_text)
|
|
if(LOG_GAME)
|
|
log_game(log_text)
|
|
else
|
|
stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
|
|
log_game(log_text)
|
|
|
|
// Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements)
|
|
/atom/proc/log_talk(message, message_type, tag=null, log_globally=TRUE, forced_by=null)
|
|
var/prefix = tag ? "([tag]) " : ""
|
|
var/suffix = forced_by ? " FORCED by [forced_by]" : ""
|
|
log_message("[prefix]\"[message]\"[suffix]", message_type, log_globally=log_globally)
|
|
|
|
// Helper for logging of messages with only one sender and receiver
|
|
/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag)
|
|
if(!tag)
|
|
stack_trace("Unspecified tag for private message")
|
|
tag = "UNKNOWN"
|
|
|
|
source.log_talk(message, message_type, tag="[tag] to [key_name(target)]")
|
|
if(source != target)
|
|
target.log_talk(message, message_type, tag="[tag] from [key_name(source)]", log_globally=FALSE)
|
|
|
|
/*
|
|
Proc for attack log creation, because really why not
|
|
1 argument is the actor performing the action
|
|
2 argument is the target of the action
|
|
3 is a verb describing the action (e.g. punched, throwed, kicked, etc.)
|
|
4 is a tool with which the action was made (usually an item)
|
|
5 is any additional text, which will be appended to the rest of the log line
|
|
*/
|
|
|
|
/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null)
|
|
var/ssource = key_name(user)
|
|
var/starget = key_name(target)
|
|
|
|
var/mob/living/living_target = target
|
|
var/hp = istype(living_target) ? " (NEWHP: [living_target.health]) " : ""
|
|
|
|
var/sobject = ""
|
|
if(object)
|
|
sobject = " with [key_name(object)]"
|
|
var/saddition = ""
|
|
if(addition)
|
|
saddition = " [addition]"
|
|
|
|
var/postfix = "[sobject][saddition][hp]"
|
|
|
|
var/message = "has [what_done] [starget][postfix]"
|
|
user.log_message(message, LOG_ATTACK, color="red")
|
|
|
|
if(user != target)
|
|
var/reverse_message = "has been [what_done] by [ssource][postfix]"
|
|
target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE)
|
|
|
|
// Filter stuff
|
|
/atom/movable/proc/add_filter(name,priority,list/params)
|
|
if(!filter_data)
|
|
filter_data = list()
|
|
var/list/p = params.Copy()
|
|
p["priority"] = priority
|
|
filter_data[name] = p
|
|
update_filters()
|
|
|
|
/atom/movable/proc/update_filters()
|
|
filters = null
|
|
sortTim(filter_data,associative = TRUE)
|
|
for(var/f in filter_data)
|
|
var/list/data = filter_data[f]
|
|
var/list/arguments = data.Copy()
|
|
arguments -= "priority"
|
|
filters += filter(arglist(arguments))
|
|
|
|
/atom/movable/proc/get_filter(name)
|
|
if(filter_data && filter_data[name])
|
|
return filters[filter_data.Find(name)]
|
|
|
|
/atom/movable/proc/remove_filter(name)
|
|
if(filter_data && filter_data[name])
|
|
filter_data -= name
|
|
update_filters()
|
|
return TRUE
|
|
|
|
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
|
|
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels) |