Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-33829

This commit is contained in:
LetterJay
2018-01-01 14:09:07 -06:00
180 changed files with 2769 additions and 4332 deletions
+2 -2
View File
@@ -472,7 +472,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
var/input = input(usr, "Enter a Command Report. Ensure it makes sense IC.", "What?", "") as message|null
if(!input)
return
@@ -523,7 +523,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ChangeTurf(T.baseturf)
T.ScrapeAway()
else
qdel(D)
@@ -168,7 +168,7 @@
else
chance_of_deletion = 100
if(prob(chance_of_deletion))
T.ChangeTurf(T.baseturf)
T.ScrapeAway()
else
T.to_be_destroyed = FALSE
T.max_fire_temperature_sustained = 0
+2 -1
View File
@@ -75,7 +75,8 @@
//Logs all hrefs, except chat pings
if(!(href_list["_src_"] == "chat" && href_list["proc"] == "ping" && LAZYLEN(href_list) == 2))
WRITE_FILE(GLOB.world_href_log, "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>")
WRITE_FILE(GLOB.world_href_log, "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr]\[[COORD(usr)]\])</small> || [hsrc ? "[hsrc] " : ""][href]<br>")
// Admin PM
if(href_list["priv_msg"])
cmd_admin_pm(href_list["priv_msg"],null)
+1
View File
@@ -206,6 +206,7 @@
sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle??
random_sensor = FALSE
resistance_flags = NONE
can_adjust = FALSE
armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50)
var/datum/action/item_action/chameleon/change/chameleon_action
+2 -2
View File
@@ -11,7 +11,7 @@
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 2//Base human is 2
var/invis_view = SEE_INVISIBLE_LIVING
var/invis_view = SEE_INVISIBLE_LIVING //admin only for now
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
var/lighting_alpha
var/list/icon/current = list() //the current hud icons
@@ -261,7 +261,7 @@
icon_state = "thermal"
item_state = "glasses"
vision_flags = SEE_MOBS
invis_view = 2
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = 0
glass_colour_type = /datum/client_colour/glass_colour/red
+1 -1
View File
@@ -174,7 +174,7 @@
icon_state = "thermal"
hud_type = DATA_HUD_SECURITY_ADVANCED
vision_flags = SEE_MOBS
invis_view = 2
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user)
+9 -1
View File
@@ -11,13 +11,21 @@
strip_delay = 20
equip_delay_other = 40
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
/obj/item/clothing/gloves/proc/clean_blood(strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
transfer_blood = 0
/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands")
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
+10 -8
View File
@@ -192,7 +192,7 @@
item_state = "wgloves"
item_color = "mime"
/obj/item/clothing/gloves/color/random/New()
/obj/item/clothing/gloves/color/random/Initialize()
..()
var/list/gloves = list(
/obj/item/clothing/gloves/color/orange = 1,
@@ -202,12 +202,14 @@
/obj/item/clothing/gloves/color/green = 1,
/obj/item/clothing/gloves/color/grey = 1,
/obj/item/clothing/gloves/color/light_brown = 1,
/obj/item/clothing/gloves/color/brown = 1)
/obj/item/clothing/gloves/color/brown = 1,
/obj/item/clothing/gloves/color/white = 1,
/obj/item/clothing/gloves/color/rainbow = 1)
var/obj/item/clothing/gloves/color/selected = pick(gloves)
name = initial(selected.name)
desc = initial(selected.desc)
icon_state = initial(selected.icon_state)
item_state = initial(selected.item_state)
item_color = initial(selected.item_color)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.equip_to_slot_or_del(new selected(H), slot_gloves)
else
new selected(loc)
return INITIALIZE_HINT_QDEL
+1 -1
View File
@@ -20,7 +20,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood")
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
+1 -1
View File
@@ -15,7 +15,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
+1 -1
View File
@@ -12,7 +12,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
/obj/item/clothing/neck/tie
+11 -6
View File
@@ -15,12 +15,16 @@
var/offset = 0
var/equipped_before_drop = FALSE
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
var/bloody = 0
if(blood_DNA)
bloody = 1
var/bloody = FALSE
IF_HAS_BLOOD_DNA(src)
bloody = TRUE
else
bloody = bloody_shoes[BLOOD_STATE_HUMAN]
@@ -53,8 +57,9 @@
var/mob/M = loc
M.update_inv_shoes()
/obj/item/clothing/shoes/clean_blood()
..()
/obj/item/clothing/shoes/proc/clean_blood(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)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
@@ -62,4 +67,4 @@
M.update_inv_shoes()
/obj/item/proc/negates_gravity()
return 0
return FALSE
+1 -1
View File
@@ -14,7 +14,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
+1 -2
View File
@@ -19,10 +19,9 @@
/obj/item/clothing/under/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
if(blood_DNA)
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
if(accessory_overlay)
. += accessory_overlay
+8 -6
View File
@@ -4,13 +4,15 @@
/obj/item/clothing/under/color/random
icon_state = "random_jumpsuit"
/obj/item/clothing/under/color/random/New()
/obj/item/clothing/under/color/random/Initialize()
..()
var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random)
name = initial(C.name)
icon_state = initial(C.icon_state)
item_state = initial(C.item_state)
item_color = initial(C.item_color)
var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.equip_to_slot_or_del(new C(H), slot_w_uniform) //or else you end up with naked assistants running around everywhere...
else
new C(loc)
return INITIALIZE_HINT_QDEL
/obj/item/clothing/under/color/black
name = "black jumpsuit"
@@ -274,6 +274,7 @@
icon_state = "burial"
item_state = "burial"
item_color = "burial"
has_sensor = NO_SENSORS
/obj/item/clothing/under/skirt/black
name = "black skirt"
+102 -119
View File
@@ -1,119 +1,102 @@
//CONTAINS: Suit fibers and Detective's Scanning Computer
/atom/var/list/suit_fibers
/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(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(M.blood_DNA))
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/add_hiddenprint(mob/living/M)
if(!M || !M.key)
return
if(!fingerprintshidden) //Add the list if it does not exist
fingerprintshidden = list()
var/hasgloves = ""
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.gloves)
hasgloves = "(gloves)"
var/current_time = time_stamp()
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
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = 0)
if(!M || !M.key)
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 = 1
if(!ignoregloves)
H.gloves.add_fingerprint(H, 1) //ignoregloves = 1 to avoid infinite loop.
return
if(!fingerprints) //Add the list if it does not exist
fingerprints = list()
var/full_print = md5(H.dna.uni_identity)
fingerprints[full_print] = full_print
/atom/proc/transfer_fingerprints_to(atom/A)
// Make sure everything are lists.
if(!islist(A.fingerprints))
A.fingerprints = list()
if(!islist(A.fingerprintshidden))
A.fingerprintshidden = list()
if(!islist(fingerprints))
fingerprints = list()
if(!islist(fingerprintshidden))
fingerprintshidden = list()
// Transfer
if(fingerprints)
A.fingerprints |= fingerprints.Copy() //detective
if(fingerprintshidden)
A.fingerprintshidden |= fingerprintshidden.Copy() //admin
A.fingerprintslast = fingerprintslast
//CONTAINS: Suit fibers and Detective's Scanning Computer
/atom/proc/return_fingerprints()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.fingerprints
/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/blood_DNA_length()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = length(D.blood_DNA)
/atom/proc/return_fibers()
GET_COMPONENT(D, /datum/component/forensics)
if(D)
. = D.fibers
/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)
/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
if(length(fibertext))
. = AddComponent(/datum/component/forensics, null, null, null, fibertext)
/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)
/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)
/atom/proc/add_hiddenprint(mob/living/M)
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
. = D.add_hiddenprint(M)
/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
return FALSE
/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, dna)
bloody_hands = rand(2, 4)
update_inv_gloves() //handles bloody hands overlays and updating
return TRUE
/atom/proc/transfer_fingerprints_to(atom/A)
A.add_fingerprint_list(return_fingerprints())
A.add_hiddenprint_list(return_hiddenprints())
A.fingerprintslast = fingerprintslast
+1 -1
View File
@@ -23,7 +23,7 @@
icon_state = initial(icon_state)
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
if(!istype(I) || I.anchored == 1)
return
@@ -46,6 +46,5 @@
user.visible_message("[user] starts to wipe down [A] with [src]!", "<span class='notice'>You start to wipe down [A] with [src]...</span>")
if(do_after(user,30, target = A))
user.visible_message("[user] finishes wiping off the [A]!", "<span class='notice'>You finish wiping off the [A].</span>")
A.clean_blood()
A.wash_cream()
A.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
return
+8 -14
View File
@@ -67,20 +67,14 @@
//Make our lists
var/list/fingerprints = list()
var/list/blood = list()
var/list/fibers = list()
var/list/blood = A.return_blood_DNA()
var/list/fibers = A.return_fibers()
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
@@ -89,8 +83,7 @@
else if(!ismob(A))
if(A.fingerprints && A.fingerprints.len)
fingerprints = A.fingerprints.Copy()
fingerprints = A.return_fingerprints()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
@@ -104,6 +97,7 @@
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
LAZYINITLIST(blood)
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
@@ -112,7 +106,7 @@
add_log("<B>[worldtime2text()][get_timestamp()] - [target_name]</B>", 0)
// Fingerprints
if(fingerprints && fingerprints.len)
if(length(fingerprints))
sleep(30)
add_log("<span class='info'><B>Prints:</B></span>")
for(var/finger in fingerprints)
@@ -120,7 +114,7 @@
found_something = 1
// Blood
if (blood && blood.len)
if (length(blood))
sleep(30)
add_log("<span class='info'><B>Blood:</B></span>")
found_something = 1
@@ -128,7 +122,7 @@
add_log("Type: <font color='red'>[blood[B]]</font> DNA: <font color='red'>[B]</font>")
//Fibers
if(fibers && fibers.len)
if(length(fibers))
sleep(30)
add_log("<span class='info'><B>Fibers:</B></span>")
for(var/fiber in fibers)
@@ -136,7 +130,7 @@
found_something = 1
//Reagents
if(reagents && reagents.len)
if(length(reagents))
sleep(30)
add_log("<span class='info'><B>Reagents:</B></span>")
for(var/R in reagents)
@@ -101,6 +101,7 @@
return
if(..())
return TRUE
add_fingerprint(usr)
if(href_list["category"])
current_category = href_list["category"]
+6 -2
View File
@@ -13,11 +13,15 @@
. = ..()
var/area/thearea = get_area(src)
for(var/turf/T in get_area_turfs(thearea, z))
if(T.baseturf != T.type) //Don't break indestructible walls and the like
T.baseturf = baseturf
if(T.baseturfs != T.type) //Don't break indestructible walls and the like
T.baseturfs = baseturf
return INITIALIZE_HINT_QDEL
/obj/effect/baseturf_helper/space
name = "space baseturf editor"
baseturf = /turf/open/space
/obj/effect/baseturf_helper/asteroid
name = "asteroid baseturf editor"
baseturf = /turf/open/floor/plating/asteroid
+1 -1
View File
@@ -339,7 +339,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new)
if(crds)
if(!no_changeturf && ispath(path, /turf))
. = crds.ChangeTurf(path, FALSE, TRUE)
. = crds.ChangeTurf(path, null, CHANGETURF_DEFER_CHANGE)
else
. = create_atom(path, crds)//first preloader pass
+2 -3
View File
@@ -257,9 +257,8 @@
if("Release")
if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user
var/out = get_step(src, output_dir)
if(params["id"] == "all")
materials.retrieve_all(out)
materials.retrieve_all(get_step(src, output_dir))
else
var/mat_id = params["id"]
if(!materials.materials[mat_id])
@@ -277,7 +276,7 @@
desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num
var/sheets_to_remove = round(min(desired,50,stored_amount))
materials.retrieve_sheets(sheets_to_remove, mat_id, out)
materials.retrieve_sheets(sheets_to_remove, mat_id, get_step(src, output_dir))
else
to_chat(usr, "<span class='warning'>Required access not found.</span>")
+3 -4
View File
@@ -251,8 +251,7 @@
drop.transfer_mob_blood_dna(src)
return
else
temp_blood_DNA = list()
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
temp_blood_DNA = drop.return_blood_DNA() //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())
@@ -265,7 +264,7 @@
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
if(temp_blood_DNA)
B.blood_DNA |= temp_blood_DNA
B.add_blood_DNA(temp_blood_DNA)
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
if(!(NOBLOOD in dna.species.species_traits))
@@ -277,7 +276,7 @@
var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
if(!B)
B = new(T)
B.blood_DNA["UNKNOWN DNA"] = "X*"
B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
if(!T)
+5 -8
View File
@@ -11,21 +11,18 @@
if (handcuffed)
msg += "<span class='warning'>[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!</span>\n"
if (head)
msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [src.head] on [t_his] head. \n"
msg += "[t_He] [t_is] wearing [head.get_examine_string(user)] on [t_his] head. \n"
if (wear_mask)
msg += "[t_He] [t_is] wearing [icon2html(wear_mask, user)] \a [src.wear_mask] on [t_his] face.\n"
msg += "[t_He] [t_is] wearing [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck)
msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
if(I.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
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"
if (back)
msg += "[t_He] [t_has] [icon2html(back, user)] \a [src.back] on [t_his] back.\n"
msg += "[t_He] [t_has] [back.get_examine_string(user)] on [t_his] back.\n"
var/appears_dead = 0
if (stat == DEAD)
appears_dead = 1
+32 -52
View File
@@ -21,54 +21,30 @@
if(U.attached_accessory)
accessory_msg += " with [icon2html(U.attached_accessory, user)] \a [U.attached_accessory]"
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [icon2html(w_uniform, user)] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][accessory_msg]!</span>\n"
else
msg += "[t_He] [t_is] wearing [icon2html(w_uniform, user)] \a [w_uniform][accessory_msg].\n"
msg += "[t_He] [t_is] wearing [w_uniform.get_examine_string(user)][accessory_msg].\n"
//head
if(head)
if(head.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!</span>\n"
else
msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [head] on [t_his] head.\n"
msg += "[t_He] [t_is] wearing [head.get_examine_string(user)] on [t_his] head.\n"
//suit/armor
if(wear_suit)
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [icon2html(wear_suit, user)] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] wearing [icon2html(wear_suit, user)] \a [wear_suit].\n"
msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
//suit/armor storage
if(s_store)
if(s_store.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] carrying [icon2html(s_store, user)] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] carrying [icon2html(s_store, user)] \a [s_store] on [t_his] [wear_suit.name].\n"
msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [icon2html(back, user)] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.</span>\n"
else
msg += "[t_He] [t_has] [icon2html(back, user)] \a [back] on [t_his] back.\n"
msg += "[t_He] [t_has] [back.get_examine_string(user)] on [t_his] back.\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
if(I.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
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))
if(gloves.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [icon2html(gloves, user)] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!</span>\n"
else
msg += "[t_He] [t_has] [icon2html(gloves, user)] \a [gloves] on [t_his] hands.\n"
else if(blood_DNA)
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
else if(FR && length(FR.blood_DNA))
var/hand_number = get_num_arms()
if(hand_number)
msg += "<span class='warning'>[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!</span>\n"
@@ -84,42 +60,33 @@
//belt
if(belt)
if(belt.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [icon2html(belt, user)] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!</span>\n"
else
msg += "[t_He] [t_has] [icon2html(belt, user)] \a [belt] about [t_his] waist.\n"
msg += "[t_He] [t_has] [belt.get_examine_string(user)] about [t_his] waist.\n"
//shoes
if(shoes && !(slot_shoes in obscured))
if(shoes.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [icon2html(shoes, user)] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!</span>\n"
else
msg += "[t_He] [t_is] wearing [icon2html(shoes, user)] \a [shoes] on [t_his] feet.\n"
msg += "[t_He] [t_is] wearing [shoes.get_examine_string(user)] on [t_his] feet.\n"
//mask
if(wear_mask && !(slot_wear_mask in obscured))
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [icon2html(wear_mask, user)] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!</span>\n"
else
msg += "[t_He] [t_has] [icon2html(wear_mask, user)] \a [wear_mask] on [t_his] face.\n"
msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck && !(slot_neck in obscured))
msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
//eyes
if(glasses && !(slot_glasses in obscured))
if(glasses.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [icon2html(glasses, user)] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!</span>\n"
else
msg += "[t_He] [t_has] [icon2html(glasses, user)] \a [glasses] covering [t_his] eyes.\n"
msg += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes.\n"
//ears
if(ears && !(slot_ears in obscured))
msg += "[t_He] [t_has] [icon2html(ears, user)] \a [ears] on [t_his] ears.\n"
msg += "[t_He] [t_has] [ears.get_examine_string(user)] on [t_his] ears.\n"
//ID
if(wear_id)
msg += "[t_He] [t_is] wearing [icon2html(wear_id, user)] \a [wear_id].\n"
msg += "[t_He] [t_is] wearing [wear_id.get_examine_string(user)].\n"
//Status effects
msg += status_effect_examines()
//Jitters
switch(jitteriness)
@@ -354,3 +321,16 @@
msg += "*---------*</span>"
to_chat(user, msg)
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
var/list/dat = list()
if(!pronoun_replacement)
pronoun_replacement = p_they(TRUE)
for(var/V in status_effects)
var/datum/status_effect/E = V
if(E.examine_text)
var/new_text = replacetext(E.examine_text, "SUBJECTPRONOUN", pronoun_replacement)
new_text = replacetext(new_text, "[pronoun_replacement] is", "[pronoun_replacement] [p_are()]") //To make sure something become "They are" or "She is", not "They are" and "She are"
dat += "[new_text]\n" //dat.Join("\n") doesn't work here, for some reason
if(dat.len)
return dat.Join()
+10 -10
View File
@@ -25,6 +25,7 @@
create_internal_organs() //most of it is done in set_species now, this is only for parent call
handcrafting = new()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
. = ..()
@@ -683,19 +684,18 @@
if(..())
dropItemToGround(I)
/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()
/mob/living/carbon/human/proc/clean_blood(strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
if(gloves)
if(gloves.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
update_inv_gloves()
else
..() // Clear the Blood_DNA list
if(H.bloody_hands)
H.bloody_hands = 0
H.update_inv_gloves()
if(bloody_hands)
bloody_hands = 0
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
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
@@ -51,8 +51,7 @@
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
if(S.blood_DNA && S.blood_DNA.len)
FP.transfer_blood_dna(S.blood_DNA)
FP.add_blood_DNA(S.return_blood_DNA())
FP.update_icon()
update_inv_shoes()
//End bloody footprints
@@ -72,6 +72,10 @@
else if(eye_blurry) //blurry eyes heal slowly
adjust_blurriness(-1)
if(has_disability(DISABILITY_PACIFISM) && a_intent == INTENT_HARM)
to_chat(src, "<span class='notice'>You don't feel like harming anybody.</span>")
a_intent_change(INTENT_HELP)
/mob/living/carbon/human/handle_mutations_and_radiation()
if(!dna || !dna.species.handle_mutations_and_radiation(src))
..()
@@ -175,7 +175,8 @@ There are several things that need to be remembered:
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
inv.update_icon()
if(!gloves && blood_DNA)
GET_COMPONENT(FR, /datum/component/forensics)
if(!gloves && FR && length(FR.blood_DNA))
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
if(get_num_arms() < 2)
if(has_left_hand())
+13 -13
View File
@@ -20,11 +20,6 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
"t" = "Syndicate",
"y" = "CentCom",
// Species
"b" = "binary",
"g" = "changeling",
"a" = "alientalk",
// Admin
"p" = "admin",
"d" = "deadmin",
@@ -55,11 +50,6 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
"å" = "Syndicate",
"í" = "CentCom",
// Species
"è" = "binary",
"ï" = "changeling",
"ô" = "alientalk",
// Admin
"ç" = "admin",
"â" = "deadmin",
@@ -81,13 +71,14 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(!message || message == "")
return
var/datum/saymode/saymode = SSradio.saymodes[talk_key]
var/message_mode = get_message_mode(message)
var/original_message = message
var/in_critical = InCritical()
if(one_character_prefix[message_mode])
message = copytext(message, 2)
else if(message_mode)
else if(message_mode || saymode)
message = copytext(message, 3)
if(findtext(message, " ", 1, 2))
message = copytext(message, 2)
@@ -135,8 +126,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
// AIs use inherent channels for the holopad. Most inherent channels
// ignore the language argument however.
var/datum/saymode/SM = SSradio.saymodes[talk_key]
if(SM && !SM.handle_message(src, message, language))
if(saymode && !saymode.handle_message(src, message, language))
return
if(!can_speak_vocal(message))
@@ -341,6 +331,15 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return message
/mob/living/proc/radio(message, message_mode, list/spans, language)
var/obj/item/implant/radio/imp = locate() in src
if(imp && imp.radio.on)
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
if(message_mode == MODE_DEPARTMENT || message_mode in GLOB.radiochannels)
imp.radio.talk_into(src, message, message_mode, spans, language)
return ITALICS | REDUCE_RANGE
switch(message_mode)
if(MODE_WHISPER)
return ITALICS
@@ -362,6 +361,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(MODE_BINARY)
return ITALICS | REDUCE_RANGE //Does not return 0 since this is only reached by humans, not borgs or AIs.
return 0
/mob/living/say_mod(input, message_mode)
@@ -6,6 +6,7 @@
var/obj/act_module = get_active_held_item()
if(act_module)
msg += "It is holding [icon2html(act_module, user)] \a [act_module].\n"
msg += status_effect_examines()
msg += "<span class='warning'>"
if (src.getBruteLoss())
if (src.getBruteLoss() < maxHealth*0.5)
@@ -321,9 +321,9 @@
sleep(50)
if(mode == BOT_REPAIRING && src.loc == target_turf)
if(autotile) //Build the floor and include a tile.
target_turf.ChangeTurf(/turf/open/floor/plasteel)
target_turf.PlaceOnTop(/turf/open/floor/plasteel)
else //Build a hull plating without a floor tile.
target_turf.ChangeTurf(/turf/open/floor/plating)
target_turf.PlaceOnTop(/turf/open/floor/plating)
else
var/turf/open/floor/F = target_turf
@@ -472,8 +472,7 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
if(blood_DNA && blood_DNA.len)
B.blood_DNA |= blood_DNA.Copy()
B.add_blood_DNA(return_blood_DNA())
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
@@ -655,8 +654,7 @@
T.add_mob_blood(H)
var/list/blood_dna = H.get_blood_dna_list()
if(blood_dna)
transfer_blood_dna(blood_dna)
add_blood_DNA(blood_dna)
bloodiness += 4
// player on mulebot attempted to move
@@ -177,24 +177,15 @@
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
if(I.blood_DNA)
msg += "<span class='warning'>It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
msg += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Internal storage
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
if(internal_storage.blood_DNA)
msg += "<span class='warning'>It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!</span>\n"
else
msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
msg += "It is holding [internal_storage.get_examine_string(user)] in its internal storage.\n"
//Cosmetic hat - provides no function other than looks
if(head && !(head.flags_1&ABSTRACT_1))
if(head.blood_DNA)
msg += "<span class='warning'>It is wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!</span>\n"
else
msg += "It is wearing [icon2html(head, user)] \a [head] on its head.\n"
msg += "It is wearing [head.get_examine_string(user)] on its head.\n"
//Braindead
if(!client && stat != DEAD)
@@ -31,16 +31,9 @@
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
if(I.blood_DNA)
msg += "<span class='warning'>It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
msg += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
if(internal_storage.blood_DNA)
msg += "<span class='warning'>It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!</span>\n"
else
msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
msg += "It is holding [internal_storage.get_examine_string(user)] in its internal storage.\n"
msg += "*---------*</span>"
to_chat(user, msg)
else
@@ -173,6 +173,6 @@
qdel(target)
return TRUE
var/atom/movable/M = target
M.clean_blood()
M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
visible_message("[src] polishes \the [target].")
return TRUE
@@ -235,7 +235,8 @@
LoseTarget()
return 0
if(target in possible_targets)
if(target.z != z)
var/turf/T = get_turf(src)
if(target.z != T.z)
LoseTarget()
return 0
var/target_distance = get_dist(targets_from,target)
@@ -417,7 +418,7 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
if(buckled)
buckled.attack_animal(src)
if(!isturf(targets_from.loc) && targets_from.loc != null)//Did someone put us in something?
var/atom/A = get_turf(targets_from)
var/atom/A = targets_from.loc
A.attack_animal(src)//Bang on it till we get out
@@ -39,7 +39,7 @@
for(var/F in RANGE_TURFS(1, src))
if(ismineralturf(F))
var/turf/closed/mineral/M = F
M.ChangeTurf(M.turf_type,FALSE,FALSE,TRUE)
M.ChangeTurf(M.turf_type, null, CHANGETURF_IGNORE_AIR)
gps = new /obj/item/device/gps/internal(src)
/mob/living/simple_animal/hostile/spawner/lavaland/Destroy()
+25 -6
View File
@@ -254,24 +254,43 @@
return 0
// reset_perspective(thing) set the eye to the thing (if it's equal to current default reset to mob perspective)
// reset_perspective() set eye to common default : mob on turf, loc otherwise
/mob/proc/reset_perspective(atom/A)
if(client)
if(ismovableatom(A))
client.perspective = EYE_PERSPECTIVE
client.eye = A
if(A)
if(ismovableatom(A))
//Set the the thing unless it's us
if(A != src)
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else if(isturf(A))
//Set to the turf unless it's our current turf
if(A != loc)
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
//Do nothing
else
if(isturf(loc) && (!A || loc == A))
//Reset to common defaults: mob if on turf, otherwise current loc
if(isturf(loc))
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
client.perspective = EYE_PERSPECTIVE
client.eye = A
client.eye = loc
return 1
/mob/living/reset_perspective(atom/A)
if(..())
update_sight()
if(client.eye != src)
if(client.eye && client.eye != src)
var/atom/AT = client.eye
AT.get_remote_view_fullscreens(src)
else
+8 -8
View File
@@ -40,26 +40,26 @@
/obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity)
if(!candrain || draining)
return 0
return FALSE
if(!ishuman(loc))
return 0 //Only works while worn
return FALSE //Only works while worn
var/mob/living/carbon/human/H = loc
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
if(!istype(suit))
return 0
return FALSE
if(isturf(A))
return 0
return FALSE
if(!proximity)
return 0
return FALSE
A.add_fingerprint(H)
draining = 1
draining = TRUE
. = A.ninjadrain_act(suit,H,src)
draining = 0
draining = FALSE
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
@@ -67,7 +67,7 @@
else
to_chat(H, "<span class='danger'>\The [A] has run dry of energy, you must find another source!</span>")
else
. = 0 //as to not cancel attack_hand()
. = FALSE //as to not cancel attack_hand()
/obj/item/clothing/gloves/space_ninja/proc/toggledrain()
+6 -3
View File
@@ -33,7 +33,9 @@
orbiting = null
return ..()
/datum/orbit/proc/Check(turf/targetloc)
/datum/orbit/proc/Check(turf/targetloc, list/checked_already = list())
//Avoid infinite loops for people who end up orbiting themself through another orbiter
checked_already[src] = TRUE
if (!orbiter)
qdel(src)
return
@@ -55,9 +57,10 @@
lastloc = orbiter.loc
for(var/other_orbit in orbiter.orbiters)
var/datum/orbit/OO = other_orbit
if(OO == src)
//Skip if checked already
if(checked_already[OO])
continue
OO.Check(targetloc)
OO.Check(targetloc, checked_already)
/atom/movable/var/datum/orbit/orbiting = null
/atom/var/list/orbiters = null
+2 -2
View File
@@ -665,7 +665,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
NC.d1 = 0
NC.d2 = fdirn
NC.add_fingerprint()
NC.add_fingerprint(user)
NC.update_icon()
//create a new powernet with the cable, if needed it will be merged later
@@ -716,7 +716,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
//updates the stored cable coil
C.update_stored(2, item_color)
C.add_fingerprint()
C.add_fingerprint(user)
C.update_icon()
+1 -1
View File
@@ -164,7 +164,7 @@
if(iscarbon(user))
var/mob/living/carbon/C = user
user_dna = C.dna
B.add_blood(user_dna)
B.add_blood_DNA(user_dna)
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)
@@ -79,8 +79,7 @@
if(!B)
B = new(T)
if(data["blood_DNA"])
B.blood_DNA[data["blood_DNA"]] = data["blood_type"]
B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/datum/reagent/liquidgibs
name = "Liquid gibs"
@@ -941,12 +940,12 @@
else
if(O)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
O.clean_blood()
O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1)
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
T.clean_blood()
T.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
for(var/obj/effect/decal/cleanable/C in T)
qdel(C)
@@ -964,26 +963,26 @@
H.lip_style = null
H.update_body()
for(var/obj/item/I in C.held_items)
I.clean_blood()
I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(C.wear_mask)
if(C.wear_mask.clean_blood())
if(C.wear_mask.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
C.update_inv_wear_mask()
if(ishuman(M))
var/mob/living/carbon/human/H = C
if(H.head)
if(H.head.clean_blood())
if(H.head.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
H.update_inv_head()
if(H.wear_suit)
if(H.wear_suit.clean_blood())
if(H.wear_suit.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
H.update_inv_wear_suit()
else if(H.w_uniform)
if(H.w_uniform.clean_blood())
if(H.w_uniform.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
H.update_inv_w_uniform()
if(H.shoes)
if(H.shoes.clean_blood())
if(H.shoes.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
H.update_inv_shoes()
H.wash_cream()
M.clean_blood()
M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
@@ -1688,3 +1687,23 @@
description = "blue sparkles that get everywhere"
color = "#4040FF" //A blueish color
glitter_type = /obj/effect/decal/cleanable/glitter/blue
/datum/reagent/pax
name = "pax"
id = "pax"
description = "A colorless liquid that suppresses violence on the subjects."
color = "#AAAAAA55"
taste_description = "water"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
/datum/reagent/pax/on_mob_add(mob/M)
..()
if(isliving(M))
var/mob/living/L = M
L.add_disability(DISABILITY_PACIFISM, CHEMICAL_DISABILITY)
/datum/reagent/pax/on_mob_delete(mob/M)
if(isliving(M))
var/mob/living/L = M
L.remove_disability(DISABILITY_PACIFISM, CHEMICAL_DISABILITY)
..()
@@ -51,7 +51,7 @@
if(isplatingturf(T))
var/turf/open/floor/plating/F = T
if(prob(10 + F.burnt + 5*F.broken)) //broken or burnt plating is more susceptible to being destroyed
F.ChangeTurf(F.baseturf)
F.ScrapeAway()
if(isfloorturf(T))
var/turf/open/floor/F = T
if(prob(reac_volume))
@@ -65,7 +65,7 @@
if(iswallturf(T))
var/turf/closed/wall/W = T
if(prob(reac_volume))
W.ChangeTurf(/turf/open/floor/plating)
W.ScrapeAway()
/datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(istype(M))
@@ -671,3 +671,9 @@
var/location = get_turf(holder.my_atom)
for(var/i in 1 to 10)
new /obj/item/stack/sheet/plastic(location)
/datum/chemical_reaction/pax
name = "pax"
id = "pax"
results = list("pax" = 3)
required_reagents = list("mindbreaker" = 1, "synaptizine" = 1, "water" = 1)
@@ -199,12 +199,24 @@
to_chat(SM, "<span class='userdanger'>You are grateful to be self aware and owe [user.real_name] a great debt. Serve [user.real_name], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.</span>")
to_chat(user, "<span class='notice'>[SM] accepts [src] and suddenly becomes attentive and aware. It worked!</span>")
SM.copy_known_languages_from(user, TRUE)
after_success(user, SM)
qdel(src)
else
to_chat(user, "<span class='notice'>[SM] looks interested for a moment, but then looks back down. Maybe you should try again later.</span>")
being_used = 0
..()
/obj/item/slimepotion/sentience/proc/after_success(mob/living/user, mob/living/simple_animal/SM)
return
/obj/item/slimepotion/sentience/nuclear
name = "syndicate intelligence potion"
desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target."
/obj/item/slimepotion/sentience/nuclear/after_success(mob/living/user, mob/living/simple_animal/SM)
var/obj/item/implant/radio/imp = new(src)
imp.implant(SM, user)
/obj/item/slimepotion/transference
name = "consciousness transference potion"
desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being."
+1
View File
@@ -14,6 +14,7 @@
if(..(user))
return
add_fingerprint(usr)
var/list/options = params2list(possible_destinations)
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]<br><br>"
+10 -6
View File
@@ -7,8 +7,15 @@ All ShuttleMove procs go here
// Called on every turf in the shuttle region, returns a bitflag for allowed movements of that turf
// returns the new move_mode (based on the old)
/turf/proc/fromShuttleMove(turf/newT, turf_type, list/baseturf_cache, move_mode)
if(!(move_mode & MOVE_AREA) || (istype(src, turf_type) && baseturf_cache[baseturf]))
if(!(move_mode & MOVE_AREA))
return move_mode
if(istype(src, turf_type))
if(length(baseturfs))
if(baseturf_cache[baseturfs[1]])
return move_mode
else if(baseturf_cache[baseturfs])
return move_mode
return move_mode | MOVE_TURF | MOVE_CONTENTS
// Called from the new turf before anything has been moved
@@ -45,9 +52,7 @@ All ShuttleMove procs go here
if(newT == src) // In case of in place shuttle rotation shenanigans.
return
//Destination turf changes
var/destination_turf_type = newT.type
newT = copyTurf(newT)
newT.baseturf = destination_turf_type
newT.CopyOnTop(src, 1, 0) // We only want a surface copy
//Air stuff
newT.blocks_air = TRUE
newT.air_update_turf(TRUE)
@@ -63,9 +68,8 @@ All ShuttleMove procs go here
/turf/proc/afterShuttleMove(turf/oldT, turf_type, baseturf_type, rotation)
//Dealing with the turf we left behind
oldT.TransferComponents(src)
oldT.ChangeTurf(turf_type, baseturf_type, FALSE, TRUE)
oldT.ChangeTurf(turf_type, baseturf_type, CHANGETURF_IGNORE_AIR) // TODO: make this oldT.ScrapeAway() which requires templating all shuttles
// Rotate and let the air move again
if(rotation)
shuttleRotate(rotation) //see shuttle_rotate.dm
+1 -1
View File
@@ -465,7 +465,7 @@
var/turf/T1 = L1[i]
if(!T1)
continue
if(T0.type != T0.baseturf)
if(T0.type != T0.baseturfs)
ripple_turfs += T1
return ripple_turfs
+7 -1
View File
@@ -104,4 +104,10 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate
//prevents shuttles attempting to rotate this since it messes up sprites
/obj/machinery/gravity_generator/shuttleRotate(rotation, params)
params = NONE
return ..()
return ..()
/obj/machinery/door/airlock/shuttleRotate(rotation, params)
. = ..()
if(cyclelinkeddir)
cyclelinkeddir = angle2dir(rotation+dir2angle(cyclelinkeddir))
cyclelinkairlock()
+9 -3
View File
@@ -1059,9 +1059,9 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/potion
name = "Sentience Potion"
item = /obj/item/slimepotion/sentience
desc = "A potion recovered at great risk by undercover syndicate operatives. Using it will make any animal sentient, and bound to serve you."
name = "Syndicate Sentience Potion"
item = /obj/item/slimepotion/sentience/nuclear
desc = "A potion recovered at great risk by undercover syndicate operatives and then subsequently modified with syndicate technology. Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication."
cost = 4
include_modes = list(/datum/game_mode/nuclear)
@@ -1152,6 +1152,12 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 20
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/implants/radio
name = "Internal Syndicate Radio Implant"
desc = "An implant injected into the body, allowing the use of an internal syndicate radio. Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection."
item = /obj/item/storage/box/syndie_kit/imp_radio
cost = 4
// Cybernetics
/datum/uplink_item/cyber_implants