diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 702229916464..7ca6ef7cd34a 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -345,6 +345,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
//debug printing macros
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
+#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 04ea69a43f9d..855675a29fd9 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: [bicon(getFlatIcon(src))]")
+ to_chat(src, "Icon is: [icon2base64html(getFlatIcon(src))]")
Label_Icon()
set name = "3. Label Icon"
@@ -993,3 +993,110 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
#undef FROZEN_RED_COLOR
#undef FROZEN_GREEN_COLOR
#undef FROZEN_BLUE_COLOR
+
+
+//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
+// exporting it as text, and then parsing the base64 from that.
+// (This relies on byond automatically storing icons in savefiles as base64)
+/proc/icon2base64(icon/icon, iconKey = "misc")
+ if (!isicon(icon))
+ return FALSE
+ WRITE_FILE(GLOB.iconCache[iconKey], icon)
+ var/iconData = GLOB.iconCache.ExportText(iconKey)
+ var/list/partial = splittext(iconData, "{")
+ return replacetext(copytext(partial[2], 3, -5), "\n", "")
+
+/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
+ if (!thing)
+ return
+
+ var/key
+ var/icon/I = thing
+ if (!target)
+ return
+ if (target == world)
+ target = GLOB.clients
+
+ var/list/targets
+ if (!islist(target))
+ targets = list(target)
+ else
+ targets = target
+ if (!targets.len)
+ return
+ if (!isicon(I))
+ if (isfile(thing)) //special snowflake
+ var/name = sanitize_filename("[generate_asset_name(thing)].png")
+ register_asset(name, thing)
+ for (var/thing2 in targets)
+ send_asset(thing2, key, FALSE)
+ return "
"
+ var/atom/A = thing
+ if (isnull(dir))
+ dir = A.dir
+ if (isnull(icon_state))
+ icon_state = A.icon_state
+ I = A.icon
+ if (ishuman(thing)) // Shitty workaround for a BYOND issue.
+ var/icon/temp = I
+ I = icon()
+ I.Insert(temp, dir = SOUTH)
+ dir = SOUTH
+ else
+ if (isnull(dir))
+ dir = SOUTH
+ if (isnull(icon_state))
+ icon_state = ""
+
+ I = icon(I, icon_state, dir, frame, moving)
+
+ key = "[generate_asset_name(I)].png"
+ register_asset(key, I)
+ for (var/thing2 in targets)
+ send_asset(thing2, key, FALSE)
+
+ return "
"
+
+/proc/icon2base64html(thing)
+ if (!thing)
+ return
+ var/static/list/bicon_cache = list()
+ if (isicon(thing))
+ var/icon/I = thing
+ var/icon_base64 = icon2base64(I)
+
+ if (I.Height() > world.icon_size || I.Width() > world.icon_size)
+ var/icon_md5 = md5(icon_base64)
+ icon_base64 = bicon_cache[icon_md5]
+ if (!icon_base64) // Doesn't exist yet, make it.
+ bicon_cache[icon_md5] = icon_base64 = icon2base64(I)
+
+
+ return "
"
+
+ // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
+ var/atom/A = thing
+ var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
+
+
+ if (!bicon_cache[key]) // Doesn't exist, make it.
+ var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1)
+ if (ishuman(thing)) // Shitty workaround for a BYOND issue.
+ var/icon/temp = I
+ I = icon()
+ I.Insert(temp, dir = SOUTH)
+
+ bicon_cache[key] = icon2base64(I, key)
+
+ return "
"
+
+//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
+/proc/costly_icon2html(thing, target)
+ if (!thing)
+ return
+
+ if (isicon(thing))
+ return icon2html(thing, target)
+
+ var/icon/I = getFlatIcon(thing)
+ return icon2html(I, target)
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 60c95f474097..53691d122e5c 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -45,6 +45,9 @@
index = findtext(t, char, index+1)
return t
+/proc/sanitize_filename(t)
+ return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
+
//Runs byond's sanitization proc along-side sanitize_simple
/proc/sanitize(t,list/repl_chars = null)
return html_encode(sanitize_simple(t,repl_chars))
@@ -560,7 +563,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
var/next_backslash = findtext(string, "\\")
if(!next_backslash)
return string
-
+
var/leng = length(string)
var/next_space = findtext(string, " ", next_backslash + 1)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index e94fc9f4b00b..4ed57f0a9307 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -857,11 +857,11 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
/obj/proc/atmosanalyzer_scan(datum/gas_mixture/air_contents, mob/user, obj/target = src)
var/obj/icon = target
- user.visible_message("[user] has used the analyzer on [bicon(icon)] [target].", "You use the analyzer on [bicon(icon)] [target].")
+ user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(src))] [target].", "You use the analyzer on [icon2html(icon, user)] [target].")
var/pressure = air_contents.return_pressure()
var/total_moles = air_contents.total_moles()
- to_chat(user, "Results of analysis of [bicon(icon)] [target].")
+ to_chat(user, "Results of analysis of [icon2html(icon, user)] [target].")
if(total_moles>0)
to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
diff --git a/code/controllers/subsystem/assets.dm b/code/controllers/subsystem/assets.dm
index 607b142c59b9..fd27c9424fbf 100644
--- a/code/controllers/subsystem/assets.dm
+++ b/code/controllers/subsystem/assets.dm
@@ -3,12 +3,15 @@ SUBSYSTEM_DEF(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, cache, FALSE), 10)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
..()
diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm
index 00b2dd10b899..9aa2ca81e825 100644
--- a/code/datums/wires/mulebot.dm
+++ b/code/datums/wires/mulebot.dm
@@ -20,12 +20,12 @@
var/mob/living/simple_animal/bot/mulebot/M = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2)
- holder.visible_message("[bicon(M)] The charge light flickers.")
+ holder.visible_message("[icon2html(M, viewers(holder))] The charge light flickers.")
if(WIRE_AVOIDANCE)
- holder.visible_message("[bicon(M)] The external warning lights flash briefly.")
+ holder.visible_message("[icon2html(M, viewers(holder))] The external warning lights flash briefly.")
if(WIRE_LOADCHECK)
- holder.visible_message("[bicon(M)] The load platform clunks.")
+ holder.visible_message("[icon2html(M, viewers(holder))] The load platform clunks.")
if(WIRE_MOTOR1, WIRE_MOTOR2)
- holder.visible_message("[bicon(M)] The drive motor whines briefly.")
+ holder.visible_message("[icon2html(M, viewers(holder))] The drive motor whines briefly.")
else
- holder.visible_message("[bicon(M)] You hear a radio crackle.")
\ No newline at end of file
+ holder.visible_message("[icon2html(M, viewers(holder))] You hear a radio crackle.")
\ No newline at end of file
diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm
index 436b8be3ecd5..d38147f1ecde 100644
--- a/code/datums/wires/particle_accelerator.dm
+++ b/code/datums/wires/particle_accelerator.dm
@@ -25,7 +25,7 @@
if(WIRE_INTERFACE)
C.interface_control = !C.interface_control
if(WIRE_LIMIT)
- C.visible_message("[bicon(C)][C] makes a large whirring noise.")
+ C.visible_message("[icon2html(C, viewers(holder))][C] makes a large whirring noise.")
/datum/wires/particle_accelerator/control_box/on_cut(wire, mend)
var/obj/machinery/particle_accelerator/control_box/C = holder
diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm
index 78acc42eb047..043110f5d3f1 100644
--- a/code/datums/wires/syndicatebomb.dm
+++ b/code/datums/wires/syndicatebomb.dm
@@ -19,21 +19,21 @@
switch(wire)
if(WIRE_BOOM)
if(B.active)
- holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
+ holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
if(WIRE_UNBOLT)
- holder.visible_message("[bicon(B)] The bolts spin in place for a moment.")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bolts spin in place for a moment.")
if(WIRE_DELAY)
if(B.delayedbig)
- holder.visible_message("[bicon(B)] The bomb has already been delayed.")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bomb has already been delayed.")
else
- holder.visible_message("[bicon(B)] The bomb chirps.")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bomb chirps.")
playsound(B, 'sound/machines/chime.ogg', 30, 1)
B.detonation_timer += 300
B.delayedbig = TRUE
if(WIRE_PROCEED)
- holder.visible_message("[bicon(B)] The bomb buzzes ominously!")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bomb buzzes ominously!")
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
var/seconds = B.seconds_remaining()
if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
@@ -44,13 +44,13 @@
B.detonation_timer = world.time + 100
if(WIRE_ACTIVATE)
if(!B.active && !B.defused)
- holder.visible_message("[bicon(B)] You hear the bomb start ticking!")
+ holder.visible_message("[icon2html(B, viewers(holder))] You hear the bomb start ticking!")
B.activate()
B.update_icon()
else if(B.delayedlittle)
- holder.visible_message("[bicon(B)] Nothing happens.")
+ holder.visible_message("[icon2html(B, viewers(holder))] Nothing happens.")
else
- holder.visible_message("[bicon(B)] The bomb seems to hesitate for a moment.")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bomb seems to hesitate for a moment.")
B.detonation_timer += 100
B.delayedlittle = TRUE
@@ -62,24 +62,24 @@
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
else
if(B.active)
- holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
+ holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
else
B.defused = TRUE
if(WIRE_UNBOLT)
if(!mend && B.anchored)
- holder.visible_message("[bicon(B)] The bolts lift out of the ground!")
+ holder.visible_message("[icon2html(B, viewers(holder))] The bolts lift out of the ground!")
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
B.anchored = FALSE
if(WIRE_PROCEED)
if(!mend && B.active)
- holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
+ holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
if(WIRE_ACTIVATE)
if(!mend && B.active)
- holder.visible_message("[bicon(B)] The timer stops! The bomb has been defused!")
+ holder.visible_message("[icon2html(B, viewers(holder))] The timer stops! The bomb has been defused!")
B.active = FALSE
B.defused = TRUE
B.update_icon()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 09d08131794e..c3c4944cdf88 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -270,7 +270,7 @@
f_name = "a "
f_name += "blood-stained [name]!"
- to_chat(user, "[bicon(src)] That's [f_name]")
+ to_chat(user, "[icon2html(src, user)] That's [f_name]")
if(desc)
to_chat(user, desc)
diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm
index 97a68fd3216e..abeb183ab01b 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs.dm
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
var/t_He = p_they(TRUE)
var/t_s = p_s()
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
msg += "[desc]\n"
if(health < maxHealth)
msg += ""
diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm
index 1a0cfcd23182..090b926dbf96 100644
--- a/code/game/gamemodes/devil/true_devil/_true_devil.dm
+++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm
@@ -61,15 +61,15 @@
/mob/living/carbon/true_devil/examine(mob/user)
- var/msg = "*---------*\nThis is [bicon(src)] [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] [src]!\n"
//Left hand items
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It is holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It is holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It is holding [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It is holding [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Braindead
if(!client && stat != DEAD)
diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm
index ba18ad757800..b7b20a73111b 100644
--- a/code/game/gamemodes/gang/gang_datum.dm
+++ b/code/game/gamemodes/gang/gang_datum.dm
@@ -191,7 +191,7 @@
var/mob/living/mob = get(tool.loc, /mob/living)
if(mob && mob.mind && mob.stat == CONSCIOUS)
if(mob.mind.gang_datum == src)
- to_chat(mob, "[bicon(tool)] [message]")
+ to_chat(mob, "[icon2html(tool, mob)] [message]")
return
diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm
index 4357f31e8373..e52db2ec5f57 100644
--- a/code/game/gamemodes/gang/gang_pen.dm
+++ b/code/game/gamemodes/gang/gang_pen.dm
@@ -66,4 +66,4 @@
cooldown = 0
icon_state = "pen"
var/mob/M = get(src, /mob)
- to_chat(M, "[bicon(src)] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.")
+ to_chat(M, "[icon2html(src, M)] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.")
diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm
index 601a1f1c0d6a..0be52e603328 100644
--- a/code/game/gamemodes/gang/recaller.dm
+++ b/code/game/gamemodes/gang/recaller.dm
@@ -110,7 +110,7 @@
if(!message || !can_use(user))
return
if(user.z > 2)
- to_chat(user, "[bicon(src)]Error: Station out of range.")
+ to_chat(user, "[icon2html(src, user)]Error: Station out of range.")
return
var/list/members = list()
members += gang.gangsters
@@ -179,35 +179,35 @@
gang.message_gangtools("[usr] is attempting to recall the emergency shuttle.")
recalling = 1
- to_chat(loc, "[bicon(src)]Generating shuttle recall order with codes retrieved from last call signal...")
+ to_chat(loc, "[icon2html(src, loc)]Generating shuttle recall order with codes retrieved from last call signal...")
sleep(rand(100,300))
if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station
- to_chat(user, "[bicon(src)]Emergency shuttle cannot be recalled at this time.")
+ to_chat(user, "[icon2html(src, user)]Emergency shuttle cannot be recalled at this time.")
recalling = 0
return 0
- to_chat(loc, "[bicon(src)]Shuttle recall order generated. Accessing station long-range communication arrays...")
+ to_chat(loc, "[icon2html(src, loc)]Shuttle recall order generated. Accessing station long-range communication arrays...")
sleep(rand(100,300))
if(!gang.dom_attempts)
- to_chat(user, "[bicon(src)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.")
+ to_chat(user, "[icon2html(src, user)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.")
recalling = 0
return 0
var/turf/userturf = get_turf(user)
if(userturf.z != ZLEVEL_STATION) //Shuttle can only be recalled while on station
- to_chat(user, "[\bicon(src)]Error: Device out of range of station communication arrays.")
+ to_chat(user, "[icon2html(src, user)]Error: Device out of range of station communication arrays.")
recalling = 0
return 0
var/datum/station_state/end_state = new /datum/station_state()
end_state.count()
if((100 * GLOB.start_state.score(end_state)) < 80) //Shuttle cannot be recalled if the station is too damaged
- to_chat(user, "[bicon(src)]Error: Station communication systems compromised. Unable to establish connection.")
+ to_chat(user, "[icon2html(src, user)]Error: Station communication systems compromised. Unable to establish connection.")
recalling = 0
return 0
- to_chat(loc, "[bicon(src)]Comm arrays accessed. Broadcasting recall signal...")
+ to_chat(loc, "[icon2html(src, loc)]Comm arrays accessed. Broadcasting recall signal...")
sleep(rand(100,300))
@@ -220,7 +220,7 @@
gang.recalls -= 1
return 1
- to_chat(loc, "[bicon(src)]No response recieved. Emergency shuttle cannot be recalled at this time.")
+ to_chat(loc, "[icon2html(src, loc)]No response recieved. Emergency shuttle cannot be recalled at this time.")
return 0
/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 759c5f4454b8..16fb1f601ddd 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -288,7 +288,7 @@
text += "
"
text += "(Syndicates used [TC_uses] TC) [purchases]"
if(TC_uses == 0 && station_was_nuked && !are_operatives_dead())
- text += "[bicon(icon('icons/badass.dmi', "badass"))]"
+ text += "[icon2html('icons/badass.dmi', world, "badass")]"
to_chat(world, text)
return 1
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 4a7a776e6ab2..8d39479d9c82 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -124,7 +124,7 @@
text += " (used [TC_uses] TC) [purchases]"
if(TC_uses==0 && traitorwin)
var/static/icon/badass = icon('icons/badass.dmi', "badass")
- text += "[bicon(badass)]"
+ text += "[icon2html(badass, world)]"
text += objectives
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 32e0e60fca01..f9d530feac5f 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -445,7 +445,7 @@ Class Procs:
/obj/machinery/proc/display_parts(mob/user)
to_chat(user, "Following parts detected in the machine:")
for(var/obj/item/C in component_parts)
- to_chat(user, "[bicon(C)] [C.name]")
+ to_chat(user, "[icon2html(C, user)] [C.name]")
/obj/machinery/examine(mob/user)
..()
diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm
index a288c9d51ca6..45c4142f0980 100644
--- a/code/game/machinery/computer/apc_control.dm
+++ b/code/game/machinery/computer/apc_control.dm
@@ -116,24 +116,24 @@
authenticated = FALSE
auth_id = "\[NULL\]"
if(href_list["restore_logging"])
- to_chat(usr, "[bicon(src)] Logging functionality restored from backup data.")
+ to_chat(usr, "[icon2html(src, usr)] Logging functionality restored from backup data.")
emagged = FALSE
LAZYADD(logs, "-=- Logging restored to full functionality at this point -=-")
if(href_list["access_apc"])
playsound(src, "terminal_type", 50, 0)
var/obj/machinery/power/apc/APC = locate(href_list["access_apc"]) in GLOB.apcs_list
if(!APC || APC.aidisabled || APC.panel_open || QDELETED(APC))
- to_chat(usr, "[bicon(src)] APC does not return interface request. Remote access may be disabled.")
+ to_chat(usr, "[icon2html(src, usr)] APC does not return interface request. Remote access may be disabled.")
return
if(active_apc)
- to_chat(usr, "[bicon(src)] Disconnected from [active_apc].")
+ to_chat(usr, "[icon2html(src, usr)] Disconnected from [active_apc].")
active_apc.say("Remote access canceled. Interface locked.")
playsound(active_apc, 'sound/machines/boltsdown.ogg', 25, 0)
playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0)
active_apc.locked = TRUE
active_apc.update_icon()
active_apc = null
- to_chat(usr, "[bicon(src)] Connected to APC in [APC.area]. Interface request sent.")
+ to_chat(usr, "[icon2html(src, usr)] Connected to APC in [APC.area]. Interface request sent.")
log_activity("remotely accessed APC in [APC.area]")
APC.interact(usr, GLOB.not_incapacitated_state)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 75655199da89..83eb464d52b2 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -414,10 +414,10 @@
customrecepient.tnote += "← From [customsender] ([customjob]):
[custommessage]
"
if (!customrecepient.silent)
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- customrecepient.audible_message("[bicon(customrecepient)] *[customrecepient.ttone]*", null, 3)
+ customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
- to_chat(H, "[bicon(customrecepient)] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)")
+ to_chat(H, "[icon2html(customrecepient, viewers(H))] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)")
log_talk(usr,"[key_name(usr)] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
customrecepient.cut_overlays()
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
@@ -427,10 +427,10 @@
customrecepient.tnote += "← From [PDARec.owner] ([customjob]):
[custommessage]
"
if (!customrecepient.silent)
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- customrecepient.audible_message("[bicon(customrecepient)] *[customrecepient.ttone]*", null, 3)
+ customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
- to_chat(H, "[bicon(customrecepient)] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)")
+ to_chat(H, "[icon2html(customrecepient, H)] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)")
log_talk(usr,"[key_name(usr)] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
customrecepient.cut_overlays()
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index ffcb36678a58..ba4b7b53e367 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -146,7 +146,7 @@
var/icon/I2 = imap[2+(ix + icx*iy)*2]
- //to_chat(world, "icon: [bicon(I)]")
+ //to_chat(world, "icon: [icon2html(I, world)]")
I.DrawBox(colour, rx, ry, rx+1, ry+1)
@@ -163,7 +163,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_chat(world, "[bicon(I)] at [H.screen_loc]")
+ //to_chat(world, "[icon2html(I, world)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
@@ -274,7 +274,7 @@
var/icon/I = imap[1+(ix + icx*iy)]
- //to_chat(world, "icon: [bicon(I)]")
+ //to_chat(world, "icon: [icon2html(I, world)]")
I.DrawBox(colour, rx, ry, rx, ry)
@@ -289,7 +289,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_chat(world, "[bicon(I)] at [H.screen_loc]")
+ //to_chat(world, "[icon2html(I, world)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index a2f97c3d54b8..4e96eb661d9e 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -207,14 +207,14 @@
var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num
if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station
timer_set = Clamp(new_timer, minimum_timer, maximum_timer)
- src.loc.visible_message("[bicon(src)] timer set for [timer_set] seconds.")
+ src.loc.visible_message("[icon2html(src, viewers(src))] timer set for [timer_set] seconds.")
if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user))
if(defused || active)
if(defused)
- src.loc.visible_message("[bicon(src)] Device error: User intervention required.")
+ src.loc.visible_message("[icon2html(src, viewers(src))] Device error: User intervention required.")
return
else
- src.loc.visible_message("[bicon(src)] [timer_set] seconds until detonation, please clear the area.")
+ src.loc.visible_message("[icon2html(src, viewers(loc))] [timer_set] seconds until detonation, please clear the area.")
activate()
update_icon()
add_fingerprint(user)
@@ -330,7 +330,7 @@
var/obj/machinery/syndicatebomb/holder = loc
if(istype(holder))
attempts++
- holder.loc.visible_message("[bicon(holder)] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...")
+ holder.loc.visible_message("[icon2html(holder, viewers(holder))] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...")
reset()
else
qdel(src)
@@ -340,7 +340,7 @@
if(istype(holder))
attempts++
defusals++
- holder.loc.visible_message("[bicon(holder)] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...")
+ holder.loc.visible_message("[icon2html(holder, viewers(holder))] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...")
sleep(50) //Just in case someone is trying to remove the bomb core this gives them a little window to crowbar it out
if(istype(holder))
reset()
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index f51e1be8bb90..1e7c2b9f206e 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -136,7 +136,7 @@
/obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message)
if(chassis)
- chassis.occupant_message("[bicon(src)] [message]")
+ chassis.occupant_message("[icon2html(src, chassis.occupant)] [message]")
return
/obj/item/mecha_parts/mecha_equipment/proc/log_message(message)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index cd385d3de357..9fb4b6c21417 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -262,7 +262,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, "[bicon(ME)] [ME]")
+ to_chat(user, "[icon2html(ME, user)] [ME]")
//processing internal damage, temperature, air regulation, alert updates, lights power use.
/obj/mecha/process()
@@ -636,7 +636,7 @@
var/can_control_mech = 0
for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers)
can_control_mech = 1
- to_chat(user, "[bicon(src)] Status of [name]:\n[A.get_mecha_info()]")
+ to_chat(user, "[icon2html(src, user)] Status of [name]:\n[A.get_mecha_info()]")
break
if(!can_control_mech)
to_chat(user, "You cannot control exosuits without AI control beacons installed.")
@@ -1004,7 +1004,7 @@
/obj/mecha/proc/occupant_message(message as text)
if(message)
if(occupant && occupant.client)
- to_chat(occupant, "[bicon(src)] [message]")
+ to_chat(occupant, "[icon2html(src, occupant)] [message]")
return
/obj/mecha/proc/log_message(message as text,red=null)
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 5127aa228585..72a721911fe2 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -169,7 +169,7 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
- . += "some [initial(S.name)] [bicon(initial(S.icon))]\n"
+ . += "some [initial(S.name)] [icon2html(initial(S.icon), user)]\n"
to_chat(user, .)
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index f9718d2208f0..80b291e5714a 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -22,7 +22,7 @@
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
return
- visible_message("[victim] sets off [bicon(src)] [src]!")
+ visible_message("[victim] sets off [icon2html(src, viewers(src))] [src]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index bca1ccce81e0..9097d8add488 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -558,7 +558,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if (!silent)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
- audible_message("[bicon(src)] *[ttone]*", null, 3)
+ audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3)
//Search for holder of the PDA.
var/mob/living/L = null
if(loc && isliving(loc))
@@ -575,7 +575,7 @@ GLOBAL_LIST_EMPTY(PDAs)
hrefstart = ""
hrefend = ""
- to_chat(L, "[\bicon(src)] Message from [hrefstart][source.owner] ([source.ownjob])[hrefend], \"[msg.message]\"[msg.get_photo_ref()] (Reply)")
+ to_chat(L, "[icon2html(src)] Message from [hrefstart][source.owner] ([source.ownjob])[hrefend], \"[msg.message]\"[msg.get_photo_ref()] (Reply)")
update_icon()
add_overlay(icon_alert)
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index e5bca7eeacba..f32f70720475 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -88,27 +88,27 @@
if(isliving(loc))
var/mob/living/M = loc
if(!emagged)
- to_chat(M, "[bicon(src)] RADIATION PULSE DETECTED.")
- to_chat(M, "[bicon(src)] Severity: [amount]")
+ to_chat(M, "[icon2html(src, M)] RADIATION PULSE DETECTED.")
+ to_chat(M, "[icon2html(src, M)] Severity: [amount]")
else
- to_chat(M, "[bicon(src)] !@%$AT!(N P!LS! D/TEC?ED.")
- to_chat(M, "[bicon(src)] &!F2rity: <=[amount]#1")
+ to_chat(M, "[icon2html(src, M)] !@%$AT!(N P!LS! D/TEC?ED.")
+ to_chat(M, "[icon2html(src, M)] &!F2rity: <=[amount]#1")
update_icon()
/obj/item/device/geiger_counter/attack_self(mob/user)
scanning = !scanning
update_icon()
- to_chat(user, "[bicon(src)] You switch [scanning ? "on" : "off"] [src].")
+ to_chat(user, "[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].")
/obj/item/device/geiger_counter/attack(mob/living/M, mob/user)
if(user.a_intent == INTENT_HELP)
if(!emagged)
user.visible_message("[user] scans [M] with [src].", "You scan [M]'s radiation levels with [src]...")
if(!M.radiation)
- to_chat(user, "[bicon(src)] Radiation levels within normal boundaries.")
+ to_chat(user, "[icon2html(src, user)] Radiation levels within normal boundaries.")
return 1
else
- to_chat(user, "[bicon(src)] Subject is irradiated. Radiation levels: [M.radiation].")
+ to_chat(user, "[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation].")
return 1
else
user.visible_message("[user] scans [M] with [src].", "You project [src]'s stored radiation into [M]'s body!")
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 348c6620cd9b..daaadeb7971f 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -527,7 +527,7 @@
return list(pick(messages))
/obj/item/toy/talking/proc/toy_talk(mob/user, message)
- user.loc.visible_message("[bicon(src)] [message]")
+ user.loc.visible_message("[icon2html(src, viewers(user.loc))] [message]")
if(chattering)
chatter(message, phomeme, user)
@@ -1082,7 +1082,7 @@
user.visible_message("[user] pulls back the string on [src].")
icon_state = "[initial(icon_state)]_used"
sleep(5)
- audible_message("[bicon(src)] Hiss!")
+ audible_message("[icon2html(src, viewers(src))] Hiss!")
var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg')
var/chosen_sound = pick(possible_sounds)
playsound(get_turf(src), chosen_sound, 50, 1)
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index 6f2310303b66..66e3e0317f2e 100644
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -525,7 +525,7 @@ AI MODULES
laws[1] = generate_ion_law()
to_chat(user, "You press the button on [src].")
playsound(user, 'sound/machines/click.ogg', 20, 1)
- src.loc.visible_message("[bicon(src)] [laws[1]]")
+ src.loc.visible_message("[icon2html(src, viewers(loc))] [laws[1]]")
/******************** Mother Drone ******************/
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 3f89e593d59d..e4a69dfab783 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -106,7 +106,7 @@
update_label()
/obj/item/weapon/card/id/attack_self(mob/user)
- user.visible_message("[user] shows you: [bicon(src)] [src.name].", \
+ user.visible_message("[user] shows you: [icon2html(src, viewers(user))] [src.name].", \
"You show \the [src.name].")
src.add_fingerprint(user)
return
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index d2f5714d5eaa..e893fec6ac8b 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -37,10 +37,10 @@
out += "You'll need to get closer to see any more."
return
for(var/obj/item/I in loadedItems)
- out += "[bicon(I)] It has \the [I] loaded."
+ out += "[icon2html(I, user)] It has \the [I] loaded."
CHECK_TICK
if(tank)
- out += "[bicon(tank)] It has \the [tank] mounted onto it."
+ out += "[icon2html(tank, user)] It has \the [tank] mounted onto it."
to_chat(user, out.Join("
"))
/obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params)
diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm
index 256cdc0433e2..77d7784852ca 100644
--- a/code/game/objects/items/weapons/powerfist.dm
+++ b/code/game/objects/items/weapons/powerfist.dm
@@ -26,7 +26,7 @@
to_chat(user, "You'll need to get closer to see any more.")
return
if(tank)
- to_chat(user, "[bicon(tank)] It has \the [tank] mounted onto it.")
+ to_chat(user, "[icon2html(tank, user)] It has \the [tank] mounted onto it.")
/obj/item/weapon/melee/powerfist/attackby(obj/item/weapon/W, mob/user, params)
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 12f5dc7bdcef..8f55884bebd3 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -33,7 +33,7 @@
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
- msg = "[bicon(cross)][prayer_type][deity ? " (to [deity])" : ""]: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [msg]"
+ msg = "[icon2html(cross, GLOB.admins)][prayer_type][deity ? " (to [deity])" : ""]: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [msg]"
for(var/client/C in GLOB.admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 2853fefcbfe1..03720d9d81b0 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -63,7 +63,7 @@
return
/obj/item/device/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
- visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
+ visible_message("[icon2html(src, viewers(src))] *beep* *beep*", "*beep* *beep*")
sleep(10)
if(!src)
return
diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm
index b454cbacfb03..180cb55db6f7 100644
--- a/code/modules/assembly/health.dm
+++ b/code/modules/assembly/health.dm
@@ -59,7 +59,7 @@
health_scan = M.health
if(health_scan <= alarm_health)
pulse()
- audible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
+ audible_message("[icon2html(src, hearers(src))] *beep* *beep*", "*beep* *beep*")
toggle_scan()
return
return
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index be1659546f21..c196e984a287 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -99,7 +99,7 @@
if(!secured || !on || next_activate > world.time)
return FALSE
pulse(0)
- audible_message("[bicon(src)] *beep* *beep*", null, 3)
+ audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3)
next_activate = world.time + 30
/obj/item/device/assembly/infra/interact(mob/user)//TODO: change this this to the wire control panel
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index 9cf534f975ce..556979070ddd 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -56,7 +56,7 @@
if(!secured || next_activate > world.time)
return 0
pulse(0)
- audible_message("[bicon(src)] *beep* *beep*", null, 3)
+ audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3)
next_activate = world.time + 30
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index b3f25ac8cfba..7c8efb14d5f4 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -143,7 +143,7 @@ Code:
if(!(src.wires & WIRE_RADIO_RECEIVE))
return 0
pulse(1)
- audible_message("[bicon(src)] *beep* *beep*", null, 1)
+ audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1)
return
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index 8938ecbe9d29..9a959bc54471 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -45,7 +45,7 @@
if(!secured || next_activate > world.time)
return FALSE
pulse(0)
- audible_message("[bicon(src)] *beep* *beep*", null, 3)
+ audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3)
if(loop)
timing = 1
update_icon()
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
index 81fecc6dda34..4f576dd3e7ba 100644
--- a/code/modules/client/asset_cache.dm
+++ b/code/modules/client/asset_cache.dm
@@ -138,6 +138,13 @@ You can set verify to TRUE if you want send() to sleep until the client has the
/proc/register_asset(var/asset_name, var/asset)
SSassets.cache[asset_name] = asset
+//Generated names do not include file extention.
+//Used mainly for code that deals with assets in a generic way
+//The same asset will always lead to the same asset name
+/proc/generate_asset_name(var/file)
+ return "asset.[md5(fcopy_rsc(file))]"
+
+
//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
@@ -170,6 +177,33 @@ GLOBAL_LIST_EMPTY(asset_datums)
send_asset_list(client,assets,verify)
+//Generates assets based on iconstates of a single icon
+/datum/asset/simple/icon_states
+ var/icon
+ var/direction = SOUTH
+ var/frame = 1
+ var/movement_states = FALSE
+
+ var/prefix = "default" //asset_name = "[prefix].[icon_state_name].png"
+ var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format
+
+ verify = FALSE
+
+/datum/asset/simple/icon_states/register()
+ for(var/icon_state_name in icon_states(icon))
+ var/asset = icon(icon, icon_state_name, direction, frame, movement_states)
+ if (!asset)
+ continue
+ asset = fcopy_rsc(asset) //dedupe
+ var/asset_name = sanitize_filename("[prefix].[icon_state_name].png")
+ if (generic_icon_names)
+ asset_name = "[generate_asset_name(asset)].png"
+
+ assets[asset_name] = asset
+
+ ..()
+
+
//DEFINITIONS FOR ASSET DATUMS START HERE.
/datum/asset/simple/tgui
@@ -306,3 +340,14 @@ GLOBAL_LIST_EMPTY(asset_datums)
for(var/path in typesof(/datum/html_interface))
var/datum/html_interface/hi = new path()
hi.registerResources()
+
+//this exists purely to avoid meta by pre-loading all language icons.
+/datum/asset/language/register()
+ for(var/path in typesof(/datum/language))
+ set waitfor = FALSE
+ var/datum/language/L = new path ()
+ L.get_icon()
+
+/datum/asset/simple/icon_states/emojis
+ icon = 'icons/emoji.dmi'
+ generic_icon_names = TRUE
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 98e4a0bb0e00..b9ddea38ede4 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -627,7 +627,7 @@ GLOBAL_LIST(external_rsc_urls)
)
spawn (10) //removing this spawn causes all clients to not get verbs.
//Precache the client with all other assets slowly, so as to not block other browse() calls
- getFilesSlow(src, SSassets.cache, register_asset = FALSE)
+ getFilesSlow(src, SSassets.preload, register_asset = FALSE)
//Hook, override it to run code when dir changes
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index aeb1a7fdcfae..cd0f893fa699 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -55,7 +55,7 @@
var/keyname = key
if(prefs.unlock_content)
if(prefs.toggles & MEMBER_PUBLIC)
- keyname = "[bicon(icon('icons/member_content.dmi', "blag"))][keyname]"
+ keyname = "[icon2html('icons/member_content.dmi', world, "blag")][keyname]"
for(var/client/C in GLOB.clients)
if(C.prefs.chat_toggles & CHAT_OOC)
diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm
index c823e0b70d12..e06634f35818 100644
--- a/code/modules/clothing/spacesuits/flightsuit.dm
+++ b/code/modules/clothing/spacesuits/flightsuit.dm
@@ -138,7 +138,7 @@
targ = mob_override
if(!istype(targ))
return
- to_chat(targ, "[bicon(src)]|[message]")
+ to_chat(targ, "[icon2html(src, targ)]|[message]")
/obj/item/device/flightpack/proc/sync_processing(datum/controller/subsystem/processing/flightpacks/FPS)
processing_mode = FPS.flightsuit_processing
@@ -924,7 +924,7 @@
targ = loc
if(!istype(targ))
return
- to_chat(targ, "[bicon(src)]|[message]")
+ to_chat(targ, "[icon2html(src, targ)]|[message]")
/obj/item/clothing/suit/space/hardsuit/flightsuit/examine(mob/user)
..()
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 00f622b7516a..4dcc0207b9ec 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -47,7 +47,7 @@
/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg)
var/mob/wearer = loc
if(msg && ishuman(wearer))
- wearer.show_message("[bicon(src)][msg]", 1)
+ wearer.show_message("[icon2html(src, wearer)][msg]", 1)
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(severity)
..()
diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm
index 5ecadbe09c7f..58f261f8cc7b 100644
--- a/code/modules/emoji/emoji_parse.dm
+++ b/code/modules/emoji/emoji_parse.dm
@@ -16,7 +16,7 @@
if(search)
emoji = lowertext(copytext(text, pos+1, search))
if(emoji in emojis)
- parsed += bicon(icon('icons/emoji.dmi', emoji))
+ parsed += icon2html('icons/emoji.dmi', world, emoji)
pos = search + 1
else
parsed += copytext(text, pos, search)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index 1df49a41a430..fc1666bbc4e5 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -100,7 +100,7 @@
var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O
if(!I.ice_creamed)
if(product_types[dispense_flavour] > 0)
- src.visible_message("[bicon(src)] [user] scoops delicious [flavour_name] ice cream into [I].")
+ visible_message("[icon2html(src, viewers(src))] [user] scoops delicious [flavour_name] ice cream into [I].")
product_types[dispense_flavour] -= 1
I.add_ice_cream(flavour_name)
// if(beaker)
diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm
index cde68b86e275..54c2154b427c 100644
--- a/code/modules/food_and_drinks/pizzabox.dm
+++ b/code/modules/food_and_drinks/pizzabox.dm
@@ -101,7 +101,7 @@
return
open = !open
if(open && !bomb_defused)
- audible_message("[bicon(src)] *beep*")
+ audible_message("[icon2html(src, hearers(src))] *beep*")
bomb_active = TRUE
START_PROCESSING(SSobj, src)
update_icon()
diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm
index 5f667a64bb80..cc44c47f4e53 100644
--- a/code/modules/goonchat/browserOutput.dm
+++ b/code/modules/goonchat/browserOutput.dm
@@ -166,57 +166,6 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
//Global chat procs
-//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
-// exporting it as text, and then parsing the base64 from that.
-// (This relies on byond automatically storing icons in savefiles as base64)
-/proc/icon2base64(icon/icon, iconKey = "misc")
- if (!isicon(icon))
- return FALSE
- WRITE_FILE(GLOB.iconCache[iconKey], icon)
- var/iconData = GLOB.iconCache.ExportText(iconKey)
- var/list/partial = splittext(iconData, "{")
- return replacetext(copytext(partial[2], 3, -5), "\n", "")
-
-/proc/bicon(thing)
- if (!thing)
- return
- var/static/list/bicon_cache = list()
- if (isicon(thing))
- var/icon/I = thing
- var/icon_md5 = md5(I)
- if (!bicon_cache[icon_md5]) // Doesn't exist yet, make it.
- I = icon(I) //copy it
- I.Scale(16,16) //scale it
- bicon_cache[icon_md5] = icon2base64(thing) //base64 it
- return "
"
-
- // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
- var/atom/A = thing
- var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
-
-
- if (!bicon_cache[key]) // Doesn't exist, make it.
- var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1)
- I.Scale(16,16)
- if (ishuman(thing)) // Shitty workaround for a BYOND issue.
- var/icon/temp = I
- I = icon()
- I.Insert(temp, dir = SOUTH)
- bicon_cache[key] = icon2base64(I, key)
-
- return "
"
-
-//Costlier version of bicon() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
-/proc/costly_bicon(thing)
- if (!thing)
- return
-
- if (isicon(thing))
- return bicon(thing)
-
- var/icon/I = getFlatIcon(thing)
- return bicon(I)
-
/proc/to_chat(target, message)
if(!target)
return
diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css
index 71bd7c2b400c..3f6a5ac5ca28 100644
--- a/code/modules/goonchat/browserassets/css/browserOutput.css
+++ b/code/modules/goonchat/browserassets/css/browserOutput.css
@@ -28,10 +28,14 @@ img {
margin: 0;
padding: 0;
line-height: 1;
+ -ms-interpolation-mode: nearest-neighbor;
+ image-rendering: pixelated;
}
img.icon {
- width: 16px;
- height: 16px;
+ height: 1em;
+ min-height: 16px;
+ width: auto;
+ vertical-align: bottom;
}
a {color: #0000ff;}
@@ -356,7 +360,6 @@ h1.alert, h2.alert {color: #000000;}
.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
-BIG IMG.icon {width: 32px; height: 32px;}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 16px;}
diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js
index 59b152ab3be8..e6e0c1d6faa3 100644
--- a/code/modules/goonchat/browserassets/js/browserOutput.js
+++ b/code/modules/goonchat/browserassets/js/browserOutput.js
@@ -29,6 +29,8 @@ var opts = {
'messageLimit': 2053, //A limit...for the messages...
'scrollSnapTolerance': 10, //If within x pixels of bottom
'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup
+ 'imageRetryDelay': 50, //how long between attempts to reload images (in ms)
+ 'imageRetryLimit': 50, //how many attempts should we make?
'popups': 0, //Amount of popups opened ever
'wasd': false, //Is the user in wasd mode?
'chatMode': 'default', //The mode the chat is in
@@ -146,6 +148,23 @@ function highlightTerms(el) {
el.innerHTML = newText;
}
}
+
+function iconError(E) {
+ var that = this;
+ setTimeout(function() {
+ var attempts = $(that).data('reload_attempts');
+ if (typeof attempts === 'undefined' || !attempts) {
+ attempts = 1;
+ }
+ if (attempts > opts.imageRetryLimit)
+ return;
+ var src = that.src;
+ that.src = null;
+ that.src = src+'#'+attempts;
+ $(that).data('reload_attempts', ++attempts);
+ }, opts.imageRetryDelay);
+}
+
//Send a message to the client
function output(message, flag) {
if (typeof message === 'undefined') {
@@ -271,7 +290,7 @@ function output(message, flag) {
entry.innerHTML = message.trim();
$messages[0].appendChild(entry);
-
+ $(entry).find("img.icon").error(iconError);
//Actually do the snap
if (!filteredOut && atBottom) {
$('body,html').scrollTop($messages.outerHeight());
@@ -861,7 +880,11 @@ $(function() {
$messages.empty();
opts.messageCount = 0;
});
-
+
+ $('img.icon').error(iconError);
+
+
+
/*****************************************
*
diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm
index 2ad7f0549c73..8b51429bd31e 100644
--- a/code/modules/language/language.dm
+++ b/code/modules/language/language.dm
@@ -35,7 +35,7 @@
return TRUE
/datum/language/proc/get_icon()
- return "[bicon(icon(icon, icon_state))]"
+ return "[icon2html(icon, world, icon_state)]"
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
if(!syllables || !syllables.len)
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index ebc349cefc46..e30556db30bb 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -6,26 +6,26 @@
var/t_has = p_have()
var/t_is = p_are()
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
if (handcuffed)
- msg += "[t_He] [t_is] [bicon(handcuffed)] handcuffed!\n"
+ msg += "[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!\n"
if (head)
- msg += "[t_He] [t_is] wearing [bicon(head)] \a [src.head] on [t_his] head. \n"
+ msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [src.head] on [t_his] head. \n"
if (wear_mask)
- msg += "[t_He] [t_is] wearing [bicon(wear_mask)] \a [src.wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_mask, user)] \a [src.wear_mask] on [t_his] face.\n"
if (wear_neck)
- msg += "[t_He] [t_is] wearing [bicon(wear_neck)] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "[t_He] [t_is] holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "[t_He] [t_is] holding [bicon(I)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
if (back)
- msg += "[t_He] [t_has] [bicon(back)] \a [src.back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [icon2html(back, user)] \a [src.back] on [t_his] back.\n"
var/appears_dead = 0
if (stat == DEAD)
appears_dead = 1
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index d21311e99731..7b2537d69056 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -19,55 +19,55 @@
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
if(U.attached_accessory)
- accessory_msg += " with [bicon(U.attached_accessory)] \a [U.attached_accessory]"
+ accessory_msg += " with [icon2html(U.attached_accessory, user)] \a [U.attached_accessory]"
if(w_uniform.blood_DNA)
- msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][accessory_msg]!\n"
+ msg += "[t_He] [t_is] wearing [icon2html(w_uniform, user)] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][accessory_msg]!\n"
else
- msg += "[t_He] [t_is] wearing [bicon(w_uniform)] \a [w_uniform][accessory_msg].\n"
+ msg += "[t_He] [t_is] wearing [icon2html(w_uniform, user)] \a [w_uniform][accessory_msg].\n"
//head
if(head)
if(head.blood_DNA)
- msg += "[t_He] [t_is] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!\n"
+ msg += "[t_He] [t_is] wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!\n"
else
- msg += "[t_He] [t_is] wearing [bicon(head)] \a [head] on [t_his] head.\n"
+ msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [head] on [t_his] head.\n"
//suit/armor
if(wear_suit)
if(wear_suit.blood_DNA)
- msg += "[t_He] [t_is] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_suit, user)] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!\n"
else
- msg += "[t_He] [t_is] wearing [bicon(wear_suit)] \a [wear_suit].\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_suit, user)] \a [wear_suit].\n"
//suit/armor storage
if(s_store)
if(s_store.blood_DNA)
- msg += "[t_He] [t_is] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!\n"
+ msg += "[t_He] [t_is] carrying [icon2html(s_store, user)] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!\n"
else
- msg += "[t_He] [t_is] carrying [bicon(s_store)] \a [s_store] on [t_his] [wear_suit.name].\n"
+ msg += "[t_He] [t_is] carrying [icon2html(s_store, user)] \a [s_store] on [t_his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
- msg += "[t_He] [t_has] [bicon(back)] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [icon2html(back, user)] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.\n"
else
- msg += "[t_He] [t_has] [bicon(back)] \a [back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [icon2html(back, user)] \a [back] on [t_his] back.\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "[t_He] [t_is] holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "[t_He] [t_is] holding [bicon(I)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
//gloves
if(gloves && !(slot_gloves in obscured))
if(gloves.blood_DNA)
- msg += "[t_He] [t_has] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!\n"
+ msg += "[t_He] [t_has] [icon2html(gloves, user)] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!\n"
else
- msg += "[t_He] [t_has] [bicon(gloves)] \a [gloves] on [t_his] hands.\n"
+ msg += "[t_He] [t_has] [icon2html(gloves, user)] \a [gloves] on [t_his] hands.\n"
else if(blood_DNA)
var/hand_number = get_num_arms()
if(hand_number)
@@ -78,48 +78,48 @@
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
- msg += "[t_He] [t_is] [bicon(handcuffed)] restrained with cable!\n"
+ msg += "[t_He] [t_is] [icon2html(handcuffed, user)] restrained with cable!\n"
else
- msg += "[t_He] [t_is] [bicon(handcuffed)] handcuffed!\n"
+ msg += "[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!\n"
//belt
if(belt)
if(belt.blood_DNA)
- msg += "[t_He] [t_has] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!\n"
+ msg += "[t_He] [t_has] [icon2html(belt, user)] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!\n"
else
- msg += "[t_He] [t_has] [bicon(belt)] \a [belt] about [t_his] waist.\n"
+ msg += "[t_He] [t_has] [icon2html(belt, user)] \a [belt] about [t_his] waist.\n"
//shoes
if(shoes && !(slot_shoes in obscured))
if(shoes.blood_DNA)
- msg += "[t_He] [t_is] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!\n"
+ msg += "[t_He] [t_is] wearing [icon2html(shoes, user)] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!\n"
else
- msg += "[t_He] [t_is] wearing [bicon(shoes)] \a [shoes] on [t_his] feet.\n"
+ msg += "[t_He] [t_is] wearing [icon2html(shoes, user)] \a [shoes] on [t_his] feet.\n"
//mask
if(wear_mask && !(slot_wear_mask in obscured))
if(wear_mask.blood_DNA)
- msg += "[t_He] [t_has] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!\n"
+ msg += "[t_He] [t_has] [icon2html(wear_mask, user)] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!\n"
else
- msg += "[t_He] [t_has] [bicon(wear_mask)] \a [wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_has] [icon2html(wear_mask, user)] \a [wear_mask] on [t_his] face.\n"
if (wear_neck && !(slot_neck in obscured))
- msg += "[t_He] [t_is] wearing [bicon(wear_neck)] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
//eyes
if(glasses && !(slot_glasses in obscured))
if(glasses.blood_DNA)
- msg += "[t_He] [t_has] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!\n"
+ msg += "[t_He] [t_has] [icon2html(glasses, user)] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!\n"
else
- msg += "[t_He] [t_has] [bicon(glasses)] \a [glasses] covering [t_his] eyes.\n"
+ msg += "[t_He] [t_has] [icon2html(glasses, user)] \a [glasses] covering [t_his] eyes.\n"
//ears
if(ears && !(slot_ears in obscured))
- msg += "[t_He] [t_has] [bicon(ears)] \a [ears] on [t_his] ears.\n"
+ msg += "[t_He] [t_has] [icon2html(ears, user)] \a [ears] on [t_his] ears.\n"
//ID
if(wear_id)
- msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id].\n"
+ msg += "[t_He] [t_is] wearing [icon2html(wear_id, user)] \a [wear_id].\n"
//Jitters
switch(jitteriness)
@@ -164,7 +164,7 @@
var/obj/item/bodypart/BP = X
missing -= BP.body_zone
for(var/obj/item/I in BP.embedded_objects)
- msg += "[t_He] [t_has] \a [bicon(I)] [I] embedded in [t_his] [BP.name]!\n"
+ msg += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!\n"
//stores missing limbs
var/l_limbs_missing = 0
diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm
index c49e9e552cad..025d3d8e6d8a 100644
--- a/code/modules/mob/living/silicon/ai/examine.dm
+++ b/code/modules/mob/living/silicon/ai/examine.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/ai/examine(mob/user)
- var/msg = "*---------*\nThis is [bicon(src)] [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] [src]!\n"
if (stat == DEAD)
msg += "It appears to be powered-down.\n"
else
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index 77874ad40350..9d2f786adeca 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -173,7 +173,7 @@
if(href_list["send"])
sradio.send_signal("ACTIVATE")
- audible_message("[bicon(src)] *beep* *beep*")
+ audible_message("[icon2html(src, world)] *beep* *beep*")
if(href_list["freq"])
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index 7f232e20f4a1..788a8f425546 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -1,11 +1,11 @@
/mob/living/silicon/robot/examine(mob/user)
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
if(desc)
msg += "[desc]\n"
var/obj/act_module = get_active_held_item()
if(act_module)
- msg += "It is holding [bicon(act_module)] \a [act_module].\n"
+ msg += "It is holding [icon2html(act_module, user)] \a [act_module].\n"
msg += ""
if (src.getBruteLoss())
if (src.getBruteLoss() < maxHealth*0.5)
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 59cb793b27f1..3c963ca8204b 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -469,7 +469,7 @@ Pass a positive integer as an argument to override a bot's default speed.
var/area/end_area = get_area(waypoint)
if(client) //Player bots instead get a location command from the AI
- to_chat(src, "Priority waypoint set by [bicon(caller)] [caller]. Proceed to [end_area.name]<\b>.")
+ to_chat(src, "Priority waypoint set by [icon2html(caller, src)] [caller]. Proceed to [end_area.name]<\b>.")
//For giving the bot temporary all-access.
var/obj/item/weapon/card/id/all_access = new /obj/item/weapon/card/id
@@ -485,7 +485,7 @@ Pass a positive integer as an argument to override a bot's default speed.
turn_on() //Saves the AI the hassle of having to activate a bot manually.
access_card = all_access //Give the bot all-access while under the AI's command.
if(message)
- to_chat(calling_ai, "[bicon(src)] [name] called to [end_area.name]. [path.len-1] meters to destination.")
+ to_chat(calling_ai, "[icon2html(src, calling_ai)] [name] called to [end_area.name]. [path.len-1] meters to destination.")
pathset = 1
mode = BOT_RESPONDING
tries = 0
@@ -500,7 +500,7 @@ Pass a positive integer as an argument to override a bot's default speed.
var/success = bot_move(ai_waypoint, 3)
if(!success)
if(calling_ai)
- to_chat(calling_ai, "[bicon(src)] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]")
+ to_chat(calling_ai, "[icon2html(src, calling_ai)] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]")
calling_ai = null
bot_reset()
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index e8936a286387..74005e84ddc3 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -596,7 +596,7 @@
if(pathset) //The AI called us here, so notify it of our arrival.
loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
if(calling_ai)
- to_chat(calling_ai, "[bicon(src)] [src] wirelessly plays a chiming sound!")
+ to_chat(calling_ai, "[icon2html(src, calling_ai)] [src] wirelessly plays a chiming sound!")
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
calling_ai = null
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 74f855bf8ccf..e0993c6ce564 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -50,7 +50,7 @@
/mob/living/simple_animal/hostile/construct/examine(mob/user)
var/t_He = p_they(TRUE)
var/t_s = p_s()
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
msg += "[desc]\n"
if(health < maxHealth)
msg += ""
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index db347cc2033a..b37d5079d734 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -171,29 +171,29 @@
/mob/living/simple_animal/drone/examine(mob/user)
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It has [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It has [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Internal storage
if(internal_storage && !(internal_storage.flags&ABSTRACT))
if(internal_storage.blood_DNA)
- msg += "It is holding [bicon(internal_storage)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
+ msg += "It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
else
- msg += "It is holding [bicon(internal_storage)] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
//Cosmetic hat - provides no function other than looks
if(head && !(head.flags&ABSTRACT))
if(head.blood_DNA)
- msg += "It is wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!\n"
+ msg += "It is wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!\n"
else
- msg += "It is wearing [bicon(head)] \a [head] on its head.\n"
+ msg += "It is wearing [icon2html(head, user)] \a [head] on its head.\n"
//Braindead
if(!client && stat != DEAD)
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 9efb7463534e..f861331b455b 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -56,7 +56,7 @@
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
- to_chat(M, "[bicon(src)] Squeek!")
+ to_chat(M, "[icon2html(src, M)] Squeek!")
playsound(src, 'sound/effects/mousesqueek.ogg', 100, 1)
..()
diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
index 5fe0ccaadef2..02754e01212a 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
@@ -26,21 +26,21 @@
/mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user)
if(dextrous)
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src)] \a [src]!\n"
msg += "[desc]\n"
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It has [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It has [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
if(internal_storage && !(internal_storage.flags&ABSTRACT))
if(internal_storage.blood_DNA)
- msg += "It is holding [bicon(internal_storage)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
+ msg += "It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
else
- msg += "It is holding [bicon(internal_storage)] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
msg += "*---------*"
to_chat(user, msg)
else
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 236b36dafd93..0e7d7a157e50 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -347,7 +347,7 @@
/mob/living/simple_animal/slime/examine(mob/user)
- var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
+ var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n"
if (src.stat == DEAD)
msg += "It is limp and unresponsive.\n"
else
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 8d2bd6002fb8..a062d5c614ef 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -401,19 +401,21 @@
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
var/list/seen = viewers(4, get_turf(my_atom))
+ var/iconhtml = icon2html(cached_my_atom, seen)
if(cached_my_atom)
if(!ismob(cached_my_atom)) // No bubbling mobs
if(C.mix_sound)
playsound(get_turf(cached_my_atom), C.mix_sound, 80, 1)
+
for(var/mob/M in seen)
- to_chat(M, "[bicon(my_atom)] [C.mix_message]")
+ to_chat(M, "[iconhtml] [C.mix_message]")
if(istype(cached_my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
- to_chat(M, "[bicon(my_atom)] \The [my_atom]'s power is consumed in the reaction.")
+ to_chat(M, "[iconhtml] \The [my_atom]'s power is consumed in the reaction.")
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index 0d0a4f769575..4388d6bcbecf 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -341,7 +341,7 @@
found = 1
break
if(!found)
- to_chat(user, "[bicon(src)]The conveyor switch did not detect any linked conveyor belts in range.")
+ to_chat(user, "[icon2html(src, user)]The conveyor switch did not detect any linked conveyor belts in range.")
return
var/obj/machinery/conveyor_switch/NC = new/obj/machinery/conveyor_switch(A, id)
transfer_fingerprints_to(NC)
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index 7b455b7d80f4..b04ebe664351 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -110,10 +110,10 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
var/obj/item/weapon/storage/box/B = A
if(istype(B) && B.contents.len > 0)
for(var/obj/item/I in B)
- U.purchase_log += "[bicon(I)]"
+ U.purchase_log += "[icon2base64html(I)]"
else
if(purchase_log_vis)
- U.purchase_log += "[bicon(A)]"
+ U.purchase_log += "[icon2base64html(A)]"
if(limited_stock > 0)
limited_stock -= 1
@@ -1394,7 +1394,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
continue
crate_value -= I.cost
new I.item(C)
- U.purchase_log += "[bicon(I.item)]"
+ U.purchase_log += "[icon2base64html(I.item)]"
SSblackbox.add_details("traitor_uplink_items_bought", "[name]|[cost]")
return C
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index 10dd0dd74d70..d8f0421892e4 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -150,7 +150,7 @@ h1.alert, h2.alert {color: #000000;}
.clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
-BIG IMG.icon {width: 32px; height: 32px;}
+.icon {height: 1em; width: auto;}
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 2;}