/atom layer = 2 var/level = 2 var/flags = 0 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/throwpass = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. ///Chemistry. var/datum/reagents/reagents = null //var/chem_is_open_container = 0 // replaced by OPENCONTAINER flags and atom/proc/is_open_container() ///Chemistry. //Detective Work, used for the duplicate data points kept in the scanners var/list/original_atom /atom/proc/assume_air(datum/gas_mixture/giver) return null /atom/proc/remove_air(amount) return null /atom/proc/return_air() if(loc) return loc.return_air() else return null //Currently used only for cryo cells, because they are also pipes and so overriding their return_air() would break their pipe-behaviour. //If cryo cells are ever rewritten so that the part that contains the human is separate from the pipe part -- //such as rewriting them so that they are a machine that contains a pipe segment (or a pipe that contains a machine that contains the human?) -- then this can be removed. /atom/proc/return_air_for_internal_lifeform() return return_air() /atom/proc/check_eye(user as mob) if (istype(user, /mob/living/silicon/ai)) // WHYYYY return 1 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 // returns true if open // false if closed /atom/proc/is_open_container() return flags & OPENCONTAINER /*//Convenience proc to see whether a container can be accessed in a certain way. proc/can_subract_container() return flags & EXTRACT_CONTAINER proc/can_add_container() return flags & INSERT_CONTAINER */ /atom/proc/meteorhit(obj/meteor as obj) return /atom/proc/allow_drop() return 1 /atom/proc/CheckExit() return 1 /atom/proc/HasProximity(atom/movable/AM as mob|obj) return /atom/proc/emp_act(var/severity) return /atom/proc/bullet_act(obj/item/projectile/P, def_zone) P.on_hit(src, 0, def_zone) . = 0 /atom/proc/in_contents_of(container)//can take class or object instance as argument if(ispath(container)) if(istype(src.loc, container)) return 1 else if(src in container) return 1 return /* * 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 /* Beam code by Gunbuddy Beam() proc will only allow one beam to come from a source at a time. Attempting to call it more than once at a time per source will cause graphical errors. Also, the icon used for the beam will have to be vertical and 32x32. The math involved assumes that the icon is vertical to begin with so unless you want to adjust the math, its easier to just keep the beam vertical. */ /atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10) //BeamTarget represents the target for the beam, basically just means the other end. //Time is the duration to draw the beam //Icon is obviously which icon to use for the beam, default is beam.dmi //Icon_state is what icon state is used. Default is b_beam which is a blue beam. //Maxdistance is the longest range the beam will persist before it gives up. var/EndTime=world.time+time while(BeamTarget&&world.timelength) var/icon/II=new(icon,icon_state) II.DrawBox(null,1,(length-N),32,32) II.Turn(Angle) X.icon=II else X.icon=I var/Pixel_x=round(sin(Angle)+32*sin(Angle)*(N+16)/32) var/Pixel_y=round(cos(Angle)+32*cos(Angle)*(N+16)/32) if(DX==0) Pixel_x=0 if(DY==0) Pixel_y=0 if(Pixel_x>32) for(var/a=0, a<=Pixel_x,a+=32) X.x++ Pixel_x-=32 if(Pixel_x<-32) for(var/a=0, a>=Pixel_x,a-=32) X.x-- Pixel_x+=32 if(Pixel_y>32) for(var/a=0, a<=Pixel_y,a+=32) X.y++ Pixel_y-=32 if(Pixel_y<-32) for(var/a=0, a>=Pixel_y,a-=32) X.y-- Pixel_y+=32 X.pixel_x=Pixel_x X.pixel_y=Pixel_y sleep(3) //Changing this to a lower value will cause the beam to follow more smoothly with movement, but it will also be more laggy. //I've found that 3 ticks provided a nice balance for my use. for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) del O //All atoms /atom/proc/examine(mob/user, var/distance = -1, var/infix = "", var/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]." user << "\icon[src] That's [f_name] [suffix]" user << desc return distance == -1 || (get_dist(src, user) <= distance) // called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set. // see code/modules/mob/mob_movement.dm for more. /atom/proc/relaymove() return //called to set the atom's dir and used to add behaviour to dir-changes /atom/proc/set_dir(new_dir) . = new_dir != dir dir = new_dir /atom/proc/ex_act() return /atom/proc/blob_act() return /atom/proc/fire_act() return /atom/proc/melt() return /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) AM.throwing = 0 return /atom/proc/add_hiddenprint(mob/living/M as mob) 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 0 if (H.gloves) if(src.fingerprintslast != H.key) src.fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []",H.real_name, H.key) src.fingerprintslast = H.key return 0 if (!( src.fingerprints )) if(src.fingerprintslast != H.key) src.fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",H.real_name, H.key) src.fingerprintslast = H.key return 1 else if(src.fingerprintslast != M.key) src.fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",M.real_name, M.key) src.fingerprintslast = M.key return /atom/proc/add_fingerprint(mob/living/M as mob, ignoregloves = 0) if(isnull(M)) return if(isAI(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 (mFingerprints in M.mutations) if(fingerprintslast != M.key) fingerprintshidden += "(Has no fingerprints) Real name: [M.real_name], Key: [M.key]" fingerprintslast = M.key return 0 //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() //Now, deal with gloves. if (H.gloves && H.gloves != src) if(fingerprintslast != H.key) fingerprintshidden += text("\[[]\](Wearing gloves). Real name: [], Key: []",time_stamp(), H.real_name, H.key) fingerprintslast = H.key H.gloves.add_fingerprint(M) //Deal with gloves the pass finger/palm prints. if(!ignoregloves) if(H.gloves != src) if(prob(75) && istype(H.gloves, /obj/item/clothing/gloves/latex)) return 0 else if(H.gloves && !istype(H.gloves, /obj/item/clothing/gloves/latex)) return 0 //More adminstuffz if(fingerprintslast != H.key) fingerprintshidden += text("\[[]\]Real name: [], Key: []",time_stamp(), H.real_name, H.key) fingerprintslast = H.key //Make the list if it does not exist. if(!fingerprints) fingerprints = list() //Hash this shit. var/full_print = md5(H.dna.uni_identity) // Add the fingerprints // if(fingerprints[full_print]) switch(stringpercent(fingerprints[full_print])) //tells us how many stars are in the current prints. if(28 to 32) if(prob(1)) fingerprints[full_print] = full_print // You rolled a one buddy. else fingerprints[full_print] = stars(full_print, rand(0,40)) // 24 to 32 if(24 to 27) if(prob(3)) fingerprints[full_print] = full_print //Sucks to be you. else fingerprints[full_print] = stars(full_print, rand(15, 55)) // 20 to 29 if(20 to 23) if(prob(5)) fingerprints[full_print] = full_print //Had a good run didn't ya. else fingerprints[full_print] = stars(full_print, rand(30, 70)) // 15 to 25 if(16 to 19) if(prob(5)) fingerprints[full_print] = full_print //Welp. else fingerprints[full_print] = stars(full_print, rand(40, 100)) // 0 to 21 if(0 to 15) if(prob(5)) fingerprints[full_print] = stars(full_print, rand(0,50)) // small chance you can smudge. else fingerprints[full_print] = full_print else fingerprints[full_print] = stars(full_print, rand(0, 20)) //Initial touch, not leaving much evidence the first time. return 1 else //Smudge up dem prints some if(fingerprintslast != M.key) fingerprintshidden += text("\[[]\]Real name: [], Key: []",time_stamp(), M.real_name, M.key) fingerprintslast = M.key //Cleaning up shit. if(fingerprints && !fingerprints.len) del(fingerprints) return /atom/proc/transfer_fingerprints_to(var/atom/A) if(!istype(A.fingerprints,/list)) A.fingerprints = list() if(!istype(A.fingerprintshidden,/list)) A.fingerprintshidden = list() if(!istype(fingerprintshidden, /list)) fingerprintshidden = list() //skytodo //A.fingerprints |= fingerprints //detective //A.fingerprintshidden |= fingerprintshidden //admin if(A.fingerprints && fingerprints) A.fingerprints |= fingerprints.Copy() //detective if(A.fingerprintshidden && fingerprintshidden) A.fingerprintshidden |= fingerprintshidden.Copy() //admin A.fingerprintslast = fingerprintslast //returns 1 if made bloody, returns 0 otherwise /atom/proc/add_blood(mob/living/carbon/human/M as mob) if(flags & NOBLOODY) return 0 if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it. blood_DNA = list() blood_color = "#A10808" if(istype(M)) if (!istype(M.dna, /datum/dna)) M.dna = new /datum/dna(null) M.dna.real_name = M.real_name M.check_dna() if (M.species) blood_color = M.species.blood_color . = 1 return 1 /atom/proc/add_vomit_floor(mob/living/carbon/M as mob, var/toxvomit = 0) if( istype(src, /turf/simulated) ) var/obj/effect/decal/cleanable/vomit/this = new /obj/effect/decal/cleanable/vomit(src) // Make toxins vomit look different if(toxvomit) this.icon_state = "vomittox_[pick(1,4)]" /atom/proc/clean_blood() src.color = initial(src.color) //paint src.germ_level = 0 if(istype(blood_DNA, /list)) del(blood_DNA) return 1 /atom/proc/get_global_map_pos() if(!islist(global_map) || isemptylist(global_map)) return var/cur_x = null var/cur_y = null var/list/y_arr = null for(cur_x=1,cur_x<=global_map.len,cur_x++) y_arr = global_map[cur_x] cur_y = y_arr.Find(src.z) if(cur_y) break // world << "X = [cur_x]; Y = [cur_y]" if(cur_x && cur_y) return list("x"=cur_x,"y"=cur_y) else return 0 /atom/proc/checkpass(passflag) return pass_flags&passflag /atom/proc/isinspace() if(istype(get_turf(src), /turf/space)) return 1 else return 0