mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +01:00
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:
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
filedesc = "Newscaster"
|
||||
required_access = list(ACCESS_LIBRARY)
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "computer"
|
||||
program_icon_state = "bountyboard"
|
||||
extended_desc = "This program allows any user to access the Newscaster network from anywhere."
|
||||
size = 2
|
||||
requires_ntnet = TRUE
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/computer_file/program/notepad
|
||||
filename = "notepad"
|
||||
filedesc = "Notepad"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "Jot down your work-safe thoughts and what not."
|
||||
size = 2
|
||||
tgui_id = "NtosNotepad"
|
||||
program_icon = "book"
|
||||
usage_flags = PROGRAM_TABLET
|
||||
|
||||
/datum/computer_file/program/notepad/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("UpdateNote")
|
||||
var/obj/item/modular_computer/tablet/comp = computer
|
||||
comp.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
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,366 @@
|
||||
/datum/computer_file/program/messenger
|
||||
filename = "nt_messenger"
|
||||
filedesc = "Direct Messenger"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "command"
|
||||
extended_desc = "This program allows old-school communication with other modular devices."
|
||||
size = 8
|
||||
usage_flags = PROGRAM_TABLET
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "NtosMessenger"
|
||||
program_icon = "comment-alt"
|
||||
alert_able = TRUE
|
||||
|
||||
/// The current ringtone (displayed in the chat when a message is received).
|
||||
var/ringtone = "beep"
|
||||
/// Whether or not the ringtone is currently on.
|
||||
var/ringer_status = TRUE
|
||||
/// Whether or not we're sending and receiving messages.
|
||||
var/sending_and_receiving = TRUE
|
||||
/// The messages currently saved in the app.
|
||||
var/messages = list()
|
||||
/// great wisdom from PDA.dm - "no spamming" (prevents people from spamming the same message over and over)
|
||||
var/last_text
|
||||
/// even more wisdom from PDA.dm - "no everyone spamming" (prevents people from spamming the same message over and over)
|
||||
var/last_text_everyone
|
||||
/// Scanned photo for sending purposes.
|
||||
var/datum/picture/picture
|
||||
/// Whether or not we allow emojis to be sent by the user.
|
||||
var/allow_emojis = FALSE
|
||||
/// Whether or not we're currently looking at the message list.
|
||||
var/viewing_messages = FALSE
|
||||
// Whether or not this device is currently hidden from the message monitor.
|
||||
var/monitor_hidden = FALSE
|
||||
// Whether or not we're sorting by job.
|
||||
var/sort_by_job = TRUE
|
||||
// Whether or not we're sending (or trying to send) a virus.
|
||||
var/sending_virus = FALSE
|
||||
|
||||
/// The path for the current loaded image in rsc
|
||||
var/photo_path
|
||||
|
||||
/// Whether or not this app is loaded on a silicon's tablet.
|
||||
var/is_silicon = FALSE
|
||||
/// Whether or not we're in a mime PDA.
|
||||
var/mime_mode = FALSE
|
||||
|
||||
/datum/computer_file/program/messenger/proc/ScrubMessengerList()
|
||||
var/list/dictionary = list()
|
||||
|
||||
for(var/obj/item/modular_computer/messenger in GetViewableDevices(sort_by_job))
|
||||
if(messenger.saved_identification && messenger.saved_job && !(messenger == computer))
|
||||
var/list/data = list()
|
||||
data["name"] = messenger.saved_identification
|
||||
data["job"] = messenger.saved_job
|
||||
data["ref"] = REF(messenger)
|
||||
|
||||
//if(data["ref"] != REF(computer)) // you cannot message yourself (despite all my rage)
|
||||
dictionary += list(data)
|
||||
|
||||
return dictionary
|
||||
|
||||
/proc/GetViewableDevices(sort_by_job = FALSE)
|
||||
var/list/dictionary = list()
|
||||
|
||||
var/sortmode
|
||||
if(sort_by_job)
|
||||
sortmode = /proc/cmp_pdajob_asc
|
||||
else
|
||||
sortmode = /proc/cmp_pdaname_asc
|
||||
|
||||
for(var/obj/item/modular_computer/P in sort_list(GLOB.TabletMessengers, sortmode))
|
||||
var/obj/item/computer_hardware/hard_drive/drive = P.all_components[MC_HDD]
|
||||
if(!drive)
|
||||
continue
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
if(!P.saved_identification || !P.saved_job || P.invisible || app.monitor_hidden)
|
||||
continue
|
||||
dictionary += P
|
||||
|
||||
return dictionary
|
||||
|
||||
/datum/computer_file/program/messenger/proc/StringifyMessengerTarget(obj/item/modular_computer/messenger)
|
||||
return "[messenger.saved_identification] ([messenger.saved_job])"
|
||||
|
||||
/datum/computer_file/program/messenger/proc/ProcessPhoto()
|
||||
if(computer.saved_image)
|
||||
var/icon/img = computer.saved_image.picture_image
|
||||
var/deter_path = "tmp_msg_photo[rand(0, 99999)].png"
|
||||
usr << browse_rsc(img, deter_path) // funny random assignment for now, i'll make an actual key later
|
||||
photo_path = deter_path
|
||||
|
||||
/datum/computer_file/program/messenger/ui_state(mob/user)
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return GLOB.reverse_contained_state
|
||||
return GLOB.default_state
|
||||
|
||||
/datum/computer_file/program/messenger/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("PDA_ringSet")
|
||||
var/t = tgui_input_text(usr, "Enter a new ringtone", "Ringtone", "", 20)
|
||||
var/mob/living/usr_mob = usr
|
||||
if(in_range(computer, usr_mob) && computer.loc == usr_mob && t)
|
||||
if(SEND_SIGNAL(computer, COMSIG_TABLET_CHANGE_ID, usr_mob, t) & COMPONENT_STOP_RINGTONE_CHANGE)
|
||||
return
|
||||
else
|
||||
ringtone = t
|
||||
return(UI_UPDATE)
|
||||
if("PDA_ringer_status")
|
||||
ringer_status = !ringer_status
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sAndR")
|
||||
sending_and_receiving = !sending_and_receiving
|
||||
return(UI_UPDATE)
|
||||
if("PDA_viewMessages")
|
||||
viewing_messages = !viewing_messages
|
||||
return(UI_UPDATE)
|
||||
if("PDA_clearMessages")
|
||||
messages = list()
|
||||
return(UI_UPDATE)
|
||||
if("PDA_changeSortStyle")
|
||||
sort_by_job = !sort_by_job
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sendEveryone")
|
||||
if(!sending_and_receiving)
|
||||
to_chat(usr, span_notice("ERROR: Device has sending disabled."))
|
||||
return
|
||||
|
||||
var/list/targets = list()
|
||||
|
||||
for(var/obj/item/modular_computer/mc in GetViewableDevices())
|
||||
targets += mc
|
||||
|
||||
if(targets.len > 0)
|
||||
send_message(usr, targets, TRUE)
|
||||
|
||||
return(UI_UPDATE)
|
||||
if("PDA_sendMessage")
|
||||
if(!sending_and_receiving)
|
||||
to_chat(usr, span_notice("ERROR: Device has sending disabled."))
|
||||
return
|
||||
var/obj/item/modular_computer/target = locate(params["ref"])
|
||||
if(!target)
|
||||
return // we don't want tommy sending his messages to nullspace
|
||||
if(!(target.saved_identification == params["name"] && target.saved_job == params["job"]))
|
||||
to_chat(usr, span_notice("ERROR: User no longer exists."))
|
||||
return
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/drive = target.all_components[MC_HDD]
|
||||
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
if(!app.sending_and_receiving && !sending_virus)
|
||||
to_chat(usr, span_notice("ERROR: Device has receiving disabled."))
|
||||
return
|
||||
if(sending_virus)
|
||||
var/obj/item/computer_hardware/hard_drive/role/virus/disk = computer.all_components[MC_HDD_JOB]
|
||||
if(istype(disk))
|
||||
disk.send_virus(target, usr)
|
||||
return(UI_UPDATE)
|
||||
send_message(usr, list(target))
|
||||
return(UI_UPDATE)
|
||||
if("PDA_clearPhoto")
|
||||
computer.saved_image = null
|
||||
photo_path = null
|
||||
return(UI_UPDATE)
|
||||
if("PDA_toggleVirus")
|
||||
sending_virus = !sending_virus
|
||||
return(UI_UPDATE)
|
||||
|
||||
|
||||
/datum/computer_file/program/messenger/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/role/disk = computer.all_components[MC_HDD_JOB]
|
||||
|
||||
data["owner"] = computer.saved_identification
|
||||
data["messages"] = messages
|
||||
data["ringer_status"] = ringer_status
|
||||
data["sending_and_receiving"] = sending_and_receiving
|
||||
data["messengers"] = ScrubMessengerList()
|
||||
data["viewing_messages"] = viewing_messages
|
||||
data["sortByJob"] = sort_by_job
|
||||
data["isSilicon"] = is_silicon
|
||||
data["photo"] = photo_path
|
||||
|
||||
if(disk)
|
||||
data["canSpam"] = disk.CanSpam()
|
||||
data["virus_attach"] = istype(disk, /obj/item/computer_hardware/hard_drive/role/virus)
|
||||
data["sending_virus"] = sending_virus
|
||||
|
||||
return data
|
||||
|
||||
////////////////////////
|
||||
// MESSAGE HANDLING
|
||||
////////////////////////
|
||||
|
||||
// How I Learned To Stop Being A PDA Bloat Chump And Learn To Embrace The Lightweight
|
||||
|
||||
// Gets the input for a message being sent.
|
||||
|
||||
/datum/computer_file/program/messenger/proc/msg_input(mob/living/U = usr, rigged = FALSE)
|
||||
var/t = null
|
||||
|
||||
if(mime_mode)
|
||||
t = emoji_sanitize(tgui_input_text(U, "Enter emojis", "NT Messaging"))
|
||||
else
|
||||
t = tgui_input_text(U, "Enter a message", "NT Messaging")
|
||||
|
||||
if (!t || !sending_and_receiving)
|
||||
return
|
||||
if(!U.canUseTopic(computer, BE_CLOSE))
|
||||
return
|
||||
return sanitize(t)
|
||||
|
||||
/datum/computer_file/program/messenger/proc/send_message(mob/living/user, list/obj/item/modular_computer/targets, everyone = FALSE, rigged = FALSE, fake_name = null, fake_job = null)
|
||||
var/message = msg_input(user, rigged)
|
||||
if(!message || !targets.len)
|
||||
return FALSE
|
||||
if((last_text && world.time < last_text + 10) || (everyone && last_text_everyone && world.time < last_text_everyone + 2 MINUTES))
|
||||
return FALSE
|
||||
|
||||
var/turf/position = get_turf(computer)
|
||||
for(var/obj/item/jammer/jammer as anything in GLOB.active_jammers)
|
||||
var/turf/jammer_turf = get_turf(jammer)
|
||||
if(position?.z == jammer_turf.z && (get_dist(position, jammer_turf) <= jammer.range))
|
||||
return FALSE
|
||||
|
||||
var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered_for_pdas(message)
|
||||
if (filter_result)
|
||||
REPORT_CHAT_FILTER_TO_USER(user, filter_result)
|
||||
return FALSE
|
||||
|
||||
var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered_for_pdas(message)
|
||||
if (soft_filter_result)
|
||||
if(tgui_alert(usr,"Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to send it?", "Soft Blocked Word", list("Yes", "No")) != "Yes")
|
||||
return FALSE
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[html_encode(message)]\"")
|
||||
log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[message]\"")
|
||||
|
||||
// Send the signal
|
||||
var/list/string_targets = list()
|
||||
for (var/obj/item/modular_computer/comp in targets)
|
||||
if (comp.saved_identification && comp.saved_job) // != src is checked by the UI
|
||||
string_targets += STRINGIFY_PDA_TARGET(comp.saved_identification, comp.saved_job)
|
||||
|
||||
if (!string_targets.len)
|
||||
return FALSE
|
||||
|
||||
var/datum/signal/subspace/messaging/tablet_msg/signal = new(computer, list(
|
||||
"name" = fake_name || computer.saved_identification,
|
||||
"job" = fake_job || computer.saved_job,
|
||||
"message" = html_decode(message),
|
||||
"ref" = REF(computer),
|
||||
"targets" = targets,
|
||||
"emojis" = allow_emojis,
|
||||
"rigged" = rigged,
|
||||
"photo" = photo_path,
|
||||
"automated" = FALSE,
|
||||
))
|
||||
if(rigged) //Will skip the message server and go straight to the hub so it can't be cheesed by disabling the message server machine
|
||||
signal.data["rigged_user"] = REF(user) // Used for bomb logging
|
||||
signal.server_type = /obj/machinery/telecomms/hub
|
||||
signal.data["reject"] = FALSE // Do not refuse the message
|
||||
|
||||
signal.send_to_receivers()
|
||||
|
||||
// If it didn't reach, note that fact
|
||||
if (!signal.data["done"])
|
||||
to_chat(user, span_notice("ERROR: Server isn't responding."))
|
||||
//if(!silent)
|
||||
//playsound(src, 'sound/machines/terminal_error.ogg', 15, TRUE)
|
||||
return FALSE
|
||||
|
||||
if(allow_emojis)
|
||||
message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat
|
||||
signal.data["message"] = emoji_parse(signal.data["message"])
|
||||
|
||||
// Log it in our logs
|
||||
var/list/message_data = list()
|
||||
message_data["name"] = signal.data["name"]
|
||||
message_data["job"] = signal.data["job"]
|
||||
message_data["contents"] = html_decode(signal.data["message"])
|
||||
message_data["outgoing"] = TRUE
|
||||
message_data["ref"] = signal.data["ref"]
|
||||
message_data["photo"] = signal.data["photo"]
|
||||
|
||||
// Show it to ghosts
|
||||
var/ghost_message = span_name("[message_data["name"]] </span><span class='game say'>[rigged ? "Rigged" : ""] PDA Message</span> --> [span_name("[signal.format_target()]")]: <span class='message'>[signal.data["message"]]")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(isobserver(M) && (M.client?.prefs.chat_toggles & CHAT_GHOSTPDA))
|
||||
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
|
||||
|
||||
// Log in the talk log
|
||||
user.log_talk(message, LOG_PDA, tag="[rigged ? "Rigged" : ""] PDA: [initial(message_data["name"])] to [signal.format_target()]")
|
||||
if(rigged)
|
||||
log_bomber(user, "sent a rigged PDA message (Name: [message_data["name"]]. Job: [message_data["job"]]) to [english_list(string_targets)] [!is_special_character(user) ? "(SENT BY NON-ANTAG)" : ""]")
|
||||
to_chat(user, span_info("PDA message sent to [signal.format_target()]: [signal.data["message"]]"))
|
||||
|
||||
if (ringer_status)
|
||||
computer.send_sound()
|
||||
|
||||
last_text = world.time
|
||||
if (everyone)
|
||||
message_data["name"] = "Everyone"
|
||||
message_data["job"] = ""
|
||||
last_text_everyone = world.time
|
||||
|
||||
messages += list(message_data)
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/messenger/proc/receive_message(datum/signal/subspace/messaging/tablet_msg/signal)
|
||||
var/list/message_data = list()
|
||||
message_data["name"] = signal.data["name"]
|
||||
message_data["job"] = signal.data["job"]
|
||||
message_data["contents"] = html_decode(signal.data["message"])
|
||||
message_data["outgoing"] = FALSE
|
||||
message_data["ref"] = signal.data["ref"]
|
||||
message_data["automated"] = signal.data["automated"]
|
||||
message_data["photo"] = signal.data["photo"]
|
||||
messages += list(message_data)
|
||||
|
||||
var/mob/living/L = null
|
||||
if(computer.loc && isliving(computer.loc))
|
||||
L = computer.loc
|
||||
//Maybe they are a pAI!
|
||||
else
|
||||
L = get(computer, /mob/living/silicon)
|
||||
|
||||
if(L && (L.stat == CONSCIOUS || L.stat == SOFT_CRIT))
|
||||
var/reply = "(<a href='byond://?src=[REF(src)];choice=[signal.data["rigged"] ? "Mess_us_up" : "Message"];skiprefresh=1;target=[signal.data["ref"]]'>Reply</a>)"
|
||||
var/hrefstart
|
||||
var/hrefend
|
||||
if (isAI(L))
|
||||
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
|
||||
hrefend = "</a>"
|
||||
|
||||
if(signal.data["automated"])
|
||||
reply = "\[Automated Message\]"
|
||||
|
||||
var/inbound_message = signal.format_message()
|
||||
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
|
||||
inbound_message = emoji_parse(inbound_message)
|
||||
|
||||
if(ringer_status)
|
||||
to_chat(L, "<span class='infoplain'>[icon2html(src)] <b>PDA message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[inbound_message] [reply]</span>")
|
||||
|
||||
|
||||
if (ringer_status)
|
||||
computer.ring(ringtone)
|
||||
|
||||
/datum/computer_file/program/messenger/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if(!href_list["close"] && usr.canUseTopic(computer, BE_CLOSE, FALSE, NO_TK))
|
||||
switch(href_list["choice"])
|
||||
if("Message")
|
||||
send_message(usr, list(locate(href_list["target"])))
|
||||
if("Mess_us_up")
|
||||
if(!HAS_TRAIT(src, TRAIT_PDA_CAN_EXPLODE))
|
||||
var/obj/item/modular_computer/tablet/comp = computer
|
||||
comp.explode(usr, from_message_menu = TRUE)
|
||||
return
|
||||
@@ -0,0 +1,78 @@
|
||||
/datum/computer_file/program/phys_scanner
|
||||
filename = "phys_scanner"
|
||||
filedesc = "Physical Scanner"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
extended_desc = "This program allows the tablet to scan physical objects and display a data output."
|
||||
size = 8
|
||||
usage_flags = PROGRAM_TABLET
|
||||
available_on_ntnet = FALSE
|
||||
tgui_id = "NtosPhysScanner"
|
||||
program_icon = "barcode"
|
||||
|
||||
var/current_mode = 0
|
||||
var/available_modes = 0
|
||||
|
||||
var/last_record = ""
|
||||
|
||||
/datum/computer_file/program/phys_scanner/proc/ReadModes()
|
||||
var/reads = list()
|
||||
|
||||
if(available_modes & DISK_CHEM)
|
||||
reads += "Reagent"
|
||||
|
||||
if(available_modes & DISK_MED)
|
||||
reads += "Health"
|
||||
|
||||
return reads
|
||||
|
||||
/datum/computer_file/program/phys_scanner/proc/ReadCurrent()
|
||||
if(current_mode & DISK_CHEM)
|
||||
return "Reagent"
|
||||
if(current_mode & DISK_MED)
|
||||
return "Health"
|
||||
|
||||
/datum/computer_file/program/phys_scanner/tap(atom/A, mob/living/user, params)
|
||||
. = ..()
|
||||
|
||||
switch(current_mode)
|
||||
if(DISK_CHEM)
|
||||
if(!isnull(A.reagents))
|
||||
if(A.reagents.reagent_list.len > 0)
|
||||
var/reagents_length = A.reagents.reagent_list.len
|
||||
last_record = "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found."
|
||||
for (var/re in A.reagents.reagent_list)
|
||||
last_record += "\t [re]"
|
||||
else
|
||||
last_record = "No active chemical agents found in [A]."
|
||||
else
|
||||
last_record = "No significant chemical agents found in [A]."
|
||||
if(DISK_MED)
|
||||
var/mob/living/carbon/carbon = A
|
||||
if(istype(carbon))
|
||||
carbon.visible_message(span_notice("[user] analyzes [A]'s vitals."))
|
||||
last_record = healthscan(user, carbon, 1, tochat = FALSE)
|
||||
|
||||
/datum/computer_file/program/phys_scanner/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("selectMode")
|
||||
switch(params["newMode"])
|
||||
if("Reagent")
|
||||
current_mode = DISK_CHEM
|
||||
if("Health")
|
||||
current_mode = DISK_MED
|
||||
|
||||
return UI_UPDATE
|
||||
|
||||
|
||||
/datum/computer_file/program/phys_scanner/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["set_mode"] = ReadCurrent()
|
||||
data["last_record"] = last_record
|
||||
data["available_modes"] = ReadModes()
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,74 @@
|
||||
/datum/computer_file/program/records
|
||||
filename = "ntrecords"
|
||||
filedesc = "Records"
|
||||
extended_desc = "Allows the user to view several basic records from the crew."
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon = "clipboard"
|
||||
program_icon_state = "crew"
|
||||
tgui_id = "NtosRecords"
|
||||
size = 4
|
||||
usage_flags = PROGRAM_TABLET | PROGRAM_LAPTOP
|
||||
available_on_ntnet = FALSE
|
||||
|
||||
var/mode
|
||||
|
||||
/datum/computer_file/program/records/medical
|
||||
filedesc = "Medical Records"
|
||||
filename = "medrecords"
|
||||
program_icon = "book-medical"
|
||||
extended_desc = "Allows the user to view several basic medical records from the crew."
|
||||
transfer_access = list(ACCESS_MEDICAL, ACCESS_FLAG_COMMAND)
|
||||
available_on_ntnet = TRUE
|
||||
mode = "medical"
|
||||
|
||||
/datum/computer_file/program/records/security
|
||||
filedesc = "Security Records"
|
||||
filename = "secrecords"
|
||||
extended_desc = "Allows the user to view several basic security records from the crew."
|
||||
transfer_access = list(ACCESS_SECURITY, ACCESS_FLAG_COMMAND)
|
||||
available_on_ntnet = TRUE
|
||||
mode = "security"
|
||||
|
||||
/datum/computer_file/program/records/proc/GetRecordsReadable()
|
||||
var/list/all_records = list()
|
||||
|
||||
switch(mode)
|
||||
if("security")
|
||||
for(var/datum/data/record/person in GLOB.data_core.general)
|
||||
var/datum/data/record/security_person = find_record("id", person.fields["id"], GLOB.data_core.security)
|
||||
var/list/current_record = list()
|
||||
|
||||
if(security_person)
|
||||
current_record["wanted"] = security_person.fields["criminal"]
|
||||
|
||||
current_record["id"] = person.fields["id"]
|
||||
current_record["name"] = person.fields["name"]
|
||||
current_record["rank"] = person.fields["rank"]
|
||||
current_record["gender"] = person.fields["gender"]
|
||||
current_record["age"] = person.fields["age"]
|
||||
current_record["species"] = person.fields["species"]
|
||||
current_record["fingerprint"] = person.fields["fingerprint"]
|
||||
|
||||
all_records += list(current_record)
|
||||
if("medical")
|
||||
for(var/datum/data/record/person in GLOB.data_core.medical)
|
||||
var/list/current_record = list()
|
||||
|
||||
current_record["name"] = person.fields["name"]
|
||||
current_record["bloodtype"] = person.fields["blood_type"]
|
||||
current_record["mi_dis"] = person.fields["mi_dis"]
|
||||
current_record["ma_dis"] = person.fields["ma_dis"]
|
||||
current_record["notes"] = person.fields["notes"]
|
||||
current_record["cnotes"] = person.fields["notes_d"]
|
||||
|
||||
all_records += list(current_record)
|
||||
|
||||
return all_records
|
||||
|
||||
|
||||
|
||||
/datum/computer_file/program/records/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
data["records"] = GetRecordsReadable()
|
||||
data["mode"] = mode
|
||||
return data
|
||||
@@ -13,6 +13,8 @@
|
||||
var/botcount = 0
|
||||
///Access granted by the used to summon robots.
|
||||
var/list/current_access = list()
|
||||
///Whether or not this is the cartridge program version.
|
||||
var/cart_mode = FALSE
|
||||
var/list/drone_ping_types = list(
|
||||
"Low",
|
||||
"Medium",
|
||||
@@ -27,20 +29,23 @@
|
||||
var/list/botlist = list()
|
||||
var/list/mulelist = list()
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/role/job_disk = computer ? computer.all_components[MC_HDD_JOB] : null
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = computer ? computer.all_components[MC_CARD] : null
|
||||
var/obj/item/card/id/id_card = card_slot?.stored_card
|
||||
data["have_id_slot"] = !!card_slot
|
||||
if(computer)
|
||||
data["has_id"] = !!id_card
|
||||
data["id_owner"] = id_card ? id_card.registered_name : "No Card Inserted."
|
||||
data["access_on_card"] = id_card ? id_card.access : null
|
||||
var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : ""
|
||||
data["id_owner"] = id_card
|
||||
if(cart_mode && job_disk)
|
||||
data["id_owner"] = "JOB DISK OVERRIDE"
|
||||
|
||||
botcount = 0
|
||||
|
||||
for(var/mob/living/simple_animal/bot/simple_bot as anything in GLOB.bots_list)
|
||||
if(simple_bot.z != zlevel || !(simple_bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Only non-emagged bots on the same Z-level are detected!
|
||||
continue
|
||||
if(computer && !simple_bot.check_access(user, id_card)) // Only check Bots we can access
|
||||
if(computer && !simple_bot.check_access(user) && !cart_mode) // Only check Bots we can access)
|
||||
continue
|
||||
if(!(simple_bot.bot_type in job_disk.bot_access) && cart_mode)
|
||||
continue
|
||||
var/list/newbot = list(
|
||||
"name" = simple_bot.name,
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros.
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(!(computer?.get_modular_computer_part(MC_SIGNALER) || istype(disk))) //Giving a clue to users why the program is spitting out zeros.
|
||||
to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\"."))
|
||||
|
||||
|
||||
/datum/computer_file/program/signaler/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(sensor?.check_functionality())
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(sensor?.check_functionality() || istype(disk))
|
||||
data["frequency"] = signal_frequency
|
||||
data["code"] = signal_code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
@@ -38,7 +40,8 @@
|
||||
if(.)
|
||||
return
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(!(sensor?.check_functionality()))
|
||||
var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB)
|
||||
if(!(sensor?.check_functionality() || istype(disk)))
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE)
|
||||
return
|
||||
switch(action)
|
||||
@@ -65,18 +68,19 @@
|
||||
return
|
||||
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/T = get_turf(computer)
|
||||
|
||||
var/logging_data
|
||||
if(usr)
|
||||
logging_data = "[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(signal_frequency)]/[signal_code]"
|
||||
message_admins("usr is true")
|
||||
logging_data = "[time] <B>:</B> [usr.key] used [computer] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(signal_frequency)]/[signal_code]"
|
||||
GLOB.lastsignalers.Add(logging_data)
|
||||
|
||||
var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data)
|
||||
radio_connection.post_signal(src, signal)
|
||||
radio_connection.post_signal(computer, signal)
|
||||
|
||||
/datum/computer_file/program/signaler/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, signal_frequency)
|
||||
SSradio.remove_object(computer, signal_frequency)
|
||||
signal_frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, signal_frequency, RADIO_SIGNALER)
|
||||
radio_connection = SSradio.add_object(computer, signal_frequency, RADIO_SIGNALER)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/datum/computer_file/program/status
|
||||
filename = "statusdisplay"
|
||||
filedesc = "Status Display"
|
||||
program_icon = "signal"
|
||||
program_icon_state = "generic"
|
||||
requires_ntnet = TRUE
|
||||
size = 4
|
||||
|
||||
extended_desc = "An app used to change the message on the station status displays."
|
||||
tgui_id = "NtosStatus"
|
||||
|
||||
usage_flags = PROGRAM_ALL
|
||||
available_on_ntnet = FALSE
|
||||
|
||||
var/upper_text
|
||||
var/lower_text
|
||||
|
||||
/datum/computer_file/program/status/proc/SendSignal()
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/status_signal = new(list("command" = "message"))
|
||||
|
||||
status_signal.data["msg1"] = reject_bad_text(upper_text || "", MAX_STATUS_LINE_LENGTH)
|
||||
status_signal.data["msg2"] = reject_bad_text(lower_text || "", MAX_STATUS_LINE_LENGTH)
|
||||
|
||||
frequency.post_signal(computer, status_signal)
|
||||
|
||||
/datum/computer_file/program/status/proc/SetText(position, text)
|
||||
switch(position)
|
||||
if("upper")
|
||||
upper_text = text
|
||||
if("lower")
|
||||
lower_text = text
|
||||
|
||||
/datum/computer_file/program/status/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("stat_send")
|
||||
SendSignal()
|
||||
if("stat_update")
|
||||
SetText(params["position"], params["text"]) // i hate the player i hate the player
|
||||
|
||||
/datum/computer_file/program/status/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
data["upper"] = upper_text
|
||||
data["lower"] = lower_text
|
||||
|
||||
return data
|
||||
@@ -7,6 +7,8 @@
|
||||
device_type = MC_CARD
|
||||
|
||||
var/obj/item/card/id/stored_card
|
||||
var/current_identification = null
|
||||
var/current_job = null
|
||||
|
||||
///What happens when the ID card is removed (or deleted) from the module, through try_eject() or not.
|
||||
/obj/item/computer_hardware/card_slot/Exited(atom/movable/gone, direction)
|
||||
@@ -76,6 +78,10 @@
|
||||
stored_card = I
|
||||
to_chat(user, span_notice("You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src]."))
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
holder.update_appearance()
|
||||
|
||||
current_identification = stored_card.registered_name
|
||||
current_job = stored_card.assignment
|
||||
|
||||
var/holder_loc = holder.loc
|
||||
if(ishuman(holder_loc))
|
||||
@@ -99,6 +105,11 @@
|
||||
|
||||
to_chat(user, span_notice("You remove the card from \the [src]."))
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
holder.update_appearance()
|
||||
|
||||
stored_card = null
|
||||
current_identification = null
|
||||
current_job = null
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/max_capacity = 128
|
||||
var/used_capacity = 0
|
||||
var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY!
|
||||
var/default_installs = TRUE // install the default progs
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/remove_from, mob/user)
|
||||
remove_from.shutdown_computer()
|
||||
@@ -130,7 +131,9 @@
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/Initialize(mapload)
|
||||
. = ..()
|
||||
install_default_programs()
|
||||
|
||||
if(default_installs)
|
||||
install_default_programs()
|
||||
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/advanced
|
||||
@@ -167,12 +170,25 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
custom_price = PAYCHECK_MEDIUM * 2
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/small/install_default_programs()
|
||||
. = ..()
|
||||
|
||||
store_file(new /datum/computer_file/program/messenger(src))
|
||||
store_file(new /datum/computer_file/program/notepad(src))
|
||||
|
||||
// For borg integrated tablets. No downloader.
|
||||
/obj/item/computer_hardware/hard_drive/small/integrated/install_default_programs()
|
||||
var/datum/computer_file/program/messenger/messenger = new(src)
|
||||
messenger.is_silicon = TRUE
|
||||
store_file(messenger)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/small/integrated/borg/install_default_programs()
|
||||
store_file(new /datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar
|
||||
store_file(new /datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation.
|
||||
store_file(new /datum/computer_file/program/robotact(src))
|
||||
|
||||
var/datum/computer_file/program/messenger/messenger = new(src)
|
||||
messenger.is_silicon = TRUE
|
||||
store_file(messenger)
|
||||
|
||||
// Syndicate variant - very slight better
|
||||
/obj/item/computer_hardware/hard_drive/small/syndicate
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/obj/item/computer_hardware/identifier
|
||||
name = "identifier"
|
||||
desc = "Used to automatically update the names of modular devices."
|
||||
power_usage = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
device_type = MC_IDENTIFY
|
||||
expansion_hw = FALSE
|
||||
|
||||
/obj/item/computer_hardware/identifier/proc/UpdateDisplay()
|
||||
var/name = holder.saved_identification
|
||||
var/job = holder.saved_job
|
||||
|
||||
holder.name = "[name] ([job])"
|
||||
@@ -0,0 +1,253 @@
|
||||
/obj/item/computer_hardware/hard_drive/role
|
||||
name = "job data disk"
|
||||
desc = "A disk meant to give a worker the needed programs to work."
|
||||
power_usage = 0
|
||||
icon_state = "datadisk6"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
critical = FALSE
|
||||
max_capacity = 500
|
||||
device_type = MC_HDD_JOB
|
||||
default_installs = FALSE
|
||||
|
||||
var/disk_flags = 0 // bit flag for the programs
|
||||
var/can_spam = FALSE
|
||||
var/list/bot_access = list()
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/on_remove(obj/item/modular_computer/remove_from, mob/user)
|
||||
return
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/Initialize(mapload)
|
||||
. = ..()
|
||||
var/list/progs_to_store = list()
|
||||
|
||||
if(disk_flags & DISK_POWER)
|
||||
progs_to_store += new /datum/computer_file/program/power_monitor(src)
|
||||
progs_to_store += new /datum/computer_file/program/supermatter_monitor(src)
|
||||
|
||||
if(disk_flags & DISK_ATMOS)
|
||||
progs_to_store += new /datum/computer_file/program/atmosscan(src)
|
||||
|
||||
if(disk_flags & DISK_MANIFEST)
|
||||
progs_to_store += new /datum/computer_file/program/crew_manifest(src)
|
||||
|
||||
if(disk_flags & DISK_SEC)
|
||||
progs_to_store += new /datum/computer_file/program/records/security(src)
|
||||
|
||||
if(disk_flags & DISK_JANI)
|
||||
progs_to_store += new /datum/computer_file/program/radar/custodial_locator(src)
|
||||
|
||||
if((disk_flags & DISK_CHEM) || (disk_flags & DISK_MED))
|
||||
var/datum/computer_file/program/phys_scanner/scanner = new(src)
|
||||
|
||||
if(disk_flags & DISK_CHEM)
|
||||
scanner.available_modes += DISK_CHEM
|
||||
|
||||
if(disk_flags & DISK_MED)
|
||||
progs_to_store += new /datum/computer_file/program/records/medical(src)
|
||||
scanner.available_modes += DISK_MED
|
||||
|
||||
progs_to_store += scanner
|
||||
|
||||
if(disk_flags & DISK_ROBOS)
|
||||
var/datum/computer_file/program/robocontrol/robo = new(src)
|
||||
robo.cart_mode = TRUE
|
||||
progs_to_store += robo
|
||||
|
||||
if(disk_flags & DISK_CARGO)
|
||||
progs_to_store += new /datum/computer_file/program/shipping(src)
|
||||
|
||||
if(disk_flags & DISK_SIGNAL)
|
||||
progs_to_store += new /datum/computer_file/program/signaler(src)
|
||||
|
||||
if(disk_flags & DISK_NEWS)
|
||||
progs_to_store += new /datum/computer_file/program/newscaster(src)
|
||||
|
||||
if(disk_flags & DISK_BUDGET)
|
||||
progs_to_store += new /datum/computer_file/program/budgetorders(src)
|
||||
|
||||
if(disk_flags & DISK_STATUS)
|
||||
progs_to_store += new /datum/computer_file/program/status(src)
|
||||
|
||||
for (var/datum/computer_file/program/prog in progs_to_store)
|
||||
prog.usage_flags = PROGRAM_ALL
|
||||
prog.required_access = list()
|
||||
prog.transfer_access = list()
|
||||
store_file(prog)
|
||||
|
||||
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/proc/CanSpam()
|
||||
return can_spam
|
||||
|
||||
// Disk Definitions
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/engineering
|
||||
name = "Power-ON disk"
|
||||
desc = "Engineers ignoring station power-draw since 2400."
|
||||
icon_state = "datadisk2"
|
||||
disk_flags = DISK_POWER
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/atmos
|
||||
name = "\improper BreatheDeep disk"
|
||||
icon_state = "datadisk2"
|
||||
disk_flags = DISK_ATMOS | DISK_ROBOS
|
||||
bot_access = list(
|
||||
FLOOR_BOT,
|
||||
FIRE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/medical
|
||||
name = "\improper Med-U disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_MED | DISK_ROBOS
|
||||
bot_access = list(
|
||||
MED_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/chemistry
|
||||
name = "\improper ChemWhiz disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_CHEM
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/security
|
||||
name = "\improper R.O.B.U.S.T. disk"
|
||||
icon_state = "datadisk9"
|
||||
disk_flags = DISK_SEC | DISK_MANIFEST | DISK_ROBOS
|
||||
bot_access = list(
|
||||
SEC_BOT,
|
||||
ADVANCED_SEC_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/detective
|
||||
name = "\improper D.E.T.E.C.T. disk"
|
||||
icon_state = "datadisk9"
|
||||
disk_flags = DISK_MED | DISK_SEC | DISK_MANIFEST | DISK_ROBOS
|
||||
bot_access = list(
|
||||
SEC_BOT,
|
||||
ADVANCED_SEC_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/janitor
|
||||
name = "\improper CustodiPRO disk"
|
||||
icon_state = "datadisk5"
|
||||
desc = "The ultimate in clean-room design."
|
||||
disk_flags = DISK_JANI | DISK_ROBOS
|
||||
bot_access = list(
|
||||
CLEAN_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/lawyer
|
||||
name = "\improper P.R.O.V.E. disk"
|
||||
icon_state = "datadisk9"
|
||||
disk_flags = DISK_SEC
|
||||
can_spam = TRUE
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/curator
|
||||
name = "\improper Lib-Tweet disk"
|
||||
icon_state = "datadisk2"
|
||||
disk_flags = DISK_NEWS
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/roboticist
|
||||
name = "\improper B.O.O.P. Remote Control disk"
|
||||
icon_state = "datadisk5"
|
||||
desc = "Packed with heavy duty quad-bot interlink!"
|
||||
disk_flags = DISK_ROBOS
|
||||
bot_access = list(
|
||||
FLOOR_BOT,
|
||||
CLEAN_BOT,
|
||||
MED_BOT,
|
||||
FIRE_BOT,
|
||||
VIBE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/signal
|
||||
name = "generic signaler disk"
|
||||
icon_state = "datadisk5"
|
||||
desc = "A data disk with an integrated radio signaler module."
|
||||
disk_flags = DISK_SIGNAL
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/signal/ordnance
|
||||
name = "\improper Signal Ace 2 disk"
|
||||
icon_state = "datadisk5"
|
||||
desc = "Complete with integrated radio signaler!"
|
||||
disk_flags = DISK_ATMOS | DISK_SIGNAL | DISK_CHEM
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/quartermaster
|
||||
name = "space parts & space vendors disk"
|
||||
icon_state = "datadisk0"
|
||||
desc = "Perfect for the Quartermaster on the go!"
|
||||
disk_flags = DISK_CARGO | DISK_ROBOS | DISK_BUDGET
|
||||
bot_access = list(
|
||||
MULE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/head
|
||||
name = "\improper Easy-Record DELUXE disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_BUDGET
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/hop
|
||||
name = "\improper HumanResources9001 disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_JANI | DISK_SEC | DISK_NEWS | DISK_CARGO | DISK_ROBOS | DISK_BUDGET
|
||||
bot_access = list(
|
||||
MULE_BOT,
|
||||
CLEAN_BOT,
|
||||
VIBE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/hos
|
||||
name = "\improper R.O.B.U.S.T. DELUXE disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_SEC | DISK_ROBOS | DISK_BUDGET
|
||||
bot_access = list(
|
||||
SEC_BOT,
|
||||
ADVANCED_SEC_BOT,
|
||||
)
|
||||
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/ce
|
||||
name = "\improper Power-On DELUXE disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_POWER | DISK_ATMOS | DISK_MANIFEST | DISK_STATUS | DISK_ROBOS | DISK_BUDGET
|
||||
bot_access = list(
|
||||
FLOOR_BOT,
|
||||
FIRE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/cmo
|
||||
name = "\improper Med-U DELUXE disk"
|
||||
icon_state = "datadisk7"
|
||||
disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_CHEM | DISK_ROBOS | DISK_BUDGET
|
||||
bot_access = list(
|
||||
MED_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/rd
|
||||
name = "\improper Signal Ace DELUXE disk"
|
||||
icon_state = "rndmajordisk"
|
||||
disk_flags = DISK_ATMOS | DISK_MANIFEST | DISK_STATUS | DISK_CHEM | DISK_ROBOS | DISK_BUDGET | DISK_SIGNAL
|
||||
bot_access = list(
|
||||
FLOOR_BOT,
|
||||
CLEAN_BOT,
|
||||
MED_BOT,
|
||||
FIRE_BOT,
|
||||
VIBE_BOT,
|
||||
)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/captain
|
||||
name = "\improper Value-PAK disk"
|
||||
icon_state = "datadisk8"
|
||||
desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie)
|
||||
disk_flags = ~0
|
||||
can_spam = TRUE
|
||||
bot_access = list(
|
||||
SEC_BOT,
|
||||
ADVANCED_SEC_BOT,
|
||||
MULE_BOT,
|
||||
FLOOR_BOT,
|
||||
CLEAN_BOT,
|
||||
MED_BOT,
|
||||
FIRE_BOT,
|
||||
VIBE_BOT,
|
||||
)
|
||||
@@ -88,10 +88,12 @@
|
||||
if(!modularInterface.borgo)
|
||||
return FALSE //No borg found
|
||||
|
||||
if(modularInterface.borgo.lockcharge)
|
||||
return FALSE //lockdown restricts borg networking
|
||||
var/mob/living/silicon/robot/robo = modularInterface.borgo
|
||||
if(istype(robo))
|
||||
if(robo.lockcharge)
|
||||
return FALSE //lockdown restricts borg networking
|
||||
|
||||
if(!modularInterface.borgo.cell || modularInterface.borgo.cell.charge == 0)
|
||||
return FALSE //borg cell dying restricts borg networking
|
||||
if(!robo.cell || robo.cell.charge == 0)
|
||||
return FALSE //borg cell dying restricts borg networking
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/obj/item/computer_hardware/hard_drive/role/virus
|
||||
name = "\improper generic virus disk"
|
||||
icon_state = "virusdisk"
|
||||
var/charges = 5
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/proc/send_virus(obj/item/modular_computer/tablet/target, mob/living/user)
|
||||
return
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/clown
|
||||
name = "\improper H.O.N.K. disk"
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/clown/send_virus(obj/item/modular_computer/tablet/target, mob/living/user)
|
||||
if(charges <= 0)
|
||||
to_chat(user, span_notice("ERROR: Out of charges."))
|
||||
return
|
||||
|
||||
if(target)
|
||||
user.show_message(span_notice("Success!"))
|
||||
charges--
|
||||
target.honkamnt = rand(15, 25)
|
||||
else
|
||||
to_chat(user, span_notice("ERROR: Could not find device."))
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/mime
|
||||
name = "\improper sound of silence disk"
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/mime/send_virus(obj/item/modular_computer/tablet/target, mob/living/user)
|
||||
if(charges <= 0)
|
||||
to_chat(user, span_notice("ERROR: Out of charges."))
|
||||
return
|
||||
|
||||
if(target)
|
||||
user.show_message(span_notice("Success!"))
|
||||
charges--
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/drive = target.all_components[MC_HDD]
|
||||
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
app.ringer_status = FALSE
|
||||
app.ringtone = ""
|
||||
else
|
||||
to_chat(user, span_notice("ERROR: Could not find device."))
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/deto
|
||||
name = "\improper D.E.T.O.M.A.T.I.X. disk"
|
||||
charges = 6
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/deto/send_virus(obj/item/modular_computer/tablet/target, mob/living/user)
|
||||
if(charges <= 0)
|
||||
to_chat(user, span_notice("ERROR: Out of charges."))
|
||||
return
|
||||
|
||||
var/difficulty = 0
|
||||
var/obj/item/computer_hardware/hard_drive/role/disk = target.all_components[MC_HDD_JOB]
|
||||
|
||||
if(disk)
|
||||
difficulty += bit_count(disk.disk_flags & (DISK_MED | DISK_SEC | DISK_POWER | DISK_MANIFEST))
|
||||
if(disk.disk_flags & DISK_MANIFEST)
|
||||
difficulty++ //if cartridge has manifest access it has extra snowflake difficulty
|
||||
if(SEND_SIGNAL(target, COMSIG_TABLET_CHECK_DETONATE) & COMPONENT_TABLET_NO_DETONATE || prob(difficulty * 15))
|
||||
user.show_message(span_danger("ERROR: Target could not be bombed."), MSG_VISUAL)
|
||||
charges--
|
||||
return
|
||||
|
||||
var/original_host = holder
|
||||
var/fakename = sanitize_name(tgui_input_text(user, "Enter a name for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE)
|
||||
if(!fakename || holder != original_host || !user.canUseTopic(holder, BE_CLOSE))
|
||||
return
|
||||
var/fakejob = sanitize_name(tgui_input_text(user, "Enter a job for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE)
|
||||
if(!fakejob || holder != original_host || !user.canUseTopic(holder, BE_CLOSE))
|
||||
return
|
||||
|
||||
var/obj/item/computer_hardware/hard_drive/drive = holder.all_components[MC_HDD]
|
||||
|
||||
for(var/datum/computer_file/program/messenger/app in drive.stored_files)
|
||||
if(charges > 0 && app.send_message(user, list(target), rigged = REF(user), fake_name = fakename, fake_job = fakejob))
|
||||
charges--
|
||||
user.show_message(span_notice("Success!"))
|
||||
var/reference = REF(src)
|
||||
ADD_TRAIT(target, TRAIT_PDA_CAN_EXPLODE, reference)
|
||||
ADD_TRAIT(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference)
|
||||
addtimer(TRAIT_CALLBACK_REMOVE(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference), 10 SECONDS)
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/frame
|
||||
name = "\improper F.R.A.M.E. disk"
|
||||
|
||||
var/telecrystals = 0
|
||||
var/current_progression = 0
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/frame/send_virus(obj/item/modular_computer/tablet/target, mob/living/user)
|
||||
if(charges <= 0)
|
||||
to_chat(user, span_notice("ERROR: Out of charges."))
|
||||
return
|
||||
|
||||
if(target)
|
||||
charges--
|
||||
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
to_chat(user, span_notice("Success! The unlock code to the target is: [lock_code]"))
|
||||
var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink)
|
||||
if(!hidden_uplink)
|
||||
var/datum/mind/target_mind
|
||||
var/list/backup_players = list()
|
||||
for(var/datum/mind/player as anything in get_crewmember_minds())
|
||||
if(player.assigned_role?.title == target.saved_job)
|
||||
backup_players += player
|
||||
if(player.name == target.saved_identification)
|
||||
target_mind = player
|
||||
break
|
||||
if(!target_mind)
|
||||
if(!length(backup_players))
|
||||
target_mind = user.mind
|
||||
else
|
||||
target_mind = pick(backup_players)
|
||||
hidden_uplink = target.AddComponent(/datum/component/uplink, target_mind, enabled = TRUE, starting_tc = telecrystals, has_progression = TRUE)
|
||||
hidden_uplink.uplink_handler.has_objectives = TRUE
|
||||
hidden_uplink.uplink_handler.owner = target_mind
|
||||
hidden_uplink.uplink_handler.can_take_objectives = FALSE
|
||||
hidden_uplink.uplink_handler.progression_points = min(SStraitor.current_global_progression, current_progression)
|
||||
hidden_uplink.uplink_handler.generate_objectives()
|
||||
SStraitor.register_uplink_handler(hidden_uplink.uplink_handler)
|
||||
else
|
||||
hidden_uplink.add_telecrystals(telecrystals)
|
||||
telecrystals = 0
|
||||
hidden_uplink.locked = FALSE
|
||||
hidden_uplink.active = TRUE
|
||||
else
|
||||
to_chat(user, span_notice("ERROR: Could not find device."))
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/role/virus/frame/attackby(obj/item/I, mob/user, params)
|
||||
. = ..()
|
||||
if(istype(I, /obj/item/stack/telecrystal))
|
||||
if(!charges)
|
||||
to_chat(user, span_notice("[src] is out of charges, it's refusing to accept [I]."))
|
||||
return
|
||||
var/obj/item/stack/telecrystal/telecrystalStack = I
|
||||
telecrystals += telecrystalStack.amount
|
||||
to_chat(user, span_notice("You slot [telecrystalStack] into [src]. The next time it's used, it will also give telecrystals."))
|
||||
telecrystalStack.use(telecrystalStack.amount)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user