diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 883856cc9b7..753a953b8f9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -151,7 +151,7 @@ // The old system would loop through lists for a total of 5000 per function call, in an empty server. // This new system will loop at around 1000 in an empty server. -/proc/get_mobs_in_view(var/R, var/atom/source) +/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE) // Returns a list of mobs in range of R from source. Used in radio and say code. var/turf/T = get_turf(source) @@ -165,7 +165,7 @@ for(var/atom/A in range) if(ismob(A)) var/mob/M = A - if(M.client) + if(M.client || include_clientless) hear += M //log_to_dd("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") else if(istype(A, /obj/item/device/radio)) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index d5b75eb4c7c..4c6abbd7d0b 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -431,3 +431,17 @@ proc/checkhtml(var/t) text = copytext(text, 1, index) + repl_chars[char] + copytext(text, index+keylength) index = findtext(text, char) return text + +//Checks if any of a given list of needles is in the haystack +/proc/text_in_list(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtext(haystack, needle, start, end)) + return 1 + return 0 + +//Like above, but case sensitive +/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtextEx(haystack, needle, start, end)) + return 1 + return 0 diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index d5b789e7523..28b3cfe7132 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -449,7 +449,7 @@ var/list/turret_icons return health -= force - if(force > 5 && prob(45)) + if(force > 5 && prob(45) && spark_system) spark_system.start() if(health <= 0) die() //the death process :( @@ -504,7 +504,8 @@ var/list/turret_icons /obj/machinery/porta_turret/proc/die() //called when the turret dies, ie, health <= 0 health = 0 stat |= BROKEN //enables the BROKEN bit - spark_system.start() //creates some sparks because they look cool + if(spark_system) + spark_system.start() //creates some sparks because they look cool update_icon() /obj/machinery/porta_turret/process() diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 558a6f8e9de..4876aa60b7b 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -221,6 +221,16 @@ if(!src.restrained()) message = "[src] is strumming the air and headbanging like a safari chimp." m_type = 1 + + if("dance") + if(!src.restrained()) + message = "[src] dances around happily." + m_type = 1 + + if("jump") + if(!src.restrained()) + message = "[src] jumps!" + m_type = 1 if("blink", "blinks") message = "[src] blinks." @@ -841,9 +851,9 @@ M.reagents.add_reagent("jenkem", 1) if("help") - var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dap(s)(none)/mob," \ - + " deathgasp(s), drool(s), eyebrow,fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), handshake-mob, hug(s)-(none)/mob," \ - + " glare(s)-(none)/mob, grin(s), johnny, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dance, dap(s)(none)/mob," \ + + " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), grin(s)," \ + + " handshake-mob, hug(s)-(none)/mob, johnny, jump, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ + " wag(s), wave(s), whimper(s), wink(s), yawn(s)" if(species.name == "Machine") diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 26ca4af83e8..7384ccc6796 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,10 +1,10 @@ -/mob/living/carbon/human/say(var/message) +/mob/living/carbon/human/say(var/message, var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE) var/alt_name = "" if(name != GetVoice()) alt_name = " (as [get_id_name("Unknown")])" - ..(message, alt_name = alt_name) //ohgod we should really be passing a datum here. + ..(message, alt_name = alt_name, sanitize = sanitize, ignore_speech_problems = ignore_speech_problems, ignore_atmospherics = ignore_atmospherics) //ohgod we should really be passing a datum here. /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d5a1580ded9..44db25814c9 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -14,6 +14,7 @@ var/list/department_radio_keys = list( ":u" = "Supply", "#u" = "Supply", ".u" = "Supply", ":z" = "Service", "#z" = "Service", ".z" = "Service", ":p" = "AI Private", "#p" = "AI Private", ".p" = "AI Private", + ":x" = "cords", "#x" = "cords", ".x" = "cords", ":R" = "right ear", "#R" = "right ear", ".R" = "right ear", ":L" = "left ear", "#L" = "left ear", ".L" = "left ear", @@ -30,7 +31,8 @@ var/list/department_radio_keys = list( ":Z" = "Service", "#Z" = "Service", ".Z" = "Service", ":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private", ":-" = "Special Ops", "#-" = "Special Ops", ".-" = "Special Ops", - ":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam" + ":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam", + ":X" = "cords", "#X" = "cords", ".X" = "cords" ) @@ -106,13 +108,14 @@ proc/get_radio_key_from_channel(var/channel) return returns -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/alt_name="") +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/alt_name = "", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE) if(client) if(client.prefs.muted & MUTE_IC) to_chat(src, "You cannot speak in IC (Muted).") return - message = trim_strip_html_properly(message) + if(sanitize) + message = trim_strip_html_properly(message) if(stat) if(stat == DEAD) @@ -146,6 +149,15 @@ proc/get_radio_key_from_channel(var/channel) if(speaking && (speaking.flags & HIVEMIND)) speaking.broadcast(src,trim(message)) return 1 + + if(message_mode == "cords") + if(iscarbon(src)) + var/mob/living/carbon/C = src + var/obj/item/organ/internal/vocal_cords/V = C.get_int_organ(/obj/item/organ/internal/vocal_cords) + if(V && V.can_speak_with()) + C.say(V.handle_speech(message), sanitize = FALSE, ignore_speech_problems = TRUE, ignore_atmospherics = TRUE) + V.speak_with(message) //words come before actions + return 1 verb = say_quote(message, speaking) @@ -162,7 +174,7 @@ proc/get_radio_key_from_channel(var/channel) message = handle_autohiss(message, speaking) - if(speaking && !(speaking.flags & NO_STUTTER)) + if(!ignore_speech_problems && (speaking && !(speaking.flags & NO_STUTTER))) var/list/handle_s = handle_speech_problems(message, verb) message = handle_s[1] verb = handle_s[2] @@ -217,12 +229,13 @@ proc/get_radio_key_from_channel(var/channel) //make sure the air can transmit speech - speaker's side var/datum/gas_mixture/environment = T.return_air() var/pressure = environment ? environment.return_pressure() : 0 - if(pressure < SOUND_MINIMUM_PRESSURE) - message_range = 1 + if(!ignore_atmospherics) + if(pressure < SOUND_MINIMUM_PRESSURE) + message_range = 1 - 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(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 var/list/hear = hear(message_range, T) var/list/hearturfs = list() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 132655bc923..b0a81e4444c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -46,7 +46,7 @@ Difficulty: Very Hard del_on_death = 1 medal_type = MEDAL_PREFIX score_type = COLOSSUS_SCORE - loot = list(/obj/machinery/anomalous_crystal/random) + loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/internal/vocal_cords/colossus) butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) deathmessage = "disintegrates, leaving a glowing core in its wake." death_sound = 'sound/misc/demon_dies.ogg' diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index f34d9797124..5ac16d095e5 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -162,6 +162,14 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/weapon/firealarm_electronics category = list("initial", "Electronics") + +/datum/design/earmuffs + name = "Earmuffs" + id = "earmuffs" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/ears/earmuffs + category = list("initial", "Miscellaneous") /datum/design/igniter name = "Igniter" @@ -188,7 +196,7 @@ category = list("initial", "Medical") /datum/design/kitchen_knife - name = "Kitchen knife" + name = "Kitchen Knife" id = "kitchen_knife" build_type = AUTOLATHE materials = list(MAT_METAL = 12000) @@ -196,7 +204,7 @@ category = list("initial","Miscellaneous") /datum/design/minihoe - name = "Mini hoe" + name = "Mini Hoe" id = "mini_hoe" build_type = AUTOLATHE materials = list(MAT_METAL = 50) @@ -204,7 +212,7 @@ category = list("initial","Miscellaneous") /datum/design/plant_analyzer - name = "Plant analyzer" + name = "Plant Analyzer" id = "plant_analyzer" build_type = AUTOLATHE materials = list(MAT_METAL = 30, MAT_GLASS = 20) @@ -324,12 +332,12 @@ category = list("initial", "Miscellaneous") /datum/design/foambox - name = "Box of Foam Force darts" - id = "foamforce" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2000) - build_path = /obj/item/ammo_box/foambox - category = list("initial", "Miscellaneous") + name = "Box of Foam Force darts" + id = "foamforce" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2000) + build_path = /obj/item/ammo_box/foambox + category = list("initial", "Miscellaneous") /datum/design/canvas/twentythreeXtwentythree name = "23px by 23px Canvas" diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm new file mode 100644 index 00000000000..99a152da957 --- /dev/null +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -0,0 +1,453 @@ +var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") +var/static/regex/weaken_words = regex("drop|fall|trip") +var/static/regex/sleep_words = regex("sleep|slumber") +var/static/regex/vomit_words = regex("vomit|throw up") +var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush") +var/static/regex/hallucinate_words = regex("see the truth|hallucinate") +var/static/regex/wakeup_words = regex("wake up|awaken") +var/static/regex/heal_words = regex("live|heal|survive|mend|heroes never die") +var/static/regex/hurt_words = regex("die|suffer") +var/static/regex/bleed_words = regex("bleed") +var/static/regex/burn_words = regex("burn|ignite") +var/static/regex/repulse_words = regex("shoo|go away|leave me alone|begone|flee|fus ro dah") +var/static/regex/whoareyou_words = regex("who are you|say your name|state your name|identify") +var/static/regex/saymyname_words = regex("say my name") +var/static/regex/knockknock_words = regex("knock knock") +var/static/regex/statelaws_words = regex("state laws|state your laws") +var/static/regex/move_words = regex("move") +var/static/regex/walk_words = regex("walk|slow down") +var/static/regex/run_words = regex("run") +var/static/regex/helpintent_words = regex("help") +var/static/regex/disarmintent_words = regex("disarm") +var/static/regex/grabintent_words = regex("grab") +var/static/regex/harmintent_words = regex("harm|fight") +var/static/regex/throwmode_words = regex("throw|catch") +var/static/regex/flip_words = regex("flip|rotate|revolve|roll|somersault") +var/static/regex/rest_words = regex("rest") +var/static/regex/getup_words = regex("get up") +var/static/regex/sit_words = regex("sit") +var/static/regex/stand_words = regex("stand") +var/static/regex/dance_words = regex("dance") +var/static/regex/jump_words = regex("jump") +var/static/regex/salute_words = regex("salute") +var/static/regex/deathgasp_words = regex("play dead") +var/static/regex/clap_words = regex("clap|applaud") +var/static/regex/honk_words = regex("ho+nk") //hooooooonk +var/static/regex/multispin_words = regex("like a record baby") + +/obj/item/organ/internal/vocal_cords //organs that are activated through speech with the :x channel + name = "vocal cords" + icon_state = "appendix" + zone = "mouth" + slot = "vocal_cords" + parent_organ = "mouth" + var/spans = null + +/obj/item/organ/internal/vocal_cords/proc/can_speak_with() //if there is any limitation to speaking with these cords + return TRUE + +/obj/item/organ/internal/vocal_cords/proc/speak_with(message) //do what the organ does + return + +/obj/item/organ/internal/vocal_cords/proc/handle_speech(message) //change the message + return message + +//Colossus drop, forces the listeners to obey certain commands +/obj/item/organ/internal/vocal_cords/colossus + name = "divine vocal cords" + desc = "They carry the voice of an ancient god." + icon_state = "voice_of_god" + actions_types = list(/datum/action/item_action/organ_action/colossus) + var/next_command = 0 + var/cooldown_stun = 1200 + var/cooldown_damage = 600 + var/cooldown_meme = 300 + var/cooldown_none = 150 + var/base_multiplier = 1 + spans = "colossus yell" + +/datum/action/item_action/organ_action/colossus + name = "Voice of God" + var/obj/item/organ/internal/vocal_cords/colossus/cords = null + +/datum/action/item_action/organ_action/colossus/New() + ..() + cords = target + +/datum/action/item_action/organ_action/colossus/IsAvailable() + if(world.time < cords.next_command) + return FALSE + if(!owner) + return FALSE + if(!owner.can_speak()) + return FALSE + if(check_flags & AB_CHECK_CONSCIOUS) + if(owner.stat) + return FALSE + return TRUE + +/datum/action/item_action/organ_action/colossus/Trigger() + . = ..() + if(!IsAvailable()) + if(world.time < cords.next_command) + to_chat(owner, "You must wait [(cords.next_command - world.time)/10] seconds before Speaking again.") + return + var/command = input(owner, "Speak with the Voice of God", "Command") + if(!command) + return + owner.say(".x[command]") + +/obj/item/organ/internal/vocal_cords/colossus/can_speak_with() + if(world.time < next_command) + to_chat(owner, "You must wait [(next_command - world.time)/10] seconds before Speaking again.") + return FALSE + if(!owner) + return FALSE + if(!owner.can_speak()) + to_chat(owner, "You are unable to speak!") + return FALSE + if(owner.stat) + return FALSE + return TRUE + +/obj/item/organ/internal/vocal_cords/colossus/handle_speech(message) + spans = "colossus yell" //reset spans, just in case someone gets deculted or the cords change owner + if(iscultist(owner)) + spans += " narsiesmall" + return "[uppertext(message)]" + +/obj/item/organ/internal/vocal_cords/colossus/speak_with(message) + var/log_message = uppertext(message) + message = lowertext(message) + playsound(get_turf(owner), 'sound/magic/invoke_general.ogg', 300, 1, 5) + + var/mob/living/list/listeners = list() + for(var/mob/living/L in get_mobs_in_view(8, owner, TRUE)) + if(!L.ear_deaf && !L.null_rod_check() && L != owner && L.stat != DEAD) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) + continue + listeners += L + + if(!listeners.len) + next_command = world.time + cooldown_none + return + + var/power_multiplier = base_multiplier + + if(owner.mind) + //Chaplains are very good at speaking with the voice of god + if(owner.mind.assigned_role == "Chaplain") + power_multiplier *= 2 + //Command staff has authority + if(owner.mind.assigned_role in command_positions) + power_multiplier *= 1.4 + //Why are you speaking + if(owner.mind.assigned_role == "Mime") + power_multiplier *= 0.5 + + //Cultists are closer to their gods and are more powerful, but they'll give themselves away + if(iscultist(owner)) + power_multiplier *= 2 + + //Try to check if the speaker specified a name or a job to focus on + var/list/specific_listeners = list() + var/found_string = null + + for(var/V in listeners) + var/mob/living/L = V + /*if(L.mind && L.mind.devilinfo && findtext(message, L.mind.devilinfo.truename)) + var/start = findtext(message, L.mind.devilinfo.truename) + listeners = list(L) //let's be honest you're never going to find two devils with the same name + power_multiplier *= 5 //if you're a devil and god himself addressed you, you fucked up + //Cut out the name so it doesn't trigger commands + message = copytext(message, 0, start)+copytext(message, start + length(L.mind.devilinfo.truename), length(message) + 1) + break*/ + if(findtext(message, L.real_name) == 1) + specific_listeners += L //focus on those with the specified name + //Cut out the name so it doesn't trigger commands + found_string = L.real_name + + else if(L.mind && findtext(message, L.mind.assigned_role) == 1) + specific_listeners += L //focus on those with the specified job + //Cut out the job so it doesn't trigger commands + found_string = L.mind.assigned_role + + if(specific_listeners.len) + listeners = specific_listeners + power_multiplier *= (1 + (1/specific_listeners.len)) //2x on a single guy, 1.5x on two and so on + message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1) + + //STUN + if(findtext(message, stun_words)) + for(var/V in listeners) + var/mob/living/L = V + L.Stun(3 * power_multiplier) + next_command = world.time + cooldown_stun + + //WEAKEN + else if(findtext(message, weaken_words)) + for(var/V in listeners) + var/mob/living/L = V + L.Weaken(3 * power_multiplier) + next_command = world.time + cooldown_stun + + //SLEEP + else if((findtext(message, sleep_words))) + for(var/V in listeners) + var/mob/living/L = V + L.Sleeping(2 * power_multiplier) + next_command = world.time + cooldown_stun + + //VOMIT + else if((findtext(message, vomit_words))) + for(var/mob/living/carbon/C in listeners) + C.vomit(10 * power_multiplier) + next_command = world.time + cooldown_stun + + //SILENCE + else if((findtext(message, silence_words))) + for(var/mob/living/carbon/C in listeners) + if(owner.mind && (owner.mind.assigned_role == "Librarian" || owner.mind.assigned_role == "Mime")) + power_multiplier *= 3 + C.silent += (10 * power_multiplier) + next_command = world.time + cooldown_stun + + //HALLUCINATE + else if((findtext(message, hallucinate_words))) + for(var/V in listeners) + var/mob/living/L = V + new /obj/effect/hallucination/delusion(get_turf(L),L,duration=150 * power_multiplier,skip_nearby=0) + next_command = world.time + cooldown_meme + + //WAKE UP + else if((findtext(message, wakeup_words))) + for(var/V in listeners) + var/mob/living/L = V + L.SetSleeping(0) + next_command = world.time + cooldown_damage + + //HEAL + else if((findtext(message, heal_words))) + for(var/V in listeners) + var/mob/living/L = V + L.heal_overall_damage(10 * power_multiplier, 10 * power_multiplier, 0, 0) + next_command = world.time + cooldown_damage + + //BRUTE DAMAGE + else if((findtext(message, hurt_words))) + for(var/V in listeners) + var/mob/living/L = V + L.apply_damage(15 * power_multiplier, def_zone = "chest") + next_command = world.time + cooldown_damage + + //BLEED + else if((findtext(message, bleed_words))) + for(var/mob/living/carbon/human/H in listeners) + H.drip(100 * power_multiplier) + next_command = world.time + cooldown_damage + + //FIRE + else if((findtext(message, burn_words))) + for(var/V in listeners) + var/mob/living/L = V + L.adjust_fire_stacks(1 * power_multiplier) + L.IgniteMob() + next_command = world.time + cooldown_damage + + //REPULSE + else if((findtext(message, repulse_words))) + for(var/V in listeners) + var/mob/living/L = V + var/throwtarget = get_edge_target_turf(owner, get_dir(owner, get_step_away(L, owner))) + L.throw_at(throwtarget, 3 * power_multiplier, 1) + next_command = world.time + cooldown_damage + + //WHO ARE YOU? + else if((findtext(message, whoareyou_words))) + for(var/V in listeners) + var/mob/living/L = V + /*if(L.mind && L.mind.devilinfo) + L.say("[L.mind.devilinfo.truename]") + else*/ + L.say("[L.real_name]") + next_command = world.time + cooldown_meme + + //SAY MY NAME + else if((findtext(message, saymyname_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("[owner.name]!") //"Unknown!" + next_command = world.time + cooldown_meme + + //KNOCK KNOCK + else if((findtext(message, knockknock_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("Who's there?") + next_command = world.time + cooldown_meme + + //STATE LAWS + else if((findtext(message, statelaws_words))) + for(var/mob/living/silicon/S in listeners) + S.statelaws(S.laws) + next_command = world.time + cooldown_stun + + //MOVE + else if((findtext(message, move_words))) + for(var/V in listeners) + var/mob/living/L = V + step(L, pick(cardinal)) + next_command = world.time + cooldown_meme + + //WALK + else if((findtext(message, walk_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.m_intent != "walk") + L.m_intent = "walk" + L.hud_used.move_intent.icon_state = "walking" + next_command = world.time + cooldown_meme + + //RUN + else if((findtext(message, run_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.m_intent != "run") + L.m_intent = "run" + L.hud_used.move_intent.icon_state = "running" + next_command = world.time + cooldown_meme + + //HELP INTENT + else if((findtext(message, helpintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_HELP) + next_command = world.time + cooldown_meme + + //DISARM INTENT + else if((findtext(message, disarmintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_DISARM) + next_command = world.time + cooldown_meme + + //GRAB INTENT + else if((findtext(message, grabintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_GRAB) + next_command = world.time + cooldown_meme + + //HARM INTENT + else if((findtext(message, harmintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_HARM) + next_command = world.time + cooldown_meme + + //THROW/CATCH + else if((findtext(message, throwmode_words))) + for(var/mob/living/carbon/C in listeners) + C.throw_mode_on() + next_command = world.time + cooldown_meme + + //FLIP + else if((findtext(message, flip_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("flip") + next_command = world.time + cooldown_meme + + //REST + else if((findtext(message, rest_words))) + for(var/V in listeners) + var/mob/living/L = V + if(!L.resting) + L.lay_down() + next_command = world.time + cooldown_meme + + //GET UP + else if((findtext(message, getup_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.resting) + L.lay_down() //aka get up + L.SetStunned(0) + L.SetWeakened(0) + L.SetParalysis(0) //i said get up i don't care if you're being tazed + next_command = world.time + cooldown_damage + + //SIT + else if((findtext(message, sit_words))) + for(var/V in listeners) + var/mob/living/L = V + for(var/obj/structure/stool/bed/chair/chair in get_turf(L)) + chair.buckle_mob(L) + break + next_command = world.time + cooldown_meme + + //STAND UP + else if((findtext(message, stand_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.buckled && istype(L.buckled, /obj/structure/stool/bed/chair)) + L.buckled.unbuckle_mob(L) + next_command = world.time + cooldown_meme + + //DANCE + else if((findtext(message, dance_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("dance") + next_command = world.time + cooldown_meme + + //JUMP + else if((findtext(message, jump_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("HOW HIGH?!!") + L.emote("jump") + next_command = world.time + cooldown_meme + + //SALUTE + else if((findtext(message, salute_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("salute") + next_command = world.time + cooldown_meme + + //PLAY DEAD + else if((findtext(message, deathgasp_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("deathgasp") + next_command = world.time + cooldown_meme + + //PLEASE CLAP + else if((findtext(message, clap_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("clap") + next_command = world.time + cooldown_meme + + //HONK + else if((findtext(message, honk_words))) + spawn(25) + playsound(get_turf(owner), "sound/items/bikehorn.ogg", 300, 1) + if(owner.mind && owner.mind.assigned_role == "Clown") + for(var/mob/living/carbon/C in listeners) + C.slip(0,7 * power_multiplier) + next_command = world.time + cooldown_stun + else + next_command = world.time + cooldown_meme + + //RIGHT ROUND + else if((findtext(message, multispin_words))) + for(var/V in listeners) + var/mob/living/L = V + L.SpinAnimation(speed = 10, loops = 5) + next_command = world.time + cooldown_meme + + else + next_command = world.time + cooldown_none + + message_admins("[key_name_admin(owner)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + log_game("[key_name(owner)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") \ No newline at end of file diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index d1669591f82..cce2a515d7b 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -239,6 +239,7 @@ em {font-style: normal; font-weight: bold;} .playerreply {color: #8800bb; font-weight: bold;} .name { font-weight: bold;} .say {} +.yell { font-weight: bold;} .siliconsay {font-family: 'Courier New', Courier, monospace;} .deadsay {color: #5c00e6;} .radio {color: #008000;} @@ -323,8 +324,9 @@ h1.alert, h2.alert {color: #000000;} .cult {color: #800080; font-weight: bold; font-style: italic;} .cultspeech {color: #7F0000; font-style: italic;} .cultitalic {color: #960000; font-style: italic;} -.cultlarge {color: #960000; font-weight: bold; font-size: 3;} -.narsie {color: #960000; font-weight: bold; font-size: 15;} +.cultlarge {color: #960000; font-weight: bold; font-size: 120%;} +.narsie {color: #960000; font-weight: bold; font-size: 300%;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 200%;} .interface {color: #330033;} .big {font-size: 150%;} .reallybig {font-size: 175%;} @@ -341,10 +343,10 @@ h1.alert, h2.alert {color: #000000;} .revennotice {color: #1d2953;} .revenboldnotice {color: #1d2953; font-weight: bold;} -.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 120%;} .revenminor {color: #823abb} .revenwarning {color: #760fbb; font-style: italic;} -.revendanger {color: #760fbb; font-weight: bold; font-size: 3;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 120%;} /* /vg/ */ .good {color: green;} @@ -358,7 +360,7 @@ h1.alert, h2.alert {color: #000000;} "} .memo {color: #638500; text-align: center;} -.memoedit {text-align: center; font-size: 2;} +.memoedit {text-align: center; font-size: 75%;} .connectionClosed, .fatalError {background: red; color: white; padding: 5px;} .connectionClosed.restored {background: green;} @@ -369,6 +371,6 @@ h1.alert, h2.alert {color: #000000;} .hidden {display: none; visibility: hidden;} /* MEGAFAUNA */ -.colossus {color: #7F282A; font-size: 5;} -.hierophant {color: #660099; font-weight: bold; font-size: 4;} +.colossus {color: #7F282A; font-size: 175%;} +.hierophant {color: #660099; font-weight: bold; font-size: 150%;} .hierophant_warning {color: #660099; font-weight: bold; font-style: italic;} \ No newline at end of file diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 033446d49d3..a5638d1db1b 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/paradise.dme b/paradise.dme index d9b5b155bb0..0f96de59c40 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2068,6 +2068,7 @@ #include "code\modules\surgery\organs\parasites.dm" #include "code\modules\surgery\organs\robolimbs.dm" #include "code\modules\surgery\organs\skeleton.dm" +#include "code\modules\surgery\organs\vocal_cords.dm" #include "code\modules\surgery\organs\wound.dm" #include "code\modules\surgery\organs\subtypes\diona.dm" #include "code\modules\surgery\organs\subtypes\drask.dm"