mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 20:17:15 +01:00
Merge pull request #6592 from VOREStation/vchat-rebase
VChat: Redone chat output in Vue.js
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
return
|
||||
|
||||
var/image/cross = image('icons/obj/storage.dmi',"bible")
|
||||
msg = "<font color='blue'>\icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>) (<A HREF='?_src_=holder;adminsmite=\ref[src]'>SMITE</a>):</b> [msg]</font>"
|
||||
msg = "<font color='blue'>[bicon(cross)] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src, src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>) (<A HREF='?_src_=holder;adminsmite=\ref[src]'>SMITE</a>):</b> [msg]</font>"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "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({"
|
||||
<script>
|
||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
||||
</script>
|
||||
"}, "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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,"<script",1,0) )
|
||||
to_world_log("Attempted use of scripts within a topic call, by [src]")
|
||||
@@ -60,8 +65,6 @@
|
||||
send2adminirc(href_list["irc_msg"])
|
||||
return
|
||||
|
||||
|
||||
|
||||
//Logs all hrefs
|
||||
if(config && config.log_hrefs && href_logfile)
|
||||
WRITE_LOG(href_logfile, "[src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]")
|
||||
@@ -71,6 +74,11 @@
|
||||
if("usr") hsrc = mob
|
||||
if("prefs") return prefs.process_link(usr,href_list)
|
||||
if("vars") return view_var_Topic(href,href_list,hsrc)
|
||||
if("chat") return chatOutput.Topic(href, href_list)
|
||||
|
||||
switch(href_list["action"])
|
||||
if("openLink")
|
||||
src << link(href_list["link"])
|
||||
|
||||
..() //redirect to hsrc.Topic()
|
||||
|
||||
@@ -105,8 +113,14 @@
|
||||
del(src)
|
||||
return
|
||||
|
||||
to_chat(src, "<font color='red'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</font>")
|
||||
chatOutput = new /datum/chatOutput(src) //veechat
|
||||
chatOutput.send_resources()
|
||||
spawn()
|
||||
chatOutput.start()
|
||||
|
||||
//Only show this if they are put into a new_player mob. Otherwise, "what title screen?"
|
||||
if(isnewplayer(src.mob))
|
||||
to_chat(src, "<font color='red'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</font>")
|
||||
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
@@ -136,6 +150,8 @@
|
||||
to_chat(src, "<span class='alert'>[custom_event_msg]</span>")
|
||||
to_chat(src, "<br>")
|
||||
|
||||
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
|
||||
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
|
||||
|
||||
if(holder)
|
||||
add_admin_verbs()
|
||||
@@ -159,14 +175,14 @@
|
||||
void.MakeGreed()
|
||||
screen += void
|
||||
|
||||
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
|
||||
if((prefs.lastchangelog != changelog_hash) && isnewplayer(src.mob)) //bolds the changelog button on the interface so we know there are updates.
|
||||
to_chat(src, "<span class='info'>You have unread updates in the changelog.</span>")
|
||||
winset(src, "rpane.changelog", "background-color=#eaeaea;font-style=bold")
|
||||
if(config.aggressive_changelog)
|
||||
src.changes()
|
||||
|
||||
hook_vr("client_new",list(src)) //VOREStation Code
|
||||
|
||||
|
||||
if(config.paranoia_logging)
|
||||
var/alert = FALSE //VOREStation Edit start.
|
||||
if(isnum(player_age) && player_age == 0)
|
||||
@@ -364,56 +380,9 @@
|
||||
|
||||
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
|
||||
/client/proc/send_resources()
|
||||
|
||||
getFiles(
|
||||
'html/search.js',
|
||||
'html/panels.css',
|
||||
'html/images/loading.gif',
|
||||
'html/images/ntlogo.png',
|
||||
'html/images/sglogo.png',
|
||||
'html/images/talisman.png',
|
||||
'html/images/paper_bg.png',
|
||||
'html/images/no_image32.png',
|
||||
'icons/pda_icons/pda_atmos.png',
|
||||
'icons/pda_icons/pda_back.png',
|
||||
'icons/pda_icons/pda_bell.png',
|
||||
'icons/pda_icons/pda_blank.png',
|
||||
'icons/pda_icons/pda_boom.png',
|
||||
'icons/pda_icons/pda_bucket.png',
|
||||
'icons/pda_icons/pda_crate.png',
|
||||
'icons/pda_icons/pda_cuffs.png',
|
||||
'icons/pda_icons/pda_eject.png',
|
||||
'icons/pda_icons/pda_exit.png',
|
||||
'icons/pda_icons/pda_flashlight.png',
|
||||
'icons/pda_icons/pda_honk.png',
|
||||
'icons/pda_icons/pda_mail.png',
|
||||
'icons/pda_icons/pda_medical.png',
|
||||
'icons/pda_icons/pda_menu.png',
|
||||
'icons/pda_icons/pda_mule.png',
|
||||
'icons/pda_icons/pda_notes.png',
|
||||
'icons/pda_icons/pda_power.png',
|
||||
'icons/pda_icons/pda_rdoor.png',
|
||||
'icons/pda_icons/pda_reagent.png',
|
||||
'icons/pda_icons/pda_refresh.png',
|
||||
'icons/pda_icons/pda_scanner.png',
|
||||
'icons/pda_icons/pda_signaler.png',
|
||||
'icons/pda_icons/pda_status.png',
|
||||
'icons/spideros_icons/sos_1.png',
|
||||
'icons/spideros_icons/sos_2.png',
|
||||
'icons/spideros_icons/sos_3.png',
|
||||
'icons/spideros_icons/sos_4.png',
|
||||
'icons/spideros_icons/sos_5.png',
|
||||
'icons/spideros_icons/sos_6.png',
|
||||
'icons/spideros_icons/sos_7.png',
|
||||
'icons/spideros_icons/sos_8.png',
|
||||
'icons/spideros_icons/sos_9.png',
|
||||
'icons/spideros_icons/sos_10.png',
|
||||
'icons/spideros_icons/sos_11.png',
|
||||
'icons/spideros_icons/sos_12.png',
|
||||
'icons/spideros_icons/sos_13.png',
|
||||
'icons/spideros_icons/sos_14.png'
|
||||
)
|
||||
|
||||
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.preload, register_asset = FALSE)
|
||||
|
||||
mob/proc/MayRespawn()
|
||||
return 0
|
||||
@@ -449,6 +418,26 @@ client/verb/character_setup()
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/client/verb/reload_vchat()
|
||||
set name = "Reload VChat"
|
||||
set category = "OOC"
|
||||
|
||||
//Timing
|
||||
if(src.chatOutputLoadedAt > (world.time - 10 SECONDS))
|
||||
alert(src, "You can only try to reload VChat every 10 seconds at most.")
|
||||
return
|
||||
|
||||
//Log, disable
|
||||
log_debug("[key_name(src)] reloaded VChat.")
|
||||
|
||||
//The hard way
|
||||
qdel_null(src.chatOutput)
|
||||
chatOutput = new /datum/chatOutput(src) //veechat
|
||||
chatOutput.send_resources()
|
||||
spawn()
|
||||
chatOutput.start()
|
||||
|
||||
|
||||
//This is for getipintel.net.
|
||||
//You're welcome to replace this proc with your own that does your own cool stuff.
|
||||
//Just set the client's ip_reputation var and make sure it makes sense with your config settings (higher numbers are worse results)
|
||||
|
||||
@@ -95,18 +95,18 @@
|
||||
var/datum/effect/effect/system/spark_spread/spark_system
|
||||
|
||||
/obj/item/weapon/rig/examine()
|
||||
to_chat(usr, "This is \icon[src][src.name].")
|
||||
to_chat(usr, "This is [bicon(src)][src.name].")
|
||||
to_chat(usr, "[src.desc]")
|
||||
if(wearer)
|
||||
for(var/obj/item/piece in list(helmet,gloves,chest,boots))
|
||||
if(!piece || piece.loc != wearer)
|
||||
continue
|
||||
to_chat(usr, "\icon[piece] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed.")
|
||||
to_chat(usr, "[bicon(piece)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed.")
|
||||
|
||||
if(src.loc == usr)
|
||||
to_chat(usr, "The access panel is [locked? "locked" : "unlocked"].")
|
||||
to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
|
||||
to_chat(usr, "Hardsuit systems are [offline ? "<font color='red'>offline</font>" : "<font color='green'>online</font>"].")
|
||||
to_chat(usr, "Hardsuit systems are [offline ? "<span class='warning'>offline</span>" : "<span class='notice'>online</span>"].")
|
||||
to_chat(usr, "The cooling stystem is [cooling_on ? "active" : "inactive"].")
|
||||
|
||||
if(open)
|
||||
@@ -265,7 +265,7 @@
|
||||
if(!failed_to_seal)
|
||||
|
||||
if(!instant)
|
||||
M.visible_message("<font color='blue'>[M]'s suit emits a quiet hum as it begins to adjust its seals.</font>","<font color='blue'>With a quiet hum, the suit begins running checks and adjusting components.</font>")
|
||||
M.visible_message("<span class='notice'>[M]'s suit emits a quiet hum as it begins to adjust its seals.</span>","<span class='notice'>With a quiet hum, the suit begins running checks and adjusting components.</span>")
|
||||
if(seal_delay && !do_after(M,seal_delay))
|
||||
if(M)
|
||||
to_chat(M, "<span class='warning'>You must remain still while the suit is adjusting the components.</span>")
|
||||
@@ -297,16 +297,16 @@
|
||||
piece.icon_state = "[suit_state][!seal_target ? "_sealed" : ""]"
|
||||
switch(msg_type)
|
||||
if("boots")
|
||||
to_chat(M, "<font color='blue'>\The [piece] [!seal_target ? "seal around your feet" : "relax their grip on your legs"].</font>")
|
||||
to_chat(M, "<span class='notice'>\The [piece] [!seal_target ? "seal around your feet" : "relax their grip on your legs"].</span>")
|
||||
M.update_inv_shoes()
|
||||
if("gloves")
|
||||
to_chat(M, "<font color='blue'>\The [piece] [!seal_target ? "tighten around your fingers and wrists" : "become loose around your fingers"].</font>")
|
||||
to_chat(M, "<span class='notice'>\The [piece] [!seal_target ? "tighten around your fingers and wrists" : "become loose around your fingers"].</span>")
|
||||
M.update_inv_gloves()
|
||||
if("chest")
|
||||
to_chat(M, "<font color='blue'>\The [piece] [!seal_target ? "cinches tight again your chest" : "releases your chest"].</font>")
|
||||
to_chat(M, "<span class='notice'>\The [piece] [!seal_target ? "cinches tight again your chest" : "releases your chest"].</span>")
|
||||
M.update_inv_wear_suit()
|
||||
if("helmet")
|
||||
to_chat(M, "<font color='blue'>\The [piece] hisses [!seal_target ? "closed" : "open"].</font>")
|
||||
to_chat(M, "<span class='notice'>\The [piece] hisses [!seal_target ? "closed" : "open"].</span>")
|
||||
M.update_inv_head()
|
||||
if(helmet)
|
||||
helmet.update_light(wearer)
|
||||
@@ -341,7 +341,7 @@
|
||||
|
||||
// Success!
|
||||
canremove = seal_target
|
||||
to_chat(M, "<font color='blue'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></font>")
|
||||
to_chat(M, "<span class='notice'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></span>")
|
||||
M.client.screen -= booting_L
|
||||
qdel(booting_L)
|
||||
booting_R.icon_state = "boot_done"
|
||||
@@ -726,7 +726,7 @@
|
||||
return
|
||||
|
||||
if(seal_delay > 0 && istype(M) && (M.back == src || M.belt == src))
|
||||
M.visible_message("<font color='blue'>[M] starts putting on \the [src]...</font>", "<font color='blue'>You start putting on \the [src]...</font>")
|
||||
M.visible_message("<span class='notice'>[M] starts putting on \the [src]...</span>", "<span class='notice'>You start putting on \the [src]...</span>")
|
||||
if(!do_after(M,seal_delay))
|
||||
if(M && (M.back == src || M.belt == src))
|
||||
if(!M.unEquip(src))
|
||||
@@ -735,7 +735,7 @@
|
||||
return
|
||||
|
||||
if(istype(M) && (M.back == src || M.belt == src))
|
||||
M.visible_message("<font color='blue'><b>[M] struggles into \the [src].</b></font>", "<font color='blue'><b>You struggle into \the [src].</b></font>")
|
||||
M.visible_message("<span class='notice'><b>[M] struggles into \the [src].</b></span>", "<span class='notice'><b>You struggle into \the [src].</b></span>")
|
||||
wearer = M
|
||||
wearer.wearing_rig = src
|
||||
update_icon()
|
||||
@@ -785,7 +785,7 @@
|
||||
holder = use_obj.loc
|
||||
if(istype(holder))
|
||||
if(use_obj && check_slot == use_obj)
|
||||
to_chat(H, "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></font>")
|
||||
to_chat(H, "<span class='notice'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></span>")
|
||||
use_obj.canremove = 1
|
||||
holder.drop_from_inventory(use_obj)
|
||||
use_obj.forceMove(get_turf(src))
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
last_process_worldtime = world.time
|
||||
|
||||
/obj/machinery/dnaforensics/proc/complete_scan()
|
||||
src.visible_message("<span class='notice'>\icon[src] makes an insistent chime.</span>", 2)
|
||||
src.visible_message("<span class='notice'>[bicon(src)] makes an insistent chime.</span>", 2)
|
||||
update_icon()
|
||||
if(bloodsamp)
|
||||
var/obj/item/weapon/paper/P = new(src)
|
||||
|
||||
+12
-12
@@ -76,7 +76,7 @@ log transactions
|
||||
|
||||
//display a message to the user
|
||||
var/response = pick("Initiating withdraw. Have a nice day!", "CRITICAL ERROR: Activating cash chamber panic siphon.","PIN Code accepted! Emptying account balance.", "Jackpot!")
|
||||
to_chat(user, "<span class='warning'>\icon[src] The [src] beeps: \"[response]\"</span>")
|
||||
to_chat(user, "<span class='warning'>[bicon(src)] The [src] beeps: \"[response]\"</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
|
||||
@@ -85,7 +85,7 @@ log transactions
|
||||
if(istype(I, /obj/item/weapon/card))
|
||||
if(emagged > 0)
|
||||
//prevent inserting id into an emagged ATM
|
||||
to_chat(user, "<font color='red'>\icon[src] CARD READER ERROR. This system has been compromised!</font>")
|
||||
to_chat(user, "<font color='red'>[bicon(src)] CARD READER ERROR. This system has been compromised!</font>")
|
||||
return
|
||||
else if(istype(I,/obj/item/weapon/card/emag))
|
||||
I.resolve_attackby(src, user)
|
||||
@@ -234,7 +234,7 @@ log transactions
|
||||
var/target_account_number = text2num(href_list["target_acc_number"])
|
||||
var/transfer_purpose = href_list["purpose"]
|
||||
if(charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
|
||||
to_chat(usr, "\icon[src]<span class='info'>Funds transfer successful.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='info'>Funds transfer successful.</span>")
|
||||
authenticated_account.money -= transfer_amount
|
||||
|
||||
//create an entry in the account transaction log
|
||||
@@ -247,10 +247,10 @@ log transactions
|
||||
T.amount = "([transfer_amount])"
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Funds transfer failed.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Funds transfer failed.</span>")
|
||||
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
if("view_screen")
|
||||
view_screen = text2num(href_list["view_screen"])
|
||||
if("change_security_level")
|
||||
@@ -288,11 +288,11 @@ log transactions
|
||||
T.time = stationtime2text()
|
||||
failed_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "<font color='red'>\icon[src] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.</font>")
|
||||
to_chat(usr, "<font color='red'>[bicon(src)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.</font>")
|
||||
previous_account_number = tried_account_num
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
else
|
||||
to_chat(usr, "<font color='red'>\icon[src] incorrect pin/account combination entered.</font>")
|
||||
to_chat(usr, "<font color='red'>[bicon(src)] incorrect pin/account combination entered.</font>")
|
||||
number_incorrect_tries = 0
|
||||
else
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
@@ -308,7 +308,7 @@ log transactions
|
||||
T.time = stationtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
|
||||
to_chat(usr, "<font color='blue'>\icon[src] Access granted. Welcome user '[authenticated_account.owner_name].</font>'")
|
||||
to_chat(usr, "<font color='blue'>[bicon(src)] Access granted. Welcome user '[authenticated_account.owner_name].</font>'")
|
||||
|
||||
previous_account_number = tried_account_num
|
||||
if("e_withdrawal")
|
||||
@@ -336,7 +336,7 @@ log transactions
|
||||
T.time = stationtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
if("withdrawal")
|
||||
var/amount = max(text2num(href_list["funds_amount"]),0)
|
||||
amount = round(amount, 0.01)
|
||||
@@ -361,7 +361,7 @@ log transactions
|
||||
T.time = stationtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>You don't have enough funds to do that!</span>")
|
||||
if("balance_statement")
|
||||
if(authenticated_account)
|
||||
var/obj/item/weapon/paper/R = new(src.loc)
|
||||
@@ -433,7 +433,7 @@ log transactions
|
||||
if(!held_card)
|
||||
//this might happen if the user had the browser window open when somebody emagged it
|
||||
if(emagged > 0)
|
||||
to_chat(usr, "<font color='red'>\icon[src] The ATM card reader rejected your ID because this machine has been sabotaged!</font>")
|
||||
to_chat(usr, "<font color='red'>[bicon(src)] The ATM card reader rejected your ID because this machine has been sabotaged!</font>")
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
@@ -461,7 +461,7 @@ log transactions
|
||||
if(I)
|
||||
authenticated_account = attempt_account_access(I.associated_account_number)
|
||||
if(authenticated_account)
|
||||
to_chat(human_user, "<font color='blue'>\icon[src] Access granted. Welcome user '[authenticated_account.owner_name].</font>'")
|
||||
to_chat(human_user, "<font color='blue'>[bicon(src)] Access granted. Welcome user '[authenticated_account.owner_name].</font>'")
|
||||
|
||||
//create a transaction log entry
|
||||
var/datum/transaction/T = new()
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
if(linked_account)
|
||||
scan_card(I, O)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
else if (istype(O, /obj/item/weapon/spacecash/ewallet))
|
||||
var/obj/item/weapon/spacecash/ewallet/E = O
|
||||
if (linked_account)
|
||||
@@ -126,7 +126,7 @@
|
||||
if(transaction_locked && !transaction_paid)
|
||||
if(transaction_amount <= E.worth)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
src.visible_message("[bicon(src)] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//transfer the money
|
||||
@@ -143,11 +143,11 @@
|
||||
T.time = stationtime2text()
|
||||
linked_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>\The [O] doesn't have that much money!</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>\The [O] doesn't have that much money!</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Connected account has been suspended.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Connected account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
|
||||
else
|
||||
..()
|
||||
@@ -165,14 +165,14 @@
|
||||
alert("That is not a valid code!")
|
||||
print_reference()
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Incorrect code entered.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Incorrect code entered.</span>")
|
||||
if("change_id")
|
||||
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
|
||||
if(attempt_code == access_code)
|
||||
eftpos_name = sanitize(input("Enter a new terminal ID for this device", "Enter new EFTPOS ID"), MAX_NAME_LEN) + " EFTPOS scanner"
|
||||
print_reference()
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Incorrect code entered.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Incorrect code entered.</span>")
|
||||
if("link_account")
|
||||
var/attempt_account_num = input("Enter account number to pay EFTPOS charges into", "New account number") as num
|
||||
var/attempt_pin = input("Enter pin code", "Account pin") as num
|
||||
@@ -180,9 +180,9 @@
|
||||
if(linked_account)
|
||||
if(linked_account.suspended)
|
||||
linked_account = null
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Account has been suspended.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Account not found.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Account not found.</span>")
|
||||
if("trans_purpose")
|
||||
var/choice = sanitize(input("Enter reason for EFTPOS transaction", "Transaction purpose"))
|
||||
if(choice) transaction_purpose = choice
|
||||
@@ -205,14 +205,14 @@
|
||||
else if(linked_account)
|
||||
transaction_locked = 1
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>No account connected to send transactions to.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>No account connected to send transactions to.</span>")
|
||||
if("scan_card")
|
||||
if(linked_account)
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card))
|
||||
scan_card(I)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Unable to link accounts.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Unable to link accounts.</span>")
|
||||
if("reset")
|
||||
//reset the access code - requires HoP/captain access
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
@@ -220,10 +220,10 @@
|
||||
var/obj/item/weapon/card/id/C = I
|
||||
if(access_cent_captain in C.access || access_hop in C.access || access_captain in C.access)
|
||||
access_code = 0
|
||||
to_chat(usr, "\icon[src]<span class='info'>Access code reset to 0.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='info'>Access code reset to 0.</span>")
|
||||
else if (istype(I, /obj/item/weapon/card/emag))
|
||||
access_code = 0
|
||||
to_chat(usr, "\icon[src]<span class='info'>Access code reset to 0.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='info'>Access code reset to 0.</span>")
|
||||
|
||||
src.attack_self(usr)
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
if(!D.suspended)
|
||||
if(transaction_amount <= D.money)
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
src.visible_message("[bicon(src)] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
|
||||
//transfer the money
|
||||
@@ -276,25 +276,25 @@
|
||||
T.time = stationtime2text()
|
||||
linked_account.transaction_log.Add(T)
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>You don't have that much money!</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>You don't have that much money!</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Your account has been suspended.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Your account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Connected account has been suspended.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Connected account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>EFTPOS is not connected to an account.</span>")
|
||||
else if (istype(I, /obj/item/weapon/card/emag))
|
||||
if(transaction_locked)
|
||||
if(transaction_paid)
|
||||
to_chat(usr, "\icon[src]<span class='info'>You stealthily swipe \the [I] through \the [src].</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='info'>You stealthily swipe \the [I] through \the [src].</span>")
|
||||
transaction_locked = 0
|
||||
transaction_paid = 0
|
||||
else
|
||||
usr.visible_message("<span class='info'>\The [usr] swipes a card through \the [src].</span>")
|
||||
playsound(src, 'sound/machines/chime.ogg', 50, 1)
|
||||
src.visible_message("\icon[src] \The [src] chimes.")
|
||||
src.visible_message("[bicon(src)] \The [src] chimes.")
|
||||
transaction_paid = 1
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
if(allowed(usr))
|
||||
locked = !locked
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Insufficient access.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Insufficient access.</span>")
|
||||
if("toggle_cash_lock")
|
||||
cash_locked = !cash_locked
|
||||
if("link_account")
|
||||
@@ -113,9 +113,9 @@
|
||||
if(linked_account)
|
||||
if(linked_account.suspended)
|
||||
linked_account = null
|
||||
src.visible_message("\icon[src]<span class='warning'>Account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Account not found.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Account not found.</span>")
|
||||
if("custom_order")
|
||||
var/t_purpose = sanitize(input("Enter purpose", "New purpose") as text)
|
||||
if (!t_purpose || !Adjacent(usr)) return
|
||||
@@ -126,7 +126,7 @@
|
||||
transaction_amount += t_amount
|
||||
price_list += t_amount
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 25)
|
||||
src.visible_message("\icon[src][transaction_purpose]: [t_amount] Thaler\s.")
|
||||
src.visible_message("[bicon(src)][transaction_purpose]: [t_amount] Thaler\s.")
|
||||
if("set_amount")
|
||||
var/item_name = locate(href_list["item"])
|
||||
var/n_amount = round(input("Enter amount", "New amount") as num)
|
||||
@@ -163,7 +163,7 @@
|
||||
price_list.Cut()
|
||||
if("reset_log")
|
||||
transaction_logs.Cut()
|
||||
to_chat(usr, "\icon[src]<span class='notice'>Transaction log reset.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='notice'>Transaction log reset.</span>")
|
||||
updateDialog()
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
return 1
|
||||
else
|
||||
confirm_item = I
|
||||
src.visible_message("\icon[src]<b>Total price:</b> [transaction_amount] Thaler\s. Swipe again to confirm.")
|
||||
src.visible_message("[bicon(src)]<b>Total price:</b> [transaction_amount] Thaler\s. Swipe again to confirm.")
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 25)
|
||||
return 0
|
||||
|
||||
@@ -219,14 +219,14 @@
|
||||
|
||||
if (cash_open)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
|
||||
to_chat(usr, "\icon[src]<span class='warning'>The cash box is open.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>The cash box is open.</span>")
|
||||
return
|
||||
|
||||
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(I))
|
||||
return
|
||||
|
||||
if (!linked_account)
|
||||
usr.visible_message("\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
usr.visible_message("[bicon(src)]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
return
|
||||
|
||||
// Access account for transaction
|
||||
@@ -239,13 +239,13 @@
|
||||
D = attempt_account_access(I.associated_account_number, attempt_pin, 2)
|
||||
|
||||
if(!D)
|
||||
src.visible_message("\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
else
|
||||
if(D.suspended)
|
||||
src.visible_message("\icon[src]<span class='warning'>Your account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Your account has been suspended.</span>")
|
||||
else
|
||||
if(transaction_amount > D.money)
|
||||
src.visible_message("\icon[src]<span class='warning'>Not enough funds.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Not enough funds.</span>")
|
||||
else
|
||||
// Transfer the money
|
||||
D.money -= transaction_amount
|
||||
@@ -284,7 +284,7 @@
|
||||
|
||||
if (cash_open)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
|
||||
to_chat(usr, "\icon[src]<span class='warning'>The cash box is open.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>The cash box is open.</span>")
|
||||
return
|
||||
|
||||
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(E))
|
||||
@@ -293,7 +293,7 @@
|
||||
// Access account for transaction
|
||||
if(check_account())
|
||||
if(transaction_amount > E.worth)
|
||||
src.visible_message("\icon[src]<span class='warning'>Not enough funds.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Not enough funds.</span>")
|
||||
else
|
||||
// Transfer the money
|
||||
E.worth -= transaction_amount
|
||||
@@ -322,14 +322,14 @@
|
||||
|
||||
if (cash_open)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
|
||||
to_chat(usr, "\icon[src]<span class='warning'>The cash box is open.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>The cash box is open.</span>")
|
||||
return
|
||||
|
||||
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(SC))
|
||||
return
|
||||
|
||||
if(transaction_amount > SC.worth)
|
||||
src.visible_message("\icon[src]<span class='warning'>Not enough money.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Not enough money.</span>")
|
||||
else
|
||||
// Insert cash into magical slot
|
||||
SC.worth -= transaction_amount
|
||||
@@ -351,20 +351,20 @@
|
||||
/obj/machinery/cash_register/proc/scan_item_price(obj/O)
|
||||
if(!istype(O)) return
|
||||
if(item_list.len > 10)
|
||||
src.visible_message("\icon[src]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
|
||||
return
|
||||
if (cash_open)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
|
||||
to_chat(usr, "\icon[src]<span class='warning'>The cash box is open.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>The cash box is open.</span>")
|
||||
return
|
||||
|
||||
// First check if item has a valid price
|
||||
var/price = O.get_item_cost()
|
||||
if(isnull(price))
|
||||
src.visible_message("\icon[src]<span class='warning'>Unable to find item in database.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Unable to find item in database.</span>")
|
||||
return
|
||||
// Call out item cost
|
||||
src.visible_message("\icon[src]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].")
|
||||
src.visible_message("[bicon(src)]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].")
|
||||
// Note the transaction purpose for later use
|
||||
if(transaction_purpose)
|
||||
transaction_purpose += "<br>"
|
||||
@@ -432,11 +432,11 @@
|
||||
|
||||
/obj/machinery/cash_register/proc/check_account()
|
||||
if (!linked_account)
|
||||
usr.visible_message("\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
usr.visible_message("[bicon(src)]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
return 0
|
||||
|
||||
if(linked_account.suspended)
|
||||
src.visible_message("\icon[src]<span class='warning'>Connected account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Connected account has been suspended.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -444,7 +444,7 @@
|
||||
/obj/machinery/cash_register/proc/transaction_complete()
|
||||
/// Visible confirmation
|
||||
playsound(src, 'sound/machines/chime.ogg', 25)
|
||||
src.visible_message("\icon[src]<span class='notice'>Transaction complete.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='notice'>Transaction complete.</span>")
|
||||
flick("register_approve", src)
|
||||
reset_memory()
|
||||
updateDialog()
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
if(allowed(usr))
|
||||
locked = !locked
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Insufficient access.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Insufficient access.</span>")
|
||||
if("link_account")
|
||||
var/attempt_account_num = input("Enter account number", "New account number") as num
|
||||
var/attempt_pin = input("Enter PIN", "Account PIN") as num
|
||||
@@ -108,9 +108,9 @@
|
||||
if(linked_account)
|
||||
if(linked_account.suspended)
|
||||
linked_account = null
|
||||
src.visible_message("\icon[src]<span class='warning'>Account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Account has been suspended.</span>")
|
||||
else
|
||||
to_chat(usr, "\icon[src]<span class='warning'>Account not found.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='warning'>Account not found.</span>")
|
||||
if("custom_order")
|
||||
var/t_purpose = sanitize(input("Enter purpose", "New purpose") as text)
|
||||
if (!t_purpose || !Adjacent(usr)) return
|
||||
@@ -121,7 +121,7 @@
|
||||
transaction_amount += t_amount
|
||||
price_list += t_amount
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 25)
|
||||
src.visible_message("\icon[src][transaction_purpose]: [t_amount] Thaler\s.")
|
||||
src.visible_message("[bicon(src)][transaction_purpose]: [t_amount] Thaler\s.")
|
||||
if("set_amount")
|
||||
var/item_name = locate(href_list["item"])
|
||||
var/n_amount = round(input("Enter amount", "New amount") as num)
|
||||
@@ -158,7 +158,7 @@
|
||||
price_list.Cut()
|
||||
if("reset_log")
|
||||
transaction_logs.Cut()
|
||||
to_chat(usr, "\icon[src]<span class='notice'>Transaction log reset.</span>")
|
||||
to_chat(usr, "[bicon(src)]<span class='notice'>Transaction log reset.</span>")
|
||||
updateDialog()
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
return 1
|
||||
else
|
||||
confirm_item = I
|
||||
src.visible_message("\icon[src]<b>Total price:</b> [transaction_amount] Thaler\s. Swipe again to confirm.")
|
||||
src.visible_message("[bicon(src)]<b>Total price:</b> [transaction_amount] Thaler\s. Swipe again to confirm.")
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 25)
|
||||
return 0
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
return
|
||||
|
||||
if (!linked_account)
|
||||
usr.visible_message("\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
usr.visible_message("[bicon(src)]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
return
|
||||
|
||||
// Access account for transaction
|
||||
@@ -217,13 +217,13 @@
|
||||
D = attempt_account_access(I.associated_account_number, attempt_pin, 2)
|
||||
|
||||
if(!D)
|
||||
src.visible_message("\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Unable to access account. Check security settings and try again.</span>")
|
||||
else
|
||||
if(D.suspended)
|
||||
src.visible_message("\icon[src]<span class='warning'>Your account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Your account has been suspended.</span>")
|
||||
else
|
||||
if(transaction_amount > D.money)
|
||||
src.visible_message("\icon[src]<span class='warning'>Not enough funds.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Not enough funds.</span>")
|
||||
else
|
||||
// Transfer the money
|
||||
D.money -= transaction_amount
|
||||
@@ -266,7 +266,7 @@
|
||||
// Access account for transaction
|
||||
if(check_account())
|
||||
if(transaction_amount > E.worth)
|
||||
src.visible_message("\icon[src]<span class='warning'>Not enough funds.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Not enough funds.</span>")
|
||||
else
|
||||
// Transfer the money
|
||||
E.worth -= transaction_amount
|
||||
@@ -292,16 +292,16 @@
|
||||
/obj/item/device/retail_scanner/proc/scan_item_price(var/obj/O)
|
||||
if(!istype(O)) return
|
||||
if(item_list.len > 10)
|
||||
src.visible_message("\icon[src]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
|
||||
return
|
||||
|
||||
// First check if item has a valid price
|
||||
var/price = O.get_item_cost()
|
||||
if(isnull(price))
|
||||
src.visible_message("\icon[src]<span class='warning'>Unable to find item in database.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Unable to find item in database.</span>")
|
||||
return
|
||||
// Call out item cost
|
||||
src.visible_message("\icon[src]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].")
|
||||
src.visible_message("[bicon(src)]\A [O]: [price ? "[price] Thaler\s" : "free of charge"].")
|
||||
// Note the transaction purpose for later use
|
||||
if(transaction_purpose)
|
||||
transaction_purpose += "<br>"
|
||||
@@ -369,11 +369,11 @@
|
||||
|
||||
/obj/item/device/retail_scanner/proc/check_account()
|
||||
if (!linked_account)
|
||||
usr.visible_message("\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
usr.visible_message("[bicon(src)]<span class='warning'>Unable to connect to linked account.</span>")
|
||||
return 0
|
||||
|
||||
if(linked_account.suspended)
|
||||
src.visible_message("\icon[src]<span class='warning'>Connected account has been suspended.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='warning'>Connected account has been suspended.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -381,7 +381,7 @@
|
||||
/obj/item/device/retail_scanner/proc/transaction_complete()
|
||||
/// Visible confirmation
|
||||
playsound(src, 'sound/machines/chime.ogg', 25)
|
||||
src.visible_message("\icon[src]<span class='notice'>Transaction complete.</span>")
|
||||
src.visible_message("[bicon(src)]<span class='notice'>Transaction complete.</span>")
|
||||
flick("retail_approve", src)
|
||||
reset_memory()
|
||||
updateDialog()
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
if (!P.message_silent)
|
||||
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(3, P.loc))
|
||||
if(!P.message_silent) O.show_message(text("\icon[P] *[P.ttone]*"))
|
||||
if(!P.message_silent) O.show_message(text("[bicon(P)] *[P.ttone]*"))
|
||||
//Search for holder of the PDA.
|
||||
var/mob/living/L = null
|
||||
if(P.loc && isliving(P.loc))
|
||||
@@ -125,4 +125,4 @@
|
||||
L = get(P, /mob/living/silicon)
|
||||
|
||||
if(L)
|
||||
to_chat(L, "\icon[P] <b>Message from [sender] (Unknown / spam?), </b>\"[message]\" (Unable to Reply)")
|
||||
to_chat(L, "[bicon(P)] <b>Message from [sender] (Unknown / spam?), </b>\"[message]\" (Unable to Reply)")
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
// Quickly adds the boilerplate code to add an image and padding for the image.
|
||||
/proc/desc_panel_image(var/icon_state)
|
||||
return "\icon[description_icons[icon_state]][EXAMINE_PANEL_PADDING]"
|
||||
return "[bicon(description_icons[icon_state])][EXAMINE_PANEL_PADDING]"
|
||||
|
||||
/mob/living/get_description_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
@@ -56,7 +56,7 @@
|
||||
description_holders["interactions"] = A.get_description_interaction()
|
||||
|
||||
description_holders["name"] = "[A.name]"
|
||||
description_holders["icon"] = "\icon[A]"
|
||||
description_holders["icon"] = "[bicon(A)]"
|
||||
description_holders["desc"] = A.desc
|
||||
|
||||
/mob/Stat()
|
||||
|
||||
@@ -92,7 +92,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("\icon[src] <span class='info'>[user] scoops delicious [flavour_name] icecream into [I].</span>")
|
||||
src.visible_message("[bicon(src)] <span class='info'>[user] scoops delicious [flavour_name] icecream into [I].</span>")
|
||||
product_types[dispense_flavour] -= 1
|
||||
I.add_ice_cream(flavour_name)
|
||||
// if(beaker)
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
<A href='?src=\ref[src];action=dispose'>Eject ingredients!<BR>\
|
||||
"}
|
||||
|
||||
to_chat(user, browse("<HEAD><TITLE>Microwave Controls</TITLE></HEAD><TT>[dat]</TT>", "window=microwave"))
|
||||
user << browse("<HEAD><TITLE>Microwave Controls</TITLE></HEAD><TT>[dat]</TT>", "window=microwave")
|
||||
onclose(user, "microwave")
|
||||
return
|
||||
|
||||
@@ -422,4 +422,4 @@
|
||||
|
||||
/obj/machinery/microwave/advanced/Initialize()
|
||||
..()
|
||||
reagents.maximum_volume = 1000
|
||||
reagents.maximum_volume = 1000
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
if (!P.message_silent)
|
||||
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
for (var/mob/O in hearers(3, P.loc))
|
||||
if(!P.message_silent) O.show_message(text("\icon[P] *[P.ttone]*"))
|
||||
if(!P.message_silent) O.show_message(text("[bicon(P)] *[P.ttone]*"))
|
||||
//Search for holder of the PDA.
|
||||
var/mob/living/L = null
|
||||
if(P.loc && isliving(P.loc))
|
||||
@@ -125,7 +125,7 @@
|
||||
L = get(P, /mob/living/silicon)
|
||||
|
||||
if(L)
|
||||
to_chat(L, "\icon[P] <b>Message from [sender] (Unknown / spam?), </b>\"[message]\" (Unable to Reply)")
|
||||
to_chat(L, "[bicon(P)] <b>Message from [sender] (Unknown / spam?), </b>\"[message]\" (Unable to Reply)")
|
||||
|
||||
/datum/gm_action/pda_spam/get_weight()
|
||||
return 25 * metric.count_people_in_department(ROLE_EVERYONE)
|
||||
|
||||
@@ -68,15 +68,15 @@
|
||||
active = 0
|
||||
if(failed_task)
|
||||
failed_task = 0
|
||||
visible_message("\icon[src] [src] pings unhappily, flashing a red warning light.")
|
||||
visible_message("[bicon(src)] [src] pings unhappily, flashing a red warning light.")
|
||||
else
|
||||
visible_message("\icon[src] [src] pings happily.")
|
||||
visible_message("[bicon(src)] [src] pings happily.")
|
||||
|
||||
if(eject_disk)
|
||||
eject_disk = 0
|
||||
if(loaded_disk)
|
||||
loaded_disk.loc = get_turf(src)
|
||||
visible_message("\icon[src] [src] beeps and spits out [loaded_disk].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
|
||||
/obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -190,14 +190,14 @@
|
||||
plant_controller.seeds[seed.seed.name] = seed.seed
|
||||
|
||||
seed.update_seed()
|
||||
visible_message("\icon[src] [src] beeps and spits out [seed].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [seed].")
|
||||
|
||||
seed = null
|
||||
|
||||
if(href_list["eject_disk"])
|
||||
if(!loaded_disk) return
|
||||
loaded_disk.loc = get_turf(src)
|
||||
visible_message("\icon[src] [src] beeps and spits out [loaded_disk].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
|
||||
usr.set_machine(src)
|
||||
|
||||
@@ -416,7 +416,7 @@
|
||||
|
||||
if(loc)
|
||||
for(var/mob/O in hearers(1, get_turf(src)))
|
||||
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2
|
||||
name = "\improper EPv2 circuit"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
var/list/nearby_things = range(0, get_turf(src))
|
||||
for(var/mob/M in nearby_things)
|
||||
var/obj/O = assembly ? assembly : src
|
||||
to_chat(M, "<span class='notice'>\icon[O] [stuff_to_display]</span>")
|
||||
to_chat(M, "<span class='notice'>[bicon(O)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/large
|
||||
name = "large screen"
|
||||
@@ -56,7 +56,7 @@
|
||||
/obj/item/integrated_circuit/output/screen/large/do_work()
|
||||
..()
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.visible_message("<span class='notice'>\icon[O] [stuff_to_display]</span>")
|
||||
O.visible_message("<span class='notice'>[bicon(O)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/light
|
||||
name = "light"
|
||||
@@ -134,7 +134,7 @@
|
||||
text = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(text))
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
audible_message("\icon[O] \The [O.name] states, \"[text]\"")
|
||||
audible_message("[bicon(O)] \The [O.name] states, \"[text]\"")
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech/advanced
|
||||
name = "advanced text-to-speech circuit"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
if(ore_type) metals[ore_type] += T.resources[metal]
|
||||
|
||||
to_chat(user, "\icon[src] <span class='notice'>The scanner beeps and displays a readout.</span>")
|
||||
to_chat(user, "[bicon(src)] <span class='notice'>The scanner beeps and displays a readout.</span>")
|
||||
|
||||
for(var/ore_type in metals)
|
||||
var/result = "no sign"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
input = message
|
||||
if(input)
|
||||
log_emote(message,src) //Log before we add junk
|
||||
message = "<B>[src]</B> [input]"
|
||||
message = "<span class='emote'><B>[src]</B> [input]</span>"
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
if(!..(user))
|
||||
return
|
||||
|
||||
var/msg = "<span class='info'>*---------*</span>\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
var/msg = "<span class='info'>*---------*</span>\nThis is [bicon(src)] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
if(src.brainmob && src.brainmob.key)
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
if(!..(user))
|
||||
return
|
||||
|
||||
var/msg = "<span class='info'>*---------*</span>\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
var/msg = "<span class='info'>*---------*</span>\nThis is [bicon(src)] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
if(src.brainmob && src.brainmob.key)
|
||||
|
||||
@@ -143,8 +143,8 @@
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/datum/gender/T = gender_datums[H.get_visible_gender()]
|
||||
src.visible_message( \
|
||||
"<font color='blue'>[src] examines [T.himself].</font>", \
|
||||
"<font color='blue'>You check yourself for injuries.</font>" \
|
||||
"<span class='notice'>[src] examines [T.himself].</span>", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>" \
|
||||
)
|
||||
|
||||
for(var/obj/item/organ/external/org in H.organs)
|
||||
|
||||
@@ -77,8 +77,7 @@
|
||||
|
||||
var/list/msg = list("<span class='info'>*---------*<br>This is ")
|
||||
|
||||
if(icon)
|
||||
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
|
||||
msg += "[bicon(src)] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
|
||||
|
||||
msg += "<EM>[src.name]</EM>"
|
||||
|
||||
@@ -143,16 +142,16 @@
|
||||
tie_msg += " Attached to it is [english_list(accessories_visible)]."
|
||||
|
||||
if(w_uniform.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [w_uniform.name]![tie_msg]</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing [bicon(w_uniform)] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [w_uniform.name]![tie_msg]</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform].[tie_msg]<br>"
|
||||
msg += "[T.He] [T.is] wearing [bicon(w_uniform)] \a [w_uniform].[tie_msg]<br>"
|
||||
|
||||
//head
|
||||
if(head && !(skip_gear & EXAMINE_SKIPHELMET) && head.show_examine)
|
||||
if(head.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] [(head.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [head.name] on [T.his] head!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.<br>"
|
||||
msg += "[T.He] [T.is] wearing [bicon(head)] \a [head] on [T.his] head.<br>"
|
||||
|
||||
//suit/armour
|
||||
if(wear_suit)
|
||||
@@ -163,71 +162,71 @@
|
||||
tie_msg += " Attached to it is [english_list(U.accessories)]."
|
||||
|
||||
if(wear_suit.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_suit.name][tie_msg]!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_suit.name][tie_msg]!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit].[tie_msg]<br>"
|
||||
msg += "[T.He] [T.is] wearing [bicon(wear_suit)] \a [wear_suit].[tie_msg]<br>"
|
||||
|
||||
//suit/armour storage
|
||||
if(s_store && !(skip_gear & EXAMINE_SKIPSUITSTORAGE) && s_store.show_examine)
|
||||
if(s_store.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].<br>"
|
||||
msg += "[T.He] [T.is] carrying [bicon(s_store)] \a [s_store] on [T.his] [wear_suit.name].<br>"
|
||||
|
||||
//back
|
||||
if(back && !(skip_gear & EXAMINE_SKIPBACKPACK) && back.show_examine)
|
||||
if(back.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [back] on [T.his] back.</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [bicon(back)] [back.gender==PLURAL?"some":"a"] [(back.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [back] on [T.his] back.</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(back)] \a [back] on [T.his] back.<br>"
|
||||
|
||||
//left hand
|
||||
if(l_hand && l_hand.show_examine)
|
||||
if(l_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding [bicon(l_hand)] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.<br>"
|
||||
msg += "[T.He] [T.is] holding [bicon(l_hand)] \a [l_hand] in [T.his] left hand.<br>"
|
||||
|
||||
//right hand
|
||||
if(r_hand && r_hand.show_examine)
|
||||
if(r_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] holding [bicon(r_hand)] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.<br>"
|
||||
msg += "[T.He] [T.is] holding [bicon(r_hand)] \a [r_hand] in [T.his] right hand.<br>"
|
||||
|
||||
//gloves
|
||||
if(gloves && !(skip_gear & EXAMINE_SKIPGLOVES) && gloves.show_examine)
|
||||
if(gloves.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(gloves)] \a [gloves] on [T.his] hands.<br>"
|
||||
else if(blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
|
||||
msg += "<span class='warning'>[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!</span><br>"
|
||||
|
||||
//handcuffed?
|
||||
if(handcuffed && handcuffed.show_examine)
|
||||
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] restrained with cable!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] [bicon(handcuffed)] restrained with cable!</span><br>"
|
||||
else
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[handcuffed] handcuffed!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] [bicon(handcuffed)] handcuffed!</span><br>"
|
||||
|
||||
//buckled
|
||||
if(buckled)
|
||||
msg += "<span class='warning'>[T.He] [T.is] \icon[buckled] buckled to [buckled]!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] [bicon(buckled)] buckled to [buckled]!</span><br>"
|
||||
|
||||
//belt
|
||||
if(belt && !(skip_gear & EXAMINE_SKIPBELT) && belt.show_examine)
|
||||
if(belt.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(belt)] \a [belt] about [T.his] waist.<br>"
|
||||
|
||||
//shoes
|
||||
if(shoes && !(skip_gear & EXAMINE_SKIPSHOES) && shoes.show_examine)
|
||||
if(shoes.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.<br>"
|
||||
msg += "[T.He] [T.is] wearing [bicon(shoes)] \a [shoes] on [T.his] feet.<br>"
|
||||
else if(feet_blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
|
||||
msg += "<span class='warning'>[T.He] [T.has] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!</span><br>"
|
||||
|
||||
@@ -238,24 +237,24 @@
|
||||
descriptor = "in [T.his] mouth"
|
||||
|
||||
if(wear_mask.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] [descriptor]!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] [descriptor].<br>"
|
||||
msg += "[T.He] [T.has] [bicon(wear_mask)] \a [wear_mask] [descriptor].<br>"
|
||||
|
||||
//eyes
|
||||
if(glasses && !(skip_gear & EXAMINE_SKIPEYEWEAR) && glasses.show_examine)
|
||||
if(glasses.blood_DNA)
|
||||
msg += "<span class='warning'>[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.has] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!</span><br>"
|
||||
else
|
||||
msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(glasses)] \a [glasses] covering [T.his] eyes.<br>"
|
||||
|
||||
//left ear
|
||||
if(l_ear && !(skip_gear & EXAMINE_SKIPEARS) && l_ear.show_examine)
|
||||
msg += "[T.He] [T.has] \icon[l_ear] \a [l_ear] on [T.his] left ear.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(l_ear)] \a [l_ear] on [T.his] left ear.<br>"
|
||||
|
||||
//right ear
|
||||
if(r_ear && !(skip_gear & EXAMINE_SKIPEARS) && r_ear.show_examine)
|
||||
msg += "[T.He] [T.has] \icon[r_ear] \a [r_ear] on [T.his] right ear.<br>"
|
||||
msg += "[T.He] [T.has] [bicon(r_ear)] \a [r_ear] on [T.his] right ear.<br>"
|
||||
|
||||
//ID
|
||||
if(wear_id && wear_id.show_examine)
|
||||
@@ -267,9 +266,9 @@
|
||||
var/obj/item/weapon/card/id/idcard = wear_id
|
||||
id = idcard.registered_name
|
||||
if(id && (id != real_name) && (get_dist(src, usr) <= 1) && prob(10))
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span><br>"
|
||||
msg += "<span class='warning'>[T.He] [T.is] wearing [bicon(wear_id)] \a [wear_id] yet something doesn't seem right...</span><br>"
|
||||
else*/
|
||||
msg += "[T.He] [T.is] wearing \icon[wear_id] \a [wear_id].<br>"
|
||||
msg += "[T.He] [T.is] wearing [bicon(wear_id)] \a [wear_id].<br>"
|
||||
|
||||
//Jitters
|
||||
if(is_jittery)
|
||||
|
||||
@@ -519,7 +519,7 @@
|
||||
if(href_list["send"])
|
||||
P.sradio.send_signal("ACTIVATE")
|
||||
for(var/mob/O in hearers(1, P.loc))
|
||||
O.show_message(text("\icon[] *beep* *beep*", P), 3, "*beep* *beep*", 2)
|
||||
O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
return 1
|
||||
|
||||
else if(href_list["freq"])
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
if( ishuman(AM) )
|
||||
if(!stat)
|
||||
var/mob/M = AM
|
||||
M.visible_message("<font color='blue'>\icon[src] Squeek!</font>")
|
||||
M.visible_message("<font color='blue'>[bicon(src)] Squeek!</font>")
|
||||
playsound(src, 'sound/effects/mouse_squeak.ogg', 35, 1)
|
||||
..()
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
/mob/living/simple_mob/construct/examine(mob/user)
|
||||
..(user)
|
||||
var/msg = "<span cass='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
|
||||
var/msg = "<span cass='info'>*---------*\nThis is [bicon(src)] \a <EM>[src]</EM>!\n"
|
||||
if (src.health < src.getMaxHealth())
|
||||
msg += "<span class='warning'>"
|
||||
if (src.health >= src.getMaxHealth()/2)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
var/new_name = sanitizeSafe(input(src, "Who would you like to be now?", "Communicator", src.client.prefs.real_name) as text, MAX_NAME_LEN)
|
||||
if(new_name)
|
||||
if(comm)
|
||||
comm.visible_message("<span class='notice'>\icon[comm] [src.name] has left, and now you see [new_name].</span>")
|
||||
comm.visible_message("<span class='notice'>[bicon(comm)] [src.name] has left, and now you see [new_name].</span>")
|
||||
//Do a bit of logging in-case anyone tries to impersonate other characters for whatever reason.
|
||||
var/msg = "[src.client.key] ([src]) has changed their communicator identity's name to [new_name]."
|
||||
message_admins(msg)
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
spawn() alert("You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
|
||||
if(matches)
|
||||
if(M.client)
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'><A href='?src=\ref[usr];priv_msg=\ref[src]'>[key_name_admin(src)]</A> has the same [matches] as <A href='?src=\ref[usr];priv_msg=\ref[M]'>[key_name_admin(M)]</A>.</font>", 1)
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] has the same [matches] as [key_name_admin(M)].</font>", 1)
|
||||
log_adminwarn("Notice: [key_name(src)] has the same [matches] as [key_name(M)].")
|
||||
else
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'><A href='?src=\ref[usr];priv_msg=\ref[src]'>[key_name_admin(src)]</A> has the same [matches] as [key_name_admin(M)] (no longer logged in). </font>", 1)
|
||||
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] has the same [matches] as [key_name_admin(M)] (no longer logged in). </font>", 1)
|
||||
log_adminwarn("Notice: [key_name(src)] has the same [matches] as [key_name(M)] (no longer logged in).")
|
||||
|
||||
/mob/Login()
|
||||
|
||||
+2
-22
@@ -331,9 +331,9 @@
|
||||
if (flavor_text && flavor_text != "")
|
||||
var/msg = replacetext(flavor_text, "\n", " ")
|
||||
if(length(msg) <= 40)
|
||||
return "<font color='blue'>[msg]</font>"
|
||||
return "<span class='notice'>[msg]</span>"
|
||||
else
|
||||
return "<font color='blue'>[copytext_preserve_html(msg, 1, 37)]... <a href='byond://?src=\ref[src];flavor_more=1'>More...</font></a>"
|
||||
return "<span class='notice'>[copytext_preserve_html(msg, 1, 37)]... <a href='byond://?src=\ref[src];flavor_more=1'>More...</span></a>"
|
||||
|
||||
/*
|
||||
/mob/verb/help()
|
||||
@@ -408,26 +408,6 @@
|
||||
/client/verb/changes()
|
||||
set name = "Changelog"
|
||||
set category = "OOC"
|
||||
getFiles(
|
||||
'html/88x31.png',
|
||||
'html/bug-minus.png',
|
||||
'html/cross-circle.png',
|
||||
'html/hard-hat-exclamation.png',
|
||||
'html/image-minus.png',
|
||||
'html/image-plus.png',
|
||||
'html/map-pencil.png',
|
||||
'html/music-minus.png',
|
||||
'html/music-plus.png',
|
||||
'html/tick-circle.png',
|
||||
'html/wrench-screwdriver.png',
|
||||
'html/spell-check.png',
|
||||
'html/burn-exclamation.png',
|
||||
'html/chevron.png',
|
||||
'html/chevron-expand.png',
|
||||
'html/changelog.css',
|
||||
'html/changelog.js',
|
||||
'html/changelog.html'
|
||||
)
|
||||
src << browse('html/changelog.html', "window=changes;size=675x650")
|
||||
if(prefs.lastchangelog != changelog_hash)
|
||||
prefs.lastchangelog = changelog_hash
|
||||
|
||||
@@ -6,6 +6,8 @@ var/obj/effect/lobby_image = new /obj/effect/lobby_image
|
||||
name = "Polaris"
|
||||
desc = "How are you reading this?"
|
||||
screen_loc = "1,1"
|
||||
icon = 'icons/misc/loading.dmi' //VOREStation Add - Loading Screen
|
||||
icon_state = "loading" //VOREStation Add - Loading Screen
|
||||
|
||||
/obj/effect/lobby_image/Initialize()
|
||||
icon = using_map.lobby_icon
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
if(input)
|
||||
log_subtle(message,src)
|
||||
message = "<B>[src]</B> <I>[input]</I>"
|
||||
message = "<span class='emote'><B>[src]</B> <I>[input]</I></span>"
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable
|
||||
/obj/item/device/nif/proc/notify(var/message,var/alert = 0)
|
||||
if(!human || stat == NIF_TEMPFAIL) return
|
||||
|
||||
to_chat(human,"<b>\[\icon[src.big_icon]NIF\]</b> displays, \"<span class='[alert ? "danger" : "notice"]'>[message]</span>\"")
|
||||
to_chat(human,"<b>\[[bicon(src.big_icon)]NIF\]</b> displays, \"<span class='[alert ? "danger" : "notice"]'>[message]</span>\"")
|
||||
if(prob(1)) human.visible_message("<span class='notice'>\The [human] [pick(look_messages)].</span>")
|
||||
if(alert)
|
||||
human << bad_sound
|
||||
|
||||
@@ -71,12 +71,12 @@
|
||||
proc/notify_into(var/message)
|
||||
var/sound = nif.good_sound
|
||||
|
||||
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice'>[message]</span>\"")
|
||||
to_chat(nif.human,"<b>\[[bicon(nif.big_icon)]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice nif'>[message]</span>\"")
|
||||
nif.human << sound
|
||||
|
||||
for(var/brainmob in brainmobs)
|
||||
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
||||
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice'>[message]</span>\"")
|
||||
to_chat(CS,"<b>\[[bicon(nif.big_icon)]NIF\]</b> <b>Soulcatcher</b> displays, \"<span class='notice nif'>[message]</span>\"")
|
||||
brainmob << sound
|
||||
|
||||
proc/say_into(var/message, var/mob/living/sender, var/mob/eyeobj)
|
||||
@@ -88,10 +88,10 @@
|
||||
|
||||
//Not AR Projecting
|
||||
else
|
||||
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"")
|
||||
to_chat(nif.human,"<span class='game say nif'><b>\[[bicon(nif.big_icon)]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"</span>")
|
||||
for(var/brainmob in brainmobs)
|
||||
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
||||
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"")
|
||||
to_chat(CS,"<span class='game say nif'><b>\[[bicon(nif.big_icon)]NIF\]</b> <b>[sender_name]</b> speaks, \"[message]\"</span>")
|
||||
|
||||
log_nsay(message,nif.human.real_name,sender)
|
||||
|
||||
@@ -104,10 +104,10 @@
|
||||
|
||||
//Not AR Projecting
|
||||
else
|
||||
to_chat(nif.human,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> [message]")
|
||||
to_chat(nif.human,"<span class='emote nif'><b>\[[bicon(nif.big_icon)]NIF\]</b> <b>[sender_name]</b> [message]</span>")
|
||||
for(var/brainmob in brainmobs)
|
||||
var/mob/living/carbon/brain/caught_soul/CS = brainmob
|
||||
to_chat(CS,"<b>\[\icon[nif.big_icon]NIF\]</b> <b>[sender_name]</b> [message]")
|
||||
to_chat(CS,"<span class='emote nif'><b>\[[bicon(nif.big_icon)]NIF\]</b> <b>[sender_name]</b> [message]</span>")
|
||||
|
||||
log_nme(message,nif.human.real_name,sender)
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@
|
||||
var/name_used = M.GetVoice()
|
||||
var/rendered = null
|
||||
if(speaking) //Language being used
|
||||
rendered = "<span class='game say'>\icon[icon_object] <span class='name'>[name_used]</span> [speaking.format_message(text, verb)]</span>"
|
||||
rendered = "<span class='game say'>[bicon(icon_object)] <span class='name'>[name_used]</span> [speaking.format_message(text, verb)]</span>"
|
||||
else
|
||||
rendered = "<span class='game say'>\icon[icon_object] <span class='name'>[name_used]</span> [verb], <span class='message'>\"[text]\"</span></span>"
|
||||
rendered = "<span class='game say'>[bicon(icon_object)] <span class='name'>[name_used]</span> [verb], <span class='message'>\"[text]\"</span></span>"
|
||||
mob.show_message(rendered, 2)
|
||||
|
||||
//Not supported by the internal one
|
||||
|
||||
@@ -91,11 +91,19 @@
|
||||
. = ..(user,2)
|
||||
if(.)
|
||||
switch(construction_stage)
|
||||
if(2) to_chat(user, "<span class='notice'>It has a metal frame loosely shaped around the stock.</span>")
|
||||
if(3) to_chat(user, "<span class='notice'>It has a metal frame duct-taped to the stock.</span>")
|
||||
if(4) to_chat(user, "<span class='notice'>It has a length of pipe attached to the body.</span>")
|
||||
if(4) to_chat(user, "<span class='notice'>It has a length of pipe welded to the body.</span>")
|
||||
if(6) to_chat(user, "<span class='notice'>It has a cable mount and capacitor jack wired to the frame.</span>")
|
||||
if(7) to_chat(user, "<span class='notice'>It has a single superconducting coil threaded onto the barrel.</span>")
|
||||
if(8) to_chat(user, "<span class='notice'>It has a pair of superconducting coils threaded onto the barrel.</span>")
|
||||
if(9) to_chat(user, "<span class='notice'>It has three superconducting coils attached to the body, waiting to be secured.</span>")
|
||||
if(2)
|
||||
to_chat(user, "<span class='notice'>It has a metal frame loosely shaped around the stock.</span>")
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>It has a metal frame duct-taped to the stock.</span>")
|
||||
if(4)
|
||||
to_chat(user, "<span class='notice'>It has a length of pipe attached to the body.</span>")
|
||||
if(4)
|
||||
to_chat(user, "<span class='notice'>It has a length of pipe welded to the body.</span>")
|
||||
if(6)
|
||||
to_chat(user, "<span class='notice'>It has a cable mount and capacitor jack wired to the frame.</span>")
|
||||
if(7)
|
||||
to_chat(user, "<span class='notice'>It has a single superconducting coil threaded onto the barrel.</span>")
|
||||
if(8)
|
||||
to_chat(user, "<span class='notice'>It has a pair of superconducting coils threaded onto the barrel.</span>")
|
||||
if(9)
|
||||
to_chat(user, "<span class='notice'>It has three superconducting coils attached to the body, waiting to be secured.</span>")
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
var/turf/T = get_turf(container)
|
||||
var/list/seen = viewers(4, T)
|
||||
for(var/mob/M in seen)
|
||||
M.show_message("<span class='notice'>\icon[container] [mix_message]</span>", 1)
|
||||
M.show_message("<span class='notice'>[bicon(container)] [mix_message]</span>", 1)
|
||||
playsound(T, reaction_sound, 80, 1)
|
||||
|
||||
//obtains any special data that will be provided to the reaction products
|
||||
|
||||
@@ -131,12 +131,12 @@ var/global/list/obj/machinery/message_server/message_servers = list()
|
||||
if(2)
|
||||
if(!Console.silent)
|
||||
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
Console.audible_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5)
|
||||
Console.message_log += "<B><FONT color='red'>High Priority message from <A href='?src=\ref[Console];write=[sender]'>[sender]</A></FONT></B><BR>[authmsg]"
|
||||
else
|
||||
if(!Console.silent)
|
||||
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
Console.audible_message(text("\icon[Console] *The Requests Console beeps: 'Message from [sender]'"),,4)
|
||||
Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4)
|
||||
Console.message_log += "<B>Message from <A href='?src=\ref[Console];write=[sender]'>[sender]</A></B><BR>[authmsg]"
|
||||
Console.set_light(2)
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
if(href_list["send"])
|
||||
P.sradio.send_signal("ACTIVATE")
|
||||
for(var/mob/O in hearers(1, P.loc))
|
||||
O.show_message(text("\icon[] *beep* *beep*", P), 3, "*beep* *beep*", 2)
|
||||
O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
return 1
|
||||
|
||||
else if(href_list["freq"])
|
||||
|
||||
@@ -258,14 +258,14 @@
|
||||
return
|
||||
|
||||
if (src.active)
|
||||
user.visible_message("<font color='blue'>\icon[src] [user] deactivated the shield generator.</font>", \
|
||||
"<font color='blue'>\icon[src] You deactivate the shield generator.</font>", \
|
||||
user.visible_message("<font color='blue'>[bicon(src)] [user] deactivated the shield generator.</font>", \
|
||||
"<font color='blue'>[bicon(src)] You deactivate the shield generator.</font>", \
|
||||
"You hear heavy droning fade out.")
|
||||
src.shields_down()
|
||||
else
|
||||
if(anchored)
|
||||
user.visible_message("<font color='blue'>\icon[src] [user] activated the shield generator.</font>", \
|
||||
"<font color='blue'>\icon[src] You activate the shield generator.</font>", \
|
||||
user.visible_message("<font color='blue'>[bicon(src)] [user] activated the shield generator.</font>", \
|
||||
"<font color='blue'>[bicon(src)] You activate the shield generator.</font>", \
|
||||
"You hear heavy droning.")
|
||||
src.shields_up()
|
||||
else
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
else if(W.is_wrench())
|
||||
src.anchored = !src.anchored
|
||||
playsound(src, W.usesound, 75, 1)
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].</font>")
|
||||
|
||||
if(anchored)
|
||||
spawn(0)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
else if(W.is_wrench())
|
||||
src.anchored = !src.anchored
|
||||
playsound(src, W.usesound, 75, 1)
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].</font>")
|
||||
|
||||
if(active)
|
||||
toggle()
|
||||
@@ -248,7 +248,7 @@
|
||||
covered_turfs = null
|
||||
|
||||
for(var/mob/M in view(5,src))
|
||||
to_chat(M, "\icon[src] You hear heavy droning start up.")
|
||||
to_chat(M, "[bicon(src)] You hear heavy droning start up.")
|
||||
for(var/obj/effect/energy_field/E in field) // Update the icons here to ensure all the shields have been made already.
|
||||
E.update_icon()
|
||||
else
|
||||
@@ -258,7 +258,7 @@
|
||||
qdel(D)
|
||||
|
||||
for(var/mob/M in view(5,src))
|
||||
to_chat(M, "\icon[src] You hear heavy droning fade out.")
|
||||
to_chat(M, "[bicon(src)] You hear heavy droning fade out.")
|
||||
|
||||
/obj/machinery/shield_gen/update_icon()
|
||||
if(stat & BROKEN)
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="semantic.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="vchat-font-embedded.css" />
|
||||
<link rel="stylesheet" type="text/css" href="ss13styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="ui top fixed pointing menu">
|
||||
<div class="item">
|
||||
Main
|
||||
</div>
|
||||
<div class="item">
|
||||
OOC
|
||||
<div class="ui top right attached red label">15</div>
|
||||
</div>
|
||||
|
||||
<div class="right menu">
|
||||
<div class="item" style="cursor: pointer;" title="New Tab"><i class="icon-folder-add"></i></div>
|
||||
<div class="item" style="cursor: pointer;" title="Pause Autoscroll">
|
||||
<i class="icon-pause-outline" :class="{ blinkwarn: paused }"></i>
|
||||
</div>
|
||||
<div class="item" style="cursor: pointer;" title="Edit Mode">
|
||||
<i class="icon-cog-outline" :class="{ blinkwarn: editing }"></i>
|
||||
</div>
|
||||
<div class="item" style="padding-left: 0px !important;"><span class="ui circular label" title="VChat Latency (Not exactly network latency)" :class="ping_classes">{{latency}}ms</span></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="contentbox">
|
||||
<div class="ui segment">
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message."</span><br>
|
||||
<span class='notice'>Testing notice message.</span><br>
|
||||
<span class='danger'>Testing danger message.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message."</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 2."</span><br>
|
||||
<span class='notice'>Testing notice message 2.</span><br>
|
||||
<span class='danger'>Testing danger message 2.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 2".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 2.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 2.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 2.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 3."</span><br>
|
||||
<span class='notice'>Testing notice message 3.</span><br>
|
||||
<span class='danger'>Testing danger message 3.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 3".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 3.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 3.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 3.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 4."</span><br>
|
||||
<span class='notice'>Testing notice message 4.</span><br>
|
||||
<span class='danger'>Testing danger message 4.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 4".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 4.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 4.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 4.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 5."</span><br>
|
||||
<span class='notice'>Testing notice message 5.</span><br>
|
||||
<span class='danger'>Testing danger message 5.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 5".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 5.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 5.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 5.</span><br>
|
||||
</div>
|
||||
<div class="ui segment inverted">
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message."</span><br>
|
||||
<span class='notice'>Testing notice message.</span><br>
|
||||
<span class='danger'>Testing danger message.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message."</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 2."</span><br>
|
||||
<span class='notice'>Testing notice message 2.</span><br>
|
||||
<span class='danger'>Testing danger message 2.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 2".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 2.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 2.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 2.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 3."</span><br>
|
||||
<span class='notice'>Testing notice message 3.</span><br>
|
||||
<span class='danger'>Testing danger message 3.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 3".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 3.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 3.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 3.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 4."</span><br>
|
||||
<span class='notice'>Testing notice message 4.</span><br>
|
||||
<span class='danger'>Testing danger message 4.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 4".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 4.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 4.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 4.</span><br>
|
||||
<span class='game say'><b>Test Person</b> says, "Testing say message 5."</span><br>
|
||||
<span class='notice'>Testing notice message 5.</span><br>
|
||||
<span class='danger'>Testing danger message 5.</span><br>
|
||||
<span class='secradio'>[Security] <b>Secu Person</b> says, "Testing radio message 5".</span><br>
|
||||
<span class='ooc'><span class='everyone'>Testing OOC message 5.</span></span><br>
|
||||
<span class='ooc'><span class='looc'>Testing LOOC message 5.</span></span><br>
|
||||
<span class='admin_channel'>Testing asay message 5.</span><br>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+404
File diff suppressed because one or more lines are too long
+110
File diff suppressed because one or more lines are too long
@@ -0,0 +1,232 @@
|
||||
/* VChat Styles */
|
||||
#contentbox {
|
||||
margin-top: 3rem; /* Make room for the fixed top menu */
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word; /* IE, blah */
|
||||
}
|
||||
|
||||
.menu, .item {
|
||||
padding-top: 0.2em !important;
|
||||
padding-bottom: 0.2em !important;
|
||||
}
|
||||
|
||||
.ui.menu .item > .label:not(.floating) {
|
||||
margin-left: 0;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#app > .menu {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon-left-open-outline:hover, .icon-right-open-outline:hover, .icon-cancel-circled-outline:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
body.inverted {
|
||||
background-color: #111111;
|
||||
}
|
||||
|
||||
.blinkwarn {
|
||||
color: #FF0000;
|
||||
animation: blink-animation 1s steps(5, start) infinite;
|
||||
}
|
||||
|
||||
@keyframes blink-animation {
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* The chat message display classes */
|
||||
#messagebox div { display: none; } /* Hide messages by default */
|
||||
#messagebox.vc_showall div { display: block; } /* Unless we have vc_showall */
|
||||
|
||||
#messagebox.vc_localchat .vc_localchat { display: block; }
|
||||
#messagebox.vc_radio .vc_radio { display: block; }
|
||||
#messagebox.vc_warnings .vc_warnings { display: block; }
|
||||
#messagebox.vc_info .vc_info { display: block; }
|
||||
#messagebox.vc_deadchat .vc_deadchat { display: block; }
|
||||
#messagebox.vc_globalooc .vc_globalooc { display: block; }
|
||||
#messagebox.vc_adminpm .vc_adminpm { display: block; }
|
||||
#messagebox.vc_adminchat .vc_adminchat { display: block; }
|
||||
#messagebox.vc_modchat .vc_modchat { display: block; }
|
||||
#messagebox.vc_eventchat .vc_eventchat { display: block; }
|
||||
#messagebox.vc_system .vc_system { display: block; }
|
||||
#messagebox.vc_nif .vc_nif { display: block; } /* VOREStation Add */
|
||||
|
||||
|
||||
/* SS13 Styles */
|
||||
#messagebox {font-family: Verdana, sans-serif;}
|
||||
|
||||
#messagebox h1, #messagebox h2, #messagebox h3, #messagebox h4, #messagebox h5, #messagebox h6 {color: #0000ff; font-family: Georgia, Verdana, sans-serif;}
|
||||
|
||||
#messagebox em {font-style: normal; font-weight: bold;}
|
||||
|
||||
.motd {color: #638500;font-family: Verdana, sans-serif;}
|
||||
.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6
|
||||
{color: #638500;text-decoration: underline;}
|
||||
.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover
|
||||
{color: #638500;}
|
||||
|
||||
.prefix {font-weight: bold;}
|
||||
.log_message {color: #386AFF; font-weight: bold;}
|
||||
/*.inverted .message {color: #386AFF; font-weight: bold;}*/
|
||||
|
||||
/* OOC */
|
||||
.ooc {font-weight: bold;}
|
||||
.ooc img.text_tag {width: 32px; height: 10px;}
|
||||
|
||||
.ooc .everyone {color: #002eb8;}
|
||||
.inverted .ooc .everyone {color: #004ed8;} /* Dark mode */
|
||||
.ooc .looc {color: #3A9696;}
|
||||
.ooc .elevated {color: #2e78d9;}
|
||||
.ooc .moderator {color: #184880;}
|
||||
.ooc .developer {color: #1b521f;}
|
||||
.ooc .admin {color: #b82e00;}
|
||||
.ooc .event_manager {color: #660033;}
|
||||
.ooc .aooc {color: #960018;}
|
||||
|
||||
/* Admin: Private Messages */
|
||||
.pm .howto {color: #ff0000; font-weight: bold; font-size: 200%;}
|
||||
.pm .in {color: #ff0000;}
|
||||
.pm .out {color: #ff0000;}
|
||||
.pm .other {color: #0000ff;}
|
||||
|
||||
/* Admin: Channels */
|
||||
.mod_channel {color: #735638; font-weight: bold;}
|
||||
.mod_channel .admin {color: #b82e00; font-weight: bold;}
|
||||
.admin_channel {color: #9611D4; font-weight: bold;}
|
||||
.event_channel {color: #cc3399; font-weight: bold;}
|
||||
|
||||
/* Radio: Misc */
|
||||
.deadsay {color: #530FAD;}
|
||||
.inverted .deadsay {color: #732FCD;} /* Dark mode */
|
||||
.radio {color: #008000;}
|
||||
.deptradio {color: #ff00ff;} /* when all other department colors fail */
|
||||
.newscaster {color: #750000;}
|
||||
|
||||
/* Radio Channels */
|
||||
.comradio {color: #193A7A;}
|
||||
.inverted .comradio {color: #395A9A;} /* Dark mode */
|
||||
.syndradio {color: #6D3F40;}
|
||||
.centradio {color: #5C5C8A;}
|
||||
.airadio {color: #FF00FF;}
|
||||
.entradio {color: #339966;}
|
||||
|
||||
.secradio {color: #A30000;}
|
||||
.engradio {color: #A66300;}
|
||||
.medradio {color: #008160;}
|
||||
.sciradio {color: #993399;}
|
||||
.supradio {color: #5F4519;}
|
||||
.srvradio {color: #6eaa2c;}
|
||||
.expradio {color: #555555;}
|
||||
|
||||
/* Miscellaneous */
|
||||
.name {font-weight: bold;}
|
||||
.say {}
|
||||
.emote {}
|
||||
.alert {color: #ff0000;}
|
||||
h1.alert, h2.alert {color: #000000;}
|
||||
.nif {} /* VOREStation Add */
|
||||
|
||||
/* Game Messages */
|
||||
|
||||
.attack {color: #ff0000;}
|
||||
.moderate {color: #CC0000;}
|
||||
.disarm {color: #990000;}
|
||||
.passive {color: #660000;}
|
||||
|
||||
.critical {color: #ff0000; font-weight: bold; font-size: 150%;}
|
||||
.danger {color: #ff0000; font-weight: bold;}
|
||||
.warning {color: #ff0000; font-style: italic;}
|
||||
.rose {color: #ff5050;}
|
||||
.info {color: #0000CC;}
|
||||
.inverted .info {color: #6060c9;} /* Dark mode */
|
||||
.notice {color: #000099;}
|
||||
.inverted .notice {color: #6060c9;} /* Dark mode */
|
||||
.alium {color: #00ff00;}
|
||||
.cult {color: #800080; font-weight: bold; font-style: italic;}
|
||||
|
||||
.reflex_shoot {color: #000099; font-style: italic;}
|
||||
|
||||
/* Languages */
|
||||
|
||||
.alien {color: #543354;}
|
||||
.tajaran {color: #803B56;}
|
||||
.tajaran_signlang {color: #941C1C;}
|
||||
.akhani {color: #AC398C;}
|
||||
.skrell {color: #00B0B3;}
|
||||
.skrellfar {color: #70FCFF;}
|
||||
.soghun {color: #228B22;}
|
||||
.solcom {color: #22228B;}
|
||||
.changeling {color: #800080;}
|
||||
.sergal {color: #0077FF; font-family: "Comic Sans MS";}
|
||||
.birdsongc {color: #CC9900;}
|
||||
.vulpkanin {color: #B97A57;}
|
||||
.enochian {color: #848A33; letter-spacing:-1pt; word-spacing:4pt; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;}
|
||||
.daemon {color: #5E339E; letter-spacing:-1pt; word-spacing:0pt; font-family: "Courier New", Courier, monospace;}
|
||||
.bug {color: #9e9e39;}
|
||||
.vox {color: #AA00AA;}
|
||||
.zaddat {color: #941C1C;}
|
||||
.rough {font-family: "Trebuchet MS", cursive, sans-serif;}
|
||||
.say_quote {font-family: Georgia, Verdana, sans-serif;}
|
||||
.terminus {font-family: "Times New Roman", Times, serif, sans-serif}
|
||||
.interface {color: #330033;}
|
||||
|
||||
/*BIG IMG.icon {width: 32px; height: 32px;}*/
|
||||
img.icon {vertical-align: middle; max-height: 1em;}
|
||||
img.icon.bigicon {max-height: 32px;}
|
||||
|
||||
/* Zoom levels */
|
||||
.zoom_normal {
|
||||
font-size: 0.9em;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.zoom_more {
|
||||
font-size: 1.2em;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.zoom_less {
|
||||
font-size: 0.8em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Debug Logs */
|
||||
.debug_error {color:#FF0000; font-weight:bold}
|
||||
.debug_warning {color:#FF0000;}
|
||||
.debug_info {}
|
||||
.debug_debug {color:#0000FF;}
|
||||
.debug_trace {color:#888888;}
|
||||
|
||||
/* Log animations */
|
||||
.msgsanim-enter-active {
|
||||
transition: opacity 0.5s, transform 0.5s;
|
||||
}
|
||||
.msgsanim-enter {
|
||||
opacity: 0;
|
||||
transform: translateX(15px);
|
||||
}
|
||||
|
||||
/* Dog mode */
|
||||
.woof {
|
||||
background-color: rgba(255,255,255,0) !important;
|
||||
background-image: url('dog.gif') !important;
|
||||
background-size: cover !important;
|
||||
|
||||
transition: background-color 15s;
|
||||
}
|
||||
|
||||
.woof div, .woof span {
|
||||
background-color: rgba(0,0,0,0) !important;
|
||||
|
||||
transition: background-color 15s;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html>
|
||||
<html debug="true">
|
||||
<head>
|
||||
<title>VChat</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="stylesheet" type="text/css" href="semantic.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="vchat-font-embedded.css" />
|
||||
<link rel="stylesheet" type="text/css" href="ss13styles.css" />
|
||||
|
||||
<!-- Important scripts -->
|
||||
<script type="text/javascript" src="polyfills.js"></script>
|
||||
<script type="text/javascript" src="vue.min.js"></script>
|
||||
<script type="text/javascript" src="vchat.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="loader">
|
||||
<p>VChat is still loading. If you see this for a very long time, try the OOC 'Reload VChat' verb, or reconnecting.</p>
|
||||
<p>Sometimes if you're still caching resources, it will take longer than usual.</p>
|
||||
</div>
|
||||
<div id="app" @mouseup="on_mouseup" style="display: none;">
|
||||
|
||||
<!-- Top menu -->
|
||||
<div class="ui top fixed pointing menu" :class="{ inverted: inverted }">
|
||||
<div v-for="(tab,index) in tabs" class="item" :class="{ active: tab.active, inverted: inverted }" @click="switchtab(tab)" @click.ctrl="editmode">
|
||||
<i v-show="editing && !tab.immutable && index >= 2" class="icon-left-open-outline" @click.stop.prevent="movetab(tab,-1)" title="Move tab left"></i>
|
||||
{{tab.name}}
|
||||
<i v-show="editing && !tab.immutable" class="icon-cancel-circled-outline" @click.stop.prevent="deltab(tab)" title="Delete tab"></i>
|
||||
<i v-show="editing && !tab.immutable && index != tabs.length-1" class="icon-right-open-outline" @click.stop.prevent="movetab(tab,1)" title="Move tab right"></i>
|
||||
<div v-if="tab_unread_count(tab) > 0" class="ui top right attached red label">{{tab_unread_count(tab)}}</div>
|
||||
</div>
|
||||
|
||||
<div class="right menu">
|
||||
<div class="item" :class="{ inverted: inverted }" @click="newtab" title="New Tab"><i class="icon-folder-add"></i></div>
|
||||
<div class="item" :class="{ inverted: inverted }" @click="pause" title="Pause Autoscroll">
|
||||
<i class="icon-pause-outline" :class="{ blinkwarn: paused }"></i>
|
||||
</div>
|
||||
<div class="item" :class="{ inverted: inverted }" @click="editmode" title="Edit Mode">
|
||||
<i class="icon-cog-outline" :class="{ blinkwarn: editing }"></i>
|
||||
</div>
|
||||
<div class="item"><span class="ui circular label" title="VChat Latency (Not exactly network latency)" :class="ping_classes">{{latency}}ms</span></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Editor box -->
|
||||
<div id="contentbox">
|
||||
<div v-show="editing" id="editbox" class="ui segment" :class="{ inverted: inverted }">
|
||||
<div class="ui internally celled grid">
|
||||
<div class="row">
|
||||
<div class="sixteen wide column">
|
||||
<div class="ui center aligned header" :class="{ inverted: inverted }">
|
||||
<h2>VChat Settings</h2>
|
||||
</div>
|
||||
<div style="text-align: center;"><a href="#" @click="editmode">Close Settings</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="eight wide column">
|
||||
<h3>'{{active_tab.name}}' Tab Settings</h3>
|
||||
<span v-show="active_tab.immutable">This tab is immutable. You cannot make changes.</span>
|
||||
<div v-show="!active_tab.immutable">
|
||||
<a href="#" @click="renametab">Rename Tab</a> - <a href="#" @click="deltab">Delete Tab</a>
|
||||
<h5>Messages to display:</h5>
|
||||
<div class="ui form">
|
||||
<div class="grouped fields">
|
||||
<div class="field" v-for="type in type_table">
|
||||
<div v-show="!type.admin || is_admin" class="ui slider checkbox" :class="{ inverted: inverted, disabled: type.required || active_tab.immutable, checked: type.required || active_tab.immutable }">
|
||||
<input type="checkbox" id="type.becomes" :value="type.becomes" v-model="active_tab.classes" :disabled="type.required || active_tab.immutable" :checked="type.required || active_tab.immutable"><label :for="type.becomes">{{type.pretty}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<h3>Global Settings</h3>
|
||||
<div class="ui form" :class="{ inverted: inverted }">
|
||||
<div class="grouped fields">
|
||||
<div class="field">
|
||||
<div class="ui slider checkbox" :class="{ inverted: inverted }">
|
||||
<input type="checkbox" id="darkmode" v-model="inverted"><label for="darkmode">Dark Mode</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui slider checkbox" :class="{ inverted: inverted }">
|
||||
<input type="checkbox" id="combining" v-model="crushing"><label for="combining">Combine Messages</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui slider checkbox" :class="{ inverted: inverted }">
|
||||
<input type="checkbox" id="combining" v-model="animated"><label for="animated">Animate Messages</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<label>Font Size</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" id="fssmall" name="fontsize" v-model="fontsize" value="zoom_less">
|
||||
<label for="fssmall">Small</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" id="fsstd" name="fontsize" v-model="fontsize" value="zoom_normal">
|
||||
<label for="fsstd">Standard</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" id="fslarge" name="fontsize" v-model="fontsize" value="zoom_more">
|
||||
<label for="fslarge">Large</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<div class="field">
|
||||
<label># Shown Messages</label>
|
||||
<input :class="{ inverted: inverted }" type="number" name="showingnum" placeholder="200" title="Will affect performance!" v-model.lazy.number="showingnum" required style="width: 5em; padding: 0.1em;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui button" :class="{ inverted: inverted }" @click="save_chatlog">Export Chatlog</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Messages box -->
|
||||
<div v-show="!editing" id="messagebox" class="ui segment" :class="active_classes" @click="click_message">
|
||||
<div v-show="messages.length > showingnum" class="vc_system">
|
||||
<span class='notice'>[ {{messages.length - showingnum}} previous messages hidden due to display settings. ]</span>
|
||||
</div>
|
||||
<transition-group name="msgsanim" tag="span" :css="animated">
|
||||
<div v-for="message in shown_messages" :class="[message.category, fontsize]" :key="message.id">
|
||||
<span v-html="message.content"></span>
|
||||
<span v-show="message.repeats > 1" class="ui grey circular label">x{{message.repeats}}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--
|
||||
Tab: {{active_tab}}<br>
|
||||
Classes: {{active_classes}}<br>
|
||||
Fontsize: {{fontsize}}<br>
|
||||
-->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//Document Ready
|
||||
(function(){
|
||||
start_vchat();
|
||||
document.getElementById("loader").style.display = 'none';
|
||||
document.getElementById("app").style.display = 'block';
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,78 @@
|
||||
// https://tc39.github.io/ecma262/#sec-array.prototype.find
|
||||
if (!Array.prototype.find) {
|
||||
Object.defineProperty(Array.prototype, 'find', {
|
||||
value: function(predicate) {
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
if (this == null) {
|
||||
throw TypeError('"this" is null or not defined');
|
||||
}
|
||||
|
||||
var o = Object(this);
|
||||
|
||||
// 2. Let len be ? ToLength(? Get(O, "length")).
|
||||
var len = o.length >>> 0;
|
||||
|
||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||
if (typeof predicate !== 'function') {
|
||||
throw TypeError('predicate must be a function');
|
||||
}
|
||||
|
||||
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
var thisArg = arguments[1];
|
||||
|
||||
// 5. Let k be 0.
|
||||
var k = 0;
|
||||
|
||||
// 6. Repeat, while k < len
|
||||
while (k < len) {
|
||||
// a. Let Pk be ! ToString(k).
|
||||
// b. Let kValue be ? Get(O, Pk).
|
||||
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
|
||||
// d. If testResult is true, return kValue.
|
||||
var kValue = o[k];
|
||||
if (predicate.call(thisArg, kValue, k, o)) {
|
||||
return kValue;
|
||||
}
|
||||
// e. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 7. Return undefined.
|
||||
return undefined;
|
||||
},
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
}
|
||||
|
||||
if (!Date.now) {
|
||||
Date.now = function now() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
}
|
||||
|
||||
//IE ugh
|
||||
function storageAvailable(type) {
|
||||
var storage;
|
||||
try {
|
||||
storage = window[type];
|
||||
var x = '__storage_test__';
|
||||
storage.setItem(x, x);
|
||||
storage.removeItem(x);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
return e instanceof DOMException && (
|
||||
// everything except Firefox
|
||||
e.code === 22 ||
|
||||
// Firefox
|
||||
e.code === 1014 ||
|
||||
// test name field too, because code might not be present
|
||||
// everything except Firefox
|
||||
e.name === 'QuotaExceededError' ||
|
||||
// Firefox
|
||||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
|
||||
// acknowledge QuotaExceededError only if there's something already stored
|
||||
(storage && storage.length !== 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,759 @@
|
||||
//The 'V' is for 'VORE' but you can pretend it's for Vue.js if you really want.
|
||||
|
||||
(function(){
|
||||
var oldLog = console.log;
|
||||
console.log = function (message) {
|
||||
send_debug(message);
|
||||
oldLog.apply(console, arguments);
|
||||
};
|
||||
var oldError = console.error;
|
||||
console.error = function (message) {
|
||||
send_debug(message);
|
||||
oldError.apply(console, arguments);
|
||||
}
|
||||
window.onerror = function (message, url, line, col, error) {
|
||||
var stacktrace = "";
|
||||
if(error && error.stack) {
|
||||
stacktrace = error.stack;
|
||||
}
|
||||
send_debug(message+" ("+url+"@"+line+":"+col+") "+error+"|UA: "+navigator.userAgent+"|Stack: "+stacktrace);
|
||||
return true;
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
//Options for vchat
|
||||
var vchat_opts = {
|
||||
crush_messages: 3, //How many messages back should we try to combine if crushing is on
|
||||
pingThisOften: 10000, //ms
|
||||
pingDropsAllowed: 2,
|
||||
cookiePrefix: "vst-" //If you're another server, you can change this if you want.
|
||||
};
|
||||
|
||||
var DARKMODE_COLORS = {
|
||||
buttonBgColor: "#40628a",
|
||||
buttonTextColor: "#FFFFFF",
|
||||
windowBgColor: "#272727",
|
||||
highlightColor: "#009900",
|
||||
tabTextColor: "#FFFFFF",
|
||||
tabBackgroundColor: "#272727"
|
||||
};
|
||||
|
||||
var LIGHTMODE_COLORS = {
|
||||
buttonBgColor: "none",
|
||||
buttonTextColor: "#000000",
|
||||
windowBgColor: "none",
|
||||
highlightColor: "#007700",
|
||||
tabTextColor: "#000000",
|
||||
tabBackgroundColor: "none"
|
||||
};
|
||||
|
||||
|
||||
/***********
|
||||
*
|
||||
* Setup Methods
|
||||
*
|
||||
************/
|
||||
|
||||
var set_storage = set_cookie;
|
||||
var get_storage = get_cookie;
|
||||
var domparser = new DOMParser();
|
||||
|
||||
//Upgrade to LS
|
||||
if (storageAvailable('localStorage')) {
|
||||
set_storage = set_localstorage;
|
||||
get_storage = get_localstorage;
|
||||
}
|
||||
|
||||
//State-tracking variables
|
||||
var vchat_state = {
|
||||
ready: false,
|
||||
|
||||
//Userinfo as reported by byond
|
||||
byond_ip: null,
|
||||
byond_cid: null,
|
||||
byond_ckey: null,
|
||||
|
||||
//Ping status
|
||||
lastPingAttempt: 0,
|
||||
lastPingReply: 0,
|
||||
missedPings: 0,
|
||||
latency: 0,
|
||||
reconnecting: false,
|
||||
|
||||
//Last ID
|
||||
lastId: 0
|
||||
}
|
||||
|
||||
function start_vchat() {
|
||||
//Instantiate Vue.js
|
||||
start_vue();
|
||||
|
||||
//Inform byond we're done
|
||||
vchat_state.ready = true;
|
||||
push_Topic('done_loading');
|
||||
|
||||
//I'll do my own winsets
|
||||
doWinset("htmloutput", {"is-visible": true});
|
||||
doWinset("oldoutput", {"is-visible": false});
|
||||
doWinset("chatloadlabel", {"is-visible": false});
|
||||
|
||||
//Commence the pingening
|
||||
send_ping();
|
||||
setInterval(send_ping, vchat_opts.pingThisOften);
|
||||
|
||||
//For fun
|
||||
send_debug("VChat Loaded!");
|
||||
//throw new Error("VChat Loaded!");
|
||||
|
||||
}
|
||||
|
||||
//Loads vue for chat usage
|
||||
var vueapp;
|
||||
function start_vue() {
|
||||
vueapp = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
messages: [], //List o messages from byond
|
||||
tabs: [ //Our tabs
|
||||
{name: "Main", classes: ["vc_showall"], immutable: true, active: true}
|
||||
],
|
||||
always_show: ["vc_looc", "vc_system"], //Classes to always display on every tab
|
||||
unread_messages: {}, //Message categories that haven't been looked at since we got one of them
|
||||
editing: false, //If we're in settings edit mode
|
||||
paused: false, //Autoscrolling
|
||||
latency: 0, //Not necessarily network latency, since the game server has to align the responses into ticks
|
||||
ext_styles: "", //Styles for chat downloaded files
|
||||
is_admin: false,
|
||||
|
||||
//Settings
|
||||
inverted: false, //Dark mode
|
||||
crushing: true, //Combine similar messages
|
||||
showingnum: 200, //How many messages to show
|
||||
animated: true, //Small CSS animations for new messages
|
||||
fontsize: "zoom_normal", //Font size nudging
|
||||
|
||||
//The table to map game css classes to our vchat classes
|
||||
type_table: [
|
||||
{
|
||||
matches: ".say, .emote",
|
||||
becomes: "vc_localchat",
|
||||
pretty: "Local Chat",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".alert, .syndradio, .centradio, .airadio, .entradio, .comradio, .secradio, .engradio, .medradio, .sciradio, .supradio, .srvradio, .expradio, .radio, .deptradio, .newscaster",
|
||||
becomes: "vc_radio",
|
||||
pretty: "Radio Comms",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".notice, .adminnotice, .info, .sinister, .cult",
|
||||
becomes: "vc_info",
|
||||
pretty: "Notices",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".critical, .danger, .userdanger, .warning, .italics",
|
||||
becomes: "vc_warnings",
|
||||
pretty: "Warnings",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".deadsay",
|
||||
becomes: "vc_deadchat",
|
||||
pretty: "Deadchat",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".ooc:not(.looc)",
|
||||
becomes: "vc_globalooc",
|
||||
pretty: "Global OOC",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
//VOREStation Add Start
|
||||
{
|
||||
matches: ".nif",
|
||||
becomes: "vc_nif",
|
||||
pretty: "NIF Messages",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
//VOREStation Add End
|
||||
{
|
||||
matches: ".pm",
|
||||
becomes: "vc_adminpm",
|
||||
pretty: "Admin PMs",
|
||||
required: false,
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".admin_channel",
|
||||
becomes: "vc_adminchat",
|
||||
pretty: "Admin Chat",
|
||||
required: false,
|
||||
admin: true
|
||||
},
|
||||
{
|
||||
matches: ".mod_channel",
|
||||
becomes: "vc_modchat",
|
||||
pretty: "Mod Chat",
|
||||
required: false,
|
||||
admin: true
|
||||
},
|
||||
{
|
||||
matches: ".event_channel",
|
||||
becomes: "vc_eventchat",
|
||||
pretty: "Event Chat",
|
||||
required: false,
|
||||
admin: true
|
||||
},
|
||||
{
|
||||
matches: ".ooc.looc, .ooc .looc", //Dumb game
|
||||
becomes: "vc_looc",
|
||||
pretty: "Local OOC",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
matches: ".boldannounce",
|
||||
becomes: "vc_system",
|
||||
pretty: "System Messages",
|
||||
required: true
|
||||
}
|
||||
],
|
||||
},
|
||||
created: function() {
|
||||
/*Dog mode
|
||||
setTimeout(function(){
|
||||
document.body.className += " woof";
|
||||
},5000);
|
||||
*/
|
||||
/* Stress test
|
||||
var varthis = this;
|
||||
setInterval( function() {
|
||||
if(varthis.messages.length > 10000) {
|
||||
return;
|
||||
}
|
||||
var stringymessages = JSON.stringify(varthis.messages);
|
||||
var unstringy = JSON.parse(stringymessages);
|
||||
unstringy.forEach( function(message) {
|
||||
message.id = ++vchat_state.lastId;
|
||||
varthis.messages.push(message);
|
||||
});
|
||||
varthis.internal_message("Now have " + varthis.messages.length + " messages in array.");
|
||||
}, 10000);
|
||||
*/
|
||||
},
|
||||
mounted: function() {
|
||||
//Load our settings
|
||||
this.load_settings();
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', 'ss13styles.css');
|
||||
xhr.onreadystatechange = (function() {
|
||||
this.ext_styles = xhr.responseText;
|
||||
}).bind(this);
|
||||
xhr.send();
|
||||
},
|
||||
updated: function() {
|
||||
if(!this.editing && !this.paused) {
|
||||
window.scrollTo(0,document.getElementById("messagebox").scrollHeight);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
//Save the inverted setting to LS
|
||||
inverted: function (newSetting) {
|
||||
set_storage("darkmode",newSetting);
|
||||
if(newSetting) { //Special treatment for <body> which is outside Vue's scope and has custom css
|
||||
document.body.classList.add("inverted");
|
||||
switch_ui_mode(DARKMODE_COLORS);
|
||||
} else {
|
||||
document.body.classList.remove("inverted");
|
||||
switch_ui_mode(LIGHTMODE_COLORS);
|
||||
}
|
||||
},
|
||||
crushing: function (newSetting) {
|
||||
set_storage("crushing",newSetting);
|
||||
},
|
||||
animated: function (newSetting) {
|
||||
set_storage("animated",newSetting);
|
||||
},
|
||||
fontsize: function (newSetting) {
|
||||
set_storage("fontsize",newSetting);
|
||||
},
|
||||
showingnum: function (newSetting, oldSetting) {
|
||||
if(!isFinite(newSetting)) {
|
||||
this.showingnum = oldSetting;
|
||||
return;
|
||||
}
|
||||
|
||||
newSetting = Math.floor(newSetting);
|
||||
if(newSetting <= 50) {
|
||||
this.showingnum = 50;
|
||||
} else if(newSetting > 2000) {
|
||||
this.showingnum = 2000;
|
||||
}
|
||||
set_storage("showingnum",this.showingnum);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//Which tab is active?
|
||||
active_tab: function() {
|
||||
//Had to polyfill this stupid .find since IE doesn't have EC6
|
||||
let tab = this.tabs.find( function(tab) {
|
||||
return tab.active;
|
||||
});
|
||||
return tab;
|
||||
},
|
||||
//Which classes does the active tab need?
|
||||
active_classes: function() {
|
||||
let classarray = this.active_tab.classes;
|
||||
let classtext = classarray.toString(); //Convert to a string
|
||||
let classproper = classtext.replace(/,/g," ");
|
||||
if(this.inverted) classproper += " inverted";
|
||||
return classproper; //Swap commas for spaces
|
||||
},
|
||||
//What color does the latency pip get?
|
||||
ping_classes: function() {
|
||||
if(this.latency === 0) { return "grey"; }
|
||||
else if(this.latency < 0 ) {return "red"; }
|
||||
else if(this.latency <= 200) { return "green"; }
|
||||
else if(this.latency <= 400) { return "yellow"; }
|
||||
else { return "red"; }
|
||||
},
|
||||
shown_messages: function() {
|
||||
if(this.messages.length <= this.showingnum) {
|
||||
return this.messages;
|
||||
} else {
|
||||
return this.messages.slice(-1*this.showingnum);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//Load the chat settings
|
||||
load_settings: function() {
|
||||
this.inverted = get_storage("darkmode", false);
|
||||
this.crushing = get_storage("crushing", true);
|
||||
this.showingnum = get_storage("showingnum", 200);
|
||||
this.animated = get_storage("animated", true);
|
||||
this.fontsize = get_storage("fontsize", 'zoom_normal');
|
||||
},
|
||||
//Change to another tab
|
||||
switchtab: function(tab) {
|
||||
if(tab == this.active_tab) return;
|
||||
this.active_tab.active = false;
|
||||
tab.active = true;
|
||||
|
||||
tab.classes.forEach( function(cls) {
|
||||
this.unread_messages[cls] = 0;
|
||||
}, this);
|
||||
},
|
||||
//Toggle edit mode
|
||||
editmode: function() {
|
||||
this.editing = !this.editing;
|
||||
},
|
||||
//Toggle autoscroll
|
||||
pause: function() {
|
||||
this.paused = !this.paused;
|
||||
},
|
||||
//Create a new tab (stupid lack of classes in ES5...)
|
||||
newtab: function() {
|
||||
this.tabs.push({
|
||||
name: "New Tab",
|
||||
classes: this.always_show,
|
||||
immutable: false,
|
||||
active: false
|
||||
});
|
||||
this.switchtab(this.tabs[this.tabs.length - 1]);
|
||||
},
|
||||
//Rename an existing tab
|
||||
renametab: function() {
|
||||
if(this.active_tab.immutable) {
|
||||
return;
|
||||
}
|
||||
var tabtorename = this.active_tab;
|
||||
var newname = window.prompt("Type the desired tab name:", tabtorename.name);
|
||||
if(newname === null || newname === "" || tabtorename === null) {
|
||||
return;
|
||||
}
|
||||
tabtorename.name = newname;
|
||||
},
|
||||
//Delete the currently active tab
|
||||
deltab: function(tab) {
|
||||
if(!tab) {
|
||||
tab = this.active_tab;
|
||||
}
|
||||
if(tab.immutable) {
|
||||
return;
|
||||
}
|
||||
this.switchtab(this.tabs[0]);
|
||||
this.tabs.splice(this.tabs.indexOf(tab), 1);
|
||||
},
|
||||
movetab: function(tab, shift) {
|
||||
if(!tab || tab.immutable) {
|
||||
return;
|
||||
}
|
||||
var at = this.tabs.indexOf(tab);
|
||||
var to = at + shift;
|
||||
this.tabs.splice(to, 0, this.tabs.splice(at, 1)[0]);
|
||||
},
|
||||
tab_unread_count: function(tab) {
|
||||
var unreads = 0;
|
||||
var thisum = this.unread_messages;
|
||||
tab.classes.find( function(cls){
|
||||
if(thisum[cls]) {
|
||||
unreads += thisum[cls];
|
||||
}
|
||||
});
|
||||
return unreads;
|
||||
},
|
||||
tab_unread_classes: function(tab) {
|
||||
var unreads = false;
|
||||
var thisum = this.unread_messages;
|
||||
tab.classes.find( function(cls){
|
||||
if(thisum[cls]) {
|
||||
unreads = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return { red: unreads, grey: !unreads};
|
||||
},
|
||||
//Push a new message into our array
|
||||
add_message: function(message) {
|
||||
//IE doesn't support the 'class' syntactic sugar so we're left making our own object.
|
||||
let newmessage = {
|
||||
time: message.time,
|
||||
category: "error",
|
||||
content: message.message,
|
||||
repeats: 1
|
||||
};
|
||||
//Get a category
|
||||
newmessage.category = this.get_category(newmessage.content);
|
||||
if(!this.active_tab.classes.some(function(cls) { return (cls == newmessage.category || cls == "vc_showall"); })) {
|
||||
if (isNaN(this.unread_messages[newmessage.category])) {
|
||||
this.unread_messages[newmessage.category] = 0;
|
||||
}
|
||||
this.unread_messages[newmessage.category] += 1;
|
||||
}
|
||||
|
||||
//Try to crush it with one of the last few
|
||||
if(this.crushing) {
|
||||
let crushwith = this.messages.slice(-(vchat_opts.crush_messages));
|
||||
for (let i = crushwith.length - 1; i >= 0; i--) {
|
||||
let oldmessage = crushwith[i];
|
||||
if(oldmessage.content == newmessage.content) {
|
||||
newmessage.repeats += oldmessage.repeats;
|
||||
this.messages.splice(this.messages.indexOf(oldmessage), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Append to vue's messages
|
||||
newmessage.id = ++vchat_state.lastId;
|
||||
this.messages.push(newmessage);
|
||||
},
|
||||
//Push an internally generated message into our array
|
||||
internal_message: function(message) {
|
||||
let newmessage = {
|
||||
time: this.messages.length ? this.messages.slice(-1).time+1 : 0,
|
||||
category: "vc_system",
|
||||
content: "<span class='notice'>[VChat Internal] " + message + "</span>"
|
||||
};
|
||||
newmessage.id = ++vchat_state.lastId;
|
||||
this.messages.push(newmessage);
|
||||
},
|
||||
on_mouseup: function(event) {
|
||||
// Focus map window on mouseup so hotkeys work. Exception for if they highlighted text or clicked an input.
|
||||
let ele = event.target;
|
||||
let textSelected = ('getSelection' in window) && window.getSelection().isCollapsed === false;
|
||||
if (!textSelected && !(ele && (ele.tagName === 'INPUT' || ele.tagName === 'TEXTAREA'))) {
|
||||
focusMapWindow();
|
||||
// Okay focusing map window appears to prevent click event from being fired. So lets do it ourselves.
|
||||
event.preventDefault();
|
||||
event.target.click();
|
||||
}
|
||||
},
|
||||
click_message: function(event) {
|
||||
let ele = event.target;
|
||||
if(ele.tagName === "A") {
|
||||
event.stopPropagation();
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue = false); //The second one is the weird IE method.
|
||||
|
||||
var href = ele.getAttribute('href'); // Gets actual href without transformation into fully qualified URL
|
||||
|
||||
if (href[0] == '?' || (href.length >= 8 && href.substring(0,8) == "byond://")) {
|
||||
window.location = href; //Internal byond link
|
||||
} else { //It's an external link
|
||||
window.location = "byond://?action=openLink&link="+encodeURIComponent(href);
|
||||
}
|
||||
}
|
||||
},
|
||||
//Derive a vchat category based on css classes
|
||||
get_category: function(message) {
|
||||
if(!vchat_state.ready) {
|
||||
push_Topic('not_ready');
|
||||
return;
|
||||
}
|
||||
|
||||
let doc = domparser.parseFromString(message, 'text/html');
|
||||
let evaluating = doc.querySelector('span');
|
||||
|
||||
let category = "nomatch"; //What we use if the classes aren't anything we know.
|
||||
if(!evaluating) return category;
|
||||
this.type_table.find( function(type) {
|
||||
if(evaluating.msMatchesSelector(type.matches)) {
|
||||
category = type.becomes;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return category;
|
||||
},
|
||||
save_chatlog: function() {
|
||||
var textToSave = "<html><head><style>"+this.ext_styles+"</style></head><body>";
|
||||
this.messages.forEach( function(message) {
|
||||
textToSave += message.content;
|
||||
if(message.repeats > 1) {
|
||||
textToSave += "(x"+message.repeats+")";
|
||||
}
|
||||
textToSave += "<br>\n";
|
||||
});
|
||||
textToSave += "</body></html>";
|
||||
var hiddenElement = document.createElement('a');
|
||||
hiddenElement.href = 'data:attachment/text,' + encodeURI(textToSave);
|
||||
hiddenElement.target = '_blank';
|
||||
|
||||
var filename = "chat_export.html";
|
||||
|
||||
//Unlikely to work unfortunately, not supported in any version of IE, only Edge
|
||||
if (hiddenElement.download !== undefined){
|
||||
hiddenElement.download = filename;
|
||||
hiddenElement.click();
|
||||
//Probably what will end up getting used
|
||||
} else {
|
||||
let blob = new Blob([textToSave], {type: 'text/html;charset=utf8;'});
|
||||
saved = window.navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/***********
|
||||
*
|
||||
* Actual Methods
|
||||
*
|
||||
************/
|
||||
//Send a 'ping' to byond and check to see if we got the last one back in a timely manner
|
||||
function send_ping() {
|
||||
vchat_state.latency = (Math.min(Math.max(vchat_state.lastPingReply - vchat_state.lastPingAttempt, -1), 999));
|
||||
//If their last reply was in the previous ping window or earlier.
|
||||
if(vchat_state.latency < 0) {
|
||||
vchat_state.missedPings++;
|
||||
if((vchat_state.missedPings >= vchat_opts.pingDropsAllowed) && !vchat_state.reconnecting) {
|
||||
system_message("Your client has lost connection with the server. It will reconnect automatically if possible.");
|
||||
vchat_state.reconnecting = true;
|
||||
}
|
||||
}
|
||||
|
||||
vueapp.latency = vchat_state.latency;
|
||||
push_Topic("keepalive_client");
|
||||
vchat_state.lastPingAttempt = Date.now();
|
||||
}
|
||||
|
||||
//We accept double-url-encoded JSON strings because Byond is garbage and UTF-8 encoded url_encode() text has crazy garbage in it.
|
||||
function byondDecode(message) {
|
||||
|
||||
//Byond encodes spaces as pluses?! This is 1998 I guess.
|
||||
message = message.replace(/\+/g, "%20");
|
||||
try {
|
||||
message = decodeURIComponent(message);
|
||||
} catch (err) {
|
||||
message = unescape(message);
|
||||
}
|
||||
return JSON.parse(message);
|
||||
}
|
||||
|
||||
//This is the function byond actually communicates with using byond's client << output() method.
|
||||
function putmessage(messages) {
|
||||
messages = byondDecode(messages);
|
||||
if (Array.isArray(messages)) {
|
||||
messages.forEach(function(message) {
|
||||
vueapp.add_message(message);
|
||||
});
|
||||
} else if (typeof messages === 'object') {
|
||||
vueapp.add_message(messages);
|
||||
}
|
||||
}
|
||||
|
||||
//Send an internal message generated in the javascript
|
||||
function system_message(message) {
|
||||
vueapp.internal_message(message);
|
||||
}
|
||||
|
||||
//This is the other direction of communication, to push a Topic message back
|
||||
function push_Topic(topic_uri) {
|
||||
window.location = '?_src_=chat&proc=' + topic_uri; //Yes that's really how it works.
|
||||
}
|
||||
|
||||
//Tells byond client to focus the main map window.
|
||||
function focusMapWindow() {
|
||||
window.location = 'byond://winset?mapwindow.map.focus=true';
|
||||
}
|
||||
|
||||
//Debug event
|
||||
function send_debug(message) {
|
||||
push_Topic("debug¶m[message]="+encodeURIComponent(message));
|
||||
}
|
||||
|
||||
//A side-channel to send events over that aren't just chat messages, if necessary.
|
||||
function get_event(event) {
|
||||
if(!vchat_state.ready) {
|
||||
push_Topic('not_ready');
|
||||
return;
|
||||
}
|
||||
|
||||
var parsed_event = {evttype: 'internal_error', event: event};
|
||||
parsed_event = byondDecode(event);
|
||||
|
||||
switch(parsed_event.evttype) {
|
||||
//We didn't parse it very well
|
||||
case 'internal_error':
|
||||
system_message("Event parse error: " + event);
|
||||
break;
|
||||
|
||||
//They provided byond data.
|
||||
case 'byond_player':
|
||||
send_client_data();
|
||||
vueapp.is_admin = (parsed_event.admin === 'true');
|
||||
vchat_state.byond_ip = parsed_event.address;
|
||||
vchat_state.byond_cid = parsed_event.cid;
|
||||
vchat_state.byond_ckey = parsed_event.ckey;
|
||||
set_storage("ip",vchat_state.byond_ip);
|
||||
set_storage("cid",vchat_state.byond_cid);
|
||||
set_storage("ckey",vchat_state.byond_ckey);
|
||||
break;
|
||||
|
||||
//Just a ping.
|
||||
case 'keepalive_server':
|
||||
vchat_state.lastPingReply = Date.now();
|
||||
vchat_state.missedPings = 0;
|
||||
reconnecting = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
system_message("Didn't know what to do with event: " + event);
|
||||
}
|
||||
}
|
||||
|
||||
//Send information retrieved from storage
|
||||
function send_client_data() {
|
||||
let client_data = {
|
||||
ip: get_storage("ip"),
|
||||
cid: get_storage("cid"),
|
||||
ckey: get_storage("ckey")
|
||||
};
|
||||
push_Topic("ident¶m[clientdata]="+JSON.stringify(client_data));
|
||||
}
|
||||
|
||||
//Newer localstorage methods
|
||||
function set_localstorage(key, value) {
|
||||
let localstorage = window.localStorage;
|
||||
localstorage.setItem(vchat_opts.cookiePrefix+key,value);
|
||||
}
|
||||
|
||||
function get_localstorage(key, deffo) {
|
||||
let localstorage = window.localStorage;
|
||||
let value = localstorage.getItem(vchat_opts.cookiePrefix+key);
|
||||
|
||||
//localstorage only stores strings.
|
||||
if(value === "null" || value === null) {
|
||||
value = deffo;
|
||||
} else if(value === "true") {
|
||||
value = true;
|
||||
} else if(value === "false") {
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//Older cookie methods
|
||||
function set_cookie(key, value) {
|
||||
let now = new Date();
|
||||
now.setFullYear(now.getFullYear() + 1);
|
||||
let then = now.toUTCString();
|
||||
document.cookie = vchat_opts.cookiePrefix+key+"="+value+";expires="+then+";path=/";
|
||||
}
|
||||
|
||||
function get_cookie(key, deffo) {
|
||||
var candidates = {cookie: null, localstorage: null, indexeddb: null};
|
||||
let cookie_array = document.cookie.split(';');
|
||||
let cookie_object = {};
|
||||
cookie_array.forEach( function(element) {
|
||||
let clean = element.replace(vchat_opts.cookiePrefix,"").trim(); //Strip the prefix, trim whitespace
|
||||
let equals = clean.search("="); //Find the equals
|
||||
let left = decodeURIComponent(clean.substring(0,equals)); //From start to one char before equals
|
||||
let right = decodeURIComponent(clean.substring(equals+1)); //From one char after equals to end
|
||||
//cookies only stores strings.
|
||||
if(right == "null" || right === null) {
|
||||
right = deffo;
|
||||
} else if(right === "true") {
|
||||
right = true;
|
||||
} else if(right === "false") {
|
||||
right = false;
|
||||
}
|
||||
cookie_object[left] = right; //Stick into object
|
||||
});
|
||||
candidates.cookie = cookie_object[key]; //Return value of that key in our object (or undefined)
|
||||
}
|
||||
|
||||
// Button Controls that need background-color and text-color set.
|
||||
var SKIN_BUTTONS = [
|
||||
/* Rpane */ "rpane.textb", "rpane.infob", "rpane.wikib", "rpane.forumb", "rpane.rulesb", "rpane.github", "rpane.mapb", "rpane.changelog",
|
||||
/* Mainwindow */ "mainwindow.saybutton", "mainwindow.mebutton", "mainwindow.hotkey_toggle"
|
||||
|
||||
];
|
||||
// Windows or controls that need background-color set.
|
||||
var SKIN_ELEMENTS = [
|
||||
/* Mainwindow */ "mainwindow", "mainwindow.mainvsplit", "mainwindow.tooltip",
|
||||
/* Rpane */ "rpane", "rpane.rpanewindow", "rpane.mediapanel",
|
||||
];
|
||||
|
||||
function switch_ui_mode(options) {
|
||||
doWinset(SKIN_BUTTONS.reduce(function(params, ctl) {params[ctl + ".background-color"] = options.buttonBgColor; return params;}, {}));
|
||||
doWinset(SKIN_BUTTONS.reduce(function(params, ctl) {params[ctl + ".text-color"] = options.buttonTextColor; return params;}, {}));
|
||||
doWinset(SKIN_ELEMENTS.reduce(function(params, ctl) {params[ctl + ".background-color"] = options.windowBgColor; return params;}, {}));
|
||||
doWinset("infowindow", {
|
||||
"background-color": options.tabBackgroundColor,
|
||||
"text-color": options.tabTextColor
|
||||
});
|
||||
doWinset("infowindow.info", {
|
||||
"background-color": options.tabBackgroundColor,
|
||||
"text-color": options.tabTextColor,
|
||||
"highlight-color": options.highlightColor,
|
||||
"tab-text-color": options.tabTextColor,
|
||||
"tab-background-color": options.tabBackgroundColor
|
||||
});
|
||||
}
|
||||
|
||||
function doWinset(control_id, params) {
|
||||
if (typeof params === 'undefined') {
|
||||
params = control_id; // Handle single-argument use case.
|
||||
control_id = null;
|
||||
}
|
||||
var url = "byond://winset?";
|
||||
if (control_id) {
|
||||
url += ("id=" + control_id + "&");
|
||||
}
|
||||
url += Object.keys(params).map(function(ctl) {
|
||||
return ctl + "=" + encodeURIComponent(params[ctl]);
|
||||
}).join("&");
|
||||
window.location = url;
|
||||
}
|
||||
Vendored
+11965
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,328 @@
|
||||
#define BACKLOG_LENGTH 20 MINUTES
|
||||
|
||||
//The 'V' is for 'VORE' but you can pretend it's for Vue.js if you really want.
|
||||
|
||||
//These are sent to the client via browse_rsc() in advance so the HTML can access them.
|
||||
GLOBAL_LIST_INIT(vchatFiles, list(
|
||||
"code/modules/vchat/css/vchat-font-embedded.css",
|
||||
"code/modules/vchat/css/semantic.min.css",
|
||||
"code/modules/vchat/css/ss13styles.css",
|
||||
"code/modules/vchat/js/polyfills.js",
|
||||
"code/modules/vchat/js/vue.min.js",
|
||||
"code/modules/vchat/js/vchat.js"
|
||||
))
|
||||
|
||||
// The to_chat() macro calls this proc
|
||||
/proc/__to_chat(var/target, var/message)
|
||||
// First do logging in database
|
||||
if(isclient(target))
|
||||
var/client/C = target
|
||||
vchat_add_message(C.ckey,message)
|
||||
else if(ismob(target))
|
||||
var/mob/M = target
|
||||
if(M.ckey)
|
||||
vchat_add_message(M.ckey,message)
|
||||
|
||||
// Now lets either queue it for sending, or send it right now
|
||||
if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.subsystem_initialized)
|
||||
to_chat_immediate(target, world.time, message)
|
||||
else
|
||||
SSchat.queue(target, world.time, message)
|
||||
|
||||
//This is used to convert icons to base64 <image> strings, because byond stores icons in base64 in savefiles.
|
||||
GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of icons for the browser output
|
||||
|
||||
//The main object attached to clients, created when they connect, and has start() called on it in client/New()
|
||||
/datum/chatOutput
|
||||
var/client/owner = null
|
||||
var/loaded = FALSE
|
||||
var/list/message_queue = list()
|
||||
var/broken = FALSE
|
||||
var/resources_sent = FALSE
|
||||
|
||||
var/last_topic_time = 0
|
||||
var/too_many_topics = 0
|
||||
var/topic_spam_limit = 10 //Just enough to get over the startup and such
|
||||
|
||||
/datum/chatOutput/New(client/C)
|
||||
. = ..()
|
||||
|
||||
owner = C
|
||||
update_vis()
|
||||
|
||||
/datum/chatOutput/Destroy()
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/datum/chatOutput/proc/update_vis()
|
||||
if(!loaded && !broken)
|
||||
winset(owner, null, "outputwindow.htmloutput.is-visible=false;outputwindow.oldoutput.is-visible=false;outputwindow.chatloadlabel.is-visible=true")
|
||||
else if(broken)
|
||||
winset(owner, null, "outputwindow.htmloutput.is-visible=false;outputwindow.oldoutput.is-visible=true;outputwindow.chatloadlabel.is-visible=false")
|
||||
else if(loaded)
|
||||
return //It can do it's own winsets from inside the JS if it's working.
|
||||
|
||||
//Shove all the assets at them
|
||||
/datum/chatOutput/proc/send_resources()
|
||||
for(var/filename in GLOB.vchatFiles)
|
||||
owner << browse_rsc(file(filename))
|
||||
resources_sent = TRUE
|
||||
|
||||
//Called from client/New() in a spawn()
|
||||
/datum/chatOutput/proc/start()
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
if(!winexists(owner, "htmloutput"))
|
||||
spawn()
|
||||
alert(owner, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.")
|
||||
become_broken()
|
||||
return FALSE
|
||||
|
||||
if(!owner) // In case the client vanishes before winexists returns
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
if(!resources_sent)
|
||||
send_resources()
|
||||
|
||||
load()
|
||||
|
||||
return TRUE
|
||||
|
||||
//Attempts to actually load the HTML page into the client's UI
|
||||
/datum/chatOutput/proc/load()
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
owner << browse(file2text("code/modules/vchat/html/vchat.html"), "window=htmloutput")
|
||||
|
||||
//Check back later
|
||||
spawn(15 SECONDS)
|
||||
if(!src)
|
||||
return
|
||||
if(!src.loaded)
|
||||
src.become_broken()
|
||||
|
||||
//var/list/joins = list() //Just for testing with the below
|
||||
//Called by Topic, when the JS in the HTML page finishes loading
|
||||
/datum/chatOutput/proc/done_loading()
|
||||
if(loaded)
|
||||
return
|
||||
|
||||
loaded = TRUE
|
||||
broken = FALSE
|
||||
owner.chatOutputLoadedAt = world.time
|
||||
|
||||
//update_vis() //It does it's own winsets
|
||||
|
||||
send_playerinfo()
|
||||
load_database()
|
||||
|
||||
//Perform DB shenanigans
|
||||
/datum/chatOutput/proc/load_database()
|
||||
set waitfor = FALSE
|
||||
var/list/results = vchat_get_messages(owner.ckey, world.time - BACKLOG_LENGTH)
|
||||
for(var/list/message in results)
|
||||
to_chat_immediate(owner, message["time"], message["message"])
|
||||
CHECK_TICK
|
||||
|
||||
//It din work
|
||||
/datum/chatOutput/proc/become_broken()
|
||||
broken = TRUE
|
||||
loaded = FALSE
|
||||
|
||||
update_vis()
|
||||
|
||||
spawn()
|
||||
alert(owner,"VChat didn't load after some time. Switching to use oldchat as a fallback. Try using 'Reload VChat' verb in OOC verbs, or reconnecting to try again.")
|
||||
|
||||
//Provide the JS with who we are
|
||||
/datum/chatOutput/proc/send_playerinfo()
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/list/playerinfo = list("evttype" = "byond_player", "cid" = owner.computer_id, "ckey" = owner.ckey, "address" = owner.address, "admin" = owner.holder ? "true" : "false")
|
||||
send_event(playerinfo)
|
||||
|
||||
//Ugh byond doesn't handle UTF-8 well so we have to do this.
|
||||
/proc/jsEncode(var/list/message) {
|
||||
if(!islist(message))
|
||||
CRASH("Passed a non-list to encode.")
|
||||
return; //Necessary?
|
||||
|
||||
return url_encode(url_encode(json_encode(message)))
|
||||
}
|
||||
|
||||
//Send a side-channel event to the chat window
|
||||
/datum/chatOutput/proc/send_event(var/event, var/client/C = owner)
|
||||
C << output(jsEncode(event), "htmloutput:get_event")
|
||||
|
||||
//Just produces a message for using in keepalives from the server to the client
|
||||
/datum/chatOutput/proc/keepalive()
|
||||
return list("evttype" = "keepalive_server")
|
||||
|
||||
//Redirected from client/Topic when the user clicks a link that pertains directly to the chat (when src == "chat")
|
||||
/datum/chatOutput/Topic(var/href, var/list/href_list)
|
||||
if(usr.client != owner)
|
||||
return 1
|
||||
|
||||
if(last_topic_time > (world.time - 3 SECONDS))
|
||||
too_many_topics++
|
||||
if(too_many_topics >= topic_spam_limit)
|
||||
log_and_message_admins("Kicking [key_name(owner)] - VChat Topic() spam")
|
||||
to_chat(owner,"<span class='danger'>You have been kicked due to VChat sending too many messages to the server. Try reconnecting.</span>")
|
||||
qdel(owner)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
too_many_topics = 0
|
||||
last_topic_time = world.time
|
||||
|
||||
var/list/params = list()
|
||||
for(var/key in href_list)
|
||||
if(length(key) > 7 && findtext(key, "param"))
|
||||
var/param_name = copytext(key, 7, -1)
|
||||
var/item = href_list[key]
|
||||
params[param_name] = item
|
||||
|
||||
var/data
|
||||
switch(href_list["proc"])
|
||||
if("not_ready")
|
||||
CRASH("Tried to send a message to [owner.ckey] chatOutput before it was ready!")
|
||||
if("done_loading")
|
||||
data = done_loading(arglist(params))
|
||||
if("keepalive_client")
|
||||
data = keepalive(arglist(params))
|
||||
if("ident")
|
||||
data = bancheck(arglist(params))
|
||||
if("unloading")
|
||||
loaded = FALSE
|
||||
if("debug")
|
||||
data = debugmsg(arglist(params))
|
||||
|
||||
if(data)
|
||||
send_event(event = data)
|
||||
|
||||
//Print a message that was an error from a client
|
||||
/datum/chatOutput/proc/debugmsg(var/message = "No String Provided")
|
||||
log_debug("VChat: [owner] got: [message]")
|
||||
|
||||
//Check relevant client info reported from JS
|
||||
/datum/chatOutput/proc/bancheck(var/clientdata)
|
||||
var/list/info = json_decode(clientdata)
|
||||
var/ckey = info["ckey"]
|
||||
var/ip = info["ip"]
|
||||
var/cid = info["cid"]
|
||||
|
||||
//Never connected? How sad!
|
||||
if(!cid && !ip && !ckey)
|
||||
return
|
||||
|
||||
var/list/ban = world.IsBanned(key = ckey, address = ip, computer_id = cid)
|
||||
if(ban)
|
||||
log_and_message_admins("[key_name(owner)] has a cookie from a banned account! (Cookie: [ckey], [ip], [cid])")
|
||||
|
||||
//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(var/icon/icon, var/iconKey = "misc")
|
||||
if (!isicon(icon)) return FALSE
|
||||
|
||||
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(var/obj, var/use_class = 1, var/custom_classes = "")
|
||||
var/class = use_class ? "class='icon misc [custom_classes]'" : null
|
||||
if (!obj)
|
||||
return
|
||||
|
||||
var/static/list/bicon_cache = list()
|
||||
if (isicon(obj))
|
||||
if (!bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it.
|
||||
bicon_cache["\ref[obj]"] = icon2base64(obj)
|
||||
|
||||
return "<img [class] src='data:image/png;base64,[bicon_cache["\ref[obj]"]]'>"
|
||||
|
||||
// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
|
||||
var/atom/A = obj
|
||||
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(obj))
|
||||
I = getFlatIcon(obj) //Ugly
|
||||
bicon_cache[key] = icon2base64(I, key)
|
||||
if(use_class)
|
||||
class = "class='icon [A.icon_state] [custom_classes]'"
|
||||
|
||||
return "<img [class] src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
//Checks if the message content is a valid to_chat message
|
||||
/proc/is_valid_tochat_message(message)
|
||||
return istext(message)
|
||||
|
||||
//Checks if the target of to_chat is something we can send to
|
||||
/proc/is_valid_tochat_target(target)
|
||||
return !istype(target, /savefile) && (ismob(target) || islist(target) || isclient(target) || target == world)
|
||||
|
||||
var/to_chat_filename
|
||||
var/to_chat_line
|
||||
var/to_chat_src
|
||||
|
||||
//This proc is only really used if the SSchat subsystem is unavailable (not started yet)
|
||||
/proc/to_chat_immediate(target, time, message)
|
||||
if(!is_valid_tochat_message(message) || !is_valid_tochat_target(target))
|
||||
target << message
|
||||
|
||||
// Info about the "message"
|
||||
if(isnull(message))
|
||||
message = "(null)"
|
||||
else if(istype(message, /datum))
|
||||
var/datum/D = message
|
||||
message = "([D.type]): '[D]'"
|
||||
else if(!is_valid_tochat_message(message))
|
||||
message = "(bad message) : '[message]'"
|
||||
|
||||
// Info about the target
|
||||
var/targetstring = "'[target]'"
|
||||
if(istype(target, /datum))
|
||||
var/datum/D = target
|
||||
targetstring += ", [D.type]"
|
||||
|
||||
// The final output
|
||||
log_debug("to_chat called with invalid message/target: [to_chat_filename], [to_chat_line], [to_chat_src], Message: '[message]', Target: [targetstring]")
|
||||
return
|
||||
|
||||
else if(is_valid_tochat_message(message))
|
||||
if(istext(target))
|
||||
log_debug("Somehow, to_chat got a text as a target")
|
||||
return
|
||||
|
||||
var/original_message = message
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
|
||||
if(isnull(time))
|
||||
time = world.time
|
||||
|
||||
var/client/C = CLIENT_FROM_VAR(target)
|
||||
if(C && C.chatOutput)
|
||||
if(C.chatOutput.broken)
|
||||
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] = list("time" = time, "message" = message)
|
||||
// return
|
||||
|
||||
var/list/tojson = list("time" = time, "message" = message);
|
||||
target << output(jsEncode(tojson), "htmloutput:putmessage")
|
||||
|
||||
#undef BACKLOG_LENGTH
|
||||
@@ -0,0 +1,122 @@
|
||||
#define VCHAT_FILENAME "data/vchat.db"
|
||||
GLOBAL_DATUM(vchatdb, /database)
|
||||
|
||||
//Boot up db file
|
||||
/proc/init_vchat()
|
||||
//Cleanup previous if exists
|
||||
fdel(VCHAT_FILENAME)
|
||||
fdel(VCHAT_FILENAME+"-shm") //Shared memory, and
|
||||
fdel(VCHAT_FILENAME+"-wal") // write ahead. Only present on unclean stop.
|
||||
|
||||
//Create a new one
|
||||
GLOB.vchatdb = new(VCHAT_FILENAME)
|
||||
|
||||
//Build our basic boring tables
|
||||
vchat_create_tables()
|
||||
|
||||
//Check to see if it's init
|
||||
/proc/check_vchat()
|
||||
if(istype(GLOB.vchatdb))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
//For INSERT/CREATE/DELETE, etc that return a RowsAffected.
|
||||
/proc/vchat_exec_update(var/query)
|
||||
if(!check_vchat())
|
||||
log_debug("There's no vchat database open but you tried to query it with: [query]")
|
||||
return FALSE
|
||||
|
||||
//Solidify our query
|
||||
var/database/query/q = vchat_build_query(query)
|
||||
|
||||
//Run it
|
||||
q.Execute(GLOB.vchatdb)
|
||||
|
||||
//Handle errors
|
||||
if(q.Error())
|
||||
log_debug("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
return FALSE
|
||||
|
||||
return q.RowsAffected()
|
||||
|
||||
//For SELECT, that return results.
|
||||
/proc/vchat_exec_query(var/query)
|
||||
if(!check_vchat())
|
||||
log_debug("There's no vchat database open but you tried to query it!")
|
||||
return FALSE
|
||||
|
||||
//Solidify our query
|
||||
var/database/query/q = vchat_build_query(query)
|
||||
|
||||
//Run it
|
||||
q.Execute(GLOB.vchatdb)
|
||||
|
||||
//Handle errors
|
||||
if(q.Error())
|
||||
log_debug("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
return FALSE
|
||||
|
||||
//Return any results
|
||||
var/list/results = list()
|
||||
//Return results if any.
|
||||
while(q.NextRow())
|
||||
results[++results.len] = q.GetRowData()
|
||||
|
||||
return results
|
||||
|
||||
//Create a query from string or list with params
|
||||
/proc/vchat_build_query(var/query)
|
||||
var/database/query/q
|
||||
|
||||
if(islist(query))
|
||||
q = new(arglist(query))
|
||||
else
|
||||
q = new(query)
|
||||
|
||||
if(!istype(q))
|
||||
return
|
||||
|
||||
return q
|
||||
|
||||
/proc/vchat_create_tables()
|
||||
//Byond is so great half the time it doesn't delete the file
|
||||
var/cleanup = "DROP TABLE IF EXISTS messages"
|
||||
vchat_exec_update(cleanup)
|
||||
cleanup = "VACUUM"
|
||||
vchat_exec_update(cleanup)
|
||||
|
||||
//Messages table
|
||||
var/tabledef = "CREATE TABLE messages(\
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
ckey VARCHAR(50) NOT NULL,\
|
||||
worldtime INTEGER NOT NULL,\
|
||||
message TEXT NOT NULL)"
|
||||
vchat_exec_update(tabledef)
|
||||
|
||||
//Index on ckey
|
||||
var/indexdef = "CREATE INDEX ckey_index ON messages (ckey)"
|
||||
vchat_exec_update(indexdef)
|
||||
|
||||
//INSERT a new message
|
||||
/proc/vchat_add_message(var/ckey, var/message)
|
||||
if(!ckey || !message)
|
||||
return
|
||||
var/list/messagedef = list(
|
||||
"INSERT INTO messages (ckey,worldtime,message) VALUES (?, ?, ?)",
|
||||
ckey,
|
||||
world.time,
|
||||
message)
|
||||
|
||||
return vchat_exec_update(messagedef)
|
||||
|
||||
//Get a player's message history
|
||||
/proc/vchat_get_messages(var/ckey, var/oldest = 0)
|
||||
if(!ckey)
|
||||
return
|
||||
|
||||
var/list/getdef = list("SELECT * FROM messages WHERE ckey = ? AND worldtime >= ?", ckey, oldest)
|
||||
|
||||
return vchat_exec_query(getdef)
|
||||
|
||||
#undef VCHAT_FILENAME
|
||||
@@ -17,4 +17,4 @@
|
||||
I.loc = src.loc
|
||||
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\icon[src] <font color='blue'>The [src.name] beeps.</font>", 2)
|
||||
O.show_message("[bicon(src)] <font color='blue'>The [src.name] beeps.</font>", 2)
|
||||
@@ -30,7 +30,7 @@
|
||||
report("Antibodies detected: [antigens2string(C.antibodies)]", user)
|
||||
|
||||
/obj/item/device/antibody_scanner/proc/report(var/text, mob/user as mob)
|
||||
to_chat(user, "<font color='blue'>\icon[src] \The [src] beeps,</font> \"<font color='blue'>[text]</font>\"")
|
||||
to_chat(user, "<font color='blue'>[bicon(src)] \The [src] beeps,</font> \"<font color='blue'>[text]</font>\"")
|
||||
|
||||
///////////////VIRUS DISH///////////////
|
||||
|
||||
|
||||
@@ -46,17 +46,17 @@
|
||||
if(!previous_power_state)
|
||||
previous_power_state = 1
|
||||
icon_state = "cellold1"
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] suddenly comes to life!</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] suddenly comes to life!</span>")
|
||||
|
||||
//slowly grow a mob
|
||||
if(prob(5))
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].</span>")
|
||||
|
||||
//if we've finished growing...
|
||||
if(time_spent_spawning >= time_per_spawn)
|
||||
time_spent_spawning = 0
|
||||
use_power = 1
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] pings!</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] pings!</span>")
|
||||
icon_state = "cellold1"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
|
||||
if(spawn_type)
|
||||
@@ -77,7 +77,7 @@
|
||||
if(previous_power_state)
|
||||
previous_power_state = 0
|
||||
icon_state = "cellold0"
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] suddenly shuts down.</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] suddenly shuts down.</span>")
|
||||
|
||||
//cloned mob slowly breaks down
|
||||
time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0)
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
viables.Remove(type)
|
||||
construction[button_desc] = type
|
||||
|
||||
fail_message = "<font color='blue'>\icon[src] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \
|
||||
fail_message = "<font color='blue'>[bicon(src)] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \
|
||||
[pick("horn","beep","bing","bleep","blat","honk","hrumph","ding")] sounds and a \
|
||||
[pick("yellow","purple","green","blue","red","orange","white")] \
|
||||
[pick("light","dial","meter","window","protrusion","knob","antenna","swirly thing")] \
|
||||
@@ -86,7 +86,7 @@
|
||||
if(spawning_types.len && powered())
|
||||
spawn_progress_time += world.time - last_process_time
|
||||
if(spawn_progress_time > max_spawn_time)
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] pings!</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] pings!</span>")
|
||||
|
||||
var/obj/source_material = pop(stored_materials)
|
||||
var/spawn_type = pop(spawning_types)
|
||||
@@ -109,7 +109,7 @@
|
||||
icon_state = "borgcharger0(old)"
|
||||
|
||||
else if(prob(5))
|
||||
src.visible_message("<span class='notice'>\icon[src] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].</span>")
|
||||
|
||||
last_process_time = world.time
|
||||
|
||||
@@ -140,9 +140,9 @@
|
||||
if(index > 0 && index <= construction.len)
|
||||
if(stored_materials.len > spawning_types.len)
|
||||
if(spawning_types.len)
|
||||
src.visible_message("<span class='notice'>\icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].</span>")
|
||||
else
|
||||
src.visible_message("<span class='notice'>\icon[src] [src]'s front compartment slides shut.</span>")
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src]'s front compartment slides shut.</span>")
|
||||
|
||||
spawning_types.Add(construction[construction[index]])
|
||||
spawn_progress_time = 0
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
var/atom/toplevelholder = holder
|
||||
while(!istype(toplevelholder.loc, /turf))
|
||||
toplevelholder = toplevelholder.loc
|
||||
toplevelholder.visible_message("<font color='red'>\icon[toplevelholder] [toplevelholder] [display_msg]</font>")
|
||||
toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")
|
||||
|
||||
/datum/artifact_effect/proc/DoEffectTouch(var/mob/user)
|
||||
/datum/artifact_effect/proc/DoEffectAura(var/atom/holder)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
..()
|
||||
else if(istype(W,/obj/item/weapon/pen))
|
||||
plaque_contents = sanitize(input("What would you like to write on the plaque:","Skeleton plaque",""))
|
||||
user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src] [src].")
|
||||
user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of [bicon(src)] [src].")
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
if(charges >= 0.1)
|
||||
if(prob(5))
|
||||
src.visible_message("<font color='red'>\icon[src] [src]'s eyes glow ruby red for a moment!</font>")
|
||||
src.visible_message("<font color='red'>[bicon(src)] [src]'s eyes glow ruby red for a moment!</font>")
|
||||
charges -= 0.1
|
||||
|
||||
//check on our shadow wights
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\
|
||||
"[holder_atom] seems to be focusing on [source]...",\
|
||||
"[holder_atom] seems to turn it's attention to [source]...")
|
||||
holder_atom.loc.visible_message("<font color='blue'>\icon[holder_atom] [pick(options)]</font>")
|
||||
holder_atom.loc.visible_message("<font color='blue'>[bicon(holder_atom)] [pick(options)]</font>")
|
||||
|
||||
if(prob(20))
|
||||
spawn(2)
|
||||
@@ -118,5 +118,5 @@
|
||||
listening|=M
|
||||
|
||||
for(var/mob/M in listening)
|
||||
to_chat(M, "\icon[holder_atom] <b>[holder_atom]</b> reverberates, \"<font color='blue'>[msg]</font>\"")
|
||||
to_chat(M, "[bicon(holder_atom)] <b>[holder_atom]</b> reverberates, \"<font color='blue'>[msg]</font>\"")
|
||||
last_talk_time = world.time
|
||||
|
||||
@@ -102,9 +102,9 @@
|
||||
if(interval > 0)
|
||||
//apply the touch effect to the holder
|
||||
if(holder)
|
||||
to_chat(holder, "the \icon[src] [src] held by [holder] shudders in your grasp.")
|
||||
to_chat(holder, "the [bicon(src)] [src] held by [holder] shudders in your grasp.")
|
||||
else
|
||||
src.loc.visible_message("the \icon[src] [src] shudders.")
|
||||
src.loc.visible_message("the [bicon(src)] [src] shudders.")
|
||||
inserted_battery.battery_effect.DoEffectTouch(holder)
|
||||
|
||||
//consume power
|
||||
@@ -130,13 +130,13 @@
|
||||
|
||||
//work out if we need to shutdown
|
||||
if(inserted_battery.stored_charge <= 0)
|
||||
src.loc.visible_message("<font color='blue'>\icon[src] [src] buzzes.</font>", "<font color='blue'>\icon[src] You hear something buzz.</font>")
|
||||
src.loc.visible_message("<font color='blue'>[bicon(src)] [src] buzzes.</font>", "<font color='blue'>[bicon(src)] You hear something buzz.</font>")
|
||||
shutdown_emission()
|
||||
else if(world.time > time_end)
|
||||
src.loc.visible_message("<font color='blue'>\icon[src] [src] chimes.</font>", "<font color='blue'>\icon[src] You hear something chime.</font>")
|
||||
src.loc.visible_message("<font color='blue'>[bicon(src)] [src] chimes.</font>", "<font color='blue'>[bicon(src)] You hear something chime.</font>")
|
||||
shutdown_emission()
|
||||
else
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] buzzes.</font>", "<font color='blue'>\icon[src] You hear something buzz.</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] buzzes.</font>", "<font color='blue'>[bicon(src)] You hear something buzz.</font>")
|
||||
shutdown_emission()
|
||||
last_process = world.time
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
if(href_list["startup"])
|
||||
if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0) )
|
||||
activated = 1
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] whirrs.</font>", "\icon[src]<font color='blue'>You hear something whirr.</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] whirrs.</font>", "[bicon(src)]<font color='blue'>You hear something whirr.</font>")
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
time_end = world.time + duration
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<br>"
|
||||
P.info += "\icon[scanned_object] [results]"
|
||||
P.info += "[bicon(scanned_object)] [results]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
|
||||
|
||||
@@ -234,16 +234,16 @@
|
||||
//emergency stop if seal integrity reaches 0
|
||||
if(scanner_seal_integrity <= 0 || (scanner_temperature >= 1273 && !rad_shield))
|
||||
stop_scanning()
|
||||
src.visible_message("<font color='blue'>\icon[src] buzzes unhappily. It has failed mid-scan!</font>", 2)
|
||||
src.visible_message("<font color='blue'>[bicon(src)] buzzes unhappily. It has failed mid-scan!</font>", 2)
|
||||
|
||||
if(prob(5))
|
||||
src.visible_message("<font color='blue'>\icon[src] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].</font>", 2)
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].</font>", 2)
|
||||
else
|
||||
//gradually cool down over time
|
||||
if(scanner_temperature > 0)
|
||||
scanner_temperature = max(scanner_temperature - 5 - 10 * rand(), 0)
|
||||
if(prob(0.75))
|
||||
src.visible_message("<font color='blue'>\icon[src] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].</font>", 2)
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].</font>", 2)
|
||||
playsound(loc, 'sound/effects/ding.ogg', 25)
|
||||
last_process_worldtime = world.time
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
used_coolant = 0
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/complete_scan()
|
||||
src.visible_message("<font color='blue'>\icon[src] makes an insistent chime.</font>", 2)
|
||||
src.visible_message("<font color='blue'>[bicon(src)] makes an insistent chime.</font>", 2)
|
||||
|
||||
if(scanned_item)
|
||||
//create report
|
||||
|
||||
@@ -182,10 +182,10 @@
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
M.weakened += 5
|
||||
M.visible_message("<font color='blue'>\icon[M] [M] begins to float in the air!</font>","You feel tingly and light, but it is difficult to move.")
|
||||
M.visible_message("<font color='blue'>[bicon(M)] [M] begins to float in the air!</font>","You feel tingly and light, but it is difficult to move.")
|
||||
|
||||
suspension_field = new(T)
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] activates with a low hum.</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] activates with a low hum.</font>")
|
||||
icon_state = "suspension3"
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
@@ -195,7 +195,7 @@
|
||||
if(collected)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
src.visible_message("<font color='blue'>\icon[suspension_field] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(suspension_field)] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].</font>")
|
||||
else
|
||||
if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall))
|
||||
suspension_field.icon_state = "shieldsparkles"
|
||||
@@ -210,7 +210,7 @@
|
||||
to_chat(M, "<span class='info'>You no longer feel like floating.</span>")
|
||||
M.weakened = min(M.weakened, 3)
|
||||
|
||||
src.visible_message("<font color='blue'>\icon[src] [src] deactivates with a gentle shudder.</font>")
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] deactivates with a gentle shudder.</font>")
|
||||
qdel(suspension_field)
|
||||
suspension_field = null
|
||||
icon_state = "suspension2"
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
positive_locations.Add(D)
|
||||
|
||||
to_chat(user, "<span class='notice'>\icon[src] [src] pings.</span>")
|
||||
to_chat(user, "<span class='notice'>[bicon(src)] [src] pings.</span>")
|
||||
|
||||
else if(istype(A, /obj/structure/boulder))
|
||||
var/obj/structure/boulder/B = A
|
||||
@@ -151,7 +151,7 @@
|
||||
|
||||
positive_locations.Add(D)
|
||||
|
||||
to_chat(user, "<span class='notice'>\icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!</span>")
|
||||
to_chat(user, "<span class='notice'>[bicon(src)] [src] pings [pick("madly","wildly","excitedly","crazily")]!</span>")
|
||||
|
||||
/obj/item/device/depth_scanner/attack_self(var/mob/living/user)
|
||||
interact(user)
|
||||
@@ -267,9 +267,9 @@
|
||||
scan_ticks = 0
|
||||
var/turf/T = get_turf(src)
|
||||
if(target_radio)
|
||||
T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] happily.")
|
||||
T.visible_message("[bicon(src)] [src] [pick("chirps","chirrups","cheeps")] happily.")
|
||||
else
|
||||
T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] sadly.")
|
||||
T.visible_message("[bicon(src)] [src] [pick("chirps","chirrups","cheeps")] sadly.")
|
||||
else
|
||||
icon_state = "pinoff"
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
var/obj/item/slime_extract/T = holder.my_atom
|
||||
T.uses--
|
||||
if(T.uses <= 0)
|
||||
T.visible_message("\icon[T]<span class='notice'>\The [T] goes inert.</span>")
|
||||
T.visible_message("[bicon(T)]<span class='notice'>\The [T] goes inert.</span>")
|
||||
T.name = "inert [initial(T.name)]"
|
||||
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
/obj/machinery/slime/extractor/proc/extract_cores()
|
||||
if(!src.occupant)
|
||||
src.visible_message("\icon[src] [src] pings unhappily.")
|
||||
src.visible_message("[bicon(src)] [src] pings unhappily.")
|
||||
else if(inuse)
|
||||
return
|
||||
|
||||
|
||||
@@ -102,15 +102,15 @@
|
||||
in_use = 0
|
||||
if(failed_task)
|
||||
failed_task = 0
|
||||
visible_message("\icon[src] [src] pings unhappily, flashing a red warning light.")
|
||||
visible_message("[bicon(src)] [src] pings unhappily, flashing a red warning light.")
|
||||
else
|
||||
visible_message("\icon[src] [src] pings happily.")
|
||||
visible_message("[bicon(src)] [src] pings happily.")
|
||||
|
||||
if(eject_disk)
|
||||
eject_disk = 0
|
||||
if(loaded_disk)
|
||||
loaded_disk.forceMove(get_turf(src))
|
||||
visible_message("\icon[src] [src] beeps and spits out [loaded_disk].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
|
||||
/obj/machinery/xenobio/extractor
|
||||
@@ -190,7 +190,7 @@
|
||||
/obj/machinery/xenobio/proc/eject_disk()
|
||||
if(!loaded_disk) return
|
||||
loaded_disk.forceMove(loc)
|
||||
visible_message("\icon[src] [src] beeps and spits out [loaded_disk].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
|
||||
/obj/machinery/xenobio/extractor/Topic(href, href_list)
|
||||
@@ -202,7 +202,7 @@
|
||||
if(!product) return
|
||||
|
||||
product.forceMove(get_turf(src))
|
||||
visible_message("\icon[src] [src] beeps and spits out [product].")
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [product].")
|
||||
product = null
|
||||
|
||||
if(href_list["eject_disk"])
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
/obj/machinery/slime/replicator/proc/replicate_slime()
|
||||
if(!src.core)
|
||||
src.visible_message("\icon[src] [src] pings unhappily.")
|
||||
src.visible_message("[bicon(src)] [src] pings unhappily.")
|
||||
else if(inuse)
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user