diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm
index 30ba553d850..25ca290b0ab 100644
--- a/code/game/jobs/job/support_chaplain.dm
+++ b/code/game/jobs/job/support_chaplain.dm
@@ -26,6 +26,7 @@
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ H.equip_or_collect(new /obj/item/device/camera/spooky(H.back), slot_in_backpack)
spawn(0)
var/religion_name = "Christianity"
var/new_religion = sanitize(copytext(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name),1,MAX_NAME_LEN))
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 076e85c6de0..298c5b75f53 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -152,6 +152,7 @@ var/global/list/image/splatter_cache=list()
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
var/fleshcolor = "#FFFFFF"
+ noclear = 1
/obj/effect/decal/cleanable/blood/gibs/update_icon()
@@ -183,6 +184,17 @@ var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+/obj/effect/decal/cleanable/blood/gibs/New()
+ ..()
+ reagents.add_reagent("liquidgibs", 5)
+
+
+/obj/effect/decal/cleanable/blood/gibs/cleangibs //most ironic name ever...
+
+/obj/effect/decal/cleanable/blood/gibs/cleangibs/New() //no reagent!
+ ..()
+ reagents.remove_reagent("liquidgibs",5)
+
/obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions)
spawn (0)
diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm
index 4ebf6b257e8..02f3289dad8 100644
--- a/code/game/objects/items/weapons/soap.dm
+++ b/code/game/objects/items/weapons/soap.dm
@@ -15,6 +15,36 @@
desc = "A Nanotrasen brand bar of soap. Smells of plasma."
icon_state = "soapnt"
+/obj/item/weapon/soap/homemade
+ desc = "A homemade bar of soap. Smells of... well...."
+ icon_state = "soapgibs"
+ cleanspeed = 45 // a little faster to reward chemists for going to the effort
+
+/obj/item/weapon/soap/ducttape
+ desc = "A homemade bar of soap. It seems to be gibs and tape..Will this clean anything?"
+ icon_state = "soapgibs"
+
+/obj/item/weapon/soap/ducttape/afterattack(atom/target, mob/user as mob, proximity)
+ if(!proximity) return
+
+ if(user.client && (target in user.client.screen))
+ user << "You need to take that [target.name] off before 'cleaning' it."
+ else
+ user.visible_message("[user] begins to smear [src] on \the [target.name].")
+ if(do_after(user, src.cleanspeed, target = target))
+ user << "You 'clean' \the [target.name]."
+ if(istype(target, /turf/simulated))
+ new /obj/effect/decal/cleanable/blood/gibs/cleangibs(target)
+ else if (istype(target,/mob/living/carbon))
+ for(var/obj/item/carried_item in target.contents)
+ if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant.
+ carried_item.add_blood(target)//Oh yes, there will be blood...
+ var/mob/living/carbon/human/H = target
+ H.bloody_hands(target,0)
+ H.bloody_body(target)
+
+ return
+
/obj/item/weapon/soap/deluxe
desc = "A deluxe Waffle Co. brand bar of soap. Smells of comdoms."
icon_state = "soapdeluxe"
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 33f79cd8fe2..fa0a59010d4 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -177,4 +177,19 @@
/obj/item/weaponcrafting/stock = 1,
/obj/item/stack/packageWrap = 5,)
tools = list(/obj/item/weapon/screwdriver)
- time = 200
\ No newline at end of file
+ time = 200
+
+/datum/table_recipe/spooky_camera
+ name = "Camera Obscura"
+ result = /obj/item/device/camera/spooky
+ time = 15
+ reqs = list(/obj/item/device/camera = 1,
+ /datum/reagent/holywater = 10)
+ parts = list(/obj/item/device/camera = 1)
+
+/datum/table_recipe/notreallysoap
+ name = "Homemade Soap"
+ result = /obj/item/weapon/soap/ducttape
+ time = 100
+ reqs = list(/obj/item/stack/tape_roll = 1,
+ /datum/reagent/liquidgibs = 10)
\ No newline at end of file
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 0ac35dd1455..1c3ea26b911 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -150,6 +150,24 @@
var/icon_on = "camera"
var/icon_off = "camera_off"
var/size = 3
+ var/see_ghosts = 0 //for the spoop of it
+
+
+/obj/item/device/camera/spooky/CheckParts()
+ var/obj/item/device/camera/C = locate(/obj/item/device/camera) in contents
+ if(C)
+ pictures_max = C.pictures_max
+ pictures_left = C.pictures_left
+ visible_message("[C] has been imbued with godlike power!")
+ qdel(C)
+
+
+var/list/SpookyGhosts = list("ghost","shade","shade2","ghost-narsie","horror","shadow","ghostian2")
+
+/obj/item/device/camera/spooky
+ name = "camera obscura"
+ desc = "A polaroid camera, some say it can see ghosts!"
+ see_ghosts = 1
/obj/item/device/camera/verb/change_size()
set name = "Set Photo Focus"
@@ -184,7 +202,7 @@
..()
-/obj/item/device/camera/proc/get_icon(list/turfs, turf/center)
+/obj/item/device/camera/proc/get_icon(list/turfs, turf/center,mob/user)
//Bigger icon base to capture those icons that were shifted to the next tile
//i.e. pretty much all wall-mounted machinery
@@ -199,8 +217,20 @@
atoms.Add(the_turf);
// As well as anything that isn't invisible.
for(var/atom/A in the_turf)
- if(A.invisibility) continue
- atoms.Add(A)
+ if(A.invisibility )
+ if(see_ghosts && istype(A,/mob/dead/observer))
+ var/mob/dead/observer/O = A
+ if(O.following)
+ continue
+ if(user.mind && !(user.mind.assigned_role == "Chaplain"))
+ atoms.Add(image('icons/mob/mob.dmi', O.loc, pick(SpookyGhosts), 4, SOUTH))
+ else
+ atoms.Add(image('icons/mob/mob.dmi', O.loc, "ghost", 4, SOUTH))
+ else//its not a ghost
+ continue
+ else//not invisable, not a spookyghost add it.
+ atoms.Add(A)
+
// Sort the atoms into their layers
var/list/sorted = sort_atoms_by_layer(atoms)
@@ -235,21 +265,35 @@
/obj/item/device/camera/proc/get_mobs(turf/the_turf as turf)
var/mob_detail
- for(var/mob/living/carbon/A in the_turf)
- if(A.invisibility) continue
- var/holding = null
- if(A.l_hand || A.r_hand)
- if(A.l_hand) holding = "They are holding \a [A.l_hand]"
- if(A.r_hand)
- if(holding)
- holding += " and \a [A.r_hand]"
+ for(var/mob/M in the_turf)
+ if(M.invisibility)
+ if(see_ghosts && istype(M,/mob/dead/observer))
+ var/mob/dead/observer/O = M
+ if(O.following)
+ continue
+ if(!mob_detail)
+ mob_detail = "You can see a g-g-g-g-ghooooost! "
else
- holding = "They are holding \a [A.r_hand]"
+ mob_detail += "You can also see a g-g-g-g-ghooooost!"
+ else
+ continue
- if(!mob_detail)
- mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
- else
- mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
+ var/holding = null
+
+ if(istype(M, /mob/living/carbon))
+ var/mob/living/carbon/A = M
+ if(A.l_hand || A.r_hand)
+ if(A.l_hand) holding = "They are holding \a [A.l_hand]"
+ if(A.r_hand)
+ if(holding)
+ holding += " and \a [A.r_hand]"
+ else
+ holding = "They are holding \a [A.r_hand]"
+
+ if(!mob_detail)
+ mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
+ else
+ mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
return mob_detail
/obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
@@ -263,6 +307,9 @@
user << "[pictures_left] photos left."
icon_state = icon_off
on = 0
+ if(user.mind && !(user.mind.assigned_role == "Chaplain"))
+ if(prob(24))
+ handle_haunt(user)
spawn(64)
icon_state = icon_on
on = 1
@@ -298,7 +345,7 @@
printpicture(user, P)
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
- var/icon/photoimage = get_icon(turfs, target)
+ var/icon/photoimage = get_icon(turfs, target,user)
var/icon/small_img = icon(photoimage)
var/icon/tiny_img = icon(photoimage)
@@ -483,3 +530,15 @@
talk_into(M, msg)
for(var/mob/living/carbon/human/H in watcherslist)
H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1)
+
+
+
+///hauntings, like hallucinations but more spooky
+
+/obj/item/device/camera/proc/handle_haunt(mob/user as mob)
+ var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\
+ 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
+ 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
+ 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
+ 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
+ user << pick(creepyasssounds)
diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/newchem/medicine.dm
index 9905345926b..764a5407776 100644
--- a/code/modules/reagents/newchem/medicine.dm
+++ b/code/modules/reagents/newchem/medicine.dm
@@ -96,7 +96,7 @@ datum/reagent/synthflesh/reaction_mob(var/mob/living/M, var/method=TOUCH, var/vo
datum/reagent/synthflesh/reaction_turf(var/turf/T, var/volume) //let's make a mess!
src = null
if(volume >= 5)
- new /obj/effect/decal/cleanable/blood/gibs(T)
+ new /obj/effect/decal/cleanable/blood/gibs/cleangibs(T)
playsound(T, 'sound/effects/splat.ogg', 50, 1, -3)
return
diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/newchem/other.dm
index 7e1e9899993..fa33c4fbf8e 100644
--- a/code/modules/reagents/newchem/other.dm
+++ b/code/modules/reagents/newchem/other.dm
@@ -305,6 +305,53 @@ datum/reagent/fartonium/on_mob_life(var/mob/living/M as mob)
return
+/datum/chemical_reaction/soapification
+ name = "Soapification"
+ id = "soapification"
+ result = null
+ required_reagents = list("liquidgibs" = 10, "lye" = 10) // requires two scooped gib tiles
+ min_temp = 374
+ result_amount = 1
+
+
+/datum/chemical_reaction/soapification/on_reaction(datum/reagents/holder, created_volume)
+ var/location = get_turf(holder.my_atom)
+ new /obj/item/weapon/soap/homemade(location)
+ return
+
+/datum/chemical_reaction/candlefication
+ name = "Candlefication"
+ id = "candlefication"
+ result = null
+ required_reagents = list("liquidgibs" = 5, "oxygen" = 5) //
+ min_temp = 374
+ result_amount = 1
+
+/datum/chemical_reaction/candlefication/on_reaction(datum/reagents/holder, created_volume)
+ var/location = get_turf(holder.my_atom)
+ new /obj/item/candle(location)
+ return
+
+
+/datum/chemical_reaction/meatification
+ name = "Meatification"
+ id = "meatification"
+ result = null
+ required_reagents = list("liquidgibs" = 10, "nutriment" = 10, "carbon" = 10)
+ result_amount = 1
+
+/datum/chemical_reaction/meatification/on_reaction(datum/reagents/holder, created_volume)
+ var/location = get_turf(holder.my_atom)
+ new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/meatproduct(location)
+ return
+
+/datum/chemical_reaction/lye
+ name = "lye"
+ id = "lye"
+ result = "lye"
+ required_reagents = list("sodium" = 1, "hydrogen" = 1, "oxygen" = 1)
+ result_amount = 3
+
///Alchemical Reagents
datum/reagent/eyenewt
diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/oldchem/reagents/reagents_water.dm
index 5377ec3f56c..1db18dd1d41 100644
--- a/code/modules/reagents/oldchem/reagents/reagents_water.dm
+++ b/code/modules/reagents/oldchem/reagents/reagents_water.dm
@@ -326,6 +326,30 @@
qdel(R)
T.Bless()
+
+/datum/reagent/liquidgibs
+ name = "Liquid gibs"
+ id = "liquidgibs"
+ color = "#FF9966"
+ description = "You don't even want to think about what's in here."
+ reagent_state = LIQUID
+
+/datum/reagent/liquidgibs/reaction_turf(var/turf/T, var/volume) //yes i took it from synthflesh...
+ src = null
+ if(volume >= 5)
+ new /obj/effect/decal/cleanable/blood/gibs/cleangibs(T)
+ playsound(T, 'sound/effects/splat.ogg', 50, 1, -3)
+ return
+
+
+
+/datum/reagent/lye
+ name = "Lye"
+ id = "lye"
+ description = "Also known as sodium hydroxide."
+ reagent_state = LIQUID
+ color = "#FFFFD6" // very very light yellow
+
/*
/datum/reagent/vaccine
//data must contain virus type
diff --git a/code/modules/reagents/reagent_containers/food/snacks/meat.dm b/code/modules/reagents/reagent_containers/food/snacks/meat.dm
index e22613e12d1..8c1e8544014 100644
--- a/code/modules/reagents/reagent_containers/food/snacks/meat.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks/meat.dm
@@ -33,6 +33,9 @@
var/subjectname = ""
var/subjectjob = null
+/obj/item/weapon/reagent_containers/food/snacks/meat/slab/meatproduct
+ name = "meat product"
+ desc = "A slab of station reclaimed and chemically processed meat product."
/obj/item/weapon/reagent_containers/food/snacks/meat/monkey
//same as plain meat
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index 7b1c38e4bef..6a9fcd3ffad 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -953,3 +953,41 @@ var/list/compatible_mobs = list(/mob/living/carbon/human)
stage = 1
activate(var/mob/living/carbon/mob,var/multiplier)
mob << " You feel optimistic!"
+
+/datum/disease2/effect/anxiety
+ name = "Severe Anxiety"
+ stage = 2
+ activate(var/mob/living/carbon/mob,var/multiplier)
+ if(prob(20))
+ mob << "You feel anxious."
+ if(prob(15))
+ mob << "You feel butterflies in your stomach."
+ if(prob(11))
+ mob.visible_message("[mob] stumbles around in a panic.", \
+ "You have a panic attack!")
+ mob.confused += (rand(6,8))
+ mob.jitteriness += (rand(6,8))
+ if(prob(10))
+ mob.visible_message("[mob] coughs up butterflies!", \
+ "You cough up butterflies!")
+ new /mob/living/simple_animal/butterfly(mob.loc)
+ new /mob/living/simple_animal/butterfly(mob.loc)
+
+/datum/disease2/effect/lycan
+ name = "Lycancoughy"
+ stage = 3
+ activate(var/mob/living/carbon/mob,var/multiplier)
+ if(prob(20))
+ mob << "You feel itchy."
+ if(prob(15))
+ mob << "You have the sudden urge for bacon.."
+ if(prob(11))
+ mob.say(pick("WOOF!", "BARK!", "Bark.", "Woof?", "AUUUUUUUUUUUUU!!"))
+ if(prob(10))
+ mob.visible_message("[mob] coughs up a dog!!", \
+ "You cough up a DOG!!!")
+ //yes i KNOW foxes technically are not normal dogs...hush....
+ var/randompup = pick(/mob/living/simple_animal/pet/corgi/puppy,/mob/living/simple_animal/pet/pug,/mob/living/simple_animal/pet/fox)
+
+ new randompup(mob.loc)
+ mob.adjustBruteLoss(rand(1,5))//you just coughed up a CANINIE, you are taking brute loss...
\ No newline at end of file
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index b7e86115e39..0aab96a6719 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index ebf42b90da2..9130736fbc2 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ