Javascript loaded, stylesheets has failed to load.
diff --git a/aurorastation.dme b/aurorastation.dme
index 71d6e4eed9b..123e989018f 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -422,6 +422,7 @@
#include "code\game\antagonist\outsider\commando.dm"
#include "code\game\antagonist\outsider\deathsquad.dm"
#include "code\game\antagonist\outsider\ert.dm"
+#include "code\game\antagonist\outsider\loner.dm"
#include "code\game\antagonist\outsider\mercenary.dm"
#include "code\game\antagonist\outsider\ninja.dm"
#include "code\game\antagonist\outsider\raider.dm"
@@ -528,6 +529,7 @@
#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\heist\heist.dm"
+#include "code\game\gamemodes\loner\loner.dm"
#include "code\game\gamemodes\malfunction\malf_hardware.dm"
#include "code\game\gamemodes\malfunction\malf_research.dm"
#include "code\game\gamemodes\malfunction\malf_research_ability.dm"
@@ -2254,6 +2256,9 @@
#include "code\modules\modular_computers\NTNet\NTNet.dm"
#include "code\modules\modular_computers\NTNet\NTNet_relay.dm"
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
+#include "code\modules\modular_computers\NTNet\NTNRC\message.dm"
+#include "code\modules\modular_computers\NTNet\NTNRC\ntnrc.dm"
+#include "code\modules\modular_computers\NTNet\NTNRC\user.dm"
#include "code\modules\multiz\_stubs.dm"
#include "code\modules\multiz\basic.dm"
#include "code\modules\multiz\hoist.dm"
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index 45db04ff5e6..8c9c892aac1 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -46,6 +46,7 @@
#define MODE_RAIDER_MAGE "raider mage"
#define MODE_RAIDER "raider"
#define MODE_BURGLAR "burglar"
+#define MODE_LONER "loner"
#define MODE_WIZARD "wizard"
#define MODE_CHANGELING "changeling"
#define MODE_CULTIST "cultist"
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 158c23b2784..418b2fe81d0 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -201,6 +201,7 @@
#define PROGRAM_ALL_REGULAR (PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_TABLET | PROGRAM_WRISTBOUND | PROGRAM_TELESCREEN)
#define PROGRAM_ALL_HANDHELD (PROGRAM_TABLET | PROGRAM_WRISTBOUND)
+#define PROGRAM_STATE_DISABLED -1
#define PROGRAM_STATE_KILLED 0
#define PROGRAM_STATE_BACKGROUND 1
#define PROGRAM_STATE_ACTIVE 2
diff --git a/code/datums/outfits/outfit_antag.dm b/code/datums/outfits/outfit_antag.dm
index f0149f82987..4236f868f52 100644
--- a/code/datums/outfits/outfit_antag.dm
+++ b/code/datums/outfits/outfit_antag.dm
@@ -166,6 +166,21 @@
if(!H.shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots/toeless(H), slot_shoes)
+/datum/outfit/admin/syndicate/mercenary/loner
+ name = "Loner"
+
+ head = /obj/item/clothing/head/helmet/space/psi_amp/lesser
+ l_ear = /obj/item/device/radio/headset/syndicate
+ r_pocket = /obj/item/device/special_uplink/burglar
+
+ backpack_contents = list(
+ /obj/item/storage/box/syndie_kit/space = 1,
+ /obj/item/gun/projectile/shotgun/foldable = 1,
+ /obj/item/device/multitool/hacktool = 1
+ )
+
+ id_access = "Lone Operative"
+
/datum/outfit/admin/syndicate/raider
name = "Raider"
allow_backbag_choice = FALSE
diff --git a/code/game/antagonist/outsider/loner.dm b/code/game/antagonist/outsider/loner.dm
new file mode 100644
index 00000000000..f45f5f7ed61
--- /dev/null
+++ b/code/game/antagonist/outsider/loner.dm
@@ -0,0 +1,46 @@
+var/datum/antagonist/loner/loners
+
+/datum/antagonist/loner
+ id = MODE_LONER
+ role_text = "Loner"
+ role_text_plural = "Loners"
+ bantype = "loner"
+ antag_indicator = "loner"
+ landmark_id = "lonerspawn"
+ welcome_text = "You are a Loner, someone underequipped to deal with the station. You will probably not survive for the whole round, so don't sweat it if you die!
\
+ You are equipped with a lesser cerebro-enhancer, which allows you to unlock your psionic potential. Use it in-hand to choose your boosted faculty, then install it on your head."
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
+ antaghud_indicator = "hudloner"
+ required_age = 7
+
+ hard_cap = 1
+ hard_cap_round = 1
+ initial_spawn_req = 1
+ initial_spawn_target = 1
+
+ faction = "syndicate"
+
+ id_type = /obj/item/card/id/syndicate
+
+/datum/antagonist/loner/New()
+ ..()
+ loners = src
+
+/datum/antagonist/loner/equip(var/mob/living/carbon/human/player)
+ if(!..())
+ return FALSE
+
+ for(var/obj/item/I in player)
+ if(istype(I, /obj/item/implant))
+ continue
+ player.drop_from_inventory(I)
+ if(I.loc != player)
+ qdel(I)
+
+ player.preEquipOutfit(/datum/outfit/admin/syndicate/mercenary/loner, FALSE)
+ player.equipOutfit(/datum/outfit/admin/syndicate/mercenary/loner, FALSE)
+ player.force_update_limbs()
+ player.update_eyes()
+ player.regenerate_icons()
+
+ return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/implements/powers/suck.dm b/code/game/gamemodes/changeling/implements/powers/suck.dm
index 13073500df7..86dc3298611 100644
--- a/code/game/gamemodes/changeling/implements/powers/suck.dm
+++ b/code/game/gamemodes/changeling/implements/powers/suck.dm
@@ -80,7 +80,7 @@
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.get_cloning_variant(), T.languages)
absorbDNA(newDNA)
- var/datum/changeling/changeling_check = T.mind.antag_datums[MODE_CHANGELING]
+ var/datum/changeling/changeling_check = T.get_antag_datum(MODE_CHANGELING)
if(changeling_check)
if(changeling_check.absorbed_dna)
for(var/datum/absorbed_dna/dna_data in changeling_check.absorbed_dna) //steal all their loot
diff --git a/code/game/gamemodes/loner/loner.dm b/code/game/gamemodes/loner/loner.dm
new file mode 100644
index 00000000000..000e294e451
--- /dev/null
+++ b/code/game/gamemodes/loner/loner.dm
@@ -0,0 +1,10 @@
+/datum/game_mode/loner
+ name = "loner"
+ config_tag = "loner"
+ max_players = 8
+ required_enemies = 1
+ required_players = 5
+ round_description = "Does anyone else hear a whistling noise...?"
+ extended_round_description = "A lone operative with a very large brain plans on dropping in and paying the crew a visit."
+ end_on_antag_death = FALSE
+ antag_tags = list(MODE_LONER)
\ No newline at end of file
diff --git a/code/game/gamemodes/vampire/vampire_helpers.dm b/code/game/gamemodes/vampire/vampire_helpers.dm
index edb506a962d..b0e9063d1fd 100644
--- a/code/game/gamemodes/vampire/vampire_helpers.dm
+++ b/code/game/gamemodes/vampire/vampire_helpers.dm
@@ -205,7 +205,7 @@
/mob/living/carbon/human/vampire_start_frenzy()
. = ..()
if(.)
- update_body()
+ update_body(force_base_icon = TRUE)
/mob/proc/vampire_stop_frenzy(var/force_stop = 0)
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
@@ -232,7 +232,7 @@
/mob/living/carbon/human/vampire_stop_frenzy()
. = ..()
if(.)
- update_body()
+ update_body(force_base_icon = TRUE)
// Removes all vampire powers.
/mob/proc/remove_vampire_powers()
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index f23e47551a8..b2699ae90ef 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -803,7 +803,7 @@
for(var/mob/living/carbon/human/T in view(5))
if(T == src)
continue
- if(!vampire_can_affect_target(T, 0, 1))
+ if(!vampire_can_affect_target(T, 0, 1, affect_ipc = FALSE)) //Will only affect IPCs at full power.
continue
if(!T.client)
continue
diff --git a/code/game/jobs/faction/zavodskoi.dm b/code/game/jobs/faction/zavodskoi.dm
index 61266dd33e0..08916d54e5c 100644
--- a/code/game/jobs/faction/zavodskoi.dm
+++ b/code/game/jobs/faction/zavodskoi.dm
@@ -114,6 +114,6 @@
backpack_contents = list(
/obj/item/device/camera = 1,
- /obj/item/gun/energy/pistol = 1,
+ /obj/item/gun/projectile/pistol = 1,
/obj/item/stamp/zavodskoi = 1
)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 6001ee141ad..64feea0c671 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -126,7 +126,7 @@ var/const/NO_EMAG_ACT = -50
var/assignment = null //can be alt title or the actual job
var/rank = null //actual job
var/dorm = 0 // determines if this ID has claimed a dorm already
- var/chat_registered = FALSE // registration for NTNET chat
+ var/datum/ntnet_user/chat_user
/obj/item/card/id/Destroy()
mob = null
@@ -151,6 +151,8 @@ var/const/NO_EMAG_ACT = -50
/obj/item/card/id/proc/update_name()
name = "ID Card ([src.registered_name] ([src.assignment]))"
+ if(istype(chat_user))
+ chat_user.username = chat_user.generateUsernameIdCard(src)
/obj/item/card/id/proc/set_id_photo(var/mob/M)
front = getFlatIcon(M, SOUTH)
@@ -334,6 +336,11 @@ var/const/NO_EMAG_ACT = -50
wear_over_suit = !wear_over_suit
mob_icon_update()
+/obj/item/card/id/proc/InitializeChatUser()
+ if(!istype(chat_user))
+ chat_user = new()
+ chat_user.username = chat_user.generateUsernameIdCard(src)
+
/obj/item/card/id/silver
icon_state = "silver"
item_state = "silver_id"
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 677262337da..40fdcac0842 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -415,11 +415,27 @@
/obj/item/storage/belt/fannypack
name = "leather fannypack"
desc = "A dorky fannypack for keeping small items in."
+ icon = 'icons/clothing/belts/fannypacks.dmi'
icon_state = "fannypack_leather"
item_state = "fannypack_leather"
max_w_class = ITEMSIZE_SMALL
+ contained_sprite = TRUE
storage_slots = null
max_storage_space = 8
+ var/flipped = FALSE
+
+/obj/item/storage/belt/fannypack/verb/ToggleFanny()
+ set name = "Adjust Fannypack"
+ set category = "Object"
+ set src in usr
+
+ if(use_check_and_message(usr))
+ return 0
+
+ flipped = !flipped
+ item_state = "[initial(icon_state)][flipped ? "_flipped" : ""]"
+ to_chat(usr, "You flip the belt [flipped ? "behind you" : "infront of you"].")
+ update_icon()
/obj/item/storage/belt/fannypack/component
name = "component pouch"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index e3b83955d9e..455d035466d 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -165,6 +165,11 @@
if(!G.wrapped)
user_unbuckle_mob(user)
+ else if(istype(W, /obj/item/disk))
+ user.drop_from_inventory(W, get_turf(src))
+ W.pixel_x = 10 //make sure they reach the pillow
+ W.pixel_y = -6
+
else if(!istype(W, /obj/item/bedsheet))
..()
diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm
index 93f66c9ac77..3f2a41ec738 100644
--- a/code/modules/admin/view_variables/view_variables.dm
+++ b/code/modules/admin/view_variables/view_variables.dm
@@ -131,7 +131,7 @@
// get_debug_type displays this
else if(istext(value))
debug_type = null // it's kinda annoying here; we can tell the type by the quotes
- vtext = "\"[value]\""
+ vtext = "\"[html_encode(value)]\""
else if(isicon(value))
vtext = "[value]"
else if(isfile(value))
diff --git a/code/modules/cciaa/cciaa_items.dm b/code/modules/cciaa/cciaa_items.dm
index 7ecca775bcf..bc9356fbf75 100644
--- a/code/modules/cciaa/cciaa_items.dm
+++ b/code/modules/cciaa/cciaa_items.dm
@@ -255,11 +255,13 @@
sLogFile << "Recorder paused at: [get_time()]"
to_chat(usr, "The device beeps and flashes \"Recording paused\".")
paused = TRUE
+ icon_state = "taperecorderpause"
else
sLogFile << "Recorder resumed at: [get_time()]"
sLogFile << "--------------------------------"
to_chat(usr, "The device beeps and flashes \"Recording resumed\".")
paused = FALSE
+ icon_state = "taperecorderrecording"
return
/obj/item/device/taperecorder/cciaa/attack_self(mob/user)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index a505bf27922..4e34c335659 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -1014,13 +1014,13 @@
rolled_down = !rolled_down
if(rolled_down)
body_parts_covered &= LOWER_TORSO|LEGS|FEET
- if(contained_sprite)
+ if(contained_sprite || !LAZYLEN(item_state_slots))
item_state = "[initial(item_state)]_d"
else
item_state_slots[slot_w_uniform_str] = "[worn_state]_d"
else
body_parts_covered = initial(body_parts_covered)
- if(contained_sprite)
+ if(contained_sprite || !LAZYLEN(item_state_slots))
item_state = initial(item_state)
else
item_state_slots[slot_w_uniform_str] = "[worn_state]"
@@ -1044,14 +1044,14 @@
rolled_sleeves = !rolled_sleeves
if(rolled_sleeves)
body_parts_covered &= ~(ARMS|HANDS)
- if(contained_sprite)
+ if(contained_sprite || !LAZYLEN(item_state_slots))
item_state = "[initial(item_state)]_r"
else
item_state_slots[slot_w_uniform_str] = "[worn_state]_r"
to_chat(usr, SPAN_NOTICE("You roll up your [src]'s sleeves."))
else
body_parts_covered = initial(body_parts_covered)
- if(contained_sprite)
+ if(contained_sprite || !LAZYLEN(item_state_slots))
item_state = initial(item_state)
else
item_state_slots[slot_w_uniform_str] = "[worn_state]"
diff --git a/code/modules/clothing/shoes/jobs.dm b/code/modules/clothing/shoes/jobs.dm
index 5ab8419d8d6..f9542fd32d5 100644
--- a/code/modules/clothing/shoes/jobs.dm
+++ b/code/modules/clothing/shoes/jobs.dm
@@ -28,9 +28,6 @@
desc = "Taller synthleather boots with an artificial shine."
icon_state = "kneeboots"
item_state = "kneeboots"
-
-/obj/item/clothing/shoes/jackboots/knee/handle_movement(var/turf/walking, var/running)
- trip_up(walking, running)
/obj/item/clothing/shoes/jackboots/thigh
name = "thigh-length black boots"
@@ -38,9 +35,6 @@
icon_state = "thighboots"
item_state = "thighboots"
-/obj/item/clothing/shoes/jackboots/thigh/handle_movement(var/turf/walking, var/running)
- trip_up(walking, running)
-
/obj/item/clothing/shoes/jackboots/toeless
name = "toe-less black boots"
desc = "Modified pair of boots, particularly friendly to those species whose toes hold claws."
diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm
index 0cedee0eebd..b43b6227190 100644
--- a/code/modules/clothing/under/accessories/badges.dm
+++ b/code/modules/clothing/under/accessories/badges.dm
@@ -210,7 +210,7 @@
/obj/item/clothing/accessory/badge/dia
name = "\improper DIA badge"
- desc = "This badge marks the holder of an investigative agent."
+ desc = "This badge marks the holder as an investigative agent."
icon_state = "diabadge"
overlay_state = "diabadge"
badge_string = "Corporate Investigator"
diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm
index d0c32b8be01..9867e5b610b 100644
--- a/code/modules/events/vent_clog.dm
+++ b/code/modules/events/vent_clog.dm
@@ -1,4 +1,3 @@
-
/datum/event/vent_clog
announceWhen = 1
startWhen = 5
@@ -6,31 +5,47 @@
var/interval = 2
var/list/vents = list()
var/list/gunk = list(
- /datum/reagent/water,
- /datum/reagent/carbon,
- /datum/reagent/nutriment/flour,
- /datum/reagent/spacecleaner,
- /datum/reagent/nutriment,
- /datum/reagent/capsaicin/condensed,
- /datum/reagent/mindbreaker,
- /datum/reagent/lube,
- /datum/reagent/paint,
- /datum/reagent/paint,
- /datum/reagent/drink/banana,
- /datum/reagent/space_drugs,
- /datum/reagent/water/holywater,
- /datum/reagent/drink/hot_coco,
- /datum/reagent/hyperzine,
- /datum/reagent/paint,
- /datum/reagent/luminol,
- /datum/reagent/fuel,
- /datum/reagent/blood,
- /datum/reagent/sterilizine,
- /datum/reagent/verunol,
- /datum/reagent/toxin/fertilizer/monoammoniumphosphate
+ /datum/reagent/water = 10,
+ /datum/reagent/carbon = 5,
+ /datum/reagent/nutriment/flour = 8,
+ /datum/reagent/spacecleaner = 6,
+ /datum/reagent/nutriment = 6,
+ /datum/reagent/capsaicin/condensed = 2,
+ /datum/reagent/mindbreaker = 0.5,
+ /datum/reagent/lube = 4,
+ /datum/reagent/paint = 3,
+ /datum/reagent/drink/banana = 3,
+ /datum/reagent/space_drugs = 3,
+ /datum/reagent/water/holywater = 1,
+ /datum/reagent/drink/hot_coco = 3,
+ /datum/reagent/hyperzine = 0.75,
+ /datum/reagent/luminol = 2,
+ /datum/reagent/fuel = 3,
+ /datum/reagent/blood = 2,
+ /datum/reagent/sterilizine = 3,
+ /datum/reagent/verunol = 3,
+ /datum/reagent/toxin/fertilizer/monoammoniumphosphate = 1,
+ /datum/reagent/saline = 2,
+ /datum/reagent/mental/kokoreed = 0.5,
+ /datum/reagent/mental/vaam = 0.5,
+ /datum/reagent/toxin/tobacco = 3,
+ /datum/reagent/stone_dust = 0.5,
+ /datum/reagent/crayon_dust = 1,
+ /datum/reagent/alcohol/butanol = 2,
+ /datum/reagent/alcohol/ethanol = 2,
+ /datum/reagent/sugar = 2,
+ /datum/reagent/drink/coffee = 4,
+ /datum/reagent/wulumunusha = 0.25,
+ /datum/reagent/nutriment/virusfood = 2,
+ /datum/reagent/sodiumchloride = 2,
+ /datum/reagent/drink/zorasoda/venomgrass = 1,
+ /datum/reagent/nutriment/protein/egg = 2,
+ /datum/reagent/serotrotium = 1,
+ /datum/reagent/psilocybin = 0.5,
+ /datum/reagent/toxin/spectrocybin = 0.1
)
var/list/gunk_data = list(
- /datum/reagent/paint = list("#FE191A", "FDFE7D")
+ /datum/reagent/paint = list("#FE191A", "#AAAA79", "#5F89E6", "#6CDB38", "#B474B6", "#F0DD34")
)
@@ -51,11 +66,11 @@
var/obj/machinery/atmospherics/unary/vent_scrubber/vent = pick_n_take(vents)
if(vent && vent.loc && !vent.is_welded())
-
- var/datum/reagents/R = new/datum/reagents(35)
+ var/datum/reagent/chem = pickweight(gunk)
+ var/reagent_amount = rand(2,5) * 5 //10 to 25 units
+ var/datum/reagents/R = new/datum/reagents(reagent_amount)
R.my_atom = vent
- var/chem = pick(gunk)
- R.add_reagent(chem, 35, pick(gunk_data[chem]))
+ R.add_reagent(chem, reagent_amount, pick(gunk_data[chem]))
var/datum/effect/effect/system/smoke_spread/chem/smoke = new
smoke.show_log = 0 // This displays a log on creation
@@ -67,4 +82,4 @@
/datum/event/vent_clog/announce()
- command_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", new_sound = 'sound/AI/scrubbers.ogg')
+ command_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", new_sound = 'sound/AI/scrubbers.ogg')
\ No newline at end of file
diff --git a/code/modules/ghostroles/spawner/base.dm b/code/modules/ghostroles/spawner/base.dm
index 08d182d3f82..cd40b8ec4b8 100644
--- a/code/modules/ghostroles/spawner/base.dm
+++ b/code/modules/ghostroles/spawner/base.dm
@@ -181,6 +181,9 @@
//Proc to enable the ghostspawner
/datum/ghostspawner/proc/enable()
+ if((max_count - count) <= 0)
+ to_chat(usr, "The ghostspawner can not be enabled - No slots available")
+ return
if(usr)
log_and_message_admins("has enabled the ghostspawner [src.name]")
enabled = TRUE
diff --git a/code/modules/mob/abstract/new_player/sprite_accessories.dm b/code/modules/mob/abstract/new_player/sprite_accessories.dm
index 4b2b770ee5c..f8efc9df6ac 100644
--- a/code/modules/mob/abstract/new_player/sprite_accessories.dm
+++ b/code/modules/mob/abstract/new_player/sprite_accessories.dm
@@ -2862,7 +2862,7 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Scalp Ports)"
icon_state = "aug_scalpports"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
vertex_left
name = "Augment (Scalp Port, Vertex Left)"
@@ -2884,7 +2884,7 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Scalp Ports Diode)"
icon_state = "aug_scalpportsdiode"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
vertex_left
name = "Augment (Scalp Port Diode, Vertex Left )"
@@ -2906,7 +2906,7 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Backside Left, Head)"
icon_state = "aug_backside_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
side_diode
name = "Augment (Backside Left Diode, Head)"
@@ -2916,7 +2916,7 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Backside Right, Head)"
icon_state = "aug_backside_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
side_diode
name = "Augment (Backside Right Diode, Head)"
@@ -2926,19 +2926,19 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Deunan, Side Left)"
icon_state = "aug_sidedeunan_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_side_deunan_right
name = "Augment (Deunan, Side Right)"
icon_state = "aug_sidedeunan_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_side_kuze_left
name = "Augment (Kuze, Side Left)"
icon_state = "aug_sidekuze_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
side_diode
name = "Augment (Kuze Diode, Side Left)"
@@ -2948,7 +2948,7 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Kuze, Side Right)"
icon_state = "aug_sidekuze_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
side_diode
name = "Augment (Kuze Diode, Side Right)"
@@ -2958,43 +2958,43 @@ Follow by example and make good judgement based on length which list to include
name = "Augment (Kinzie, Side Left)"
icon_state = "aug_sidekinzie_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_side_kinzie_right
name = "Augment (Kinzie, Side Right)"
icon_state = "aug_sidekinzie_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_side_shelly_left
name = "Augment (Shelly, Side Left)"
icon_state = "aug_sideshelly_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_side_shelly_right
name = "Augment (Shelly, Side Right)"
icon_state = "aug_sideshelly_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
aug_chestports
name = "Augment (Chest Ports)"
icon_state = "aug_chestports"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
aug_abdomenports
name = "Augment (Abdomen Ports)"
icon_state = "aug_abdomenports"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
backstripe
name = "Back Stripe"
icon_state = "backstripe"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
spinemarks
name = "Back Stripe Marks"
@@ -3004,7 +3004,7 @@ Follow by example and make good judgement based on length which list to include
name = "Color Bands (All)"
icon_state = "bands"
body_parts = list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_GROIN, BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/diona, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
chest
name = "Color Bands (Torso)"
@@ -3047,7 +3047,7 @@ Follow by example and make good judgement based on length which list to include
name = "Color Bands (Left Foot)"
icon_state = "bandshuman"
body_parts = list(BP_L_FOOT)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell)
right_foot
name = "Color Bands (Right Foot)"
@@ -3058,7 +3058,7 @@ Follow by example and make good judgement based on length which list to include
name = "Color Bands (Right Foot)"
icon_state = "bandshuman"
body_parts = list(BP_R_FOOT)
- species_allowed = list(/datum/species/human, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell)
bandsface
name = "Color Bands (Face)"
@@ -3070,241 +3070,241 @@ Follow by example and make good judgement based on length which list to include
name = "Color Bands (Face)"
icon_state = "bandshumanface"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell)
bindi
name = "Bindi"
icon_state = "bindi"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
blush
name = "Blush"
icon_state= "blush"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
cheekspot_left
name = "Cheek Spot (Left Cheek)"
icon_state = "cheekspot_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
cheekspot_right
name = "Cheek Spot (Right Cheek)"
icon_state = "cheekspot_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
cheshire_left
name = "Cheshire (Left Cheek)"
icon_state = "cheshire_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
cheshire_right
name = "Cheshire (Right Cheek)"
icon_state = "cheshire_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
crow_left
name = "Crow Mark (Left Eye)"
icon_state = "crow_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
crow_right
name = "Crow Mark (Right Eye)"
icon_state = "crow_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
ear_left
name = "Ear Cover (Left)"
icon_state = "ear_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell)
ear_right
name = "Ear Cover (Right)"
icon_state = "ear_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell)
eyestripe
name = "Eye Stripe"
icon_state = "eyestripe"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
eyecorner_left
name = "Eye Corner Left"
icon_state = "eyecorner_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
eyecorner_right
name = "Eye Corner Right"
icon_state = "eyecorner_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
eyelash_left
name = "Eyelash Left"
icon_state = "eyelash_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
eyelash_right
name = "Eyelash Right"
icon_state = "eyelash_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
lips
name = "Lips"
icon_state = "lips"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
lipcorner_left
name = "Lip Corner Left"
icon_state = "lipcorner_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
lipcorner_right
name = "Lip Corner Right"
icon_state = "lipcorner_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
lowercheek_left
name = "Lower Cheek Left"
icon_state = "lowercheek_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
lowercheek_left
name = "Lower Cheek Right"
icon_state = "lowercheek_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
neck
name = "Neck Cover"
icon_state = "neck"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
neckthick
name = "Neck Cover (Thick)"
icon_state = "neckthick"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
nosestripe
name = "Nose Stripe"
icon_state = "nosestripe"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
nosetape
name = "Nose Tape"
icon_state = "nosetape"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, "Vaurca")
scratch_abdomen_left
name = "Scratch, Abdomen Left"
icon_state = "scratch_abdomen_l"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
scratch_abdomen_right
name = "Scratch, Abdomen Right"
icon_state = "scratch_abdomen_r"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
scratch_abdomen_small_left
name = "Scratch, Abdomen Small Left"
icon_state = "scratch_abdomensmall_l"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
scratch_abdomen_small_right
name = "Scratch, Abdomen Small Right"
icon_state = "scratch_abdomensmall_r"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
scratch_back
name = "Scratch, Back"
icon_state = "scratch_back"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, "Vaurca")
scratch_chest_left
name = "Scratch, Chest (Left)"
icon_state = "scratch_chest_l"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
scratch_chest_right
name = "Scratch, Chest (Right)"
icon_state = "scratch_chest_r"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_belly
name = "Tattoo (Belly)"
icon_state = "tat_belly"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_campbell_leftarm
name = "Tattoo (Campbell, Left Arm)"
icon_state = "tat_campbell"
body_parts = list(BP_L_ARM)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_campbell_rightarm
name = "Tattoo (Campbell, Right Arm)"
icon_state = "tat_campbell"
body_parts= list(BP_R_ARM)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_campbell_leftleg
name = "Tattoo (Campbell, Left Leg)"
icon_state = "tat_campbell"
body_parts= list(BP_L_LEG)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_campbell_rightleg
name = "Tattoo (Campbell, Right Leg)"
icon_state = "tat_campbell"
body_parts= list(BP_R_LEG)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_forrest_left
name = "Tattoo (Forrest, Left Eye)"
icon_state = "tat_forrest_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_forrest_right
name = "Tattoo (Forrest, Right Eye)"
icon_state = "tat_forrest_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_hive
name = "Tattoo (Hive, Back)"
icon_state = "tat_hive"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_heart
name = "Tattoo (Heart, Chest)"
@@ -3316,97 +3316,97 @@ Follow by example and make good judgement based on length which list to include
name = "Tattoo (Heart, Lower Back)"
icon_state = "tat_heartback"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell)
tat_hunter_left
name = "Tattoo (Hunter, Left Eye)"
icon_state = "tat_hunter_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_hunter_right
name = "Tattoo (Hunter, Right Eye)"
icon_state = "tat_hunter_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_jaeger_left
name = "Tattoo (Jaeger, Left Eye)"
icon_state = "tat_jaeger_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_jaeger_right
name = "Tattoo (Jaeger, Right Eye)"
icon_state = "tat_jaeger_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_kater_left
name = "Tattoo (Kater, Left Eye)"
icon_state = "tat_kater_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_kater_right
name = "Tattoo (Kater, Right Eye)"
icon_state = "tat_kater_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_lujan_left
name = "Tattoo (Lujan, Left Eye)"
icon_state = "tat_lujan_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_lujan_right
name = "Tattoo (Lujan, Right Eye)"
icon_state = "tat_lujan_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_natasha_left
name = "Tattoo (Natasha, Left Eye)"
icon_state = "tat_natasha_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_natasha_right
name = "Tattoo (Natasha, Right Eye)"
icon_state = "tat_natasha_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_nightling
name = "Tattoo (Nightling, Back)"
icon_state = "tat_nightling"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_silverburgh_left
name = "Tattoo (Silverburgh, Left Leg)"
icon_state = "tat_silverburgh"
body_parts = list(BP_L_LEG)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_silverburgh_right
name = "Tattoo (Silverburgh, Right Leg)"
icon_state = "tat_silverburgh"
body_parts = list(BP_R_LEG)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_tamoko
name = "Tattoo (Ta Moko, Face)"
icon_state = "tat_tamoko"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell)
tat_tiger
name = "Tattoo (Tiger Stripes, All)"
icon_state = "tat_tiger"
body_parts = list(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_GROIN,BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
chest
name = "Tattoo (Tiger Stripes, Chest)"
@@ -3452,25 +3452,25 @@ Follow by example and make good judgement based on length which list to include
name = "Tattoo (Toshi, Left Eye)"
icon_state = "tat_toshi_l"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_toshi_right
name = "Tattoo (Volgin, Right Eye)"
icon_state = "tat_toshi_r"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tat_wings_back
name = "Tattoo (Wings, Lower Back)"
icon_state = "tat_wingsback"
body_parts = list(BP_CHEST)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell)
tigerhead
name = "Tiger Stripes (Head, Minor)"
icon_state = "tigerhead"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/human, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
+ species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
tiger_stripes
name = "Tiger Stripes (Tajara)"
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index ef7dc248d5f..2c2fffaace5 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -259,4 +259,11 @@
return species.icon_y_offset
/mob/living/carbon/human/proc/protected_from_sound()
- return (l_ear?.item_flags & SOUNDPROTECTION) || (r_ear?.item_flags & SOUNDPROTECTION) || (head?.item_flags & SOUNDPROTECTION)
\ No newline at end of file
+ return (l_ear?.item_flags & SOUNDPROTECTION) || (r_ear?.item_flags & SOUNDPROTECTION) || (head?.item_flags & SOUNDPROTECTION)
+
+/mob/living/carbon/human/get_antag_datum(var/antag_role)
+ if(!mind)
+ return
+ var/datum/D = mind.antag_datums[antag_role]
+ if(D)
+ return D
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 3707988d441..49f471ba389 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -255,7 +255,7 @@ There are several things that need to be remembered:
. += M
//BASE MOB SPRITE
-/mob/living/carbon/human/proc/update_body(var/update_icons=1)
+/mob/living/carbon/human/proc/update_body(var/update_icons=1, var/force_base_icon = FALSE)
if (QDELING(src))
return
@@ -263,7 +263,6 @@ There are several things that need to be remembered:
var/husk = (HUSK in mutations)
var/fat = (FAT in mutations)
- var/hulk = (HULK in mutations)
var/skeleton = (SKELETON in mutations)
var/g = (gender == FEMALE ? "f" : "m")
@@ -278,12 +277,12 @@ There are several things that need to be remembered:
qdel(stand_icon)
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
- var/is_frenzied = FALSE
+ var/is_frenzied = "nofrenzy"
if(mind)
var/datum/vampire/vampire = mind.antag_datums[MODE_VAMPIRE]
if(vampire && (vampire.status & VAMP_FRENZIED))
- is_frenzied = TRUE
- var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin][lip_style || "nolips"][!!husk][!!fat][!!hulk][!!skeleton][is_frenzied]"
+ is_frenzied = "frenzy"
+ var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin][lip_style || "nolips"][!!husk][!!fat][!!skeleton][is_frenzied]"
var/obj/item/organ/internal/eyes/eyes = get_eyes()
if(eyes)
icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]"
@@ -298,7 +297,7 @@ There are several things that need to be remembered:
icon_key += SSicon_cache.get_organ_shortcode(part)
var/icon/base_icon = SSicon_cache.human_icon_cache[icon_key]
- if (!base_icon) // Icon ain't in the cache, so generate it.
+ if (!base_icon || force_base_icon) // Icon ain't in the cache, so generate it.
//BEGIN CACHED ICON GENERATION.
var/obj/item/organ/external/chest = get_organ(BP_CHEST)
base_icon = chest.get_icon(skeleton)
@@ -326,6 +325,7 @@ There are several things that need to be remembered:
else
base_icon.Blend(temp, ICON_OVERLAY)
+ part.cut_additional_images(src)
var/list/add_images = part.get_additional_images(src)
if(add_images)
add_overlay(add_images, TRUE)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index ea1114046b8..a90be690727 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -95,6 +95,10 @@
/mob/living/silicon/proc/SetName(pickedName as text)
real_name = pickedName
name = real_name
+ if(istype(id_card))
+ if(!istype(id_card.chat_user))
+ id_card.InitializeChatUser()
+ id_card.chat_user.username = real_name
/mob/living/silicon/proc/show_laws()
return
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 875f0bfb69b..780d11b83a7 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -635,7 +635,7 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
set name = "Make Sound"
set category = "Abilities"
- if((usr && usr.stat == DEAD) || !make_sound)
+ if(stat || !make_sound) //Can't make noise if there's no noise or if you're unconscious/dead
return
if(usr && !sound_time)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index e489734dd9d..408bd4424bf 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -1210,4 +1210,7 @@ proc/is_blind(A)
disabilities &= ~NEARSIGHTED
/mob/proc/remove_deaf()
- sdisabilities &= ~DEAF
\ No newline at end of file
+ sdisabilities &= ~DEAF
+
+/mob/proc/get_antag_datum(var/antag_role)
+ return
\ No newline at end of file
diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
index 692451011d5..ead8bf1b721 100644
--- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
+++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
@@ -2,9 +2,9 @@ var/global/ntnrc_uid = 0
/datum/ntnet_conversation
var/id
var/title = "Untitled Conversation"
- var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator,
+ var/datum/ntnet_user/operator // "Administrator" of this channel. Creator starts as channel's operator,
var/list/messages = list()
- var/list/clients = list()
+ var/list/users = list()
var/direct = FALSE
var/password
@@ -19,25 +19,32 @@ var/global/ntnrc_uid = 0
operator = "NanoTrasen Information Technology Division" // assign a fake operator
..()
-/datum/ntnet_conversation/proc/add_message(var/message, var/username, var/mob/user, var/reply_ref)
- log_ntirc("[user.client.ckey]/([username]) : [message]", ckey=key_name(user), conversation=title)
+/datum/ntnet_conversation/proc/process_message(var/datum/ntnet_message/message, var/update_ui = TRUE)
+ var/admin_log = message.format_admin_log()
+ if (admin_log)
+ log_ntirc("[message.user.client.ckey]/([message.nuser.username]): [admin_log]", ckey=key_name(message.user), conversation=title)
- for(var/datum/computer_file/program/chatclient/C in clients)
- if(C.program_state > PROGRAM_STATE_KILLED)
- C.computer.output_message("([get_title(C)]) [username]: [message] (Reply)", 0)
- if(!C.silent && C.username != username && C.program_state == PROGRAM_STATE_BACKGROUND)
- playsound(C.computer, 'sound/machines/twobeep.ogg', 50, 1)
- C.computer.output_message("*[C.ringtone]*")
- else if(C.username == username)
- ntnet_global.add_log(message, C.computer.network_card, TRUE)
+ for(var/datum/ntnet_user/U in users)
+ for(var/datum/computer_file/program/chat_client/Cl in U.clients)
+ var/notification_text = message.format_chat_notification(src, Cl)
+ if(notification_text && Cl.can_receive_notification(message.client))
+ Cl.computer.output_message(notification_text, 0)
+ if(message.play_sound)
+ Cl.play_notification_sound(message.client)
- message = "[worldtime2text()] [username]: [message]"
- messages.Add(message)
- trim_message_list()
+ var/ntnet_log = message.format_ntnet_log(src)
+ if(ntnet_log)
+ ntnet_global.add_log(ntnet_log, message.client.computer.network_card, TRUE)
-/datum/ntnet_conversation/proc/add_status_message(var/message)
- messages.Add("[worldtime2text()] -!- [message]")
- trim_message_list()
+ var/chat_log = message.format_chat_log(src)
+ if(chat_log)
+ messages.Add(chat_log)
+ trim_message_list()
+
+ if(update_ui)
+ for(var/datum/ntnet_user/U in users)
+ for(var/datum/computer_file/program/chat_client/Cl)
+ SSvueui.check_uis_for_change(Cl)
/datum/ntnet_conversation/proc/trim_message_list()
if(messages.len <= 50)
@@ -47,89 +54,119 @@ var/global/ntnrc_uid = 0
if(messages.len <= 50)
return
-/datum/ntnet_conversation/proc/add_client(var/datum/computer_file/program/chatclient/C)
- if(!istype(C))
- return
- if (C in clients)
- return
- clients.Add(C)
- // No operator, so we assume the channel was empty. Assign this user as operator.
- if(!operator)
- changeop(C)
- for(var/datum/computer_file/program/chatclient/CC in clients)
- if(CC.program_state > PROGRAM_STATE_KILLED && CC != C)
- if(!direct)
- CC.computer.output_message(FONT_SMALL("([get_title(CC)]) [C.username] has entered the chat."), 0)
+/// EXTERNAL PROCs
-/datum/ntnet_conversation/proc/begin_direct(var/datum/computer_file/program/chatclient/CA, var/datum/computer_file/program/chatclient/CB)
- if(!istype(CA) || !istype(CB))
- return
- direct = TRUE
- clients.Add(CA)
- clients.Add(CB)
-
- add_status_message("[CA.username] has opened direct conversation.")
- if(CB.program_state > PROGRAM_STATE_KILLED)
- CB.computer.output_message(FONT_SMALL("([get_title(CB)]) [CA.username] has opened direct conversation with you."), 0)
-
-/datum/ntnet_conversation/proc/remove_client(var/datum/computer_file/program/chatclient/C)
- if(!istype(C) || !(C in clients))
- return
- clients.Remove(C)
-
- // Channel operator left, pick new operator
- if(C == operator)
- operator = null
- if(clients.len)
- var/datum/computer_file/program/chatclient/newop = pick(clients)
- changeop(newop)
-
- for(var/datum/computer_file/program/chatclient/CC in clients)
- if(CC.program_state > PROGRAM_STATE_KILLED && CC != C)
- CC.computer.output_message(FONT_SMALL("([get_title(CC)]) [C.username] has left the chat."), 0)
-
-
-/datum/ntnet_conversation/proc/changeop(var/datum/computer_file/program/chatclient/newop)
- if(istype(newop))
- operator = newop
- add_status_message("Channel operator status transferred to [newop.username].")
-
-/datum/ntnet_conversation/proc/change_title(var/newtitle, var/datum/computer_file/program/chatclient/client)
- if(operator != client)
- return 0 // Not Authorised
-
- add_status_message("[client.username] has changed channel title from [get_title(client)] to [newtitle]")
-
- for(var/datum/computer_file/program/chatclient/C in clients)
- if(C.program_state > PROGRAM_STATE_KILLED && C != client)
- C.computer.output_message(FONT_SMALL("([get_title(C)]) [client.username] has changed the channel title to [newtitle]."), 0)
- title = newtitle
-
-/datum/ntnet_conversation/proc/get_title(var/datum/computer_file/program/chatclient/cl = null)
+/datum/ntnet_conversation/proc/get_title(var/datum/computer_file/program/chat_client/cl = null)
if(direct)
var/names = list()
- for(var/datum/computer_file/program/chatclient/C in clients)
- names += C.username
- if(cl)
- names -= cl.username
+ for(var/datum/ntnet_user/U in users)
+ names += U.username
+ if(istype(cl) && istype(cl.my_user))
+ names -= cl.my_user.username
return "\[DM] [english_list(names)]"
else
return title
-/datum/ntnet_conversation/proc/get_dead_title()
- if(direct)
- var/names = list()
- for(var/datum/computer_file/program/chatclient/C in clients)
- names += C.username
- return "\[DM] [english_list(names)]"
- else
- return title
-
-/datum/ntnet_conversation/proc/can_see(var/datum/computer_file/program/chatclient/cl)
- if(cl in clients)
- return TRUE
+/datum/ntnet_conversation/proc/can_see(var/datum/computer_file/program/chat_client/cl)
if(cl.netadmin_mode)
return TRUE
+ if(istype(cl.my_user))
+ if(cl.my_user in users)
+ return TRUE
+ else
+ for(var/datum/ntnet_user/user in users)
+ if(cl in user.clients)
+ return TRUE
if(!direct)
return TRUE
return FALSE
+
+/datum/ntnet_conversation/proc/can_interact(var/datum/computer_file/program/chat_client/cl)
+ if(cl.netadmin_mode)
+ return TRUE
+ if(istype(cl.my_user))
+ if(cl.my_user in users)
+ return TRUE
+ else
+ for(var/datum/ntnet_user/user in users)
+ if(cl in user.clients)
+ return TRUE
+ return FALSE
+
+/datum/ntnet_conversation/proc/can_manage(var/datum/computer_file/program/chat_client/cl)
+ if(cl.netadmin_mode)
+ return TRUE
+ if(cl.my_user == operator)
+ return TRUE
+ return FALSE
+
+/datum/ntnet_conversation/proc/cl_send(var/datum/computer_file/program/chat_client/Cl, var/message, var/mob/user)
+ if(!istype(Cl) || !can_interact(Cl))
+ return
+ var/datum/ntnet_message/message/msg = new(Cl)
+ msg.message = message
+ msg.user = user
+ process_message(msg)
+
+/datum/ntnet_conversation/proc/cl_join(var/datum/computer_file/program/chat_client/Cl)
+ if(!istype(Cl) || !can_see(Cl) || direct)
+ return
+ var/datum/ntnet_message/join/msg = new(Cl)
+ Cl.my_user.channels.Add(src)
+ users.Add(Cl.my_user)
+ if(!operator)
+ operator = Cl.my_user
+ var/datum/ntnet_message/new_op/msg2 = new(Cl)
+ process_message(msg, FALSE)
+ process_message(msg2)
+ return
+ process_message(msg)
+
+/datum/ntnet_conversation/proc/cl_leave(var/datum/computer_file/program/chat_client/Cl)
+ if(!istype(Cl) || !istype(Cl.my_user) || !(Cl.my_user in users) || !can_interact(Cl) || direct)
+ return
+ var/datum/ntnet_message/leave/msg = new(Cl)
+ Cl.my_user.channels.Remove(src)
+ users.Remove(Cl.my_user)
+ if(operator == Cl.my_user)
+ if(users.len)
+ operator = pick(users)
+ var/datum/ntnet_message/new_op/msg2 = new()
+ msg2.nuser = operator
+ process_message(msg, FALSE)
+ process_message(msg2)
+ return
+ process_message(msg)
+
+/datum/ntnet_conversation/proc/cl_change_title(var/datum/computer_file/program/chat_client/Cl, var/newTitle)
+ if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || direct)
+ return
+ var/datum/ntnet_message/new_title/msg = new(Cl)
+ msg.title = newTitle
+ process_message(msg)
+ title = newTitle
+
+/datum/ntnet_conversation/proc/cl_set_password(var/datum/computer_file/program/chat_client/Cl, var/newPassword)
+ if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || direct)
+ return
+ if(newPassword)
+ password = newPassword
+ else
+ password = FALSE
+
+/datum/ntnet_conversation/proc/cl_kick(var/datum/computer_file/program/chat_client/Cl, var/datum/ntnet_user/target)
+ if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || !(target in users) || direct)
+ return
+ var/datum/ntnet_message/kick/msg = new(Cl)
+ msg.target = target
+ target.channels.Remove(src)
+ users.Remove(target)
+ if(operator == target)
+ if(users.len)
+ operator = pick(users)
+ var/datum/ntnet_message/new_op/msg2 = new()
+ msg2.nuser = operator
+ process_message(msg, FALSE)
+ process_message(msg2)
+ return
+ process_message(msg)
\ No newline at end of file
diff --git a/code/modules/modular_computers/NTNet/NTNRC/message.dm b/code/modules/modular_computers/NTNet/NTNRC/message.dm
new file mode 100644
index 00000000000..e4e24aa1c89
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNRC/message.dm
@@ -0,0 +1,96 @@
+// Container for all essesal state for NTRC message while it's proccessed
+/datum/ntnet_message
+ var/mob/user
+ var/datum/computer_file/program/chat_client/client
+ var/datum/ntnet_user/nuser
+ var/play_sound = FALSE
+
+/datum/ntnet_message/New(var/datum/computer_file/program/chat_client/Pr = null, var/mob/user = null)
+ if(user)
+ src.user = user
+ if(Pr)
+ client = Pr
+ nuser = Pr.my_user
+
+// Should be sanitized
+/datum/ntnet_message/proc/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ return FALSE
+
+/datum/ntnet_message/proc/format_admin_log(var/datum/ntnet_conversation/Conv)
+ return FALSE
+
+// Should be sanitized
+/datum/ntnet_message/proc/format_ntnet_log(var/datum/ntnet_conversation/Conv)
+ return FALSE
+
+/datum/ntnet_message/proc/format_chat_log(var/datum/ntnet_conversation/Conv)
+ return FALSE
+
+
+
+/datum/ntnet_message/message
+ play_sound = TRUE
+ var/message = ""
+
+/datum/ntnet_message/message/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = "([sanitize(Conv.get_title(Cl))]) [nuser.username]: [sanitize(message)] (Reply)"
+
+/datum/ntnet_message/message/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] [nuser.username]: [message]"
+
+/datum/ntnet_message/message/format_admin_log(var/datum/ntnet_conversation/Conv)
+ . = message
+
+/datum/ntnet_message/message/format_ntnet_log(var/datum/ntnet_conversation/Conv)
+ . = "[sanitize(Conv.get_title())] [nuser.username]: [sanitize(message)]"
+
+
+
+/datum/ntnet_message/join/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = FONT_SMALL("([sanitize(Conv.get_title(Cl))]) [nuser.username] has entered the chat.")
+
+/datum/ntnet_message/join/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has entered the chat."
+
+
+
+/datum/ntnet_message/leave/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = FONT_SMALL("([sanitize(Conv.get_title(Cl))]) [nuser.username] has left the chat.")
+
+/datum/ntnet_message/leave/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has left the chat."
+
+
+
+/datum/ntnet_message/new_op/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has become operator."
+
+
+
+/datum/ntnet_message/new_title
+ var/title = ""
+
+/datum/ntnet_message/new_title/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has changed channel title from [Conv.get_title()] to [title]"
+
+/datum/ntnet_message/new_title/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = FONT_SMALL("([sanitize(Conv.get_title(Cl))]) [nuser.username] has changed the channel title to [sanitize(title)].")
+
+
+
+/datum/ntnet_message/kick
+ var/datum/ntnet_user/target
+
+/datum/ntnet_message/kick/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has kicked [target.username] from conversation."
+
+/datum/ntnet_message/kick/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = FONT_SMALL("([sanitize(Conv.get_title(Cl))]) [nuser.username] has kicked [target.username] from conversation.")
+
+
+
+/datum/ntnet_message/direct/format_chat_log(var/datum/ntnet_conversation/Conv)
+ . = "[worldtime2text()] -!- [nuser.username] has opened direct conversation."
+
+/datum/ntnet_message/direct/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
+ . = FONT_SMALL("([sanitize(Conv.get_title(Cl))]) [nuser.username] has opened direct conversation with you.")
\ No newline at end of file
diff --git a/code/modules/modular_computers/NTNet/NTNRC/ntnrc.dm b/code/modules/modular_computers/NTNet/NTNRC/ntnrc.dm
new file mode 100644
index 00000000000..db6cd0148ba
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNRC/ntnrc.dm
@@ -0,0 +1,28 @@
+/datum/ntnet
+ var/list/chat_channels = list()
+ var/list/chat_clients = list()
+ var/list/chat_users = list()
+
+/datum/ntnet/proc/begin_conversation(var/datum/computer_file/program/chat_client/Cl, var/title)
+ if(!istype(Cl) || !istype(Cl.my_user))
+ return
+
+ var/datum/ntnet_conversation/Conv = new(title)
+ Conv.cl_join(Cl)
+
+ return Conv
+
+/datum/ntnet/proc/begin_direct(var/datum/computer_file/program/chat_client/Cl, var/datum/ntnet_user/target)
+ if(!istype(Cl) || !istype(Cl.my_user) || !istype(target) || istype(Cl.my_user.dm_channels[target], /datum/ntnet_conversation))
+ return
+
+ var/datum/ntnet_conversation/Conv = new()
+ Conv.direct = TRUE
+ Conv.users.Add(Cl.my_user)
+ Conv.users.Add(target)
+
+ target.dm_channels[Cl.my_user] = Conv
+ Cl.my_user.dm_channels[target] = Conv
+
+ var/datum/ntnet_message/direct/msg = new(Cl)
+ Conv.process_message(msg)
\ No newline at end of file
diff --git a/code/modules/modular_computers/NTNet/NTNRC/user.dm b/code/modules/modular_computers/NTNet/NTNRC/user.dm
new file mode 100644
index 00000000000..feb79715bec
--- /dev/null
+++ b/code/modules/modular_computers/NTNet/NTNRC/user.dm
@@ -0,0 +1,21 @@
+/datum/ntnet_user
+ var/username
+ var/list/channels = list()
+ var/list/dm_channels = list()
+ var/list/clients = list()
+
+/datum/ntnet_user/New()
+ . = ..()
+ ntnet_global.chat_users.Add(src)
+
+/datum/ntnet_user/Destroy(force)
+ . = ..()
+ ntnet_global.chat_users.Remove(src)
+
+/datum/ntnet_user/proc/generateUsernameIdCard(var/obj/item/card/id/card)
+ if(!card)
+ return "Unknown"
+ return "[card.registered_name] ([card.assignment])"
+
+/datum/ntnet_user/proc/generateUsernameSilicon(var/mob/living/silicon/silicon)
+ return silicon.name
diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm
index f1d53a06b57..e61f97b3d46 100644
--- a/code/modules/modular_computers/NTNet/NTNet.dm
+++ b/code/modules/modular_computers/NTNet/NTNet.dm
@@ -11,8 +11,6 @@ var/global/datum/ntnet/ntnet_global = new()
var/list/available_software = list()
var/list/available_software_presets = list()
var/list/available_news = list()
- var/list/chat_channels = list()
- var/list/chat_clients = list()
var/list/fileservers = list()
var/list/datum/ntnet_account/users = list()
// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.
diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm
index c858e406e36..837b35e2889 100644
--- a/code/modules/modular_computers/computers/modular_computer/core.dm
+++ b/code/modules/modular_computers/computers/modular_computer/core.dm
@@ -98,7 +98,6 @@
/obj/item/modular_computer/Destroy()
kill_program(TRUE)
if(registered_id)
- registered_id.chat_registered = FALSE
registered_id = null
for(var/obj/item/computer_hardware/CH in src.get_all_components())
uninstall_component(null, CH)
@@ -197,7 +196,7 @@
if(network_card)
return network_card.get_signal(specific_action)
else
- return 0
+ return FALSE
/obj/item/modular_computer/proc/add_log(var/text)
if(!get_ntnet_status())
@@ -366,6 +365,7 @@
/obj/item/modular_computer/proc/enable_service(service, mob/user, var/datum/computer_file/program/S = null)
+ . = FALSE
if(!S)
S = hard_drive?.find_file_by_name(service)
@@ -382,9 +382,11 @@
return
// Start service
- if(S.service_activate())
+ if(S.service_enable())
enabled_services += S
S.service_state = PROGRAM_STATE_ACTIVE
+ return TRUE
+
/obj/item/modular_computer/proc/disable_service(service, mob/user, var/datum/computer_file/program/S = null)
@@ -399,8 +401,8 @@
enabled_services -= S
// Stop service
- S.service_deactivate()
- S.service_state = PROGRAM_STATE_KILLED
+ S.service_disable()
+ S.service_state = PROGRAM_STATE_DISABLED
/obj/item/modular_computer/proc/output_message(var/message, var/message_range)
message_range += message_output_range
@@ -434,12 +436,13 @@
if(!istype(id))
output_error("No ID card found!")
return FALSE
- if(id.chat_registered)
- output_error("This card is already registered to another account!")
- return FALSE
- id.chat_registered = TRUE
registered_id = id
+
+ if(hard_drive)
+ for(var/datum/computer_file/program/P in hard_drive.stored_files)
+ P.event_registered()
+
output_notice("Registration successful!")
playsound(get_turf(src), 'sound/machines/ping.ogg', 10, 0)
return registered_id
@@ -448,12 +451,11 @@
if(!registered_id)
return FALSE
- registered_id.chat_registered = FALSE
- registered_id = null
-
if(hard_drive)
- var/datum/computer_file/program/P = hard_drive.find_file_by_name("ntnrc_client")
- P.event_unregistered()
+ for(var/datum/computer_file/program/P in hard_drive.stored_files)
+ P.event_unregistered()
+
+ registered_id = null
output_message(SPAN_NOTICE("\The [src] beeps: \"Successfully unregistered ID!\""))
playsound(get_turf(src), 'sound/machines/ping.ogg', 20, 0)
@@ -476,7 +478,6 @@
return TRUE
/obj/item/modular_computer/proc/silence_notifications()
- for (var/datum/computer_file/program/P in hard_drive.stored_files)
- if (istype(P))
- P.event_silentmode()
silent = !silent
+ for (var/datum/computer_file/program/P in hard_drive.stored_files)
+ P.event_silentmode()
diff --git a/code/modules/modular_computers/computers/modular_computer/power.dm b/code/modules/modular_computers/computers/modular_computer/power.dm
index 183ad33294e..97ee8674215 100644
--- a/code/modules/modular_computers/computers/modular_computer/power.dm
+++ b/code/modules/modular_computers/computers/modular_computer/power.dm
@@ -3,8 +3,9 @@
visible_message(SPAN_WARNING("\The [src]'s screen flickers briefly and then goes dark."))
if(active_program)
active_program.event_powerfailure(FALSE)
- for(var/datum/computer_file/program/PRG in idle_threads)
- PRG.event_powerfailure(TRUE)
+ for(var/datum/computer_file/program/PRG in hard_drive.stored_files)
+ if(PRG != active_program)
+ PRG.event_powerfailure(TRUE)
shutdown_computer(FALSE)
power_has_failed = TRUE
update_icon()
diff --git a/code/modules/modular_computers/computers/modular_computer/variables.dm b/code/modules/modular_computers/computers/modular_computer/variables.dm
index 6810fc99494..9b79adeab84 100644
--- a/code/modules/modular_computers/computers/modular_computer/variables.dm
+++ b/code/modules/modular_computers/computers/modular_computer/variables.dm
@@ -4,6 +4,7 @@
name = "Modular Computer"
desc = "A modular computer. You shouldn't see this."
+ var/lexical_name = "computer"
var/enabled = FALSE // Whether the computer is turned on.
var/screen_on = TRUE // Whether the computer is active/opened/it's screen is on.
var/working = TRUE // Whether the computer is working.
diff --git a/code/modules/modular_computers/computers/subtypes/dev_handheld.dm b/code/modules/modular_computers/computers/subtypes/dev_handheld.dm
index 0ffe87b34c6..4cb40032295 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_handheld.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_handheld.dm
@@ -1,5 +1,6 @@
/obj/item/modular_computer/handheld
name = "tablet computer"
+ lexical_name = "tablet"
desc = "A portable device for your needs on the go."
desc_info = "To deploy the charging cable on this device, either drag and drop it over a nearby APC, or click on the APC with the computer in hand."
icon = 'icons/obj/modular_tablet.dmi'
diff --git a/code/modules/modular_computers/computers/subtypes/dev_laptop.dm b/code/modules/modular_computers/computers/subtypes/dev_laptop.dm
index 38df46a87b7..0090c80e083 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_laptop.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_laptop.dm
@@ -1,6 +1,7 @@
/obj/item/modular_computer/laptop
anchored = TRUE
name = "laptop computer"
+ lexical_name = "laptop"
desc = "A portable computer."
desc_info = "You can alt-click the laptop while it's set down on surface to open it up and work with it. Left clicking while it is open will allow you to operate it."
hardware_flag = PROGRAM_LAPTOP
diff --git a/code/modules/modular_computers/computers/subtypes/dev_pda.dm b/code/modules/modular_computers/computers/subtypes/dev_pda.dm
index 00c61b358e7..12369654393 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_pda.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_pda.dm
@@ -1,5 +1,6 @@
/obj/item/modular_computer/handheld/pda
name = "PDA"
+ lexical_name = "tablet"
desc = "The latest in portable microcomputer solutions from Thinktronic Systems, LTD."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
diff --git a/code/modules/modular_computers/computers/subtypes/dev_silicon.dm b/code/modules/modular_computers/computers/subtypes/dev_silicon.dm
index 1ea422ac828..6767be11604 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_silicon.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_silicon.dm
@@ -53,7 +53,7 @@
/obj/item/modular_computer/silicon/install_default_programs()
hard_drive.store_file(new /datum/computer_file/program/filemanager(src))
hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(src))
- hard_drive.store_file(new /datum/computer_file/program/chatclient(src))
+ hard_drive.store_file(new /datum/computer_file/program/chat_client(src))
hard_drive.remove_file(hard_drive.find_file_by_name("clientmanager"))
addtimer(CALLBACK(src, .proc/register_chat), 1 SECOND)
@@ -62,24 +62,6 @@
enable_computer(null, TRUE) // passing null because we don't want the UI to open
minimize_program()
-/obj/item/modular_computer/silicon/verb/send_pda_message()
- set category = "AI IM"
- set name = "Send Direct Message"
- set src in usr
- if (usr.stat == DEAD)
- to_chat(usr, "You can't send PDA messages because you are dead!")
- return
- var/datum/computer_file/program/chatclient/CL = hard_drive.find_file_by_name("ntnrc_client")
- if(!istype(CL))
- output_error("Chat client not installed!")
- return
- else if(CL.program_state == PROGRAM_STATE_KILLED)
- run_program("ntnrc_client")
-
- CL.direct_message()
- if(CL.channel)
- CL.add_message(CL.send_message())
-
/obj/item/modular_computer/silicon/robot/drone/install_default_programs()
hard_drive.store_file(new /datum/computer_file/program/filemanager(src))
hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(src))
diff --git a/code/modules/modular_computers/computers/subtypes/dev_wristbound.dm b/code/modules/modular_computers/computers/subtypes/dev_wristbound.dm
index fffd01dd33c..f7c25243ea5 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_wristbound.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_wristbound.dm
@@ -1,5 +1,6 @@
/obj/item/modular_computer/handheld/wristbound
name = "wristbound computer"
+ lexical_name = "wristbound"
desc = "A portable wristbound device for your needs on the go. Quite comfortable."
desc_fluff = "A NanoTrasen design, this wristbound computer allows the user to quickly and safely access critical info, without taking their hands out of the equation."
icon = 'icons/obj/modular_wristbound.dmi'
diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
index 62c64e649fe..e3b727ea8df 100644
--- a/code/modules/modular_computers/file_system/program.dm
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -24,7 +24,7 @@
var/computer_emagged = FALSE // Set to TRUE if computer that's running us was emagged. Computer updates this every Process() tick
var/ui_header // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images!
var/color = "#FFFFFF" // The color of light the computer should emit when this program is open.
- var/service_state = PROGRAM_STATE_KILLED // PROGRAM_STATE_KILLED or PROGRAM_STATE_ACTIVE - specifies whether this program's service is running.
+ var/service_state = PROGRAM_STATE_DISABLED // PROGRAM_STATE_KILLED or PROGRAM_STATE_ACTIVE - specifies whether this program's service is running.
var/silent = FALSE
/datum/computer_file/program/New(var/obj/item/modular_computer/comp)
@@ -196,27 +196,6 @@
if(computer)
return computer.get_header_data()
-// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
-// When implementing new program based device, use this to run the program.
-/datum/computer_file/program/proc/run_program(var/mob/user)
- if(can_run(user, 1) || !requires_access_to_run)
- if(nanomodule_path)
- NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
- if(requires_ntnet && network_destination)
- generate_network_log("Connection opened to [network_destination].")
- program_state = PROGRAM_STATE_ACTIVE
- return TRUE
- return FALSE
-
-// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
-/datum/computer_file/program/proc/kill_program(var/forced = 0)
- program_state = PROGRAM_STATE_KILLED
- if(network_destination)
- generate_network_log("Connection to [network_destination] closed.")
- if(NM)
- qdel(NM)
- NM = null
- return TRUE
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable.
@@ -248,18 +227,9 @@
else
return -1
-// Is called when program service is being activated
-// Returns 1 if service startup was sucessfull
-/datum/computer_file/program/proc/service_activate()
- return FALSE
-
-// Is called when program service is being deactivated
-/datum/computer_file/program/proc/service_deactivate()
- return
-
/datum/computer_file/program/proc/message_dead(var/message)
for(var/mob/M in player_list)
if(M.stat == DEAD && (M.client && M.client.prefs.toggles & CHAT_GHOSTEARS))
if(isnewplayer(M))
continue
- to_chat(M, message)
+ to_chat(M, message)
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm
index 8172ddcb299..a0d469ae79b 100644
--- a/code/modules/modular_computers/file_system/program_events.dm
+++ b/code/modules/modular_computers/file_system/program_events.dm
@@ -1,6 +1,47 @@
// Events are sent to the program by the computer.
// Always include a parent call when overriding an event.
+// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
+// When implementing new program based device, use this to run the program.
+/datum/computer_file/program/proc/run_program(var/mob/user)
+ if(can_run(user, 1) || !requires_access_to_run)
+ if(nanomodule_path)
+ NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
+ if(requires_ntnet && network_destination)
+ generate_network_log("Connection opened to [network_destination].")
+ program_state = PROGRAM_STATE_ACTIVE
+ return TRUE
+ return FALSE
+
+// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
+/datum/computer_file/program/proc/kill_program(var/forced = 0)
+ program_state = PROGRAM_STATE_KILLED
+ if(network_destination)
+ generate_network_log("Connection to [network_destination] closed.")
+ if(NM)
+ qdel(NM)
+ NM = null
+ return TRUE
+
+// Is called when program service is being activated
+// Returns 1 if service startup was sucessfull
+/datum/computer_file/program/proc/service_activate()
+ return FALSE
+
+// Is called when program service is being deactivated
+/datum/computer_file/program/proc/service_deactivate()
+ return
+
+// Is called when program service is being activated for first time.
+/datum/computer_file/program/proc/service_enable()
+ return service_activate()
+
+// Is called when program service is being deactivated without
+/datum/computer_file/program/proc/service_disable()
+ return service_deactivate()
+
+/// SECOND ORDER EVENTS
+
// Called when the ID card is removed from computer. ID is removed AFTER this proc.
/datum/computer_file/program/proc/event_idremoved(var/background)
return
@@ -9,12 +50,17 @@
return
// Called when an ID is unregistered from the device.
-/datum/computer_file/program/proc/event_unregistered(var/background)
+/datum/computer_file/program/proc/event_unregistered()
+ return
+
+// Called when an ID is unregistered from the device.
+/datum/computer_file/program/proc/event_registered()
return
// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.
/datum/computer_file/program/proc/event_powerfailure(var/background)
- kill_program(TRUE)
+ if(program_state > PROGRAM_STATE_KILLED)
+ kill_program(TRUE)
// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met.
/datum/computer_file/program/proc/event_networkfailure(var/background)
diff --git a/code/modules/modular_computers/file_system/programs/app_presets.dm b/code/modules/modular_computers/file_system/programs/app_presets.dm
index b5b771662ea..5cc1792e079 100644
--- a/code/modules/modular_computers/file_system/programs/app_presets.dm
+++ b/code/modules/modular_computers/file_system/programs/app_presets.dm
@@ -32,7 +32,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/power_monitor(comp),
new /datum/computer_file/program/alarm_monitor(comp),
@@ -56,7 +56,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/power_monitor(comp),
new /datum/computer_file/program/alarm_monitor(comp),
@@ -81,7 +81,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/comm(comp, FALSE),
new /datum/computer_file/program/game/sudoku(comp),
@@ -108,7 +108,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/suit_sensors(comp),
new /datum/computer_file/program/records/medical(comp),
@@ -130,7 +130,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/comm(comp, FALSE),
new /datum/computer_file/program/suit_sensors(comp),
@@ -155,7 +155,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/ntnetmonitor(comp),
new /datum/computer_file/program/aidiag(comp),
@@ -178,7 +178,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/ntnetmonitor(comp),
new /datum/computer_file/program/aidiag(comp),
@@ -201,7 +201,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/comm(comp, FALSE),
new /datum/computer_file/program/ntnetmonitor(comp),
@@ -225,7 +225,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/card_mod(comp),
new /datum/computer_file/program/comm(comp, FALSE),
@@ -246,7 +246,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/civilian/cargocontrol(comp),
new /datum/computer_file/program/card_mod(comp),
@@ -269,7 +269,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/card_mod(comp),
new /datum/computer_file/program/comm(comp, FALSE),
new /datum/computer_file/program/camera_monitor(comp),
@@ -317,7 +317,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/camera_monitor(comp),
new /datum/computer_file/program/comm(comp),
@@ -341,7 +341,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/camera_monitor(comp),
new /datum/computer_file/program/comm(comp),
@@ -367,7 +367,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/camera_monitor(comp),
new /datum/computer_file/program/digitalwarrant(comp),
new /datum/computer_file/program/penal_mechs(comp),
@@ -391,7 +391,7 @@
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/filemanager(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/comm(comp, FALSE),
new /datum/computer_file/program/camera_monitor(comp),
@@ -415,7 +415,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/game/arcade(comp),
new /datum/computer_file/program/game/sudoku(comp),
@@ -435,7 +435,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/civilian/janitor(comp),
new /datum/computer_file/program/game/arcade(comp),
@@ -468,7 +468,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargocontrol(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/civilian/cargodelivery(comp),
@@ -488,7 +488,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargodelivery(comp),
new /datum/computer_file/program/ntsl2_interpreter(comp)
)
@@ -506,7 +506,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/game/sudoku(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/records/employment(comp),
@@ -525,7 +525,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/newsbrowser(comp),
new /datum/computer_file/program/manifest(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/civilian/cargoorder(comp),
new /datum/computer_file/program/camera_monitor(comp),
new /datum/computer_file/program/alarm_monitor(comp),
@@ -594,7 +594,7 @@
new /datum/computer_file/program/filemanager(comp),
new /datum/computer_file/program/manifest(comp),
new /datum/computer_file/program/newsbrowser(comp),
- new /datum/computer_file/program/chatclient(comp),
+ new /datum/computer_file/program/chat_client(comp),
new /datum/computer_file/program/merchant(comp)
)
return _prg_list
diff --git a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm
index c1bf676e2c3..a4bac57b0a4 100644
--- a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm
+++ b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm
@@ -1,381 +1,253 @@
-/datum/computer_file/program/chatclient
+/datum/computer_file/program/chat_client
filename = "ntnrc_client"
filedesc = "Chat Client"
program_icon_state = "command"
- extended_desc = "This program allows communication over the NTNRC network."
+ extended_desc = "This program allows communication over the NTRC network."
size = 2
requires_ntnet = TRUE
requires_ntnet_feature = NTNET_COMMUNICATION
- network_destination = "NTNRC server"
- ui_header = "ntnrc_idle.gif"
+ program_type = PROGRAM_TYPE_ALL
+ network_destination = "NTRC server"
available_on_ntnet = TRUE
- nanomodule_path = /datum/nano_module/program/computer_chatclient
color = LIGHT_COLOR_GREEN
silent = FALSE
- var/last_message // Used to generate the toolbar icon
- var/username
- var/datum/ntnet_conversation/channel
- var/operator_mode = FALSE // Channel operator mode
+ var/datum/ntnet_user/my_user
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
- var/set_offline = FALSE // appear "invisible"
- var/list/directmessagechannels = list()
+ var/set_offline = FALSE // appear "invisible"
var/ringtone = "beep"
var/syndi_auth = FALSE
-/datum/computer_file/program/chatclient/New(var/obj/item/modular_computer/comp)
- ..(comp)
- if(!comp)
- return
-/datum/computer_file/program/chatclient/Destroy()
- ntnet_global.chat_clients -= src
+/datum/computer_file/program/chat_client/Destroy()
return ..()
-/datum/computer_file/program/chatclient/Topic(href, href_list)
+/datum/computer_file/program/chat_client/proc/can_receive_notification(var/datum/computer_file/program/chat_client/from)
+ return ((program_state > PROGRAM_STATE_KILLED || service_state > PROGRAM_STATE_KILLED) && from != src && get_signal(NTNET_COMMUNICATION))
+
+/datum/computer_file/program/chat_client/proc/play_notification_sound(var/datum/computer_file/program/chat_client/from)
+ if(!silent && src != from && program_state == PROGRAM_STATE_BACKGROUND)
+ playsound(computer, 'sound/machines/twobeep.ogg', 50, 1)
+ computer.output_message("[icon2html(computer, world)] *[ringtone]*", 2)
+
+/datum/computer_file/program/chat_client/Topic(href, href_list)
if(..())
return TRUE
-
- if(href_list["PRG_toggleringer"])
- . = TRUE
- silent = !silent
-
- if(href_list["PRG_setringtone"])
- . = TRUE
- var/t = input(usr, "Please enter new ringtone", filedesc, ringtone) as text|null
- if(!usr.Adjacent(computer) || !t)
- return
+
+ if(href_list["ringtone"])
+ var/newRingtone = href_list["ringtone"]
var/obj/item/device/uplink/hidden/H = computer.hidden_uplink
- if(istype(H) && H.check_trigger(usr, lowertext(t), lowertext(H.pda_code)))
+ if(istype(H) && H.check_trigger(usr, lowertext(newRingtone), lowertext(H.pda_code)))
to_chat(usr, SPAN_NOTICE("\The [computer] softly beeps."))
syndi_auth = TRUE
- SSnanoui.close_uis(NM)
+ SSvueui.close_uis(src)
else
- t = sanitize(t, 20)
- ringtone = t
-
- if(href_list["PRG_speak"])
- . = TRUE
- add_message(send_message())
-
- if(href_list["Reply"])
- . = TRUE
- var/datum/ntnet_conversation/C = locate(href_list["Reply"]) in ntnet_global.chat_channels
- if(!istype(C))
- to_chat(usr, SPAN_WARNING("The target channel couldn't be found and has likely been deleted!"))
- return
- var/message = send_message()
- if(!(C in ntnet_global.chat_channels))
- to_chat(usr, SPAN_WARNING("The target channel couldn't be found and has likely been deleted!"))
- return
- add_message(message, C)
-
- if(href_list["PRG_joinchannel"])
- . = TRUE
- var/datum/ntnet_conversation/C
- for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
- if(chan.id == text2num(href_list["PRG_joinchannel"]))
- C = chan
- break
-
- if(!C)
- return TRUE
-
- if(netadmin_mode)
- channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
- return TRUE
-
- if(C.password)
- var/mob/living/user = usr
- var/password = sanitize(input(user, "Access Denied. Enter password:"))
- if(C?.password == password)
- C.add_client(src)
- channel = C
- return TRUE
- C.add_client(src)
- message_dead(FONT_SMALL("([C.get_dead_title()]) A new client ([username]) has entered the chat."))
- channel = C
- if(href_list["PRG_leavechannel"])
- . = TRUE
- if(channel && !channel.direct)
- channel.remove_client(src)
- message_dead(FONT_SMALL(FONT_SMALL("([channel.get_dead_title()]) A client ([username]) has left the chat.")))
- channel = null
- if(href_list["PRG_backtomain"])
- . = TRUE
- channel = null
- if(href_list["PRG_newchannel"])
- . = TRUE
+ newRingtone = sanitize(newRingtone, 20)
+ ringtone = newRingtone
+ SSvueui.check_uis_for_change(src)
+
+ // User only commands
+ if(!istype(my_user))
+ return
+ // Following actions require signal
+ if(!get_signal(NTNET_COMMUNICATION))
+ return
+
+ if(href_list["send"])
var/mob/living/user = usr
- var/channel_title = sanitize(input(user, "Enter channel name or leave blank to cancel:"))
- if(!channel_title)
- return
- var/datum/ntnet_conversation/C = new /datum/ntnet_conversation(channel_title)
- C.add_client(src)
- C.operator = src
- channel = C
- message_dead(FONT_SMALL("([channel.get_dead_title()]) A new channel has been made by [username]."))
- if(href_list["PRG_toggleadmin"])
- . = TRUE
+ var/datum/ntnet_conversation/conv = locate(href_list["send"]["target"])
+ var/message = href_list["send"]["message"]
+ if(istype(conv) && message)
+ if(ishuman(user))
+ user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] [computer.lexical_name]'s screen.")
+ conv.cl_send(src, message, user)
+ if(href_list["join"])
+ var/datum/ntnet_conversation/conv = locate(href_list["join"]["target"])
+ var/password = href_list["join"]["password"]
+ if(istype(conv))
+ if(conv.password)
+ if(conv.password == password)
+ conv.cl_join(src)
+ else
+ // How do I alert of password invalid?
+ else
+ conv.cl_join(src)
+ if(href_list["leave"])
+ var/datum/ntnet_conversation/conv = locate(href_list["leave"])
+ if(istype(conv))
+ conv.cl_leave(src)
+ SSvueui.check_uis_for_change(src)
+ if(href_list["kick"])
+ var/datum/ntnet_conversation/conv = locate(href_list["kick"]["target"])
+ var/datum/ntnet_user/tUser = locate(href_list["kick"]["user"])
+ if(istype(conv) && istype(tUser))
+ conv.cl_kick(src, tUser)
+ if(href_list["set_password"])
+ var/datum/ntnet_conversation/conv = locate(href_list["set_password"]["target"])
+ var/password = href_list["set_password"]["password"]
+ if(istype(conv))
+ conv.cl_set_password(src, password)
+ if(href_list["change_title"])
+ var/datum/ntnet_conversation/conv = locate(href_list["change_title"]["target"])
+ var/newTitle = href_list["change_title"]["title"]
+ if(istype(conv))
+ conv.cl_change_title(src, newTitle)
+ if(href_list["new_channel"])
+ ntnet_global.begin_conversation(src, sanitize(href_list["new_channel"]))
+ if(href_list["delete"])
+ var/datum/ntnet_conversation/conv = locate(href_list["delete"])
+ if(istype(conv) && conv.can_manage(src))
+ ntnet_global.chat_channels.Remove(conv)
+ qdel(conv)
+ SSvueui.check_uis_for_change(src)
+ if(href_list["direct"])
+ var/datum/ntnet_user/tUser = locate(href_list["direct"])
+ ntnet_global.begin_direct(src, tUser)
+
+ if(href_list["toggleadmin"])
if(netadmin_mode)
netadmin_mode = FALSE
- if(channel)
- channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
- channel = null
- return TRUE
- var/mob/living/user = usr
- if(can_run(usr, 1, access_network))
- if(channel)
- var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No")
- if(response == "Yes")
- if(channel)
- channel.remove_client(src)
- channel = null
- else
- return
- netadmin_mode = TRUE
- if(href_list["PRG_changename"])
- . = TRUE
- var/mob/living/user = usr
- var/new_name = sanitize(input(user, "Enter new nickname or leave blank to cancel:"))
- if(!new_name)
- return TRUE
- var/comp_name = ckey(new_name)
- for(var/cl in ntnet_global.chat_clients)
- var/datum/computer_file/program/chatclient/C = cl
- if(ckey(C.username) == comp_name || comp_name == "cancel")
- alert(user, "This nickname is already taken.")
- return TRUE
- for(var/datum/ntnet_conversation/channel in ntnet_global.chat_channels)
- if(src in channel.clients)
- channel.add_status_message("[username] is now known as [new_name].")
- username = new_name
- if(href_list["PRG_savelog"])
- . = TRUE
- if(!channel)
- return
- var/mob/living/user = usr
- var/logname = input(user, "Enter desired logfile name (.log) or leave blank to cancel:")
- if(!logname || !channel)
- return TRUE
- var/datum/computer_file/data/logfile = new /datum/computer_file/data/logfile()
- // Now we will generate HTML-compliant file that can actually be viewed/printed.
- logfile.filename = logname
- logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]"
- for(var/logstring in channel.messages)
- logfile.stored_data += "[logstring]\[BR\]"
- logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]"
- logfile.calculate_size()
- if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile))
- if(!computer)
- // This program shouldn't even be runnable without computer.
- crash_with("Var computer is null!")
- return TRUE
- if(!computer.hard_drive)
- computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
- else // In 99.9% cases this will mean our HDD is full
- computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")
- if(href_list["PRG_renamechannel"])
- . = TRUE
- if(!operator_mode || !channel)
- return TRUE
- var/mob/living/user = usr
- var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:"))
- if(!newname || !channel)
- return
- channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
- channel.title = newname
- if(href_list["PRG_deletechannel"])
- . = TRUE
- if(channel && ((channel.operator == src) || netadmin_mode))
- qdel(channel)
- channel = null
- if(href_list["PRG_setpassword"])
- . = TRUE
- if(!channel || ((channel.operator != src) && !netadmin_mode))
- return TRUE
-
- var/mob/living/user = usr
- var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:"))
- if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode))
- return TRUE
-
- if(newpassword == "nopassword")
- channel.password = ""
else
- channel.password = newpassword
- if(href_list["PRG_directmessage"])
- . = TRUE
- direct_message(usr)
-
-/datum/computer_file/program/chatclient/proc/send_message()
- var/mob/living/user = usr
- if(ishuman(user))
- user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] computer's screen.")
- var/message = sanitize(input(user, "Enter a message to send: ") as null|text)
- if(!message)
- return
- return message
-
-/datum/computer_file/program/chatclient/proc/add_message(var/message, var/datum/ntnet_conversation/specific_channel)
- if(!message)
- return
- var/datum/ntnet_conversation/sent_channel
- if(specific_channel)
- sent_channel = specific_channel
+ var/mob/living/user = usr
+ if(can_run(user, TRUE, access_network))
+ netadmin_mode = TRUE
+ SSvueui.check_uis_for_change(src)
+ if(href_list["Reply"])
+ var/mob/living/user = usr
+ var/datum/ntnet_conversation/conv = locate(href_list["Reply"])
+ var/message = input(user, "Enter message or leave blank to cancel: ")
+ if(istype(conv) && message)
+ if(ishuman(user))
+ user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] [computer.lexical_name]'s screen.")
+ conv.cl_send(src, message, user)
+
+
+/datum/computer_file/program/chat_client/service_activate()
+ . = ..()
+ if(istype(my_user) && get_signal(NTNET_COMMUNICATION))
+ activate_chat_client()
+ return TRUE
else
- sent_channel = channel
- if(!sent_channel) // panikk - geeves
- return
- sent_channel.add_message(message, username, usr)
- message_dead(FONT_SMALL("([sent_channel.get_dead_title()]) [username]: [message]"))
+ return FALSE
-/datum/computer_file/program/chatclient/proc/direct_message(var/mob/user)
- var/clients = list()
- var/names = list()
- for(var/cl in ntnet_global.chat_clients - src)
- var/datum/computer_file/program/chatclient/C = cl
- if(C.set_offline)
- continue
- clients[C.username] = C
- names += C.username
- if(!length(names))
- to_chat(user, SPAN_WARNING("You are the only user with an active account!"))
- return
- var/picked = input(user, "Select with whom you would like to start a conversation.") as null|anything in names
- if(!picked)
- return
- var/datum/computer_file/program/chatclient/otherClient = clients[picked]
- if(picked)
- if(directmessagechannels[otherClient])
- channel = directmessagechannels[otherClient]
- return
- var/datum/ntnet_conversation/C = new /datum/ntnet_conversation("", TRUE)
- C.begin_direct(src, otherClient)
- channel = C
- directmessagechannels[otherClient] = C
- otherClient.directmessagechannels[src] = C
+/datum/computer_file/program/chat_client/service_deactivate()
+ . = ..()
+ deactivate_chat_client()
+/datum/computer_file/program/chat_client/process_tick()
+ . = ..()
-/datum/computer_file/program/chatclient/process_tick()
- ..()
- if(program_state != PROGRAM_STATE_KILLED)
- ui_header = "ntnrc_idle.gif"
- if(channel)
- // Remember the last message. If there is no message in the channel remember null.
- if(length(channel.messages) > 1) // len - 1 = 0 and that's array out of bounds
- last_message = channel.messages[channel.messages.len - 1]
- else
- last_message = null
+/datum/computer_file/program/chat_client/kill_program(var/forced = FALSE)
+ return ..(forced)
+
+/datum/computer_file/program/chat_client/run_program(var/mob/user)
+ if(!istype(my_user))
+ if(istype(computer, /obj/item/modular_computer/silicon))
+ var/obj/item/modular_computer/silicon/SC = computer
+ var/mob/living/silicon/S = SC.computer_host
+ S.id_card.InitializeChatUser()
+ my_user = S.id_card.chat_user
else
- last_message = null
- return 1
- if(channel?.messages?.len)
- ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
- else
- ui_header = "ntnrc_idle.gif"
-
-/datum/computer_file/program/chatclient/kill_program(var/forced = FALSE)
- if(!forced)
- var/confirm = alert("Are you sure you want to close the NTNRC Client? You will not be reachable via messaging if you do so.", "Close?", "Yes", "No")
- if((confirm != "Yes") || (CanUseTopic(usr) != STATUS_INTERACTIVE))
- return FALSE
-
- ntnet_global.chat_clients -= src
-
- channel = null
- ..(forced)
- return TRUE
-
-/datum/computer_file/program/chatclient/run_program(var/mob/user)
- if(!computer)
- return
- if(!istype(computer, /obj/item/modular_computer/silicon))
- if((!computer.registered_id && !computer.register_account(src)))
+ if((!computer.registered_id && !computer.register_account(src)))
+ return
+ if(service_state == PROGRAM_STATE_DISABLED)
+ if(!computer.enable_service(null, user, src))
return
- if(!(src in ntnet_global.chat_clients))
- ntnet_global.chat_clients += src
- if(!username)
- username = username_from_id()
return ..(user)
-/datum/computer_file/program/chatclient/proc/username_from_id()
- if(istype(computer, /obj/item/modular_computer/silicon))
- var/obj/item/modular_computer/silicon/SC = computer
- return SC.computer_host.name
- if(!computer.registered_id)
- return "Unknown"
+/datum/computer_file/program/chat_client/event_registered()
+ . = ..()
+ computer.registered_id.InitializeChatUser()
+ my_user = computer.registered_id.chat_user
+ if(service_state > PROGRAM_STATE_KILLED)
+ activate_chat_client()
+
- return "[computer.registered_id.registered_name] ([computer.registered_id.assignment])"
+/datum/computer_file/program/chat_client/event_unregistered()
+ . = ..()
+ if(service_state > PROGRAM_STATE_KILLED)
+ deactivate_chat_client()
+ my_user = null
-/datum/computer_file/program/chatclient/event_unregistered()
- ..()
- computer.set_autorun(filename)
- ntnet_global.chat_clients -= src
- kill_program(TRUE)
+/datum/computer_file/program/chat_client/event_silentmode()
+ . = ..()
+ silent = computer.silent
-/datum/computer_file/program/chatclient/event_silentmode()
- ..()
- if(computer.silent != silent)
- silent = computer.silent
-/datum/nano_module/program/computer_chatclient
- name = "Chat Client"
-
-/datum/nano_module/program/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
- if(!ntnet_global || !ntnet_global.chat_channels)
- return
-
- var/datum/computer_file/program/chatclient/C = program
-
- if(C.computer.hidden_uplink && C.syndi_auth)
- if(alert(user, "Resume or close and secure?", name, "Resume", "Close") == "Resume")
- C.computer.hidden_uplink.trigger(user)
+/datum/computer_file/program/chat_client/ui_interact(var/mob/user)
+ if(computer.hidden_uplink && syndi_auth)
+ if(alert(user, "Resume or close and secure?", filedesc, "Resume", "Close") == "Resume")
+ computer.hidden_uplink.trigger(user)
return
else
- C.syndi_auth = FALSE
+ syndi_auth = FALSE
- var/list/data = list()
- if(program)
- data = list("_PC" = program.get_header_data())
-
- if(!istype(C))
- return
-
- data["adminmode"] = C.netadmin_mode
- if(C.channel)
- data["title"] = C.channel.get_title(C)
- var/list/messages[0]
- for(var/M in C.channel.messages)
- messages.Add(list(list(
- "msg" = M
- )))
- data["messages"] = messages
- var/list/clients[0]
- for(var/datum/computer_file/program/chatclient/cl in C.channel.clients)
- clients.Add(list(list(
- "name" = cl.username,
- "active" = cl.program_state > PROGRAM_STATE_KILLED
- )))
- data["clients"] = clients
- C.operator_mode = (C.channel.operator == C) ? 1 : 0
- data["is_operator"] = C.operator_mode || C.netadmin_mode
- data["is_direct"] = C.channel.direct
- else // Channel selection screen
- var/list/all_channels[0]
- for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels)
- if(conv && conv.title && conv.can_see(program))
- all_channels.Add(list(list(
- "chan" = conv.get_title(C),
- "id" = conv.id,
- "con" = (program in conv.clients)
- )))
- data["all_channels"] = all_channels
-
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
+ var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
if (!ui)
- ui = new(user, src, ui_key, "ntnet_chat.tmpl", "NTNet Relay Chat Client", 575, 700, state = state)
- ui.auto_update_layout = 1
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(TRUE)
+ ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-chat-index", 600, 500, capitalize(filedesc))
+ ui.open()
+
+/datum/computer_file/program/chat_client/vueui_transfer(oldobj)
+ SSvueui.transfer_uis(oldobj, src, "mcomputer-chat-index", 600, 500, capitalize(filedesc))
+ return TRUE
+
+/datum/computer_file/program/chat_client/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
+ . = ..()
+ data = . || data || list()
+ // Gather data for computer header
+ var/headerdata = get_header_data(data["_PC"])
+ if(headerdata)
+ data["_PC"] = headerdata
+ . = data
+
+ data["service"] = service_state > PROGRAM_STATE_KILLED
+ data["registered"] = istype(my_user)
+ data["signal"] = get_signal(NTNET_COMMUNICATION)
+ data["ringtone"] = ringtone
+ data["netadmin_mode"] = netadmin_mode
+ data["can_netadmin_mode"] = can_run(user, FALSE, access_network)
+
+ if(data["registered"] && data["service"] && data["signal"])
+ data["channels"] = list()
+ for(var/c in ntnet_global.chat_channels)
+ var/datum/ntnet_conversation/Channel = c
+ if(istype(Channel) && Channel.can_see(src))
+ var/ref = ref(Channel)
+ var/can_interact = Channel.can_interact(src)
+ var/can_manage = Channel.can_manage(src)
+ data["channels"][ref] = list(
+ "title" = Channel.get_title(src),
+ "direct" = Channel.direct,
+ "password" = !!Channel.password,
+ "can_interact" = can_interact,
+ "can_manage" = can_manage
+ )
+ if(can_interact)
+ data["channels"][ref]["msg"] = Channel.messages
+ data["channels"][ref]["users"] = list()
+ for(var/datum/ntnet_user/U in Channel.users)
+ var/uref = ref(U)
+ data["channels"][ref]["users"][uref] = U.username
+ data["users"] = list()
+ for(var/u in ntnet_global.chat_users)
+ var/datum/ntnet_user/nUser = u
+ if(nUser != my_user)
+ var/ref = ref(nUser)
+ data["users"][ref] = nUser.username
+ return data
+
+/datum/computer_file/program/chat_client/proc/activate_chat_client()
+ if(!istype(my_user))
+ return
+ if(!(src in my_user.clients))
+ my_user.clients.Add(src)
+ if(!(src in ntnet_global.chat_clients))
+ ntnet_global.chat_clients.Add(src)
+
+/datum/computer_file/program/chat_client/proc/deactivate_chat_client()
+ if(!istype(my_user))
+ return
+ if(src in my_user.clients)
+ my_user.clients.Remove(src)
+ if(src in ntnet_global.chat_clients)
+ ntnet_global.chat_clients.Remove(src)
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/programs/system/client_manager.dm b/code/modules/modular_computers/file_system/programs/system/client_manager.dm
index 6374d725a21..a38b2f5f0ea 100644
--- a/code/modules/modular_computers/file_system/programs/system/client_manager.dm
+++ b/code/modules/modular_computers/file_system/programs/system/client_manager.dm
@@ -70,7 +70,7 @@
computer.enrolled = 2 // private devices
computer.hard_drive.store_file(new /datum/computer_file/program/filemanager(computer))
computer.hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(computer))
- computer.hard_drive.store_file(new /datum/computer_file/program/chatclient(computer))
+ computer.hard_drive.store_file(new /datum/computer_file/program/chat_client(computer))
return TRUE
//Set´s up the programs from the preset
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 39e6d5d0b35..8d0b9dec0f7 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -82,6 +82,7 @@
var/list/genetic_markings // Markings (body_markings) to apply to the icon
var/list/temporary_markings // Same as above, but not preserved when cloning
var/list/cached_markings // The two above lists cached for perf. reasons.
+ var/list/additional_images
var/atom/movable/applied_pressure //Pressure applied to wounds. It'll make them bleed less, generally.
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index c3fd7fce6c9..61fd17c31c8 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -112,6 +112,7 @@
if(vampire && (vampire.status & VAMP_FRENZIED))
var/image/return_image = image(H.species.eyes_icons, H, "[H.species.eyes]_frenzy", EFFECTS_ABOVE_LIGHTING_LAYER)
return_image.appearance_flags = KEEP_APART
+ LAZYADD(additional_images, return_image)
return list(return_image)
/obj/item/organ/external/proc/apply_markings(restrict_to_robotic = FALSE)
@@ -223,6 +224,11 @@
/obj/item/organ/external/proc/get_additional_images(var/mob/living/carbon/human/H)
return
+/obj/item/organ/external/proc/cut_additional_images(var/mob/living/carbon/human/H)
+ if(LAZYLEN(additional_images))
+ H.cut_overlay(additional_images, TRUE)
+ LAZYCLEARLIST(additional_images)
+
// new damage icon system
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
/obj/item/organ/external/update_icon()
diff --git a/code/modules/projectiles/guns/energy/disrupter.dm b/code/modules/projectiles/guns/energy/disrupter.dm
index f08d5eaf51b..ec12cef41d1 100644
--- a/code/modules/projectiles/guns/energy/disrupter.dm
+++ b/code/modules/projectiles/guns/energy/disrupter.dm
@@ -17,7 +17,6 @@
secondary_projectile_type = /obj/item/projectile/energy/blaster
max_shots = 8
charge_cost = 150
- fire_delay = 8
accuracy = 1
has_item_ratio = FALSE
modifystate = "disruptorpistolstun"
@@ -35,7 +34,7 @@
name = "miniature disruptor pistol"
desc = "A Nanotrasen designed blaster pistol with two settings: stun and lethal. This is the miniature version."
icon = 'icons/obj/guns/disruptorpistol/disruptorpistolc.dmi'
- max_shots = 5
+ max_shots = 6
force = 3
slot_flags = SLOT_BELT|SLOT_HOLSTER|SLOT_POCKET
w_class = ITEMSIZE_SMALL
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 905b9f9471c..38c205a78d9 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -208,7 +208,7 @@
/obj/item/projectile/energy/disruptorstun
name = "disruptor bolt"
icon_state = "blue_laser"
- agony = 25
+ agony = 30
speed = 0.4
damage_type = PAIN // Can't blow your own head off with a stunbolt.
taser_effect = TRUE
diff --git a/code/modules/psionics/equipment/cerebro_enhancers.dm b/code/modules/psionics/equipment/cerebro_enhancers.dm
index 684a3c53aa0..0fb48ce86d5 100644
--- a/code/modules/psionics/equipment/cerebro_enhancers.dm
+++ b/code/modules/psionics/equipment/cerebro_enhancers.dm
@@ -2,6 +2,7 @@
/obj/item/clothing/head/helmet/space/psi_amp
name = "cerebro-energetic enhancer"
desc = "A matte-black, eyeless cerebro-energetic enhancement helmet. It uses highly sophisticated, and illegal, techniques to drill into your brain and install psi-infected AIs into the fluid cavities between your lobes."
+ desc_info = "Due to the nature of this headgear, it will also protect you from the pressure of space. When installing the boosters, your chosen faculties will be boosted to the headgear's maximum potential, but the unchosen faculties will also be boosted somewhat."
action_button_name = "Install Boosters"
icon_state = "amp"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index e6518d901d3..8c2f56386e7 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -561,7 +561,8 @@
if((locate(/datum/reagent/adrenaline) in M.reagents.reagent_list))
if(M.reagents.get_reagent_amount(/datum/reagent/adrenaline) > 5) //So you can tolerate being attacked whilst hyperzine is in your system.
- overdose = volume/2 //Straight to overdose.
+ overdose = 10 //Volume of hyperzine required to OD reduced from 15u to 10u.
+ od_minimum_dose = 0
/datum/reagent/hyperzine/overdose(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustNutritionLoss(5*removed)
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index 93fc79f3418..8d8fecb7247 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -636,9 +636,9 @@
name = "Saline Plus"
id = "saline"
result = /datum/reagent/saline
- required_reagents = list(/datum/reagent/water = 2, /datum/reagent/sugar = 0.2, /datum/reagent/sodiumchloride = 0.4)
+ required_reagents = list(/datum/reagent/water = 2, /datum/reagent/sugar = 0.5, /datum/reagent/sodiumchloride = 1)
catalysts = list(/datum/reagent/toxin/phoron = 5)
- result_amount = 1
+ result_amount = 2
/datum/chemical_reaction/cataleptinol
name = "Cataleptinol"
diff --git a/config/example/config.txt b/config/example/config.txt
index 47d71d6088c..983fbb02585 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -128,6 +128,7 @@ PROBABILITY S EXTENDED 1
PROBABILITY S MALFUNCTION 1
PROBABILITY S MERCENARY 1
PROBABILITY S WIZARD 1
+PROBABILITY S LONER 1
PROBABILITY S CHANGELING 1
PROBABILITY S CULT 1
PROBABILITY S BURGLARS 1
diff --git a/html/changelog.html b/html/changelog.html
index a1222502591..6c05635cba6 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -35,6 +35,50 @@
-->
| {{:helper.link("Return to channel list", null, {'PRG_backtomain' : 1})}} - |
| {{:helper.link("Direct message", null, {'PRG_directmessage' : 1})}} - |
| {{:helper.link("Change nickname", null, {'PRG_changename' : 1})}} - |
| {{:helper.link("Toggle administration mode", null, {'PRG_toggleadmin' : 1})}} - {{if !data.is_direct}} - |
| {{:helper.link("Leave channel", null, {'PRG_leavechannel' : 1})}} - {{/if}} - |
| {{:helper.link("Save log to local drive", null, {'PRG_savelog' : 1})}} - {{if data.is_operator}} - |
| {{:helper.link("Rename channel", null, {'PRG_renamechannel' : 1})}} - |
| {{:helper.link("Set password", null, {'PRG_setpassword' : 1})}} - |
| {{:helper.link("Delete channel", null, {'PRG_deletechannel' : 1})}} - {{/if}} - |
| {{:helper.link("Send message", null, {'PRG_speak' : 1})}} |
| {{:helper.link("Direct message", null, {'PRG_directmessage' : 1})}} - |
| {{:helper.link("Change nickname", null, {'PRG_changename' : 1})}} - |
| {{:helper.link("New Channel", null, {'PRG_newchannel' : 1})}} - |
| {{:helper.link("Toggle Administration Mode", null, {'PRG_toggleadmin' : 1})}} - |
| {{:helper.link("Toggle Ringer", null, {'PRG_toggleringer' : 1})}} - |
| {{:helper.link("Set Ringtone", null, {'PRG_setringtone' : 1})}} - |
| {{:helper.link(value.chan, null, {'PRG_joinchannel' : value.id}, null, value.con ? 'selected' : null)}} - {{/for}} - |
|
- Device Type:
-
- {{:helper.link('Company', null, { "PRG_dev_type" : 1 }, data.dev_type == 1 ? 'selected' : null)}}
- {{:helper.link('Private', null, { "PRG_dev_type" : 2 }, data.dev_type == 2 ? 'selected' : null)}}
-
- |
-
- {{if data.dev_type == 1}}
- Device Preset:
-
- {{for data.dev_presets}}
-
- {{/if}}
- {{:helper.link(value.display_name,null,{"PRG_dev_preset" : value.name}, value.name == data.dev_preset ? 'selected' : null)}}
- {{/for}}
- |
-
|
- Enroll Device:
- {{:helper.link('Confirm', null, { "PRG_enroll" : 1 })}}
- |
-
{{url}}{{ JSON.stringify(this.$root.$data, null, \' \') }}{{url}}{{ JSON.stringify(this.$root.$data, null, \' \') }}=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"===typeof t.then&&"function"===typeof t.catch}function p(t){return null==t?"":Array.isArray(t)||l(t)&&t.toString===c?JSON.stringify(t,null,2):String(t)}function h(t){var e=parseFloat(t);return isNaN(e)?t:e}function m(t,e){for(var n=Object.create(null),r=t.split(","),a=0;a 1)throw new Error('"weight" property in key must bein the range of [0, 1)');i=null==i?f:Math.max(i,f),a=null==a?f:Math.min(a,f),this._keyWeights[l]=f,o+=f}if(o>1)throw new Error("Total of weights cannot exceed 1")}}},{key:"search",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{limit:!1};this._log('---------\nSearch pattern: "'.concat(t,'"'));var n=this._prepareSearchers(t),r=n.tokenSearchers,a=n.fullSearcher,i=this._search(r,a);return this._computeScore(i),this.options.shouldSort&&this._sort(i),e.limit&&"number"==typeof e.limit&&(i=i.slice(0,e.limit)),this._format(i)}},{key:"_prepareSearchers",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e=[];if(this.options.tokenize)for(var n=t.split(this.options.tokenSeparator),r=0,a=n.length;r0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1?arguments[1]:void 0,n=this.list,r={},a=[];if("string"==typeof n[0]){for(var i=0,o=n.length;i \n Welcome, {{ character_name }}. Item selected:{{s.sel_name}} Charge: {{s.sel_price}}电 / {{s.sel_price}}cr Swipe your NanoTrasen ID or insert credits to purchase. {{s.message}} Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you! \n What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.\n \n Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.\n , or missing 0&&r(d))v=o(t,e,d,a(d.length),v,c-1)-1;else{if(v>=9007199254740991)throw TypeError("Exceed the acceptable array length");t[v]=d}v++}p++}return v};t.exports=o},a434:function(t,e,n){"use strict";var r=n("23e7"),a=n("23cb"),i=n("a691"),o=n("50c4"),s=n("7b0b"),u=n("65f0"),c=n("8418"),l=n("1dde"),f=n("ae40"),d=l("splice"),v=f("splice",{ACCESSORS:!0,0:0,1:2}),p=Math.max,h=Math.min,m=9007199254740991,g="Maximum allowed length exceeded";r({target:"Array",proto:!0,forced:!d||!v},{splice:function(t,e){var n,r,l,f,d,v,_=s(this),b=o(_.length),y=a(t,b),w=arguments.length;if(0===w?n=r=0:1===w?(n=0,r=b-y):(n=w-2,r=h(p(i(e),0),b-y)),b+n-r>m)throw TypeError(g);for(l=u(_,r),f=0;fQueue
\n \n
\n \n \n \n Name \n Progress \n Action \n \n \n {{ program.filename }} \n \n \n \n \n Available Programs
\n \n \n \n
\n Jammer Level:
\n
\n
\n
\n
\n
\n
\n\n \n \n
\n \n \n GPS Tag \n Location \n Area \n Remove \n \n \n {{ gps.tag }} \n {{ gps.pos_x }}, {{ gps.pos_y }}, {{ gps.pos_z }} \n {{ gps.area }} \n \n Selected Ores:
\n
\n Power Supply
\n File System
\n Misc. Settings
\n Computer Components
\n {{name}}
\n Engine Status:
\n \n
\n Patient Status
\n
\n\n \n
\n\n \n
\n Blood Status
\n
\n Internal Organ Status
\n
\n \n \n
\n\n \n \n \n \n \n Organ \n Trauma \n Wounds \n Location \n \n \n \n The occupant has no internal injuries. \n \n \n \n {{ organ.name }} \n {{ organ.damage }} \n \n {{ organ.location }} \n \n
\n External Bodypart Status
\n
\n \n \n
\n \n \n \n \n Organ \n Physical / Burn Trauma \n Wounds \n \n \n \n The occupant has no external injuries. \n \n \n \n {{ organ.name }} \n {{ organ.bruteDmg }} / {{ organ.burnDmg }} \n \n \n Actions
\n Programs
\n No program loaded. Please select program from list below.\n Services
\n
\n \n
\n \n \n Name \n Description \n Available Slots \n Actions \n \n \n {{data.name}} \n {{data.desc}} \n 0\">{{data.max_count - data.count}} / {{data.max_count}} \n 0\">{{data.spawnatoms}} \n ∞ \n \n \n Storage
\n \n {{ locked == -1 ? \"Sec.re ACC_** //):securi_nt.diag=>##'or 1=1'%($...\" : \"Secure Access: Please have your identification ready.\" }}\n \n
\n Auxiliary Timing Unit:
\n Time Left:
\n Scanning:
\n Range:
\n Tank Status
\n Holding Tank Status
\n Release Valve Status
\n
\n Round duration: {{ round_duration }}
\n Alert level: {{ alert_level }}
\n
\n Choose from the following available positions:\n
\n Remote Penal Mechs
\n
\n \n
\n \n \n Pilot \n Mech Type \n Location \n Camera \n Lockdown \n End Connection \n \n \n \n \n {{ mech.name }} \n {{ mech.location }} \n \n \n \n
\n Remote Penal Cyborgs
\n
\n \n
\n \n \n Pilot \n Robot Type \n Location \n End Connection \n \n \n \n \n {{ robot.name }} \n {{ robot.location }} \n \n
'))}}),_c('vui-button',{attrs:{\"params\":{ _openurl: item[4] }}},[_vm._v(\"Open\")])],1)}),0)]:_vm._e(),_vm._t(\"default\")],2),_c('div',{staticClass:\"bottombuttons\"},[_c('vui-button',{attrs:{\"params\":{ setactive: 'null'},\"push-state\":\"\"},on:{\"click\":function($event){_vm.activeview = 'list'}}},[_vm._v(\"Unload Record\")]),(_vm.canprint)?_c('vui-button',{attrs:{\"params\":{ print: 'active'}}},[_vm._v(\"Print\")]):_vm._e(),(!_vm.hideAdvanced && (_vm.editable & 1))?_c('vui-button',{staticClass:\"danger\",attrs:{\"params\":{ deleterecord: 1 },\"icon\":\"trash-alt\"}},[_vm._v(\"Delete record\")]):_vm._e()],1)],1):_vm._e()}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n
\n {{ item[0] }} ({{ item[1] }})
\n ')\"/>\n Gas Temperature
\n Status
\n Fuel
\n Output
\n Temperature
\n
\n \n
\n \n Damage type: {{damage_type}} \n Item's estimated force-rating: {{force}} points \n \n Item's estimated throw force-rating: {{throw_force}} points \n Item's estimated force-rating when activated: {{active_force}} points \n Item's estimated throw force-rating when activated: {{active_throw_force}} points \n Base block chance is: {{base_block_chance}}% \n Base reflect chance is: {{base_reflectchance}}% \n Item's estimated shield rating: {{shield_power}} points \n \n Can block bullets: {{can_block}} \n Is sharp: {{sharp}} \n Chance to dismember: {{edge}} \n Item's estimated armor penetration rating: {{penetration}} points \n
\n \n Maximum shots: {{max_shots}} \n Burst: {{burst}} \n Self recharge: {{recharge}} \n Recharge time: {{recharge_time}} \n Reliability: {{reliability}}
First projectile information:
\n \n Projectile's estimated damage rating: {{damage}} points \n Projectile's Damage type: {{damage_type}} \n Projectile's estimated armor penetration rating: {{armor_penetration}} points \n Projectile's armor damage type: {{check_armor}} \n Projectile's shrapnel type: {{shrapnel_type}} \n \n Stun: {{stun}}
Second projectile information:
\n \n Projectile's estimated damage rating: {{secondary_damage}} points \n Projectile's damage type: {{secondary_damage_type}} \n Projectile's estimated armor penetration rating: {{secondary_armor_penetration}} points \n Projectile's armor damage type: {{secondary_check_armor}} \n Projectile's shrapnel type: {{secondary_shrapnel_type}} \n \n Stun: {{secondary_stun}}
Modular gun information:
\n \n
\n \n \n Name \n Reliability \n Damage modifier \n Fire delay modifier \n Number of shots modifier \n Burst modifier \n Accuracy modifier \n Repair tool \n \n \n {{mod_index}} \n \n {{mod_info[index]}}\n \n Frequency:
\n Code:
\n \n {{state._PC.batterypercent}}\n
\n
\n
Selected Products:
\n Total: {{ priceSum }}
\n Destination Account: {{ destinationact }}
\n Please swipe your ID to pay.
\n \n
\n \n No laws found.\n \n\n \n \n Index Law \n \n {{law.index}} \n {{law.law}} \n Engine Status:
\n NT-X1 Vacuum Cleaner Status:
\n Tank Control System
\n
\n
\n Debug this UI with inspector by opening URL in your browser:
{{url}}Current data of UI:
{{ JSON.stringify(this.$root.$data, null, \\' \\') }}Fuel Injection System
\n \n
\n
\n \n \n
\n Please insert something to copy.
\n
\n Please insert a new toner cartridge!
\n \n \n \n\n\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./group-row.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./group-row.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./group-row.vue?vue&type=template&id=6522a5fa&\"\nimport script from \"./group-row.vue?vue&type=script&lang=js&\"\nexport * from \"./group-row.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS = require('../internals/typed-array-constructors-require-wrappers');\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar ArrayBufferModule = require('../internals/array-buffer');\nvar anInstance = require('../internals/an-instance');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar toLength = require('../internals/to-length');\nvar toIndex = require('../internals/to-index');\nvar toOffset = require('../internals/to-offset');\nvar toPrimitive = require('../internals/to-primitive');\nvar has = require('../internals/has');\nvar classof = require('../internals/classof');\nvar isObject = require('../internals/is-object');\nvar create = require('../internals/object-create');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar typedArrayFrom = require('../internals/typed-array-from');\nvar forEach = require('../internals/array-iteration').forEach;\nvar setSpecies = require('../internals/set-species');\nvar definePropertyModule = require('../internals/object-define-property');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar InternalStateModule = require('../internals/internal-state');\nvar inheritIfRequired = require('../internals/inherit-if-required');\n\nvar getInternalState = InternalStateModule.get;\nvar setInternalState = InternalStateModule.set;\nvar nativeDefineProperty = definePropertyModule.f;\nvar nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\nvar round = Math.round;\nvar RangeError = global.RangeError;\nvar ArrayBuffer = ArrayBufferModule.ArrayBuffer;\nvar DataView = ArrayBufferModule.DataView;\nvar NATIVE_ARRAY_BUFFER_VIEWS = ArrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;\nvar TYPED_ARRAY_TAG = ArrayBufferViewCore.TYPED_ARRAY_TAG;\nvar TypedArray = ArrayBufferViewCore.TypedArray;\nvar TypedArrayPrototype = ArrayBufferViewCore.TypedArrayPrototype;\nvar aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor;\nvar isTypedArray = ArrayBufferViewCore.isTypedArray;\nvar BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';\nvar WRONG_LENGTH = 'Wrong length';\n\nvar fromList = function (C, list) {\n var index = 0;\n var length = list.length;\n var result = new (aTypedArrayConstructor(C))(length);\n while (length > index) result[index] = list[index++];\n return result;\n};\n\nvar addGetter = function (it, key) {\n nativeDefineProperty(it, key, { get: function () {\n return getInternalState(this)[key];\n } });\n};\n\nvar isArrayBuffer = function (it) {\n var klass;\n return it instanceof ArrayBuffer || (klass = classof(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer';\n};\n\nvar isTypedArrayIndex = function (target, key) {\n return isTypedArray(target)\n && typeof key != 'symbol'\n && key in target\n && String(+key) == String(key);\n};\n\nvar wrappedGetOwnPropertyDescriptor = function getOwnPropertyDescriptor(target, key) {\n return isTypedArrayIndex(target, key = toPrimitive(key, true))\n ? createPropertyDescriptor(2, target[key])\n : nativeGetOwnPropertyDescriptor(target, key);\n};\n\nvar wrappedDefineProperty = function defineProperty(target, key, descriptor) {\n if (isTypedArrayIndex(target, key = toPrimitive(key, true))\n && isObject(descriptor)\n && has(descriptor, 'value')\n && !has(descriptor, 'get')\n && !has(descriptor, 'set')\n // TODO: add validation descriptor w/o calling accessors\n && !descriptor.configurable\n && (!has(descriptor, 'writable') || descriptor.writable)\n && (!has(descriptor, 'enumerable') || descriptor.enumerable)\n ) {\n target[key] = descriptor.value;\n return target;\n } return nativeDefineProperty(target, key, descriptor);\n};\n\nif (DESCRIPTORS) {\n if (!NATIVE_ARRAY_BUFFER_VIEWS) {\n getOwnPropertyDescriptorModule.f = wrappedGetOwnPropertyDescriptor;\n definePropertyModule.f = wrappedDefineProperty;\n addGetter(TypedArrayPrototype, 'buffer');\n addGetter(TypedArrayPrototype, 'byteOffset');\n addGetter(TypedArrayPrototype, 'byteLength');\n addGetter(TypedArrayPrototype, 'length');\n }\n\n $({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, {\n getOwnPropertyDescriptor: wrappedGetOwnPropertyDescriptor,\n defineProperty: wrappedDefineProperty\n });\n\n module.exports = function (TYPE, wrapper, CLAMPED) {\n var BYTES = TYPE.match(/\\d+$/)[0] / 8;\n var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array';\n var GETTER = 'get' + TYPE;\n var SETTER = 'set' + TYPE;\n var NativeTypedArrayConstructor = global[CONSTRUCTOR_NAME];\n var TypedArrayConstructor = NativeTypedArrayConstructor;\n var TypedArrayConstructorPrototype = TypedArrayConstructor && TypedArrayConstructor.prototype;\n var exported = {};\n\n var getter = function (that, index) {\n var data = getInternalState(that);\n return data.view[GETTER](index * BYTES + data.byteOffset, true);\n };\n\n var setter = function (that, index, value) {\n var data = getInternalState(that);\n if (CLAMPED) value = (value = round(value)) < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF;\n data.view[SETTER](index * BYTES + data.byteOffset, value, true);\n };\n\n var addElement = function (that, index) {\n nativeDefineProperty(that, index, {\n get: function () {\n return getter(this, index);\n },\n set: function (value) {\n return setter(this, index, value);\n },\n enumerable: true\n });\n };\n\n if (!NATIVE_ARRAY_BUFFER_VIEWS) {\n TypedArrayConstructor = wrapper(function (that, data, offset, $length) {\n anInstance(that, TypedArrayConstructor, CONSTRUCTOR_NAME);\n var index = 0;\n var byteOffset = 0;\n var buffer, byteLength, length;\n if (!isObject(data)) {\n length = toIndex(data);\n byteLength = length * BYTES;\n buffer = new ArrayBuffer(byteLength);\n } else if (isArrayBuffer(data)) {\n buffer = data;\n byteOffset = toOffset(offset, BYTES);\n var $len = data.byteLength;\n if ($length === undefined) {\n if ($len % BYTES) throw RangeError(WRONG_LENGTH);\n byteLength = $len - byteOffset;\n if (byteLength < 0) throw RangeError(WRONG_LENGTH);\n } else {\n byteLength = toLength($length) * BYTES;\n if (byteLength + byteOffset > $len) throw RangeError(WRONG_LENGTH);\n }\n length = byteLength / BYTES;\n } else if (isTypedArray(data)) {\n return fromList(TypedArrayConstructor, data);\n } else {\n return typedArrayFrom.call(TypedArrayConstructor, data);\n }\n setInternalState(that, {\n buffer: buffer,\n byteOffset: byteOffset,\n byteLength: byteLength,\n length: length,\n view: new DataView(buffer)\n });\n while (index < length) addElement(that, index++);\n });\n\n if (setPrototypeOf) setPrototypeOf(TypedArrayConstructor, TypedArray);\n TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = create(TypedArrayPrototype);\n } else if (TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS) {\n TypedArrayConstructor = wrapper(function (dummy, data, typedArrayOffset, $length) {\n anInstance(dummy, TypedArrayConstructor, CONSTRUCTOR_NAME);\n return inheritIfRequired(function () {\n if (!isObject(data)) return new NativeTypedArrayConstructor(toIndex(data));\n if (isArrayBuffer(data)) return $length !== undefined\n ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES), $length)\n : typedArrayOffset !== undefined\n ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES))\n : new NativeTypedArrayConstructor(data);\n if (isTypedArray(data)) return fromList(TypedArrayConstructor, data);\n return typedArrayFrom.call(TypedArrayConstructor, data);\n }(), dummy, TypedArrayConstructor);\n });\n\n if (setPrototypeOf) setPrototypeOf(TypedArrayConstructor, TypedArray);\n forEach(getOwnPropertyNames(NativeTypedArrayConstructor), function (key) {\n if (!(key in TypedArrayConstructor)) {\n createNonEnumerableProperty(TypedArrayConstructor, key, NativeTypedArrayConstructor[key]);\n }\n });\n TypedArrayConstructor.prototype = TypedArrayConstructorPrototype;\n }\n\n if (TypedArrayConstructorPrototype.constructor !== TypedArrayConstructor) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, 'constructor', TypedArrayConstructor);\n }\n\n if (TYPED_ARRAY_TAG) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, TYPED_ARRAY_TAG, CONSTRUCTOR_NAME);\n }\n\n exported[CONSTRUCTOR_NAME] = TypedArrayConstructor;\n\n $({\n global: true, forced: TypedArrayConstructor != NativeTypedArrayConstructor, sham: !NATIVE_ARRAY_BUFFER_VIEWS\n }, exported);\n\n if (!(BYTES_PER_ELEMENT in TypedArrayConstructor)) {\n createNonEnumerableProperty(TypedArrayConstructor, BYTES_PER_ELEMENT, BYTES);\n }\n\n if (!(BYTES_PER_ELEMENT in TypedArrayConstructorPrototype)) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, BYTES_PER_ELEMENT, BYTES);\n }\n\n setSpecies(CONSTRUCTOR_NAME);\n };\n} else module.exports = function () { /* empty */ };\n","/** Used to match words composed of alphanumeric characters. */\nvar reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n/**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction asciiWords(string) {\n return string.match(reAsciiWord) || [];\n}\n\nmodule.exports = asciiWords;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","// IEEE754 conversions based on https://github.com/feross/ieee754\n// eslint-disable-next-line no-shadow-restricted-names\nvar Infinity = 1 / 0;\nvar abs = Math.abs;\nvar pow = Math.pow;\nvar floor = Math.floor;\nvar log = Math.log;\nvar LN2 = Math.LN2;\n\nvar pack = function (number, mantissaLength, bytes) {\n var buffer = new Array(bytes);\n var exponentLength = bytes * 8 - mantissaLength - 1;\n var eMax = (1 << exponentLength) - 1;\n var eBias = eMax >> 1;\n var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;\n var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;\n var index = 0;\n var exponent, mantissa, c;\n number = abs(number);\n // eslint-disable-next-line no-self-compare\n if (number != number || number === Infinity) {\n // eslint-disable-next-line no-self-compare\n mantissa = number != number ? 1 : 0;\n exponent = eMax;\n } else {\n exponent = floor(log(number) / LN2);\n if (number * (c = pow(2, -exponent)) < 1) {\n exponent--;\n c *= 2;\n }\n if (exponent + eBias >= 1) {\n number += rt / c;\n } else {\n number += rt * pow(2, 1 - eBias);\n }\n if (number * c >= 2) {\n exponent++;\n c /= 2;\n }\n if (exponent + eBias >= eMax) {\n mantissa = 0;\n exponent = eMax;\n } else if (exponent + eBias >= 1) {\n mantissa = (number * c - 1) * pow(2, mantissaLength);\n exponent = exponent + eBias;\n } else {\n mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);\n exponent = 0;\n }\n }\n for (; mantissaLength >= 8; buffer[index++] = mantissa & 255, mantissa /= 256, mantissaLength -= 8);\n exponent = exponent << mantissaLength | mantissa;\n exponentLength += mantissaLength;\n for (; exponentLength > 0; buffer[index++] = exponent & 255, exponent /= 256, exponentLength -= 8);\n buffer[--index] |= sign * 128;\n return buffer;\n};\n\nvar unpack = function (buffer, mantissaLength) {\n var bytes = buffer.length;\n var exponentLength = bytes * 8 - mantissaLength - 1;\n var eMax = (1 << exponentLength) - 1;\n var eBias = eMax >> 1;\n var nBits = exponentLength - 7;\n var index = bytes - 1;\n var sign = buffer[index--];\n var exponent = sign & 127;\n var mantissa;\n sign >>= 7;\n for (; nBits > 0; exponent = exponent * 256 + buffer[index], index--, nBits -= 8);\n mantissa = exponent & (1 << -nBits) - 1;\n exponent >>= -nBits;\n nBits += mantissaLength;\n for (; nBits > 0; mantissa = mantissa * 256 + buffer[index], index--, nBits -= 8);\n if (exponent === 0) {\n exponent = 1 - eBias;\n } else if (exponent === eMax) {\n return mantissa ? NaN : sign ? -Infinity : Infinity;\n } else {\n mantissa = mantissa + pow(2, mantissaLength);\n exponent = exponent - eBias;\n } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);\n};\n\nmodule.exports = {\n pack: pack,\n unpack: unpack\n};\n","// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","var $ = require('../internals/export');\nvar expm1 = require('../internals/math-expm1');\n\nvar exp = Math.exp;\n\n// `Math.tanh` method\n// https://tc39.github.io/ecma262/#sec-math.tanh\n$({ target: 'Math', stat: true }, {\n tanh: function tanh(x) {\n var a = expm1(x = +x);\n var b = expm1(-x);\n return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));\n }\n});\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var $ = require('../internals/export');\n\nvar nativeAsinh = Math.asinh;\nvar log = Math.log;\nvar sqrt = Math.sqrt;\n\nfunction asinh(x) {\n return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : log(x + sqrt(x * x + 1));\n}\n\n// `Math.asinh` method\n// https://tc39.github.io/ecma262/#sec-math.asinh\n// Tor Browser bug: Math.asinh(0) -> -0\n$({ target: 'Math', stat: true, forced: !(nativeAsinh && 1 / nativeAsinh(0) > 0) }, {\n asinh: asinh\n});\n","var $ = require('../internals/export');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar objectDefinePropertyModile = require('../internals/object-define-property');\n\n// `Object.defineProperty` method\n// https://tc39.github.io/ecma262/#sec-object.defineproperty\n$({ target: 'Object', stat: true, forced: !DESCRIPTORS, sham: !DESCRIPTORS }, {\n defineProperty: objectDefinePropertyModile.f\n});\n","var requireObjectCoercible = require('../internals/require-object-coercible');\n\n// `ToObject` abstract operation\n// https://tc39.github.io/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return Object(requireObjectCoercible(argument));\n};\n","var anObject = require('../internals/an-object');\nvar defineProperties = require('../internals/object-define-properties');\nvar enumBugKeys = require('../internals/enum-bug-keys');\nvar hiddenKeys = require('../internals/hidden-keys');\nvar html = require('../internals/html');\nvar documentCreateElement = require('../internals/document-create-element');\nvar sharedKey = require('../internals/shared-key');\n\nvar GT = '>';\nvar LT = '<';\nvar PROTOTYPE = 'prototype';\nvar SCRIPT = 'script';\nvar IE_PROTO = sharedKey('IE_PROTO');\n\nvar EmptyConstructor = function () { /* empty */ };\n\nvar scriptTag = function (content) {\n return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;\n};\n\n// Create object with fake `null` prototype: use ActiveX Object with cleared prototype\nvar NullProtoObjectViaActiveX = function (activeXDocument) {\n activeXDocument.write(scriptTag(''));\n activeXDocument.close();\n var temp = activeXDocument.parentWindow.Object;\n activeXDocument = null; // avoid memory leak\n return temp;\n};\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar NullProtoObjectViaIFrame = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = documentCreateElement('iframe');\n var JS = 'java' + SCRIPT + ':';\n var iframeDocument;\n iframe.style.display = 'none';\n html.appendChild(iframe);\n // https://github.com/zloirock/core-js/issues/475\n iframe.src = String(JS);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(scriptTag('document.F=Object'));\n iframeDocument.close();\n return iframeDocument.F;\n};\n\n// Check for document.domain and active x support\n// No need to use active x approach when document.domain is not set\n// see https://github.com/es-shims/es5-shim/issues/150\n// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346\n// avoid IE GC bug\nvar activeXDocument;\nvar NullProtoObject = function () {\n try {\n /* global ActiveXObject */\n activeXDocument = document.domain && new ActiveXObject('htmlfile');\n } catch (error) { /* ignore */ }\n NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();\n var length = enumBugKeys.length;\n while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];\n return NullProtoObject();\n};\n\nhiddenKeys[IE_PROTO] = true;\n\n// `Object.create` method\n// https://tc39.github.io/ecma262/#sec-object.create\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n EmptyConstructor[PROTOTYPE] = anObject(O);\n result = new EmptyConstructor();\n EmptyConstructor[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = NullProtoObject();\n return Properties === undefined ? result : defineProperties(result, Properties);\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar $find = require('../internals/array-iteration').find;\nvar addToUnscopables = require('../internals/add-to-unscopables');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar FIND = 'find';\nvar SKIPS_HOLES = true;\n\nvar USES_TO_LENGTH = arrayMethodUsesToLength(FIND);\n\n// Shouldn't skip holes\nif (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.find` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.find\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES || !USES_TO_LENGTH }, {\n find: function find(callbackfn /* , that = undefined */) {\n return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND);\n","export * from \"-!../../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./photocopier.vue?vue&type=style&index=0&id=927b9430&lang=scss&scoped=true&\"","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.s.mode == 0 || _vm.s.sel_price == 0)?[_c('div',{staticClass:\"cancel-button\"},[_c('vui-input-search',{attrs:{\"input\":_vm.products,\"keys\":['name'],\"autofocus\":\"\",\"threshold\":_vm.threshold},model:{value:(_vm.output),callback:function ($$v) {_vm.output=$$v},expression:\"output\"}}),_c('vui-button',{attrs:{\"disabled\":!_vm.s.coin,\"params\":{ remove_coin: 1 },\"icon\":\"sign-out-alt\"}},[_vm._v(_vm._s(_vm.s.coin ? _vm.s.coin : \"No coin inserted.\"))])],1),_c('div',{staticClass:\"t-parent\"},_vm._l((_vm.output),function(vend){return _c('vui-button',{key:vend.key,staticClass:\"t-child tooltip\",class:vend.amount > 0 ? '' : 'no-stock',attrs:{\"disabled\":vend.amount == 0 || _vm.s.mode == 1,\"params\":{ vendItem: vend.key }}},[_c('div',{staticClass:\"t-container\",style:({ height: _vm.s.ui_size + 'px', width: _vm.s.ui_size + 'px'})},[_c('span',{staticClass:\"food-icon\",class:[vend.amount > 0 ? '' : 'no-stock', vend.icon_tag]}),(vend.price > 0)?_c('span',{staticClass:\"cart-icon fas ic-shopping-cart\"}):_vm._e(),(vend.price > 0)?_c('span',{staticClass:\"price\"},[_vm._v(_vm._s(vend.price)+\"电\")]):_vm._e(),_c('span',{staticClass:\"qty\",class:vend.amount > 0 ? '' : 'no-stock'},[_vm._v(\"(x\"+_vm._s(vend.amount)+\")\")])]),_c('span',{staticClass:\"tooltiptext\"},[_vm._v(_vm._s(vend.name))])])}),1)]:(_vm.s.sel_name && _vm.s.sel_price > 0)?[_c('div',{staticClass:\"t-parent\"},[_c('p',[_vm._v(\"Item selected:\"),_c('span',{staticClass:\"purchase-icon\",class:_vm.s.sel_icon}),_vm._v(_vm._s(_vm.s.sel_name))]),_c('p',[_vm._v(\"Charge: \"+_vm._s(_vm.s.sel_price)+\"电 / \"+_vm._s(_vm.s.sel_price)+\"cr\")]),_c('p',[_vm._v(\"Swipe your NanoTrasen ID or insert credits to purchase.\")]),(_vm.s.message_err == 1)?_c('p',{staticClass:\"danger\"},[_vm._v(_vm._s(_vm.s.message))]):_vm._e(),_c('div',{staticClass:\"cancel-button\"},[_c('vui-button',{attrs:{\"params\":{ cancelpurchase: 1 },\"icon\":\"undo\"}},[_vm._v(\"Cancel Transaction\")])],1)])]:[_c('vui-button',{staticClass:\"cancel-button danger\",attrs:{\"params\":{ reset: 1},\"icon\":\"undo\"}},[_vm._v(\"Reset Machine\")])]],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n \n \n\n\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./img.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./img.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./img.vue?vue&type=template&id=6aea3df6&\"\nimport script from \"./img.vue?vue&type=script&lang=js&\"\nexport * from \"./img.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.toPrimitive` well-known symbol\n// https://tc39.github.io/ecma262/#sec-symbol.toprimitive\ndefineWellKnownSymbol('toPrimitive');\n","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.unscopables` well-known symbol\n// https://tc39.github.io/ecma262/#sec-symbol.unscopables\ndefineWellKnownSymbol('unscopables');\n","'use strict';\nvar toObject = require('../internals/to-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar toLength = require('../internals/to-length');\n\n// `Array.prototype.fill` method implementation\n// https://tc39.github.io/ecma262/#sec-array.prototype.fill\nmodule.exports = function fill(value /* , start = 0, end = @length */) {\n var O = toObject(this);\n var length = toLength(O.length);\n var argumentsLength = arguments.length;\n var index = toAbsoluteIndex(argumentsLength > 1 ? arguments[1] : undefined, length);\n var end = argumentsLength > 2 ? arguments[2] : undefined;\n var endPos = end === undefined ? length : toAbsoluteIndex(end, length);\n while (endPos > index) O[index++] = value;\n return O;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar aFunction = require('../internals/a-function');\nvar newPromiseCapabilityModule = require('../internals/new-promise-capability');\nvar perform = require('../internals/perform');\nvar iterate = require('../internals/iterate');\n\n// `Promise.allSettled` method\n// https://github.com/tc39/proposal-promise-allSettled\n$({ target: 'Promise', stat: true }, {\n allSettled: function allSettled(iterable) {\n var C = this;\n var capability = newPromiseCapabilityModule.f(C);\n var resolve = capability.resolve;\n var reject = capability.reject;\n var result = perform(function () {\n var promiseResolve = aFunction(C.resolve);\n var values = [];\n var counter = 0;\n var remaining = 1;\n iterate(iterable, function (promise) {\n var index = counter++;\n var alreadyCalled = false;\n values.push(undefined);\n remaining++;\n promiseResolve.call(C, promise).then(function (value) {\n if (alreadyCalled) return;\n alreadyCalled = true;\n values[index] = { status: 'fulfilled', value: value };\n --remaining || resolve(values);\n }, function (error) {\n if (alreadyCalled) return;\n alreadyCalled = true;\n values[index] = { status: 'rejected', reason: error };\n --remaining || resolve(values);\n });\n });\n --remaining || resolve(values);\n });\n if (result.error) reject(result.value);\n return capability.promise;\n }\n});\n","var isObject = require('../internals/is-object');\n\nmodule.exports = function (it) {\n if (!isObject(it)) {\n throw TypeError(String(it) + ' is not an object');\n } return it;\n};\n","var $ = require('../internals/export');\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\n\nvar NATIVE_ARRAY_BUFFER_VIEWS = ArrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;\n\n// `ArrayBuffer.isView` method\n// https://tc39.github.io/ecma262/#sec-arraybuffer.isview\n$({ target: 'ArrayBuffer', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, {\n isView: ArrayBufferViewCore.isView\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $includes = require('../internals/array-includes').includes;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.includes` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.includes\nexportTypedArrayMethod('includes', function includes(searchElement /* , fromIndex */) {\n return $includes(aTypedArray(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n});\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('vui-input-search',{attrs:{\"input\":_vm.records,\"keys\":['id', 'name', 'rank']},model:{value:(_vm.filtered),callback:function ($$v) {_vm.filtered=$$v},expression:\"filtered\"}}),_vm._l((_vm.filtered),function(record){return _c('div',{key:record.id},[_c('vui-button',{attrs:{\"params\":{ setactive_virus: record.id},\"push-state\":\"\"},on:{\"click\":function($event){_vm.activeview = _vm.defaultview}}},[_vm._v(_vm._s(record.id)+\": \"+_vm._s(record.name))])],1)})],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n
Sensor Data:
\n No sensors connected.\n
\n \n
\n \n \n\n Ckey \n Rank \n Permissions \n \n \n \n \n \n \n \n \n PDAs to notify:
\n