diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 0081954da84..4195f6d1385 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -324,7 +324,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use "name" = displayname, // the mob's display name "job" = jobname, // the mob's job "key" = mobkey, // the mob's key - "vmessage" = M.voice_message, // the message to display if the voice wasn't understood + "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood "vname" = M.voice_name, // the name to display if the voice wasn't understood "vmask" = voicemask, // 1 if the mob is using a voice gas mask @@ -381,7 +381,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use "name" = displayname, // the mob's display name "job" = jobname, // the mob's job "key" = mobkey, // the mob's key - "vmessage" = M.voice_message, // the message to display if the voice wasn't understood + "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood "vname" = M.voice_name, // the name to display if the voice wasn't understood "vmask" = voicemask, // 1 if the mob is using a voice gas mas @@ -414,7 +414,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use //THIS IS TEMPORARY. if(!connection) return //~Carn - Broadcast_Message(connection, M, voicemask, M.voice_message, + Broadcast_Message(connection, M, voicemask, pick(M.speak_emote), src, message, displayname, jobname, real_name, M.voice_name, filter_type, signal.data["compression"], list(position.z), connection.frequency) @@ -477,10 +477,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use else heard_normal += R else - if (M.voice_message) - heard_voice += R - else - heard_garbled += R + heard_garbled += R if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled)) var/part_a = "" @@ -576,11 +573,11 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use R.show_message(rendered, 2) if (length(heard_voice)) - var/rendered = "[part_a][M.voice_name][part_b][M.voice_message][part_c]" + var/rendered = "[part_a][M.voice_name][part_b][pick(M.speak_emote)][part_c]" for (var/mob/R in heard_voice) if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][M.voice_name] ([eqjobname]) [part_b][M.voice_message][part_c]", 2) + R.show_message("[part_a][M.voice_name] ([eqjobname]) [part_b][pick(M.speak_emote)][part_c]", 2) else R.show_message(rendered, 2) diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index eaa345be1bd..416528d3fc0 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -1,7 +1,7 @@ // All mobs should have custom emote, really.. /mob/proc/custom_emote(var/m_type=1,var/message = null) - if(!use_me && usr == src) + if(stat || !use_me && usr == src) usr << "You are unable to emote." return diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index ba868a2bd46..df71b214492 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -43,11 +43,18 @@ key = "v" flags = RESTRICTED -/* +/datum/language/diona + name = "Rootspeak" + desc = "A creaking, subvocal language spoken instinctively by the Dionaea. Due to the unique makeup of the average Diona, a phrase of Rootspeak can be a combination of anywhere from one to twelve individual voices and notes." + speech_verb = "creaks and rustles" + colour = "soghun" + key = "q" + flags = RESTRICTED + /datum/language/human name = "Sol Common" desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." - key = "hum" + key = "1" flags = RESTRICTED // Galactic common languages (systemwide accepted standards). @@ -55,14 +62,13 @@ name = "Tradeband" desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." speech_verb = "enunciates" - key = "tra" + key = "2" /datum/language/gutter name = "Gutter" desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements." speech_verb = "growls" - key = "gut" -*/ + key = "3" // Language handling. /mob/proc/add_language(var/language) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 6edffa4f359..4d4ddf7bde3 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -5,8 +5,7 @@ /mob/living/carbon/alien name = "alien" voice_name = "alien" - voice_message = "hisses" - say_message = "hisses" + speak_emote = list("hisses") icon = 'icons/mob/alien.dmi' gender = NEUTER dna = null diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index ee6e046089f..6e6a9eb4178 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -22,11 +22,12 @@ return ..(message) else -// ~lol~ +/* ~lol~ /mob/living/carbon/alien/say_quote(var/text) // var/ending = copytext(text, length(text)) return "[say_message], \"[text]\""; +*/ /mob/living/proc/alien_talk(var/message) @@ -77,4 +78,4 @@ continue if (M.stat > 1 && istype(M, /mob/dead/observer)) rendered2 = "Hivemind, [name] (Follow) [message_a]" - M.show_message(rendered2, 2) + M.show_message(rendered2, 2) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index a2cc5d21a9a..d0a8ce5a876 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -5,7 +5,6 @@ var/list/datum/disease2/disease/virus2 = list() var/antibodies = 0 - var/silent = null //Can't talk. Value goes down every life proc. var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm var/life_tick = 0 // The amount of life ticks that have processed on this mob. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index befb0e9703c..c44f35aa61f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -169,6 +169,114 @@ stat("Energy Charge", round(wear_suit:cell:charge/100)) +/mob/living/carbon/human/ex_act(severity) + if(!blinded) + flick("flash", flash) + + var/shielded = 0 + var/b_loss = null + var/f_loss = null + switch (severity) + if (1.0) + b_loss += 500 + if (!prob(getarmor(null, "bomb"))) + gib() + return + else + var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) + throw_at(target, 200, 4) + //return +// var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src))) + //user.throw_at(target, 200, 4) + + if (2.0) + if (!shielded) + b_loss += 60 + + f_loss += 60 + + if (prob(getarmor(null, "bomb"))) + b_loss = b_loss/1.5 + f_loss = f_loss/1.5 + + if (!istype(ears, /obj/item/clothing/ears/earmuffs)) + ear_damage += 30 + ear_deaf += 120 + if (prob(70) && !shielded) + Paralyse(10) + + if(3.0) + b_loss += 30 + if (prob(getarmor(null, "bomb"))) + b_loss = b_loss/2 + if (!istype(ears, /obj/item/clothing/ears/earmuffs)) + ear_damage += 15 + ear_deaf += 60 + if (prob(50) && !shielded) + Paralyse(10) + + var/update = 0 + + // focus most of the blast on one organ + var/datum/organ/external/take_blast = pick(organs) + update |= take_blast.take_damage(b_loss * 0.9, f_loss * 0.9, used_weapon = "Explosive blast") + + // distribute the remaining 10% on all limbs equally + b_loss *= 0.1 + f_loss *= 0.1 + + var/weapon_message = "Explosive Blast" + + for(var/datum/organ/external/temp in organs) + switch(temp.name) + if("head") + update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message) + if("chest") + update |= temp.take_damage(b_loss * 0.4, f_loss * 0.4, used_weapon = weapon_message) + if("l_arm") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("r_arm") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("l_leg") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("r_leg") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("r_foot") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("l_foot") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("r_arm") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if("l_arm") + update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) + if(update) UpdateDamageIcon() + + +/mob/living/carbon/human/blob_act() + if(stat == 2) return + show_message("\red The blob attacks you!") + var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") + var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone)) + apply_damage(rand(30,40), BRUTE, affecting, run_armor_check(affecting, "melee")) + return + +/mob/living/carbon/human/meteorhit(O as obj) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\red [src] has been hit by [O]", 1) + if (health > 0) + var/datum/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head")) + if(!affecting) return + if (istype(O, /obj/effect/immovablerod)) + if(affecting.take_damage(101, 0)) + UpdateDamageIcon() + else + if(affecting.take_damage((istype(O, /obj/effect/meteor/small) ? 10 : 25), 30)) + UpdateDamageIcon() + updatehealth() + return + + /mob/living/carbon/human/hand_p(mob/M as mob) var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index c22b6136066..d17b9e39503 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -235,6 +235,16 @@ radiation = 0 else + if(species.flags & RAD_ABSORB) + var/rads = radiation/25 + radiation -= rads + nutrition += rads + heal_overall_damage(rads,rads) + adjustOxyLoss(-(rads)) + adjustToxLoss(-(rads)) + updatehealth() + return + var/damage = 0 switch(radiation) if(1 to 49) @@ -274,6 +284,7 @@ if(reagents.has_reagent("lexorin")) return if(mNobreath in mutations) return // No breath mutation means no breathing. if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return + if(species && species.flags & NO_BREATHE) return var/datum/organ/internal/lungs/L = internal_organs["lungs"] L.process() @@ -311,7 +322,6 @@ breath = loc.remove_air(breath_moles) - if(!is_lung_ruptured()) if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) if(prob(5)) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 42cb5038f39..c6fc84c517a 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -68,11 +68,18 @@ O.hear_talk(src, message) var/list/listening = hearers(message_range, src) - listening -= src - listening += src + listening |= src + + //Pass whispers on to anything inside the immediate listeners. + for(var/mob/L in listening) + for(var/mob/C in L.contents) + if(istype(C,/mob/living)) + listening += C + var/list/eavesdropping = hearers(2, src) eavesdropping -= src eavesdropping -= listening + var/list/watching = hearers(5, src) watching -= src watching -= listening @@ -110,10 +117,7 @@ if (length(heard_b)) var/message_b - if (src.voice_message) - message_b = src.voice_message - else - message_b = stars(message) + message_b = stars(message) if (italics) message_b = "[message_b]" diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index dc0f916be23..e6b8d0067a6 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -3,8 +3,7 @@ icon = 'icons/mob/slimes.dmi' icon_state = "grey baby slime" pass_flags = PASSTABLE - voice_message = "skree!" - say_message = "hums" + speak_emote = list("hums") layer = 5 @@ -56,6 +55,7 @@ name = "adult slime" icon = 'icons/mob/slimes.dmi' icon_state = "grey adult slime" + speak_emote = list("telepathically chirps") health = 200 gender = NEUTER diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 6b174e9fa74..010e0fa2d63 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -117,6 +117,17 @@ emote("collapse") if (radiation) + + if(istype(src,/mob/living/carbon/monkey/diona)) //Filthy check. Dionaea don't take rad damage. + var/rads = radiation/25 + radiation -= rads + nutrition += rads + heal_overall_damage(rads,rads) + adjustOxyLoss(-(rads)) + adjustToxLoss(-(rads)) + updatehealth() + return + if (radiation > 100) radiation = 100 Weaken(10) @@ -408,6 +419,25 @@ proc/handle_chemicals_in_body() + if(istype(src,/mob/living/carbon/monkey/diona)) //Filthy check. Dionaea nymphs need light or they get sad. + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(loc)) //else, there's considered to be no light + var/turf/T = loc + var/area/A = T.loc + if(A) + if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights + else light_amount = 5 + + nutrition += light_amount + traumatic_shock -= light_amount + + if(nutrition > 500) + nutrition = 500 + if(light_amount > 2) //if there's enough light, heal + heal_overall_damage(1,1) + adjustToxLoss(-1) + adjustOxyLoss(-1) + if(reagents) reagents.metabolize(src) if (drowsyness) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index a073dfa10d5..7f109dd7d7a 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -1,8 +1,7 @@ /mob/living/carbon/monkey name = "monkey" voice_name = "monkey" - voice_message = "chimpers" - say_message = "chimpers" + speak_emote = list("chimpers") icon_state = "monkey1" icon = 'icons/mob/monkey.dmi' gender = NEUTER @@ -17,24 +16,21 @@ /mob/living/carbon/monkey/tajara name = "farwa" voice_name = "farwa" - voice_message = "mews" - say_message = "mews" + speak_emote = list("mews") ico = "tajkey" uni_append = "0A0E00" /mob/living/carbon/monkey/skrell name = "neaera" voice_name = "neaera" - voice_message = "squicks" - say_message = "squicks" + speak_emote = list("squicks") ico = "skrellkey" uni_append = "01CC92" /mob/living/carbon/monkey/unathi name = "stok" voice_name = "stok" - voice_message = "hisses" - say_message = "hisses" + speak_emote = list("hisses") ico = "stokkey" uni_append = "044C5D" @@ -43,7 +39,7 @@ reagents = R R.my_atom = src - if(name == "monkey" || name == "farwa" || name == "stok" || name == "neara") //Hideous but necessary to stop Pun-Pun becoming generic. + if(name == "monkey" || name == "farwa" || name == "stok" || name == "neara" || name == "diona nymph") //Hideous but necessary to stop Pun-Pun becoming generic. name = "[name] ([rand(1, 1000)])" real_name = name @@ -71,18 +67,29 @@ ..() dna.mutantrace = "lizard" greaterform = "Unathi" + add_language("Sinta'unathi") /mob/living/carbon/monkey/skrell/New() ..() dna.mutantrace = "skrell" greaterform = "Skrell" + add_language("Skrellian") /mob/living/carbon/monkey/tajara/New() ..() dna.mutantrace = "tajaran" greaterform = "Tajaran" + add_language("Siik'tajr") + +/mob/living/carbon/monkey/diona/New() + + ..() + gender = NEUTER + dna.mutantrace = "plant" + greaterform = "Diona" + add_language("Rootspeak") /mob/living/carbon/monkey/movement_delay() var/tally = 0 diff --git a/code/modules/mob/living/carbon/monkey/say.dm b/code/modules/mob/living/carbon/monkey/say.dm index b2136593683..8df10082f70 100644 --- a/code/modules/mob/living/carbon/monkey/say.dm +++ b/code/modules/mob/living/carbon/monkey/say.dm @@ -1,8 +1,9 @@ -/mob/living/carbon/monkey/say(var/message) +/mob/living/carbon/monkey/say(var/message,var/forced_by=null) if (silent) return else return ..() - +/* /mob/living/carbon/monkey/say_quote(var/text) return "[src.say_message], \"[text]\""; +*/ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 4c650040651..27020376c00 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -15,7 +15,7 @@ var/attack_verb = "punch" // Empty hand hurt intent verb. var/mutantrace // Safeguard due to old code. - var/breath_type // Non-oxygen gas breathed, if any. + var/breath_type = "oxygen" // Non-oxygen gas breathed, if any. var/survival_gear = /obj/item/weapon/storage/box/survival // For spawnin'. var/cold_level_1 = 260 // Cold damage level 1 below this point. @@ -73,6 +73,14 @@ attack_verb = "scratch" darksight = 8 + cold_level_1 = 200 + cold_level_2 = 140 + cold_level_3 = 80 + + heat_level_1 = 330 + heat_level_2 = 380 + heat_level_3 = 800 + primitive = /mob/living/carbon/monkey/tajara flags = WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL @@ -92,6 +100,13 @@ deform = 'icons/mob/human_races/r_def_vox.dmi' language = "Vox-pidgin" + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + eyes = "vox_eyes_s" breath_type = "nitrogen" survival_gear=/obj/item/weapon/storage/box/survival/vox @@ -102,6 +117,19 @@ name = "Diona" icobase = 'icons/mob/human_races/r_plant.dmi' deform = 'icons/mob/human_races/r_def_plant.dmi' + language = "Rootspeak" attack_verb = "slash" + primitive = /mob/living/carbon/monkey/diona - flags = WHITELISTED | NO_EAT | NO_BREATHE | REQUIRE_LIGHT | NON_GENDERED | NO_SCAN | IS_PLANT \ No newline at end of file + warning_low_pressure = 50 + hazard_low_pressure = -1 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 2000 + heat_level_2 = 3000 + heat_level_3 = 4000 + + flags = WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NON_GENDERED | NO_SCAN | IS_PLANT | RAD_ABSORB diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index a5f347679a6..f350b03d8fd 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -29,7 +29,6 @@ var/t_sl_gas = null var/t_n2 = null - var/now_pushing = null var/cameraFollow = null @@ -39,4 +38,5 @@ var/specialsauce = 0 //Has this person consumed enough special sauce? IF so they're a ticking time bomb of death. - var/implanting = 0 //Used for the mind-slave implant \ No newline at end of file + var/implanting = 0 //Used for the mind-slave implant + var/silent = null //Can't talk. Value goes down every life proc. \ No newline at end of file diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 162106e00e4..8e207abaff1 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -15,10 +15,6 @@ var/list/department_radio_keys = list( ":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate", ":u" = "Supply", "#u" = "Supply", ".u" = "Supply", ":g" = "changeling", "#g" = "changeling", ".g" = "changeling", - ":k" = "skrell", "#k" = "skrell", ".k" = "skrell", - ":j" = "tajaran", "#j" = "tajaran", ".j" = "tajaran", - ":o" = "soghun", "#o" = "soghun", ".o" = "soghun", - ":v" = "vox", "#v" = "vox", ".v" = "vox", ":R" = "right hand", "#R" = "right hand", ".R" = "right hand", ":L" = "left hand", "#L" = "left hand", ".L" = "left hand", @@ -35,10 +31,6 @@ var/list/department_radio_keys = list( ":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate", ":U" = "Supply", "#U" = "Supply", ".U" = "Supply", ":G" = "changeling", "#G" = "changeling", ".G" = "changeling", - ":K" = "skrell", "#K" = "skrell", ".K" = "skrell", - ":J" = "tajaran", "#J" = "tajaran", ".J" = "tajaran", - ":O" = "soghun", "#O" = "soghun", ".O" = "soghun", - ":V" = "vox", "#V" = "vox", ".V" = "vox", //kinda localization -- rastaf0 //same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding. @@ -56,10 +48,7 @@ var/list/department_radio_keys = list( ":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk", ":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate", ":é" = "Supply", "#é" = "Supply", ".é" = "Supply", - ":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling", - ":ë" = "skrell", "#ë" = "skrell", ".ë" = "skrell", - ":î" = "tajaran", "#î" = "tajaran", ".î" = "tajaran", - ":ù" = "soghun", "#ù" = "soghun", ".ù" = "soghun" + ":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling" ) /mob/living/proc/binarycheck() @@ -84,15 +73,21 @@ var/list/department_radio_keys = list( if(!istype(dongle)) return if(dongle.translate_hive) return 1 -/mob/living/say(var/message) +// /vg/edit: Added forced_by for handling braindamage messages and meme stuff +/mob/living/say(var/message, var/forced_by=null) message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) message = capitalize(message) if (!message) return - if (stat == 2) + if(silent) + return + + if (stat == 2) // Dead. return say_dead(message) + else if (stat) // Unconcious. + return if (src.client) if(client.prefs.muted & MUTE_IC) @@ -109,6 +104,7 @@ var/list/department_radio_keys = list( if (sdisabilities & MUTE) return + // Muzzled. if (istype(wear_mask, /obj/item/clothing/mask/muzzle)) return @@ -125,38 +121,41 @@ var/list/department_radio_keys = list( var/message_mode = null var/datum/language/speaking = null //For use if a specific language is being spoken. - // If brain damaged, talk on headset at random. - if (getBrainLoss() >= 60 && prob(50)) - if (ishuman(src)) - message_mode = "headset" + var/braindam = getBrainLoss() + if (braindam >= 60) + if(prob(braindam/4)) + message = stutter(message) + if(prob(braindam)) + message = uppertext(message) // General public key. Special message handling - else if (copytext(message, 1, 2) == ";") + else if (copytext(message, 1, 2) == ";" || prob(braindam/2)) if (ishuman(src)) message_mode = "headset" else if(ispAI(src) || isrobot(src)) message_mode = "pAI" message = copytext(message, 2) - + // Begin checking for either a message mode or a language to speak. else if (length(message) >= 2) var/channel_prefix = copytext(message, 1, 3) //Check if the person is speaking a language that they know. - for(var/datum/language/L in languages) - if(lowertext(channel_prefix) == ":[L.key]") - speaking = L - break + if(languages.len) + for(var/datum/language/L in languages) + if(lowertext(channel_prefix) == ":[L.key]") + speaking = L + break message_mode = department_radio_keys[channel_prefix] - if (message_mode) + if (message_mode || speaking || copytext(message,1,2) == ":") message = trim(copytext(message, 3)) - if (!(ishuman(src) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department" || (message_mode in radiochannels)))) + if (!(istype(src,/mob/living/carbon/human) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department" || (message_mode in radiochannels)))) message_mode = null //only humans can use headsets // Check changed so that parrots can use headsets. Other simple animals do not have ears and will cause runtimes. // And borgs -Sieve /* /vg/ removals if(src.stunned > 2 || (traumatic_shock > 61 && prob(50))) - message_mode = "" //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it + message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it */ if (!message) return @@ -398,7 +397,10 @@ var/list/department_radio_keys = list( //BEGIN TELEPORT CHANGES if(!istype(M, /mob/new_player)) if(M && M.stat == DEAD) - rendered2 = "[GetVoice()] [alt_name] (Follow) [message_a]" + if(forced_by) + rendered2 = "[GetVoice()] (forced by [forced_by])[alt_name] (Follow) [message_a]" + else + rendered2 = "[GetVoice()] [alt_name] (Follow) [message_a]" M:show_message(rendered2, 2) continue //END CHANGES @@ -415,12 +417,8 @@ var/list/department_radio_keys = list( if (length(heard_b)) var/message_b - - if (voice_message) - message_b = voice_message - else - message_b = stars(message) - message_b = say_quote(message_b,speaking) + message_b = stars(message) + message_b = say_quote(message_b,speaking) if (italics) message_b = "[message_b]" @@ -434,7 +432,10 @@ var/list/department_radio_keys = list( MM = M if(!istype(MM, /mob/new_player) && MM) if(MM && MM.stat == DEAD) - rendered2 = "[voice_name] (Follow) [message_b]" + if(forced_by) + rendered2 = "[voice_name] (forced by [forced_by]) (Follow) [message_b]" + else + rendered2 = "[voice_name] (Follow) [message_b]" MM:show_message(rendered2, 2) continue if(hascall(M,"show_message")) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 9ea8a4be1fd..6fd7db5d10e 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -14,9 +14,9 @@ turns_per_move = 5 see_in_dark = 6 meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "pokes the" stop_automated_movement_when_pulled = 0 maxHealth = 60 health = 60 @@ -43,28 +43,25 @@ desc = "" response_help = "pets" response_disarm = "gently pushes aside" - response_harm = "hits" - -/mob/living/simple_animal/hostile/bear/Move() - ..() - if(stat != DEAD) - if(loc && istype(loc,/turf/space)) - icon_state = "bear" - else - icon_state = "bearfloor" + response_harm = "pokes" /mob/living/simple_animal/hostile/bear/Life() . =..() if(!.) return + if(loc && istype(loc,/turf/space)) + icon_state = "bear" + else + icon_state = "bearfloor" + switch(stance) if(HOSTILE_STANCE_TIRED) stop_automated_movement = 1 stance_step++ if(stance_step >= 10) //rests for 10 ticks - if(target && target in ListTargets()) + if(target_mob && target_mob in ListTargets(10)) stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle. else stance = HOSTILE_STANCE_IDLE @@ -72,15 +69,15 @@ if(HOSTILE_STANCE_ALERT) stop_automated_movement = 1 var/found_mob = 0 - if(target && target in ListTargets()) - if(!(SA_attackable(target))) + if(target_mob && target_mob in ListTargets(10)) + if(!(SA_attackable(target_mob))) stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again. stance_step++ found_mob = 1 - src.dir = get_dir(src,target) //Keep staring at the mob + src.dir = get_dir(src,target_mob) //Keep staring at the mob if(stance_step in list(1,4,7)) //every 3 ticks - var/action = pick( list( "growls at [target]", "stares angrily at [target]", "prepares to attack [target]", "closely watches [target]" ) ) + var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) ) if(action) emote(action) if(!found_mob) @@ -105,18 +102,18 @@ if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING) stance = HOSTILE_STANCE_ALERT stance_step = 6 - target = user + target_mob = user ..() /mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob) if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING) stance = HOSTILE_STANCE_ALERT stance_step = 6 - target = M + target_mob = M ..() /mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0) - return 1 //No drifting in space for space bears! + return //No drifting in space for space bears! /mob/living/simple_animal/hostile/bear/FindTarget() . = ..() @@ -128,22 +125,22 @@ ..(5) /mob/living/simple_animal/hostile/bear/AttackingTarget() - emote( pick( list("slashes at [target]", "bites [target]") ) ) + emote( pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) var/damage = rand(20,30) - if(ishuman(target)) - var/mob/living/carbon/human/H = target + if(ishuman(target_mob)) + var/mob/living/carbon/human/H = target_mob var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee")) return H - else if(isliving(target)) - var/mob/living/L = target + else if(isliving(target_mob)) + var/mob/living/L = target_mob L.adjustBruteLoss(damage) return L - else if(istype(target,/obj/mecha)) - var/obj/mecha/M = target + else if(istype(target_mob,/obj/mecha)) + var/obj/mecha/M = target_mob M.attack_animal(src) return M diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index bfb1430b224..353ca6156f3 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -34,7 +34,7 @@ max_n2 = 0 minbodytemp = 0 - //break_stuff_probability = 2 + break_stuff_probability = 2 faction = "carp" diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index d4f89aa6ee4..04398bfb702 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -18,9 +18,9 @@ turns_per_move = 5 see_in_dark = 10 meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "pokes the" stop_automated_movement_when_pulled = 0 maxHealth = 75 // Was 200 health = 75 // 150/2 @@ -34,6 +34,7 @@ var/busy = 0 pass_flags = PASSTABLE move_to_delay = 6 + speed = 3 //nursemaids - these create webs and eggs // Slower @@ -69,8 +70,8 @@ /mob/living/simple_animal/hostile/giant_spider/AttackingTarget() ..() - if(isliving(target)) - var/mob/living/L = target + if(isliving(target_mob)) + var/mob/living/L = target_mob if(L.reagents) if(prob(poison_per_bite)) src.visible_message("\red \the [src] injects a powerful toxin!") @@ -107,14 +108,14 @@ if(D.density==1) // Closed busy=MOVING_TO_TARGET Goto(D, move_to_delay) - target=D + target_mob=D GiveUp(D) return if(busy) - if(busy == MOVING_TO_TARGET && target) - var/obj/machinery/door/D = target + if(busy == MOVING_TO_TARGET && target_mob) + var/obj/machinery/door/D = target_mob if(D.density==1) - if(get_dist(src, target) > 1) + if(get_dist(src, target_mob) > 1) return // keep movin'. stop_automated_movement = 1 walk(src,0) @@ -134,11 +135,12 @@ cocoon_target = null busy = 0 stop_automated_movement = 0 + /mob/living/simple_animal/hostile/giant_spider/hunter/proc/GiveUp(var/C) spawn(100) if(busy == MOVING_TO_TARGET) - if(target == C && get_dist(src,target) > 1) - target = null + if(target_mob == C && get_dist(src,target_mob) > 1) + target_mob = null busy = 0 stop_automated_movement = 0 @@ -146,7 +148,7 @@ ..() if(!stat) if(stance == HOSTILE_STANCE_IDLE) - var/list/can_see = ListTargets() + var/list/can_see = view(src, 10) //30% chance to stop wandering and do something if(!busy && prob(30)) //first, check for potential food nearby to cocoon @@ -220,7 +222,6 @@ //give up if we can't reach them after 10 seconds GiveUp(O) - else if(busy == MOVING_TO_TARGET && cocoon_target) if(get_dist(src, cocoon_target) <= 1) if(istype(cocoon_target, /mob/living/simple_animal/hostile/giant_spider)) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index f8262ce8832..45b639fc045 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -1,23 +1,27 @@ /mob/living/simple_animal/hostile faction = "hostile" var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior - var/target + var/target_mob // /vg/ edit: Removed type specification so spiders can target doors. var/attack_same = 0 var/ranged = 0 var/rapid = 0 var/projectiletype var/projectilesound var/casingtype - var/move_to_delay = 2 //delay for the automated movement. + var/move_to_delay = 4 //delay for the automated movement. var/list/friends = list() - var/vision_range = 10 + var/break_stuff_probability = 10 stop_automated_movement_when_pulled = 0 + var/destroy_surroundings = 1 /mob/living/simple_animal/hostile/proc/FindTarget() var/atom/T = null stop_automated_movement = 0 - for(var/atom/A in ListTargets()) + for(var/atom/A in ListTargets(10)) + + if(A == src) + continue var/atom/F = Found(A) if(F) @@ -32,19 +36,27 @@ continue else if(!L.stat) + stance = HOSTILE_STANCE_ATTACK T = L break else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets(). var/obj/mecha/M = A if (M.occupant) + stance = HOSTILE_STANCE_ATTACK T = M break + if(istype(A, /obj/machinery/bot)) + var/obj/machinery/bot/B = A + if (B.health > 0) + stance = HOSTILE_STANCE_ATTACK + T = B + break return T /mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target) - target = new_target + target_mob = new_target stance = HOSTILE_STANCE_ATTACK return @@ -56,44 +68,47 @@ /mob/living/simple_animal/hostile/proc/MoveToTarget() stop_automated_movement = 1 - if(!target || SA_attackable(target)) - LoseTarget() - if(target in ListTargets()) + if(!target_mob || SA_attackable(target_mob)) + stance = HOSTILE_STANCE_IDLE + if(target_mob in ListTargets(10)) if(ranged) - if(get_dist(src, target) <= 6) - OpenFire(target) + if(get_dist(src, target_mob) <= 6) + OpenFire(target_mob) else - Goto(target, move_to_delay) + Goto(target_mob, move_to_delay) else stance = HOSTILE_STANCE_ATTACKING - Goto(target, move_to_delay) + Goto(target_mob, move_to_delay) /mob/living/simple_animal/hostile/proc/AttackTarget() stop_automated_movement = 1 - if(!target || SA_attackable(target)) + if(!target_mob || SA_attackable(target_mob)) LoseTarget() return 0 - if(!(target in ListTargets())) + if(!(target_mob in ListTargets(10))) LostTarget() return 0 - if(get_dist(src, target) <= 1) //Attacking + if(get_dist(src, target_mob) <= 1) //Attacking AttackingTarget() return 1 /mob/living/simple_animal/hostile/proc/AttackingTarget() - if(isliving(target)) - var/mob/living/L = target + if(isliving(target_mob)) + var/mob/living/L = target_mob L.attack_animal(src) return L - if(istype(target,/obj/mecha)) - var/obj/mecha/M = target + if(istype(target_mob,/obj/mecha)) + var/obj/mecha/M = target_mob M.attack_animal(src) return M + if(istype(target_mob,/obj/machinery/bot)) + var/obj/machinery/bot/B = target_mob + B.attack_animal(src) /mob/living/simple_animal/hostile/proc/LoseTarget() stance = HOSTILE_STANCE_IDLE - target = null + target_mob = null walk(src, 0) /mob/living/simple_animal/hostile/proc/LostTarget() @@ -101,16 +116,11 @@ walk(src, 0) -/mob/living/simple_animal/hostile/proc/ListTargets(var/override = -1) - - // Allows you to override how much the mob can see. Defaults to vision_range if none is entered. - if(override == -1) - override = vision_range - - var/list/L = hearers(src, override) +/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7) + var/list/L = hearers(src, dist) for(var/obj/mecha/M in mechas_list) // Will check the distance before checking the line of sight, if the distance is small enough. - if(get_dist(M, src) <= override && can_see(src, M, override)) + if(get_dist(M, src) <= dist && can_see(src, M, dist)) L += M return L @@ -130,19 +140,20 @@ if(!stat) switch(stance) if(HOSTILE_STANCE_IDLE) - var/new_target = FindTarget() - GiveTarget(new_target) + target_mob = FindTarget() if(HOSTILE_STANCE_ATTACK) - DestroySurroundings() + if(destroy_surroundings) + DestroySurroundings() MoveToTarget() if(HOSTILE_STANCE_ATTACKING) - DestroySurroundings() + if(destroy_surroundings) + DestroySurroundings() AttackTarget() -/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target) - var/target = the_target +/mob/living/simple_animal/hostile/proc/OpenFire(target_mob) + var/target = target_mob visible_message("\red [src] fires at [target]!", 1) var/tturf = get_turf(target) @@ -165,7 +176,7 @@ new casingtype stance = HOSTILE_STANCE_IDLE - target = null + target_mob = null return @@ -188,7 +199,8 @@ return /mob/living/simple_animal/hostile/proc/DestroySurroundings() - for(var/dir in cardinal) // North, South, East, West - var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir)) - if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) - obstacle.attack_animal(src) + if(prob(break_stuff_probability)) + for(var/dir in cardinal) // North, South, East, West + var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir)) + if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) + obstacle.attack_animal(src) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index a9cb3d7a4ac..f97e0eb8c28 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -22,7 +22,7 @@ speed = 8 projectiletype = /obj/item/projectile/beam/drone projectilesound = 'sound/weapons/laser3.ogg' - //destroy_surroundings = 0 + destroy_surroundings = 0 var/datum/effect/effect/system/ion_trail_follow/ion_trail //the drone randomly switches between these states because it's malfunctioning diff --git a/code/modules/mob/living/simple_animal/kobold.dm b/code/modules/mob/living/simple_animal/kobold.dm index acf1fa1ea7c..3d9515c88b6 100644 --- a/code/modules/mob/living/simple_animal/kobold.dm +++ b/code/modules/mob/living/simple_animal/kobold.dm @@ -2,7 +2,7 @@ /mob/living/simple_animal/kobold name = "kobold" desc = "A small, rat-like creature." - icon = 'mob.dmi' + icon = 'icons/mob/mob.dmi' icon_state = "kobold_idle" icon_living = "kobold_idle" icon_dead = "kobold_dead" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d943a0e8fef..8cab8e6096a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -9,7 +9,6 @@ var/icon_gib = null //We only try to show a gibbing animation if this exists. var/list/speak = list() - var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable. var/speak_chance = 0 var/list/emote_hear = list() //Hearable emotes var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps @@ -24,9 +23,9 @@ var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it. //Interaction - var/response_help = "pokes" - var/response_disarm = "shoves" - var/response_harm = "hits" + var/response_help = "You try to help" + var/response_disarm = "You try to disarm" + var/response_harm = "You try to hurt" var/harm_intent_damage = 3 //Temperature effect @@ -96,7 +95,7 @@ AdjustParalysis(-1) //Movement - if(!client && !stop_automated_movement && wander) + if(!client && !stop_automated_movement && wander && !anchored) if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. turns_since_move++ if(turns_since_move >= turns_per_move) @@ -229,14 +228,10 @@ return "[emote], \"[text]\"" return "says, \"[text]\""; -/mob/living/simple_animal/emote(var/act) - if(stat) - return +/mob/living/simple_animal/emote(var/act, var/type, var/desc) if(act) - if(act == "scream") act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P - for (var/mob/O in viewers(src, null)) - O.show_message("[src] [act].") - + if(act == "scream") act = "whimper" //ugly hack to stop animals screaming when crushed :P + ..(act, type, desc) /mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) @@ -265,7 +260,7 @@ if (health > 0) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O.show_message("\blue [M] [response_help] [src].") + O.show_message("\blue [M] [response_help] [src]") if("grab") if (M == src || anchored) @@ -290,7 +285,7 @@ adjustBruteLoss(harm_intent_damage) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O.show_message("\red [M] [response_harm] [src]!") + O.show_message("\red [M] [response_harm] [src]") return @@ -353,7 +348,7 @@ if(M.Victim) return // can't attack while eating! - visible_message("\red [M.name] glomps [src]!") + visible_message("\red \The [M.name] glomps [src]!") var/damage = rand(1, 3) @@ -375,32 +370,22 @@ var/obj/item/stack/medical/MED = O if(health < maxHealth) if(MED.amount >= 1) - if(MED.heal_brute >= 1) - adjustBruteLoss(-MED.heal_brute) - MED.amount -= 1 - if(MED.amount <= 0) - del(MED) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\blue [user] applies [MED] on [src]") - return - else - user << "\blue [MED] won't help at all." - return - else - user << "\blue [src] is at full health." - return + adjustBruteLoss(-MED.heal_brute) + MED.amount -= 1 + if(MED.amount <= 0) + del(MED) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\blue [user] applies the [MED] on [src]") else - user << "\blue [src] is dead, medical items won't bring it back to life." - return - else if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. + user << "\blue this [src] is dead, medical items won't bring it back to life." + if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) new meat_type (get_turf(src)) if(prob(95)) del(src) return gib() - return else if(O.force) var/damage = O.force @@ -409,12 +394,12 @@ adjustBruteLoss(damage) for(var/mob/M in viewers(src, null)) if ((M.client && !( M.blinded ))) - M.show_message("\red \b "+"[src] has been attacked with [O] by [user]. ") + M.show_message("\red \b [src] has been attacked with the [O] by [user]. ") else usr << "\red This weapon is ineffective, it does no damage." for(var/mob/M in viewers(src, null)) if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") + M.show_message("\red [user] gently taps [src] with the [O]. ") @@ -460,13 +445,25 @@ if(health < 1) Die() -/mob/living/simple_animal/proc/SA_attackable(target) - if (isliving(target)) - var/mob/living/L = target - if(!L.stat) - return 0 - if (istype(target,/obj/mecha)) - var/obj/mecha/M = target +/mob/living/simple_animal/proc/SA_attackable(target_mob) + if (isliving(target_mob)) + var/mob/living/L = target_mob + if(!L.stat && L.health >= 0) + return (0) + if (istype(target_mob,/obj/mecha)) + var/obj/mecha/M = target_mob if (M.occupant) - return 0 - return 1 + return (0) + if (istype(target_mob,/obj/machinery/bot)) + var/obj/machinery/bot/B = target_mob + if(B.health > 0) + return (0) + return (1) + +//Call when target overlay should be added/removed +/mob/living/simple_animal/update_targeted() + if(!targeted_by && target_locked) + del(target_locked) + overlays = null + if (targeted_by && target_locked) + overlays += target_locked \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index fe55adf8a80..5bb896f9792 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -26,10 +26,10 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\mob\mob.dm:25: t+= "\red Temperature: [environment.temperature] \n" t += {"\red Temperature: [environment.temperature] \n - \blue Nitrogen: [environment.nitrogen] \n - \blue Oxygen: [environment.oxygen] \n - \blue Plasma : [environment.toxins] \n - \blue Carbon Dioxide: [environment.carbon_dioxide] \n"} +\blue Nitrogen: [environment.nitrogen] \n +\blue Oxygen: [environment.oxygen] \n +\blue Plasma : [environment.toxins] \n +\blue Carbon Dioxide: [environment.carbon_dioxide] \n"} // END AUTOFIX for(var/datum/gas/trace_gas in environment.trace_gases) usr << "\blue [trace_gas.type]: [trace_gas.moles] \n" diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 2131c899a08..782aab7324b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -86,9 +86,11 @@ var/lastpuke = 0 var/unacidable = 0 var/small = 0 - var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm) - var/list/embedded = list() //Embedded items, since simple mobs don't have organs. - var/list/languages = list() // For speaking/listening. + var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm) + var/list/embedded = list() //Embedded items, since simple mobs don't have organs. + var/list/languages = list() // For speaking/listening. + var/list/speak_emote = list("says") //Verbs used when speaking. Defaults to 'say' if speak_emote is null. + var/name_archive //For admin things like possession var/timeofdeath = 0.0//Living @@ -155,8 +157,6 @@ //see: setup.dm for list of mutations var/voice_name = "unidentifiable voice" - var/voice_message = null // When you are not understood by others (replaced with just screeches, hisses, chimpers etc.) - var/say_message = null // When you are understood by others. Currently only used by aliens and monkeys in their say_quote procs var/faction = "neutral" //Used for checking whether hostile simple animals will attack you, possibly more stuff later var/move_on_shuttle = 1 // Can move on the shuttle. diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 44554ed984a..eae5ed931ee 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -346,7 +346,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /proc/shake_camera(mob/M, duration, strength=1) if(!M || !M.client || M.shakecamera) return - spawn(0) + spawn(1) var/oldeye=M.client.eye var/x M.shakecamera = 1 diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index ae437a894c8..d443d53271b 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -37,6 +37,10 @@ usr << "\red Speech is currently admin-disabled." return + if(client && !(client.prefs.toggles & CHAT_DEAD)) + usr << "\red You have deadchat muted." + return + if(mind && mind.name) name = "[mind.name]" else @@ -57,49 +61,67 @@ M.show_message(rendered2, 2) //Takes into account blindness and such. return -/mob/proc/say_understands(var/mob/other) +/mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null) + if(!other) return 1 - if (src.stat == 2) + //Universal speak makes everything understandable, for obvious reasons. + else if(other.universal_speak || src.universal_speak) return 1 - else if (istype(other, src.type)) + else if (src.stat == 2) return 1 + else if (speaking) //Language check. + + var/understood + for(var/datum/language/L in src.languages) + if(speaking.name == L.name) + understood = 1 + break + + if(understood || universal_speak) + return 1 + else + return 0 + else if(other.universal_speak || src.universal_speak) return 1 else if(isAI(src) && ispAI(other)) return 1 + else if (istype(other, src.type) || istype(src, other.type)) + return 1 return 0 -/mob/proc/say_quote(var/text,var/is_speaking_soghun,var/is_speaking_skrell,var/is_speaking_tajaran,var/is_speaking_vox) +/mob/proc/say_quote(var/text,var/datum/language/speaking) + if(!text) return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code //tcomms code is still runtiming somewhere here var/ending = copytext(text, length(text)) - if (is_speaking_soghun) - return "hisses, \"[text]\""; - if (is_speaking_skrell) - return "warbles, \"[text]\""; - if (is_speaking_tajaran) - return "mrowls, \"[text]\""; - if (is_speaking_vox) - return "chirps, \"[text]\""; -//Needs Virus2 -// if (src.disease_symptoms & DISEASE_HOARSE) -// return "rasps, \"[text]\""; - if (src.stuttering) - return "stammers, \"[text]\""; - if (src.slurring) - return "slurrs, \"[text]\""; - if(isliving(src)) + + var/speechverb = "" + + if (speaking) + speechverb = "[speaking.speech_verb], \"" + else if(speak_emote && speak_emote.len) + speechverb = "[pick(speak_emote)], \"" + else if (src.stuttering) + speechverb = "stammers, \"" + else if (src.slurring) + speechverb = "slurrs, \"" + else if (ending == "?") + speechverb = "asks, \"" + else if (ending == "!") + speechverb = "exclaims, \"" + else if(isliving(src)) var/mob/living/L = src if (L.getBrainLoss() >= 60) - return "gibbers, \"[text]\""; - if (ending == "?") - return "asks, \"[text]\""; - if (ending == "!") - return "exclaims, \"[text]\""; + speechverb = "gibbers, \"" + else + speechverb = "says, \"" + else + speechverb = "says, \"" - return "says, \"[text]\""; + return "[speechverb][text]\"" /mob/proc/emote(var/act, var/type, var/message) if(act == "me") diff --git a/code/modules/virus2/centrifuge.dm b/code/modules/virus2/centrifuge.dm index cf1cb141aca..95d76d75566 100644 --- a/code/modules/virus2/centrifuge.dm +++ b/code/modules/virus2/centrifuge.dm @@ -42,7 +42,7 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\centrifuge.dm:41: dat += "
Blood sample:" dat += {"
Blood sample: -
"} +
"} // END AUTOFIX if(sample) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list @@ -53,8 +53,8 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\centrifuge.dm:48: dat += "
" dat += {"
- Antibodies: [antigens2string(B.data["antibodies"])] - Isolate"} +Antibodies: [antigens2string(B.data["antibodies"])] +Isolate"} // END AUTOFIX var/list/virus = B.data["virus2"] for (var/ID in virus) @@ -63,7 +63,7 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\centrifuge.dm:55: dat += "
pathogen [V.name()]" dat += {"
pathogen [V.name()] - Isolate"} +Isolate"} // END AUTOFIX else dat += "Please check container contents." diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm index 44d90c97f41..21da6c2669f 100644 --- a/code/modules/virus2/curer.dm +++ b/code/modules/virus2/curer.dm @@ -63,7 +63,7 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\curer.dm:62: dat += "
Antibodies: [code]" dat += {"
Antibodies: [code] -
Begin antibody production"} +
Begin antibody production"} // END AUTOFIX else dat += "
Please check container contents." diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 261d46f179d..f315dc88dfa 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -128,7 +128,10 @@ var/list/res = list() for (var/ID in viruses) var/datum/disease2/disease/V = viruses[ID] - res["[V.uniqueID]"] = V.getcopy() + if(istype(V)) + res["[V.uniqueID]"] = V.getcopy() + else + testing("Got a NULL disease2 in virus_copylist!") return res diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index fff77e7ef4e..59abb2890d1 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -62,7 +62,7 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\diseasesplicer.dm:61: dat += "" dat += {" -
Burn DNA Sequence to data storage disk"} +
Burn DNA Sequence to data storage disk"} // END AUTOFIX else dat += "Empty." diff --git a/code/modules/virus2/dishincubator.dm b/code/modules/virus2/dishincubator.dm index 57b35c82663..df939172e31 100644 --- a/code/modules/virus2/dishincubator.dm +++ b/code/modules/virus2/dishincubator.dm @@ -109,41 +109,41 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\dishincubator.dm:108: dat += "Power status : [string]" dat += {"Power status : [string] -
- Food supply : [foodsupply] -
- Radiation Levels : [radiation] RADS : Radiate -
- Toxins : [toxins] -

"} +
+Food supply : [foodsupply] +
+Radiation Levels : [radiation] RADS : Radiate +
+Toxins : [toxins] +

"} // END AUTOFIX if(beaker) // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\dishincubator.dm:117: dat += "Eject chemicals : Eject" dat += {"Eject chemicals : Eject -
"} +
"} // END AUTOFIX if(dish) // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\dishincubator.dm:120: dat += "Eject Virus dish : Eject" dat += {"Eject Virus dish : Eject -
"} +
"} // END AUTOFIX if(beaker) // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\dishincubator.dm:123: dat += "Breed viral culture in beaker : Start" dat += {"Breed viral culture in beaker : Start -
"} +
"} // END AUTOFIX // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\virus2\dishincubator.dm:125: dat += "

" dat += {"

- Flush system
- Close
"} +Flush system
+Close
"} // END AUTOFIX user << browse("Pathogenic incubatorincubator menu:

[dat]", "window=incubator;size=575x400") onclose(user, "incubator") diff --git a/code/modules/virus2/isolator.dm b/code/modules/virus2/isolator.dm index 9e09f330733..b3dbcaa062b 100644 --- a/code/modules/virus2/isolator.dm +++ b/code/modules/virus2/isolator.dm @@ -39,6 +39,11 @@ if(B) Blood = B break + // /vg/: Try to fix isolators + if(!Blood) + usr << "\red ERROR: Unable to locate blood within the beaker. Bug?" + testing("Unable to locate blood in [beaker]!") + return var/list/virus = virus_copylist(Blood.data["virus2"]) var/choice = text2num(href_list["isolate"]); for (var/datum/disease2/disease/V in virus) diff --git a/code/setup.dm b/code/setup.dm index 1477faf880f..41343379ec5 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -722,7 +722,7 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define NO_EAT 1 #define NO_BREATHE 2 #define NO_SLEEP 4 -#define NO_SHOCK 8 +#define RAD_ABSORB 8 #define NO_SCAN 16 #define NON_GENDERED 32 #define REQUIRE_LIGHT 64 diff --git a/html/changelog.html b/html/changelog.html index 0b7ff46b0c6..0fe95912707 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -93,14 +93,14 @@

Pomf123 updated

  • Space is cold for humans again.
  • -
  • Bhangometer now logs the 'theoretical' size of the bomb if its over the cap.
  • +
  • Bhangmeter now logs the 'theoretical' size of the bomb if its over the cap.
  • Adds 50 milk and x5 meat button for biogenerator
  • Fixed ventcrawling being broken by aliens (possibly).
  • Posibrains no longer speak or hear binary.
  • Fixed pump shotguns fucking up when fired point-blank.
  • Fixed users using flavor text to pretend being braindead.
  • -
  • Aliums can see in the dark now
  • -
  • Phazon removed due to be imbalanced as fuck.
  • +
  • Aliums can see in the dark now.
  • +
  • Phazon removed due to being imbalanced as fuck.