mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 03:27:46 +01:00
Saycode Overhaul -- Multilingualism
This commit is contained in:
@@ -1,63 +1,42 @@
|
||||
/mob/observer/dead/say(var/message)
|
||||
/mob/observer/dead/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
message = sanitize(message)
|
||||
|
||||
if (!message)
|
||||
return
|
||||
|
||||
log_ghostsay(message, src)
|
||||
|
||||
if (src.client)
|
||||
if(message)
|
||||
client.handle_spam_prevention(MUTE_DEADCHAT)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<font color='red'>You cannot talk in deadchat (muted).</font>")
|
||||
return
|
||||
|
||||
. = src.say_dead(message)
|
||||
|
||||
|
||||
/mob/observer/dead/emote(var/act, var/type, var/message)
|
||||
//message = sanitize(message) - already sanitized in verb/me_verb()
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
if(act != "me")
|
||||
log_ghostsay(message, src)
|
||||
|
||||
if (client)
|
||||
if(message)
|
||||
client.handle_spam_prevention(MUTE_DEADCHAT)
|
||||
if(client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<font color='red'>You cannot talk in deadchat (muted).</font>")
|
||||
return
|
||||
|
||||
. = say_dead(message)
|
||||
|
||||
|
||||
/mob/observer/dead/me_verb(message as text)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
log_ghostemote(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(client)
|
||||
if(message)
|
||||
client.handle_spam_prevention(MUTE_DEADCHAT)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
if(client.prefs.muted & MUTE_DEADCHAT)
|
||||
to_chat(src, "<font color='red'>You cannot emote in deadchat (muted).</font>")
|
||||
return
|
||||
|
||||
. = src.emote_dead(message)
|
||||
. = emote_dead(message)
|
||||
|
||||
/*
|
||||
for (var/mob/M in hearers(null, null))
|
||||
if (!M.stat)
|
||||
if(M.job == "Chaplain")
|
||||
if (prob (49))
|
||||
M.show_message("<span class='game'><i>You hear muffled speech... but nothing is there...</i></span>", 2)
|
||||
if(prob(20))
|
||||
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
|
||||
else
|
||||
M.show_message("<span class='game'><i>You hear muffled speech... you can almost make out some words...</i></span>", 2)
|
||||
// M.show_message("<span class='game'><i>[stutter(message)]</i></span>", 2)
|
||||
if(prob(30))
|
||||
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
|
||||
else
|
||||
if (prob(50))
|
||||
return
|
||||
else if (prob (95))
|
||||
M.show_message("<span class='game'><i>You hear muffled speech... but nothing is there...</i></span>", 2)
|
||||
if(prob(20))
|
||||
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
|
||||
else
|
||||
M.show_message("<span class='game'><i>You hear muffled speech... you can almost make out some words...</i></span>", 2)
|
||||
// M.show_message("<span class='game'><i>[stutter(message)]</i></span>", 2)
|
||||
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
|
||||
*/
|
||||
/mob/observer/dead/handle_track(message, verb = "says", mob/speaker = null, speaker_name, hard_to_hear)
|
||||
return "[speaker_name] ([ghost_follow_link(speaker, src)])"
|
||||
|
||||
/mob/observer/dead/handle_speaker_name(mob/speaker = null, vname, hard_to_hear)
|
||||
var/speaker_name = ..()
|
||||
//Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker))
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
return speaker_name
|
||||
+119
-139
@@ -1,54 +1,96 @@
|
||||
// At minimum every mob has a hear_say proc.
|
||||
/mob/proc/combine_message(var/list/message_pieces, var/verb, var/mob/speaker, always_stars = FALSE, var/radio = FALSE)
|
||||
var/iteration_count = 0
|
||||
var/msg = "" // This is to make sure that the pieces have actually added something
|
||||
. = "[verb], \""
|
||||
for(var/datum/multilingual_say_piece/SP in message_pieces)
|
||||
iteration_count++
|
||||
var/piece = SP.message
|
||||
if(piece == "")
|
||||
continue
|
||||
|
||||
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
if(SP.speaking && SP.speaking.flags & INNATE) // Snowflake for noise lang
|
||||
if(radio)
|
||||
return SP.speaking.format_message_radio(piece)
|
||||
else
|
||||
return SP.speaking.format_message(piece)
|
||||
|
||||
if(iteration_count == 1)
|
||||
piece = capitalize(piece)
|
||||
|
||||
if(always_stars)
|
||||
piece = stars(piece)
|
||||
else if(!say_understands(speaker, SP.speaking))
|
||||
piece = saypiece_scramble(SP)
|
||||
if(isliving(speaker))
|
||||
var/mob/living/S = speaker
|
||||
if(istype(S.say_list) && length(S.say_list.speak))
|
||||
piece = pick(S.say_list.speak)
|
||||
|
||||
if(!SP.speaking) // Catch the most generic case first
|
||||
piece = "<span class='message body'>[piece]</span>"
|
||||
else if(radio) // SP.speaking == TRUE enforced by previous !SP.speaking
|
||||
piece = SP.speaking.format_message_radio(piece)
|
||||
else // SP.speaking == TRUE && radio == FALSE
|
||||
piece = SP.speaking.format_message(piece)
|
||||
|
||||
msg += (piece + " ")
|
||||
|
||||
if(msg == "")
|
||||
// There is literally no content left in this message, we need to shut this shit down
|
||||
. = "" // hear_say will suppress it
|
||||
else
|
||||
. = trim(. + trim(msg))
|
||||
. += "\""
|
||||
|
||||
/mob/proc/saypiece_scramble(datum/multilingual_say_piece/SP)
|
||||
if(SP.speaking)
|
||||
return SP.speaking.scramble(SP.message)
|
||||
else
|
||||
return stars(SP.message)
|
||||
|
||||
/mob/proc/hear_say(var/list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
if(!client && !teleop)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(speaker && !speaker.client && istype(src,/mob/observer/dead) && is_preference_enabled(/datum/client_preference/ghost_ears) && !(speaker in view(src)))
|
||||
if(isobserver(src) && is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
if(speaker && !speaker.client && !(speaker in view(src)))
|
||||
//Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE')
|
||||
//Or someone snoring. So we make it where they won't hear it.
|
||||
return
|
||||
return FALSE
|
||||
|
||||
//make sure the air can transmit speech - hearer's side
|
||||
var/turf/T = get_turf(src)
|
||||
if ((T) && (!(istype(src, /mob/observer/dead)))) //Ghosts can hear even in vacuum.
|
||||
if(T && !isobserver(src)) //Ghosts can hear even in vacuum.
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = (environment)? environment.return_pressure() : 0
|
||||
var/pressure = environment ? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
|
||||
italics = 1
|
||||
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
|
||||
|
||||
if(sleeping || stat == 1)
|
||||
hear_sleep(message)
|
||||
return
|
||||
|
||||
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
|
||||
if (language && (language.flags & NONVERBAL))
|
||||
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
|
||||
message = stars(message)
|
||||
|
||||
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
|
||||
if(!say_understands(speaker,language))
|
||||
if(language)
|
||||
message = language.scramble(message, languages)
|
||||
else
|
||||
message = stars(message)
|
||||
|
||||
var/speaker_name = speaker.name
|
||||
if(istype(speaker, /mob/living/carbon/human))
|
||||
if(ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
speaker_name = H.GetVoice()
|
||||
|
||||
var/message = combine_message(message_pieces, verb, speaker)
|
||||
if(message == "")
|
||||
return
|
||||
|
||||
if(sleeping || stat == UNCONSCIOUS)
|
||||
hear_sleep(message)
|
||||
return FALSE
|
||||
|
||||
if(italics)
|
||||
message = "<i>[message]</i>"
|
||||
|
||||
message = encode_html_emphasis(message)
|
||||
|
||||
var/track = null
|
||||
if(istype(src, /mob/observer/dead))
|
||||
if(isobserver(src))
|
||||
if(italics && is_preference_enabled(/datum/client_preference/ghost_radio))
|
||||
return
|
||||
if(speaker_name != speaker.real_name && speaker.real_name)
|
||||
@@ -58,31 +100,27 @@
|
||||
message = "<b>[message]</b>"
|
||||
|
||||
if(is_deaf())
|
||||
if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
|
||||
if(speaker == src)
|
||||
to_chat(src, "<span class='warning'>You cannot hear yourself speak!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear.")
|
||||
if(speaker == src)
|
||||
to_chat(src, "<span class='filter_say'><span class='warning'>You cannot hear yourself speak!</span></span>")
|
||||
else
|
||||
to_chat(src, "<span class='filter_say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] makes a noise, possibly speech, but you cannot hear them.</span>")
|
||||
else
|
||||
var/message_to_send = null
|
||||
if(language)
|
||||
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>"
|
||||
else
|
||||
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>"
|
||||
if(check_mentioned(message) && is_preference_enabled(/datum/client_preference/check_mention))
|
||||
message_to_send = "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][message]</span>"
|
||||
if(check_mentioned(multilingual_to_message(message_pieces)) && is_preference_enabled(/datum/client_preference/check_mention))
|
||||
message_to_send = "<font size='3'><b>[message_to_send]</b></font>"
|
||||
|
||||
on_hear_say(message_to_send)
|
||||
|
||||
if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
|
||||
var/turf/source = speaker? get_turf(speaker) : get_turf(src)
|
||||
src.playsound_local(source, speech_sound, sound_vol, 1)
|
||||
if(speech_sound && (get_dist(speaker, src) <= world.view && z == speaker.z))
|
||||
var/turf/source = speaker ? get_turf(speaker) : get_turf(src)
|
||||
playsound_local(source, speech_sound, sound_vol, 1)
|
||||
|
||||
// Done here instead of on_hear_say() since that is NOT called if the mob is clientless (which includes most AI mobs).
|
||||
/mob/living/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
/mob/living/hear_say(var/list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
..()
|
||||
if(has_AI()) // Won't happen if no ai_holder exists or there's a player inside w/o autopilot active.
|
||||
ai_holder.on_hear_say(speaker, message)
|
||||
ai_holder.on_hear_say(speaker, multilingual_to_message(message_pieces))
|
||||
|
||||
/mob/proc/on_hear_say(var/message)
|
||||
to_chat(src, message)
|
||||
@@ -124,114 +162,25 @@
|
||||
|
||||
return tagged_message
|
||||
|
||||
/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
|
||||
|
||||
/mob/proc/hear_radio(var/list/message_pieces, var/verb = "says", var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname = "")
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(sleeping || stat==1) //If unconscious or sleeping
|
||||
var/message = combine_message(message_pieces, verb, speaker, always_stars = hard_to_hear, radio = TRUE)
|
||||
if(sleeping || stat == UNCONSCIOUS) //If unconscious or sleeping
|
||||
hear_sleep(message)
|
||||
return
|
||||
|
||||
var/track = null
|
||||
|
||||
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
|
||||
if (language && (language.flags & NONVERBAL))
|
||||
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
|
||||
message = stars(message)
|
||||
|
||||
if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages
|
||||
if(!say_understands(speaker,language))
|
||||
if(language)
|
||||
message = language.scramble(message, languages)
|
||||
else
|
||||
message = stars(message)
|
||||
|
||||
if(hard_to_hear)
|
||||
message = stars(message)
|
||||
|
||||
var/speaker_name = speaker.name
|
||||
|
||||
if(vname)
|
||||
speaker_name = vname
|
||||
|
||||
if(istype(speaker, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
if(H.voice)
|
||||
speaker_name = H.voice
|
||||
|
||||
if(hard_to_hear)
|
||||
speaker_name = "unknown"
|
||||
|
||||
var/changed_voice
|
||||
|
||||
if(istype(src, /mob/living/silicon/ai) && !hard_to_hear)
|
||||
var/jobname // the mob's "job"
|
||||
var/mob/living/carbon/human/impersonating //The crew member being impersonated, if any.
|
||||
|
||||
if (ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
|
||||
if(H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))
|
||||
changed_voice = 1
|
||||
var/list/impersonated = new()
|
||||
var/mob/living/carbon/human/I = impersonated[speaker_name]
|
||||
|
||||
if(!I)
|
||||
for(var/mob/living/carbon/human/M in mob_list)
|
||||
if(M.real_name == speaker_name)
|
||||
I = M
|
||||
impersonated[speaker_name] = I
|
||||
break
|
||||
|
||||
// If I's display name is currently different from the voice name and using an agent ID then don't impersonate
|
||||
// as this would allow the AI to track I and realize the mismatch.
|
||||
if(I && !(I.name != speaker_name && I.wear_id && istype(I.wear_id,/obj/item/weapon/card/id/syndicate)))
|
||||
impersonating = I
|
||||
jobname = impersonating.get_assignment()
|
||||
else
|
||||
jobname = "Unknown"
|
||||
else
|
||||
jobname = H.get_assignment()
|
||||
|
||||
else if (iscarbon(speaker)) // Nonhuman carbon mob
|
||||
jobname = "No id"
|
||||
else if (isAI(speaker))
|
||||
jobname = "AI"
|
||||
else if (isrobot(speaker))
|
||||
jobname = "Cyborg"
|
||||
else if (istype(speaker, /mob/living/silicon/pai))
|
||||
jobname = "Personal AI"
|
||||
else
|
||||
jobname = "Unknown"
|
||||
|
||||
if(changed_voice)
|
||||
if(impersonating)
|
||||
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
|
||||
else
|
||||
track = "[speaker_name] ([jobname])"
|
||||
else
|
||||
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
|
||||
|
||||
if(istype(src, /mob/observer/dead))
|
||||
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
|
||||
speaker_name = "[speaker.real_name] ([speaker_name])"
|
||||
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
|
||||
var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear)
|
||||
var/track = handle_track(message, verb, speaker, speaker_name, hard_to_hear)
|
||||
|
||||
message = encode_html_emphasis(message)
|
||||
|
||||
var/formatted
|
||||
if(language)
|
||||
formatted = "[language.format_message_radio(message, verb)][part_c]"
|
||||
else
|
||||
formatted = "[verb], <span class=\"body\">\"[message]\"</span>[part_c]"
|
||||
|
||||
|
||||
if((sdisabilities & DEAF) || ear_deaf)
|
||||
if(prob(20))
|
||||
to_chat(src, "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>")
|
||||
else
|
||||
on_hear_radio(part_a, speaker_name, track, part_b, formatted)
|
||||
on_hear_radio(part_a, speaker_name, track, part_b, message)
|
||||
|
||||
/proc/say_timestamp()
|
||||
return "<span class='say_quote'>\[[stationtime2text()]\]</span>"
|
||||
@@ -296,9 +245,40 @@
|
||||
heardword = copytext(heardword,2)
|
||||
if(copytext(heardword,-1) in punctuation)
|
||||
heardword = copytext(heardword,1,length(heardword))
|
||||
heard = "<span class = 'game_say'>...You hear something about...[heardword]</span>"
|
||||
heard = "<span class='game say'>...You hear something about...[heardword]</span>"
|
||||
|
||||
else
|
||||
heard = "<span class = 'game_say'>...<i>You almost hear someone talking</i>...</span>"
|
||||
heard = "<span class='game say'>...<i>You almost hear someone talking</i>...</span>"
|
||||
|
||||
to_chat(src,heard)
|
||||
to_chat(src, heard)
|
||||
|
||||
/mob/proc/handle_speaker_name(mob/speaker, vname, hard_to_hear)
|
||||
var/speaker_name = "unknown"
|
||||
if(speaker)
|
||||
speaker_name = speaker.name
|
||||
|
||||
if(ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
if(H.voice)
|
||||
speaker_name = H.voice
|
||||
|
||||
if(vname)
|
||||
speaker_name = vname
|
||||
|
||||
if(hard_to_hear)
|
||||
speaker_name = "unknown"
|
||||
|
||||
return speaker_name
|
||||
|
||||
/mob/proc/handle_track(message, verb = "says", mob/speaker = null, speaker_name, hard_to_hear)
|
||||
return
|
||||
|
||||
/mob/proc/hear_holopad_talk(list/message_pieces, var/verb = "says", var/mob/speaker = null)
|
||||
var/message = combine_message(message_pieces, verb, speaker)
|
||||
|
||||
var/name = speaker.name
|
||||
if(!say_understands(speaker))
|
||||
name = speaker.voice_name
|
||||
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> [message]</span>"
|
||||
to_chat(src, rendered)
|
||||
@@ -5,12 +5,6 @@
|
||||
key = ""
|
||||
flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER
|
||||
|
||||
/datum/language/noise/format_message(message, verb)
|
||||
return "<span class='message'><span class='[colour]'>[message]</span></span>"
|
||||
|
||||
/datum/language/noise/format_message_plain(message, verb)
|
||||
return message
|
||||
|
||||
/datum/language/noise/format_message_radio(message, verb)
|
||||
return "<span class='[colour]'>[message]</span>"
|
||||
|
||||
@@ -143,6 +137,17 @@
|
||||
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
|
||||
return (hands || !iscarbon(speaker))
|
||||
|
||||
/datum/language/sign/scramble(var/input, var/list/known_languages)
|
||||
return stars(input)
|
||||
|
||||
// This is a little weird because broadcast is traditionally for hivemind languages
|
||||
// But in practice, it's just a way for a language to override all other languages and bypass hear_say
|
||||
// which is exactly what sign language does.
|
||||
/datum/language/sign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
|
||||
log_say("(SIGN) [message]", speaker)
|
||||
speaker.say_signlang(message, pick(signlang_verb), src)
|
||||
|
||||
|
||||
// Silly language for those times when you try to talk a languague you normally can't
|
||||
/datum/language/gibberish
|
||||
name = LANGUAGE_GIBBERISH
|
||||
|
||||
@@ -113,13 +113,13 @@
|
||||
return scrambled_text
|
||||
|
||||
/datum/language/proc/format_message(message, verb)
|
||||
return "[verb], <span class='message'><span class='[colour]'>\"[capitalize(message)]\"</span></span>"
|
||||
return "<span class='message'><span class='[colour]'>[message]</span></span>"
|
||||
|
||||
/datum/language/proc/format_message_plain(message, verb)
|
||||
return "[verb], \"[capitalize(message)]\""
|
||||
return "[capitalize(message)]"
|
||||
|
||||
/datum/language/proc/format_message_radio(message, verb)
|
||||
return "[verb], <span class='[colour]'>\"[capitalize(message)]\"</span>"
|
||||
return "<span class='[colour]'>[capitalize(message)]</span>"
|
||||
|
||||
/datum/language/proc/get_talkinto_msg_range(message)
|
||||
// if you yell, you'll be heard from two tiles over instead of one
|
||||
@@ -129,7 +129,7 @@
|
||||
log_say("(HIVE) [message]", speaker)
|
||||
|
||||
if(!speaker_mask) speaker_mask = speaker.name
|
||||
message = format_message(message, get_spoken_verb(message))
|
||||
message = "[get_spoken_verb(message)], \"[format_message(message, get_spoken_verb(message))]\""
|
||||
|
||||
for(var/mob/player in player_list)
|
||||
player.hear_broadcast(src, speaker, speaker_mask, message)
|
||||
@@ -233,36 +233,36 @@
|
||||
return prefix in config.language_prefixes
|
||||
|
||||
//TBD
|
||||
/mob/proc/check_lang_data()
|
||||
. = ""
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b><br/>[L.desc]<br/><br/>"
|
||||
|
||||
/mob/living/check_lang_data()
|
||||
. = ""
|
||||
|
||||
if(default_language)
|
||||
. += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
if(L == default_language)
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b> - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/>[L.desc]<br/><br/>"
|
||||
else if (can_speak(L))
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b> - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a><br/>[L.desc]<br/><br/>"
|
||||
else
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b> - cannot speak!<br/>[L.desc]<br/><br/>"
|
||||
|
||||
/mob/verb/check_languages()
|
||||
set name = "Check Known Languages"
|
||||
set category = "IC"
|
||||
set src = usr
|
||||
|
||||
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b><br/>[L.desc]<br/><br/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
return
|
||||
|
||||
/mob/living/check_languages()
|
||||
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
|
||||
|
||||
if(default_language)
|
||||
dat += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
if(L == default_language)
|
||||
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b> - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/>[L.desc]<br/><br/>"
|
||||
else if (can_speak(L))
|
||||
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b> - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a><br/>[L.desc]<br/><br/>"
|
||||
else
|
||||
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b> - cannot speak!<br/>[L.desc]<br/><br/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
var/datum/browser/popup = new(src, "checklanguage", "Known Languages", 420, 470)
|
||||
popup.set_content(check_lang_data())
|
||||
popup.open()
|
||||
|
||||
/mob/living/Topic(href, href_list)
|
||||
if(href_list["default_lang"])
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
key = "l"
|
||||
flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL
|
||||
|
||||
/datum/language/tajsign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
|
||||
log_say("(SIGN) [message]", speaker)
|
||||
speaker.say_signlang(message, pick(signlang_verb), src)
|
||||
|
||||
/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
|
||||
var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this.
|
||||
if(iscarbon(speaker))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define AUTOHISS_NUM 3
|
||||
|
||||
|
||||
/mob/living/proc/handle_autohiss(message, datum/language/L)
|
||||
/mob/proc/handle_autohiss(message, datum/language/L)
|
||||
return message // no autohiss at this level
|
||||
|
||||
/mob/living/carbon/human/handle_autohiss(message, datum/language/L)
|
||||
|
||||
@@ -144,12 +144,8 @@
|
||||
/mob/living/bot/attack_ai(var/mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/mob/living/bot/say(var/message)
|
||||
var/verb = "beeps"
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
..(message, null, verb)
|
||||
/mob/living/bot/say_quote(var/message, var/datum/language/speaking = null)
|
||||
return "beeps"
|
||||
|
||||
/mob/living/bot/speech_bubble_appearance()
|
||||
return "machine"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/mob/living/carbon/alien
|
||||
|
||||
name = "alien"
|
||||
desc = "What IS that?"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
@@ -52,4 +51,23 @@
|
||||
return //Consider adding cuffs and hats to this, for the sake of fun.
|
||||
|
||||
/mob/living/carbon/alien/cannot_use_vents()
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/get_default_language()
|
||||
if(default_language)
|
||||
return default_language
|
||||
return GLOB.all_languages["Xenomorph"]
|
||||
|
||||
/mob/living/carbon/alien/say_quote(var/message, var/datum/language/speaking = null)
|
||||
var/verb = "hisses"
|
||||
var/ending = copytext(message, length(message))
|
||||
|
||||
if(speaking && (speaking.name != "Galactic Common")) //this is so adminbooze xenos speaking common have their custom verbs,
|
||||
verb = speaking.get_spoken_verb(ending) //and use normal verbs for their own languages and non-common languages
|
||||
else
|
||||
if(ending == "!")
|
||||
verb = "roars"
|
||||
else if(ending == "?")
|
||||
verb = "hisses curiously"
|
||||
return verb
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/living/carbon/alien/diona/say_understands(var/mob/other,var/datum/language/speaking = null)
|
||||
|
||||
if (istype(other, /mob/living/carbon/human) && !speaking)
|
||||
/mob/living/carbon/alien/diona/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
if(ishuman(other) && !speaking)
|
||||
if(languages.len >= 2) // They have sucked down some blood.
|
||||
return 1
|
||||
return TRUE
|
||||
return ..()
|
||||
@@ -1,131 +1,107 @@
|
||||
/mob/living/carbon/alien/emote(var/act,var/m_type=1,var/message = null)
|
||||
|
||||
/mob/living/carbon/alien/emote(var/act, var/m_type=1, var/message = null)
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
var/muzzled = is_muzzled()
|
||||
|
||||
switch(act)
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if (src.client)
|
||||
if (client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<font color='red'>You cannot send IC messages (muted).</font>")
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if ("custom")
|
||||
return custom_emote(m_type, message)
|
||||
if("sign")
|
||||
if (!src.restrained())
|
||||
message = text("<B>The alien</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
|
||||
m_type = 1
|
||||
if ("burp")
|
||||
if (!muzzled)
|
||||
if(!restrained())
|
||||
var/num = null
|
||||
if(text2num(param))
|
||||
num = "the number [text2num(param)]"
|
||||
if(num)
|
||||
message = "<B>[src]</B> signs [num]."
|
||||
m_type = 1
|
||||
if("burp")
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> burps."
|
||||
m_type = 2
|
||||
if("deathgasp")
|
||||
message = "<B>The [src.name]</B> lets out a waning guttural screech, green blood bubbling from its maw."
|
||||
message = "<B>[src]</B> lets out a waning guttural screech, green blood bubbling from its maw."
|
||||
m_type = 2
|
||||
if("scratch")
|
||||
if (!src.restrained())
|
||||
message = "<B>The [src.name]</B> scratches."
|
||||
if(!restrained())
|
||||
message = "<B>[src]</B> scratches."
|
||||
m_type = 1
|
||||
if("whimper")
|
||||
if (!muzzled)
|
||||
message = "<B>The [src.name]</B> whimpers."
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> whimpers."
|
||||
m_type = 2
|
||||
if("tail")
|
||||
message = "<B>The [src.name]</B> waves its tail."
|
||||
message = "<B>[src]</B> waves its tail."
|
||||
m_type = 1
|
||||
if("gasp")
|
||||
message = "<B>The [src.name]</B> gasps."
|
||||
message = "<B>[src]</B> gasps."
|
||||
m_type = 2
|
||||
if("shiver")
|
||||
message = "<B>The [src.name]</B> shivers."
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 2
|
||||
if("drool")
|
||||
message = "<B>The [src.name]</B> drools."
|
||||
message = "<B>[src]</B> drools."
|
||||
m_type = 1
|
||||
if("scretch")
|
||||
if (!muzzled)
|
||||
message = "<B>The [src.name]</B> scretches."
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> scretches."
|
||||
m_type = 2
|
||||
if("choke")
|
||||
message = "<B>The [src.name]</B> chokes."
|
||||
message = "<B>[src]</B> chokes."
|
||||
m_type = 2
|
||||
if("moan")
|
||||
message = "<B>The [src.name]</B> moans!"
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
if("nod")
|
||||
message = "<B>The [src.name]</B> nods its head."
|
||||
message = "<B>[src]</B> nods its head."
|
||||
m_type = 1
|
||||
// if("sit")
|
||||
// message = "<B>The [src.name]</B> sits down." //Larvan can't sit down, /N
|
||||
// message = "<B>[src]</B> sits down." //Larvan can't sit down, /N
|
||||
// m_type = 1
|
||||
if("sway")
|
||||
message = "<B>The [src.name]</B> sways around dizzily."
|
||||
message = "<B>[src]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
if("sulk")
|
||||
message = "<B>The [src.name]</B> sulks down sadly."
|
||||
message = "<B>[src]</B> sulks down sadly."
|
||||
m_type = 1
|
||||
if("twitch")
|
||||
message = "<B>The [src.name]</B> twitches."
|
||||
message = "<B>[src]</B> twitches."
|
||||
m_type = 1
|
||||
if("twitch_v")
|
||||
message = "<B>The [src.name]</B> twitches violently."
|
||||
message = "<B>[src]</B> twitches violently."
|
||||
m_type = 1
|
||||
if("dance")
|
||||
if (!src.restrained())
|
||||
message = "<B>The [src.name]</B> dances around happily."
|
||||
if(!restrained())
|
||||
message = "<B>[src]</B> dances around happily."
|
||||
m_type = 1
|
||||
if("roll")
|
||||
if (!src.restrained())
|
||||
message = "<B>The [src.name]</B> rolls."
|
||||
if(!restrained())
|
||||
message = "<B>[src]</B> rolls."
|
||||
m_type = 1
|
||||
if("shake")
|
||||
message = "<B>The [src.name]</B> shakes its head."
|
||||
message = "<B>[src]</B> shakes its head."
|
||||
m_type = 1
|
||||
if("gnarl")
|
||||
if (!muzzled)
|
||||
message = "<B>The [src.name]</B> gnarls and shows its teeth.."
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
if("jump")
|
||||
message = "<B>The [src.name]</B> jumps!"
|
||||
message = "<B>[src]</B> jumps!"
|
||||
m_type = 1
|
||||
if("hiss_")
|
||||
message = "<B>The [src.name]</B> hisses softly."
|
||||
message = "<B>[src]</B> hisses softly."
|
||||
m_type = 1
|
||||
if("collapse")
|
||||
Paralyse(2)
|
||||
message = text("<B>[]</B> collapses!", src)
|
||||
message = "<B>[src]</B> collapses!"
|
||||
m_type = 2
|
||||
if("chirp")
|
||||
message = "<B>The [src.name]</B> chirps!"
|
||||
playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
|
||||
message = "<B>[src]</B> chirps!"
|
||||
playsound(loc, 'sound/misc/nymphchirp.ogg', 50, 0)
|
||||
m_type = 2
|
||||
if("help")
|
||||
to_chat(src, "burp, chirp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper")
|
||||
else
|
||||
to_chat(src, "Invalid Emote: [act]")
|
||||
if ((message && src.stat == 0))
|
||||
log_emote(message, src)
|
||||
if (m_type & 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
//Foreach goto(703)
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
//Foreach goto(746)
|
||||
return
|
||||
to_chat(src, "<span class='filter_say'>burp, chirp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper</span>")
|
||||
|
||||
if(!stat)
|
||||
..(act, m_type, message)
|
||||
@@ -1,25 +0,0 @@
|
||||
/mob/living/carbon/alien/say(var/message)
|
||||
var/verb = "says"
|
||||
var/message_range = world.view
|
||||
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<font color='red'>You cannot speak in IC (Muted).</font>")
|
||||
return
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
if(stat == 2)
|
||||
return say_dead(message)
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
return emote(copytext(message,2))
|
||||
|
||||
var/datum/language/speaking = parse_language(message)
|
||||
|
||||
message = trim(message)
|
||||
|
||||
if(!message || stat)
|
||||
return
|
||||
|
||||
..(message, speaking, verb, null, null, message_range, null)
|
||||
@@ -18,36 +18,19 @@
|
||||
|
||||
/mob/living/carbon/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
if(stat != DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/say_understands(var/other)//Goddamn is this hackish, but this say code is so odd
|
||||
if (istype(other, /mob/living/silicon/ai))
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon/decoy))
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon/pai))
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon/robot))
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
if (istype(other, /mob/living/carbon/human))
|
||||
return 1
|
||||
if (istype(other, /mob/living/simple_mob/slime))
|
||||
return 1
|
||||
if(istype(container, /obj/item/device/mmi))
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(ishuman(other))
|
||||
return TRUE
|
||||
if(isslime(other))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/update_canmove()
|
||||
|
||||
@@ -2,79 +2,46 @@
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
|
||||
return
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
if(src.stat == DEAD)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
switch(act)
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if (src.client)
|
||||
if (client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<font color='red'>You cannot send IC messages (muted).</font>")
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if ("custom")
|
||||
return custom_emote(m_type, message)
|
||||
if ("alarm")
|
||||
if("alarm")
|
||||
to_chat(src, "You sound an alarm.")
|
||||
message = "<B>[src]</B> sounds an alarm."
|
||||
m_type = 2
|
||||
if ("alert")
|
||||
if("alert")
|
||||
to_chat(src, "You let out a distressed noise.")
|
||||
message = "<B>[src]</B> lets out a distressed noise."
|
||||
m_type = 2
|
||||
if ("notice")
|
||||
if("notice")
|
||||
to_chat(src, "You play a loud tone.")
|
||||
message = "<B>[src]</B> plays a loud tone."
|
||||
m_type = 2
|
||||
if ("flash")
|
||||
if("flash")
|
||||
message = "The lights on <B>[src]</B> flash quickly."
|
||||
m_type = 1
|
||||
if ("blink")
|
||||
if("blink")
|
||||
message = "<B>[src]</B> blinks."
|
||||
m_type = 1
|
||||
if ("whistle")
|
||||
if("whistle")
|
||||
to_chat(src, "You whistle.")
|
||||
message = "<B>[src]</B> whistles."
|
||||
m_type = 2
|
||||
if ("beep")
|
||||
if("beep")
|
||||
to_chat(src, "You beep.")
|
||||
message = "<B>[src]</B> beeps."
|
||||
m_type = 2
|
||||
if ("boop")
|
||||
if("boop")
|
||||
to_chat(src, "You boop.")
|
||||
message = "<B>[src]</B> boops."
|
||||
m_type = 2
|
||||
if ("help")
|
||||
to_chat(src, "alarm,alert,notice,flash,blink,whistle,beep,boop")
|
||||
else
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>")
|
||||
if("help")
|
||||
to_chat(src, "<span class='filter_say'>alarm, alert, notice, flash, blink, whistle, beep, boop</span>")
|
||||
|
||||
if (message)
|
||||
log_emote(message, src)
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if (!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers, and new_players
|
||||
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_sight) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
|
||||
if (m_type & 1)
|
||||
for (var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
else if (m_type & 2)
|
||||
for (var/mob/O in hearers(src.loc, null))
|
||||
O.show_message(message, m_type)
|
||||
if(!stat)
|
||||
..(act, m_type, message)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//TODO: Convert this over for languages.
|
||||
/mob/living/carbon/brain/say(var/message)
|
||||
if (silent)
|
||||
/mob/living/carbon/brain/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
if(silent)
|
||||
return
|
||||
|
||||
message = sanitize(message)
|
||||
@@ -8,39 +8,22 @@
|
||||
if(!(container && container.can_speak))
|
||||
return //Certain objects can speak, like MMIs. Most others cannot. -Q
|
||||
else
|
||||
var/datum/language/speaking = parse_language(message)
|
||||
if(speaking)
|
||||
message = copytext(message, 2+length(speaking.key))
|
||||
var/verb = "says"
|
||||
var/ending = copytext(message, length(message))
|
||||
if (speaking)
|
||||
verb = speaking.get_spoken_verb(ending)
|
||||
else
|
||||
if(ending=="!")
|
||||
verb=pick("exclaims","shouts","yells")
|
||||
if(ending=="?")
|
||||
verb="asks"
|
||||
|
||||
if(prob(emp_damage*4))
|
||||
if(prob(emp_damage * 4))
|
||||
if(prob(10))//10% chance to drop the message entirely
|
||||
return
|
||||
else
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
|
||||
if(speaking && speaking.flags & HIVEMIND)
|
||||
speaking.broadcast(src,trim(message))
|
||||
return
|
||||
..()
|
||||
|
||||
..(trim(message), speaking, verb)
|
||||
|
||||
/mob/living/carbon/brain/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/carbon/brain/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
var/obj/item/device/mmi/R = container
|
||||
if (R.radio && R.radio.radio_enabled)
|
||||
if(R.radio && R.radio.radio_enabled)
|
||||
if(message_mode == "general")
|
||||
message_mode = null
|
||||
return R.radio.talk_into(src,message,message_mode,verb,speaking)
|
||||
return R.radio.talk_into(src, message, message_mode, verb, speaking)
|
||||
else
|
||||
to_chat(src, "<span class='danger'>Your radio is disabled.</span>")
|
||||
return 0
|
||||
|
||||
@@ -3,29 +3,26 @@
|
||||
|
||||
var/datum/gender/T = gender_datums[get_visible_gender()]
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
//var/m_type = 1
|
||||
|
||||
for(var/obj/item/organ/O in src.organs)
|
||||
for (var/obj/item/weapon/implant/I in O)
|
||||
if (I.implanted)
|
||||
if(I.implanted)
|
||||
I.trigger(act, src)
|
||||
|
||||
if(src.stat == 2.0 && (act != "deathgasp"))
|
||||
if(stat == DEAD && (act != "deathgasp"))
|
||||
return
|
||||
if(attempt_vr(src,"handle_emote_vr",list(act,m_type,message))) return //VOREStation Add - Custom Emote Handler
|
||||
switch(act)
|
||||
|
||||
if ("airguitar")
|
||||
if (!src.restrained())
|
||||
if("airguitar")
|
||||
if(!src.restrained())
|
||||
message = "is strumming the air and headbanging like a safari chimp."
|
||||
m_type = 1
|
||||
|
||||
@@ -39,7 +36,7 @@
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
@@ -75,7 +72,7 @@
|
||||
else
|
||||
use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "[display_msg] at [param]."
|
||||
else
|
||||
message = "[display_msg]."
|
||||
@@ -103,142 +100,142 @@
|
||||
message = "warbles."
|
||||
m_type = 2
|
||||
|
||||
if ("blink")
|
||||
if("blink")
|
||||
message = "blinks."
|
||||
m_type = 1
|
||||
|
||||
if ("blink_r")
|
||||
if("blink_r")
|
||||
message = "blinks rapidly."
|
||||
m_type = 1
|
||||
|
||||
if ("bow")
|
||||
if (!src.buckled)
|
||||
if("bow")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "bows to [param]."
|
||||
else
|
||||
message = "bows."
|
||||
m_type = 1
|
||||
|
||||
if ("custom")
|
||||
if("custom")
|
||||
var/input = sanitize(input("Choose an emote to display.") as text|null)
|
||||
if (!input)
|
||||
if(!input)
|
||||
return
|
||||
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
|
||||
if (input2 == "Visible")
|
||||
if(input2 == "Visible")
|
||||
m_type = 1
|
||||
else if (input2 == "Hearable")
|
||||
if (src.miming)
|
||||
else if(input2 == "Hearable")
|
||||
if(src.miming)
|
||||
return
|
||||
m_type = 2
|
||||
else
|
||||
alert("Unable to use this emote, must be either hearable or visible.")
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
return custom_emote(m_type, input)
|
||||
|
||||
if ("me")
|
||||
if("me")
|
||||
|
||||
//if(silent && silent > 0 && findtext(message,"\"",1, null) > 0)
|
||||
// return //This check does not work and I have no idea why, I'm leaving it in for reference.
|
||||
|
||||
if (src.client)
|
||||
if (client.prefs.muted & MUTE_IC)
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<font color='red'>You cannot send IC messages (muted).</font>")
|
||||
return
|
||||
if (stat)
|
||||
if(stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if ("salute")
|
||||
if (!src.buckled)
|
||||
if("salute")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "salutes to [param]."
|
||||
else
|
||||
message = "salutes."
|
||||
m_type = 1
|
||||
|
||||
if ("choke")
|
||||
if("choke")
|
||||
if(miming)
|
||||
message = "clutches [T.his] throat desperately!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "chokes!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a strong noise."
|
||||
m_type = 2
|
||||
|
||||
if ("clap")
|
||||
if (!src.restrained())
|
||||
if("clap")
|
||||
if(!src.restrained())
|
||||
message = "claps."
|
||||
playsound(src.loc, 'sound/misc/clapping.ogg')
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("flap")
|
||||
if (!src.restrained())
|
||||
if("flap")
|
||||
if(!src.restrained())
|
||||
message = "flaps [T.his] wings."
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
if("aflap")
|
||||
if(!src.restrained())
|
||||
message = "flaps [T.his] wings ANGRILY!"
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("drool")
|
||||
if("drool")
|
||||
message = "drools."
|
||||
m_type = 1
|
||||
|
||||
if ("eyebrow")
|
||||
if("eyebrow")
|
||||
message = "raises an eyebrow."
|
||||
m_type = 1
|
||||
|
||||
if ("chuckle")
|
||||
if("chuckle")
|
||||
if(miming)
|
||||
message = "appears to chuckle."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "chuckles."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("twitch")
|
||||
if("twitch")
|
||||
message = "twitches."
|
||||
m_type = 1
|
||||
|
||||
if ("twitch_v")
|
||||
if("twitch_v")
|
||||
message = "twitches violently."
|
||||
m_type = 1
|
||||
|
||||
if ("faint")
|
||||
if("faint")
|
||||
message = "faints."
|
||||
if(src.sleeping)
|
||||
return //Can't faint while asleep
|
||||
@@ -277,167 +274,167 @@
|
||||
message = "makes a strong noise."
|
||||
m_type = 2
|
||||
|
||||
if ("frown")
|
||||
if("frown")
|
||||
message = "frowns."
|
||||
m_type = 1
|
||||
|
||||
if ("nod")
|
||||
if("nod")
|
||||
message = "nods."
|
||||
m_type = 1
|
||||
|
||||
if ("blush")
|
||||
if("blush")
|
||||
message = "blushes."
|
||||
m_type = 1
|
||||
|
||||
if ("wave")
|
||||
if("wave")
|
||||
message = "waves."
|
||||
m_type = 1
|
||||
|
||||
if ("gasp")
|
||||
if("gasp")
|
||||
if(miming)
|
||||
message = "appears to be gasping!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "gasps!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a weak noise."
|
||||
m_type = 2
|
||||
|
||||
if ("deathgasp")
|
||||
if("deathgasp")
|
||||
message = "[species.get_death_message()]"
|
||||
m_type = 1
|
||||
|
||||
if ("giggle")
|
||||
if("giggle")
|
||||
if(miming)
|
||||
message = "giggles silently!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "giggles."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("glare")
|
||||
if("glare")
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "glares at [param]."
|
||||
else
|
||||
message = "glares."
|
||||
|
||||
if ("stare")
|
||||
if("stare")
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "stares at [param]."
|
||||
else
|
||||
message = "stares."
|
||||
|
||||
if ("look")
|
||||
if("look")
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
if(param)
|
||||
message = "looks at [param]."
|
||||
else
|
||||
message = "looks."
|
||||
m_type = 1
|
||||
|
||||
if ("grin")
|
||||
if("grin")
|
||||
message = "grins."
|
||||
m_type = 1
|
||||
|
||||
if ("cry")
|
||||
if("cry")
|
||||
if(miming)
|
||||
message = "cries."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "cries."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a weak noise. [T.he] [get_visible_gender() == NEUTER ? "frown" : "frowns"]." // no good, non-unwieldy alternative to this ternary at the moment
|
||||
m_type = 2
|
||||
|
||||
if ("sigh")
|
||||
if("sigh")
|
||||
if(miming)
|
||||
message = "sighs."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "sighs."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a weak noise."
|
||||
m_type = 2
|
||||
|
||||
if ("laugh")
|
||||
if("laugh")
|
||||
if(miming)
|
||||
message = "acts out a laugh."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "laughs."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("mumble")
|
||||
if("mumble")
|
||||
message = "mumbles!"
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("grumble")
|
||||
if("grumble")
|
||||
if(miming)
|
||||
message = "grumbles!"
|
||||
m_type = 1
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "grumbles!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("groan")
|
||||
if("groan")
|
||||
if(miming)
|
||||
message = "appears to groan!"
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "groans!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a loud noise."
|
||||
m_type = 2
|
||||
|
||||
if ("moan")
|
||||
if("moan")
|
||||
if(miming)
|
||||
message = "appears to moan!"
|
||||
m_type = 1
|
||||
@@ -445,11 +442,11 @@
|
||||
message = "moans!"
|
||||
m_type = 2
|
||||
|
||||
if ("johnny")
|
||||
if("johnny")
|
||||
var/M
|
||||
if (param)
|
||||
if(param)
|
||||
M = param
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
else
|
||||
if(miming)
|
||||
@@ -459,27 +456,27 @@
|
||||
message = "says, \"[M], please. He had a family.\" [src.name] takes a drag from a cigarette and blows his name out in smoke."
|
||||
m_type = 2
|
||||
|
||||
if ("point")
|
||||
if (!src.restrained())
|
||||
if("point")
|
||||
if(!src.restrained())
|
||||
var/mob/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/atom/A as mob|obj|turf|area in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
|
||||
if (!M)
|
||||
if(!M)
|
||||
message = "points."
|
||||
else
|
||||
pointed(M)
|
||||
|
||||
if (M)
|
||||
if(M)
|
||||
message = "points to [M]."
|
||||
else
|
||||
m_type = 1
|
||||
|
||||
if ("raise")
|
||||
if (!src.restrained())
|
||||
if("raise")
|
||||
if(!src.restrained())
|
||||
message = "raises a hand."
|
||||
m_type = 1
|
||||
|
||||
@@ -487,35 +484,35 @@
|
||||
message = "shakes [T.his] head."
|
||||
m_type = 1
|
||||
|
||||
if ("shrug")
|
||||
if("shrug")
|
||||
message = "shrugs."
|
||||
m_type = 1
|
||||
|
||||
if ("signal")
|
||||
if (!src.restrained())
|
||||
if("signal")
|
||||
if(!src.restrained())
|
||||
var/t1 = round(text2num(param))
|
||||
if (isnum(t1))
|
||||
if (t1 <= 5 && (!src.r_hand || !src.l_hand))
|
||||
if(isnum(t1))
|
||||
if(t1 <= 5 && (!src.r_hand || !src.l_hand))
|
||||
message = "raises [t1] finger\s."
|
||||
else if (t1 <= 10 && (!src.r_hand && !src.l_hand))
|
||||
else if(t1 <= 10 && (!src.r_hand && !src.l_hand))
|
||||
message = "raises [t1] finger\s."
|
||||
m_type = 1
|
||||
|
||||
if ("smile")
|
||||
if("smile")
|
||||
message = "smiles."
|
||||
m_type = 1
|
||||
|
||||
if ("shiver")
|
||||
if("shiver")
|
||||
message = "shivers."
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("pale")
|
||||
if("pale")
|
||||
message = "goes pale for a second."
|
||||
m_type = 1
|
||||
|
||||
if ("tremble")
|
||||
if("tremble")
|
||||
message = "trembles in fear!"
|
||||
m_type = 1
|
||||
|
||||
@@ -550,48 +547,48 @@
|
||||
message = "makes a strange noise."
|
||||
m_type = 2
|
||||
|
||||
if ("sniff")
|
||||
if("sniff")
|
||||
message = "sniffs."
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("snore")
|
||||
if (miming)
|
||||
if("snore")
|
||||
if(miming)
|
||||
message = "sleeps soundly."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "snores."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("whimper")
|
||||
if (miming)
|
||||
if("whimper")
|
||||
if(miming)
|
||||
message = "appears hurt."
|
||||
m_type = 1
|
||||
else
|
||||
if (!muzzled)
|
||||
if(!muzzled)
|
||||
message = "whimpers."
|
||||
m_type = 2
|
||||
else
|
||||
message = "makes a weak noise."
|
||||
m_type = 2
|
||||
|
||||
if ("wink")
|
||||
if("wink")
|
||||
message = "winks."
|
||||
m_type = 1
|
||||
|
||||
if ("yawn")
|
||||
if (!muzzled)
|
||||
if("yawn")
|
||||
if(!muzzled)
|
||||
message = "yawns."
|
||||
m_type = 2
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
if ("collapse")
|
||||
if("collapse")
|
||||
Paralyse(2)
|
||||
message = "collapses!"
|
||||
m_type = 2
|
||||
@@ -600,49 +597,49 @@
|
||||
|
||||
if("hug")
|
||||
m_type = 1
|
||||
if (!src.restrained())
|
||||
if(!src.restrained())
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(1, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M == src)
|
||||
if(M == src)
|
||||
M = null
|
||||
|
||||
if (M)
|
||||
if(M)
|
||||
message = "hugs [M]."
|
||||
else
|
||||
message = "hugs [T.himself]."
|
||||
|
||||
if ("handshake")
|
||||
if("handshake")
|
||||
m_type = 1
|
||||
if (!src.restrained() && !src.r_hand)
|
||||
if(!src.restrained() && !src.r_hand)
|
||||
var/mob/living/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/living/A in view(1, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M == src)
|
||||
if(M == src)
|
||||
M = null
|
||||
|
||||
if (M)
|
||||
if (M.canmove && !M.r_hand && !M.restrained())
|
||||
if(M)
|
||||
if(M.canmove && !M.r_hand && !M.restrained())
|
||||
message = "shakes hands with [M]."
|
||||
else
|
||||
message = "holds out [T.his] hand to [M]."
|
||||
|
||||
if("dap")
|
||||
m_type = 1
|
||||
if (!src.restrained())
|
||||
if(!src.restrained())
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(1, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M)
|
||||
if(M)
|
||||
message = "gives daps to [M]."
|
||||
else
|
||||
message = "sadly can't find anybody to give daps to, and daps [T.himself]. Shameful."
|
||||
@@ -737,16 +734,20 @@
|
||||
else
|
||||
message = "makes a light spitting noise, a poor attempt at a whistle."
|
||||
|
||||
if ("help")
|
||||
to_chat(src, "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
|
||||
if("help")
|
||||
to_chat(src, "<span class='filter_say'>blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
|
||||
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \
|
||||
raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch, \
|
||||
twitch_v, vomit, whimper, wink, yawn. Prometheans: squish Synthetics: beep, buzz, dwoop, yes, no, rcough, rsneeze, ping. Skrell: warble")
|
||||
twitch_v, vomit, whimper, wink, yawn. Prometheans: squish Synthetics: beep, buzz, dwoop, yes, no, rcough, rsneeze, ping. Skrell: warble</span>")
|
||||
|
||||
else
|
||||
<<<<<<< HEAD
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help or *vhelp for a list.</font>") //VOREStation Edit, mention *vhelp for Virgo-specific emotes located in emote_vr.dm.
|
||||
=======
|
||||
to_chat(src, "<span class='filter_say'><font color='blue'>Unusable emote '[act]'. Say *help for a list.</font></span>")
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
if (message)
|
||||
if(message)
|
||||
custom_emote(m_type,message)
|
||||
|
||||
/mob/living/carbon/human/verb/pose()
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/mob/living/carbon/human/say(var/message,var/whispering=0)
|
||||
var/alt_name = ""
|
||||
/mob/living/carbon/human/GetAltName()
|
||||
if(name != GetVoice())
|
||||
alt_name = "(as [get_id_name("Unknown")])"
|
||||
return " (as [get_id_name("Unknown")])"
|
||||
|
||||
<<<<<<< HEAD
|
||||
message = sanitize_or_reflect(message,src) //VOREStation Edit - Reflect too-long messages, within reason
|
||||
..(message, alt_name = alt_name, whispering = whispering)
|
||||
=======
|
||||
return ..()
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -47,18 +50,18 @@
|
||||
return species.speech_bubble_appearance
|
||||
return "normal"
|
||||
|
||||
/mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null)
|
||||
|
||||
/mob/living/carbon/human/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(species.can_understand(other))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//These only pertain to common. Languages are handled by mob/say_understands()
|
||||
if (!speaking)
|
||||
if (istype(other, /mob/living/carbon/alien/diona))
|
||||
if(!speaking)
|
||||
if(istype(other, /mob/living/carbon/alien/diona))
|
||||
if(other.languages.len >= 2) //They've sucked down some blood and can speak common now.
|
||||
<<<<<<< HEAD
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon))
|
||||
return 1
|
||||
@@ -72,11 +75,19 @@
|
||||
// if((other.universal_speak && !speaking) || src.universal_speak || src.universal_understand)
|
||||
// return 1
|
||||
// return 0
|
||||
=======
|
||||
return TRUE
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(isbrain(other))
|
||||
return TRUE
|
||||
if(isslime(other))
|
||||
return TRUE
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
|
||||
var/voice_sub
|
||||
if(istype(get_rig(),/obj/item/weapon/rig))
|
||||
var/obj/item/weapon/rig/rig = get_rig()
|
||||
@@ -113,30 +124,6 @@
|
||||
/mob/living/carbon/human/proc/GetSpecialVoice()
|
||||
return special_voice
|
||||
|
||||
|
||||
/*
|
||||
***Deprecated***
|
||||
let this be handled at the hear_say or hear_radio proc
|
||||
This is left in for robot speaking when humans gain binary channel access until I get around to rewriting
|
||||
robot_talk() proc.
|
||||
There is no language handling build into it however there is at the /mob level so we accept the call
|
||||
for it but just ignore it.
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/say_quote(var/message, var/datum/language/speaking = null)
|
||||
var/verb = "says"
|
||||
var/ending = copytext(message, length(message))
|
||||
|
||||
if(speaking)
|
||||
verb = speaking.get_spoken_verb(ending)
|
||||
else
|
||||
if(ending == "!")
|
||||
verb=pick("exclaims","shouts","yells")
|
||||
else if(ending == "?")
|
||||
verb="asks"
|
||||
|
||||
return verb
|
||||
|
||||
/mob/living/carbon/human/handle_speech_problems(var/list/message_data)
|
||||
if(silent || (sdisabilities & MUTE))
|
||||
message_data[1] = ""
|
||||
@@ -152,59 +139,72 @@
|
||||
else
|
||||
. = ..(message_data)
|
||||
|
||||
/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/carbon/human/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
|
||||
switch(message_mode)
|
||||
if("intercom")
|
||||
if(!src.restrained())
|
||||
if(!restrained())
|
||||
for(var/obj/item/device/radio/intercom/I in view(1))
|
||||
I.talk_into(src, message, null, verb, speaking)
|
||||
I.talk_into(src, message_pieces, null, verb)
|
||||
I.add_fingerprint(src)
|
||||
used_radios += I
|
||||
if("headset")
|
||||
if(l_ear && istype(l_ear,/obj/item/device/radio))
|
||||
var/obj/item/device/radio/R = l_ear
|
||||
R.talk_into(src,message,null,verb,speaking)
|
||||
used_radios += l_ear
|
||||
else if(r_ear && istype(r_ear,/obj/item/device/radio))
|
||||
var/obj/item/device/radio/R = r_ear
|
||||
R.talk_into(src,message,null,verb,speaking)
|
||||
used_radios += r_ear
|
||||
if("right ear")
|
||||
var/obj/item/device/radio/R
|
||||
var/has_radio = 0
|
||||
if(r_ear && istype(r_ear,/obj/item/device/radio))
|
||||
R = r_ear
|
||||
has_radio = 1
|
||||
if(r_hand && istype(r_hand, /obj/item/device/radio))
|
||||
R = r_hand
|
||||
has_radio = 1
|
||||
if(has_radio)
|
||||
R.talk_into(src,message,null,verb,speaking)
|
||||
used_radios += R
|
||||
if("left ear")
|
||||
var/obj/item/device/radio/R
|
||||
var/has_radio = 0
|
||||
if(l_ear && istype(l_ear,/obj/item/device/radio))
|
||||
var/obj/item/device/radio/R = null
|
||||
if(isradio(l_ear))
|
||||
R = l_ear
|
||||
has_radio = 1
|
||||
if(l_hand && istype(l_hand,/obj/item/device/radio))
|
||||
if(R.talk_into(src, message_pieces, null, verb))
|
||||
used_radios += R
|
||||
return
|
||||
|
||||
if(isradio(r_ear))
|
||||
R = r_ear
|
||||
if(R.talk_into(src, message_pieces, null, verb))
|
||||
used_radios += R
|
||||
return
|
||||
if("right ear")
|
||||
var/obj/item/device/radio/R = null
|
||||
if(isradio(r_ear))
|
||||
R = r_ear
|
||||
if(isradio(r_hand))
|
||||
R = r_hand
|
||||
if(istype(R))
|
||||
if(R.talk_into(src, message_pieces, null, verb))
|
||||
used_radios += R
|
||||
if("left ear")
|
||||
var/obj/item/device/radio/R = null
|
||||
if(isradio(l_ear))
|
||||
R = l_ear
|
||||
if(isradio(l_hand))
|
||||
R = l_hand
|
||||
has_radio = 1
|
||||
if(has_radio)
|
||||
R.talk_into(src,message,null,verb,speaking)
|
||||
used_radios += R
|
||||
if(istype(R))
|
||||
if(R.talk_into(src, message_pieces, null, verb))
|
||||
used_radios += R
|
||||
else
|
||||
if(message_mode)
|
||||
if(l_ear && istype(l_ear,/obj/item/device/radio))
|
||||
l_ear.talk_into(src,message, message_mode, verb, speaking)
|
||||
used_radios += l_ear
|
||||
else if(r_ear && istype(r_ear,/obj/item/device/radio))
|
||||
r_ear.talk_into(src,message, message_mode, verb, speaking)
|
||||
used_radios += r_ear
|
||||
if(isradio(l_ear))
|
||||
if(l_ear.talk_into(src, message_pieces, message_mode, verb))
|
||||
used_radios += l_ear
|
||||
return
|
||||
|
||||
if(isradio(r_ear))
|
||||
if(r_ear.talk_into(src, message_pieces, message_mode, verb))
|
||||
used_radios += r_ear
|
||||
|
||||
/mob/living/carbon/human/handle_speech_sound()
|
||||
var/list/returns[2]
|
||||
if(species.speech_sounds && prob(species.speech_chance))
|
||||
var/list/returns[2]
|
||||
returns[1] = sound(pick(species.speech_sounds))
|
||||
returns[2] = 50
|
||||
return ..()
|
||||
return returns
|
||||
|
||||
/mob/living/carbon/human/binarycheck()
|
||||
. = FALSE
|
||||
var/obj/item/device/radio/headset/R = null
|
||||
if(istype(l_ear, /obj/item/device/radio/headset))
|
||||
R = l_ear
|
||||
if(R.translate_binary)
|
||||
. = TRUE
|
||||
|
||||
if(istype(r_ear, /obj/item/device/radio/headset))
|
||||
R = r_ear
|
||||
if(R.translate_binary)
|
||||
. = TRUE
|
||||
|
||||
@@ -532,10 +532,9 @@
|
||||
genders = list(PLURAL)
|
||||
|
||||
/datum/species/diona/can_understand(var/mob/other)
|
||||
var/mob/living/carbon/alien/diona/D = other
|
||||
if(istype(D))
|
||||
return 1
|
||||
return 0
|
||||
if(istype(other, /mob/living/carbon/alien/diona))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/species/diona/equip_survival_gear(var/mob/living/carbon/human/H)
|
||||
if(H.backbag == 1)
|
||||
|
||||
@@ -86,11 +86,9 @@
|
||||
return "alien [caste_name] ([alien_number])"
|
||||
|
||||
/datum/species/xenos/can_understand(var/mob/other)
|
||||
|
||||
if(istype(other,/mob/living/carbon/alien/larva))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
if(istype(other, /mob/living/carbon/alien/larva))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
|
||||
H.visible_message("<span class='notice'>[H] caresses [target] with its scythe-like arm.</span>", \
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/mob/living/carbon/slime/death(gibbed)
|
||||
|
||||
if(stat == DEAD) return
|
||||
|
||||
if(!gibbed && is_adult)
|
||||
var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc, colour)
|
||||
M.rabid = 1
|
||||
M.Friends = Friends.Copy()
|
||||
step_away(M, src)
|
||||
is_adult = 0
|
||||
maxHealth = 150
|
||||
revive()
|
||||
if (!client) rabid = 1
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
return
|
||||
|
||||
. = ..(gibbed, "seizes up and falls limp...")
|
||||
mood = null
|
||||
regenerate_icons()
|
||||
|
||||
return
|
||||
@@ -1,99 +0,0 @@
|
||||
/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null)
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
//param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
var/updateicon = 0
|
||||
|
||||
switch(act) //Alphabetical please
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if (src.client)
|
||||
if (client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<font color='red'>You cannot send IC messages (muted).</font>")
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
if("bounce")
|
||||
message = "<B>The [src.name]</B> bounces in place."
|
||||
m_type = 1
|
||||
|
||||
if ("custom")
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if("jiggle")
|
||||
message = "<B>The [src.name]</B> jiggles!"
|
||||
m_type = 1
|
||||
|
||||
if("light")
|
||||
message = "<B>The [src.name]</B> lights up for a bit, then stops."
|
||||
m_type = 1
|
||||
|
||||
if("moan")
|
||||
message = "<B>The [src.name]</B> moans."
|
||||
m_type = 2
|
||||
|
||||
if("shiver")
|
||||
message = "<B>The [src.name]</B> shivers."
|
||||
m_type = 2
|
||||
|
||||
if("sway")
|
||||
message = "<B>The [src.name]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
|
||||
if("twitch")
|
||||
message = "<B>The [src.name]</B> twitches."
|
||||
m_type = 1
|
||||
|
||||
if("vibrate")
|
||||
message = "<B>The [src.name]</B> vibrates!"
|
||||
m_type = 1
|
||||
|
||||
if("nomood")
|
||||
mood = null
|
||||
updateicon = 1
|
||||
|
||||
if("pout")
|
||||
mood = "pout"
|
||||
updateicon = 1
|
||||
|
||||
if("sad")
|
||||
mood = "sad"
|
||||
updateicon = 1
|
||||
|
||||
if("angry")
|
||||
mood = "angry"
|
||||
updateicon = 1
|
||||
|
||||
if("frown")
|
||||
mood = "mischevous"
|
||||
updateicon = 1
|
||||
|
||||
if("smile")
|
||||
mood = ":3"
|
||||
updateicon = 1
|
||||
|
||||
if ("help") //This is an exception
|
||||
to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate. You can also set your face with: \n\nnomood, pout, sad, angry, frown, smile")
|
||||
|
||||
else
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>")
|
||||
if ((message && src.stat == 0))
|
||||
if (m_type & 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
if(updateicon)
|
||||
regenerate_icons()
|
||||
return
|
||||
@@ -1,31 +0,0 @@
|
||||
/mob/living/carbon/slime/examine(mob/user)
|
||||
..(user)
|
||||
var/msg = ""
|
||||
if (src.stat == DEAD)
|
||||
msg += "<span class='deadsay'>It is limp and unresponsive.</span>\n"
|
||||
else
|
||||
if (src.getBruteLoss())
|
||||
msg += "<span class='warning'>"
|
||||
if (src.getBruteLoss() < 40)
|
||||
msg += "It has some punctures in its flesh!"
|
||||
else
|
||||
msg += "<B>It has severe punctures and tears in its flesh!</B>"
|
||||
msg += "</span>\n"
|
||||
|
||||
switch(powerlevel)
|
||||
|
||||
if(2 to 3)
|
||||
msg += "It is flickering gently with a little electrical activity.\n"
|
||||
|
||||
if(4 to 5)
|
||||
msg += "It is glowing gently with moderate levels of electrical activity.\n"
|
||||
|
||||
if(6 to 9)
|
||||
msg += "<span class='warning'>It is glowing brightly with high levels of electrical activity.</span>\n"
|
||||
|
||||
if(10)
|
||||
msg += "<span class='warning'><B>It is radiating with massive levels of electrical activity!</B></span>\n"
|
||||
|
||||
msg += "*---------*"
|
||||
to_chat(user,msg)
|
||||
return
|
||||
@@ -1,2 +0,0 @@
|
||||
/mob/living/carbon/slime/handle_regular_hud_updates()
|
||||
return
|
||||
@@ -1,527 +0,0 @@
|
||||
/mob/living/carbon/slime/Life()
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
|
||||
if (src.transforming)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_nutrition()
|
||||
|
||||
if (!client)
|
||||
handle_targets()
|
||||
if (!AIproc)
|
||||
spawn()
|
||||
handle_AI()
|
||||
handle_speech_and_mood()
|
||||
|
||||
/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
adjustToxLoss(rand(10,20))
|
||||
return
|
||||
|
||||
//var/environment_heat_capacity = environment.heat_capacity()
|
||||
var/loc_temp = T0C
|
||||
if(istype(get_turf(src), /turf/space))
|
||||
//environment_heat_capacity = loc:heat_capacity
|
||||
var/turf/heat_turf = get_turf(src)
|
||||
loc_temp = heat_turf.temperature
|
||||
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
loc_temp = loc:air_contents.temperature
|
||||
else
|
||||
loc_temp = environment.temperature
|
||||
|
||||
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
|
||||
|
||||
if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
|
||||
if(bodytemperature <= hurt_temperature)
|
||||
if(bodytemperature <= die_temperature)
|
||||
adjustToxLoss(200)
|
||||
else
|
||||
// could be more fancy, but doesn't worth the complexity: when the slimes goes into a cold area
|
||||
// the damage is mostly determined by how fast its body cools
|
||||
adjustToxLoss(30)
|
||||
|
||||
updatehealth()
|
||||
|
||||
return //TODO: DEFERRED
|
||||
|
||||
/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost)
|
||||
var/temperature = current
|
||||
var/difference = abs(current-loc_temp) //get difference
|
||||
var/increments// = difference/10 //find how many increments apart they are
|
||||
if(difference > 50)
|
||||
increments = difference/5
|
||||
else
|
||||
increments = difference/10
|
||||
var/change = increments*boost // Get the amount to change by (x per increment)
|
||||
var/temp_change
|
||||
if(current < loc_temp)
|
||||
temperature = min(loc_temp, temperature+change)
|
||||
else if(current > loc_temp)
|
||||
temperature = max(loc_temp, temperature-change)
|
||||
temp_change = (temperature - current)
|
||||
return temp_change
|
||||
|
||||
/mob/living/carbon/slime/handle_chemicals_in_body()
|
||||
chem_effects.Cut()
|
||||
|
||||
if(touching) touching.metabolize()
|
||||
if(ingested) ingested.metabolize()
|
||||
if(bloodstr) bloodstr.metabolize()
|
||||
|
||||
src.updatehealth()
|
||||
|
||||
return //TODO: DEFERRED
|
||||
|
||||
/mob/living/carbon/slime/handle_regular_status_updates()
|
||||
|
||||
src.blinded = null
|
||||
|
||||
health = getMaxHealth() - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
|
||||
|
||||
if(health < 0 && stat != DEAD)
|
||||
death()
|
||||
return
|
||||
|
||||
if (halloss)
|
||||
halloss = 0
|
||||
|
||||
if(prob(30))
|
||||
adjustOxyLoss(-1)
|
||||
adjustToxLoss(-1)
|
||||
adjustFireLoss(-1)
|
||||
adjustCloneLoss(-1)
|
||||
adjustBruteLoss(-1)
|
||||
|
||||
if (src.stat == DEAD)
|
||||
src.lying = 1
|
||||
src.blinded = 1
|
||||
else
|
||||
if (src.paralysis || src.stunned || src.weakened || (status_flags & FAKEDEATH)) //Stunned etc.
|
||||
if (src.stunned > 0)
|
||||
src.set_stat(CONSCIOUS)
|
||||
if (src.weakened > 0)
|
||||
src.lying = 0
|
||||
src.set_stat(CONSCIOUS)
|
||||
if (src.paralysis > 0)
|
||||
src.blinded = 0
|
||||
src.lying = 0
|
||||
src.set_stat(CONSCIOUS)
|
||||
|
||||
else
|
||||
src.lying = 0
|
||||
src.set_stat(CONSCIOUS)
|
||||
|
||||
if (src.stuttering) src.stuttering = 0
|
||||
|
||||
if (src.eye_blind)
|
||||
SetBlinded(0)
|
||||
src.blinded = 1
|
||||
|
||||
if (src.ear_deaf > 0) src.ear_deaf = 0
|
||||
if (src.ear_damage < 25)
|
||||
src.ear_damage = 0
|
||||
|
||||
src.density = !( src.lying )
|
||||
|
||||
if (src.sdisabilities & BLIND)
|
||||
src.blinded = 1
|
||||
if (src.sdisabilities & DEAF)
|
||||
src.ear_deaf = 1
|
||||
|
||||
if (src.eye_blurry > 0)
|
||||
src.eye_blurry = 0
|
||||
|
||||
if (src.druggy > 0)
|
||||
src.druggy = 0
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_nutrition()
|
||||
|
||||
if (prob(15))
|
||||
nutrition -= 1 + is_adult
|
||||
|
||||
if(nutrition <= 0)
|
||||
nutrition = 0
|
||||
adjustToxLoss(rand(1,3))
|
||||
if (client && prob(5))
|
||||
to_chat(src, "<span class='danger'>You are starving!</span>")
|
||||
|
||||
else if (nutrition >= get_grow_nutrition() && amount_grown < 10)
|
||||
nutrition -= 20
|
||||
amount_grown++
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_targets()
|
||||
if(attacked > 50) attacked = 50 // Let's not get into absurdly long periods of rage
|
||||
|
||||
if(attacked > 0)
|
||||
attacked--
|
||||
|
||||
if(Discipline > 0)
|
||||
|
||||
if(Discipline >= 5 && rabid)
|
||||
if(prob(60)) rabid = 0
|
||||
|
||||
if(prob(10))
|
||||
Discipline--
|
||||
|
||||
if(!canmove) return
|
||||
|
||||
if(Victim) return // if it's eating someone already, continue eating!
|
||||
|
||||
if(Target)
|
||||
--target_patience
|
||||
if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention
|
||||
target_patience = 0
|
||||
Target = null
|
||||
|
||||
var/hungry = 0 // determines if the slime is hungry
|
||||
|
||||
if (nutrition < get_starve_nutrition())
|
||||
hungry = 2
|
||||
else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
|
||||
hungry = 1
|
||||
|
||||
if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends
|
||||
if(Friends.len > 0 && prob(1))
|
||||
var/mob/nofriend = pick(Friends)
|
||||
if(nofriend && Friends[nofriend])
|
||||
Friends[nofriend] -= 1
|
||||
if (Friends[nofriend] <= 0)
|
||||
Friends[nofriend] = null
|
||||
Friends -= nofriend
|
||||
Friends -= null
|
||||
|
||||
if(!Target)
|
||||
if(will_hunt(hungry) || attacked || rabid) // Only add to the list if we need to
|
||||
var/list/targets = list()
|
||||
|
||||
for(var/mob/living/L in view(7,src))
|
||||
|
||||
if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs
|
||||
continue
|
||||
|
||||
if(L in Friends) // No eating friends!
|
||||
continue
|
||||
|
||||
if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence
|
||||
targets += L // Possible target found!
|
||||
|
||||
if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.species.name == "Promethean")
|
||||
continue
|
||||
|
||||
if(!L.canmove) // Only one slime can latch on at a time.
|
||||
var/notarget = 0
|
||||
for(var/mob/living/carbon/slime/M in view(1,L))
|
||||
if(M.Victim == L)
|
||||
notarget = 1
|
||||
if(notarget)
|
||||
continue
|
||||
|
||||
targets += L // Possible target found!
|
||||
|
||||
if(targets.len > 0)
|
||||
if(attacked || rabid || hungry == 2)
|
||||
Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care
|
||||
else
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
if(ishuman(C) && !Discipline && prob(5))
|
||||
Target = C
|
||||
break
|
||||
|
||||
if(isalien(C) || issmall(C) || isanimal(C))
|
||||
Target = C
|
||||
break
|
||||
|
||||
if (Target)
|
||||
target_patience = rand(5,7)
|
||||
if (is_adult)
|
||||
target_patience += 3
|
||||
|
||||
if(!Target) // If we have no target, we are wandering or following orders
|
||||
if (Leader)
|
||||
if (holding_still)
|
||||
holding_still = max(holding_still - 1, 0)
|
||||
else if(canmove && isturf(loc))
|
||||
step_to(src, Leader)
|
||||
|
||||
else if(hungry)
|
||||
if (holding_still)
|
||||
holding_still = max(holding_still - 1 - hungry, 0)
|
||||
else if(canmove && isturf(loc) && prob(50))
|
||||
step(src, pick(cardinal))
|
||||
|
||||
else
|
||||
if (holding_still)
|
||||
holding_still = max(holding_still - 1, 0)
|
||||
else if(canmove && isturf(loc) && prob(33))
|
||||
step(src, pick(cardinal))
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_AI() // the master AI process
|
||||
|
||||
if(stat == DEAD || client || Victim) return // If we're dead or have a client, we don't need AI, if we're feeding, we continue feeding
|
||||
AIproc = 1
|
||||
|
||||
if(amount_grown >= 10 && !Target)
|
||||
if(is_adult)
|
||||
Reproduce()
|
||||
else
|
||||
Evolve()
|
||||
AIproc = 0
|
||||
return
|
||||
|
||||
if(Target) // We're chasing the target
|
||||
if(Target.stat == DEAD)
|
||||
Target = null
|
||||
AIproc = 0
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/slime/M in view(1, Target))
|
||||
if(M.Victim == Target)
|
||||
Target = null
|
||||
AIproc = 0
|
||||
return
|
||||
|
||||
if(Target.Adjacent(src))
|
||||
if(istype(Target, /mob/living/silicon)) // Glomp the silicons
|
||||
if(!Atkcool)
|
||||
a_intent = I_HURT
|
||||
UnarmedAttack(Target)
|
||||
Atkcool = 1
|
||||
spawn(45)
|
||||
Atkcool = 0
|
||||
AIproc = 0
|
||||
return
|
||||
|
||||
if(Target.client && !Target.lying && prob(60 + powerlevel * 4)) // Try to take down the target first
|
||||
if(!Atkcool)
|
||||
Atkcool = 1
|
||||
spawn(45)
|
||||
Atkcool = 0
|
||||
|
||||
a_intent = I_DISARM
|
||||
UnarmedAttack(Target)
|
||||
|
||||
else
|
||||
if(!Atkcool)
|
||||
a_intent = I_GRAB
|
||||
UnarmedAttack(Target)
|
||||
|
||||
else if(Target in view(7, src))
|
||||
step_to(src, Target)
|
||||
|
||||
else
|
||||
Target = null
|
||||
AIproc = 0
|
||||
return
|
||||
|
||||
else
|
||||
var/mob/living/carbon/slime/frenemy
|
||||
for (var/mob/living/carbon/slime/S in view(1, src))
|
||||
if (S != src)
|
||||
frenemy = S
|
||||
if (frenemy && prob(1))
|
||||
if (frenemy.colour == colour)
|
||||
a_intent = I_HELP
|
||||
else
|
||||
a_intent = I_HURT
|
||||
UnarmedAttack(frenemy)
|
||||
|
||||
var/sleeptime = movement_delay()
|
||||
if(sleeptime <= 5) sleeptime = 5 // Maximum one action per half a second
|
||||
spawn (sleeptime)
|
||||
handle_AI()
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/proc/handle_speech_and_mood()
|
||||
//Mood starts here
|
||||
var/newmood = ""
|
||||
a_intent = I_HELP
|
||||
if (rabid || attacked)
|
||||
newmood = "angry"
|
||||
a_intent = I_HURT
|
||||
else if (Target) newmood = "mischevous"
|
||||
|
||||
if (!newmood)
|
||||
if (Discipline && prob(25))
|
||||
newmood = "pout"
|
||||
else if (prob(1))
|
||||
newmood = pick("sad", ":3", "pout")
|
||||
|
||||
if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood)
|
||||
if (prob(75)) newmood = mood
|
||||
|
||||
if (newmood != mood) // This is so we don't redraw them every time
|
||||
mood = newmood
|
||||
regenerate_icons()
|
||||
|
||||
//Speech understanding starts here
|
||||
var/to_say
|
||||
if (speech_buffer.len > 0)
|
||||
var/who = speech_buffer[1] // Who said it?
|
||||
var/phrase = speech_buffer[2] // What did they say?
|
||||
if ((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us
|
||||
if (findtext(phrase, "hello") || findtext(phrase, "hi"))
|
||||
to_say = pick("Hello...", "Hi...")
|
||||
else if (findtext(phrase, "follow"))
|
||||
if (Leader)
|
||||
if (Leader == who) // Already following him
|
||||
to_say = pick("Yes...", "Lead...", "Following...")
|
||||
else if (Friends[who] > Friends[Leader]) // VIVA
|
||||
Leader = who
|
||||
to_say = "Yes... I follow [who]..."
|
||||
else
|
||||
to_say = "No... I follow [Leader]..."
|
||||
else
|
||||
if (Friends[who] > 2)
|
||||
Leader = who
|
||||
to_say = "I follow..."
|
||||
else // Not friendly enough
|
||||
to_say = pick("No...", "I won't follow...")
|
||||
else if (findtext(phrase, "stop"))
|
||||
if (Victim) // We are asked to stop feeding
|
||||
if (Friends[who] > 4)
|
||||
Victim = null
|
||||
Target = null
|
||||
if (Friends[who] < 7)
|
||||
--Friends[who]
|
||||
to_say = "Grrr..." // I'm angry but I do it
|
||||
else
|
||||
to_say = "Fine..."
|
||||
else if (Target) // We are asked to stop chasing
|
||||
if (Friends[who] > 3)
|
||||
Target = null
|
||||
if (Friends[who] < 6)
|
||||
--Friends[who]
|
||||
to_say = "Grrr..." // I'm angry but I do it
|
||||
else
|
||||
to_say = "Fine..."
|
||||
else if (Leader) // We are asked to stop following
|
||||
if (Leader == who)
|
||||
to_say = "Yes... I'll stay..."
|
||||
Leader = null
|
||||
else
|
||||
if (Friends[who] > Friends[Leader])
|
||||
Leader = null
|
||||
to_say = "Yes... I'll stop..."
|
||||
else
|
||||
to_say = "No... I'll keep following..."
|
||||
else if (findtext(phrase, "stay"))
|
||||
if (Leader)
|
||||
if (Leader == who)
|
||||
holding_still = Friends[who] * 10
|
||||
to_say = "Yes... Staying..."
|
||||
else if (Friends[who] > Friends[Leader])
|
||||
holding_still = (Friends[who] - Friends[Leader]) * 10
|
||||
to_say = "Yes... Staying..."
|
||||
else
|
||||
to_say = "No... I'll keep following..."
|
||||
else
|
||||
if (Friends[who] > 2)
|
||||
holding_still = Friends[who] * 10
|
||||
to_say = "Yes... Staying..."
|
||||
else
|
||||
to_say = "No... I won't stay..."
|
||||
speech_buffer = list()
|
||||
|
||||
//Speech starts here
|
||||
if (to_say)
|
||||
say (to_say)
|
||||
else if(prob(1))
|
||||
emote(pick("bounce","sway","light","vibrate","jiggle"))
|
||||
else
|
||||
var/t = 10
|
||||
var/slimes_near = -1 // Don't count myself
|
||||
var/dead_slimes = 0
|
||||
var/friends_near = list()
|
||||
for (var/mob/living/carbon/M in view(7,src))
|
||||
if (isslime(M))
|
||||
++slimes_near
|
||||
if (M.stat == DEAD)
|
||||
++dead_slimes
|
||||
if (M in Friends)
|
||||
t += 20
|
||||
friends_near += M
|
||||
if (nutrition < get_hunger_nutrition()) t += 10
|
||||
if (nutrition < get_starve_nutrition()) t += 10
|
||||
if (prob(2) && prob(t))
|
||||
var/phrases = list()
|
||||
if (Target) phrases += "[Target]... looks tasty..."
|
||||
if (nutrition < get_starve_nutrition())
|
||||
phrases += "So... hungry..."
|
||||
phrases += "Very... hungry..."
|
||||
phrases += "Need... food..."
|
||||
phrases += "Must... eat..."
|
||||
else if (nutrition < get_hunger_nutrition())
|
||||
phrases += "Hungry..."
|
||||
phrases += "Where is the food?"
|
||||
phrases += "I want to eat..."
|
||||
phrases += "Rawr..."
|
||||
phrases += "Blop..."
|
||||
phrases += "Blorble..."
|
||||
if (rabid || attacked)
|
||||
phrases += "Hrr..."
|
||||
phrases += "Nhuu..."
|
||||
phrases += "Unn..."
|
||||
if (mood == ":3")
|
||||
phrases += "Purr..."
|
||||
if (attacked)
|
||||
phrases += "Grrr..."
|
||||
if (getToxLoss() > 30)
|
||||
phrases += "Cold..."
|
||||
if (getToxLoss() > 60)
|
||||
phrases += "So... cold..."
|
||||
phrases += "Very... cold..."
|
||||
if (getToxLoss() > 90)
|
||||
phrases += "..."
|
||||
phrases += "C... c..."
|
||||
if (Victim)
|
||||
phrases += "Nom..."
|
||||
phrases += "Tasty..."
|
||||
if (powerlevel > 3) phrases += "Bzzz..."
|
||||
if (powerlevel > 5) phrases += "Zap..."
|
||||
if (powerlevel > 8) phrases += "Zap... Bzz..."
|
||||
if (mood == "sad") phrases += "Bored..."
|
||||
if (slimes_near) phrases += "Brother..."
|
||||
if (slimes_near > 1) phrases += "Brothers..."
|
||||
if (dead_slimes) phrases += "What happened?"
|
||||
if (!slimes_near)
|
||||
phrases += "Lonely..."
|
||||
for (var/M in friends_near)
|
||||
phrases += "[M]... friend..."
|
||||
if (nutrition < get_hunger_nutrition())
|
||||
phrases += "[M]... feed me..."
|
||||
say (pick(phrases))
|
||||
|
||||
/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it
|
||||
if (is_adult) return 1200
|
||||
else return 1000
|
||||
|
||||
/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
|
||||
if (is_adult) return 1000
|
||||
else return 800
|
||||
|
||||
/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat
|
||||
if (is_adult) return 600
|
||||
else return 500
|
||||
|
||||
/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
|
||||
if (is_adult) return 300
|
||||
else return 200
|
||||
|
||||
/mob/living/carbon/slime/proc/will_hunt(var/hunger) // Check for being stopped from feeding and chasing
|
||||
if (hunger == 2 || rabid || attacked) return 1
|
||||
if (Leader) return 0
|
||||
if (holding_still) return 0
|
||||
if (hunger == 1 || prob(25))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/slime/slip() //Can't slip something without legs.
|
||||
return 0
|
||||
@@ -1,4 +0,0 @@
|
||||
/mob/living/carbon/slime/Login()
|
||||
..()
|
||||
update_hud()
|
||||
return
|
||||
@@ -1,384 +0,0 @@
|
||||
/mob/living/carbon/slime
|
||||
name = "baby slime"
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "grey baby slime"
|
||||
pass_flags = PASSTABLE
|
||||
var/is_adult = 0
|
||||
speak_emote = list("chirps")
|
||||
|
||||
plane = MOB_PLANE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
gender = NEUTER
|
||||
|
||||
update_icon = 0
|
||||
nutrition = 700
|
||||
|
||||
see_in_dark = 8
|
||||
update_slimes = 0
|
||||
|
||||
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
|
||||
// for the sake of cleanliness, though, here they are.
|
||||
status_flags = CANPARALYSE|CANPUSH
|
||||
|
||||
var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside
|
||||
var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35
|
||||
|
||||
var/powerlevel = 0 // 0-10 controls how much electricity they are generating
|
||||
var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
|
||||
|
||||
var/number = 0 // Used to understand when someone is talking to it
|
||||
|
||||
var/mob/living/Victim = null // the person the slime is currently feeding on
|
||||
var/mob/living/Target = null // AI variable - tells the slime to hunt this down
|
||||
var/mob/living/Leader = null // AI variable - tells the slime to follow this person
|
||||
|
||||
var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable
|
||||
var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with
|
||||
var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place
|
||||
var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target
|
||||
|
||||
var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting
|
||||
|
||||
var/list/speech_buffer = list() // Last phrase said near it and person who said it
|
||||
|
||||
var/mood = "" // To show its face
|
||||
|
||||
var/AIproc = 0 // If it's 0, we need to launch an AI proc
|
||||
var/Atkcool = 0 // attack cooldown
|
||||
var/SStun = 0 // NPC stun variable. Used to calm them down when they are attacked while feeding, or they will immediately re-attach
|
||||
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while. The part about freeze gun is a lie
|
||||
|
||||
var/hurt_temperature = T0C-50 // slime keeps taking damage when its bodytemperature is below this
|
||||
var/die_temperature = 50 // slime dies instantly when its bodytemperature is below this
|
||||
|
||||
///////////TIME FOR SUBSPECIES
|
||||
|
||||
var/colour = "grey"
|
||||
var/coretype = /obj/item/slime_extract/grey
|
||||
var/list/slime_mutation[4]
|
||||
|
||||
var/core_removal_stage = 0 //For removing cores.
|
||||
|
||||
/mob/living/carbon/slime/New(var/location, var/colour="grey")
|
||||
|
||||
verbs += /mob/living/proc/ventcrawl
|
||||
|
||||
src.colour = colour
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
real_name = name
|
||||
slime_mutation = mutation_table(colour)
|
||||
mutation_chance = rand(25, 35)
|
||||
var/sanitizedcolour = replacetext(colour, " ", "")
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
regenerate_icons()
|
||||
..(location)
|
||||
|
||||
/mob/living/carbon/slime/movement_delay()
|
||||
if (bodytemperature >= 330.23) // 135 F
|
||||
return -1 // slimes become supercharged at high temperatures
|
||||
|
||||
var/tally = 0
|
||||
|
||||
var/health_deficiency = (getMaxHealth() - health)
|
||||
if(health_deficiency >= 30) tally += (health_deficiency / 25)
|
||||
|
||||
if (bodytemperature < 183.222)
|
||||
tally += (283.222 - bodytemperature) / 10 * 1.75
|
||||
|
||||
if(reagents)
|
||||
if(reagents.has_reagent("hyperzine")) // Hyperzine slows slimes down
|
||||
tally *= 2
|
||||
|
||||
if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
|
||||
tally *= 5
|
||||
|
||||
if(health <= 0) // if damaged, the slime moves twice as slow
|
||||
tally *= 2
|
||||
|
||||
return tally + config.slime_delay
|
||||
|
||||
/mob/living/carbon/slime/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if ((!(yes) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
|
||||
if(isobj(AM) && !client && powerlevel > 0)
|
||||
var/probab = 10
|
||||
switch(powerlevel)
|
||||
if(1 to 2) probab = 20
|
||||
if(3 to 4) probab = 30
|
||||
if(5 to 6) probab = 40
|
||||
if(7 to 8) probab = 60
|
||||
if(9) probab = 70
|
||||
if(10) probab = 95
|
||||
if(prob(probab))
|
||||
if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
|
||||
if(nutrition <= get_hunger_nutrition() && !Atkcool)
|
||||
if (is_adult || prob(5))
|
||||
UnarmedAttack(AM)
|
||||
Atkcool = 1
|
||||
spawn(45)
|
||||
Atkcool = 0
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
|
||||
if(is_adult)
|
||||
if(istype(tmob, /mob/living/carbon/human))
|
||||
if(prob(90))
|
||||
now_pushing = 0
|
||||
return
|
||||
else
|
||||
if(istype(tmob, /mob/living/carbon/human))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
now_pushing = 0
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/slime/Process_Spacemove()
|
||||
return 2
|
||||
|
||||
/mob/living/carbon/slime/Stat()
|
||||
..()
|
||||
|
||||
statpanel("Status")
|
||||
stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
|
||||
stat(null, "Intent: [a_intent]")
|
||||
|
||||
if (client.statpanel == "Status")
|
||||
stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
|
||||
if(amount_grown >= 10)
|
||||
if(is_adult)
|
||||
stat(null, "You can reproduce!")
|
||||
else
|
||||
stat(null, "You can evolve!")
|
||||
|
||||
stat(null,"Power Level: [powerlevel]")
|
||||
|
||||
/mob/living/carbon/slime/adjustFireLoss(amount)
|
||||
..(-abs(amount)) // Heals them
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/bullet_act(var/obj/item/projectile/Proj)
|
||||
attacked += 10
|
||||
..(Proj)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/slime/emp_act(severity)
|
||||
powerlevel = 0 // oh no, the power!
|
||||
..()
|
||||
|
||||
/mob/living/carbon/slime/ex_act(severity)
|
||||
..()
|
||||
|
||||
var/b_loss = null
|
||||
var/f_loss = null
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if (2.0)
|
||||
|
||||
b_loss += 60
|
||||
f_loss += 60
|
||||
|
||||
|
||||
if(3.0)
|
||||
b_loss += 30
|
||||
|
||||
adjustBruteLoss(b_loss)
|
||||
adjustFireLoss(f_loss)
|
||||
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/slime/u_equip(obj/item/W as obj)
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/attack_ui(slot)
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob)
|
||||
|
||||
..()
|
||||
|
||||
if(Victim)
|
||||
if(Victim == M)
|
||||
if(prob(60))
|
||||
visible_message("<span class='warning'>[M] attempts to wrestle \the [name] off!</span>")
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
|
||||
else
|
||||
visible_message("<span class='warning'> [M] manages to wrestle \the [name] off!</span>")
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(prob(90) && !client)
|
||||
Discipline++
|
||||
|
||||
SStun = 1
|
||||
spawn(rand(45,60))
|
||||
SStun = 0
|
||||
|
||||
Victim = null
|
||||
anchored = 0
|
||||
step_away(src,M)
|
||||
|
||||
return
|
||||
|
||||
else
|
||||
if(prob(30))
|
||||
visible_message("<span class='warning'>[M] attempts to wrestle \the [name] off of [Victim]!</span>")
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
|
||||
else
|
||||
visible_message("<span class='warning'> [M] manages to wrestle \the [name] off of [Victim]!</span>")
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(prob(80) && !client)
|
||||
Discipline++
|
||||
|
||||
if(!is_adult)
|
||||
if(Discipline == 1)
|
||||
attacked = 0
|
||||
|
||||
SStun = 1
|
||||
spawn(rand(55,65))
|
||||
SStun = 0
|
||||
|
||||
Victim = null
|
||||
anchored = 0
|
||||
step_away(src,M)
|
||||
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
|
||||
if (I_HELP)
|
||||
help_shake_act(M)
|
||||
|
||||
if (I_GRAB)
|
||||
if (M == src || anchored)
|
||||
return
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
|
||||
|
||||
M.put_in_active_hand(G)
|
||||
|
||||
G.synch()
|
||||
|
||||
LAssailant = M
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='warning'>[M] has grabbed [src] passively!</span>")
|
||||
|
||||
else
|
||||
|
||||
var/damage = rand(1, 9)
|
||||
|
||||
attacked += 10
|
||||
if (prob(90))
|
||||
if (HULK in M.mutations)
|
||||
damage += 5
|
||||
if(Victim || Target)
|
||||
Victim = null
|
||||
Target = null
|
||||
anchored = 0
|
||||
if(prob(80) && !client)
|
||||
Discipline++
|
||||
spawn(0)
|
||||
step_away(src,M,15)
|
||||
sleep(3)
|
||||
step_away(src,M,15)
|
||||
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='danger'>[M] has punched [src]!</span>")
|
||||
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/attackby(obj/item/W, mob/user)
|
||||
if(W.force > 0)
|
||||
attacked += 10
|
||||
if(prob(25))
|
||||
to_chat(user, "<span class='danger'>[W] passes right through [src]!</span>")
|
||||
return
|
||||
if(Discipline && prob(50)) // wow, buddy, why am I getting attacked??
|
||||
Discipline = 0
|
||||
if(W.force >= 3)
|
||||
if(is_adult)
|
||||
if(prob(5 + round(W.force/2)))
|
||||
if(Victim || Target)
|
||||
if(prob(80) && !client)
|
||||
Discipline++
|
||||
|
||||
Victim = null
|
||||
Target = null
|
||||
anchored = 0
|
||||
|
||||
SStun = 1
|
||||
spawn(rand(5,20))
|
||||
SStun = 0
|
||||
|
||||
spawn(0)
|
||||
if(user)
|
||||
canmove = 0
|
||||
step_away(src, user)
|
||||
if(prob(25 + W.force))
|
||||
sleep(2)
|
||||
if(user)
|
||||
step_away(src, user)
|
||||
canmove = 1
|
||||
|
||||
else
|
||||
if(prob(10 + W.force*2))
|
||||
if(Victim || Target)
|
||||
if(prob(80) && !client)
|
||||
Discipline++
|
||||
if(Discipline == 1)
|
||||
attacked = 0
|
||||
SStun = 1
|
||||
spawn(rand(5,20))
|
||||
SStun = 0
|
||||
|
||||
Victim = null
|
||||
Target = null
|
||||
anchored = 0
|
||||
|
||||
spawn(0)
|
||||
if(user)
|
||||
canmove = 0
|
||||
step_away(src, user)
|
||||
if(prob(25 + W.force*4))
|
||||
sleep(2)
|
||||
if(user)
|
||||
step_away(src, user)
|
||||
canmove = 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/slime/restrained()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/slime/var/co2overloadtime = null
|
||||
/mob/living/carbon/slime/var/temperature_resistance = T0C+75
|
||||
|
||||
/mob/living/carbon/slime/toggle_throw_mode()
|
||||
return
|
||||
|
||||
/mob/living/carbon/slime/proc/gain_nutrition(var/amount)
|
||||
nutrition += amount
|
||||
if(prob(amount * 2)) // Gain around one level per 50 nutrition
|
||||
powerlevel++
|
||||
if(powerlevel > 10)
|
||||
powerlevel = 10
|
||||
adjustToxLoss(-10)
|
||||
nutrition = max(nutrition, get_max_nutrition())
|
||||
@@ -1,39 +0,0 @@
|
||||
/mob/living/carbon/slime/say(var/message)
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
var/verb = say_quote(message)
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
return emote(copytext(message,2))
|
||||
|
||||
return ..(message, null, verb)
|
||||
|
||||
/mob/living/carbon/slime/say_quote(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
|
||||
if (ending == "?")
|
||||
return "asks";
|
||||
else if (ending == "!")
|
||||
return "cries";
|
||||
|
||||
return "chirps";
|
||||
|
||||
/mob/living/carbon/slime/say_understands(var/other)
|
||||
if (istype(other, /mob/living/carbon/slime))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
|
||||
if (speaker in Friends)
|
||||
speech_buffer = list()
|
||||
speech_buffer.Add(speaker)
|
||||
speech_buffer.Add(lowertext(html_decode(message)))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/slime/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
|
||||
if (speaker in Friends)
|
||||
speech_buffer = list()
|
||||
speech_buffer.Add(speaker)
|
||||
speech_buffer.Add(lowertext(html_decode(message)))
|
||||
..()
|
||||
@@ -1,79 +0,0 @@
|
||||
/mob/living/carbon/slime/proc/mutation_table(var/colour)
|
||||
var/list/slime_mutation[4]
|
||||
switch(colour)
|
||||
//Tier 1
|
||||
if("grey")
|
||||
slime_mutation[1] = "orange"
|
||||
slime_mutation[2] = "metal"
|
||||
slime_mutation[3] = "blue"
|
||||
slime_mutation[4] = "purple"
|
||||
//Tier 2
|
||||
if("purple")
|
||||
slime_mutation[1] = "dark purple"
|
||||
slime_mutation[2] = "dark blue"
|
||||
slime_mutation[3] = "green"
|
||||
slime_mutation[4] = "green"
|
||||
if("metal")
|
||||
slime_mutation[1] = "silver"
|
||||
slime_mutation[2] = "yellow"
|
||||
slime_mutation[3] = "gold"
|
||||
slime_mutation[4] = "gold"
|
||||
if("orange")
|
||||
slime_mutation[1] = "dark purple"
|
||||
slime_mutation[2] = "yellow"
|
||||
slime_mutation[3] = "red"
|
||||
slime_mutation[4] = "red"
|
||||
if("blue")
|
||||
slime_mutation[1] = "dark blue"
|
||||
slime_mutation[2] = "silver"
|
||||
slime_mutation[3] = "pink"
|
||||
slime_mutation[4] = "pink"
|
||||
//Tier 3
|
||||
if("dark blue")
|
||||
slime_mutation[1] = "purple"
|
||||
slime_mutation[2] = "purple"
|
||||
slime_mutation[3] = "blue"
|
||||
slime_mutation[4] = "blue"
|
||||
if("dark purple")
|
||||
slime_mutation[1] = "purple"
|
||||
slime_mutation[2] = "purple"
|
||||
slime_mutation[3] = "orange"
|
||||
slime_mutation[4] = "orange"
|
||||
if("yellow")
|
||||
slime_mutation[1] = "metal"
|
||||
slime_mutation[2] = "metal"
|
||||
slime_mutation[3] = "orange"
|
||||
slime_mutation[4] = "orange"
|
||||
if("silver")
|
||||
slime_mutation[1] = "metal"
|
||||
slime_mutation[2] = "metal"
|
||||
slime_mutation[3] = "blue"
|
||||
slime_mutation[4] = "blue"
|
||||
//Tier 4
|
||||
if("pink")
|
||||
slime_mutation[1] = "pink"
|
||||
slime_mutation[2] = "pink"
|
||||
slime_mutation[3] = "light pink"
|
||||
slime_mutation[4] = "light pink"
|
||||
if("red")
|
||||
slime_mutation[1] = "red"
|
||||
slime_mutation[2] = "red"
|
||||
slime_mutation[3] = "oil"
|
||||
slime_mutation[4] = "oil"
|
||||
if("gold")
|
||||
slime_mutation[1] = "gold"
|
||||
slime_mutation[2] = "gold"
|
||||
slime_mutation[3] = "adamantine"
|
||||
slime_mutation[4] = "adamantine"
|
||||
if("green")
|
||||
slime_mutation[1] = "green"
|
||||
slime_mutation[2] = "green"
|
||||
slime_mutation[3] = "black"
|
||||
slime_mutation[4] = "black"
|
||||
// Tier 5
|
||||
else
|
||||
slime_mutation[1] = colour
|
||||
slime_mutation[2] = colour
|
||||
slime_mutation[3] = colour
|
||||
slime_mutation[4] = colour
|
||||
return(slime_mutation)
|
||||
@@ -1,9 +0,0 @@
|
||||
/mob/living/carbon/slime/regenerate_icons()
|
||||
if (stat == DEAD)
|
||||
icon_state = "[colour] baby slime dead"
|
||||
else
|
||||
icon_state = "[colour] [is_adult ? "adult" : "baby"] slime[Victim ? "" : " eat"]"
|
||||
overlays.len = 0
|
||||
if (mood)
|
||||
overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]")
|
||||
..()
|
||||
@@ -10,7 +10,7 @@
|
||||
return 0
|
||||
|
||||
if(language == GLOB.all_languages[src.species_language])
|
||||
to_chat(src, "<span class='notice'>You will now speak your standard default language, [language], if you do not specify a language when speaking.</span>")
|
||||
to_chat(src, "<span class='notice'>You will now speak your standard default language, [language ? language : "common"], if you do not specify a language when speaking.</span>")
|
||||
else if (language)
|
||||
|
||||
if(language && !can_speak(language))
|
||||
|
||||
+133
-95
@@ -70,34 +70,23 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return key
|
||||
|
||||
/mob/living/proc/binarycheck()
|
||||
return FALSE
|
||||
|
||||
if (istype(src, /mob/living/silicon/pai))
|
||||
return
|
||||
/mob/proc/get_default_language()
|
||||
return null
|
||||
|
||||
if (!ishuman(src))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if (H.l_ear || H.r_ear)
|
||||
var/obj/item/device/radio/headset/dongle
|
||||
if(istype(H.l_ear,/obj/item/device/radio/headset))
|
||||
dongle = H.l_ear
|
||||
else
|
||||
dongle = H.r_ear
|
||||
if(!istype(dongle)) return
|
||||
if(dongle.translate_binary) return 1
|
||||
|
||||
/mob/living/proc/get_default_language()
|
||||
/mob/living/get_default_language()
|
||||
return default_language
|
||||
|
||||
//Takes a list of the form list(message, verb, whispering) and modifies it as needed
|
||||
//Returns 1 if a speech problem was applied, 0 otherwise
|
||||
/mob/living/proc/handle_speech_problems(var/list/message_data)
|
||||
var/message = message_data[1]
|
||||
var/list/message_pieces = message_data[1]
|
||||
var/verb = message_data[2]
|
||||
var/whispering = message_data[3]
|
||||
. = 0
|
||||
|
||||
<<<<<<< HEAD
|
||||
if((HULK in mutations) && health >= 25 && length(message))
|
||||
message = "[uppertext(message)]!!!"
|
||||
verb = pick("yells","roars","hollers")
|
||||
@@ -119,13 +108,35 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
//VOREStation Edit End
|
||||
|
||||
message_data[1] = message
|
||||
=======
|
||||
// Technically this rerolls the verb for as many say pieces as there are. _shrug_
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking && (S.speaking.flags & NO_STUTTER || S.speaking.flags & SIGNLANG))
|
||||
continue
|
||||
|
||||
if((HULK in mutations) && health >= 25 && length(S.message))
|
||||
S.message = "[uppertext(S.message)]!!!"
|
||||
verb = pick("yells","roars","hollers")
|
||||
whispering = 0
|
||||
. = 1
|
||||
if(slurring)
|
||||
S.message = slur(S.message)
|
||||
verb = pick("slobbers","slurs")
|
||||
. = 1
|
||||
if(stuttering)
|
||||
S.message = stutter(S.message)
|
||||
verb = pick("stammers","stutters")
|
||||
. = 1
|
||||
|
||||
message_data[1] = message_pieces
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
message_data[2] = verb
|
||||
message_data[3] = whispering
|
||||
|
||||
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/proc/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
|
||||
if(message_mode == "intercom")
|
||||
for(var/obj/item/device/radio/intercom/I in view(1, null))
|
||||
I.talk_into(src, message, verb, speaking)
|
||||
I.talk_into(src, message_pieces, verb)
|
||||
used_radios += I
|
||||
return 0
|
||||
|
||||
@@ -136,13 +147,13 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
return returns
|
||||
|
||||
/mob/living/proc/get_speech_ending(verb, var/ending)
|
||||
if(ending=="!")
|
||||
if(ending == "!")
|
||||
return pick("exclaims","shouts","yells")
|
||||
if(ending=="?")
|
||||
if(ending == "?")
|
||||
return "asks"
|
||||
return verb
|
||||
|
||||
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering = 0)
|
||||
/mob/living/say(var/message, var/whispering = 0)
|
||||
//If you're muted for IC chat
|
||||
if(client)
|
||||
if(message)
|
||||
@@ -161,98 +172,81 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
//Maybe they are using say/whisper to do a quick emote, so do those
|
||||
switch(copytext(message,1,2))
|
||||
if("*") return emote(copytext(message,2))
|
||||
if("^") return custom_emote(1, copytext(message,2))
|
||||
switch(copytext(message, 1, 2))
|
||||
if("*") return emote(copytext(message, 2))
|
||||
if("^") return custom_emote(1, copytext(message, 2))
|
||||
|
||||
//Parse the radio code and consume it
|
||||
if (message_mode)
|
||||
if (message_mode == "headset")
|
||||
message = copytext(message,2) //it would be really nice if the parse procs could do this for us.
|
||||
else if (message_mode == "whisper")
|
||||
if(message_mode)
|
||||
if(message_mode == "headset")
|
||||
message = copytext(message, 2) //it would be really nice if the parse procs could do this for us.
|
||||
else if(message_mode == "whisper")
|
||||
whispering = 1
|
||||
message_mode = null
|
||||
message = copytext(message,3)
|
||||
message = copytext(message, 3)
|
||||
else
|
||||
message = copytext(message,3)
|
||||
message = copytext(message, 3)
|
||||
|
||||
//Clean up any remaining space on the left
|
||||
message = trim_left(message)
|
||||
|
||||
//Parse the language code and consume it
|
||||
if(!speaking)
|
||||
speaking = parse_language(message)
|
||||
|
||||
if(!speaking)
|
||||
speaking = get_default_language()
|
||||
|
||||
if(!can_speak(speaking))
|
||||
speaking = GLOB.all_languages[LANGUAGE_GIBBERISH]
|
||||
var/babble_key = ",r"
|
||||
message = babble_key + message
|
||||
|
||||
if(speaking == get_default_language())
|
||||
var/new_message = ",[speaking.key]"
|
||||
new_message += message
|
||||
message = new_message
|
||||
|
||||
if(speaking)
|
||||
message = copytext(message,2+length(speaking.key))
|
||||
|
||||
//HIVEMIND languages always send to all people with that language
|
||||
if(speaking && (speaking.flags & HIVEMIND))
|
||||
speaking.broadcast(src,trim(message))
|
||||
var/list/message_pieces = parse_languages(message)
|
||||
if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quark for dealing with hivemind/signlang languages.
|
||||
var/datum/multilingual_say_piece/S = message_pieces // Yay for BYOND's hilariously broken typecasting for allowing us to do this.
|
||||
S.speaking.broadcast(src, S.message)
|
||||
return 1
|
||||
|
||||
//Self explanatory.
|
||||
if(is_muzzled() && !(speaking && (speaking.flags & SIGNLANG)))
|
||||
if(!LAZYLEN(message_pieces))
|
||||
log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]"))
|
||||
return 0
|
||||
|
||||
// If you're muzzled, you can only speak sign language
|
||||
// However, sign language is handled above.
|
||||
if(is_muzzled())
|
||||
to_chat(src, "<span class='danger'>You're muzzled and cannot speak!</span>")
|
||||
return
|
||||
|
||||
//Clean up any remaining junk on the left like spaces.
|
||||
message = trim_left(message)
|
||||
|
||||
//Autohiss handles auto-rolling tajaran R's and unathi S's/Z's
|
||||
message = handle_autohiss(message, speaking)
|
||||
|
||||
//Whisper vars
|
||||
var/w_scramble_range = 5 //The range at which you get ***as*th**wi****
|
||||
var/w_adverb //An adverb prepended to the verb in whispers
|
||||
var/w_not_heard //The message for people in watching range
|
||||
|
||||
var/datum/multilingual_say_piece/first_piece = message_pieces[1]
|
||||
var/verb = ""
|
||||
//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)
|
||||
else if(whispering && speaking.whisper_verb) //Language has defined whisper verb
|
||||
verb = speaking.whisper_verb
|
||||
verb = say_quote(message, first_piece.speaking)
|
||||
else if(whispering && first_piece.speaking.whisper_verb) //Language has defined whisper verb
|
||||
verb = first_piece.speaking.whisper_verb
|
||||
w_not_heard = "[verb] something"
|
||||
else //Whispering but language has no whisper verb, use say verb
|
||||
w_adverb = pick("quietly", "softly")
|
||||
verb = speaking.speech_verb
|
||||
w_not_heard = "[speaking.speech_verb] something [w_adverb]"
|
||||
verb = first_piece.speaking.speech_verb
|
||||
w_not_heard = "[first_piece.speaking.speech_verb] something [w_adverb]"
|
||||
|
||||
//For speech disorders (hulk, slurring, stuttering)
|
||||
if(!(speaking && (speaking.flags & NO_STUTTER || speaking.flags & SIGNLANG)))
|
||||
var/list/message_data = list(message, verb, whispering)
|
||||
if(handle_speech_problems(message_data))
|
||||
message = message_data[1]
|
||||
whispering = message_data[3]
|
||||
var/list/message_data = list(message_pieces, verb, whispering)
|
||||
if(handle_speech_problems(message_data))
|
||||
message_pieces = message_data[1]
|
||||
whispering = message_data[3]
|
||||
|
||||
if(verb != message_data[2]) //They changed our verb
|
||||
if(whispering)
|
||||
w_adverb = pick("quietly", "softly")
|
||||
verb = message_data[2]
|
||||
if(verb != message_data[2]) //They changed our verb
|
||||
if(whispering)
|
||||
w_adverb = pick("quietly", "softly")
|
||||
verb = message_data[2]
|
||||
|
||||
//Whisper may have adverbs, add those if one was set
|
||||
if(w_adverb) verb = "[verb] [w_adverb]"
|
||||
if(w_adverb)
|
||||
verb = "[verb] [w_adverb]"
|
||||
|
||||
//If something nulled or emptied the message, forget it
|
||||
if(!message || message == "")
|
||||
if(!LAZYLEN(message_pieces))
|
||||
return 0
|
||||
|
||||
//Radio message handling
|
||||
var/list/obj/item/used_radios = new
|
||||
if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, whispering))
|
||||
var/list/used_radios = list()
|
||||
if(handle_message_mode(message_mode, message_pieces, verb, used_radios, whispering))
|
||||
return 1
|
||||
|
||||
//For languages with actual speech sounds
|
||||
@@ -268,16 +262,19 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(used_radios.len)
|
||||
italics = 1
|
||||
message_range = 1
|
||||
if(speaking)
|
||||
message_range = speaking.get_talkinto_msg_range(message)
|
||||
|
||||
if(first_piece.speaking)
|
||||
message_range = first_piece.speaking.get_talkinto_msg_range(message)
|
||||
var/msg
|
||||
if(!speaking || !(speaking.flags & NO_TALK_MSG))
|
||||
msg = "<span class='notice'>\The [src] talks into \the [used_radios[1]]</span>"
|
||||
for(var/mob/living/M in hearers(5, src))
|
||||
if((M != src) && msg)
|
||||
if(!first_piece.speaking || !(first_piece.speaking.flags & NO_TALK_MSG))
|
||||
msg = "<span class='notice'>[src] talks into [used_radios[1]]</span>"
|
||||
|
||||
if(msg)
|
||||
for(var/mob/living/M in hearers(5, src) - src)
|
||||
M.show_message(msg)
|
||||
if (speech_sound)
|
||||
sound_vol *= 0.5
|
||||
|
||||
if(speech_sound)
|
||||
sound_vol *= 0.5
|
||||
|
||||
//Set vars if we're still whispering by this point
|
||||
if(whispering)
|
||||
@@ -285,6 +282,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
message_range = 1
|
||||
sound_vol *= 0.5
|
||||
|
||||
<<<<<<< HEAD
|
||||
//VOREStation edit - allows for custom say verbs, overriding all other say-verb types- e.g. "says loudly" instead of "shouts"
|
||||
//You'll still stammer if injured or slur if drunk, but it won't have those specific words
|
||||
var/ending = copytext(message, length(message))
|
||||
@@ -308,6 +306,13 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if (speaking.flags & NONVERBAL)
|
||||
if (prob(30))
|
||||
src.custom_emote(1, "[pick(speaking.signlang_verb)].")
|
||||
=======
|
||||
//Handle nonverbal languages here
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking.flags & NONVERBAL)
|
||||
if(prob(30))
|
||||
custom_emote(1, "[pick(S.speaking.signlang_verb)].")
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
//These will contain the main receivers of the message
|
||||
var/list/listening = list()
|
||||
@@ -318,12 +323,12 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(T)
|
||||
//Air is too thin to carry sound at all, contact speech only
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = (environment)? environment.return_pressure() : 0
|
||||
var/pressure = environment ? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE)
|
||||
message_range = 1
|
||||
|
||||
//Air is nearing minimum levels, make text italics as a hint, and muffle sound
|
||||
if (pressure < ONE_ATMOSPHERE*0.4)
|
||||
if(pressure < ONE_ATMOSPHERE * 0.4)
|
||||
italics = 1
|
||||
sound_vol *= 0.5
|
||||
|
||||
@@ -376,16 +381,16 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
var/image/I1 = listening[M] || speech_bubble
|
||||
images_to_clients[I1] |= M.client
|
||||
M << I1
|
||||
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
|
||||
M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol)
|
||||
if(whispering) //Don't even bother with these unless whispering
|
||||
if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range
|
||||
if(M.client)
|
||||
var/image/I2 = listening[M] || speech_bubble
|
||||
images_to_clients[I2] |= M.client
|
||||
M << I2
|
||||
M.hear_say(stars(message), verb, speaking, alt_name, italics, src, speech_sound, sound_vol*0.2)
|
||||
M.hear_say(stars_all(message_pieces), verb, italics, src, speech_sound, sound_vol*0.2)
|
||||
if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range
|
||||
M.show_message("<span class='game say'><span class='name'>[src.name]</span> [w_not_heard].</span>", 2)
|
||||
M.show_message("<span class='game say'><span class='name'>[name]</span> [w_not_heard].</span>", 2)
|
||||
|
||||
//Object message delivery
|
||||
for(var/obj/O in listening_obj)
|
||||
@@ -393,7 +398,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(O && src) //If we still exist, when the spawn processes
|
||||
var/dst = get_dist(get_turf(O),get_turf(src))
|
||||
if(dst <= message_range)
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
O.hear_talk(src, message_pieces, verb)
|
||||
|
||||
//Remove all those images. At least it's just ONE spawn this time.
|
||||
spawn(30)
|
||||
@@ -410,7 +415,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(message_mode)
|
||||
message = "([message_mode == "headset" ? "Common" : capitalize(message_mode)]) [message]" //Adds radio keys used if available
|
||||
if(whispering)
|
||||
log_whisper(message,src)
|
||||
log_whisper(message, src)
|
||||
else
|
||||
log_say(message, src)
|
||||
return 1
|
||||
@@ -438,8 +443,41 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
/obj/effect/speech_bubble
|
||||
var/mob/parent
|
||||
|
||||
/mob/living/proc/GetVoice()
|
||||
/mob/proc/GetVoice()
|
||||
return name
|
||||
|
||||
/mob/living/emote(var/act, var/type, var/message) //emote code is terrible, this is so that anything that isn't
|
||||
if(stat) //already snowflaked to shit can call the parent and handle emoting sanely
|
||||
return FALSE
|
||||
|
||||
if(..(act, type, message))
|
||||
return TRUE
|
||||
|
||||
if(act && type && message)
|
||||
log_emote(message, src)
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.is_preference_enabled(/datum/client_preference/ghost_sight))
|
||||
M.show_message(message)
|
||||
|
||||
switch(type)
|
||||
if(1) // Visible
|
||||
visible_message(message)
|
||||
return TRUE
|
||||
if(2) // Audible
|
||||
audible_message(message)
|
||||
return TRUE
|
||||
else
|
||||
if(act == "help")
|
||||
return // Mobs handle this individually
|
||||
to_chat(src, "<span class='warning'>Unusable emote '[act]'. Say *help for a list.</span>")
|
||||
|
||||
|
||||
/mob/proc/speech_bubble_appearance()
|
||||
return "normal"
|
||||
|
||||
@@ -837,6 +837,69 @@ var/list/ai_verbs_default = list(
|
||||
// If that is ever fixed please update this proc.
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/silicon/ai/handle_track(message, verb = "says", mob/speaker = null, speaker_name, hard_to_hear)
|
||||
if(hard_to_hear)
|
||||
return
|
||||
|
||||
var/jobname // the mob's "job"
|
||||
var/mob/living/carbon/human/impersonating //The crew member being impersonated, if any.
|
||||
var/changed_voice
|
||||
|
||||
if(ishuman(speaker))
|
||||
var/mob/living/carbon/human/H = speaker
|
||||
|
||||
if(H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))
|
||||
changed_voice = 1
|
||||
var/list/impersonated = new()
|
||||
var/mob/living/carbon/human/I = impersonated[speaker_name]
|
||||
|
||||
if(!I)
|
||||
for(var/mob/living/carbon/human/M in mob_list)
|
||||
if(M.real_name == speaker_name)
|
||||
I = M
|
||||
impersonated[speaker_name] = I
|
||||
break
|
||||
|
||||
// If I's display name is currently different from the voice name and using an agent ID then don't impersonate
|
||||
// as this would allow the AI to track I and realize the mismatch.
|
||||
if(I && !(I.name != speaker_name && I.wear_id && istype(I.wear_id,/obj/item/weapon/card/id/syndicate)))
|
||||
impersonating = I
|
||||
jobname = impersonating.get_assignment()
|
||||
else
|
||||
jobname = "Unknown"
|
||||
else
|
||||
jobname = H.get_assignment()
|
||||
|
||||
else if(iscarbon(speaker)) // Nonhuman carbon mob
|
||||
jobname = "No id"
|
||||
else if(isAI(speaker))
|
||||
jobname = "AI"
|
||||
else if(isrobot(speaker))
|
||||
jobname = "Cyborg"
|
||||
else if(istype(speaker, /mob/living/silicon/pai))
|
||||
jobname = "Personal AI"
|
||||
else
|
||||
jobname = "Unknown"
|
||||
|
||||
var/track = ""
|
||||
if(changed_voice)
|
||||
if(impersonating)
|
||||
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
|
||||
else
|
||||
track = "[speaker_name] ([jobname])"
|
||||
else
|
||||
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
|
||||
|
||||
return track
|
||||
|
||||
/mob/living/silicon/ai/proc/relay_speech(mob/living/M, list/message_pieces, verb)
|
||||
var/message = combine_message(message_pieces, verb, M)
|
||||
var/name_used = M.GetVoice()
|
||||
//This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only.
|
||||
var/rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [message]</span></i>"
|
||||
show_message(rendered, 2)
|
||||
|
||||
//Special subtype kept around for global announcements
|
||||
/mob/living/silicon/ai/announcer/
|
||||
is_dummy = 1
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/mob/living/silicon/emote(var/act, var/m_type = 1,var/message = null)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act, "s", -1) && !findtext(act, "_", -2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act, 1, length(act))
|
||||
|
||||
switch(act)
|
||||
if("beep")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> beeps at [param]."
|
||||
else
|
||||
message = "<b>[src]</b> beeps."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("ping")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> pings at [param]."
|
||||
else
|
||||
message = "<b>[src]</b> pings."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("buzz")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> buzzes at [param]."
|
||||
else
|
||||
message = "<b>[src]</b> buzzes."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("yes", "ye")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> emits an affirmative blip at [param]."
|
||||
else
|
||||
message = "<b>[src]</b> emits an affirmative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("dwoop")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> chirps happily at [param]"
|
||||
else
|
||||
message = "<b>[src]</b> chirps happily."
|
||||
playsound(src.loc, 'sound/machines/dwoop.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("no")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "<b>[src]</b> emits a negative blip at [param]."
|
||||
else
|
||||
message = "<b>[src]</b> emits a negative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
..(act, m_type, message)
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/pai/say(var/msg)
|
||||
/mob/living/silicon/pai/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
if(silence_time)
|
||||
to_chat(src, "<font color=green>Communication circuits remain uninitialized.</font>")
|
||||
else
|
||||
..(msg)
|
||||
..()
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/silicon/robot/drone/say(var/message)
|
||||
/mob/living/silicon/robot/drone/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
if(local_transmit)
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
@@ -36,4 +36,4 @@
|
||||
if(M.client)
|
||||
to_chat(M, "<b>[src]</b> transmits, \"[message]\"")
|
||||
return 1
|
||||
return ..(message, 0)
|
||||
return ..()
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/silicon/robot/emote(var/act,var/m_type=1,var/message = null)
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
@@ -9,236 +9,124 @@
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
switch(act)
|
||||
if ("me")
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "You cannot send IC messages (muted).")
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
else
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if ("custom")
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if ("salute")
|
||||
if (!src.buckled)
|
||||
if("salute")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "salutes to [param]."
|
||||
if(param)
|
||||
message = "<b>[src]</b> salutes to [param]."
|
||||
else
|
||||
message = "salutes."
|
||||
message = "<b>[src]</b> salutes."
|
||||
m_type = 1
|
||||
if ("bow")
|
||||
if (!src.buckled)
|
||||
if("bow")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "bows to [param]."
|
||||
if(param)
|
||||
message = "<b>[src]</b> bows to [param]."
|
||||
else
|
||||
message = "bows."
|
||||
message = "<b>[src]</b> bows."
|
||||
m_type = 1
|
||||
|
||||
if ("clap")
|
||||
if (!src.restrained())
|
||||
message = "claps."
|
||||
if("clap")
|
||||
if(!src.restrained())
|
||||
message = "<b>[src]</b> claps."
|
||||
m_type = 2
|
||||
if ("flap")
|
||||
if (!src.restrained())
|
||||
message = "flaps its wings."
|
||||
if("flap")
|
||||
if(!src.restrained())
|
||||
message = "<b>[src]</b> flaps its wings."
|
||||
m_type = 2
|
||||
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "flaps its wings ANGRILY!"
|
||||
if("aflap")
|
||||
if(!src.restrained())
|
||||
message = "<b>[src]</b> flaps its wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("twitch")
|
||||
message = "twitches."
|
||||
if("twitch")
|
||||
message = "<b>[src]</b> twitches."
|
||||
m_type = 1
|
||||
|
||||
if ("twitch_v")
|
||||
message = "twitches violently."
|
||||
if("twitch_v")
|
||||
message = "<b>[src]</b> twitches violently."
|
||||
m_type = 1
|
||||
|
||||
if ("nod")
|
||||
message = "nods."
|
||||
if("nod")
|
||||
message = "<b>[src]</b> nods."
|
||||
m_type = 1
|
||||
|
||||
if ("deathgasp")
|
||||
message = "shudders violently for a moment, then becomes motionless, its eyes slowly darkening."
|
||||
if("deathgasp")
|
||||
message = "<b>[src]</b> shudders violently for a moment, then becomes motionless, its eyes slowly darkening."
|
||||
m_type = 1
|
||||
|
||||
if ("glare")
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "glares at [param]."
|
||||
else
|
||||
message = "glares."
|
||||
|
||||
if ("stare")
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "stares at [param]."
|
||||
else
|
||||
message = "stares."
|
||||
|
||||
if ("look")
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
|
||||
if (!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "looks at [param]."
|
||||
else
|
||||
message = "looks."
|
||||
m_type = 1
|
||||
|
||||
if("beep")
|
||||
if("glare")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "beeps at [param]."
|
||||
if(param)
|
||||
message = "<b>[src]</b> glares at [param]."
|
||||
else
|
||||
message = "beeps."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 1
|
||||
message = "<b>[src]</b> glares."
|
||||
|
||||
if("ping")
|
||||
if("stare")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "pings at [param]."
|
||||
if(param)
|
||||
message = "<b>[src]</b> stares at [param]."
|
||||
else
|
||||
message = "pings."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 1
|
||||
message = "<b>[src]</b> stares."
|
||||
|
||||
if("buzz")
|
||||
if("look")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "buzzes at [param]."
|
||||
else
|
||||
message = "buzzes."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("yes", "ye")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "emits an affirmative blip at [param]."
|
||||
message = "<b>[src]</b> looks at [param]."
|
||||
else
|
||||
message = "emits an affirmative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
if("dwoop")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "chirps happily at [param]"
|
||||
else
|
||||
message = "chirps happily."
|
||||
playsound(src.loc, 'sound/machines/dwoop.ogg', 50, 0)
|
||||
m_type = 1
|
||||
|
||||
|
||||
if("no")
|
||||
var/M = null
|
||||
if(param)
|
||||
for (var/mob/A in view(null, null))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if (param)
|
||||
message = "emits a negative blip at [param]."
|
||||
else
|
||||
message = "emits a negative blip."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
message = "<b>[src]</b> looks."
|
||||
m_type = 1
|
||||
|
||||
if("law")
|
||||
<<<<<<< HEAD
|
||||
if (istype(module,/obj/item/weapon/robot_module/robot/security) || istype(module,/obj/item/weapon/robot_module/robot/knine)) //VOREStation Add - K9
|
||||
message = "shows its legal authorization barcode."
|
||||
=======
|
||||
if(istype(module,/obj/item/weapon/robot_module/robot/security))
|
||||
message = "<b>[src]</b> shows its legal authorization barcode."
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
playsound(src.loc, 'sound/voice/biamthelaw.ogg', 50, 0)
|
||||
m_type = 2
|
||||
@@ -246,20 +134,20 @@
|
||||
to_chat(src, "You are not THE LAW, pal.")
|
||||
|
||||
if("halt")
|
||||
<<<<<<< HEAD
|
||||
if (istype(module,/obj/item/weapon/robot_module/robot/security) || istype(module,/obj/item/weapon/robot_module/robot/knine)) //VOREStation Add - K9
|
||||
message = "<B>'s</B> speakers skreech, \"Halt! Security!\"."
|
||||
=======
|
||||
if(istype(module,/obj/item/weapon/robot_module/robot/security))
|
||||
message = "<b>[src]</b> <B>'s</B> speakers skreech, \"Halt! Security!\"."
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
|
||||
playsound(src.loc, 'sound/voice/halt.ogg', 50, 0)
|
||||
m_type = 2
|
||||
else
|
||||
to_chat(src, "You are not security.")
|
||||
|
||||
if ("help")
|
||||
if("help")
|
||||
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt, yes, dwoop, no")
|
||||
else
|
||||
to_chat(src, "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>")
|
||||
|
||||
if ((message && src.stat == 0))
|
||||
custom_emote(m_type,message)
|
||||
|
||||
return
|
||||
..(act, m_type, message)
|
||||
@@ -1,10 +1,4 @@
|
||||
/mob/living/silicon/say(var/message, var/sanitize = 1, var/whispering = 0)
|
||||
return ..((sanitize ? sanitize(message) : message), whispering = whispering)
|
||||
|
||||
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
log_say(message, src)
|
||||
|
||||
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(!is_component_functioning("radio"))
|
||||
@@ -17,7 +11,7 @@
|
||||
/mob/living/silicon/speech_bubble_appearance()
|
||||
return "synthetic"
|
||||
|
||||
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode == "department")
|
||||
return holopad_talk(message, verb, speaking)
|
||||
@@ -29,7 +23,7 @@
|
||||
message_mode = null
|
||||
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
|
||||
|
||||
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
|
||||
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(message_mode == "general")
|
||||
@@ -50,29 +44,24 @@
|
||||
#define IS_ROBOT 2
|
||||
#define IS_PAI 3
|
||||
|
||||
/mob/living/silicon/say_understands(var/other,var/datum/language/speaking = null)
|
||||
/mob/living/silicon/say_understands(var/other, var/datum/language/speaking = null)
|
||||
//These only pertain to common. Languages are handled by mob/say_understands()
|
||||
if (!speaking)
|
||||
if (istype(other, /mob/living/carbon))
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon))
|
||||
return 1
|
||||
if (istype(other, /mob/living/carbon/brain))
|
||||
return 1
|
||||
if(!speaking)
|
||||
if(iscarbon(other))
|
||||
return TRUE
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(isbrain(other))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
|
||||
|
||||
log_say("(HPAD) [message]",src)
|
||||
|
||||
message = trim(message)
|
||||
|
||||
if (!message)
|
||||
return
|
||||
/mob/living/silicon/ai/proc/holopad_talk(list/message_pieces, verb)
|
||||
log_say("(HPAD) [multilingual_to_message(message_pieces)]",src)
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])//If there is a hologram and its master is the user.
|
||||
<<<<<<< HEAD
|
||||
//Human-like, sorta, heard by those who understand humans.
|
||||
var/rendered_a
|
||||
//Speech distorted, heard by those who do not understand AIs.
|
||||
@@ -87,33 +76,29 @@
|
||||
rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
|
||||
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'><span class='body'>\"[message]\"</span></span></span></i>") //The AI can "hear" its own message.
|
||||
=======
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
var/list/listeners = get_mobs_and_objs_in_view_fast(get_turf(T), world.view)
|
||||
var/list/listening = listeners["mobs"]
|
||||
var/list/listening_obj = listeners["objs"]
|
||||
for(var/mob/M in listening)
|
||||
spawn(0)
|
||||
if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
|
||||
M.show_message(rendered_a, 2)
|
||||
else//If they do not.
|
||||
M.show_message(rendered_b, 2)
|
||||
M.hear_holopad_talk(message_pieces, verb, src)
|
||||
for(var/obj/O in listening_obj)
|
||||
if(O == T) //Don't recieve your own speech
|
||||
continue
|
||||
spawn(0)
|
||||
if(O && src) //If we still exist, when the spawn processes
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
O.hear_talk(src, message_pieces, verb)
|
||||
/*Radios "filter out" this conversation channel so we don't need to account for them.
|
||||
This is another way of saying that we won't bother dealing with them.*/
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [combine_message(message_pieces, verb, src)]</span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
|
||||
|
||||
message = trim(message)
|
||||
|
||||
if (!message)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
@@ -147,11 +132,11 @@
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
var/obj/machinery/hologram/holopad/T = holo
|
||||
if(T && T.masters[src]) //Is the AI using a holopad?
|
||||
src.holopad_emote(message)
|
||||
. = holopad_emote(message)
|
||||
else //Emote normally, then.
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
#undef IS_AI
|
||||
#undef IS_ROBOT
|
||||
|
||||
@@ -193,7 +193,14 @@
|
||||
//Silicon mob language procs
|
||||
|
||||
/mob/living/silicon/can_speak(datum/language/speaking)
|
||||
return universal_speak || (speaking in src.speech_synthesizer_langs) || (speaking.name == "Noise") //need speech synthesizer support to vocalize a language
|
||||
if(universal_speak)
|
||||
return TRUE
|
||||
//need speech synthesizer support to vocalize a language
|
||||
if(speaking in speech_synthesizer_langs)
|
||||
return TRUE
|
||||
if(speaking && speaking.flags & INNATE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/add_language(var/language, var/can_speak=1)
|
||||
var/var/datum/language/added_language = GLOB.all_languages[language]
|
||||
@@ -213,15 +220,11 @@
|
||||
..(rem_language)
|
||||
speech_synthesizer_langs -= removed_language
|
||||
|
||||
/mob/living/silicon/check_languages()
|
||||
set name = "Check Known Languages"
|
||||
set category = "IC"
|
||||
set src = usr
|
||||
|
||||
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
|
||||
/mob/living/silicon/check_lang_data()
|
||||
. = ""
|
||||
|
||||
if(default_language)
|
||||
dat += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
|
||||
. += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br><br>"
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
@@ -232,10 +235,7 @@
|
||||
default_str = " - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a>"
|
||||
|
||||
var/synth = (L in speech_synthesizer_langs)
|
||||
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
|
||||
|
||||
src << browse(dat, "window=checklanguage")
|
||||
return
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b>[synth ? default_str : null]<br>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br>[L.desc]<br><br>"
|
||||
|
||||
/mob/living/silicon/proc/toggle_sensor_mode()
|
||||
var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security","Medical","Disable")
|
||||
|
||||
@@ -194,12 +194,6 @@
|
||||
. = ..()
|
||||
to_chat(src,"<b>You are \the [src].</b> [player_msg]")
|
||||
|
||||
|
||||
/mob/living/simple_mob/emote(var/act, var/type, var/desc)
|
||||
if(act)
|
||||
..(act, type, desc)
|
||||
|
||||
|
||||
/mob/living/simple_mob/SelfMove(turf/n, direct)
|
||||
var/turf/old_turf = get_turf(src)
|
||||
var/old_dir = dir
|
||||
@@ -264,14 +258,11 @@
|
||||
update_icon()
|
||||
|
||||
|
||||
/mob/living/simple_mob/say(var/message,var/datum/language/language)
|
||||
var/verb = "says"
|
||||
/mob/living/simple_mob/say_quote(var/message, var/datum/language/speaking = null)
|
||||
if(speak_emote.len)
|
||||
verb = pick(speak_emote)
|
||||
|
||||
message = sanitize(message)
|
||||
|
||||
..(message, null, verb)
|
||||
. = pick(speak_emote)
|
||||
else if(speaking)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_mob/get_speech_ending(verb, var/ending)
|
||||
return verb
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
return
|
||||
|
||||
// This is awful but its literally say code.
|
||||
/mob/living/simple_mob/animal/borer/say(message)
|
||||
/mob/living/simple_mob/animal/borer/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
message = sanitize(message)
|
||||
message = capitalize(message)
|
||||
|
||||
@@ -224,10 +224,11 @@
|
||||
if(copytext(message, 1, 2) == "*")
|
||||
return emote(copytext(message, 2))
|
||||
|
||||
var/datum/language/L = parse_language(message)
|
||||
if(L && L.flags & HIVEMIND)
|
||||
L.broadcast(src,trim(copytext(message,3)), src.true_name)
|
||||
return
|
||||
var/list/message_pieces = parse_languages(message)
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking && S.speaking.flags & HIVEMIND)
|
||||
S.speaking.broadcast(src, trim(copytext(message, 3)), src.true_name)
|
||||
return
|
||||
|
||||
if(!host)
|
||||
if(chemicals >= 30)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
real_name = "host brain"
|
||||
universal_understand = 1
|
||||
|
||||
/mob/living/captive_brain/say(var/message)
|
||||
/mob/living/captive_brain/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
@@ -31,7 +31,12 @@
|
||||
else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
to_chat(M, "The captive mind of [src] whispers, \"[message]\"")
|
||||
|
||||
/mob/living/captive_brain/me_verb(message as text)
|
||||
to_chat(src, "<span class='danger'>You cannot emote as a captive mind.</span>")
|
||||
return
|
||||
|
||||
/mob/living/captive_brain/emote(var/message)
|
||||
to_chat(src, "<span class='danger'>You cannot emote as a captive mind.</span>")
|
||||
return
|
||||
|
||||
/mob/living/captive_brain/process_resist()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
// Parrots can talk, and may repeat things it hears.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot
|
||||
name = "parrot"
|
||||
@@ -249,4 +250,257 @@
|
||||
if(holder.stat || !holder.say_list || !message || speaker == holder)
|
||||
return
|
||||
var/datum/say_list/S = holder.say_list
|
||||
=======
|
||||
// Parrots can talk, and may repeat things it hears.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot
|
||||
name = "parrot"
|
||||
description_info = "You can give it a headset by clicking on it with a headset. \
|
||||
To remove it, click the bird while on grab intent."
|
||||
has_langs = list("Galactic Common", "Bird")
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/passive/parrot
|
||||
|
||||
// A headset, so that talking parrots can yell at the crew over comms.
|
||||
// If set to a type, on initialize it will be instantiated into that type.
|
||||
var/obj/item/device/radio/headset/my_headset = null
|
||||
|
||||
// Say list
|
||||
/datum/say_list/bird/poly
|
||||
speak = list(
|
||||
"Poly wanna cracker!",
|
||||
"Check the singulo, you chucklefucks!",
|
||||
"Wire the solars, you lazy bums!",
|
||||
"WHO TOOK THE DAMN HARDSUITS?",
|
||||
"OH GOD ITS FREE CALL THE SHUTTLE",
|
||||
"Danger! Crystal hyperstructure instability!",
|
||||
"CRYSTAL DELAMINATION IMMINENT.",
|
||||
"Tweet tweet, I'm a Teshari.",
|
||||
"Chitters.",
|
||||
"Meteors have been detected on a collision course with the station!"
|
||||
)
|
||||
|
||||
// Lets the AI use headsets.
|
||||
// Player-controlled parrots will need to do it manually.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/ISay(message)
|
||||
if(my_headset && prob(50))
|
||||
var/list/keys = list()
|
||||
for(var/channel in my_headset.channels)
|
||||
var/key = get_radio_key_from_channel(channel)
|
||||
if(key)
|
||||
keys += key
|
||||
if(keys.len)
|
||||
var/key_used = pick(keys)
|
||||
return say("[key_used] [message]")
|
||||
return say(message)
|
||||
|
||||
// Ugly saycode so parrots can use their headsets.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/handle_message_mode(message_mode, message, verb, speaking, used_radios)
|
||||
..()
|
||||
if(message_mode)
|
||||
if(my_headset && istype(my_headset, /obj/item/device/radio))
|
||||
my_headset.talk_into(src, message, message_mode, verb, speaking)
|
||||
used_radios += my_headset
|
||||
|
||||
// Clicked on while holding an object.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/device/radio/headset))
|
||||
give_headset(I, user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
// Clicked on by empty hand.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/attack_hand(mob/living/L)
|
||||
if(L.a_intent == I_GRAB && my_headset)
|
||||
remove_headset(L)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/proc/give_headset(obj/item/device/radio/headset/new_headset, mob/living/user)
|
||||
if(!istype(new_headset))
|
||||
to_chat(user, span("warning", "\The [new_headset] isn't a headset."))
|
||||
return
|
||||
if(my_headset)
|
||||
to_chat(user, span("warning", "\The [src] is already wearing \a [my_headset]."))
|
||||
return
|
||||
else
|
||||
user.drop_item(new_headset)
|
||||
my_headset = new_headset
|
||||
new_headset.forceMove(src)
|
||||
to_chat(user, span("warning", "You place \a [new_headset] on \the [src]. You monster."))
|
||||
to_chat(src, span("notice", "\The [user] gives you \a [new_headset]. You should put it to good use immediately."))
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/proc/remove_headset(mob/living/user)
|
||||
if(!my_headset)
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't have a headset to remove, thankfully.</span>")
|
||||
else
|
||||
ISay("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
my_headset.forceMove(get_turf(src))
|
||||
user.put_in_hands(my_headset)
|
||||
to_chat(user, span("notice", "You take away \the [src]'s [my_headset.name]. Finally."))
|
||||
to_chat(src, span("warning", "\The [user] takes your [my_headset.name] away! How cruel!"))
|
||||
my_headset = null
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/examine(mob/user)
|
||||
..()
|
||||
if(my_headset)
|
||||
to_chat(user, "It is wearing \a [my_headset].")
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/Initialize()
|
||||
if(my_headset)
|
||||
my_headset = new my_headset(src)
|
||||
return ..()
|
||||
|
||||
// Subtypes.
|
||||
|
||||
// Best Bird
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/poly
|
||||
name = "Poly"
|
||||
desc = "It's a parrot. An expert on quantum cracker theory."
|
||||
icon_state = "poly"
|
||||
icon_rest = "poly-held"
|
||||
icon_dead = "poly-dead"
|
||||
tt_desc = "E Ara macao"
|
||||
my_headset = /obj/item/device/radio/headset/headset_eng
|
||||
say_list_type = /datum/say_list/bird/poly
|
||||
|
||||
// Best Bird with best headset.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/poly/ultimate
|
||||
my_headset = /obj/item/device/radio/headset/omni
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/kea
|
||||
name = "kea"
|
||||
desc = "A species of parrot. On Earth, they are unique among other parrots for residing in alpine climates. \
|
||||
They are known to be intelligent and curious, which has made some consider them a pest."
|
||||
icon_state = "kea"
|
||||
icon_rest = "kea-held"
|
||||
icon_dead = "kea-dead"
|
||||
tt_desc = "E Nestor notabilis"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/eclectus
|
||||
name = "eclectus"
|
||||
desc = "A species of parrot, this species features extreme sexual dimorphism in their plumage's colors. \
|
||||
A male eclectus has emerald green plumage, where as a female eclectus has red and purple plumage."
|
||||
icon_state = "eclectus"
|
||||
icon_rest = "eclectus-held"
|
||||
icon_dead = "eclectus-dead"
|
||||
tt_desc = "E Eclectus roratus"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/eclectus/Initialize()
|
||||
gender = pick(MALE, FEMALE)
|
||||
if(gender == FEMALE)
|
||||
icon_state = "eclectusf"
|
||||
icon_rest = "eclectusf-held"
|
||||
icon_dead = "eclectusf-dead"
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot
|
||||
name = "grey parrot"
|
||||
desc = "A species of parrot. This one is predominantly grey, but has red tail feathers."
|
||||
icon_state = "agrey"
|
||||
icon_rest = "agrey-held"
|
||||
icon_dead = "agrey-dead"
|
||||
tt_desc = "E Psittacus erithacus"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique
|
||||
name = "black-headed caique"
|
||||
desc = "A species of parrot, these birds have a distinct black color on their heads, distinguishing them from their relative Caiques."
|
||||
icon_state = "bcaique"
|
||||
icon_rest = "bcaique-held"
|
||||
icon_dead = "bcaique-dead"
|
||||
tt_desc = "E Pionites melanocephalus"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/white_caique
|
||||
name = "white-bellied caique"
|
||||
desc = "A species of parrot, they are also known as the Green-Thighed Parrot."
|
||||
icon_state = "wcaique"
|
||||
icon_rest = "wcaique-held"
|
||||
icon_dead = "wcaique-dead"
|
||||
tt_desc = "E Pionites leucogaster"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar
|
||||
name = "budgerigar"
|
||||
desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \
|
||||
This one is has its natural colors of green and yellow."
|
||||
icon_state = "gbudge"
|
||||
icon_rest = "gbudge-held"
|
||||
icon_dead = "gbudge-dead"
|
||||
tt_desc = "E Melopsittacus undulatus"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue
|
||||
icon_state = "bbudge"
|
||||
icon_rest = "bbudge-held"
|
||||
icon_dead = "bbudge-dead"
|
||||
desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \
|
||||
This one has a mutation which altered its color to be blue instead of green and yellow."
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen
|
||||
icon_state = "bgbudge"
|
||||
icon_rest = "bgbudge-held"
|
||||
icon_dead = "bgbudge-dead"
|
||||
desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \
|
||||
This one has a mutation which altered its color to be a mix of blue and green."
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel
|
||||
name = "cockatiel"
|
||||
desc = "A species of parrot. This one has a highly visible crest."
|
||||
icon_state = "tiel"
|
||||
icon_rest = "tiel-held"
|
||||
icon_dead = "tiel-dead"
|
||||
tt_desc = "E Nymphicus hollandicus"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white
|
||||
icon_state = "wtiel"
|
||||
icon_rest = "wtiel-held"
|
||||
icon_dead = "wtiel-dead"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish
|
||||
icon_state = "luttiel"
|
||||
icon_rest = "luttiel-held"
|
||||
icon_dead = "luttiel-dead"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey
|
||||
icon_state = "blutiel" // idk why this is blu.
|
||||
icon_rest = "blutiel-held"
|
||||
icon_dead = "blutiel-dead"
|
||||
|
||||
// This actually might be the yellow-crested cockatoo but idk.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo
|
||||
name = "sulphur-crested cockatoo"
|
||||
desc = "A species of parrot. This one has an expressive yellow crest. Their underwing and tail feathers are also yellow."
|
||||
icon_state = "too"
|
||||
icon_rest = "too-held"
|
||||
icon_dead = "too-dead"
|
||||
tt_desc = "E Cacatua galerita"
|
||||
|
||||
// This was originally called 'hooded_too', which might not mean the unbrella cockatoo but idk.
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo
|
||||
name = "white cockatoo"
|
||||
desc = "A species of parrot. This one is also known as the Umbrella Cockatoo, due to the semicircular shape of its crest."
|
||||
icon_state = "utoo"
|
||||
icon_rest = "utoo-held"
|
||||
icon_dead = "utoo-dead"
|
||||
tt_desc = "E Cacatua alba"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo
|
||||
name = "pink cockatoo"
|
||||
desc = "A species of parrot. This one is also known as Major Mitchell's cockatoo, \
|
||||
in honor of a human surveyor and explorer who existed before humans fully explored their home planet."
|
||||
icon_state = "mtoo"
|
||||
icon_rest = "mtoo-held"
|
||||
icon_dead = "mtoo-dead"
|
||||
tt_desc = "E Lophochroa leadbeateri"
|
||||
|
||||
|
||||
// AI
|
||||
/datum/ai_holder/simple_mob/passive/parrot
|
||||
speak_chance = 2
|
||||
base_wander_delay = 8
|
||||
|
||||
/datum/ai_holder/simple_mob/passive/parrot/on_hear_say(mob/living/speaker, message)
|
||||
if(holder.stat || !holder.say_list || !message || speaker == holder)
|
||||
return
|
||||
var/datum/say_list/S = holder.say_list
|
||||
>>>>>>> 54a8a58... Saycode Overhaul -- Multilingualism (#6956)
|
||||
S.speak |= message
|
||||
@@ -104,7 +104,7 @@
|
||||
// Proc: say()
|
||||
// Parameters: 4 (generic say() arguments)
|
||||
// Description: Adds a speech bubble to the communicator device, then calls ..() to do the real work.
|
||||
/mob/living/voice/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering=0)
|
||||
/mob/living/voice/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
//Speech bubbles.
|
||||
if(comm)
|
||||
var/speech_bubble_test = say_test(message)
|
||||
@@ -118,7 +118,7 @@
|
||||
M << speech_bubble
|
||||
src << speech_bubble
|
||||
|
||||
..(message, speaking, verb, alt_name, whispering) //mob/living/say() can do the actual talking.
|
||||
..() //mob/living/say() can do the actual talking.
|
||||
|
||||
// Proc: speech_bubble_appearance()
|
||||
// Parameters: 0
|
||||
@@ -126,15 +126,15 @@
|
||||
/mob/living/voice/speech_bubble_appearance()
|
||||
return "comm"
|
||||
|
||||
/mob/living/voice/say_understands(var/other,var/datum/language/speaking = null)
|
||||
/mob/living/voice/say_understands(var/other, var/datum/language/speaking = null)
|
||||
//These only pertain to common. Languages are handled by mob/say_understands()
|
||||
if (!speaking)
|
||||
if (istype(other, /mob/living/carbon))
|
||||
return 1
|
||||
if (istype(other, /mob/living/silicon))
|
||||
return 1
|
||||
if (istype(other, /mob/living/carbon/brain))
|
||||
return 1
|
||||
if(!speaking)
|
||||
if(iscarbon(other))
|
||||
return TRUE
|
||||
if(issilicon(other))
|
||||
return TRUE
|
||||
if(isbrain(other))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/voice/custom_emote(var/m_type=1,var/message = null,var/range=world.view)
|
||||
|
||||
@@ -1224,3 +1224,6 @@ mob/proc/yank_out_object()
|
||||
selfimage.loc = src
|
||||
|
||||
return selfimage
|
||||
|
||||
/mob/proc/GetAltName()
|
||||
return ""
|
||||
|
||||
@@ -184,6 +184,12 @@ proc/getsensorlevel(A)
|
||||
p++
|
||||
return t
|
||||
|
||||
/proc/stars_all(list/message_pieces, pr)
|
||||
// eugh, we have to clone the list to avoid collateral damage due to the nature of these messages
|
||||
. = list()
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
. += new /datum/multilingual_say_piece(S.speaking, stars(S.message))
|
||||
|
||||
proc/slur(phrase)
|
||||
phrase = html_decode(phrase)
|
||||
var/leng=length(phrase)
|
||||
|
||||
@@ -605,7 +605,7 @@
|
||||
return ready && ..()
|
||||
|
||||
// Prevents lobby players from seeing say, even with ghostears
|
||||
/mob/new_player/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
|
||||
/mob/new_player/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null)
|
||||
return
|
||||
|
||||
// Prevents lobby players from seeing emotes, even with ghosteyes
|
||||
|
||||
+140
-55
@@ -1,4 +1,4 @@
|
||||
/mob/proc/say()
|
||||
/mob/proc/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
return
|
||||
|
||||
/mob/verb/whisper(message as text)
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
set_typing_indicator(FALSE)
|
||||
if(use_me)
|
||||
usr.emote("me",usr.emote_type,message)
|
||||
custom_emote(usr.emote_type, message)
|
||||
else
|
||||
usr.emote(message)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(!client)
|
||||
return // Clientless mobs shouldn't be trying to talk in deadchat.
|
||||
|
||||
if(!src.client.holder)
|
||||
if(!client.holder)
|
||||
if(!config.dsay_allowed)
|
||||
to_chat(src, "<span class='danger'>Deadchat is globally muted.</span>")
|
||||
return
|
||||
@@ -55,55 +55,55 @@
|
||||
|
||||
say_dead_direct("[pick("complains","moans","whines","laments","blubbers")], <span class='message'>\"[message]\"</span>", src)
|
||||
|
||||
/mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null)
|
||||
|
||||
if (src.stat == DEAD)
|
||||
return 1
|
||||
/mob/proc/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
if(stat == DEAD)
|
||||
return TRUE
|
||||
|
||||
//Universal speak makes everything understandable, for obvious reasons.
|
||||
else if(src.universal_speak || src.universal_understand)
|
||||
return 1
|
||||
else if(universal_speak || universal_understand)
|
||||
return TRUE
|
||||
|
||||
//Languages are handled after.
|
||||
if (!speaking)
|
||||
if(!speaking)
|
||||
if(!other)
|
||||
return 1
|
||||
return TRUE
|
||||
if(other.universal_speak)
|
||||
return 1
|
||||
return TRUE
|
||||
if(isAI(src) && ispAI(other))
|
||||
return 1
|
||||
if (istype(other, src.type) || istype(src, other.type))
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
if(istype(other, type) || istype(src, other.type))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
if(speaking.flags & INNATE)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
|
||||
if(speaking.flags & NONVERBAL)
|
||||
if(sdisabilities & BLIND || blinded)
|
||||
return FALSE
|
||||
if(!other || !(other in view(src)))
|
||||
return FALSE
|
||||
|
||||
//Language check.
|
||||
for(var/datum/language/L in src.languages)
|
||||
for(var/datum/language/L in languages)
|
||||
if(speaking.name == L.name)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
|
||||
/*
|
||||
***Deprecated***
|
||||
let this be handled at the hear_say or hear_radio proc
|
||||
This is left in for robot speaking when humans gain binary channel access until I get around to rewriting
|
||||
robot_talk() proc.
|
||||
There is no language handling build into it however there is at the /mob level so we accept the call
|
||||
for it but just ignore it.
|
||||
*/
|
||||
return FALSE
|
||||
|
||||
/mob/proc/say_quote(var/message, var/datum/language/speaking = null)
|
||||
var/verb = "says"
|
||||
var/ending = copytext(message, length(message))
|
||||
if(ending=="!")
|
||||
verb=pick("exclaims","shouts","yells")
|
||||
else if(ending=="?")
|
||||
verb="asks"
|
||||
var/verb = "says"
|
||||
var/ending = copytext(message, length(message))
|
||||
|
||||
return verb
|
||||
if(speaking)
|
||||
verb = speaking.get_spoken_verb(ending)
|
||||
else
|
||||
if(ending == "!")
|
||||
verb = pick("exclaims", "shouts", "yells")
|
||||
else if(ending == "?")
|
||||
verb = "asks"
|
||||
return verb
|
||||
|
||||
|
||||
/mob/proc/emote(var/act, var/type, var/message)
|
||||
@@ -120,38 +120,123 @@
|
||||
|
||||
/mob/proc/say_test(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
if (ending == "?")
|
||||
if(ending == "?")
|
||||
return "1"
|
||||
else if (ending == "!")
|
||||
else if(ending == "!")
|
||||
return "2"
|
||||
return "0"
|
||||
|
||||
//parses the message mode code (e.g. :h, :w) from text, such as that supplied to say.
|
||||
//returns the message mode string or null for no message mode.
|
||||
//standard mode is the mode returned for the special ';' radio code.
|
||||
/mob/proc/parse_message_mode(var/message, var/standard_mode="headset")
|
||||
if(length(message) >= 1 && copytext(message,1,2) == ";")
|
||||
/mob/proc/parse_message_mode(var/message, var/standard_mode = "headset")
|
||||
if(length(message) >= 1 && copytext(message, 1, 2) == ";")
|
||||
return standard_mode
|
||||
|
||||
if(length(message) >= 2)
|
||||
var/channel_prefix = copytext(message, 1 ,3)
|
||||
var/channel_prefix = copytext(message, 1, 3)
|
||||
return department_radio_keys[channel_prefix]
|
||||
|
||||
return null
|
||||
|
||||
//parses the language code (e.g. :j) from text, such as that supplied to say.
|
||||
//returns the language object only if the code corresponds to a language that src can speak, otherwise null.
|
||||
/mob/proc/parse_language(var/message)
|
||||
var/prefix = copytext(message,1,2)
|
||||
// This is for audible emotes
|
||||
if(length(message) >= 1 && prefix == "!")
|
||||
return GLOB.all_languages["Noise"]
|
||||
/datum/multilingual_say_piece
|
||||
var/datum/language/speaking = null
|
||||
var/message = ""
|
||||
|
||||
if(length(message) >= 2 && is_language_prefix(prefix))
|
||||
var/language_prefix = copytext(message, 2 ,3)
|
||||
var/datum/language/L = GLOB.language_keys[language_prefix]
|
||||
if (can_speak(L))
|
||||
return L
|
||||
/datum/multilingual_say_piece/New(datum/language/new_speaking, new_message)
|
||||
. = ..()
|
||||
speaking = new_speaking
|
||||
if(new_message)
|
||||
message = new_message
|
||||
|
||||
/mob/proc/find_valid_prefixes(message)
|
||||
var/list/prefixes = list() // [["Common", start, end], ["Gutter", start, end]]
|
||||
for(var/i in 1 to length(message))
|
||||
// This grabs trimmed 3 character substrings, to allow for up to 1 prefix and 1 letter language keys
|
||||
var/selection = trim_right(lowertext(copytext(message, i, i + 2)))
|
||||
// The first character in the selection will always be the prefix (if this is a valid language invocation)
|
||||
var/prefix = copytext(selection, 1, 2)
|
||||
var/language_key = copytext(selection, 2, 3)
|
||||
if(is_language_prefix(prefix))
|
||||
// Okay, we're definitely now trying to invoke a language (probably)
|
||||
// This "[]" is probably unnecessary but BYOND will runtime if a number is used
|
||||
var/datum/language/L = GLOB.language_keys["[language_key]"]
|
||||
// It's kinda silly that we have to check L != null and this isn't done for us by can_speak (it runtimes instead), but w/e
|
||||
if(L && can_speak(L))
|
||||
// So we have a valid language invocation, and we can speak that language, let's make a piece for it
|
||||
// This language will be the language until the next prefixes[] index, or the end of the message if there are none.
|
||||
prefixes[++prefixes.len] = list(L, i, i + length(selection))
|
||||
else if(L)
|
||||
// We found a valid language, but they can't speak it. Let's make them speak gibberish instead.
|
||||
prefixes[++prefixes.len] = list(GLOB.all_languages[LANGUAGE_GIBBERISH], i, i + length(selection))
|
||||
continue
|
||||
if(i == 1)
|
||||
// This covers the case of "no prefixes in use."
|
||||
prefixes[++prefixes.len] = list(get_default_language(), i, i)
|
||||
|
||||
return prefixes
|
||||
|
||||
/mob/proc/strip_prefixes(message, mob/prefixer = null)
|
||||
. = ""
|
||||
var/last_index = 1
|
||||
for(var/i in 1 to length(message))
|
||||
var/selection = trim_right(lowertext(copytext(message, i, i + 2)))
|
||||
// The first character in the selection will always be the prefix (if this is a valid language invocation)
|
||||
var/prefix = copytext(selection, 1, 2)
|
||||
var/language_key = copytext(selection, 2, 3)
|
||||
if(is_language_prefix(prefix))
|
||||
var/datum/language/L = GLOB.language_keys["[language_key]"]
|
||||
if(L)
|
||||
. += copytext(message, last_index, i)
|
||||
last_index = i + 2
|
||||
if(i + 1 > length(message))
|
||||
. += copytext(message, last_index)
|
||||
|
||||
// this returns a structured message with language sections
|
||||
// list(/datum/multilingual_say_piece(common, "hi"), /datum/multilingual_say_piece(farwa, "squik"), /datum/multilingual_say_piece(common, "meow!"))
|
||||
/mob/proc/parse_languages(message)
|
||||
. = list()
|
||||
|
||||
// Noise language is a snowflake.
|
||||
if(copytext(message, 1, 2) == "!" && length(message) > 1)
|
||||
// Note that list() here is intended
|
||||
// Returning a raw /datum/multilingual_say_piece is supported, but only for hivemind languages
|
||||
// What we actually want is a normal say piece that's all noise lang
|
||||
return list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], trim(strip_prefixes(copytext(message, 2)))))
|
||||
|
||||
// Scan the message for prefixes
|
||||
var/list/prefix_locations = find_valid_prefixes(message)
|
||||
if(!LAZYLEN(prefix_locations)) // There are no prefixes... or at least, no _valid_ prefixes.
|
||||
. += new /datum/multilingual_say_piece(get_default_language(), trim(strip_prefixes(message))) // So we'll just strip those pesky things and still make the message.
|
||||
|
||||
for(var/i in 1 to length(prefix_locations))
|
||||
var/current = prefix_locations[i] // ["Common", start, end]
|
||||
|
||||
// There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages.
|
||||
var/datum/language/L = current[1]
|
||||
if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG))
|
||||
return new /datum/multilingual_say_piece(L, trim(strip_prefixes(message)))
|
||||
|
||||
if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang
|
||||
var/spoke_message = handle_autohiss(trim(copytext(message, current[3])), L)
|
||||
. += new /datum/multilingual_say_piece(current[1], spoke_message)
|
||||
else
|
||||
return GLOB.all_languages[LANGUAGE_GIBBERISH]
|
||||
return null
|
||||
var/next = prefix_locations[i + 1] // We look ahead at the next message to see where we need to stop.
|
||||
var/spoke_message = handle_autohiss(trim(copytext(message, current[3], next[2])), L)
|
||||
. += new /datum/multilingual_say_piece(current[1], spoke_message)
|
||||
|
||||
/* These are here purely because it would be hell to try to convert everything over to using the multi-lingual system at once */
|
||||
/proc/message_to_multilingual(message, datum/language/speaking = null)
|
||||
. = list(new /datum/multilingual_say_piece(speaking, message))
|
||||
|
||||
/proc/multilingual_to_message(list/message_pieces, var/requires_machine_understands = FALSE, var/with_capitalization = FALSE)
|
||||
. = ""
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
var/message_to_append = S.message
|
||||
if(S.speaking)
|
||||
if(with_capitalization)
|
||||
message_to_append = S.speaking.format_message_plain(S.message)
|
||||
if(requires_machine_understands && !S.speaking.machine_understands)
|
||||
message_to_append = S.speaking.scramble(S.message)
|
||||
. += message_to_append + " "
|
||||
. = trim_right(.)
|
||||
|
||||
Reference in New Issue
Block a user