Files
Bubberstation/code/game/atoms.dm
T
Iamgoofball a98eee4fa8 here we gop
2015-04-13 12:01:38 -07:00

435 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/last_bumped = 0
var/throwpass = 0
///Chemistry.
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
var/list/image/hud_list = list()
//HUD images that this atom can provide.
var/list/hud_possible
//var/chem_is_open_container = 0
// replaced by OPENCONTAINER flags and atom/proc/is_open_container()
///Chemistry.
var/allow_spin = 1
/atom/proc/onCentcom()
var/turf/T = get_turf(src)
if(!T)
return 0
if(T.z != ZLEVEL_CENTCOM)//if not, don't bother
return 0
//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 1
//finally check for centcom itself
return istype(T.loc,/area/centcom)
/atom/proc/throw_impact(atom/hit_atom)
if(istype(hit_atom,/mob/living))
var/mob/living/M = hit_atom
M.hitby(src)
else if(isobj(hit_atom))
var/obj/O = hit_atom
if(!O.anchored)
step(O, src.dir)
O.hitby(src)
else if(isturf(hit_atom))
var/turf/T = hit_atom
if(T.density)
spawn(2)
step(src, turn(src.dir, 180))
if(istype(src,/mob/living))
var/mob/living/M = src
M.take_organ_damage(20)
/atom/proc/attack_hulk(mob/living/carbon/human/hulk, do_attack_animation = 0)
if(do_attack_animation)
hulk.changeNext_move(CLICK_CD_MELEE)
add_logs(hulk, src, "punched", "hulk powers", admin=0)
hulk.do_attack_animation(src)
return
/atom/proc/CheckParts()
return
/atom/proc/assume_air(datum/gas_mixture/giver)
del(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(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/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)
/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.time<EndTime&&get_dist(src,BeamTarget)<maxdistance&&z==BeamTarget.z)
//If the BeamTarget gets deleted, the time expires, or the BeamTarget gets out
//of range or to another z-level, then the beam will stop. Otherwise it will
//continue to draw.
dir=get_dir(src,BeamTarget) //Causes the source of the beam to rotate to continuosly face the BeamTarget.
for(var/obj/effect/overlay/beam/O in orange(10,src)) //This section erases the previously drawn beam because I found it was easier to
if(O.BeamSource==src) //just draw another instance of the beam instead of trying to manipulate all the
qdel(O) //pieces to a new orientation.
var/Angle=round(Get_Angle(src,BeamTarget))
var/icon/I=new(icon,icon_state)
I.Turn(Angle)
var/DX=(32*BeamTarget.x+BeamTarget.pixel_x)-(32*x+pixel_x)
var/DY=(32*BeamTarget.y+BeamTarget.pixel_y)-(32*y+pixel_y)
var/N=0
var/length=round(sqrt((DX)**2+(DY)**2))
for(N,N<length,N+=32)
var/obj/effect/overlay/beam/X=new(loc)
X.BeamSource=src
if(N+32>length)
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) qdel(O)
/atom/proc/examine(mob/user)
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src]."
if(src.blood_DNA && !istype(src, /obj/effect/decal))
if(gender == PLURAL)
f_name = "some "
else
f_name = "a "
f_name += "<span class='danger'>blood-stained</span> [name]!"
user << "\icon[src] That's [f_name]"
if(desc)
user << desc
// *****RM
//user << "[name]: Dn:[density] dir:[dir] cont:[contents] icon:[icon] is:[icon_state] loc:[loc]"
if(reagents && is_open_container()) //is_open_container() isn't really the right proc for this, but w/e
user << "It contains:"
if(reagents.reagent_list.len)
for(var/datum/reagent/R in reagents.reagent_list)
user << "[R.volume] units of [R.name]"
else
user << "Nothing."
/atom/proc/relaymove()
return
/atom/proc/contents_explosion(severity, target)
for(var/atom/A in contents)
A.ex_act(severity, target)
/atom/proc/ex_act(severity, target)
contents_explosion(severity, target)
/atom/proc/blob_act()
return
/atom/proc/fire_act()
return
/atom/proc/hitby(atom/movable/AM as mob|obj)
return
var/list/blood_splatter_icons = list()
/atom/proc/blood_splatter_index()
return "\ref[initial(icon)]-[initial(icon_state)]"
/atom/proc/add_blood_list(mob/living/carbon/M)
// Returns 0 if we have that blood already
if(!istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it.
blood_DNA = list()
//if this blood isn't already in the list, add it
if(blood_DNA[M.dna.unique_enzymes])
return 0 //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.blood_type
return 1
//returns 1 if made bloody, returns 0 otherwise
/atom/proc/add_blood(mob/living/carbon/M)
if(ishuman(M) && M.dna)
var/mob/living/carbon/human/H = M
if(NOBLOOD in H.dna.species.specflags)
return 0
if(rejects_blood())
return 0
if(!istype(M))
return 0
if(!check_dna_integrity(M)) //check dna is valid and create/setup if necessary
return 0 //no dna!
return 1
/obj/add_blood(mob/living/carbon/M)
if(..() == 0)
return 0
return add_blood_list(M)
/obj/item/add_blood(mob/living/carbon/M)
var/blood_count = blood_DNA == null ? 0 : blood_DNA.len
if(..() == 0)
return 0
//apply the blood-splatter overlay if it isn't already in there
if(!blood_count && 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 = 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)
blood_splatter_icons[index] = blood_splatter_icon
overlays += blood_splatter_icon
return 1 //we applied blood to the item
/obj/item/clothing/gloves/add_blood(mob/living/carbon/M)
if(..() == 0)
return 0
transfer_blood = rand(2, 4)
bloody_hands_mob = M
return 1
/turf/simulated/add_blood(mob/living/carbon/human/M)
if(..() == 0)
return 0
var/obj/effect/decal/cleanable/blood/B = locate() in contents //check for existing blood splatter
if(!B)
blood_splatter(src,M.get_blood(M.vessel),1)
B = locate(/obj/effect/decal/cleanable/blood) in contents
B.add_blood_list(M)
return 1 //we bloodied the floor
/mob/living/carbon/human/add_blood(mob/living/carbon/M)
if(..() == 0)
return 0
add_blood_list(M)
bloody_hands = rand(2, 4)
bloody_hands_mob = M
update_inv_gloves() //handles bloody hands overlays and updating
return 1 //we applied blood to the item
/atom/proc/rejects_blood()
return 0
/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)
if(M.reagents)
M.reagents.trans_to(this, M.reagents.total_volume / 10)
// Make toxins vomit look different
if(toxvomit)
this.icon_state = "vomittox_[pick(1,4)]"
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
this.viruses += newDisease
newDisease.holder = this*/
// Only adds blood on the floor -- Skie
/atom/proc/add_blood_floor(mob/living/carbon/M as mob)
if(istype(src, /turf/simulated))
if(check_dna_integrity(M)) //mobs with dna = (monkeys + humans at time of writing)
var/obj/effect/decal/cleanable/blood/B = locate() in contents
if(!B)
blood_splatter(src,M,1)
B = locate(/obj/effect/decal/cleanable/blood) in contents
B.blood_DNA[M.dna.unique_enzymes] = M.dna.blood_type
else if(istype(M, /mob/living/carbon/alien))
var/obj/effect/decal/cleanable/xenoblood/B = locate() in contents
if(!B) B = new(src)
B.blood_DNA["UNKNOWN BLOOD"] = "X*"
else if(istype(M, /mob/living/silicon/robot))
var/obj/effect/decal/cleanable/oil/B = locate() in contents
if(!B) B = new(src)
/atom/proc/clean_blood()
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/isinspace()
if(istype(get_turf(src), /turf/space))
return 1
else
return 0
/atom/proc/handle_fall()
return
/atom/proc/handle_slip()
return
/atom/proc/singularity_act()
return
/atom/proc/singularity_pull()
return
/atom/proc/acid_act(var/acidpwr, var/toxpwr, var/acid_volume)
return
/atom/proc/emag_act()
return
/atom/proc/narsie_act()
return