diff --git a/.gitignore b/.gitignore
index 1d9b7c7723..e32aa6c2a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
#ignore misc BYOND files
Thumbs.db
+vchat.db
+vchat.db*
*.log
*.int
*.rsc
diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm
index d3222965a9..47226383ea 100644
--- a/code/__defines/is_helpers.dm
+++ b/code/__defines/is_helpers.dm
@@ -6,6 +6,7 @@
//---------------
#define isatom(D) istype(D, /atom)
+#define isclient(D) istype(D, /client)
//---------------
//#define isobj(D) istype(D, /obj) //Built in
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 8fcabca714..a8e77c0a3c 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -79,7 +79,7 @@
#define COLOR_DEEP_SKY_BLUE "#00e1ff"
-
+#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : null))
// Shuttles.
diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm
index 58552c6905..140f10a716 100644
--- a/code/__defines/subsystems.dm
+++ b/code/__defines/subsystems.dm
@@ -63,12 +63,14 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_LIGHTING 0
#define INIT_ORDER_AIR -1
+#define INIT_ORDER_ASSETS -3
#define INIT_ORDER_PLANETS -4
#define INIT_ORDER_HOLOMAPS -5
#define INIT_ORDER_OVERLAY -6
#define INIT_ORDER_XENOARCH -20
#define INIT_ORDER_CIRCUIT -21
#define INIT_ORDER_AI -22
+#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
// Subsystem fire priority, from lowest to highest priority
@@ -88,6 +90,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_PLANETS 75
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_PROJECTILES 150
+#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed)
diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm
index 1eb39e30cd..5f4cc4dd08 100644
--- a/code/_helpers/_lists.dm
+++ b/code/_helpers/_lists.dm
@@ -53,7 +53,7 @@
// atoms/items/objects can be pretty and whatnot
var/atom/A = item
if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons
- item_str += "\icon[A] "
+ item_str += "[bicon(A)] "
switch(determiners)
if(DET_NONE) item_str += A.name
if(DET_DEFINITE) item_str += "\the [A]"
diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm
index 8f2fc9c3c3..5abedfe9ac 100644
--- a/code/_helpers/icons.dm
+++ b/code/_helpers/icons.dm
@@ -167,7 +167,7 @@ mob
Output_Icon()
set name = "2. Output Icon"
- to_chat(src, "Icon is: \icon[getFlatIcon(src)]")
+ to_chat(src, "Icon is: [bicon(getFlatIcon(src))]")
Label_Icon()
set name = "3. Label Icon"
diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index 688e1c2a68..6776555348 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -305,7 +305,8 @@ proc/TextPreview(var/string,var/len=40)
/proc/create_text_tag(var/tagname, var/tagdesc = tagname, var/client/C = null)
if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags)))
return tagdesc
- return "
"
+ var/icon/tag = icon(text_tag_icons.icon, tagname)
+ return bicon(tag,TRUE,"text_tag") //"
"
/proc/contains_az09(var/input)
for(var/i=1, i<=length(input), i++)
diff --git a/code/_macros.dm b/code/_macros.dm
index 7b44246eb1..afff35b713 100644
--- a/code/_macros.dm
+++ b/code/_macros.dm
@@ -4,7 +4,8 @@
#define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
-#define to_chat(target, message) target << message
+// #define to_chat(target, message) target << message Not anymore!
+#define to_chat to_chat_filename=__FILE__;to_chat_line=__LINE__;to_chat_src=src;__to_chat
#define to_world(message) to_chat(world, message)
#define to_world_log(message) world.log << message
// TODO - Baystation has this log to crazy places. For now lets just world.log, but maybe look into it later.
diff --git a/code/controllers/subsystems/assets.dm b/code/controllers/subsystems/assets.dm
new file mode 100644
index 0000000000..cd531db614
--- /dev/null
+++ b/code/controllers/subsystems/assets.dm
@@ -0,0 +1,17 @@
+SUBSYSTEM_DEF(assets)
+ name = "Assets"
+ init_order = INIT_ORDER_ASSETS
+ flags = SS_NO_FIRE
+ var/list/cache = list()
+ var/list/preload = list()
+
+/datum/controller/subsystem/assets/Initialize(timeofday)
+ for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
+ var/datum/asset/A = new type()
+ A.register()
+
+ preload = cache.Copy() //don't preload assets generated during the round
+
+ for(var/client/C in GLOB.clients)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
+ return ..()
\ No newline at end of file
diff --git a/code/controllers/subsystems/chat.dm b/code/controllers/subsystems/chat.dm
new file mode 100644
index 0000000000..3afbcae374
--- /dev/null
+++ b/code/controllers/subsystems/chat.dm
@@ -0,0 +1,87 @@
+SUBSYSTEM_DEF(chat)
+ name = "Chat"
+ flags = SS_TICKER
+ wait = 1 // SS_TICKER means this runs every tick
+ priority = FIRE_PRIORITY_CHAT
+ init_order = INIT_ORDER_CHAT
+
+ var/list/msg_queue = list()
+
+/datum/controller/subsystem/chat/Initialize(timeofday)
+ init_vchat()
+ ..()
+
+/datum/controller/subsystem/chat/fire()
+ var/list/msg_queue = src.msg_queue // Local variable for sanic speed.
+ for(var/i in msg_queue)
+ var/client/C = i
+ var/list/messages = msg_queue[C]
+ msg_queue -= C
+ if (C)
+ C << output(jsEncode(messages), "htmloutput:putmessage")
+
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/chat/stat_entry()
+ ..("C:[msg_queue.len]")
+
+/datum/controller/subsystem/chat/proc/queue(target, time, message, handle_whitespace = TRUE)
+ if(!target || !message)
+ return
+
+ if(!istext(message))
+ stack_trace("to_chat called with invalid input type")
+ return
+
+ // Currently to_chat(world, ...) gets sent individually to each client. Consider.
+ if(target == world)
+ target = GLOB.clients
+
+ //Some macros remain in the string even after parsing and fuck up the eventual output
+ var/original_message = message
+ message = replacetext(message, "\n", "
")
+ message = replacetext(message, "\improper", "")
+ message = replacetext(message, "\proper", "")
+
+ if(isnull(time))
+ time = world.time
+
+ var/list/messageStruct = list("time" = time, "message" = message);
+
+ if(islist(target))
+ for(var/I in target)
+ var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
+
+ if(!C)
+ return
+
+ if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
+ //Send it to the old style output window.
+ DIRECT_OUTPUT(C, original_message)
+ continue
+
+ // // Client still loading, put their messages in a queue - Actually don't, logged already in database.
+ // if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
+ // C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
+ // continue
+
+ LAZYINITLIST(msg_queue[C])
+ msg_queue[C][++msg_queue[C].len] = messageStruct
+ else
+ var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
+
+ if(!C)
+ return
+
+ if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
+ DIRECT_OUTPUT(C, original_message)
+ return
+
+ // // Client still loading, put their messages in a queue - Actually don't, logged already in database.
+ // if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
+ // C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
+ // return
+
+ LAZYINITLIST(msg_queue[C])
+ msg_queue[C][++msg_queue[C].len] = messageStruct
diff --git a/code/controllers/subsystems/nanoui.dm b/code/controllers/subsystems/nanoui.dm
index 520973514d..78f47e8c7b 100644
--- a/code/controllers/subsystems/nanoui.dm
+++ b/code/controllers/subsystems/nanoui.dm
@@ -24,7 +24,7 @@ SUBSYSTEM_DEF(nanoui)
for(var/filename in filenames)
if(copytext(filename, length(filename)) != "/") // filenames which end in "/" are actually directories, which we want to ignore
if(fexists(path + filename))
- asset_files.Add(fcopy_rsc(path + filename)) // add this file to asset_files for sending to clients when they connect
+ asset_files[filename] = fcopy_rsc(path + filename) // add this file to asset_files for sending to clients when they connect
.=..()
for(var/i in GLOB.clients)
send_resources(i)
@@ -49,5 +49,4 @@ SUBSYSTEM_DEF(nanoui)
/datum/controller/subsystem/nanoui/proc/send_resources(client)
if(!subsystem_initialized)
return
- for(var/file in asset_files)
- client << browse_rsc(file) // send the file to the client
+ getFilesSlow(client, asset_files)
\ No newline at end of file
diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm
index 463c55dcc1..65f71f2584 100644
--- a/code/datums/uplink/badassery.dm
+++ b/code/datums/uplink/badassery.dm
@@ -91,4 +91,4 @@
var/obj/structure/largecrate/C = /obj/structure/largecrate
icon = image(initial(C.icon), initial(C.icon_state))
- return "\icon[icon]"
\ No newline at end of file
+ return "[bicon(icon)]"
\ No newline at end of file
diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm
index 94b1281dd3..a3cd630793 100644
--- a/code/datums/uplink/uplink_items.dm
+++ b/code/datums/uplink/uplink_items.dm
@@ -146,7 +146,7 @@ datum/uplink_item/dd_SortValue()
/datum/uplink_item/item/log_icon()
var/obj/I = path
- return "\icon[I]"
+ return "[bicon(I)]"
/********************************
* *
@@ -160,7 +160,7 @@ datum/uplink_item/dd_SortValue()
if(!default_abstract_uplink_icon)
default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn")
- return "\icon[default_abstract_uplink_icon]"
+ return "[bicon(default_abstract_uplink_icon)]"
/****************
* Support procs *
diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm
index 1724b9469c..fd3099bbe7 100644
--- a/code/datums/wires/camera.dm
+++ b/code/datums/wires/camera.dm
@@ -61,7 +61,7 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
C.light_disabled = !C.light_disabled
if(CAMERA_WIRE_ALARM)
- C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
+ C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
return
/datum/wires/camera/proc/CanDeconstruct()
diff --git a/code/datums/wires/jukebox.dm b/code/datums/wires/jukebox.dm
index 900c778189..6b7b7e97c7 100644
--- a/code/datums/wires/jukebox.dm
+++ b/code/datums/wires/jukebox.dm
@@ -34,16 +34,16 @@ var/const/WIRE_NEXT = 1024
var/obj/machinery/media/jukebox/A = holder
switch(index)
if(WIRE_POWER)
- holder.visible_message("\icon[holder] The power light flickers.")
+ holder.visible_message("[bicon(holder)] The power light flickers.")
A.shock(usr, 90)
if(WIRE_HACK)
- holder.visible_message("\icon[holder] The parental guidance light flickers.")
+ holder.visible_message("[bicon(holder)] The parental guidance light flickers.")
if(WIRE_REVERSE)
- holder.visible_message("\icon[holder] The data light blinks ominously.")
+ holder.visible_message("[bicon(holder)] The data light blinks ominously.")
if(WIRE_SPEEDUP)
- holder.visible_message("\icon[holder] The speakers squeaks.")
+ holder.visible_message("[bicon(holder)] The speakers squeaks.")
if(WIRE_SPEEDDOWN)
- holder.visible_message("\icon[holder] The speakers rumble.")
+ holder.visible_message("[bicon(holder)] The speakers rumble.")
if(WIRE_START)
A.StartPlaying()
if(WIRE_STOP)
diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm
index 2d0aecaaf0..372810988c 100644
--- a/code/datums/wires/mines.dm
+++ b/code/datums/wires/mines.dm
@@ -23,15 +23,15 @@
switch(index)
if(WIRE_DETONATE)
- C.visible_message("\icon[C] *BEEE-*", "\icon[C] *BEEE-*")
+ C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*")
C.explode()
if(WIRE_TIMED_DET)
- C.visible_message("\icon[C] *BEEE-*", "\icon[C] *BEEE-*")
+ C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*")
C.explode()
if(WIRE_DISARM)
- C.visible_message("\icon[C] *click!*", "\icon[C] *click!*")
+ C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
new C.mineitemtype(get_turf(C))
spawn(0)
qdel(C)
@@ -45,7 +45,7 @@
return
if(WIRE_BADDISARM)
- C.visible_message("\icon[C] *BEEPBEEPBEEP*", "\icon[C] *BEEPBEEPBEEP*")
+ C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
return
@@ -56,24 +56,24 @@
return
switch(index)
if(WIRE_DETONATE)
- C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
+ C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
if(WIRE_TIMED_DET)
- C.visible_message("\icon[C] *BEEPBEEPBEEP*", "\icon[C] *BEEPBEEPBEEP*")
+ C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
if(WIRE_DISARM)
- C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
+ C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
if(WIRE_DUMMY_1)
- C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
+ C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
if(WIRE_DUMMY_2)
- C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
+ C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
if(WIRE_BADDISARM)
- C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
+ C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
return
/datum/wires/mines/CanUse(var/mob/living/L)
diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm
index 8356238692..3d90236b46 100644
--- a/code/datums/wires/particle_accelerator.dm
+++ b/code/datums/wires/particle_accelerator.dm
@@ -28,7 +28,7 @@ var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be.
C.interface_control = !C.interface_control
if(PARTICLE_LIMIT_POWER_WIRE)
- C.visible_message("\icon[C][C] makes a large whirring noise.")
+ C.visible_message("[bicon(C)][C] makes a large whirring noise.")
/datum/wires/particle_acc/control_box/UpdateCut(var/index, var/mended)
var/obj/machinery/particle_accelerator/control_box/C = holder
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 539efdf1a6..87035942c4 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -183,7 +183,7 @@
else
f_name += "oil-stained [name][infix]."
- to_chat(user, "\icon[src] That's [f_name] [suffix]")
+ to_chat(user, "[bicon(src)] That's [f_name] [suffix]")
to_chat(user,desc)
return distance == -1 || (get_dist(src, user) <= distance)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 9d14bb3d10..d62d53a551 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -97,7 +97,7 @@
//dat += "Recover object.
" //VOREStation Removal - Just log them.
//dat += "Recover all objects.
" //VOREStation Removal
- to_chat(user, browse(dat, "window=cryopod_console"))
+ user << browse(dat, "window=cryopod_console")
onclose(user, "cryopod_console")
/obj/machinery/computer/cryopod/Topic(href, href_list)
@@ -116,7 +116,7 @@
dat += "[person]
"
dat += "
"
- to_chat(user, browse(dat, "window=cryolog"))
+ user << browse(dat, "window=cryolog")
if(href_list["view"])
if(!allow_items) return
@@ -128,7 +128,7 @@
//VOREStation Edit End
dat += "
"
- to_chat(user, browse(dat, "window=cryoitems"))
+ user << browse(dat, "window=cryoitems")
else if(href_list["item"])
if(!allow_items) return
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 5d2ed9a174..d7f4b8f581 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -268,7 +268,7 @@ Class Procs:
/obj/machinery/proc/state(var/msg)
for(var/mob/O in hearers(src, null))
- O.show_message("\icon[src] [msg]", 2)
+ O.show_message("[bicon(src)] [msg]", 2)
/obj/machinery/proc/ping(text=null)
if(!text)
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index 4c67aa09a9..557f9169dd 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -138,7 +138,7 @@
var/icon/I = imap[1+(ix + icx*iy)*2]
var/icon/I2 = imap[2+(ix + icx*iy)*2]
- //to_world("icon: \icon[I]")
+ //to_world("icon: [bicon(I)]")
I.DrawBox(colour, rx, ry, rx+1, ry+1)
@@ -153,7 +153,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_world("\icon[I] at [H.screen_loc]")
+ //to_world("[bicon(I)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
@@ -266,7 +266,7 @@
//to_world("trying [ix],[iy] : [ix+icx*iy]")
var/icon/I = imap[1+(ix + icx*iy)]
- //to_world("icon: \icon[I]")
+ //to_world("icon: [bicon(I)]")
I.DrawBox(colour, rx, ry, rx, ry)
@@ -279,7 +279,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_world("\icon[I] at [H.screen_loc]")
+ //to_world("[bicon(I)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index a150aaf566..d9f044ed3c 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -176,7 +176,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
screen = RCS_SENTPASS
message_log += "Message sent to [recipient]
[message]"
else
- audible_message(text("\icon[src] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4)
+ audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4)
//Handle printing
if (href_list["print"])
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index a59fa181e8..555f9b70c7 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -931,7 +931,7 @@
/obj/machinery/suit_cycler/proc/finished_job()
var/turf/T = get_turf(src)
- T.visible_message("\icon[src]The [src] beeps several times.")
+ T.visible_message("[bicon(src)]The [src] beeps several times.")
icon_state = initial(icon_state)
active = 0
playsound(src, 'sound/machines/boobeebeep.ogg', 50)
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 5eb18d6d2f..ed3a4ba4d4 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -348,7 +348,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/part_b_extra = ""
if(data == 3) // intercepted radio message
part_b_extra = " (Intercepted)"
- var/part_a = "\icon[radio]\[[freq_text]\][part_b_extra] " // goes in the actual output
+ var/part_a = "[bicon(radio)]\[[freq_text]\][part_b_extra] " // goes in the actual output
// --- Some more pre-message formatting ---
var/part_b = " " // Tweaked for security headsets -- TLE
@@ -547,7 +547,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// Create a radio headset for the sole purpose of using its icon
var/obj/item/device/radio/headset/radio = new
- var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE
+ var/part_b = " [bicon(radio)]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE
var/part_blackbox_b = " \[[freq_text]\] " // Tweaked for security headsets -- TLE
var/part_c = ""
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index d41104df25..3e3d89643a 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -105,7 +105,7 @@
dat += ""
temp = ""
- to_chat(user, browse(dat, "window=tcommachine;size=520x500;can_resize=0"))
+ user << browse(dat, "window=tcommachine;size=520x500;can_resize=0")
onclose(user, "dormitory")
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 90f801c7a3..57d087cc67 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -227,7 +227,7 @@
// This is not a status display message, since it's something the character
// themselves is meant to see BEFORE putting the money in
- to_chat(usr, "\icon[cashmoney] That is not enough money.")
+ to_chat(usr, "[bicon(cashmoney)] That is not enough money.")
return 0
if(istype(cashmoney, /obj/item/weapon/spacecash))
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index 8f02187132..abfd8492cf 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -266,7 +266,7 @@
/obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message)
if(chassis)
- chassis.occupant_message("\icon[src] [message]")
+ chassis.occupant_message("[bicon(src)] [message]")
return
/obj/item/mecha_parts/mecha_equipment/proc/log_message(message)
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 0b23214a03..71a7610547 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -177,20 +177,20 @@
switch(emagged)
if(0)
emagged = 0.5
- visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"")
+ visible_message("[bicon(src)] [src] beeps: \"DB error \[Code 0x00F1\]\"")
sleep(10)
- visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"")
+ visible_message("[bicon(src)] [src] beeps: \"Attempting auto-repair\"")
sleep(15)
- visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
+ visible_message("[bicon(src)] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
sleep(30)
- visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"")
+ visible_message("[bicon(src)] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"")
req_access = null
emagged = 1
return 1
if(0.5)
- visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
+ visible_message("[bicon(src)] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
if(1)
- visible_message("\icon[src] [src] beeps: \"No records in User DB\"")
+ visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"")
/obj/machinery/mecha_part_fabricator/proc/update_busy()
if(queue.len)
diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm
index 5382cabb46..39b4cf1623 100644
--- a/code/game/mecha/mech_prosthetics.dm
+++ b/code/game/mecha/mech_prosthetics.dm
@@ -204,20 +204,20 @@
switch(emagged)
if(0)
emagged = 0.5
- visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"")
+ visible_message("[bicon(src)] [src] beeps: \"DB error \[Code 0x00F1\]\"")
sleep(10)
- visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"")
+ visible_message("[bicon(src)] [src] beeps: \"Attempting auto-repair\"")
sleep(15)
- visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
+ visible_message("[bicon(src)] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
sleep(30)
- visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"")
+ visible_message("[bicon(src)] [src] beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"")
req_access = null
emagged = 1
return 1
if(0.5)
- visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
+ visible_message("[bicon(src)] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
if(1)
- visible_message("\icon[src] [src] beeps: \"No records in User DB\"")
+ visible_message("[bicon(src)] [src] beeps: \"No records in User DB\"")
/obj/machinery/pros_fabricator/proc/update_busy()
if(queue.len)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 8ad7d0166e..d6bcedc569 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -281,7 +281,7 @@
if(equipment && equipment.len)
to_chat(user, "It's equipped with:")
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
- to_chat(user, "\icon[ME] [ME]")
+ to_chat(user, "[bicon(ME)] [ME]")
return
@@ -1596,7 +1596,7 @@
/obj/mecha/proc/occupant_message(message as text)
if(message)
if(src.occupant && src.occupant.client)
- to_chat(src.occupant, "\icon[src] [message]")
+ to_chat(src.occupant, "[bicon(src)] [message]")
return
/obj/mecha/proc/log_message(message as text,red=null)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 66e7e46008..6a5fcc2a98 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -648,8 +648,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
// auto update every Master Controller tick
ui.set_auto_update(auto_update)
-//NOTE: graphic resources are loaded on client login
/obj/item/device/pda/attack_self(mob/user as mob)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/pda)
+ assets.send(user)
user.set_machine(src)
@@ -1136,7 +1137,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if (!beep_silent)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
- O.show_message(text("\icon[src] *[message_tone]*"))
+ O.show_message(text("[bicon(src)] *[message_tone]*"))
//Search for holder of the PDA.
var/mob/living/L = null
if(loc && isliving(loc))
@@ -1151,7 +1152,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
SSnanoui.update_user_uis(L, src) // Update the receiving user's PDA UI so that they can see the new message
/obj/item/device/pda/proc/new_news(var/message)
- new_info(news_silent, newstone, news_silent ? "" : "\icon[src] [message]")
+ new_info(news_silent, newstone, news_silent ? "" : "[bicon(src)] [message]")
if(!news_silent)
new_news = 1
@@ -1166,7 +1167,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
new_message(sending_device, sending_device.owner, sending_device.ownjob, message)
/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message, var/reply = 1)
- var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])"
+ var/reception_message = "[bicon(src)] Message from [sender] ([sender_job]), \"[message]\" ([reply ? "Reply" : "Unable to Reply"])"
new_info(message_silent, ttone, reception_message)
log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]", usr)
@@ -1178,7 +1179,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(ismob(sending_unit.loc) && isAI(loc))
track = "(Follow)"
- var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply) [track]"
+ var/reception_message = "[bicon(src)] Message from [sender] ([sender_job]), \"[message]\" (Reply) [track]"
new_info(message_silent, newstone, reception_message)
log_pda("(PDA: [sending_unit]) sent \"[message]\" to [name]",usr)
diff --git a/code/game/objects/items/devices/ai_detector.dm b/code/game/objects/items/devices/ai_detector.dm
index fde112706f..94d3a35912 100644
--- a/code/game/objects/items/devices/ai_detector.dm
+++ b/code/game/objects/items/devices/ai_detector.dm
@@ -94,22 +94,22 @@
if(new_state != old_state)
switch(new_state)
if(PROXIMITY_OFF_CAMERANET)
- to_chat(carrier, "\icon[src] Now outside of camera network.")
+ to_chat(carrier, "[bicon(src)] Now outside of camera network.")
carrier << 'sound/machines/defib_failed.ogg'
if(PROXIMITY_NONE)
- to_chat(carrier, "\icon[src] Now within camera network, AI and cameras unfocused.")
+ to_chat(carrier, "[bicon(src)] Now within camera network, AI and cameras unfocused.")
carrier << 'sound/machines/defib_safetyOff.ogg'
if(PROXIMITY_NEAR)
- to_chat(carrier, "\icon[src] Warning: AI focus at nearby location.")
+ to_chat(carrier, "[bicon(src)] Warning: AI focus at nearby location.")
carrier << 'sound/machines/defib_SafetyOn.ogg'
if(PROXIMITY_ON_SCREEN)
- to_chat(carrier, "\icon[src] Alert: AI or camera focused at current location!")
+ to_chat(carrier, "[bicon(src)] Alert: AI or camera focused at current location!")
carrier <<'sound/machines/defib_ready.ogg'
if(PROXIMITY_TRACKING)
- to_chat(carrier, "\icon[src] Danger: AI is actively tracking you!")
+ to_chat(carrier, "[bicon(src)] Danger: AI is actively tracking you!")
carrier << 'sound/machines/defib_success.ogg'
if(PROXIMITY_TRACKING_FAIL)
- to_chat(carrier, "\icon[src] Danger: AI is attempting to actively track you, but you are outside of the camera network!")
+ to_chat(carrier, "[bicon(src)] Danger: AI is attempting to actively track you, but you are outside of the camera network!")
carrier <<'sound/machines/defib_ready.ogg'
diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm
index af3ae77ef5..f34ca86c27 100644
--- a/code/game/objects/items/devices/communicator/communicator.dm
+++ b/code/game/objects/items/devices/communicator/communicator.dm
@@ -313,7 +313,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/item/device/communicator/Destroy()
for(var/mob/living/voice/voice in contents)
voice_mobs.Remove(voice)
- to_chat(voice, "\icon[src] Connection timed out with remote host.")
+ to_chat(voice, "[bicon(src)] Connection timed out with remote host.")
qdel(voice)
close_connection(reason = "Connection timed out")
diff --git a/code/game/objects/items/devices/communicator/messaging.dm b/code/game/objects/items/devices/communicator/messaging.dm
index e50540acb0..57e480957f 100644
--- a/code/game/objects/items/devices/communicator/messaging.dm
+++ b/code/game/objects/items/devices/communicator/messaging.dm
@@ -34,7 +34,7 @@
if(src in comm.voice_invites)
comm.open_connection(src)
return
- to_chat(src, "\icon[origin_atom] Receiving communicator request from [origin_atom]. To answer, use the Call Communicator \
+ to_chat(src, "[bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the Call Communicator \
verb, and select that name to answer the call.")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
@@ -44,7 +44,7 @@
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
- to_chat(src, "\icon[origin_atom] Received text message from [origin_atom]: \"[text]\"")
+ to_chat(src, "[bicon(origin_atom)] Received text message from [origin_atom]: \"[text]\"")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("From [origin_atom]:
[text]")
return
@@ -78,7 +78,7 @@
if(ringer)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
- O.show_message(text("\icon[src] *beep*"))
+ O.show_message(text("[bicon(src)] *beep*"))
alert_called = 1
update_icon()
@@ -89,7 +89,7 @@
L = loc
if(L)
- to_chat(L, "\icon[src] Message from [who].")
+ to_chat(L, "[bicon(src)] Message from [who].")
// Verb: text_communicator()
// Parameters: None
diff --git a/code/game/objects/items/devices/communicator/phone.dm b/code/game/objects/items/devices/communicator/phone.dm
index 7b283786c6..3042b06fa9 100644
--- a/code/game/objects/items/devices/communicator/phone.dm
+++ b/code/game/objects/items/devices/communicator/phone.dm
@@ -39,15 +39,15 @@
comm.voice_requests.Remove(src)
if(user)
- comm.visible_message("\icon[src] Connecting to [src].")
- to_chat(user, "\icon[src] Attempting to call [comm].")
+ comm.visible_message("[bicon(src)] Connecting to [src].")
+ to_chat(user, "[bicon(src)] Attempting to call [comm].")
sleep(10)
- to_chat(user, "\icon[src] Dialing internally from [station_name()], [system_name()].")
+ to_chat(user, "[bicon(src)] Dialing internally from [station_name()], [system_name()].")
sleep(20) //If they don't have an exonet something is very wrong and we want a runtime.
- to_chat(user, "\icon[src] Connection re-routed to [comm] at [comm.exonet.address].")
+ to_chat(user, "[bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].")
sleep(40)
- to_chat(user, "\icon[src] Connection to [comm] at [comm.exonet.address] established.")
- comm.visible_message("\icon[src] Connection to [src] at [exonet.address] established.")
+ to_chat(user, "[bicon(src)] Connection to [comm] at [comm.exonet.address] established.")
+ comm.visible_message("[bicon(src)] Connection to [src] at [exonet.address] established.")
sleep(20)
src.add_communicating(comm)
@@ -86,28 +86,28 @@
//Now for some connection fluff.
if(user)
- to_chat(user, "\icon[src] Connecting to [candidate].")
- to_chat(new_voice, "\icon[src] Attempting to call [src].")
+ to_chat(user, "[bicon(src)] Connecting to [candidate].")
+ to_chat(new_voice, "[bicon(src)] Attempting to call [src].")
sleep(10)
- to_chat(new_voice, "\icon[src] Dialing to [station_name()], Kara Subsystem, [system_name()].")
+ to_chat(new_voice, "[bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].")
sleep(20)
- to_chat(new_voice, "\icon[src] Connecting to [station_name()] telecommunications array.")
+ to_chat(new_voice, "[bicon(src)] Connecting to [station_name()] telecommunications array.")
sleep(40)
- to_chat(new_voice, "\icon[src] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].")
+ to_chat(new_voice, "[bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].")
sleep(20)
//We're connected, no need to hide everything.
new_voice.client.screen.Remove(blackness)
qdel(blackness)
- to_chat(new_voice, "\icon[src] Connection to [src] established.")
+ to_chat(new_voice, "[bicon(src)] Connection to [src] established.")
to_chat(new_voice, "To talk to the person on the other end of the call, just talk normally.")
to_chat(new_voice, "If you want to end the call, use the 'Hang Up' verb. The other person can also hang up at any time.")
to_chat(new_voice, "Remember, your character does not know anything you've learned from observing!")
if(new_voice.mind)
new_voice.mind.assigned_role = "Disembodied Voice"
if(user)
- to_chat(user, "\icon[src] Your communicator is now connected to [candidate]'s communicator.")
+ to_chat(user, "[bicon(src)] Your communicator is now connected to [candidate]'s communicator.")
// Proc: close_connection()
// Parameters: 3 (user - the user who initiated the disconnect, target - the mob or device being disconnected, reason - string shown when disconnected)
@@ -120,8 +120,8 @@
for(var/mob/living/voice/voice in voice_mobs) //Handle ghost-callers
if(target && voice != target) //If no target is inputted, it deletes all of them.
continue
- to_chat(voice, "\icon[src] [reason].")
- visible_message("\icon[src] [reason].")
+ to_chat(voice, "[bicon(src)] [reason].")
+ visible_message("[bicon(src)] [reason].")
voice_mobs.Remove(voice)
qdel(voice)
update_icon()
@@ -131,8 +131,8 @@
continue
src.del_communicating(comm)
comm.del_communicating(src)
- comm.visible_message("\icon[src] [reason].")
- visible_message("\icon[src] [reason].")
+ comm.visible_message("[bicon(src)] [reason].")
+ visible_message("[bicon(src)] [reason].")
if(comm.camera && video_source == comm.camera) //We hung up on the person on video
end_video()
if(camera && comm.video_source == camera) //We hung up on them while they were watching us
@@ -163,7 +163,7 @@
if(ringer)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
- O.show_message(text("\icon[src] *beep*"))
+ O.show_message(text("[bicon(src)] *beep*"))
alert_called = 1
update_icon()
@@ -174,7 +174,7 @@
L = loc
if(L)
- to_chat(L, "\icon[src] Communications request from [who].")
+ to_chat(L, "[bicon(src)] Communications request from [who].")
// Proc: del_request()
// Parameters: 1 (candidate - the ghost or communicator to be declined)
@@ -197,13 +197,13 @@
us = loc
if(us)
- to_chat(us, "\icon[src] Declined request.")
+ to_chat(us, "[bicon(src)] Declined request.")
// Proc: see_emote()
// Parameters: 2 (M - the mob the emote originated from, text - the emote's contents)
// Description: Relays the emote to all linked communicators.
/obj/item/device/communicator/see_emote(mob/living/M, text)
- var/rendered = "\icon[src] [text]"
+ var/rendered = "[bicon(src)] [text]"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
@@ -255,16 +255,16 @@
var/name_used = M.GetVoice()
var/rendered = null
if(speaking) //Language being used
- rendered = "\icon[src] [name_used] [speaking.format_message(text, verb)]"
+ rendered = "[bicon(src)] [name_used] [speaking.format_message(text, verb)]"
else
- rendered = "\icon[src] [name_used] [verb], \"[text]\""
+ rendered = "[bicon(src)] [name_used] [verb], \"[text]\""
mob.show_message(rendered, 2)
// Proc: show_message()
// Parameters: 4 (msg - the message, type - number to determine if message is visible or audible, alt - unknown, alt_type - unknown)
// Description: Relays the message to all linked communicators.
/obj/item/device/communicator/show_message(msg, type, alt, alt_type)
- var/rendered = "\icon[src] [msg]"
+ var/rendered = "[bicon(src)] [msg]"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
@@ -345,14 +345,14 @@
to_chat(user, "You cannot see well enough to do that!")
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
- to_chat(user, "\icon[src]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.")
+ to_chat(user, "[bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.")
- to_chat(user, "\icon[src] Attempting to start video over existing call.")
+ to_chat(user, "[bicon(src)] Attempting to start video over existing call.")
sleep(30)
- to_chat(user, "\icon[src] Please wait...")
+ to_chat(user, "[bicon(src)] Please wait...")
video_source = comm.camera
- comm.visible_message("\icon[src] New video connection from [comm].")
+ comm.visible_message("[bicon(src)] New video connection from [comm].")
watch_video(user)
update_icon()
@@ -391,7 +391,7 @@
/obj/item/device/communicator/proc/end_video(var/reason)
video_source = null
- . = "\icon[src] [reason ? reason : "Video session ended"]."
+ . = "[bicon(src)] [reason ? reason : "Video session ended"]."
visible_message(.)
update_icon()
diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm
index 92ff449855..c6f7c3f9f1 100644
--- a/code/game/objects/items/devices/geiger.dm
+++ b/code/game/objects/items/devices/geiger.dm
@@ -62,7 +62,7 @@
scanning = !scanning
update_icon()
update_sound()
- to_chat(user, "\icon[src] You switch [scanning ? "on" : "off"] \the [src].")
+ to_chat(user, "[bicon(src)] You switch [scanning ? "on" : "off"] \the [src].")
/obj/item/device/geiger/update_icon()
if(!scanning)
diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm
index f6fad2efb5..0b6d25f0c9 100644
--- a/code/game/objects/items/devices/hacktool.dm
+++ b/code/game/objects/items/devices/hacktool.dm
@@ -47,7 +47,7 @@
to_chat(user, "You are already hacking!")
return 0
if(!is_type_in_list(target, supported_types))
- to_chat(user, "\icon[src] Unable to hack this target!")
+ to_chat(user, "[bicon(src)] Unable to hack this target!")
return 0
var/found = known_targets.Find(target)
if(found)
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index c0493e1f42..8948a1ec11 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -361,7 +361,7 @@ var/global/list/default_medbay_channels = list(
var/list/jamming = is_jammed(src)
if(jamming)
var/distance = jamming["distance"]
- to_chat(M, "\icon[src] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.")
+ to_chat(M, "[bicon(src)] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.")
return FALSE
// First, we want to generate a new radio signal
diff --git a/code/game/objects/items/devices/text_to_speech.dm b/code/game/objects/items/devices/text_to_speech.dm
index 47dfc256fc..f3feacd86e 100644
--- a/code/game/objects/items/devices/text_to_speech.dm
+++ b/code/game/objects/items/devices/text_to_speech.dm
@@ -25,4 +25,4 @@
var/message = sanitize(input(user,"Choose a message to relay to those around you.") as text|null)
if(message)
var/obj/item/device/text_to_speech/O = src
- audible_message("\icon[O] \The [O.name] states, \"[message]\"")
+ audible_message("[bicon(O)] \The [O.name] states, \"[message]\"")
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index ec8cb44e5a..850de74ba4 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -441,7 +441,7 @@
/obj/item/toy/waterflower/examine(mob/user)
if(..(user, 0))
- to_chat(user, "\icon[src] [src.reagents.total_volume] units of water left!")
+ to_chat(user, "[bicon(src)] [src.reagents.total_volume] units of water left!")
/*
* Bosun's whistle
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index 6445c205a9..87fb0ffb7d 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -40,7 +40,7 @@
/obj/item/weapon/extinguisher/examine(mob/user)
if(..(user, 0))
- to_chat(user, text("\icon[] [] contains [] units of water left!", src, src.name, src.reagents.total_volume))
+ to_chat(user, "[bicon(src)] [src.name] contains [src.reagents.total_volume] units of water left!")
/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
safety = !safety
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index 56cdde182e..c43217919a 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -91,8 +91,8 @@
return dat
/obj/item/weapon/card/id/attack_self(mob/user as mob)
- user.visible_message("\The [user] shows you: \icon[src] [src.name]. The assignment on the card: [src.assignment]",\
- "You flash your ID card: \icon[src] [src.name]. The assignment on the card: [src.assignment]")
+ user.visible_message("\The [user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\
+ "You flash your ID card: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]")
src.add_fingerprint(user)
return
@@ -108,7 +108,7 @@
set category = "Object"
set src in usr
- to_chat(usr, "\icon[src] [src.name]: The current assignment on the card is [src.assignment].")
+ to_chat(usr, "[bicon(src)] [src.name]: The current assignment on the card is [src.assignment].")
to_chat(usr, "The blood type on the card is [blood_type].")
to_chat(usr, "The DNA hash on the card is [dna_hash].")
to_chat(usr, "The fingerprint hash on the card is [fingerprint_hash].")
diff --git a/code/game/objects/items/weapons/syndie.dm b/code/game/objects/items/weapons/syndie.dm
index ee528cb6f8..c4e273deea 100644
--- a/code/game/objects/items/weapons/syndie.dm
+++ b/code/game/objects/items/weapons/syndie.dm
@@ -50,7 +50,7 @@
icon_state = "c-4[size]_1"
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1)
for(var/mob/O in hearers(src, null))
- O.show_message("\icon[src] The [src.name] beeps! ")
+ O.show_message("[bicon(src)] The [src.name] beeps! ")
sleep(50)
explosion(get_turf(src), devastate, heavy_impact, light_impact, flash_range)
for(var/dirn in cardinal) //This is to guarantee that C4 at least breaks down all immediately adjacent walls and doors.
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index a2113aab63..9c54377e8f 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -464,7 +464,7 @@ var/list/global/tank_gauge_cache = list()
return
T.assume_air(air_contents)
playsound(get_turf(src), 'sound/weapons/Gunshot_shotgun.ogg', 20, 1)
- visible_message("\icon[src] \The [src] flies apart!", "You hear a bang!")
+ visible_message("[bicon(src)] \The [src] flies apart!", "You hear a bang!")
T.hotspot_expose(air_contents.temperature, 70, 1)
@@ -509,7 +509,7 @@ var/list/global/tank_gauge_cache = list()
T.assume_air(leaked_gas)
if(!leaking)
- visible_message("\icon[src] \The [src] relief valve flips open with a hiss!", "You hear hissing.")
+ visible_message("[bicon(src)] \The [src] relief valve flips open with a hiss!", "You hear hissing.")
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
leaking = 1
#ifdef FIREDBG
diff --git a/code/game/objects/items/weapons/tools/combitool.dm b/code/game/objects/items/weapons/tools/combitool.dm
index 96b64d18f7..b154f059af 100644
--- a/code/game/objects/items/weapons/tools/combitool.dm
+++ b/code/game/objects/items/weapons/tools/combitool.dm
@@ -27,7 +27,7 @@
if(loc == usr && tools.len)
to_chat(usr, "It has the following fittings:")
for(var/obj/item/tool in tools)
- to_chat(usr, "\icon[tool] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
+ to_chat(usr, "[bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
/obj/item/weapon/combitool/New()
..()
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index 38bfdf3d94..0a1699ca3a 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -57,7 +57,7 @@
/obj/item/weapon/weldingtool/examine(mob/user)
if(..(user, 0))
if(max_fuel)
- to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel ))
+ to_chat(user, "[bicon(src)] The [src.name] contains [get_fuel()]/[src.max_fuel] units of fuel!")
/obj/item/weapon/weldingtool/attack(atom/A, mob/living/user, def_zone)
if(ishuman(A) && user.a_intent == I_HELP)
@@ -560,9 +560,9 @@
to_chat(user, desc)
else
if(power_supply)
- to_chat(user, "\icon[src] The [src.name] has [get_fuel()] charge left.")
+ to_chat(user, "[bicon(src)] The [src.name] has [get_fuel()] charge left.")
else
- to_chat(user, "\icon[src] The [src.name] has no power cell!")
+ to_chat(user, "[bicon(src)] The [src.name] has no power cell!")
/obj/item/weapon/weldingtool/electric/get_fuel()
if(use_external_power)
diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm
index b33eeca7c2..886f90498a 100644
--- a/code/game/objects/items/weapons/weldbackpack.dm
+++ b/code/game/objects/items/weapons/weldbackpack.dm
@@ -144,7 +144,7 @@
/obj/item/weapon/weldpack/examine(mob/user)
..(user)
- to_chat(user, "\icon[src] [src.reagents.total_volume] units of fuel left!")
+ to_chat(user, "[bicon(src)] [src.reagents.total_volume] units of fuel left!")
return
/obj/item/weapon/weldpack/survival
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index c7b8c07f8d..faafdb62f3 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -58,7 +58,7 @@
/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state)
if(user.CanUseObjTopic(src))
return ..()
- to_chat(user, "\icon[src]Access Denied!")
+ to_chat(user, "[bicon(src)]Access Denied!")
return STATUS_CLOSE
/mob/living/silicon/CanUseObjTopic(var/obj/O)
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index 6e01e0035e..93c48fe8a9 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -25,7 +25,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/janitorialcart/examine(mob/user)
if(..(user, 1))
- to_chat(user, "[src] \icon[src] contains [reagents.total_volume] unit\s of liquid!")
+ to_chat(user, "[src] [bicon(src)] contains [reagents.total_volume] unit\s of liquid!")
//everything else is visible, so doesn't need to be mentioned
@@ -189,7 +189,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
if(!..(user, 1))
return
- to_chat(user, "\icon[src] This [callme] contains [reagents.total_volume] unit\s of water!")
+ to_chat(user, "[bicon(src)] This [callme] contains [reagents.total_volume] unit\s of water!")
if(mybag)
to_chat(user, "\A [mybag] is hanging on the [callme].")
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index c1180aa6db..17e594c4c3 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -18,7 +18,7 @@ GLOBAL_LIST_BOILERPLATE(all_mopbuckets, /obj/structure/mopbucket)
/obj/structure/mopbucket/examine(mob/user)
if(..(user, 1))
- to_chat(user, "[src] \icon[src] contains [reagents.total_volume] unit\s of water!")
+ to_chat(user, "[src] [bicon(src)] contains [reagents.total_volume] unit\s of water!")
/obj/structure/mopbucket/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/mop) || istype(I, /obj/item/weapon/soap) || istype(I, /obj/item/weapon/reagent_containers/glass/rag)) //VOREStation Edit - "Allows soap and rags to be used on mopbuckets"
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index c4facdaa20..353df5ecb8 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -192,7 +192,7 @@ obj/structure/windoor_assembly/Destroy()
if(src.electronics && istype(src.electronics, /obj/item/weapon/circuitboard/broken))
to_chat(usr,"The assembly has broken airlock electronics.")
return
- to_chat(usr,browse(null, "window=windoor_access")) //Not sure what this actually does... -Ner
+ usr << browse(null, "window=windoor_access") //Not sure what this actually does... -Ner
playsound(src, W.usesound, 100, 1)
user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame.")
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index b4421d5c63..000c9991b7 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -162,12 +162,12 @@
if(target in admins)
admin_stuff += "/([key])"
- to_chat(target, "" + create_text_tag("looc", "LOOC:", target) + " [display_name][admin_stuff]: [msg]")
+ to_chat(target, "" + create_text_tag("looc", "LOOC:", target) + " [display_name][admin_stuff]: [msg]")
for(var/client/target in r_receivers)
var/admin_stuff = "/([key])([admin_jump_link(mob, target.holder)])"
- to_chat(target, "" + create_text_tag("looc", "LOOC:", target) + " (R)[display_name][admin_stuff]: [msg]")
+ to_chat(target, "" + create_text_tag("looc", "LOOC:", target) + " (R)[display_name][admin_stuff]: [msg]")
/mob/proc/get_looc_source()
return src
diff --git a/code/game/world.dm b/code/game/world.dm
index 79e4a1c4b9..47a0153cf4 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -28,6 +28,7 @@
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
callHook("startup")
+ init_vchat()
//Emergency Fix
load_mods()
//end-emergency fix
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 3cff6300b0..d018c6c475 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -17,7 +17,7 @@
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
- msg = "\icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, src)]) (CA) (SC) (SMITE): [msg]"
+ msg = "[bicon(cross)] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, src)]) (CA) (SC) (SMITE): [msg]"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 7db2d4e827..441367c80d 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -203,7 +203,7 @@
/obj/item/device/assembly_holder/process_activation(var/obj/D, var/normal = 1, var/special = 1)
if(!D) return 0
if(!secured)
- visible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
+ visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
if((normal) && (a_right) && (a_left))
if(a_right != D)
a_right.pulsed(0)
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 6afdb163cc..75985f7822 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -97,7 +97,7 @@
if((!secured)||(!on)||(cooldown > 0)) return 0
pulse(0)
if(!holder)
- visible_message("\icon[src] *beep* *beep*")
+ visible_message("[bicon(src)] *beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index a03130ea92..2ac1fdf90f 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -25,7 +25,7 @@
/obj/item/device/assembly/prox_sensor/toggle_secure()
secured = !secured
if(secured)
- START_PROCESSING(SSobj, src)
+ START_PROCESSING(SSobj, src)
else
scanning = 0
timing = 0
@@ -46,11 +46,11 @@
/obj/item/device/assembly/prox_sensor/proc/sense()
var/turf/mainloc = get_turf(src)
// if(scanning && cooldown <= 0)
-// mainloc.visible_message("\icon[src] *boop* *boop*", "*boop* *boop*")
+// mainloc.visible_message("[bicon(src)] *boop* *boop*", "*boop* *boop*")
if((!holder && !secured)||(!scanning)||(cooldown > 0)) return 0
pulse(0)
if(!holder)
- mainloc.visible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
+ mainloc.visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index a8859e7c1c..448e0c9860 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -148,7 +148,7 @@ Code:
if(!holder)
for(var/mob/O in hearers(1, src.loc))
- O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
+ O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
return
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index 488083d11a..543d7d1801 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -25,7 +25,7 @@
/obj/item/device/assembly/timer/toggle_secure()
secured = !secured
if(secured)
- START_PROCESSING(SSobj, src)
+ START_PROCESSING(SSobj, src)
else
timing = 0
STOP_PROCESSING(SSobj, src)
@@ -37,7 +37,7 @@
if(!secured) return 0
pulse(0)
if(!holder)
- visible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
+ visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
cooldown = 2
spawn(10)
process_cooldown()
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index 7e8c89cc79..0cf4b85665 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -12,7 +12,7 @@
recorded = msg
listening = 0
var/turf/T = get_turf(src) //otherwise it won't work in hand
- T.visible_message("\icon[src] beeps, \"Activation message is '[recorded]'.\"")
+ T.visible_message("[bicon(src)] beeps, \"Activation message is '[recorded]'.\"")
else
if(findtext(msg, recorded))
pulse(0)
@@ -22,7 +22,7 @@
if(!holder)
listening = !listening
var/turf/T = get_turf(src)
- T.visible_message("\icon[src] beeps, \"[listening ? "Now" : "No longer"] recording input.\"")
+ T.visible_message("[bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"")
/obj/item/device/assembly/voice/attack_self(mob/user)
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
new file mode 100644
index 0000000000..0e2f2f9f21
--- /dev/null
+++ b/code/modules/client/asset_cache.dm
@@ -0,0 +1,287 @@
+/*
+Asset cache quick users guide:
+
+Make a datum at the bottom of this file with your assets for your thing.
+The simple subsystem will most like be of use for most cases.
+Then call get_asset_datum() with the type of the datum you created and store the return
+Then call .send(client) on that stored return value.
+
+You can set verify to TRUE if you want send() to sleep until the client has the assets.
+*/
+
+
+// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
+// This is doubled for the first asset, then added per asset after
+#define ASSET_CACHE_SEND_TIMEOUT 7
+
+//When sending mutiple assets, how many before we give the client a quaint little sending resources message
+#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
+
+//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
+#define ASSET_CACHE_PRELOAD_CONCURRENT 3
+
+/client
+ var/list/cache = list() // List of all assets sent to this client by the asset cache.
+ var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
+ var/list/sending = list()
+ var/last_asset_job = 0 // Last job done.
+
+//This proc sends the asset to the client, but only if it needs it.
+//This proc blocks(sleeps) unless verify is set to false
+/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
+ if(!istype(client))
+ if(ismob(client))
+ var/mob/M = client
+ if(M.client)
+ client = M.client
+
+ else
+ return 0
+
+ else
+ return 0
+
+ if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
+ return 0
+
+ client << browse_rsc(SSassets.cache[asset_name], asset_name)
+ if(!verify) // Can't access the asset cache browser, rip.
+ client.cache += asset_name
+ return 1
+
+ client.sending |= asset_name
+ var/job = ++client.last_asset_job
+
+ client << browse({"
+
+ "}, "window=asset_cache_browser")
+
+ var/t = 0
+ var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
+ while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
+ sleep(1) // Lock up the caller until this is received.
+ t++
+
+ if(client)
+ client.sending -= asset_name
+ client.cache |= asset_name
+ client.completed_asset_jobs -= job
+
+ return 1
+
+//This proc blocks(sleeps) unless verify is set to false
+/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
+ if(!istype(client))
+ if(ismob(client))
+ var/mob/M = client
+ if(M.client)
+ client = M.client
+
+ else
+ return 0
+
+ else
+ return 0
+
+ var/list/unreceived = asset_list - (client.cache + client.sending)
+ if(!unreceived || !unreceived.len)
+ return 0
+ if(unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
+ to_chat(client, "Sending Resources...")
+ for(var/asset in unreceived)
+ if(asset in SSassets.cache)
+ client << browse_rsc(SSassets.cache[asset], asset)
+
+ if(!verify) // Can't access the asset cache browser, rip.
+ client.cache += unreceived
+ return 1
+
+ client.sending |= unreceived
+ var/job = ++client.last_asset_job
+
+ client << browse({"
+
+ "}, "window=asset_cache_browser")
+
+ var/t = 0
+ var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
+ while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
+ sleep(1) // Lock up the caller until this is received.
+ t++
+
+ if(client)
+ client.sending -= unreceived
+ client.cache |= unreceived
+ client.completed_asset_jobs -= job
+
+ return 1
+
+//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
+//The proc calls procs that sleep for long times.
+/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
+ var/concurrent_tracker = 1
+ for(var/file in files)
+ if(!client)
+ break
+ if(register_asset)
+ register_asset(file, files[file])
+ if(concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT)
+ concurrent_tracker = 1
+ send_asset(client, file)
+ else
+ concurrent_tracker++
+ send_asset(client, file, verify = FALSE)
+ sleep(0) //queuing calls like this too quickly can cause issues in some client versions
+
+//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
+//if it's an icon or something be careful, you'll have to copy it before further use.
+/proc/register_asset(var/asset_name, var/asset)
+ SSassets.cache[asset_name] = asset
+
+//These datums are used to populate the asset cache, the proc "register()" does this.
+
+//all of our asset datums, used for referring to these later
+/var/global/list/asset_datums = list()
+
+//get a assetdatum or make a new one
+/proc/get_asset_datum(var/type)
+ if(!(type in asset_datums))
+ return new type()
+ return asset_datums[type]
+
+/datum/asset/New()
+ asset_datums[type] = src
+
+/datum/asset/proc/register()
+ return
+
+/datum/asset/proc/send(client)
+ return
+
+//If you don't need anything complicated.
+/datum/asset/simple
+ var/assets = list()
+ var/verify = FALSE
+
+/datum/asset/simple/register()
+ for(var/asset_name in assets)
+ register_asset(asset_name, assets[asset_name])
+/datum/asset/simple/send(client)
+ send_asset_list(client,assets,verify)
+
+
+//DEFINITIONS FOR ASSET DATUMS START HERE.
+/datum/asset/simple/pda
+ assets = list(
+ "pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
+ "pda_back.png" = 'icons/pda_icons/pda_back.png',
+ "pda_bell.png" = 'icons/pda_icons/pda_bell.png',
+ "pda_blank.png" = 'icons/pda_icons/pda_blank.png',
+ "pda_boom.png" = 'icons/pda_icons/pda_boom.png',
+ "pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
+ "pda_crate.png" = 'icons/pda_icons/pda_crate.png',
+ "pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
+ "pda_eject.png" = 'icons/pda_icons/pda_eject.png',
+ "pda_exit.png" = 'icons/pda_icons/pda_exit.png',
+ "pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
+ "pda_honk.png" = 'icons/pda_icons/pda_honk.png',
+ "pda_mail.png" = 'icons/pda_icons/pda_mail.png',
+ "pda_medical.png" = 'icons/pda_icons/pda_medical.png',
+ "pda_menu.png" = 'icons/pda_icons/pda_menu.png',
+ "pda_mule.png" = 'icons/pda_icons/pda_mule.png',
+ "pda_notes.png" = 'icons/pda_icons/pda_notes.png',
+ "pda_power.png" = 'icons/pda_icons/pda_power.png',
+ "pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
+ "pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
+ "pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
+ "pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
+ "pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
+ "pda_status.png" = 'icons/pda_icons/pda_status.png'
+ )
+
+/datum/asset/simple/generic
+ assets = list(
+ "search.js" = 'html/search.js',
+ "panels.css" = 'html/panels.css',
+ "loading.gif" = 'html/images/loading.gif',
+ "ntlogo.png" = 'html/images/ntlogo.png',
+ "sglogo.png" = 'html/images/sglogo.png',
+ "talisman.png" = 'html/images/talisman.png',
+ "paper_bg.png" = 'html/images/paper_bg.png',
+ "no_image32.png" = 'html/images/no_image32.png',
+ "sos_1.png" = 'icons/spideros_icons/sos_1.png',
+ "sos_2.png" = 'icons/spideros_icons/sos_2.png',
+ "sos_3.png" = 'icons/spideros_icons/sos_3.png',
+ "sos_4.png" = 'icons/spideros_icons/sos_4.png',
+ "sos_5.png" = 'icons/spideros_icons/sos_5.png',
+ "sos_6.png" = 'icons/spideros_icons/sos_6.png',
+ "sos_7.png" = 'icons/spideros_icons/sos_7.png',
+ "sos_8.png" = 'icons/spideros_icons/sos_8.png',
+ "sos_9.png" = 'icons/spideros_icons/sos_9.png',
+ "sos_10.png" = 'icons/spideros_icons/sos_10.png',
+ "sos_11.png" = 'icons/spideros_icons/sos_11.png',
+ "sos_12.png" = 'icons/spideros_icons/sos_12.png',
+ "sos_13.png" = 'icons/spideros_icons/sos_13.png',
+ "sos_14.png" = 'icons/spideros_icons/sos_14.png'
+ )
+
+/datum/asset/simple/changelog
+ assets = list(
+ "88x31.png" = 'html/88x31.png',
+ "bug-minus.png" = 'html/bug-minus.png',
+ "cross-circle.png" = 'html/cross-circle.png',
+ "hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png',
+ "image-minus.png" = 'html/image-minus.png',
+ "image-plus.png" = 'html/image-plus.png',
+ "map-pencil.png" = 'html/map-pencil.png',
+ "music-minus.png" = 'html/music-minus.png',
+ "music-plus.png" = 'html/music-plus.png',
+ "tick-circle.png" = 'html/tick-circle.png',
+ "wrench-screwdriver.png" = 'html/wrench-screwdriver.png',
+ "spell-check.png" = 'html/spell-check.png',
+ "burn-exclamation.png" = 'html/burn-exclamation.png',
+ "chevron.png" = 'html/chevron.png',
+ "chevron-expand.png" = 'html/chevron-expand.png',
+ "changelog.css" = 'html/changelog.css',
+ "changelog.js" = 'html/changelog.js',
+ "changelog.html" = 'html/changelog.html'
+ )
+
+/datum/asset/nanoui
+ var/list/common = list()
+
+ var/list/common_dirs = list(
+ "nano/css/",
+ "nano/images/",
+ "nano/js/"
+ )
+ var/list/uncommon_dirs = list(
+ "nano/templates/"
+ )
+
+/datum/asset/nanoui/register()
+ // Crawl the directories to find files.
+ for(var/path in common_dirs)
+ var/list/filenames = flist(path)
+ for(var/filename in filenames)
+ if(copytext(filename, length(filename)) != "/") // Ignore directories.
+ if(fexists(path + filename))
+ common[filename] = fcopy_rsc(path + filename)
+ register_asset(filename, common[filename])
+ for(var/path in uncommon_dirs)
+ var/list/filenames = flist(path)
+ for(var/filename in filenames)
+ if(copytext(filename, length(filename)) != "/") // Ignore directories.
+ if(fexists(path + filename))
+ register_asset(filename, fcopy_rsc(path + filename))
+
+/datum/asset/nanoui/send(client, uncommon)
+ if(!islist(uncommon))
+ uncommon = list(uncommon)
+
+ send_asset_list(client, uncommon)
+ send_asset_list(client, common)
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index d624ec6f15..169dcd5b07 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -24,6 +24,8 @@
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
var/datum/tooltip/tooltips = null
+ var/datum/chatOutput/chatOutput
+ var/chatOutputLoadedAt
var/adminhelped = 0
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 97c425f958..d09986360d 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -34,6 +34,11 @@
#endif
+ if(href_list["asset_cache_confirm_arrival"])
+ var/job = text2num(href_list["asset_cache_confirm_arrival"])
+ completed_asset_jobs += job
+ return
+
//search the href for script injection
if( findtext(href,"
+
+
+
+
+
+
+
VChat is still loading. If you see this for a very long time, try the OOC 'Reload VChat' verb, or reconnecting.
+
Sometimes if you're still caching resources, it will take longer than usual.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
'{{active_tab.name}}' Tab Settings
+
This tab is immutable. You cannot make changes.
+
+
+
+
Global Settings
+
+
+
+
+
+
+
+
+
+
+ [ {{messages.length - showingnum}} previous messages hidden due to display settings. ]
+
+
+
+
+ x{{message.repeats}}
+
+
+
+
+
+
+
+
+
+
+
+
+