/* * 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 = ITEM_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) ..() to_chat(user, "Alt-click to fold it.") var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper) assets.send(user) if(in_range(user, src) || isobserver(user)) if(user.is_literate()) user << browse("[name][info]
[stamps]", "window=[name]") onclose(user, "[name]") else user << browse("[name][stars(info)]
[stamps]", "window=[name]") onclose(user, "[name]") else to_chat(user, "You're too far away to read it!") /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.has_trait(TRAIT_CLUMSY) && prob(25)) to_chat(H, "You cut yourself on the paper! Ahhhh! Ahhhhh!") 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("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...") return (BRUTELOSS) /obj/item/paper/proc/reset_spamflag() spam_flag = FALSE /obj/item/paper/attack_self(mob/user) user.examinate(src) if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS])) if(!spam_flag) spam_flag = TRUE playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) addtimer(CALLBACK(src, .proc/reset_spamflag), 20) /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("[name][info]
[stamps]", "window=[name]") onclose(usr, "[name]") else usr << browse("[name][stars(info)]
[stamps]", "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, "", laststart) else istart = findtext(info, "", 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, "", istart) else iend = findtext(info, "", 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, "write", 1) info_links = info_links + "write" /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 = parsemarkdown(t, user, iscrayon) if(!iscrayon) t = "[t]" else var/obj/item/toy/crayon/C = P t = "[t]" // Count the fields var/laststart = 1 while(1) var/i = findtext(t, "", 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, "", laststart) if(i == 0) break laststart = i+1 fields++ updateinfolinks() /obj/item/paper/proc/openhelp(mob/user) user << browse({"Paper Help You can use backslash (\\) to escape special characters.

Crayon&Pen commands


# text : Defines a header.
|text| : Centers the text.
**text** : Makes the text bold.
*text* : Makes the text italic.
^text^ : Increases the size of the text.
%s : Inserts a signature of your name in a foolproof way.
%f : Inserts an invisible field which lets you start type from there. Useful for forms.

Pen exclusive commands

((text)) : Decreases the size of the text.
* item : An unordered list item.
  * item: An unordered list child item.
--- : Adds a horizontal rule. "}, "window=paper_help") /obj/item/paper/Topic(href, href_list) ..() var/literate = usr.is_literate() if(!usr.canUseTopic(src, BE_CLOSE, literate)) 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 || !usr.canUseTopic(src, BE_CLOSE, literate)) 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("[name][info_links]
[stamps]
\[?\]
", "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("[name][info_links]
[stamps]
\[?\]
", "window=[name]") return else to_chat(user, "You don't know how to read or write.") return else if(istype(P, /obj/item/stamp)) if(!in_range(src, user)) return stamps += "" 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, "You stamp the paper with your rubber stamp.") if(P.is_hot()) if(user.has_trait(TRAIT_CLUMSY) && prob(10)) user.visible_message("[user] accidentally ignites themselves!", \ "You miss the paper and accidentally light yourself on fire!") 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("[user] lights [src] ablaze with [P]!", "You light [src] on fire!") 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"