Files
Bubberstation/code/modules/paperwork/paper.dm
Joan Lung e83d72219d Soft crit, except not terrible (#30262)
* Soft crit, except a little bit harder.

* tweak

* 👌

* why was this even in here

* no radios in critical

* fix that too

* keep to original logic

* not very smart, really

* tip: do nothing tgui-side that you can do code-side, because we can't do defines in tgui

* blood trail

* can't do blood trails

* how does this even work

* harsher slowdown and more obscured vision

* it really puts it into perspective; you're fucking dying.

* stat_attack

* stop fuckin whispering into radios or whatever it is you're doing

* more fixes

* fix

* fix

* fix the radio shit

* bikeshed?
2017-09-04 18:58:34 -05:00

404 lines
12 KiB
Plaintext

/*
* Paper
* also scraps of paper
*
* lipstick wiping is in code/game/objects/items/weapons/cosmetics.dm!
*/
/obj/item/paper
name = "paper"
gender = NEUTER
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper"
item_state = "paper"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_range = 1
throw_speed = 1
pressure_resistance = 0
slot_flags = SLOT_HEAD
body_parts_covered = HEAD
resistance_flags = FLAMMABLE
max_integrity = 50
dog_fashion = /datum/dog_fashion/head
var/info //What's actually written on the paper.
var/info_links //A different version of the paper which includes html links at fields and EOF
var/stamps //The (text for the) stamps on the paper.
var/fields = 0 //Amount of user created fields
var/list/stamped
var/rigged = 0
var/spam_flag = 0
var/contact_poison // Reagent ID to transfer on contact
var/contact_poison_volume = 0
/obj/item/paper/pickup(user)
if(contact_poison && ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/gloves/G = H.gloves
if(!istype(G) || G.transfer_prints)
H.reagents.add_reagent(contact_poison,contact_poison_volume)
contact_poison = null
..()
/obj/item/paper/Initialize()
. = ..()
pixel_y = rand(-8, 8)
pixel_x = rand(-9, 9)
update_icon()
updateinfolinks()
/obj/item/paper/update_icon()
if(resistance_flags & ON_FIRE)
icon_state = "paper_onfire"
return
if(info)
icon_state = "paper_words"
return
icon_state = "paper"
/obj/item/paper/examine(mob/user)
..()
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
assets.send(user)
if(istype(src, /obj/item/paper/talisman)) //Talismans cannot be read
if(!iscultist(user) && !user.stat)
to_chat(user, "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>")
return
if(in_range(user, src) || isobserver(user))
if(user.is_literate())
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info]<HR>[stamps]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
to_chat(user, "<span class='notice'>It is too far away.</span>")
/obj/item/paper/verb/rename()
set name = "Rename paper"
set category = "Object"
set src in usr
if(usr.incapacitated() || !usr.is_literate())
return
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
if(H.disabilities & CLUMSY && prob(25))
to_chat(H, "<span class='warning'>You cut yourself on the paper! Ahhhh! Ahhhhh!</span>")
H.damageoverlaytemp = 9001
H.update_damage_hud()
return
var/n_name = stripped_input(usr, "What would you like to label the paper?", "Paper Labelling", null, MAX_NAME_LEN)
if((loc == usr && usr.stat == CONSCIOUS))
name = "paper[(n_name ? text("- '[n_name]'") : null)]"
add_fingerprint(usr)
/obj/item/paper/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...</span>")
return (BRUTELOSS)
/obj/item/paper/attack_self(mob/user)
user.examinate(src)
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
if(spam_flag == 0)
spam_flag = 1
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
spawn(20)
spam_flag = 0
/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
var/dist
if(istype(user) && user.current) //is AI
dist = get_dist(src, user.current)
else //cyborg or AI not seeing through a camera
dist = get_dist(src, user)
if(dist < 2)
usr << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info]<HR>[stamps]</BODY></HTML>", "window=[name]")
onclose(usr, "[name]")
else
usr << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>", "window=[name]")
onclose(usr, "[name]")
/obj/item/paper/proc/addtofield(id, text, links = 0)
var/locid = 0
var/laststart = 1
var/textindex = 1
while(1) //I know this can cause infinite loops and fuck up the whole server, but the if(istart==0) should be safe as fuck
var/istart = 0
if(links)
istart = findtext(info_links, "<span class=\"paper_field\">", laststart)
else
istart = findtext(info, "<span class=\"paper_field\">", laststart)
if(istart == 0)
return //No field found with matching id
laststart = istart+1
locid++
if(locid == id)
var/iend = 1
if(links)
iend = findtext(info_links, "</span>", istart)
else
iend = findtext(info, "</span>", istart)
//textindex = istart+26
textindex = iend
break
if(links)
var/before = copytext(info_links, 1, textindex)
var/after = copytext(info_links, textindex)
info_links = before + text + after
else
var/before = copytext(info, 1, textindex)
var/after = copytext(info, textindex)
info = before + text + after
updateinfolinks()
/obj/item/paper/proc/updateinfolinks()
info_links = info
for(var/i in 1 to min(fields, 15))
addtofield(i, "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=[i]'>write</A></font>", 1)
info_links = info_links + "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=end'>write</A></font>"
/obj/item/paper/proc/clearpaper()
info = null
stamps = null
LAZYCLEARLIST(stamped)
cut_overlays()
updateinfolinks()
update_icon()
/obj/item/paper/proc/parsepencode(t, obj/item/pen/P, mob/user, iscrayon = 0)
if(length(t) < 1) //No input means nothing needs to be parsed
return
// t = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
t = replacetext(t, "\[center\]", "<center>")
t = replacetext(t, "\[/center\]", "</center>")
t = replacetext(t, "\[br\]", "<BR>")
t = replacetext(t, "\n", "<BR>")
t = replacetext(t, "\[b\]", "<B>")
t = replacetext(t, "\[/b\]", "</B>")
t = replacetext(t, "\[i\]", "<I>")
t = replacetext(t, "\[/i\]", "</I>")
t = replacetext(t, "\[u\]", "<U>")
t = replacetext(t, "\[/u\]", "</U>")
t = replacetext(t, "\[large\]", "<font size=\"4\">")
t = replacetext(t, "\[/large\]", "</font>")
t = replacetext(t, "\[sign\]", "<font face=\"[SIGNFONT]\"><i>[user.real_name]</i></font>")
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;")
if(!iscrayon)
t = replacetext(t, "\[*\]", "<li>")
t = replacetext(t, "\[hr\]", "<HR>")
t = replacetext(t, "\[small\]", "<font size = \"1\">")
t = replacetext(t, "\[/small\]", "</font>")
t = replacetext(t, "\[list\]", "<ul>")
t = replacetext(t, "\[/list\]", "</ul>")
t = "<font face=\"[P.font]\" color=[P.colour]>[t]</font>"
else // If it is a crayon, and he still tries to use these, make them empty!
var/obj/item/toy/crayon/C = P
t = replacetext(t, "\[*\]", "")
t = replacetext(t, "\[hr\]", "")
t = replacetext(t, "\[small\]", "")
t = replacetext(t, "\[/small\]", "")
t = replacetext(t, "\[list\]", "")
t = replacetext(t, "\[/list\]", "")
t = "<font face=\"[CRAYON_FONT]\" color=[C.paint_color]><b>[t]</b></font>"
// t = replacetext(t, "#", "") // Junk converted to nothing!
//Count the fields
var/laststart = 1
while(1)
var/i = findtext(t, "<span class=\"paper_field\">", laststart)
if(i == 0)
break
laststart = i+1
fields++
return t
/obj/item/paper/proc/reload_fields() // Useful if you made the paper programicly and want to include fields. Also runs updateinfolinks() for you.
fields = 0
var/laststart = 1
while(1)
var/i = findtext(info, "<span class=\"paper_field\">", laststart)
if(i == 0)
break
laststart = i+1
fields++
updateinfolinks()
/obj/item/paper/proc/openhelp(mob/user)
user << browse({"<HTML><HEAD><TITLE>Paper Help</TITLE></HEAD>
<BODY>
<b><center>Crayon&Pen commands</center></b><br>
<br>
\[br\] : Creates a linebreak.<br>
\[center\] - \[/center\] : Centers the text.<br>
\[b\] - \[/b\] : Makes the text <b>bold</b>.<br>
\[i\] - \[/i\] : Makes the text <i>italic</i>.<br>
\[u\] - \[/u\] : Makes the text <u>underlined</u>.<br>
\[large\] - \[/large\] : Increases the <font size = \"4\">size</font> of the text.<br>
\[sign\] : Inserts a signature of your name in a foolproof way.<br>
\[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.<br>
<br>
<b><center>Pen exclusive commands</center></b><br>
\[small\] - \[/small\] : Decreases the <font size = \"1\">size</font> of the text.<br>
\[list\] - \[/list\] : A list.<br>
\[*\] : A dot used for lists.<br>
\[hr\] : Adds a horizontal rule.
</BODY></HTML>"}, "window=paper_help")
/obj/item/paper/Topic(href, href_list)
..()
if(usr.stat || usr.restrained())
return
if(href_list["help"])
openhelp(usr)
return
if(href_list["write"])
var/id = href_list["write"]
var/t = stripped_multiline_input("Enter what you want to write:", "Write", no_trim=TRUE)
if(!t)
return
var/obj/item/i = usr.get_active_held_item() //Check to see if he still got that darn pen, also check if he's using a crayon or pen.
var/iscrayon = 0
if(!istype(i, /obj/item/pen))
if(!istype(i, /obj/item/toy/crayon))
return
iscrayon = 1
if(!in_range(src, usr) && loc != usr && !istype(loc, /obj/item/clipboard) && loc.loc != usr && usr.get_active_held_item() != i) //Some check to see if he's allowed to write
return
t = parsepencode(t, i, usr, iscrayon) // Encode everything from pencode to html
if(t != null) //No input from the user means nothing needs to be added
if(id!="end")
addtofield(text2num(id), t) // He wants to edit a field, let him.
else
info += t // Oh, he wants to edit to the end of the file, let him.
updateinfolinks()
usr << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links]<HR>[stamps]</BODY><div align='right'style='position:fixed;bottom:0;font-style:bold;'><A href='?src=\ref[src];help=1'>\[?\]</A></div></HTML>", "window=[name]") // Update the window
update_icon()
/obj/item/paper/attackby(obj/item/P, mob/living/carbon/human/user, params)
..()
if(resistance_flags & ON_FIRE)
return
if(is_blind(user))
return
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
if(user.is_literate())
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links]<HR>[stamps]</BODY><div align='right'style='position:fixed;bottom:0;font-style:bold;'><A href='?src=\ref[src];help=1'>\[?\]</A></div></HTML>", "window=[name]")
return
else
to_chat(user, "<span class='notice'>You don't know how to read or write.</span>")
return
if(istype(src, /obj/item/paper/talisman/))
to_chat(user, "<span class='warning'>[P]'s ink fades away shortly after it is written.</span>")
return
else if(istype(P, /obj/item/stamp))
if(!in_range(src, user))
return
stamps += "<img src=large_[P.icon_state].png>"
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]")
stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2)
LAZYADD(stamped, P.icon_state)
add_overlay(stampoverlay)
to_chat(user, "<span class='notice'>You stamp the paper with your rubber stamp.</span>")
if(P.is_hot())
if(user.disabilities & CLUMSY && prob(10))
user.visible_message("<span class='warning'>[user] accidentally ignites themselves!</span>", \
"<span class='userdanger'>You miss the paper and accidentally light yourself on fire!</span>")
user.dropItemToGround(P)
user.adjust_fire_stacks(1)
user.IgniteMob()
return
if(!(in_range(user, src))) //to prevent issues as a result of telepathically lighting a paper
return
user.dropItemToGround(src)
user.visible_message("<span class='danger'>[user] lights [src] ablaze with [P]!</span>", "<span class='danger'>You light [src] on fire!</span>")
fire_act()
add_fingerprint(user)
/obj/item/paper/fire_act(exposed_temperature, exposed_volume)
..()
if(!(resistance_flags & FIRE_PROOF))
icon_state = "paper_onfire"
info = "[stars(info)]"
/obj/item/paper/extinguish()
..()
update_icon()
/*
* Construction paper
*/
/obj/item/paper/construction
/obj/item/paper/construction/Initialize()
. = ..()
color = pick("FF0000", "#33cc33", "#ffb366", "#551A8B", "#ff80d5", "#4d94ff")
/*
* Natural paper
*/
/obj/item/paper/natural/Initialize()
. = ..()
color = "#FFF5ED"
/obj/item/paper/crumpled
name = "paper scrap"
icon_state = "scrap"
slot_flags = null
/obj/item/paper/crumpled/update_icon()
return
/obj/item/paper/crumpled/bloody
icon_state = "scrap_bloodied"