Files
Aurora.3/code/game/atoms.dm
LordFowl 76372c4b15 [Ready for Review] Unapologetic Vaurca Buffs III: Revenge of the Buffs (#4885)
Implements various changes at the behest of lore-dev BygoneHero, namely:

Vaurca can now wear specially modified softsuits.
Vaurca now have their own special rigsuit a la the breacher: the combat exoskeleton. It comes with various special modules, including a boring laser that allows them to dig below themselves rapidly, a vaurca variant of the combat injector which includes phoron and k'ois paste, and a neural lattice which reduces halloss by sharing it with everyone else wearing a neural lattice.
Vaurca also have received various other currently unavailable event items, including a variant of the tactical mask that filters out nitrogen and allows the Vaurca wearing it to eat, tachyon rifles and carbines which penetrate up to three layers of walls and possess other fringe benefits, the gauss rifle which is a semi-automatic variant of the crossbow with greater power and a 6 rod magazine, the energy zweihander, commando armor and scout armor.
Introduces a general climbing mechanic. Climbing can be initiated by clicking on a wall or an open turf, and it is a percentage chance that is modified by the amount of stable/large items beneath you, and decreased by the amount of unstable/small items. Vaurca are naturally proficient and always succeed at climbing.
Changes Vaurca to see in blue-green vision. Their vision is generally brighter and reddish colors are converted to a blue-green color.
Adds the Sedantis flag, an interhive flag that celebrates the universal longing for Sedantis and is a symbol of the Vaurca diaspora.
2018-07-22 19:17:03 +03:00

456 lines
13 KiB
Plaintext

/atom
layer = 2
var/level = 2
var/flags = 0
var/list/fingerprints
var/list/fingerprintshidden
var/fingerprintslast = null
var/list/blood_DNA
var/list/other_DNA
var/other_DNA_type = null
var/was_bloodied
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.
var/simulated = 1 //filter for actions - used by lighting overlays
var/fluorescent // Shows up under a UV light.
///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
var/gfi_layer_rotation = GFI_ROTATION_DEFAULT
/atom/proc/reveal_blood()
return
/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
//return flags that should be added to the viewer's sight var.
//Otherwise return a negative number to indicate that the view should be cancelled.
/atom/proc/check_eye(user as mob)
if (istype(user, /mob/living/silicon/ai)) // WHYYYY
return 0
return -1
/atom/proc/on_reagent_change()
return
// This is called when AM collides with us.
/atom/proc/CollidedWith(atom/movable/AM)
set waitfor = FALSE
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/CheckExit()
return 1
// If you want to use this, the atom must have the PROXMOVE flag, and the moving
// atom must also have the PROXMOVE flag currently to help with lag. ~ ComicIronic
/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
//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 += "<span class='danger'>blood-stained</span> [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
// Lighting
if (.)
var/datum/light_source/L
for (var/thing in light_sources)
L = thing
if (L.light_angle)
L.source_atom.update_light()
/atom/proc/ex_act()
set waitfor = FALSE
return
/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
return NO_EMAG_ACT
/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)
if(isnull(M)) return
if(!istype(M, /mob)) 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, ignoregloves = 0)
if(isnull(M)) return
if(!istype(M, /mob)) 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(istype(H.gloves, /obj/item/clothing/gloves) && H.gloves != src)
var/obj/item/clothing/gloves/G = H.gloves
if(!prob(G.fingerprint_chance))
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 = H.get_full_print()
// 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)
qdel(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)
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()
was_bloodied = 1
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, 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()
if(!simulated)
return
fluorescent = 0
src.germ_level = 0
if(istype(blood_DNA, /list))
blood_DNA = null
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
// Show a message to all mobs and objects in sight of this atom
// Use for objects performing visible actions
// message is output to anyone who can see, e.g. "The [src] does something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/atom/proc/visible_message(var/message, var/blind_message, var/range = world.view)
var/turf/T = get_turf(src)
var/list/mobs = list()
var/list/objs = list()
get_mobs_and_objs_in_view_fast(T,range, mobs, objs, ONLY_GHOSTS_IN_VIEW)
for(var/o in objs)
var/obj/O = o
O.show_message(message,1,blind_message,2)
for(var/m in mobs)
var/mob/M = m
if(M.see_invisible >= invisibility)
M.show_message(message,1,blind_message,2)
else if(blind_message)
M.show_message(blind_message, 2)
// Show a message to all mobs and objects in earshot of this atom
// Use for objects performing audible actions
// message is the message output to anyone who can hear.
// deaf_message (optional) is what deaf people will see.
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance)
var/range = world.view
if(hearing_distance)
range = hearing_distance
var/turf/T = get_turf(src)
var/list/mobs = list()
var/list/objs = list()
get_mobs_and_objs_in_view_fast(T,range, mobs, objs, ONLY_GHOSTS_IN_VIEW)
for(var/m in mobs)
var/mob/M = m
M.show_message(message,2,deaf_message,1)
for(var/o in objs)
var/obj/O = o
O.show_message(message,2,deaf_message,1)
/atom/proc/change_area(var/area/oldarea, var/area/newarea)
change_area_name(oldarea.name, newarea.name)
/atom/proc/change_area_name(var/oldname, var/newname)
name = replacetext(name,oldname,newname)
/atom/movable/proc/dropInto(var/atom/destination)
while(istype(destination))
var/atom/drop_destination = destination.onDropInto(src)
if(!istype(drop_destination) || drop_destination == destination)
return forceMove(destination)
destination = drop_destination
return forceMove(null)
/atom/proc/onDropInto(var/atom/movable/AM)
return // If onDropInto returns null, then dropInto will forceMove AM into us.
/atom/movable/onDropInto(var/atom/movable/AM)
return loc // If onDropInto returns something, then dropInto will attempt to drop AM there.