This commit is contained in:
EmeraldSundisk
2020-09-02 14:07:09 -07:00
parent d6d708c142
commit 0efa9eb5e5
531 changed files with 10708 additions and 18524 deletions
-45
View File
@@ -1,45 +0,0 @@
/obj/item/paper/carbon
name = "sheet of carbon"
icon_state = "paper_stack"
item_state = "paper"
// inhand_icon_state = "paper"
show_written_words = FALSE
var/copied = FALSE
var/iscopy = FALSE
/obj/item/paper/carbon/update_icon_state()
if(iscopy)
icon_state = "cpaper"
else if(copied)
icon_state = "paper"
else
icon_state = "paper_stack"
if(info)
icon_state = "[icon_state]_words"
/obj/item/paper/carbon/proc/removecopy(mob/living/user)
if(!copied)
var/obj/item/paper/carbon/C = src
var/copycontents = C.info
var/obj/item/paper/carbon/Copy = new /obj/item/paper/carbon(user.loc)
if(info)
copycontents = replacetext(copycontents, "<font face=\"[PEN_FONT]\" color=", "<font face=\"[PEN_FONT]\" nocolor=")
copycontents = replacetext(copycontents, "<font face=\"[CRAYON_FONT]\" color=", "<font face=\"[CRAYON_FONT]\" nocolor=")
Copy.info += copycontents
Copy.info += "</font>"
Copy.name = "Copy - [C.name]"
to_chat(user, "<span class='notice'>You tear off the carbon-copy!</span>")
C.copied = TRUE
Copy.iscopy = TRUE
Copy.update_icon_state()
C.update_icon_state()
user.put_in_hands(Copy)
else
to_chat(user, "<span class='notice'>There are no more carbon copies attached to this paper!</span>")
/obj/item/paper/carbon/on_attack_hand(mob/living/user)
if(loc == user && user.is_holding(src))
removecopy(user)
return
return ..()
+9 -10
View File
@@ -3,8 +3,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "clipboard"
item_state = "clipboard"
// inhand_icon_state = "clipboard"
// worn_icon_state = "clipboard"
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
@@ -36,6 +34,7 @@
. += "clipboard_pen"
. += "clipboard_over"
/obj/item/clipboard/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/paper))
if(!user.transferItemToLoc(W, src))
@@ -93,14 +92,14 @@
to_chat(usr, "<span class='notice'>You slot [W] into [src].</span>")
if(href_list["write"])
var/obj/item/P = locate(href_list["write"]) in src
if(istype(P))
var/obj/item/P = locate(href_list["write"])
if(istype(P) && P.loc == src)
if(usr.get_active_held_item())
P.attackby(usr.get_active_held_item(), usr)
if(href_list["remove"])
var/obj/item/P = locate(href_list["remove"]) in src
if(istype(P))
var/obj/item/P = locate(href_list["remove"])
if(istype(P) && P.loc == src)
P.forceMove(usr.loc)
usr.put_in_hands(P)
if(P == toppaper)
@@ -112,13 +111,13 @@
toppaper = null
if(href_list["read"])
var/obj/item/paper/P = locate(href_list["read"]) in src
if(istype(P))
var/obj/item/paper/P = locate(href_list["read"])
if(istype(P) && P.loc == src)
usr.examinate(P)
if(href_list["top"])
var/obj/item/P = locate(href_list["top"]) in src
if(istype(P))
var/obj/item/P = locate(href_list["top"])
if(istype(P) && P.loc == src)
toppaper = P
to_chat(usr, "<span class='notice'>You move [P.name] to the top.</span>")
+14 -13
View File
@@ -35,7 +35,7 @@
. = ..()
if(mapload)
for(var/obj/item/I in loc)
if(I.w_class < WEIGHT_CLASS_NORMAL) //there probably shouldn't be anything placed ontop of filing cabinets in a map that isn't meant to go in them
if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo))
I.forceMove(src)
/obj/structure/filingcabinet/deconstruct(disassembled = TRUE)
@@ -46,12 +46,7 @@
qdel(src)
/obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params)
if(P.tool_behaviour == TOOL_WRENCH && user.a_intent != INTENT_HELP)
to_chat(user, "<span class='notice'>You begin to [anchored ? "unwrench" : "wrench"] [src].</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You successfully [anchored ? "unwrench" : "wrench"] [src].</span>")
anchored = !anchored
else if(P.w_class < WEIGHT_CLASS_NORMAL)
if(istype(P, /obj/item/paper) || istype(P, /obj/item/folder) || istype(P, /obj/item/photo) || istype(P, /obj/item/documents))
if(!user.transferItemToLoc(P, src))
return
to_chat(user, "<span class='notice'>You put [P] in [src].</span>")
@@ -59,6 +54,11 @@
sleep(5)
icon_state = initial(icon_state)
updateUsrDialog()
else if(istype(P, /obj/item/wrench))
to_chat(user, "<span class='notice'>You begin to [anchored ? "unwrench" : "wrench"] [src].</span>")
if(P.use_tool(src, user, 20, volume=50))
to_chat(user, "<span class='notice'>You successfully [anchored ? "unwrench" : "wrench"] [src].</span>")
anchored = !anchored
else if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='warning'>You can't put [P] in [src]!</span>")
else
@@ -67,6 +67,9 @@
/obj/structure/filingcabinet/ui_interact(mob/user)
. = ..()
if(isobserver(user))
return
if(contents.len <= 0)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
@@ -97,17 +100,16 @@
to_chat(user, "<span class='notice'>You find nothing in [src].</span>")
/obj/structure/filingcabinet/Topic(href, href_list)
if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr)))
return
if(href_list["retrieve"])
usr << browse("", "window=filingcabinet") // Close the menu
var/obj/item/P = locate(href_list["retrieve"]) in src //contents[retrieveindex]
if(istype(P) && in_range(src, usr))
var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex]
if(istype(P) && P.loc == src && in_range(src, usr))
usr.put_in_hands(P)
updateUsrDialog()
icon_state = "[initial(icon_state)]-open"
addtimer(VARSET_CALLBACK(src, icon_state, initial(icon_state)), 5)
sleep(5)
icon_state = initial(icon_state)
/*
@@ -168,7 +170,6 @@
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
//before the records have been generated, so we do this inside the loop.
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/filingcabinet/medical/on_attack_hand()
populate()
. = ..()
+5 -11
View File
@@ -33,10 +33,7 @@
if(contents.len)
. += "folder_paper"
/obj/item/folder/attackby(obj/item/W, mob/user, params)
if(burn_paper_product_attackby_check(W, user))
return
if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/documents))
if(!user.transferItemToLoc(W, src))
return
@@ -46,14 +43,11 @@
if(!user.is_literate())
to_chat(user, "<span class='notice'>You scribble illegibly on the cover of [src]!</span>")
return
var/inputvalue = stripped_input(user, "What would you like to label the folder?", "Folder Labelling", "", MAX_NAME_LEN)
if(!inputvalue)
return
if(user.canUseTopic(src, BE_CLOSE))
name = "folder[(inputvalue ? " - '[inputvalue]'" : null)]"
name = "folder - '[inputvalue]'"
/obj/item/folder/Destroy()
@@ -82,14 +76,14 @@
if(usr.contents.Find(src))
if(href_list["remove"])
var/obj/item/I = locate(href_list["remove"]) in src
if(istype(I))
var/obj/item/I = locate(href_list["remove"])
if(istype(I) && I.loc == src)
I.forceMove(usr.loc)
usr.put_in_hands(I)
if(href_list["read"])
var/obj/item/I = locate(href_list["read"]) in src
if(istype(I))
var/obj/item/I = locate(href_list["read"])
if(istype(I) && I.loc == src)
usr.examinate(I)
//Update everything
+5 -10
View File
@@ -1,10 +1,9 @@
/obj/item/hand_labeler
name = "hand labeler"
desc = "A combined label printer, applicator, and remover, all in a single portable device. Designed to be easy to operate and use."
desc = "A combined label printer and applicator in a portable device, designed to be easy to operate and use."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "labeler0"
item_state = "flight"
// inhand_icon_state = "flight"
var/label = null
var/labels_left = 30
var/mode = 0
@@ -56,10 +55,9 @@
to_chat(user, "<span class='warning'>You can't label creatures!</span>") // use a collar
return
user.visible_message("<span class='notice'>[user] labels [A] with \"[label]\".</span>", \
"<span class='notice'>You label [A] with \"[label]\".</span>")
A.AddComponent(/datum/component/label, label)
// playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE)
user.visible_message("[user] labels [A] as [label].", \
"<span class='notice'>You label [A] as [label].</span>")
A.name = "[A.name] ([label])"
labels_left--
@@ -92,9 +90,7 @@
name = "cyborg-hand labeler"
/obj/item/hand_labeler/borg/afterattack(atom/A, mob/user, proximity)
. = ..()
if(!proximity)
return
. = ..(A, user, proximity)
if(!iscyborg(user))
return
@@ -118,7 +114,6 @@
desc = "A roll of paper. Use it on a hand labeler to refill it."
icon_state = "labeler_refill"
item_state = "electropack"
// inhand_icon_state = "electropack"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
+176 -92
View File
@@ -11,6 +11,41 @@
#define MODE_WRITING 1
#define MODE_STAMPING 2
/**
* This is a custom ui state. All it really does is keep track of pen
* being used and if they are editing it or not. This way we can keep
* the data with the ui rather than on the paper
*/
/datum/ui_state/default/paper_state
/// What edit mode we are in and who is
/// writing on it right now
var/edit_mode = MODE_READING
/// Setup for writing to a sheet
var/pen_color = "black"
var/pen_font = ""
var/is_crayon = FALSE
/// Setup for stamping a sheet
// Why not the stamp obj? I have no idea
// what happens to states out of scope so
// don't want to put instances in this
var/stamp_icon_state = ""
var/stamp_name = ""
var/stamp_class = ""
/datum/ui_state/default/paper_state/proc/copy_from(datum/ui_state/default/paper_state/from)
switch(from.edit_mode)
if(MODE_READING)
edit_mode = MODE_READING
if(MODE_WRITING)
edit_mode = MODE_WRITING
pen_color = from.pen_color
pen_font = from.pen_font
is_crayon = from.is_crayon
if(MODE_STAMPING)
edit_mode = MODE_STAMPING
stamp_icon_state = from.stamp_icon_state
stamp_class = from.stamp_class
stamp_name = from.stamp_name
/**
* Paper is now using markdown (like in github pull notes) for ALL rendering
@@ -23,9 +58,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper"
item_state = "paper"
// inhand_icon_state = "paper"
// worn_icon_state = "paper"
// custom_fire_overlay = "paper_onfire_overlay"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_range = 1
@@ -48,19 +80,34 @@
var/list/stamps /// Positioning for the stamp in tgui
var/list/stamped /// Overlay info
/// This REALLY should be a componenet. Basicly used during, april fools
/// to honk at you
var/rigged = 0
var/spam_flag = 0
var/contact_poison // Reagent ID to transfer on contact
var/contact_poison_volume = 0
// Ok, so WHY are we caching the ui's?
// Since we are not using autoupdate we
// need some way to update the ui's of
// other people looking at it and if
// its been updated. Yes yes, lame
// but canot be helped. However by
// doing it this way, we can see
// live updates and have multipule
// people look at it
var/list/viewing_ui = list()
/// When the sheet can be "filled out"
/// This is an associated list
var/list/form_fields = list()
var/field_counter = 1
/obj/item/paper/Destroy()
close_all_ui()
stamps = null
stamped = null
form_fields = null
stamped = null
. = ..()
/**
@@ -115,7 +162,7 @@
set category = "Object"
set src in usr
if(!usr.can_read(src) || usr.incapacitated(TRUE, TRUE) || (isobserver(usr) && !IsAdminGhost(usr)))
if(usr.incapacitated() || !usr.is_literate())
return
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
@@ -133,6 +180,18 @@
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)
/// ONLY USED FOR APRIL FOOLS
/obj/item/paper/proc/reset_spamflag()
spam_flag = FALSE
/obj/item/paper/attack_self(mob/user)
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
if(!spam_flag)
spam_flag = TRUE
playsound(loc, 'sound/items/bikehorn.ogg', 50, TRUE)
addtimer(CALLBACK(src, .proc/reset_spamflag), 20)
. = ..()
/obj/item/paper/proc/clearpaper()
info = ""
stamps = null
@@ -140,39 +199,28 @@
cut_overlays()
update_icon_state()
/obj/item/paper/examine(mob/user)
. = ..()
if(!in_range(user, src) && !isobserver(user))
. += "<span class='warning'>You're too far away to read it!</span>"
return
if(user.can_read(src))
ui_interact(user)
return
. += "<span class='warning'>You cannot read it!</span>"
/obj/item/paper/ui_status(mob/user,/datum/ui_state/state)
// Are we on fire? Hard ot read if so
if(resistance_flags & ON_FIRE)
return UI_CLOSE
if(!in_range(user,src))
return UI_CLOSE
if(user.incapacitated(TRUE, TRUE) || (isobserver(user) && !IsAdminGhost(user)))
return UI_UPDATE
// Even harder to read if your blind...braile? humm
// .. or if you cannot read
if(!user.can_read(src))
return UI_CLOSE
if(in_contents_of(/obj/machinery/door/airlock))
return UI_INTERACTIVE
return ..()
/obj/item/paper/examine_more(mob/user)
ui_interact(user)
return list("<span class='notice'><i>You try to read [src]...</i></span>")
/obj/item/paper/can_interact(mob/user)
if(in_contents_of(/obj/machinery/door/airlock))
return TRUE
return ..()
if(!..())
return FALSE
// Are we on fire? Hard ot read if so
if(resistance_flags & ON_FIRE)
return FALSE
// Even harder to read if your blind...braile? humm
if(user.is_blind())
return FALSE
// checks if the user can read.
return user.can_read(src)
/**
* This creates the ui, since we are using a custom state but not much else
* just makes it easyer to make it.
*/
/obj/item/paper/proc/create_ui(mob/user, datum/ui_state/default/paper_state/state)
ui_interact(user, state = state)
/obj/item/proc/burn_paper_product_attackby_check(obj/item/I, mob/living/user, bypass_clumsy)
var/ignition_message = I.ignition_effect(src, user)
@@ -196,22 +244,49 @@
/obj/item/paper/attackby(obj/item/P, mob/living/user, params)
if(burn_paper_product_attackby_check(P, user))
SStgui.close_uis(src)
close_all_ui()
return
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
if(length(info) >= MAX_PAPER_LENGTH) // Sheet must have less than 1000 charaters
to_chat(user, "<span class='warning'>This sheet of paper is full!</span>")
return
ui_interact(user)
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_WRITING
// should a crayon be in the same subtype as a pen? How about a brush or charcoal?
// TODO: Convert all writing stuff to one type, /obj/item/art_tool maybe?
state.is_crayon = istype(P, /obj/item/toy/crayon);
if(state.is_crayon)
var/obj/item/toy/crayon/PEN = P
state.pen_font = CRAYON_FONT
state.pen_color = PEN.paint_color
else
var/obj/item/pen/PEN = P
state.pen_font = PEN.font
state.pen_color = PEN.colour
create_ui(user, state)
return
else if(istype(P, /obj/item/stamp))
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_STAMPING // we are read only becausse the sheet is full
state.stamp_icon_state = P.icon_state
state.stamp_name = P.name
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
state.stamp_class = sheet.icon_class_name(P.icon_state)
to_chat(user, "<span class='notice'>You ready your stamp over the paper! </span>")
ui_interact(user)
create_ui(user, state)
return /// Normaly you just stamp, you don't need to read the thing
else
// cut paper? the sky is the limit!
ui_interact(user) // The other ui will be created with just read mode outside of this
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_READING
create_ui(user, state) // The other ui will be created with just read mode outside of this
return ..()
@@ -226,64 +301,68 @@
get_asset_datum(/datum/asset/spritesheet/simple/paper),
)
/obj/item/paper/ui_interact(mob/user, datum/tgui/ui)
/obj/item/paper/ui_interact(mob/user, datum/tgui/ui,
datum/ui_state/default/paper_state/state)
// Update the state
ui = ui || SStgui.get_open_ui(user, src)
if(ui && state)
var/datum/ui_state/default/paper_state/current_state = ui.state
current_state.copy_from(state)
// Update the UI
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PaperSheet", name)
state = new
ui.set_state(state)
ui.set_autoupdate(FALSE)
viewing_ui[user] = ui
ui.open()
/obj/item/paper/ui_close(mob/user)
/// close the editing window and change the mode
viewing_ui[user] = null
. = ..()
/obj/item/paper/ui_static_data(mob/user)
. = list()
.["text"] = info
.["max_length"] = MAX_PAPER_LENGTH
.["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set
.["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling?
.["stamps"] = stamps
// Again, we have to do this as autoupdate is off
/obj/item/paper/proc/update_all_ui()
for(var/datum/tgui/ui in viewing_ui)
ui.process(force = TRUE)
// Again, we have to do this as autoupdate is off
/obj/item/paper/proc/close_all_ui()
for(var/datum/tgui/ui in viewing_ui)
ui.close()
viewing_ui = list()
/obj/item/paper/ui_data(mob/user)
var/list/data = list()
var/obj/O = user.get_active_held_item()
if(istype(O, /obj/item/toy/crayon))
var/obj/item/toy/crayon/PEN = O
data["pen_font"] = CRAYON_FONT
data["pen_color"] = PEN.paint_color
data["edit_mode"] = MODE_WRITING
data["is_crayon"] = TRUE
data["stamp_class"] = "FAKE"
data["stamp_icon_state"] = "FAKE"
else if(istype(O, /obj/item/pen))
var/obj/item/pen/PEN = O
data["pen_font"] = PEN.font
data["pen_color"] = PEN.colour
data["edit_mode"] = MODE_WRITING
data["is_crayon"] = FALSE
data["stamp_class"] = "FAKE"
data["stamp_icon_state"] = "FAKE"
else if(istype(O, /obj/item/stamp))
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
data["stamp_icon_state"] = O.icon_state
data["stamp_class"] = sheet.icon_class_name(O.icon_state)
data["edit_mode"] = MODE_STAMPING
data["pen_font"] = "FAKE"
data["pen_color"] = "FAKE"
data["is_crayon"] = FALSE
else
data["edit_mode"] = MODE_READING
data["pen_font"] = "FAKE"
data["pen_color"] = "FAKE"
data["is_crayon"] = FALSE
data["stamp_icon_state"] = "FAKE"
data["stamp_class"] = "FAKE"
var/datum/tgui/ui = viewing_ui[user]
var/datum/ui_state/default/paper_state/state = ui.state
// Should all this go in static data and just do a forced update?
data["text"] = info
data["max_length"] = MAX_PAPER_LENGTH
data["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling?
data["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set
data["stamps"] = stamps
data["edit_mode"] = state.edit_mode
data["edit_usr"] = "[ui.user]";
// pen info for editing
data["is_crayon"] = state.is_crayon
data["pen_font"] = state.pen_font
data["pen_color"] = state.pen_color
// stamping info for..stamping
data["stamp_class"] = state.stamp_class
data["field_counter"] = field_counter
data["form_fields"] = form_fields
return data
/obj/item/paper/ui_act(action, params,datum/tgui/ui)
/obj/item/paper/ui_act(action, params, datum/tgui/ui, datum/ui_state/default/paper_state/state)
if(..())
return
switch(action)
@@ -291,33 +370,34 @@
var/stamp_x = text2num(params["x"])
var/stamp_y = text2num(params["y"])
var/stamp_r = text2num(params["r"]) // rotation in degrees
var/stamp_icon_state = params["stamp_icon_state"]
var/stamp_class = params["stamp_class"]
if (isnull(stamps))
stamps = list()
stamps = new/list()
if(stamps.len < MAX_PAPER_STAMPS)
// I hate byond when dealing with freaking lists
stamps[++stamps.len] = list(stamp_class, stamp_x, stamp_y, stamp_r) /// WHHHHY
stamps += list(list(state.stamp_class, stamp_x, stamp_y,stamp_r)) /// WHHHHY
/// This does the overlay stuff
if (isnull(stamped))
stamped = list()
stamped = new/list()
if(stamped.len < MAX_PAPER_STAMPS_OVERLAYS)
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[stamp_icon_state]")
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[state.stamp_icon_state]")
stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2)
add_overlay(stampoverlay)
LAZYADD(stamped, stamp_icon_state)
LAZYADD(stamped, state.stamp_icon_state)
update_static_data(usr,ui)
ui.user.visible_message("<span class='notice'>[ui.user] stamps [src] with [stamp_class]!</span>", "<span class='notice'>You stamp [src] with [stamp_class]!</span>")
ui.user.visible_message("<span class='notice'>[ui.user] stamps [src] with [state.stamp_name]!</span>", "<span class='notice'>You stamp [src] with [state.stamp_name]!</span>")
else
to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!"))
update_all_ui()
. = TRUE
if("save")
var/in_paper = params["text"]
var/paper_len = length(in_paper)
var/list/fields = params["form_fields"]
field_counter = params["field_counter"] ? text2num(params["field_counter"]) : field_counter
if(paper_len > MAX_PAPER_LENGTH)
@@ -333,10 +413,14 @@
if(info != in_paper)
to_chat(ui.user, "You have added to your paper masterpiece!");
info = in_paper
update_static_data(usr,ui)
for(var/key in fields)
form_fields[key] = fields[key];
update_all_ui()
update_icon()
. = TRUE
/**
+11 -16
View File
@@ -26,11 +26,11 @@
var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD)
if(BP)
BP.drop_limb()
playsound(loc, pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg'),50, TRUE, -1)
playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1)
return (BRUTELOSS)
else
user.visible_message("<span class='suicide'>[user] repeatedly bashes [src.name] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1)
return (BRUTELOSS)
@@ -42,12 +42,11 @@
if(storedpaper)
. += "paper"
/obj/item/papercutter/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/paper) && !storedpaper)
if(!user.transferItemToLoc(P, src))
return
playsound(loc, "pageturn", 60, TRUE)
playsound(loc, "pageturn", 60, 1)
to_chat(user, "<span class='notice'>You place [P] in [src].</span>")
storedpaper = P
update_icon()
@@ -60,17 +59,17 @@
storedcutter = P
update_icon()
return
if(P.tool_behaviour == TOOL_SCREWDRIVER && storedcutter)
if(istype(P, /obj/item/screwdriver) && storedcutter)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>[storedcutter] has been [cuttersecured ? "unsecured" : "secured"].</span>")
cuttersecured = !cuttersecured
return
..()
/obj/item/papercutter/on_attack_hand(mob/user)
/obj/item/papercutter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(!storedcutter)
to_chat(user, "<span class='warning'>The cutting blade is gone! You can't use [src] now.</span>")
to_chat(user, "<span class='notice'>The cutting blade is gone! You can't use [src] now.</span>")
return
if(!cuttersecured)
@@ -80,7 +79,7 @@
update_icon()
if(storedpaper)
playsound(src.loc, 'sound/weapons/slash.ogg', 50, TRUE)
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1)
to_chat(user, "<span class='notice'>You neatly cut [storedpaper].</span>")
storedpaper = null
qdel(storedpaper)
@@ -89,7 +88,6 @@
update_icon()
/obj/item/papercutter/MouseDrop(atom/over_object)
. = ..()
var/mob/M = usr
if(M.incapacitated() || !Adjacent(M))
return
@@ -100,6 +98,10 @@
else if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
else
. = ..()
add_fingerprint(M)
/obj/item/paperslip
@@ -110,12 +112,6 @@
resistance_flags = FLAMMABLE
max_integrity = 50
/obj/item/paperslip/attackby(obj/item/I, mob/living/user, params)
if(burn_paper_product_attackby_check(I, user))
return
return ..()
/obj/item/paperslip/Initialize()
. = ..()
pixel_x = rand(-5, 5)
@@ -128,6 +124,5 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "cutterblade"
item_state = "knife"
// inhand_icon_state = "knife"
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
+56 -58
View File
@@ -4,22 +4,53 @@
/obj/item/paper/fluff/sop
name = "paper- 'Standard Operating Procedure'"
info = "Alert Levels:<BR>\nBlue- Emergency<BR>\n\t1. Caused by fire<BR>\n\t2. Caused by manual interaction<BR>\n\tAction:<BR>\n\t\tClose all fire doors. These can only be opened by resetting the alarm<BR>\nRed- Ejection/Self-Destruct<BR>\n\t1. Caused by module operating computer.<BR>\n\tAction:<BR>\n\t\tAfter the specified time the module will eject completely.<BR>\n<BR>\nEngine Maintenance Instructions:<BR>\n\tShut off ignition systems:<BR>\n\tActivate internal power<BR>\n\tActivate orbital balance matrix<BR>\n\tRemove volatile liquids from area<BR>\n\tWear a fire suit<BR>\n<BR>\n\tAfter<BR>\n\t\tDecontaminate<BR>\n\t\tVisit medical examiner<BR>\n<BR>\nToxin Laboratory Procedure:<BR>\n\tWear a gas mask regardless<BR>\n\tGet an oxygen tank.<BR>\n\tActivate internal atmosphere<BR>\n<BR>\n\tAfter<BR>\n\t\tDecontaminate<BR>\n\t\tVisit medical examiner<BR>\n<BR>\nDisaster Procedure:<BR>\n\tFire:<BR>\n\t\tActivate sector fire alarm.<BR>\n\t\tMove to a safe area.<BR>\n\t\tGet a fire suit<BR>\n\t\tAfter:<BR>\n\t\t\tAssess Damage<BR>\n\t\t\tRepair damages<BR>\n\t\t\tIf needed, Evacuate<BR>\n\tMeteor Shower:<BR>\n\t\tActivate fire alarm<BR>\n\t\tMove to the back of ship<BR>\n\t\tAfter<BR>\n\t\t\tRepair damage<BR>\n\t\t\tIf needed, Evacuate<BR>\n\tAccidental Reentry:<BR>\n\t\tActivate fire alarms in front of ship.<BR>\n\t\tMove volatile matter to a fire proof area!<BR>\n\t\tGet a fire suit.<BR>\n\t\tStay secure until an emergency ship arrives.<BR>\n<BR>\n\t\tIf ship does not arrive-<BR>\n\t\t\tEvacuate to a nearby safe area!"
info = {"
Alert Levels:
* Blue - Emergency
* Caused by fire
* Caused by manual interaction
* Action: Close all fire doors. These can only be opened by resetting the alarm
* Red- Ejection/Self Destruct
* Caused by module operating computer.
* Action: After the specified time the module will eject completely.
Engine Maintenance Instructions:
1. Shut off ignition systems:
2. Activate internal power
3. Activate orbital balance matrix
4. Remove volatile liquids from area
5. Wear a fire suit
6. After Decontaminate Visit medical examiner
Toxin Laboratory Procedure:
1. Wear a gas mask regardless
2. Get an oxygen tank.
3. Activate internal atmosphere
4. After Decontaminate Visit medical examiner
Disaster Procedure:
Fire:
1. Activate sector fire alarm.
2. Move to a safe area.
3. Get a fire suit
* After:
1. Assess Damage
2. Repair damages
3. If needed, Evacuate
Meteor Shower:
1. Activate fire alarm
2. Move to the back of ship
* After
1. Repair damage
2. If needed, Evacuate
Accidental Reentry:
1. Activate fire alarms in front of ship.
2. Move volatile matter to a fire proof area!
3. Get a fire suit.
4. Stay secure until an emergency ship arrives.
5. If ship does not arrive-Evacuate to a nearby safe area!
"};
/obj/item/paper/fluff/shuttles/daniel
info = "i love daniel<br>daniel is my best friend<br><br>you are tearing me apart elise"
/obj/item/paper/fluff/jobs/prisoner/letter
name = "letter from home"
info = {"Dearest sweetheart,
<br>It is truly saddening you must spend your time locked up in an awful prison on that dangerous station. I have spoken to your lawyer who will attempt to appeal to the judge so your sentence may hopefully be reduced.
<br>Regardless, I just want you to understand that all of us out here still love you, and want to see you released safely some day! I know that prison can be a very vicious place, so please promise us you'll avoid getting into any fights or trouble, okay?
<br>We all care for your safety deeply, and could not live with ourselves if you ended up getting hurt. We've scheduled a visit to see you, and with any luck, hopefully our request will be granted soon.
<br>Anyways, please do your best to make it by in that place, and never forget we'll be always here for you, no matter if we're separated.
<br>
<br>Please stay safe,
<br>-Love, <i>Your Dearest</i>"}
//////////// Job guides n' fluff
@@ -59,46 +90,13 @@
name = "paper- 'Chemical Information'"
info = "Known Onboard Toxins:<BR>\n\tGrade A Semi-Liquid Plasma:<BR>\n\t\tHighly poisonous. You cannot sustain concentrations above 15 units.<BR>\n\t\tA gas mask fails to filter plasma after 50 units.<BR>\n\t\tWill attempt to diffuse like a gas.<BR>\n\t\tFiltered by scrubbers.<BR>\n\t\tThere is a bottled version which is very different<BR>\n\t\t\tfrom the version found in canisters!<BR>\n<BR>\n\t\tWARNING: Highly Flammable. Keep away from heat sources<BR>\n\t\texcept in an enclosed fire area!<BR>\n\t\tWARNING: It is a crime to use this without authorization.<BR>\nKnown Onboard Anti-Toxin:<BR>\n\tAnti-Toxin Type 01P: Works against Grade A Plasma.<BR>\n\t\tBest if injected directly into bloodstream.<BR>\n\t\tA full injection is in every regular Med-Kit.<BR>\n\t\tSpecial toxin Kits hold around 7.<BR>\n<BR>\nKnown Onboard Chemicals (other):<BR>\n\tRejuvenation T#001:<BR>\n\t\tEven 1 unit injected directly into the bloodstream<BR>\n\t\t\twill cure unconscious and sleep toxins.<BR>\n\t\tIf administered to a dying patient it will prevent<BR>\n\t\t\tfurther damage for about units*3 seconds.<BR>\n\t\t\tit will not cure them or allow them to be cured.<BR>\n\t\tIt can be administered to a non-dying patient<BR>\n\t\t\tbut the chemicals disappear just as fast.<BR>\n\tMorphine T#054:<BR>\n\t\t5 units will induce precisely 1 minute of sleep.<BR>\n\t\t\tThe effect are cumulative.<BR>\n\t\tWARNING: It is a crime to use this without authorization"
/obj/item/paper/fluff/jobs/medical/hippocratic
name = "paper- 'Hippocratic Oath'"
info = {"<i>I swear to fulfill, to the best of my ability and judgment, this covenant:
<br>
I will respect the hard-won scientific gains of those physicians in whose steps I walk,
and gladly share such knowledge as is mine with those who are to follow.
<br>
I will apply, for the benefit of the sick, all measures that are required,
avoiding those twin traps of overtreatment and therapeutic nihilism.
<br>
I will remember that there is art to medicine as well as science,
and that warmth, sympathy, and understanding may outweigh the surgeon's knife or the chemist's drug.
<br>
I will not be ashamed to say "I know not,"
nor will I fail to call in my colleagues when the skills of another are needed for a patient's recovery.
<br>
I will respect the privacy of my patients, for their problems are not disclosed to me that the world may know. Most especially must I tread with care in matters of life and death.
If it is given me to save a life, all thanks. But it may also be within my power to take a life;
this awesome responsibility must be faced with great humbleness and awareness of my own frailty. Above all, I must not play at God.
<br>
I will remember that I do not treat a fever chart, a cancerous growth, but a sick human being, whose illness may affect the person's family and economic stability.
My responsibility includes these related problems, if I am to care adequately for the sick.
<br>
I will prevent disease whenever I can, for prevention is preferable to cure.
<br>
I will remember that I remain a member of society, with special obligations to all my fellow human beings,
those sound of mind and body as well as the infirm.
<br>
If I do not violate this oath, may I enjoy life and art, respected while I live and remembered with affection thereafter.
May I always act so as to preserve the finest traditions of my calling and may I long experience the joy of healing those who seek my help.
</i>"}
/*
* Stations
*/
////////// cogstation.
/obj/item/paper/guides/cogstation/job_changes
name = "MEMO: Job Changes"
info = "To ensure minimal employee downtime, please take note of the following changes to select professions that CogStation specifically requires:<BR>\n<BR>\n- Engineers and Atmospheric Technicians <I>are</I> to have Warehouse and Mining access. <BR>\n- The Cook should <I>not</I> have Morgue access. <BR>\n- The Clown and Mime <I>are</I> to have Maintenance access. This is necessary due to the location of their offices.<BR>\n<BR>\n<I>Generated by Organic Resources Bot #2053</I>"
info = "To ensure minimal employee downtime, please take note of the following changes to select professions that CogStation specifically requires:<BR>\n<BR>\n- Scientists <I>are</I> to have access to chemistry in order to reach the MedSci router.<BR>\n<BR>\n- Chemists should at the very least be provided with an encryption key for the Science channel, if not basic access to the Research department at large. <BR>\n- Roboticists are to have <B>basic Medical and Morgue access</B>. <BR>\n- Engineers and Atmospheric Technicians <I>are</I> to have Warehouse and Mining access.<BR>\n- The Cook should <I>not</I> have Morgue access <BR>\n- The Clown and Mime <I>are</I> to have Maintenance access. This is necessary due to the location of their offices.<BR>\n<BR>\n<I>Generated by Organic Resources Bot #2053</I>"
/obj/item/paper/guides/cogstation/letter_sec
name = "To future Security personnel"
@@ -106,7 +104,7 @@
/obj/item/paper/guides/cogstation/disposals
name = "Regarding the disposal system:"
info = "As you might have noticed, this station has far more disposal pipes than you may expect from your average Nanotrasen research facility. Part of the reason for this is specialization - mail, trash, even corpses have their own disposal systems. Unfortunately, the convenient color-coding was lost in translocation and we've had to compensate by marking the area around each bin. <BR>\n<BR>\n- <B>WHITE/GRAY STRIPES are for DELIVERIES. <BR>\n- RED STRIPES are for CORPSES. <BR>\n- EVERYTHING ELSE is for TRASH,</B> barring a few exceptions that should be labeled as such. <BR>\n<BR>\nIdeally the station won't sustain any heavy structural damage during your time here but if it does, or someone decides to tamper with/sabotage this system, you'll be forgiven if you can't put it back together perfectly. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>Architectural Analyst"
info = "As you might have noticed, this station has far more disposal pipes than you may expect from your average Nanotrasen research facility. Part of the reason for this is specialization - mail, trash, even corpses have their own disposal systems. Unfortunately, the convenient color-coding was lost in translocation and we've had to compensate by marking the area around each bin. <BR>\n<BR>\n- <B>WHITE/GRAY STRIPES is for DELIVERIES. <BR>\n- RED STRIPES is for CORPSES. <BR>\n- EVERYTHING ELSE is for TRASH,</B> barring a few exceptions that should be labeled as such. <BR>\n<BR>\nIdeally the station won't sustain any heavy structural damage during your time here but if it does, or someone decides to tamper with/sabotage this system, you'll be forgiven if you can't put it back together perfectly. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>Architectural Analyst"
/obj/item/paper/guides/cogstation/janitor
name = "a quick tip"
@@ -130,7 +128,7 @@
/obj/item/paper/guides/cogstation/letter_eng
name = "To future Engineering staff:"
info = "I'm not gonna sugarcoat this. Compared to other departments, <I>you might have your work cut out for you.</I> CogStation is an entirely different beast than your standard Box, but everyone's still gonna expect you to keep the place running. <BR>\n<BR>\n If there's any good news, <B>it's your time to shine if you know how to run a thermo-electric generator.</B> That's what this station runs on, and that isn't likely to change anytime soon. If it's absolutely critical you <I>might</I> be able to run a singularity or tesla engine east of mining, but it won't have any sort of protection out there. <BR>\n<BR>\n<B>You still have three solar arrays to work with,</B> two of them being on each end of the starboard side. The port side array will need you to either get access from a head of staff or security, unless you want to spacewalk around the whole station. Don't be afraid to ask the latter - they're there for you, after all. As for other utilities <B>the air system is a bit different than you'd expect</B>, but fortunately you should have the atmos techs this station needed a long time ago. <B>The disposal network is significantly more complicated, yet more capable.</B> I've already elaborated on it, so I'll let you find and read my write-up for that. <B>As for the routing system,</B> it's just begging to get hit by a stray meteor so <B>consider other utilities a higher priority.</B> <BR>\n<BR>\nGood luck. You're gonna need it. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>Architectural Analyst"
info = "I'm not gonna sugarcoat this. Compared to other departments, <I>you might have your work cut out for you.</I> CogStation is an entirely different beast than your standard Box, but everyone's still gonna expect you to keep the place running. <BR>\n<BR>\n If there's any good news, <B>it's your time to shine if you know how to run a thermo-electric generator.</B> That's what this station runs on, and that isn't likely to change anytime soon. If it's absolutely critical you <I>might</I> be able to run a singularity or tesla engine east of mining, but it won't have any sort of shielding out there. <BR>\n<BR>\n<B>You still have three solar arrays to work with,</B> two of them being on each end of the starboard side. The port side array will need you to either get access from a head of staff or security, unless you want to spacewalk around the whole station. Don't be afraid to ask the latter - they're there for you, after all. As for other utilities <B>the air system is a bit different than you'd expect</B>, but fortunately you should have the atmos techs this station needed a long time ago. <B>The disposal network is significantly more complicated, yet more capable.</B> I've already elaborated on it, so I'll let you find and read my write-up for that. <B>As for the routing system,</B> it's just begging to get hit by a stray meteor so <B>consider other utilities a higher priority.</B> <BR>\n<BR>\nGood luck. You're gonna need it. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>Architectural Analyst"
/obj/item/paper/guides/cogstation/letter_atmos
name = "To future Atmospheric Technicians:"
@@ -142,15 +140,15 @@
/obj/item/paper/guides/cogstation/letter_hos
name = "To the future HoS"
info = "I'm gonna be rather disappointed if Central Command doesn't brief you about this station, but if they don't <B>I wrote up another letter for your department that should cover it pretty well.</B> Make sure your officers read it if they aren't up to speed. <BR>\n<BR>\nSomething you in particular should know is that if someone's getting to be too much to handle, the boys and I have constructed a 'discount transfer centre' just behind the router. <B>Use it only as a last resort</B> - the walls may be reinforced but they're still thin, and you'll have big trouble on your hands if the AI or any cyborgs find out about it. <BR>\n<BR><I>-LC</I>"
info = "I'm gonna be rather disappointed if CentCom doesn't brief you about this station, but if they don't <B>I wrote up another letter for your department that should cover it pretty well.</B> Make sure your officers read it if they aren't up to speed. <BR>\n<BR>\nSomething you in particular should know is that if someone's getting to be too much to handle, the boys and I have constructed a 'discount transfer centre' just behind the router. <B>Use it only as a last resort</B> - the walls may be reinforced but they're still thin, and you'll have big trouble on your hands if the AI or any cyborgs find out about it. <BR>\n<BR><I>-LC</I>"
/obj/item/paper/guides/cogstation/letter_supp
name = "To future Supply Staff:"
info = "Cargo, move freight. Miners, don't die. Your jobs are pretty straightforward, which is likely why they originally fell under Engineering on this station as opposed to their own department. Although we've considerably readjusted this part of the station to accommodate you, there are potential differences you should be aware of.<BR>\n<BR>\nEngineering<I>will</I> have access to some of your department, namely the warehouse and mining dock. Mining operations on this station were originally asteroid-based, hence the catwalk into the great beyond. Although you won't need to worry about being space-worthy due to a newly installed shuttle dock, they might need to get out there. <BR>\n<BR>\nYou'll have all your usual means of shipping out goods, but the disposal network is more complex with a separate line for mail and trash. It also isn't fully space-proofed, meanin it may not be the best choice for livestock, monkey cubes, or clowns. I've left another note that explains this in detail, but know trash is the janitor's responsibility, not yours. <BR>\n<BR>\nThe biggest difference has to be this station's router system, which allows departments to ship goods between themselves. Even if the belts aren't working properly they'll still have their own request consoles, so you'll want to check for orders regularly. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>\nArchitectural Analyst"
info = "Cargo, move freight. Miners, don't die. Your jobs are pretty straightforward, which is likely why they originally fell under Engineering on this station as opposed to their own department. Although we've considerably readjusted this part of the station to accommodate you, there are potential differences you should be aware of.<BR>\n<BR>\nEngineering<I>will</I> have access to some of your department, namely the warehouse and mining dock. Mining operations on this station were originally asteroid-based, hence the catwalk into the great beyond. Although you won't need to worry about being space-worthy due to a newly installed shuttle dock, they might need to get out there. <BR>\n<BR>\nYou'll have all your usual means of shipping out goods, but the disposal network is more complex with a separate line for mail and trash. I've left another note that explains this in detail, but know trash is the janitor's responsibility, not yours. <BR>\n<BR>\nThe biggest difference has to be this station's router system, which allows departments to ship goods between themselves. Even if the belts aren't working properly they'll still have their own request consoles, so you'll want to check for orders regularly. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>\nArchitectural Analyst"
/obj/item/paper/guides/cogstation/letter_med
name = "Re: Future Medical Staff"
info = "With this station nearing approval for regular use, I've been told to consolidate anything noteworthy about its general medical department into a single document. As you may be able to guess, this is that document. <BR>\n<BR>\n- First, you should know a <B>medical clinic is present in the civilian (starboard bow) wing.</B> If you have personnel to spare, it's recommended you have someone staff it - that way people with minor injuries can report there instead of clogging up the research wing. <BR>\n<BR>\n- Despite recent renovations to bring this station in line with regional policy, you'll still find the robotics lab directly adjacent to your department. <B>I advise you take full advantage of this,</B> whether it's requesting prosthetics in advance or harvesting organs from those who have undergone more...permanent procedures. <BR>\n<BR>\n- Lastly, <B>please make a habit of checking the morgue on a regular basis.</B> Thanks to the Corpse Disposal Network (or CDN for short), you may find the station's deceased delivered directly to you. Some may be employees capable of being revived - more information can be found in the morgue itself. <BR>\n<BR>\n<I>- Dr. Halley</I>"
/obj/item/paper/fluff/cogstation/sleepers
name = "Re: Sleepers?"
info = "Yes, the sleepers are meant to be publicly accessible. Policies in this station's original location encouraged crew to visit the clinic or treat themselves when it came to minor injuries. <BR>\n<BR>\n<B>This is no excuse for you not to do your jobs.</B> You may wish to keep an eye on the sleepers as to ensure they're being used responsibly. Remember, allowing an overdose to happen under your watch isn't much different from administering that overdose yourself. <BR>\n<BR>\n<I>- Dr. Halley</I>"
/obj/item/paper/fluff/cogstation/cloner
name = "Re: Issue with the cloner?"
@@ -174,7 +172,7 @@
/obj/item/paper/fluff/cogstation/letter_chap
name = "A message from the DHDA"
info = "Regardless of what the name leads you to believe, CogStation is neither Ratvarian in origin nor designed by members of this so-called 'clock cult'. Despite a potential common enemy and instances of exhibiting peaceful behavior, their beliefs have been labeled 'Heretical' by the Department of Higher-Dimensional Affairs and following them is grounds for immediate termination. <BR>\nAs the station's designated Chaplain, it is advised you correct anyone who claims this station and/or its designers are Ratvarian. While they are most likely misinformed or 'joking around', untruths gain credibility the more they are repeated. <BR>\n<BR>\n<I>Soulstone Obelisk</I> <BR>\n<BR>\nDepartment of Higher-Dimensional Affairs"
info = "Regardless of what the name leads you to believe, CogStation is neither Ratvarian in origin nor designed by members of this so-called 'clock cult'. Despite a potential common enemy and instances of exhibiting peaceful behavior, their beliefs have been labeled 'Heretical' by the Department of Higher-Dimensional Affairs and following them is grounds for immediate termination. <BR>\nAs the station's designated Chaplain, it is advised you correct anyone who claims this station and/or its designers are Ratvarian. While they are most likely misinformed or 'joking around', untruths gain credibility the more they are repeated. <BR>\n<BR>\n<I>Soulstone Obelisk</I> <BR>\n<BR>\nDepartment of Higher-Dimensional Affairs"
/obj/item/paper/fluff/cogstation/cluwne
name = "Mysterious Note"
@@ -186,7 +184,7 @@
/obj/item/paper/fluff/cogstation/eva
name = "MEMO: Spacesuits"
info = "As a Head of Personnel, you may be familiar with crew members requesting EVA access, particularly when there is an absence of credible threats on the station. While it is your decision to grant or deny access unless overriden by your superior(s), you should be aware of an abundance of spacesuits on this station. While intended for emergencies, these suits are cheaper to replace. You may find it beneficial to direct aspiring 'space explorers' towards finding one of these suits instead, although it is advised you order replacement suits in advance through the cargo department. <BR>\n<BR>\n<I>Generated by Organic Resources Bot #2053</I>"
info = "As a Head of Personnel, you may be familiar with crew members requesting EVA access, particularly when there is an absence of credible threats on the station. While it is your decision to grant or deny access unless overriden by your superior(s), you should be aware of an abundance of spacesuits on this station. While intended for emergencies, these suits are cheaper to replace. You may find it beneficial to direct aspiring 'space explorers' towards finding one of these suits instead, although it is advised you order replacement suits in advance through the cargo department. <BR>\n<BR>\n-Generated by Organic Resources Bot #2053"
/obj/item/paper/fluff/cogstation/chemists
name = "Re: Scientists?!"
@@ -216,9 +214,9 @@
name = "ROUTER STATUS: LIMITED"
info = "Currently, this router cannot receive deliveries from the Airbridge, MedSci, Security, or Service Routers. Cargo and the recycler are the only points currently accepting deliveries from here, although manual input from the routing depot is currently required. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>\n<BR>\nArchitectural Analyst"
/obj/item/paper/fluff/cogstation/mulebot
name = "MEMO: MULEbots"
info = "As you may know, MULEbots have been coded to minimize travel distance for maximum efficiency. In the case of this station, that may include travelling through depressurized areas exposed to space. Please bear this in mind before using them to transport living tissue. <BR>\n<BR>\n<I>Generated by Organic Resources Bot #2053</I>"
/obj/item/paper/fluff/cogstation/router_cargo
name = "ROUTER STATUS: VERY LIMITED"
info = "Currently, this router cannot receive deliveries from the Airbridge, MedSci, Security, or Service Routers. It is not yet capable of making deliveries, beyond sending items to the recycler. <BR>\n<BR>\n<I>-C. Donnelly</I> <BR>\n<BR>\nArchitectural Analyst"
/////////// CentCom
+10 -18
View File
@@ -4,7 +4,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper_bin1"
item_state = "sheet-metal"
// inhand_icon_state = "sheet-metal"
lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi'
throwforce = 0
@@ -44,7 +43,6 @@
..()
/obj/item/paper_bin/MouseDrop(atom/over_object)
. = ..()
var/mob/living/M = usr
if(!istype(M) || M.incapacitated() || !Adjacent(M))
return
@@ -56,18 +54,17 @@
var/obj/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
else
. = ..()
add_fingerprint(M)
/obj/item/paper_bin/attack_paw(mob/user)
return attack_hand(user)
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/paper_bin/on_attack_hand(mob/user)
if(isliving(user))
var/mob/living/L = user
if(!(L.mobility_flags & MOBILITY_PICKUP))
return
// user.changeNext_move(CLICK_CD_MELEE)
/obj/item/paper_bin/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.lying)
return
if(bin_pen)
var/obj/item/pen/P = bin_pen
P.add_fingerprint(user)
@@ -88,8 +85,8 @@
P = new papertype(src)
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(30))
P.info = "<font face=\"[CRAYON_FONT]\" color=\"red\"><b>HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK<br>APRIL FOOLS</b></font>"
P.AddComponent(/datum/component/honkspam)
P.info = "*HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK*\n*APRIL FOOLS*\n"
P.rigged = 1
P.add_fingerprint(user)
P.forceMove(user.loc)
@@ -151,7 +148,8 @@
papertype = /obj/item/paper/natural
resistance_flags = FLAMMABLE
/obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user)
/obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
..()
if(total_paper < 1)
qdel(src)
@@ -175,9 +173,3 @@
qdel(src)
else
..()
/obj/item/paper_bin/carbon
name = "carbon paper bin"
desc = "Contains all the paper you'll ever need, in duplicate!"
icon_state = "paper_bin_carbon"
papertype = /obj/item/paper/carbon
+28 -24
View File
@@ -1,9 +1,9 @@
/obj/item/paperplane
name = "paper plane"
desc = "Paper, folded in the shape of a plane."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paperplane"
// custom_fire_overlay = "paperplane_onfire"
throw_range = 7
throw_speed = 1
throwforce = 0
@@ -11,7 +11,7 @@
resistance_flags = FLAMMABLE
max_integrity = 50
var/hit_probability = 2 //%
var/hit_probability = 2//%
var/obj/item/paper/internalPaper
/obj/item/paperplane/origami
@@ -41,13 +41,6 @@
qdel(src)
return ..()
/obj/item/paperplane/Exited(atom/movable/AM, atom/newLoc)
. = ..()
if (AM == internalPaper)
internalPaper = null
if(!QDELETED(src))
qdel(src)
/obj/item/paperplane/Destroy()
QDEL_NULL(internalPaper)
return ..()
@@ -78,19 +71,31 @@
user.put_in_hands(internal_paper_tmp)
/obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params)
if(burn_paper_product_attackby_check(P, user))
return
..()
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
to_chat(user, "<span class='warning'>You should unfold [src] before changing it!</span>")
to_chat(user, "<span class='notice'>You should unfold [src] before changing it.</span>")
return
else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane
internalPaper.attackby(P, user) //spoofed attack to update internal paper.
update_icon()
add_fingerprint(user)
return
return ..()
else if(P.get_temperature())
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
user.visible_message("<span class='warning'>[user] accidentally ignites [user.p_them()]self!</span>", \
"<span class='userdanger'>You miss [src] 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/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback)
@@ -107,28 +112,26 @@
if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman
return
var/mob/living/carbon/human/H = hit_atom
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
if(prob(hit_probability))
if(H.is_eyes_covered())
return
visible_message("<span class='danger'>\The [src] hits [H] in the eye[eyes ? "" : " socket"]!</span>")
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
visible_message("<span class='danger'>\The [src] hits [H] in the eye!</span>")
H.adjust_blurriness(6)
eyes?.applyOrganDamage(rand(6,8))
if(eyes)
eyes.applyOrganDamage(rand(6,8))
H.DefaultCombatKnockdown(40)
H.emote("scream")
/obj/item/paper/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click [src] to fold it into a paper plane.</span>"
/obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK))
return
if(istype(src, /obj/item/paper/carbon))
var/obj/item/paper/carbon/Carbon = src
if(!Carbon.iscopy && !Carbon.copied)
to_chat(user, "<span class='notice'>Take off the carbon copy first.</span>")
return
to_chat(user, "<span class='notice'>You fold [src] into the shape of a plane!</span>")
user.temporarilyRemoveItemFromInventory(src)
var/obj/item/paperplane/plane_type = /obj/item/paperplane
@@ -139,3 +142,4 @@
I = new plane_type(user, src)
user.put_in_hands(I)
return TRUE
+13 -42
View File
@@ -16,8 +16,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "pen"
item_state = "pen"
// inhand_icon_state = "pen"
// worn_icon_state = "pen"
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS
throwforce = 0
w_class = WEIGHT_CLASS_TINY
@@ -78,22 +76,6 @@
icon_state = "pen-fountain"
font = FOUNTAIN_PEN_FONT
/obj/item/pen/charcoal
name = "charcoal stylus"
desc = "It's just a wooden stick with some compressed ash on the end. At least it can write."
icon_state = "pen-charcoal"
colour = "dimgray"
font = CHARCOAL_FONT
custom_materials = null
grind_results = list(/datum/reagent/ash = 5, /datum/reagent/cellulose = 10)
/datum/crafting_recipe/charcoal_stylus
name = "Charcoal Stylus"
result = /obj/item/pen/charcoal
reqs = list(/obj/item/stack/sheet/mineral/wood = 1, /datum/reagent/ash = 30)
time = 30
category = CAT_PRIMAL
/obj/item/pen/fountain/captain
name = "captain's fountain pen"
desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
@@ -111,7 +93,6 @@
"Black and Silver" = "pen-fountain-b",
"Command Blue" = "pen-fountain-cb"
)
embedding = list("embed_chance" = 75)
/obj/item/pen/fountain/captain/Initialize()
. = ..()
@@ -158,18 +139,20 @@
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
return
if(oldname == input)
to_chat(user, "<span class='notice'>You changed \the [O.name] to... well... \the [O.name].</span>")
to_chat(user, "You changed \the [O.name] to... well... \the [O.name].")
else
O.name = input
to_chat(user, "<span class='notice'>\The [oldname] has been successfully been renamed to \the [input].</span>")
to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].")
O.renamedByPlayer = TRUE
log_game("[user] [key_name(user)] has renamed [O] to [input]")
if(penchoice == "Change description")
var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 100)
var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 2048)
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
return
O.desc = input
to_chat(user, "<span class='notice'>You have successfully changed \the [O.name]'s description.</span>")
to_chat(user, "You have successfully changed \the [O.name]'s description.")
log_game("[user] [key_name(user)] has changed [O]'s description to to [input]")
/*
* Sleepypens
@@ -198,10 +181,9 @@
*/
/obj/item/pen/edagger
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off
// attack_verb_continuous = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") //these won't show up if the pen is off
// attack_verb_simple = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
sharpness = SHARP_EDGED
var/on = FALSE
embedding = list(embed_chance = EMBED_CHANCE)
/obj/item/pen/edagger/ComponentInitialize()
. = ..()
@@ -211,38 +193,29 @@
/obj/item/pen/edagger/get_sharpness()
return on * sharpness
/obj/item/pen/edagger/suicide_act(mob/user)
. = BRUTELOSS
if(on)
user.visible_message("<span class='suicide'>[user] forcefully rams the pen into their mouth!</span>")
else
user.visible_message("<span class='suicide'>[user] is holding a pen up to their mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
attack_self(user)
/obj/item/pen/edagger/attack_self(mob/living/user)
if(on)
on = FALSE
force = initial(force)
throw_speed = initial(throw_speed)
w_class = initial(w_class)
name = initial(name)
hitsound = initial(hitsound)
embedding = list(embed_chance = EMBED_CHANCE)
embedding = null
throwforce = initial(throwforce)
playsound(user, 'sound/weapons/saberoff.ogg', 5, TRUE)
playsound(user, 'sound/weapons/saberoff.ogg', 5, 1)
to_chat(user, "<span class='warning'>[src] can now be concealed.</span>")
updateEmbedding()
else
on = TRUE
force = 18
throw_speed = 4
w_class = WEIGHT_CLASS_NORMAL
name = "energy dagger"
hitsound = 'sound/weapons/blade1.ogg'
embedding = list(embed_chance = 100) //rule of cool
embedding = list(embed_chance = 100, fall_chance = 0) //rule of cool
throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, TRUE)
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
to_chat(user, "<span class='warning'>[src] is now active.</span>")
updateEmbedding()
updateEmbedding()
update_icon()
/obj/item/pen/edagger/update_icon_state()
@@ -262,8 +235,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "digging_pen"
item_state = "pen"
// inhand_icon_state = "pen"
// worn_icon_state = "pen"
force = 3
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10)
+210 -370
View File
@@ -1,20 +1,12 @@
/* Photocopiers!
* Contains:
* Photocopier
* Toner Cartridge
*/
/// For use with the `color_mode` var. Photos will be printed in greyscale while the var has this value.
#define PHOTO_GREYSCALE "Greyscale"
/// For use with the `color_mode` var. Photos will be printed in full color while the var has this value.
#define PHOTO_COLOR "Color"
/// How much toner is used for making a copy of a paper.
#define PAPER_TONER_USE 0.125
/// How much toner is used for making a copy of a photo.
#define PHOTO_TONER_USE 0.625
/// How much toner is used for making a copy of a document.
#define DOCUMENT_TONER_USE 0.75
/// How much toner is used for making a copy of an ass.
#define ASS_TONER_USE 0.625
/// The maximum amount of copies you can make with one press of the copy button.
#define MAX_COPIES_AT_ONCE 10
/*
* Photocopier
*/
/obj/machinery/photocopier
name = "photocopier"
desc = "Used to copy important documents and anatomy studies."
@@ -27,316 +19,183 @@
power_channel = EQUIP
max_integrity = 300
integrity_failure = 0.33
/// A reference to an `/obj/item/paper` inside the copier, if one is inserted. Otherwise null.
var/obj/item/paper/paper_copy
/// A reference to an `/obj/item/photo` inside the copier, if one is inserted. Otherwise null.
var/obj/item/photo/photo_copy
/// A reference to an `/obj/item/documents` inside the copier, if one is inserted. Otherwise null.
var/obj/item/documents/document_copy
/// A reference to a mob on top of the photocopier trying to copy their ass. Null if there is no mob.
var/mob/living/ass
/// A reference to the toner cartridge that's inserted into the copier. Null if there is no cartridge.
var/obj/item/toner/toner_cartridge
/// How many copies will be printed with one click of the "copy" button.
var/num_copies = 1
/// Used with photos. Determines if the copied photo will be in greyscale or color.
var/color_mode = PHOTO_COLOR
/// Indicates whether the printer is currently busy copying or not.
var/obj/item/paper/copy = null //what's in the copier!
var/obj/item/photo/photocopy = null
var/obj/item/documents/doccopy = null
var/copies = 1 //how many copies to print!
var/toner = 40 //how much toner is left! woooooo~
var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
var/greytoggle = "Greyscale"
var/mob/living/ass //i can't believe i didn't write a stupid-ass comment about this var when i first coded asscopy.
var/busy = FALSE
/obj/machinery/photocopier/Initialize()
/obj/machinery/photocopier/ui_interact(mob/user)
. = ..()
//AddComponent(/datum/component/payment, 5, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL)
toner_cartridge = new(src)
/obj/machinery/photocopier/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Photocopier")
ui.open()
/obj/machinery/photocopier/ui_data(mob/user)
var/list/data = list()
data["has_item"] = !copier_empty()
data["num_copies"] = num_copies
if(photo_copy)
data["is_photo"] = TRUE
data["color_mode"] = color_mode
var/list/dat = list("Photocopier<BR><BR>")
if(copy || photocopy || doccopy || (ass && (ass.loc == src.loc)))
dat += "<a href='byond://?src=[REF(src)];remove=1'>Remove Paper</a><BR>"
if(toner)
dat += "<a href='byond://?src=[REF(src)];copy=1'>Copy</a><BR>"
dat += "Printing: [copies] copies."
dat += "<a href='byond://?src=[REF(src)];min=1'>-</a> "
dat += "<a href='byond://?src=[REF(src)];add=1'>+</a><BR><BR>"
if(photocopy)
dat += "Printing in <a href='byond://?src=[REF(src)];colortoggle=1'>[greytoggle]</a><BR><BR>"
else if(toner)
dat += "Please insert paper to copy.<BR><BR>"
if(isAI(user))
data["isAI"] = TRUE
data["can_AI_print"] = toner_cartridge ? toner_cartridge.charges >= PHOTO_TONER_USE : FALSE
else
data["isAI"] = FALSE
dat += "<a href='byond://?src=[REF(src)];aipic=1'>Print photo from database</a><BR><BR>"
dat += "Current toner level: [toner]"
if(!toner)
dat +="<BR>Please insert a new toner cartridge!"
user << browse(dat.Join(""), "window=copier")
onclose(user, "copier")
if(toner_cartridge)
data["has_toner"] = TRUE
data["current_toner"] = toner_cartridge.charges
data["max_toner"] = toner_cartridge.max_charges
data["has_enough_toner"] = has_enough_toner()
else
data["has_toner"] = FALSE
data["has_enough_toner"] = FALSE
return data
/obj/machinery/photocopier/ui_act(action, list/params)
/obj/machinery/photocopier/Topic(href, href_list)
if(..())
return
switch(action)
// Copying paper, photos, documents and asses.
if("make_copy")
if(busy)
to_chat(usr, "<span class='warning'>[src] is currently busy copying something. Please wait until it is finished.</span>")
return FALSE
if(paper_copy)
if(!length(paper_copy.info))
to_chat(usr, "<span class='warning'>An error message flashes across [src]'s screen: \"The supplied paper is blank. Aborting.\"</span>")
return FALSE
// Basic paper
if(istype(paper_copy, /obj/item/paper))
do_copy_loop(CALLBACK(src, .proc/make_paper_copy), usr)
return TRUE
// Devil contract paper.
if(istype(paper_copy, /obj/item/paper/contract/employment))
do_copy_loop(CALLBACK(src, .proc/make_devil_paper_copy), usr)
return TRUE
// Copying photo.
if(photo_copy)
do_copy_loop(CALLBACK(src, .proc/make_photo_copy), usr)
return TRUE
// Copying Documents.
if(document_copy)
do_copy_loop(CALLBACK(src, .proc/make_document_copy), usr)
return TRUE
// ASS COPY. By Miauw
if(ass)
do_copy_loop(CALLBACK(src, .proc/make_ass_copy), usr)
return TRUE
// Remove the paper/photo/document from the photocopier.
if("remove")
if(paper_copy)
remove_photocopy(paper_copy, usr)
paper_copy = null
else if(photo_copy)
remove_photocopy(photo_copy, usr)
photo_copy = null
else if(document_copy)
remove_photocopy(document_copy, usr)
document_copy = null
else if(check_ass())
to_chat(ass, "<span class='notice'>You feel a slight pressure on your ass.</span>")
return TRUE
// AI printing photos from their saved images.
if("ai_photo")
if(busy)
to_chat(usr, "<span class='warning'>[src] is currently busy copying something. Please wait until it is finished.</span>")
return FALSE
if(href_list["copy"])
if(copy)
for(var/i = 0, i < copies, i++)
if(toner > 0 && !busy && copy)
var/copy_as_paper = 1
if(istype(copy, /obj/item/paper/contract/employment))
var/obj/item/paper/contract/employment/E = copy
var/obj/item/paper/contract/employment/C = new /obj/item/paper/contract/employment (loc, E.target.current)
if(C)
copy_as_paper = 0
if(copy_as_paper)
var/obj/item/paper/c = new /obj/item/paper (loc)
if(length(copy.info) > 0) //Only print and add content if the copied doc has words on it
if(toner > 10) //lots of toner, make it dark
c.info = "<font color = #101010>"
else //no toner? shitty copies for you!
c.info = "<font color = #808080>"
var/copied = copy.info
copied = replacetext(copied, "<font face=\"[PEN_FONT]\" color=", "<font face=\"[PEN_FONT]\" nocolor=") //state of the art techniques in action
copied = replacetext(copied, "<font face=\"[CRAYON_FONT]\" color=", "<font face=\"[CRAYON_FONT]\" nocolor=") //This basically just breaks the existing color tag, which we need to do because the innermost tag takes priority.
c.info += copied
c.info += "</font>"
c.name = copy.name
c.update_icon()
c.stamps = copy.stamps
if(copy.stamped)
c.stamped = copy.stamped.Copy()
c.copy_overlays(copy, TRUE)
toner--
busy = TRUE
addtimer(CALLBACK(src, .proc/reset_busy), 1.5 SECONDS)
else
break
updateUsrDialog()
else if(photocopy)
for(var/i = 0, i < copies, i++)
if(toner >= 5 && !busy && photocopy) //Was set to = 0, but if there was say 3 toner left and this ran, you would get -2 which would be weird for ink
new /obj/item/photo (loc, photocopy.picture.Copy(greytoggle == "Greyscale"? TRUE : FALSE))
busy = TRUE
addtimer(CALLBACK(src, .proc/reset_busy), 1.5 SECONDS)
else
break
else if(doccopy)
for(var/i = 0, i < copies, i++)
if(toner > 5 && !busy && doccopy)
new /obj/item/documents/photocopy(loc, doccopy)
toner-= 6 // the sprite shows 6 papers, yes I checked
busy = TRUE
addtimer(CALLBACK(src, .proc/reset_busy), 1.5 SECONDS)
else
break
updateUsrDialog()
else if(ass) //ASS COPY. By Miauw
for(var/i = 0, i < copies, i++)
var/icon/temp_img
if(ishuman(ass) && (ass.get_item_by_slot(ITEM_SLOT_ICLOTHING) || ass.get_item_by_slot(ITEM_SLOT_OCLOTHING)))
to_chat(usr, "<span class='notice'>You feel kind of silly, copying [ass == usr ? "your" : ass][ass == usr ? "" : "\'s"] ass with [ass == usr ? "your" : "[ass.p_their()]"] clothes on.</span>" )
break
else if(toner >= 5 && !busy && check_ass()) //You have to be sitting on the copier and either be a xeno or a human without clothes on.
if(isalienadult(ass) || istype(ass, /mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro.
temp_img = icon('icons/ass/assalien.png')
else if(ishuman(ass)) //Suit checks are in check_ass
temp_img = icon(ass.gender == FEMALE ? 'icons/ass/assfemale.png' : 'icons/ass/assmale.png')
else if(isdrone(ass)) //Drones are hot
temp_img = icon('icons/ass/assdrone.png')
else
break
busy = TRUE
sleep(15)
var/obj/item/photo/p = new /obj/item/photo (loc)
var/datum/picture/toEmbed = new(name = "[ass]'s Ass", desc = "You see [ass]'s ass on the photo.", image = temp_img)
p.pixel_x = rand(-10, 10)
p.pixel_y = rand(-10, 10)
toEmbed.psize_x = 128
toEmbed.psize_y = 128
p.set_picture(toEmbed, TRUE, TRUE)
toner -= 5
busy = FALSE
else
break
updateUsrDialog()
else if(href_list["remove"])
if(copy)
remove_photocopy(copy, usr)
copy = null
else if(photocopy)
remove_photocopy(photocopy, usr)
photocopy = null
else if(doccopy)
remove_photocopy(doccopy, usr)
doccopy = null
else if(check_ass())
to_chat(ass, "<span class='notice'>You feel a slight pressure on your ass.</span>")
updateUsrDialog()
else if(href_list["min"])
if(copies > 1)
copies--
updateUsrDialog()
else if(href_list["add"])
if(copies < maxcopies)
copies++
updateUsrDialog()
else if(href_list["aipic"])
if(!isAI(usr))
return
if(toner >= 5 && !busy)
var/mob/living/silicon/ai/tempAI = usr
if(!length(tempAI.aicamera.stored))
to_chat(usr, "<span class='boldannounce'>No images saved.</span>")
if(tempAI.aicamera.stored.len == 0)
to_chat(usr, "<span class='boldannounce'>No images saved</span>")
return
var/datum/picture/selection = tempAI.aicamera.selectpicture(usr)
var/obj/item/photo/photo = new(loc, selection) // AI prints color photos only.
give_pixel_offset(photo)
toner_cartridge.charges -= PHOTO_TONER_USE
return TRUE
var/obj/item/photo/photo = new(loc, selection)
photo.pixel_x = rand(-10, 10)
photo.pixel_y = rand(-10, 10)
toner -= 5 //AI prints color pictures only, thus they can do it more efficiently
busy = TRUE
addtimer(CALLBACK(src, .proc/reset_busy), 1.5 SECONDS)
updateUsrDialog()
else if(href_list["colortoggle"])
if(greytoggle == "Greyscale")
greytoggle = "Color"
else
greytoggle = "Greyscale"
updateUsrDialog()
// Switch between greyscale and color photos
if("color_mode")
if(params["mode"] in list(PHOTO_GREYSCALE, PHOTO_COLOR))
color_mode = params["mode"]
return TRUE
// Remove the toner cartridge from the copier.
if("remove_toner")
if(issilicon(usr) || (ishuman(usr) && !usr.put_in_hands(toner_cartridge)))
toner_cartridge.forceMove(drop_location())
toner_cartridge = null
return TRUE
// Set the number of copies to be printed with 1 click of the "copy" button.
if("set_copies")
num_copies = clamp(text2num(params["num_copies"]), 1, MAX_COPIES_AT_ONCE)
return TRUE
/**
* Determines if the photocopier has enough toner to create `num_copies` amount of copies of the currently inserted item.
*/
/obj/machinery/photocopier/proc/has_enough_toner()
if(paper_copy)
return toner_cartridge.charges >= (PAPER_TONER_USE * num_copies)
else if(document_copy)
return toner_cartridge.charges >= (DOCUMENT_TONER_USE * num_copies)
else if(photo_copy)
return toner_cartridge.charges >= (PHOTO_TONER_USE * num_copies)
else if(ass)
return toner_cartridge.charges >= (ASS_TONER_USE * num_copies)
return FALSE
/**
* Will invoke the passed in `copy_cb` callback in 1 second intervals, and charge the user 5 credits for each copy made.
*
* Arguments:
* * copy_cb - a callback for which proc to call. Should only be one of the `make_x_copy()` procs, such as `make_paper_copy()`.
* * user - the mob who clicked copy.
*/
/obj/machinery/photocopier/proc/do_copy_loop(datum/callback/copy_cb, mob/user)
busy = TRUE
var/i
for(i in 1 to num_copies)
//if(attempt_charge(src, user) & COMPONENT_OBJ_CANCEL_CHARGE)
// break
addtimer(copy_cb, i SECONDS)
addtimer(CALLBACK(src, .proc/reset_busy), i SECONDS)
/**
* Sets busy to `FALSE`. Created as a proc so it can be used in callbacks.
*/
/obj/machinery/photocopier/proc/reset_busy()
busy = FALSE
updateUsrDialog()
/**
* Gives items a random x and y pixel offset, between -10 and 10 for each.
*
* This is done that when someone prints multiple papers, we dont have them all appear to be stacked in the same exact location.
*
* Arguments:
* * copied_item - The paper, document, or photo that was just spawned on top of the printer.
*/
/obj/machinery/photocopier/proc/give_pixel_offset(obj/item/copied_item)
copied_item.pixel_x = rand(-10, 10)
copied_item.pixel_y = rand(-10, 10)
/**
* Handles the copying of devil contract paper. Transfers all the text, stamps and so on from the old paper, to the copy.
*
* Checks first if `paper_copy` exists. Since this proc is called from a timer, it's possible that it was removed.
* Does not check if it has enough toner because devil contracts cost no toner to print.
*/
/obj/machinery/photocopier/proc/make_devil_paper_copy()
if(!paper_copy)
return
var/obj/item/paper/contract/employment/E = paper_copy
var/obj/item/paper/contract/employment/C = new(loc, E.target.current)
give_pixel_offset(C)
/**
* Handles the copying of paper. Transfers all the text, stamps and so on from the old paper, to the copy.
*
* Checks first if `paper_copy` exists. Since this proc is called from a timer, it's possible that it was removed.
*/
/obj/machinery/photocopier/proc/make_paper_copy()
if(!paper_copy)
return
var/obj/item/paper/copied_paper = new(loc)
give_pixel_offset(copied_paper)
if(toner_cartridge.charges > 10) // Lots of toner, make it dark.
copied_paper.info = "<font color = #101010>"
else // No toner? shitty copies for you!
copied_paper.info = "<font color = #808080>"
var/copied_info = paper_copy.info
copied_info = replacetext(copied_info, "<font face=\"[PEN_FONT]\" color=", "<font face=\"[PEN_FONT]\" nocolor=") //state of the art techniques in action
copied_info = replacetext(copied_info, "<font face=\"[CRAYON_FONT]\" color=", "<font face=\"[CRAYON_FONT]\" nocolor=") //This basically just breaks the existing color tag, which we need to do because the innermost tag takes priority.
copied_paper.info += copied_info
copied_paper.info += "</font>"
copied_paper.name = paper_copy.name
copied_paper.update_icon()
copied_paper.stamps = paper_copy.stamps
if(paper_copy.stamped)
copied_paper.stamped = paper_copy.stamped.Copy()
copied_paper.copy_overlays(paper_copy, TRUE)
toner_cartridge.charges -= PAPER_TONER_USE
/**
* Handles the copying of photos, which can be printed in either color or greyscale.
*
* Checks first if `photo_copy` exists. Since this proc is called from a timer, it's possible that it was removed.
*/
/obj/machinery/photocopier/proc/make_photo_copy()
if(!photo_copy)
return
var/obj/item/photo/copied_pic = new(loc, photo_copy.picture.Copy(color_mode == PHOTO_GREYSCALE ? TRUE : FALSE))
give_pixel_offset(copied_pic)
toner_cartridge.charges -= PHOTO_TONER_USE
/**
* Handles the copying of documents.
*
* Checks first if `document_copy` exists. Since this proc is called from a timer, it's possible that it was removed.
*/
/obj/machinery/photocopier/proc/make_document_copy()
if(!document_copy)
return
var/obj/item/documents/photocopy/copied_doc = new(loc, document_copy)
give_pixel_offset(copied_doc)
toner_cartridge.charges -= DOCUMENT_TONER_USE
/**
* Handles the copying of an ass photo.
*
* Calls `check_ass()` first to make sure that `ass` exists, among other conditions. Since this proc is called from a timer, it's possible that it was removed.
* Additionally checks that the mob has their clothes off.
*/
/obj/machinery/photocopier/proc/make_ass_copy()
if(!check_ass())
return
if(ishuman(ass)) //(ass.get_item_by_slot(ITEM_SLOT_ICLOTHING) || ass.get_item_by_slot(ITEM_SLOT_OCLOTHING)))
var/mob/living/carbon/C = ass //have to typecast to this, is_groin_exposed is carbon level
if(C.is_groin_exposed())
to_chat(usr, "<span class='notice'>You feel kind of silly, copying [ass == usr ? "your" : ass][ass == usr ? "" : "\'s"] ass with [ass == usr ? "your" : "[ass.p_their()]"] clothes on.</span>" )
return
var/icon/temp_img
if(isalienadult(ass) || istype(ass, /mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro.
temp_img = icon('icons/ass/assalien.png')
else if(ishuman(ass)) //Suit checks are after check_ass
temp_img = icon(ass.gender == FEMALE ? 'icons/ass/assfemale.png' : 'icons/ass/assmale.png')
else if(isdrone(ass)) //Drones are hot
temp_img = icon('icons/ass/assdrone.png')
var/obj/item/photo/copied_ass = new /obj/item/photo(loc)
var/datum/picture/toEmbed = new(name = "[ass]'s Ass", desc = "You see [ass]'s ass on the photo.", image = temp_img)
give_pixel_offset(copied_ass)
toEmbed.psize_x = 128
toEmbed.psize_y = 128
copied_ass.set_picture(toEmbed, TRUE, TRUE)
toner_cartridge.charges -= ASS_TONER_USE
/**
* Inserts the item into the copier. Called in `attackby()` after a human mob clicked on the copier with a paper, photo, or document.
*
* Arugments:
* * object - the object that got inserted.
* * user - the mob that inserted the object.
*/
/obj/machinery/photocopier/proc/do_insertion(obj/item/object, mob/user)
object.forceMove(src)
to_chat(user, "<span class='notice'>You insert [object] into [src].</span>")
/obj/machinery/photocopier/proc/do_insertion(obj/item/O, mob/user)
O.forceMove(src)
to_chat(user, "<span class='notice'>You insert [O] into [src].</span>")
flick("photocopier1", src)
updateUsrDialog()
/**
* Called when someone hits the "remove item" button on the copier UI.
*
* If the user is a silicon, it drops the object at the location of the copier. If the user is not a silicon, it tries to put the object in their hands first.
* Sets `busy` to `FALSE` because if the inserted item is removed, the copier should halt copying.
*
* Arguments:
* * object - the item we're trying to remove.
* * user - the user removing the item.
*/
/obj/machinery/photocopier/proc/remove_photocopy(obj/item/object, mob/user)
/obj/machinery/photocopier/proc/remove_photocopy(obj/item/O, mob/user)
if(!issilicon(user)) //surprised this check didn't exist before, putting stuff in AI's hand is bad
object.forceMove(user.loc)
user.put_in_hands(object)
O.forceMove(user.loc)
user.put_in_hands(O)
else
object.forceMove(drop_location())
to_chat(user, "<span class='notice'>You take [object] out of [src]. [busy ? "The [src] comes to a halt." : ""]</span>")
O.forceMove(drop_location())
to_chat(user, "<span class='notice'>You take [O] out of [src].</span>")
/obj/machinery/photocopier/attackby(obj/item/O, mob/user, params)
if(default_unfasten_wrench(user, O))
@@ -351,7 +210,7 @@
else
if(!user.temporarilyRemoveItemFromInventory(O))
return
paper_copy = O
copy = O
do_insertion(O, user)
else
to_chat(user, "<span class='warning'>There is already something in [src]!</span>")
@@ -360,7 +219,7 @@
if(copier_empty())
if(!user.temporarilyRemoveItemFromInventory(O))
return
photo_copy = O
photocopy = O
do_insertion(O, user)
else
to_chat(user, "<span class='warning'>There is already something in [src]!</span>")
@@ -369,35 +228,38 @@
if(copier_empty())
if(!user.temporarilyRemoveItemFromInventory(O))
return
document_copy = O
doccopy = O
do_insertion(O, user)
else
to_chat(user, "<span class='warning'>There is already something in [src]!</span>")
else if(istype(O, /obj/item/toner))
if(toner_cartridge)
to_chat(user, "<span class='warning'>[src] already has a toner cartridge inserted. Remove that one first.</span>")
return
O.forceMove(src)
toner_cartridge = O
to_chat(user, "<span class='notice'>You insert [O] into [src].</span>")
if(toner <= 0)
if(!user.temporarilyRemoveItemFromInventory(O))
return
qdel(O)
toner = 40
to_chat(user, "<span class='notice'>You insert [O] into [src].</span>")
updateUsrDialog()
else
to_chat(user, "<span class='warning'>This cartridge is not yet ready for replacement! Use up the rest of the toner.</span>")
else if(istype(O, /obj/item/areaeditor/blueprints))
to_chat(user, "<span class='warning'>The Blueprint is too large to put into the copier. You need to find something else to record the document.</span>")
to_chat(user, "<span class='warning'>The Blueprint is too large to put into the copier. You need to find something else to record the document</span>")
else
return ..()
/obj/machinery/photocopier/obj_break(damage_flag)
. = ..()
if(. && toner_cartridge.charges)
if(. && toner > 0)
new /obj/effect/decal/cleanable/oil(get_turf(src))
toner_cartridge.charges = 0
toner = 0
/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/user)
check_ass() //Just to make sure that you can re-drag somebody onto it after they moved off.
if(!istype(target) || target.anchored || target.buckled || !Adjacent(target) || !user.canUseTopic(src, BE_CLOSE) || target == ass || copier_blocked())
if (!istype(target) || target.anchored || target.buckled || !Adjacent(target) || !user.canUseTopic(src, BE_CLOSE) || target == ass || copier_blocked())
return
add_fingerprint(user)
src.add_fingerprint(user)
if(target == user)
user.visible_message("<span class='notice'>[user] starts climbing onto the photocopier!</span>", "<span class='notice'>You start climbing onto the photocopier...</span>")
else
@@ -415,63 +277,49 @@
target.forceMove(drop_location())
ass = target
if(photo_copy)
photo_copy.forceMove(drop_location())
visible_message("<span class='warning'>[photo_copy] is shoved out of the way by [ass]!</span>")
photo_copy = null
if(photocopy)
photocopy.forceMove(drop_location())
visible_message("<span class='warning'>[photocopy] is shoved out of the way by [ass]!</span>")
photocopy = null
else if(paper_copy)
paper_copy.forceMove(drop_location())
visible_message("<span class='warning'>[paper_copy] is shoved out of the way by [ass]!</span>")
paper_copy = null
else if(copy)
copy.forceMove(drop_location())
visible_message("<span class='warning'>[copy] is shoved out of the way by [ass]!</span>")
copy = null
updateUsrDialog()
else if(document_copy)
document_copy.forceMove(drop_location())
visible_message("<span class='warning'>[document_copy] is shoved out of the way by [ass]!</span>")
document_copy = null
/obj/machinery/photocopier/Exited(atom/movable/AM, atom/newloc)
check_ass() // There was potentially a person sitting on the copier, check if they're still there.
return ..()
/**
* Checks the living mob `ass` exists and its location is the same as the photocopier.
*
* Returns FALSE if `ass` doesn't exist or is not at the copier's location. Returns TRUE otherwise.
*/
/obj/machinery/photocopier/proc/check_ass() //I'm not sure wether I made this proc because it's good form or because of the name.
if(!ass)
return FALSE
if(ass.loc != loc)
return 0
if(ass.loc != src.loc)
ass = null
return FALSE
return TRUE
updateUsrDialog()
return 0
else if(ishuman(ass))
if(!ass.get_item_by_slot(ITEM_SLOT_ICLOTHING) && !ass.get_item_by_slot(ITEM_SLOT_OCLOTHING))
return 1
else
return 0
else
return 1
/**
* Checks if the copier is deleted, or has something dense at its location. Called in `MouseDrop_T()`
*/
/obj/machinery/photocopier/proc/copier_blocked()
if(QDELETED(src))
return
if(loc.density)
return TRUE
return 1
for(var/atom/movable/AM in loc)
if(AM == src)
continue
if(AM.density)
return TRUE
return FALSE
return 1
return 0
/**
* Checks if there is an item inserted into the copier or a mob sitting on top of it.
*
* Return `FALSE` is the copier has something inside of it. Returns `TRUE` if it doesn't.
*/
/obj/machinery/photocopier/proc/copier_empty()
if(paper_copy || photo_copy || document_copy || check_ass())
return FALSE
if(copy || photocopy || check_ass())
return 0
else
return TRUE
return 1
/*
* Toner cartridge
@@ -495,11 +343,3 @@
desc = "Why would ANYONE need THIS MUCH TONER?"
charges = 200
max_charges = 200
#undef PHOTO_GREYSCALE
#undef PHOTO_COLOR
#undef PAPER_TONER_USE
#undef PHOTO_TONER_USE
#undef DOCUMENT_TONER_USE
#undef ASS_TONER_USE
#undef MAX_COPIES_AT_ONCE
-23
View File
@@ -4,7 +4,6 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "stamp-ok"
item_state = "stamp"
// inhand_icon_state = "stamp"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
@@ -12,8 +11,6 @@
custom_materials = list(/datum/material/iron=60)
pressure_resistance = 2
attack_verb = list("stamped")
// attack_verb_continuous = list("stamps")
// attack_verb_simple = list("stamp")
/obj/item/stamp/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.</span>")
@@ -69,25 +66,5 @@
icon_state = "stamp-clown"
dye_color = DYE_CLOWN
/obj/item/stamp/mime
name = "mime's rubber stamp"
icon_state = "stamp-mime"
dye_color = DYE_MIME
/obj/item/stamp/chap
name = "chaplain's rubber stamp"
icon_state = "stamp-chap"
dye_color = DYE_CHAP
/obj/item/stamp/centcom
name = "CentCom rubber stamp"
icon_state = "stamp-centcom"
dye_color = DYE_CENTCOM
/obj/item/stamp/syndicate
name = "Syndicate rubber stamp"
icon_state = "stamp-syndicate"
dye_color = DYE_SYNDICATE
/obj/item/stamp/attack_paw(mob/user)
return attack_hand(user)
-231
View File
@@ -1,231 +0,0 @@
//Bureaucracy machine!
//Simply set this up in the hopline and you can serve people based on ticket numbers
/obj/machinery/ticket_machine
name = "ticket machine"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "ticketmachine"
desc = "A marvel of bureaucratic engineering encased in an efficient plastic shell. It can be refilled with a hand labeler refill roll and linked to buttons with a multitool."
density = FALSE
maptext_height = 26
maptext_width = 32
maptext_x = 7
maptext_y = 10
layer = HIGH_OBJ_LAYER
var/ticket_number = 0 //Increment the ticket number whenever the HOP presses his button
var/current_number = 0 //What ticket number are we currently serving?
var/max_number = 100 //At this point, you need to refill it.
var/cooldown = 50
var/ready = TRUE
var/id = "ticket_machine_default" //For buttons
var/list/ticket_holders = list()
var/list/obj/item/ticket_machine_ticket/tickets = list()
/obj/machinery/ticket_machine/multitool_act(mob/living/user, obj/item/I)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
var/obj/item/multitool/M = I
M.buffer = src
to_chat(user, "<span class='notice'>You store linkage information in [I]'s buffer.</span>")
return TRUE
/obj/machinery/ticket_machine/emag_act(mob/user) //Emag the ticket machine to dispense burning tickets, as well as randomize its number to destroy the HoP's mind.
if(obj_flags & EMAGGED)
return
to_chat(user, "<span class='warning'>You overload [src]'s bureaucratic logic circuitry to its MAXIMUM setting.</span>")
ticket_number = rand(0,max_number)
current_number = ticket_number
obj_flags |= EMAGGED
if(tickets.len)
for(var/obj/item/ticket_machine_ticket/ticket in tickets)
ticket.audible_message("<span class='notice'>\the [ticket] disperses!</span>")
qdel(ticket)
tickets.Cut()
update_icon()
/obj/machinery/ticket_machine/Initialize()
. = ..()
update_icon()
/obj/machinery/ticket_machine/proc/increment()
if(current_number > ticket_number)
return
if(current_number && !(obj_flags & EMAGGED) && tickets[current_number])
tickets[current_number].audible_message("<span class='notice'>\the [tickets[current_number]] disperses!</span>")
qdel(tickets[current_number])
if(current_number < ticket_number)
current_number ++ //Increment the one we're serving.
playsound(src, 'sound/misc/announce_dig.ogg', 50, FALSE)
say("Now serving ticket #[current_number]!")
if(!(obj_flags & EMAGGED) && tickets[current_number])
tickets[current_number].audible_message("<span class='notice'>\the [tickets[current_number]] vibrates!</span>")
update_icon() //Update our icon here rather than when they take a ticket to show the current ticket number being served
/obj/machinery/button/ticket_machine
name = "increment ticket counter"
desc = "Use this button after you've served someone to tell the next person to come forward."
device_type = /obj/item/assembly/control/ticket_machine
req_access = list()
id = "ticket_machine_default"
/obj/machinery/button/ticket_machine/Initialize()
. = ..()
if(device)
var/obj/item/assembly/control/ticket_machine/ours = device
ours.id = id
/obj/machinery/button/ticket_machine/multitool_act(mob/living/user, obj/item/I)
. = ..()
if(I.tool_behaviour == TOOL_MULTITOOL)
var/obj/item/multitool/M = I
if(M.buffer && !istype(M.buffer, /obj/machinery/ticket_machine))
return
var/obj/item/assembly/control/ticket_machine/controller = device
controller.linked = M.buffer
id = null
controller.id = null
to_chat(user, "<span class='warning'>You've linked [src] to [controller.linked].</span>")
/obj/item/assembly/control/ticket_machine
name = "ticket machine controller"
desc = "A remote controller for the HoP's ticket machine."
var/obj/machinery/ticket_machine/linked //To whom are we linked?
/obj/item/assembly/control/ticket_machine/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/item/assembly/control/ticket_machine/LateInitialize()
find_machine()
/obj/item/assembly/control/ticket_machine/proc/find_machine() //Locate the one to which we're linked
for(var/obj/machinery/ticket_machine/ticketsplease in GLOB.machines)
if(ticketsplease.id == id)
linked = ticketsplease
if(linked)
return TRUE
else
return FALSE
/obj/item/assembly/control/ticket_machine/activate()
if(cooldown)
return
if(!linked)
return
cooldown = TRUE
linked.increment()
addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10)
/obj/machinery/ticket_machine/update_icon()
switch(ticket_number) //Gives you an idea of how many tickets are left
if(0 to 49)
icon_state = "ticketmachine_100"
if(50 to 99)
icon_state = "ticketmachine_50"
if(100)
icon_state = "ticketmachine_0"
handle_maptext()
/obj/machinery/ticket_machine/proc/handle_maptext()
switch(ticket_number) //This is here to handle maptext offsets so that the numbers align.
if(0 to 9)
maptext_x = 13
if(10 to 99)
maptext_x = 10
if(100)
maptext_x = 8
maptext = "[current_number]" //Finally, apply the maptext
/obj/machinery/ticket_machine/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/hand_labeler_refill))
if(!(ticket_number >= max_number))
to_chat(user, "<span class='notice'>[src] refuses [I]! There [max_number-ticket_number==1 ? "is" : "are"] still [max_number-ticket_number] ticket\s left!</span>")
return
to_chat(user, "<span class='notice'>You start to refill [src]'s ticket holder (doing this will reset its ticket count!).</span>")
if(do_after(user, 30, target = src))
to_chat(user, "<span class='notice'>You insert [I] into [src] as it whirs nondescriptly.</span>")
qdel(I)
ticket_number = 0
current_number = 0
if(tickets.len)
for(var/obj/item/ticket_machine_ticket/ticket in tickets)
ticket.audible_message("<span class='notice'>\the [ticket] disperses!</span>")
qdel(ticket)
tickets.Cut()
max_number = initial(max_number)
update_icon()
return
/obj/machinery/ticket_machine/proc/reset_cooldown()
ready = TRUE
/obj/machinery/ticket_machine/attack_hand(mob/living/carbon/user)
. = ..()
if(!ready)
to_chat(user,"<span class='warning'>You press the button, but nothing happens...</span>")
return
if(ticket_number >= max_number)
to_chat(user,"<span class='warning'>Ticket supply depleted, please refill this unit with a hand labeller refill cartridge!</span>")
return
if((user in ticket_holders) && !(obj_flags & EMAGGED))
to_chat(user, "<span class='warning'>You already have a ticket!</span>")
return
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 100, FALSE)
ticket_number ++
to_chat(user, "<span class='notice'>You take a ticket from [src], looks like you're ticket number #[ticket_number]...</span>")
var/obj/item/ticket_machine_ticket/theirticket = new /obj/item/ticket_machine_ticket(get_turf(src))
theirticket.name = "Ticket #[ticket_number]"
theirticket.maptext = "<font color='#000000'>[ticket_number]</font>"
theirticket.saved_maptext = "<font color='#000000'>[ticket_number]</font>"
theirticket.ticket_number = ticket_number
theirticket.source = src
theirticket.owner = user
user.put_in_hands(theirticket)
ticket_holders += user
tickets += theirticket
if(obj_flags & EMAGGED) //Emag the machine to destroy the HOP's life.
ready = FALSE
addtimer(CALLBACK(src, .proc/reset_cooldown), cooldown)//Small cooldown to prevent piles of flaming tickets
theirticket.fire_act()
user.dropItemToGround(theirticket)
user.adjust_fire_stacks(1)
user.IgniteMob()
return
/obj/item/ticket_machine_ticket
name = "Ticket"
desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper®. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "ticket"
maptext_x = 7
maptext_y = 10
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
max_integrity = 50
var/saved_maptext = null
var/mob/living/carbon/owner
var/obj/machinery/ticket_machine/source
var/ticket_number
/obj/item/ticket_machine_ticket/attack_hand(mob/user)
. = ..()
maptext = saved_maptext //For some reason, storage code removes all maptext off objs, this stops its number from being wiped off when taken out of storage.
/obj/item/ticket_machine_ticket/attackby(obj/item/P, mob/living/carbon/human/user, params) //Stolen from papercode
if(burn_paper_product_attackby_check(P, user))
return
return ..()
/obj/item/paper/extinguish()
..()
update_icon()
/obj/item/ticket_machine_ticket/Destroy()
if(owner && source)
source.ticket_holders -= owner
source.tickets[ticket_number] = null
owner = null
source = null
return ..()