diff --git a/code/__DEFINES/dye_keys.dm b/code/__DEFINES/dye_keys.dm index 133f9c47d3..a01dcacc18 100644 --- a/code/__DEFINES/dye_keys.dm +++ b/code/__DEFINES/dye_keys.dm @@ -4,6 +4,7 @@ #define DYE_REGISTRY_SNEAKERS "sneakers" #define DYE_REGISTRY_FANNYPACK "fannypack" #define DYE_REGISTRY_BEDSHEET "bedsheet" +#define DYE_LAWYER_SPECIAL "lawyer_special" #define DYE_RED "red" #define DYE_ORANGE "orange" @@ -16,6 +17,7 @@ #define DYE_RAINBOW "rainbow" #define DYE_MIME "mime" #define DYE_COSMIC "cosmic" +#define DYE_SYNDICATE "syndicate" #define DYE_QM "qm" #define DYE_LAW "law" #define DYE_CAPTAIN "captain" @@ -26,3 +28,5 @@ #define DYE_CMO "cmo" #define DYE_REDCOAT "redcoat" #define DYE_CLOWN "clown" +#define DYE_CHAP "chap" +#define DYE_CENTCOM "centcom" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index fc1706a948..0704947dda 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -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 PRINTER_FONT "Times New Roman" #define SIGNFONT "Times New Roman" +#define CHARCOAL_FONT "Candara" #define RESIZE_DEFAULT_SIZE 1 diff --git a/code/datums/components/honkspam.dm b/code/datums/components/honkspam.dm new file mode 100644 index 0000000000..73b5e3335a --- /dev/null +++ b/code/datums/components/honkspam.dm @@ -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) diff --git a/code/datums/components/label.dm b/code/datums/components/label.dm new file mode 100644 index 0000000000..c6d0c595eb --- /dev/null +++ b/code/datums/components/label.dm @@ -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, "You remove the label from [parent].") + 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 += "It has a label with some words written on it. Use a hand labeler to remove it." + +/// 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. diff --git a/code/modules/NTNet/netdata.dm b/code/modules/NTNet/netdata.dm index 857869fc21..2a3a85f706 100644 --- a/code/modules/NTNet/netdata.dm +++ b/code/modules/NTNet/netdata.dm @@ -11,23 +11,6 @@ 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) data["data"] = primary data["data_secondary"] = secondary diff --git a/code/modules/NTNet/network.dm b/code/modules/NTNet/network.dm index d86ad792fe..2a2820d289 100644 --- a/code/modules/NTNet/network.dm +++ b/code/modules/NTNet/network.dm @@ -206,7 +206,7 @@ for(var/datum/ntnet_conversation/chan in chat_channels) if(chan.id == id) return chan - + // Resets the IDS alarm /datum/ntnet/proc/resetIDS() intrusion_detection_alarm = FALSE diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index e7bdbc6d52..712ee4c867 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -105,11 +105,11 @@ "stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png', "stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png', "stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png', - "stamp-law" = 'icons/stamp_icons/large_stamp-law.png' - // "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png', - // "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png', - // "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png', - // "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png' + "stamp-law" = 'icons/stamp_icons/large_stamp-law.png', + "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png', + "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png', + "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png', + "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png' ) diff --git a/code/modules/modular_computers/computers/_modular_computer_shared.dm b/code/modules/modular_computers/computers/_modular_computer_shared.dm index 8ca93e8347..f0583a9af1 100644 --- a/code/modules/modular_computers/computers/_modular_computer_shared.dm +++ b/code/modules/modular_computers/computers/_modular_computer_shared.dm @@ -44,18 +44,20 @@ . += "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_slot2 = get_modular_computer_part(MC_CARD2) + var/multiple_slots = istype(card_slot) && istype(card_slot2) 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/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) 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 - . += "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." . += "Alt-click [src] to eject the identification card[multiple_cards ? "s":""]." 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) if(printer_slot) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 67c04de13f..4313f4fa98 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -4,6 +4,12 @@ /obj/item/modular_computer name = "modular 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/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 // 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_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. @@ -31,20 +35,16 @@ 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. - 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) - - // Important hardware (must be installed for computer to work) - - // 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 + /// List of "connection ports" in this computer and the components with which they are plugged + var/list/all_components = list() + /// Lazy List of extra hardware slots that can be used modularly. + var/list/expansion_bays + /// Number of total expansion bays this computer has available. + var/max_bays = 0 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/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_color //The color of that light @@ -71,80 +71,15 @@ physical = null 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) ..() if(issilicon(user)) return 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/ai_slot/ai_slot = all_components[MC_AI] - 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) - + return (card_slot2?.try_eject(user) || card_slot?.try_eject(user)) //Try the secondary one first. // Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. /obj/item/modular_computer/GetAccess() @@ -160,19 +95,25 @@ return ..() /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] - if(!card_slot) - return - return card_slot.RemoveID() + return (card_slot2?.try_eject() || card_slot?.try_eject()) //Try the secondary one first. /obj/item/modular_computer/InsertID(obj/item/inserting_item) 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, "There isn't anywhere you can fit a card into on this computer.") return FALSE + var/obj/item/card/inserting_id = inserting_item.RemoveID() if(!inserting_id) 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, "This computer doesn't have an open card slot.") + return FALSE /obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location) var/mob/M = usr @@ -189,7 +130,7 @@ return if(enabled) 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") if(response == "Yes") turn_on(user) diff --git a/code/modules/modular_computers/computers/item/computer_components.dm b/code/modules/modular_computers/computers/item/computer_components.dm index 3c94a66384..8668b279cf 100644 --- a/code/modules/modular_computers/computers/item/computer_components.dm +++ b/code/modules/modular_computers/computers/item/computer_components.dm @@ -6,6 +6,14 @@ to_chat(user, "This component is too large for \the [src]!") return FALSE + if(H.expansion_hw) + if(LAZYLEN(expansion_bays) >= max_bays) + to_chat(user, "All of the computer's expansion bays are filled.") + return FALSE + if(LAZYACCESS(expansion_bays, H.device_type)) + to_chat(user, "The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\".") + return FALSE + if(all_components[H.device_type]) to_chat(user, "This computer's hardware slot is already occupied by \the [all_components[H.device_type]].") return FALSE @@ -20,6 +28,8 @@ if(user && !user.transferItemToLoc(H, src)) return FALSE + if(H.expansion_hw) + LAZYSET(expansion_bays, H.device_type, H) all_components[H.device_type] = H to_chat(user, "You install \the [H] into \the [src].") @@ -32,7 +42,9 @@ /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. return FALSE + if(H.expansion_hw) + LAZYREMOVE(expansion_bays, H.device_type) all_components.Remove(H.device_type) to_chat(user, "You remove \the [H] from \the [src].") @@ -43,6 +55,7 @@ if(enabled && !use_power()) shutdown_computer() update_icon() + return TRUE // Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index fd017e2b0f..4a985b93c1 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -44,6 +44,33 @@ /obj/item/modular_computer/ui_data(mob/user) var/list/data = get_header_data() 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() 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) @@ -157,6 +184,36 @@ light_color = new_color update_light() 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 return diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index 5927d57a0b..ef83140a8f 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -12,6 +12,7 @@ hardware_flag = PROGRAM_LAPTOP max_hardware_size = 2 w_class = WEIGHT_CLASS_NORMAL + max_bays = 4 // No running around with open laptops in hands. item_flags = SLOWS_WHILE_IN_HAND diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index c79d7a9361..0d7b567877 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -8,6 +8,7 @@ icon_state_unpowered = null icon_state_menu = null hardware_flag = 0 + max_bays = 4 var/obj/machinery/modular_computer/machinery_computer = null @@ -18,7 +19,7 @@ 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 @@ -56,23 +57,5 @@ machinery_computer.update_icon() 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) ui_interact(user) diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index 41a256467f..67e8118c7a 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -5,10 +5,11 @@ icon_state_unpowered = "tablet" icon_state_powered = "tablet" icon_state_menu = "menu" - //worn_icon_state = "tablet" + // worn_icon_state = "tablet" hardware_flag = PROGRAM_TABLET max_hardware_size = 1 w_class = WEIGHT_CLASS_SMALL + max_bays = 3 steel_sheet_cost = 1 slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT has_light = TRUE //LED flashlight! diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm index 7cca8ea5b4..d4945d04de 100644 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/tablet_presets.dm @@ -26,10 +26,20 @@ 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(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/printer/mini) 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. /obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize() diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 9d29b23e76..12b2f6d25a 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -1,6 +1,6 @@ /obj/machinery/modular_computer/console/preset // 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_battery = FALSE var/_has_ai = FALSE @@ -11,8 +11,9 @@ return 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) cpu.install_component(new /obj/item/computer_hardware/printer) if(_has_battery) @@ -59,7 +60,7 @@ console_department = "Command" name = "command console" desc = "A stationary computer. This one comes preloaded with command programs." - _has_id_slot = TRUE + _has_second_id_slot = TRUE _has_printer = TRUE /obj/machinery/modular_computer/console/preset/command/install_programs() @@ -73,7 +74,7 @@ console_department = "Identification" name = "identification console" desc = "A stationary computer. This one comes preloaded with identification modification programs." - _has_id_slot = TRUE + _has_second_id_slot = TRUE _has_printer = TRUE /obj/machinery/modular_computer/console/preset/id/install_programs() diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 6f016ad147..0e6f4d161a 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -75,30 +75,6 @@ add_overlay("bsod") 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) if(cpu) cpu.AltClick(user) @@ -136,7 +112,7 @@ 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)) return cpu.attackby(W, user) return ..() @@ -169,5 +145,4 @@ // "Brute" damage mostly damages the casing. /obj/machinery/modular_computer/bullet_act(obj/item/projectile/Proj) if(cpu) - return cpu.bullet_act(Proj) - return ..() + cpu.bullet_act(Proj) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 12e5ef6e95..6d6a48d567 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -25,8 +25,6 @@ var/ntnet_status = 1 /// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or 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. var/available_on_ntnet = 1 /// 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() 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. -// Can also be called manually, with optional parameter being access_to_check to scan the user's ID -/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE) +/** + *Check if the user can run program. Only humans can operate computer. Automatically called in run_program() + *ID must be inserted into a card slot to be read. If the program is not currently installed (as is the case when + *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 if(!access_to_check) if(transfer && transfer_access) @@ -104,29 +110,24 @@ if(issilicon(user)) return TRUE - if(ishuman(user)) + if(!length(access)) var/obj/item/card/id/D var/obj/item/computer_hardware/card_slot/card_slot - if(computer && card_slot) + if(computer) card_slot = computer.all_components[MC_CARD] - D = card_slot.GetID() - var/mob/living/carbon/human/h = user - var/obj/item/card/id/I = h.get_idcard(TRUE) + D = card_slot?.GetID() - if(!I && !D) + if(!D) if(loud) to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") return FALSE + access = D.GetAccess() - if(I) - if(access_to_check in I.GetAccess()) - return TRUE - else if(D) - if(access_to_check in D.GetAccess()) - return TRUE - if(loud) - to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") - return 0 + if(access_to_check in access) + return TRUE + if(loud) + to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") + return FALSE // 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. @@ -139,8 +140,12 @@ // When implementing new program based device, use this to run the program. /datum/computer_file/program/proc/run_program(mob/living/user) if(can_run(user, 1)) - if(requires_ntnet && network_destination) - generate_network_log("Connection opened to [network_destination].") + if(requires_ntnet) + 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 return 1 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. /datum/computer_file/program/proc/kill_program(forced = FALSE) program_state = PROGRAM_STATE_KILLED - if(network_destination) - generate_network_log("Connection to [network_destination] closed.") + if(requires_ntnet) + 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 /datum/computer_file/program/ui_interact(mob/user, datum/tgui/ui) diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm index 3c1daa5af3..1cb74a227b 100644 --- a/code/modules/modular_computers/file_system/program_events.dm +++ b/code/modules/modular_computers/file_system/program_events.dm @@ -2,7 +2,7 @@ // Always include a parent call when overriding an event. // 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 // Called when the computer fails due to power loss. Override when program wants to specifically react to power loss. diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index 364ad79737..7ae6dd203a 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -1,8 +1,8 @@ /datum/computer_file/program/aidiag filename = "aidiag" - filedesc = "AI Integrity Restorer" + filedesc = "NT FRK" 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 requires_ntnet = FALSE usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP @@ -48,7 +48,7 @@ if(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) - ai_slot.try_eject(0,usr) + ai_slot.try_eject(usr) return TRUE /datum/computer_file/program/aidiag/process_tick() @@ -71,14 +71,19 @@ ai_slot.locked = FALSE restoring = FALSE return - ai_slot.locked =TRUE + ai_slot.locked = TRUE A.adjustOxyLoss(-5, 0)//, FALSE) A.adjustFireLoss(-5, 0)//, FALSE) A.adjustToxLoss(-5, 0) A.adjustBruteLoss(-5, 0) + + // Please don't forget to update health, otherwise the below if statements will probably always fail. A.updatehealth() + if(A.health >= 0 && A.stat == DEAD) A.revive(full_heal = FALSE, admin_revive = FALSE) + cardhold.update_icon() + // Finished restoring if(A.health >= 100) ai_slot.locked = FALSE diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 577fad83d0..55dea600e3 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -1,11 +1,10 @@ /datum/computer_file/program/alarm_monitor filename = "alarmmonitor" - filedesc = "Alarm Monitor" + filedesc = "Canary" ui_header = "alarm_green.gif" 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 - network_destination = "alarm monitoring network" size = 5 tgui_id = "NtosStationAlertConsole" var/has_alert = 0 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm index 3accb8e02d..aa361d4544 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm @@ -14,7 +14,7 @@ var/assigned = FALSE 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) /datum/computer_file/program/contract_uplink/ui_act(action, params) diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm index 2ba3d69fe6..4f1c488b9e 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -10,7 +10,7 @@ tgui_id = "NtosRevelation" 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) if(armed) activate() diff --git a/code/modules/modular_computers/file_system/programs/arcade.dm b/code/modules/modular_computers/file_system/programs/arcade.dm index 2503073f9a..87a3f1ec94 100644 --- a/code/modules/modular_computers/file_system/programs/arcade.dm +++ b/code/modules/modular_computers/file_system/programs/arcade.dm @@ -1,10 +1,9 @@ /datum/computer_file/program/arcade - filename = "arcade" - filedesc = "Nanotrasen Micro Arcade" + filename = "dsarcade" + filedesc = "Donksoft Micro 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." requires_ntnet = FALSE - network_destination = "arcade network" size = 6 tgui_id = "NtosArcade" @@ -25,7 +24,7 @@ /datum/computer_file/program/arcade/proc/game_check(mob/user) 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) heads_up = "You have crushed [boss_name]! Rejoice!" playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10) @@ -34,7 +33,7 @@ if(istype(computer)) computer.update_icon() ticket_count += 1 - //user?.mind?.adjust_experience(/datum/skill/gaming, 50) + // user?.mind?.adjust_experience(/datum/skill/gaming, 50) sleep(10) else if(player_hp <= 0 || player_mp <= 0) heads_up = "You have been defeated... how will the station survive?" @@ -43,7 +42,7 @@ program_icon_state = "arcade_off" if(istype(computer)) computer.update_icon() - //user?.mind?.adjust_experience(/datum/skill/gaming, 10) + // user?.mind?.adjust_experience(/datum/skill/gaming, 10) sleep(10) /datum/computer_file/program/arcade/proc/enemy_check(mob/user) @@ -98,8 +97,8 @@ if(computer) printer = computer.all_components[MC_PRINT] - //var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming) - //var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) + // var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming) + // var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) switch(action) if("Attack") var/attackamt = 0 //Spam prevention. @@ -119,8 +118,8 @@ if(pause_state == FALSE) healamt = rand(6,8)// + rand(0, gamerSkill) var/maxPointCost = 3 - //if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN) - // maxPointCost = 2 + // if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN) + // maxPointCost = 2 healcost = rand(1, maxPointCost) pause_state = TRUE heads_up = "You heal for [healamt] damage." diff --git a/code/modules/modular_computers/file_system/programs/atmosscan.dm b/code/modules/modular_computers/file_system/programs/atmosscan.dm index 2df751bebd..ebb2770f2e 100644 --- a/code/modules/modular_computers/file_system/programs/atmosscan.dm +++ b/code/modules/modular_computers/file_system/programs/atmosscan.dm @@ -1,29 +1,41 @@ /datum/computer_file/program/atmosscan filename = "atmosscan" - filedesc = "Atmospheric Scanner" + filedesc = "AtmoZphere" program_icon_state = "air" extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." - network_destination = "atmos scan" size = 4 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, "\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".") + + /datum/computer_file/program/atmosscan/ui_data(mob/user) var/list/data = get_header_data() var/list/airlist = list() 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/list/env_gases = environment.get_gases() + var/list/env_gases = environment.gases var/pressure = environment.return_pressure() var/total_moles = environment.total_moles() data["AirPressure"] = round(pressure,0.1) - data["AirTemp"] = round(environment.return_temperature()-T0C) + data["AirTemp"] = round(environment.temperature-T0C) if (total_moles) 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) - 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 + else + data["AirPressure"] = 0 + data["AirTemp"] = 0 + data["AirData"] = list(list()) return data /datum/computer_file/program/atmosscan/ui_act(action, list/params) diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm index c2160a0e92..d1bf7dbab3 100644 --- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm @@ -1,12 +1,11 @@ /datum/computer_file/program/borg_monitor - filename = "cyborgmonitor" - filedesc = "Cyborg Remote Monitoring" + filename = "siliconnect" + filedesc = "SiliConnect" ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of station cyborgs." requires_ntnet = TRUE transfer_access = ACCESS_ROBOTICS - network_destination = "cyborg remote monitoring" size = 5 tgui_id = "NtosCyborgRemoteMonitor" @@ -81,8 +80,8 @@ return ID.registered_name /datum/computer_file/program/borg_monitor/syndicate - filename = "scyborgmonitor" - filedesc = "Mission-Specific Cyborg Remote Monitoring" + filename = "roboverlord" + filedesc = "Roboverlord" ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs." @@ -90,7 +89,6 @@ available_on_ntnet = FALSE available_on_syndinet = TRUE transfer_access = null - network_destination = "cyborg remote monitoring" tgui_id = "NtosCyborgRemoteMonitorSyndicate" /datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R) diff --git a/code/modules/modular_computers/file_system/programs/bounty_board.dm b/code/modules/modular_computers/file_system/programs/bounty_board.dm index 46fde84f65..2e7d3cc87f 100644 --- a/code/modules/modular_computers/file_system/programs/bounty_board.dm +++ b/code/modules/modular_computers/file_system/programs/bounty_board.dm @@ -4,7 +4,6 @@ program_icon_state = "bountyboard" extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.." requires_ntnet = TRUE - network_destination = "bounty board interface" size = 10 tgui_id = "NtosRequestKiosk" ///Reference to the currently logged in user. diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 842d6e2588..6d45914add 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -7,8 +7,8 @@ #define CARDCON_DEPARTMENT_COMMAND "Command" /datum/computer_file/program/card_mod - filename = "cardmod" - filedesc = "ID Card Modification" + filename = "plexagonidwriter" + filedesc = "Plexagon Access Management" program_icon_state = "id" extended_desc = "Program for programming employee ID cards to access parts of the station." transfer_access = ACCESS_HEADS @@ -98,17 +98,19 @@ return TRUE 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 if(computer) card_slot = computer.all_components[MC_CARD] + card_slot2 = computer.all_components[MC_CARD2] printer = computer.all_components[MC_PRINT] - if(!card_slot) + if(!card_slot || !card_slot2) return 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) if("PRG_authenticate") @@ -129,14 +131,14 @@ return var/contents = {"

Access Report

Prepared By: [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]
- For: [id_card.registered_name ? id_card.registered_name : "Unregistered"]
+ For: [target_id_card.registered_name ? target_id_card.registered_name : "Unregistered"]

- Assignment: [id_card.assignment]
+ Assignment: [target_id_card.assignment]
Access:
"} 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) contents += " [get_access_desc(A)]" @@ -148,43 +150,40 @@ computer.visible_message("\The [computer] prints out a paper.") return TRUE if("PRG_eject") - if(!computer || !card_slot) + if(!computer || !card_slot2) return - if(id_card) - GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) - card_slot.try_eject(TRUE, user) + if(target_id_card) + GLOB.data_core.manifest_modify(target_id_card.registered_name, target_id_card.assignment) + return card_slot2.try_eject(user) else var/obj/item/I = user.get_active_held_item() if(istype(I, /obj/item/card/id)) - if(!user.transferItemToLoc(I, computer)) - return - card_slot.stored_card = I - playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - return TRUE + return card_slot2.try_insert(I) + return FALSE if("PRG_terminate") if(!computer || !authenticated) return 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 - id_card.access -= get_all_centcom_access() + get_all_accesses() - id_card.assignment = "Unassigned" - id_card.update_label() + target_id_card.access -= get_all_centcom_access() + get_all_accesses() + target_id_card.assignment = "Unassigned" + target_id_card.update_label() playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return TRUE if("PRG_edit") - if(!computer || !authenticated || !id_card) + if(!computer || !authenticated || !target_id_card) return var/new_name = params["name"] if(!new_name) return - id_card.registered_name = new_name - id_card.update_label() + target_id_card.registered_name = new_name + target_id_card.update_label() playsound(computer, "terminal_type", 50, FALSE) return TRUE if("PRG_assign") - if(!computer || !authenticated || !id_card) + if(!computer || !authenticated || !target_id_card) return var/target = params["assign_target"] if(!target) @@ -193,8 +192,8 @@ if(target == "Custom") var/custom_name = params["custom_name"] if(custom_name) - id_card.assignment = custom_name - id_card.update_label() + target_id_card.assignment = custom_name + target_id_card.update_label() else if(minor && !(target in head_subordinates)) return @@ -212,10 +211,10 @@ to_chat(user, "No class exists for this job: [target]") return new_access = job.get_access() - id_card.access -= get_all_centcom_access() + get_all_accesses() - id_card.access |= new_access - id_card.assignment = target - id_card.update_label() + target_id_card.access -= get_all_centcom_access() + get_all_accesses() + target_id_card.access |= new_access + target_id_card.assignment = target + target_id_card.update_label() playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) return TRUE if("PRG_access") @@ -223,22 +222,22 @@ return var/access_type = text2num(params["access_target"]) if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses())) - if(access_type in id_card.access) - id_card.access -= access_type + if(access_type in target_id_card.access) + target_id_card.access -= access_type else - id_card.access |= access_type + target_id_card.access |= access_type playsound(computer, "terminal_type", 50, FALSE) return TRUE if("PRG_grantall") if(!computer || !authenticated || minor) 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) return TRUE if("PRG_denyall") if(!computer || !authenticated || minor) return - id_card.access.Cut() + target_id_card.access.Cut() playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return TRUE if("PRG_grantregion") @@ -247,7 +246,7 @@ var/region = text2num(params["region"]) if(isnull(region)) 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) return TRUE if("PRG_denyregion") @@ -256,7 +255,7 @@ var/region = text2num(params["region"]) if(isnull(region)) 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) return TRUE @@ -321,17 +320,17 @@ /datum/computer_file/program/card_mod/ui_data(mob/user) 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 if(computer) - card_slot = computer.all_components[MC_CARD] + card_slot2 = computer.all_components[MC_CARD2] printer = computer.all_components[MC_PRINT] data["station_name"] = station_name() if(computer) - data["have_id_slot"] = !!card_slot + data["have_id_slot"] = !!(card_slot2) data["have_printer"] = !!printer else data["have_id_slot"] = FALSE @@ -340,7 +339,7 @@ data["authenticated"] = authenticated 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["id_name"] = id_card ? id_card.name : "-----" if(id_card) diff --git a/code/modules/modular_computers/file_system/programs/cargobounty.dm b/code/modules/modular_computers/file_system/programs/cargobounty.dm index d9bc65c98d..74ac44ade3 100644 --- a/code/modules/modular_computers/file_system/programs/cargobounty.dm +++ b/code/modules/modular_computers/file_system/programs/cargobounty.dm @@ -5,7 +5,6 @@ extended_desc = "A basic interface for supply personnel to check and claim bounties." requires_ntnet = TRUE transfer_access = ACCESS_CARGO - network_destination = "cargo claims interface" size = 10 tgui_id = "NtosBountyConsole" ///cooldown var for printing paper sheets. diff --git a/code/modules/modular_computers/file_system/programs/cargoship.dm b/code/modules/modular_computers/file_system/programs/cargoship.dm index 3ba08a3719..db8d6d9f82 100644 --- a/code/modules/modular_computers/file_system/programs/cargoship.dm +++ b/code/modules/modular_computers/file_system/programs/cargoship.dm @@ -1,9 +1,8 @@ /datum/computer_file/program/shipping filename = "shipping" - filedesc = "Nanotrasen Shipping Scanner" + filedesc = "GrandArk Exporter" program_icon_state = "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 tgui_id = "NtosShipping" ///Account used for creating barcodes. diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index a1503ce3a8..4f2688d8f1 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -1,10 +1,10 @@ /datum/computer_file/program/crew_manifest - filename = "crewmani" - filedesc = "Crew Manifest" + filename = "plexagoncrew" + filedesc = "Plexagon Crew List" program_icon_state = "id" extended_desc = "Program for viewing and printing the current crew manifest" transfer_access = ACCESS_HEADS - requires_ntnet = FALSE + requires_ntnet = TRUE size = 4 tgui_id = "NtosCrewManifest" diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm index bccc6e4dbe..b88b793b66 100644 --- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm +++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm @@ -1,10 +1,10 @@ /datum/computer_file/program/job_management - filename = "job_manage" - filedesc = "Job Manager" + filename = "plexagoncore" + filedesc = "Plexagon HR Core" program_icon_state = "id" extended_desc = "Program for viewing and changing job slot avalibility." transfer_access = ACCESS_HEADS - requires_ntnet = 0 + requires_ntnet = TRUE size = 4 tgui_id = "NtosJobManager" diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index 6401d6207f..8fbcfd0b01 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -1,14 +1,14 @@ /datum/computer_file/program/ntnetdownload - filename = "ntndownloader" - filedesc = "Software Download Tool" + filename = "ntsoftwarehub" + filedesc = "NT Software Hub" program_icon_state = "generic" extended_desc = "This program allows downloads of software from official NT repositories" - unsendable = 1 - undeletable = 1 + unsendable = TRUE + undeletable = TRUE size = 4 - requires_ntnet = 1 + requires_ntnet = TRUE requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD - available_on_ntnet = 0 + available_on_ntnet = FALSE ui_header = "downloader_finished.gif" tgui_id = "NtosNetDownloader" @@ -125,6 +125,8 @@ if(!istype(my_computer)) 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() @@ -146,7 +148,7 @@ for(var/A in main_repo) var/datum/computer_file/program/P = A // 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 all_entries.Add(list(list( "filename" = P.filename, diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index 7d6d89f32c..bbbde14780 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -1,6 +1,6 @@ /datum/computer_file/program/ntnetmonitor - filename = "ntmonitor" - filedesc = "NTNet Diagnostics and Monitoring" + filename = "wirecarp" + filedesc = "WireCarp" //wireshark. program_icon_state = "comm_monitor" extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" size = 12 diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index df9b02d8ec..f03ff3f8fd 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -6,7 +6,6 @@ size = 8 requires_ntnet = 1 requires_ntnet_feature = NTNET_COMMUNICATION - network_destination = "NTNRC server" ui_header = "ntnrc_idle.gif" available_on_ntnet = 1 tgui_id = "NtosNetChat" diff --git a/code/modules/modular_computers/file_system/programs/powermonitor.dm b/code/modules/modular_computers/file_system/programs/powermonitor.dm index bd11474858..e87a731a40 100644 --- a/code/modules/modular_computers/file_system/programs/powermonitor.dm +++ b/code/modules/modular_computers/file_system/programs/powermonitor.dm @@ -1,15 +1,14 @@ //normal computer version is located in code\modules\power\monitor.dm, /obj/machinery/computer/monitor /datum/computer_file/program/power_monitor - filename = "powermonitor" - filedesc = "Power Monitor" + filename = "ampcheck" + filedesc = "AmpCheck" program_icon_state = "power_monitor" extended_desc = "This program connects to sensors around the station to provide information about electrical systems" ui_header = "power_norm.gif" transfer_access = ACCESS_ENGINE usage_flags = PROGRAM_CONSOLE requires_ntnet = 0 - network_destination = "power monitoring system" size = 9 tgui_id = "NtosPowerMonitor" diff --git a/code/modules/modular_computers/file_system/programs/radar.dm b/code/modules/modular_computers/file_system/programs/radar.dm index 9b0e09ef99..216365d6ea 100644 --- a/code/modules/modular_computers/file_system/programs/radar.dm +++ b/code/modules/modular_computers/file_system/programs/radar.dm @@ -7,7 +7,6 @@ transfer_access = null available_on_ntnet = FALSE usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET - network_destination = "tracking program" size = 5 tgui_id = "NtosRadar" ///List of trackable entities. Updated by the scan() proc. @@ -207,7 +206,7 @@ ///A program that tracks crew members via suit sensors /datum/computer_file/program/radar/lifeline - filename = "Lifeline" + filename = "lifeline" filedesc = "Lifeline" extended_desc = "This program allows for tracking of crew members via their suit sensors." requires_ntnet = TRUE @@ -252,9 +251,9 @@ //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 - filename = "Fission360" + filename = "fission360" filedesc = "Fission360" program_icon_state = "radarsyndicate" extended_desc = "This program allows for tracking of nuclear authorization disks and warheads." @@ -276,8 +275,6 @@ objects = list() for(var/i in GLOB.nuke_list) var/obj/machinery/nuclearbomb/nuke = i - if(!trackable(nuke)) - continue var/list/nukeinfo = list( ref = REF(nuke), @@ -285,9 +282,8 @@ ) objects += list(nukeinfo) var/obj/item/disk/nuclear/disk = locate() in GLOB.poi_list - if(trackable(disk)) - var/list/nukeinfo = list( - ref = REF(disk), - name = disk.name, - ) - objects += list(nukeinfo) + var/list/nukeinfo = list( + ref = REF(disk), + name = "Nuke Auth. Disk", + ) + objects += list(nukeinfo) diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm index 8644ce09b4..c0b82b9c95 100644 --- a/code/modules/modular_computers/file_system/programs/robocontrol.dm +++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm @@ -1,12 +1,11 @@ /datum/computer_file/program/robocontrol - filename = "robocontrol" - filedesc = "Bot Remote Controller" + filename = "botkeeper" + filedesc = "Botkeeper" program_icon_state = "robot" extended_desc = "A remote controller used for giving basic commands to non-sentient robots." transfer_access = ACCESS_ROBOTICS requires_ntnet = TRUE - network_destination = "robotics control network" size = 12 tgui_id = "NtosRoboControl" ///Number of simple robots on-station. @@ -78,7 +77,7 @@ return if(id_card) 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 playsound(get_turf(ui_host()) , 'sound/machines/buzz-sigh.ogg', 25, FALSE) return diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 32ad102871..564f952b54 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -1,12 +1,11 @@ /datum/computer_file/program/supermatter_monitor - filename = "smmonitor" - filedesc = "Supermatter Monitoring" + filename = "ntcims" + filedesc = "NT CIMS" ui_header = "smmon_0.gif" 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 transfer_access = ACCESS_CONSTRUCTION - network_destination = "supermatter monitoring system" size = 5 tgui_id = "NtosSupermatterMonitor" var/last_status = SUPERMATTER_INACTIVE @@ -70,7 +69,7 @@ data["active"] = TRUE data["SM_integrity"] = active.get_integrity() data["SM_power"] = active.power - data["SM_ambienttemp"] = air.return_temperature() + data["SM_ambienttemp"] = air.temperature data["SM_ambientpressure"] = air.return_pressure() //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) var/list/gasdata = list() diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm index b33442f99b..81555340b2 100644 --- a/code/modules/modular_computers/hardware/_hardware.dm +++ b/code/modules/modular_computers/hardware/_hardware.dm @@ -10,9 +10,11 @@ // Computer that holds this hardware, if any. 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/critical = 0 // Prevent disabling for important component, like the CPU. - var/can_install = 1 // Prevents direct installation of removable media. + var/enabled = TRUE // If the hardware is turned off set this to 0. + var/critical = FALSE // Prevent disabling for important component, like the CPU. + 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/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 @@ -20,7 +22,7 @@ var/malfunction_probability = 10// Chance of malfunction when the component is damaged var/device_type -/obj/item/computer_hardware/New(var/obj/L) +/obj/item/computer_hardware/New(obj/L) ..() pixel_x = rand(-8, 8) pixel_y = rand(-8, 8) @@ -56,7 +58,7 @@ return TRUE // 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"]") // Handles damage checks @@ -73,7 +75,7 @@ return TRUE // Good to go. -/obj/item/computer_hardware/examine(var/mob/user) +/obj/item/computer_hardware/examine(mob/user) . = ..() if(damage > damage_failure) . += "It seems to be severely damaged!" diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index 0ad157afcb..c874d786a0 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -5,6 +5,7 @@ icon_state = "card_mini" w_class = WEIGHT_CLASS_SMALL device_type = MC_AI + expansion_hw = TRUE var/obj/item/aicard/stored_card = null var/locked = FALSE @@ -19,12 +20,6 @@ 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." -/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) if(!holder) return FALSE @@ -44,7 +39,7 @@ 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) to_chat(user, "There is no card in \the [src].") return FALSE diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 6e3193abfd..0668248315 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -21,7 +21,7 @@ /obj/item/computer_hardware/battery/handle_atom_del(atom/A) 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) @@ -48,7 +48,7 @@ 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) to_chat(user, "There is no power cell connected to \the [src].") return FALSE diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 18b423a42e..c243bf7db1 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -7,13 +7,10 @@ device_type = MC_CARD 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) if(A == stored_card) - try_eject(1, null, TRUE) - if(A == stored_card2) - try_eject(2, null, TRUE) + try_eject(null, TRUE) . = ..() /obj/item/computer_hardware/card_slot/Destroy() @@ -21,37 +18,25 @@ return ..() /obj/item/computer_hardware/card_slot/GetAccess() - if(stored_card && stored_card2) // Best of both worlds - return (stored_card.GetAccess() | stored_card2.GetAccess()) - else if(stored_card) - return stored_card.GetAccess() - else if(stored_card2) - return stored_card2.GetAccess() - return ..() + var/list/total_access + if(stored_card) + total_access = stored_card.GetAccess() + var/obj/item/computer_hardware/card_slot/card_slot2 = holder?.all_components[MC_CARD2] //Best of both worlds + if(card_slot2?.stored_card) + total_access |= card_slot2.stored_card.GetAccess() + return total_access /obj/item/computer_hardware/card_slot/GetID() if(stored_card) return stored_card - else if(stored_card2) - return stored_card2 return ..() /obj/item/computer_hardware/card_slot/RemoveID() if(stored_card) . = stored_card - if(!try_eject(1)) + if(!try_eject()) return null 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) if(!holder) @@ -60,8 +45,7 @@ if(!istype(I, /obj/item/card/id)) return FALSE - if(stored_card && stored_card2) - to_chat(user, "You try to insert \the [I] into \the [src], but its slots are occupied.") + if(stored_card) return FALSE if(user) if(!user.transferItemToLoc(I, src)) @@ -69,11 +53,8 @@ else I.forceMove(src) - if(!stored_card) - stored_card = I - else - stored_card2 = I - to_chat(user, "You insert \the [I] into \the [src].") + stored_card = I + to_chat(user, "You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].") playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) if(ishuman(user)) var/mob/living/carbon/human/H = user @@ -82,53 +63,58 @@ return TRUE -/obj/item/computer_hardware/card_slot/try_eject(slot=0, mob/living/user = null, forced = 0) - if(!stored_card && !stored_card2) +/obj/item/computer_hardware/card_slot/try_eject(mob/living/user = null, forced = FALSE) + if(!stored_card) to_chat(user, "There are no cards in \the [src].") return FALSE - var/ejected = 0 - if(stored_card && (!slot || slot == 1)) - if(user) - user.put_in_hands(stored_card) - else - stored_card.forceMove(drop_location()) - stored_card = null - ejected++ + if(user) + user.put_in_hands(stored_card) + else + stored_card.forceMove(drop_location()) + stored_card = null - if(stored_card2 && (!slot || slot == 2)) - if(user) - user.put_in_hands(stored_card2) - else - stored_card2.forceMove(drop_location()) - stored_card2 = null - ejected++ + if(holder) + if(holder.active_program) + holder.active_program.event_idremoved(0) - if(ejected) - if(holder) - if(holder.active_program) - holder.active_program.event_idremoved(0, slot) - - for(var/I in holder.idle_threads) - var/datum/computer_file/program/P = I - P.event_idremoved(1, slot) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.sec_hud_set_ID() - to_chat(user, "You remove the card[ejected>1 ? "s" : ""] from \the [src].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - return TRUE - return FALSE + for(var/p in holder.idle_threads) + var/datum/computer_file/program/computer_program = p + computer_program.event_idremoved(1) + if(ishuman(user)) + var/mob/living/carbon/human/human_user = user + human_user.sec_hud_set_ID() + to_chat(user, "You remove the card from \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE /obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user) if(..()) return if(I.tool_behaviour == TOOL_SCREWDRIVER) - to_chat(user, "You press down on the manual eject button with \the [I].") - try_eject(0,user) - return + if(stored_card) + to_chat(user, "You press down on the manual eject button with \the [I].") + try_eject(user) + return + swap_slot() + to_chat(user, "You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].") + +/** + *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) . = ..() - 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." + +/obj/item/computer_hardware/card_slot/secondary + device_type = MC_CARD2 + expansion_hw = TRUE diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index b8b9624388..e5c133de20 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -22,14 +22,14 @@ . = ..() . += "It has [max_capacity] GQ of storage capacity." -/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. to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999") 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. -/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)) return 0 @@ -52,7 +52,7 @@ return 1 // 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)) return 0 @@ -78,7 +78,7 @@ 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. -/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)) return 0 @@ -101,7 +101,7 @@ // 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()) return null diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index fe1b1879cb..04bf494fe4 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -11,7 +11,7 @@ device_type = MC_NET 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 User Tag: [identification_string]") @@ -22,7 +22,7 @@ if(ethernet) 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++ @@ -31,7 +31,7 @@ return "[identification_string] (NID [identification_id])" // 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? return 0 diff --git a/code/modules/modular_computers/hardware/portable_disk.dm b/code/modules/modular_computers/hardware/portable_disk.dm index b5a957be04..89b0382e86 100644 --- a/code/modules/modular_computers/hardware/portable_disk.dm +++ b/code/modules/modular_computers/hardware/portable_disk.dm @@ -8,12 +8,8 @@ max_capacity = 16 device_type = MC_SDD -/obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/modular_computer/M, mob/living/user = null) - M.add_verb(device_type) - -/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/on_remove(obj/item/modular_computer/MC, mob/user) + 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/install_default_programs() return // Empty by default diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm index ebe40c1922..3bd5946435 100644 --- a/code/modules/modular_computers/hardware/printer.dm +++ b/code/modules/modular_computers/hardware/printer.dm @@ -5,6 +5,7 @@ icon_state = "printer" w_class = WEIGHT_CLASS_NORMAL device_type = MC_PRINT + expansion_hw = TRUE var/stored_paper = 20 var/max_paper = 30 diff --git a/code/modules/modular_computers/hardware/sensor_package.dm b/code/modules/modular_computers/hardware/sensor_package.dm new file mode 100644 index 0000000000..c0363bc809 --- /dev/null +++ b/code/modules/modular_computers/hardware/sensor_package.dm @@ -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 diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index a8d30bad21..a3b34c4b9b 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -52,6 +52,7 @@ var/obj/item/computer_hardware/battery/battery_module = null if(fabricate) 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) battery_module = fabricated_laptop.all_components[MC_CELL] total_price = 99 @@ -107,7 +108,7 @@ if(dev_card) total_price += 199 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 else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. @@ -116,6 +117,7 @@ fabricated_tablet = new(src) 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/card_slot) battery_module = fabricated_tablet.all_components[MC_CELL] total_price = 199 switch(dev_battery) @@ -154,11 +156,11 @@ if(dev_printer) total_price += 99 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) total_price += 199 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 FALSE @@ -222,7 +224,7 @@ return FALSE /obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui) - if(stat & (BROKEN | NOPOWER | MAINT)) + if(machine_stat & (BROKEN | NOPOWER | MAINT)) if(ui) ui.close() return FALSE @@ -257,7 +259,7 @@ say("Insufficient credits on card to purchase!") return 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 ..() diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm new file mode 100644 index 0000000000..dc8f172069 --- /dev/null +++ b/code/modules/paperwork/carbonpaper.dm @@ -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, "" + Copy.name = "Copy - [C.name]" + to_chat(user, "You tear off the carbon-copy!") + C.copied = TRUE + Copy.iscopy = TRUE + Copy.update_icon_state() + C.update_icon_state() + user.put_in_hands(Copy) + else + to_chat(user, "There are no more carbon copies attached to this paper!") + +/obj/item/paper/carbon/on_attack_hand(mob/living/user) + if(loc == user && user.is_holding(src)) + removecopy(user) + return + return ..() diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 1a93661c76..5b576a2438 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -3,6 +3,8 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "clipboard" item_state = "clipboard" + // inhand_icon_state = "clipboard" + // worn_icon_state = "clipboard" throwforce = 0 w_class = WEIGHT_CLASS_SMALL throw_speed = 3 @@ -34,7 +36,6 @@ . += "clipboard_pen" . += "clipboard_over" - /obj/item/clipboard/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/paper)) if(!user.transferItemToLoc(W, src)) @@ -92,14 +93,14 @@ to_chat(usr, "You slot [W] into [src].") if(href_list["write"]) - var/obj/item/P = locate(href_list["write"]) - if(istype(P) && P.loc == src) + var/obj/item/P = locate(href_list["write"]) in src + if(istype(P)) if(usr.get_active_held_item()) P.attackby(usr.get_active_held_item(), usr) if(href_list["remove"]) - var/obj/item/P = locate(href_list["remove"]) - if(istype(P) && P.loc == src) + var/obj/item/P = locate(href_list["remove"]) in src + if(istype(P)) P.forceMove(usr.loc) usr.put_in_hands(P) if(P == toppaper) @@ -111,13 +112,13 @@ toppaper = null if(href_list["read"]) - var/obj/item/paper/P = locate(href_list["read"]) - if(istype(P) && P.loc == src) + var/obj/item/paper/P = locate(href_list["read"]) in src + if(istype(P)) usr.examinate(P) if(href_list["top"]) - var/obj/item/P = locate(href_list["top"]) - if(istype(P) && P.loc == src) + var/obj/item/P = locate(href_list["top"]) in src + if(istype(P)) toppaper = P to_chat(usr, "You move [P.name] to the top.") diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index b8f2c95762..390cd0cf83 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -35,7 +35,7 @@ . = ..() if(mapload) 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) /obj/structure/filingcabinet/deconstruct(disassembled = TRUE) @@ -46,7 +46,12 @@ qdel(src) /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, "You begin to [anchored ? "unwrench" : "wrench"] [src].") + if(P.use_tool(src, user, 20, volume=50)) + to_chat(user, "You successfully [anchored ? "unwrench" : "wrench"] [src].") + anchored = !anchored + else if(P.w_class < WEIGHT_CLASS_NORMAL) if(!user.transferItemToLoc(P, src)) return to_chat(user, "You put [P] in [src].") @@ -54,11 +59,6 @@ sleep(5) icon_state = initial(icon_state) updateUsrDialog() - else if(istype(P, /obj/item/wrench)) - to_chat(user, "You begin to [anchored ? "unwrench" : "wrench"] [src].") - if(P.use_tool(src, user, 20, volume=50)) - to_chat(user, "You successfully [anchored ? "unwrench" : "wrench"] [src].") - anchored = !anchored else if(user.a_intent != INTENT_HARM) to_chat(user, "You can't put [P] in [src]!") else @@ -67,9 +67,6 @@ /obj/structure/filingcabinet/ui_interact(mob/user) . = ..() - if(isobserver(user)) - return - if(contents.len <= 0) to_chat(user, "[src] is empty.") return @@ -100,16 +97,17 @@ to_chat(user, "You find nothing in [src].") /obj/structure/filingcabinet/Topic(href, href_list) + if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr))) + return if(href_list["retrieve"]) usr << browse("", "window=filingcabinet") // Close the menu - var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex] - if(istype(P) && P.loc == src && in_range(src, usr)) + var/obj/item/P = locate(href_list["retrieve"]) in src //contents[retrieveindex] + if(istype(P) && in_range(src, usr)) usr.put_in_hands(P) updateUsrDialog() icon_state = "[initial(icon_state)]-open" - sleep(5) - icon_state = initial(icon_state) + addtimer(VARSET_CALLBACK(src, icon_state, initial(icon_state)), 5) /* @@ -170,6 +168,7 @@ virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. +//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/structure/filingcabinet/medical/on_attack_hand() populate() . = ..() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index c32afab342..305099d115 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -33,7 +33,10 @@ if(contents.len) . += "folder_paper" + /obj/item/folder/attackby(obj/item/W, mob/user, params) + if(burn_paper_product_attackby_check(W, user)) + return if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/documents)) if(!user.transferItemToLoc(W, src)) return @@ -43,11 +46,14 @@ if(!user.is_literate()) to_chat(user, "You scribble illegibly on the cover of [src]!") return + var/inputvalue = stripped_input(user, "What would you like to label the folder?", "Folder Labelling", "", MAX_NAME_LEN) + if(!inputvalue) return + if(user.canUseTopic(src, BE_CLOSE)) - name = "folder - '[inputvalue]'" + name = "folder[(inputvalue ? " - '[inputvalue]'" : null)]" /obj/item/folder/Destroy() @@ -76,14 +82,14 @@ if(usr.contents.Find(src)) if(href_list["remove"]) - var/obj/item/I = locate(href_list["remove"]) - if(istype(I) && I.loc == src) + var/obj/item/I = locate(href_list["remove"]) in src + if(istype(I)) I.forceMove(usr.loc) usr.put_in_hands(I) if(href_list["read"]) - var/obj/item/I = locate(href_list["read"]) - if(istype(I) && I.loc == src) + var/obj/item/I = locate(href_list["read"]) in src + if(istype(I)) usr.examinate(I) //Update everything diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index d054e5ff12..da9fdc4ca4 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -1,9 +1,10 @@ /obj/item/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_state = "labeler0" item_state = "flight" + // inhand_icon_state = "flight" var/label = null var/labels_left = 30 var/mode = 0 @@ -55,9 +56,10 @@ to_chat(user, "You can't label creatures!") // use a collar return - user.visible_message("[user] labels [A] as [label].", \ - "You label [A] as [label].") - A.name = "[A.name] ([label])" + user.visible_message("[user] labels [A] with \"[label]\".", \ + "You label [A] with \"[label]\".") + A.AddComponent(/datum/component/label, label) + // playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE) labels_left-- @@ -90,7 +92,9 @@ name = "cyborg-hand labeler" /obj/item/hand_labeler/borg/afterattack(atom/A, mob/user, proximity) - . = ..(A, user, proximity) + . = ..() + if(!proximity) + return if(!iscyborg(user)) return @@ -114,6 +118,7 @@ desc = "A roll of paper. Use it on a hand labeler to refill it." icon_state = "labeler_refill" item_state = "electropack" + // inhand_icon_state = "electropack" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 5d842ef11a..20ec678e45 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -11,41 +11,6 @@ #define MODE_WRITING 1 #define MODE_STAMPING 2 -/** - * This is a custom ui state. All it really does is keep track of pen - * being used and if they are editing it or not. This way we can keep - * the data with the ui rather than on the paper - */ -/datum/ui_state/default/paper_state - /// What edit mode we are in and who is - /// writing on it right now - var/edit_mode = MODE_READING - /// Setup for writing to a sheet - var/pen_color = "black" - var/pen_font = "" - var/is_crayon = FALSE - /// Setup for stamping a sheet - // Why not the stamp obj? I have no idea - // what happens to states out of scope so - // don't want to put instances in this - var/stamp_icon_state = "" - var/stamp_name = "" - var/stamp_class = "" - -/datum/ui_state/default/paper_state/proc/copy_from(datum/ui_state/default/paper_state/from) - switch(from.edit_mode) - if(MODE_READING) - edit_mode = MODE_READING - if(MODE_WRITING) - edit_mode = MODE_WRITING - pen_color = from.pen_color - pen_font = from.pen_font - is_crayon = from.is_crayon - if(MODE_STAMPING) - edit_mode = MODE_STAMPING - stamp_icon_state = from.stamp_icon_state - stamp_class = from.stamp_class - stamp_name = from.stamp_name /** * Paper is now using markdown (like in github pull notes) for ALL rendering @@ -58,6 +23,9 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper" item_state = "paper" + // inhand_icon_state = "paper" + // worn_icon_state = "paper" + // custom_fire_overlay = "paper_onfire_overlay" throwforce = 0 w_class = WEIGHT_CLASS_TINY throw_range = 1 @@ -80,34 +48,19 @@ var/list/stamps /// Positioning for the stamp in tgui var/list/stamped /// Overlay info - /// This REALLY should be a componenet. Basicly used during, april fools - /// to honk at you - var/rigged = 0 - var/spam_flag = 0 - var/contact_poison // Reagent ID to transfer on contact var/contact_poison_volume = 0 - // Ok, so WHY are we caching the ui's? - // Since we are not using autoupdate we - // need some way to update the ui's of - // other people looking at it and if - // its been updated. Yes yes, lame - // but canot be helped. However by - // doing it this way, we can see - // live updates and have multipule - // people look at it - var/list/viewing_ui = list() - /// When the sheet can be "filled out" /// This is an associated list var/list/form_fields = list() var/field_counter = 1 /obj/item/paper/Destroy() - close_all_ui() stamps = null stamped = null + form_fields = null + stamped = null . = ..() /** @@ -162,7 +115,7 @@ set category = "Object" set src in usr - if(usr.incapacitated() || !usr.is_literate()) + if(!usr.can_read(src) || usr.incapacitated(TRUE, TRUE) || (isobserver(usr) && !IsAdminGhost(usr))) return if(ishuman(usr)) var/mob/living/carbon/human/H = usr @@ -180,18 +133,6 @@ user.visible_message("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...") return (BRUTELOSS) -/// ONLY USED FOR APRIL FOOLS -/obj/item/paper/proc/reset_spamflag() - spam_flag = FALSE - -/obj/item/paper/attack_self(mob/user) - if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS])) - if(!spam_flag) - spam_flag = TRUE - playsound(loc, 'sound/items/bikehorn.ogg', 50, TRUE) - addtimer(CALLBACK(src, .proc/reset_spamflag), 20) - . = ..() - /obj/item/paper/proc/clearpaper() info = "" stamps = null @@ -199,28 +140,39 @@ cut_overlays() update_icon_state() -/obj/item/paper/examine_more(mob/user) - ui_interact(user) - return list("You try to read [src]...") +/obj/item/paper/examine(mob/user) + . = ..() + if(!in_range(user, src) && !isobserver(user)) + . += "You're too far away to read it!" + return + if(user.can_read(src)) + ui_interact(user) + return + . += "You cannot read it!" + +/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) - if(!..()) - return FALSE - // Are we on fire? Hard ot read if so - if(resistance_flags & ON_FIRE) - return FALSE - // Even harder to read if your blind...braile? humm - if(user.is_blind()) - return FALSE - // checks if the user can read. - return user.can_read(src) + if(in_contents_of(/obj/machinery/door/airlock)) + return TRUE + return ..() -/** - * This creates the ui, since we are using a custom state but not much else - * just makes it easyer to make it. - */ -/obj/item/paper/proc/create_ui(mob/user, datum/ui_state/default/paper_state/state) - ui_interact(user, state = state) /obj/item/proc/burn_paper_product_attackby_check(obj/item/I, mob/living/user, bypass_clumsy) var/ignition_message = I.ignition_effect(src, user) @@ -244,49 +196,22 @@ /obj/item/paper/attackby(obj/item/P, mob/living/user, params) if(burn_paper_product_attackby_check(P, user)) - close_all_ui() + SStgui.close_uis(src) return if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) if(length(info) >= MAX_PAPER_LENGTH) // Sheet must have less than 1000 charaters to_chat(user, "This sheet of paper is full!") return - - 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) + ui_interact(user) return else if(istype(P, /obj/item/stamp)) - - var/datum/ui_state/default/paper_state/state = new - state.edit_mode = MODE_STAMPING // we are read only becausse the sheet is full - state.stamp_icon_state = P.icon_state - state.stamp_name = P.name - - var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper) - state.stamp_class = sheet.icon_class_name(P.icon_state) - to_chat(user, "You ready your stamp over the paper! ") - - create_ui(user, state) + ui_interact(user) return /// Normaly you just stamp, you don't need to read the thing else // cut paper? the sky is the limit! - var/datum/ui_state/default/paper_state/state = new - state.edit_mode = MODE_READING - create_ui(user, state) // The other ui will be created with just read mode outside of this + ui_interact(user) // The other ui will be created with just read mode outside of this return ..() @@ -301,68 +226,64 @@ get_asset_datum(/datum/asset/spritesheet/simple/paper), ) -/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) +/obj/item/paper/ui_interact(mob/user, datum/tgui/ui) // Update the UI ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "PaperSheet", name) - state = new - ui.set_state(state) - ui.set_autoupdate(FALSE) - viewing_ui[user] = ui ui.open() -/obj/item/paper/ui_close(mob/user) - /// close the editing window and change the mode - viewing_ui[user] = null - . = ..() -// Again, we have to do this as autoupdate is off -/obj/item/paper/proc/update_all_ui() - for(var/datum/tgui/ui in viewing_ui) - ui.process(force = TRUE) +/obj/item/paper/ui_static_data(mob/user) + . = list() + .["text"] = info + .["max_length"] = MAX_PAPER_LENGTH + .["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set + .["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling? + .["stamps"] = stamps + -// Again, we have to do this as autoupdate is off -/obj/item/paper/proc/close_all_ui() - for(var/datum/tgui/ui in viewing_ui) - ui.close() - viewing_ui = list() /obj/item/paper/ui_data(mob/user) var/list/data = list() - - var/datum/tgui/ui = viewing_ui[user] - var/datum/ui_state/default/paper_state/state = ui.state - - // Should all this go in static data and just do a forced update? - data["text"] = info - data["max_length"] = MAX_PAPER_LENGTH - data["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling? - data["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set - data["stamps"] = stamps - - data["edit_mode"] = state.edit_mode - data["edit_usr"] = "[ui.user]"; - - // pen info for editing - data["is_crayon"] = state.is_crayon - data["pen_font"] = state.pen_font - data["pen_color"] = state.pen_color - // stamping info for..stamping - data["stamp_class"] = state.stamp_class - + var/obj/O = user.get_active_held_item() + if(istype(O, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/PEN = O + data["pen_font"] = CRAYON_FONT + data["pen_color"] = PEN.paint_color + data["edit_mode"] = MODE_WRITING + data["is_crayon"] = TRUE + data["stamp_class"] = "FAKE" + data["stamp_icon_state"] = "FAKE" + else if(istype(O, /obj/item/pen)) + var/obj/item/pen/PEN = O + data["pen_font"] = PEN.font + data["pen_color"] = PEN.colour + data["edit_mode"] = MODE_WRITING + data["is_crayon"] = FALSE + data["stamp_class"] = "FAKE" + data["stamp_icon_state"] = "FAKE" + else if(istype(O, /obj/item/stamp)) + var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper) + data["stamp_icon_state"] = O.icon_state + data["stamp_class"] = sheet.icon_class_name(O.icon_state) + data["edit_mode"] = MODE_STAMPING + data["pen_font"] = "FAKE" + data["pen_color"] = "FAKE" + data["is_crayon"] = FALSE + else + data["edit_mode"] = MODE_READING + data["pen_font"] = "FAKE" + data["pen_color"] = "FAKE" + data["is_crayon"] = FALSE + data["stamp_icon_state"] = "FAKE" + data["stamp_class"] = "FAKE" data["field_counter"] = field_counter data["form_fields"] = form_fields 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(..()) return switch(action) @@ -370,34 +291,33 @@ var/stamp_x = text2num(params["x"]) var/stamp_y = text2num(params["y"]) var/stamp_r = text2num(params["r"]) // rotation in degrees - + var/stamp_icon_state = params["stamp_icon_state"] + var/stamp_class = params["stamp_class"] if (isnull(stamps)) - stamps = new/list() + stamps = list() if(stamps.len < MAX_PAPER_STAMPS) // 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 if (isnull(stamped)) - stamped = new/list() + stamped = list() 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_y = rand(-3, 2) add_overlay(stampoverlay) - LAZYADD(stamped, state.stamp_icon_state) + LAZYADD(stamped, stamp_icon_state) - ui.user.visible_message("[ui.user] stamps [src] with [state.stamp_name]!", "You stamp [src] with [state.stamp_name]!") + update_static_data(usr,ui) + ui.user.visible_message("[ui.user] stamps [src] with [stamp_class]!", "You stamp [src] with [stamp_class]!") else to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!")) - - update_all_ui() . = TRUE if("save") var/in_paper = params["text"] var/paper_len = length(in_paper) - var/list/fields = params["form_fields"] field_counter = params["field_counter"] ? text2num(params["field_counter"]) : field_counter if(paper_len > MAX_PAPER_LENGTH) @@ -413,14 +333,10 @@ if(info != in_paper) to_chat(ui.user, "You have added to your paper masterpiece!"); info = in_paper - - for(var/key in fields) - form_fields[key] = fields[key]; + update_static_data(usr,ui) - update_all_ui() update_icon() - . = TRUE /** diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 3937720f74..a3b9b23141 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -26,11 +26,11 @@ var/obj/item/bodypart/BP = C.get_bodypart(BODY_ZONE_HEAD) if(BP) BP.drop_limb() - playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 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) else user.visible_message("[user] repeatedly bashes [src.name] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) + playsound(loc, 'sound/items/gavel.ogg', 50, TRUE, -1) return (BRUTELOSS) @@ -42,11 +42,12 @@ if(storedpaper) . += "paper" + /obj/item/papercutter/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/paper) && !storedpaper) if(!user.transferItemToLoc(P, src)) return - playsound(loc, "pageturn", 60, 1) + playsound(loc, "pageturn", 60, TRUE) to_chat(user, "You place [P] in [src].") storedpaper = P update_icon() @@ -59,17 +60,17 @@ storedcutter = P update_icon() return - if(istype(P, /obj/item/screwdriver) && storedcutter) + if(P.tool_behaviour == TOOL_SCREWDRIVER && storedcutter) P.play_tool_sound(src) to_chat(user, "[storedcutter] has been [cuttersecured ? "unsecured" : "secured"].") cuttersecured = !cuttersecured 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) if(!storedcutter) - to_chat(user, "The cutting blade is gone! You can't use [src] now.") + to_chat(user, "The cutting blade is gone! You can't use [src] now.") return if(!cuttersecured) @@ -79,7 +80,7 @@ update_icon() if(storedpaper) - playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1) + playsound(src.loc, 'sound/weapons/slash.ogg', 50, TRUE) to_chat(user, "You neatly cut [storedpaper].") storedpaper = null qdel(storedpaper) @@ -88,6 +89,7 @@ update_icon() /obj/item/papercutter/MouseDrop(atom/over_object) + . = ..() var/mob/M = usr if(M.incapacitated() || !Adjacent(M)) return @@ -98,10 +100,6 @@ else if(istype(over_object, /obj/screen/inventory/hand)) var/obj/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) - - else - . = ..() - add_fingerprint(M) /obj/item/paperslip @@ -112,6 +110,12 @@ resistance_flags = FLAMMABLE max_integrity = 50 +/obj/item/paperslip/attackby(obj/item/I, mob/living/user, params) + if(burn_paper_product_attackby_check(I, user)) + return + return ..() + + /obj/item/paperslip/Initialize() . = ..() pixel_x = rand(-5, 5) @@ -124,5 +128,6 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "cutterblade" item_state = "knife" + // inhand_icon_state = "knife" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' diff --git a/code/modules/paperwork/paper_premade.dm b/code/modules/paperwork/paper_premade.dm index 414026924a..97b15628a8 100644 --- a/code/modules/paperwork/paper_premade.dm +++ b/code/modules/paperwork/paper_premade.dm @@ -4,53 +4,22 @@ /obj/item/paper/fluff/sop name = "paper- 'Standard Operating Procedure'" - info = {" -Alert Levels: -* Blue - Emergency - * Caused by fire - * Caused by manual interaction - * Action: Close all fire doors. These can only be opened by resetting the alarm -* Red- Ejection/Self Destruct - * Caused by module operating computer. - * Action: After the specified time the module will eject completely. -Engine Maintenance Instructions: -1. Shut off ignition systems: -2. Activate internal power -3. Activate orbital balance matrix -4. Remove volatile liquids from area -5. Wear a fire suit -6. After Decontaminate Visit medical examiner -Toxin Laboratory Procedure: -1. Wear a gas mask regardless -2. Get an oxygen tank. -3. Activate internal atmosphere -4. After Decontaminate Visit medical examiner -Disaster Procedure: -Fire: -1. Activate sector fire alarm. -2. Move to a safe area. -3. Get a fire suit -* After: - 1. Assess Damage - 2. Repair damages - 3. If needed, Evacuate -Meteor Shower: -1. Activate fire alarm -2. Move to the back of ship -* After - 1. Repair damage - 2. If needed, Evacuate -Accidental Reentry: -1. Activate fire alarms in front of ship. -2. Move volatile matter to a fire proof area! -3. Get a fire suit. -4. Stay secure until an emergency ship arrives. -5. If ship does not arrive-Evacuate to a nearby safe area! -"}; + info = "Alert Levels:
\nBlue- Emergency
\n\t1. Caused by fire
\n\t2. Caused by manual interaction
\n\tAction:
\n\t\tClose all fire doors. These can only be opened by resetting the alarm
\nRed- Ejection/Self-Destruct
\n\t1. Caused by module operating computer.
\n\tAction:
\n\t\tAfter the specified time the module will eject completely.
\n
\nEngine Maintenance Instructions:
\n\tShut off ignition systems:
\n\tActivate internal power
\n\tActivate orbital balance matrix
\n\tRemove volatile liquids from area
\n\tWear a fire suit
\n
\n\tAfter
\n\t\tDecontaminate
\n\t\tVisit medical examiner
\n
\nToxin Laboratory Procedure:
\n\tWear a gas mask regardless
\n\tGet an oxygen tank.
\n\tActivate internal atmosphere
\n
\n\tAfter
\n\t\tDecontaminate
\n\t\tVisit medical examiner
\n
\nDisaster Procedure:
\n\tFire:
\n\t\tActivate sector fire alarm.
\n\t\tMove to a safe area.
\n\t\tGet a fire suit
\n\t\tAfter:
\n\t\t\tAssess Damage
\n\t\t\tRepair damages
\n\t\t\tIf needed, Evacuate
\n\tMeteor Shower:
\n\t\tActivate fire alarm
\n\t\tMove to the back of ship
\n\t\tAfter
\n\t\t\tRepair damage
\n\t\t\tIf needed, Evacuate
\n\tAccidental Reentry:
\n\t\tActivate fire alarms in front of ship.
\n\t\tMove volatile matter to a fire proof area!
\n\t\tGet a fire suit.
\n\t\tStay secure until an emergency ship arrives.
\n
\n\t\tIf ship does not arrive-
\n\t\t\tEvacuate to a nearby safe area!" /obj/item/paper/fluff/shuttles/daniel info = "i love daniel
daniel is my best friend

you are tearing me apart elise" +/obj/item/paper/fluff/jobs/prisoner/letter + name = "letter from home" + info = {"Dearest sweetheart, +
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. +
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? +
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. +
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. +
+
Please stay safe, +
-Love, Your Dearest"} + //////////// Job guides n' fluff @@ -90,9 +59,42 @@ Accidental Reentry: name = "paper- 'Chemical Information'" info = "Known Onboard Toxins:
\n\tGrade A Semi-Liquid Plasma:
\n\t\tHighly poisonous. You cannot sustain concentrations above 15 units.
\n\t\tA gas mask fails to filter plasma after 50 units.
\n\t\tWill attempt to diffuse like a gas.
\n\t\tFiltered by scrubbers.
\n\t\tThere is a bottled version which is very different
\n\t\t\tfrom the version found in canisters!
\n
\n\t\tWARNING: Highly Flammable. Keep away from heat sources
\n\t\texcept in an enclosed fire area!
\n\t\tWARNING: It is a crime to use this without authorization.
\nKnown Onboard Anti-Toxin:
\n\tAnti-Toxin Type 01P: Works against Grade A Plasma.
\n\t\tBest if injected directly into bloodstream.
\n\t\tA full injection is in every regular Med-Kit.
\n\t\tSpecial toxin Kits hold around 7.
\n
\nKnown Onboard Chemicals (other):
\n\tRejuvenation T#001:
\n\t\tEven 1 unit injected directly into the bloodstream
\n\t\t\twill cure unconscious and sleep toxins.
\n\t\tIf administered to a dying patient it will prevent
\n\t\t\tfurther damage for about units*3 seconds.
\n\t\t\tit will not cure them or allow them to be cured.
\n\t\tIt can be administered to a non-dying patient
\n\t\t\tbut the chemicals disappear just as fast.
\n\tMorphine T#054:
\n\t\t5 units will induce precisely 1 minute of sleep.
\n\t\t\tThe effect are cumulative.
\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 swear to fulfill, to the best of my ability and judgment, this covenant: +
+ 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. +
+ I will apply, for the benefit of the sick, all measures that are required, + avoiding those twin traps of overtreatment and therapeutic nihilism. +
+ 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. +
+ 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. +
+ 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. +
+ 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. +
+ I will prevent disease whenever I can, for prevention is preferable to cure. +
+ 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. +
+ 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. +
"} + /* * Stations */ +////////// cogstation. /obj/item/paper/guides/cogstation/job_changes name = "MEMO: Job Changes" diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 28cb5ffae9..b8bbd0a30e 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper_bin1" item_state = "sheet-metal" + // inhand_icon_state = "sheet-metal" lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi' throwforce = 0 @@ -43,6 +44,7 @@ ..() /obj/item/paper_bin/MouseDrop(atom/over_object) + . = ..() var/mob/living/M = usr if(!istype(M) || M.incapacitated() || !Adjacent(M)) return @@ -54,17 +56,18 @@ var/obj/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) - else - . = ..() - add_fingerprint(M) /obj/item/paper_bin/attack_paw(mob/user) return attack_hand(user) -/obj/item/paper_bin/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - if(user.lying) - return +//ATTACK HAND IGNORING PARENT RETURN VALUE +/obj/item/paper_bin/on_attack_hand(mob/user) + if(isliving(user)) + var/mob/living/L = user + if(!(L.mobility_flags & MOBILITY_PICKUP)) + return + // user.changeNext_move(CLICK_CD_MELEE) if(bin_pen) var/obj/item/pen/P = bin_pen P.add_fingerprint(user) @@ -85,8 +88,8 @@ P = new papertype(src) if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) if(prob(30)) - P.info = "*HONK HONK HONK HONK HONK HONK HONK
HOOOOOOOOOOOOOOOOOOOOOONK*\n*APRIL FOOLS*\n" - P.rigged = 1 + P.info = "HONK HONK HONK HONK HONK HONK HONK
HOOOOOOOOOOOOOOOOOOOOOONK
APRIL FOOLS
" + P.AddComponent(/datum/component/honkspam) P.add_fingerprint(user) P.forceMove(user.loc) @@ -148,8 +151,7 @@ papertype = /obj/item/paper/natural 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) qdel(src) @@ -173,3 +175,9 @@ qdel(src) else ..() + +/obj/item/paper_bin/carbon + name = "carbon paper bin" + desc = "Contains all the paper you'll ever need, in duplicate!" + icon_state = "paper_bin_carbon" + papertype = /obj/item/paper/carbon diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index c6a1ee1389..d496ae8068 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -1,9 +1,9 @@ - /obj/item/paperplane name = "paper plane" desc = "Paper, folded in the shape of a plane." icon = 'icons/obj/bureaucracy.dmi' icon_state = "paperplane" + // custom_fire_overlay = "paperplane_onfire" throw_range = 7 throw_speed = 1 throwforce = 0 @@ -11,7 +11,7 @@ resistance_flags = FLAMMABLE max_integrity = 50 - var/hit_probability = 2//% + var/hit_probability = 2 //% var/obj/item/paper/internalPaper /obj/item/paperplane/origami @@ -41,6 +41,13 @@ qdel(src) return ..() +/obj/item/paperplane/Exited(atom/movable/AM, atom/newLoc) + . = ..() + if (AM == internalPaper) + internalPaper = null + if(!QDELETED(src)) + qdel(src) + /obj/item/paperplane/Destroy() QDEL_NULL(internalPaper) return ..() @@ -71,35 +78,23 @@ user.put_in_hands(internal_paper_tmp) /obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params) - ..() + if(burn_paper_product_attackby_check(P, user)) + return if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) - to_chat(user, "You should unfold [src] before changing it.") + to_chat(user, "You should unfold [src] before changing it!") return else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane internalPaper.attackby(P, user) //spoofed attack to update internal paper. update_icon() + add_fingerprint(user) + return - else if(P.get_temperature()) - if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10)) - user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ - "You miss [src] and accidentally light yourself on fire!") - user.dropItemToGround(P) - user.adjust_fire_stacks(1) - user.IgniteMob() - return - - if(!(in_range(user, src))) //to prevent issues as a result of telepathically lighting a paper - return - user.dropItemToGround(src) - user.visible_message("[user] lights [src] ablaze with [P]!", "You light [src] on fire!") - fire_act() - - add_fingerprint(user) + return ..() -/obj/item/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback) - . = ..(target, range, speed, thrower, FALSE, diagonals_first, 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, quickstart = quickstart) /obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(iscarbon(hit_atom)) @@ -112,26 +107,28 @@ if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman return var/mob/living/carbon/human/H = hit_atom + var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) if(prob(hit_probability)) if(H.is_eyes_covered()) return - var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) - visible_message("\The [src] hits [H] in the eye!") + visible_message("\The [src] hits [H] in the eye[eyes ? "" : " socket"]!") H.adjust_blurriness(6) - if(eyes) - eyes.applyOrganDamage(rand(6,8)) + eyes?.applyOrganDamage(rand(6,8)) H.DefaultCombatKnockdown(40) H.emote("scream") - /obj/item/paper/examine(mob/user) . = ..() . += "Alt-click [src] to fold it into a paper plane." /obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I) - . = ..() - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK)) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) return + if(istype(src, /obj/item/paper/carbon)) + var/obj/item/paper/carbon/Carbon = src + if(!Carbon.iscopy && !Carbon.copied) + to_chat(user, "Take off the carbon copy first.") + return to_chat(user, "You fold [src] into the shape of a plane!") user.temporarilyRemoveItemFromInventory(src) var/obj/item/paperplane/plane_type = /obj/item/paperplane @@ -142,4 +139,3 @@ I = new plane_type(user, src) user.put_in_hands(I) - return TRUE diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 91b8a6719b..13890ae69e 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -16,6 +16,8 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "pen" item_state = "pen" + // inhand_icon_state = "pen" + // worn_icon_state = "pen" slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS throwforce = 0 w_class = WEIGHT_CLASS_TINY @@ -76,6 +78,22 @@ icon_state = "pen-fountain" font = FOUNTAIN_PEN_FONT +/obj/item/pen/charcoal + name = "charcoal stylus" + desc = "It's just a wooden stick with some compressed ash on the end. At least it can write." + icon_state = "pen-charcoal" + colour = "dimgray" + font = CHARCOAL_FONT + custom_materials = null + grind_results = list(/datum/reagent/ash = 5, /datum/reagent/cellulose = 10) + +/datum/crafting_recipe/charcoal_stylus + name = "Charcoal Stylus" + result = /obj/item/pen/charcoal + reqs = list(/obj/item/stack/sheet/mineral/wood = 1, /datum/reagent/ash = 30) + time = 30 + category = CAT_PRIMAL + /obj/item/pen/fountain/captain name = "captain's fountain pen" desc = "It's an expensive Oak fountain pen. The nib is quite sharp." @@ -93,6 +111,7 @@ "Black and Silver" = "pen-fountain-b", "Command Blue" = "pen-fountain-cb" ) + embedding = list("embed_chance" = 75) /obj/item/pen/fountain/captain/Initialize() . = ..() @@ -139,20 +158,18 @@ if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return if(oldname == input) - to_chat(user, "You changed \the [O.name] to... well... \the [O.name].") + to_chat(user, "You changed \the [O.name] to... well... \the [O.name].") else O.name = input - to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].") + to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].") O.renamedByPlayer = TRUE - log_game("[user] [key_name(user)] has renamed [O] to [input]") if(penchoice == "Change description") - var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 2048) + var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 100) if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return O.desc = input - to_chat(user, "You have successfully changed \the [O.name]'s description.") - log_game("[user] [key_name(user)] has changed [O]'s description to to [input]") + to_chat(user, "You have successfully changed \the [O.name]'s description.") /* * Sleepypens @@ -181,9 +198,10 @@ */ /obj/item/pen/edagger attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off + // attack_verb_continuous = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") //these won't show up if the pen is off + // attack_verb_simple = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED var/on = FALSE - embedding = list(embed_chance = EMBED_CHANCE) /obj/item/pen/edagger/ComponentInitialize() . = ..() @@ -193,29 +211,38 @@ /obj/item/pen/edagger/get_sharpness() return on * sharpness +/obj/item/pen/edagger/suicide_act(mob/user) + . = BRUTELOSS + if(on) + user.visible_message("[user] forcefully rams the pen into their mouth!") + else + user.visible_message("[user] is holding a pen up to their mouth! It looks like [user.p_theyre()] trying to commit suicide!") + attack_self(user) + /obj/item/pen/edagger/attack_self(mob/living/user) if(on) on = FALSE force = initial(force) + throw_speed = initial(throw_speed) w_class = initial(w_class) name = initial(name) hitsound = initial(hitsound) - embedding = null + embedding = list(embed_chance = EMBED_CHANCE) throwforce = initial(throwforce) - playsound(user, 'sound/weapons/saberoff.ogg', 5, 1) + playsound(user, 'sound/weapons/saberoff.ogg', 5, TRUE) to_chat(user, "[src] can now be concealed.") - updateEmbedding() else on = TRUE force = 18 + throw_speed = 4 w_class = WEIGHT_CLASS_NORMAL name = "energy dagger" hitsound = 'sound/weapons/blade1.ogg' - embedding = list(embed_chance = 100, fall_chance = 0) //rule of cool + embedding = list(embed_chance = 100) //rule of cool throwforce = 35 - playsound(user, 'sound/weapons/saberon.ogg', 5, 1) + playsound(user, 'sound/weapons/saberon.ogg', 5, TRUE) to_chat(user, "[src] is now active.") - updateEmbedding() + updateEmbedding() update_icon() /obj/item/pen/edagger/update_icon_state() @@ -235,6 +262,8 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "digging_pen" item_state = "pen" + // inhand_icon_state = "pen" + // worn_icon_state = "pen" force = 3 w_class = WEIGHT_CLASS_TINY custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10) diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 241dde13a8..104f70bfdf 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "stamp-ok" item_state = "stamp" + // inhand_icon_state = "stamp" throwforce = 0 w_class = WEIGHT_CLASS_TINY throw_speed = 3 @@ -11,6 +12,8 @@ custom_materials = list(/datum/material/iron=60) pressure_resistance = 2 attack_verb = list("stamped") + // attack_verb_continuous = list("stamps") + // attack_verb_simple = list("stamp") /obj/item/stamp/suicide_act(mob/user) user.visible_message("[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.") @@ -66,5 +69,25 @@ icon_state = "stamp-clown" dye_color = DYE_CLOWN +/obj/item/stamp/mime + name = "mime's rubber stamp" + icon_state = "stamp-mime" + dye_color = DYE_MIME + +/obj/item/stamp/chap + name = "chaplain's rubber stamp" + icon_state = "stamp-chap" + dye_color = DYE_CHAP + +/obj/item/stamp/centcom + name = "CentCom rubber stamp" + icon_state = "stamp-centcom" + dye_color = DYE_CENTCOM + +/obj/item/stamp/syndicate + name = "Syndicate rubber stamp" + icon_state = "stamp-syndicate" + dye_color = DYE_SYNDICATE + /obj/item/stamp/attack_paw(mob/user) return attack_hand(user) diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm new file mode 100644 index 0000000000..e46ed64971 --- /dev/null +++ b/code/modules/paperwork/ticketmachine.dm @@ -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, "You store linkage information in [I]'s buffer.") + 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, "You overload [src]'s bureaucratic logic circuitry to its MAXIMUM setting.") + 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("\the [ticket] disperses!") + 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("\the [tickets[current_number]] disperses!") + 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("\the [tickets[current_number]] vibrates!") + 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, "You've linked [src] to [controller.linked].") + +/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, "[src] refuses [I]! There [max_number-ticket_number==1 ? "is" : "are"] still [max_number-ticket_number] ticket\s left!") + return + to_chat(user, "You start to refill [src]'s ticket holder (doing this will reset its ticket count!).") + if(do_after(user, 30, target = src)) + to_chat(user, "You insert [I] into [src] as it whirs nondescriptly.") + qdel(I) + ticket_number = 0 + current_number = 0 + if(tickets.len) + for(var/obj/item/ticket_machine_ticket/ticket in tickets) + ticket.audible_message("\the [ticket] disperses!") + 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,"You press the button, but nothing happens...") + return + if(ticket_number >= max_number) + to_chat(user,"Ticket supply depleted, please refill this unit with a hand labeller refill cartridge!") + return + if((user in ticket_holders) && !(obj_flags & EMAGGED)) + to_chat(user, "You already have a ticket!") + return + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 100, FALSE) + ticket_number ++ + to_chat(user, "You take a ticket from [src], looks like you're ticket number #[ticket_number]...") + var/obj/item/ticket_machine_ticket/theirticket = new /obj/item/ticket_machine_ticket(get_turf(src)) + theirticket.name = "Ticket #[ticket_number]" + theirticket.maptext = "[ticket_number]" + theirticket.saved_maptext = "[ticket_number]" + theirticket.ticket_number = ticket_number + theirticket.source = src + theirticket.owner = user + user.put_in_hands(theirticket) + ticket_holders += user + tickets += theirticket + if(obj_flags & EMAGGED) //Emag the machine to destroy the HOP's life. + ready = FALSE + addtimer(CALLBACK(src, .proc/reset_cooldown), cooldown)//Small cooldown to prevent piles of flaming tickets + theirticket.fire_act() + user.dropItemToGround(theirticket) + user.adjust_fire_stacks(1) + user.IgniteMob() + return + +/obj/item/ticket_machine_ticket + name = "Ticket" + desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper®. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing." + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "ticket" + maptext_x = 7 + maptext_y = 10 + w_class = WEIGHT_CLASS_TINY + resistance_flags = FLAMMABLE + max_integrity = 50 + var/saved_maptext = null + var/mob/living/carbon/owner + var/obj/machinery/ticket_machine/source + var/ticket_number + +/obj/item/ticket_machine_ticket/attack_hand(mob/user) + . = ..() + maptext = saved_maptext //For some reason, storage code removes all maptext off objs, this stops its number from being wiped off when taken out of storage. + +/obj/item/ticket_machine_ticket/attackby(obj/item/P, mob/living/carbon/human/user, params) //Stolen from papercode + if(burn_paper_product_attackby_check(P, user)) + return + + return ..() + +/obj/item/paper/extinguish() + ..() + update_icon() + +/obj/item/ticket_machine_ticket/Destroy() + if(owner && source) + source.ticket_holders -= owner + source.tickets[ticket_number] = null + owner = null + source = null + return ..() diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 95ae326f1e..b778a9d1a2 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/stamp_icons/font.png b/icons/stamp_icons/font.png new file mode 100644 index 0000000000..4297937696 Binary files /dev/null and b/icons/stamp_icons/font.png differ diff --git a/icons/stamp_icons/large_stamp-cap.png b/icons/stamp_icons/large_stamp-cap.png index 7f7ce460a4..19883563b2 100644 Binary files a/icons/stamp_icons/large_stamp-cap.png and b/icons/stamp_icons/large_stamp-cap.png differ diff --git a/icons/stamp_icons/large_stamp-ce.png b/icons/stamp_icons/large_stamp-ce.png index 189db310cf..d07f70c4d5 100644 Binary files a/icons/stamp_icons/large_stamp-ce.png and b/icons/stamp_icons/large_stamp-ce.png differ diff --git a/icons/stamp_icons/large_stamp-centcom.png b/icons/stamp_icons/large_stamp-centcom.png new file mode 100644 index 0000000000..6250cbff88 Binary files /dev/null and b/icons/stamp_icons/large_stamp-centcom.png differ diff --git a/icons/stamp_icons/large_stamp-chap.png b/icons/stamp_icons/large_stamp-chap.png new file mode 100644 index 0000000000..2586c13bad Binary files /dev/null and b/icons/stamp_icons/large_stamp-chap.png differ diff --git a/icons/stamp_icons/large_stamp-clown.png b/icons/stamp_icons/large_stamp-clown.png index 5abbff7113..d606870507 100644 Binary files a/icons/stamp_icons/large_stamp-clown.png and b/icons/stamp_icons/large_stamp-clown.png differ diff --git a/icons/stamp_icons/large_stamp-cmo.png b/icons/stamp_icons/large_stamp-cmo.png index eb004be621..bac4c7b2f9 100644 Binary files a/icons/stamp_icons/large_stamp-cmo.png and b/icons/stamp_icons/large_stamp-cmo.png differ diff --git a/icons/stamp_icons/large_stamp-deny.png b/icons/stamp_icons/large_stamp-deny.png index 7c216fce48..1c7f416597 100644 Binary files a/icons/stamp_icons/large_stamp-deny.png and b/icons/stamp_icons/large_stamp-deny.png differ diff --git a/icons/stamp_icons/large_stamp-hop.png b/icons/stamp_icons/large_stamp-hop.png index 3f9aa4a76f..1447d58a87 100644 Binary files a/icons/stamp_icons/large_stamp-hop.png and b/icons/stamp_icons/large_stamp-hop.png differ diff --git a/icons/stamp_icons/large_stamp-hos.png b/icons/stamp_icons/large_stamp-hos.png index 67b69d7503..bd59590975 100644 Binary files a/icons/stamp_icons/large_stamp-hos.png and b/icons/stamp_icons/large_stamp-hos.png differ diff --git a/icons/stamp_icons/large_stamp-law.png b/icons/stamp_icons/large_stamp-law.png index d6d77eee9b..aee5aa3fbc 100644 Binary files a/icons/stamp_icons/large_stamp-law.png and b/icons/stamp_icons/large_stamp-law.png differ diff --git a/icons/stamp_icons/large_stamp-mime.png b/icons/stamp_icons/large_stamp-mime.png new file mode 100644 index 0000000000..c9a0143439 Binary files /dev/null and b/icons/stamp_icons/large_stamp-mime.png differ diff --git a/icons/stamp_icons/large_stamp-ok.png b/icons/stamp_icons/large_stamp-ok.png index e568ae0921..b40d3e3f1b 100644 Binary files a/icons/stamp_icons/large_stamp-ok.png and b/icons/stamp_icons/large_stamp-ok.png differ diff --git a/icons/stamp_icons/large_stamp-qm.png b/icons/stamp_icons/large_stamp-qm.png index ea863078b4..4ba31b3741 100644 Binary files a/icons/stamp_icons/large_stamp-qm.png and b/icons/stamp_icons/large_stamp-qm.png differ diff --git a/icons/stamp_icons/large_stamp-rd.png b/icons/stamp_icons/large_stamp-rd.png index 35479e805f..a9e7ad040b 100644 Binary files a/icons/stamp_icons/large_stamp-rd.png and b/icons/stamp_icons/large_stamp-rd.png differ diff --git a/icons/stamp_icons/large_stamp-syndicate.png b/icons/stamp_icons/large_stamp-syndicate.png new file mode 100644 index 0000000000..68f17d8f5e Binary files /dev/null and b/icons/stamp_icons/large_stamp-syndicate.png differ diff --git a/tgstation.dme b/tgstation.dme index e5a59d5dde..e7eec0af7d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -432,6 +432,7 @@ #include "code\datums\components\footstep.dm" #include "code\datums\components\fried.dm" #include "code\datums\components\gps.dm" +#include "code\datums\components\honkspam.dm" #include "code\datums\components\identification.dm" #include "code\datums\components\igniter.dm" #include "code\datums\components\infective.dm" @@ -439,6 +440,7 @@ #include "code\datums\components\killerqueen.dm" #include "code\datums\components\knockback.dm" #include "code\datums\components\knockoff.dm" +#include "code\datums\components\label.dm" #include "code\datums\components\lifesteal.dm" #include "code\datums\components\lockon_aiming.dm" #include "code\datums\components\magnetic_catch.dm" @@ -2836,6 +2838,7 @@ #include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\relays.dm" #include "code\modules\NTNet\services\_service.dm" +#include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\filingcabinet.dm" @@ -2849,6 +2852,7 @@ #include "code\modules\paperwork\pen.dm" #include "code\modules\paperwork\photocopier.dm" #include "code\modules\paperwork\stamps.dm" +#include "code\modules\paperwork\ticketmachine.dm" #include "code\modules\photography\_pictures.dm" #include "code\modules\photography\camera\camera.dm" #include "code\modules\photography\camera\camera_image_capturing.dm"