[MIRROR] Removes AI and Charge parts from tablets, adds support for more later. [MDB IGNORE] (#16381)

* Removes AI and Charge parts from tablets, adds support for more later.

* merge conflict

* remove modular tablet loadout item

* fix SR maps referencing tablets, add clear PDA instead of modular tablet loadout

* remove pda loadout item

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: tastyfish <crazychris32@gmail.com>
This commit is contained in:
SkyratBot
2022-09-27 23:52:24 +02:00
committed by GitHub
parent 3ddbc27081
commit d0b706c041
49 changed files with 311 additions and 726 deletions

View File

@@ -1,68 +0,0 @@
/obj/proc/is_modular_computer()
return FALSE
//item
/obj/item/modular_computer/is_modular_computer()
return TRUE
//machine
/obj/machinery/modular_computer/is_modular_computer()
return TRUE
/obj/proc/get_modular_computer_part(part_type)
return null
//item
/obj/item/modular_computer/get_modular_computer_part(part_type)
if(!part_type)
stack_trace("get_modular_computer_part() called without a valid part_type")
return null
return all_components[part_type]
//machine
/obj/machinery/modular_computer/get_modular_computer_part(part_type)
if(!part_type)
stack_trace("get_modular_computer_part() called without a valid part_type")
return null
return cpu?.all_components[part_type]
/obj/proc/get_modular_computer_parts_examine(mob/user)
. = list()
if(!is_modular_computer())
return
var/user_is_adjacent = Adjacent(user) //don't reveal full details unless they're close enough to see it on the screen anyway.
var/obj/item/computer_hardware/ai_slot/ai_slot = get_modular_computer_part(MC_AI)
if(ai_slot)
if(ai_slot.stored_card)
if(user_is_adjacent)
. += "It has a slot installed for an intelliCard which contains: [ai_slot.stored_card.name]"
else
. += "It has a slot installed for an intelliCard, which appears to be occupied."
. += span_info("Alt-click to eject the intelliCard.")
else
. += "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_slot2?.stored_card)
var/obj/item/card/id/first_ID = card_slot?.stored_card
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 [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 [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_info("Alt-click [src] to eject the identification card[multiple_cards ? "s":""].")
else
. += "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)
. += "It has a printer installed."
if(user_is_adjacent)
. += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].</span>"

View File

@@ -295,7 +295,33 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
else if(atom_integrity < max_integrity)
. += span_warning("It is damaged.")
. += get_modular_computer_parts_examine(user)
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
for(var/datum/computer_file/app_examine as anything in hdd.stored_files)
if(app_examine.on_examine(src, user))
. += app_examine.on_examine(src, user)
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
var/multiple_slots = istype(card_slot) && istype(card_slot2)
if(card_slot)
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_slot2?.stored_card
var/multiple_cards = (first_ID && second_ID)
if(Adjacent(user))
. += "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 || second_ID]"]."
else
. += "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_info("Alt-click [src] to eject the identification card[multiple_cards ? "s":""].")
else
. += "It has [multiple_slots ? "two slots" : "a slot"] installed for identification cards."
var/obj/item/computer_hardware/printer/printer_slot = all_components[MC_PRINT]
if(printer_slot)
. += "It has a printer installed."
if(Adjacent(user))
. += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].</span>"
/obj/item/modular_computer/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
@@ -354,11 +380,6 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
to_chat(user, span_warning("You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again."))
return FALSE
// If we have a recharger, enable it automatically. Lets computer without a battery work.
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger)
recharger.enabled = 1
if(use_power()) // use_power() checks if the PC is powered
if(issynth)
to_chat(user, span_notice("You send an activation signal to \the [src], turning it on."))
@@ -403,8 +424,7 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
else
active_program = null
for(var/I in idle_threads)
var/datum/computer_file/program/P = I
for(var/datum/computer_file/program/P as anything in idle_threads)
if(P.program_state != PROGRAM_STATE_KILLED)
P.process_tick(delta_time)
P.ntnet_status = get_ntnet_status()
@@ -417,7 +437,7 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
/**
* Displays notification text alongside a soundbeep when requested to by a program.
*
* After checking tha the requesting program is allowed to send an alert, creates
* After checking that the requesting program is allowed to send an alert, creates
* a visible message of the requested text alongside a soundbeep. This proc adds
* text to indicate that the message is coming from this device and the program
* on it, so the supplied text should be the exact message and ending punctuation.
@@ -426,15 +446,11 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
* The program calling this proc.
* The message that the program wishes to display.
*/
/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
return FALSE
playsound(src, sound, 50, TRUE)
visible_message(span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]"))
var/mob/living/holder = loc
if(istype(holder))
to_chat(holder, "[icon2html(src)] [span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")]")
visible_message(span_notice("[icon2html(src)] [span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")]"))
/obj/item/modular_computer/proc/ring(ringtone) // bring bring
if(HAS_TRAIT(SSstation, STATION_TRAIT_PDA_GLITCHED))
@@ -453,7 +469,6 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
data["PC_device_theme"] = device_theme
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(battery_module && battery_module.battery)
switch(battery_module.battery.percent())
@@ -476,9 +491,6 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
data["PC_batterypercent"] = "N/C"
data["PC_showbatteryicon"] = battery_module ? 1 : 0
if(recharger && recharger.enabled && recharger.check_functionality() && recharger.use_power(0))
data["PC_apclinkicon"] = "charging.gif"
switch(get_ntnet_status())
if(0)
data["PC_ntneticon"] = "sig_none.gif"
@@ -582,9 +594,9 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
idle_threads.Remove(P)
if(looping_sound)
soundloop.stop()
if(loud)
if(physical && loud)
physical.visible_message(span_notice("\The [src] shuts down."))
enabled = 0
enabled = FALSE
update_appearance()
/obj/item/modular_computer/ui_action_click(mob/user, actiontype)
@@ -668,9 +680,10 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
to_chat(user, span_notice("You slot \the [attacking_item] into [src]."))
return
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
// Scan a photo.
if(istype(attacking_item, /obj/item/photo))
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
var/obj/item/photo/pic = attacking_item
if(hdd)
for(var/datum/computer_file/program/messenger/messenger in hdd.stored_files)
@@ -684,6 +697,11 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar
if(H.try_insert(attacking_item, user))
return
// Insert items into applications
for(var/datum/computer_file/item_holding_app as anything in hdd.stored_files)
if(item_holding_app.try_insert(attacking_item, user))
return
// Insert new hardware
if(istype(attacking_item, /obj/item/computer_hardware) && upgradable)
if(install_component(attacking_item, user))

View File

@@ -3,14 +3,13 @@
if(check_power_override())
return TRUE
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger?.check_functionality())
if(recharger.use_power(amount))
if(ismachinery(loc))
var/obj/machinery/machine_holder = loc
if(machine_holder.powered())
machine_holder.use_power(amount)
return TRUE
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
if(battery_module && battery_module.battery && battery_module.battery.charge)
var/obj/item/stock_parts/cell/cell = battery_module.battery
if(cell.use(amount JOULES))
@@ -42,10 +41,6 @@
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
/obj/item/modular_computer/proc/handle_power(delta_time)
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger)
recharger.process(delta_time)
var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage
for(var/obj/item/computer_hardware/H in all_components)
@@ -59,6 +54,10 @@
power_failure()
return FALSE
// Used by child types if they have other power source than battery or recharger
///Used by subtypes for special cases for power usage, returns TRUE if it should stop the use_power chain.
/obj/item/modular_computer/proc/check_power_override()
return FALSE
//Integrated (Silicon) tablets don't drain power, because the tablet is required to state laws, so it being disabled WILL cause problems.
/obj/item/modular_computer/tablet/integrated/check_power_override()
return TRUE

View File

@@ -89,18 +89,19 @@
IDJob = cardholder.current_job,
)
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
data["removable_media"] = list()
if(all_components[MC_SDD])
data["removable_media"] += "Eject Disk"
var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI]
if(intelliholder?.stored_card)
var/datum/computer_file/program/ai_restorer/airestore_app = locate() in hard_drive.stored_files
if(airestore_app?.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)
var/running = FALSE
if(P in idle_threads)
@@ -189,10 +190,10 @@
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)
var/datum/computer_file/program/ai_restorer/airestore_app = locate() in hard_drive.stored_files
if(!airestore_app)
return
if(intelliholder.try_eject(user))
if(airestore_app.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]

View File

@@ -2,7 +2,7 @@
//TODO: REFACTOR THIS SPAGHETTI CODE, MAKE IT A COMPUTER_HARDWARE COMPONENT OR REMOVE IT
/obj/item/modular_computer/processor
name = "processing unit"
desc = "You shouldn't see this. If you do, report it."
desc = "An advanced computer." //modular PCs examine us
icon = null
icon_state = null
icon_state_unpowered = null
@@ -50,12 +50,3 @@
..()
machinery_computer.update_appearance()
return
/obj/item/modular_computer/processor/attack_ghost(mob/user)
ui_interact(user)
/obj/item/modular_computer/processor/alert_call(datum/computer_file/program/caller, alerttext)
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext)
return
playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
machinery_computer.visible_message(span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]"))

View File

@@ -21,7 +21,7 @@
name = "captain PDA"
greyscale_config = /datum/greyscale_config/tablet/captain
greyscale_colors = "#2C7CB2#FF0000#FFFFFF#FFD55B"
insert_type = /obj/item/pen/fountain/captain
inserted_item = /obj/item/pen/fountain/captain
/obj/item/modular_computer/tablet/pda/heads/captain/Initialize(mapload)
. = ..()
@@ -92,7 +92,7 @@
name = "research director PDA"
greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head
greyscale_colors = "#FAFAFA#000099#B347BC"
insert_type = /obj/item/pen/fountain
inserted_item = /obj/item/pen/fountain
default_applications = list(
/datum/computer_file/program/crew_manifest,
/datum/computer_file/program/status,
@@ -111,7 +111,7 @@
name = "quartermaster PDA"
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#D6B328#6506CA#927444"
insert_type = /obj/item/pen/survival
inserted_item = /obj/item/pen/survival
default_applications = list(
/datum/computer_file/program/crew_manifest,
/datum/computer_file/program/status,
@@ -287,7 +287,7 @@
/obj/item/modular_computer/tablet/pda/lawyer
name = "lawyer PDA"
greyscale_colors = "#4C76C8#FFE243"
insert_type = /obj/item/pen/fountain
inserted_item = /obj/item/pen/fountain
default_applications = list(
/datum/computer_file/program/records/security,
)
@@ -319,7 +319,7 @@
icon_state = "pda-clown"
greyscale_config = null
greyscale_colors = null
insert_type = /obj/item/toy/crayon/rainbow
inserted_item = /obj/item/toy/crayon/rainbow
/obj/item/modular_computer/tablet/pda/clown/Initialize(mapload)
. = ..()
@@ -345,7 +345,7 @@
loaded_cartridge = /obj/item/computer_hardware/hard_drive/portable/virus/mime
greyscale_config = /datum/greyscale_config/tablet/mime
greyscale_colors = "#FAFAFA#EA3232"
insert_type = /obj/item/toy/crayon/mime
inserted_item = /obj/item/toy/crayon/mime
/obj/item/modular_computer/tablet/pda/mime/Initialize(mapload)
. = ..()
@@ -361,7 +361,7 @@
greyscale_config = null
greyscale_colors = null
icon_state = "pda-library"
insert_type = /obj/item/pen/fountain
inserted_item = /obj/item/pen/fountain
default_applications = list(
/datum/computer_file/program/newscaster,
)

View File

@@ -27,10 +27,7 @@
var/finish_color = null
var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette)
var/obj/item/insert_type = /obj/item/pen
var/obj/item/inserted_item
var/note = "Congratulations on your station upgrading to the new NtOS and Thinktronic based collaboration effort, bringing you the best in electronics and software since 2467!" // the note used by the notekeeping app, stored here for convenience
var/obj/item/inserted_item = /obj/item/pen
/obj/item/modular_computer/tablet/update_icon_state()
if(has_variants && !bypass_state)
@@ -255,12 +252,6 @@
robo.toggle_headlamp(FALSE, TRUE)
return TRUE
/obj/item/modular_computer/tablet/integrated/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
borgo.playsound_local(src, sound, 50, TRUE)
to_chat(borgo, span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]"))
/obj/item/modular_computer/tablet/integrated/ui_state(mob/user)
return GLOB.reverse_contained_state
@@ -326,5 +317,5 @@
var/obj/item/computer_hardware/hard_drive/portable/disk = new loaded_cartridge(src)
install_component(disk)
if(insert_type)
inserted_item = new insert_type(src)
if(inserted_item)
inserted_item = new inserted_item(src)

View File

@@ -1,93 +1,3 @@
// This is literally the worst possible cheap tablet
/obj/item/modular_computer/tablet/preset/cheap
desc = "A low-end tablet often seen among low ranked station personnel."
/obj/item/modular_computer/tablet/preset/cheap/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer/micro))
install_component(new /obj/item/computer_hardware/hard_drive/small)
install_component(new /obj/item/computer_hardware/network_card)
// Alternative version, an average one, for higher ranked positions mostly
/obj/item/modular_computer/tablet/preset/advanced/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
install_component(new /obj/item/computer_hardware/hard_drive/small)
install_component(new /obj/item/computer_hardware/network_card)
install_component(new /obj/item/computer_hardware/card_slot)
install_component(new /obj/item/computer_hardware/printer/mini)
/obj/item/modular_computer/tablet/preset/science/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = new
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)
hard_drive.store_file(new /datum/computer_file/program/signal_commander)
/obj/item/modular_computer/tablet/preset/cargo/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = new
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/shipping)
var/datum/computer_file/program/chatclient/chatprogram
chatprogram = new
hard_drive.store_file(chatprogram)
chatprogram.username = get_cargochat_username()
/obj/item/modular_computer/tablet/preset/cargo/proc/get_cargochat_username()
return "cargonian_[rand(1,999)]"
/obj/item/modular_computer/tablet/preset/cargo/quartermaster/get_cargochat_username()
return "quartermaster"
/obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize(mapload) //This will be defunct and will be replaced when NtOS PDAs are done
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/alarm_monitor)
hard_drive.store_file(new /datum/computer_file/program/atmosscan)
/obj/item/modular_computer/tablet/preset/advanced/custodial/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/radar/custodial_locator)
/obj/item/modular_computer/tablet/preset/advanced/curator/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/newscaster)
/obj/item/modular_computer/tablet/preset/advanced/engineering/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/alarm_monitor)
hard_drive.store_file(new /datum/computer_file/program/supermatter_monitor)
/obj/item/modular_computer/tablet/preset/advanced/security/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/crew_manifest)
hard_drive.store_file(new /datum/computer_file/program/robocontrol)
/obj/item/modular_computer/tablet/preset/advanced/command/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
install_component(new /obj/item/computer_hardware/card_slot/secondary)
hard_drive.store_file(new /datum/computer_file/program/budgetorders)
hard_drive.store_file(new /datum/computer_file/program/science)
/obj/item/modular_computer/tablet/preset/advanced/command/engineering/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
hard_drive.store_file(new /datum/computer_file/program/alarm_monitor)
hard_drive.store_file(new /datum/computer_file/program/supermatter_monitor)
/// Given to Nuke Ops members.
/obj/item/modular_computer/tablet/nukeops/Initialize(mapload)
. = ..()
@@ -98,5 +8,4 @@
//Borg Built-in tablet
/obj/item/modular_computer/tablet/integrated/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/recharger/cyborg)
install_component(new /obj/item/computer_hardware/network_card/integrated)

View File

@@ -3,7 +3,6 @@
var/_has_second_id_slot = FALSE
var/_has_printer = FALSE
var/_has_battery = FALSE
var/_has_ai = FALSE
/obj/machinery/modular_computer/console/preset/Initialize(mapload)
. = ..()
@@ -17,8 +16,6 @@
cpu.install_component(new /obj/item/computer_hardware/printer)
if(_has_battery)
cpu.install_component(new /obj/item/computer_hardware/battery(cpu, /obj/item/stock_parts/cell/computer/super))
if(_has_ai)
cpu.install_component(new /obj/item/computer_hardware/ai_slot)
install_programs()
// Override in child types to install preset-specific programs.
@@ -43,13 +40,12 @@
name = "research director's console"
desc = "A stationary computer. This one comes preloaded with research programs."
_has_second_id_slot = TRUE
_has_ai = TRUE
/obj/machinery/modular_computer/console/preset/research/install_programs()
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
hard_drive.store_file(new/datum/computer_file/program/chatclient())
hard_drive.store_file(new/datum/computer_file/program/aidiag())
hard_drive.store_file(new/datum/computer_file/program/ai_restorer())
hard_drive.store_file(new/datum/computer_file/program/robocontrol())
hard_drive.store_file(new/datum/computer_file/program/scipaper_program())

View File

@@ -2,12 +2,12 @@
// DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead.
/obj/machinery/modular_computer
name = "modular computer"
desc = "An advanced computer."
desc = "You shouldn't see this. If you do, report it." //they should be examining the processor instead
// Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..)
// 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 = null
icon = 'icons/obj/modular_console.dmi'
icon_state = null
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.05
@@ -39,7 +39,7 @@
var/base_idle_power_usage = 10
///CPU that handles most logic while this type only handles power and other specific things.
var/obj/item/modular_computer/processor/cpu = null
var/obj/item/modular_computer/processor/cpu
/obj/machinery/modular_computer/Initialize(mapload)
. = ..()
@@ -51,8 +51,9 @@
return ..()
/obj/machinery/modular_computer/examine(mob/user)
. = ..()
. += get_modular_computer_parts_examine(user)
if(cpu)
return cpu.examine(user)
return ..()
/obj/machinery/modular_computer/attack_ghost(mob/dead/observer/user)
. = ..()
@@ -65,27 +66,33 @@
if(!cpu)
to_chat(user, span_warning("You'd need to turn the [src] on first."))
return FALSE
return (cpu.emag_act(user))
return cpu.emag_act(user)
/obj/machinery/modular_computer/update_appearance(updates)
. = ..()
set_light(cpu?.enabled ? light_strength : 0)
/obj/machinery/modular_computer/update_icon_state()
icon_state = (cpu?.enabled || (!(machine_stat & NOPOWER) && cpu?.use_power())) ? icon_state_powered : icon_state_unpowered
if(!cpu || !cpu.enabled || !cpu.use_power() || (machine_stat & NOPOWER))
icon_state = icon_state_unpowered
else
icon_state = icon_state_powered
return ..()
/obj/machinery/modular_computer/update_overlays()
. = ..()
if(!cpu?.enabled)
if (!(machine_stat & NOPOWER) && (cpu?.use_power()))
. += screen_icon_screensaver
else
. += cpu.active_program?.program_icon_state || screen_icon_state_menu
if(!cpu)
return .
if(cpu && cpu.get_integrity() <= cpu.integrity_failure * cpu.max_integrity)
if(cpu.enabled && cpu.use_power())
. += cpu.active_program?.program_icon_state || screen_icon_state_menu
else if(!(machine_stat & NOPOWER))
. += screen_icon_screensaver
if(cpu.get_integrity() <= cpu.integrity_failure * cpu.max_integrity)
. += "bsod"
. += "broken"
return .
/// Eats the "source" arg because update_icon actually expects args now.
/obj/machinery/modular_computer/proc/relay_icon_update(datum/source, updates, updated)
@@ -103,9 +110,8 @@
// On-click handling. Turns on the computer if it's off and opens the GUI.
/obj/machinery/modular_computer/interact(mob/user)
if(cpu)
return cpu.interact(user) // CPU is an item, that's why we route attack_hand to attack_self
else
return ..()
return cpu.interact(user)
return ..()
// Process currently calls handle_power(), may be expanded in future if more things are added.
/obj/machinery/modular_computer/process(delta_time)
@@ -114,33 +120,23 @@
cpu.name = name
cpu.process(delta_time)
// Used in following function to reduce copypaste
/obj/machinery/modular_computer/proc/power_failure(malfunction = 0)
var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
if(cpu?.enabled) // Shut down the computer
visible_message(span_danger("\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly."))
if(cpu)
cpu.shutdown_computer(0)
set_machine_stat(machine_stat | NOPOWER)
update_appearance()
// Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us.
/obj/machinery/modular_computer/power_change()
if(cpu?.use_power()) // If it still has a power source, PC wouldn't go offline.
set_machine_stat(machine_stat & ~NOPOWER)
update_appearance()
return
. = ..()
return ..()
/obj/machinery/modular_computer/screwdriver_act(mob/user, obj/item/tool)
if(cpu)
return cpu.screwdriver_act(user, tool)
/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/living/user)
if (!user.combat_mode && cpu && !(flags_1 & NODECONSTRUCT_1))
return cpu.attackby(W, user)
return ..()
/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/living/user)
if (cpu && !user.combat_mode && !(flags_1 & NODECONSTRUCT_1))
return cpu.attackby(W, user)
return ..()
// Stronger explosions cause serious damage to internal components
// Minor explosions are mostly mitigitated by casing.
@@ -170,4 +166,5 @@
// "Brute" damage mostly damages the casing.
/obj/machinery/modular_computer/bullet_act(obj/projectile/Proj)
if(cpu)
cpu.bullet_act(Proj)
return cpu.bullet_act(Proj)
return ..()

View File

@@ -6,7 +6,6 @@
icon_state = "console"
icon_state_powered = "console"
icon_state_unpowered = "console-off"
screen_icon_state_menu = "menu"
hardware_flag = PROGRAM_CONSOLE
density = TRUE
base_idle_power_usage = 100
@@ -24,10 +23,8 @@
// User-built consoles start as empty frames.
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
var/obj/item/computer_hardware/hard_drive/network_card = cpu.all_components[MC_NET]
var/obj/item/computer_hardware/hard_drive/recharger = cpu.all_components[MC_CHARGE]
qdel(recharger)
qdel(network_card)
qdel(hard_drive)
qdel(network_card)
/obj/machinery/modular_computer/console/Initialize(mapload)
. = ..()
@@ -38,7 +35,6 @@
var/obj/item/computer_hardware/network_card/wired/network_card = new()
cpu.install_component(network_card)
cpu.install_component(new /obj/item/computer_hardware/recharger/apc_recharger)
cpu.install_component(new /obj/item/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations
var/area/A = get_area(src)

View File

@@ -13,7 +13,7 @@
..()
uid = file_uid++
/datum/computer_file/Destroy()
/datum/computer_file/Destroy(force)
if(!holder)
return ..()
@@ -37,3 +37,29 @@
temp.filename = filename
temp.filetype = filetype
return temp
/**
* Called when examining a modular computer
* Args:
* Source - The tablet that's being examined
* User - Person examining the computer
*
* note: please replace this with signals when hdd's are removed and program's New() already has the tablet set.
*/
/datum/computer_file/proc/on_examine(obj/item/modular_computer/source, mob/user)
return null
/// Called when someone tries to insert something one of your applications needs, like an Intellicard for AI restoration.
/datum/computer_file/proc/try_insert(obj/item/attacking_item, mob/living/user)
return FALSE
/**
* Implement this when your program has an object that the user can eject.
*
* Examples include ejecting cells AI intellicards.
* Arguments:
* * user - The mob requesting the eject.
* * forced - Whether we are forced to eject everything (usually by the app being deleted)
*/
/datum/computer_file/proc/try_eject(mob/living/user, forced = FALSE)
return FALSE

View File

@@ -1,127 +1,139 @@
/datum/computer_file/program/aidiag
filename = "aidiag"
filedesc = "NT FRK"
/datum/computer_file/program/ai_restorer
filename = "ai_restore"
filedesc = "AI Manager & Restorer"
category = PROGRAM_CATEGORY_SCI
program_icon_state = "generic"
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
transfer_access = list(ACCESS_COMMAND)
transfer_access = list(ACCESS_RD)
available_on_ntnet = TRUE
tgui_id = "NtosAiRestorer"
program_icon = "laptop-code"
/// The AI stored in the program
var/obj/item/aicard/stored_card
/// Variable dictating if we are in the process of restoring the AI in the inserted intellicard
var/restoring = FALSE
/datum/computer_file/program/aidiag/proc/get_ai(cardcheck)
/datum/computer_file/program/ai_restorer/on_examine(obj/item/modular_computer/source, mob/user)
var/list/examine_text = list()
if(!stored_card)
examine_text += "It has a slot installed for an intelliCard."
return examine_text
var/obj/item/computer_hardware/ai_slot/ai_slot
if(computer.Adjacent(user))
examine_text += "It has a slot installed for an intelliCard which contains: [stored_card.name]"
else
examine_text += "It has a slot installed for an intelliCard, which appears to be occupied."
examine_text += span_info("Alt-click to eject the intelliCard.")
return examine_text
if(computer)
ai_slot = computer.all_components[MC_AI]
/datum/computer_file/program/ai_restorer/kill_program(forced)
try_eject(forced = TRUE)
return ..()
if(computer && ai_slot?.check_functionality())
if(cardcheck == 1)
return ai_slot
if(ai_slot.enabled && ai_slot.stored_card)
if(cardcheck == 2)
return ai_slot.stored_card
if(ai_slot.stored_card.AI)
return ai_slot.stored_card.AI
return
/datum/computer_file/program/aidiag/ui_act(action, params)
. = ..()
if(.)
return
var/mob/living/silicon/ai/A = get_ai()
if(!A)
restoring = FALSE
switch(action)
if("PRG_beginReconstruction")
if(A && A.health < 100)
restoring = TRUE
A.notify_ghost_cloning("Your core files are being restored!", source = computer)
return TRUE
if("PRG_eject")
if(computer.all_components[MC_AI])
var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI]
if(ai_slot?.stored_card)
ai_slot.try_eject(usr)
return TRUE
/datum/computer_file/program/aidiag/process_tick()
/datum/computer_file/program/ai_restorer/process_tick(delta_time)
. = ..()
if(!restoring) //Put the check here so we don't check for an ai all the time
return
var/obj/item/aicard/cardhold = get_ai(2)
var/obj/item/computer_hardware/ai_slot/ai_slot = get_ai(1)
var/mob/living/silicon/ai/A = get_ai()
if(!A || !cardhold)
restoring = FALSE // If the AI was removed, stop the restoration sequence.
if(ai_slot)
ai_slot.locked = FALSE
return
if(cardhold.flush)
ai_slot.locked = FALSE
var/mob/living/silicon/ai/A = stored_card.AI
if(stored_card.flush)
restoring = FALSE
return
ai_slot.locked = TRUE
A.adjustOxyLoss(-5, FALSE)
A.adjustFireLoss(-5, FALSE)
A.adjustBruteLoss(-5, FALSE)
// 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_appearance()
stored_card.update_appearance()
// Finished restoring
if(A.health >= 100)
ai_slot.locked = FALSE
restoring = FALSE
return TRUE
/datum/computer_file/program/ai_restorer/try_insert(obj/item/attacking_item, mob/living/user)
if(!computer)
return FALSE
if(!istype(attacking_item, /obj/item/aicard))
return FALSE
/datum/computer_file/program/aidiag/ui_data(mob/user)
if(stored_card)
to_chat(user, span_warning("You try to insert \the [attacking_item] into \the [computer.name], but the slot is occupied."))
return FALSE
if(user && !user.transferItemToLoc(attacking_item, computer))
return FALSE
stored_card = attacking_item
to_chat(user, span_notice("You insert \the [attacking_item] into \the [computer.name]."))
return TRUE
/datum/computer_file/program/ai_restorer/try_eject(mob/living/user, forced = FALSE)
if(!stored_card)
if(user)
to_chat(user, span_warning("There is no card in \the [computer.name]."))
return FALSE
if(restoring && !forced)
if(user)
to_chat(user, span_warning("Safeties prevent you from removing the card until reconstruction is complete..."))
return FALSE
if(user && computer.Adjacent(user))
to_chat(user, span_notice("You remove [stored_card] from [computer.name]."))
user.put_in_hands(stored_card)
else
stored_card.forceMove(computer.drop_location())
stored_card = null
restoring = FALSE
return TRUE
/datum/computer_file/program/ai_restorer/ui_act(action, params)
. = ..()
if(.)
return
switch(action)
if("PRG_beginReconstruction")
if(!stored_card || !stored_card.AI)
return FALSE
var/mob/living/silicon/ai/A = stored_card.AI
if(A && A.health < 100)
restoring = TRUE
A.notify_ghost_cloning("Your core files are being restored!", source = computer)
return TRUE
if("PRG_eject")
if(stored_card)
try_eject(usr)
return TRUE
/datum/computer_file/program/ai_restorer/ui_data(mob/user)
var/list/data = get_header_data()
var/mob/living/silicon/ai/AI = get_ai()
var/obj/item/aicard/aicard = get_ai(2)
data["ejectable"] = TRUE
data["AI_present"] = FALSE
data["AI_present"] = !!stored_card?.AI
data["error"] = null
if(!aicard)
if(!stored_card)
data["error"] = "Please insert an intelliCard."
else if(!stored_card.AI)
data["error"] = "No AI located..."
else if(stored_card.flush)
data["error"] = "Flush in progress!"
else
if(!AI)
data["error"] = "No AI located"
else
var/obj/item/aicard/cardhold = AI.loc
if(cardhold.flush)
data["error"] = "Flush in progress"
else
data["AI_present"] = TRUE
data["name"] = AI.name
data["restoring"] = restoring
data["health"] = (AI.health + 100) / 2
data["isDead"] = AI.stat == DEAD
data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
data["name"] = stored_card.AI.name
data["restoring"] = restoring
data["health"] = (stored_card.AI.health + 100) / 2
data["isDead"] = stored_card.AI.stat == DEAD
data["laws"] = stored_card.AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
return data
/datum/computer_file/program/aidiag/kill_program(forced)
restoring = FALSE
return ..()

View File

@@ -26,7 +26,7 @@
QDEL_NULL(alert_control)
return ..()
/datum/computer_file/program/alarm_monitor/process_tick()
/datum/computer_file/program/alarm_monitor/process_tick(delta_time)
..()
if(has_alert)

View File

@@ -16,7 +16,7 @@
var/error = ""
var/executed = 0
/datum/computer_file/program/ntnet_dos/process_tick()
/datum/computer_file/program/ntnet_dos/process_tick(delta_time)
dos_speed = 0
switch(ntnet_status)
if(1)

View File

@@ -30,7 +30,6 @@
computer.update_appearance()
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
var/obj/item/computer_hardware/battery/battery_module = computer.all_components[MC_CELL]
var/obj/item/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE]
qdel(hard_drive)
computer.take_damage(25, BRUTE, 0, 0)
if(battery_module && prob(25))
@@ -39,12 +38,6 @@
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()
if(recharger && prob(50))
qdel(recharger)
computer.visible_message(span_notice("\The [computer]'s recharger explodes in rain of sparks."))
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()
/datum/computer_file/program/revelation/ui_act(action, params)
. = ..()

View File

@@ -47,7 +47,7 @@
borgo.logevent("File request by [username]: /var/logs/syslog")
return TRUE
/datum/computer_file/program/borg_monitor/process_tick()
/datum/computer_file/program/borg_monitor/process_tick(delta_time)
if(!DL_source)
DL_progress = -1
return

View File

@@ -9,6 +9,9 @@
program_icon = "book"
usage_flags = PROGRAM_TABLET
var/written_note = "Congratulations on your station upgrading to the new NtOS and Thinktronic based collaboration effort, \
bringing you the best in electronics and software since 2467!"
/datum/computer_file/program/notepad/ui_act(action, list/params, datum/tgui/ui)
. = ..()
if(.)
@@ -16,14 +19,12 @@
switch(action)
if("UpdateNote")
var/obj/item/modular_computer/tablet/comp = computer
comp.note = params["newnote"]
written_note = params["newnote"]
return UI_UPDATE
/datum/computer_file/program/notepad/ui_data(mob/user)
var/list/data = get_header_data()
var/obj/item/modular_computer/tablet/comp = computer
data["note"] = comp.note
data["note"] = written_note
return data

View File

@@ -93,7 +93,7 @@
download_completion = FALSE
ui_header = "downloader_finished.gif"
/datum/computer_file/program/ntnetdownload/process_tick()
/datum/computer_file/program/ntnetdownload/process_tick(delta_time)
if(!downloaded_file)
return
if(download_completion >= downloaded_file.size)

View File

@@ -171,7 +171,7 @@
channel.ping_user(src, pinged)
return TRUE
/datum/computer_file/program/chatclient/process_tick()
/datum/computer_file/program/chatclient/process_tick(delta_time)
. = ..()
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
if(program_state != PROGRAM_STATE_KILLED)

View File

@@ -31,7 +31,7 @@
history["demand"] = list()
/datum/computer_file/program/power_monitor/process_tick()
/datum/computer_file/program/power_monitor/process_tick(delta_time)
if(!get_powernet())
search()
else

View File

@@ -197,7 +197,7 @@
computer.setDir(get_dir(here_turf, target_turf))
//We can use process_tick to restart fast processing, since the computer will be running this constantly either way.
/datum/computer_file/program/radar/process_tick()
/datum/computer_file/program/radar/process_tick(delta_time)
if(computer.active_program == src)
START_PROCESSING(SSfastprocess, src)
@@ -316,19 +316,13 @@
return
RegisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_ARMED, .proc/on_nuke_armed)
if(computer)
RegisterSignal(computer, COMSIG_PARENT_EXAMINE, .proc/on_examine)
/datum/computer_file/program/radar/fission360/kill_program(forced)
UnregisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_ARMED)
if(computer)
UnregisterSignal(computer, COMSIG_PARENT_EXAMINE)
return ..()
/datum/computer_file/program/radar/fission360/Destroy()
UnregisterSignal(SSdcs, COMSIG_GLOB_NUKE_DEVICE_ARMED)
if(computer)
UnregisterSignal(computer, COMSIG_PARENT_EXAMINE)
return ..()
/datum/computer_file/program/radar/fission360/find_atom()
@@ -364,16 +358,14 @@
)
objects += list(ship_info)
/*
* Signal proc for [COMSIG_PARENT_EXAMINE], registered on the computer.
* Shows how long any armed nukes are to detonating.
*/
/datum/computer_file/program/radar/fission360/proc/on_examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
///Shows how long until the nuke detonates, if one is active.
/datum/computer_file/program/radar/fission360/on_examine(obj/item/modular_computer/source, mob/user)
var/list/examine_list = list()
for(var/obj/machinery/nuclearbomb/bomb as anything in GLOB.nuke_list)
if(bomb.timing)
examine_list += span_danger("Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()].")
return examine_list
/*
* Signal proc for [COMSIG_GLOB_NUKE_DEVICE_ARMED].
@@ -392,4 +384,4 @@
computer.audible_message(
span_danger("[computer] vibrates and lets out an ominous alarm. Uh oh."),
span_notice("[computer] begins to vibrate rapidly. Wonder what that means..."),
)
)

View File

@@ -20,7 +20,7 @@
active = null
return ..()
/datum/computer_file/program/supermatter_monitor/process_tick()
/datum/computer_file/program/supermatter_monitor/process_tick(delta_time)
..()
var/new_status = get_status()
if(last_status != new_status)

View File

@@ -71,7 +71,8 @@
/// Called on multitool click, prints diagnostic information to the user.
/obj/item/computer_hardware/proc/diagnostics(mob/user)
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) \
[damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
/// Handles damage checks
/obj/item/computer_hardware/proc/check_functionality()

View File

@@ -1,66 +0,0 @@
/obj/item/computer_hardware/ai_slot
name = "intelliCard interface slot"
desc = "A module allowing this computer to interface with most common intelliCard modules. Necessary for some programs to run properly."
power_usage = 100 //W
icon_state = "card_mini"
w_class = WEIGHT_CLASS_SMALL
device_type = MC_AI
expansion_hw = TRUE
var/obj/item/aicard/stored_card
var/locked = FALSE
///What happens when the intellicard is removed (or deleted) from the module, through try_eject() or not.
/obj/item/computer_hardware/ai_slot/Exited(atom/movable/gone, direction)
if(stored_card == gone)
stored_card = null
return ..()
/obj/item/computer_hardware/ai_slot/examine(mob/user)
. = ..()
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/try_insert(obj/item/I, mob/living/user = null)
if(!holder)
return FALSE
if(!istype(I, /obj/item/aicard))
return FALSE
if(stored_card)
to_chat(user, span_warning("You try to insert \the [I] into \the [src], but the slot is occupied."))
return FALSE
if(user && !user.transferItemToLoc(I, src))
return FALSE
stored_card = I
to_chat(user, span_notice("You insert \the [I] into \the [src]."))
return TRUE
/obj/item/computer_hardware/ai_slot/try_eject(mob/living/user = null, forced = FALSE)
if(!stored_card)
to_chat(user, span_warning("There is no card in \the [src]."))
return FALSE
if(locked && !forced)
to_chat(user, span_warning("Safeties prevent you from removing the card until reconstruction is complete..."))
return FALSE
if(stored_card)
to_chat(user, span_notice("You remove [stored_card] from [src]."))
locked = FALSE
if(Adjacent(user))
user.put_in_hands(stored_card)
else
stored_card.forceMove(drop_location())
return TRUE
return FALSE
/obj/item/computer_hardware/ai_slot/screwdriver_act(mob/living/user, obj/item/tool)
to_chat(user, span_notice("You press down on the manual eject button with [tool]."))
try_eject(user, TRUE)
return TOOL_ACT_TOOLTYPE_SUCCESS

View File

@@ -4,8 +4,8 @@
icon_state = "cell_con"
critical = 1
malfunction_probability = 1
var/obj/item/stock_parts/cell/battery
device_type = MC_CELL
var/obj/item/stock_parts/cell/battery
/obj/item/computer_hardware/battery/get_cell()
return battery

View File

@@ -88,6 +88,10 @@
return FALSE
if(F in stored_files)
if(istype(F, /datum/computer_file/program))
var/datum/computer_file/program/program_file = F
if(program_file.program_state != PROGRAM_STATE_KILLED)
program_file.kill_program(TRUE)
SEND_SIGNAL(F, COMSIG_MODULAR_COMPUTER_FILE_DELETING)
stored_files -= F
recalculate_size()

View File

@@ -27,7 +27,6 @@
var/obj/item/paper/printed_paper = new/obj/item/paper(holder.drop_location())
// Damaged printer causes the resulting paper to be somewhat harder to read.
if(damage > damage_malfunction)
printed_paper.add_raw_text(stars(text_to_print, 100-malfunction_probability))
else

View File

@@ -1,99 +0,0 @@
/obj/item/computer_hardware/recharger
critical = TRUE
enabled = TRUE
device_type = MC_CHARGE
var/charge_rate = 100
/obj/item/computer_hardware/recharger/proc/use_power(amount, charging=0)
if(charging)
return TRUE
return FALSE
/obj/item/computer_hardware/recharger/process()
..()
var/obj/item/computer_hardware/battery/battery_module = holder.all_components[MC_CELL]
if(!holder || !battery_module || !battery_module.battery)
return
var/obj/item/stock_parts/cell/cell = battery_module.battery
if(cell.charge >= cell.maxcharge)
return
if(use_power(charge_rate, charging=1))
holder.give_power(charge_rate JOULES)
/obj/item/computer_hardware/recharger/apc_recharger
name = "area power connector"
desc = "A device that wirelessly recharges connected device from nearby APC."
icon_state = "charger_APC"
w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs
/obj/item/computer_hardware/recharger/apc_recharger/use_power(amount, charging=0)
if(ismachinery(holder.physical))
var/obj/machinery/M = holder.physical
if(M.powered())
M.use_power(amount)
return TRUE
else
var/area/A = get_area(src)
if(!istype(A))
return FALSE
if(A.powered(AREA_USAGE_EQUIP))
A.use_power(amount, AREA_USAGE_EQUIP)
return TRUE
return FALSE
/obj/item/computer_hardware/recharger/wired
name = "wired power connector"
desc = "A power connector that recharges connected device from nearby power wire. Incompatible with portable computers."
icon_state = "charger_wire"
w_class = WEIGHT_CLASS_NORMAL
/obj/item/computer_hardware/recharger/wired/can_install(obj/item/modular_computer/install_into, mob/living/user = null)
if(ismachinery(install_into.physical) && install_into.physical.anchored)
return ..()
to_chat(user, span_warning("\The [src] is incompatible with portable computers!"))
return FALSE
/obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0)
if(ismachinery(holder.physical) && holder.physical.anchored)
var/obj/machinery/M = holder.physical
var/turf/T = M.loc
if(!T || !istype(T))
return FALSE
var/obj/structure/cable/C = T.get_cable_node()
if(!C || !C.powernet)
return FALSE
var/power_in_net = C.powernet.avail-C.powernet.load
if(power_in_net && power_in_net > amount)
C.powernet.load += amount
return TRUE
return FALSE
/// This recharger exists only in borg built-in tablets. I would have tied it to the borg's cell but
/// the program that displays laws should always be usable, and the exceptions were starting to pile.
/obj/item/computer_hardware/recharger/cyborg
name = "modular interface power harness"
desc = "A standard connection to power a small computer device from a cyborg's chassis."
/obj/item/computer_hardware/recharger/cyborg/use_power(amount, charging=0)
return TRUE
// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes.
/obj/item/computer_hardware/recharger/lambda
name = "lambda coil"
desc = "A very complex device that draws power from its own bluespace dimension."
icon_state = "charger_lambda"
w_class = WEIGHT_CLASS_TINY
charge_rate = 100000
/obj/item/computer_hardware/recharger/lambda/use_power(amount, charging=0)
return 1

View File

@@ -22,7 +22,6 @@
var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced
var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced
var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range
var/dev_apc_recharger = 0 // 0: None, 1: Standard (LAPTOP ONLY)
var/dev_printer = 0 // 0: None, 1: Standard
var/dev_card = 0 // 0: None, 1: Standard
@@ -39,7 +38,6 @@
dev_battery = 1
dev_disk = 1
dev_netcard = 0
dev_apc_recharger = 0
dev_printer = 0
dev_card = 0
@@ -87,10 +85,6 @@
if(fabricate)
fabricated_laptop.install_component(new /obj/item/computer_hardware/network_card/advanced)
total_price += 299
if(dev_apc_recharger)
total_price += 399
if(fabricate)
fabricated_laptop.install_component(new /obj/item/computer_hardware/recharger/apc_recharger)
if(dev_printer)
total_price += 99
if(fabricate)
@@ -195,10 +189,6 @@
dev_netcard = text2num(params["netcard"])
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_tesla")
dev_apc_recharger = text2num(params["tesla"])
fabricate_and_recalc_price(FALSE)
return TRUE
if("hw_nanoprint")
dev_printer = text2num(params["print"])
fabricate_and_recalc_price(FALSE)
@@ -266,7 +256,6 @@
data["hw_battery"] = dev_battery
data["hw_disk"] = dev_disk
data["hw_netcard"] = dev_netcard
data["hw_tesla"] = dev_apc_recharger
data["hw_nanoprint"] = dev_printer
data["hw_card"] = dev_card
if(state == 1 || state == 2)