Fixes "Write in Blood" (#29676)

* write in blood

* BLUD

* oh ok

* so how are you doing, it's 2 am over here

* noalpha
This commit is contained in:
DeityLink
2021-06-04 02:05:45 +02:00
committed by GitHub
parent 8eca5864e7
commit 8413351078
12 changed files with 181 additions and 138 deletions

View File

@@ -93,25 +93,17 @@ var/global/list/blood_list = list()
base_icon = 'icons/effects/drip.dmi' base_icon = 'icons/effects/drip.dmi'
/obj/effect/decal/cleanable/blood/writing /obj/effect/decal/cleanable/blood/writing
icon_state = "tracks" name = "bloody writings"
desc = "It looks like a writing in blood." desc = "It looks like a writing in blood."
gender = NEUTER gender = NEUTER
random_icon_states = list("writing1","writing2","writing3","writing4","writing5") icon = 'icons/effects/effects.dmi'
icon_state = ""
amount = 0 amount = 0
var/message maptext_height = 32
maptext_width = 64
maptext_x = -16
maptext_y = -2
/obj/effect/decal/cleanable/blood/writing/New()
..()
if(random_icon_states.len)
for(var/obj/effect/decal/cleanable/blood/writing/W in loc)
random_icon_states.Remove(W.icon_state)
icon_state = pick(random_icon_states)
else
icon_state = "writing1"
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
..()
to_chat(user, "It reads: <font color='[basecolor]'>\"[message]\"<font>")
/obj/effect/decal/cleanable/blood/gibs /obj/effect/decal/cleanable/blood/gibs
name = "gibs" name = "gibs"

View File

@@ -45,6 +45,7 @@
//It is populated every time we use AddTracks(). //It is populated every time we use AddTracks().
var/list/steps_to_remake = list() var/list/steps_to_remake = list()
var/last_blood_color = DEFAULT_BLOOD //when ghost use those tracks to write, they'll use the most recent blood color added
var/list/setdirs=list( var/list/setdirs=list(
"1"=0, "1"=0,
@@ -91,6 +92,7 @@
if (!counts_as_blood) if (!counts_as_blood)
if (DNA && DNA.len > 0) if (DNA && DNA.len > 0)
counts_as_blood = 1 counts_as_blood = 1
last_blood_color = bloodcolor
bloodspill_add() bloodspill_add()
var/updated=0 var/updated=0

View File

@@ -175,33 +175,6 @@ var/list/infected_cleanables = list()
if(amount > 0) if(amount > 0)
add_blood_to(perp, amount) add_blood_to(perp, amount)
//With "mouse_opacity = 0", this kinda makes no sense.
//And also, the bloody hands thing does not work properly.
//
//obj/effect/decal/cleanable/attack_hand(mob/living/carbon/human/user)
// ..()
// if (amount && istype(user))
// add_fingerprint(user)
// if (user.gloves)
// return
// var/taken = rand(1,amount)
// amount -= taken
// to_chat(user, "<span class='notice'>You get some of \the [src] on your hands.</span>")
//
// user.bloody_hands(src, taken)
// user.hand_blood_color = basecolor
// user.update_inv_gloves(1)
// if(transfers_dna)
// if (!user.blood_DNA)
// user.blood_DNA = list()
// user.blood_DNA |= blood_DNA.Copy()
// user.add_blood()
// user.bloody_hands += taken
// user.hand_blood_color = basecolor
// user.update_inv_gloves(1)
// user.verbs += /mob/living/carbon/human/proc/bloody_doodle
//
/obj/effect/decal/cleanable/proc/messcheck(var/obj/effect/decal/cleanable/M) /obj/effect/decal/cleanable/proc/messcheck(var/obj/effect/decal/cleanable/M)
return 1 return 1

View File

@@ -347,6 +347,9 @@
var/attack_verb_override = "punches" var/attack_verb_override = "punches"
var/transfer_blood = 0
var/list/bloody_hands_data = list()
/obj/item/clothing/gloves/get_cell() /obj/item/clothing/gloves/get_cell()
return cell return cell

View File

@@ -8,9 +8,11 @@ atom/proc/add_fibers(mob/living/carbon/human/M)
if(G.transfer_blood) //bloodied gloves transfer blood to touched objects if(G.transfer_blood) //bloodied gloves transfer blood to touched objects
if(add_blood_from_data(G.bloody_hands_data)) //only reduces the bloodiness of our gloves if the item wasn't already bloody if(add_blood_from_data(G.bloody_hands_data)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
G.transfer_blood-- G.transfer_blood--
M.update_inv_gloves()
else if(M.bloody_hands) else if(M.bloody_hands)
if(add_blood_from_data(M.bloody_hands_data)) if(add_blood_from_data(M.bloody_hands_data))
M.bloody_hands-- M.bloody_hands--
M.update_inv_gloves()
if(!suit_fibers) if(!suit_fibers)
suit_fibers = list() suit_fibers = list()
var/fibertext var/fibertext

View File

@@ -6,10 +6,6 @@
var/feet_blood_color var/feet_blood_color
var/track_blood_type var/track_blood_type
/obj/item/clothing/gloves
var/transfer_blood = 0
var/list/bloody_hands_data = list()
/obj/item/clothing/shoes /obj/item/clothing/shoes
var/track_blood = 0 var/track_blood = 0

View File

@@ -287,71 +287,109 @@
set name = "Write in blood" set name = "Write in blood"
set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC." set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC."
//Some basic checks first
if(!(config.cult_ghostwriter)) if(!(config.cult_ghostwriter))
to_chat(src, "<span class='warning'>That verb is not currently permitted.</span>") to_chat(src, "<span class='warning'>That verb is not currently permitted.</span>")
return return
if (!src.stat) var/ghosts_can_write = FALSE
return //legacy cult
if (usr != src)
return 0 //something is terribly wrong
var/ghosts_can_write
var/datum/faction/cult/narsie/C = find_active_faction_by_type(/datum/faction/cult/narsie) var/datum/faction/cult/narsie/C = find_active_faction_by_type(/datum/faction/cult/narsie)
if(C && C.members.len > config.cult_ghostwriter_req_cultists) if(C && C.members.len > config.cult_ghostwriter_req_cultists)
ghosts_can_write = 1 ghosts_can_write = TRUE
//new cult
if (veil_thickness >= CULT_ACT_III) if (veil_thickness >= CULT_ACT_III)
ghosts_can_write = 1 ghosts_can_write = TRUE
if (invisibility == 0)
ghosts_can_write = TRUE
if(!ghosts_can_write) if(!ghosts_can_write)
to_chat(src, "<span class='warning'>The veil is not thin enough for you to do that.</span>") to_chat(src, "<span class='warning'>The veil is not thin enough for you to do that.</span>")
return return
var/turf/T = get_turf(src)
if (!isfloor(T))
to_chat(src, "<span class='warning'>You can only doodle over floors.</span>")
return
for (var/obj/effect/decal/cleanable/blood/writing/W in T)
to_chat(src, "<span class='warning'>This floor is already filled with writings.</span>")
return
//Ok the place is clear, now we need some blood
var/list/choices = list() var/list/choices = list()
for(var/obj/effect/decal/cleanable/blood/B in view(1,src)) var/i = 1
if(B.amount > 0) for(var/obj/effect/decal/cleanable/blood/B in range(1,T))
choices += B if(B.counts_as_blood)
if (istype(B,/obj/effect/decal/cleanable/blood/tracks))
var/obj/effect/decal/cleanable/blood/tracks/tracks = B
choices["[i] - [B] (color = [tracks.last_blood_color])"] = B
else
choices["[i] - [B] (color = [B.basecolor])"] = B
i++
if(!choices.len) if(!choices.len)
to_chat(src, "<span class = 'warning'>There is no blood to use nearby.</span>") to_chat(src, "<span class = 'warning'>There is no blood to use nearby.</span>")
return return
var/obj/effect/decal/cleanable/blood/choice = input(src,"What blood would you like to use?") in null|choices var/choice = input(src,"What blood would you like to use?") in null|choices
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
var/turf/simulated/T = src.loc
if (direction != "Here")
T = get_step(T,text2dir(direction))
if (!istype(T)) if(!choice || !Adjacent(T))
to_chat(src, "<span class='warning'>You cannot doodle there.</span>")
return return
if(!choice || choice.amount == 0 || !(src.Adjacent(choice))) var/obj/effect/decal/cleanable/blood/blood_source = choices[choice]
if(!blood_source)
return return
var/doodle_color = (choice.basecolor) ? choice.basecolor : DEFAULT_BLOOD var/doodle_color = (blood_source.basecolor) ? blood_source.basecolor : DEFAULT_BLOOD
var/num_doodles = 0 if (istype(blood_source,/obj/effect/decal/cleanable/blood/tracks))
for (var/obj/effect/decal/cleanable/blood/writing/W in T) var/obj/effect/decal/cleanable/blood/tracks/tracks = blood_source
num_doodles++ doodle_color = tracks.last_blood_color
if (num_doodles > 4)
to_chat(src, "<span class='warning'>There is no space to write on!</span>") //Blood found, now to write a message
var/max_length = 30
var/message = stripped_input(src,"Write a message. You will be able to preview it.","Bloody writings", "")
if (!message)
return return
var/max_length = 50 message = copytext(message, 1, max_length)
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
if (message) var/letter_amount = length(replacetext(message, " ", ""))
if (length(message) > max_length) if(!letter_amount) //If there is no text
message += "-" return
to_chat(src, "<span class='warning'>You ran out of blood to write with!</span>")
var/obj/effect/decal/cleanable/blood/writing/W = new /obj/effect/decal/cleanable/blood/writing(T) //Previewing our message
W.basecolor = doodle_color var/image/I = image(icon = null)
W.update_icon() I.maptext = {"<span style="color:[doodle_color];font-size:9pt;font-family:'Ink Free';" align="center" valign="top">[message]</span>"}
W.message = message I.maptext_height = 32
W.add_hiddenprint(src) I.maptext_width = 64
W.visible_message("<span class='warning'>Invisible fingers crudely paint something in blood on [T]...</span>") I.maptext_x = -16
I.maptext_y = -2
I.loc = T
I.alpha = 180
client.images.Add(I)
var/continue_drawing = alert(src, "This is how your message will look. Continue?", "Bloody writings", "Yes", "Cancel")
client.images.Remove(I)
animate(I) //Cancel the animation so that the image gets garbage collected
I.loc = null
qdel(I)
if(continue_drawing != "Yes" || !Adjacent(T) || !blood_source)
return
//Finally writing our message
var/obj/effect/decal/cleanable/blood/writing/W = new /obj/effect/decal/cleanable/blood/writing(T)
W.basecolor = doodle_color
W.maptext = {"<span style="color:[doodle_color];font-size:9pt;font-family:'Ink Free';" align="center" valign="top">[message]</span>"}
W.add_hiddenprint(src)
W.visible_message("<span class='warning'>Invisible fingers crudely paint something in blood on \the [T]...</span>")
if(istype(blood_source.blood_DNA,/list))
W.blood_DNA |= blood_source.blood_DNA.Copy()
/mob/dead/observer/verb/hide_ghosts() /mob/dead/observer/verb/hide_ghosts()
set name = "Hide Ghosts" set name = "Hide Ghosts"

View File

@@ -996,7 +996,6 @@
return FALSE //already bloodied with this blood. Cannot add more. return FALSE //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
update_inv_gloves() //handles bloody hands overlays and updating update_inv_gloves() //handles bloody hands overlays and updating
verbs += /mob/living/carbon/human/proc/bloody_doodle
return 1 //we applied blood to the item return 1 //we applied blood to the item
/mob/living/carbon/human/add_blood_from_data(var/list/blood_data) /mob/living/carbon/human/add_blood_from_data(var/list/blood_data)
@@ -1012,7 +1011,6 @@
return FALSE //already bloodied with this blood. Cannot add more. return FALSE //already bloodied with this blood. Cannot add more.
blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"] blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"]
update_inv_gloves() //handles bloody hands overlays and updating update_inv_gloves() //handles bloody hands overlays and updating
verbs += /mob/living/carbon/human/proc/bloody_doodle
return TRUE //we applied blood to the item return TRUE //we applied blood to the item
/mob/living/carbon/human/clean_blood(var/clean_feet) /mob/living/carbon/human/clean_blood(var/clean_feet)
@@ -1244,63 +1242,95 @@
to_chat(src, "<span class = 'notice'>[species.species_intro]</span>") to_chat(src, "<span class = 'notice'>[species.species_intro]</span>")
return 1 return 1
/mob/living/carbon/human/proc/bloody_doodle() /mob/living/carbon/human/verb/bloody_doodle()
set category = "IC" set category = "IC"
set name = "Write in blood" set name = "Write in blood"
set desc = "Use blood on your hands to write a short message on the floor or a wall, murder mystery style." set desc = "Use blood on your hands to write a short message on the floor, murder mystery style."
if (src.stat) if (incapacitated() || isUnconscious())
return return
if (!(bloody_hands_data?.len)) var/turf/T = get_turf(src)
if (!isfloor(T))
to_chat(src, "<span class='warning'>You can only doodle over floors.</span>")
return return
if (usr != src)
return 0 //something is terribly wrong
if (!bloody_hands)
verbs -= /mob/living/carbon/human/proc/bloody_doodle
if (src.gloves)
to_chat(src, "<span class='warning'>Your [src.gloves] are getting in the way.</span>")
return
var/turf/simulated/T = src.loc
if (!istype(T)) //to prevent doodling out of mechs and lockers
to_chat(src, "<span class='warning'>You cannot reach the floor.</span>")
return
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
if (direction != "Here")
T = get_step(T,text2dir(direction))
if (!istype(T))
to_chat(src, "<span class='warning'>You cannot doodle there.</span>")
return
var/num_doodles = 0
for (var/obj/effect/decal/cleanable/blood/writing/W in T) for (var/obj/effect/decal/cleanable/blood/writing/W in T)
num_doodles++ to_chat(src, "<span class='warning'>This floor is already filled with writings.</span>")
if (num_doodles > 4)
to_chat(src, "<span class='warning'>There is no space to write on!</span>")
return return
var/max_length = bloody_hands * 30 //tweeter style var/doodle_color
var/doodle_DNA
var/doodle_type
var/obj/item/clothing/gloves/actual_gloves
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "") if (istype(gloves, /obj/item/clothing/gloves))
actual_gloves = gloves
if(actual_gloves.transfer_blood > 0 && actual_gloves.blood_DNA?.len)
doodle_DNA = pick(actual_gloves.blood_DNA)
doodle_type = actual_gloves.blood_DNA[doodle_DNA]
doodle_color = actual_gloves.blood_color
if (message) if(!actual_gloves && bloody_hands > 0 && bloody_hands_data?.len)
var/used_blood_amount = round(length(message) / 30, 1) doodle_DNA = bloody_hands_data["blood_DNA"]
bloody_hands = max(0, bloody_hands - used_blood_amount) //use up some blood doodle_type = bloody_hands_data["blood_type"]
doodle_color = bloody_hands_data["blood_colour"]
if (!doodle_color)
to_chat(src, "<span class='warning'>There is no blood on your hands or gloves.</span>")
return
//Blood found, now to write a message
var/max_length = 30
var/message = stripped_input(src,"Write a message. You will be able to preview it.","Bloody writings", "")
if (!message)
return
message = copytext(message, 1, max_length)
var/letter_amount = length(replacetext(message, " ", ""))
if(!letter_amount) //If there is no text
return
//Previewing our message
var/image/I = image(icon = null)
I.maptext = {"<span style="color:[doodle_color];font-size:9pt;font-family:'Ink Free';" align="center" valign="top">[message]</span>"}
I.maptext_height = 32
I.maptext_width = 64
I.maptext_x = -16
I.maptext_y = -2
I.loc = T
I.alpha = 180
client.images.Add(I)
var/continue_drawing = alert(src, "This is how your message will look. Continue?", "Bloody writings", "Yes", "Cancel")
client.images.Remove(I)
animate(I) //Cancel the animation so that the image gets garbage collected
I.loc = null
qdel(I)
if(continue_drawing != "Yes" || !Adjacent(T))
return
//Finally writing our message
var/obj/effect/decal/cleanable/blood/writing/W = new /obj/effect/decal/cleanable/blood/writing(T)
W.basecolor = doodle_color
W.maptext = {"<span style="color:[doodle_color];font-size:9pt;font-family:'Ink Free';" align="center" valign="top">[message]</span>"}
W.add_fingerprint(src)
var/invisible = invisibility || !alpha
W.visible_message("<span class='warning'>[invisible ? "Invisible fingers" : "\The [src]"] crudely paint[invisible ? "" : "s"] something in blood on \the [T]...</span>")
W.blood_DNA[doodle_DNA] = doodle_type
if (actual_gloves)
actual_gloves.transfer_blood = max(0,actual_gloves.transfer_blood - 1)
else
bloody_hands = max(0,bloody_hands - 1)
update_inv_gloves()
if (length(message) > max_length)
message += "-"
to_chat(src, "<span class='warning'>You ran out of blood to write with!</span>")
var/obj/effect/decal/cleanable/blood/writing/W = new /obj/effect/decal/cleanable/blood/writing(T)
W.basecolor = (bloody_hands_data["blood_colour"]) ? bloody_hands_data["blood_colour"] : DEFAULT_BLOOD
W.update_icon()
W.message = message
W.add_fingerprint(src)
/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) /mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone)
. = 1 . = 1
if(!user) if(!user)

View File

@@ -263,7 +263,12 @@
return M.grab_mob(src) return M.grab_mob(src)
if(I_HURT) if(I_HURT)
return M.unarmed_attack_mob(src) var/punch_damage = M.unarmed_attack_mob(src)
if (punch_damage)
var/punch_zone = get_part_from_limb(M.zone_sel.selecting)
if (check_bodypart_bleeding(punch_zone))
M.bloody_hands(src,1)
return punch_damage
if(I_DISARM) if(I_DISARM)
return M.disarm_mob(src) return M.disarm_mob(src)

View File

@@ -699,11 +699,13 @@ var/global/list/damage_icon_parts = list()
var/image/dyn_overlay = gloves.dynamic_overlay["[GLOVES_LAYER]"] var/image/dyn_overlay = gloves.dynamic_overlay["[GLOVES_LAYER]"]
O.overlays += dyn_overlay O.overlays += dyn_overlay
if(gloves.blood_DNA && gloves.blood_DNA.len) if (istype(gloves, /obj/item/clothing/gloves))
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands") var/obj/item/clothing/gloves/actual_gloves = gloves
bloodsies.color = gloves.blood_color if(actual_gloves.transfer_blood > 0 && actual_gloves.blood_DNA?.len)
standing.overlays += bloodsies var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
O.overlays += bloodsies bloodsies.color = actual_gloves.blood_color
standing.overlays += bloodsies
O.overlays += bloodsies
gloves.screen_loc = ui_gloves gloves.screen_loc = ui_gloves
gloves.generate_accessory_overlays(O) gloves.generate_accessory_overlays(O)
@@ -716,7 +718,7 @@ var/global/list/damage_icon_parts = list()
O.pixel_y = species.inventory_offsets["[slot_gloves]"]["pixel_y"] * PIXEL_MULTIPLIER O.pixel_y = species.inventory_offsets["[slot_gloves]"]["pixel_y"] * PIXEL_MULTIPLIER
obj_to_plane_overlay(O,GLOVES_LAYER) obj_to_plane_overlay(O,GLOVES_LAYER)
else else
if(blood_DNA?.len && bloody_hands_data?.len) if(bloody_hands > 0 && bloody_hands_data?.len)
O.icon = 'icons/effects/blood.dmi' O.icon = 'icons/effects/blood.dmi'
O.icon_state = "bloodyhands" O.icon_state = "bloodyhands"
O.color = bloody_hands_data["blood_colour"] O.color = bloody_hands_data["blood_colour"]

View File

@@ -46,7 +46,7 @@
affected.wounds -= W affected.wounds -= W
affected.update_damages() affected.update_damages()
if (ishuman(user) && prob(40)) if (ishuman(user) && prob(40))
user:bloody_hands(target, 0) user:bloody_hands(target, 1)
/datum/surgery_step/fix_vein/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) /datum/surgery_step/fix_vein/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone) var/datum/organ/external/affected = target.get_organ(target_zone)

View File

@@ -71,7 +71,7 @@
if (ishuman(user) && prob(60)) if (ishuman(user) && prob(60))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if (blood_level) if (blood_level)
H.bloody_hands(target,0)//potentially spreads diseases from them to us, wear latex gloves! H.bloody_hands(target,1)//potentially spreads diseases from them to us, wear latex gloves!
if (blood_level > 1) if (blood_level > 1)
H.bloody_body(target,0)//potentially spreads diseases from them to us, wear a bio suit, or at least a labcoat! H.bloody_body(target,0)//potentially spreads diseases from them to us, wear a bio suit, or at least a labcoat!