mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 07:48:55 +00:00
873 lines
26 KiB
Plaintext
873 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
|
|
///overlays managed by update_overlays() to prevent removing overlays that weren't added by the same proc
|
|
var/list/managed_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()
|
|
world.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 = FALSE)
|
|
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, .)
|
|
|
|
/// Updates the icon of the atom
|
|
/atom/proc/update_icon()
|
|
// I expect we're going to need more return flags and options in this proc
|
|
var/signalOut = SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON)
|
|
|
|
if(!(signalOut & COMSIG_ATOM_NO_UPDATE_ICON_STATE))
|
|
update_icon_state()
|
|
|
|
if(!(signalOut & COMSIG_ATOM_NO_UPDATE_OVERLAYS))
|
|
var/list/new_overlays = update_overlays()
|
|
if(managed_overlays)
|
|
cut_overlay(managed_overlays)
|
|
managed_overlays = null
|
|
if(length(new_overlays))
|
|
managed_overlays = new_overlays
|
|
add_overlay(new_overlays)
|
|
|
|
/// Updates the icon state of the atom
|
|
/atom/proc/update_icon_state()
|
|
|
|
/// Updates the overlays of the atom
|
|
/atom/proc/update_overlays()
|
|
SHOULD_CALL_PARENT(1)
|
|
. = list()
|
|
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)
|
|
|
|
/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/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, 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/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/multitool_check_buffer(user, obj/item/I, silent = FALSE)
|
|
if(!istype(I, /obj/item/multitool))
|
|
if(user && !silent)
|
|
to_chat(user, "<span class='warning'>[I] has no data buffer!</span>")
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/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)
|
|
LAZYINITLIST(filter_data)
|
|
var/list/p = params.Copy()
|
|
p["priority"] = priority
|
|
filter_data[name] = p
|
|
update_filters()
|
|
|
|
/atom/movable/proc/update_filters()
|
|
filters = null
|
|
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, 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) |