diff --git a/baystation12.dme b/baystation12.dme
index 1162f91e05..7c8a965b1f 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -124,6 +124,7 @@
#define FILE_DIR "code/modules/mob/new_player"
#define FILE_DIR "code/modules/mob/organ"
#define FILE_DIR "code/modules/mob/simple_animal"
+#define FILE_DIR "code/modules/paperwork"
#define FILE_DIR "code/modules/power"
#define FILE_DIR "code/modules/power/antimatter"
#define FILE_DIR "code/modules/power/singularity"
diff --git a/code/game/objects/items/weapons/wrappingpaper.dm b/code/game/objects/items/weapons/wrappingpaper.dm
new file mode 100644
index 0000000000..8d3bb9a849
--- /dev/null
+++ b/code/game/objects/items/weapons/wrappingpaper.dm
@@ -0,0 +1,230 @@
+/*
+CONTAINS:
+WRAPPING PAPER
+GIFTS
+BEDSHEET BIN
+PHOTOGRAPHS
+
+*/
+// WRAPPING PAPER
+
+/obj/item/weapon/wrapping_paper/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if (!( locate(/obj/structure/table, src.loc) ))
+ user << "\blue You MUST put the paper on a table!"
+ if (W.w_class < 4)
+ if ((istype(user.l_hand, /obj/item/weapon/wirecutters) || istype(user.r_hand, /obj/item/weapon/wirecutters)))
+ var/a_used = 2 ** (src.w_class - 1)
+ if (src.amount < a_used)
+ user << "\blue You need more paper!"
+ return
+ else
+ src.amount -= a_used
+ user.drop_item()
+ var/obj/item/weapon/gift/G = new /obj/item/weapon/gift( src.loc )
+ G.size = W.w_class
+ G.w_class = G.size + 1
+ G.icon_state = text("gift[]", G.size)
+ G.gift = W
+ W.loc = G
+ G.add_fingerprint(user)
+ W.add_fingerprint(user)
+ src.add_fingerprint(user)
+ if (src.amount <= 0)
+ new /obj/item/weapon/c_tube( src.loc )
+ //SN src = null
+ del(src)
+ return
+ else
+ user << "\blue You need scissors!"
+ else
+ user << "\blue The object is FAR too large!"
+ return
+
+
+/obj/item/weapon/wrapping_paper/examine()
+ set src in oview(1)
+
+ ..()
+ usr << text("There is about [] square units of paper left!", src.amount)
+ return
+
+/obj/item/weapon/wrapping_paper/attack(mob/target as mob, mob/user as mob)
+ if (!istype(target, /mob/living/carbon/human)) return
+ if (istype(target:wear_suit, /obj/item/clothing/suit/straight_jacket) || target:stat)
+ if (src.amount > 2)
+ var/obj/effect/spresent/present = new /obj/effect/spresent (target:loc)
+ src.amount -= 2
+
+ if (target:client)
+ target:client:perspective = EYE_PERSPECTIVE
+ target:client:eye = present
+
+ target:loc = present
+ target.attack_log += text("\[[time_stamp()]\] Has been wrapped with [src.name] by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to wrap [target.name] ([target.ckey])")
+
+ log_attack("[user.name] ([user.ckey]) used the [src.name] to wrap [target.name] ([target.ckey])")
+
+ else
+ user << "/blue You need more paper."
+ else
+ user << "Theyre moving around too much. a Straitjacket would help."
+
+
+
+
+
+// GIFTS
+
+/obj/item/weapon/gift/attack_self(mob/user as mob)
+ if(!src.gift)
+ user << "\blue The gift was empty!"
+ del(src)
+ src.gift.loc = user
+ if (user.hand)
+ user.l_hand = src.gift
+ else
+ user.r_hand = src.gift
+ src.gift.layer = 20
+ src.gift.add_fingerprint(user)
+ del(src)
+ return
+
+/obj/item/weapon/a_gift/ex_act()
+ del(src)
+ return
+
+
+/obj/effect/spresent/relaymove(mob/user as mob)
+ if (user.stat)
+ return
+ user << "\blue You cant move."
+
+/obj/effect/spresent/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+
+ if (!istype(W, /obj/item/weapon/wirecutters))
+ user << "/blue I need wirecutters for that."
+ return
+
+ user << "\blue You cut open the present."
+
+ for(var/mob/M in src) //Should only be one but whatever.
+ M.loc = src.loc
+ if (M.client)
+ M.client.eye = M.client.mob
+ M.client.perspective = MOB_PERSPECTIVE
+
+ del(src)
+
+
+/obj/item/weapon/a_gift/attack_self(mob/M as mob)
+ switch(pick("flash", "t_gun", "l_gun", "shield", "sword", "axe"))
+ if("flash")
+ var/obj/item/device/flash/W = new /obj/item/device/flash( M )
+ if (M.hand)
+ M.l_hand = W
+ else
+ M.r_hand = W
+ W.layer = 20
+ W.add_fingerprint(M)
+ //SN src = null
+ del(src)
+ return
+ if("l_gun")
+ var/obj/item/weapon/gun/energy/laser/W = new /obj/item/weapon/gun/energy/laser( M )
+ if (M.hand)
+ M.l_hand = W
+ else
+ M.r_hand = W
+ W.layer = 20
+ W.add_fingerprint(M)
+ //SN src = null
+ del(src)
+ return
+ if("t_gun")
+ var/obj/item/weapon/gun/energy/taser/W = new /obj/item/weapon/gun/energy/taser( M )
+ if (M.hand)
+ M.l_hand = W
+ else
+ M.r_hand = W
+ W.layer = 20
+ W.add_fingerprint(M)
+ //SN src = null
+ del(src)
+ return
+ if("sword")
+ var/obj/item/weapon/melee/energy/sword/W = new /obj/item/weapon/melee/energy/sword( M )
+ if (M.hand)
+ M.l_hand = W
+ else
+ M.r_hand = W
+ W.layer = 20
+ W.add_fingerprint(M)
+ //SN src = null
+ del(src)
+ return
+ if("axe")
+ var/obj/item/weapon/melee/energy/axe/W = new /obj/item/weapon/melee/energy/axe( M )
+ if (M.hand)
+ M.l_hand = W
+ else
+ M.r_hand = W
+ W.layer = 20
+ W.add_fingerprint(M)
+ //SN src = null
+ del(src)
+ return
+ else
+ return
+
+// BEDSHEET BIN
+
+/obj/structure/bedsheetbin/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/bedsheet))
+ //W = null
+ del(W)
+ src.amount++
+ return
+
+/obj/structure/bedsheetbin/attack_paw(mob/user as mob)
+ return src.attack_hand(user)
+
+/obj/structure/bedsheetbin/attack_hand(mob/user as mob)
+ if (src.amount >= 1)
+ src.amount--
+ new /obj/item/weapon/bedsheet( src.loc )
+ add_fingerprint(user)
+
+/obj/structure/bedsheetbin/examine()
+ set src in oview(1)
+
+ src.amount = round(src.amount)
+ if (src.amount <= 0)
+ src.amount = 0
+ usr << "There are no bed sheets in the bin."
+ else
+ if (src.amount == 1)
+ usr << "There is one bed sheet in the bin."
+ else
+ usr << text("There are [] bed sheets in the bin.", src.amount)
+ return
+
+// PHOTOGRAPH
+
+/obj/item/weapon/paper/photograph/New()
+
+ ..()
+ src.pixel_y = 0
+ src.pixel_x = 0
+ return
+
+/obj/item/weapon/paper/photograph/attack_self(mob/user as mob)
+
+ var/n_name = input(user, "What would you like to label the photo?", "Paper Labelling", null) as text
+ n_name = copytext(n_name, 1, 32)
+ if ((src.loc == user && user.stat == 0))
+ src.name = text("photo[]", (n_name ? text("- '[]'", n_name) : null))
+ src.add_fingerprint(user)
+ return
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
new file mode 100644
index 0000000000..413171387e
--- /dev/null
+++ b/code/modules/paperwork/clipboard.dm
@@ -0,0 +1,144 @@
+/obj/item/weapon/clipboard
+ name = "clipboard"
+ icon = 'bureaucracy.dmi'
+ icon_state = "clipboard"
+ item_state = "clipboard"
+ throwforce = 0
+ w_class = 2.0
+ throw_speed = 3
+ throw_range = 10
+ var/obj/item/weapon/pen/haspen //The stored pen.
+ var/obj/item/weapon/paper/toppaper //The topmost piece of paper.
+ flags = FPRINT | TABLEPASS | ONBELT
+
+/obj/item/weapon/clipboard/New()
+ update_icon()
+
+/obj/item/weapon/clipboard/MouseDrop(obj/over_object as obj) //Quick clipboard fix. -Agouri
+ if(ishuman(usr) || ismonkey(usr)) //Can monkeys even place items in the pocket slots? Leaving this in just in case~
+ var/mob/M = usr
+ if (!(istype(over_object, /obj/screen) ))
+ return ..()
+ if((!(M.restrained()) && !(M.stat)))
+ if(over_object.name == "r_hand")
+ if(!(M.r_hand))
+ M.u_equip(src)
+ M.r_hand = src
+ else
+ if(over_object.name == "l_hand")
+ if(!(M.l_hand))
+ M.u_equip(src)
+ M.l_hand = src
+ M.update_clothing()
+ src.add_fingerprint(usr)
+ return
+
+/obj/item/weapon/clipboard/update_icon()
+ overlays = null
+ if(toppaper)
+ overlays += toppaper.icon_state
+ overlays += toppaper.overlays
+ if(haspen)
+ overlays += "clipboard_pen"
+ overlays += "clipboard_over"
+ return
+
+/obj/item/weapon/clipboard/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/paper))
+ user.drop_item()
+ W.loc = src
+ toppaper = W
+ user << "\blue You clip the paper onto the clipboard."
+ update_icon()
+ else if(toppaper)
+ toppaper.attackby(usr.get_active_hand(), usr)
+ update_icon()
+ return
+
+/obj/item/weapon/clipboard/attack_self(mob/user as mob)
+ var/dat = "
Clipboard"
+ if (haspen)
+ dat += "Remove Pen
"
+ else
+ dat += "Add Pen
"
+
+ //The topmost paper. I don't think there's any way to organise contents in byond, so this is what we're stuck with. -Pete
+ if(toppaper)
+ var/obj/item/weapon/paper/P = toppaper
+ dat += "Write Remove - [P.name]
"
+
+ for(P in src)
+ if(P == toppaper)
+ continue
+ dat += "Write Remove Move to top - [P.name]
"
+ user << browse(dat, "window=clipboard")
+ onclose(user, "clipboard")
+ add_fingerprint(usr)
+ return
+
+/obj/item/weapon/clipboard/Topic(href, href_list)
+ ..()
+ if ((usr.stat || usr.restrained()))
+ return
+
+ if (usr.contents.Find(src))
+
+ if(href_list["pen"])
+ if(haspen)
+ haspen.loc = usr.loc
+ if(ishuman(usr))
+ if(!usr.get_active_hand())
+ usr.put_in_hand(haspen)
+ haspen = null
+
+ if(href_list["addpen"])
+ if(!haspen)
+ if(istype(usr.get_active_hand(), /obj/item/weapon/pen))
+ var/obj/item/weapon/pen/W = usr.get_active_hand()
+ usr.drop_item()
+ W.loc = src
+ haspen = W
+ usr << "\blue You slot the pen into the clipboard."
+
+ if(href_list["write"])
+ var/obj/item/P = locate(href_list["write"])
+ if(P)
+ if(usr.get_active_hand())
+ P.attackby(usr.get_active_hand(), usr)
+
+ if(href_list["remove"])
+ var/obj/item/P = locate(href_list["remove"])
+ if(P)
+ P.loc = usr.loc
+ if(ishuman(usr))
+ if(!usr.get_active_hand())
+ usr.put_in_hand(P)
+ else
+ P.loc = get_turf(usr)
+ if(P == toppaper)
+ var/obj/item/weapon/paper/newtop = locate(/obj/item/weapon/paper in src)
+ if(newtop && (newtop != toppaper))
+ toppaper = newtop
+ else
+ toppaper = null
+
+ if(href_list["read"])
+ var/obj/item/weapon/paper/P = locate(href_list["read"])
+ if(P)
+ if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon)))
+ usr << browse("[P.name][stars(P.info)][P.stamps]", "window=[P.name]")
+ onclose(usr, "[P.name]")
+ else
+ usr << browse("[P.name][P.info][P.stamps]", "window=[P.name]")
+ onclose(usr, "[P.name]")
+
+ if(href_list["top"])
+ var/obj/item/P = locate(href_list["top"])
+ if(P)
+ toppaper = P
+ usr << "You move [P.name] to the top."
+
+ //Update everything
+ attack_self(usr)
+ update_icon()
+ return
\ No newline at end of file
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
new file mode 100644
index 0000000000..a22754c29d
--- /dev/null
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -0,0 +1,37 @@
+/obj/structure/filingcabinet
+ name = "filing cabinet"
+ desc = "A large cabinet with drawers."
+ icon = 'bureaucracy.dmi'
+ icon_state = "filing_cabinet0"
+ density = 1
+ anchored = 1
+
+/obj/structure/filingcabinet/attackby(obj/item/P as obj, mob/user as mob)
+ if(istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/folder))
+ user << "You put the [P] in the [src]."
+ user.drop_item()
+ P.loc = src
+ spawn()
+ icon_state = "filing_cabinet1"
+ sleep(5)
+ icon_state = "filing_cabinet0"
+ else if(istype(P, /obj/item/weapon/wrench))
+ playsound(loc, 'Ratchet.ogg', 50, 1)
+ anchored = !anchored
+ user << "You [anchored ? "wrench" : "unwrench"] the [src]."
+ else
+ user << "You can't put a [P] in the [src]!"
+
+/obj/structure/filingcabinet/attack_hand(mob/user as mob)
+ if(src.contents.len <= 0)
+ user << "The [src] is empty."
+ return
+ icon_state = "filing_cabinet1" //make it look open for kicks
+ var/obj/item/P = input(user,"Choose a file or folder to take out.","[src]", "Cancel") as null|obj in contents
+ if(!isnull(P) && in_range(src,user))
+ if(!user.get_active_hand())
+ user.put_in_hand(P)
+ else
+ P.loc = get_turf_loc(src)
+ icon_state = "filing_cabinet0"
+ return
\ No newline at end of file
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
new file mode 100644
index 0000000000..00b4c61cbf
--- /dev/null
+++ b/code/modules/paperwork/folders.dm
@@ -0,0 +1,86 @@
+//THIS IS OBVIOUSLY WIP, SORRY -PETE
+/obj/item/weapon/folder
+ name = "folder"
+ desc = "A folder."
+ icon = 'bureaucracy.dmi'
+ icon_state = "folder"
+ w_class = 2
+
+/obj/item/weapon/folder/blue
+ desc = "A blue folder."
+ icon_state = "folder_blue"
+
+/obj/item/weapon/folder/red
+ desc = "A red folder."
+ icon_state = "folder_red"
+
+/obj/item/weapon/folder/yellow
+ desc = "A yellow folder."
+ icon_state = "folder_yellow"
+
+/obj/item/weapon/folder/white
+ desc = "A white folder."
+ icon_state = "folder_white"
+
+/obj/item/weapon/folder/update_icon()
+ overlays = null
+ if(contents.len)
+ overlays += "folder_paper"
+ return
+
+/obj/item/weapon/folder/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo))
+ user.drop_item()
+ W.loc = src
+ user << "\blue You put the [W] into the folder."
+ update_icon()
+ else if(istype(W, /obj/item/weapon/pen))
+ var/n_name = input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text
+ n_name = copytext(n_name, 1, 32)
+ if ((loc == usr && usr.stat == 0))
+ name = "folder[(n_name ? text("- '[n_name]'") : null)]"
+ return
+
+/obj/item/weapon/folder/attack_self(mob/user as mob)
+ var/dat = "[name]"
+
+ for(var/obj/item/weapon/paper/P in src)
+ dat += "Remove - [P.name]
"
+ for(var/obj/item/weapon/photo/Ph in src)
+ dat += "Remove - [Ph.name]
"
+ user << browse(dat, "window=folder")
+ onclose(user, "folder")
+ add_fingerprint(usr)
+ return
+
+/obj/item/weapon/folder/Topic(href, href_list)
+ ..()
+ if ((usr.stat || usr.restrained()))
+ return
+
+ if (usr.contents.Find(src))
+
+ if(href_list["remove"])
+ var/obj/item/P = locate(href_list["remove"])
+ if(P)
+ P.loc = usr.loc
+ if(ishuman(usr))
+ if(!usr.get_active_hand())
+ usr.put_in_hand(P)
+ else
+ P.loc = get_turf(usr)
+
+ if(href_list["read"])
+ var/obj/item/weapon/paper/P = locate(href_list["read"])
+ if(P)
+ if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon)))
+ usr << browse("[P.name][stars(P.info)][P.stamps]", "window=[P.name]")
+ onclose(usr, "[P.name]")
+ else
+ usr << browse("[P.name][P.info][P.stamps]", "window=[P.name]")
+ onclose(usr, "[P.name]")
+
+ //Update everything
+ attack_self(usr)
+ update_icon()
+ return
\ No newline at end of file
diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm
new file mode 100644
index 0000000000..41b4242c5d
--- /dev/null
+++ b/code/modules/paperwork/handlabeler.dm
@@ -0,0 +1,53 @@
+/obj/item/weapon/hand_labeler
+ name = "Hand labeler"
+ icon = 'bureaucracy.dmi'
+ icon_state = "labeler0"
+ item_state = "flight"
+ var/label = null
+ var/labels_left = 30
+ var/mode = 0 //off or on.
+
+/obj/item/weapon/hand_labeler/afterattack(atom/A, mob/user as mob)
+ if(!mode) //if it's off, give up.
+ return
+ if(A==loc) // if placing the labeller into something (e.g. backpack)
+ return // don't set a label
+
+ if(!labels_left)
+ user << "\blue No labels left."
+ return
+ if(!label || !length(label))
+ user << "\blue No text set."
+ return
+ if(length(A.name) + length(label) > 64)
+ user << "\blue Label too big."
+ return
+ if(ishuman(A))
+ user << "\blue You can't label humans."
+ return
+ if(issilicon(A))
+ user << "\blue You can't label cyborgs."
+ return
+
+ for(var/mob/M in viewers())
+ if ((M.client && !( M.blinded )))
+ M << "\blue [user] labels [A] as [label]."
+ A.name = "[A.name] ([label])"
+
+/obj/item/weapon/hand_labeler/attack_self()
+ mode = !mode
+ icon_state = "labeler[mode]"
+ if(mode)
+ usr << "\blue You turn on the hand labeler."
+ //Now let them chose the text.
+ var/str = input(usr,"Label text?","Set label","")
+ if(!str || !length(str))
+ usr << "\red Invalid text."
+ return
+ if(length(str) > 64)
+ usr << "\red Text too long."
+ return
+ label = str
+ usr << "\blue You set the text to '[str]'."
+ else
+ usr << "\blue You turn off the hand labeler."
\ No newline at end of file
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
new file mode 100644
index 0000000000..ae382a555c
--- /dev/null
+++ b/code/modules/paperwork/paper.dm
@@ -0,0 +1,287 @@
+/obj/item/weapon/paper
+ name = "paper"
+ gender = PLURAL
+ icon = 'bureaucracy.dmi'
+ icon_state = "paper"
+ throwforce = 0
+ w_class = 1.0
+ throw_speed = 3
+ throw_range = 15
+ layer = 4
+
+ var
+ info //What's actually written on the paper.
+ info_links //A different version of the paper which includes html links at fields and EOF
+ stamps //The (text for the) stamps on the paper.
+ fields //Amount of user created fields
+ list/stamped
+ see_face = 1
+ body_parts_covered = HEAD
+ protective_temperature = 0
+ rigged = 0
+ spam_flag = 0
+
+ const
+ deffont = "Verdana"
+ signfont = "Times New Roman"
+ crayonfont = "Comic Sans MS"
+
+ New()
+ ..()
+ src.pixel_y = rand(-8, 8)
+ src.pixel_x = rand(-9, 9)
+ spawn(2)
+ if(src.info)
+ src.overlays += "paper_words"
+ updateinfolinks()
+ return
+
+ update_icon()
+ if(src.info)
+ src.overlays += "paper_words"
+ return
+
+ examine()
+ set src in oview(1)
+
+ // ..() //We don't want them to see the dumb "this is a paper" thing every time.
+ if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon)))
+ usr << browse("[name][stars(info)][stamps]", "window=[name]")
+ onclose(usr, "[name]")
+ else
+ usr << browse("[name][info][stamps]", "window=[name]")
+ onclose(usr, "[name]")
+ return
+
+ verb/rename()
+ set name = "Rename paper"
+ set category = "Object"
+ set src in usr
+
+ if ((usr.mutations & CLUMSY) && prob(50))
+ usr << "\red You cut yourself on the paper."
+ return
+ var/n_name = input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text
+ n_name = copytext(n_name, 1, 32)
+ if ((loc == usr && usr.stat == 0))
+ name = "paper[(n_name ? text("- '[n_name]'") : null)]"
+ add_fingerprint(usr)
+ return
+
+ attack_self(mob/living/user as mob)
+ examine()
+ if(rigged && (Holiday == "April Fool's Day"))
+ if(spam_flag == 0)
+ spam_flag = 1
+ playsound(src.loc, 'bikehorn.ogg', 50, 1)
+ spawn(20)
+ spam_flag = 0
+ return
+
+ attack_ai(var/mob/living/silicon/ai/user as mob)
+ 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]")
+ return
+
+ proc
+ addtofield(var/id, var/text, var/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()
+
+ updateinfolinks()
+ info_links = info
+ var/i = 0
+ for(i=1,i<=fields,i++)
+ addtofield(i, "write", 1)
+ info_links = info_links + "write"
+
+ parsepencode(var/t, var/obj/item/weapon/pen/P, mob/user as mob, var/iscrayon = 0)
+ t = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
+
+ t = dd_replacetext(t, "\[center\]", "")
+ t = dd_replacetext(t, "\[/center\]", "")
+ t = dd_replacetext(t, "\[br\]", "
")
+ t = dd_replacetext(t, "\[b\]", "")
+ t = dd_replacetext(t, "\[/b\]", "")
+ t = dd_replacetext(t, "\[i\]", "")
+ t = dd_replacetext(t, "\[/i\]", "")
+ t = dd_replacetext(t, "\[u\]", "")
+ t = dd_replacetext(t, "\[/u\]", "")
+ t = dd_replacetext(t, "\[large\]", "")
+ t = dd_replacetext(t, "\[/large\]", "")
+ t = dd_replacetext(t, "\[sign\]", "[user.real_name]")
+ t = dd_replacetext(t, "\[field\]", "")
+
+ if(!iscrayon)
+ t = dd_replacetext(t, "\[*\]", "")
+ t = dd_replacetext(t, "\[hr\]", "
")
+ t = dd_replacetext(t, "\[small\]", "")
+ t = dd_replacetext(t, "\[/small\]", "")
+ t = dd_replacetext(t, "\[list\]", "")
+ t = dd_replacetext(t, "\[/list\]", "
")
+
+ t = "[t]"
+ else // If it is a crayon, and he still tries to use these, make them empty!
+ t = dd_replacetext(t, "\[*\]", "")
+ t = dd_replacetext(t, "\[hr\]", "")
+ t = dd_replacetext(t, "\[small\]", "")
+ t = dd_replacetext(t, "\[/small\]", "")
+ t = dd_replacetext(t, "\[list\]", "")
+ t = dd_replacetext(t, "\[/list\]", "")
+
+ 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
+
+ openhelp(mob/user as mob)
+ user << browse({"Pen Help
+
+ Crayon&Pen commands
+
+ \[br\] : Creates a linebreak.
+ \[center\] - \[/center\] : Centers the text.
+ \[b\] - \[/b\] : Makes the text bold.
+ \[i\] - \[/i\] : Makes the text italic.
+ \[u\] - \[/u\] : Makes the text underlined.
+ \[large\] - \[/large\] : Increases the size of the text.
+ \[sign\] : Inserts a signature of your name in a foolproof way.
+ \[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.
+
+ Pen exclusive commands
+ \[small\] - \[/small\] : Decreases the size of the text.
+ \[list\] - \[/list\] : A list.
+ \[*\] : A dot used for lists.
+ \[hr\] : Adds a horizontal rule.
+ "}, "window=paper_help")
+
+
+ Topic(href, href_list)
+ ..()
+ if ((usr.stat || usr.restrained()))
+ return
+
+ if(href_list["write"])
+ var/id = href_list["write"]
+ var/t = strip_html_simple(input(usr, "What text do you wish to add to " + (id=="end" ? "the end of the paper" : "field "+id) + "?", "[name]", null),8192) as text
+
+ var/obj/item/i = usr.equipped() // 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/weapon/pen))
+ if(!istype(i, /obj/item/toy/crayon))
+ return
+ iscrayon = 1
+
+
+ if ((!in_range(src, usr) && src.loc != usr && !( istype(src.loc, /obj/item/weapon/clipboard) ) && src.loc.loc != usr && usr.equipped() != 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(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
+
+ if(!overlays.Find("paper_words"))
+ overlays += "paper_words"
+
+ attackby(obj/item/weapon/P as obj, mob/user as mob)
+ ..()
+ var/clown = 0
+ if(user.mind && (user.mind.assigned_role == "Clown"))
+ clown = 1
+
+ if (istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon))
+ usr << browse("[name][info_links][stamps]", "window=[name]")
+ //openhelp(user)
+ return
+ else if(istype(P, /obj/item/weapon/stamp))
+ if ((!in_range(src, usr) && src.loc != user && !( istype(src.loc, /obj/item/weapon/clipboard) ) && src.loc.loc != user && user.equipped() != P))
+ return
+
+ stamps += (stamps=="" ? "
" : "
") + "This paper has been stamped with the [P.name]."
+
+ switch(P.type)
+ if(/obj/item/weapon/stamp/captain)
+ overlays += "paper_stamped_cap"
+ if(/obj/item/weapon/stamp/hop)
+ overlays += "paper_stamped_hop"
+ if(/obj/item/weapon/stamp/hos)
+ overlays += "paper_stamped_hos"
+ if(/obj/item/weapon/stamp/ce)
+ overlays += "paper_stamped_ce"
+ if(/obj/item/weapon/stamp/rd)
+ overlays += "paper_stamped_rd"
+ if(/obj/item/weapon/stamp/cmo)
+ overlays += "paper_stamped_cmo"
+ if(/obj/item/weapon/stamp/denied)
+ overlays += "paper_stamped_denied"
+ if(/obj/item/weapon/stamp/clown)
+ if (!clown)
+ usr << "\red You are totally unable to use the stamp. HONK!"
+ return
+ else
+ overlays += "paper_stamped_clown"
+ else
+ overlays += "paper_stamped"
+ if(!stamped)
+ stamped = new
+ stamped += P.type
+
+ user << "\blue You stamp the paper with your rubber stamp."
+ add_fingerprint(user)
+ return
\ No newline at end of file
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
new file mode 100644
index 0000000000..931ae4597b
--- /dev/null
+++ b/code/modules/paperwork/paperbin.dm
@@ -0,0 +1,88 @@
+/obj/item/weapon/paper_bin
+ name = "paper bin"
+ icon = 'bureaucracy.dmi'
+ icon_state = "paper_bin1"
+ item_state = "sheet-metal"
+ throwforce = 1
+ w_class = 3
+ throw_speed = 3
+ throw_range = 7
+ var
+ amount = 30 //How much paper is in the bin.
+ list/papers = new/list() //List of papers put in the bin for reference.
+ sealed = 1 //If it's brandnew and unopened, it's sealed.
+
+ MouseDrop(mob/user as mob)
+ if ((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr))))))
+ if (usr.hand)
+ if (!( usr.l_hand ))
+ spawn( 0 )
+ src.attack_hand(usr, 1, 1)
+ return
+ else
+ if (!( usr.r_hand ))
+ spawn( 0 )
+ src.attack_hand(usr, 0, 1)
+ return
+ return
+
+
+ attack_paw(mob/user as mob)
+ return src.attack_hand(user)
+
+ attack_hand(mob/user as mob)
+ if (amount >= 1)
+ amount--
+ if(amount==0)
+ update_icon()
+
+ var/obj/item/weapon/paper/P
+ if (papers.len > 0) // If there's any custom paper on the stack, use that instead of creating a new paper.
+ P = papers[papers.len]
+ papers.Remove(P)
+ else
+ P = new /obj/item/weapon/paper
+ if(Holiday == "April Fool's Day")
+ if(prob(30))
+ P.info = "HONK HONK HONK HONK HONK HONK HONK
HOOOOOOOOOOOOOOOOOOOOOONK
APRIL FOOLS"
+ P.rigged = 1
+ P.updateinfolinks()
+
+ P.loc = user.loc
+ if(ishuman(user))
+ if(!user.get_active_hand())
+ user.put_in_hand(P)
+ user << "You take a paper out of the bin."
+ else
+ P.loc = get_turf_loc(src)
+ user << "You take a paper out of the bin."
+ else
+ user << "The paper bin is empty!"
+
+ add_fingerprint(user)
+ return
+
+ attackby(obj/item/weapon/paper/i as obj, mob/user as mob)
+ if(!istype(i))
+ return
+
+ user.drop_item()
+ i.loc = src
+ usr << "You put the paper on the top of the paper bin."
+ papers.Add(i)
+ amount++
+
+ examine()
+ set src in oview(1)
+
+ if(amount)
+ usr << "There " + (amount > 1 ? "are [amount] papers" : "is one paper") + " in the bin."
+ else
+ usr << "There are no papers in the bin."
+ return
+
+ update_icon()
+ if(amount < 1)
+ icon_state = "paper_bin0"
+ else
+ icon_state = "paper_bin1"
\ No newline at end of file
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
new file mode 100644
index 0000000000..471c4389e6
--- /dev/null
+++ b/code/modules/paperwork/pen.dm
@@ -0,0 +1,22 @@
+/obj/item/weapon/pen
+ desc = "It's a normal black ink pen."
+ name = "pen"
+ icon = 'bureaucracy.dmi'
+ icon_state = "pen"
+ flags = FPRINT | ONBELT | TABLEPASS
+ throwforce = 0
+ w_class = 1.0
+ throw_speed = 7
+ throw_range = 15
+ m_amt = 10
+ var/colour = "black" //what colour the ink is!
+
+/obj/item/weapon/pen/blue
+ desc = "It's a normal blue ink pen."
+ icon_state = "pen_blue"
+ colour = "blue"
+
+/obj/item/weapon/pen/red
+ desc = "It's a normal red ink pen."
+ icon_state = "pen_red"
+ colour = "red"
\ No newline at end of file
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
new file mode 100644
index 0000000000..dfbf6b8dd3
--- /dev/null
+++ b/code/modules/paperwork/photocopier.dm
@@ -0,0 +1,135 @@
+/obj/machinery/photocopier
+ name = "Photocopier"
+ icon = 'library.dmi'
+ icon_state = "bigscanner"
+ anchored = 1
+ density = 1
+ use_power = 1
+ idle_power_usage = 30
+ active_power_usage = 200
+ power_channel = EQUIP
+ var
+ obj/item/weapon/paper/copy = null //what's in the copier!
+ copies = 1 //how many copies to print!
+ toner = 30 //how much toner is left! woooooo~
+ maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
+
+ attack_ai(mob/user as mob)
+ return src.attack_hand(user)
+
+ attack_paw(mob/user as mob)
+ return src.attack_hand(user)
+
+ attack_hand(mob/user as mob)
+ user.machine = src
+
+ var/dat = "Photocopier
"
+ if(copy)
+ dat += "Remove Paper
"
+ if(toner)
+ dat += "Copy
"
+ dat += "Printing: [copies] copies."
+ dat += "- "
+ dat += "+
"
+ else if(toner)
+ dat += "Please insert paper to copy.
"
+ dat += "Current toner level: [toner]"
+ if(!toner)
+ dat +="
Please insert a new toner cartridge!"
+ user << browse(dat, "window=copier")
+ onclose(user, "copier")
+ return
+
+ Topic(href, href_list)
+ if(href_list["copy"])
+ if(copy)
+ for(var/i = 0, i < copies, i++)
+ if(toner > 0)
+ var/obj/item/weapon/paper/c = new /obj/item/weapon/paper (src.loc)
+ if(toner > 10) //lots of toner, make it dark
+ c.info = ""
+ else //no toner? shitty copies for you!
+ c.info = ""
+ var/copied = html_decode(copy.info)
+ copied = dd_replacetext(copied, ""
+ c.name = copy.name // -- Doohl
+ c.fields = copy.fields
+ c.updateinfolinks()
+ toner--
+ sleep(15)
+ else
+ break
+ updateUsrDialog()
+ else if(href_list["remove"])
+ if(copy)
+ if(ishuman(usr))
+ if(!usr.get_active_hand())
+ copy.loc = usr.loc
+ usr.put_in_hand(copy)
+ usr << "You take the paper out of the photocopier."
+ copy = null
+ updateUsrDialog()
+ else if(href_list["min"])
+ if(copies > 1)
+ copies--
+ updateUsrDialog()
+ else if(href_list["add"])
+ if(copies < maxcopies)
+ copies++
+ updateUsrDialog()
+
+ attackby(obj/item/O as obj, mob/user as mob)
+ if(istype(O, /obj/item/weapon/paper))
+ if(!copy)
+ user.drop_item()
+ copy = O
+ O.loc = src
+ user << "You insert the paper into the photocopier."
+ flick("bigscanner1", src)
+ updateUsrDialog()
+ else
+ user << "There is already paper in the photocopier."
+ else if(istype(O, /obj/item/device/toner))
+ if(toner == 0)
+ user.drop_item()
+ del(O)
+ toner = 30
+ user << "You insert the toner cartridge into the photocopier."
+ updateUsrDialog()
+ else
+ user << "This cartridge is not yet ready for replacement! Use up the rest of the toner."
+ return
+
+ ex_act(severity)
+ switch(severity)
+ if(1.0)
+ del(src)
+ if(2.0)
+ if(prob(50))
+ del(src)
+ else
+ if(toner > 0)
+ new /obj/effect/decal/cleanable/oil(get_turf(src))
+ toner = 0
+ else
+ if(prob(50))
+ if(toner > 0)
+ new /obj/effect/decal/cleanable/oil(get_turf(src))
+ toner = 0
+ return
+
+ blob_act()
+ if(prob(50))
+ del(src)
+ else
+ if(toner > 0)
+ new /obj/effect/decal/cleanable/oil(get_turf(src))
+ toner = 0
+ return
+
+/obj/item/device/toner
+ name = "toner cartridge"
+ icon_state = "tonercartridge"
\ No newline at end of file
diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm
new file mode 100644
index 0000000000..92d9afd326
--- /dev/null
+++ b/code/modules/paperwork/stamps.dm
@@ -0,0 +1,53 @@
+/obj/item/weapon/stamp
+ desc = "A rubber stamp for stamping important documents."
+ name = "rubber stamp"
+ icon = 'bureaucracy.dmi'
+ icon_state = "stamp-qm"
+ item_state = "stamp"
+ flags = FPRINT | TABLEPASS
+ throwforce = 0
+ w_class = 1.0
+ throw_speed = 7
+ throw_range = 15
+ m_amt = 60
+ var/color = "cargo"
+
+/obj/item/weapon/stamp/captain
+ name = "captain's rubber stamp"
+ icon_state = "stamp-cap"
+ color = "captain"
+
+/obj/item/weapon/stamp/hop
+ name = "head of personnel's rubber stamp"
+ icon_state = "stamp-hop"
+ color = "hop"
+
+/obj/item/weapon/stamp/hos
+ name = "head of security's rubber stamp"
+ icon_state = "stamp-hos"
+ color = "hosred"
+
+/obj/item/weapon/stamp/ce
+ name = "chief engineer's rubber stamp"
+ icon_state = "stamp-ce"
+ color = "chief"
+
+/obj/item/weapon/stamp/rd
+ name = "research director's rubber stamp"
+ icon_state = "stamp-rd"
+ color = "director"
+
+/obj/item/weapon/stamp/cmo
+ name = "chief medical officer's rubber stamp"
+ icon_state = "stamp-cmo"
+ color = "medical"
+
+/obj/item/weapon/stamp/denied
+ name = "\improper DENIED rubber stamp"
+ icon_state = "stamp-qm"
+ color = "redcoat"
+
+/obj/item/weapon/stamp/clown
+ name = "clown's rubber stamp"
+ icon_state = "stamp-clown"
+ color = "clown"
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 9d58d3d39a..5e70bb3741 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/gun/energy
icon_state = "energy"
- name = "\improper Energy gun"
- desc = "A basic energy-based gun with two settings: Stun and kill."
+ name = "energy gun"
+ desc = "A basic energy-based gun."
fire_sound = 'Taser.ogg'
var
@@ -9,6 +9,7 @@
charge_cost = 100 //How much energy is needed to fire.
cell_type = "/obj/item/weapon/cell"
projectile_type = "/obj/item/projectile/energy"
+ modifystate
emp_act(severity)
power_supply.use(round(power_supply.maxcharge / severity))
@@ -42,7 +43,10 @@
update_icon()
var/ratio = power_supply.charge / power_supply.maxcharge
ratio = round(ratio, 0.25) * 100
- icon_state = text("[][]", initial(icon_state), ratio)
+ if(modifystate)
+ icon_state = text("[][]", modifystate, ratio)
+ else
+ icon_state = text("[][]", initial(icon_state), ratio)
diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi
index 854f82bd17..1077150055 100644
Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ