the unexpected paperwork update. paperwork rp? And also includes ntnet upgrade because fuck it.

This commit is contained in:
Letter N
2020-08-20 19:40:47 +08:00
parent 2dd3d71b19
commit 8d70e21239
80 changed files with 1080 additions and 727 deletions

View File

@@ -4,6 +4,7 @@
#define DYE_REGISTRY_SNEAKERS "sneakers" #define DYE_REGISTRY_SNEAKERS "sneakers"
#define DYE_REGISTRY_FANNYPACK "fannypack" #define DYE_REGISTRY_FANNYPACK "fannypack"
#define DYE_REGISTRY_BEDSHEET "bedsheet" #define DYE_REGISTRY_BEDSHEET "bedsheet"
#define DYE_LAWYER_SPECIAL "lawyer_special"
#define DYE_RED "red" #define DYE_RED "red"
#define DYE_ORANGE "orange" #define DYE_ORANGE "orange"
@@ -16,6 +17,7 @@
#define DYE_RAINBOW "rainbow" #define DYE_RAINBOW "rainbow"
#define DYE_MIME "mime" #define DYE_MIME "mime"
#define DYE_COSMIC "cosmic" #define DYE_COSMIC "cosmic"
#define DYE_SYNDICATE "syndicate"
#define DYE_QM "qm" #define DYE_QM "qm"
#define DYE_LAW "law" #define DYE_LAW "law"
#define DYE_CAPTAIN "captain" #define DYE_CAPTAIN "captain"
@@ -26,3 +28,5 @@
#define DYE_CMO "cmo" #define DYE_CMO "cmo"
#define DYE_REDCOAT "redcoat" #define DYE_REDCOAT "redcoat"
#define DYE_CLOWN "clown" #define DYE_CLOWN "clown"
#define DYE_CHAP "chap"
#define DYE_CENTCOM "centcom"

View File

@@ -116,6 +116,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define CRAYON_FONT "Comic Sans MS" #define CRAYON_FONT "Comic Sans MS"
#define PRINTER_FONT "Times New Roman" #define PRINTER_FONT "Times New Roman"
#define SIGNFONT "Times New Roman" #define SIGNFONT "Times New Roman"
#define CHARCOAL_FONT "Candara"
#define RESIZE_DEFAULT_SIZE 1 #define RESIZE_DEFAULT_SIZE 1

View File

@@ -0,0 +1,22 @@
// This used to be in paper.dm, it was some snowflake code that was
// used ONLY on april's fool. I moved it to a component so it could be
// used in other places
/datum/component/honkspam
dupe_mode = COMPONENT_DUPE_UNIQUE
var/spam_flag = FALSE
/datum/component/honkspam/Initialize()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
/datum/component/honkspam/proc/reset_spamflag()
spam_flag = FALSE
/datum/component/honkspam/proc/interact(mob/user)
if(!spam_flag)
spam_flag = TRUE
var/obj/item/parent_item = parent
playsound(parent_item.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
addtimer(CALLBACK(src, .proc/reset_spamflag), 2 SECONDS)

View File

@@ -0,0 +1,87 @@
/**
The label component.
This component is used to manage labels applied by the hand labeler.
Atoms can only have one instance of this component, and therefore only one label at a time.
This is to avoid having names like "Backpack (label1) (label2) (label3)". This is annoying and abnoxious to read.
When a player clicks the atom with a hand labeler to apply a label, this component gets applied to it.
If the labeler is off, the component will be removed from it, and the label will be removed from its name.
*/
/datum/component/label
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/// The name of the label the player is applying to the parent.
var/label_name
/datum/component/label/Initialize(_label_name)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
label_name = _label_name
apply_label()
/datum/component/label/RegisterWithParent()
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackby)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/Examine)
/datum/component/label/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE))
/**
This proc will fire after the parent is hit by a hand labeler which is trying to apply another label.
Since the parent already has a label, it will remove the old one from the parent's name, and apply the new one.
*/
/datum/component/label/InheritComponent(datum/component/label/new_comp , i_am_original, _label_name)
remove_label()
if(new_comp)
label_name = new_comp.label_name
else
label_name = _label_name
apply_label()
/**
This proc will trigger when any object is used to attack the parent.
If the attacking object is not a hand labeler, it will return.
If the attacking object is a hand labeler it will restore the name of the parent to what it was before this component was added to it, and the component will be deleted.
Arguments:
* source: The parent.
* attacker: The object that is hitting the parent.
* user: The mob who is wielding the attacking object.
*/
/datum/component/label/proc/OnAttackby(datum/source, obj/item/attacker, mob/user)
// If the attacking object is not a hand labeler or its mode is 1 (has a label ready to apply), return.
// The hand labeler should be off (mode is 0), in order to remove a label.
var/obj/item/hand_labeler/labeler = attacker
if(!istype(labeler) || labeler.mode)
return
remove_label()
playsound(parent, 'sound/items/poster_ripped.ogg', 20, TRUE)
to_chat(user, "<span class='warning'>You remove the label from [parent].</span>")
qdel(src) // Remove the component from the object.
/**
This proc will trigger when someone examines the parent.
It will attach the text found in the body of the proc to the `examine_list` and display it to the player examining the parent.
Arguments:
* source: The parent.
* user: The mob exmaining the parent.
* examine_list: The current list of text getting passed from the parent's normal examine() proc.
*/
/datum/component/label/proc/Examine(datum/source, mob/user, list/examine_list)
examine_list += "<span class='notice'>It has a label with some words written on it. Use a hand labeler to remove it.</span>"
/// Applies a label to the name of the parent in the format of: "parent_name (label)"
/datum/component/label/proc/apply_label()
var/atom/owner = parent
owner.name += " ([label_name])"
/// Removes the label from the parent's name
/datum/component/label/proc/remove_label()
var/atom/owner = parent
owner.name = replacetext(owner.name, "([label_name])", "") // Remove the label text from the parent's name, wherever it's located.
owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name.

View File

@@ -11,23 +11,6 @@
var/list/passkey var/list/passkey
// Process data before sending it
/datum/netdata/proc/pre_send(datum/component/ntnet_interface/interface)
// Decrypt the passkey.
if(autopasskey)
if(data["encrypted_passkey"] && !passkey)
var/result = XorEncrypt(hextostr(data["encrypted_passkey"], TRUE), SScircuit.cipherkey)
if(length(result) > 1)
passkey = json_decode(XorEncrypt(hextostr(data["encrypted_passkey"], TRUE), SScircuit.cipherkey))
// Encrypt the passkey.
if(!data["encrypted_passkey"] && passkey)
data["encrypted_passkey"] = strtohex(XorEncrypt(json_encode(passkey), SScircuit.cipherkey))
// If there is no sender ID, set the default one.
if(!sender_id && interface)
sender_id = interface.hardware_id
/datum/netdata/proc/standard_format_data(primary, secondary, passkey) /datum/netdata/proc/standard_format_data(primary, secondary, passkey)
data["data"] = primary data["data"] = primary
data["data_secondary"] = secondary data["data_secondary"] = secondary

View File

@@ -206,7 +206,7 @@
for(var/datum/ntnet_conversation/chan in chat_channels) for(var/datum/ntnet_conversation/chan in chat_channels)
if(chan.id == id) if(chan.id == id)
return chan return chan
// Resets the IDS alarm // Resets the IDS alarm
/datum/ntnet/proc/resetIDS() /datum/ntnet/proc/resetIDS()
intrusion_detection_alarm = FALSE intrusion_detection_alarm = FALSE

View File

@@ -105,11 +105,11 @@
"stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png', "stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png',
"stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png', "stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
"stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png', "stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png' "stamp-law" = 'icons/stamp_icons/large_stamp-law.png',
// "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png', "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png',
// "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png', "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png',
// "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png', "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png',
// "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png' "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png'
) )

View File

@@ -44,18 +44,20 @@
. += "It has a slot installed for an intelliCard." . += "It has a slot installed for an intelliCard."
var/obj/item/computer_hardware/card_slot/card_slot = get_modular_computer_part(MC_CARD) var/obj/item/computer_hardware/card_slot/card_slot = get_modular_computer_part(MC_CARD)
var/obj/item/computer_hardware/card_slot/card_slot2 = get_modular_computer_part(MC_CARD2)
var/multiple_slots = istype(card_slot) && istype(card_slot2)
if(card_slot) if(card_slot)
if(card_slot.stored_card || card_slot.stored_card2) if(card_slot.stored_card || card_slot2.stored_card)
var/obj/item/card/id/first_ID = card_slot.stored_card var/obj/item/card/id/first_ID = card_slot.stored_card
var/obj/item/card/id/second_ID = card_slot.stored_card2 var/obj/item/card/id/second_ID = card_slot2.stored_card
var/multiple_cards = istype(first_ID) && istype(second_ID) var/multiple_cards = istype(first_ID) && istype(second_ID)
if(user_is_adjacent) if(user_is_adjacent)
. += "It has two slots for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]." . += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]."
else else
. += "It has two slots for identification cards installed, [multiple_cards ? "both of which appear" : "and one of them appears"] to be occupied." . += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed, [multiple_cards ? "both of which appear" : "and one of them appears"] to be occupied."
. += "<span class='info'>Alt-click [src] to eject the identification card[multiple_cards ? "s":""].</span>" . += "<span class='info'>Alt-click [src] to eject the identification card[multiple_cards ? "s":""].</span>"
else else
. += "It has two slots installed for identification cards." . += "It has [multiple_slots ? "two slots" : "a slot"] installed for identification cards."
var/obj/item/computer_hardware/printer/printer_slot = get_modular_computer_part(MC_PRINT) var/obj/item/computer_hardware/printer/printer_slot = get_modular_computer_part(MC_PRINT)
if(printer_slot) if(printer_slot)

View File

@@ -4,6 +4,12 @@
/obj/item/modular_computer /obj/item/modular_computer
name = "modular microcomputer" name = "modular microcomputer"
desc = "A small portable microcomputer." desc = "A small portable microcomputer."
icon = 'icons/obj/computer.dmi'
icon_state = "laptop-open"
light_on = FALSE
integrity_failure = 0.5
max_integrity = 100
armor = list("melee" = 0, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
var/enabled = 0 // Whether the computer is turned on. var/enabled = 0 // Whether the computer is turned on.
var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. var/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
@@ -22,8 +28,6 @@
// must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently
// If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example. // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example.
icon = 'icons/obj/computer.dmi'
icon_state = "laptop-open"
var/icon_state_unpowered = null // Icon state when the computer is turned off. var/icon_state_unpowered = null // Icon state when the computer is turned off.
var/icon_state_powered = null // Icon state when the computer is turned on. var/icon_state_powered = null // Icon state when the computer is turned on.
var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
@@ -31,20 +35,16 @@
var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4. var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4.
var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer. var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer.
integrity_failure = 0.5 /// List of "connection ports" in this computer and the components with which they are plugged
max_integrity = 100 var/list/all_components = list()
armor = list("melee" = 0, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) /// Lazy List of extra hardware slots that can be used modularly.
var/list/expansion_bays
// Important hardware (must be installed for computer to work) /// Number of total expansion bays this computer has available.
var/max_bays = 0
// Optional hardware (improves functionality, but is not critical for computer to work)
var/list/all_components = list() // List of "connection ports" in this computer and the components with which they are plugged
var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with. var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with.
var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks. var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks.
var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed
var/light_on = FALSE //If that light is enabled
var/comp_light_luminosity = 3 //The brightness of that light var/comp_light_luminosity = 3 //The brightness of that light
var/comp_light_color //The color of that light var/comp_light_color //The color of that light
@@ -71,80 +71,15 @@
physical = null physical = null
return ..() return ..()
/obj/item/modular_computer/proc/add_verb(var/path)
switch(path)
if(MC_CARD)
verbs += /obj/item/modular_computer/proc/eject_id
if(MC_SDD)
verbs += /obj/item/modular_computer/proc/eject_disk
if(MC_AI)
verbs += /obj/item/modular_computer/proc/eject_card
/obj/item/modular_computer/proc/remove_verb(path)
switch(path)
if(MC_CARD)
verbs -= /obj/item/modular_computer/proc/eject_id
if(MC_SDD)
verbs -= /obj/item/modular_computer/proc/eject_disk
if(MC_AI)
verbs -= /obj/item/modular_computer/proc/eject_card
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/modular_computer/proc/eject_id()
set name = "Eject ID"
set category = "Object"
set src in view(1)
if(issilicon(usr))
return
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(usr.canUseTopic(src, BE_CLOSE))
card_slot.try_eject(null, usr)
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/modular_computer/proc/eject_card()
set name = "Eject Intellicard"
set category = "Object"
if(issilicon(usr))
return
var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
if(usr.canUseTopic(src, BE_CLOSE))
ai_slot.try_eject(null, usr,1)
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/modular_computer/proc/eject_disk()
set name = "Eject Data Disk"
set category = "Object"
if(issilicon(usr))
return
if(usr.canUseTopic(src, BE_CLOSE))
var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
if(uninstall_component(portable_drive, usr))
portable_drive.verb_pickup()
/obj/item/modular_computer/AltClick(mob/user) /obj/item/modular_computer/AltClick(mob/user)
..() ..()
if(issilicon(user)) if(issilicon(user))
return return
if(user.canUseTopic(src, BE_CLOSE)) if(user.canUseTopic(src, BE_CLOSE))
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI] return (card_slot2?.try_eject(user) || card_slot?.try_eject(user)) //Try the secondary one first.
var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
if(portable_drive)
if(uninstall_component(portable_drive, user))
portable_drive.verb_pickup()
else
if(card_slot && card_slot.try_eject(null, user))
return
if(ai_slot)
ai_slot.try_eject(null, user)
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. // Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
/obj/item/modular_computer/GetAccess() /obj/item/modular_computer/GetAccess()
@@ -160,19 +95,25 @@
return ..() return ..()
/obj/item/modular_computer/RemoveID() /obj/item/modular_computer/RemoveID()
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(!card_slot) return (card_slot2?.try_eject() || card_slot?.try_eject()) //Try the secondary one first.
return
return card_slot.RemoveID()
/obj/item/modular_computer/InsertID(obj/item/inserting_item) /obj/item/modular_computer/InsertID(obj/item/inserting_item)
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(!card_slot) var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
if(!(card_slot || card_slot2))
//to_chat(user, "<span class='warning'>There isn't anywhere you can fit a card into on this computer.</span>")
return FALSE return FALSE
var/obj/item/card/inserting_id = inserting_item.RemoveID() var/obj/item/card/inserting_id = inserting_item.RemoveID()
if(!inserting_id) if(!inserting_id)
return FALSE return FALSE
return card_slot.try_insert(inserting_id)
if((card_slot?.try_insert(inserting_id)) || (card_slot2?.try_insert(inserting_id)))
return TRUE
//to_chat(user, "<span class='warning'>This computer doesn't have an open card slot.</span>")
return FALSE
/obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location) /obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location)
var/mob/M = usr var/mob/M = usr
@@ -189,7 +130,7 @@
return return
if(enabled) if(enabled)
ui_interact(user) ui_interact(user)
else if(IsAdminGhost(user)) else if(isAdminGhostAI(user))
var/response = alert(user, "This computer is turned off. Would you like to turn it on?", "Admin Override", "Yes", "No") var/response = alert(user, "This computer is turned off. Would you like to turn it on?", "Admin Override", "Yes", "No")
if(response == "Yes") if(response == "Yes")
turn_on(user) turn_on(user)

View File

@@ -6,6 +6,14 @@
to_chat(user, "<span class='warning'>This component is too large for \the [src]!</span>") to_chat(user, "<span class='warning'>This component is too large for \the [src]!</span>")
return FALSE return FALSE
if(H.expansion_hw)
if(LAZYLEN(expansion_bays) >= max_bays)
to_chat(user, "<span class='warning'>All of the computer's expansion bays are filled.</span>")
return FALSE
if(LAZYACCESS(expansion_bays, H.device_type))
to_chat(user, "<span class='warning'>The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\".</span>")
return FALSE
if(all_components[H.device_type]) if(all_components[H.device_type])
to_chat(user, "<span class='warning'>This computer's hardware slot is already occupied by \the [all_components[H.device_type]].</span>") to_chat(user, "<span class='warning'>This computer's hardware slot is already occupied by \the [all_components[H.device_type]].</span>")
return FALSE return FALSE
@@ -20,6 +28,8 @@
if(user && !user.transferItemToLoc(H, src)) if(user && !user.transferItemToLoc(H, src))
return FALSE return FALSE
if(H.expansion_hw)
LAZYSET(expansion_bays, H.device_type, H)
all_components[H.device_type] = H all_components[H.device_type] = H
to_chat(user, "<span class='notice'>You install \the [H] into \the [src].</span>") to_chat(user, "<span class='notice'>You install \the [H] into \the [src].</span>")
@@ -32,7 +42,9 @@
/obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/H, mob/living/user = null) /obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/H, mob/living/user = null)
if(H.holder != src) // Not our component at all. if(H.holder != src) // Not our component at all.
return FALSE return FALSE
if(H.expansion_hw)
LAZYREMOVE(expansion_bays, H.device_type)
all_components.Remove(H.device_type) all_components.Remove(H.device_type)
to_chat(user, "<span class='notice'>You remove \the [H] from \the [src].</span>") to_chat(user, "<span class='notice'>You remove \the [H] from \the [src].</span>")
@@ -43,6 +55,7 @@
if(enabled && !use_power()) if(enabled && !use_power())
shutdown_computer() shutdown_computer()
update_icon() update_icon()
return TRUE
// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null // Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null

View File

@@ -44,6 +44,33 @@
/obj/item/modular_computer/ui_data(mob/user) /obj/item/modular_computer/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
data["device_theme"] = device_theme data["device_theme"] = device_theme
data["login"] = list()
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
if(cardholder)
var/obj/item/card/id/stored_card = cardholder.GetID()
if(stored_card)
var/stored_name = stored_card.registered_name
var/stored_title = stored_card.assignment
if(!stored_name)
stored_name = "Unknown"
if(!stored_title)
stored_title = "Unknown"
data["login"] = list(
IDName = stored_name,
IDJob = stored_title,
)
data["removable_media"] = list()
if(all_components[MC_SDD])
data["removable_media"] += "removable storage disk"
var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI]
if(intelliholder?.stored_card)
data["removable_media"] += "intelliCard"
var/obj/item/computer_hardware/card_slot/secondarycardholder = all_components[MC_CARD2]
if(secondarycardholder?.stored_card)
data["removable_media"] += "secondary RFID card"
data["programs"] = list() data["programs"] = list()
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
for(var/datum/computer_file/program/P in hard_drive.stored_files) for(var/datum/computer_file/program/P in hard_drive.stored_files)
@@ -157,6 +184,36 @@
light_color = new_color light_color = new_color
update_light() update_light()
return TRUE return TRUE
if("PC_Eject_Disk")
var/param = params["name"]
var/mob/user = usr
switch(param)
if("removable storage disk")
var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
if(!portable_drive)
return
if(uninstall_component(portable_drive, usr))
user.put_in_hands(portable_drive)
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("intelliCard")
var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI]
if(!intelliholder)
return
if(intelliholder.try_eject(user))
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("ID")
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
if(!cardholder)
return
cardholder.try_eject(user)
if("secondary RFID card")
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD2]
if(!cardholder)
return
cardholder.try_eject(user)
else else
return return

View File

@@ -12,6 +12,7 @@
hardware_flag = PROGRAM_LAPTOP hardware_flag = PROGRAM_LAPTOP
max_hardware_size = 2 max_hardware_size = 2
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
max_bays = 4
// No running around with open laptops in hands. // No running around with open laptops in hands.
item_flags = SLOWS_WHILE_IN_HAND item_flags = SLOWS_WHILE_IN_HAND

View File

@@ -8,6 +8,7 @@
icon_state_unpowered = null icon_state_unpowered = null
icon_state_menu = null icon_state_menu = null
hardware_flag = 0 hardware_flag = 0
max_bays = 4
var/obj/machinery/modular_computer/machinery_computer = null var/obj/machinery/modular_computer/machinery_computer = null
@@ -18,7 +19,7 @@
machinery_computer = null machinery_computer = null
. = ..() . = ..()
/obj/item/modular_computer/processor/New(comp) //intentional new probably /obj/item/modular_computer/processor/New(comp)
..() ..()
STOP_PROCESSING(SSobj, src) // Processed by its machine STOP_PROCESSING(SSobj, src) // Processed by its machine
@@ -56,23 +57,5 @@
machinery_computer.update_icon() machinery_computer.update_icon()
return return
/obj/item/modular_computer/processor/add_verb(path)
switch(path)
if(MC_CARD)
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_id
if(MC_SDD)
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_disk
if(MC_AI)
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_card
/obj/item/modular_computer/processor/remove_verb(path)
switch(path)
if(MC_CARD)
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_id
if(MC_SDD)
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk
if(MC_AI)
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_card
/obj/item/modular_computer/processor/attack_ghost(mob/user) /obj/item/modular_computer/processor/attack_ghost(mob/user)
ui_interact(user) ui_interact(user)

View File

@@ -5,10 +5,11 @@
icon_state_unpowered = "tablet" icon_state_unpowered = "tablet"
icon_state_powered = "tablet" icon_state_powered = "tablet"
icon_state_menu = "menu" icon_state_menu = "menu"
//worn_icon_state = "tablet" // worn_icon_state = "tablet"
hardware_flag = PROGRAM_TABLET hardware_flag = PROGRAM_TABLET
max_hardware_size = 1 max_hardware_size = 1
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
max_bays = 3
steel_sheet_cost = 1 steel_sheet_cost = 1
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
has_light = TRUE //LED flashlight! has_light = TRUE //LED flashlight!

View File

@@ -26,10 +26,20 @@
install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
install_component(hard_drive) install_component(hard_drive)
install_component(new /obj/item/computer_hardware/card_slot)
install_component(new /obj/item/computer_hardware/network_card) install_component(new /obj/item/computer_hardware/network_card)
install_component(new /obj/item/computer_hardware/printer/mini) install_component(new /obj/item/computer_hardware/printer/mini)
hard_drive.store_file(new /datum/computer_file/program/bounty) hard_drive.store_file(new /datum/computer_file/program/bounty)
//hard_drive.store_file(new /datum/computer_file/program/shipping) hard_drive.store_file(new /datum/computer_file/program/shipping)
/obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize() //This will be defunct and will be replaced when NtOS PDAs are done
. = ..()
install_component(new /obj/item/computer_hardware/sensorpackage)
/obj/item/modular_computer/tablet/preset/advanced/command/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/sensorpackage)
install_component(new /obj/item/computer_hardware/card_slot/secondary)
/// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink. /// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink.
/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize() /obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize()

View File

@@ -1,6 +1,6 @@
/obj/machinery/modular_computer/console/preset /obj/machinery/modular_computer/console/preset
// Can be changed to give devices specific hardware // Can be changed to give devices specific hardware
var/_has_id_slot = FALSE var/_has_second_id_slot = FALSE
var/_has_printer = FALSE var/_has_printer = FALSE
var/_has_battery = FALSE var/_has_battery = FALSE
var/_has_ai = FALSE var/_has_ai = FALSE
@@ -11,8 +11,9 @@
return return
cpu.install_component(new /obj/item/computer_hardware/processor_unit) cpu.install_component(new /obj/item/computer_hardware/processor_unit)
if(_has_id_slot) cpu.install_component(new /obj/item/computer_hardware/card_slot)
cpu.install_component(new /obj/item/computer_hardware/card_slot) if(_has_second_id_slot)
cpu.install_component(new /obj/item/computer_hardware/card_slot/secondary)
if(_has_printer) if(_has_printer)
cpu.install_component(new /obj/item/computer_hardware/printer) cpu.install_component(new /obj/item/computer_hardware/printer)
if(_has_battery) if(_has_battery)
@@ -59,7 +60,7 @@
console_department = "Command" console_department = "Command"
name = "command console" name = "command console"
desc = "A stationary computer. This one comes preloaded with command programs." desc = "A stationary computer. This one comes preloaded with command programs."
_has_id_slot = TRUE _has_second_id_slot = TRUE
_has_printer = TRUE _has_printer = TRUE
/obj/machinery/modular_computer/console/preset/command/install_programs() /obj/machinery/modular_computer/console/preset/command/install_programs()
@@ -73,7 +74,7 @@
console_department = "Identification" console_department = "Identification"
name = "identification console" name = "identification console"
desc = "A stationary computer. This one comes preloaded with identification modification programs." desc = "A stationary computer. This one comes preloaded with identification modification programs."
_has_id_slot = TRUE _has_second_id_slot = TRUE
_has_printer = TRUE _has_printer = TRUE
/obj/machinery/modular_computer/console/preset/id/install_programs() /obj/machinery/modular_computer/console/preset/id/install_programs()

View File

@@ -75,30 +75,6 @@
add_overlay("bsod") add_overlay("bsod")
add_overlay("broken") add_overlay("broken")
// Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/proc/eject_id()
set name = "Eject ID"
set category = "Object"
if(cpu)
cpu.eject_id()
// Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/proc/eject_disk()
set name = "Eject Data Disk"
set category = "Object"
if(cpu)
cpu.eject_disk()
/obj/machinery/modular_computer/proc/eject_card()
set name = "Eject Intellicard"
set category = "Object"
set src in view(1)
if(cpu)
cpu.eject_card()
/obj/machinery/modular_computer/AltClick(mob/user) /obj/machinery/modular_computer/AltClick(mob/user)
if(cpu) if(cpu)
cpu.AltClick(user) cpu.AltClick(user)
@@ -136,7 +112,7 @@
return return
. = ..() . = ..()
/obj/machinery/modular_computer/attackby(var/obj/item/W as obj, mob/user) /obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/user)
if(cpu && !(flags_1 & NODECONSTRUCT_1)) if(cpu && !(flags_1 & NODECONSTRUCT_1))
return cpu.attackby(W, user) return cpu.attackby(W, user)
return ..() return ..()
@@ -169,5 +145,4 @@
// "Brute" damage mostly damages the casing. // "Brute" damage mostly damages the casing.
/obj/machinery/modular_computer/bullet_act(obj/item/projectile/Proj) /obj/machinery/modular_computer/bullet_act(obj/item/projectile/Proj)
if(cpu) if(cpu)
return cpu.bullet_act(Proj) cpu.bullet_act(Proj)
return ..()

View File

@@ -25,8 +25,6 @@
var/ntnet_status = 1 var/ntnet_status = 1
/// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL /// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL
var/usage_flags = PROGRAM_ALL var/usage_flags = PROGRAM_ALL
/// Optional string that describes what NTNet server/system this program connects to. Used in default logging.
var/network_destination = null
/// Whether the program can be downloaded from NTNet. Set to 0 to disable. /// Whether the program can be downloaded from NTNet. Set to 0 to disable.
var/available_on_ntnet = 1 var/available_on_ntnet = 1
/// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. /// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
@@ -82,10 +80,18 @@
/datum/computer_file/program/proc/process_tick() /datum/computer_file/program/proc/process_tick()
return 1 return 1
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program() /**
// User has to wear their ID for ID Scan to work. *Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
// Can also be called manually, with optional parameter being access_to_check to scan the user's ID *ID must be inserted into a card slot to be read. If the program is not currently installed (as is the case when
/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE) *NT Software Hub is checking available software), a list can be given to be used instead.
*Arguments:
*user is a ref of the mob using the device.
*loud is a bool deciding if this proc should use to_chats
*access_to_check is an access level that will be checked against the ID
*transfer, if TRUE and access_to_check is null, will tell this proc to use the program's transfer_access in place of access_to_check
*access can contain a list of access numbers to check against. If access is not empty, it will be used istead of checking any inserted ID.
*/
/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE, var/list/access)
// Defaults to required_access // Defaults to required_access
if(!access_to_check) if(!access_to_check)
if(transfer && transfer_access) if(transfer && transfer_access)
@@ -104,29 +110,24 @@
if(issilicon(user)) if(issilicon(user))
return TRUE return TRUE
if(ishuman(user)) if(!length(access))
var/obj/item/card/id/D var/obj/item/card/id/D
var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/card_slot/card_slot
if(computer && card_slot) if(computer)
card_slot = computer.all_components[MC_CARD] card_slot = computer.all_components[MC_CARD]
D = card_slot.GetID() D = card_slot?.GetID()
var/mob/living/carbon/human/h = user
var/obj/item/card/id/I = h.get_idcard(TRUE)
if(!I && !D) if(!D)
if(loud) if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>") to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
return FALSE return FALSE
access = D.GetAccess()
if(I) if(access_to_check in access)
if(access_to_check in I.GetAccess()) return TRUE
return TRUE if(loud)
else if(D) to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
if(access_to_check in D.GetAccess()) return FALSE
return TRUE
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
return 0
// This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones // This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones
// always include the device here in this proc. This proc basically relays the request to whatever is running the program. // always include the device here in this proc. This proc basically relays the request to whatever is running the program.
@@ -139,8 +140,12 @@
// When implementing new program based device, use this to run the program. // When implementing new program based device, use this to run the program.
/datum/computer_file/program/proc/run_program(mob/living/user) /datum/computer_file/program/proc/run_program(mob/living/user)
if(can_run(user, 1)) if(can_run(user, 1))
if(requires_ntnet && network_destination) if(requires_ntnet)
generate_network_log("Connection opened to [network_destination].") var/obj/item/card/id/ID
var/obj/item/computer_hardware/card_slot/card_holder = computer.all_components[MC_CARD]
if(card_holder)
ID = card_holder.GetID()
generate_network_log("Connection opened -- Program ID: [filename] User:[ID?"[ID.registered_name]":"None"]")
program_state = PROGRAM_STATE_ACTIVE program_state = PROGRAM_STATE_ACTIVE
return 1 return 1
return 0 return 0
@@ -162,8 +167,12 @@
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client. // Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
/datum/computer_file/program/proc/kill_program(forced = FALSE) /datum/computer_file/program/proc/kill_program(forced = FALSE)
program_state = PROGRAM_STATE_KILLED program_state = PROGRAM_STATE_KILLED
if(network_destination) if(requires_ntnet)
generate_network_log("Connection to [network_destination] closed.") var/obj/item/card/id/ID
var/obj/item/computer_hardware/card_slot/card_holder = computer.all_components[MC_CARD]
if(card_holder)
ID = card_holder.GetID()
generate_network_log("Connection closed -- Program ID: [filename] User:[ID?"[ID.registered_name]":"None"]")
return 1 return 1
/datum/computer_file/program/ui_interact(mob/user, datum/tgui/ui) /datum/computer_file/program/ui_interact(mob/user, datum/tgui/ui)

View File

@@ -2,7 +2,7 @@
// Always include a parent call when overriding an event. // Always include a parent call when overriding an event.
// Called when the ID card is removed from computer. ID is removed AFTER this proc. // Called when the ID card is removed from computer. ID is removed AFTER this proc.
/datum/computer_file/program/proc/event_idremoved(background, slot) /datum/computer_file/program/proc/event_idremoved(background)
return return
// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss. // Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.

View File

@@ -1,8 +1,8 @@
/datum/computer_file/program/aidiag /datum/computer_file/program/aidiag
filename = "aidiag" filename = "aidiag"
filedesc = "AI Integrity Restorer" filedesc = "NT FRK"
program_icon_state = "generic" program_icon_state = "generic"
extended_desc = "This program is capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot."
size = 12 size = 12
requires_ntnet = FALSE requires_ntnet = FALSE
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
@@ -48,7 +48,7 @@
if(computer.all_components[MC_AI]) if(computer.all_components[MC_AI])
var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI] var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI]
if(ai_slot && ai_slot.stored_card) if(ai_slot && ai_slot.stored_card)
ai_slot.try_eject(0,usr) ai_slot.try_eject(usr)
return TRUE return TRUE
/datum/computer_file/program/aidiag/process_tick() /datum/computer_file/program/aidiag/process_tick()
@@ -71,14 +71,19 @@
ai_slot.locked = FALSE ai_slot.locked = FALSE
restoring = FALSE restoring = FALSE
return return
ai_slot.locked =TRUE ai_slot.locked = TRUE
A.adjustOxyLoss(-5, 0)//, FALSE) A.adjustOxyLoss(-5, 0)//, FALSE)
A.adjustFireLoss(-5, 0)//, FALSE) A.adjustFireLoss(-5, 0)//, FALSE)
A.adjustToxLoss(-5, 0) A.adjustToxLoss(-5, 0)
A.adjustBruteLoss(-5, 0) A.adjustBruteLoss(-5, 0)
// Please don't forget to update health, otherwise the below if statements will probably always fail.
A.updatehealth() A.updatehealth()
if(A.health >= 0 && A.stat == DEAD) if(A.health >= 0 && A.stat == DEAD)
A.revive(full_heal = FALSE, admin_revive = FALSE) A.revive(full_heal = FALSE, admin_revive = FALSE)
cardhold.update_icon()
// Finished restoring // Finished restoring
if(A.health >= 100) if(A.health >= 100)
ai_slot.locked = FALSE ai_slot.locked = FALSE

View File

@@ -1,11 +1,10 @@
/datum/computer_file/program/alarm_monitor /datum/computer_file/program/alarm_monitor
filename = "alarmmonitor" filename = "alarmmonitor"
filedesc = "Alarm Monitor" filedesc = "Canary"
ui_header = "alarm_green.gif" ui_header = "alarm_green.gif"
program_icon_state = "alert-green" program_icon_state = "alert-green"
extended_desc = "This program provides visual interface for station's alarm system." extended_desc = "This program provides visual interface for a station's alarm system."
requires_ntnet = 1 requires_ntnet = 1
network_destination = "alarm monitoring network"
size = 5 size = 5
tgui_id = "NtosStationAlertConsole" tgui_id = "NtosStationAlertConsole"
var/has_alert = 0 var/has_alert = 0

View File

@@ -14,7 +14,7 @@
var/assigned = FALSE var/assigned = FALSE
var/first_load = TRUE var/first_load = TRUE
/datum/computer_file/program/contract_uplink/run_program(var/mob/living/user) /datum/computer_file/program/contract_uplink/run_program(mob/living/user)
. = ..(user) . = ..(user)
/datum/computer_file/program/contract_uplink/ui_act(action, params) /datum/computer_file/program/contract_uplink/ui_act(action, params)

View File

@@ -10,7 +10,7 @@
tgui_id = "NtosRevelation" tgui_id = "NtosRevelation"
var/armed = 0 var/armed = 0
/datum/computer_file/program/revelation/run_program(var/mob/living/user) /datum/computer_file/program/revelation/run_program(mob/living/user)
. = ..(user) . = ..(user)
if(armed) if(armed)
activate() activate()

View File

@@ -1,10 +1,9 @@
/datum/computer_file/program/arcade /datum/computer_file/program/arcade
filename = "arcade" filename = "dsarcade"
filedesc = "Nanotrasen Micro Arcade" filedesc = "Donksoft Micro Arcade"
program_icon_state = "arcade" program_icon_state = "arcade"
extended_desc = "This port of the classic game 'Outbomb Cuban Pete', redesigned to run on tablets, with thrilling graphics and chilling storytelling." extended_desc = "This port of the classic game 'Outbomb Cuban Pete', redesigned to run on tablets, with thrilling graphics and chilling storytelling."
requires_ntnet = FALSE requires_ntnet = FALSE
network_destination = "arcade network"
size = 6 size = 6
tgui_id = "NtosArcade" tgui_id = "NtosArcade"
@@ -25,7 +24,7 @@
/datum/computer_file/program/arcade/proc/game_check(mob/user) /datum/computer_file/program/arcade/proc/game_check(mob/user)
sleep(5) sleep(5)
//user?.mind?.adjust_experience(/datum/skill/gaming, 1) No gaming(TM) Yet // user?.mind?.adjust_experience(/datum/skill/gaming, 1)
if(boss_hp <= 0) if(boss_hp <= 0)
heads_up = "You have crushed [boss_name]! Rejoice!" heads_up = "You have crushed [boss_name]! Rejoice!"
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10) playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10)
@@ -34,7 +33,7 @@
if(istype(computer)) if(istype(computer))
computer.update_icon() computer.update_icon()
ticket_count += 1 ticket_count += 1
//user?.mind?.adjust_experience(/datum/skill/gaming, 50) // user?.mind?.adjust_experience(/datum/skill/gaming, 50)
sleep(10) sleep(10)
else if(player_hp <= 0 || player_mp <= 0) else if(player_hp <= 0 || player_mp <= 0)
heads_up = "You have been defeated... how will the station survive?" heads_up = "You have been defeated... how will the station survive?"
@@ -43,7 +42,7 @@
program_icon_state = "arcade_off" program_icon_state = "arcade_off"
if(istype(computer)) if(istype(computer))
computer.update_icon() computer.update_icon()
//user?.mind?.adjust_experience(/datum/skill/gaming, 10) // user?.mind?.adjust_experience(/datum/skill/gaming, 10)
sleep(10) sleep(10)
/datum/computer_file/program/arcade/proc/enemy_check(mob/user) /datum/computer_file/program/arcade/proc/enemy_check(mob/user)
@@ -98,8 +97,8 @@
if(computer) if(computer)
printer = computer.all_components[MC_PRINT] printer = computer.all_components[MC_PRINT]
//var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming) // var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming)
//var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) // var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER)
switch(action) switch(action)
if("Attack") if("Attack")
var/attackamt = 0 //Spam prevention. var/attackamt = 0 //Spam prevention.
@@ -119,8 +118,8 @@
if(pause_state == FALSE) if(pause_state == FALSE)
healamt = rand(6,8)// + rand(0, gamerSkill) healamt = rand(6,8)// + rand(0, gamerSkill)
var/maxPointCost = 3 var/maxPointCost = 3
//if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN) // if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN)
// maxPointCost = 2 // maxPointCost = 2
healcost = rand(1, maxPointCost) healcost = rand(1, maxPointCost)
pause_state = TRUE pause_state = TRUE
heads_up = "You heal for [healamt] damage." heads_up = "You heal for [healamt] damage."

View File

@@ -1,29 +1,41 @@
/datum/computer_file/program/atmosscan /datum/computer_file/program/atmosscan
filename = "atmosscan" filename = "atmosscan"
filedesc = "Atmospheric Scanner" filedesc = "AtmoZphere"
program_icon_state = "air" program_icon_state = "air"
extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device."
network_destination = "atmos scan"
size = 4 size = 4
tgui_id = "NtosAtmos" tgui_id = "NtosAtmos"
/datum/computer_file/program/atmosscan/run_program(mob/living/user)
. = ..()
if (!.)
return
if(!computer?.get_modular_computer_part(MC_SENSORS)) //Giving a clue to users why the program is spitting out zeros.
to_chat(user, "<span class='warning'>\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".</span>")
/datum/computer_file/program/atmosscan/ui_data(mob/user) /datum/computer_file/program/atmosscan/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
var/list/airlist = list() var/list/airlist = list()
var/turf/T = get_turf(ui_host()) var/turf/T = get_turf(ui_host())
if(T) var/obj/item/computer_hardware/sensorpackage/sensors = computer?.get_modular_computer_part(MC_SENSORS)
if(T && sensors?.check_functionality())
var/datum/gas_mixture/environment = T.return_air() var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.get_gases() var/list/env_gases = environment.gases
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles() var/total_moles = environment.total_moles()
data["AirPressure"] = round(pressure,0.1) data["AirPressure"] = round(pressure,0.1)
data["AirTemp"] = round(environment.return_temperature()-T0C) data["AirTemp"] = round(environment.temperature-T0C)
if (total_moles) if (total_moles)
for(var/id in env_gases) for(var/id in env_gases)
var/gas_level = environment.get_moles(id)/total_moles var/gas_level = env_gases[id][MOLES]/total_moles
if(gas_level > 0) if(gas_level > 0)
airlist += list(list("name" = "[GLOB.meta_gas_names[id]]", "percentage" = round(gas_level*100, 0.01))) airlist += list(list("name" = "[env_gases[id][GAS_META][META_GAS_NAME]]", "percentage" = round(gas_level*100, 0.01)))
data["AirData"] = airlist data["AirData"] = airlist
else
data["AirPressure"] = 0
data["AirTemp"] = 0
data["AirData"] = list(list())
return data return data
/datum/computer_file/program/atmosscan/ui_act(action, list/params) /datum/computer_file/program/atmosscan/ui_act(action, list/params)

View File

@@ -1,12 +1,11 @@
/datum/computer_file/program/borg_monitor /datum/computer_file/program/borg_monitor
filename = "cyborgmonitor" filename = "siliconnect"
filedesc = "Cyborg Remote Monitoring" filedesc = "SiliConnect"
ui_header = "borg_mon.gif" ui_header = "borg_mon.gif"
program_icon_state = "generic" program_icon_state = "generic"
extended_desc = "This program allows for remote monitoring of station cyborgs." extended_desc = "This program allows for remote monitoring of station cyborgs."
requires_ntnet = TRUE requires_ntnet = TRUE
transfer_access = ACCESS_ROBOTICS transfer_access = ACCESS_ROBOTICS
network_destination = "cyborg remote monitoring"
size = 5 size = 5
tgui_id = "NtosCyborgRemoteMonitor" tgui_id = "NtosCyborgRemoteMonitor"
@@ -81,8 +80,8 @@
return ID.registered_name return ID.registered_name
/datum/computer_file/program/borg_monitor/syndicate /datum/computer_file/program/borg_monitor/syndicate
filename = "scyborgmonitor" filename = "roboverlord"
filedesc = "Mission-Specific Cyborg Remote Monitoring" filedesc = "Roboverlord"
ui_header = "borg_mon.gif" ui_header = "borg_mon.gif"
program_icon_state = "generic" program_icon_state = "generic"
extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs." extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs."
@@ -90,7 +89,6 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
available_on_syndinet = TRUE available_on_syndinet = TRUE
transfer_access = null transfer_access = null
network_destination = "cyborg remote monitoring"
tgui_id = "NtosCyborgRemoteMonitorSyndicate" tgui_id = "NtosCyborgRemoteMonitorSyndicate"
/datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R) /datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R)

View File

@@ -4,7 +4,6 @@
program_icon_state = "bountyboard" program_icon_state = "bountyboard"
extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.." extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.."
requires_ntnet = TRUE requires_ntnet = TRUE
network_destination = "bounty board interface"
size = 10 size = 10
tgui_id = "NtosRequestKiosk" tgui_id = "NtosRequestKiosk"
///Reference to the currently logged in user. ///Reference to the currently logged in user.

View File

@@ -7,8 +7,8 @@
#define CARDCON_DEPARTMENT_COMMAND "Command" #define CARDCON_DEPARTMENT_COMMAND "Command"
/datum/computer_file/program/card_mod /datum/computer_file/program/card_mod
filename = "cardmod" filename = "plexagonidwriter"
filedesc = "ID Card Modification" filedesc = "Plexagon Access Management"
program_icon_state = "id" program_icon_state = "id"
extended_desc = "Program for programming employee ID cards to access parts of the station." extended_desc = "Program for programming employee ID cards to access parts of the station."
transfer_access = ACCESS_HEADS transfer_access = ACCESS_HEADS
@@ -98,17 +98,19 @@
return TRUE return TRUE
var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/card_slot/card_slot
var/obj/item/computer_hardware/card_slot/card_slot2
var/obj/item/computer_hardware/printer/printer var/obj/item/computer_hardware/printer/printer
if(computer) if(computer)
card_slot = computer.all_components[MC_CARD] card_slot = computer.all_components[MC_CARD]
card_slot2 = computer.all_components[MC_CARD2]
printer = computer.all_components[MC_PRINT] printer = computer.all_components[MC_PRINT]
if(!card_slot) if(!card_slot || !card_slot2)
return return
var/mob/user = usr var/mob/user = usr
var/obj/item/card/id/user_id_card = user.get_idcard(FALSE) var/obj/item/card/id/user_id_card = card_slot.stored_card
var/obj/item/card/id/id_card = card_slot.stored_card var/obj/item/card/id/target_id_card = card_slot2.stored_card
switch(action) switch(action)
if("PRG_authenticate") if("PRG_authenticate")
@@ -129,14 +131,14 @@
return return
var/contents = {"<h4>Access Report</h4> var/contents = {"<h4>Access Report</h4>
<u>Prepared By:</u> [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br> <u>Prepared By:</u> [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br>
<u>For:</u> [id_card.registered_name ? id_card.registered_name : "Unregistered"]<br> <u>For:</u> [target_id_card.registered_name ? target_id_card.registered_name : "Unregistered"]<br>
<hr> <hr>
<u>Assignment:</u> [id_card.assignment]<br> <u>Assignment:</u> [target_id_card.assignment]<br>
<u>Access:</u><br> <u>Access:</u><br>
"} "}
var/known_access_rights = get_all_accesses() var/known_access_rights = get_all_accesses()
for(var/A in id_card.access) for(var/A in target_id_card.access)
if(A in known_access_rights) if(A in known_access_rights)
contents += " [get_access_desc(A)]" contents += " [get_access_desc(A)]"
@@ -148,43 +150,40 @@
computer.visible_message("<span class='notice'>\The [computer] prints out a paper.</span>") computer.visible_message("<span class='notice'>\The [computer] prints out a paper.</span>")
return TRUE return TRUE
if("PRG_eject") if("PRG_eject")
if(!computer || !card_slot) if(!computer || !card_slot2)
return return
if(id_card) if(target_id_card)
GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) GLOB.data_core.manifest_modify(target_id_card.registered_name, target_id_card.assignment)
card_slot.try_eject(TRUE, user) return card_slot2.try_eject(user)
else else
var/obj/item/I = user.get_active_held_item() var/obj/item/I = user.get_active_held_item()
if(istype(I, /obj/item/card/id)) if(istype(I, /obj/item/card/id))
if(!user.transferItemToLoc(I, computer)) return card_slot2.try_insert(I)
return return FALSE
card_slot.stored_card = I
playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
return TRUE
if("PRG_terminate") if("PRG_terminate")
if(!computer || !authenticated) if(!computer || !authenticated)
return return
if(minor) if(minor)
if(!(id_card.assignment in head_subordinates) && id_card.assignment != "Assistant") if(!(target_id_card.assignment in head_subordinates) && target_id_card.assignment != "Assistant")
return return
id_card.access -= get_all_centcom_access() + get_all_accesses() target_id_card.access -= get_all_centcom_access() + get_all_accesses()
id_card.assignment = "Unassigned" target_id_card.assignment = "Unassigned"
id_card.update_label() target_id_card.update_label()
playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return TRUE return TRUE
if("PRG_edit") if("PRG_edit")
if(!computer || !authenticated || !id_card) if(!computer || !authenticated || !target_id_card)
return return
var/new_name = params["name"] var/new_name = params["name"]
if(!new_name) if(!new_name)
return return
id_card.registered_name = new_name target_id_card.registered_name = new_name
id_card.update_label() target_id_card.update_label()
playsound(computer, "terminal_type", 50, FALSE) playsound(computer, "terminal_type", 50, FALSE)
return TRUE return TRUE
if("PRG_assign") if("PRG_assign")
if(!computer || !authenticated || !id_card) if(!computer || !authenticated || !target_id_card)
return return
var/target = params["assign_target"] var/target = params["assign_target"]
if(!target) if(!target)
@@ -193,8 +192,8 @@
if(target == "Custom") if(target == "Custom")
var/custom_name = params["custom_name"] var/custom_name = params["custom_name"]
if(custom_name) if(custom_name)
id_card.assignment = custom_name target_id_card.assignment = custom_name
id_card.update_label() target_id_card.update_label()
else else
if(minor && !(target in head_subordinates)) if(minor && !(target in head_subordinates))
return return
@@ -212,10 +211,10 @@
to_chat(user, "<span class='warning'>No class exists for this job: [target]</span>") to_chat(user, "<span class='warning'>No class exists for this job: [target]</span>")
return return
new_access = job.get_access() new_access = job.get_access()
id_card.access -= get_all_centcom_access() + get_all_accesses() target_id_card.access -= get_all_centcom_access() + get_all_accesses()
id_card.access |= new_access target_id_card.access |= new_access
id_card.assignment = target target_id_card.assignment = target
id_card.update_label() target_id_card.update_label()
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
return TRUE return TRUE
if("PRG_access") if("PRG_access")
@@ -223,22 +222,22 @@
return return
var/access_type = text2num(params["access_target"]) var/access_type = text2num(params["access_target"])
if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses())) if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses()))
if(access_type in id_card.access) if(access_type in target_id_card.access)
id_card.access -= access_type target_id_card.access -= access_type
else else
id_card.access |= access_type target_id_card.access |= access_type
playsound(computer, "terminal_type", 50, FALSE) playsound(computer, "terminal_type", 50, FALSE)
return TRUE return TRUE
if("PRG_grantall") if("PRG_grantall")
if(!computer || !authenticated || minor) if(!computer || !authenticated || minor)
return return
id_card.access |= (is_centcom ? get_all_centcom_access() : get_all_accesses()) target_id_card.access |= (is_centcom ? get_all_centcom_access() : get_all_accesses())
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
return TRUE return TRUE
if("PRG_denyall") if("PRG_denyall")
if(!computer || !authenticated || minor) if(!computer || !authenticated || minor)
return return
id_card.access.Cut() target_id_card.access.Cut()
playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return TRUE return TRUE
if("PRG_grantregion") if("PRG_grantregion")
@@ -247,7 +246,7 @@
var/region = text2num(params["region"]) var/region = text2num(params["region"])
if(isnull(region)) if(isnull(region))
return return
id_card.access |= get_region_accesses(region) target_id_card.access |= get_region_accesses(region)
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
return TRUE return TRUE
if("PRG_denyregion") if("PRG_denyregion")
@@ -256,7 +255,7 @@
var/region = text2num(params["region"]) var/region = text2num(params["region"])
if(isnull(region)) if(isnull(region))
return return
id_card.access -= get_region_accesses(region) target_id_card.access -= get_region_accesses(region)
playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return TRUE return TRUE
@@ -321,17 +320,17 @@
/datum/computer_file/program/card_mod/ui_data(mob/user) /datum/computer_file/program/card_mod/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/card_slot/card_slot2
var/obj/item/computer_hardware/printer/printer var/obj/item/computer_hardware/printer/printer
if(computer) if(computer)
card_slot = computer.all_components[MC_CARD] card_slot2 = computer.all_components[MC_CARD2]
printer = computer.all_components[MC_PRINT] printer = computer.all_components[MC_PRINT]
data["station_name"] = station_name() data["station_name"] = station_name()
if(computer) if(computer)
data["have_id_slot"] = !!card_slot data["have_id_slot"] = !!(card_slot2)
data["have_printer"] = !!printer data["have_printer"] = !!printer
else else
data["have_id_slot"] = FALSE data["have_id_slot"] = FALSE
@@ -340,7 +339,7 @@
data["authenticated"] = authenticated data["authenticated"] = authenticated
if(computer) if(computer)
var/obj/item/card/id/id_card = card_slot.stored_card var/obj/item/card/id/id_card = card_slot2.stored_card
data["has_id"] = !!id_card data["has_id"] = !!id_card
data["id_name"] = id_card ? id_card.name : "-----" data["id_name"] = id_card ? id_card.name : "-----"
if(id_card) if(id_card)

View File

@@ -5,7 +5,6 @@
extended_desc = "A basic interface for supply personnel to check and claim bounties." extended_desc = "A basic interface for supply personnel to check and claim bounties."
requires_ntnet = TRUE requires_ntnet = TRUE
transfer_access = ACCESS_CARGO transfer_access = ACCESS_CARGO
network_destination = "cargo claims interface"
size = 10 size = 10
tgui_id = "NtosBountyConsole" tgui_id = "NtosBountyConsole"
///cooldown var for printing paper sheets. ///cooldown var for printing paper sheets.

View File

@@ -1,9 +1,8 @@
/datum/computer_file/program/shipping /datum/computer_file/program/shipping
filename = "shipping" filename = "shipping"
filedesc = "Nanotrasen Shipping Scanner" filedesc = "GrandArk Exporter"
program_icon_state = "shipping" program_icon_state = "shipping"
extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping." extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping."
network_destination = "ship scanner"
size = 6 size = 6
tgui_id = "NtosShipping" tgui_id = "NtosShipping"
///Account used for creating barcodes. ///Account used for creating barcodes.

View File

@@ -1,10 +1,10 @@
/datum/computer_file/program/crew_manifest /datum/computer_file/program/crew_manifest
filename = "crewmani" filename = "plexagoncrew"
filedesc = "Crew Manifest" filedesc = "Plexagon Crew List"
program_icon_state = "id" program_icon_state = "id"
extended_desc = "Program for viewing and printing the current crew manifest" extended_desc = "Program for viewing and printing the current crew manifest"
transfer_access = ACCESS_HEADS transfer_access = ACCESS_HEADS
requires_ntnet = FALSE requires_ntnet = TRUE
size = 4 size = 4
tgui_id = "NtosCrewManifest" tgui_id = "NtosCrewManifest"

View File

@@ -1,10 +1,10 @@
/datum/computer_file/program/job_management /datum/computer_file/program/job_management
filename = "job_manage" filename = "plexagoncore"
filedesc = "Job Manager" filedesc = "Plexagon HR Core"
program_icon_state = "id" program_icon_state = "id"
extended_desc = "Program for viewing and changing job slot avalibility." extended_desc = "Program for viewing and changing job slot avalibility."
transfer_access = ACCESS_HEADS transfer_access = ACCESS_HEADS
requires_ntnet = 0 requires_ntnet = TRUE
size = 4 size = 4
tgui_id = "NtosJobManager" tgui_id = "NtosJobManager"

View File

@@ -1,14 +1,14 @@
/datum/computer_file/program/ntnetdownload /datum/computer_file/program/ntnetdownload
filename = "ntndownloader" filename = "ntsoftwarehub"
filedesc = "Software Download Tool" filedesc = "NT Software Hub"
program_icon_state = "generic" program_icon_state = "generic"
extended_desc = "This program allows downloads of software from official NT repositories" extended_desc = "This program allows downloads of software from official NT repositories"
unsendable = 1 unsendable = TRUE
undeletable = 1 undeletable = TRUE
size = 4 size = 4
requires_ntnet = 1 requires_ntnet = TRUE
requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD
available_on_ntnet = 0 available_on_ntnet = FALSE
ui_header = "downloader_finished.gif" ui_header = "downloader_finished.gif"
tgui_id = "NtosNetDownloader" tgui_id = "NtosNetDownloader"
@@ -125,6 +125,8 @@
if(!istype(my_computer)) if(!istype(my_computer))
return return
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
var/list/access = card_slot?.GetAccess()
var/list/data = get_header_data() var/list/data = get_header_data()
@@ -146,7 +148,7 @@
for(var/A in main_repo) for(var/A in main_repo)
var/datum/computer_file/program/P = A var/datum/computer_file/program/P = A
// Only those programs our user can run will show in the list // Only those programs our user can run will show in the list
if(!P.can_run(user,transfer = 1) || hard_drive.find_file_by_name(P.filename)) if(!P.can_run(user,transfer = 1, access = access) || hard_drive.find_file_by_name(P.filename))
continue continue
all_entries.Add(list(list( all_entries.Add(list(list(
"filename" = P.filename, "filename" = P.filename,

View File

@@ -1,6 +1,6 @@
/datum/computer_file/program/ntnetmonitor /datum/computer_file/program/ntnetmonitor
filename = "ntmonitor" filename = "wirecarp"
filedesc = "NTNet Diagnostics and Monitoring" filedesc = "WireCarp" //wireshark.
program_icon_state = "comm_monitor" program_icon_state = "comm_monitor"
extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes"
size = 12 size = 12

View File

@@ -6,7 +6,6 @@
size = 8 size = 8
requires_ntnet = 1 requires_ntnet = 1
requires_ntnet_feature = NTNET_COMMUNICATION requires_ntnet_feature = NTNET_COMMUNICATION
network_destination = "NTNRC server"
ui_header = "ntnrc_idle.gif" ui_header = "ntnrc_idle.gif"
available_on_ntnet = 1 available_on_ntnet = 1
tgui_id = "NtosNetChat" tgui_id = "NtosNetChat"

View File

@@ -1,15 +1,14 @@
//normal computer version is located in code\modules\power\monitor.dm, /obj/machinery/computer/monitor //normal computer version is located in code\modules\power\monitor.dm, /obj/machinery/computer/monitor
/datum/computer_file/program/power_monitor /datum/computer_file/program/power_monitor
filename = "powermonitor" filename = "ampcheck"
filedesc = "Power Monitor" filedesc = "AmpCheck"
program_icon_state = "power_monitor" program_icon_state = "power_monitor"
extended_desc = "This program connects to sensors around the station to provide information about electrical systems" extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
ui_header = "power_norm.gif" ui_header = "power_norm.gif"
transfer_access = ACCESS_ENGINE transfer_access = ACCESS_ENGINE
usage_flags = PROGRAM_CONSOLE usage_flags = PROGRAM_CONSOLE
requires_ntnet = 0 requires_ntnet = 0
network_destination = "power monitoring system"
size = 9 size = 9
tgui_id = "NtosPowerMonitor" tgui_id = "NtosPowerMonitor"

View File

@@ -7,7 +7,6 @@
transfer_access = null transfer_access = null
available_on_ntnet = FALSE available_on_ntnet = FALSE
usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET
network_destination = "tracking program"
size = 5 size = 5
tgui_id = "NtosRadar" tgui_id = "NtosRadar"
///List of trackable entities. Updated by the scan() proc. ///List of trackable entities. Updated by the scan() proc.
@@ -207,7 +206,7 @@
///A program that tracks crew members via suit sensors ///A program that tracks crew members via suit sensors
/datum/computer_file/program/radar/lifeline /datum/computer_file/program/radar/lifeline
filename = "Lifeline" filename = "lifeline"
filedesc = "Lifeline" filedesc = "Lifeline"
extended_desc = "This program allows for tracking of crew members via their suit sensors." extended_desc = "This program allows for tracking of crew members via their suit sensors."
requires_ntnet = TRUE requires_ntnet = TRUE
@@ -252,9 +251,9 @@
//Nuke Disk Finder App// //Nuke Disk Finder App//
//////////////////////// ////////////////////////
///A program that tracks crew members via suit sensors ///A program that tracks nukes and nuclear accessories
/datum/computer_file/program/radar/fission360 /datum/computer_file/program/radar/fission360
filename = "Fission360" filename = "fission360"
filedesc = "Fission360" filedesc = "Fission360"
program_icon_state = "radarsyndicate" program_icon_state = "radarsyndicate"
extended_desc = "This program allows for tracking of nuclear authorization disks and warheads." extended_desc = "This program allows for tracking of nuclear authorization disks and warheads."
@@ -276,8 +275,6 @@
objects = list() objects = list()
for(var/i in GLOB.nuke_list) for(var/i in GLOB.nuke_list)
var/obj/machinery/nuclearbomb/nuke = i var/obj/machinery/nuclearbomb/nuke = i
if(!trackable(nuke))
continue
var/list/nukeinfo = list( var/list/nukeinfo = list(
ref = REF(nuke), ref = REF(nuke),
@@ -285,9 +282,8 @@
) )
objects += list(nukeinfo) objects += list(nukeinfo)
var/obj/item/disk/nuclear/disk = locate() in GLOB.poi_list var/obj/item/disk/nuclear/disk = locate() in GLOB.poi_list
if(trackable(disk)) var/list/nukeinfo = list(
var/list/nukeinfo = list( ref = REF(disk),
ref = REF(disk), name = "Nuke Auth. Disk",
name = disk.name, )
) objects += list(nukeinfo)
objects += list(nukeinfo)

View File

@@ -1,12 +1,11 @@
/datum/computer_file/program/robocontrol /datum/computer_file/program/robocontrol
filename = "robocontrol" filename = "botkeeper"
filedesc = "Bot Remote Controller" filedesc = "Botkeeper"
program_icon_state = "robot" program_icon_state = "robot"
extended_desc = "A remote controller used for giving basic commands to non-sentient robots." extended_desc = "A remote controller used for giving basic commands to non-sentient robots."
transfer_access = ACCESS_ROBOTICS transfer_access = ACCESS_ROBOTICS
requires_ntnet = TRUE requires_ntnet = TRUE
network_destination = "robotics control network"
size = 12 size = 12
tgui_id = "NtosRoboControl" tgui_id = "NtosRoboControl"
///Number of simple robots on-station. ///Number of simple robots on-station.
@@ -78,7 +77,7 @@
return return
if(id_card) if(id_card)
GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment)
card_slot.try_eject(TRUE, current_user) card_slot.try_eject(current_user)
else else
playsound(get_turf(ui_host()) , 'sound/machines/buzz-sigh.ogg', 25, FALSE) playsound(get_turf(ui_host()) , 'sound/machines/buzz-sigh.ogg', 25, FALSE)
return return

View File

@@ -1,12 +1,11 @@
/datum/computer_file/program/supermatter_monitor /datum/computer_file/program/supermatter_monitor
filename = "smmonitor" filename = "ntcims"
filedesc = "Supermatter Monitoring" filedesc = "NT CIMS"
ui_header = "smmon_0.gif" ui_header = "smmon_0.gif"
program_icon_state = "smmon_0" program_icon_state = "smmon_0"
extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." extended_desc = "Crystal Integrity Monitoring System, connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines."
requires_ntnet = TRUE requires_ntnet = TRUE
transfer_access = ACCESS_CONSTRUCTION transfer_access = ACCESS_CONSTRUCTION
network_destination = "supermatter monitoring system"
size = 5 size = 5
tgui_id = "NtosSupermatterMonitor" tgui_id = "NtosSupermatterMonitor"
var/last_status = SUPERMATTER_INACTIVE var/last_status = SUPERMATTER_INACTIVE
@@ -70,7 +69,7 @@
data["active"] = TRUE data["active"] = TRUE
data["SM_integrity"] = active.get_integrity() data["SM_integrity"] = active.get_integrity()
data["SM_power"] = active.power data["SM_power"] = active.power
data["SM_ambienttemp"] = air.return_temperature() data["SM_ambienttemp"] = air.temperature
data["SM_ambientpressure"] = air.return_pressure() data["SM_ambientpressure"] = air.return_pressure()
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
var/list/gasdata = list() var/list/gasdata = list()

View File

@@ -10,9 +10,11 @@
// Computer that holds this hardware, if any. // Computer that holds this hardware, if any.
var/power_usage = 0 // If the hardware uses extra power, change this. var/power_usage = 0 // If the hardware uses extra power, change this.
var/enabled = 1 // If the hardware is turned off set this to 0. var/enabled = TRUE // If the hardware is turned off set this to 0.
var/critical = 0 // Prevent disabling for important component, like the CPU. var/critical = FALSE // Prevent disabling for important component, like the CPU.
var/can_install = 1 // Prevents direct installation of removable media. var/can_install = TRUE // Prevents direct installation of removable media.
var/expansion_hw = FALSE // Hardware that fits into expansion bays.
var/removable = TRUE // Whether the hardware is removable or not.
var/damage = 0 // Current damage level var/damage = 0 // Current damage level
var/max_damage = 100 // Maximal damage level. var/max_damage = 100 // Maximal damage level.
var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things
@@ -20,7 +22,7 @@
var/malfunction_probability = 10// Chance of malfunction when the component is damaged var/malfunction_probability = 10// Chance of malfunction when the component is damaged
var/device_type var/device_type
/obj/item/computer_hardware/New(var/obj/L) /obj/item/computer_hardware/New(obj/L)
..() ..()
pixel_x = rand(-8, 8) pixel_x = rand(-8, 8)
pixel_y = rand(-8, 8) pixel_y = rand(-8, 8)
@@ -56,7 +58,7 @@
return TRUE return TRUE
// Called on multitool click, prints diagnostic information to the user. // Called on multitool click, prints diagnostic information to the user.
/obj/item/computer_hardware/proc/diagnostics(var/mob/user) /obj/item/computer_hardware/proc/diagnostics(mob/user)
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]") to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
// Handles damage checks // Handles damage checks
@@ -73,7 +75,7 @@
return TRUE // Good to go. return TRUE // Good to go.
/obj/item/computer_hardware/examine(var/mob/user) /obj/item/computer_hardware/examine(mob/user)
. = ..() . = ..()
if(damage > damage_failure) if(damage > damage_failure)
. += "<span class='danger'>It seems to be severely damaged!</span>" . += "<span class='danger'>It seems to be severely damaged!</span>"

View File

@@ -5,6 +5,7 @@
icon_state = "card_mini" icon_state = "card_mini"
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
device_type = MC_AI device_type = MC_AI
expansion_hw = TRUE
var/obj/item/aicard/stored_card = null var/obj/item/aicard/stored_card = null
var/locked = FALSE var/locked = FALSE
@@ -19,12 +20,6 @@
if(stored_card) if(stored_card)
. += "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it." . += "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it."
/obj/item/computer_hardware/ai_slot/on_install(obj/item/modular_computer/M, mob/living/user = null)
M.add_verb(device_type)
/obj/item/computer_hardware/ai_slot/on_remove(obj/item/modular_computer/M, mob/living/user = null)
M.remove_verb(device_type)
/obj/item/computer_hardware/ai_slot/try_insert(obj/item/I, mob/living/user = null) /obj/item/computer_hardware/ai_slot/try_insert(obj/item/I, mob/living/user = null)
if(!holder) if(!holder)
return FALSE return FALSE
@@ -44,7 +39,7 @@
return TRUE return TRUE
/obj/item/computer_hardware/ai_slot/try_eject(slot=0,mob/living/user = null,forced = 0) /obj/item/computer_hardware/ai_slot/try_eject(mob/living/user = null,forced = FALSE)
if(!stored_card) if(!stored_card)
to_chat(user, "<span class='warning'>There is no card in \the [src].</span>") to_chat(user, "<span class='warning'>There is no card in \the [src].</span>")
return FALSE return FALSE

View File

@@ -21,7 +21,7 @@
/obj/item/computer_hardware/battery/handle_atom_del(atom/A) /obj/item/computer_hardware/battery/handle_atom_del(atom/A)
if(A == battery) if(A == battery)
try_eject(0, null, TRUE) try_eject(forced = TRUE)
. = ..() . = ..()
/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null) /obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null)
@@ -48,7 +48,7 @@
return TRUE return TRUE
/obj/item/computer_hardware/battery/try_eject(slot=0, mob/living/user = null, forced = 0) /obj/item/computer_hardware/battery/try_eject(mob/living/user = null, forced = FALSE)
if(!battery) if(!battery)
to_chat(user, "<span class='warning'>There is no power cell connected to \the [src].</span>") to_chat(user, "<span class='warning'>There is no power cell connected to \the [src].</span>")
return FALSE return FALSE

View File

@@ -7,13 +7,10 @@
device_type = MC_CARD device_type = MC_CARD
var/obj/item/card/id/stored_card = null var/obj/item/card/id/stored_card = null
var/obj/item/card/id/stored_card2 = null
/obj/item/computer_hardware/card_slot/handle_atom_del(atom/A) /obj/item/computer_hardware/card_slot/handle_atom_del(atom/A)
if(A == stored_card) if(A == stored_card)
try_eject(1, null, TRUE) try_eject(null, TRUE)
if(A == stored_card2)
try_eject(2, null, TRUE)
. = ..() . = ..()
/obj/item/computer_hardware/card_slot/Destroy() /obj/item/computer_hardware/card_slot/Destroy()
@@ -21,37 +18,25 @@
return ..() return ..()
/obj/item/computer_hardware/card_slot/GetAccess() /obj/item/computer_hardware/card_slot/GetAccess()
if(stored_card && stored_card2) // Best of both worlds var/list/total_access
return (stored_card.GetAccess() | stored_card2.GetAccess()) if(stored_card)
else if(stored_card) total_access = stored_card.GetAccess()
return stored_card.GetAccess() var/obj/item/computer_hardware/card_slot/card_slot2 = holder?.all_components[MC_CARD2] //Best of both worlds
else if(stored_card2) if(card_slot2?.stored_card)
return stored_card2.GetAccess() total_access |= card_slot2.stored_card.GetAccess()
return ..() return total_access
/obj/item/computer_hardware/card_slot/GetID() /obj/item/computer_hardware/card_slot/GetID()
if(stored_card) if(stored_card)
return stored_card return stored_card
else if(stored_card2)
return stored_card2
return ..() return ..()
/obj/item/computer_hardware/card_slot/RemoveID() /obj/item/computer_hardware/card_slot/RemoveID()
if(stored_card) if(stored_card)
. = stored_card . = stored_card
if(!try_eject(1)) if(!try_eject())
return null return null
return return
if(stored_card2)
. = stored_card2
if(!try_eject(2))
return null
/obj/item/computer_hardware/card_slot/on_install(obj/item/modular_computer/M, mob/living/user = null)
M.add_verb(device_type)
/obj/item/computer_hardware/card_slot/on_remove(obj/item/modular_computer/M, mob/living/user = null)
M.remove_verb(device_type)
/obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null) /obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null)
if(!holder) if(!holder)
@@ -60,8 +45,7 @@
if(!istype(I, /obj/item/card/id)) if(!istype(I, /obj/item/card/id))
return FALSE return FALSE
if(stored_card && stored_card2) if(stored_card)
to_chat(user, "<span class='warning'>You try to insert \the [I] into \the [src], but its slots are occupied.</span>")
return FALSE return FALSE
if(user) if(user)
if(!user.transferItemToLoc(I, src)) if(!user.transferItemToLoc(I, src))
@@ -69,11 +53,8 @@
else else
I.forceMove(src) I.forceMove(src)
if(!stored_card) stored_card = I
stored_card = I to_chat(user, "<span class='notice'>You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].</span>")
else
stored_card2 = I
to_chat(user, "<span class='notice'>You insert \the [I] into \the [src].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
if(ishuman(user)) if(ishuman(user))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
@@ -82,53 +63,58 @@
return TRUE return TRUE
/obj/item/computer_hardware/card_slot/try_eject(slot=0, mob/living/user = null, forced = 0) /obj/item/computer_hardware/card_slot/try_eject(mob/living/user = null, forced = FALSE)
if(!stored_card && !stored_card2) if(!stored_card)
to_chat(user, "<span class='warning'>There are no cards in \the [src].</span>") to_chat(user, "<span class='warning'>There are no cards in \the [src].</span>")
return FALSE return FALSE
var/ejected = 0 if(user)
if(stored_card && (!slot || slot == 1)) user.put_in_hands(stored_card)
if(user) else
user.put_in_hands(stored_card) stored_card.forceMove(drop_location())
else stored_card = null
stored_card.forceMove(drop_location())
stored_card = null
ejected++
if(stored_card2 && (!slot || slot == 2)) if(holder)
if(user) if(holder.active_program)
user.put_in_hands(stored_card2) holder.active_program.event_idremoved(0)
else
stored_card2.forceMove(drop_location())
stored_card2 = null
ejected++
if(ejected) for(var/p in holder.idle_threads)
if(holder) var/datum/computer_file/program/computer_program = p
if(holder.active_program) computer_program.event_idremoved(1)
holder.active_program.event_idremoved(0, slot) if(ishuman(user))
var/mob/living/carbon/human/human_user = user
for(var/I in holder.idle_threads) human_user.sec_hud_set_ID()
var/datum/computer_file/program/P = I to_chat(user, "<span class='notice'>You remove the card from \the [src].</span>")
P.event_idremoved(1, slot) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
if(ishuman(user)) return TRUE
var/mob/living/carbon/human/H = user
H.sec_hud_set_ID()
to_chat(user, "<span class='notice'>You remove the card[ejected>1 ? "s" : ""] from \the [src].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
return TRUE
return FALSE
/obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user) /obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user)
if(..()) if(..())
return return
if(I.tool_behaviour == TOOL_SCREWDRIVER) if(I.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>") if(stored_card)
try_eject(0,user) to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
return try_eject(user)
return
swap_slot()
to_chat(user, "<span class='notice'>You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].</span>")
/**
*Swaps the card_slot hardware between using the dedicated card slot bay on a computer, and using an expansion bay.
*/
/obj/item/computer_hardware/card_slot/proc/swap_slot()
expansion_hw = !expansion_hw
if(expansion_hw)
device_type = MC_CARD2
else
device_type = MC_CARD
/obj/item/computer_hardware/card_slot/examine(mob/user) /obj/item/computer_hardware/card_slot/examine(mob/user)
. = ..() . = ..()
if(stored_card || stored_card2) . += "The connector is set to fit into [expansion_hw ? "an expansion bay" : "a computer's primary ID bay"], but can be adjusted with a screwdriver."
if(stored_card)
. += "There appears to be something loaded in the card slots." . += "There appears to be something loaded in the card slots."
/obj/item/computer_hardware/card_slot/secondary
device_type = MC_CARD2
expansion_hw = TRUE

View File

@@ -22,14 +22,14 @@
. = ..() . = ..()
. += "<span class='notice'>It has [max_capacity] GQ of storage capacity.</span>" . += "<span class='notice'>It has [max_capacity] GQ of storage capacity.</span>"
/obj/item/computer_hardware/hard_drive/diagnostics(var/mob/user) /obj/item/computer_hardware/hard_drive/diagnostics(mob/user)
..() ..()
// 999 is a byond limit that is in place. It's unlikely someone will reach that many files anyway, since you would sooner run out of space. // 999 is a byond limit that is in place. It's unlikely someone will reach that many files anyway, since you would sooner run out of space.
to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999") to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999")
to_chat(user, "Storage capacity: [used_capacity]/[max_capacity]GQ") to_chat(user, "Storage capacity: [used_capacity]/[max_capacity]GQ")
// Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. // Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
/obj/item/computer_hardware/hard_drive/proc/store_file(var/datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/store_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return 0
@@ -52,7 +52,7 @@
return 1 return 1
// Use this proc to remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. // Use this proc to remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
/obj/item/computer_hardware/hard_drive/proc/remove_file(var/datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/remove_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return 0
@@ -78,7 +78,7 @@
used_capacity = total_size used_capacity = total_size
// Checks whether file can be stored on the hard drive. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file. // Checks whether file can be stored on the hard drive. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file.
/obj/item/computer_hardware/hard_drive/proc/can_store_file(var/datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/can_store_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return 0
@@ -101,7 +101,7 @@
// Tries to find the file by filename. Returns null on failure // Tries to find the file by filename. Returns null on failure
/obj/item/computer_hardware/hard_drive/proc/find_file_by_name(var/filename) /obj/item/computer_hardware/hard_drive/proc/find_file_by_name(filename)
if(!check_functionality()) if(!check_functionality())
return null return null

View File

@@ -11,7 +11,7 @@
device_type = MC_NET device_type = MC_NET
var/static/ntnet_card_uid = 1 var/static/ntnet_card_uid = 1
/obj/item/computer_hardware/network_card/diagnostics(var/mob/user) /obj/item/computer_hardware/network_card/diagnostics(mob/user)
..() ..()
to_chat(user, "NIX Unique ID: [identification_id]") to_chat(user, "NIX Unique ID: [identification_id]")
to_chat(user, "NIX User Tag: [identification_string]") to_chat(user, "NIX User Tag: [identification_string]")
@@ -22,7 +22,7 @@
if(ethernet) if(ethernet)
to_chat(user, "OpenEth (Physical Connection) - Physical network connection port") to_chat(user, "OpenEth (Physical Connection) - Physical network connection port")
/obj/item/computer_hardware/network_card/New(var/l) /obj/item/computer_hardware/network_card/New(l)
..() ..()
identification_id = ntnet_card_uid++ identification_id = ntnet_card_uid++
@@ -31,7 +31,7 @@
return "[identification_string] (NID [identification_id])" return "[identification_string] (NID [identification_id])"
// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection // 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection
/obj/item/computer_hardware/network_card/proc/get_signal(var/specific_action = 0) /obj/item/computer_hardware/network_card/proc/get_signal(specific_action = 0)
if(!holder) // Hardware is not installed in anything. No signal. How did this even get called? if(!holder) // Hardware is not installed in anything. No signal. How did this even get called?
return 0 return 0

View File

@@ -8,12 +8,8 @@
max_capacity = 16 max_capacity = 16
device_type = MC_SDD device_type = MC_SDD
/obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/modular_computer/M, mob/living/user = null) /obj/item/computer_hardware/hard_drive/portable/on_remove(obj/item/modular_computer/MC, mob/user)
M.add_verb(device_type) return //this is a floppy disk, let's not shut the computer down when it gets pulled out.
/obj/item/computer_hardware/hard_drive/portable/on_remove(obj/item/modular_computer/M, mob/living/user = null)
..()
M.remove_verb(device_type)
/obj/item/computer_hardware/hard_drive/portable/install_default_programs() /obj/item/computer_hardware/hard_drive/portable/install_default_programs()
return // Empty by default return // Empty by default

View File

@@ -5,6 +5,7 @@
icon_state = "printer" icon_state = "printer"
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
device_type = MC_PRINT device_type = MC_PRINT
expansion_hw = TRUE
var/stored_paper = 20 var/stored_paper = 20
var/max_paper = 30 var/max_paper = 30

View File

@@ -0,0 +1,8 @@
//This item doesn't do much on its own, but is required by apps such as AtmoZphere.
/obj/item/computer_hardware/sensorpackage
name = "sensor package"
desc = "An integrated sensor package allowing a computer to take readings from the environment. Required by certain programs."
icon_state = "servo"
w_class = WEIGHT_CLASS_TINY
device_type = MC_SENSORS
expansion_hw = TRUE

View File

@@ -52,6 +52,7 @@
var/obj/item/computer_hardware/battery/battery_module = null var/obj/item/computer_hardware/battery/battery_module = null
if(fabricate) if(fabricate)
fabricated_laptop = new /obj/item/modular_computer/laptop/buildable(src) fabricated_laptop = new /obj/item/modular_computer/laptop/buildable(src)
fabricated_laptop.install_component(new /obj/item/computer_hardware/card_slot)
fabricated_laptop.install_component(new /obj/item/computer_hardware/battery) fabricated_laptop.install_component(new /obj/item/computer_hardware/battery)
battery_module = fabricated_laptop.all_components[MC_CELL] battery_module = fabricated_laptop.all_components[MC_CELL]
total_price = 99 total_price = 99
@@ -107,7 +108,7 @@
if(dev_card) if(dev_card)
total_price += 199 total_price += 199
if(fabricate) if(fabricate)
fabricated_laptop.install_component(new /obj/item/computer_hardware/card_slot) fabricated_laptop.install_component(new /obj/item/computer_hardware/card_slot/secondary)
return total_price return total_price
else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this.
@@ -116,6 +117,7 @@
fabricated_tablet = new(src) fabricated_tablet = new(src)
fabricated_tablet.install_component(new /obj/item/computer_hardware/battery) fabricated_tablet.install_component(new /obj/item/computer_hardware/battery)
fabricated_tablet.install_component(new /obj/item/computer_hardware/processor_unit/small) fabricated_tablet.install_component(new /obj/item/computer_hardware/processor_unit/small)
fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot)
battery_module = fabricated_tablet.all_components[MC_CELL] battery_module = fabricated_tablet.all_components[MC_CELL]
total_price = 199 total_price = 199
switch(dev_battery) switch(dev_battery)
@@ -154,11 +156,11 @@
if(dev_printer) if(dev_printer)
total_price += 99 total_price += 99
if(fabricate) if(fabricate)
fabricated_tablet.install_component(new/obj/item/computer_hardware/printer) fabricated_tablet.install_component(new/obj/item/computer_hardware/printer/mini)
if(dev_card) if(dev_card)
total_price += 199 total_price += 199
if(fabricate) if(fabricate)
fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot) fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot/secondary)
return total_price return total_price
return FALSE return FALSE
@@ -222,7 +224,7 @@
return FALSE return FALSE
/obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui) /obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN | NOPOWER | MAINT)) if(machine_stat & (BROKEN | NOPOWER | MAINT))
if(ui) if(ui)
ui.close() ui.close()
return FALSE return FALSE
@@ -257,7 +259,7 @@
say("Insufficient credits on card to purchase!") say("Insufficient credits on card to purchase!")
return return
credits += target_credits credits += target_credits
say("[target_credits] cr has been deposited from your account.") say("[target_credits] cr have been withdrawn from your account.")
return return
return ..() return ..()

View File

@@ -0,0 +1,45 @@
/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 ..()

View File

@@ -3,6 +3,8 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "clipboard" icon_state = "clipboard"
item_state = "clipboard" item_state = "clipboard"
// inhand_icon_state = "clipboard"
// worn_icon_state = "clipboard"
throwforce = 0 throwforce = 0
w_class = WEIGHT_CLASS_SMALL w_class = WEIGHT_CLASS_SMALL
throw_speed = 3 throw_speed = 3
@@ -34,7 +36,6 @@
. += "clipboard_pen" . += "clipboard_pen"
. += "clipboard_over" . += "clipboard_over"
/obj/item/clipboard/attackby(obj/item/W, mob/user, params) /obj/item/clipboard/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/paper)) if(istype(W, /obj/item/paper))
if(!user.transferItemToLoc(W, src)) if(!user.transferItemToLoc(W, src))
@@ -92,14 +93,14 @@
to_chat(usr, "<span class='notice'>You slot [W] into [src].</span>") to_chat(usr, "<span class='notice'>You slot [W] into [src].</span>")
if(href_list["write"]) if(href_list["write"])
var/obj/item/P = locate(href_list["write"]) var/obj/item/P = locate(href_list["write"]) in src
if(istype(P) && P.loc == src) if(istype(P))
if(usr.get_active_held_item()) if(usr.get_active_held_item())
P.attackby(usr.get_active_held_item(), usr) P.attackby(usr.get_active_held_item(), usr)
if(href_list["remove"]) if(href_list["remove"])
var/obj/item/P = locate(href_list["remove"]) var/obj/item/P = locate(href_list["remove"]) in src
if(istype(P) && P.loc == src) if(istype(P))
P.forceMove(usr.loc) P.forceMove(usr.loc)
usr.put_in_hands(P) usr.put_in_hands(P)
if(P == toppaper) if(P == toppaper)
@@ -111,13 +112,13 @@
toppaper = null toppaper = null
if(href_list["read"]) if(href_list["read"])
var/obj/item/paper/P = locate(href_list["read"]) var/obj/item/paper/P = locate(href_list["read"]) in src
if(istype(P) && P.loc == src) if(istype(P))
usr.examinate(P) usr.examinate(P)
if(href_list["top"]) if(href_list["top"])
var/obj/item/P = locate(href_list["top"]) var/obj/item/P = locate(href_list["top"]) in src
if(istype(P) && P.loc == src) if(istype(P))
toppaper = P toppaper = P
to_chat(usr, "<span class='notice'>You move [P.name] to the top.</span>") to_chat(usr, "<span class='notice'>You move [P.name] to the top.</span>")

View File

@@ -35,7 +35,7 @@
. = ..() . = ..()
if(mapload) if(mapload)
for(var/obj/item/I in loc) for(var/obj/item/I in loc)
if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo)) 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
I.forceMove(src) I.forceMove(src)
/obj/structure/filingcabinet/deconstruct(disassembled = TRUE) /obj/structure/filingcabinet/deconstruct(disassembled = TRUE)
@@ -46,7 +46,12 @@
qdel(src) qdel(src)
/obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params) /obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/paper) || istype(P, /obj/item/folder) || istype(P, /obj/item/photo) || istype(P, /obj/item/documents)) 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(!user.transferItemToLoc(P, src)) if(!user.transferItemToLoc(P, src))
return return
to_chat(user, "<span class='notice'>You put [P] in [src].</span>") to_chat(user, "<span class='notice'>You put [P] in [src].</span>")
@@ -54,11 +59,6 @@
sleep(5) sleep(5)
icon_state = initial(icon_state) icon_state = initial(icon_state)
updateUsrDialog() 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) else if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='warning'>You can't put [P] in [src]!</span>") to_chat(user, "<span class='warning'>You can't put [P] in [src]!</span>")
else else
@@ -67,9 +67,6 @@
/obj/structure/filingcabinet/ui_interact(mob/user) /obj/structure/filingcabinet/ui_interact(mob/user)
. = ..() . = ..()
if(isobserver(user))
return
if(contents.len <= 0) if(contents.len <= 0)
to_chat(user, "<span class='notice'>[src] is empty.</span>") to_chat(user, "<span class='notice'>[src] is empty.</span>")
return return
@@ -100,16 +97,17 @@
to_chat(user, "<span class='notice'>You find nothing in [src].</span>") to_chat(user, "<span class='notice'>You find nothing in [src].</span>")
/obj/structure/filingcabinet/Topic(href, href_list) /obj/structure/filingcabinet/Topic(href, href_list)
if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr)))
return
if(href_list["retrieve"]) if(href_list["retrieve"])
usr << browse("", "window=filingcabinet") // Close the menu usr << browse("", "window=filingcabinet") // Close the menu
var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex] var/obj/item/P = locate(href_list["retrieve"]) in src //contents[retrieveindex]
if(istype(P) && P.loc == src && in_range(src, usr)) if(istype(P) && in_range(src, usr))
usr.put_in_hands(P) usr.put_in_hands(P)
updateUsrDialog() updateUsrDialog()
icon_state = "[initial(icon_state)]-open" icon_state = "[initial(icon_state)]-open"
sleep(5) addtimer(VARSET_CALLBACK(src, icon_state, initial(icon_state)), 5)
icon_state = initial(icon_state)
/* /*
@@ -170,6 +168,7 @@
virgin = 0 //tabbing here is correct- it's possible for people to try and use it 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. //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() /obj/structure/filingcabinet/medical/on_attack_hand()
populate() populate()
. = ..() . = ..()

View File

@@ -33,7 +33,10 @@
if(contents.len) if(contents.len)
. += "folder_paper" . += "folder_paper"
/obj/item/folder/attackby(obj/item/W, mob/user, params) /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(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/documents))
if(!user.transferItemToLoc(W, src)) if(!user.transferItemToLoc(W, src))
return return
@@ -43,11 +46,14 @@
if(!user.is_literate()) if(!user.is_literate())
to_chat(user, "<span class='notice'>You scribble illegibly on the cover of [src]!</span>") to_chat(user, "<span class='notice'>You scribble illegibly on the cover of [src]!</span>")
return return
var/inputvalue = stripped_input(user, "What would you like to label the folder?", "Folder Labelling", "", MAX_NAME_LEN) var/inputvalue = stripped_input(user, "What would you like to label the folder?", "Folder Labelling", "", MAX_NAME_LEN)
if(!inputvalue) if(!inputvalue)
return return
if(user.canUseTopic(src, BE_CLOSE)) if(user.canUseTopic(src, BE_CLOSE))
name = "folder - '[inputvalue]'" name = "folder[(inputvalue ? " - '[inputvalue]'" : null)]"
/obj/item/folder/Destroy() /obj/item/folder/Destroy()
@@ -76,14 +82,14 @@
if(usr.contents.Find(src)) if(usr.contents.Find(src))
if(href_list["remove"]) if(href_list["remove"])
var/obj/item/I = locate(href_list["remove"]) var/obj/item/I = locate(href_list["remove"]) in src
if(istype(I) && I.loc == src) if(istype(I))
I.forceMove(usr.loc) I.forceMove(usr.loc)
usr.put_in_hands(I) usr.put_in_hands(I)
if(href_list["read"]) if(href_list["read"])
var/obj/item/I = locate(href_list["read"]) var/obj/item/I = locate(href_list["read"]) in src
if(istype(I) && I.loc == src) if(istype(I))
usr.examinate(I) usr.examinate(I)
//Update everything //Update everything

View File

@@ -1,9 +1,10 @@
/obj/item/hand_labeler /obj/item/hand_labeler
name = "hand labeler" name = "hand labeler"
desc = "A combined label printer and applicator in a portable device, designed to be easy to operate and use." desc = "A combined label printer, applicator, and remover, all in a single portable device. Designed to be easy to operate and use."
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "labeler0" icon_state = "labeler0"
item_state = "flight" item_state = "flight"
// inhand_icon_state = "flight"
var/label = null var/label = null
var/labels_left = 30 var/labels_left = 30
var/mode = 0 var/mode = 0
@@ -55,9 +56,10 @@
to_chat(user, "<span class='warning'>You can't label creatures!</span>") // use a collar to_chat(user, "<span class='warning'>You can't label creatures!</span>") // use a collar
return return
user.visible_message("[user] labels [A] as [label].", \ user.visible_message("<span class='notice'>[user] labels [A] with \"[label]\".</span>", \
"<span class='notice'>You label [A] as [label].</span>") "<span class='notice'>You label [A] with \"[label]\".</span>")
A.name = "[A.name] ([label])" A.AddComponent(/datum/component/label, label)
// playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE)
labels_left-- labels_left--
@@ -90,7 +92,9 @@
name = "cyborg-hand labeler" name = "cyborg-hand labeler"
/obj/item/hand_labeler/borg/afterattack(atom/A, mob/user, proximity) /obj/item/hand_labeler/borg/afterattack(atom/A, mob/user, proximity)
. = ..(A, user, proximity) . = ..()
if(!proximity)
return
if(!iscyborg(user)) if(!iscyborg(user))
return return
@@ -114,6 +118,7 @@
desc = "A roll of paper. Use it on a hand labeler to refill it." desc = "A roll of paper. Use it on a hand labeler to refill it."
icon_state = "labeler_refill" icon_state = "labeler_refill"
item_state = "electropack" item_state = "electropack"
// inhand_icon_state = "electropack"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY

View File

@@ -11,41 +11,6 @@
#define MODE_WRITING 1 #define MODE_WRITING 1
#define MODE_STAMPING 2 #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 * Paper is now using markdown (like in github pull notes) for ALL rendering
@@ -58,6 +23,9 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper" icon_state = "paper"
item_state = "paper" item_state = "paper"
// inhand_icon_state = "paper"
// worn_icon_state = "paper"
// custom_fire_overlay = "paper_onfire_overlay"
throwforce = 0 throwforce = 0
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
throw_range = 1 throw_range = 1
@@ -80,34 +48,19 @@
var/list/stamps /// Positioning for the stamp in tgui var/list/stamps /// Positioning for the stamp in tgui
var/list/stamped /// Overlay info 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 // Reagent ID to transfer on contact
var/contact_poison_volume = 0 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" /// When the sheet can be "filled out"
/// This is an associated list /// This is an associated list
var/list/form_fields = list() var/list/form_fields = list()
var/field_counter = 1 var/field_counter = 1
/obj/item/paper/Destroy() /obj/item/paper/Destroy()
close_all_ui()
stamps = null stamps = null
stamped = null stamped = null
form_fields = null
stamped = null
. = ..() . = ..()
/** /**
@@ -162,7 +115,7 @@
set category = "Object" set category = "Object"
set src in usr set src in usr
if(usr.incapacitated() || !usr.is_literate()) if(!usr.can_read(src) || usr.incapacitated(TRUE, TRUE) || (isobserver(usr) && !IsAdminGhost(usr)))
return return
if(ishuman(usr)) if(ishuman(usr))
var/mob/living/carbon/human/H = usr var/mob/living/carbon/human/H = usr
@@ -180,18 +133,6 @@
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>") 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) 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() /obj/item/paper/proc/clearpaper()
info = "" info = ""
stamps = null stamps = null
@@ -199,28 +140,39 @@
cut_overlays() cut_overlays()
update_icon_state() update_icon_state()
/obj/item/paper/examine_more(mob/user) /obj/item/paper/examine(mob/user)
ui_interact(user) . = ..()
return list("<span class='notice'><i>You try to read [src]...</i></span>") 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/can_interact(mob/user) /obj/item/paper/can_interact(mob/user)
if(!..()) if(in_contents_of(/obj/machinery/door/airlock))
return FALSE return TRUE
// Are we on fire? Hard ot read if so return ..()
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) /obj/item/proc/burn_paper_product_attackby_check(obj/item/I, mob/living/user, bypass_clumsy)
var/ignition_message = I.ignition_effect(src, user) var/ignition_message = I.ignition_effect(src, user)
@@ -244,49 +196,22 @@
/obj/item/paper/attackby(obj/item/P, mob/living/user, params) /obj/item/paper/attackby(obj/item/P, mob/living/user, params)
if(burn_paper_product_attackby_check(P, user)) if(burn_paper_product_attackby_check(P, user))
close_all_ui() SStgui.close_uis(src)
return return
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) 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 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>") to_chat(user, "<span class='warning'>This sheet of paper is full!</span>")
return 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 return
else if(istype(P, /obj/item/stamp)) 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>") 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 return /// Normaly you just stamp, you don't need to read the thing
else else
// cut paper? the sky is the limit! // cut paper? the sky is the limit!
var/datum/ui_state/default/paper_state/state = new ui_interact(user) // The other ui will be created with just read mode outside of this
state.edit_mode = MODE_READING
create_ui(user, state) // The other ui will be created with just read mode outside of this
return ..() return ..()
@@ -301,68 +226,64 @@
get_asset_datum(/datum/asset/spritesheet/simple/paper), 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 // Update the UI
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, "PaperSheet", name) ui = new(user, src, "PaperSheet", name)
state = new
ui.set_state(state)
ui.set_autoupdate(FALSE)
viewing_ui[user] = ui
ui.open() ui.open()
/obj/item/paper/ui_close(mob/user)
/// close the editing window and change the mode
viewing_ui[user] = null
. = ..()
// Again, we have to do this as autoupdate is off /obj/item/paper/ui_static_data(mob/user)
/obj/item/paper/proc/update_all_ui() . = list()
for(var/datum/tgui/ui in viewing_ui) .["text"] = info
ui.process(force = TRUE) .["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/close_all_ui()
for(var/datum/tgui/ui in viewing_ui)
ui.close()
viewing_ui = list()
/obj/item/paper/ui_data(mob/user) /obj/item/paper/ui_data(mob/user)
var/list/data = list() var/list/data = list()
var/obj/O = user.get_active_held_item()
var/datum/tgui/ui = viewing_ui[user] if(istype(O, /obj/item/toy/crayon))
var/datum/ui_state/default/paper_state/state = ui.state var/obj/item/toy/crayon/PEN = O
data["pen_font"] = CRAYON_FONT
// Should all this go in static data and just do a forced update? data["pen_color"] = PEN.paint_color
data["text"] = info data["edit_mode"] = MODE_WRITING
data["max_length"] = MAX_PAPER_LENGTH data["is_crayon"] = TRUE
data["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling? data["stamp_class"] = "FAKE"
data["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set data["stamp_icon_state"] = "FAKE"
data["stamps"] = stamps else if(istype(O, /obj/item/pen))
var/obj/item/pen/PEN = O
data["edit_mode"] = state.edit_mode data["pen_font"] = PEN.font
data["edit_usr"] = "[ui.user]"; data["pen_color"] = PEN.colour
data["edit_mode"] = MODE_WRITING
// pen info for editing data["is_crayon"] = FALSE
data["is_crayon"] = state.is_crayon data["stamp_class"] = "FAKE"
data["pen_font"] = state.pen_font data["stamp_icon_state"] = "FAKE"
data["pen_color"] = state.pen_color else if(istype(O, /obj/item/stamp))
// stamping info for..stamping var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
data["stamp_class"] = state.stamp_class 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"
data["field_counter"] = field_counter data["field_counter"] = field_counter
data["form_fields"] = form_fields data["form_fields"] = form_fields
return data return data
/obj/item/paper/ui_act(action, params, datum/tgui/ui, datum/ui_state/default/paper_state/state) /obj/item/paper/ui_act(action, params,datum/tgui/ui)
if(..()) if(..())
return return
switch(action) switch(action)
@@ -370,34 +291,33 @@
var/stamp_x = text2num(params["x"]) var/stamp_x = text2num(params["x"])
var/stamp_y = text2num(params["y"]) var/stamp_y = text2num(params["y"])
var/stamp_r = text2num(params["r"]) // rotation in degrees 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)) if (isnull(stamps))
stamps = new/list() stamps = list()
if(stamps.len < MAX_PAPER_STAMPS) if(stamps.len < MAX_PAPER_STAMPS)
// I hate byond when dealing with freaking lists // I hate byond when dealing with freaking lists
stamps += list(list(state.stamp_class, stamp_x, stamp_y,stamp_r)) /// WHHHHY stamps[++stamps.len] = list(stamp_class, stamp_x, stamp_y, stamp_r) /// WHHHHY
/// This does the overlay stuff /// This does the overlay stuff
if (isnull(stamped)) if (isnull(stamped))
stamped = new/list() stamped = list()
if(stamped.len < MAX_PAPER_STAMPS_OVERLAYS) if(stamped.len < MAX_PAPER_STAMPS_OVERLAYS)
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[state.stamp_icon_state]") var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[stamp_icon_state]")
stampoverlay.pixel_x = rand(-2, 2) stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2) stampoverlay.pixel_y = rand(-3, 2)
add_overlay(stampoverlay) add_overlay(stampoverlay)
LAZYADD(stamped, state.stamp_icon_state) LAZYADD(stamped, stamp_icon_state)
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>") 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>")
else else
to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!")) to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!"))
update_all_ui()
. = TRUE . = TRUE
if("save") if("save")
var/in_paper = params["text"] var/in_paper = params["text"]
var/paper_len = length(in_paper) var/paper_len = length(in_paper)
var/list/fields = params["form_fields"]
field_counter = params["field_counter"] ? text2num(params["field_counter"]) : field_counter field_counter = params["field_counter"] ? text2num(params["field_counter"]) : field_counter
if(paper_len > MAX_PAPER_LENGTH) if(paper_len > MAX_PAPER_LENGTH)
@@ -413,14 +333,10 @@
if(info != in_paper) if(info != in_paper)
to_chat(ui.user, "You have added to your paper masterpiece!"); to_chat(ui.user, "You have added to your paper masterpiece!");
info = in_paper info = in_paper
update_static_data(usr,ui)
for(var/key in fields)
form_fields[key] = fields[key];
update_all_ui()
update_icon() update_icon()
. = TRUE . = TRUE
/** /**

View File

@@ -26,11 +26,11 @@
var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD) var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD)
if(BP) if(BP)
BP.drop_limb() BP.drop_limb()
playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) playsound(loc, pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg'),50, TRUE, -1)
return (BRUTELOSS) return (BRUTELOSS)
else 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>") 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, 1, -1) playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1)
return (BRUTELOSS) return (BRUTELOSS)
@@ -42,11 +42,12 @@
if(storedpaper) if(storedpaper)
. += "paper" . += "paper"
/obj/item/papercutter/attackby(obj/item/P, mob/user, params) /obj/item/papercutter/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/paper) && !storedpaper) if(istype(P, /obj/item/paper) && !storedpaper)
if(!user.transferItemToLoc(P, src)) if(!user.transferItemToLoc(P, src))
return return
playsound(loc, "pageturn", 60, 1) playsound(loc, "pageturn", 60, TRUE)
to_chat(user, "<span class='notice'>You place [P] in [src].</span>") to_chat(user, "<span class='notice'>You place [P] in [src].</span>")
storedpaper = P storedpaper = P
update_icon() update_icon()
@@ -59,17 +60,17 @@
storedcutter = P storedcutter = P
update_icon() update_icon()
return return
if(istype(P, /obj/item/screwdriver) && storedcutter) if(P.tool_behaviour == TOOL_SCREWDRIVER && storedcutter)
P.play_tool_sound(src) P.play_tool_sound(src)
to_chat(user, "<span class='notice'>[storedcutter] has been [cuttersecured ? "unsecured" : "secured"].</span>") to_chat(user, "<span class='notice'>[storedcutter] has been [cuttersecured ? "unsecured" : "secured"].</span>")
cuttersecured = !cuttersecured cuttersecured = !cuttersecured
return return
..() ..()
/obj/item/papercutter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/papercutter/on_attack_hand(mob/user)
add_fingerprint(user) add_fingerprint(user)
if(!storedcutter) if(!storedcutter)
to_chat(user, "<span class='notice'>The cutting blade is gone! You can't use [src] now.</span>") to_chat(user, "<span class='warning'>The cutting blade is gone! You can't use [src] now.</span>")
return return
if(!cuttersecured) if(!cuttersecured)
@@ -79,7 +80,7 @@
update_icon() update_icon()
if(storedpaper) if(storedpaper)
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1) playsound(src.loc, 'sound/weapons/slash.ogg', 50, TRUE)
to_chat(user, "<span class='notice'>You neatly cut [storedpaper].</span>") to_chat(user, "<span class='notice'>You neatly cut [storedpaper].</span>")
storedpaper = null storedpaper = null
qdel(storedpaper) qdel(storedpaper)
@@ -88,6 +89,7 @@
update_icon() update_icon()
/obj/item/papercutter/MouseDrop(atom/over_object) /obj/item/papercutter/MouseDrop(atom/over_object)
. = ..()
var/mob/M = usr var/mob/M = usr
if(M.incapacitated() || !Adjacent(M)) if(M.incapacitated() || !Adjacent(M))
return return
@@ -98,10 +100,6 @@
else if(istype(over_object, /obj/screen/inventory/hand)) else if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object var/obj/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(src, H.held_index) M.putItemFromInventoryInHandIfPossible(src, H.held_index)
else
. = ..()
add_fingerprint(M) add_fingerprint(M)
/obj/item/paperslip /obj/item/paperslip
@@ -112,6 +110,12 @@
resistance_flags = FLAMMABLE resistance_flags = FLAMMABLE
max_integrity = 50 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() /obj/item/paperslip/Initialize()
. = ..() . = ..()
pixel_x = rand(-5, 5) pixel_x = rand(-5, 5)
@@ -124,5 +128,6 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "cutterblade" icon_state = "cutterblade"
item_state = "knife" item_state = "knife"
// inhand_icon_state = "knife"
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'

View File

@@ -4,53 +4,22 @@
/obj/item/paper/fluff/sop /obj/item/paper/fluff/sop
name = "paper- 'Standard Operating Procedure'" name = "paper- 'Standard Operating Procedure'"
info = {" 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!"
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 /obj/item/paper/fluff/shuttles/daniel
info = "i love daniel<br>daniel is my best friend<br><br>you are tearing me apart elise" 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 //////////// Job guides n' fluff
@@ -90,9 +59,42 @@ Accidental Reentry:
name = "paper- 'Chemical Information'" 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" 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 * Stations
*/ */
////////// cogstation.
/obj/item/paper/guides/cogstation/job_changes /obj/item/paper/guides/cogstation/job_changes
name = "MEMO: Job Changes" name = "MEMO: Job Changes"

View File

@@ -4,6 +4,7 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper_bin1" icon_state = "paper_bin1"
item_state = "sheet-metal" item_state = "sheet-metal"
// inhand_icon_state = "sheet-metal"
lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi' lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi' righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi'
throwforce = 0 throwforce = 0
@@ -43,6 +44,7 @@
..() ..()
/obj/item/paper_bin/MouseDrop(atom/over_object) /obj/item/paper_bin/MouseDrop(atom/over_object)
. = ..()
var/mob/living/M = usr var/mob/living/M = usr
if(!istype(M) || M.incapacitated() || !Adjacent(M)) if(!istype(M) || M.incapacitated() || !Adjacent(M))
return return
@@ -54,17 +56,18 @@
var/obj/screen/inventory/hand/H = over_object var/obj/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(src, H.held_index) M.putItemFromInventoryInHandIfPossible(src, H.held_index)
else
. = ..()
add_fingerprint(M) add_fingerprint(M)
/obj/item/paper_bin/attack_paw(mob/user) /obj/item/paper_bin/attack_paw(mob/user)
return attack_hand(user) return attack_hand(user)
/obj/item/paper_bin/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) //ATTACK HAND IGNORING PARENT RETURN VALUE
if(user.lying) /obj/item/paper_bin/on_attack_hand(mob/user)
return if(isliving(user))
var/mob/living/L = user
if(!(L.mobility_flags & MOBILITY_PICKUP))
return
// user.changeNext_move(CLICK_CD_MELEE)
if(bin_pen) if(bin_pen)
var/obj/item/pen/P = bin_pen var/obj/item/pen/P = bin_pen
P.add_fingerprint(user) P.add_fingerprint(user)
@@ -85,8 +88,8 @@
P = new papertype(src) P = new papertype(src)
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(30)) if(prob(30))
P.info = "*HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK*\n*APRIL FOOLS*\n" P.info = "<font face=\"[CRAYON_FONT]\" color=\"red\"><b>HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK<br>APRIL FOOLS</b></font>"
P.rigged = 1 P.AddComponent(/datum/component/honkspam)
P.add_fingerprint(user) P.add_fingerprint(user)
P.forceMove(user.loc) P.forceMove(user.loc)
@@ -148,8 +151,7 @@
papertype = /obj/item/paper/natural papertype = /obj/item/paper/natural
resistance_flags = FLAMMABLE resistance_flags = FLAMMABLE
/obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user)
..()
if(total_paper < 1) if(total_paper < 1)
qdel(src) qdel(src)
@@ -173,3 +175,9 @@
qdel(src) qdel(src)
else 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

View File

@@ -1,9 +1,9 @@
/obj/item/paperplane /obj/item/paperplane
name = "paper plane" name = "paper plane"
desc = "Paper, folded in the shape of a plane." desc = "Paper, folded in the shape of a plane."
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paperplane" icon_state = "paperplane"
// custom_fire_overlay = "paperplane_onfire"
throw_range = 7 throw_range = 7
throw_speed = 1 throw_speed = 1
throwforce = 0 throwforce = 0
@@ -11,7 +11,7 @@
resistance_flags = FLAMMABLE resistance_flags = FLAMMABLE
max_integrity = 50 max_integrity = 50
var/hit_probability = 2//% var/hit_probability = 2 //%
var/obj/item/paper/internalPaper var/obj/item/paper/internalPaper
/obj/item/paperplane/origami /obj/item/paperplane/origami
@@ -41,6 +41,13 @@
qdel(src) qdel(src)
return ..() return ..()
/obj/item/paperplane/Exited(atom/movable/AM, atom/newLoc)
. = ..()
if (AM == internalPaper)
internalPaper = null
if(!QDELETED(src))
qdel(src)
/obj/item/paperplane/Destroy() /obj/item/paperplane/Destroy()
QDEL_NULL(internalPaper) QDEL_NULL(internalPaper)
return ..() return ..()
@@ -71,35 +78,23 @@
user.put_in_hands(internal_paper_tmp) user.put_in_hands(internal_paper_tmp)
/obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params) /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)) if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
to_chat(user, "<span class='notice'>You should unfold [src] before changing it.</span>") to_chat(user, "<span class='warning'>You should unfold [src] before changing it!</span>")
return return
else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane 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. internalPaper.attackby(P, user) //spoofed attack to update internal paper.
update_icon() update_icon()
add_fingerprint(user)
return
else if(P.get_temperature()) return ..()
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) /obj/item/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback, quickstart = TRUE)
. = ..(target, range, speed, thrower, FALSE, diagonals_first, callback) . = ..(target, range, speed, thrower, FALSE, diagonals_first, callback, quickstart = quickstart)
/obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) /obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscarbon(hit_atom)) if(iscarbon(hit_atom))
@@ -112,26 +107,28 @@
if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman
return return
var/mob/living/carbon/human/H = hit_atom var/mob/living/carbon/human/H = hit_atom
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
if(prob(hit_probability)) if(prob(hit_probability))
if(H.is_eyes_covered()) if(H.is_eyes_covered())
return return
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) visible_message("<span class='danger'>\The [src] hits [H] in the eye[eyes ? "" : " socket"]!</span>")
visible_message("<span class='danger'>\The [src] hits [H] in the eye!</span>")
H.adjust_blurriness(6) H.adjust_blurriness(6)
if(eyes) eyes?.applyOrganDamage(rand(6,8))
eyes.applyOrganDamage(rand(6,8))
H.DefaultCombatKnockdown(40) H.DefaultCombatKnockdown(40)
H.emote("scream") H.emote("scream")
/obj/item/paper/examine(mob/user) /obj/item/paper/examine(mob/user)
. = ..() . = ..()
. += "<span class='notice'>Alt-click [src] to fold it into a paper plane.</span>" . += "<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) /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 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>") to_chat(user, "<span class='notice'>You fold [src] into the shape of a plane!</span>")
user.temporarilyRemoveItemFromInventory(src) user.temporarilyRemoveItemFromInventory(src)
var/obj/item/paperplane/plane_type = /obj/item/paperplane var/obj/item/paperplane/plane_type = /obj/item/paperplane
@@ -142,4 +139,3 @@
I = new plane_type(user, src) I = new plane_type(user, src)
user.put_in_hands(I) user.put_in_hands(I)
return TRUE

View File

@@ -16,6 +16,8 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "pen" icon_state = "pen"
item_state = "pen" item_state = "pen"
// inhand_icon_state = "pen"
// worn_icon_state = "pen"
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS
throwforce = 0 throwforce = 0
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
@@ -76,6 +78,22 @@
icon_state = "pen-fountain" icon_state = "pen-fountain"
font = FOUNTAIN_PEN_FONT 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 /obj/item/pen/fountain/captain
name = "captain's fountain pen" name = "captain's fountain pen"
desc = "It's an expensive Oak fountain pen. The nib is quite sharp." desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
@@ -93,6 +111,7 @@
"Black and Silver" = "pen-fountain-b", "Black and Silver" = "pen-fountain-b",
"Command Blue" = "pen-fountain-cb" "Command Blue" = "pen-fountain-cb"
) )
embedding = list("embed_chance" = 75)
/obj/item/pen/fountain/captain/Initialize() /obj/item/pen/fountain/captain/Initialize()
. = ..() . = ..()
@@ -139,20 +158,18 @@
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
return return
if(oldname == input) if(oldname == input)
to_chat(user, "You changed \the [O.name] to... well... \the [O.name].") to_chat(user, "<span class='notice'>You changed \the [O.name] to... well... \the [O.name].</span>")
else else
O.name = input O.name = input
to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].") to_chat(user, "<span class='notice'>\The [oldname] has been successfully been renamed to \the [input].</span>")
O.renamedByPlayer = TRUE O.renamedByPlayer = TRUE
log_game("[user] [key_name(user)] has renamed [O] to [input]")
if(penchoice == "Change description") if(penchoice == "Change description")
var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 2048) var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 100)
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
return return
O.desc = input O.desc = input
to_chat(user, "You have successfully changed \the [O.name]'s description.") to_chat(user, "<span class='notice'>You have successfully changed \the [O.name]'s description.</span>")
log_game("[user] [key_name(user)] has changed [O]'s description to to [input]")
/* /*
* Sleepypens * Sleepypens
@@ -181,9 +198,10 @@
*/ */
/obj/item/pen/edagger /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 = 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 sharpness = SHARP_EDGED
var/on = FALSE var/on = FALSE
embedding = list(embed_chance = EMBED_CHANCE)
/obj/item/pen/edagger/ComponentInitialize() /obj/item/pen/edagger/ComponentInitialize()
. = ..() . = ..()
@@ -193,29 +211,38 @@
/obj/item/pen/edagger/get_sharpness() /obj/item/pen/edagger/get_sharpness()
return on * 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) /obj/item/pen/edagger/attack_self(mob/living/user)
if(on) if(on)
on = FALSE on = FALSE
force = initial(force) force = initial(force)
throw_speed = initial(throw_speed)
w_class = initial(w_class) w_class = initial(w_class)
name = initial(name) name = initial(name)
hitsound = initial(hitsound) hitsound = initial(hitsound)
embedding = null embedding = list(embed_chance = EMBED_CHANCE)
throwforce = initial(throwforce) throwforce = initial(throwforce)
playsound(user, 'sound/weapons/saberoff.ogg', 5, 1) playsound(user, 'sound/weapons/saberoff.ogg', 5, TRUE)
to_chat(user, "<span class='warning'>[src] can now be concealed.</span>") to_chat(user, "<span class='warning'>[src] can now be concealed.</span>")
updateEmbedding()
else else
on = TRUE on = TRUE
force = 18 force = 18
throw_speed = 4
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
name = "energy dagger" name = "energy dagger"
hitsound = 'sound/weapons/blade1.ogg' hitsound = 'sound/weapons/blade1.ogg'
embedding = list(embed_chance = 100, fall_chance = 0) //rule of cool embedding = list(embed_chance = 100) //rule of cool
throwforce = 35 throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, 1) playsound(user, 'sound/weapons/saberon.ogg', 5, TRUE)
to_chat(user, "<span class='warning'>[src] is now active.</span>") to_chat(user, "<span class='warning'>[src] is now active.</span>")
updateEmbedding() updateEmbedding()
update_icon() update_icon()
/obj/item/pen/edagger/update_icon_state() /obj/item/pen/edagger/update_icon_state()
@@ -235,6 +262,8 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "digging_pen" icon_state = "digging_pen"
item_state = "pen" item_state = "pen"
// inhand_icon_state = "pen"
// worn_icon_state = "pen"
force = 3 force = 3
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10) custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10)

View File

@@ -4,6 +4,7 @@
icon = 'icons/obj/bureaucracy.dmi' icon = 'icons/obj/bureaucracy.dmi'
icon_state = "stamp-ok" icon_state = "stamp-ok"
item_state = "stamp" item_state = "stamp"
// inhand_icon_state = "stamp"
throwforce = 0 throwforce = 0
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
throw_speed = 3 throw_speed = 3
@@ -11,6 +12,8 @@
custom_materials = list(/datum/material/iron=60) custom_materials = list(/datum/material/iron=60)
pressure_resistance = 2 pressure_resistance = 2
attack_verb = list("stamped") attack_verb = list("stamped")
// attack_verb_continuous = list("stamps")
// attack_verb_simple = list("stamp")
/obj/item/stamp/suicide_act(mob/user) /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>") user.visible_message("<span class='suicide'>[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.</span>")
@@ -66,5 +69,25 @@
icon_state = "stamp-clown" icon_state = "stamp-clown"
dye_color = DYE_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) /obj/item/stamp/attack_paw(mob/user)
return attack_hand(user) return attack_hand(user)

View File

@@ -0,0 +1,231 @@
//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<65>. 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 ..()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
icons/stamp_icons/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -432,6 +432,7 @@
#include "code\datums\components\footstep.dm" #include "code\datums\components\footstep.dm"
#include "code\datums\components\fried.dm" #include "code\datums\components\fried.dm"
#include "code\datums\components\gps.dm" #include "code\datums\components\gps.dm"
#include "code\datums\components\honkspam.dm"
#include "code\datums\components\identification.dm" #include "code\datums\components\identification.dm"
#include "code\datums\components\igniter.dm" #include "code\datums\components\igniter.dm"
#include "code\datums\components\infective.dm" #include "code\datums\components\infective.dm"
@@ -439,6 +440,7 @@
#include "code\datums\components\killerqueen.dm" #include "code\datums\components\killerqueen.dm"
#include "code\datums\components\knockback.dm" #include "code\datums\components\knockback.dm"
#include "code\datums\components\knockoff.dm" #include "code\datums\components\knockoff.dm"
#include "code\datums\components\label.dm"
#include "code\datums\components\lifesteal.dm" #include "code\datums\components\lifesteal.dm"
#include "code\datums\components\lockon_aiming.dm" #include "code\datums\components\lockon_aiming.dm"
#include "code\datums\components\magnetic_catch.dm" #include "code\datums\components\magnetic_catch.dm"
@@ -2836,6 +2838,7 @@
#include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\network.dm"
#include "code\modules\NTNet\relays.dm" #include "code\modules\NTNet\relays.dm"
#include "code\modules\NTNet\services\_service.dm" #include "code\modules\NTNet\services\_service.dm"
#include "code\modules\paperwork\carbonpaper.dm"
#include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\contract.dm"
#include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\filingcabinet.dm"
@@ -2849,6 +2852,7 @@
#include "code\modules\paperwork\pen.dm" #include "code\modules\paperwork\pen.dm"
#include "code\modules\paperwork\photocopier.dm" #include "code\modules\paperwork\photocopier.dm"
#include "code\modules\paperwork\stamps.dm" #include "code\modules\paperwork\stamps.dm"
#include "code\modules\paperwork\ticketmachine.dm"
#include "code\modules\photography\_pictures.dm" #include "code\modules\photography\_pictures.dm"
#include "code\modules\photography\camera\camera.dm" #include "code\modules\photography\camera\camera.dm"
#include "code\modules\photography\camera\camera_image_capturing.dm" #include "code\modules\photography\camera\camera_image_capturing.dm"