mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
[MIRROR] Support for expansion-class modPC hardware, a modPC hardware item required for the atmos scanning app, and reworking ID card slots in a related fashion (#284)
* Support for expansion-class modPC hardware (#52644) * Support for expansion-class modPC hardware * end of the line * As requested Did anyone know that the tablet vendor was attaching the wrong ModPC printer? I bet no one knew that. * update * Support for expansion-class modPC hardware, a modPC hardware item required for the atmos scanning app, and reworking ID card slots in a related fashion Co-authored-by: zxaber <37497534+zxaber@users.noreply.github.com>
This commit is contained in:
@@ -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."
|
||||
. += "<span class='info'>Alt-click [src] to eject the identification card[multiple_cards ? "s":""].</span>"
|
||||
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)
|
||||
|
||||
@@ -35,11 +35,12 @@
|
||||
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.
|
||||
|
||||
// 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.
|
||||
@@ -76,9 +77,9 @@
|
||||
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]
|
||||
if(card_slot)
|
||||
card_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()
|
||||
@@ -94,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, "<span class='warning'>There isn't anywhere you can fit a card into on this computer.</span>")
|
||||
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, "<span class='warning'>This computer doesn't have an open card slot.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location)
|
||||
var/mob/M = usr
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
to_chat(user, "<span class='warning'>This component is too large for \the [src]!</span>")
|
||||
return FALSE
|
||||
|
||||
if(H.expansion_hw)
|
||||
if(LAZYLEN(expansion_bays) >= max_bays)
|
||||
to_chat(user, "<span class='warning'>All of the computer's expansion bays are filled.</span>")
|
||||
return FALSE
|
||||
if(LAZYACCESS(expansion_bays, H.device_type))
|
||||
to_chat(user, "<span class='warning'>The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\".</span>")
|
||||
return FALSE
|
||||
|
||||
if(all_components[H.device_type])
|
||||
to_chat(user, "<span class='warning'>This computer's hardware slot is already occupied by \the [all_components[H.device_type]].</span>")
|
||||
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, "<span class='notice'>You install \the [H] into \the [src].</span>")
|
||||
@@ -32,7 +42,9 @@
|
||||
/obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/H, mob/living/user = null)
|
||||
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, "<span class='notice'>You remove \the [H] from \the [src].</span>")
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
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]
|
||||
@@ -197,13 +200,19 @@
|
||||
var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI]
|
||||
if(!intelliholder)
|
||||
return
|
||||
if(intelliholder.try_eject(0,user))
|
||||
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(0, user)
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
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!
|
||||
|
||||
@@ -26,11 +26,21 @@
|
||||
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)
|
||||
|
||||
/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()
|
||||
. = ..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -80,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)
|
||||
@@ -102,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, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
|
||||
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, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
|
||||
return 0
|
||||
if(access_to_check in access)
|
||||
return TRUE
|
||||
if(loud)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -6,11 +6,20 @@
|
||||
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, "<span class='warning'>\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".</span>")
|
||||
|
||||
|
||||
/datum/computer_file/program/atmosscan/ui_data(mob/user)
|
||||
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.gases
|
||||
var/pressure = environment.return_pressure()
|
||||
@@ -23,6 +32,10 @@
|
||||
if(gas_level > 0)
|
||||
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)
|
||||
|
||||
@@ -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 = {"<h4>Access Report</h4>
|
||||
<u>Prepared By:</u> [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br>
|
||||
<u>For:</u> [id_card.registered_name ? id_card.registered_name : "Unregistered"]<br>
|
||||
<u>For:</u> [target_id_card.registered_name ? target_id_card.registered_name : "Unregistered"]<br>
|
||||
<hr>
|
||||
<u>Assignment:</u> [id_card.assignment]<br>
|
||||
<u>Assignment:</u> [target_id_card.assignment]<br>
|
||||
<u>Access:</u><br>
|
||||
"}
|
||||
|
||||
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("<span class='notice'>\The [computer] prints out a paper.</span>")
|
||||
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, "<span class='warning'>No class exists for this job: [target]</span>")
|
||||
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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -77,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -38,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, "<span class='warning'>There is no card in \the [src].</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -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, "<span class='warning'>There is no power cell connected to \the [src].</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -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,31 +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/try_insert(obj/item/I, mob/living/user = null)
|
||||
if(!holder)
|
||||
@@ -54,8 +45,7 @@
|
||||
if(!istype(I, /obj/item/card/id))
|
||||
return FALSE
|
||||
|
||||
if(stored_card && stored_card2)
|
||||
to_chat(user, "<span class='warning'>You try to insert \the [I] into \the [src], but its slots are occupied.</span>")
|
||||
if(stored_card)
|
||||
return FALSE
|
||||
if(user)
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
@@ -63,11 +53,8 @@
|
||||
else
|
||||
I.forceMove(src)
|
||||
|
||||
if(!stored_card)
|
||||
stored_card = I
|
||||
else
|
||||
stored_card2 = I
|
||||
to_chat(user, "<span class='notice'>You insert \the [I] into \the [src].</span>")
|
||||
stored_card = I
|
||||
to_chat(user, "<span class='notice'>You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -76,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, "<span class='warning'>There are no cards in \the [src].</span>")
|
||||
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, "<span class='notice'>You remove the card[ejected>1 ? "s" : ""] from \the [src].</span>")
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
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, "<span class='notice'>You remove the card from \the [src].</span>")
|
||||
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, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
|
||||
try_eject(0,user)
|
||||
return
|
||||
if(stored_card)
|
||||
to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
|
||||
try_eject(user)
|
||||
return
|
||||
swap_slot()
|
||||
to_chat(user, "<span class='notice'>You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].</span>")
|
||||
|
||||
/**
|
||||
*Swaps the card_slot hardware between using the dedicated card slot bay on a computer, and using an expansion bay.
|
||||
*/
|
||||
/obj/item/computer_hardware/card_slot/proc/swap_slot()
|
||||
expansion_hw = !expansion_hw
|
||||
if(expansion_hw)
|
||||
device_type = MC_CARD2
|
||||
else
|
||||
device_type = MC_CARD
|
||||
|
||||
/obj/item/computer_hardware/card_slot/examine(mob/user)
|
||||
. = ..()
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user