This commit is contained in:
Ghommie
2019-10-25 00:27:04 +02:00
139 changed files with 2438 additions and 1109 deletions
-6
View File
@@ -93,12 +93,6 @@
#define isgenital(A) (istype(A, /obj/item/organ/genital))
#define isborer(A) (istype(A, /mob/living/simple_animal/borer))
#define isipcperson(A) (is_species(A, /datum/species/ipc))
#define ismammal(A) (is_species(A, /datum/species/mammal))
#define isavian(A) (is_species(A, /datum/species/avian))
#define isaquatic(A) (is_species(A, /datum/species/aquatic))
#define isinsect(A) (is_species(A, /datum/species/insect))
#define isxenoperson(A) (is_species(A, /datum/species/xeno))
#define CITADEL_MENTOR_OOC_COLOUR "#224724"
-5
View File
@@ -5,8 +5,3 @@
#define CLEAN_STRONG 4 // Industrial strength
#define CLEAN_IMPRESSIVE 5 // Cleaning strong enough your granny would be proud
#define CLEAN_GOD 6 // Cleans things spotless down to the atomic structure
//How strong things have to be to wipe forensic evidence...
#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
#define CLEAN_STRENGTH_BLOOD CLEAN_WEAK
#define CLEAN_STRENGTH_FIBERS CLEAN_IMPRESSIVE
+3
View File
@@ -7,6 +7,7 @@
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
#define COMPONENT_INCOMPATIBLE 1
#define COMPONENT_NOTRANSFER 2
// How multiple components of the exact same type are handled in the same datum
@@ -225,6 +226,8 @@
#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
//Blood color
#define COMSIG_BLOOD_COLOR "blood_DNA_to_color" //RGB blood stuff
//Food
#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
+9
View File
@@ -15,6 +15,15 @@
//misc footstep sounds
#define FOOTSTEP_GENERIC_HEAVY "heavy"
#define FOOTPRINT_SHOE "shoe"
#define FOOTPRINT_FOOT "foot"
#define FOOTPRINT_PAW "paw"
#define FOOTPRINT_CLAW "claw"
#define FOOTPRINT_WHEEL "wheels"
#define FOOTPRINT_TRAIL "trails_"
#define FOOTPRINT_SNAKE "snake"
#define FOOTPRINT_DRAG "drag"
/*
id = list(
-2
View File
@@ -1,2 +0,0 @@
#define IF_HAS_BLOOD_DNA(__thing) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA))
#define IF_HAS_BLOOD_DNA_AND(__thing, __conditions...) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA) && (##__conditions))
+11
View File
@@ -61,6 +61,15 @@
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid) )
#define isdwarf(A) (is_species(A, /datum/species/dwarf))
// Citadel specific species
#define isipcperson(A) (is_species(A, /datum/species/ipc))
#define ismammal(A) (is_species(A, /datum/species/mammal))
#define isavian(A) (is_species(A, /datum/species/avian))
#define isaquatic(A) (is_species(A, /datum/species/aquatic))
#define isinsect(A) (is_species(A, /datum/species/insect))
#define isxenoperson(A) (is_species(A, /datum/species/xeno))
#define isstartjelly(A) (is_species(A, /datum/species/jelly/roundstartslime))
//more carbon mobs
#define ismonkey(A) (istype(A, /mob/living/carbon/monkey))
@@ -176,6 +185,8 @@ GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list(
#define iscameramob(A) (istype(A, /mob/camera))
#define isaicamera(A) (istype(A, /mob/camera/aiEye))
#define iseminence(A) (istype(A, /mob/camera/eminence))
//Footstep helpers
+12 -2
View File
@@ -171,12 +171,22 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
#define BLOOD_LOSS_IN_SPREAD 20
//Bloody shoe blood states
#define BLOOD_STATE_HUMAN "blood"
#define BLOOD_STATE_XENO "xeno"
#define BLOOD_STATE_BLOOD "blood"
#define BLOOD_STATE_OIL "oil"
#define BLOOD_STATE_NOT_BLOODY "no blood whatsoever"
#define BLOOD_AMOUNT_PER_DECAL 20
//Blood Decal Colors
#define BLOOD_COLOR_HUMAN "#dc0000"
#define BLOOD_COLOR_XENO "#94a83c"
#define BLOOD_COLOR_OIL "#301d02"
#define BLOOD_COLOR_SYNTHETIC "#3f48aa"
#define BLOOD_COLOR_SLIME "#00ff90"
#define BLOOD_COLOR_LIZARD "#db004D"
#define BLOOD_COLOR_UNIVERSAL "#db3300"
#define BLOOD_COLOR_BUG "#a37c0f"
//suit sensors: sensor_mode defines
#define SENSOR_OFF 0
-1
View File
@@ -756,7 +756,6 @@ Turf and target are separate in case you want to teleport some distance from a t
loc = loc.loc
return null
//For objects that should embed, but make no sense being is_sharp or is_pointed()
//e.g: rods
GLOBAL_LIST_INIT(can_embed_types, typecacheof(list(
+61
View File
@@ -58,3 +58,64 @@ GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traito
for(var/i in GLOB.mob_list)
var/mob/M = i
M.update_config_movespeed()
GLOBAL_LIST_INIT(noodle_taurs, list(
"Naga",
"Tentacle"
))
GLOBAL_LIST_INIT(paw_taurs, list(
"Fox",
"Wolf",
"Otie",
"Drake",
"Lab",
"Shepherd",
"Husky",
"Eevee",
"Panther",
"Horse",
"Cow",
"Tiger"
))
//blood types
GLOBAL_LIST_INIT(regular_bloods,list(
"O-",
"O+",
"A-",
"A+",
"B-",
"B+",
"AB-",
"AB+"
))
GLOBAL_LIST_INIT(all_types_bloods,list(
"O-",
"O+",
"A-",
"A+",
"B-",
"B+",
"AB-",
"AB+",
"SY",
"X*",
"HF",
"L",
"U",
"GEL",
"BUG"
))
GLOBAL_LIST_INIT(blood_types, list(
"blood",
"jellyblood"
))
GLOBAL_LIST_INIT(blood_id_types, list(
"blood" = /datum/reagent/blood,
"jellyblood" = /datum/reagent/blood/jellyblood
))
+17 -8
View File
@@ -2,6 +2,10 @@
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
var/dupe_type
var/datum/parent
//only set to true if you are able to properly transfer this component
//At a minimum RegisterWithParent and UnregisterFromParent should be used
//Make sure you also implement PostTransfer for any post transfer handling
var/can_transfer = FALSE
/datum/component/New(datum/P, ...)
parent = P
@@ -154,7 +158,7 @@
return
/datum/component/proc/PostTransfer()
return
return COMPONENT_INCOMPATIBLE //Do not support transfer by default as you must properly support it
/datum/component/proc/_GetInverseTypeList(our_type = type)
//we can do this one simple trick
@@ -285,10 +289,12 @@
if(target.parent)
target.RemoveComponent()
target.parent = src
if(target.PostTransfer() == COMPONENT_INCOMPATIBLE)
var/c_type = target.type
qdel(target)
CRASH("Incompatible [c_type] transfer attempt to a [type]!")
var/result = target.PostTransfer()
switch(result)
if(COMPONENT_INCOMPATIBLE)
var/c_type = target.type
qdel(target)
CRASH("Incompatible [c_type] transfer attempt to a [type]!")
if(target == AddComponent(target))
target._JoinParent()
@@ -298,10 +304,13 @@
return
var/comps = dc[/datum/component]
if(islist(comps))
for(var/I in comps)
target.TakeComponent(I)
for(var/datum/component/I in comps)
if(I.can_transfer)
target.TakeComponent(I)
else
target.TakeComponent(comps)
var/datum/component/C = comps
if(C.can_transfer)
target.TakeComponent(comps)
/datum/component/ui_host()
return parent
+24 -17
View File
@@ -8,32 +8,39 @@
/datum/component/cleaning/proc/Clean()
var/atom/movable/AM = parent
var/turf/tile = AM.loc
if(!isturf(tile))
return
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
for(var/A in tile)
var/turf/T = AM.loc
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/A in T)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/I = A
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(ismob(I.loc))
var/mob/M = I.loc
else if(isitem(A))
var/obj/item/cleaned_item = A
SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_item.clean_blood()
if(ismob(cleaned_item.loc))
var/mob/M = cleaned_item.loc
M.regenerate_icons()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes()
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.clean_blood()
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
to_chat(cleaned_human, "<span class='danger'>[AM] cleans your face!</span>")
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
+1 -1
View File
@@ -1,6 +1,6 @@
/datum/component/decal
dupe_mode = COMPONENT_DUPE_ALLOWED
can_transfer = TRUE
var/cleanable
var/description
var/mutable_appearance/pic
+13 -39
View File
@@ -1,39 +1,13 @@
/datum/component/decal/blood
dupe_mode = COMPONENT_DUPE_UNIQUE
/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
var/obj/item/I = parent
if(!_icon)
_icon = 'icons/effects/blood.dmi'
if(!_icon_state)
_icon_state = "itemblood"
var/icon = initial(I.icon)
var/icon_state = initial(I.icon_state)
if(!icon || !icon_state)
// It's something which takes on the look of other items, probably
icon = I.icon
icon_state = I.icon_state
var/static/list/blood_splatter_appearances = list()
//try to find a pre-processed blood-splatter. otherwise, make a new one
var/index = "[REF(icon)]-[icon_state]"
pic = blood_splatter_appearances[index]
if(!pic)
var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.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(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state))
blood_splatter_appearances[index] = pic
return TRUE
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
var/atom/A = parent
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
return COMPONENT_EXNAME_CHANGED
/datum/component/decal/blood
dupe_mode = COMPONENT_DUPE_UNIQUE
/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
var/atom/A = parent
return COMPONENT_EXNAME_CHANGED
-159
View File
@@ -1,159 +0,0 @@
/datum/component/forensics
dupe_mode = COMPONENT_DUPE_UNIQUE
var/list/fingerprints //assoc print = print
var/list/hiddenprints //assoc ckey = realname/gloves/ckey
var/list/blood_DNA //assoc dna = bloodtype
var/list/fibers //assoc print = print
/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL.
fingerprints = fingerprints | F.fingerprints
hiddenprints = hiddenprints | F.hiddenprints
blood_DNA = blood_DNA | F.blood_DNA
fibers = fibers | F.fibers
check_blood()
return ..()
/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
fingerprints = new_fingerprints
hiddenprints = new_hiddenprints
blood_DNA = new_blood_DNA
fibers = new_fibers
check_blood()
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act)
/datum/component/forensics/proc/wipe_fingerprints()
fingerprints = null
return TRUE
/datum/component/forensics/proc/wipe_hiddenprints()
return //no.
/datum/component/forensics/proc/wipe_blood_DNA()
blood_DNA = null
if(isitem(parent))
qdel(parent.GetComponent(/datum/component/decal/blood))
return TRUE
/datum/component/forensics/proc/wipe_fibers()
fibers = null
return TRUE
/datum/component/forensics/proc/clean_act(datum/source, strength)
if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
wipe_fingerprints()
if(strength >= CLEAN_STRENGTH_BLOOD)
wipe_blood_DNA()
if(strength >= CLEAN_STRENGTH_FIBERS)
wipe_fibers()
/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text)
if(!length(_fingerprints))
return
LAZYINITLIST(fingerprints)
for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
fingerprints[i] = i
return TRUE
/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
if(!M)
return
add_hiddenprint(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
add_fibers(H)
if(H.gloves) //Check if the gloves (if any) hide fingerprints
var/obj/item/clothing/gloves/G = H.gloves
if(G.transfer_prints)
ignoregloves = TRUE
if(!ignoregloves)
H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop.
return
var/full_print = md5(H.dna.uni_identity)
LAZYSET(fingerprints, full_print, full_print)
return TRUE
/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text)
if(!length(_fibertext))
return
LAZYINITLIST(fibers)
for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours.
fibers[i] = i
return TRUE
/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M)
var/fibertext
var/item_multiplier = isitem(src)?1.2:1
if(M.wear_suit)
fibertext = "Material from \a [M.wear_suit]."
if(prob(10*item_multiplier) && !LAZYACCESS(fibers, fibertext))
LAZYSET(fibers, fibertext, fibertext)
if(!(M.wear_suit.body_parts_covered & CHEST))
if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(12*item_multiplier) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed.
LAZYSET(fibers, fibertext, fibertext)
if(!(M.wear_suit.body_parts_covered & HANDS))
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
LAZYSET(fibers, fibertext, fibertext)
else if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext))
// "Added fibertext: [fibertext]"
LAZYSET(fibers, fibertext, fibertext)
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
LAZYSET(fibers, fibertext, fibertext)
else if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext))
LAZYSET(fibers, fibertext, fibertext)
return TRUE
/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text)
if(!length(_hiddenprints))
return
LAZYINITLIST(hiddenprints)
for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours.
hiddenprints[i] = _hiddenprints[i]
return TRUE
/datum/component/forensics/proc/add_hiddenprint(mob/living/M)
if(!M || !M.key)
return
var/hasgloves = ""
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.gloves)
hasgloves = "(gloves)"
var/current_time = TIME_STAMP("hh:mm:ss", FALSE)
if(!LAZYACCESS(hiddenprints, M.key))
LAZYSET(hiddenprints, M.key, "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]")
else
var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), " Last: ")
if(laststamppos)
LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos))
hiddenprints[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else
var/atom/A = parent
A.fingerprintslast = M.ckey
return TRUE
/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type)
if(!length(dna))
return
LAZYINITLIST(blood_DNA)
for(var/i in dna)
blood_DNA[i] = dna[i]
check_blood()
return TRUE
/datum/component/forensics/proc/check_blood()
if(!isitem(parent))
return
if(!length(blood_DNA))
return
parent.LoadComponent(/datum/component/decal/blood)
-3
View File
@@ -237,6 +237,3 @@
LOCKON_RANGING_BREAK_CHECK
cd++
CHECK_TICK
/datum/component/lockon_aiming/PostTransfer(datum/new_parent)
return COMPONENT_INCOMPATIBLE
+1
View File
@@ -1,4 +1,5 @@
/datum/component/mirage_border
can_transfer = TRUE
var/obj/effect/abstract/mirage_holder/holder
/datum/component/mirage_border/Initialize(turf/target, direction, range=world.view)
+28 -7
View File
@@ -44,19 +44,21 @@
if(src.rotation_flags & ROTATION_CLOCKWISE)
default_rotation_direction = ROTATION_CLOCKWISE
if(src.rotation_flags & ROTATION_ALTCLICK)
/datum/component/simple_rotation/proc/add_signals()
if(rotation_flags & ROTATION_ALTCLICK)
RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/HandRot)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/ExamineMessage)
if(src.rotation_flags & ROTATION_WRENCH)
if(rotation_flags & ROTATION_WRENCH)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/WrenchRot)
if(src.rotation_flags & ROTATION_VERBS)
/datum/component/simple_rotation/proc/add_verbs()
if(rotation_flags & ROTATION_VERBS)
var/atom/movable/AM = parent
if(src.rotation_flags & ROTATION_FLIP)
if(rotation_flags & ROTATION_FLIP)
AM.verbs += /atom/movable/proc/simple_rotate_flip
if(src.rotation_flags & ROTATION_CLOCKWISE)
if(rotation_flags & ROTATION_CLOCKWISE)
AM.verbs += /atom/movable/proc/simple_rotate_clockwise
if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE)
if(rotation_flags & ROTATION_COUNTERCLOCKWISE)
AM.verbs += /atom/movable/proc/simple_rotate_counterclockwise
/datum/component/simple_rotation/proc/remove_verbs()
@@ -66,11 +68,30 @@
AM.verbs -= /atom/movable/proc/simple_rotate_clockwise
AM.verbs -= /atom/movable/proc/simple_rotate_counterclockwise
/datum/component/simple_rotation/Destroy()
/datum/component/simple_rotation/proc/remove_signals()
UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY))
/datum/component/simple_rotation/RegisterWithParent()
add_verbs()
add_signals()
. = ..()
/datum/component/simple_rotation/PostTransfer()
//Because of the callbacks which we don't track cleanly we can't transfer this
//item cleanly, better to let the new of the new item create a new rotation datum
//instead (there's no real state worth transferring)
return COMPONENT_NOTRANSFER
/datum/component/simple_rotation/UnregisterFromParent()
remove_verbs()
remove_signals()
. = ..()
/datum/component/simple_rotation/Destroy()
QDEL_NULL(can_user_rotate)
QDEL_NULL(can_be_rotated)
QDEL_NULL(after_rotation)
//Signals + verbs removed via UnRegister
. = ..()
/datum/component/simple_rotation/RemoveComponent()
@@ -4,6 +4,7 @@
// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement
/datum/component/storage/concrete
can_transfer = TRUE
var/drop_all_on_deconstruct = TRUE
var/drop_all_on_destroy = FALSE
var/drop_all_on_break = FALSE
+16 -2
View File
@@ -1,5 +1,6 @@
/datum/component/wet_floor
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
can_transfer = TRUE
var/highest_strength = TURF_DRY
var/lube_flags = NONE //why do we have this?
var/list/time_left_list //In deciseconds.
@@ -26,14 +27,20 @@
if(!isopenturf(parent))
return COMPONENT_INCOMPATIBLE
add_wet(strength, duration_minimum, duration_add, duration_maximum)
RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet)
RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry)
permanent = _permanent
if(!permanent)
START_PROCESSING(SSwet_floors, src)
addtimer(CALLBACK(src, .proc/gc, TRUE), 1) //GC after initialization.
last_process = world.time
/datum/component/wet_floor/RegisterWithParent()
RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet)
RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry)
/datum/component/wet_floor/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY))
/datum/component/wet_floor/Destroy()
STOP_PROCESSING(SSwet_floors, src)
var/turf/T = parent
@@ -138,12 +145,19 @@
/datum/component/wet_floor/PreTransfer()
var/turf/O = parent
O.cut_overlay(current_overlay)
//That turf is no longer slippery, we're out of here
//Slippery components don't transfer due to callbacks
qdel(O.GetComponent(/datum/component/slippery))
/datum/component/wet_floor/PostTransfer()
if(!isopenturf(parent))
return COMPONENT_INCOMPATIBLE
var/turf/T = parent
T.add_overlay(current_overlay)
//Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent)
update_flags()
//NB it's possible we get deleted after this, due to inherit
/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE)
var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST)
+2 -1
View File
@@ -10,10 +10,11 @@
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
// Helper similar to image()
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE)
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, color = "#FFFFFF")
var/mutable_appearance/MA = new()
MA.icon = icon
MA.icon_state = icon_state
MA.layer = layer
MA.plane = plane
MA.color = color
return MA
+127 -9
View File
@@ -36,6 +36,12 @@
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()
@@ -220,7 +226,7 @@
return FALSE
/atom/proc/CheckExit()
return 1
return TRUE
/atom/proc/HasProximity(atom/movable/AM as mob|obj)
return
@@ -254,14 +260,26 @@
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)
. = "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
/atom/proc/examine(mob/user)
to_chat(user, get_examine_string(user, TRUE))
to_chat(user, "[get_examine_string(user, TRUE)].")
if(desc)
to_chat(user, desc)
@@ -326,12 +344,14 @@
//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")
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()
if(get_blood_id() != "blood")
var/blood_id = get_blood_id()
if(!(blood_id =="blood" || blood_id == "jellyblood"))
return
var/list/blood_dna = list()
if(dna)
@@ -349,18 +369,116 @@
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
return FALSE
var/old_length = blood_DNA_length()
add_blood_DNA(new_blood_dna)
if(blood_DNA_length() == old_length)
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)
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
@@ -714,4 +832,4 @@ Proc for attack log creation, because really why not
if(filter_data[name])
filter_data -= name
update_filters()
return TRUE
return TRUE
+1 -1
View File
@@ -317,7 +317,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
/obj/effect/meteor/meaty/xeno/ram_turf(turf/T)
if(!isspaceturf(T))
new /obj/effect/decal/cleanable/xenoblood(T)
new /obj/effect/decal/cleanable/blood/xeno(T)
//Station buster Tunguska
/obj/effect/meteor/tunguska
+361
View File
@@ -0,0 +1,361 @@
/obj/machinery/bloodbankgen
name = "blood bank generator"
desc = "Generates universally applicable synthetics for all blood types. Add regular blood to convert."
icon = 'icons/obj/bloodbank.dmi'
icon_state = "bloodbank-off"
density = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 80
circuit = /obj/item/circuitboard/machine/bloodbankgen
interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON
var/draining = FALSE
var/filling = FALSE
var/obj/item/reagent_containers/blood/bag = null
var/obj/item/reagent_containers/blood/outbag = null
var/bloodstored = 0
var/maxbloodstored = 1000
var/menustat = "menu"
var/efficiency = 0
var/productivity = 0
/obj/machinery/bloodbankgen/Initialize()
. = ..()
create_reagents(1000)
update_icon()
/obj/machinery/bloodbankgen/Destroy()
QDEL_NULL(bag)
QDEL_NULL(outbag)
return ..()
/obj/machinery/bloodbankgen/contents_explosion(severity, target)
..()
if(bag)
bag.ex_act(severity, target)
if(outbag)
outbag.ex_act(severity, target)
/obj/machinery/bloodbankgen/handle_atom_del(atom/A)
..()
if(A == bag)
bag = null
update_icon()
updateUsrDialog()
if(A == outbag)
outbag = null
update_icon()
updateUsrDialog()
/obj/machinery/bloodbankgen/RefreshParts()
var/E = 0
var/P = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
E += M.rating
efficiency = E
productivity = P
/obj/machinery/bloodbankgen/update_icon()
cut_overlays()
if(is_operational())
icon_state = "bloodbank-on"
if(panel_open)
add_overlay("bloodbank-panel")
if(src.bag)
add_overlay("bloodbag-input")
if(bag.reagents.total_volume)
var/mutable_appearance/filling_overlay = mutable_appearance(icon, "input-reagent")
var/percent = round((bag.reagents.total_volume / bag.volume) * 100)
switch(percent)
if(0 to 9)
filling_overlay.icon_state = "input-reagent0"
if(10 to 24)
filling_overlay.icon_state = "input-reagent10"
if(25 to 49)
filling_overlay.icon_state = "input-reagent25"
if(50 to 74)
filling_overlay.icon_state = "input-reagent50"
if(75 to 79)
filling_overlay.icon_state = "input-reagent75"
if(80 to 90)
filling_overlay.icon_state = "input-reagent80"
if(91 to INFINITY)
filling_overlay.icon_state = "input-reagent100"
filling_overlay.color = list(mix_color_from_reagents(bag.reagents.reagent_list))
add_overlay(filling_overlay)
if(src.outbag)
add_overlay("bloodbag-output")
if(outbag.reagents.total_volume)
var/mutable_appearance/filling_overlay = mutable_appearance(icon, "output-reagent")
var/percent = round((outbag.reagents.total_volume / outbag.volume) * 100)
switch(percent)
if(0 to 9)
filling_overlay.icon_state = "output-reagent0"
if(10 to 24)
filling_overlay.icon_state = "output-reagent10"
if(25 to 49)
filling_overlay.icon_state = "output-reagent25"
if(50 to 74)
filling_overlay.icon_state = "output-reagent50"
if(75 to 79)
filling_overlay.icon_state = "output-reagent75"
if(80 to 90)
filling_overlay.icon_state = "output-reagent80"
if(91 to INFINITY)
filling_overlay.icon_state = "output-reagent100"
filling_overlay.color = list(mix_color_from_reagents(outbag.reagents.reagent_list))
add_overlay(filling_overlay)
return
/obj/machinery/bloodbankgen/process()
if(!is_operational())
return PROCESS_KILL
bloodstored = reagents.total_volume
var/transfer_amount = 20
if(draining)
if(reagents.total_volume >= reagents.maximum_volume)
draining = FALSE
return
if(bag)
if(bag.reagents.total_volume)
var/datum/reagent/blood/B = bag.reagents.has_reagent("blood")
if(B)
var/amount = reagents.maximum_volume - reagents.total_volume //monitor the machine's internal storage
amount = min(amount, transfer_amount)
if(!amount)
draining = FALSE
updateUsrDialog()
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
return
if(bag.blood_type == "SY") //no infinite loops using synthetics.
reagents.add_reagent("syntheticblood", amount)
else
reagents.add_reagent("syntheticblood", (amount+(5*efficiency)))
if(bag.reagents.total_volume >= amount)
bag.reagents.remove_reagent("blood", amount)
else
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
draining = FALSE
bag.update_icon()
update_icon()
updateUsrDialog()
else
draining = FALSE
updateUsrDialog()
return
if(filling)
if(!reagents || !reagents.total_volume)
filling = FALSE //there ain't anything in the machine yo.
return
if(outbag && outbag.reagents.total_volume < outbag.reagents.maximum_volume)
var/amount = outbag.reagents.maximum_volume - outbag.reagents.total_volume //monitor the output bag's internal storage
amount = min(amount, transfer_amount)
if(!amount)
filling = FALSE
visible_message("[src] pings.")
playsound(loc, 'sound/machines/beep.ogg', 50, 1)
updateUsrDialog()
return
reagents.trans_to(outbag, amount)
outbag.update_icon()
update_icon()
updateUsrDialog()
else
visible_message("[src] pings.")
playsound(loc, 'sound/machines/beep.ogg', 50, 1)
filling = FALSE
updateUsrDialog()
return
/obj/machinery/bloodbankgen/attackby(obj/item/O, mob/user, params)
if(user.a_intent == INTENT_HARM)
return ..()
if(default_deconstruction_screwdriver(user, "bloodbank-off", "bloodbank-off", O))
if(bag)
var/obj/item/reagent_containers/blood/B = bag
B.forceMove(drop_location())
bag = null
if(outbag)
var/obj/item/reagent_containers/blood/B = outbag
B.forceMove(drop_location())
outbag = null
update_icon()
return
if(default_deconstruction_crowbar(O))
return
if(istype(O, /obj/item/reagent_containers/blood))
. = 1 //no afterattack
if(!panel_open)
if(bag && outbag)
to_chat(user, "<span class='warning'>This machine already has bags attached.</span>")
if(!bag && !outbag)
var/choice = alert(user, "Choose where to place [O]", "", "Input", "Cancel", "Output")
switch(choice)
if("Cancel")
return FALSE
if("Input")
attachinput(O, user)
if("Output")
attachoutput(O, user)
else if(!bag)
attachinput(O, user)
else if(!outbag)
attachoutput(O, user)
else
to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>")
return
else
to_chat(user, "<span class='warning'>You cannot put this in [src]!</span>")
/obj/machinery/bloodbankgen/ui_interact(mob/user)
. = ..()
if(!is_operational())
return
var/dat
switch(menustat)
if("noblood")
dat += "<div class='statusDisplay'>You do not have enough blood product to create synthetics.</div>"
menustat = "menu"
if("complete")
dat += "<div class='statusDisplay'>Operation complete.</div>"
menustat = "menu"
if("nobagspace")
dat += "<div class='statusDisplay'>Not enough space left in container. Please replace receptical.</div>"
menustat = "menu"
dat+= "<br><B>Current Synthetics stockpile: [reagents.total_volume] units.</B><HR>"
dat += "<br>Supply Bag<HR>"
if(bag)
dat += "<br>Current Capacity: [bag.reagents.total_volume] of [bag.reagents.maximum_volume]"
if(bag.reagents && bag.reagents.total_volume)
dat += "<br><a href='?src=\ref[src];activateinput=1'>Drain</a>"
dat += "<br><a href='?src=\ref[src];detachinput=1'>Detach</a>"
dat += "<br><br>Synthetics Bag<HR>"
if(outbag)
dat += "<br>Current Capacity:[outbag.reagents.total_volume] of [outbag.reagents.maximum_volume]"
if(!(outbag.reagents.total_volume >= outbag.reagents.maximum_volume))
dat += "<br><a href='?src=\ref[src];activateoutput=1'>Fill</a>"
dat += "<br><a href='?src=\ref[src];detachoutput=1'>Detach</a>"
if(!bag && !outbag)
dat += "<div class='statusDisplay'>No containers inside, please insert container.</div>"
var/datum/browser/popup = new(user, "bloodbankgen", name, 350, 520)
popup.set_content(dat)
popup.open()
/obj/machinery/bloodbankgen/proc/activateinput()
if(bag)
draining = TRUE
update_icon()
else
to_chat(usr, "<span class='warning'>There is no blood bag in the input slot.</span>")
return
/obj/machinery/bloodbankgen/proc/activateoutput()
if(outbag)
filling = TRUE
update_icon()
else
to_chat(usr, "<span class='warning'>There is no blood bag in the output slot.</span>")
return
/obj/machinery/bloodbankgen/proc/check_container_volume(list/reagents, multiplier = 1)
var/sum_reagents = 0
for(var/R in reagents)
sum_reagents += reagents[R]
sum_reagents *= multiplier
if(outbag.reagents.total_volume + sum_reagents > outbag.reagents.maximum_volume)
menustat = "nobagspace"
return FALSE
return TRUE
/obj/machinery/bloodbankgen/proc/detachinput()
if(bag)
bag.forceMove(drop_location())
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
usr.put_in_hands(bag)
bag = null
update_icon()
/obj/machinery/bloodbankgen/proc/detachoutput()
if(outbag)
outbag.forceMove(drop_location())
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
usr.put_in_hands(outbag)
outbag = null
update_icon()
/obj/machinery/bloodbankgen/proc/attachinput(obj/item/O, mob/user)
if(!bag)
if(!user.transferItemToLoc(O, src))
return
bag = O
to_chat(user, "<span class='notice'>You add [O] to the machine's input slot.</span>")
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>There is already something in this slot!</span>")
/obj/machinery/bloodbankgen/proc/attachoutput(obj/item/O, mob/user)
if(!outbag)
if(!user.transferItemToLoc(O, src))
return
outbag = O
to_chat(user, "<span class='notice'>You add [O] to the machine's output slot.</span>")
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='notice'>There is already something in this slot!</span>")
/obj/machinery/bloodbankgen/Topic(href, href_list)
if(..() || panel_open)
return
usr.set_machine(src)
if(href_list["activateinput"])
activateinput()
updateUsrDialog()
else if(href_list["detachinput"])
detachinput()
updateUsrDialog()
else if(href_list["activateoutput"])
activateoutput()
updateUsrDialog()
else if(href_list["detachoutput"])
detachoutput()
updateUsrDialog()
+1 -1
View File
@@ -326,7 +326,7 @@
else //for simple_animals & borgs
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
var/turf/location = get_turf(src)
//add_blood doesn't work for borgs/xenos, but add_blood_floor does.
//add_blood_DNA doesn't work for borgs/xenos, but add_blood_floor does.
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(DOOR_CRUSH_DAMAGE)
+20 -14
View File
@@ -8,14 +8,14 @@
icon_state = "iv_drip"
anchored = FALSE
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
var/mob/living/carbon/attached = null
var/mob/living/carbon/attached
var/mode = IV_INJECTING
var/obj/item/reagent_containers/beaker = null
var/obj/item/reagent_containers/beaker
var/static/list/drip_containers = typecacheof(list(/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/food,
/obj/item/reagent_containers/glass))
/obj/machinery/iv_drip/Initialize()
/obj/machinery/iv_drip/Initialize(mapload)
. = ..()
update_icon()
@@ -84,6 +84,8 @@
if(Adjacent(target) && usr.Adjacent(target))
if(beaker)
usr.visible_message("<span class='warning'>[usr] attaches [src] to [target].</span>", "<span class='notice'>You attach [src] to [target].</span>")
log_combat(usr, target, "attached", src, "containing: [beaker.name] - ([beaker.reagents.log_list()])")
add_fingerprint(usr)
attached = target
START_PROCESSING(SSmachines, src)
update_icon()
@@ -100,6 +102,8 @@
return
beaker = W
to_chat(user, "<span class='notice'>You attach [W] to [src].</span>")
user.log_message("attached a [W] to [src] at [AREACOORD(src)] containing ([beaker.reagents.log_list()])", LOG_ATTACK)
add_fingerprint(user)
update_icon()
return
else
@@ -142,10 +146,11 @@
if(!amount)
if(prob(5))
visible_message("[src] pings.")
playsound(loc, 'sound/machines/beep.ogg', 50, 1)
return
// If the human is losing too much blood, beep.
if(attached.blood_volume < ( (BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) ) )
if(attached.blood_volume < ((BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) && ishuman(attached))) //really couldn't care less about monkeys
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
attached.transfer_blood_to(beaker, amount)
@@ -178,9 +183,10 @@
if(usr.incapacitated())
return
if(beaker)
beaker.forceMove(drop_location())
if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
if(!usr.put_in_hands(beaker))
beaker.forceMove(drop_location())
beaker = null
update_icon()
@@ -195,27 +201,27 @@
if(usr.incapacitated())
return
mode = !mode
to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].")
update_icon()
/obj/machinery/iv_drip/examine(mob/user)
..()
. = ..()
if(get_dist(user, src) > 2)
return
to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
. += "[src] is [mode ? "injecting" : "taking blood"].\n"
if(beaker)
if(beaker.reagents && beaker.reagents.reagent_list.len)
to_chat(user, "<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>")
. += "\t<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>\n"
else
to_chat(user, "<span class='notice'>Attached is an empty [beaker.name].</span>")
. += "\t<span class='notice'>Attached is an empty [beaker.name].</span>\n"
else
to_chat(user, "<span class='notice'>No chemicals are attached.</span>")
. += "\t<span class='notice'>No chemicals are attached.</span>\n"
to_chat(user, "<span class='notice'>[attached ? attached : "No one"] is attached.</span>")
. += "\t<span class='notice'>[attached ? attached : "No one"] is attached.</span>"
to_chat(user,.)
#undef IV_TAKING
#undef IV_INJECTING
#undef IV_INJECTING
+3 -1
View File
@@ -265,6 +265,8 @@
things_to_clear += occupant.GetAllContents()
for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
AM.clean_blood()
AM.fingerprints = list()
var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
@@ -435,4 +437,4 @@
if(I)
I.forceMove(loc)
. = TRUE
update_icon()
update_icon()
+4 -6
View File
@@ -11,10 +11,6 @@
var/obj/item/color_source
var/max_wash_capacity = 5
/obj/machinery/washing_machine/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click it to start a wash cycle.</span>")
@@ -59,7 +55,8 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
/obj/machinery/washing_machine/proc/clean_blood()
/obj/machinery/washing_machine/clean_blood()
..()
if(!busy)
bloody_mess = FALSE
update_icon()
@@ -67,7 +64,8 @@
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
AM.clean_blood()
AM.machine_wash(src)
busy = FALSE
@@ -8,6 +8,7 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
@@ -27,7 +28,7 @@
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
return TRUE
qdel(C)
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
@@ -81,7 +82,9 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
S.add_blood_DNA(return_blood_DNA())
if(blood_DNA && blood_DNA.len)
S.add_blood_DNA(blood_DNA)
S.add_blood_overlay()
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
@@ -90,4 +93,4 @@
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return bloodiness
else
return 0
return FALSE
@@ -1,71 +1,72 @@
// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code.
/obj/effect/decal/cleanable/xenoblood
/obj/effect/decal/cleanable/blood/xeno
name = "xeno blood"
desc = "It's green and acidic. It looks like... <i>blood?</i>"
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
bloodiness = BLOOD_AMOUNT_PER_DECAL
blood_state = BLOOD_STATE_XENO
color = BLOOD_COLOR_XENO
/obj/effect/decal/cleanable/xenoblood/Initialize()
/obj/effect/decal/cleanable/blood/splatter/xeno
color = BLOOD_COLOR_XENO
/obj/effect/decal/cleanable/blood/gibs/xeno
color = BLOOD_COLOR_XENO
gibs_reagent_id = "liquidxenogibs"
gibs_bloodtype = "X*"
/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
. = ..()
add_blood_DNA(list("UNKNOWN DNA" = "X*"))
update_icon()
/obj/effect/decal/cleanable/xenoblood/xsplatter
random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]x_flesh")
flesh.appearance_flags = RESET_COLOR
flesh.color = body_colors
add_overlay(flesh)
/obj/effect/decal/cleanable/xenoblood/xgibs
name = "xeno gibs"
desc = "Gnarly..."
icon = 'icons/effects/blood.dmi'
icon_state = "xgib1"
layer = LOW_OBJ_LAYER
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
mergeable_decal = FALSE
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
/obj/effect/decal/cleanable/blood/gibs/xeno/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if(i > 0)
new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
var/list/datum/disease/diseases
GET_COMPONENT(infective, /datum/component/infective)
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/xenoblood/xgibs/ex_act()
return
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/xenoblood/xgibs/up
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
/obj/effect/decal/cleanable/blood/gibs/xeno/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/xenoblood/xgibs/down
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
/obj/effect/decal/cleanable/blood/gibs/xeno/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/xenoblood/xgibs/body
random_icon_states = list("xgibhead", "xgibtorso")
/obj/effect/decal/cleanable/blood/gibs/xeno/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/xenoblood/xgibs/torso
random_icon_states = list("xgibtorso")
/obj/effect/decal/cleanable/blood/gibs/xeno/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/xenoblood/xgibs/limb
random_icon_states = list("xgibleg", "xgibarm")
/obj/effect/decal/cleanable/blood/gibs/xeno/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/xenoblood/xgibs/core
random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
/obj/effect/decal/cleanable/xenoblood/xgibs/larva
/obj/effect/decal/cleanable/blood/gibs/xeno/larva
random_icon_states = list("xgiblarva1", "xgiblarva2")
/obj/effect/decal/cleanable/xenoblood/xgibs/larva/body
/obj/effect/decal/cleanable/blood/gibs/xeno/larva/body
random_icon_states = list("xgiblarvahead", "xgiblarvatorso")
/obj/effect/decal/cleanable/blood/xtracks
icon_state = "xtracks"
icon_state = "tracks"
random_icon_states = null
/obj/effect/decal/cleanable/blood/xtracks/Initialize()
. = ..()
add_blood_DNA(list("Unknown DNA" = "X*"))
add_blood_DNA(list("UNKNOWN DNA" = "X*"))
. = ..()
@@ -0,0 +1,233 @@
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
icon_state = "gibbl5"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = "liquidgibs"
var/gibs_bloodtype = "A+"
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
. = ..()
if(random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
if(gibs_reagent_id)
reagents.add_reagent(gibs_reagent_id, 5)
if(gibs_bloodtype)
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]_guts")
guts.appearance_flags = RESET_COLOR
add_overlay(guts)
var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
flesh.appearance_flags = RESET_COLOR
flesh.color = body_colors
add_overlay(flesh)
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
if(istype(L) && has_gravity(loc))
playsound(loc, 'sound/effects/gib_step.ogg', !HAS_TRAIT(L,TRAIT_LIGHT_STEP) ? 20 : 50, 1)
. = ..()
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if(i > 0)
var/list/datum/disease/diseases
GET_COMPONENT(infective, /datum/component/infective)
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/old
name = "old rotting gibs"
desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
bloodiness = 0
/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
setDir(pick(GLOB.cardinals))
icon_state += "-old"
update_icon()
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's gooey."
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
return TRUE
/obj/effect/decal/cleanable/blood/gibs/human
/obj/effect/decal/cleanable/blood/gibs/human/Initialize(mapload, list/datum/disease/diseases)
. = ..()
update_icon()
/obj/effect/decal/cleanable/blood/gibs/human/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/human/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/human/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/human/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/human/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/human/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
//Lizards
/obj/effect/decal/cleanable/blood/gibs/human/lizard
body_colors = "117720"
gibs_reagent_id = "liquidgibs"
gibs_bloodtype = "L"
/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
. = ..()
update_icon()
/obj/effect/decal/cleanable/blood/gibs/human/lizard/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/human/lizard/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/human/lizard/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/human/lizard/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/human/lizard/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/human/lizard/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
// Slime Gibs
/obj/effect/decal/cleanable/blood/gibs/slime
desc = "They look gooey and gruesome."
gibs_reagent_id = "liquidslimegibs"
gibs_bloodtype = "GEL"
/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
. = ..()
update_icon()
/obj/effect/decal/cleanable/blood/gibs/slime/update_icon()
add_atom_colour(body_colors, FIXED_COLOUR_PRIORITY)
cut_overlays()
var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]s_guts")
guts.appearance_flags = RESET_COLOR
guts.color = body_colors
add_overlay(guts)
var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
flesh.appearance_flags = RESET_COLOR
flesh.color = body_colors
add_overlay(flesh)
/obj/effect/decal/cleanable/blood/gibs/slime/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/slime/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/slime/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/slime/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/slime/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/slime/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/synth
desc = "They look sludgy and disgusting."
gibs_reagent_id = "liquidsyntheticgibs"
gibs_bloodtype = "SY"
/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
. = ..()
update_icon()
//IPCs
/obj/effect/decal/cleanable/blood/gibs/ipc
desc = "They look sharp yet oozing."
body_colors = "00ff00"
gibs_reagent_id = "liquidoilgibs"
gibs_bloodtype = "HF"
/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
. = ..()
update_icon()
/obj/effect/decal/cleanable/blood/gibs/ipc/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]r-overlay")
guts.appearance_flags = RESET_COLOR
add_overlay(guts)
/obj/effect/decal/cleanable/blood/gibs/ipc/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/ipc/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/ipc/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/ipc/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/ipc/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/ipc/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
@@ -1,31 +1,45 @@
/obj/effect/decal/cleanable/blood
name = "blood"
desc = "It's red and gooey. Perhaps it's the chef's cooking?"
desc = "It's gooey. Perhaps it's the chef's cooking?"
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_HUMAN
bloodiness = BLOOD_AMOUNT_PER_DECAL
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
C.add_blood_DNA(return_blood_DNA())
if (bloodiness)
if (C.bloodiness < MAX_SHOE_BLOODINESS)
C.bloodiness += bloodiness
return ..()
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
update_icon()
..()
/obj/effect/decal/cleanable/blood/transfer_blood_dna()
..()
update_icon()
/obj/effect/decal/cleanable/blood/transfer_mob_blood_dna()
. = ..()
update_icon()
/obj/effect/decal/cleanable/blood/update_icon()
color = blood_DNA_to_color()
/obj/effect/decal/cleanable/blood/old
name = "dried blood"
desc = "Looks like it's been here a while. Eew."
desc = "Looks like it's been here a while. Eew."
bloodiness = 0
/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases)
icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
add_blood_DNA(list("Non-human DNA" = "A+")) // Needs to happen before ..()
return ..()
..()
icon_state += "-old"
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/splats
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
random_icon_states = list("splatter1", "splatter2", "splatter3", "splatter4", "splatter5")
/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
@@ -39,84 +53,23 @@
random_icon_states = null
var/list/existing_dirs = list()
/obj/effect/decal/cleanable/trail_holder/update_icon()
color = blood_DNA_to_color()
/obj/effect/cleanable/trail_holder/Initialize()
. = ..()
update_icon()
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
return TRUE
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
/obj/effect/decal/cleanable/trail_holder/transfer_blood_dna()
..()
update_icon()
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
/obj/effect/decal/cleanable/trail_holder/transfer_mob_blood_dna()
. = ..()
reagents.add_reagent("liquidgibs", 5)
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
if(istype(L) && has_gravity(loc))
playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1)
. = ..()
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if(i > 0)
var/list/datum/disease/diseases
GET_COMPONENT(infective, /datum/component/infective)
if(infective)
diseases = infective.diseases
new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/old
name = "old rotting gibs"
desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
bloodiness = 0
/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
setDir(pick(1,2,4,8))
icon_state += "-old"
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's red."
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
return TRUE
update_icon()
//BLOODY FOOTPRINTS
/obj/effect/decal/cleanable/blood/footprints
@@ -127,15 +80,16 @@
random_icon_states = null
var/entered_dirs = 0
var/exited_dirs = 0
blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
blood_state = BLOOD_STATE_BLOOD //the icon state to load images from
var/list/shoe_types = list()
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
if(color != bloodtype_to_color(S.last_bloodtype))
return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(entered_dirs & H.dir))
@@ -143,21 +97,21 @@
update_icon()
/obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O)
..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
if(color != bloodtype_to_color(S.last_bloodtype))//last entry - we check its color
return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(exited_dirs & H.dir))
exited_dirs |= H.dir
update_icon()
/obj/effect/decal/cleanable/blood/footprints/update_icon()
..()
cut_overlays()
for(var/Ddir in GLOB.cardinals)
if(entered_dirs & Ddir)
var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"]
@@ -170,7 +124,7 @@
GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir)
add_overlay(bloodstep_overlay)
alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness
alpha = BLOODY_FOOTPRINT_BASE_ALPHA + bloodiness
/obj/effect/decal/cleanable/blood/footprints/examine(mob/user)
@@ -179,16 +133,62 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
. += "[icon2html(initial(S.icon), user)] Some <B>[initial(S.name)]</B>.\n"
. += "some <B>[initial(S.name)]</B> [icon2html(initial(S.icon), user)]\n"
to_chat(user, .)
/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C)
if(blood_state != C.blood_state) //We only replace footprints of the same type as us
return
if(color != C.color)
return
..()
/obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return 1
return 0
return TRUE
return FALSE
/* Eventually TODO: make snowflake trails like baycode's
/obj/effect/decal/cleanable/blood/footprints/tracks/shoe
name = "footprints"
desc = "They look like tracks left by footwear."
icon_state = FOOTPRINT_SHOE
print_state = FOOTPRINT_SHOE
/obj/effect/decal/cleanable/blood/footprints/tracks/foot
name = "footprints"
desc = "They look like tracks left by a bare foot."
icon_state = FOOTPRINT_FOOT
print_state = FOOTPRINT_FOOT
/obj/effect/decal/cleanable/blood/footprints/tracks/snake
name = "tracks"
desc = "They look like tracks left by a giant snake."
icon_state = FOOTPRINT_SNAKE
print_state = FOOTPRINT_SNAKE
/obj/effect/decal/cleanable/blood/footprints/tracks/paw
name = "footprints"
desc = "They look like tracks left by paws."
icon_state = FOOTPRINT_PAW
print_state = FOOTPRINT_PAW
/obj/effect/decal/cleanable/blood/footprints/tracks/claw
name = "footprints"
desc = "They look like tracks left by claws."
icon_state = FOOTPRINT_CLAW
print_state = FOOTPRINT_CLAW
/obj/effect/decal/cleanable/blood/footprints/tracks/wheels
name = "tracks"
desc = "They look like tracks left by wheels."
gender = PLURAL
icon_state = FOOTPRINT_WHEEL
print_state = FOOTPRINT_WHEEL
/obj/effect/decal/cleanable/blood/footprints/tracks/body
name = "trails"
desc = "A trail left by something being dragged."
icon_state = FOOTPRINT_DRAG
print_state = FOOTPRINT_DRAG */
@@ -11,6 +11,10 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
@@ -50,6 +54,7 @@
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
reagents.add_reagent("oil", 30)
reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
+175 -52
View File
@@ -1,25 +1,69 @@
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread
var/sparks = FALSE //whether sparks spread
var/virusProb = 20 //the chance for viruses to spread on the gibs
var/gib_mob_type //generate a fake mob to transfer DNA from if we weren't passed a mob.
var/gib_mob_species //We'll want to nip-pick their species for blood type stuff
var/sound_to_play = 'sound/effects/blobattack.ogg'
var/sound_vol = 60
var/list/gibtypes = list() //typepaths of the gib decals to spawn
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
/obj/effect/gibspawner/Initialize(mapload, datum/dna/MobDNA, list/datum/disease/diseases)
/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases)
. = ..()
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
to_chat(world, "<span class='danger'>Gib list length mismatch!</span>")
if(gibtypes.len != gibamounts.len)
stack_trace("Gib list amount length mismatch!")
return
if(gibamounts.len != gibdirections.len)
stack_trace("Gib list dir length mismatch!")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
if(sound_to_play && isnum(sound_vol))
playsound(src, sound_to_play, sound_vol, TRUE)
if(sparks)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, loc)
s.start()
var/list/dna_to_add //find the dna to pass to the spawned gibs. do note this can be null if the mob doesn't have blood. add_blood_DNA() has built in null handling.
var/body_coloring = ""
if(source_mob)
dna_to_add = source_mob.get_blood_dna_list() //ez pz
if(ishuman(source_mob))
var/mob/living/carbon/human/H = source_mob
if(H.dna.species.use_skintones)
body_coloring = "#[skintone2hex(H.skin_tone)]"
else
body_coloring = "#[H.dna.features["mcolor"]]"
else if(gib_mob_type)
var/mob/living/temp_mob = new gib_mob_type(src) //generate a fake mob so that we pull the right type of DNA for the gibs.
if(gib_mob_species)
if(ishuman(temp_mob))
var/mob/living/carbon/human/H = temp_mob
H.set_species(gib_mob_species)
dna_to_add = temp_mob.get_blood_dna_list()
if(H.dna.species.use_skintones)
body_coloring = "#[skintone2hex(H.skin_tone)]"
else
body_coloring = "#[H.dna.features["mcolor"]]"
qdel(H)
else
dna_to_add = temp_mob.get_blood_dna_list()
qdel(temp_mob)
else if(!issilicon(temp_mob))
dna_to_add = temp_mob.get_blood_dna_list()
qdel(temp_mob)
else
qdel(temp_mob)
else
dna_to_add = list("Non-human DNA" = random_blood_type()) //else, generate a random bloodtype for it.
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
@@ -29,10 +73,11 @@
var/mob/living/carbon/digester = loc
digester.stomach_contents += gib
if(MobDNA)
if(dna_to_add && dna_to_add.len)
gib.add_blood_DNA(dna_to_add)
gib.body_colors = body_coloring
gib.update_icon()
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
gib.add_blood_DNA(list("Non-human DNA" = "A+"))
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
@@ -41,80 +86,158 @@
return INITIALIZE_HINT_QDEL
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(2,2,1)
gibamounts = list(2, 2, 1)
sound_vol = 40
/obj/effect/gibspawner/generic/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 40, 1)
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
. = ..()
if(!gibdirections.len)
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
return ..()
/obj/effect/gibspawner/generic/animal
gib_mob_type = /mob/living/simple_animal/pet
/obj/effect/gibspawner/human
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up, /obj/effect/decal/cleanable/blood/gibs/down, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/body, /obj/effect/decal/cleanable/blood/gibs/limb, /obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(1,1,1,1,1,1,1)
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/up, /obj/effect/decal/cleanable/blood/gibs/human/down, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/body, /obj/effect/decal/cleanable/blood/gibs/human/limb, /obj/effect/decal/cleanable/blood/gibs/human/core)
gibamounts = list(1, 1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/human
gib_mob_species = /datum/species/human
sound_vol = 50
/obj/effect/gibspawner/human/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
. = ..()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/humanbodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso)
/obj/effect/gibspawner/human/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/humanbodypartless/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
. = ..()
/obj/effect/gibspawner/human/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/lizard
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard/up, /obj/effect/decal/cleanable/blood/gibs/human/lizard/down, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/body, /obj/effect/decal/cleanable/blood/gibs/human/lizard/limb, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core)
gibamounts = list(1, 1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/human/species/lizard
gib_mob_species = /datum/species/lizard
sound_vol = 50
/obj/effect/gibspawner/lizard/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/lizard/bodypartless
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/lizard/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/slime
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime/up, /obj/effect/decal/cleanable/blood/gibs/slime/down, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/body, /obj/effect/decal/cleanable/blood/gibs/slime/limb, /obj/effect/decal/cleanable/blood/gibs/slime/core)
gibamounts = list(1, 1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/human/species/roundstartslime
gib_mob_species = /datum/species/jelly/roundstartslime
sound_vol = 50
/obj/effect/gibspawner/slime/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/slime/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/slime/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/ipc
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc/up, /obj/effect/decal/cleanable/blood/gibs/ipc/down, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/body, /obj/effect/decal/cleanable/blood/gibs/ipc/limb, /obj/effect/decal/cleanable/blood/gibs/ipc/core)
gibamounts = list(1, 1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/human/species/ipc
gib_mob_species = /datum/species/ipc
sound_vol = 50
sparks = TRUE
sound_to_play = 'sound/effects/bang.ogg'
/obj/effect/gibspawner/ipc/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/ipc/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/ipc/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/xeno
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up, /obj/effect/decal/cleanable/xenoblood/xgibs/down, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core)
gibamounts = list(1,1,1,1,1,1,1)
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up, /obj/effect/decal/cleanable/blood/gibs/xeno/down, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/body, /obj/effect/decal/cleanable/blood/gibs/xeno/limb, /obj/effect/decal/cleanable/blood/gibs/xeno/core)
gibamounts = list(1, 1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/alien
/obj/effect/gibspawner/xeno/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
. = ..()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/xenobodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso)
/obj/effect/gibspawner/xeno/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/xeno/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
return ..()
/obj/effect/gibspawner/xenobodypartless/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
. = ..()
/obj/effect/gibspawner/xeno/xenoperson
gib_mob_type = /mob/living/carbon/human/species/xeno
gib_mob_species = /datum/species/xeno
/obj/effect/gibspawner/xeno/xenoperson/bodypartless
/obj/effect/gibspawner/larva
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body)
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body)
gibamounts = list(1, 1, 1, 1)
gib_mob_type = /mob/living/carbon/alien/larva
/obj/effect/gibspawner/larva/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
. = ..()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
return ..()
/obj/effect/gibspawner/larvabodypartless
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva)
/obj/effect/gibspawner/larva/bodypartless
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva)
gibamounts = list(1, 1, 1)
/obj/effect/gibspawner/larvabodypartless/Initialize()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
. = ..()
/obj/effect/gibspawner/larva/bodypartless/Initialize()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
return ..()
/obj/effect/gibspawner/robot
sparks = 1
sparks = TRUE
gibtypes = list(/obj/effect/decal/cleanable/robot_debris/up, /obj/effect/decal/cleanable/robot_debris/down, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris/limb)
gibamounts = list(1,1,1,1,1,1)
gibamounts = list(1, 1, 1, 1, 1, 1)
gib_mob_type = /mob/living/silicon/robot
/obj/effect/gibspawner/robot/Initialize()
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
gibamounts[6] = pick(0,1,2)
. = ..()
if(!gibdirections.len)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
gibamounts[6] = pick(0, 1, 2)
return ..()
@@ -6,7 +6,9 @@
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir, new_color)
if(new_color)
color = new_color
if(set_dir in GLOB.diagonals)
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
@@ -41,7 +43,7 @@
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter
splatter_type = "xsplatter"
color = BLOOD_COLOR_XENO
/obj/effect/temp_visual/dir_setting/speedbike_trail
name = "speedbike trails"
+11 -1
View File
@@ -111,7 +111,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
/obj/item/Initialize()
materials = typelist("materials", materials)
@@ -537,6 +536,17 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
/obj/item/clean_blood()
. = ..()
if(.)
if(blood_splatter_icon)
cut_overlay(blood_splatter_icon)
/obj/item/clothing/gloves/clean_blood()
. = ..()
if(.)
transfer_blood = 0
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
@@ -31,6 +31,15 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/machine/bloodbankgen
name = "Blood Bank Generator (Machine Board)"
build_path = /obj/machinery/bloodbankgen
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/cable_coil = 5,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/machine/clonepod
name = "Clone Pod (Machine Board)"
build_path = /obj/machinery/clonepod
+1 -1
View File
@@ -410,7 +410,7 @@ SLIME SCANNER
msg += "<span class='danger'>Subject is bleeding!</span>\n"
var/blood_percent = round((C.blood_volume / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
if(blood_id != "blood")//special blood substance
if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
+1
View File
@@ -27,6 +27,7 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
A.clean_blood()
for(var/obj/effect/O in A)
if(is_cleanable(O))
qdel(O)
@@ -17,7 +17,6 @@
var/self_delay = 50
/obj/item/stack/medical/attack(mob/living/M, mob/user)
if(M.stat == DEAD && !stop_bleeding)
var/t_him = "it"
if(M.gender == MALE)
+4 -4
View File
@@ -390,9 +390,9 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
add_blood_DNA(from.return_blood_DNA())
add_fingerprint_list(from.return_fingerprints())
add_hiddenprint_list(from.return_hiddenprints())
blood_DNA = from.blood_DNA
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
@@ -437,4 +437,4 @@
/datum/stack_recipe_list/New(title, recipes)
src.title = title
src.recipes = recipes
src.recipes = recipes
@@ -35,6 +35,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
if(blood_DNA && blood_DNA.len)
add_blood_overlay()
if(has_latches)
var/icon/I = icon('icons/obj/storage.dmi', latches)
add_overlay(I)
+4 -3
View File
@@ -347,7 +347,8 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
clean_blood()
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
@@ -537,7 +538,7 @@
var/mob/M = loc
M.update_inv_hands()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is)
clean_blood()
/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
@@ -1002,4 +1003,4 @@
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
user.client.pixel_y = 0
+14 -7
View File
@@ -318,6 +318,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -328,8 +329,9 @@
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
tile.clean_blood()
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
@@ -381,7 +383,8 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
H.clean_blood()
SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -398,9 +401,11 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
M.clean_blood()
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
else
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
L.clean_blood()
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -498,7 +503,8 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
user.clean_blood()
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -554,7 +560,8 @@
busy = FALSE
return 1
busy = FALSE
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.clean_blood()
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
@@ -675,4 +682,4 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
+1
View File
@@ -251,6 +251,7 @@
M.apply_water()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
clean_blood()
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)
@@ -366,6 +366,8 @@
break
if(!GLOB.ratvar_awakens)
if(GLOB.clockwork_vitality <= 0)
break
GLOB.clockwork_vitality -= vitality_used
sleep(2)
@@ -324,14 +324,11 @@
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
possible = list()
LAZYINITLIST(possible)
if(!voodoo_link)
return
var/list/prints = voodoo_link.return_fingerprints()
if(!length(prints))
return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(prints[md5(H.dna.uni_identity)])
if(md5(H.dna.uni_identity) in voodoo_link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
+1 -1
View File
@@ -35,4 +35,4 @@
A.flags_1 |= ADMIN_SPAWNED_1
else
for(var/item in contains)
new item(C)
new item(C)
+18 -4
View File
@@ -30,17 +30,31 @@
/datum/supply_pack/medical/bloodpacks
name = "Blood Pack Variety Crate"
desc = "Contains eight different blood packs for reintroducing blood to patients."
desc = "Contains ten different blood packs for reintroducing blood to patients."
cost = 3000
contains = list(/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/blood,
contains = list(/obj/item/reagent_containers/blood/random,
/obj/item/reagent_containers/blood/random,
/obj/item/reagent_containers/blood/APlus,
/obj/item/reagent_containers/blood/AMinus,
/obj/item/reagent_containers/blood/BPlus,
/obj/item/reagent_containers/blood/BMinus,
/obj/item/reagent_containers/blood/OPlus,
/obj/item/reagent_containers/blood/OMinus,
/obj/item/reagent_containers/blood/lizard)
/obj/item/reagent_containers/blood/lizard,
/obj/item/reagent_containers/blood/jellyblood,
/obj/item/reagent_containers/blood/insect)
crate_name = "blood freezer"
crate_type = /obj/structure/closet/crate/freezer
/datum/supply_pack/medical/bloodpackssynth
name = "Synthetics Blood Pack Crate"
desc = "Contains five synthetics blood packs for reintroducing blood to patients."
cost = 3000
contains = list(/obj/item/reagent_containers/blood/synthetics,
/obj/item/reagent_containers/blood/synthetics,
/obj/item/reagent_containers/blood/synthetics,
/obj/item/reagent_containers/blood/synthetics,
/obj/item/reagent_containers/blood/synthetics)
crate_name = "blood freezer"
crate_type = /obj/structure/closet/crate/freezer
+6 -7
View File
@@ -14,11 +14,10 @@
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/gloves/clean_blood)))
/obj/item/clothing/gloves/proc/clean_blood(datum/source, strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
/obj/item/clothing/gloves/clean_blood(datum/source, strength)
. = ..()
transfer_blood = 0
/obj/item/clothing/gloves/suicide_act(mob/living/carbon/user)
@@ -30,8 +29,8 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color())
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
..()
@@ -41,4 +40,4 @@
// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/proc/Touch(atom/A, proximity)
return 0 // return 1 to cancel attack_hand()
return FALSE // return TRUE to cancel attack_hand()
+2 -2
View File
@@ -46,8 +46,8 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color())
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
..()
+2 -2
View File
@@ -59,8 +59,8 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
..()
+2 -2
View File
@@ -12,8 +12,8 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/neck/tie
name = "tie"
+19 -11
View File
@@ -11,17 +11,19 @@
permeability_coefficient = 0.5
slowdown = SHOES_SLOWDOWN
var/blood_state = BLOOD_STATE_NOT_BLOODY
var/list/bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
var/list/bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
var/offset = 0
var/equipped_before_drop = FALSE
//CITADEL EDIT Enables digitigrade shoe styles
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
var/last_bloodtype = "" //used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans
var/last_blood_DNA = "" //same as last one
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/shoes/clean_blood)))
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
@@ -42,22 +44,29 @@
playsound(user, 'sound/weapons/genhit2.ogg', 50, 1)
return(BRUTELOSS)
/obj/item/clothing/shoes/transfer_blood_dna(list/blood_dna, diseases)
..()
if(blood_dna.len)
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
last_blood_DNA = blood_dna[blood_dna.len]
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
var/bloody = FALSE
IF_HAS_BLOOD_DNA(src)
if(blood_DNA)
bloody = TRUE
else
bloody = bloody_shoes[BLOOD_STATE_HUMAN]
bloody = bloody_shoes[BLOOD_STATE_BLOOD]
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
if(bloody)
if(adjusted == NORMAL_STYLE)
. += mutable_appearance('icons/effects/blood.dmi', "shoeblood")
. += mutable_appearance('icons/effects/blood.dmi', "shoeblood", color = blood_DNA_to_color())
else
. += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood")
. += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood", color = blood_DNA_to_color())
/obj/item/clothing/shoes/equipped(mob/user, slot)
. = ..()
@@ -93,14 +102,13 @@
var/mob/M = loc
M.update_inv_shoes()
/obj/item/clothing/shoes/proc/clean_blood(datum/source, strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
/obj/item/clothing/shoes/clean_blood(datum/source, strength)
. = ..()
bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
var/mob/M = loc
M.update_inv_shoes()
/obj/item/proc/negates_gravity()
return FALSE
return FALSE
+74 -74
View File
@@ -1,74 +1,74 @@
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
slot_flags = ITEM_SLOT_OCLOTHING
body_parts_covered = CHEST
var/blood_overlay_type = "suit"
var/togglename = null
var/suittoggled = FALSE
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
var/tauric = FALSE //Citadel Add for tauric hardsuits
var/taurmode = NOT_TAURIC
var/dimension_x = 32
var/dimension_y = 32
var/center = FALSE //Should we center the sprite?
/obj/item/clothing/suit/equipped(mob/user, slot)
..()
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(mutantrace_variation)
if(DIGITIGRADE in H.dna.species.species_traits)
adjusted = ALT_STYLE
H.update_inv_wear_suit()
else if(adjusted == ALT_STYLE)
adjusted = NORMAL_STYLE
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
if(H.dna.features["taur"] in list("Naga", "Tentacle"))
taurmode = SNEK_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else if(H.dna.features["taur"] in list("Fox","Wolf","Otie","Drake","Lab","Shepherd","Husky","Eevee","Panther","Horse","Cow","Tiger","Deer"))
taurmode = PAW_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else
taurmode = NOT_TAURIC
if(tauric == TRUE)
center = FALSE
dimension_x = 32
H.update_inv_wear_suit()
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
IF_HAS_BLOOD_DNA(src)
if(tauric)
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood")
else
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
if(istype(U) && U.attached_accessory)
var/obj/item/clothing/accessory/A = U.attached_accessory
if(A.above_suit)
. += U.accessory_overlay
/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE)
..()
if(ismob(loc))
var/mob/M = loc
M.update_inv_wear_suit()
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
slot_flags = ITEM_SLOT_OCLOTHING
body_parts_covered = CHEST
var/blood_overlay_type = "suit"
var/togglename = null
var/suittoggled = FALSE
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
var/tauric = FALSE //Citadel Add for tauric hardsuits
var/taurmode = NOT_TAURIC
var/dimension_x = 32
var/dimension_y = 32
var/center = FALSE //Should we center the sprite?
/obj/item/clothing/suit/equipped(mob/user, slot)
..()
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(mutantrace_variation)
if(DIGITIGRADE in H.dna.species.species_traits)
adjusted = ALT_STYLE
H.update_inv_wear_suit()
else if(adjusted == ALT_STYLE)
adjusted = NORMAL_STYLE
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
if(H.dna.features["taur"] in GLOB.noodle_taurs)
taurmode = SNEK_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else if(H.dna.features["taur"] in GLOB.paw_taurs)
taurmode = PAW_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else
taurmode = NOT_TAURIC
if(tauric == TRUE)
center = FALSE
dimension_x = 32
H.update_inv_wear_suit()
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
if(blood_DNA)
if(tauric)
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
else
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
if(istype(U) && U.attached_accessory)
var/obj/item/clothing/accessory/A = U.attached_accessory
if(A.above_suit)
. += U.accessory_overlay
/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE)
..()
if(ismob(loc))
var/mob/M = loc
M.update_inv_wear_suit()
+2 -2
View File
@@ -22,8 +22,8 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
if(accessory_overlay)
. += accessory_overlay
+89 -93
View File
@@ -1,111 +1,107 @@
//CONTAINS: Suit fibers and Detective's Scanning Computer
/atom/proc/return_fingerprints()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.fingerprints
/atom/proc/add_fibers(mob/living/carbon/human/M)
if(M.gloves && istype(M.gloves, /obj/item/clothing/))
var/obj/item/clothing/gloves/G = M.gloves
if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
if(add_blood_DNA(G.blood_DNA)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
G.transfer_blood--
else if(M.bloody_hands > 1)
if(add_blood_DNA(M.blood_DNA, M.diseases))
M.bloody_hands--
if(!suit_fibers)
suit_fibers = list()
var/fibertext
var/item_multiplier = isitem(src)?1.2:1
if(M.wear_suit)
fibertext = "Material from \a [M.wear_suit]."
if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & CHEST))
if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & HANDS))
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
suit_fibers += fibertext
else if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(15*item_multiplier) && !(fibertext in suit_fibers))
// "Added fibertext: [fibertext]"
suit_fibers += fibertext
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
suit_fibers += "Material from a pair of [M.gloves.name]."
else if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
suit_fibers += "Material from a pair of [M.gloves.name]."
/atom/proc/return_hiddenprints()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.hiddenprints
/atom/proc/return_blood_DNA()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.blood_DNA
/atom/proc/add_hiddenprint(mob/living/M)
if(!M || !M.key)
return
/atom/proc/blood_DNA_length()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = length(D.blood_DNA)
if(!fingerprintshidden) //Add the list if it does not exist
fingerprintshidden = list()
/atom/proc/return_fibers()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.fibers
var/hasgloves = ""
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.gloves)
hasgloves = "(gloves)"
var/current_time = TIME_STAMP("hh:mm:ss", FALSE)
if(!fingerprintshidden[M.key])
fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
else
var/laststamppos = findtext(fingerprintshidden[M.key], " Last: ")
if(laststamppos)
fingerprintshidden[M.key] = copytext(fingerprintshidden[M.key], 1, laststamppos)
fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
fingerprintslast = M.ckey
/atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT
if(length(fingerprints))
. = AddComponent(/datum/component/forensics, fingerprints)
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
. = D.add_fingerprint(M, ignoregloves)
if(!M || !M.key)
return
/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
if(length(fibertext))
. = AddComponent(/datum/component/forensics, null, null, null, fibertext)
add_hiddenprint(M)
/atom/proc/add_fibers(mob/living/carbon/human/M)
var/old = 0
if(M.gloves && istype(M.gloves, /obj/item/clothing))
var/obj/item/clothing/gloves/G = M.gloves
old = length(G.return_blood_DNA())
if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
G.transfer_blood--
else if(M.bloody_hands > 1)
old = length(M.return_blood_DNA())
if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
M.bloody_hands--
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
. = D.add_fibers(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
/atom/proc/add_hiddenprint_list(list/hiddenprints) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
if(length(hiddenprints))
. = AddComponent(/datum/component/forensics, null, hiddenprints)
add_fibers(H)
/atom/proc/add_hiddenprint(mob/living/M)
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
. = D.add_hiddenprint(M)
if(H.gloves) //Check if the gloves (if any) hide fingerprints
var/obj/item/clothing/gloves/G = H.gloves
if(G.transfer_prints)
ignoregloves = TRUE
/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
return FALSE
if(!ignoregloves)
H.gloves.add_fingerprint(H, TRUE) //ignoregloves = TRUE to avoid infinite loop.
return
/obj/add_blood_DNA(list/dna)
. = ..()
if(length(dna))
. = AddComponent(/datum/component/forensics, null, null, dna)
/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.add_blood_DNA(blood_dna) //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(wear_suit)
wear_suit.add_blood_DNA(blood_dna)
update_inv_wear_suit()
else if(w_uniform)
w_uniform.add_blood_DNA(blood_dna)
update_inv_w_uniform()
if(gloves)
var/obj/item/clothing/gloves/G = gloves
G.add_blood_DNA(blood_dna)
else if(length(blood_dna))
AddComponent(/datum/component/forensics, null, null, blood_dna)
bloody_hands = rand(2, 4)
if(head)
head.add_blood_DNA(blood_dna)
update_inv_head()
else if(wear_mask)
wear_mask.add_blood_DNA(blood_dna)
update_inv_wear_mask()
if(wear_neck)
wear_neck.add_blood_DNA(blood_dna)
update_inv_neck()
update_inv_gloves() //handles bloody hands overlays and updating
return TRUE
LAZYINITLIST(fingerprints) //Add the list if it does not exist
var/full_print = md5(H.dna.uni_identity)
fingerprints[full_print] = full_print
/atom/proc/transfer_fingerprints_to(atom/A)
A.add_fingerprint_list(return_fingerprints())
A.add_hiddenprint_list(return_hiddenprints())
A.fingerprintslast = fingerprintslast
// Make sure everything are lists.
LAZYINITLIST(A.fingerprints)
LAZYINITLIST(A.fingerprintshidden)
LAZYINITLIST(fingerprints)
LAZYINITLIST(fingerprintshidden)
// Transfer
if(fingerprints)
A.fingerprints |= fingerprints.Copy() //detective
if(fingerprintshidden)
A.fingerprintshidden |= fingerprintshidden.Copy() //admin
A.fingerprintslast = fingerprintslast
+4 -4
View File
@@ -16,7 +16,7 @@
/obj/item/evidencebag/attackby(obj/item/I, mob/user, params)
if(evidencebagEquip(I, user))
return 1
return TRUE
/obj/item/evidencebag/handle_atom_del(atom/A)
cut_overlays()
@@ -25,12 +25,12 @@
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
if(!istype(I) || I.anchored == 1)
if(!istype(I) || I.anchored == TRUE)
return
if(istype(I, /obj/item/evidencebag))
to_chat(user, "<span class='notice'>You find putting an evidence bag in another evidence bag to be slightly absurd.</span>")
return 1 //now this is podracing
return TRUE //now this is podracing
if(I.w_class > WEIGHT_CLASS_NORMAL)
to_chat(user, "<span class='notice'>[I] won't fit in [src].</span>")
@@ -62,7 +62,7 @@
desc = "An evidence bag containing [I]. [I.desc]"
I.forceMove(src)
w_class = I.w_class
return 1
return TRUE
/obj/item/evidencebag/attack_self(mob/user)
if(contents.len)
+26 -19
View File
@@ -14,7 +14,7 @@
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
var/scanning = 0
var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
@@ -30,7 +30,7 @@
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
scanning = 1
scanning = TRUE
to_chat(user, "<span class='notice'>Printing report, please wait...</span>")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
@@ -56,7 +56,7 @@
// Clear the logs
log = list()
scanning = 0
scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
@@ -70,7 +70,7 @@
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = 1
scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "<span class='notice'>You scan \the [A]. The scanner is now analysing the results...</span>")
@@ -80,14 +80,20 @@
//Make our lists
var/list/fingerprints = list()
var/list/blood = A.return_blood_DNA()
var/list/fibers = A.return_fibers()
var/list/blood = list()
var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
if(A.blood_DNA && A.blood_DNA.len)
blood = A.blood_DNA.Copy()
if(A.suit_fibers && A.suit_fibers.len)
fibers = A.suit_fibers.Copy()
if(ishuman(A))
var/mob/living/carbon/human/H = A
@@ -96,7 +102,8 @@
else if(!ismob(A))
fingerprints = A.return_fingerprints()
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
@@ -115,40 +122,40 @@
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
var/found_something = 0
var/found_something = FALSE
add_log("<B>[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(length(fingerprints))
sleep(30)
sleep(3 SECONDS)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
add_log("[finger]")
found_something = 1
found_something = TRUE
// Blood
if (length(blood))
sleep(30)
sleep(3 SECONDS)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = 1
found_something = TRUE
for(var/B in blood)
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(length(fibers))
sleep(30)
sleep(3 SECONDS)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
add_log("[fiber]")
found_something = 1
found_something = TRUE
//Reagents
if(length(reagents))
sleep(30)
sleep(3 SECONDS)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
add_log("Reagent: <font color='red'>[R]</font> Volume: <font color='red'>[reagents[R]]</font>")
found_something = 1
found_something = TRUE
// Get a new user
var/mob/holder = null
@@ -164,10 +171,10 @@
to_chat(holder, "<span class='notice'>You finish scanning \the [target_name].</span>")
add_log("---------------------------------------------------------", 0)
scanning = 0
scanning = FALSE
return
/obj/item/detective_scanner/proc/add_log(msg, broadcast = 1)
/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
@@ -207,4 +214,4 @@
return
to_chat(user, "<span class='notice'><B>Scanner Report</B></span>")
for(var/iterLog in log)
to_chat(user, iterLog)
to_chat(user, iterLog)
@@ -54,6 +54,10 @@
name = "Redpanda"
icon_state = "redpanda"
/datum/sprite_accessory/mam_body_markings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/mam_body_markings/bee
name = "Bee"
icon_state = "bee"
@@ -176,6 +176,10 @@
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_ears/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/mam_ears/bear
name = "Bear"
icon_state = "bear"
@@ -194,6 +194,10 @@
name = "Mammal, Short ALT"
icon_state = "scanidalt"
/datum/sprite_accessory/mam_snouts/scanidalt2
name = "Mammal, Short ALT 2"
icon_state = "scanidalt2"
/datum/sprite_accessory/mam_snouts/wolf
name = "Mammal, Thick"
icon_state = "wolf"
@@ -306,6 +310,10 @@
name = "Mammal, Short ALT (Top)"
icon_state = "fscanidalt"
/datum/sprite_accessory/mam_snouts/fscanidalt2
name = "Mammal, Short ALT 2 (Top)"
icon_state = "fscanidalt2"
/datum/sprite_accessory/mam_snouts/fwolf
name = "Mammal, Thick (Top)"
icon_state = "fwolf"
@@ -114,6 +114,26 @@
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/mam_tails/batl
name = "Bat (Long)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "batl"
/datum/sprite_accessory/mam_tails_animated/batl
name = "Bat (Long)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "batl"
/datum/sprite_accessory/mam_tails/bats
name = "Bat (Short)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "bats"
/datum/sprite_accessory/mam_tails_animated/bats
name = "Bat (Short)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "bats"
/datum/sprite_accessory/tails/human/bee
name = "Bee"
icon_state = "bee"
@@ -469,6 +489,22 @@
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_tails/batl
name = "Bat (Long)"
icon_state = "batl"
/datum/sprite_accessory/mam_tails_animated/batl
name = "Bat (Long)"
icon_state = "batl"
/datum/sprite_accessory/mam_tails/bats
name = "Bat (Short)"
icon_state = "bats"
/datum/sprite_accessory/mam_tails_animated/bats
name = "Bat (Short)"
icon_state = "bats"
/datum/sprite_accessory/mam_tails/bee
name = "Bee"
icon_state = "bee"
@@ -28,74 +28,14 @@
locked = TRUE
// Decorative wings
/datum/sprite_accessory/deco_wings
icon = 'icons/mob/wings.dmi'
color_src = WINGCOLOR
/datum/sprite_accessory/deco_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/deco_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/deco_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/deco_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/deco_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/deco_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/deco_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/deco_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/deco_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
/datum/sprite_accessory/deco_wings/punished
name = "Burnt Off"
icon_state = "punished"
locked = TRUE
/datum/sprite_accessory/deco_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/deco_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/deco_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/deco_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/deco_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/deco_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/deco_wings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/deco_wings/angel
name = "Angel"
@@ -105,6 +45,10 @@
center = TRUE
dimension_y = 34
/datum/sprite_accessory/deco_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/deco_wings/bee
name = "Bee"
icon_state = "bee"
@@ -113,18 +57,73 @@
name = "Fairy"
icon_state = "fairy"
/datum/sprite_accessory/deco_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/deco_wings/feathery
name = "Feathery"
icon_state = "feathery"
/datum/sprite_accessory/deco_wings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/deco_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/deco_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/deco_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/deco_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/deco_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/deco_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/deco_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/deco_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/deco_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/deco_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/deco_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/deco_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/deco_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/deco_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/deco_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/deco_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
//INSECT WINGS
@@ -136,69 +135,9 @@
name = "None"
icon_state = "none"
/datum/sprite_accessory/insect_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/insect_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/insect_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/insect_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/insect_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/insect_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/insect_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/insect_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/insect_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
/datum/sprite_accessory/insect_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/insect_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/insect_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/insect_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/insect_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/insect_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/insect_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/insect_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/insect_wings/bee
name = "Bee"
@@ -208,10 +147,70 @@
name = "Fairy"
icon_state = "fairy"
/datum/sprite_accessory/insect_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/insect_wings/feathery
name = "Feathery"
icon_state = "feathery"
/datum/sprite_accessory/insect_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/insect_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/insect_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/insect_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/insect_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/insect_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/insect_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/insect_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/insect_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/insect_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/insect_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/insect_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/insect_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/insect_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/insect_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/insect_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
+94 -50
View File
@@ -2,6 +2,9 @@
BLOOD SYSTEM
****************************************************/
#define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations.
/mob/living/carbon/human/proc/suppress_bloodloss(amount)
if(bleedsuppress)
return
@@ -30,6 +33,9 @@
bleed_rate = 0
return
if(bleed_rate <= 0)
bleed_rate = 0
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
@@ -80,6 +86,9 @@
var/obj/item/bodypart/BP = X
var/brutedamage = BP.brute_dam
if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty.
continue
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
temp_bleed += 0.5*BP.embedded_objects.len
@@ -87,7 +96,7 @@
if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
@@ -105,9 +114,11 @@
/mob/living/carbon/human/bleed(amt)
amt *= physiology.bleed_mod
if(!(NOBLOOD in dna.species.species_traits))
..()
.=..()
if(dna.species.exotic_blood && .) // Do we have exotic blood, and have we left any on the ground?
var/datum/reagent/R = GLOB.chemical_reagents_list[get_blood_id()]
if(istype(R) && isturf(loc))
R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER)
/mob/living/proc/restore_blood()
blood_volume = initial(blood_volume)
@@ -123,16 +134,16 @@
//Gets blood from mob to a container or other mob, preserving all data in it.
/mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced)
if(!blood_volume || !AM.reagents)
return 0
return FALSE
if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced)
return 0
return FALSE
if(blood_volume < amount)
amount = blood_volume
var/blood_id = get_blood_id()
if(!blood_id)
return 0
return FALSE
blood_volume -= amount
@@ -141,29 +152,27 @@
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if(blood_id == C.get_blood_id())//both mobs have the same blood substance
if(blood_id == "blood") //normal blood
if(blood_id == "blood" || blood_id == "jellyblood") //normal blood
if(blood_data["viruses"])
for(var/thing in blood_data["viruses"])
var/datum/disease/D = thing
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
continue
C.ForceContractDisease(D)
if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)))
C.reagents.add_reagent("toxin", amount * 0.5)
return 1
//This used to inject oof ouch results, but since we add the reagent, and the reagent causes oof ouch on mob life... why double dip?
C.blood_volume = min(C.blood_volume + round(amount, 0.1), BLOOD_VOLUME_MAXIMUM)
return 1
return TRUE
AM.reagents.add_reagent(blood_id, amount, blood_data, bodytemperature)
return 1
return TRUE
/mob/living/proc/get_blood_data(blood_id)
return
/mob/living/carbon/get_blood_data(blood_id)
if(blood_id == "blood") //actual blood reagent
if(blood_id == "blood" || blood_id == "jellyblood") //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
@@ -174,6 +183,7 @@
blood_data["viruses"] += D.Copy()
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type)
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
@@ -206,21 +216,6 @@
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff.
var/blood_data = list()
if(mind)
blood_data["mind"] = mind
else if(last_mind)
blood_data["mind"] = last_mind
if(ckey)
blood_data["ckey"] = ckey
else if(last_mind)
blood_data["ckey"] = ckey(last_mind.key)
blood_data["gender"] = gender
blood_data["real_name"] = real_name
return blood_data
//get the id of the substance this mob use as blood.
/mob/proc/get_blood_id()
@@ -234,12 +229,15 @@
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
return "blood"
/mob/living/carbon/human/get_blood_id()
if(dna.species.exotic_blood)
/mob/living/carbon/get_blood_id()
if(isjellyperson(src))
return "jellyblood"
if(dna?.species?.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
return
return "blood"
else
return "blood"
// This is has more potential uses, and is probably faster than the old proc.
/proc/get_safe_blood(bloodtype)
@@ -248,16 +246,21 @@
return
var/static/list/bloodtypes_safe = list(
"A-" = list("A-", "O-"),
"A+" = list("A-", "A+", "O-", "O+"),
"B-" = list("B-", "O-"),
"B+" = list("B-", "B+", "O-", "O+"),
"AB-" = list("A-", "B-", "O-", "AB-"),
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+"),
"O-" = list("O-"),
"O+" = list("O-", "O+"),
"L" = list("L"),
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U")
"A-" = list("A-", "O-", "SY"),
"A+" = list("A-", "A+", "O-", "O+", "SY"),
"B-" = list("B-", "O-", "SY"),
"B+" = list("B-", "B+", "O-", "O+", "SY"),
"AB-" = list("A-", "B-", "O-", "AB-", "SY"),
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "SY"),
"O-" = list("O-","SY"),
"O+" = list("O-", "O+","SY"),
"L" = list("L","SY"),
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
"HF" = list("HF", "SY"),
"X*" = list("X*", "SY"),
"SY" = list("SY"),
"GEL" = list("GEL","SY"),
"BUG" = list("BUG", "SY")
)
var/safe = bloodtypes_safe[bloodtype]
@@ -266,7 +269,7 @@
//to add a splatter of blood or other mob liquid.
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
if(get_blood_id() != "blood")
if(get_blood_id() == null)
return
if(!T)
T = get_turf(src)
@@ -280,24 +283,27 @@
drop.drips++
drop.add_overlay(pick(drop.random_icon_states))
drop.transfer_mob_blood_dna(src)
drop.update_icon()
return
else
temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
temp_blood_DNA = list()
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
drop.transfer_mob_blood_dna(src)
drop.update_icon()
return
// Find a blood decal or create a new one.
var/obj/effect/decal/cleanable/blood/B = locate() in T
var/obj/effect/decal/cleanable/blood/splats/B = locate() in T
if(!B)
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
if (B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B = new /obj/effect/decal/cleanable/blood/splats(T, get_static_viruses())
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
if(temp_blood_DNA)
B.add_blood_DNA(temp_blood_DNA)
B.blood_DNA |= temp_blood_DNA
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
if(!(NOBLOOD in dna.species.species_traits))
@@ -306,10 +312,10 @@
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
if(!B)
B = new(T)
B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
B.blood_DNA["UNKNOWN DNA"] = "X*"
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
if(!T)
@@ -318,6 +324,44 @@
if(!B)
B = new(T)
/mob/living/proc/add_splash_floor(turf/T)
if(get_blood_id() == null)
return
if(!T)
T = get_turf(src)
var/list/temp_blood_DNA
// Find a blood decal or create a new one.
var/obj/effect/decal/cleanable/blood/B = locate() in T
if(!B)
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
src.transfer_blood_to(B, 10) //very heavy bleeding, should logically leave larger pools
if(temp_blood_DNA)
B.blood_DNA |= temp_blood_DNA
/mob/living/carbon/human/add_splash_floor(turf/T)
if(!(NOBLOOD in dna.species.species_traits))
..()
/mob/living/carbon/alien/add_splash_floor(turf/T)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
if(!B)
B = new(T)
B.blood_DNA["UNKNOWN DNA"] = "X*"
/mob/living/silicon/robot/add_splash_floor(turf/T)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
if(!B)
B = new(T)
//This is a terrible way of handling it.
/mob/living/proc/ResetBloodVol()
if(ishuman(src))
+3 -3
View File
@@ -147,9 +147,9 @@
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
//Makes the mob have the color of the blood pool it came out of
var/newcolor = rgb(149, 10, 10)
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
newcolor = rgb(43, 186, 0)
var/newcolor = BLOOD_COLOR_HUMAN
if(istype(B, /obj/effect/decal/cleanable/blood/xeno))
newcolor = BLOOD_COLOR_XENO
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
// but only for a few seconds
spawn(30)
+6 -1
View File
@@ -10,7 +10,10 @@
/mob/living/brain/Initialize()
. = ..()
create_dna(src)
stored_dna.initialize_dna(random_blood_type())
if(stored_dna.blood_type)
stored_dna.initialize_dna(stored_dna.blood_type)
else
stored_dna.initialize_dna(random_blood_type())
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
OB.brainmob = src
@@ -21,6 +24,8 @@
if(!stored_dna.species)
var/rando_race = pick(GLOB.roundstart_races)
stored_dna.species = new rando_race()
if(stored_dna.species.exotic_bloodtype)
stored_dna.blood_type = stored_dna.species.exotic_bloodtype
/mob/living/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
@@ -20,7 +20,7 @@
var/heat_protection = 0.5
var/leaping = 0
gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
gib_type = /obj/effect/decal/cleanable/blood/gibs/xeno
unique_name = 1
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
@@ -2,7 +2,7 @@
if(with_bodyparts)
new /obj/effect/gibspawner/xeno(drop_location())
else
new /obj/effect/gibspawner/xenobodypartless(drop_location())
new /obj/effect/gibspawner/xeno/bodypartless(drop_location())
/mob/living/carbon/alien/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a")
@@ -10,7 +10,7 @@
if(with_bodyparts)
new /obj/effect/gibspawner/larva(drop_location())
else
new /obj/effect/gibspawner/larvabodypartless(drop_location())
new /obj/effect/gibspawner/larva/bodypartless(drop_location())
/mob/living/carbon/alien/larva/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l")
@@ -89,6 +89,8 @@
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt)
if(owner.blood_volume && (owner.blood_volume < BLOOD_VOLUME_NORMAL))
owner.blood_volume += 5
else
owner.adjustPlasma(plasma_rate * 0.1)
@@ -49,6 +49,7 @@
//Gets filled up in create_bodyparts()
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
var/list/leg_bodyparts = list()
var/icon_render_key = ""
var/static/list/limb_icon_cache = list()
@@ -85,7 +85,7 @@
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough.
else
blood_volume -= amount
return ..()
+28 -3
View File
@@ -5,10 +5,35 @@
new /obj/effect/temp_visual/dust_animation(loc, "dust-h")
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
if(with_bodyparts)
new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
if(isjellyperson(src))
if(with_bodyparts)
new /obj/effect/gibspawner/slime(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/slime/bodypartless(drop_location(), dna, get_static_viruses())
if(isipcperson(src))
if(with_bodyparts)
new /obj/effect/gibspawner/ipc(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/ipc/bodypartless(drop_location(), dna, get_static_viruses())
if(isxenoperson(src))
if(with_bodyparts)
new /obj/effect/gibspawner/xeno/xenoperson(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/xeno/xenoperson/bodypartless(drop_location(), dna, get_static_viruses())
if(islizard(src))
if(with_bodyparts)
new /obj/effect/gibspawner/lizard(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/lizard/bodypartless(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/humanbodypartless(drop_location(), dna, get_static_viruses())
if(with_bodyparts)
new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
else
new /obj/effect/gibspawner/human/bodypartless(drop_location(), dna, get_static_viruses())
/mob/living/carbon/human/spawn_dust(just_ash = FALSE)
if(just_ash)
@@ -1,4 +1,4 @@
/mob/living/carbon/human/examine(mob/user) //User is the person being examined
/mob/living/carbon/human/examine(mob/user)
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
var/t_He = p_they(TRUE)
var/t_His = p_their(TRUE)
@@ -45,7 +45,7 @@
if(wear_suit)
msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
//suit/armor storage
if(s_store)
if(s_store && !(SLOT_S_STORE in obscured))
msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
//back
if(back)
@@ -56,11 +56,10 @@
if(!(I.item_flags & ABSTRACT))
msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
GET_COMPONENT(FR, /datum/component/forensics)
//gloves
if(gloves && !(SLOT_GLOVES in obscured))
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
else if(FR && length(FR.blood_DNA))
else if(length(blood_DNA))
var/hand_number = get_num_arms(FALSE)
if(hand_number)
msg += "<span class='warning'>[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!</span>\n"
@@ -86,7 +85,7 @@
if(wear_mask && !(SLOT_WEAR_MASK in obscured))
msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck && !(SLOT_NECK in obscured))
if(wear_neck && !(SLOT_NECK in obscured))
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
//eyes
@@ -152,7 +151,7 @@
var/temp = getBruteLoss() //no need to calculate each of these twice
msg += "<span class='warning'>"
msg += "<span class='warning'>" //Everything below gets this span
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/list/disabled = list()
+26 -10
View File
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /mob/living/carbon/human/clean_blood)))
/mob/living/carbon/human/ComponentInitialize()
@@ -689,16 +689,17 @@
if(..())
dropItemToGround(I)
/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
if(gloves)
if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
update_inv_gloves()
/mob/living/carbon/human/clean_blood()
var/mob/living/carbon/human/H = src
if(H.gloves)
if(H.gloves.clean_blood())
H.update_inv_gloves()
else
if(bloody_hands)
bloody_hands = 0
update_inv_gloves()
..() // Clear the Blood_DNA list
if(H.bloody_hands)
H.bloody_hands = 0
H.update_inv_gloves()
update_icons() //apply the now updated overlays to the mob
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
@@ -1104,3 +1105,18 @@
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict
/mob/living/carbon/human/species/mammal
race = /datum/species/mammal
/mob/living/carbon/human/species/insect
race = /datum/species/insect
/mob/living/carbon/human/species/xeno
race = /datum/species/xeno
/mob/living/carbon/human/species/ipc
race = /datum/species/ipc
/mob/living/carbon/human/species/roundstartslime
race = /datum/species/jelly/roundstartslime
@@ -51,6 +51,9 @@
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
var/blood_state = BLOOD_STATE_NOT_BLOODY
var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
var/name_override //For temporary visible name changes
var/genital_override = FALSE //Force genitals on things incase of chems
@@ -127,3 +127,9 @@
return FALSE
return .
/*
/mob/living/carbon/human/transfer_blood_dna(list/blood_dna)
..()
if(blood_dna.len)
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
last_blood_DNA = blood_dna[blood_dna.len]*/
@@ -56,20 +56,20 @@
//Bloody footprints
var/turf/T = get_turf(src)
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
for(var/obj/effect/decal/cleanable/blood/footprints/oldFP in T)
if (oldFP.blood_state == S.blood_state)
return
//No oldFP or they're all a different kind of blood
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
if (S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
FP.add_blood_DNA(S.return_blood_DNA())
FP.update_icon()
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype)))
return
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state]
if(S.last_bloodtype)
FP.blood_DNA += list(S.last_blood_DNA = S.last_bloodtype)
FP.update_icon()
update_inv_shoes()
//End bloody footprints
S.step_action()
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
@@ -339,7 +339,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
if(!new_species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
else
C.dna.blood_type = new_species.exotic_bloodtype
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
for(var/X in inherent_traits)
@@ -1024,6 +1027,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return "TAUR"
//END EDIT
/* TODO: Snowflake trail marks
// Impliments different trails for species depending on if they're wearing shoes.
/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H)
if(H.lying)
return /obj/effect/decal/cleanable/blood/footprints/tracks/body
if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))
var/obj/item/clothing/shoes/shoes = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) ? H.wear_suit : H.shoes // suits take priority over shoes
return shoes.move_trail
else
return move_trail */
/datum/species/proc/spec_life(mob/living/carbon/human/H)
if(HAS_TRAIT(H, TRAIT_NOBREATH))
@@ -17,6 +17,7 @@
toxic_food = MEAT | RAW
mutanteyes = /obj/item/organ/eyes/insect
should_draw_citadel = TRUE
exotic_bloodtype = "BUG"
/datum/species/insect/on_species_gain(mob/living/carbon/C)
. = ..()
@@ -10,6 +10,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly
disliked_food = null
liked_food = GROSS
exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "pestkiller")
@@ -65,7 +65,7 @@
miss_sound = 'sound/weapons/slashmiss.ogg'
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
skinned_type = /obj/item/stack/sheet/animalhide/xeno
exotic_bloodtype = "L"
exotic_bloodtype = "X*"
damage_overlay_type = "xeno"
liked_food = MEAT
@@ -12,8 +12,8 @@
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
mutanttongue = /obj/item/organ/tongue/robot/ipc
exotic_blood = "oil"
mutant_heart = /obj/item/organ/heart/ipc
exotic_bloodtype = "HF"
var/datum/action/innate/monitor_change/screen
@@ -4,13 +4,15 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,WINGCOLOR)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
mutantlungs = /obj/item/organ/lungs/slime
mutant_heart = /obj/item/organ/heart/slime
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
inherent_traits = list(TRAIT_TOXINLOVER)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = "slimejelly"
exotic_blood = "jellyblood"
exotic_bloodtype = "GEL"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
var/datum/action/innate/slime_change/slime_change //CIT CHANGE
@@ -121,7 +123,7 @@
name = "Xenobiological Slime Entity"
id = "slime"
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
say_mod = "says"
hair_color = "mutcolor"
hair_alpha = 150
@@ -396,7 +398,7 @@
id = "slimeperson"
limbs_id = "slime"
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
inherent_traits = list(TRAIT_TOXINLOVER)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur")
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
@@ -180,7 +180,7 @@ There are several things that need to be remembered:
inv.update_icon()
if(!gloves && bloody_hands)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
if(get_num_arms() < 2)
if(has_left_hand())
bloody_overlay.icon_state = "bloodyhands_left"
@@ -270,6 +270,32 @@ There are several things that need to be remembered:
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
/*
if(!shoes && bloody_feet)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(dna.features["taur"] != "None")
if(dna.features["taur"] in GLOB.noodle_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "snekbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "snekbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "snekbloodyfeet_right"
else if(dna.features["taur"] in GLOB.paw_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "pawbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "pawbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "pawbloodyfeet_right"
else
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "bloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "bloodyfeet_right"
overlays_standing[GLOVES_LAYER] = bloody_overlay*/
if(shoes)
var/obj/item/clothing/shoes/S = shoes
@@ -97,8 +97,12 @@
/mob/living/carbon/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
var/dam_colors = "#E62525"
if(ishuman(src))
var/mob/living/carbon/human/H = src
dam_colors = bloodtype_to_color(H.dna.blood_type)
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER)
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER, color = dam_colors)
overlays_standing[DAMAGE_LAYER] = damage_overlay
for(var/X in bodyparts)
@@ -198,7 +198,6 @@
)
if(blood)
target_types += /obj/effect/decal/cleanable/xenoblood
target_types += /obj/effect/decal/cleanable/blood
target_types += /obj/effect/decal/cleanable/trail_holder
target_types += /obj/effect/decal/cleanable/insectguts
@@ -476,7 +476,8 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
B.add_blood_DNA(return_blood_DNA())
if(blood_DNA && blood_DNA.len)
B.blood_DNA |= blood_DNA.Copy()
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
@@ -489,7 +490,6 @@
B.setDir(newdir)
bloodiness--
var/oldloc = loc
var/moved = step_towards(src, next) // attempt to move
if(cell)
@@ -168,7 +168,6 @@
/mob/living/simple_animal/hostile/alien/maid/Initialize(mapload)
. = ..()
AddComponent(/datum/component/cleaning)
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
if(ismovableatom(target))
@@ -177,6 +176,7 @@
qdel(target)
return TRUE
var/atom/movable/M = target
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
M.clean_blood()
visible_message("[src] polishes \the [target].")
return TRUE
@@ -39,7 +39,7 @@
animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch
childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck = 45, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen = 55)
wanted_objects = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/blood/gibs/)
wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/)
var/obj/item/udder/gutlunch/udder = null
/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize()
+21 -1
View File
@@ -487,6 +487,26 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/can_hear()
. = TRUE
/proc/bloodtype_to_color(var/type)
. = BLOOD_COLOR_HUMAN
switch(type)
if("U")//Universal blood; a bit orange
. = BLOOD_COLOR_UNIVERSAL
if("SY")//Synthetics blood; blue
. = BLOOD_COLOR_SYNTHETIC
if("L")//lizard, a bit pink/purple
. = BLOOD_COLOR_LIZARD
if("X*")//xeno blood; greenish yellow
. = BLOOD_COLOR_XENO
if("HF")// Oil/Hydraulic blood. something something why not. reee
. = BLOOD_COLOR_OIL
if("GEL")// slimepeople blood, rgb 0, 255, 144
. = BLOOD_COLOR_SLIME
if("BUG")// yellowish, like, y'know bug guts I guess.
. = BLOOD_COLOR_BUG
//add more stuff to the switch if you have more blood colors for different types
// the defines are in _DEFINES/misc.dm
//Examine text for traits shared by multiple types. I wish examine was less copypasted.
/mob/proc/common_trait_examine()
if(HAS_TRAIT(src, TRAIT_DISSECTED))
@@ -497,4 +517,4 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
dissectionmsg = " via Experimental Dissection"
else if(HAS_TRAIT_FROM(src, TRAIT_DISSECTED,"Thorough Dissection"))
dissectionmsg = " via Thorough Dissection"
. += "<span class='notice'>This body has been dissected and analyzed[dissectionmsg].</span><br>"
. += "<span class='notice'>This body has been dissected and analyzed[dissectionmsg].</span><br>"
+1
View File
@@ -158,6 +158,7 @@
if(..())
if(reagents.total_volume)
if(M.reagents)
reagents.reaction(M, INJECT)
reagents.trans_to(M, reagents.total_volume)
+1 -1
View File
@@ -170,7 +170,7 @@
if(iscarbon(user))
var/mob/living/carbon/C = user
user_dna = C.dna
B.add_blood_DNA(user_dna)
B.add_blood_DNA(user_dna, C.diseases)
var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, /proc/spawn_atom_to_turf, /obj/effect/gibspawner/generic, B, 1, FALSE, list(user_dna))
B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner)
return(BRUTELOSS)
+13 -2
View File
@@ -163,15 +163,26 @@
var/splatter_dir = dir
if(starting)
splatter_dir = get_dir(starting, target_loca)
if(isalien(L))
var/obj/item/bodypart/B = L.get_bodypart(def_zone)
if(B.status == BODYPART_ROBOTIC) // So if you hit a robotic, it sparks instead of bloodspatters
do_sparks(2, FALSE, target.loc)
if(prob(25))
new /obj/effect/decal/cleanable/oil(target_loca)
else if(isalien(L))
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
else
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir)
if(ishuman(target))
var/mob/living/carbon/human/H = target
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color(H.dna.blood_type))
else
new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color())
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(damage)
else
L.add_splatter_floor(target_loca)
else if(impact_effect_type && !hitscan)
new impact_effect_type(target_loca, hitx, hity)
@@ -17,31 +17,40 @@
/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
. = ..()
var/turf/T = get_turf(target)
//section shamelessly copypasta'd from the clean component
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/A in T)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/I = A
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(ismob(I.loc))
var/mob/M = I.loc
else if(isitem(A))
var/obj/item/cleaned_item = A
SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_item.clean_blood()
if(ismob(cleaned_item.loc))
var/mob/M = cleaned_item.loc
M.regenerate_icons()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.head)
SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(cleaned_human.wear_suit)
SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else if(cleaned_human.w_uniform)
SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(cleaned_human.shoes)
SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
if(cleaned_human.lying)
if(cleaned_human.head)
SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes()
SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
cleaned_human.clean_blood()
cleaned_human.wash_cream()
cleaned_human.regenerate_icons()
// 4.6x30mm (Autorifles)
@@ -57,4 +66,4 @@
/obj/item/projectile/bullet/incendiary/c46x30mm
name = "4.6x30mm incendiary bullet"
damage = 10
fire_stacks = 1
fire_stacks = 1
@@ -188,7 +188,7 @@
to_chat(usr, "<span class='warning'>ERROR: Cannot replicate virus strain.</span>")
return
A = A.Copy()
var/list/data = list("viruses" = list(A))
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY", "viruses" = list(A))
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
@@ -1,9 +1,9 @@
/datum/reagent/blood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Blood"
id = "blood"
color = "#C80000" // rgb: 200, 0, 0
description = "Blood from a human, or otherwise."
color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0
description = "Blood from some creature."
metabolization_rate = 5 //fast rate so it disappears fast.
taste_description = "iron"
taste_mult = 1.3
@@ -28,27 +28,75 @@
if(iscarbon(L))
var/mob/living/carbon/C = L
if(C.get_blood_id() == "blood" && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type)))
C.reagents.add_reagent("toxin", reac_volume * 0.5)
else
C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM)
var/blood_id = C.get_blood_id()
if((blood_id == "blood" || blood_id == "jellyblood") && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM * C.blood_ratio)
// we don't care about bloodtype here, we're just refilling the mob
if(reac_volume >= 10 && istype(L))
if(reac_volume >= 10 && istype(L) && method != INJECT)
L.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino.
var/blood_id = C.get_blood_id()
if((blood_id == "blood" || blood_id == "jellyblood"))
if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be
C.adjustToxLoss(rand(2,8)*REM, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person
..()
/datum/reagent/blood/reaction_obj(obj/O, volume)
if(volume >= 3 && istype(O))
O.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
O.add_blood_DNA(data)
/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
if(!istype(T))
return
if(reac_volume < 3)
return
var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
if(!B)
B = new(T)
if(data["blood_DNA"])
B.blood_DNA[data["blood_DNA"]] = data["blood_type"]
if(!B.reagents)
B.reagents.add_reagent(id, reac_volume)
B.update_icon()
/datum/reagent/blood/on_new(list/data)
if(istype(data))
SetViruses(src, data)
color = bloodtype_to_color(data["blood_type"])
if(data["blood_type"] == "SY")
name = "Synthetic Blood"
taste_description = "oily"
if(data["blood_type"] == "X*")
name = "Xenomorph Blood"
taste_description = "acidic heresy"
shot_glass_icon_state = "shotglassgreen"
pH = 2.5
if(data["blood_type"] == "HF")
name = "Hydraulic Blood"
taste_description = "burnt oil"
pH = 9.75
if(data["blood_type"] == "BUG")
name = "Insect Blood"
taste_description = "greasy"
pH = 7.25
if(data["blood_type"] == "L")
name = "Lizard Blood"
taste_description = "spicy"
pH = 6.85
/datum/reagent/blood/on_merge(list/mix_data)
if(data && mix_data)
if(data["blood_DNA"] != mix_data["blood_DNA"])
data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
data["cloneable"] = FALSE //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
if(data["viruses"] || mix_data["viruses"])
var/list/mix1 = data["viruses"]
@@ -78,27 +126,111 @@
var/datum/disease/D = thing
. += D
/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
if(!istype(T))
return
if(reac_volume < 3)
return
/datum/reagent/blood/synthetics
data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Synthetic Blood"
id = "syntheticblood"
taste_description = "oily"
color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48
var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
if(!B)
B = new(T)
if(data["blood_DNA"])
B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/datum/reagent/blood/lizard
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_LIZARD, "blood_type"="L","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Lizard Blood"
id = "lizardblood"
taste_description = "spicy"
color = BLOOD_COLOR_LIZARD // rgb: 11, 7, 48
pH = 6.85
/datum/reagent/blood/jellyblood
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Slime Jelly Blood"
id = "jellyblood"
description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
color = BLOOD_COLOR_SLIME
taste_description = "slime"
taste_mult = 1.3
pH = 4
/datum/reagent/blood/xenomorph
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Xenomorph Blood"
id = "xenoblood"
taste_description = "acidic heresy"
color = BLOOD_COLOR_XENO // greenish yellow ooze
shot_glass_icon_state = "shotglassgreen"
pH = 2.5
/datum/reagent/blood/oil
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Hydraulic Blood"
id = "oilblood"
taste_description = "burnt oil"
color = BLOOD_COLOR_OIL // dark, y'know, expected batman colors.
pH = 9.75
/datum/reagent/blood/insect
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_BUG, "blood_type"="BUG","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Insectoid Blood"
id = "bugblood"
taste_description = "waxy"
color = BLOOD_COLOR_BUG // Bug colored, I guess.
pH = 7.25
/datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M)
if(prob(10))
if(M.dna?.species?.exotic_bloodtype != "GEL")
to_chat(M, "<span class='danger'>Your insides are burning!</span>")
M.adjustToxLoss(rand(20,60)*REM, 0)
. = 1
else if(prob(40) && isjellyperson(M))
M.heal_bodypart_damage(2*REM)
. = 1
..()
/datum/reagent/liquidgibs
name = "Liquid gibs"
id = "liquidgibs"
color = "#FF9966"
color = BLOOD_COLOR_HUMAN
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
shot_glass_icon_state = "shotglassred"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 7.45
/datum/reagent/liquidgibs/xeno
name = "Liquid xeno gibs"
id = "liquidxenogibs"
color = BLOOD_COLOR_XENO
taste_description = "blended heresy"
shot_glass_icon_state = "shotglassgreen"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 2.5
/datum/reagent/liquidgibs/slime
name = "Slime sludge"
id = "liquidslimegibs"
color = BLOOD_COLOR_SLIME
taste_description = "slime"
shot_glass_icon_state = "shotglassgreen"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 4
/datum/reagent/liquidgibs/synth
name = "Synthetic sludge"
id = "liquidsyntheticgibs"
color = BLOOD_COLOR_SYNTHETIC
taste_description = "jellied plastic"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
/datum/reagent/liquidgibs/oil
name = "Hydraulic sludge"
id = "liquidoilgibs"
color = BLOOD_COLOR_OIL
taste_description = "chunky burnt oil"
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 9.75
/datum/reagent/vaccine
//data must contain virus type
name = "Vaccine"
@@ -585,6 +717,30 @@
race = /datum/species/android
mutationtext = "<span class='danger'>The pain subsides. You feel... artificial.</span>"
//Citadel Races
/datum/reagent/mutationtoxin/mammal
name = "Mammal Mutation Toxin"
id = "mammalmutationtoxin"
description = "A glowing toxin."
color = "#5EFF3B" //RGB: 94, 255, 59
race = /datum/species/mammal
mutationtext = "<span class='danger'>The pain subsides. You feel... fluffier.</span>"
/datum/reagent/mutationtoxin/insect
name = "Insect Mutation Toxin"
id = "insectmutationtoxin"
description = "A glowing toxin."
color = "#5EFF3B" //RGB: 94, 255, 59
race = /datum/species/insect
mutationtext = "<span class='danger'>The pain subsides. You feel... attracted to dark, moist areas.</span>"
/datum/reagent/mutationtoxin/xenoperson
name = "Xeno-Hybrid Mutation Toxin"
id = "xenopersonmutationtoxin"
description = "A glowing toxin."
color = "#5EFF3B" //RGB: 94, 255, 59
race = /datum/species/xeno
mutationtext = "<span class='danger'>The pain subsides. You feel... oddly longing for the Queen.</span>" //sadly, not the British one.
//BLACKLISTED RACES
/datum/reagent/mutationtoxin/skeleton
@@ -947,12 +1103,12 @@
reagent_state = SOLID
taste_description = "iron"
pH = 6
overdose_threshold = 30
color = "#c2391d"
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
C.blood_volume += 0.5
C.blood_volume += 0.01 //we'll have synthetics from medbay.
..()
/datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -961,6 +1117,17 @@
M.reagents.add_reagent("toxin", reac_volume)
..()
/datum/reagent/iron/overdose_start(mob/living/M)
to_chat(M, "<span class='userdanger'>You start feeling your guts twisting painfully!</span>")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[id]_overdose", /datum/mood_event/overdose, name)
/datum/reagent/iron/overdose_process(mob/living/carbon/C)
if(prob(20))
var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
if (istype(L))
C.applyLiverDamage(2) //mild until the fabled med rework comes out. the organ damage galore
..()
/datum/reagent/gold
name = "Gold"
id = "gold"
@@ -1077,17 +1244,19 @@
pH = 5.5
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
if(istype(O, /obj/effect/decal/cleanable))
if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
qdel(O)
else
if(O)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.clean_blood()
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1)
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
T.clean_blood()
for(var/obj/effect/decal/cleanable/C in T)
qdel(C)
@@ -1105,26 +1274,33 @@
H.lip_style = null
H.update_body()
for(var/obj/item/I in C.held_items)
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
I.clean_blood()
if(C.wear_mask)
if(SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(C.wear_mask.clean_blood())
C.update_inv_wear_mask()
if(ishuman(M))
var/mob/living/carbon/human/H = C
if(H.head)
if(SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.head.clean_blood())
H.update_inv_head()
if(H.wear_suit)
if(SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.wear_suit.clean_blood())
H.update_inv_wear_suit()
else if(H.w_uniform)
if(SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.w_uniform.clean_blood())
H.update_inv_w_uniform()
if(H.shoes)
if(SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.shoes.clean_blood())
H.update_inv_shoes()
H.wash_cream()
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
M.clean_blood()
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
@@ -283,6 +283,12 @@
results = list("regen_jelly" = 2)
required_reagents = list("tricordrazine" = 1, "slimejelly" = 1)
/datum/chemical_reaction/jelly_convert
name = "Blood Jelly Conversion"
id = "blood_jelly"
results = list("slimejelly" = 1)
required_reagents = list("toxin" = 1, "jellyblood" = 1)
/datum/chemical_reaction/corazone
name = "Corazone"
id = "corazone"
+1 -1
View File
@@ -26,7 +26,7 @@
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("viruses"= list(F))
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent("blood", disease_amount, data)
add_initial_reagents()
@@ -4,13 +4,16 @@
icon = 'icons/obj/bloodpack.dmi'
icon_state = "bloodpack"
volume = 200
reagent_flags = DRAINABLE
var/blood_type = null
var/labelled = 0
var/color_to_apply = "#FFFFFF"
var/mutable_appearance/fill_overlay
/obj/item/reagent_containers/blood/Initialize()
. = ..()
if(blood_type != null)
reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_colour"=color, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/reagent_containers/blood/on_reagent_change(changetype)
@@ -18,6 +21,7 @@
var/datum/reagent/blood/B = reagents.has_reagent("blood")
if(B && B.data && B.data["blood_type"])
blood_type = B.data["blood_type"]
color_to_apply = bloodtype_to_color(blood_type)
else
blood_type = null
update_pack_name()
@@ -45,7 +49,7 @@
/obj/item/reagent_containers/blood/random/Initialize()
icon_state = "bloodpack"
blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L", "SY", "HF", "GEL", "BUG")
return ..()
/obj/item/reagent_containers/blood/APlus
@@ -72,6 +76,18 @@
/obj/item/reagent_containers/blood/universal
blood_type = "U"
/obj/item/reagent_containers/blood/synthetics
blood_type = "SY"
/obj/item/reagent_containers/blood/oilblood
blood_type = "HF"
/obj/item/reagent_containers/blood/jellyblood
blood_type = "GEL"
/obj/item/reagent_containers/blood/insect
blood_type = "BUG"
/obj/item/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/pen) || istype(I, /obj/item/toy/crayon))
if(!user.is_literate())

Some files were not shown because too many files have changed in this diff Show More