atom_say, working runechat checkpoint

a lot of work, ports from both vorestation and nebula
This commit is contained in:
nevimer
2021-05-26 07:15:08 -04:00
parent 0fa68bcc9d
commit 0fbbede014
9 changed files with 192 additions and 37 deletions
+49
View File
@@ -0,0 +1,49 @@
/proc/remove_images_from_clients(image/I, list/show_to)
for(var/client/C in show_to)
C.images -= I
qdel(I)
/proc/fade_out(image/I, list/show_to)
animate(I, alpha = 0, time = 0.5 SECONDS, easing = EASE_IN)
addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_images_from_clients, I, show_to), 0.5 SECONDS)
/proc/animate_speech_bubble(image/I, list/show_to, duration)
var/matrix/M = matrix()
M.Scale(0,0)
I.transform = M
I.alpha = 0
for(var/client/C in show_to)
C.images += I
animate(I, transform = 0, alpha = 255, time = 0.2 SECONDS, easing = EASE_IN)
addtimer(CALLBACK(GLOBAL_PROC, .proc/fade_out, I, show_to), (duration - 0.5 SECONDS))
/proc/animate_receive_damage(atom/A)
var/pixel_x_diff = rand(-2,2)
var/pixel_y_diff = rand(-2,2)
animate(A, pixel_x = A.pixel_x + pixel_x_diff, pixel_y = A.pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = initial(A.pixel_x), pixel_y = initial(A.pixel_y), time = 2)
/proc/animate_throw(atom/A)
var/ipx = A.pixel_x
var/ipy = A.pixel_y
var/mpx = 0
var/mpy = 0
if(A.dir & NORTH)
mpy += 3
else if(A.dir & SOUTH)
mpy -= 3
if(A.dir & EAST)
mpx += 3
else if(A.dir & WEST)
mpx -= 3
var/x = mpx + ipx
var/y = mpy + ipy
animate(A, pixel_x = x, pixel_y = y, time = 0.6, easing = EASE_OUT)
var/matrix/M = matrix(A.transform)
animate(transform = turn(A.transform, (mpx - mpy) * 4), time = 0.6, easing = EASE_OUT)
animate(pixel_x = ipx, pixel_y = ipy, time = 0.6, easing = EASE_IN)
animate(transform = M, time = 0.6, easing = EASE_IN)
+2
View File
@@ -25,3 +25,5 @@
#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id)
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
#define JOINTEXT(X) jointext(X, null)
+9 -2
View File
@@ -751,19 +751,26 @@
/atom/proc/is_incorporeal()
return FALSE
/atom/proc/atom_say(message)
/atom/proc/atom_say(message, var/datum/language/speaking = null)
if(!message)
return
var/italics = 0
var/list/speech_bubble_hearers = list()
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk_vr.dmi',src,"h[speech_bubble_test]")
speech_bubble.layer = layer
speech_bubble.plane = plane
for(var/mob/M in get_mobs_in_view(7, src))
M.show_message("<span class='game say'><span class='name'>[src]</span> [atom_say_verb], \"[message]\"</span>", 2, null, 1)
if(M.client)
speech_bubble_hearers += M.client
if(length(speech_bubble_hearers))
var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
INVOKE_ASYNC(GLOBAL_PROC, .proc/animate_speech_bubble, speech_bubble, speech_bubble_hearers , 30)
INVOKE_ASYNC(src, /atom/movable/proc/animate_chat, message, speaking, italics, speech_bubble_hearers, 30)
/atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
return
+70
View File
@@ -0,0 +1,70 @@
var/list/floating_chat_colors = list()
/atom/movable
var/list/stored_chat_text
/atom/movable/proc/animate_chat(message, var/datum/language/speaking = null, small, list/show_to, duration)
set waitfor = FALSE
// Get rid of any URL schemes that might cause BYOND to automatically wrap something in an anchor tag
var/static/regex/url_scheme = new(@"[A-Za-z][A-Za-z0-9+-\.]*:\/\/", "g")
message = replacetext(message, url_scheme, "")
var/static/regex/html_metachars = new(@"&[A-Za-z]{1,7};", "g")
message = replacetext(message, html_metachars, "")
var/style //additional style params for the message
var/fontsize = 6
if(small)
fontsize = 4
var/limit = 50
if(copytext_char(message, length_char(message) - 1) == "!!")
fontsize = 8
limit = 80
style += "font-weight: bold;"
if(length_char(message) > limit)
message = "[copytext_char(message, 1, limit)]..."
if(!floating_chat_colors[name])
floating_chat_colors[name] = get_random_colour(0,160,230)
style += "color: [floating_chat_colors[name]];"
// create 2 messages, one that appears if you know the language, and one that appears when you don't know the language
var/image/understood = generate_floating_text(src, capitalize(message), style, fontsize, duration, show_to)
var/image/gibberish = speaking ? generate_floating_text(src, speaking.scramble(message), style, fontsize, duration, show_to) : understood
for(var/client/C in show_to)
if(!C.mob.is_deaf())
if(C.mob.say_understands(null, speaking))
C.images += understood
else
C.images += gibberish
/proc/generate_floating_text(atom/movable/holder, message, style, size, duration, show_to)
var/image/I = image(null, holder)
I.plane = PLANE_PLAYER_HUD
I.layer = PLANE_PLAYER_HUD_ITEMS
I.alpha = 0
I.maptext_width = 80
I.maptext_height = 64
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
I.pixel_x = -round(I.maptext_width/2) + 16
//style = "font: 'Small Fonts'; -dm-text-outline: 1px black; font-size: [size]px; [style]"
I.maptext = "<center><span style=\"colour: white; font: 'Small Fonts'; -dm-text-outline: 1px black; font-size: 5px; font-weight: bold; \">[message]</span></center>"
animate(I, 1, alpha = 255, pixel_y = 16)
for(var/image/old in holder.stored_chat_text)
animate(old, 2, pixel_y = old.pixel_y + 8)
LAZYADD(holder.stored_chat_text, I)
addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_floating_text, holder, I), duration)
addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_images_from_clients, I, show_to), duration + 4)
return I
/proc/remove_floating_text(atom/movable/holder, image/I)
animate(I, 2, pixel_y = I.pixel_y + 10, alpha = 0)
LAZYREMOVE(holder.stored_chat_text, I)
+1
View File
@@ -230,6 +230,7 @@ proc/get_radio_key_from_channel(var/channel)
//Handle language-specific verbs and adverb setup if necessary
if(!whispering) //Just doing normal 'say' (for now, may change below)
verb = say_quote(message, speaking)
usr.say_overhead(message, speaking)
else if(whispering && speaking.whisper_verb) //Language has defined whisper verb
verb = speaking.whisper_verb
w_not_heard = "[verb] something"
+39 -26
View File
@@ -177,32 +177,7 @@ proc/getsensorlevel(A)
return zone
/proc/stars(n, pr)
if (pr == null)
pr = 25
if (pr < 0)
return null
else
if (pr >= 100)
return n
var/te = n
var/t = ""
n = length(n)
var/p = null
p = 1
var/intag = 0
while(p <= n)
var/char = copytext(te, p, p + 1)
if (char == "<") //let's try to not break tags
intag = !intag
if (intag || char == " " || prob(pr))
t = text("[][]", t, char)
else
t = text("[]*", t)
if (char == ">")
intag = !intag
p++
return t
proc/slur(phrase)
phrase = html_decode(phrase)
@@ -705,3 +680,41 @@ var/global/image/backplane
/mob/proc/can_see_reagents()
return stat == DEAD || issilicon(src) //Dead guys and silicons can always see reagents
/proc/stars(n, pr = 25, re_encode = 1)
if (pr < 0)
return null
else if (pr >= 100)
return n
var/intag = 0
var/block = list()
. = list()
for(var/i = 1, i <= length_char(n), i++)
var/char = copytext_char(n, i, i+1)
if(!intag && (char == "<"))
intag = 1
. += stars_no_html(JOINTEXT(block), pr, re_encode) //stars added here
block = list()
block += char
if(intag && (char == ">"))
intag = 0
. += block //We don't mess up html tags with stars
block = list()
. += (intag ? block : stars_no_html(JOINTEXT(block), pr, re_encode))
. = JOINTEXT(.)
//Ingnores the possibility of breaking tags.
/proc/stars_no_html(text, pr, re_encode)
text = html_decode(text) //We don't want to screw up escaped characters
. = list()
for(var/i = 1, i <= length_char(text), i++)
var/char = copytext_char(text, i, i+1)
if(char == " " || prob(pr))
. += char
else
. += "*"
. = JOINTEXT(.)
if(re_encode)
. = html_encode(.)
+12
View File
@@ -1,6 +1,18 @@
/mob/proc/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering = 0)
return
/mob/proc/say_overhead(var/message, var/datum/language/speaking = null)
var/list/speech_bubble_hearers = list()
var/italics = 0
for(var/mob/M in get_mobs_in_view(7, src))
if(M.client)
speech_bubble_hearers += M.client
if(length(speech_bubble_hearers))
var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
INVOKE_ASYNC(src, /atom/movable/proc/animate_chat, message, speaking, italics, speech_bubble_hearers, 30)
/mob/proc/whisper_wrapper()
var/message = input("","whisper (text)") as text|null
if(message)
+8 -9
View File
@@ -1,12 +1,11 @@
/proc/generate_speech_bubble(var/bubble_loc, var/speech_state, var/set_layer = FLOAT_LAYER)
var/image/I = image('icons/mob/talk_vr.dmi', bubble_loc, speech_state, set_layer) //VOREStation Edit - talk_vr.dmi instead of talk.dmi for right-side icons
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE) //VOREStation Edit
if(istype(bubble_loc, /atom/movable))
var/atom/movable/AM = bubble_loc
var/x_scale = AM.get_icon_scale_x()
if(abs(x_scale) < 2) // reset transform on bubbles, except for the Very Large
I.pixel_z = (AM.icon_expected_height * (x_scale-1))
I.appearance_flags |= RESET_TRANSFORM
/proc/generate_speech_bubble(var/bubble_loc, var/speech_state, var/set_layer = FLOAT_LAYER, list/show_to)
var/image/I = image('icons/mob/talk_vr.dmi') //VOREStation Edit - talk_vr.dmi instead of talk.dmi for right-side icons
var/list/speech_bubble_hearers = list()
for(var/mob/M in get_mobs_in_view(7, src))
if(M.client)
speech_bubble_hearers += M.client
INVOKE_ASYNC(GLOBAL_PROC, .proc/animate_speech_bubble, I, speech_bubble_hearers , 30)
return I
+2
View File
@@ -112,6 +112,7 @@
#include "code\__HELPERS\_global_objects.dm"
#include "code\__HELPERS\_lists_tg.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\animations.dm"
#include "code\__HELPERS\areas.dm"
#include "code\__HELPERS\atmospherics.dm"
#include "code\__HELPERS\atom_movables.dm"
@@ -2206,6 +2207,7 @@
#include "code\modules\mob\animations.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\emote.dm"
#include "code\modules\mob\floating_message.dm"
#include "code\modules\mob\gender.dm"
#include "code\modules\mob\hear_say.dm"
#include "code\modules\mob\holder.dm"