Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Dahlular
2021-03-10 01:08:21 -07:00
20 changed files with 87037 additions and 2427 deletions
File diff suppressed because it is too large Load Diff
+1
View File
@@ -15,6 +15,7 @@
#define DISABLE_DEATHRATTLE (1<<12)
#define DISABLE_ARRIVALRATTLE (1<<13)
#define COMBOHUD_LIGHTING (1<<14)
#define ANTAG_SYNC_WITH_CHARS (1<<15)
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
+1 -4
View File
@@ -390,6 +390,7 @@ SUBSYSTEM_DEF(job)
var/datum/job/job = GetJob(rank)
H.job = rank
equip_loadout(N, H)
//If we joined at roundstart we should be positioned at our workstation
if(!joined_late)
@@ -416,8 +417,6 @@ SUBSYSTEM_DEF(job)
H.mind.assigned_role = rank
if(job)
if(!job.dresscodecompliant)// CIT CHANGE - dress code compliance
equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items
var/new_mob = job.equip(H, null, null, joined_late)
if(ismob(new_mob))
H = new_mob
@@ -449,8 +448,6 @@ SUBSYSTEM_DEF(job)
H.add_memory("Your account ID is [wageslave.account_id].")
if(job && H)
if(job.dresscodecompliant)// CIT CHANGE - dress code compliance
equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
+25 -25
View File
@@ -40,31 +40,44 @@
//Start with uniform,suit,backpack for additional slots
if(uniform)
H.equip_to_slot_or_del(new uniform(H),SLOT_W_UNIFORM)
H.equip_to_slot_or_store_and_del(new uniform(H),SLOT_W_UNIFORM)
if(suit)
H.equip_to_slot_or_del(new suit(H),SLOT_WEAR_SUIT)
H.equip_to_slot_or_store_and_del(new suit(H),SLOT_WEAR_SUIT)
if(back)
H.equip_to_slot_or_del(new back(H),SLOT_BACK)
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_store_and_del(new l_pocket(H),SLOT_L_STORE)
if(r_pocket)
H.equip_to_slot_or_store_and_del(new r_pocket(H),SLOT_R_STORE)
if(backpack_contents)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
if(belt)
H.equip_to_slot_or_del(new belt(H),SLOT_BELT)
H.equip_to_slot_or_store_and_del(new belt(H),SLOT_BELT)
if(gloves)
H.equip_to_slot_or_del(new gloves(H),SLOT_GLOVES)
H.equip_to_slot_or_store_and_del(new gloves(H),SLOT_GLOVES)
if(shoes)
H.equip_to_slot_or_del(new shoes(H),SLOT_SHOES)
H.equip_to_slot_or_store_and_del(new shoes(H),SLOT_SHOES)
if(head)
H.equip_to_slot_or_del(new head(H),SLOT_HEAD)
H.equip_to_slot_or_store_and_del(new head(H),SLOT_HEAD)
if(mask)
H.equip_to_slot_or_del(new mask(H),SLOT_WEAR_MASK)
H.equip_to_slot_or_store_and_del(new mask(H),SLOT_WEAR_MASK)
if(neck)
H.equip_to_slot_or_del(new neck(H),SLOT_NECK)
H.equip_to_slot_or_store_and_del(new neck(H),SLOT_NECK)
if(ears)
H.equip_to_slot_or_del(new ears(H),SLOT_EARS)
H.equip_to_slot_or_store_and_del(new ears(H),SLOT_EARS)
if(glasses)
H.equip_to_slot_or_del(new glasses(H),SLOT_GLASSES)
H.equip_to_slot_or_store_and_del(new glasses(H),SLOT_GLASSES)
if(id)
H.equip_to_slot_or_del(new id(H),SLOT_WEAR_ID)
H.equip_to_slot_or_store_and_del(new id(H),SLOT_WEAR_ID)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),SLOT_S_STORE)
H.equip_to_slot_or_store_and_del(new suit_store(H),SLOT_S_STORE)
if(accessory)
var/obj/item/clothing/under/U = H.w_uniform
@@ -78,19 +91,6 @@
if(r_hand)
H.put_in_r_hand(new r_hand(H))
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H),SLOT_L_STORE)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),SLOT_R_STORE)
if(backpack_contents)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
HS.ToggleHelmet()
+37 -2
View File
@@ -69,6 +69,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/pda_skin = PDA_SKIN_ALT
var/list/alt_titles_preferences = list()
var/static/preview_job_outfit = TRUE //shouldn't be something that's saved, but this is a preference option
var/uses_glasses_colour = 0
@@ -1049,8 +1050,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(!gear_tab)
gear_tab = GLOB.loadout_items[1]
dat += "<table align='center' width='100%'>"
dat += "<tr><td colspan=4><center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout points remaining.</b> \[<a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
dat += "<tr><td colspan=4><center>You can only choose one item per category, unless it's an item that spawns in your backpack or hands.</center></td></tr>"
dat += "<tr><td colspan=4><center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout points remaining.</b> \[<a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\] \[<a href='?_src_=prefs;preference=gear;toggle_outfit_visibility=1'>[preview_job_outfit ? "Enable" : "Disable"] Job Outfit Preview</a>\]</center></td></tr>"
dat += "<tr><td colspan=4><center>You can only choose two items per category, unless it's an item that spawns in your backpack or hands.</center></td></tr>"
dat += "<tr><td colspan=4><center><b>"
var/firstcat = TRUE
for(var/i in GLOB.loadout_items)
@@ -1102,6 +1103,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</table>"
if(4) //Antag Preferences
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h1>Special Role Settings</h1>"
if(jobban_isbanned(user, ROLE_SYNDICATE))
dat += "<font color=red><h3><b>You are banned from antagonist roles.</b></h3></font>"
@@ -1122,6 +1124,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
dat += "</td><td width='340px' height='300px' valign='top'>"
dat += "<h1>Sync Settings</h1>"
dat += "<b>Sync</b> antag prefs. with all characters: <a href='?_src_=prefs;preference=sync_antag_with_chars'>[(toggles & ANTAG_SYNC_WITH_CHARS) ? "Yes" : "No"]</a><br>"
dat += "<b>Copy</b> and save antag prefs. to all characters: <a href='?_src_=prefs;preference=copy_antag_to_chars'>Copy</a><br>"
dat += "<b>Reset</b> antag prefs. for this character: <a href='?_src_=prefs;preference=reset_antag'>Reset</a><br>"
dat += "</td></tr></table>"
dat += "<hr><center>"
@@ -2523,6 +2532,30 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("allow_midround_antag")
toggles ^= MIDROUND_ANTAG
if("sync_antag_with_chars")
toggles ^= ANTAG_SYNC_WITH_CHARS
if(!(toggles & ANTAG_SYNC_WITH_CHARS) && path)
var/savefile/S = new /savefile(path)
if(S)
S["special_roles"] >> be_special
if("copy_antag_to_chars")
if(path)
var/savefile/S = new /savefile(path)
if(S)
var/initial_cd = S.cd
for(var/i=1, i<=max_save_slots, i++)
S.cd = "/character[i]"
if(S["real_name"])
WRITE_FILE(S["special_roles"], be_special)
S.cd = initial_cd
to_chat(parent, "<span class='notice'>Successfully copied antagonist preferences to all characters.</span>")
else
to_chat(parent, "<span class='notice'>Could not write to file.</span>")
if("reset_antag")
be_special = list()
if("parallaxup")
parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
@@ -2610,6 +2643,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(gear_points >= initial(G.cost))
LAZYADD(chosen_gear, G.type)
gear_points -= initial(G.cost)
if(href_list["toggle_outfit_visibility"])
preview_job_outfit = !preview_job_outfit
ShowChoices(user)
return 1
+4 -2
View File
@@ -366,7 +366,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["job_engsec_low"] >> job_engsec_low
//Antags
S["special_roles"] >> be_special
if(!(toggles & ANTAG_SYNC_WITH_CHARS))
S["special_roles"] >> be_special
//Quirks
S["all_quirks"] >> all_quirks
@@ -606,7 +607,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["medical_records"] , medical_records)
//Misc.
WRITE_FILE(S["special_roles"] , be_special) //Preferences don't load every character change
if(!(toggles & ANTAG_SYNC_WITH_CHARS))
WRITE_FILE(S["special_roles"] , be_special) //Preferences don't load every character change
WRITE_FILE(S["hide_ckey"] , hide_ckey)
WRITE_FILE(S["all_quirks"] , all_quirks)
@@ -174,43 +174,6 @@
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/output/sound/beepsky
name = "securitron sound circuit"
desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is similar to those used in Securitrons."
sounds = list(
"creep" = 'sound/voice/beepsky/creep.ogg',
"criminal" = 'sound/voice/beepsky/criminal.ogg',
"freeze" = 'sound/voice/beepsky/freeze.ogg',
"god" = 'sound/voice/beepsky/god.ogg',
"i am the law" = 'sound/voice/beepsky/iamthelaw.ogg',
"insult" = 'sound/voice/beepsky/insult.ogg',
"radio" = 'sound/voice/beepsky/radio.ogg',
"secure day" = 'sound/voice/beepsky/secureday.ogg',
)
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/output/sound/medbot
name = "medbot sound circuit"
desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in medical robots."
sounds = list(
"surgeon" = 'sound/voice/medbot/surgeon.ogg',
"radar" = 'sound/voice/medbot/radar.ogg',
"feel better" = 'sound/voice/medbot/feelbetter.ogg',
"patched up" = 'sound/voice/medbot/patchedup.ogg',
"injured" = 'sound/voice/medbot/injured.ogg',
"insult" = 'sound/voice/medbot/insult.ogg',
"coming" = 'sound/voice/medbot/coming.ogg',
"help" = 'sound/voice/medbot/help.ogg',
"live" = 'sound/voice/medbot/live.ogg',
"lost" = 'sound/voice/medbot/lost.ogg',
"flies" = 'sound/voice/medbot/flies.ogg',
"catch" = 'sound/voice/medbot/catch.ogg',
"delicious" = 'sound/voice/medbot/delicious.ogg',
"apple" = 'sound/voice/medbot/apple.ogg',
"no" = 'sound/voice/medbot/no.ogg',
)
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/output/sound/vox
name = "ai vox sound circuit"
desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in AI announcement systems."
+1 -1
View File
@@ -224,7 +224,7 @@
if(!J)
J = SSjob.GetJob(H.job)
if(H.nameless && J.dresscodecompliant)
if(H.nameless)
if(J.title in GLOB.command_positions)
H.real_name = J.title
else
@@ -51,6 +51,12 @@
var/datum/job/previewJob
var/highRankFlag = job_civilian_high | job_medsci_high | job_engsec_high
if(chosen_gear && current_tab != 2)
for(var/A in chosen_gear)
var/datum/gear/G = new A //Shouldn't really be anything else, but byond fuckery
if(!mannequin.get_item_by_slot(G.category))
mannequin.equip_to_appropriate_slot(new G.path)
if(job_civilian_low & ASSISTANT)
previewJob = SSjob.GetJob("Assistant")
else if(highRankFlag)
@@ -67,7 +73,7 @@
previewJob = job
break
if(previewJob)
if(previewJob && preview_job_outfit)
if(current_tab != 2)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
@@ -10,6 +10,9 @@
mutantears = /obj/item/organ/ears/cat
mutanttail = /obj/item/organ/tail/cat
liked_food = MEAT | RAW | DAIRY
disliked_food = FRIED | FRUIT
/datum/species/human/felinid/qualifies_for_rank(rank, list/features)
return TRUE
+14 -4
View File
@@ -235,15 +235,19 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
//set qdel_on_fail to have it delete W if it fails to equip
//set disable_warning to disable the 'you are unable to equip that' warning.
//unset redraw_mob to prevent the mob from being redrawn at the end.
/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE)
/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE, store = FALSE)
if(!istype(W))
return FALSE
if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self))
if(store && istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/obj/item/storage/backpack/BP = H.back
if(BP)
return SEND_SIGNAL(BP, COMSIG_TRY_STORAGE_INSERT, W, null, TRUE, TRUE)
if(qdel_on_fail)
qdel(W)
else
if(!disable_warning)
to_chat(src, "<span class='warning'>You are unable to equip that!</span>")
else if(!disable_warning)
to_chat(src, "<span class='warning'>You are unable to equip that!</span>")
return FALSE
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
return TRUE
@@ -258,6 +262,12 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
/mob/proc/equip_to_slot_or_del(obj/item/W, slot)
return equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE)
/mob/proc/equip_to_slot_or_store(obj/item/W, slot)
return equip_to_slot_if_possible(W, slot, FALSE, TRUE, FALSE, TRUE, TRUE)
/mob/proc/equip_to_slot_or_store_and_del(obj/item/W, slot)
return equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE, TRUE)
//puts the item "W" into an appropriate slot in a human's inventory
//returns 0 if it cannot, 1 if successful
/mob/proc/equip_to_appropriate_slot(obj/item/W)
@@ -1,4 +1,4 @@
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff)
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, backpackstuffs)
var/mob/the_mob = N
if(!the_mob)
the_mob = M // cause this doesn't get assigned if player is a latejoiner
@@ -10,18 +10,22 @@
G = GLOB.loadout_items[slot_to_string(initial(G.category))][initial(G.name)]
if(!G)
continue
var/permitted = TRUE
if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
permitted = FALSE
if(G.ckeywhitelist && G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist))
permitted = FALSE
if(!equipbackpackstuff && G.category == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs
permitted = FALSE
if(equipbackpackstuff && G.category != SLOT_IN_BACKPACK)//ditto
permitted = FALSE
if(!permitted)
continue
if(G.ckeywhitelist && G.ckeywhitelist.len && !(the_mob.client.ckey in G.ckeywhitelist))
continue
var/obj/item/I = new G.path
if(iscarbon(M) && backpackstuffs && (G.category == SLOT_IN_BACKPACK || G.blacklist_join_equip))
var/mob/living/carbon/C = M
var/obj/item/storage/backpack/B = C.back
if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE))
I.forceMove(get_turf(C))
continue
else if(G.blacklist_join_equip) //Assume we're gonna be put in a backpack and not equipped
continue
else if(backpackstuffs && G.category != SLOT_IN_BACKPACK)
continue
if(!M.equip_to_slot_if_possible(I, G.category, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first
if(iscarbon(M))
var/mob/living/carbon/C = M
@@ -35,7 +35,7 @@
#define COIN_CHARGE 3
/obj/machinery/vending/kink
name = "KinkMate"
name = "\improper KinkMate"
desc = "A vending machine for all your unmentionable desires."
icon = 'icons/obj/citvending.dmi'
icon_state = "kink"
@@ -66,6 +66,7 @@
/obj/item/electropack/vibrator = 2,
)
contraband = list(
/obj/item/clothing/under/gear_harness = 3,
/obj/item/restraints/handcuffs/fake/kinky = 5,
/obj/item/clothing/neck/petcollar = 5,
/obj/item/clothing/under/mankini = 1,
@@ -19,4 +19,4 @@
name = "A diamond ring"
category = SLOT_GLOVES
path = /obj/item/clothing/gloves/ring/diamond
cost = 4
cost = 4
@@ -70,4 +70,4 @@
name = "Improper Roman shield"
category = SLOT_HANDS
path = /obj/item/shield/riot/roman/fake
cost = 2
cost = 2
@@ -27,6 +27,7 @@
name = "Rice hat"
category = SLOT_HEAD
path = /obj/item/clothing/head/rice_hat
blacklist_join_equip = TRUE
/datum/gear/ushanka
name = "Ushanka"
@@ -53,12 +54,14 @@
category = SLOT_HEAD
path = /obj/item/clothing/head/flakhelm
cost = 2
blacklist_join_equip = TRUE
/datum/gear/delinquent //Now you too can become like your favorite punchy ghost protagonist
name = "Delinquent Hat"
category = SLOT_HEAD
path = /obj/item/clothing/head/delinquent
cost = 3
blacklist_join_equip = TRUE
/datum/gear/bunnyears
name = "Bunny Ears"
@@ -53,6 +53,7 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids)
var/list/restricted_roles
var/list/ckeywhitelist
var/restricted_desc
var/blacklist_join_equip = FALSE //If we don't equip this when we join
/datum/gear/New()
..()
@@ -412,38 +412,45 @@
name = "Gear Harness"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/gear_harness
blacklist_join_equip = TRUE
/datum/gear/pinkstripper
name = "Pink stripper outfit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/stripper_pink
blacklist_join_equip = TRUE
/datum/gear/greenstripper
name = "Green stripper outfit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/stripper_green
blacklist_join_equip = TRUE
/datum/gear/polybikini
name = "Polychromic Bikini"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/polychromic/bikini
cost = 2
blacklist_join_equip = TRUE
/datum/gear/polystripper
name = "Polychromic Stripper Outfit"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/polychromic/stripper
cost = 2
blacklist_join_equip = TRUE
/datum/gear/polypantsu
name = "Polychromic Panties"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/polychromic/shortpants/pantsu
blacklist_join_equip = TRUE
/datum/gear/polybulge
name = "Polychromic Voluminous Thong"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/polychromic/bulge
blacklist_join_equip = TRUE
/datum/gear/polybottomless
name = "Polychromic Bottomless Shirt"
@@ -456,18 +463,14 @@
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/corset
cost = 1
/datum/gear/corset
name = "Corset"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/corset
cost = 1
blacklist_join_equip = TRUE
/datum/gear/shortsbra
name = "Kromatic Shorts and Top"
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/polychromic/shortsbra
cost = 1
blacklist_join_equip = TRUE
/datum/gear/gladiator
name = "Gladiator uniform"
@@ -486,4 +489,4 @@
category = SLOT_W_UNIFORM
path = /obj/item/clothing/under/greenplaidshirt
cost = 1
ckeywhitelist = list("chemlight")
ckeywhitelist = list("chemlight")
@@ -1,8 +0,0 @@
//This file controls whether or not a job complies with dresscodes.
//If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack.
/datum/job
var/dresscodecompliant = TRUE
/datum/job/assistant
dresscodecompliant = FALSE
-1
View File
@@ -3228,7 +3228,6 @@
#include "modular_citadel\code\modules\events\blob.dm"
#include "modular_citadel\code\modules\events\wizard\magicarp.dm"
#include "modular_citadel\code\modules\integrated_electronics\subtypes\manipulation.dm"
#include "modular_citadel\code\modules\jobs\dresscode_values.dm"
#include "modular_citadel\code\modules\mentor\follow.dm"
#include "modular_citadel\code\modules\mentor\mentor.dm"
#include "modular_citadel\code\modules\mentor\mentor_memo.dm"