[MODULAR] Fixes syndicate ghost roles not spawning with codespeak language, & an assortment of language related fixes/improvements (#19311)

* Fixes syndicate ghost roles not spawning with codespeak language

* Fixes related NRI issues as well while we're at it

* Fixes a couple issue and adds the new naming scheme

* Phonetic alphabet numbers, fixes trailing space in formatting

* change to NATO numbers rather than phonetic

* final quality sweep

* moved this into the proper place

* Removes the no longer in use 'rank' var

* fixes a runtime

* Update modular_skyrat/master_files/code/modules/mob_spawn/mob_spawn.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* Fixes a mistake

* refactor outfit paths

* Doc

* Fixes ashwalkers sometimes spawning without language

* Removes the need for post_transfer_prefs for languages and fixes language prefs not being applied correctly due to a bug

Fixes another bug - the innate language (common) was always being applied when a new mob was spawned on the station, but interestingly it works fine for ghost roles.

My solution to ensure that things are always set up correctly is to use the proc 'adjust_language_to_prefs' to do just that, and call it at the highest level after a mob spawns.

This fixes the bug that was making it so that even if you deselected common from language prefs you'd still get it no matter what. Which honestly I am still fuzzy on the precise cause of because of how much coupling there is between mind code, language holders, and spawning new mobs.  The logic of this code is absolutely mental and rather than try to weave things into functions it seems best to just do this instead. Less prone to breakage that way.

* Update modular_skyrat/master_files/code/modules/client/preferences/middleware/languages.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* Suggestions

* A more fitting description for this var

* Modifies language perk tooltips to better fit the codebase, refactors do_not_sanitize into a whitelist instead that can be configured for species

The Ashwalker tooltip inaccurately listed common as a language they were able to speak. Also slightly changed the wording of the rest of the tooltips to reflect the fact it is possible to disable a species' native tongue via prefs.

Refactored the 'do_not_sanitize' var to use a whitelist instead, allowing for more reliable sanitizing and also more configuration for new species to have such features.

* rephrasing

---------

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
This commit is contained in:
Bloop
2023-03-10 19:56:28 +00:00
committed by GitHub
co-authored by GoldenAlpharex
parent 089868ded3
commit 6d36e7cd5d
19 changed files with 231 additions and 57 deletions
@@ -0,0 +1,3 @@
// LANGUAGE SOURCE DEFINES
/// Use this when granting languages in special() for spawner roles, to prevent prefs from removing them
#define LANGUAGE_SPAWNER "spawner"
+1 -13
View File
@@ -53,22 +53,10 @@ Key procs
var/atom/owner
/// Initializes, and copies in the languages from the current atom if available.
///datum/language_holder/New(atom/_owner) //ORIGINAL
/datum/language_holder/New(atom/_owner, datum/preferences/pref_load) //SKYRAT EDIT CHANGE - CUSTOMIZATION
/datum/language_holder/New(atom/_owner)
if(_owner && QDELETED(_owner))
CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(_owner)]")
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
if(pref_load)
//If we're loading a holder from prefs, override the languages
understood_languages.Cut()
spoken_languages.Cut()
for(var/lang_path in pref_load.languages)
understood_languages[lang_path] = list(LANGUAGE_ATOM)
if(pref_load.languages[lang_path] == LANGUAGE_SPOKEN)
spoken_languages[lang_path] = list(LANGUAGE_ATOM)
//SKYRAT EDIT ADDITION END
owner = _owner
if(istype(owner, /datum/mind))
var/datum/mind/M = owner
@@ -2201,7 +2201,11 @@ GLOBAL_LIST_EMPTY(features_by_species)
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "comment",
SPECIES_PERK_NAME = "Native Speaker",
/* SKYRAT EDIT - Digitigrade customization - ORIGINAL:
SPECIES_PERK_DESC = "Alongside [initial(common_language.name)], [plural_form] gain the ability to speak [english_list(bonus_languages)].",
*/ // ORIGINAL END - SKYRAT EDIT START:
SPECIES_PERK_DESC = "Alongside [initial(common_language.name)], [plural_form] commonly speak [english_list(bonus_languages)].",
// SKYRAT EDIT END
))
qdel(temp_holder)
@@ -294,7 +294,7 @@
/obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/special(mob/living/new_spawn)
. = ..()
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_SPAWNER) // SKYRAT EDIT CHANGE - ORIGINAL: new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_mind)
/obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/comms
name = "Syndicate Comms Agent"
@@ -271,7 +271,7 @@
/obj/effect/mob_spawn/ghost_role/human/syndicatespace/special(mob/living/new_spawn)
. = ..()
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_SPAWNER) // SKYRAT EDIT CHANGE - ORIGINAL: new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
var/datum/job/spawn_job = SSjob.GetJobType(spawner_job_path)
var/policy = get_policy(spawn_job.policy_index)
if(policy)
@@ -38,11 +38,9 @@
"remove_language" = PROC_REF(remove_language),
)
/datum/preference_middleware/languages/apply_to_human(mob/living/carbon/human/target, datum/preferences/preferences) // SKYRAT EDIT CHANGE
/datum/preference_middleware/languages/apply_to_human(mob/living/carbon/human/target, datum/preferences/preferences)
var/datum/language_holder/language_holder = target.get_language_holder()
language_holder.remove_all_languages()
for(var/lang_path in preferences.languages)
language_holder.grant_language(lang_path)
language_holder.adjust_languages_to_prefs(preferences)
/datum/preference_middleware/languages/get_ui_assets()
return list(
@@ -90,7 +88,7 @@
for (var/language_name in GLOB.all_languages)
var/datum/language/language = GLOB.language_datum_instances[language_name]
if(language.secret)
if(language.secret && !(language.type in species.language_prefs_whitelist)) // For ghostrole species who are able to speak a secret language, e.g. ashwalkers, display it.
continue
if(species.always_customizable && !(language.type in lang_holder.spoken_languages)) // For the ghostrole species. We don't want ashwalkers speaking beachtongue now.
@@ -1,3 +1,55 @@
GLOBAL_DATUM_INIT(language_holder_adjustor, /datum/language_holder_adjustor, new)
/// Language code needs to be purged. Make sure, once and for all, that we get the correct languages on spawn.
/// Every time a crew member joins the adjustor will personally fix their language, because there is too much coupling between mind and language code to do it reliably otherwise.
/// It has already needed to be fixed like 3 times. This will (hopefully) be the final time.
/datum/language_holder_adjustor/New()
RegisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED, PROC_REF(handle_new_player))
/datum/language_holder_adjustor/proc/handle_new_player(datum/source, mob/living/new_crewmember, rank)
SIGNAL_HANDLER
// sanity checking because we really do not want to be causing any runtimes
if(!ishuman(new_crewmember))
return
if(isnull(new_crewmember.mind))
return
if(isnull(new_crewmember.mind.language_holder))
return
var/mob/living/carbon/human/new_human = new_crewmember
var/datum/language_holder/language_holder = new_human.get_language_holder()
if(isnull(language_holder))
return
language_holder.adjust_languages_to_prefs(new_human.client?.prefs)
/datum/language_holder_adjustor/Destroy()
..()
UnregisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED)
/datum/language_holder/proc/adjust_languages_to_prefs(datum/preferences/preferences)
// no prefs? then don't remove any languages
if(!preferences)
return
// remove the innate languages (like common, and other species languages) and instead use the language prefs
// do not remove any languages granted by spawners, which are denoted by source = LANGUAGE_SPAWNER
remove_all_languages(source = LANGUAGE_MIND)
remove_all_languages(source = LANGUAGE_ATOM)
for(var/lang_path in preferences.languages)
grant_language(lang_path)
get_selected_language()
//************************************************
//* Specific language holders *
//* Use atom language sources only. *
//************************************************/
/datum/language_holder/machine // SYNTHETIC LIZARD & CO LANGUAGE
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
/datum/language/machine = list(LANGUAGE_ATOM))
@@ -0,0 +1,13 @@
/**
* # species datum
*
* Datum that handles different species in the game.
*
* This datum handles species in the game, such as lizardpeople, mothmen, zombies, skeletons, etc.
* It is used in [carbon humans][mob/living/carbon/human] to determine various things about them, like their food preferences, if they have biological genders, their damage resistances, and more.
*
*/
/datum/species
/// Adding a language type to this in the form of /datum/language will allow the language to be displayed in preferences for that species, even if it is a secret language.
/// Currently used for ashtongue in ashwalkers.
var/list/language_prefs_whitelist
@@ -0,0 +1,21 @@
/*
Lizard subspecies: ASHWALKERS
*/
/datum/species/lizard/ashwalker/
language_prefs_whitelist = list(/datum/language/ashtongue)
/datum/species/lizard/ashwalker/create_pref_language_perk()
var/list/to_add = list()
// Holding these variables so we can grab the exact names for our perk.
var/datum/language/common_language = /datum/language/ashtongue
to_add += list(list(
SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
SPECIES_PERK_ICON = "comment",
SPECIES_PERK_NAME = "Native Speaker",
SPECIES_PERK_DESC = "Ashwalkers can only speak [initial(common_language.name)]. \
It is rare, but not impossible, for an Ashwalker to learn another language."
))
return to_add
@@ -20,6 +20,8 @@
if(quirks_enabled)
SSquirks.AssignQuirks(spawned_human, spawned_human.client)
post_transfer_prefs(spawned_human)
if(loadout_enabled)
spawned_human.equip_outfit_and_loadout(outfit, spawned_human.client.prefs)
else
@@ -36,3 +38,10 @@
if(!is_pref_loaded)
equip(spawned_mob)
return spawned_mob
// Anything that can potentially be overwritten by transferring prefs must go in this proc
// This is needed because safe_transfer_prefs_to() can override some things that get set in special() for certain roles, like name replacement
// In those cases, please override this proc as well as special()
// TODO: refactor create() and special() so that this is no longer necessary
/obj/effect/mob_spawn/ghost_role/proc/post_transfer_prefs(mob/living/new_spawn)
return
@@ -12,7 +12,7 @@
/obj/effect/mob_spawn/ghost_role/human/black_mesa/special(mob/living/carbon/human/spawned_human)
. = ..()
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_SPAWNER)
/datum/outfit/science_team
name = "Scientist"
@@ -44,7 +44,7 @@
/obj/effect/mob_spawn/ghost_role/human/black_mesa/guard/special(mob/living/carbon/human/spawned_human)
. = ..()
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_SPAWNER)
/datum/outfit/security_guard
name = "Security Guard"
@@ -86,7 +86,7 @@
/obj/effect/mob_spawn/ghost_role/human/black_mesa/hecu/special(mob/living/carbon/human/spawned_human)
. = ..()
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_SPAWNER)
/obj/item/clothing/under/rank/security/officer/hecu //Subtype of security for armor (and because I dont want to repath it)
name = "urban camouflage BDU"
@@ -181,9 +181,9 @@
/obj/effect/mob_spawn/ghost_role/human/black_mesa/hecu/leader/special(mob/living/carbon/human/spawned_human)
. = ..()
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_SPAWNER)
spawned_human.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_SPAWNER)
spawned_human.grant_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_SPAWNER)
/datum/outfit/hecu/leader
name = "HECU Captain"
@@ -4,3 +4,5 @@ GLOBAL_LIST_INIT(last_names_vulp, world.file2list("modular_skyrat/modules/custom
GLOBAL_LIST_INIT(first_names_male_taj, world.file2list("modular_skyrat/modules/customization/strings/names/first_male_taj.txt"))
GLOBAL_LIST_INIT(first_names_female_taj, world.file2list("modular_skyrat/modules/customization/strings/names/first_female_taj.txt"))
GLOBAL_LIST_INIT(last_names_taj, world.file2list("modular_skyrat/modules/customization/strings/names/last_taj.txt"))
GLOBAL_LIST_INIT(callsigns_nri, world.file2list("modular_skyrat/modules/customization/strings/names/callsigns_nri.txt"))
GLOBAL_LIST_INIT(phonetic_alphabet_numbers, world.file2list("modular_skyrat/modules/customization/strings/names/phonetic_alphabet_numbers.txt"))
@@ -10,7 +10,9 @@
var/datum/language/language = new lang_path()
// Yes, checking subtypes is VERY necessary, because byond doesn't check to see if a path is valid at runtime!
// If you delete /datum/language/meme, it will still load as /datum/language/meme, and will instantiate with /datum/language's defaults!
if(!(language.type in subtypesof(/datum/language)) || language.secret)
var/species_type = read_preference(/datum/preference/choiced/species)
var/datum/species/species = new species_type()
if(!(language.type in subtypesof(/datum/language)) || (language.secret && !(language.type in species.language_prefs_whitelist)))
languages.Remove(lang_path)
languages_edited = TRUE
return languages_edited
@@ -0,0 +1,46 @@
Defender
Hero
Jury
King
Line
Patrol
Roller
Union
Victor
Xray
Yellow
Apex
Ion
Jet
Kilo
Mace
Nova
Payback
Sundown
Uniform
Echo
Flatline
Helix
Ice
Quicksand
Ripcord
Flash
Ranger
Hammer
Sweeper
Swift
Sword
Tracker
Razor
Spear
Dagger
Ghost
Reaper
Nomad
Hurricane
Phantom
Judge
Shadow
Stinger
Storm
Winder
@@ -0,0 +1,10 @@
Zero
One
Two
Three
Four
Five
Six
Seven
Eight
Niner
@@ -1,3 +1,6 @@
/// To know whether or not we have an officer already
GLOBAL_VAR(first_officer)
///NRI police patrol with a mission to find out if the fine reason is legitimate and then act from there.
/datum/pirate_gang/nri_raiders
name = "NRI IAC Police Patrol"
@@ -50,7 +53,20 @@
built_threat_content = replacetext(built_threat_content, "%STATION", station_designation)
return new /datum/comm_message(threat_title, built_threat_content, possible_answers)
/datum/outfit/pirate/nri_officer
/datum/outfit/pirate/nri/post_equip(mob/living/carbon/human/equipped)
. = ..()
equipped.faction -= "pirate"
equipped.faction |= "raider"
// make sure we update the ID's name too
var/obj/item/card/id/id_card = equipped.wear_id
if(istype(id_card))
id_card.registered_name = equipped.real_name
id_card.update_label()
handlebank(equipped)
/datum/outfit/pirate/nri/officer
name = "NRI Field Officer"
head = /obj/item/clothing/head/beret/sec/nri
@@ -75,15 +91,10 @@
id = /obj/item/card/id/advanced
id_trim = /datum/id_trim/nri_raider/officer
/datum/outfit/pirate/nri_officer/post_equip(mob/living/carbon/human/equipped)
. = ..()
equipped.faction -= "pirate"
equipped.faction |= "raider"
/datum/id_trim/nri_raider/officer
assignment = "NRI Field Officer"
/datum/outfit/pirate/nri_marine
/datum/outfit/pirate/nri/marine
name = "NRI Marine"
head = null
@@ -107,11 +118,6 @@
id = /obj/item/card/id/advanced
id_trim = /datum/id_trim/nri_raider
/datum/outfit/pirate/nri_marine/post_equip(mob/living/carbon/human/equipped)
. = ..()
equipped.faction -= "pirate"
equipped.faction |= "raider"
/datum/id_trim/nri_raider
assignment = "NRI Marine"
trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
@@ -129,21 +135,27 @@
icon_state = "cryopod"
mob_species = /datum/species/human
faction = list("raider")
var/rank = "NRI Marine"
you_are_text = "You are a Novaya Rossiyskaya Imperiya task force."
flavour_text = "The station has refused to pay the fine for breaking Imperial regulations, you are here to recover the debt. Do so by demanding the funds. Force approach is usually recommended, but isn't the only method."
important_text = "Allowed races are humans, Akulas, IPCs. Follow your field officer's orders. Important mention - while you are listed as the pirates gamewise, you really aren't lore-and-everything-else-wise. Roleplay accordingly."
outfit = /datum/outfit/pirate/nri_marine
spawner_job_path = null
outfit = /datum/outfit/pirate/nri/marine
restricted_species = list(/datum/species/human, /datum/species/akula, /datum/species/synthetic)
random_appearance = FALSE
show_flavor = TRUE
/obj/effect/mob_spawn/ghost_role/human/nri_raider/proc/apply_codename(mob/living/carbon/human/spawned_human)
var/callsign = pick(GLOB.callsigns_nri)
var/number = pick(GLOB.phonetic_alphabet_numbers)
spawned_human.fully_replace_character_name(null, "[callsign] [number]")
/obj/effect/mob_spawn/ghost_role/human/nri_raider/special(mob/living/carbon/human/spawned_human)
. = ..()
var/last_name = pick(GLOB.last_names)
spawned_human.fully_replace_character_name(null, "[rank] [last_name]")
spawned_human.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_SPAWNER)
apply_codename(spawned_human)
/obj/effect/mob_spawn/ghost_role/human/nri_raider/post_transfer_prefs(mob/living/carbon/human/spawned_human)
. = ..()
apply_codename(spawned_human)
/obj/effect/mob_spawn/ghost_role/human/nri_raider/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
@@ -156,18 +168,29 @@
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer
name = "NRI Officer sleeper"
mob_name = "Novaya Rossiyskaya Imperiya raiding party's field officer"
outfit = /datum/outfit/pirate/nri_officer
rank = "Field Officer"
outfit = /datum/outfit/pirate/nri/officer
important_text = "Allowed races are humans, Akulas, IPCs. Important mention - while you are listed as the pirates gamewise, you really aren't lore-and-everything-else-wise. Roleplay accordingly. There is an important document in your pocket I'd advise you to read and keep safe."
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/apply_codename(mob/living/carbon/human/spawned_human)
var/callsign = pick(GLOB.callsigns_nri)
var/number = pick(GLOB.phonetic_alphabet_numbers)
spawned_human.fully_replace_character_name(null, "[callsign] [number][GLOB.first_officer == spawned_human ? " Actual" : ""]")
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/special(mob/living/carbon/human/spawned_human)
. = ..()
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/panslavic, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_MIND)
spawned_human.grant_language(/datum/language/uncommon, TRUE, TRUE, LANGUAGE_SPAWNER)
spawned_human.grant_language(/datum/language/yangyu, TRUE, TRUE, LANGUAGE_SPAWNER)
// if this is the first officer, keep a reference to them
if(!GLOB.first_officer)
GLOB.first_officer = spawned_human
/obj/effect/mob_spawn/ghost_role/human/nri_raider/marine
rank = "Marine"
apply_codename(spawned_human)
/obj/effect/mob_spawn/ghost_role/human/nri_raider/officer/post_transfer_prefs(mob/living/carbon/human/spawned_human)
. = ..()
apply_codename(spawned_human)
/datum/map_template/shuttle/pirate/nri_raider
prefix = "_maps/shuttles/skyrat/"
@@ -167,7 +167,7 @@ GLOBAL_LIST_INIT(call911_do_and_do_not, list(
cop.mind.add_antag_datum(ert_antag)
cop.mind.set_assigned_role(SSjob.GetJobType(ert_antag.ert_job_path))
SSjob.SendToLateJoin(cop)
cop.grant_language(/datum/language/common, TRUE, TRUE, LANGUAGE_MIND)
cop.grant_language(/datum/language/common, TRUE, TRUE, LANGUAGE_SPAWNER)
var/obj/item/gangster_cellphone/phone = new() // biggest gang in the city
phone.gang_id = cell_phone_number
@@ -585,7 +585,7 @@ GLOBAL_LIST_INIT(call911_do_and_do_not, list(
cop.mind.add_antag_datum(ert_antag)
cop.mind.set_assigned_role(SSjob.GetJobType(ert_antag.ert_job_path))
SSjob.SendToLateJoin(cop)
cop.grant_language(/datum/language/common, TRUE, TRUE, LANGUAGE_MIND)
cop.grant_language(/datum/language/common, TRUE, TRUE, LANGUAGE_SPAWNER)
var/obj/item/gangster_cellphone/phone = new() // biggest gang in the city
phone.gang_id = cell_phone_number
@@ -83,11 +83,11 @@
/obj/effect/mob_spawn/ghost_role/human/ds2/syndicate/special(mob/living/new_spawn)
. = ..()
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_SPAWNER)
/obj/effect/mob_spawn/ghost_role/human/ds2/syndicate_command/special(mob/living/new_spawn)
. = ..()
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_SPAWNER)
/obj/effect/mob_spawn/ghost_role/human/ds2/syndicate/service
outfit = /datum/outfit/ds2/syndicate/service
+4 -1
View File
@@ -353,6 +353,7 @@
#include "code\__DEFINES\~skyrat_defines\is_helpers.dm"
#include "code\__DEFINES\~skyrat_defines\jobs.dm"
#include "code\__DEFINES\~skyrat_defines\keybindings.dm"
#include "code\__DEFINES\~skyrat_defines\language.dm"
#include "code\__DEFINES\~skyrat_defines\lewd_defines.dm"
#include "code\__DEFINES\~skyrat_defines\liquids.dm"
#include "code\__DEFINES\~skyrat_defines\loadouts.dm"
@@ -5339,7 +5340,7 @@
#include "modular_skyrat\master_files\code\modules\jobs\job_types\mime.dm"
#include "modular_skyrat\master_files\code\modules\jobs\job_types\tarkon.dm"
#include "modular_skyrat\master_files\code\modules\language\language.dm"
#include "modular_skyrat\master_files\code\modules\language\language_holders.dm"
#include "modular_skyrat\master_files\code\modules\language\language_holder.dm"
#include "modular_skyrat\master_files\code\modules\mob\dead\new_player\latejoin_menu.dm"
#include "modular_skyrat\master_files\code\modules\mob\dead\new_player\preferences_setup.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\blood.dm"
@@ -5348,6 +5349,8 @@
#include "modular_skyrat\master_files\code\modules\mob\living\living_defines.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human_helpers.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species_type\lizardpeople.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species_type\snail.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\human\monkey.dm"
#include "modular_skyrat\master_files\code\modules\mob\living\human\species.dm"