Modular Tablets: Converting PDAs to the NtOS System (SKYRAT VERSION) (#12920)

* hot-patch 1

* hot patch 2

* hot patch 3

* slight issue
This commit is contained in:
magatsuchi
2022-04-20 16:55:49 +01:00
committed by GitHub
parent d7222be1a3
commit dc8adc2924
182 changed files with 2968 additions and 4053 deletions
@@ -1,3 +1,5 @@
GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar to GLOB.PDAs (used primarily with ntmessenger.dm)
// This is the base type that does all the hardware stuff.
// Other types expand it - tablets use a direct subtypes, and
// consoles and laptops use "procssor" item that is held inside machinery piece
@@ -11,7 +13,11 @@
max_integrity = 100
armor = list(MELEE = 0, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 100, FIRE = 0, ACID = 0)
var/bypass_state = FALSE // bypassing the set icon state
var/enabled = 0 // Whether the computer is turned on.
var/upgradable = TRUE // whether or not the computer can be upgraded
var/deconstructable = TRUE // whether or not the computer can be deconstructed
var/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
var/device_theme = "ntos" // Sets the theme for the main menu, hardware config, and file browser apps. Overridden by certain non-NT devices.
var/datum/computer_file/program/active_program = null // A currently active program running on the computer.
@@ -46,14 +52,26 @@
/// Number of total expansion bays this computer has available.
var/max_bays = 0
var/saved_identification = null // next two values are the currently imprinted id and job values
var/saved_job = null
var/honkamnt = 0 /// honk honk honk honk honk honkh onk honkhnoohnk
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/comp_light_luminosity = 3 //The brightness of that light
var/comp_light_color //The color of that light
var/invisible = FALSE // whether or not the tablet is invisible in messenger and other apps
var/datum/picture/saved_image // the saved image used for messaging purpose like come on dude
var/obj/item/paicard/pai = null
/obj/item/modular_computer/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/identifier/id = all_components[MC_IDENTIFY]
START_PROCESSING(SSobj, src)
if(!physical)
physical = src
@@ -61,20 +79,28 @@
idle_threads = list()
if(looping_sound)
soundloop = new(src, enabled)
if(id)
id.UpdateDisplay()
update_appearance()
Add_Messenger()
/obj/item/modular_computer/Destroy()
wipe_program(forced = TRUE)
for(var/datum/computer_file/program/idle as anything in idle_threads)
idle.kill_program(TRUE)
idle_threads.Cut()
idle_threads?.Cut()
STOP_PROCESSING(SSobj, src)
for(var/port in all_components)
var/obj/item/computer_hardware/component = all_components[port]
qdel(component)
all_components.Cut() //Die demon die
all_components?.Cut()
//Some components will actually try and interact with this, so let's do it later
QDEL_NULL(soundloop)
Remove_Messenger()
if(istype(pai))
QDEL_NULL(pai)
physical = null
return ..()
@@ -86,6 +112,16 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
return ..()
// shameless copy of newscaster photo saving
/obj/item/modular_computer/proc/save_photo(icon/photo)
var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
//Clean up repeated frames
var/icon/clean = new /icon()
clean.Insert(photo, "", SOUTH, 1, 0)
fcopy(clean, "[GLOB.log_directory]/photos/[photo_file].png")
return photo_file
/**
* Plays a ping sound.
@@ -103,7 +139,10 @@
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]
return (card_slot2?.try_eject(user) || card_slot?.try_eject(user)) //Try the secondary one first.
if(card_slot2?.try_eject(user) || card_slot?.try_eject(user))
return TRUE
if(!istype(src, /obj/item/modular_computer/tablet))
return FALSE
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
/obj/item/modular_computer/GetAccess()
@@ -169,6 +208,8 @@
if(human_wearer.wear_id == src)
human_wearer.sec_hud_set_ID()
update_slot_icon()
update_appearance()
return removed_id
return ..()
@@ -176,10 +217,11 @@
/obj/item/modular_computer/InsertID(obj/item/inserting_item)
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
if(!(card_slot || card_slot2))
return FALSE
var/obj/item/card/inserting_id = inserting_item.RemoveID()
var/obj/item/card/inserting_id = inserting_item.GetID()
if(!inserting_id)
return FALSE
@@ -188,8 +230,8 @@
var/mob/living/carbon/human/human_wearer = loc
if(human_wearer.wear_id == src)
human_wearer.sec_hud_set_ID()
update_appearance()
update_slot_icon()
return TRUE
return FALSE
@@ -241,19 +283,24 @@
. += get_modular_computer_parts_examine(user)
/obj/item/modular_computer/update_icon_state()
icon_state = enabled ? icon_state_powered : icon_state_unpowered
if(!bypass_state)
icon_state = enabled ? icon_state_powered : icon_state_unpowered
return ..()
/obj/item/modular_computer/update_overlays()
. = ..()
var/init_icon = initial(icon)
if(!init_icon)
return
if(!display_overlays)
return
if(enabled)
. += active_program?.program_icon_state || icon_state_menu
. += active_program ? mutable_appearance(init_icon, active_program.program_icon_state) : mutable_appearance(init_icon, icon_state_menu)
if(atom_integrity <= integrity_failure * max_integrity)
. += "bsod"
. += "broken"
. += mutable_appearance(init_icon, "bsod")
. += mutable_appearance(init_icon, "broken")
// On-click handling. Turns on the computer if it's off and opens the GUI.
@@ -353,6 +400,16 @@
if(istype(holder))
to_chat(holder, "[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))
playsound(src, pick('sound/machines/twobeep_voice1.ogg', 'sound/machines/twobeep_voice2.ogg'), 50, TRUE)
else
playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
visible_message("*[ringtone]*")
/obj/item/modular_computer/proc/send_sound()
playsound(src, 'sound/machines/terminal_success.ogg', 15, TRUE)
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
/obj/item/modular_computer/proc/get_header_data()
var/list/data = list()
@@ -489,6 +546,8 @@
return TRUE
/obj/item/modular_computer/screwdriver_act(mob/user, obj/item/tool)
if(!deconstructable)
return
if(!length(all_components))
balloon_alert(user, "no components installed!")
return
@@ -520,6 +579,25 @@
if(istype(W, /obj/item/card/id) && InsertID(W))
return
// Insert a PAI.
if(istype(W, /obj/item/paicard) && !pai)
if(!user.transferItemToLoc(W, src))
return
pai = W
pai.slotted = TRUE
to_chat(user, span_notice("You slot \the [W] into [src]."))
return
// Scan a photo.
if(istype(W, /obj/item/photo))
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
var/obj/item/photo/pic = W
if(hdd)
for(var/datum/computer_file/program/messenger/messenger in hdd.stored_files)
saved_image = pic.picture
messenger.ProcessPhoto()
return
// Insert items into the components
for(var/h in all_components)
var/obj/item/computer_hardware/H = all_components[h]
@@ -527,7 +605,7 @@
return
// Insert new hardware
if(istype(W, /obj/item/computer_hardware))
if(istype(W, /obj/item/computer_hardware) && upgradable)
if(install_component(W, user))
return
@@ -574,3 +652,9 @@
if(physical && physical != src)
return physical.Adjacent(neighbor)
return ..()
/obj/item/modular_computer/proc/Add_Messenger()
GLOB.TabletMessengers += src
/obj/item/modular_computer/proc/Remove_Messenger()
GLOB.TabletMessengers -= src
@@ -4,6 +4,8 @@
// Operates TGUI
/obj/item/modular_computer/ui_interact(mob/user, datum/tgui/ui)
if(issilicon(user)) // silicons have some issues regarding real_name
saved_identification = user.real_name
if(!enabled)
if(ui)
ui.close()
@@ -37,6 +39,10 @@
to_chat(user, span_danger("\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning."))
return // No HDD, No HDD files list or no stored files. Something is very broken.
if(honkamnt > 0) // EXTRA annoying, huh!
honkamnt--
playsound(src, 'sound/items/bikehorn.ogg', 30, TRUE)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "NtosMain")
@@ -44,28 +50,55 @@
if(ui.open())
ui.send_asset(get_asset_datum(/datum/asset/simple/headers))
/obj/item/modular_computer/ui_static_data(mob/user)
. = ..()
var/list/data = list()
data["show_imprint"] = istype(src, /obj/item/modular_computer/tablet/)
return data
/obj/item/modular_computer/ui_data(mob/user)
var/list/data = get_header_data()
data["device_theme"] = device_theme
data["login"] = list()
data["disk"] = null
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB]
data["cardholder"] = FALSE
if(cardholder)
data["cardholder"] = TRUE
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,
)
var/stored_name = saved_identification
var/stored_title = saved_job
if(!stored_name)
stored_name = "Unknown"
if(!stored_title)
stored_title = "Unknown"
data["login"] = list(
IDName = saved_identification,
IDJob = saved_job,
)
data["proposed_login"] = list(
IDName = cardholder.current_identification,
IDJob = cardholder.current_job,
)
if(ssd)
data["disk"] = ssd
data["disk_name"] = ssd.name
for(var/datum/computer_file/program/prog in ssd.stored_files)
var/running = FALSE
if(prog in idle_threads)
running = TRUE
data["disk_programs"] += list(list("name" = prog.filename, "desc" = prog.filedesc, "running" = running, "icon" = prog.program_icon, "alert" = prog.alert_pending))
data["removable_media"] = list()
if(all_components[MC_SDD])
@@ -89,6 +122,7 @@
data["has_light"] = has_light
data["light_on"] = light_on
data["comp_light_color"] = comp_light_color
data["pai"] = pai
return data
@@ -134,10 +168,15 @@
if("PC_runprogram")
var/prog = params["name"]
var/is_disk = params["is_disk"]
var/datum/computer_file/program/P = null
var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB]
var/mob/user = usr
if(hard_drive)
if(hard_drive && !is_disk)
P = hard_drive.find_file_by_name(prog)
if(ssd && is_disk)
P = ssd.find_file_by_name(prog)
if(!P || !istype(P)) // Program not found or it's not executable program.
to_chat(user, span_danger("\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning."))
@@ -198,6 +237,13 @@
if(uninstall_component(portable_drive, usr))
user.put_in_hands(portable_drive)
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("job disk")
var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB]
if(!ssd)
return
if(uninstall_component(ssd, usr))
user.put_in_hands(ssd)
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("intelliCard")
var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI]
if(!intelliholder)
@@ -208,14 +254,37 @@
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
if(!cardholder)
return
cardholder.try_eject(user)
if(cardholder.try_eject(user))
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("secondary RFID card")
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD2]
if(!cardholder)
return
cardholder.try_eject(user)
if(cardholder.try_eject(user))
playsound(src, 'sound/machines/card_slide.ogg', 50)
if("PC_Imprint_ID")
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
var/obj/item/computer_hardware/identifier/id_hardware = all_components[MC_IDENTIFY]
if(!cardholder)
return
saved_identification = cardholder.current_identification
saved_job = cardholder.current_job
if(id_hardware)
id_hardware.UpdateDisplay()
playsound(src, 'sound/machines/terminal_processing.ogg', 15, TRUE)
if("PC_Pai_Interact")
switch(params["option"])
if("eject")
usr.put_in_hands(pai)
pai.slotted = FALSE
pai = null
to_chat(usr, span_notice("You remove the pAI from the [name]."))
if("interact")
pai.attack_self(usr)
return UI_UPDATE
else
return
@@ -0,0 +1,227 @@
/obj/item/modular_computer/tablet/pda/medical
name = "medical PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/medical
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#e2e2e2#000099#5d99be"
/obj/item/modular_computer/tablet/pda/viro
name = "virology PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/medical
greyscale_config = /datum/greyscale_config/tablet/stripe_split
greyscale_colors = "#e2e2e2#355FAC#789876"
/obj/item/modular_computer/tablet/pda/engineering
name = "engineering PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/engineering
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#C5994C#69DBF3#D9D65B"
/obj/item/modular_computer/tablet/pda/security
name = "security PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/security
greyscale_colors = "#cc4242#0000cc"
/obj/item/modular_computer/tablet/pda/detective
name = "detective PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/detective
greyscale_colors = "#90714F#990202"
/obj/item/modular_computer/tablet/pda/warden
name = "warden PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/security
greyscale_config = /datum/greyscale_config/tablet/stripe_split
greyscale_colors = "#cc4242#0000cc#666666"
/obj/item/modular_computer/tablet/pda/janitor
name = "janitor PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/janitor
greyscale_colors = "#933ea8#235AB2"
/obj/item/modular_computer/tablet/pda/science
name = "scientist PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/signal/ordnance
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#e2e2e2#000099#9F5CA5"
/obj/item/modular_computer/tablet/pda/heads
default_disk = /obj/item/computer_hardware/hard_drive/role/head
greyscale_config = /datum/greyscale_config/tablet/head
greyscale_colors = "#789876#a92323"
/obj/item/modular_computer/tablet/pda/heads/hop
name = "head of personnel PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/hop
/obj/item/modular_computer/tablet/pda/heads/hos
name = "head of security PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/hos
greyscale_config = /datum/greyscale_config/tablet/head
greyscale_colors = "#cc4242#0000cc"
/obj/item/modular_computer/tablet/pda/heads/ce
name = "chief engineer PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/ce
greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head
greyscale_colors = "#C4A56D#69DBF3#e2e2e2"
/obj/item/modular_computer/tablet/pda/heads/cmo
name = "chief medical officer PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/cmo
greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head
greyscale_colors = "#e2e2e2#000099#5d99be"
/obj/item/modular_computer/tablet/pda/heads/rd
name = "research director PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/rd
greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head
greyscale_colors = "#e2e2e2#000099#9F5CA5"
insert_type = /obj/item/pen/fountain
/obj/item/modular_computer/tablet/pda/captain
name = "captain PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/captain
greyscale_config = /datum/greyscale_config/tablet/captain
greyscale_colors = "#2C7CB2#FF0000#FFFFFF#F5D67B"
insert_type = /obj/item/pen/fountain
/obj/item/modular_computer/tablet/pda/captain/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_TABLET_CHECK_DETONATE, .proc/tab_no_detonate)
/obj/item/modular_computer/tablet/pda/cargo
name = "cargo technician PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/quartermaster
greyscale_colors = "#D6B328#6506ca"
/obj/item/modular_computer/tablet/pda/quartermaster/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/printer/mini)
/obj/item/modular_computer/tablet/pda/quartermaster
name = "quartermaster PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/quartermaster
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#D6B328#6506ca#927444"
/obj/item/modular_computer/tablet/pda/quartermaster/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/printer/mini)
/obj/item/modular_computer/tablet/pda/shaftminer
name = "shaft miner PDA"
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#927444#D6B328#6C3BA1"
/obj/item/modular_computer/tablet/pda/chaplain
name = "chaplain PDA"
greyscale_config = /datum/greyscale_config/tablet/chaplain
greyscale_colors = "#333333#d11818"
/obj/item/modular_computer/tablet/pda/lawyer
name = "lawyer PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/lawyer
greyscale_colors = "#5B74A5#f7e062"
insert_type = /obj/item/pen/fountain
/obj/item/modular_computer/tablet/pda/botanist
name = "botanist PDA"
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#50E193#E26F41#71A7CA"
/obj/item/modular_computer/tablet/pda/roboticist
name = "roboticist PDA"
greyscale_config = /datum/greyscale_config/tablet/stripe_split
greyscale_colors = "#484848#0099cc#d33725"
default_disk = /obj/item/computer_hardware/hard_drive/role/roboticist
/obj/item/modular_computer/tablet/pda/cook
name = "cook PDA"
greyscale_colors = "#e2e2e2#a92323"
/obj/item/modular_computer/tablet/pda/bar
name = "bartender PDA"
greyscale_colors = "#333333#c7c7c7"
/obj/item/modular_computer/tablet/pda/atmos
name = "atmospherics PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/atmos
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#ceca2b#00E5DA#727272"
/obj/item/modular_computer/tablet/pda/chemist
name = "chemist PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/chemistry
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
greyscale_colors = "#e2e2e2#355FAC#ea6400"
/obj/item/modular_computer/tablet/pda/geneticist
name = "geneticist PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/medical
greyscale_config = /datum/greyscale_config/tablet/stripe_split
greyscale_colors = "#e2e2e2#000099#0097ca"
/obj/item/modular_computer/tablet/pda/clown
name = "clown PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/virus/clown
icon_state = "pda-clown"
greyscale_config = null
greyscale_colors = null
insert_type = /obj/item/toy/crayon/rainbow
/obj/item/modular_computer/tablet/pda/clown/ComponentInitialize()
. = ..()
AddComponent(/datum/component/slippery/clowning, 120, NO_SLIP_WHEN_WALKING, CALLBACK(src, .proc/AfterSlip), slot_whitelist = list(ITEM_SLOT_ID, ITEM_SLOT_BELT))
AddComponent(/datum/component/wearertargeting/sitcomlaughter, CALLBACK(src, .proc/after_sitcom_laugh))
/obj/item/modular_computer/tablet/pda/clown/update_overlays()
. = ..()
. += mutable_appearance(icon, "pda_stripe_clown") // clowns have eyes that go over their screen, so it needs to be compiled last
/obj/item/modular_computer/tablet/pda/clown/proc/AfterSlip(mob/living/carbon/human/M)
if (istype(M) && (M.real_name != saved_identification))
var/obj/item/computer_hardware/hard_drive/role/virus/clown/cart = all_components[MC_HDD_JOB]
if(istype(cart) && cart.charges < 5)
cart.charges++
playsound(src,'sound/machines/ping.ogg',30,TRUE)
/obj/item/modular_computer/tablet/pda/clown/proc/after_sitcom_laugh(mob/victim)
victim.visible_message("[src] lets out a burst of laughter!")
/obj/item/modular_computer/tablet/pda/mime
name = "mime PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/virus/mime
greyscale_config = /datum/greyscale_config/tablet/mime
greyscale_colors = "#e2e2e2#cc4242"
insert_type = /obj/item/toy/crayon/mime
/obj/item/modular_computer/tablet/pda/mime/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
if(hdd)
for(var/datum/computer_file/program/messenger/msg in hdd.stored_files)
msg.mime_mode = TRUE
msg.allow_emojis = TRUE
/obj/item/modular_computer/tablet/pda/curator
name = "curator PDA"
default_disk = /obj/item/computer_hardware/hard_drive/role/curator
greyscale_config = null
greyscale_colors = null
icon_state = "pda-library"
insert_type = /obj/item/pen/fountain
display_overlays = FALSE
/obj/item/modular_computer/tablet/pda/syndicate
name = "military PDA"
greyscale_colors = "#891417#80FF80"
saved_identification = "John Doe"
saved_job = "Citizen"
invisible = TRUE
/obj/item/modular_computer/tablet/pda/clear
name = "clear PDA"
icon_state = "pda-clear"
greyscale_config = null
greyscale_colors = null
@@ -16,16 +16,95 @@
has_light = TRUE //LED flashlight!
comp_light_luminosity = 2.3 //Same as the PDA
looping_sound = FALSE
var/has_variants = TRUE
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
/obj/item/modular_computer/tablet/update_icon_state()
if(has_variants)
if(has_variants && !bypass_state)
if(!finish_color)
finish_color = pick("red", "blue", "brown", "green", "black")
icon_state = icon_state_powered = icon_state_unpowered = "[base_icon_state]-[finish_color]"
return ..()
/obj/item/modular_computer/tablet/interact(mob/user)
. = ..()
if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED))
explode(usr, from_message_menu = TRUE)
return
/obj/item/modular_computer/tablet/attackby(obj/item/W, mob/user)
. = ..()
if(is_type_in_list(W, contained_item))
if(inserted_item)
to_chat(user, span_warning("There is already \a [inserted_item] in \the [src]!"))
else
if(!user.transferItemToLoc(W, src))
return
to_chat(user, span_notice("You insert \the [W] into \the [src]."))
inserted_item = W
playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE)
/obj/item/modular_computer/tablet/AltClick(mob/user)
. = ..()
if(.)
return
remove_pen(user)
/obj/item/modular_computer/tablet/proc/tab_no_detonate()
SIGNAL_HANDLER
return COMPONENT_TABLET_NO_DETONATE
/obj/item/modular_computer/tablet/proc/remove_pen(mob/user)
if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) //TK doesn't work even with this removed but here for readability
return
if(inserted_item)
to_chat(user, span_notice("You remove [inserted_item] from [src]."))
user.put_in_hands(inserted_item)
inserted_item = null
update_appearance()
playsound(src, 'sound/machines/pda_button2.ogg', 50, TRUE)
else
to_chat(user, span_warning("This tablet does not have a pen in it!"))
// Tablet 'splosion..
/obj/item/modular_computer/tablet/proc/explode(mob/target, mob/bomber, from_message_menu = FALSE)
var/turf/T = get_turf(src)
if(from_message_menu)
log_bomber(null, null, target, "'s tablet exploded as [target.p_they()] tried to open their tablet message menu because of a recent tablet bomb.")
else
log_bomber(bomber, "successfully tablet-bombed", target, "as [target.p_they()] tried to reply to a rigged tablet message [bomber && !is_special_character(bomber) ? "(SENT BY NON-ANTAG)" : ""]")
if (ismob(loc))
var/mob/M = loc
M.show_message(span_userdanger("Your [src] explodes!"), MSG_VISUAL, span_warning("You hear a loud *pop*!"), MSG_AUDIBLE)
else
visible_message(span_danger("[src] explodes!"), span_warning("You hear a loud *pop*!"))
target.client?.give_award(/datum/award/achievement/misc/clickbait, target)
if(T)
T.hotspot_expose(700,125)
if(istype(all_components[MC_HDD_JOB], /obj/item/computer_hardware/hard_drive/role/virus/deto))
explosion(src, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flash_range = 4)
else
explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flash_range = 3)
qdel(src)
// SUBTYPES
/obj/item/modular_computer/tablet/syndicate_contract_uplink
name = "contractor tablet"
icon = 'icons/obj/contractor_tablet.dmi'
@@ -65,8 +144,8 @@
has_light = FALSE //tablet light button actually enables/disables the borg lamp
comp_light_luminosity = 0
has_variants = FALSE
///Ref to the borg we're installed in. Set by the borg during our creation.
var/mob/living/silicon/robot/borgo
///Ref to the silicon we're installed in. Set by the borg during our creation.
var/mob/living/silicon/borgo
///Ref to the RoboTact app. Important enough to borgs to deserve a ref.
var/datum/computer_file/program/robotact/robotact
///IC log that borgs can view in their personal management app
@@ -119,22 +198,28 @@
/obj/item/modular_computer/tablet/integrated/ui_data(mob/user)
. = ..()
.["has_light"] = TRUE
.["light_on"] = borgo?.lamp_enabled
.["comp_light_color"] = borgo?.lamp_color
if(istype(borgo, /mob/living/silicon/robot))
var/mob/living/silicon/robot/robo = borgo
.["light_on"] = robo.lamp_enabled
.["comp_light_color"] = robo.lamp_color
//Makes the flashlight button affect the borg rather than the tablet
/obj/item/modular_computer/tablet/integrated/toggle_flashlight()
if(!borgo || QDELETED(borgo))
return FALSE
borgo.toggle_headlamp()
if(istype(borgo, /mob/living/silicon/robot))
var/mob/living/silicon/robot/robo = borgo
robo.toggle_headlamp()
return TRUE
//Makes the flashlight color setting affect the borg rather than the tablet
/obj/item/modular_computer/tablet/integrated/set_flashlight_color(color)
if(!borgo || QDELETED(borgo) || !color)
return FALSE
borgo.lamp_color = color
borgo.toggle_headlamp(FALSE, TRUE)
if(istype(borgo, /mob/living/silicon/robot))
var/mob/living/silicon/robot/robo = borgo
robo.lamp_color = color
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')
@@ -143,6 +228,8 @@
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
/obj/item/modular_computer/tablet/integrated/syndicate
icon_state = "tablet-silicon-syndicate"
@@ -153,4 +240,51 @@
/obj/item/modular_computer/tablet/integrated/syndicate/Initialize(mapload)
. = ..()
borgo.lamp_color = COLOR_RED //Syndicate likes it red
if(istype(borgo, /mob/living/silicon/robot))
var/mob/living/silicon/robot/robo = borgo
robo.lamp_color = COLOR_RED //Syndicate likes it red
// Round start tablets
/obj/item/modular_computer/tablet/pda
icon_state = "pda"
greyscale_config = /datum/greyscale_config/tablet
greyscale_colors = "#999875#a92323"
bypass_state = TRUE
var/default_disk = 0
/obj/item/modular_computer/tablet/pda/update_overlays()
. = ..()
var/init_icon = initial(icon)
var/obj/item/computer_hardware/card_slot/card = all_components[MC_CARD]
if(!init_icon)
return
if(card)
if(card.stored_card)
. += mutable_appearance(init_icon, "id_overlay")
if(light_on)
. += mutable_appearance(init_icon, "light_overlay")
/obj/item/modular_computer/tablet/pda/attack_ai(mob/user)
to_chat(user, span_notice("It doesn't feel right to snoop around like that..."))
return // we don't want ais or cyborgs using a private role tablet
/obj/item/modular_computer/tablet/pda/Initialize(mapload)
. = ..()
install_component(new /obj/item/computer_hardware/hard_drive/small)
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
install_component(new /obj/item/computer_hardware/network_card)
install_component(new /obj/item/computer_hardware/card_slot)
install_component(new /obj/item/computer_hardware/identifier)
install_component(new /obj/item/computer_hardware/sensorpackage)
if(default_disk)
var/obj/item/computer_hardware/hard_drive/portable/disk = new default_disk(src)
install_component(disk)
if(insert_type)
inserted_item = new insert_type(src)
@@ -106,9 +106,6 @@
//Borg Built-in tablet
/obj/item/modular_computer/tablet/integrated/Initialize(mapload)
. = ..()
var/obj/item/computer_hardware/hard_drive/small/integrated/hard_drive = new // SKYRAT EDIT ADD
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(hard_drive) // SKYRAT EDIT -- ORIGINAL install_component(new /obj/item/computer_hardware/hard_drive/small/integrated/)
install_component(new /obj/item/computer_hardware/recharger/cyborg)
install_component(new /obj/item/computer_hardware/network_card/integrated)
hard_drive.store_file(new /datum/computer_file/program/crew_manifest) // SKYRAT EDIT ADD