/atom layer = TURF_LAYER plane = GAME_PLANE var/level = 2 var/flags = NONE var/flags_2 = NONE var/list/fingerprints var/list/fingerprintshidden var/fingerprintslast = null var/list/blood_DNA var/blood_color var/last_bumped = 0 var/pass_flags = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. var/simulated = TRUE //filter for actions - used by lighting overlays var/atom_say_verb = "says" var/bubble_icon = "default" ///what icon the mob uses for speechbubbles var/dont_save = FALSE // For atoms that are temporary by necessity - like lighting overlays ///Chemistry. var/container_type = NONE var/datum/reagents/reagents = null //This atom's HUD (med/sec, etc) images. Associative list. var/list/image/hud_list //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 //Detective Work, used for the duplicate data points kept in the scanners var/list/original_atom //Detective Work, used for allowing a given atom to leave its fibers on stuff. Allowed by default var/can_leave_fibers = TRUE var/allow_spin = TRUE //Set this to 1 for a _target_ that is being thrown at; if an atom has this set to 1 then atoms thrown AT it will not spin; currently used for the singularity. -Fox var/admin_spawned = FALSE //was this spawned by an admin? used for stat tracking stuff. var/initialized = FALSE 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/atom_colours //used to store the different colors on an atom //its inherent color, the colored paint applied on it, special color effect etc... /atom/New(loc, ...) 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) . = ..() attempt_init(arglist(args)) // This is distinct from /tg/ because of our space management system // This is overriden in /atom/movable and the parent isn't called if the SMS wants to deal with it's init /atom/proc/attempt_init(...) 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(initialized) stack_trace("Warning: [src]([type]) initialized multiple times!") initialized = TRUE 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 guranteed to be on afterwards anyways. if(loc) loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs. 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/proc/InitializedOn(atom/A) // Proc for when something is initialized on a atom - Optional to call. Useful for observer pattern etc. return /atom/proc/onCentcom() . = FALSE var/turf/T = get_turf(src) if(!T) return if(!is_admin_level(T.z))//if not, don't bother return //check for centcomm shuttles for(var/centcom_shuttle in list("emergency", "pod1", "pod2", "pod3", "pod4", "ferry")) var/obj/docking_port/mobile/M = SSshuttle.getShuttle(centcom_shuttle) if(T in M.areaInstance) return TRUE //finally check for centcom itself return istype(T.loc, /area/centcom) /atom/proc/onSyndieBase() . = FALSE var/turf/T = get_turf(src) if(!T) return if(!is_admin_level(T.z))//if not, don't bother return if(istype(T.loc, /area/shuttle/syndicate_elite) || istype(T.loc, /area/syndicate_mothership)) return TRUE /atom/Destroy() if(alternate_appearances) for(var/aakey in alternate_appearances) var/datum/alternate_appearance/AA = alternate_appearances[aakey] qdel(AA) alternate_appearances = null QDEL_NULL(reagents) invisibility = INVISIBILITY_MAXIMUM LAZYCLEARLIST(overlays) LAZYCLEARLIST(priority_overlays) QDEL_NULL(light) return ..() //Hook for running code when a dir change occurs /atom/proc/setDir(newdir) SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir) dir = newdir /* Sets the atom's pixel locations based on the atom's `dir` variable, and what pixel offset arguments are passed into it If no arguments are supplied, `pixel_x` or `pixel_y` will be set to 0 Used primarily for when players attach mountable frames to walls (APC frame, fire alarm frame, etc.) */ /atom/proc/set_pixel_offsets_from_dir(pixel_north = 0, pixel_south = 0, pixel_east = 0, pixel_west = 0) switch(dir) if(NORTH) pixel_y = pixel_north if(SOUTH) pixel_y = pixel_south if(EAST) pixel_x = pixel_east if(WEST) pixel_x = pixel_west if(NORTHEAST) pixel_y = pixel_north pixel_x = pixel_east if(NORTHWEST) pixel_y = pixel_north pixel_x = pixel_west if(SOUTHEAST) pixel_y = pixel_south pixel_x = pixel_east if(SOUTHWEST) pixel_y = pixel_south pixel_x = pixel_west ///Handle melee attack by a mech /atom/proc/mech_melee_attack(obj/mecha/M) return /atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) if(does_attack_animation) user.changeNext_move(CLICK_CD_MELEE) add_attack_logs(user, src, "Punched with 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(istype(A, /atom/movable)) var/atom/movable/M = A if(istype(M.loc, /mob/living)) var/mob/living/L = M.loc L.unEquip(M) M.forceMove(src) /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/on_reagent_change() return /atom/proc/Bumped(AM as mob|obj) return /// Convenience proc to see if a container is open for chemistry handling /atom/proc/is_open_container() return is_refillable() && is_drainable() /// Is this atom injectable into other atoms /atom/proc/is_injectable(mob/user, allowmobs = TRUE) return reagents && (container_type & (INJECTABLE|REFILLABLE)) /// Can we draw from this atom with an injectable atom /atom/proc/is_drawable(mob/user, allowmobs = TRUE) return reagents && (container_type & (DRAWABLE|DRAINABLE)) /// Can this atoms reagents be refilled /atom/proc/is_refillable() return reagents && (container_type & REFILLABLE) /// Is this atom drainable of reagents /atom/proc/is_drainable() return reagents && (container_type & DRAINABLE) /atom/proc/CheckExit() return TRUE /atom/proc/HasProximity(atom/movable/AM as mob|obj) return /atom/proc/emp_act(severity) return /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) /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/search_contents_for(path, list/filter_path = null) * Recursevly searches all atom contens (including contents contents and so on). * * ARGS: path - search atom contents for atoms of this type * list/filter_path - if set, contents of atoms not of types in this list are excluded from search. * * RETURNS: list of found atoms */ /atom/proc/search_contents_for(path, list/filter_path = null) var/list/found = list() for(var/atom/A in src) if(istype(A, path)) found += A if(filter_path) var/pass = 0 for(var/type in filter_path) pass |= istype(A, type) if(!pass) continue if(A.contents.len) found += A.search_contents_for(path, filter_path) return found //All atoms /atom/proc/examine(mob/user, infix = "", suffix = "") //This reformat names to get a/an properly working on item descriptions when they are bloody var/f_name = "\a [src][infix]." if(src.blood_DNA && !istype(src, /obj/effect/decal)) if(gender == PLURAL) f_name = "some " else f_name = "a " if(blood_color != "#030303") f_name += "blood-stained [name][infix]!" else f_name += "oil-stained [name][infix]." . = list("[bicon(src)] That's [f_name] [suffix]") if(desc) . += desc if(reagents) if(container_type & TRANSPARENT) . += "It contains:" if(reagents.reagent_list.len) if(user.can_see_reagents()) //Show each individual reagent for(var/I in reagents.reagent_list) var/datum/reagent/R = I . += "[R.volume] units of [R.name]" else //Otherwise, just show the total volume if(reagents && reagents.reagent_list.len) . += "[reagents.total_volume] units of various reagents." else . += "Nothing." else if(container_type & AMOUNT_VISIBLE) if(reagents.total_volume) . += "It has [reagents.total_volume] unit\s left." else . += "It's empty." SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) /atom/proc/relaymove() return /atom/proc/ex_act() return /atom/proc/blob_act(obj/structure/blob/B) SEND_SIGNAL(src, COMSIG_ATOM_BLOB_ACT, B) /atom/proc/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) if(reagents) reagents.temperature_reagents(exposed_temperature) /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) // 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 //Check if the multitool has an item in its data buffer /atom/proc/multitool_check_buffer(user, silent = FALSE) if(!silent) to_chat(user, "[src] has no data buffer!") return FALSE /atom/proc/screwdriver_act(mob/living/user, obj/item/I) return /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/emag_act() return /atom/proc/fart_act(mob/living/M) return FALSE /atom/proc/rpd_act() return /atom/proc/rpd_blocksusage() // Atoms that return TRUE prevent RPDs placing any kind of pipes on their turf. return FALSE /atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) 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/get_spooked() return /** Base proc, intended to be overriden. This should only be called from one place: inside the slippery component. Called after a human mob slips on this atom. If you want the person who slipped to have something special done to them, put it here. */ /atom/proc/after_slip(mob/living/carbon/human/H) return /atom/proc/add_hiddenprint(mob/living/M) if(isnull(M)) return if(isnull(M.key)) return if(ishuman(M)) var/mob/living/carbon/human/H = M if(!istype(H.dna, /datum/dna)) return FALSE if(H.gloves) if(fingerprintslast != H.ckey) //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []", H.real_name, H.key) fingerprintslast = H.ckey return FALSE if(!fingerprints) if(fingerprintslast != H.ckey) //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []", H.real_name, H.key) fingerprintslast = H.ckey return TRUE else if(fingerprintslast != M.ckey) //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []", M.real_name, M.key) fingerprintslast = M.ckey return //Set ignoregloves to add prints irrespective of the mob having gloves on. /atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE) if(isnull(M)) return if(isnull(M.key)) return if(ishuman(M)) //Add the list if it does not exist. if(!fingerprintshidden) fingerprintshidden = list() //Fibers~ add_fibers(M) //He has no prints! if(FINGERPRINTS in M.mutations) if(fingerprintslast != M.key) fingerprintshidden += "(Has no fingerprints) Real name: [M.real_name], Key: [M.key]" fingerprintslast = M.key return FALSE //Now, lets get to the dirty work. //First, make sure their DNA makes sense. var/mob/living/carbon/human/H = M if(!istype(H.dna, /datum/dna) || !H.dna.uni_identity || (length(H.dna.uni_identity) != 32)) if(!istype(H.dna, /datum/dna)) H.dna = new /datum/dna(null) H.dna.real_name = H.real_name H.check_dna() //Check if the gloves (if any) hide fingerprints if(H.gloves) var/obj/item/clothing/gloves/G = H.gloves if(G.transfer_prints) ignoregloves = TRUE //Now, deal with gloves. if(!ignoregloves) if(H.gloves && H.gloves != src) if(fingerprintslast != H.ckey) fingerprintshidden += text("\[[]\](Wearing gloves). Real name: [], Key: []", time_stamp(), H.real_name, H.key) fingerprintslast = H.ckey H.gloves.add_fingerprint(M) return FALSE //More adminstuffz if(fingerprintslast != H.ckey) fingerprintshidden += text("\[[]\]Real name: [], Key: []", time_stamp(), H.real_name, H.key) fingerprintslast = H.ckey //Make the list if it does not exist. if(!fingerprints) fingerprints = list() //Hash this shit. var/full_print = H.get_full_print() // Add the fingerprints fingerprints[full_print] = full_print return TRUE else //Smudge up dem prints some if(fingerprintslast != M.ckey) fingerprintshidden += text("\[[]\]Real name: [], Key: []", time_stamp(), M.real_name, M.key) fingerprintslast = M.ckey return /atom/proc/transfer_fingerprints_to(atom/A) // Make sure everything are lists. if(!islist(A.fingerprints)) A.fingerprints = list() if(!islist(A.fingerprintshidden)) A.fingerprintshidden = list() if(!islist(fingerprints)) fingerprints = list() if(!islist(fingerprintshidden)) fingerprintshidden = list() // Transfer if(fingerprints) A.fingerprints |= fingerprints.Copy() //detective if(fingerprintshidden) A.fingerprintshidden |= fingerprintshidden.Copy() //admin A.fingerprintslast = fingerprintslast GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/blood_splatter_index() return "\ref[initial(icon)]-[initial(icon_state)]" //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() if(get_blood_id() != "blood") return return list("ANIMAL DNA" = "Y-") /mob/living/carbon/get_blood_dna_list() if(get_blood_id() != "blood") 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) var/new_blood_dna = L.get_blood_dna_list() if(!new_blood_dna) return FALSE return transfer_blood_dna(new_blood_dna) /obj/effect/decal/cleanable/blood/splatter/transfer_mob_blood_dna(mob/living/L) ..(L) var/list/b_data = L.get_blood_data(L.get_blood_id()) if(b_data) basecolor = b_data["blood_color"] else basecolor = "#A10808" update_icon() /obj/effect/decal/cleanable/blood/footprints/transfer_mob_blood_dna(mob/living/L) ..(L) var/list/b_data = L.get_blood_data(L.get_blood_id()) if(b_data) basecolor = b_data["blood_color"] else basecolor = "#A10808" update_icon() //to add blood dna info to the object's blood_DNA list /atom/proc/transfer_blood_dna(list/blood_dna) if(!blood_DNA) blood_DNA = list() 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 var/bloodcolor = "#A10808" var/list/b_data = M.get_blood_data(M.get_blood_id()) if(b_data) bloodcolor = b_data["blood_color"] return add_blood(blood_dna, bloodcolor) //to add blood onto something, with blood dna info to include. /atom/proc/add_blood(list/blood_dna, color) return FALSE /obj/add_blood(list/blood_dna, color) return transfer_blood_dna(blood_dna) /obj/item/add_blood(list/blood_dna, color) var/blood_count = !blood_DNA ? 0 : blood_DNA.len if(!..()) return FALSE if(!blood_count)//apply the blood-splatter overlay if it isn't already in there add_blood_overlay(color) return TRUE //we applied blood to the item /obj/item/clothing/gloves/add_blood(list/blood_dna, color) . = ..() transfer_blood = rand(2, 4) /turf/add_blood(list/blood_dna, color) var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src if(!B) B = new /obj/effect/decal/cleanable/blood/splatter(src) B.transfer_blood_dna(blood_dna) //give blood info to the blood decal. B.basecolor = color return TRUE //we bloodied the floor /mob/living/carbon/human/add_blood(list/blood_dna, color) if(wear_suit) wear_suit.add_blood(blood_dna, color) wear_suit.blood_color = color update_inv_wear_suit() else if(w_uniform) w_uniform.add_blood(blood_dna, color) w_uniform.blood_color = color update_inv_w_uniform() if(head) head.add_blood(blood_dna, color) head.blood_color = color update_inv_head() if(glasses) glasses.add_blood(blood_dna, color) glasses.blood_color = color update_inv_glasses() if(gloves) var/obj/item/clothing/gloves/G = gloves G.add_blood(blood_dna, color) G.blood_color = color verbs += /mob/living/carbon/human/proc/bloody_doodle else hand_blood_color = color bloody_hands = rand(2, 4) transfer_blood_dna(blood_dna) verbs += /mob/living/carbon/human/proc/bloody_doodle update_inv_gloves() //handles bloody hands overlays and updating return TRUE /obj/item/proc/add_blood_overlay(color) if(initial(icon) && initial(icon_state)) //try to find a pre-processed blood-splatter. otherwise, make a new one var/index = blood_splatter_index() var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index] if(!blood_splatter_icon) 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 = fcopy_rsc(blood_splatter_icon) GLOB.blood_splatter_icons[index] = blood_splatter_icon blood_overlay = image(blood_splatter_icon) blood_overlay.color = color overlays += blood_overlay /atom/proc/clean_blood() germ_level = 0 if(islist(blood_DNA)) blood_DNA = null return TRUE /obj/effect/decal/cleanable/blood/clean_blood() return // While this seems nonsensical, clean_blood isn't supposed to be used like this on a blood decal. /obj/item/clean_blood() . = ..() if(.) if(blood_overlay) overlays -= blood_overlay /obj/item/clothing/gloves/clean_blood() . = ..() if(.) transfer_blood = 0 /obj/item/clothing/shoes/clean_blood() ..() bloody_shoes = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0) blood_state = BLOOD_STATE_NOT_BLOODY if(ismob(loc)) var/mob/M = loc M.update_inv_shoes() /mob/living/carbon/human/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE) if(w_uniform && !(wear_suit && wear_suit.flags_inv & HIDEJUMPSUIT)) if(w_uniform.clean_blood()) update_inv_w_uniform() if(gloves && !(wear_suit && wear_suit.flags_inv & HIDEGLOVES)) if(gloves.clean_blood()) update_inv_gloves() gloves.germ_level = 0 clean_hands = FALSE if(shoes && !(wear_suit && wear_suit.flags_inv & HIDESHOES)) if(shoes.clean_blood()) update_inv_shoes() clean_feet = FALSE if(s_store && !(wear_suit && wear_suit.flags_inv & HIDESUITSTORAGE)) if(s_store.clean_blood()) update_inv_s_store() if(lip_style && !(head && head.flags_inv & HIDEMASK)) lip_style = null update_body() if(glasses && !(wear_mask && wear_mask.flags_inv & HIDEEYES)) if(glasses.clean_blood()) update_inv_glasses() if(l_ear && !(wear_mask && wear_mask.flags_inv & HIDEEARS)) if(l_ear.clean_blood()) update_inv_ears() if(r_ear && !(wear_mask && wear_mask.flags_inv & HIDEEARS)) if(r_ear.clean_blood()) update_inv_ears() if(belt) if(belt.clean_blood()) update_inv_belt() ..(clean_hands, clean_mask, clean_feet) update_icons() //apply the now updated overlays to the mob /atom/proc/add_vomit_floor(toxvomit = FALSE, green = FALSE) playsound(src, 'sound/effects/splat.ogg', 50, TRUE) if(!isspaceturf(src)) var/type = green ? /obj/effect/decal/cleanable/vomit/green : /obj/effect/decal/cleanable/vomit var/vomit_reagent = green ? "green_vomit" : "vomit" for(var/obj/effect/decal/cleanable/vomit/V in get_turf(src)) if(V.type == type) V.reagents.add_reagent(vomit_reagent, 5) return var/obj/effect/decal/cleanable/vomit/this = new type(src) // Make toxins vomit look different if(toxvomit) this.icon_state = "vomittox_[pick(1, 4)]" /atom/proc/get_global_map_pos() if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map)) return var/cur_x = null var/cur_y = null var/list/y_arr = null for(cur_x in 1 to GLOB.global_map.len) y_arr = GLOB.global_map[cur_x] cur_y = y_arr.Find(src.z) if(cur_y) break // to_chat(world, "X = [cur_x]; Y = [cur_y]") if(cur_x && cur_y) return list("x" = cur_x, "y" = cur_y) else return null // Used to provide overlays when using this atom as a viewing focus // (cameras, locker tint, etc.) /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) user.sync_lighting_plane_alpha() return /atom/proc/checkpass(passflag) return pass_flags & passflag /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) /** * Respond to acid being used on our atom * * Default behaviour is to send COMSIG_ATOM_ACID_ACT and return */ /atom/proc/acid_act(acidpwr, acid_volume) SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume) /atom/proc/narsie_act() return /atom/proc/ratvar_act() return /atom/proc/handle_ricochet(obj/item/projectile/P) return //This proc is called on the location of an atom when the atom is Destroy()'d /atom/proc/handle_atom_del(atom/A) return /atom/proc/atom_say(message) if(!message) return var/list/speech_bubble_hearers = list() for(var/mob/M in get_mobs_in_view(7, src)) M.show_message("[src] [atom_say_verb], \"[message]\"", 2, null, 1) if(M.client) speech_bubble_hearers += M.client if(length(speech_bubble_hearers)) var/image/I = image('icons/mob/talk.dmi', src, "[bubble_icon][say_test(message)]", FLY_LAYER) I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30) /atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list()) return /atom/vv_edit_var(var_name, var_value) if(!GLOB.debug2) admin_spawned = TRUE . = ..() switch(var_name) if("light_power", "light_range", "light_color") update_light() if("color") add_atom_colour(color, ADMIN_COLOUR_PRIORITY) /atom/vv_get_dropdown() . = ..() var/turf/curturf = get_turf(src) if(curturf) .["Jump to turf"] = "?_src_=holder;adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]" .["Add reagent"] = "?_src_=vars;addreagent=[UID()]" .["Trigger explosion"] = "?_src_=vars;explode=[UID()]" .["Trigger EM pulse"] = "?_src_=vars;emp=[UID()]" /atom/proc/AllowDrop() return FALSE /atom/proc/drop_location() var/atom/L = loc if(!L) return null return L.AllowDrop() ? L : get_turf(L) /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) /* 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