mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-30 15:38:02 +01:00
Suggested changes, small opts
This commit is contained in:
@@ -124,6 +124,7 @@ What is the naming convention for planes or layers?
|
||||
#define PLANE_PLANETLIGHTING 4 //Lighting on planets
|
||||
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
|
||||
#define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness
|
||||
#define PLANE_RUNECHAT 7
|
||||
|
||||
#define PLANE_GHOSTS 10 //Spooooooooky ghooooooosts
|
||||
#define PLANE_AI_EYE 11 //The AI eye lives here
|
||||
|
||||
@@ -1691,19 +1691,3 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||
return "CLIENT: [D]"
|
||||
else
|
||||
return "Unknown data type: [D]"
|
||||
|
||||
/*
|
||||
is_holder_of(): Returns 1 if A is a holder of B, meaning, A is B.loc or B.loc.loc or B.loc.loc.loc etc.
|
||||
This is essentially the same as calling (locate(B) in A), but a little clearer as to what you're doing, and locate() has been known to bug out or be extremely slow in the past.
|
||||
*/
|
||||
/proc/is_holder_of(const/atom/movable/A, const/atom/movable/B)
|
||||
if(istype(A, /turf) || istype(B, /turf)) //Clicking on turfs is a common thing and turfs are also not /atom/movable, so it was causing the assertion to fail.
|
||||
return 0
|
||||
ASSERT(istype(A) && istype(B))
|
||||
var/atom/O = B
|
||||
while(O && !isturf(O))
|
||||
if(O == A)
|
||||
return 1
|
||||
O = O.loc
|
||||
return 0
|
||||
|
||||
+70
-39
@@ -14,6 +14,9 @@
|
||||
#define CHAT_MESSAGE_OBJ 2
|
||||
#define WXH_TO_HEIGHT(x) text2num(copytext((x), findtextEx((x), "x") + 1)) // thanks lummox
|
||||
|
||||
#define CHAT_RUNE_EMOTE 0x1
|
||||
#define CHAT_RUNE_RADIO 0x2
|
||||
|
||||
/**
|
||||
* # Chat Message Overlay
|
||||
*
|
||||
@@ -22,7 +25,17 @@
|
||||
*/
|
||||
|
||||
// Cached runechat icon
|
||||
var/runechat_icon = null
|
||||
var/list/runechat_image_cache = list()
|
||||
|
||||
|
||||
/hook/startup/proc/runechat_images()
|
||||
var/image/radio_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio")
|
||||
runechat_image_cache["radio"] = radio_image
|
||||
|
||||
var/image/emote_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "emote")
|
||||
runechat_image_cache["emote"] = emote_image
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/chatmessage
|
||||
/// The visual element of the chat messsage
|
||||
@@ -35,6 +48,8 @@ var/runechat_icon = null
|
||||
var/scheduled_destruction
|
||||
/// Contains the approximate amount of lines for height decay
|
||||
var/approx_lines
|
||||
/// If we are currently processing animation and cleanup at EOL
|
||||
var/ending_life
|
||||
|
||||
/**
|
||||
* Constructs a chat message overlay
|
||||
@@ -48,7 +63,7 @@ var/runechat_icon = null
|
||||
*/
|
||||
/datum/chatmessage/New(text, atom/target, mob/owner, list/extra_classes = null, lifespan = CHAT_MESSAGE_LIFESPAN)
|
||||
. = ..()
|
||||
if (!istype(target))
|
||||
if(!istype(target))
|
||||
CRASH("Invalid target given for chatmessage")
|
||||
if(!istype(owner) || QDELETED(owner) || !owner.client)
|
||||
stack_trace("/datum/chatmessage created with [isnull(owner) ? "null" : "invalid"] mob owner")
|
||||
@@ -57,10 +72,12 @@ var/runechat_icon = null
|
||||
generate_image(text, target, owner, extra_classes, lifespan)
|
||||
|
||||
/datum/chatmessage/Destroy()
|
||||
if (owned_by)
|
||||
owned_by.seen_messages.Remove(src)
|
||||
if(owned_by)
|
||||
LAZYREMOVEASSOC(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images.Remove(message)
|
||||
UnregisterSignal(owned_by, COMSIG_PARENT_QDELETING)
|
||||
if(message_loc)
|
||||
UnregisterSignal(message_loc, COMSIG_PARENT_QDELETING)
|
||||
owned_by = null
|
||||
message_loc = null
|
||||
message = null
|
||||
@@ -78,20 +95,21 @@ var/runechat_icon = null
|
||||
*/
|
||||
/datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, list/extra_classes, lifespan)
|
||||
set waitfor = FALSE
|
||||
|
||||
// Register client who owns this message
|
||||
owned_by = owner.client
|
||||
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
|
||||
var/erp_king = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
|
||||
var/maxlen = erp_king ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
|
||||
var/msgwidth = erp_king ? CHAT_MESSAGE_EXT_WIDTH : CHAT_MESSAGE_WIDTH
|
||||
var/extra_length = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
|
||||
var/maxlen = extra_length ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
|
||||
var/msgwidth = extra_length ? CHAT_MESSAGE_EXT_WIDTH : CHAT_MESSAGE_WIDTH
|
||||
|
||||
// Clip message
|
||||
if (length_char(text) > maxlen)
|
||||
if(length_char(text) > maxlen)
|
||||
text = copytext_char(text, 1, maxlen + 1) + "..." // BYOND index moment
|
||||
|
||||
// Calculate target color if not already present
|
||||
if (!target.chat_color || target.chat_color_name != target.name)
|
||||
if(!target.chat_color || target.chat_color_name != target.name)
|
||||
target.chat_color = colorize_string(target.name)
|
||||
target.chat_color_darkened = colorize_string(target.name, 0.85, 0.85)
|
||||
target.chat_color_name = target.name
|
||||
@@ -102,56 +120,68 @@ var/runechat_icon = null
|
||||
|
||||
// Reject whitespace
|
||||
var/static/regex/whitespace = new(@"^\s*$")
|
||||
if (whitespace.Find(text))
|
||||
if(whitespace.Find(text))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Non mobs speakers can be small
|
||||
if (!ismob(target))
|
||||
if(!ismob(target))
|
||||
extra_classes |= "small"
|
||||
|
||||
// If we heard our name, it's important
|
||||
// Differnt from our own system of name emphasis, maybe unify
|
||||
var/list/names = splittext(owner.name, " ")
|
||||
for (var/word in names)
|
||||
text = replacetext(text, word, "<b>[word]</b>")
|
||||
|
||||
// Append radio icon if comes from a radio
|
||||
if (extra_classes.Find("spoken_into_radio"))
|
||||
if (!runechat_icon)
|
||||
var/image/r_icon = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio")
|
||||
runechat_icon = "\icon[r_icon] "
|
||||
text = runechat_icon + text
|
||||
var/list/prefixes
|
||||
|
||||
// Append prefixes
|
||||
if(extra_classes.Find("virtual-speaker"))
|
||||
LAZYADD(prefixes, "\icon[runechat_image_cache["radio"]]")
|
||||
if(extra_classes.Find("emote"))
|
||||
// Icon on both ends?
|
||||
//var/image/I = runechat_image_cache["emote"]
|
||||
//text = "\icon[I][text]\icon[I]"
|
||||
|
||||
// Icon on one end?
|
||||
//LAZYADD(prefixes, "\icon[runechat_image_cache["emote"]]")
|
||||
|
||||
// Asterisks instead?
|
||||
text = "* [text] *"
|
||||
|
||||
text = "[prefixes?.Join(" ")][text]"
|
||||
|
||||
// We dim italicized text to make it more distinguishable from regular text
|
||||
var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color
|
||||
|
||||
// Approximate text height
|
||||
// Note we have to replace HTML encoded metacharacters otherwise MeasureText will return a zero height
|
||||
// BYOND Bug #2563917
|
||||
// Construct text
|
||||
var/static/regex/html_metachars = new(@"&[A-Za-z]{1,7};", "g")
|
||||
var/complete_text = "<span class='center maptext [extra_classes != null ? extra_classes.Join(" ") : ""]' style='color: [tgt_color];'>[text]</span>"
|
||||
var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(replacetext(complete_text, html_metachars, "m"), null, msgwidth))
|
||||
var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, msgwidth))
|
||||
approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT)
|
||||
|
||||
// Translate any existing messages upwards, apply exponential decay factors to timers
|
||||
message_loc = target
|
||||
if (owned_by.seen_messages)
|
||||
RegisterSignal(message_loc, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
if(owned_by.seen_messages)
|
||||
var/idx = 1
|
||||
var/combined_height = approx_lines
|
||||
for(var/msg in owned_by.seen_messages)
|
||||
for(var/msg in owned_by.seen_messages[message_loc])
|
||||
var/datum/chatmessage/m = msg
|
||||
animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
combined_height += m.approx_lines
|
||||
var/sched_remaining = m.scheduled_destruction - world.time
|
||||
if (sched_remaining > CHAT_MESSAGE_SPAWN_TIME)
|
||||
var/remaining_time = (sched_remaining) * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height)
|
||||
m.scheduled_destruction = world.time + remaining_time
|
||||
spawn(remaining_time)
|
||||
m.end_of_life()
|
||||
|
||||
if(!m.ending_life) // Don't bother!
|
||||
var/sched_remaining = m.scheduled_destruction - world.time
|
||||
if(sched_remaining > CHAT_MESSAGE_SPAWN_TIME)
|
||||
var/remaining_time = (sched_remaining) * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height)
|
||||
m.scheduled_destruction = world.time + remaining_time
|
||||
spawn(remaining_time)
|
||||
m.end_of_life()
|
||||
|
||||
// Build message image
|
||||
message = image(loc = message_loc, layer = ABOVE_MOB_LAYER)
|
||||
message.plane = PLANE_LIGHTING_ABOVE
|
||||
message.plane = PLANE_RUNECHAT
|
||||
message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART
|
||||
message.alpha = 0
|
||||
message.pixel_y = owner.bound_height * 0.95
|
||||
@@ -160,11 +190,11 @@ var/runechat_icon = null
|
||||
message.maptext_x = (msgwidth - owner.bound_width) * -0.5
|
||||
message.maptext = complete_text
|
||||
|
||||
if (is_holder_of(owner, target)) // Special case, holding an atom speaking (pAI, recorder...)
|
||||
if(owner.contains(target)) // Special case, holding an atom speaking (pAI, recorder...)
|
||||
message.plane = PLANE_PLAYER_HUD_ABOVE
|
||||
|
||||
// View the message
|
||||
owned_by.seen_messages.Add(src)
|
||||
LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images += message
|
||||
animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
|
||||
@@ -177,8 +207,9 @@ var/runechat_icon = null
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
*/
|
||||
/datum/chatmessage/proc/end_of_life(fadetime = CHAT_MESSAGE_EOL_FADE)
|
||||
if (gc_destroyed)
|
||||
if(gc_destroyed || ending_life)
|
||||
return
|
||||
ending_life = TRUE
|
||||
animate(message, alpha = 0, time = fadetime, flags = ANIMATION_PARALLEL)
|
||||
spawn(fadetime)
|
||||
qdel(src)
|
||||
@@ -207,7 +238,7 @@ var/runechat_icon = null
|
||||
return
|
||||
|
||||
// Check for virtual speakers (aka hearing a message through a radio)
|
||||
if (existing_extra_classes.Find("radio"))
|
||||
if(existing_extra_classes.Find("radio"))
|
||||
return
|
||||
|
||||
/* Not currently necessary
|
||||
@@ -219,17 +250,17 @@ var/runechat_icon = null
|
||||
var/list/extra_classes = list()
|
||||
extra_classes += existing_extra_classes
|
||||
|
||||
if (italics)
|
||||
if(italics)
|
||||
extra_classes |= "italics"
|
||||
|
||||
if (client.is_preference_enabled(/datum/client_preference/runechat_border))
|
||||
if(client.is_preference_enabled(/datum/client_preference/runechat_border))
|
||||
extra_classes |= "black_outline"
|
||||
|
||||
var/dist = get_dist(src, speaker)
|
||||
switch (dist)
|
||||
if (4 to 5)
|
||||
if(4 to 5)
|
||||
extra_classes |= "small"
|
||||
if (5 to 16)
|
||||
if(5 to 16)
|
||||
extra_classes |= "very_small"
|
||||
|
||||
// Display visual above source
|
||||
|
||||
+2
-2
@@ -523,7 +523,7 @@
|
||||
if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane))
|
||||
M.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "* [runemessage || message] *", FALSE, list("emote"), audible = FALSE)
|
||||
M.create_chat_message(src, "[runemessage]", FALSE, list("emote"), audible = FALSE)
|
||||
else if(blind_message)
|
||||
M.show_message(blind_message, AUDIBLE_MESSAGE)
|
||||
|
||||
@@ -554,7 +554,7 @@
|
||||
var/msg = message
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "* [runemessage || message] *", FALSE, list("emote"))
|
||||
M.create_chat_message(src, "[runemessage || message]", FALSE, list("emote"))
|
||||
|
||||
/atom/movable/proc/dropInto(var/atom/destination)
|
||||
while(istype(destination))
|
||||
|
||||
@@ -78,4 +78,4 @@
|
||||
var/connection_timeofday
|
||||
|
||||
// Runechat messages
|
||||
var/list/seen_messages = list()
|
||||
var/list/seen_messages
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
if(isobserver(M))
|
||||
message = "<span class='emote'><B>[src]</B> ([ghost_follow_link(src, M)]) [input]</span>"
|
||||
M.show_message(message, m_type)
|
||||
M.create_chat_message(src, "* [runemessage] *", FALSE, list("emote"), (m_type == AUDIBLE_MESSAGE))
|
||||
M.create_chat_message(src, "[runemessage]", FALSE, list("emote"), (m_type == AUDIBLE_MESSAGE))
|
||||
|
||||
for(var/obj in o_viewers)
|
||||
var/obj/O = obj
|
||||
|
||||
@@ -1,57 +1,62 @@
|
||||
var/list/department_radio_keys = list(
|
||||
":r" = "right ear", ".r" = "right ear",
|
||||
":l" = "left ear", ".l" = "left ear",
|
||||
":i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", ".h" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", ".e" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":s" = "Security", ".s" = "Security",
|
||||
":w" = "whisper", ".w" = "whisper",
|
||||
":t" = "Mercenary", ".t" = "Mercenary",
|
||||
":x" = "Raider", ".x" = "Raider",
|
||||
":u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", ".v" = "Service",
|
||||
":p" = "AI Private", ".p" = "AI Private",
|
||||
":y" = "Explorer", ".y" = "Explorer",
|
||||
":a" = "Talon", ".a" = "Talon", //VOREStation Add,
|
||||
":r" = "right ear", ".r" = "right ear",
|
||||
":l" = "left ear", ".l" = "left ear",
|
||||
":i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", ".h" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", ".e" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":s" = "Security", ".s" = "Security",
|
||||
":w" = "whisper", ".w" = "whisper",
|
||||
":t" = "Mercenary", ".t" = "Mercenary",
|
||||
":x" = "Raider", ".x" = "Raider",
|
||||
":u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", ".v" = "Service",
|
||||
":p" = "AI Private", ".p" = "AI Private",
|
||||
":y" = "Explorer", ".y" = "Explorer",
|
||||
":a" = "Talon", ".a" = "Talon", //VOREStation Add,
|
||||
|
||||
":R" = "right ear", ".R" = "right ear",
|
||||
":L" = "left ear", ".L" = "left ear",
|
||||
":I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", ".H" = "department",
|
||||
":C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", ".E" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":S" = "Security", ".S" = "Security",
|
||||
":W" = "whisper", ".W" = "whisper",
|
||||
":T" = "Mercenary", ".T" = "Mercenary",
|
||||
":X" = "Raider", ".X" = "Raider",
|
||||
":U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", ".V" = "Service",
|
||||
":P" = "AI Private", ".P" = "AI Private",
|
||||
":Y" = "Explorer", ".Y" = "Explorer",
|
||||
":A" = "Talon", ".A" = "Talon", //VOREStation Add,
|
||||
":R" = "right ear", ".R" = "right ear",
|
||||
":L" = "left ear", ".L" = "left ear",
|
||||
":I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", ".H" = "department",
|
||||
":C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", ".E" = "Engineering",
|
||||
":k" = "Response Team", ".k" = "Response Team",
|
||||
":S" = "Security", ".S" = "Security",
|
||||
":W" = "whisper", ".W" = "whisper",
|
||||
":T" = "Mercenary", ".T" = "Mercenary",
|
||||
":X" = "Raider", ".X" = "Raider",
|
||||
":U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", ".V" = "Service",
|
||||
":P" = "AI Private", ".P" = "AI Private",
|
||||
":Y" = "Explorer", ".Y" = "Explorer",
|
||||
":A" = "Talon", ".A" = "Talon", //VOREStation Add,
|
||||
|
||||
//kinda localization -- rastaf0
|
||||
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
|
||||
":�" = "right ear", ".�" = "right ear",
|
||||
":�" = "left ear", ".�" = "left ear",
|
||||
":�" = "intercom", ".�" = "intercom",
|
||||
":�" = "department", ".�" = "department",
|
||||
":�" = "Command", ".�" = "Command",
|
||||
":�" = "Science", ".�" = "Science",
|
||||
":�" = "Medical", ".�" = "Medical",
|
||||
":�" = "Engineering", ".�" = "Engineering",
|
||||
":�" = "Security", ".�" = "Security",
|
||||
":�" = "whisper", ".�" = "whisper",
|
||||
":�" = "Mercenary", ".�" = "Mercenary",
|
||||
":�" = "Supply", ".�" = "Supply",
|
||||
// Cyrillic characters on the same keys on the Russian QWERTY (phonetic) layout
|
||||
":к" = "right ear", ".к" = "right ear",
|
||||
":д" = "left ear", ".д" = "left ear",
|
||||
":ш" = "intercom", ".ш" = "intercom",
|
||||
":р" = "department", ".р" = "department",
|
||||
":+" = "special", ".+" = "special", //activate radio-specific special functions
|
||||
":с" = "Command", ".с" = "Command",
|
||||
":т" = "Science", ".т" = "Science",
|
||||
":ь" = "Medical", ".ь" = "Medical",
|
||||
":у" = "Engineering", ".у" = "Engineering",
|
||||
":л" = "Response Team", ".л" = "Response Team",
|
||||
":ы" = "Security", ".ы" = "Security",
|
||||
":ц" = "whisper", ".ц" = "whisper",
|
||||
":е" = "Mercenary", ".е" = "Mercenary",
|
||||
":ч" = "Raider", ".ч" = "Raider",
|
||||
":г" = "Supply", ".г" = "Supply",
|
||||
":м" = "Service", ".м" = "Service",
|
||||
":з" = "AI Private", ".з" = "AI Private",
|
||||
":н" = "Explorer", ".н" = "Explorer"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
msg = self_message
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "* [runemessage || message] *", FALSE, list("emote"), audible = FALSE)
|
||||
M.create_chat_message(src, "[runemessage || message]", FALSE, list("emote"), audible = FALSE)
|
||||
|
||||
/mob/proc/findname(msg)
|
||||
for(var/mob/M in mob_list)
|
||||
|
||||
Reference in New Issue
Block a user