diff --git a/_maps/map_files/daftmarsh/daftmarsh.dmm b/_maps/map_files/daftmarsh/daftmarsh.dmm
index 8658fb30ee2..99ee51a2bf5 100644
--- a/_maps/map_files/daftmarsh/daftmarsh.dmm
+++ b/_maps/map_files/daftmarsh/daftmarsh.dmm
@@ -3169,6 +3169,13 @@
},
/turf/open/floor/ruinedwood/spiral,
/area/outdoors/town)
+"crT" = (
+/obj/structure/fluff/railing/wood{
+ dir = 4
+ },
+/obj/structure/mercstatue,
+/turf/open/floor/twig,
+/area/outdoors/town)
"cso" = (
/turf/open/floor/grass/yel,
/area/outdoors/exposed/church)
@@ -9512,6 +9519,10 @@
},
/turf/closed/wall/mineral/stone/moss,
/area/under/town/basement)
+"hCH" = (
+/obj/structure/mercstatue,
+/turf/open/floor/grass,
+/area/outdoors/town/keep)
"hCR" = (
/obj/structure/fluff/walldeco/church/line{
dir = 8
@@ -127081,7 +127092,7 @@ xuJ
oQv
iHi
dcH
-bYV
+crT
ffK
lfe
owc
@@ -130676,7 +130687,7 @@ eUn
ttL
ttL
iiV
-vVc
+hCH
tea
tea
tea
diff --git a/_maps/map_files/vanderlin/vanderlin.dmm b/_maps/map_files/vanderlin/vanderlin.dmm
index 0aa51839907..a542a8de527 100644
--- a/_maps/map_files/vanderlin/vanderlin.dmm
+++ b/_maps/map_files/vanderlin/vanderlin.dmm
@@ -37,6 +37,7 @@
/obj/structure/fluff/walldeco/customflag{
pixel_x = -32
},
+/obj/structure/mercstatue,
/turf/open/floor/grass/red,
/area/outdoors/woods_safe)
"aaX" = (
@@ -2597,6 +2598,16 @@
"bfG" = (
/turf/closed/wall/mineral/decowood,
/area/under/town/basement)
+"bfN" = (
+/obj/structure/fluff/railing/wood{
+ dir = 1;
+ layer = 2.7;
+ pixel_x = 2;
+ pixel_y = 7
+ },
+/obj/structure/mercstatue,
+/turf/open/floor/cobble,
+/area/outdoors/town)
"bfO" = (
/obj/machinery/light/fueled/torchholder/l{
dir = 1
@@ -25427,6 +25438,13 @@
/obj/structure/bed/shit,
/turf/open/floor/greenstone,
/area/under/town/sewer)
+"kCm" = (
+/obj/machinery/light/fueled/torchholder{
+ dir = 4
+ },
+/obj/structure/mercstatue,
+/turf/open/floor/dirt/road,
+/area/outdoors/town)
"kCM" = (
/obj/effect/landmark/start/vagrant,
/turf/open/floor/dirt,
@@ -26906,6 +26924,10 @@
},
/turf/open/floor/ruinedwood/spiral,
/area/indoors/town/keep/library)
+"lht" = (
+/obj/structure/mercstatue,
+/turf/open/floor/dirt/road,
+/area/outdoors/beach)
"lhy" = (
/obj/structure/fluff/railing/border{
dir = 8
@@ -33767,6 +33789,10 @@
/obj/item/clothing/face/shepherd/clothmask,
/turf/open/floor/tile,
/area/indoors/town/keep/courtagent)
+"oaS" = (
+/obj/structure/mercstatue,
+/turf/open/floor/dirt/road,
+/area/outdoors/town/keep)
"oba" = (
/turf/open/floor/cobble,
/area/indoors/dungeon)
@@ -45714,6 +45740,7 @@
/obj/effect/decal/borderfall{
dir = 1
},
+/obj/structure/mercstatue,
/turf/open/floor/blocks,
/area/outdoors/town)
"sKG" = (
@@ -51780,6 +51807,7 @@
/area/indoors/town/shop)
"vjZ" = (
/obj/structure/fake_machine/hailerboard/r,
+/obj/structure/mercstatue,
/turf/open/floor/tile/brownbrick,
/area/indoors/town/merc_guild)
"vkc" = (
@@ -67718,7 +67746,7 @@ pao
uvp
mIW
nTH
-qAA
+lht
npN
npN
qAA
@@ -113820,7 +113848,7 @@ oWd
mFi
kwJ
mFi
-cJK
+kCm
kwJ
eYe
xRO
@@ -118829,7 +118857,7 @@ qFx
qVe
weQ
oho
-xTl
+oaS
xTl
vqf
viN
@@ -124992,7 +125020,7 @@ wmF
wrm
wrm
wrm
-vbp
+bfN
mFi
hZn
hZn
diff --git a/_maps/map_files/whitepalacepass/WhitePalacePass.dmm b/_maps/map_files/whitepalacepass/WhitePalacePass.dmm
index 70e3aa5cfbc..9df2b99cb85 100644
--- a/_maps/map_files/whitepalacepass/WhitePalacePass.dmm
+++ b/_maps/map_files/whitepalacepass/WhitePalacePass.dmm
@@ -14563,6 +14563,10 @@
/obj/machinery/light/fueled/wallfire/candle/skull/l,
/turf/open/floor/dirt,
/area/under/cavewet)
+"iNM" = (
+/obj/structure/mercstatue,
+/turf/open/floor/cobble,
+/area/indoors/town/merc_guild)
"iNV" = (
/obj/structure/soil/mushmound,
/obj/machinery/light/fueled/wallfire/candle/lamp,
@@ -38430,6 +38434,10 @@
/obj/item/natural/melded/t5,
/turf/open/floor/tile/masonic/spiral,
/area/under/town/basement)
+"ybs" = (
+/obj/structure/mercstatue,
+/turf/open/floor/grass/cold,
+/area/outdoors/town/keep)
"ybJ" = (
/obj/structure/bars,
/turf/open/floor/cobblerock,
@@ -59990,7 +59998,7 @@ qPf
jxh
vhP
vhP
-vhP
+iNM
gBj
tnl
dIH
@@ -180521,7 +180529,7 @@ aYU
ewa
aYU
ewa
-tck
+ybs
tck
gLm
rZA
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 49dc1590d05..263e498e821 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -34,6 +34,9 @@ GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
GLOBAL_LIST_EMPTY(aiEyes)
+GLOBAL_LIST_EMPTY(available_mercenaries)
+GLOBAL_LIST_EMPTY(contracted_mercenaries)
+
GLOBAL_LIST_EMPTY(language_datum_instances)
GLOBAL_LIST_EMPTY(all_languages)
diff --git a/code/game/objects/items/mercenary_ring.dm b/code/game/objects/items/mercenary_ring.dm
new file mode 100644
index 00000000000..c2f25e9cd71
--- /dev/null
+++ b/code/game/objects/items/mercenary_ring.dm
@@ -0,0 +1,140 @@
+/obj/item/mercenary_ring
+ name = "mercenary ring"
+ desc = "A beautiful golden ring, which resonates in a mercenary's mind when twisted. Usually given to their employers as a way of communication. Only a mercenary may bind themselves to such ring."
+ icon = 'icons/roguetown/clothing/rings.dmi'
+ icon_state = "g_newring_topaz"
+ slot_flags = ITEM_SLOT_RING
+ sellprice = 1
+ dyeable = FALSE
+ detail_tag = null
+ detail_color = null
+ dropshrink = 0.7
+ grid_height = 32
+ grid_width = 32
+ item_weight = 60 GRAMS
+
+ var/datum/weakref/mob_ref
+
+ COOLDOWN_DECLARE(ring_bell)
+ var/cooldown = 3 MINUTES
+ var/hear_distance = 100
+
+/obj/item/mercenary_ring/Initialize(mapload)
+ . = ..()
+ RegisterSignal(SSdcs, COMSIG_GLOB_HUMAN_ENTER_CRYO, PROC_REF(remove_mercenary))
+
+/obj/item/mercenary_ring/Destroy()
+ mob_ref = null
+ . = ..()
+
+/obj/item/mercenary_ring/examine(mob/user)
+ . = ..()
+ if(!mob_ref)
+ to_chat(user, span_warning("There is no mercenary bound to the ring."))
+ return
+
+ var/mob/living/carbon/human/bound_merc = mob_ref.resolve()
+ . += span_notice("The ring is bound to [bound_merc.real_name].")
+
+/obj/item/mercenary_ring/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
+
+ if(!ishuman(interacting_with))
+ return NONE
+
+ var/mob/living/carbon/human/H = interacting_with
+
+ if(!H.mind)
+ return ITEM_INTERACT_BLOCKING
+
+ if(mob_ref)
+ to_chat(user, span_warning("It can hold no more minds."))
+ return ITEM_INTERACT_BLOCKING
+
+ if(!(user == H))
+ to_chat(user, span_warning("I can only bind myself to the ring."))
+ return
+ if(!is_mercenary_job(user.mind.assigned_role))
+ to_chat(user, span_warning("I am not a mercenary, the ring does not answer to me."))
+ return
+
+ if(IS_DEADITE(H))
+ to_chat(user, span_warning("The deadite curse resists the bell's charm."))
+ else
+ add_mercenary(H)
+ to_chat(user, span_smallnotice("I bind myself to the ring."))
+
+ playsound(src, 'sound/items/servant_bell.ogg', 80, TRUE)
+ return ITEM_INTERACT_SUCCESS
+
+/obj/item/mercenary_ring/attack_self(mob/living/user, list/modifiers)
+ . = ..()
+ if(COOLDOWN_FINISHED(src, ring_bell))
+ ring_bell(user)
+ COOLDOWN_START(src, ring_bell, cooldown)
+ else
+ playsound(src, 'sound/items/servant_bell.ogg', 80, TRUE)
+
+/obj/item/mercenary_ring/proc/ring_bell(mob/living/user)
+ if(!mob_ref)
+ return
+ var/mob/living/carbon/human/player = mob_ref.resolve()
+ if(!player)
+ return
+ if(!player.client)
+ return
+ if(player.stat >= DEAD)
+ return
+ if(HAS_TRAIT(player, TRAIT_DEAF))
+ return
+ if(player.can_block_magic(MAGIC_RESISTANCE_MIND, 0))
+ return
+ var/turf/origin_turf = get_turf(src)
+ if(!is_in_zweb(player.z, origin_turf.z))
+ return
+ var/distance = get_dist(player, origin_turf)
+ if(distance > hear_distance)
+ return
+
+ user.visible_message("[user] twists the mercenary ring.")
+ playsound(src, 'sound/items/servant_bell.ogg', 100, TRUE)
+
+ player.apply_status_effect(/datum/status_effect/signal_horn/mercenary_ring, null, origin_turf)
+ var/dirText = ""
+ var/z_dist = origin_turf.z - player.z
+ if(z_dist != 0)
+ var/abs_z = abs(z_dist)
+ switch(abs_z)
+ if(1)
+ dirText += " one story"
+ if(2)
+ dirText += " two stories"
+ else
+ dirText += " far"
+ dirText += z_dist > 0 ? " above me" : " below me"
+ to_chat(player, span_warning("The mercenary ring resonates[dirText]."))
+ if(distance <= 7)
+ return
+ //sound played for other players, by fem_tanyl !!!1!!
+ player.playsound_local(get_turf(player), 'sound/items/servant_bell.ogg', 35, FALSE, pressure_affected = FALSE)
+
+/obj/item/mercenary_ring/proc/add_mercenary(mob/living/carbon/human/H)
+ if(mob_ref)
+ return
+ mob_ref = WEAKREF(H)
+
+/obj/item/mercenary_ring/proc/remove_mercenary(datum/source, mob/living/carbon/human/H)
+ if(!mob_ref || !ishuman(H))
+ return
+ var/mob/living/carbon/human/bound_mob = mob_ref.resolve()
+ if(!bound_mob || bound_mob == H)
+ mob_ref = null
+
+/datum/status_effect/signal_horn/mercenary_ring
+ id = "mercenary ring indicator"
+ duration = 25 SECONDS
+ alert_type = /atom/movable/screen/alert/status_effect/mercenary_ring
+
+/atom/movable/screen/alert/status_effect/mercenary_ring
+ name = "Mercenary Ring"
+ desc = "I've been summoned by the ring."
+ icon_state = "mercenary_ring"
diff --git a/code/game/objects/items/servant_bell.dm b/code/game/objects/items/servant_bell.dm
index 5c5fb95ffd1..984aca23cb7 100644
--- a/code/game/objects/items/servant_bell.dm
+++ b/code/game/objects/items/servant_bell.dm
@@ -64,6 +64,7 @@
return ITEM_INTERACT_BLOCKING
var/mob/living/carbon/human/H = interacting_with
+
if(!H.mind)
return ITEM_INTERACT_BLOCKING
@@ -243,3 +244,4 @@
name = "Servant Bell"
desc = "I've been summoned by the bell."
icon_state = "servant_bell"
+
diff --git a/code/game/objects/structures/mercstatue.dm b/code/game/objects/structures/mercstatue.dm
new file mode 100644
index 00000000000..d0856783be8
--- /dev/null
+++ b/code/game/objects/structures/mercstatue.dm
@@ -0,0 +1,141 @@
+/obj/structure/mercstatue
+ name = "mercenary statue"
+ desc = "A bronze statue of a mercenary from ages long past."
+ icon = 'icons/roguetown/misc/machines.dmi'
+ icon_state = "mercstatue"
+ density = TRUE
+ anchored = TRUE
+ max_integrity = 500
+ var/message_char_limit = 300
+ var/response_timeout = 2 MINUTES
+ var/single_cooldown = 5 MINUTES
+ var/static/list/sender_cooldowns = list()
+ var/static/list/pending_direct_responses = list()
+ var/static/response_id_counter = 0
+
+/obj/structure/mercstatue/attack_hand(mob/living/carbon/human/user)
+ use(user)
+
+/obj/structure/mercstatue/proc/use(mob/living/carbon/human/user)
+ if(!user)
+ return
+ var/obj/item/mercenary_ring/mercring
+
+ if(ishuman(user) && user.mind && istype(user.mind.assigned_role, /datum/job/advclass/mercenary))
+ if(tgui_alert(user, "Do you want to change your mercenary description", "MERCENARY", DEFAULT_INPUT_CHOICES, 20 SECONDS) == CHOICE_YES)
+ user.mercdesc = stripped_input(user, "Write a description which will be shown to potential employers.", "Description", "", message_char_limit)
+
+ if(user in GLOB.contracted_mercenaries)
+ if(tgui_alert(user, "Do you want to cancel your current contract?", "MERCENARY", DEFAULT_INPUT_CHOICES, 20 SECONDS) == CHOICE_YES)
+ GLOB.contracted_mercenaries -= user
+ GLOB.available_mercenaries += user
+
+ if(user in GLOB.available_mercenaries)
+ if(tgui_alert(user, "Do you want to unregister as an available mercenary for the mercenary statue?", "MERCENARY", DEFAULT_INPUT_CHOICES, 20 SECONDS) == CHOICE_YES)
+ GLOB.available_mercenaries -= user
+ for(var/obj/item/mercenary_ring/ring in world)
+ if(ring.mob_ref)
+ var/mob/living/M = ring.mob_ref.resolve()
+ if(M == user)
+ qdel(ring)
+ return
+ if(mercring)
+ qdel(mercring)
+ return
+
+ if(ishuman(user) && user.mind && istype(user.mind.assigned_role, /datum/job/advclass/mercenary))
+ if(tgui_alert(user, "Do you want to register as an available mercenary for the mercenary statue?", "MERCENARY", DEFAULT_INPUT_CHOICES, 20 SECONDS) == CHOICE_YES)
+ GLOB.available_mercenaries += user
+ mercring = new /obj/item/mercenary_ring(src)
+ mercring.add_mercenary(user)
+ user.put_in_hands(mercring)
+ if(user.mercdesc && (user.mercdesc != ""))
+ return
+ user.mercdesc = stripped_input(user, "Write a description which will be shown to potential employers.", "Description", "", message_char_limit)
+ return
+
+ if(length(GLOB.available_mercenaries))
+ var/mob/selected_merc = tgui_input_list(user, "Choose an available mercenary", "Mercenaries", GLOB.available_mercenaries)
+
+ if(selected_merc)
+ var/cooldown_key = "[user.real_name]_[selected_merc.real_name]"
+ if(sender_cooldowns[cooldown_key])
+ var/time_left = sender_cooldowns[cooldown_key] + single_cooldown - world.time
+ if(time_left > 0)
+ var/mins_left = max(1, round(time_left / 600))
+ to_chat(user, span_warning("I need to wait [mins_left] minute[mins_left == 1 ? "" : "s"] before contacting [selected_merc.real_name] again."))
+ return
+
+ if(!Adjacent(user))
+ to_chat(user, span_warning("I need to stay close to the statue."))
+ return
+
+ var/message = stripped_input(user, "Send a message to [selected_merc] detailing your offer. Maximum [message_char_limit] characters.", "Message for the mercenary", "", message_char_limit)
+ if(message)
+ var/response_id = ++response_id_counter
+ var/response_key = "[response_id]"
+ sender_cooldowns[cooldown_key] = world.time
+ pending_direct_responses[response_key] = list("sender" = user, "target" = selected_merc, "message" = message)
+ addtimer(CALLBACK(src, PROC_REF(expire_direct_response), response_id), response_timeout)
+ to_chat(selected_merc, span_boldnotice("The mercenary statue whispers in my mind: [message] - [user.real_name]
\[INTERESTED\] | \[NOT INTERESTED\]"))
+ playsound(selected_merc, 'sound/misc/notice (2).ogg', 100, FALSE, -1)
+ to_chat(user, "My message has been sent.")
+ return
+
+
+ return
+ to_chat(user, "No mercenaries are currently available!")
+
+/obj/structure/mercstatue/Topic(href, href_list)
+ . = ..()
+ if(!ishuman(usr))
+ return
+
+ var/mob/living/carbon/human/responder = usr
+ var/response_type = href_list["direct_response"]
+ var/response_id = href_list["response_id"]
+
+ if(!pending_direct_responses[response_id])
+ to_chat(responder, span_warning("That response link has expired or already been used."))
+ return
+
+ var/list/response_data = pending_direct_responses[response_id]
+ var/mob/living/carbon/human/sender = response_data["sender"]
+
+ if(!sender || QDELETED(sender))
+ to_chat(responder, span_warning("The sender is no longer available."))
+ pending_direct_responses -= response_id
+ return
+
+ pending_direct_responses -= response_id
+ if(response_type == "interested")
+ to_chat(sender, span_notice("[responder.real_name] responded in affirmation to my message."))
+ to_chat(responder, span_notice("I responded in affirmation to [sender.real_name]."))
+ GLOB.available_mercenaries -= responder
+ GLOB.contracted_mercenaries += responder
+ else
+ to_chat(sender, span_notice("[responder.real_name] responded negatively to my message."))
+ to_chat(responder, span_notice("I responded negatively to [sender.real_name]."))
+
+ playsound(sender, 'sound/misc/notice (2).ogg', 100, FALSE, -1)
+ playsound(responder, 'sound/misc/beep.ogg', 100, FALSE, -1)
+ return
+
+/obj/structure/mercstatue/proc/expire_direct_response(response_id)
+ var/response_key = "[response_id]"
+ if(pending_direct_responses[response_key])
+ pending_direct_responses -= response_key
+
+/obj/structure/mercstatue/examine(mob/user)
+ . = ..()
+
+ if(GLOB.available_mercenaries)
+ . += span_notice("These mercenaries are currently available:")
+ for(var/mob/living/carbon/human/merc in GLOB.available_mercenaries)
+ if(merc.job)
+ . += "[merc.real_name], [merc.job]: [merc.mercdesc]"
+ else
+ . += "[merc.real_name]: [merc.mercdesc]"
+ return
+ else
+ . += span_notice("No mercenaries are currently available.")
diff --git a/code/modules/client/preferences/datums/list/role_preferences/mercenary_description.dm b/code/modules/client/preferences/datums/list/role_preferences/mercenary_description.dm
new file mode 100644
index 00000000000..cc99e708fc0
--- /dev/null
+++ b/code/modules/client/preferences/datums/list/role_preferences/mercenary_description.dm
@@ -0,0 +1,6 @@
+/datum/preference/list_type/role_setting/mercenary_description
+ savefile_key = "mercenary_description"
+ setting_display_name = "Mercenary Description"
+ ui_category = "Mercenary"
+ example_text = "Professional fistfighter, struck down a troll with my bare hands."
+ max_lines = 1
diff --git a/code/modules/jobs/job_types/other/mercenary.dm b/code/modules/jobs/job_types/other/mercenary.dm
index f661c53e431..dcf067bbe5d 100644
--- a/code/modules/jobs/job_types/other/mercenary.dm
+++ b/code/modules/jobs/job_types/other/mercenary.dm
@@ -32,7 +32,25 @@
/datum/job/mercenary/after_spawn(mob/living/carbon/human/spawned, client/player_client)
. = ..()
- to_chat(spawned, "
The Gaffer, who feeds and houses you may have work for you todae, go see him at the office outside your lodgings.
")
+ if(SSmapping.config?.map_name != "Voyage")
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/job/mercenary, set_availability), spawned), 0)
+ if(player_client?.prefs)
+ var/datum/preferences/prefs = player_client.prefs
+ spawned.mercdesc = prefs.read_preference(/datum/preference/list_type/role_setting/mercenary_description)
+ return
+
+/datum/job/mercenary/proc/set_availability(mob/living/carbon/human/spawned)
+ if(!spawned || QDELETED(spawned) || !spawned.client)
+ return
+ if(tgui_alert(spawned, "Do you want to join the available mercenaries list for the mercenary statue?", "MERCENARY", DEFAULT_INPUT_CHOICES, 30 SECONDS) == CHOICE_YES)
+ GLOB.available_mercenaries += spawned
+ to_chat(spawned, "You have been added to the available mercenaries list.")
+ var/obj/item/mercenary_ring/mercring = new /obj/item/mercenary_ring(spawned.loc)
+ spawned.put_in_hands(mercring)
+ mercring.add_mercenary(spawned)
+ if(spawned.mercdesc && (spawned.mercdesc != ""))
+ return
+ spawned.mercdesc = stripped_input(spawned, "Write a description which will be shown to potential employers.", "Description", "", 300)
/datum/job/advclass/mercenary
department_flag = OUTSIDERS
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 27c0a1d7b21..ccbf3400aca 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -132,6 +132,7 @@
var/breathe_tick = 0 // Used for gas mask delays.
var/merctype = 0 // Used for mercenary backgrounds - check mail.dm
+ var/mercdesc // Description used for mercenary statue.
var/tokenclaimed = FALSE // Check for one-time tri reward.
possible_rmb_intents = list(/datum/rmb_intent/feint,\
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index e4fd18d4807..21c18954691 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ
diff --git a/icons/roguetown/misc/machines.dmi b/icons/roguetown/misc/machines.dmi
index 067ebd2c22b..ff147a93931 100644
Binary files a/icons/roguetown/misc/machines.dmi and b/icons/roguetown/misc/machines.dmi differ
diff --git a/vanderlin.dme b/vanderlin.dme
index e47d3a623b0..a4bccaaef55 100644
--- a/vanderlin.dme
+++ b/vanderlin.dme
@@ -2124,6 +2124,7 @@
#include "code\game\objects\items\locks.dm"
#include "code\game\objects\items\mageitems.dm"
#include "code\game\objects\items\magic.dm"
+#include "code\game\objects\items\mercenary_ring.dm"
#include "code\game\objects\items\natural.dm"
#include "code\game\objects\items\needle.dm"
#include "code\game\objects\items\ore.dm"
@@ -2287,6 +2288,7 @@
#include "code\game\objects\structures\mannequin.dm"
#include "code\game\objects\structures\meathook.dm"
#include "code\game\objects\structures\memorial.dm"
+#include "code\game\objects\structures\mercstatue.dm"
#include "code\game\objects\structures\mirror.dm"
#include "code\game\objects\structures\musicbox.dm"
#include "code\game\objects\structures\newtree.dm"
@@ -2819,6 +2821,7 @@
#include "code\modules\client\preferences\datums\list\role_preferences\_base.dm"
#include "code\modules\client\preferences\datums\list\role_preferences\_family_menu.dm"
#include "code\modules\client\preferences\datums\list\role_preferences\_ui_menu.dm"
+#include "code\modules\client\preferences\datums\list\role_preferences\mercenary_description.dm"
#include "code\modules\client\preferences\datums\list\role_preferences\monarch_decree.dm"
#include "code\modules\client\preferences\datums\list\role_preferences\monarch_law.dm"
#include "code\modules\client\preferences\datums\list\role_preferences\list_pick\_base.dm"