From f50256eabbc8c5e820791bfdd495f9c90b790019 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 31 Jul 2013 11:50:56 -0700 Subject: [PATCH] Work progresses on species datums. Mass-commit due to repo issues requiring a reset. --- baystation12.dme | 1 - code/datums/datumvars.dm | 60 ++++++++++++++ code/game/gamemodes/heist/heist.dm | 3 +- code/modules/admin/verbs/one_click_antag.dm | 2 +- code/modules/admin/verbs/vox_raiders.dm | 3 - code/modules/mob/language.dm | 33 ++++++++ code/modules/mob/living/carbon/human/human.dm | 56 +++++++++++-- .../mob/living/carbon/human/species.dm | 82 +++++++++++++++++++ .../mob/living/carbon/human/update_icons.dm | 14 +++- code/modules/mob/living/say.dm | 69 ++++++++-------- code/modules/mob/living/simple_animal/vox.dm | 1 - code/modules/mob/mob.dm | 19 +++++ code/modules/mob/mob_defines.dm | 10 +-- code/modules/mob/new_player/new_player.dm | 20 ++--- code/modules/mob/say.dm | 14 ++-- 15 files changed, 312 insertions(+), 75 deletions(-) create mode 100644 code/modules/mob/language.dm create mode 100644 code/modules/mob/living/carbon/human/species.dm diff --git a/baystation12.dme b/baystation12.dme index a163701542..e2259a029c 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1344,7 +1344,6 @@ #include "code\ZAS\ZAS_Zones.dm" #include "interface\interface.dm" #include "interface\skin.dmf" -#include "maps\tgstation.2.1.0.0.1.dmm" #include "maps\RandomZLevels\Academy.dm" #include "maps\RandomZLevels\challenge.dm" #include "maps\RandomZLevels\stationCollision.dm" diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 81abf92546..cafc1c58cd 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -256,9 +256,12 @@ client body += "" body += "" + body += "" + body += "" if(ishuman(D)) body += "" body += "" + body += "" body += "" body += "" body += "" @@ -743,6 +746,63 @@ client H.dna.mutantrace = new_mutantrace H.update_mutantrace() + else if(href_list["setspecies"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["setspecies"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob/living/carbon/human" + return + + var/datum/species/new_species = input("Please choose a new species.","Species",null) as null|anything in (typesof(/datum/species)-/datum/species) + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.set_species(new new_species)) + usr << "Set species of [H] to [H.species]." + else + usr << "Failed! Something went wrong." + + else if(href_list["addlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["addlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + var/datum/language/new_language = input("Please choose a language to add.","Language",null) as null|anything in (typesof(/datum/language)-/datum/language) + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.add_language(new new_language)) + usr << "Added [new_language] to [H]." + else + usr << "Mob already knows that language." + + else if(href_list["remlanguage"]) + if(!check_rights(R_SPAWN)) return + + var/mob/H = locate(href_list["remlanguage"]) + if(!istype(H)) + usr << "This can only be done to instances of type /mob" + return + + var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages + + if(!H) + usr << "Mob doesn't exist anymore" + return + + if(H.remove_language(rem_language)) + usr << "Removed [rem_language] from [H]." + else + usr << "Mob doesn't know that language." + else if(href_list["regenerateicons"]) if(!check_rights(0)) return diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 6daacd3ffe..fa4299c3c1 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -95,10 +95,11 @@ var/global/vox_kills = 0 //Used to check the Inviolate. var/mob/living/carbon/human/vox = raider.current - vox.vox_talk_understand = 1 + vox.languages += new /datum/language/vox vox.real_name = capitalize(newname) vox.name = vox.real_name vox.age = rand(12,20) + vox.set_species(new /datum/species/vox) vox.dna.mutantrace = "vox" vox.h_style = "Short Vox Quills" vox.equip_vox_raider() diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 72e22b1c82..cfeb8fe4dc 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -507,7 +507,7 @@ client/proc/one_click_antag() i++ newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) - new_vox.vox_talk_understand = 1 + new_vox.languages += new /datum/language/vox new_vox.real_name = capitalize(newname) new_vox.name = new_vox.real_name new_vox.age = rand(12,20) diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index d226500fa8..65a0f65ad2 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -35,9 +35,6 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(src), slot_l_store) equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand) - var/obj/item/weapon/storage/pneumatic/W = new(src) - W.tank = new /obj/item/weapon/tank/nitrogen(W) - equip_to_slot_or_del(W, slot_r_hand) if(3) // Vox saboteur! equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(src), slot_wear_suit) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm new file mode 100644 index 0000000000..727437a19f --- /dev/null +++ b/code/modules/mob/language.dm @@ -0,0 +1,33 @@ +/* + Datum based languages. Easily editable and modular. +*/ + +/datum/language + var/name = "name" // Fluff name of language if any. + var/speech_verb // 'says', 'hisses', 'farts'. + var/colour // CSS style to use for strings in this language. + var/key // Character used to speak in language eg. :o for Unathi. + +/datum/language/unathi + name = "Sinta'unathi" + speech_verb = "hisses" + colour = "soghun" + key = "o" + +/datum/language/tajaran + name = "Siik'mas" + speech_verb = "mrowls" + colour = "tajaran" + key = "j" + +/datum/language/skrell + name = "Skrellian" + speech_verb = "warbles" + colour = "skrell" + key = "k" + +/datum/language/vox + name = "Vox-pidgin" + speech_verb = "shrieks" + colour = "vox" + key = "v" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1ceeba4e67..b8443a4f38 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -5,15 +5,40 @@ icon = 'icons/mob/human.dmi' icon_state = "body_m_s" var/list/hud_list = list() - + var/datum/species/species //Contains icon generation and language information, set during New(). /mob/living/carbon/human/dummy real_name = "Test Dummy" status_flags = GODMODE|CANPUSH +/mob/living/carbon/human/skrell/New() + h_style = "Skrell Male Tentacles" + set_species(new /datum/species/skrell(src)) + ..() +/mob/living/carbon/human/tajaran/New() + h_style = "Tajaran Ears" + set_species(new /datum/species/tajaran(src)) + ..() + +/mob/living/carbon/human/unathi/New() + h_style = "Unathi Horns" + set_species(new /datum/species/unathi(src)) + ..() + +/mob/living/carbon/human/vox/New() + h_style = "Short Vox Quills" + species = new /datum/species/vox(src) + ..() /mob/living/carbon/human/New() + + if(!species) + set_species() + + if(species.language) + languages += species.language + var/datum/reagents/R = new/datum/reagents(1000) reagents = R R.my_atom = src @@ -825,13 +850,13 @@ /mob/living/carbon/proc/update_mutantrace_languages() if(src.dna) if(src.dna.mutantrace == "lizard") - src.soghun_talk_understand = 1 + src.languages += new /datum/language/unathi else if(src.dna.mutantrace == "skrell") - src.skrell_talk_understand = 1 + src.languages += new /datum/language/skrell else if(src.dna.mutantrace == "tajaran") - src.tajaran_talk_understand = 1 + src.languages += new /datum/language/tajaran else if(src.dna.mutantrace == "vox") - src.vox_talk_understand = 1 + src.languages += new /datum/language/vox /mob/living/carbon/human/proc/play_xylophone() if(!src.xylophone) @@ -1246,3 +1271,24 @@ mob/living/carbon/human/yank_out_object() else usr << "\blue [self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)]." +/mob/living/carbon/human/proc/set_species(var/datum/species/new_species) + + if(!new_species) + new_species = new /datum/species/human + + if(species) + + if(species.name == new_species.name) + return + + var/temp = species + species = new_species + del(temp) + else + species = new_species + + if(species) + update_icons() + return 1 + else + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm new file mode 100644 index 0000000000..43db816b61 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species.dm @@ -0,0 +1,82 @@ +#define NO_EAT 1 +#define NO_BREATHE 2 +#define NO_SLEEP 4 +#define NO_SHOCK 8 +#define CLOTHING_RESTRICTED 16 +#define NON_GENDERED 32 +#define NO_ORGANS 64 +#define WHITELISTED 128 +#define REQUIRE_LIGHT 256 +#define ABHOR_LIGHT 512 + +/* + Datum-based species. Should make for much cleaner and easier to maintain mutantrace code. +*/ + +/datum/species + var/name // Species name. + var/icobase // Icon file to generate icons from. + var/deform // Icon file for deformities. + var/primitive // Lesser form, if any (ie. monkey for humans) + var/datum/language/language // Default racial language, if any. + + var/breath_type // Non-oxygen gas breathed, if any. + + var/heat_min // Freeze below this point. + var/heat_max // Overheat about this point. + var/pressure_min // Low-pressure brute below this point. + var/pressure_max // Crushing above this point. + + var/brute_resist // Physical damage reduction. + var/burn_resist // Burn damage reduction. + + var/flags = 0 // Various specific features. + +/datum/species/human + name = "Human" + icobase = 'icons/mob/human_races/r_human.dmi' + deform = 'icons/mob/human_races/r_def_human.dmi' + +/datum/species/unathi + name = "Unathi" + icobase = 'icons/mob/human_races/r_lizard.dmi' + deform = 'icons/mob/human_races/r_def_lizard.dmi' + language = new /datum/language/unathi + + flags = WHITELISTED + +/datum/species/tajaran + name = "Tajara" + icobase = 'icons/mob/human_races/r_tajaran.dmi' + deform = 'icons/mob/human_races/r_def_tajaran.dmi' + language = new /datum/language/tajaran + + flags = WHITELISTED + +/datum/species/skrell + name = "Skrell" + icobase = 'icons/mob/human_races/r_skrell.dmi' + deform = 'icons/mob/human_races/r_def_skrell.dmi' + language = new /datum/language/skrell + + flags = WHITELISTED + +/datum/species/vox + name = "Vox" + icobase = 'icons/mob/human_races/r_vox.dmi' + deform = 'icons/mob/human_races/r_def_vox.dmi' + language = new /datum/language/vox + + breath_type = "nitrogen" + +/datum/species/diona + name = "Diona" + icobase = 'icons/mob/human_races/r_plant.dmi' + deform = 'icons/mob/human_races/r_def_plant.dmi' + + flags = NO_EAT | NO_BREATHE | REQUIRE_LIGHT | NON_GENDERED + +/datum/species/shadow + name = "Shadow" + + flags = ABHOR_LIGHT | NON_GENDERED \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index eed0e94f1e..093e85d657 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -429,7 +429,17 @@ proc/get_damage_icon_part(damage_state, body_part) var/skeleton = (SKELETON in src.mutations) if(skeleton) race_icon = 'icons/mob/human_races/r_skeleton.dmi' - else if(dna) + + //Icon data is kept in species datums within the mob. + race_icon = 'icons/mob/human_races/r_human.dmi' + deform_icon = 'icons/mob/human_races/r_def_human.dmi' + + if(species.icobase) + race_icon = species.icobase + if(species.deform) + deform_icon = species.deform + + /*else if(dna) switch(dna.mutantrace) if("tajaran") race_icon = 'icons/mob/human_races/r_tajaran.dmi' @@ -450,7 +460,7 @@ proc/get_damage_icon_part(damage_state, body_part) race_icon = 'icons/mob/human_races/r_human.dmi' deform_icon = 'icons/mob/human_races/r_def_human.dmi' else - icon = 'icons/mob/human_races/r_human.dmi' + icon = 'icons/mob/human_races/r_human.dmi' */ if(dna) switch(dna.mutantrace) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 420e20a1b9..28d49b3904 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -85,6 +85,8 @@ var/list/department_radio_keys = list( if(dongle.translate_hive) return 1 /mob/living/say(var/message) + + //world << "[src] speaks! [message]" message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) message = capitalize(message) @@ -123,11 +125,14 @@ var/list/department_radio_keys = list( var/italics = 0 var/message_range = null var/message_mode = null + var/datum/language/speaking //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" - // Special message handling + + // General public key. Special message handling else if (copytext(message, 1, 2) == ";") if (ishuman(src)) message_mode = "headset" @@ -138,6 +143,12 @@ var/list/department_radio_keys = list( 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]") + //world << "Key [L.key] matches [lowertext(channel_prefix)] for [src]." + speaking = L + break message_mode = department_radio_keys[channel_prefix] //world << "channel_prefix=[channel_prefix]; message_mode=[message_mode]" if (message_mode) @@ -183,11 +194,6 @@ var/list/department_radio_keys = list( message += "Z" */ var/list/obj/item/used_radios = new - - var/is_speaking_skrell = 0 - var/is_speaking_soghun = 0 - var/is_speaking_taj = 0 - var/is_speaking_vox = 0 var/is_speaking_radio = 0 switch (message_mode) @@ -274,22 +280,6 @@ var/list/department_radio_keys = list( message_range = 1 italics = 1 - if ("tajaran") - if(tajaran_talk_understand || universal_speak) - is_speaking_taj = 1 - - if ("soghun") - if(soghun_talk_understand || universal_speak) - is_speaking_soghun = 1 - - if ("skrell") - if(skrell_talk_understand || universal_speak) - is_speaking_skrell = 1 - - if ("vox") - if(vox_talk_understand || universal_speak) - is_speaking_vox = 1 - if("changeling") if(mind && mind.changeling) for(var/mob/Changeling in mob_list) @@ -377,20 +367,31 @@ var/list/department_radio_keys = list( for (var/M in listening) if(hascall(M,"say_understands")) - if (M:say_understands(src) && !is_speaking_skrell && !is_speaking_soghun && !is_speaking_vox && !is_speaking_taj) + if (M:say_understands(src) && !speaking) + //world << "[M] understood [src] (0)." heard_a += M else if(ismob(M)) - if(is_speaking_skrell && (M:skrell_talk_understand || M:universal_speak)) - heard_a += M - else if(is_speaking_soghun && (M:soghun_talk_understand || M:universal_speak)) - heard_a += M - else if(is_speaking_taj && (M:tajaran_talk_understand || M:universal_speak)) - heard_a += M - else if(is_speaking_vox && (M:vox_talk_understand || M:universal_speak)) - heard_a += M + + // If speaking is set, it means that a language has been found that uses the given key. + // If it hasn't, then they are likely just speaking English. + + var/understood + var/mob/P = M + if (speaking) + for(var/datum/language/L in P.languages) + if(speaking.name == L.name) + understood = 1 + if(understood) + //world << "[M] understood [src] (1)." + heard_a += M + else + //world << "[M] didn't understand [src]." + heard_b += M else - heard_b += M + heard_a += M + else + //world << "[M] understood [src] (2)." heard_a += M var/speech_bubble_test = say_test(message) @@ -403,7 +404,7 @@ var/list/department_radio_keys = list( var/rendered = null if (length(heard_a)) - var/message_a = say_quote(message,is_speaking_soghun,is_speaking_skrell,is_speaking_taj,is_speaking_vox) + var/message_a = say_quote(message,speaking) if (italics) message_a = "[message_a]" @@ -428,7 +429,7 @@ var/list/department_radio_keys = list( message_b = voice_message else message_b = stars(message) - message_b = say_quote(message_b,is_speaking_soghun,is_speaking_skrell,is_speaking_taj,is_speaking_vox) + message_b = say_quote(message_b,speaking) if (italics) message_b = "[message_b]" diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm index 66d580c0d9..30f3ff19a6 100644 --- a/code/modules/mob/living/simple_animal/vox.dm +++ b/code/modules/mob/living/simple_animal/vox.dm @@ -18,7 +18,6 @@ attack_sound = 'sound/weapons/bladeslice.ogg' status_flags = 0 universal_speak = 1 - vox_talk_understand = 1 var/armour = null var/amp = null diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index adc535e70d..0bd7802709 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -956,3 +956,22 @@ mob/verb/yank_out_object() if(!pinned.len) anchored = 0 return 1 + +// Language handling. +/mob/proc/add_language(var/datum/language/new_language) + + for(var/datum/language/L in languages) + if(L && L.name == new_language.name) + return 0 + + languages += new_language + return 1 + +/mob/proc/remove_language(var/datum/language/rem_language) + + for(var/datum/language/L in languages) + if(L && L.name == rem_language.name) + languages -= L + return 1 + + return 0 \ No newline at end of file diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 45391a31f6..6cbd091c0c 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -86,9 +86,9 @@ 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/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/name_archive //For admin things like possession var/timeofdeath = 0.0//Living @@ -211,10 +211,6 @@ var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE var/robot_talk_understand = 0 var/alien_talk_understand = 0 - var/tajaran_talk_understand = 0 - var/soghun_talk_understand = 0 - var/skrell_talk_understand = 0 - var/vox_talk_understand = 0 var/has_limbs = 1 //Whether this mob have any limbs he can move with var/can_stand = 1 //Whether this mob have ability to stand diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index ea35f3c083..78ee54c6a9 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -350,30 +350,28 @@ if(client.prefs.species == "Tajaran") //This is like the worst, but it works, so meh. - Erthilo if(is_alien_whitelisted(src, "Tajaran") || !config.usealienwhitelist) new_character.dna.mutantrace = "tajaran" - new_character.tajaran_talk_understand = 1 + new_character.set_species(new /datum/species/tajaran) + new_character.languages += new /datum/language/tajaran if(client.prefs.species == "Unathi") if(is_alien_whitelisted(src, "Soghun") || !config.usealienwhitelist) new_character.dna.mutantrace = "lizard" - new_character.soghun_talk_understand = 1 + new_character.set_species(new /datum/species/unathi) + new_character.languages += new /datum/language/unathi if(client.prefs.species == "Skrell") if(is_alien_whitelisted(src, "Skrell") || !config.usealienwhitelist) new_character.dna.mutantrace = "skrell" - new_character.skrell_talk_understand = 1 - if(client.prefs.species == "Vox") - if(is_alien_whitelisted(src, "Vox"|| !config.usealienwhitelist)) - new_character.dna.mutantrace = "vox" - new_character.vox_talk_understand = 1 + new_character.set_species(new /datum/species/skrell) + new_character.languages += new /datum/language/skrell if(client.prefs.language == "Tajaran") if(is_alien_whitelisted(src, "Language_Tajaran") || !config.usealienwhitelist) - new_character.tajaran_talk_understand = 1 + new_character.languages += new /datum/language/tajaran if(client.prefs.language == "Unathi") if(is_alien_whitelisted(src, "Language_Soghun") || !config.usealienwhitelist) - new_character.soghun_talk_understand = 1 + new_character.languages += new /datum/language/unathi if(client.prefs.language == "Skrell") if(is_alien_whitelisted(src, "Language_Skrell") || !config.usealienwhitelist) - new_character.skrell_talk_understand = 1 - + new_character.languages += new /datum/language/skrell if(ticker.random_players) new_character.gender = pick(MALE, FEMALE) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index b6452266a0..a2786198e1 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -74,19 +74,15 @@ 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]\""; + + if (speaking) + return "[speaking.speech_verb], \"[text]\""; + //Needs Virus2 // if (src.disease_symptoms & DISEASE_HOARSE) // return "rasps, \"[text]\"";