mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-15 20:22:07 +00:00
* Fix: #41250 You can't use a tablet while inside a locker (#68171) * Fix: #41250 You can't use a tablet while inside a locker Co-authored-by: Matt <gavxn@zanidrak.com>
334 lines
12 KiB
Plaintext
334 lines
12 KiB
Plaintext
/obj/item/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized
|
|
name = "tablet computer"
|
|
icon = 'icons/obj/modular_tablet.dmi'
|
|
icon_state = "tablet-red"
|
|
icon_state_unpowered = "tablet-red"
|
|
icon_state_powered = "tablet-red"
|
|
icon_state_menu = "menu"
|
|
base_icon_state = "tablet"
|
|
worn_icon_state = "tablet"
|
|
hardware_flag = PROGRAM_TABLET
|
|
max_hardware_size = 1
|
|
max_idle_programs = 2
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
max_bays = 3
|
|
steel_sheet_cost = 2
|
|
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
|
|
has_light = TRUE //LED flashlight!
|
|
comp_light_luminosity = 2.3 //Same as the PDA
|
|
looping_sound = FALSE
|
|
custom_materials = list(/datum/material/iron=300, /datum/material/glass=100, /datum/material/plastic=100)
|
|
interaction_flags_atom = INTERACT_ATOM_ALLOW_USER_LOCATION
|
|
|
|
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 && !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/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
|
. = ..()
|
|
|
|
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Remove pen"
|
|
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
/obj/item/modular_computer/tablet/attackby(obj/item/W, mob/user)
|
|
. = ..()
|
|
|
|
if(is_type_in_list(W, contained_item))
|
|
if(W.w_class >= WEIGHT_CLASS_SMALL) // Anything equal to or larger than small won't work
|
|
return
|
|
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)
|
|
|
|
if(istype(W, /obj/item/paper))
|
|
var/obj/item/paper/paper = W
|
|
|
|
to_chat(user, span_notice("You scan \the [W] into \the [src]."))
|
|
note = paper.info
|
|
|
|
/obj/item/modular_computer/tablet/AltClick(mob/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
remove_pen(user)
|
|
|
|
/obj/item/modular_computer/tablet/CtrlClick(mob/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
remove_pen(user)
|
|
|
|
///Finds how hard it is to send a virus to this tablet, checking all programs downloaded.
|
|
/obj/item/modular_computer/tablet/proc/get_detomatix_difficulty()
|
|
var/detomatix_difficulty
|
|
|
|
var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD]
|
|
if(hdd)
|
|
for(var/datum/computer_file/program/downloaded_apps as anything in hdd.stored_files)
|
|
detomatix_difficulty += downloaded_apps.detomatix_resistance
|
|
|
|
return detomatix_difficulty
|
|
|
|
/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_SDD], /obj/item/computer_hardware/hard_drive/portable/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'
|
|
icon_state = "tablet"
|
|
icon_state_unpowered = "tablet"
|
|
icon_state_powered = "tablet"
|
|
icon_state_menu = "assign"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
|
|
comp_light_luminosity = 6.3
|
|
has_variants = FALSE
|
|
|
|
/// Given to Nuke Ops members.
|
|
/obj/item/modular_computer/tablet/nukeops
|
|
icon_state = "tablet-syndicate"
|
|
icon_state_powered = "tablet-syndicate"
|
|
icon_state_unpowered = "tablet-syndicate"
|
|
comp_light_luminosity = 6.3
|
|
has_variants = FALSE
|
|
device_theme = "syndicate"
|
|
light_color = COLOR_RED
|
|
|
|
/obj/item/modular_computer/tablet/nukeops/emag_act(mob/user)
|
|
if(!enabled)
|
|
to_chat(user, span_warning("You'd need to turn the [src] on first."))
|
|
return FALSE
|
|
to_chat(user, span_notice("You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\"."))
|
|
return FALSE
|
|
|
|
/// Borg Built-in tablet interface
|
|
/obj/item/modular_computer/tablet/integrated
|
|
name = "modular interface"
|
|
icon_state = "tablet-silicon"
|
|
icon_state_powered = "tablet-silicon"
|
|
icon_state_unpowered = "tablet-silicon"
|
|
base_icon_state = "tablet-silicon"
|
|
has_light = FALSE //tablet light button actually enables/disables the borg lamp
|
|
comp_light_luminosity = 0
|
|
has_variants = FALSE
|
|
///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
|
|
var/list/borglog = list()
|
|
|
|
/obj/item/modular_computer/tablet/integrated/Initialize(mapload)
|
|
. = ..()
|
|
vis_flags |= VIS_INHERIT_ID
|
|
borgo = loc
|
|
if(!istype(borgo))
|
|
borgo = null
|
|
stack_trace("[type] initialized outside of a borg, deleting.")
|
|
return INITIALIZE_HINT_QDEL
|
|
|
|
/obj/item/modular_computer/tablet/integrated/Destroy()
|
|
borgo = null
|
|
return ..()
|
|
|
|
/obj/item/modular_computer/tablet/integrated/turn_on(mob/user, open_ui = FALSE)
|
|
if(borgo?.stat != DEAD)
|
|
return ..()
|
|
return FALSE
|
|
|
|
/**
|
|
* Returns a ref to the RoboTact app, creating the app if need be.
|
|
*
|
|
* The RoboTact app is important for borgs, and so should always be available.
|
|
* This proc will look for it in the tablet's robotact var, then check the
|
|
* hard drive if the robotact var is unset, and finally attempt to create a new
|
|
* copy if the hard drive does not contain the app. If the hard drive rejects
|
|
* the new copy (such as due to lack of space), the proc will crash with an error.
|
|
* RoboTact is supposed to be undeletable, so these will create runtime messages.
|
|
*/
|
|
/obj/item/modular_computer/tablet/integrated/proc/get_robotact()
|
|
if(!borgo)
|
|
return null
|
|
if(!robotact)
|
|
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
|
|
robotact = hard_drive.find_file_by_name("robotact")
|
|
if(!robotact)
|
|
stack_trace("Cyborg [borgo] ( [borgo.type] ) was somehow missing their self-manage app in their tablet. A new copy has been created.")
|
|
robotact = new(hard_drive)
|
|
if(!hard_drive.store_file(robotact))
|
|
qdel(robotact)
|
|
robotact = null
|
|
CRASH("Cyborg [borgo]'s tablet hard drive rejected recieving a new copy of the self-manage app. To fix, check the hard drive's space remaining. Please make a bug report about this.")
|
|
return robotact
|
|
|
|
//Makes the light settings reflect the borg's headlamp settings
|
|
/obj/item/modular_computer/tablet/integrated/ui_data(mob/user)
|
|
. = ..()
|
|
.["has_light"] = TRUE
|
|
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
|
|
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
|
|
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')
|
|
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
|
|
return
|
|
borgo.playsound_local(src, sound, 50, TRUE)
|
|
to_chat(borgo, span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]"))
|
|
|
|
/obj/item/modular_computer/tablet/integrated/ui_state(mob/user)
|
|
return GLOB.reverse_contained_state
|
|
|
|
/obj/item/modular_computer/tablet/integrated/syndicate
|
|
icon_state = "tablet-silicon-syndicate"
|
|
icon_state_powered = "tablet-silicon-syndicate"
|
|
icon_state_unpowered = "tablet-silicon-syndicate"
|
|
device_theme = "syndicate"
|
|
|
|
|
|
/obj/item/modular_computer/tablet/integrated/syndicate/Initialize(mapload)
|
|
. = ..()
|
|
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 = 'icons/obj/modular_pda.dmi'
|
|
icon_state = "pda"
|
|
|
|
greyscale_config = /datum/greyscale_config/tablet
|
|
greyscale_colors = "#999875#a92323"
|
|
|
|
bypass_state = TRUE
|
|
allow_chunky = TRUE
|
|
|
|
///All applications this tablet has pre-installed
|
|
var/list/default_applications = list()
|
|
///The pre-installed cartridge that comes with the tablet
|
|
var/loaded_cartridge
|
|
|
|
/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/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)
|
|
|
|
if(!isnull(default_applications))
|
|
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
|
|
for(var/datum/computer_file/program/default_programs as anything in default_applications)
|
|
hard_drive.store_file(new default_programs)
|
|
|
|
if(loaded_cartridge)
|
|
var/obj/item/computer_hardware/hard_drive/portable/disk = new loaded_cartridge(src)
|
|
install_component(disk)
|
|
|
|
if(insert_type)
|
|
inserted_item = new insert_type(src)
|