mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
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:
@@ -93,25 +93,17 @@ var/global/list/blood_list = list()
|
||||
base_icon = 'icons/effects/drip.dmi'
|
||||
|
||||
/obj/effect/decal/cleanable/blood/writing
|
||||
icon_state = "tracks"
|
||||
name = "bloody writings"
|
||||
desc = "It looks like a writing in blood."
|
||||
gender = NEUTER
|
||||
random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = ""
|
||||
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
|
||||
name = "gibs"
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
//It is populated every time we use AddTracks().
|
||||
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(
|
||||
"1"=0,
|
||||
@@ -91,6 +92,7 @@
|
||||
if (!counts_as_blood)
|
||||
if (DNA && DNA.len > 0)
|
||||
counts_as_blood = 1
|
||||
last_blood_color = bloodcolor
|
||||
bloodspill_add()
|
||||
|
||||
var/updated=0
|
||||
|
||||
@@ -175,33 +175,6 @@ var/list/infected_cleanables = list()
|
||||
if(amount > 0)
|
||||
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)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -347,6 +347,9 @@
|
||||
|
||||
var/attack_verb_override = "punches"
|
||||
|
||||
var/transfer_blood = 0
|
||||
var/list/bloody_hands_data = list()
|
||||
|
||||
/obj/item/clothing/gloves/get_cell()
|
||||
return cell
|
||||
|
||||
|
||||
@@ -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(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--
|
||||
M.update_inv_gloves()
|
||||
else if(M.bloody_hands)
|
||||
if(add_blood_from_data(M.bloody_hands_data))
|
||||
M.bloody_hands--
|
||||
M.update_inv_gloves()
|
||||
if(!suit_fibers)
|
||||
suit_fibers = list()
|
||||
var/fibertext
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
var/feet_blood_color
|
||||
var/track_blood_type
|
||||
|
||||
/obj/item/clothing/gloves
|
||||
var/transfer_blood = 0
|
||||
var/list/bloody_hands_data = list()
|
||||
|
||||
/obj/item/clothing/shoes
|
||||
var/track_blood = 0
|
||||
|
||||
|
||||
@@ -287,71 +287,109 @@
|
||||
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."
|
||||
|
||||
//Some basic checks first
|
||||
if(!(config.cult_ghostwriter))
|
||||
to_chat(src, "<span class='warning'>That verb is not currently permitted.</span>")
|
||||
return
|
||||
|
||||
if (!src.stat)
|
||||
return
|
||||
|
||||
if (usr != src)
|
||||
return 0 //something is terribly wrong
|
||||
|
||||
var/ghosts_can_write
|
||||
var/ghosts_can_write = FALSE
|
||||
//legacy cult
|
||||
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)
|
||||
ghosts_can_write = 1
|
||||
ghosts_can_write = TRUE
|
||||
|
||||
//new cult
|
||||
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)
|
||||
to_chat(src, "<span class='warning'>The veil is not thin enough for you to do that.</span>")
|
||||
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()
|
||||
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
|
||||
if(B.amount > 0)
|
||||
choices += B
|
||||
var/i = 1
|
||||
for(var/obj/effect/decal/cleanable/blood/B in range(1,T))
|
||||
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)
|
||||
to_chat(src, "<span class = 'warning'>There is no blood to use nearby.</span>")
|
||||
return
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/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))
|
||||
var/choice = input(src,"What blood would you like to use?") in null|choices
|
||||
|
||||
if (!istype(T))
|
||||
to_chat(src, "<span class='warning'>You cannot doodle there.</span>")
|
||||
if(!choice || !Adjacent(T))
|
||||
return
|
||||
|
||||
if(!choice || choice.amount == 0 || !(src.Adjacent(choice)))
|
||||
var/obj/effect/decal/cleanable/blood/blood_source = choices[choice]
|
||||
|
||||
if(!blood_source)
|
||||
return
|
||||
|
||||
var/doodle_color = (choice.basecolor) ? choice.basecolor : DEFAULT_BLOOD
|
||||
var/num_doodles = 0
|
||||
for (var/obj/effect/decal/cleanable/blood/writing/W in T)
|
||||
num_doodles++
|
||||
if (num_doodles > 4)
|
||||
to_chat(src, "<span class='warning'>There is no space to write on!</span>")
|
||||
var/doodle_color = (blood_source.basecolor) ? blood_source.basecolor : DEFAULT_BLOOD
|
||||
if (istype(blood_source,/obj/effect/decal/cleanable/blood/tracks))
|
||||
var/obj/effect/decal/cleanable/blood/tracks/tracks = blood_source
|
||||
doodle_color = tracks.last_blood_color
|
||||
|
||||
//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
|
||||
|
||||
var/max_length = 50
|
||||
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
|
||||
message = copytext(message, 1, max_length)
|
||||
|
||||
if (message)
|
||||
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 = doodle_color
|
||||
W.update_icon()
|
||||
W.message = message
|
||||
W.add_hiddenprint(src)
|
||||
W.visible_message("<span class='warning'>Invisible fingers crudely paint something in blood on [T]...</span>")
|
||||
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) || !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()
|
||||
set name = "Hide Ghosts"
|
||||
|
||||
@@ -996,7 +996,6 @@
|
||||
return FALSE //already bloodied with this blood. Cannot add more.
|
||||
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
|
||||
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
|
||||
|
||||
/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.
|
||||
blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"]
|
||||
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
|
||||
|
||||
/mob/living/carbon/human/clean_blood(var/clean_feet)
|
||||
@@ -1244,63 +1242,95 @@
|
||||
to_chat(src, "<span class = 'notice'>[species.species_intro]</span>")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/bloody_doodle()
|
||||
/mob/living/carbon/human/verb/bloody_doodle()
|
||||
set category = "IC"
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
num_doodles++
|
||||
if (num_doodles > 4)
|
||||
to_chat(src, "<span class='warning'>There is no space to write on!</span>")
|
||||
to_chat(src, "<span class='warning'>This floor is already filled with writings.</span>")
|
||||
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)
|
||||
var/used_blood_amount = round(length(message) / 30, 1)
|
||||
bloody_hands = max(0, bloody_hands - used_blood_amount) //use up some blood
|
||||
if(!actual_gloves && bloody_hands > 0 && bloody_hands_data?.len)
|
||||
doodle_DNA = bloody_hands_data["blood_DNA"]
|
||||
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)
|
||||
. = 1
|
||||
if(!user)
|
||||
|
||||
@@ -263,7 +263,12 @@
|
||||
return M.grab_mob(src)
|
||||
|
||||
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)
|
||||
return M.disarm_mob(src)
|
||||
|
||||
@@ -699,11 +699,13 @@ var/global/list/damage_icon_parts = list()
|
||||
var/image/dyn_overlay = gloves.dynamic_overlay["[GLOVES_LAYER]"]
|
||||
O.overlays += dyn_overlay
|
||||
|
||||
if(gloves.blood_DNA && gloves.blood_DNA.len)
|
||||
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
|
||||
bloodsies.color = gloves.blood_color
|
||||
standing.overlays += bloodsies
|
||||
O.overlays += bloodsies
|
||||
if (istype(gloves, /obj/item/clothing/gloves))
|
||||
var/obj/item/clothing/gloves/actual_gloves = gloves
|
||||
if(actual_gloves.transfer_blood > 0 && actual_gloves.blood_DNA?.len)
|
||||
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
|
||||
bloodsies.color = actual_gloves.blood_color
|
||||
standing.overlays += bloodsies
|
||||
O.overlays += bloodsies
|
||||
gloves.screen_loc = ui_gloves
|
||||
|
||||
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
|
||||
obj_to_plane_overlay(O,GLOVES_LAYER)
|
||||
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_state = "bloodyhands"
|
||||
O.color = bloody_hands_data["blood_colour"]
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
affected.wounds -= W
|
||||
affected.update_damages()
|
||||
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)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if (ishuman(user) && prob(60))
|
||||
var/mob/living/carbon/human/H = user
|
||||
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)
|
||||
H.bloody_body(target,0)//potentially spreads diseases from them to us, wear a bio suit, or at least a labcoat!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user