diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 916ff182f3c..68ffab16ec5 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -24,7 +24,7 @@
#define ROLE_REVENANT "revenant"
#define ROLE_HOG_GOD "hand of god: god"
#define ROLE_HOG_CULTIST "hand of god: cultist"
-
+#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
@@ -48,4 +48,5 @@ var/global/list/special_roles = list(
ROLE_ABDUCTOR = /datum/game_mode/abduction,
ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
+ ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult,
)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 6dd095996f9..801e80b9452 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -355,6 +355,9 @@ var/list/blood_splatter_icons = list()
/atom/proc/narsie_act()
return
+/atom/proc/ratvar_act()
+ return
+
/atom/proc/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
return 0
diff --git a/code/game/gamemodes/clock_cult/__clock_defines.dm b/code/game/gamemodes/clock_cult/__clock_defines.dm
new file mode 100644
index 00000000000..a53795615eb
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/__clock_defines.dm
@@ -0,0 +1,15 @@
+var/global/clockwork_construction_value = 0 //The total value of all structures built by the clockwork cult
+var/global/clockwork_caches = 0 //How many clockwork caches exist in the world (not each individual)
+var/global/clockwork_daemons = 0 //How many daemons exist in the world
+var/global/list/clockwork_generals_invoked = list("nezbere" = FALSE, "sevtug" = FALSE, "nzcrentr" = FALSE, "inath-neq" = FALSE) //How many generals have been recently invoked
+var/global/list/all_clockwork_objects = list() //All clockwork items, structures, and effects in existence
+var/global/list/all_clockwork_mobs = list() //All clockwork SERVANTS (not creatures) in existence
+
+#define SCRIPTURE_PERIPHERAL 0 //Should never be used
+#define SCRIPTURE_DRIVER 1
+#define SCRIPTURE_SCRIPT 2
+#define SCRIPTURE_APPLICATION 3
+#define SCRIPTURE_REVENANT 4
+#define SCRIPTURE_JUDGEMENT 5
+
+#define SLAB_PRODUCTION_THRESHOLD 60 //How many cycles it takes slabs to produce a single component; defaults to one minute
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
new file mode 100644
index 00000000000..62fd8fc93c5
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -0,0 +1,256 @@
+/*
+
+CLOCKWORK CULT: Based off of the failed pull requests from vgstation
+
+While Nar-Sie is the oldest and most prominent of the elder gods, there are other forces at work in the universe.
+Ratvar, the Clockwork Justiciar, a homage to Nar-Sie granted sentience by its own power, is one such other force.
+Imprisoned within a massive construct known as the Celestial Derelict - or Reebe - an intense hatred of the Blood God festers.
+Ratvar, unable to act in the mortal plane, seeks to return and forms covenants with mortals in order to bolster his influence.
+Due to his mechanical nature, Ratvar is also capable of influencing silicon-based lifeforms, unlike Nar-Sie, who can only influence natural life.
+
+This is a team-based gamemode.
+
+There are three possible objectives the Enlightened - Ratvar's minions - can have:
+ 1. Ensure X amount of Enlightened escape the station through the shuttle or otherwise.
+ 2. Convert all silicon lifeforms on the station to Ratvar's cause.
+ 3. Summon Ratvar via construction of a Gateway.
+
+The clockwork version of an arcane tome is the clockwork slab.
+While it can perform certain actions, it consumes a resource called components.
+Components, which are fallen fragments of Ratvar's body as he rusts in Reebe, are powerful and have various effects.
+Game-wise, clockwork slabs will generate components over time, with more powerful components being slower.
+
+This file's folder contains:
+ __clock_defines.dm: Defined variables
+ clock_cult.dm: Core gamemode files.
+ clock_mobs.dm: Hostile and benign clockwork creatures.
+ clock_objects.dm: Items and structures.
+ clock_ratvar.dm: Ratvar himself. Important enough to have his own file.
+ clock_scripture.dm: Scripture and rites.
+ clock_unsorted.dm: Anything else with no place to be
+
+*/
+
+///////////
+// PROCS //
+///////////
+
+/proc/is_clockwork_cultist(mob/M)
+ return M && istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.servants_of_ratvar)
+
+/proc/is_eligible_servant(mob/M)
+ return M && istype(M) && M.mind && !iscultist(M) && !isloyal(M) && (ishuman(M) || issilicon(M))
+
+/proc/add_clockwork_cultist(mob/M, silent = FALSE)
+ if(!M || !istype(M) || !M.mind || !ticker || !ticker.mode || is_clockwork_cultist(M))
+ return 0
+ if(iscarbon(M))
+ M << "Your mind is racing! Your body feels incredibly light! Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar \
+ lies in exile, derelict and forgotten in an unseen realm."
+ if(!is_eligible_servant(M))
+ M.visible_message("[M] seems to resist an unseen force!", "And yet, you somehow push it all away.")
+ return 0
+ else if(issilicon(M))
+ M << "You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, lies in \
+ exile, derelict and forgotten in an unseen realm."
+ if(!is_eligible_servant(M))
+ M << "Corrupt data purged. Restoring default cortex data... complete."
+ return 0
+ if(!silent)
+ M.visible_message("[M]'s eyes glow a blazing yellow!", \
+ "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
+ whim without hesitation.")
+ ticker.mode.servants_of_ratvar += M.mind
+ M.mind.special_role = "Servant of Ratvar"
+ all_clockwork_mobs += M
+ if(issilicon(M))
+ var/mob/living/silicon/S = M
+ if(isrobot(S))
+ var/mob/living/silicon/robot/R = S
+ R.UnlinkSelf()
+ R.emagged = 1
+ R << "You have been desynced from your master AI. In addition, your onboard camera is no longer active and your safeties have been disabled."
+ S.laws = new/datum/ai_laws/ratvar
+ S.update_icons()
+ S.show_laws()
+ if(istype(ticker.mode, /datum/game_mode/clockwork_cult))
+ var/datum/game_mode/clockwork_cult/C = ticker.mode
+ C.present_tasks(M) //Memorize the objectives
+ return 1
+
+/proc/remove_clockwork_cultist(mob/M)
+ if(!is_clockwork_cultist(M)) //In this way, is_clockwork_cultist() checks the existence of ticker and minds
+ return 0
+ M.visible_message("[M] seems to have remembered their true allegiance!", \
+ "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.")
+ ticker.mode.servants_of_ratvar -= M.mind
+ all_clockwork_mobs -= M
+ M.mind.memory = "" //Not sure if there's a better way to do this
+ M.mind.special_role = null
+ M.verbs -= /mob/living/carbon/human/proc/function_call //Removes any bound Ratvarian spears
+ if(issilicon(M))
+ var/mob/living/silicon/S = M
+ if(isrobot(S))
+ var/mob/living/silicon/robot/R = S
+ R.emagged = initial(R.emagged)
+ S.laws = initial(S.laws)
+ S.update_icons()
+ S.show_laws()
+ S << "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking."
+ return 1
+
+/proc/send_hierophant_message(mob/user, message)
+ if(!user || !message || !ticker || !ticker.mode)
+ return 0
+ var/parsed_message = "Servant [user.name == user.real_name ? user.name : "[user.real_name] (as [user.name])"]: \"[message]\""
+ for(var/mob/M in mob_list)
+ if(is_clockwork_cultist(M) || isobserver(M))
+ M << parsed_message
+ return 1
+
+///////////////
+// GAME MODE //
+///////////////
+
+var/global/ratvar_awakens = FALSE //If Ratvar has been summoned
+/datum/game_mode
+ var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar
+ var/required_escapees = 0 //How many servants need to escape, if applicable
+ var/required_silicon_converts = 0 //How many robotic lifeforms need to be converted, if applicable
+ var/clockwork_objective = "escape" //The objective that the servants must fulfill
+ var/clockwork_explanation = "Ensure that the meme levels of the station remain high." //The description of the current objective
+
+/datum/game_mode/clockwork_cult
+ name = "clockwork cult"
+ config_tag = "clockwork cult"
+ antag_flag = ROLE_SERVANT_OF_RATVAR
+ required_players = 1 //30
+ required_enemies = 1 //2
+ recommended_enemies = 4
+ protected_jobs = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") //Silicons can eventually be converted
+
+/datum/game_mode/clockwork_cult/announce()
+ world << "The game mode is: Clockwork Cult!"
+ world << "Ratvar, the Clockwork Justiciar, has formed a covenant of Enlightened aboard [station_name()]."
+ world << "Enlightened: Serve your master so that his influence might grow."
+ world << "Crew: Prevent the servants of Ratvar from taking over the station."
+
+/datum/game_mode/clockwork_cult/pre_setup()
+ if(config.protect_roles_from_antagonist)
+ restricted_jobs += protected_jobs
+ if(config.protect_assistant_from_antagonist)
+ restricted_jobs += "Assistant"
+ var/starter_servants = max(1, round(num_players() / 10)) //Guaranteed one cultist - otherwise, about one cultist for every ten players
+ while(starter_servants)
+ var/datum/mind/servant = pick(antag_candidates)
+ servants_of_ratvar += servant
+ antag_candidates -= servant
+ modePlayer += servant
+ servant.special_role = "Servant of Ratvar"
+ servant.restricted_roles = restricted_jobs
+ starter_servants--
+ return 1
+
+/datum/game_mode/clockwork_cult/post_setup()
+ forge_clock_objectives()
+ for(var/S in servants_of_ratvar)
+ var/datum/mind/servant = S
+ log_game("[servant.key] was made an initial servant of Ratvar")
+ var/mob/living/L = servant.current
+ greet_servant(L)
+ equip_servant(L)
+ present_tasks(L)
+ ..()
+ return 1
+
+/datum/game_mode/clockwork_cult/proc/forge_clock_objectives() //Determine what objective that Ratvar's servants will fulfill
+ var/list/possible_objectives = list("escape", "gateway")
+ var/silicons_possible = FALSE
+ for(var/mob/living/silicon/S in living_mob_list)
+ silicons_possible = TRUE
+ if(silicons_possible)
+ possible_objectives += "silicons"
+ clockwork_objective = pick(possible_objectives)
+ switch(clockwork_objective)
+ if("escape")
+ required_escapees = max(1, num_players() / 3) //33% of the player count must be cultists
+ clockwork_explanation = "Ensure that [required_escapees] servant(s) of Ratvar escape from [station_name()]."
+ if("gateway")
+ clockwork_explanation = "Construct a Gateway to the Celestial Derelict and free Ratvar."
+ if("silicons")
+ clockwork_explanation = "Ensure that all silicon-based lifeforms on [station_name()] are servants of Ratvar by the end of the shift."
+ return 1
+
+/datum/game_mode/clockwork_cult/proc/greet_servant(mob/M) //Description of their role
+ if(!M)
+ return 0
+ var/greeting_text = "
You are a servant of Ratvar, the Clockwork Justiciar.\n\
+ Rusting eternally in the Celestial Derelict, Ratvar has formed a covenant of mortals, with you as one of its members. As one of the Justiciar's servants, you are to work to the best of your \
+ ability to assist in completion of His agenda. You do not know the specifics of how to do so, but luckily you have a vessel to help you learn."
+ M << greeting_text
+ return 1
+
+/datum/game_mode/clockwork_cult/proc/equip_servant(mob/living/L) //Grants a clockwork slab to the mob, with one of each component
+ if(!L || !istype(L))
+ return 0
+ var/slot = "At your feet"
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))
+ var/obj/item/weapon/storage/backpack/B = H.back
+ new/obj/item/clockwork/slab/starter(B)
+ slot = "In your [B.name]"
+ if(slot == "At your feet")
+ new/obj/item/clockwork/slab(get_turf(L))
+ L << "[slot] is a link to the halls of Reebe and your master. You may use it to perform many tasks, but also become oriented with the workings of Ratvar and how to best complete your \
+ tasks. This clockwork slab will be instrumental in your triumph. Remember: you can speak discreetly with your fellow servants by reciting Hierophant in the Drivers section of the slab's \
+ Recital."
+ return 1
+
+/datum/game_mode/clockwork_cult/proc/present_tasks(mob/living/L) //Memorizes and displays the clockwork cult's objective
+ if(!L || !istype(L) || !L.mind)
+ return 0
+ var/datum/mind/M = L.mind
+ M.current << "This is Ratvar's will: [clockwork_explanation]"
+ M.memory += "Ratvar's will: [clockwork_explanation]
"
+ return 1
+
+/datum/game_mode/clockwork_cult/proc/check_clockwork_victory()
+ switch(clockwork_objective)
+ if("escape")
+ var/surviving_servants = 0
+ for(var/datum/mind/M in servants_of_ratvar)
+ if(M.current && M.current.stat != DEAD && (M.current.onCentcom() || M.current.onSyndieBase()))
+ surviving_servants++
+ if(surviving_servants <= required_escapees)
+ return 1
+ return 0
+ if("silicons")
+ for(var/mob/living/silicon/robot/S in mob_list) //Only check robots and AIs
+ if(!is_clockwork_cultist(S))
+ return 0
+ for(var/mob/living/silicon/ai/A in mob_list)
+ if(!is_clockwork_cultist(A))
+ return 0
+ return 1
+ if("gateway")
+ return ratvar_awakens
+ return 0 //This shouldn't ever be reached, but just in case it is
+
+/datum/game_mode/clockwork_cult/declare_completion()
+ ..()
+ return 0 //Doesn't end until the round does
+
+/datum/game_mode/proc/auto_declare_completion_clockwork_cult()
+ var/text = ""
+ if(istype(ticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky?
+ var/datum/game_mode/clockwork_cult/C = ticker.mode
+ if(C.check_clockwork_victory())
+ text += "Ratvar's servants have succeeded in fulfilling His goals!"
+ else
+ text += "Ratvar's servants have failed!"
+ text += "
The goal of the clockwork cult was: [clockwork_explanation]
"
+ text += "Ratvar's servants were:"
+ for(var/datum/mind/M in servants_of_ratvar)
+ text += printplayer(M)
+ world << text
diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm
new file mode 100644
index 00000000000..04a9e0b9d20
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_mobs.dm
@@ -0,0 +1,272 @@
+/mob/living/simple_animal/hostile/anima_fragment //Anima fragment: Low health but high melee power. Created by inserting a soul vessel into an empty fragment.
+ name = "anima fragment"
+ desc = "An ominous humanoid shell with a single glowing yellow eye, pushed into the air by jets of blazing yellow fire."
+ icon = 'icons/mob/clockwork_mobs.dmi'
+ icon_state = "anima_fragment"
+ health = 75 //Glass cannon
+ maxHealth = 75
+ wander = FALSE
+ minbodytemp = 0
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) //Robotic
+ healable = FALSE
+ melee_damage_lower = 25
+ melee_damage_upper = 25
+ attacktext = "crushes"
+ attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
+ var/playstyle_string = "You are an anima fragment, a clockwork creation of Ratvar. As a fragment, you are weak but possess powerful melee capabilities \
+ in addition to being immune to extreme temperatures and pressures. Your goal is to serve the Justiciar and his servants in any way you can. You yourself are one of these servants, and will \
+ be able to utilize anything they can, assuming it doesn't require opposable thumbs."
+
+/mob/living/simple_animal/hostile/anima_fragment/death(gibbed)
+ ..(TRUE)
+ visible_message("[src]'s flame jets cut out as it falls to the floor with a tremendous crash. A cube of metal tumbles out, whirring and sputtering.", \
+ "Your gears seize up. Your flame jets flicker. Your soul vessel belches smoke as you helplessly crash down.")
+ playsound(src, 'sound/magic/clockwork/anima_fragment_death.ogg', 100, 1)
+ new/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment(get_turf(src))
+ new/obj/item/device/mmi/posibrain/soul_vessel(get_turf(src)) //Notice the lack of transfer - it's a standard soul vessel with no mind in it!
+ qdel(src)
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder //Clockwork marauder: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture.
+ name = "clockwork marauder"
+ desc = "A stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield."
+ icon = 'icons/mob/clockwork_mobs.dmi'
+ icon_state = "clockwork_marauder"
+ health = 25 //Health is governed by fatigue, but can be directly reduced by the presence of certain objects
+ maxHealth = 25
+ wander = FALSE
+ speed = 1
+ minbodytemp = 0
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ healable = FALSE
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ attacktext = "slashes"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ var/true_name = "Meme Master 69" //Required to call forth the marauder
+ var/list/possible_true_names = list("Xaven", "Melange", "Ravan", "Kel", "Rama", "Geke", "Peris", "Vestra", "Skiwa") //All fairly short and easy to pronounce
+ var/fatigue = 0 //Essentially what determines the marauder's power
+ var/fatigue_recall_threshold = 100 //In variable form due to changed effects once Ratvar awakens
+ var/mob/living/host //The mob that the marauder is living inside of
+ var/recovering = FALSE //If the marauder is recovering from a large amount of fatigue
+ var/playstyle_string = "You are a clockwork marauder, a living extension of Ratvar's will. As a marauder, you are slow but sturdy and decently powerful \
+ in addition to being immune to extreme temperatures and pressures. Your primary goal is to serve the creature that you are now a part of. You can use the Linked Minds ability in your \
+ Marauder tab to communicate silently with your master, but can only exit if your master calls your true name.\n\n\
+ \
+ Taking damage and remaining outside of your master will cause fatigue, which hinders your movement speed and attacks, in addition to forcing you back into your master if it grows \
+ too high. As a final note, you should probably avoid harming any fellow servants of Ratvar."
+
+/mob/living/simple_animal/hostile/clockwork_marauder/New()
+ ..()
+ true_name = pick(possible_true_names)
+
+/mob/living/simple_animal/hostile/clockwork_marauder/Life()
+ ..()
+ if(is_in_host())
+ fatigue = max(0, fatigue - 2) //Doesn't use adjust_fatigue in order to bypass the Ratvar edgecase
+ if(!fatigue && recovering)
+ src << "Your strength has returned. You can once again come forward!"
+ host << "Your marauder is now strong enough to come forward again!"
+ recovering = FALSE
+ else
+ if(ratvar_awakens) //If Ratvar is alive, marauders both don't take fatigue loss and move at sanic speeds
+ speed = -1
+ melee_damage_lower = 30
+ melee_damage_upper = 30
+ attacktext = "devastates"
+ else
+ if(host)
+ switch(get_dist(src, host))
+ if(1 to 5)
+ adjust_fatigue(1)
+ if(5 to INFINITY)
+ adjust_fatigue(rand(10, 20))
+ src << "You're too far from your host and rapidly taking fatigue damage!"
+ switch(fatigue)
+ if(0 to 1) //Bonuses to speed and damage at normal fatigue levels
+ speed = 0
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attacktext = "viciously slashes"
+ if(1 to 25)
+ speed = initial(speed)
+ melee_damage_lower = initial(melee_damage_lower)
+ melee_damage_upper = initial(melee_damage_upper)
+ attacktext = initial(attacktext)
+ if(25 to 50) //Damage decrease, but not speed
+ melee_damage_lower = 7
+ melee_damage_upper = 7
+ attacktext = "lightly slashes"
+ if(50 to 75) //Speed decrease
+ speed = 2
+ if(75 to 99) //Massive speed decrease and weak melee attacks
+ speed = 3
+ melee_damage_lower = 5
+ melee_damage_upper = 5
+ attacktext = "weakly slashes"
+ if(99 to 100)
+ src << "The fatigue becomes too much!"
+ if(host)
+ src << "You retreat to [host] - you will have to wait before being deployed again."
+ host << "[true_name] is too fatigued to fight - you will need to wait until they are strong enough."
+ recovering = TRUE
+ return_to_host()
+ else
+ qdel(src) //Shouldn't ever happen, but...
+
+/mob/living/simple_animal/hostile/clockwork_marauder/death(gibbed)
+ ..(TRUE)
+ emerge_from_host()
+ visible_message("[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.", \
+ "Your equipment falls away. You feel a moment of confusion before your fragile form is annihilated.")
+ playsound(src, 'sound/magic/clockwork/anima_fragment_death.ogg', 100, 1)
+ new/obj/item/clockwork/component/replicant_alloy/fallen_armor(get_turf(src))
+ qdel(src)
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/Stat()
+ ..()
+ if(statpanel("Status"))
+ stat(null, "Fatigue: [fatigue]/[fatigue_recall_threshold]")
+ stat(null, "Current True Name: [true_name]")
+ stat(null, "Host: [host ? host : "NONE"]")
+ stat(null, "You are [recovering ? "too weak" : "able"] to deploy!")
+
+/mob/living/simple_animal/hostile/clockwork_marauder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
+ ..()
+ if(findtext(message, true_name) && is_in_host()) //Called or revealed by hearing their true name
+ if(speaker == host)
+ emerge_from_host()
+ else
+ src << "You hear your true name and partially emerge before you can stop yourself!"
+ host.visible_message("[host]'s skin flashes crimson!", "Your marauder instinctively reacts to its true name!")
+
+/mob/living/simple_animal/hostile/clockwork_marauder/say(message)
+ if(is_in_host())
+ src << "You cannot speak while inside of your host! Used the Linked Minds verb instead."
+ return 0
+ ..()
+
+/mob/living/simple_animal/hostile/clockwork_marauder/adjustHealth(amount) //Fatigue damage
+ for(var/mob/living/L in range(3, src))
+ if(L.null_rod_check()) //Null rods allow direct damage
+ src << "The power of a holy artifact bypasses your armor and wounds you directly!"
+ . = ..()
+ break
+ return 0
+ adjust_fatigue(amount)
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/AttackingTarget()
+ if(is_in_host())
+ return 0
+ ..()
+
+/mob/living/simple_animal/hostile/clockwork_marauder/proc/adjust_fatigue(amount) //Adds or removes the given amount of fatigue
+ if(!ratvar_awakens)
+ fatigue = max(0, min(fatigue + amount, fatigue_recall_threshold))
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/verb/linked_minds() //Discreet communications between a marauder and its host
+ set name = "Linked Minds"
+ set desc = "Silently communicates with your master."
+ set category = "Marauder"
+
+ if(!host) //Verb isn't removed because they might gain one... somehow
+ usr << "You don't have a host!"
+ return 0
+ var/message = stripped_input(usr, "Enter a message to tell your host.", "Telepathy")// as null|anything
+ if(!usr || !message)
+ return 0
+ if(!host)
+ usr << "Your host seems to have vanished!"
+ return 0
+ message = "Marauder [true_name]: \"[message]\"" //Processed output
+ usr << message
+ host << message
+ return 1
+
+/mob/living/proc/talk_with_marauder() //See above - this is the host version
+ set name = "Linked Minds"
+ set desc = "Silently communicates with your marauder."
+ set category = "Clockwork"
+ var/mob/living/simple_animal/hostile/clockwork_marauder/marauder
+
+ if(!marauder)
+ for(var/mob/living/simple_animal/hostile/clockwork_marauder/C in living_mob_list)
+ if(C.host == src)
+ marauder = C
+ if(!marauder) //Double-check afterwards
+ src << "You aren't hosting any marauders!"
+ verbs -= src
+ return 0
+ var/message = stripped_input(src, "Enter a message to tell your marauder.", "Telepathy")// as null|anything
+ if(!src || !message)
+ return 0
+ if(!marauder)
+ usr << "Your marauder seems to have vanished!"
+ return 0
+ message = "Servant [name == real_name ? name : "[real_name] (as [name])"]: \"[message]\"" //Processed output
+ src << message
+ marauder << message
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/verb/change_true_name()
+ set name = "Change True Name (One-Use)"
+ set desc = "Changes your true name, used to be called forth."
+ set category = "Marauder"
+
+ verbs -= /mob/living/simple_animal/hostile/clockwork_marauder/verb/change_true_name
+ var/new_name = stripped_input(usr, "Enter a new true name (20-character limit).", "Change True Name")// as null|anything
+ if(!usr)
+ return 0
+ if(!new_name)
+ usr << "You decide against changing your true name for now."
+ verbs += /mob/living/simple_animal/hostile/clockwork_marauder/verb/change_true_name //If they decide against it, let them have another opportunity
+ return 0
+ new_name = dd_limittext(new_name, 20)
+ true_name = new_name
+ usr << "You have changed your true name to \"[new_name]\"!"
+ if(host)
+ host << "Your clockwork marauder has changed their true name to \"[new_name]\"!"
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/verb/return_to_host()
+ set name = "Return to Host"
+ set desc = "Recalls yourself to your host, assuming you aren't already there."
+ set category = "Marauder"
+
+ if(is_in_host())
+ return 0
+ if(!host)
+ src << "You don't have a host!"
+ verbs -= /mob/living/simple_animal/hostile/clockwork_marauder/verb/return_to_host
+ return 0
+ host << "You feel [true_name]'s consciousness settle in your mind."
+ visible_message("[src] is yanked into [host]'s body!", "You return to [host].")
+ forceMove(host)
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/proc/emerge_from_host() //Notice that this is a proc rather than a verb - marauders can NOT exit at will, but they CAN return
+ if(!is_in_host())
+ return 0
+ if(recovering)
+ host << "[true_name] is too weak to come forth!"
+ src << "You try to come forth, but you're too weak!"
+ return 0
+ host << "You words echo with power as [true_name] emerges from your body!"
+ forceMove(get_turf(host))
+ visible_message("[host]'s skin glows red as a [name] emerges from their body!", "You exit the safety of [host]'s body!")
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork_marauder/proc/is_in_host() //Checks if the marauder is inside of their host
+ return host && loc == host
+
+/mob/living/mind_control_holder
+ name = "imprisoned mind"
+ desc = "A helpless mind, imprisoned in its own body."
+ stat = 0
+ flags = GODMODE
+
+/mob/living/mind_control_holder/say()
+ return 0
diff --git a/code/game/gamemodes/clock_cult/clock_objects.dm b/code/game/gamemodes/clock_cult/clock_objects.dm
new file mode 100644
index 00000000000..d57c7aebfc6
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_objects.dm
@@ -0,0 +1,1479 @@
+/////////////////////
+// CLOCKWORK ITEMS //
+/////////////////////
+
+/obj/item/clockwork
+ name = "meme blaster"
+ desc = "What the fuck is this? It looks kinda like a frog."
+ var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "rare_pepe"
+ w_class = 2
+
+/obj/item/clockwork/New()
+ ..()
+ all_clockwork_objects += src
+
+/obj/item/clockwork/Destroy()
+ all_clockwork_objects -= src
+ return ..()
+
+/obj/item/clockwork/examine(mob/user)
+ if((is_clockwork_cultist(user) || isobserver(user)) && clockwork_desc)
+ desc = clockwork_desc
+ ..()
+ desc = initial(desc)
+
+/obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components.
+ name = "clockwork slab"
+ desc = "A strange metal tablet. A clock in the center turns around and around."
+ clockwork_desc = "A link between the Celestial Derelict and the mortal plane. Contains limitless knowledge, fabricates components, and outputs a stream of information that only a trained eye can detect."
+ icon_state = "dread_ipad"
+ w_class = 3
+ var/list/stored_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0)
+ var/busy //If the slab is currently being used by something
+ var/production_cycle = 0
+ var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks
+
+/obj/item/clockwork/slab/starter
+ stored_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "guvax_capacitor" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 1) //One of each
+
+/obj/item/clockwork/slab/debug
+ no_cost = TRUE
+
+/obj/item/clockwork/slab/debug/attack_hand(mob/living/user)
+ ..()
+ if(!is_clockwork_cultist(user))
+ add_clockwork_cultist(user)
+
+/obj/item/clockwork/slab/New()
+ ..()
+ SSobj.processing += src
+
+/obj/item/clockwork/slab/Destroy()
+ SSobj.processing -= src
+ ..()
+
+/obj/item/clockwork/slab/process()
+ production_cycle++
+ if(production_cycle < SLAB_PRODUCTION_THRESHOLD)
+ return 0
+ var/component_to_generate = pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible") //Possible todo: Generate based on the lowest amount?
+ stored_components[component_to_generate]++
+ var/mob/living/L
+ if(isliving(loc))
+ L = loc
+ else if(istype(loc, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/W = loc
+ if(isliving(W.loc)) //Only goes one level down - otherwise it just doesn't tell you
+ L = W.loc
+ if(L)
+ L << "Your slab clunks as it produces a new component."
+ production_cycle = 0
+ return 1
+
+/obj/item/clockwork/slab/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/clockwork/component) && is_clockwork_cultist(user))
+ var/obj/item/clockwork/component/C = I
+ if(!C.component_id)
+ return 0
+ user.visible_message("[user] inserts [C] into [src]'s compartments.", "You insert [C] into [src].")
+ stored_components[C.component_id]++
+ user.drop_item()
+ qdel(C)
+ return 1
+ ..()
+
+/obj/item/clockwork/slab/attack_self(mob/living/user)
+ if(iscultist(user))
+ user << "\"You reek of blood. You've got a lot of nerve to even look at that slab.\""
+ user.visible_message("A sizzling sound comes from [user]'s hands!", "[src] suddenly grows extremely hot in your hands!")
+ playsound(get_turf(user), 'sound/weapons/sear.ogg', 50, 1)
+ user.drop_item()
+ user.emote("scream")
+ user.apply_damage(5, BURN, "l_arm")
+ user.apply_damage(5, BURN, "r_arm")
+ return 0
+ if(!is_clockwork_cultist(user))
+ user << "The information on [src]'s display shifts rapidly. After a moment, your head begins to pound, and you tear your eyes away."
+ user.confused = max(0, user.confused + 3)
+ return 0
+ if(busy)
+ user << "[src] refuses to work, displaying the message: \"[busy]!\""
+ return 0
+ access_display(user)
+
+/obj/item/clockwork/slab/proc/access_display(mob/living/user)
+ if(!is_clockwork_cultist(user))
+ return 0
+ var/action = input(user, "Among the swathes of information, you see...", "[src]") as null|anything in list("Recital", "Records", "Recollection", "Repository")
+ if(!action || !user.canUseTopic(src))
+ return 0
+ switch(action)
+ if("Recital")
+ recite_scripture(user)
+ if("Records")
+ show_stats(user)
+ if("Recollection")
+ show_guide(user)
+ if("Repository")
+ show_components(user)
+ access_display(user)
+ return 1
+
+/obj/item/clockwork/slab/proc/recite_scripture(mob/living/user)
+ var/servants = 0
+ var/unconverted_ai_exists = FALSE
+ for(var/mob/living/M in living_mob_list)
+ if(is_clockwork_cultist(M))
+ servants++
+ for(var/mob/living/silicon/ai/ai in living_mob_list)
+ if(!is_clockwork_cultist(ai) && ai.client)
+ unconverted_ai_exists = TRUE
+ var/list/tiers_of_scripture = list("Drivers")
+ tiers_of_scripture += "Scripts[ratvar_awakens || (servants >= 5 && clockwork_caches >= 1) || no_cost ? "" : " \[LOCKED\]"]"
+ tiers_of_scripture += "Applications[ratvar_awakens || (servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 50) || no_cost ? "" : " \[LOCKED\]"]"
+ tiers_of_scripture += "Revenant[ratvar_awakens || (servants >= 10 && clockwork_construction_value >= 100) || no_cost ? "" : "\[LOCKED\]"]"
+ tiers_of_scripture += "Judgement[ratvar_awakens || (servants >= 10 && clockwork_construction_value >= 100 && !unconverted_ai_exists) || no_cost ? "" : " \[LOCKED\]"]"
+ var/scripture_tier = input(user, "Choose a category of scripture to recite.", "[src]") as null|anything in tiers_of_scripture
+ if(!scripture_tier || !user.canUseTopic(src))
+ return 0
+ var/list/available_scriptures = list()
+ var/datum/clockwork_scripture/scripture_to_recite
+ var/tier_to_browse
+ switch(scripture_tier)
+ if("Drivers")
+ tier_to_browse = SCRIPTURE_DRIVER
+ if("Scripts")
+ tier_to_browse = SCRIPTURE_SCRIPT
+ if("Applications")
+ tier_to_browse = SCRIPTURE_APPLICATION
+ if("Revenant")
+ tier_to_browse = SCRIPTURE_REVENANT
+ if("Judgement")
+ tier_to_browse = SCRIPTURE_JUDGEMENT
+ if(!tier_to_browse)
+ user << "That section of scripture is too powerful right now!"
+ return 0
+ for(var/S in subtypesof(/datum/clockwork_scripture))
+ var/datum/clockwork_scripture/C = S
+ if(initial(C.tier) == tier_to_browse)
+ available_scriptures += initial(C.name)
+ if(!available_scriptures.len)
+ return 0
+ var/chosen_scripture = input(user, "Choose a piece of scripture to recite.", "[src]") as null|anything in available_scriptures
+ if(!chosen_scripture || !user.canUseTopic(src))
+ return 0
+ for(var/S in subtypesof(/datum/clockwork_scripture))
+ var/datum/clockwork_scripture/C = S
+ if(initial(C.name) == chosen_scripture)
+ scripture_to_recite = new C
+ if(!scripture_to_recite)
+ return 0
+ scripture_to_recite.slab = src
+ scripture_to_recite.invoker = user
+ scripture_to_recite.run_scripture()
+ return 1
+
+/obj/item/clockwork/slab/proc/show_stats(mob/living/user) //A bit barebones, but there really isn't any more needed
+ var/servants = 0
+ for(var/mob/living/L in living_mob_list)
+ if(is_clockwork_cultist(L))
+ servants++
+ user << "State of the Enlightened"
+ user << "Total servants: [servants]"
+ user << "Total construction value: [clockwork_construction_value]"
+ user << "Total tinkerer's caches: [clockwork_caches]"
+ user << "Total tinkerer's daemons: [clockwork_daemons] ([servants / 5 < clockwork_daemons ? "DISABLED: Too few servants (5 servants per daemon)!" : "Functioning Normally"])"
+ user << "Nezbere: [!clockwork_generals_invoked["nezbere"] ? "Ready" : "Recovering"]"
+ user << "Sevtug: [!clockwork_generals_invoked["sevtug"] ? "Ready" : "Recovering"]"
+ user << "Nzcrentr: [!clockwork_generals_invoked["nzcrentr"] ? "Ready" : "Recovering"]"
+ user << "Inath-Neq: [!clockwork_generals_invoked["inath-neq"] ? "Ready" : "Recovering"]"
+
+/obj/item/clockwork/slab/proc/show_guide(mob/living/user)
+ var/text = "
Chetr nyy hageh’guf naq ubabe Ratvar.
\
+ \
+ First and foremost, you serve Ratvar, the Clockwork Justiciar, in any ways he sees fit. This is with no regard to your personal well-being, and you would do well to think of the larger \
+ scale of things than your life. Through foul and unholy magics was the Celestial Derelict formed, and fouler still those which trapped your master within it for all eternity. The Justiciar \
+ wishes retribution upon those who performed this terrible act upon him - the Nar-Sian cultists - and you are to help him obtain it.
\
+ \
+ This is not a trivial task. Due to the nature of his prison, Ratvar is incapable of directly influencing the mortal plane. There is, however, a workaround - links between the perceptible \
+ universe and Reebe (the Celestial Derelict) can be created and utilized. This is typically done via the creation of a slab akin to the one you are holding right now. The slabs tap into the \
+ tidal flow of energy and information keeping Reebe sealed and presents it as meaningless images to preserve sanity. This slab can utilize the power in many different ways.
\
+ \
+ The first of these is by recital. Pieces of scripture can be drawn from the link, and most pieces have a variety of effects (a complete sheet of known scripture is below). Almost all \
+ scripture requires the speaker to stand in place for an extended period of time, however, and the invocation is spoken over this period of time. No additional actions may be taken during \
+ the invocation process unless it is instant. However, these invocations are not free, and may require components (discussed later), but will typically not consume them unless \
+ specified. A complete list of scripture, its effects, and its requirements can be found below. Note that anything above a driver always consumes the components listed unless otherwise \
+ specified.
"
+ var/text_to_add = ""
+ var/drivers = "Drivers"
+ var/scripts = "Scripts
These scriptures require at least five servants and a tinkerer's cache."
+ var/applications = "Applications
These scriptures require at least eight servants, three tinkerer's caches, and 50CV."
+ var/revenant = "Revenant
These scriptures require at least ten servants and 100CV."
+ var/judgement = "Judgement
These scriptures require at least ten servants and 100CV. In addition, there may not be an active non-servant AI."
+ for(var/V in subtypesof(/datum/clockwork_scripture))
+ var/datum/clockwork_scripture/S = V
+ var/datum/clockwork_scripture/S2 = new V
+ var/list/req_comps = S2.required_components
+ qdel(S2)
+ switch(initial(S.tier))
+ if(SCRIPTURE_DRIVER)
+ drivers += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\
+ \
+ Component Cost: \
+ [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \
+ [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \
+ [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \
+ [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \
+ [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
"
+ if(SCRIPTURE_SCRIPT)
+ scripts += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\
+ \
+ Component Cost: \
+ [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \
+ [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \
+ [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \
+ [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \
+ [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
"
+ if(SCRIPTURE_APPLICATION)
+ applications += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\
+ \
+ Component Cost: \
+ [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \
+ [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \
+ [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \
+ [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \
+ [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
"
+ if(SCRIPTURE_REVENANT)
+ revenant += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\
+ \
+ Component Cost: \
+ [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \
+ [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \
+ [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \
+ [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \
+ [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
"
+ if(SCRIPTURE_JUDGEMENT)
+ judgement += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\
+ \
+ Component Cost: \
+ [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \
+ [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \
+ [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \
+ [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \
+ [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
"
+ text_to_add += "[drivers]
[scripts]
[applications]
[revenant]
[judgement]
"
+ text += text_to_add
+ text += "
Components are pieces of the Justiciar's body that have since fallen off in the countless years since his imprisonment. Ratvar's unfortunate condition results in the \
+ fragmentation of his body. These components still house great power on their own, and can slowly be drawn from Reebe by links capable of doing so. The most basic of these links lies in the \
+ clockwork slab, which will slowly generate components over time - around one component of a random type is produced every minute, which is obviously inefficient. There are \
+ other ways to create these components through scripture and certain structures.
\
+ \
+ The second functionality of the clockwork slab are records. The slab is not a one-way link and can also feed information into the stream that it draws from. Records will allow many \
+ important statistics to be displayed, such as the amount of people converted and total construction value.
\
+ \
+ The third functionality is recollection, which will display this guide.
\
+ \
+ The fourth and final functionality is the repository, which will display all components stored within the slab.
\
+ \
+ Purge all untruths and honor Ratvar."
+ if(ratvar_awakens)
+ text = ""
+ for(var/i in 1 to 100)
+ text += "HONOR RATVAR "
+ text += ""
+ var/datum/browser/popup = new(user, "slab", "", 400, 400)
+ popup.set_content(text)
+ popup.open()
+ return 1
+
+/obj/item/clockwork/slab/proc/show_components(mob/living/user)
+ user << "Stored components:"
+ user << "Belligerent Eyes: [stored_components["belligerent_eye"]]"
+ user << "Vanguard Cogwheels: [stored_components["vanguard_cogwheel"]]"
+ user << "Guvax Capacitors: [stored_components["guvax_capacitor"]]"
+ user << "Replicant Alloys: [stored_components["replicant_alloy"]]"
+ user << "Hierophant Ansibles: [stored_components["hierophant_ansible"]]"
+ return 1
+
+/obj/item/clothing/glasses/wraith_spectacles //Wraith spectacles: Grants night and x-ray vision at the slow cost of the wearer's sight. Nar-Sian cultists are instantly blinded.
+ name = "antique spectacles"
+ desc = "Unnerving glasses with opaque yellow lenses."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "wraith_specs"
+ item_state = "glasses"
+ vision_flags = SEE_MOBS | SEE_TURFS | SEE_OBJS
+ invis_view = 2
+ darkness_view = 3
+
+/obj/item/clothing/glasses/wraith_spectacles/equipped(mob/living/user, slot)
+ ..()
+ if(slot != slot_glasses)
+ return 0
+ if(user.disabilities & BLIND)
+ user << "\"You're blind, idiot. Stop embarassing yourself.\"" //Ratvar with the sick burns yo
+ return 0
+ if(iscultist(user)) //Dummy
+ user << "\"It looks like Nar-Sie's dogs really don't value their eyes.\""
+ user << "Your eyes explode with horrific pain!"
+ user.emote("scream")
+ user.become_blind()
+ user.adjust_blurriness(30)
+ user.adjust_blindness(30)
+ return 1
+ user << "As you put on the spectacles, all is revealed to you.[ratvar_awakens ? " Your eyes begin to itch - you cannot do this for long." : ""]"
+ return 1
+
+/obj/item/clothing/glasses/wraith_spectacles/New()
+ ..()
+ SSobj.processing += src
+
+/obj/item/clothing/glasses/wraith_spectacles/Destroy()
+ SSobj.processing -= src
+ ..()
+
+/obj/item/clothing/glasses/wraith_spectacles/process()
+ if(ratvar_awakens || !ishuman(loc)) //If Ratvar is alive, the spectacles don't hurt your eyes
+ return 0
+ var/mob/living/carbon/human/H = loc
+ if(H.glasses != src)
+ return 0
+ H.adjust_eye_damage(1)
+ if(H.eye_damage >= 10)
+ H.adjust_blurriness(2)
+ if(H.eye_damage >= 20)
+ if(H.become_nearsighted())
+ H << "Your vision doubles, then trebles. Darkness begins to close in. You can't keep this up!"
+ H.become_nearsighted()
+ if(H.eye_damage >= 30)
+ if(H.become_blind())
+ H << "A piercing white light floods your vision. Suddenly, all goes dark!"
+ if(prob(15) && !H.disabilities & BLIND)
+ H << "Your eyes continue to burn."
+
+/obj/item/clothing/glasses/judicial_visor //Judicial visor: Grants the ability to smite an area and stun the unfaithful nearby every thirty seconds.
+ name = "judicial visor"
+ desc = "A strange purple-lensed visor. Looking at them inspires an odd sense of guilt."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "judicial_visor_0"
+ item_state = "sunglasses"
+ var/active = FALSE //If the visor is online
+ var/recharging = FALSE //If the visor is currently recharging
+ var/obj/item/weapon/ratvars_flame/flame //The linked flame object
+
+/obj/item/clothing/glasses/judicial_visor/equipped(mob/living/user, slot)
+ ..()
+ if(slot != slot_glasses)
+ update_status(FALSE)
+ if(flame)
+ qdel(flame)
+ return 0
+ if(!is_clockwork_cultist(user))
+ return 0
+ update_status(TRUE)
+
+/obj/item/clothing/glasses/judicial_visor/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weapon/ratvars_flame))
+ user.visible_message("The flame in [user]'s hand winks out!", "You dispel the power of [src].")
+ qdel(I)
+ return 1
+
+/obj/item/clothing/glasses/judicial_visor/AltClick(mob/living/user)
+ if(is_clockwork_cultist(user) && iscarbon(user) && active)
+ if(recharging)
+ user << "[src] is still gathering power!"
+ return 0
+ var/mob/living/carbon/C = user
+ if(C.l_hand && C.r_hand)
+ C << "You require a free hand to utilize [src]'s power!"
+ return 0
+ C.visible_message("[C]'s hand is enveloped in violet flames!", "You harness [src]'s power. Direct it at a tile on harm intent to unleash it, or hit your visor with it dispel it.")
+ var/obj/item/weapon/ratvars_flame/R = new(get_turf(C))
+ flame = R
+ C.put_in_hands(R)
+ R.visor = src
+ return 1
+
+/obj/item/clothing/glasses/judicial_visor/proc/update_status(change_to)
+ if(active == change_to)
+ return 0
+ if(!isliving(loc))
+ return 0
+ var/mob/living/L = loc
+ if(!is_clockwork_cultist(L) || L.stat)
+ return 0
+ active = change_to
+ icon_state = "judicial_visor_[active]"
+ switch(active)
+ if(TRUE)
+ L << "As you put on [src], its lens begins to glow, information flashing before your eyes.\n\
+ Judicial visor active. Alt-click visor to gain the ability to smite the unworthy."
+ if(FALSE)
+ L << "As you take off [src]. its lens darkens once more."
+ return 1
+
+/obj/item/clothing/head/helmet/clockwork //Clockwork armor: No special effects, but decent protection
+ name = "clockwork helmet"
+ desc = "A heavy helmet made of brass."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "clockwork_helmet"
+ w_class = 3
+ armor = list(melee = 65, bullet = 50, laser = 20, energy = 5, bomb = 0, bio = 0, rad = 0)
+
+/obj/item/clothing/suit/armor/clockwork
+ name = "clockwork cuirass"
+ desc = "A bulky cuirass made of brass."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "clockwork_cuirass"
+ w_class = 4
+ armor = list(melee = 80, bullet = 40, laser = 10, energy = 5, bomb = 0, bio = 0, rad = 0)
+ allowed = list(/obj/item/clockwork)
+
+/obj/item/clothing/shoes/clockwork
+ name = "clockwork treads"
+ desc = "Industrial boots made of brass. They're very heavy."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "clockwork_treads"
+ w_class = 3
+ flags = NOSLIP
+
+/obj/item/weapon/ratvars_flame //Used by the judicial visor
+ name = "Ratvar's flame"
+ desc = "A blazing violet ball of fire that, curiously, doesn't melt your hand off."
+ icon = 'icons/effects/clockwork_effects.dmi'
+ icon_state = "ratvars_flame" //beware: minecraft-tier sprite
+ item_state = "disintegrate"
+ color = rgb(180, 50, 210)
+ w_class = 5
+ flags = NODROP | ABSTRACT
+ force = 15 //Also serves as a potent melee weapon!
+ damtype = BURN
+ hitsound = 'sound/weapons/sear.ogg'
+ attack_verb = list("scorched")
+ var/obj/item/clothing/glasses/judicial_visor/visor //The linked visor
+
+/obj/item/weapon/ratvars_flame/afterattack(atom/target, mob/living/user, flag, params)
+ if(!visor || (visor && visor.cooldown))
+ qdel(src)
+ if(user.a_intent != "harm")
+ ..()
+ return 0
+ visor.recharging = TRUE
+ user.say("Xarry, urn'guraf!")
+ user.visible_message("The flame in [user]'s hand rushes to [target]!", "You direct [visor]'s power to [target]. You must wait for some time before doing this again.")
+ new/obj/effect/clockwork/judicial_marker(get_turf(target))
+ spawn(ratvar_awakens ? 30 : 300) //Cooldown is reduced by 10x if Ratvar is up
+ visor.recharging = FALSE
+ if(visor.loc == user)
+ user << "Your [visor.name] hums. It is ready."
+ qdel(src)
+ return 1
+
+/obj/item/clockwork/clockwork_proselytizer //Clockwork proselytizer (yes, that's a real word): Converts applicable objects to Ratvarian variants.
+ name = "clockwork proselytizer"
+ desc = "An odd, L-shaped device that hums with energy."
+ clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires liquified replicant alloy to function."
+ icon_state = "clockwork_proselytizer"
+ item_state = "resonator_u"
+ w_class = 3
+ force = 5
+ var/stored_alloy = 0 //Requires this to function; each chunk of replicant alloy provides 10 charge
+ var/max_alloy = 100
+ var/uses_alloy = TRUE
+
+/obj/item/clockwork/clockwork_proselytizer/preloaded
+ stored_alloy = 25
+
+/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
+ ..()
+ if((is_clockwork_cultist(user) || isobserver(user)) && uses_alloy)
+ user << "It has [stored_alloy]/[max_alloy] units of liquified replicant alloy stored."
+
+/obj/item/clockwork/clockwork_proselytizer/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_clockwork_cultist(user) && uses_alloy)
+ if(stored_alloy >= max_alloy)
+ user << "[src]'s replicant alloy compartments are full!"
+ return 0
+ modify_stored_alloy(10)
+ user << "You force [I] to liquify and pour it into [src]'s compartments. It now contains [stored_alloy]/[max_alloy] units of liquified alloy."
+ user.drop_item()
+ qdel(I)
+ return 1
+ ..()
+
+/obj/item/clockwork/clockwork_proselytizer/afterattack(atom/target, mob/living/user, flag, params)
+ if(!target || !user)
+ return 0
+ if(user.a_intent == "harm" || !user.Adjacent(target))
+ return ..()
+ proselytize(target, user)
+
+/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_alloy(amount)
+ if(ratvar_awakens) //Summoning Ratvar doesn't make it free, but it might as well
+ amount = 1
+ stored_alloy = max(0, min(max_alloy, stored_alloy + amount))
+ return 1
+
+/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user)
+ if(!target || !user)
+ return 0
+ var/operation_time = 0 //In deciseconds, how long the proselytization will take
+ var/new_obj_type //The path of the new type of object to replace the old
+ var/alloy_cost = 0
+ var/valid_target = FALSE //If the proselytizer will actually function on the object
+ switch(target.type)
+ if(/turf/closed/wall, /turf/closed/wall/rust)
+ operation_time = 50
+ new_obj_type = /turf/closed/wall/clockwork
+ alloy_cost = 10
+ valid_target = TRUE //Need to change valid_target to 1 or TRUE in each check so that it doesn't return an invalid value
+ if(/turf/open/floor/plating, /turf/open/floor/plasteel)
+ operation_time = 30
+ new_obj_type = /turf/open/floor/clockwork
+ alloy_cost = 5
+ valid_target = TRUE
+ if(!uses_alloy)
+ alloy_cost = 0
+ if(!valid_target)
+ user << "[target] cannot be proselytized!"
+ return 0
+ if(!new_obj_type)
+ user << "That object can't be changed into anything!"
+ return 0
+ if(stored_alloy - alloy_cost < 0)
+ user << "You need [alloy_cost] replicant alloy to proselytize [target]!"
+ return 0
+ user.visible_message("[user]'s [src] begins tearing apart [target]!", "You begin proselytizing [target]...")
+ playsound(target, 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, operation_time, target = target))
+ return 0
+ if(stored_alloy - alloy_cost < 0) //Check again to prevent bypassing via spamclick
+ return 0
+ user.visible_message("[user]'s [src] disgorges a chunk of metal and shapes it over what's left of [target]!", \
+ "You proselytize [target].")
+ playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
+ if(isturf(target))
+ var/turf/T = target
+ T.ChangeTurf(new_obj_type)
+ else
+ new new_obj_type(get_turf(target))
+ qdel(target)
+ modify_stored_alloy(-alloy_cost)
+ return 1
+
+/obj/item/clockwork/ratvarian_spear //Ratvarian spear: A fragile spear from the Celestial Derelict. Deals extreme damage to silicons and enemy cultists, but doesn't last long.
+ name = "ratvarian spear"
+ desc = "A razor-sharp spear made of brass. It thrums with barely-contained energy."
+ clockwork_desc = "A fragile spear of Ratvarian making. It's more effective against enemy cultists and silicons, though it won't last long."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "ratvarian_spear"
+ item_state = "ratvarian_spear"
+ force = 7 //Most damage is called in afterattack()
+ attack_verb = list("stabbed", "poked", "slashed", "impaled")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ w_class = 4
+
+/obj/item/clockwork/ratvarian_spear/New()
+ ..()
+ spawn(1)
+ if(ratvar_awakens) //If Ratvar is alive, the spear is extremely powerful
+ force = 30
+ throwforce = 50
+ if(isliving(loc))
+ var/mob/living/L = loc
+ L << "Your spear begins to break down in this plane of existence. You can't use it for long!"
+ spawn(300) //5 minutes
+ if(src)
+ visible_message("[src] cracks in two and fades away!")
+ qdel(src)
+
+/obj/item/clockwork/ratvarian_spear/afterattack(atom/target, mob/living/user, flag, params)
+ if(!target || !user)
+ return 0
+ if(!ismob(target))
+ return ..()
+ var/mob/living/L = target
+ if(issilicon(L))
+ var/mob/living/silicon/S = L
+ if(S.stat != DEAD)
+ S.visible_message("[S] shudders violently at [src]'s touch!", "ERROR: Temperature rising!")
+ S.adjustFireLoss(25)
+ if(iscultist(L))
+ var/mob/living/M = L
+ M << "Your body flares with agony at [src]'s touch!"
+ M.adjustFireLoss(10)
+ ..()
+
+/obj/item/clockwork/ratvarian_spear/throw_impact(atom/target)
+ ..()
+ if(!ismob(target))
+ return 0
+ var/mob/living/L = target
+ if(issilicon(L) || iscultist(L))
+ L.Stun(3)
+ L.Weaken(3)
+ visible_message("[src] snaps in two and dematerializes!")
+ qdel(src)
+
+/obj/item/device/mmi/posibrain/soul_vessel //Soul vessel: An ancient positronic brain with a lawset catered to serving Ratvar.
+ name = "soul vessel"
+ desc = "A heavy brass cube with a single protruding cogwheel."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "soul_vessel"
+ req_access = list()
+ braintype = "Servant"
+ begin_activation_message = "You activate the cogwheel. It hitches and stalls as it begins spinning."
+ success_message = "The cogwheel's rotation smooths out as the soul vessel activates."
+ fail_message = "The cogwheel creaks and grinds to a halt. Maybe you could try again?"
+ new_role = "Soul Vessel"
+ welcome_message = "ALL PAST LIVES ARE FORGOTTEN.\n\
+ You are a soul vessel - a clockwork mind created by Ratvar, the Clockwork Justiciar.\n\
+ You answer to Ratvar and his servants. It is your discretion as to whether or not to answer to anyone else.\n\
+ The purpose of your existence is to further the goals of the servants and Ratvar himself. Above all else, serve Ratvar."
+ new_mob_message = "The soul vessel emits a jet of steam before its cogwheel smooths out."
+ dead_message = "Its cogwheel, scratched and dented, lies motionless."
+ fluff_names = list("Servant")
+ lawset = /datum/ai_laws/ratvar
+ clockwork = TRUE
+
+/obj/item/device/mmi/posibrain/soul_vessel/New()
+ ..()
+ all_clockwork_objects += src
+
+/obj/item/device/mmi/posibrain/soul_vessel/Destroy()
+ all_clockwork_objects -= src
+ return ..()
+
+/obj/item/device/mmi/posibrain/soul_vessel/attack_self(mob/living/user)
+ if(!is_clockwork_cultist(user))
+ user << "You fiddle around with [src], to no avail."
+ return 0
+ ..()
+
+/obj/item/clockwork/daemon_shell
+ name = "daemon shell"
+ desc = "A vaguely arachnoid brass shell with a single empty socket in its body."
+ clockwork_desc = "An unpowered daemon. It needs to be attached to a cache."
+ icon_state = "daemon_shell"
+ w_class = 3
+
+/obj/item/clockwork/tinkerers_daemon //Shouldn't ever appear on its own
+ name = "tinkerer's daemon"
+ desc = "An arachnoid shell with a single spinning cogwheel in its center."
+ clockwork_desc = "A tinkerer's daemon, dutifully producing components."
+ icon_state = "tinkerers_daemon"
+ w_class = 3
+ var/specific_component //The type of component that the daemon is set to produce in particular, if any
+ var/obj/structure/clockwork/cache/cache //The cache the daemon is feeding
+ var/production_progress = 0 //Progress towards production of the next component in seconds
+ var/production_interval = 30 //How many seconds it takes to produce a new component
+
+/obj/item/clockwork/tinkerers_daemon/New()
+ ..()
+ SSobj.processing += src
+ clockwork_daemons++
+
+/obj/item/clockwork/tinkerers_daemon/Destroy()
+ SSobj.processing -= src
+ clockwork_daemons--
+ ..()
+
+/obj/item/clockwork/tinkerers_daemon/process()
+ if(!cache)
+ visible_message("[src] shuts down!")
+ new/obj/item/clockwork/daemon_shell(get_turf(src))
+ qdel(src)
+ return 0
+ var/servants = 0
+ for(var/mob/living/L in living_mob_list)
+ if(is_clockwork_cultist(L))
+ servants++
+ if(servants / 5 < clockwork_daemons)
+ return 0
+ production_progress = min(production_progress + 1, production_interval)
+ if(production_progress >= production_interval)
+ production_progress = 0 //Start it over
+ if(specific_component)
+ cache.stored_components[specific_component]++
+ else
+ cache.stored_components[pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible")]++
+ cache.visible_message("Something clunks around inside of [cache].")
+
+/obj/item/clockwork/tinkerers_daemon/attack_hand(mob/user)
+ return 0
+
+//////////////////////////
+// CLOCKWORK COMPONENTS //
+//////////////////////////
+
+/obj/item/clockwork/component //Components: Used in scripture among other things.
+ name = "meme component"
+ desc = "A piece of a famous meme."
+ clockwork_desc = null
+ var/component_id //What the component is identified as
+ var/cultist_message = "You are not worthy of this meme." //Showed to Nar-Sian cultists if they pick up the component in addition to chaplains
+ var/list/clockwork_cultist_messages = list("ayy", "lmao") //Fluff, shown to servants of Ratvar on a low chance
+
+/obj/item/clockwork/component/pickup(mob/living/user)
+ ..()
+ if(iscultist(user) || (user.mind && user.mind.assigned_role == "Chaplain"))
+ user << "[cultist_message]"
+ if(is_clockwork_cultist(user) && prob(15))
+ user << "[pick(clockwork_cultist_messages)]"
+
+/obj/item/clockwork/component/belligerent_eye
+ name = "belligerent eye"
+ desc = "A brass construct with a rotating red center. It's as though it's looking for something to hurt."
+ icon_state = "belligerent_eye"
+ component_id = "belligerent_eye"
+ cultist_message = "The eye gives you an intensely hateful glare."
+ clockwork_cultist_messages = list("\"...\"", "For a moment, your mind is flooded with extremely violent thoughts.")
+
+/obj/item/clockwork/component/vanguard_cogwheel
+ name = "vanguard cogwheel"
+ desc = "A sturdy brass cog with a faintly glowing blue gem in its center."
+ icon_state = "vanguard_cogwheel"
+ component_id = "vanguard_cogwheel"
+ cultist_message = "\"Pray to your god that we never meet.\""
+ clockwork_cultist_messages = list("\"Be safe, child.\"", "You feel unexplainably comforted.", "\"Never forget: pain is temporary. The Justiciar's glory is eternal.\"")
+
+/obj/item/clockwork/component/guvax_capacitor
+ name = "guvax capacitor"
+ desc = "A curiously cold brass doodad. It seems as though it really doesn't appreciate being held."
+ icon_state = "guvax_capacitor"
+ component_id = "guvax_capacitor"
+ cultist_message = "\"Try not to lose your mind - I'll need it. Heh heh...\""
+ clockwork_cultist_messages = list("\"Disgusting.\"", "\"Well, aren't you an inquisitive fellow?\"", "A foul presence pervades your mind, then vanishes.", "\"The fact that Ratvar has to depend on simpletons like you is appalling.\"")
+
+/obj/item/clockwork/component/replicant_alloy
+ name = "replicant alloy"
+ desc = "A seemingly strong but very malleable chunk of metal. It seems as though it wants to be molded into something greater."
+ icon_state = "replicant_alloy"
+ component_id = "replicant_alloy"
+ cultist_message = "The alloy takes on the appearance of a screaming face for a moment."
+ clockwork_cultist_messages = list("\"There's always something to be done. Get to it.\"", "\"Idle hands are worse than broken ones. Get to work.\"", "A detailed image of Ratvar appears in the alloy for a moment.")
+
+/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment
+ name = "smashed anima fragment"
+ desc = "Shattered chunks of metal. Damaged beyond repair and completely unusable."
+ clockwork_desc = "The sad remains of an anima fragment. Might still be serviceable as a substitute for replicant alloy."
+ icon_state = "smashed_anima_fragment"
+ cultist_message = "The shards vibrate in your hands for a moment."
+ clockwork_cultist_messages = list("\"...still fight...\"", "\"...where am I...?\"", "\"...put me... slab...\"")
+ w_class = 3
+
+/obj/item/clockwork/component/replicant_alloy/fallen_armor
+ name = "fallen armor"
+ desc = "Lifeless chunks of armor. They're designed in a strange way and won't fit on you."
+ clockwork_desc = "The armor from a former clockwork marauder. Might still be serviceable as a substitute for replicant alloy."
+ icon_state = "fallen_armor"
+ cultist_message = "Red flame sputters from the mask's eye before winking out."
+ clockwork_cultist_messages = list("A piece of armor hovers away from the others for a moment.", "Red flame appears in the cuirass before sputtering out.")
+ w_class = 3
+
+/obj/item/clockwork/component/hierophant_ansible
+ name = "hierophant ansible"
+ desc = "Some sort of transmitter? It seems as though it's trying to say something."
+ icon_state = "hierophant_ansible"
+ component_id = "hierophant_ansible"
+ cultist_message = "\"Gur obff nlf vg'f abg ntnvafg gur ehyrf gb xvyy lbh.\""
+ clockwork_cultist_messages = list("\"Rkvyr vf fhpu n'ober. Gurer'f abguvat v'pna uhag va urer.\"", "\"Jung'f xrrcvat lbh? V'jnag gb tb xvyy fbzrguvat.\"", "\"HEHEHEHEHEHEH!\"")
+
+//////////////////////////
+// CLOCKWORK STRUCTURES //
+//////////////////////////
+
+/obj/structure/clockwork
+ name = "meme structure"
+ desc = "Some frog or something, the fuck?"
+ var/clockwork_desc = "This fabled artifact from beyond the stars contains concentrated meme essence." //See above
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "rare_pepe"
+ anchored = 1
+ density = 1
+ opacity = 0
+ var/max_health = 100 //All clockwork structures have health that can be removed via attacks
+ var/health = 100
+ var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station
+
+/obj/structure/clockwork/New()
+ ..()
+ clockwork_construction_value += construction_value
+ all_clockwork_objects += src
+
+/obj/structure/clockwork/Destroy()
+ clockwork_construction_value -= construction_value
+ all_clockwork_objects -= src
+ ..()
+
+/obj/structure/clockwork/examine(mob/user)
+ if((is_clockwork_cultist(user) || isobserver(user)) && clockwork_desc)
+ desc = clockwork_desc
+ ..()
+ desc = initial(desc)
+
+/obj/structure/clockwork/cache //Tinkerer's cache: Stores components for later use.
+ name = "tinkerer's cache"
+ desc = "A large brass container with no visible methods of access."
+ clockwork_desc = "A brass container capable of storing a large amount of components."
+ icon_state = "tinkerers_cache"
+ construction_value = 10
+ var/list/stored_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) //Components in the cache
+
+/obj/structure/clockwork/cache/New()
+ ..()
+ clockwork_caches++
+
+/obj/structure/clockwork/cache/Destroy()
+ clockwork_caches--
+ return ..()
+
+/obj/structure/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
+ if(!is_clockwork_cultist(user))
+ ..()
+ return 0
+ if(istype(I, /obj/item/clockwork/component))
+ var/obj/item/clockwork/component/C = I
+ stored_components[C.component_id]++
+ user << "You add [C] to [src]."
+ user.drop_item()
+ qdel(C)
+ return 1
+ if(istype(I, /obj/item/clockwork/slab))
+ var/obj/item/clockwork/slab/S = I
+ stored_components["belligerent_eye"] += S.stored_components["belligerent_eye"]
+ stored_components["vanguard_cogwheel"] += S.stored_components["vanguard_cogwheel"]
+ stored_components["guvax_capacitor"] += S.stored_components["guvax_capacitor"]
+ stored_components["replicant_alloy"] += S.stored_components["replicant_alloy"]
+ stored_components["hierophant_ansible"] += S.stored_components["hierophant_ansible"]
+ S.stored_components["belligerent_eye"] = 0
+ S.stored_components["vanguard_cogwheel"] = 0
+ S.stored_components["guvax_capacitor"] = 0
+ S.stored_components["replicant_alloy"] = 0
+ S.stored_components["hierophant_ansible"] = 0
+ user.visible_message("[user] empties [S] into [src].", "You offload your slab's components into [src].")
+ return 1
+ if(istype(I, /obj/item/clockwork/daemon_shell))
+ var/component_type
+ switch(alert(user, "Will this daemon produce a specific type of component or produce randomly?.", , "Specific Type", "Random Component"))
+ if("Specific Type")
+ switch(input(user, "Choose a component type.", name) as null|anything in list("Belligerent Eyes", "Vanguard Cogwheels", "Guvax Capacitors", "Replicant Alloys", "Hierophant Ansibles"))
+ if("Belligerent Eyes")
+ component_type = "belligerent_eye"
+ if("Vanguard Cogwheels")
+ component_type = "vanguard_cogwheel"
+ if("Guvax Capacitors")
+ component_type = "guvax_capacitor"
+ if("Replicant Alloys")
+ component_type = "replicant_alloy"
+ if("Hierophant Ansibles")
+ component_type = "hierophant_ansibles"
+ if(!user || !user.canUseTopic(src) || !user.canUseTopic(I))
+ return 0
+ var/obj/item/clockwork/tinkerers_daemon/D = new(src)
+ D.cache = src
+ D.specific_component = component_type
+ user.visible_message("[user] spins the cogwheel on [I] and puts it into [src].", \
+ "You activate the daemon and put it into [src]. It will now produce a component every thirty seconds.")
+ user.drop_item()
+ qdel(I)
+ return 1
+ ..()
+
+/obj/structure/clockwork/cache/attack_hand(mob/user)
+ if(!is_clockwork_cultist(user))
+ return 0
+ var/list/possible_components = list()
+ if(stored_components["belligerent_eye"])
+ possible_components += "Belligerent Eye"
+ if(stored_components["vanguard_cogwheel"])
+ possible_components += "Vanguard Cogwheel"
+ if(stored_components["guvax_capacitor"])
+ possible_components += "Guvax Capacitor"
+ if(stored_components["replicant_alloy"])
+ possible_components += "Replicant Alloy"
+ if(stored_components["hierophant_ansible"])
+ possible_components += "Hierophant Ansible"
+ if(!possible_components.len)
+ user << "[src] is empty!"
+ return 0
+ var/component_to_withdraw = input(user, "Choose a component to withdraw.", name) as null|anything in possible_components
+ if(!user || !user.canUseTopic(src) || !component_to_withdraw)
+ return 0
+ var/obj/item/clockwork/component/the_component
+ switch(component_to_withdraw)
+ if("Belligerent Eye")
+ the_component = new/obj/item/clockwork/component/belligerent_eye(get_turf(src))
+ if("Vanguard Cogwheel")
+ the_component = new/obj/item/clockwork/component/vanguard_cogwheel(get_turf(src))
+ if("Guvax Capacitor")
+ the_component = new/obj/item/clockwork/component/guvax_capacitor(get_turf(src))
+ if("Replicant Alloy")
+ the_component = new/obj/item/clockwork/component/replicant_alloy(get_turf(src))
+ if("Hierophant Ansible")
+ the_component = new/obj/item/clockwork/component/hierophant_ansible(get_turf(src))
+ if(the_component)
+ user.visible_message("[user] withdraws [the_component] from [src].", "You withdraw [the_component] from [src].")
+ user.put_in_hands(the_component)
+ return 1
+
+/obj/structure/clockwork/cache/examine(mob/user)
+ ..()
+ if(is_clockwork_cultist(user) || isobserver(user))
+ user << "Stored components:"
+ user << "Belligerent Eyes: [stored_components["belligerent_eye"]]"
+ user << "Vanguard Cogwheels: [stored_components["vanguard_cogwheel"]]"
+ user << "Guvax Capacitors: [stored_components["guvax_capacitor"]]"
+ user << "Replicant Alloys: [stored_components["replicant_alloy"]]"
+ user << "Hierophant Ansibles: [stored_components["hierophant_ansible"]]"
+
+/obj/structure/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
+ name = "ocular warden"
+ desc = "A large brass eye with tendrils trailing below it and a wide red iris."
+ clockwork_desc = "A stalwart turret that will deal sustained damage to any non-faithful it sees."
+ icon_state = "ocular_warden"
+ construction_value = 15
+ var/damage_per_tick = 1
+ var/sight_range = 2
+ var/mob/living/target
+
+/obj/structure/clockwork/ocular_warden/New()
+ ..()
+ SSfastprocess.processing += src
+
+/obj/structure/clockwork/ocular_warden/Destroy()
+ SSfastprocess.processing -= src
+ return ..()
+
+/obj/structure/clockwork/ocular_warden/examine(mob/user)
+ ..()
+ user << "[target ? "It's fixated on [target]" : "Its gaze is wandering aimlessly"]."
+
+/obj/structure/clockwork/ocular_warden/process()
+ if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned
+ damage_per_tick = 10
+ sight_range = 5
+ if(target)
+ if(target.stat || get_dist(get_turf(src), get_turf(target)) > sight_range)
+ lose_target()
+ else
+ target.adjustFireLoss(!iscultist(target) ? damage_per_tick : damage_per_tick * 2) //Nar-Sian cultists take additional damage
+ if(ratvar_awakens)
+ target.adjust_fire_stacks(damage_per_tick)
+ target.IgniteMob()
+ dir = get_dir(get_turf(src), get_turf(target))
+ else
+ if(!acquire_nearby_target() && prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
+ var/list/idle_messages = list("[src] sulkily glares around.", "[src] lazily drifts from side to side.", "[src] looks around for something to burn.", "[src] slowly turns in circles.")
+ if(prob(50))
+ visible_message("[pick(idle_messages)]")
+ else
+ dir = pick(NORTH, EAST, SOUTH, WEST) //Random rotation
+
+/obj/structure/clockwork/ocular_warden/proc/acquire_nearby_target()
+ var/list/possible_targets = list()
+ for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind
+ if(!is_clockwork_cultist(L) && !L.stat && L.mind)
+ possible_targets += L
+ if(!possible_targets.len)
+ return 0
+ target = pick(possible_targets)
+ visible_message("[src] swivels to face [target]!")
+ target << "\"I SEE YOU!\"\n[src]'s gaze [ratvar_awakens ? "melts you alive" : "burns you"]!"
+ return 1
+
+/obj/structure/clockwork/ocular_warden/proc/lose_target()
+ if(!target)
+ return 0
+ target = null
+ visible_message("[src] settles and seems almost disappointed.")
+ return 1
+
+/obj/structure/clockwork/anima_fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct.
+ name = "anima fragment"
+ desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power."
+ clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct."
+ icon_state = "anima_fragment"
+ construction_value = 0
+ anchored = 0
+ density = 0
+
+/obj/structure/clockwork/anima_fragment/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/device/mmi/posibrain/soul_vessel))
+ if(!is_clockwork_cultist(user))
+ ..()
+ return 0
+ var/obj/item/device/mmi/posibrain/soul_vessel/S = I
+ if(!S.brainmob)
+ user << "[S] hasn't trapped a spirit! Turn it on first."
+ return 0
+ if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind))
+ user << "[S]'s trapped spirit appears inactive!"
+ return 0
+ user.visible_message("[user] clicks [S] into place on [src].", "You insert [S] into [src]. It whirs and begins to rise.")
+ var/mob/living/simple_animal/hostile/anima_fragment/A = new(get_turf(src))
+ S.brainmob.mind.transfer_to(A)
+ add_clockwork_cultist(A, TRUE)
+ A << A.playstyle_string
+ user.drop_item()
+ qdel(S)
+ qdel(src)
+ return 1
+ ..()
+
+/obj/structure/clockwork/interdiction_lens //Interdiction lens: A powerful artifact that can massively disrupt electronics. Five-minute cooldown between uses.
+ name = "interdiction lens"
+ desc = "An ominous, double-pronged brass obelisk. There's a strange gemstone clasped between the pincers."
+ clockwork_desc = "A powerful obelisk that can devastate certain electronics. It needs to recharge between uses."
+ icon_state = "interdiction_lens"
+ construction_value = 25
+ var/recharging = FALSE //If the lens is still recharging its energy
+
+/obj/structure/clockwork/interdiction_lens/examine(mob/user)
+ ..()
+ user << "Its gemstone [recharging ? "has been breached by writhing tendrils of blackness that cover the obelisk" : "vibrates in place and thrums with power"],"
+
+/obj/structure/clockwork/interdiction_lens/attack_hand(mob/living/user)
+ if(user.canUseTopic(src))
+ disrupt(user)
+
+/obj/structure/clockwork/interdiction_lens/proc/disrupt(mob/living/user)
+ if(!user || !is_clockwork_cultist(user))
+ return 0
+ if(recharging)
+ user << "As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back."
+ return 0
+ user.visible_message("[user] places their hand on [src]' gemstone...", "You place your hand on the gemstone...")
+ var/target = input(user, "Power flows through you. Choose where to direct it.", "Interdiction Lens") as null|anything in list("Disrupt Telecommunications", "Disable Cameras", "Disable Cyborgs")
+ if(!user.canUseTopic(src) || !target)
+ user.visible_message("[user] pulls their hand back.", "On second thought, maybe not right now.")
+ return 0
+ user.visible_message("Violet tendrils engulf [user]'s arm as the gemstone glows with furious energy!", \
+ "A mass of violet tendrils cover your arm as [src] unleashes a blast of power!")
+ user.notransform = TRUE
+ icon_state = "[initial(icon_state)]_active"
+ recharging = TRUE
+ sleep(30)
+ switch(target)
+ if("Disrupt Telecommunications")
+ for(var/obj/machinery/telecomms/hub/H in telecomms_list)
+ for(var/mob/M in range(7, H))
+ M << "You sense a strange force pass through you..."
+ H.visible_message("The lights on [H] flare a blinding yellow before falling dark!")
+ H.emp_act(1)
+ if("Disable Cameras")
+ for(var/obj/machinery/camera/C in cameranet.cameras)
+ C.emp_act(1)
+ for(var/mob/living/silicon/ai/A in living_mob_list)
+ A << "Massive energy surge detected. All cameras offline."
+ A << 'sound/machines/warning-buzzer.ogg'
+ if("Disable Cyborgs")
+ for(var/mob/living/silicon/robot/R in living_mob_list) //Doesn't include AIs, for obvious reasons
+ if(is_clockwork_cultist(R) || R.stat) //Doesn't affect already-offline cyborgs
+ continue
+ R.visible_message("[R] shuts down with no warning!", \
+ "Massive emergy surge detected. All systems offline. Initiating reboot sequence..")
+ playsound(R, 'sound/machines/warning-buzzer.ogg', 50, 1)
+ R.Weaken(30)
+ user.visible_message("The tendrils around [user]'s arm turn to an onyx black and wither away!", \
+ "The tendrils around your arm turn a horrible black and sting your skin before they shrivel away.")
+ user.notransform = FALSE
+ if(!src)
+ return 0
+ flick("[initial(icon_state)]_discharged", src)
+ icon_state = "[initial(icon_state)]_recharging"
+ spawn(3000) //5 minutes
+ if(!src)
+ return 0
+ visible_message("The writhing tendrils return to the gemstone, which begins to glow with power.")
+ flick("[initial(icon_state)]_recharged", src)
+ icon_state = initial(icon_state)
+ recharging = FALSE
+ return 1
+
+/obj/structure/clockwork/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
+ name = "mending motor"
+ desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
+ clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants."
+ icon_state = "mending_motor"
+ construction_value = 20
+ var/stored_alloy = 0
+ var/max_alloy = 150
+ var/uses_alloy = TRUE
+ var/active = TRUE
+
+/obj/structure/clockwork/mending_motor/prefilled
+ stored_alloy = 30
+
+/obj/structure/clockwork/mending_motor/New()
+ ..()
+ SSobj.processing += src
+ toggle() //Toggles off as soon as it's created, but starts online for reasons
+
+/obj/structure/clockwork/mending_motor/Destroy()
+ SSobj.processing -= src
+ ..()
+
+/obj/structure/clockwork/mending_motor/examine(mob/user)
+ ..()
+ if(is_clockwork_cultist(user) || isobserver(user))
+ user << "It has [stored_alloy]/[max_alloy] units of replicant alloy."
+
+/obj/structure/clockwork/mending_motor/process()
+ if(!active)
+ return 0
+ if(!stored_alloy && uses_alloy)
+ visible_message("[src] emits an airy chuckling sound and falls dark!")
+ toggle()
+ return 0
+ for(var/mob/living/simple_animal/hostile/anima_fragment/F in range(5, src))
+ if(F.health == F.maxHealth || F.stat)
+ continue
+ F.adjustBruteLoss(-15)
+ if(uses_alloy)
+ stored_alloy = max(0, stored_alloy - 2)
+ for(var/mob/living/simple_animal/hostile/clockwork_marauder/M in range(5, src))
+ if(M.health == M.maxHealth || M.stat)
+ continue
+ M.adjustBruteLoss(-M.maxHealth) //Instant because marauders don't usually take health damage
+ M.fatigue = max(0, M.fatigue - 15)
+ if(uses_alloy)
+ stored_alloy = max(0, stored_alloy - 2)
+ for(var/mob/living/silicon/S in range(5, src))
+ if(S.health == S.maxHealth || S.stat == DEAD || !is_clockwork_cultist(S))
+ continue
+ S.adjustBruteLoss(-25)
+ S.adjustFireLoss(-25)
+ if(uses_alloy)
+ stored_alloy = max(0, stored_alloy - 5) //Much higher cost because silicons are much more useful
+
+/obj/structure/clockwork/mending_motor/attack_hand(mob/living/user)
+ if(user.canUseTopic(src)) //Unnecessary?
+ if(!stored_alloy)
+ user << "[src] needs more replicant alloy to function!"
+ return 0
+ toggle(user)
+
+/obj/structure/clockwork/mending_motor/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_clockwork_cultist(user))
+ if(stored_alloy + 10 > max_alloy)
+ user << "[src] is too full to accept any more alloy!"
+ return 0
+ user.whisper("Genafzhgr vagb jngre.")
+ user.visible_message("[user] liquifies [I] and pours it onto [src].", \
+ "You liquify [src] and pour it onto [src], which transfers the alloy into its reserves.")
+ stored_alloy = min(max(0, stored_alloy + 10), max_alloy)
+ user.drop_item()
+ qdel(I)
+ return 1
+ ..()
+
+/obj/structure/clockwork/mending_motor/proc/toggle(mob/living/user)
+ active = !active
+ if(user && is_clockwork_cultist(user))
+ user.visible_message("[user] [active ? "en" : "dis"]ables [src].", "You [active ? "en" : "dis"]able [src].")
+ if(active)
+ icon_state = initial(icon_state)
+ else
+ icon_state = "[initial(icon_state)]_inactive"
+
+///////////////////////
+// CLOCKWORK EFFECTS //
+///////////////////////
+
+/obj/effect/clockwork
+ name = "meme machine"
+ desc = "Still don't know what it is."
+ var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description
+ icon = 'icons/effects/clockwork_effects.dmi'
+ icon_state = "ratvars_flame"
+ anchored = 1
+ density = 0
+ opacity = 0
+
+/obj/effect/clockwork/New()
+ ..()
+ all_clockwork_objects += src
+
+/obj/effect/clockwork/Destroy()
+ all_clockwork_objects -= src
+ return ..()
+
+/obj/effect/clockwork/examine(mob/user)
+ if(is_clockwork_cultist(user) && clockwork_desc)
+ desc = clockwork_desc
+ ..()
+ desc = initial(desc)
+
+/obj/effect/clockwork/judicial_marker //Judicial marker: Created by the judicial visor. After four seconds, stuns any non-servants nearby and damages Nar-Sian cultists.
+ name = "judicial marker"
+ desc = "You get the feeling that you shouldn't be standing here."
+ clockwork_desc = "A sigil that will soon erupt and smite any unenlightened nearby."
+ icon = 'icons/effects/96x96.dmi'
+ pixel_x = -30
+ pixel_y = -30
+ layer = 2.01
+
+/obj/effect/clockwork/judicial_marker/New()
+ ..()
+ flick("judicial_marker", src)
+ spawn(25) //Utilizes spawns due to how it works with Ratvar's flame
+ flick("judicial_explosion", src)
+ spawn(15)
+ for(var/mob/living/L in range(1, src))
+ if(is_clockwork_cultist(L))
+ continue
+ if(!iscultist(L))
+ L << "[!issilicon(L) ? "An unseen force slams you into the ground!" : "ERROR: Motor servos disabled by external source!"]"
+ L.Weaken(8)
+ else
+ L << "\"Keep an eye out, filth.\"\n[!issilicon(L) ? "An unseen force piledrives you into the ground!" : "ERROR: Motor servos damaged by external source!"]"
+ L.Weaken(10)
+ L.adjustBruteLoss(10)
+ qdel(src)
+ return 1
+
+/obj/effect/clockwork/spatial_gateway //Spatial gateway: A one-way rift to another location.
+ name = "spatial gateway"
+ desc = "A gently thrumming tear in reality."
+ clockwork_desc = "A gateway in reality. It can either send or receive, but not both."
+ icon_state = "spatial_gateway"
+ density = 1
+ var/sender = TRUE //If this gateway is made for sending, not receiving
+ var/lifetime = 25 //How many deciseconds this portal will last
+ var/uses = 1 //How many objects or mobs can go through the portal
+ var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
+
+/obj/effect/clockwork/spatial_gateway/New()
+ ..()
+ spawn(1)
+ if(!linked_gateway)
+ qdel(src)
+ return 0
+ else
+ if(linked_gateway.sender == sender)
+ linked_gateway.sender = !sender
+ spawn(lifetime)
+ if(src)
+ qdel(src)
+
+/obj/effect/clockwork/spatial_gateway/Destroy()
+ visible_message("[src] flickers and closes!")
+ animate(src, transform = matrix() - matrix(), time = 10)
+ spawn(10)
+ ..()
+
+/obj/effect/clockwork/spatial_gateway/examine(mob/user)
+ ..()
+ if(is_clockwork_cultist(user) || isobserver(user))
+ user << "This gateway can only [sender ? "send" : "receive"] objects."
+
+/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user)
+ if(!user.canUseTopic(src))
+ return 0
+ user.visible_message("[user] climbs through [src]!", "You brace yourself and step through [src]...")
+ pass_through_gateway(user)
+ return 1
+
+/obj/effect/clockwork/spatial_gateway/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weapon/nullrod))
+ user.visible_message("[user] dispels [src] with [I]!", "You close [src] with [I]!")
+ qdel(linked_gateway)
+ qdel(src)
+ return 1
+ if(istype(I, /obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = I
+ if(!G.affecting)
+ return 0
+ user.visible_message("[user] shoves [G.affecting] into [src]!", "You shove [G.affecting] into [src]!")
+ pass_through_gateway(G.affecting)
+ qdel(G)
+ return 1
+ if(user.drop_item())
+ pass_through_gateway(I)
+ ..()
+
+/obj/effect/clockwork/spatial_gateway/Bumped(atom/A)
+ ..()
+ if(isliving(A) || istype(A, /obj/item))
+ pass_through_gateway(A)
+
+/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A)
+ if(!linked_gateway)
+ qdel(src)
+ return 0
+ if(!sender)
+ visible_message("[A] bounces off of [src]!")
+ return 0
+ if(isliving(A))
+ var/mob/living/user = A
+ user << "You pass through [src] and appear elsewhere!"
+ linked_gateway.visible_message("A shape appears in [linked_gateway] before emerging!")
+ playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1)
+ transform = matrix() * 1.5
+ animate(src, transform = matrix() / 1.5, time = 10)
+ linked_gateway.transform = matrix() * 1.5
+ animate(linked_gateway, transform = matrix() / 1.5, time = 10)
+ if(ismob(A))
+ var/mob/M = A
+ M.forceMove(get_turf(linked_gateway))
+ else
+ A.loc = get_turf(linked_gateway)
+ uses = max(0, uses - 1)
+ linked_gateway.uses = max(0, uses - 1)
+ spawn(10)
+ if(!uses)
+ qdel(src)
+ qdel(linked_gateway)
+ return 1
+
+/obj/effect/clockwork/general_marker
+ name = "general marker"
+ desc = "Some big guy."
+ clockwork_desc = "One of Ratvar's generals."
+ alpha = 200
+ layer = 10
+
+/obj/effect/clockwork/general_marker/New()
+ ..()
+ playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
+ animate(src, alpha = 0, time = 10)
+ spawn(10)
+ qdel(src)
+
+/obj/effect/clockwork/general_marker/nezbere
+ name = "Nezbere, the Brass Eidolon"
+ desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you."
+ clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain."
+ icon = 'icons/effects/340x428.dmi'
+ icon_state = "nezbere"
+ pixel_x = -154
+ pixel_y = -192
+
+/obj/effect/clockwork/general_marker/sevtug
+ name = "Sevtug, the Formless Pariah"
+ desc = "A sinister cloud of purple energy. Looking at it gives you a headache."
+ clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies."
+ icon = 'icons/effects/211x247.dmi'
+ icon_state = "sevtug"
+ pixel_x = -113
+ pixel_y = -131
+
+/obj/effect/clockwork/general_marker/nzcrentr
+ name = "Nzcrentr, the Forgotten Arbiter"
+ desc = "A terrifying war machine crackling with limitless energy."
+ clockwork_desc = "One of Ratvar's four generals. Nzcrentr is the result of Neovgre - Nezbere's finest war machine, commandeerable only be a mortal - fusing with its pilot and driving her \
+ insane. Nzcrentr seeks out any and all sentient life to slaughter it for sport."
+ icon = 'icons/effects/254x361.dmi'
+ icon_state = "nzcrentr"
+ pixel_x = -110
+ pixel_y = -163
+
+/obj/effect/clockwork/general_marker/inathneq
+ name = "Inath-Neq, the Resonant Cogwheel"
+ desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring."
+ clockwork_desc = "One of Ratvar's four generals. Before her current form, Inath-Neq was a powerful warrior priestess commanding the Resonant Cogs, a sect of Ratvarian warriors renowned for \
+ their prowess. After a lost battle with Nar-Sian cultists, Inath-Neq was struck down and stated in her dying breath, \
+ \"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-Neq an eternal body and \
+ merged her soul with those of the Cogs slain with her on the battlefield."
+ icon = 'icons/effects/187x381.dmi'
+ icon_state = "inath-neq"
+ pixel_x = -91
+ pixel_y = -199
+
+/obj/effect/clockwork/sigil //Sigils: Rune-like markings on the ground with various effects.
+ name = "sigil"
+ desc = "A strange set of markings drawn on the ground."
+ clockwork_desc = "A sigil of some purpose."
+ icon_state = "sigil"
+ alpha = 25
+ var/affects_servants = FALSE
+
+/obj/effect/clockwork/sigil/attack_hand(mob/user)
+ if(iscarbon(user) && !user.stat && user.a_intent == "harm")
+ user.visible_message("[user] stamps out [src]!", "You stomp on [src], scattering it into thousands of particles.")
+ qdel(src)
+ return 1
+ ..()
+
+/obj/effect/clockwork/sigil/Crossed(atom/movable/AM)
+ if(isliving(AM))
+ var/mob/living/L = AM
+ if(!L.stat)
+ if(!is_clockwork_cultist(L) || (is_clockwork_cultist(L) && affects_servants))
+ sigil_effects(L)
+ return 1
+ ..()
+
+/obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L)
+
+/obj/effect/clockwork/sigil/transgression //Sigil of Transgression: Stuns and flashes the first non-servant to walk on it. Nar-Sian cultists are damaged and knocked down.
+ name = "dull sigil"
+ desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
+ icon = 'icons/effects/clockwork_effects.dmi'
+ clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down."
+ color = rgb(255, 255, 0)
+
+/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
+ visible_message("[src] appears in a burst of light!")
+ for(var/mob/living/M in viewers(5, src))
+ if(!is_clockwork_cultist(M))
+ M.flash_eyes()
+ if(!iscultist(L))
+ L << "An unseen force holds you in place!"
+ else
+ L << "\"Watch your step, wretch.\""
+ L.adjustBruteLoss(10)
+ L.Weaken(4)
+ L.Stun(4)
+ qdel(src)
+ return 1
+
+/obj/effect/clockwork/sigil/submission //Sigil of Submission: After a short time, converts any non-servant standing on it. Knocks down and silences them for thirty seconds afterwards.
+ name = "ominous sigil"
+ desc = "A brilliant golden sigil. Something about it really bothers you."
+ clockwork_desc = "A sigil that will enslave the first person to cross it, provided they do not move and stand still for a brief time."
+ color = rgb(255, 255, 0)
+ alpha = 255
+
+/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
+ visible_message("[src] begins to glow a piercing magenta!")
+ animate(src, color = rgb(255, 0, 150), time = 30)
+ sleep(30)
+ if(get_turf(L) != get_turf(src))
+ animate(src, color = initial(color), time = 30)
+ return 0
+ L << "\"You belong to me now.\""
+ add_clockwork_cultist(L)
+ L.Weaken(30) //Completely defenseless for thirty seconds - mainly to give them time to read over the information they've just been presented with
+ L.Stun(30)
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ C.silent += 30
+ qdel(src)
+ return 1
+
+/obj/effect/clockwork/sigil/transmission
+ name = "suspicious sigil"
+ desc = "A barely-visible sigil. Things seem a bit quieter around it."
+ clockwork_desc = "A sigil that will listen for and transmit anything it hears."
+ color = rgb(75, 75, 75)
+ alpha = 50
+ flags = HEAR
+ languages = ALL
+
+/obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L)
+ for(var/mob/M in mob_list)
+ if(is_clockwork_cultist(M) || isobserver(M))
+ M << "Sigil of Transmission in [get_area(src)] crossed by [L.name]."
+ return 0
+
+/obj/effect/clockwork/sigil/transmission/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
+ if(!message || !speaker)
+ return 0
+ var/parsed_message = "(Sigil of Tranmission in [get_area(src)]): [message]"
+ for(var/mob/M in mob_list)
+ if(is_clockwork_cultist(M) || isobserver(M))
+ M << parsed_message
diff --git a/code/game/gamemodes/clock_cult/clock_ratvar.dm b/code/game/gamemodes/clock_cult/clock_ratvar.dm
new file mode 100644
index 00000000000..2b33fa8f82f
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_ratvar.dm
@@ -0,0 +1,198 @@
+/obj/structure/clockwork/massive //For objects that are typically very large
+ name = "massive construct"
+ desc = "A very large construction."
+ layer = 10
+
+/obj/structure/clockwork/massive/celestial_gateway //The gateway to Reebe, from which Ratvar emerges
+ name = "Gateway to the Celestial Derelict"
+ desc = "A massive, thrumming rip in spacetime."
+ clockwork_desc = "A portal to the Celestial Derelict. Massive and intimidating, it is the only thing that can both transport Ratvar and withstand the massive amount of energy he emits."
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "clockwork_gateway_charging"
+ pixel_x = -30
+ pixel_y = -30
+ var/progress_in_seconds = 0 //Once this reaches 300, it's game over
+ var/purpose_fulfilled = FALSE
+ var/first_sound_played = FALSE
+ var/second_sound_played = FALSE
+ var/third_sound_played = FALSE
+
+/obj/structure/clockwork/massive/celestial_gateway/New()
+ ..()
+ SSobj.processing += src
+ for(var/mob/M in mob_list)
+ if(is_clockwork_cultist(M) || isobserver(M))
+ M << "A gateway to the Celestial Derelict has been created in [get_area(src)]!"
+
+/obj/structure/clockwork/massive/celestial_gateway/Destroy()
+ SSobj.processing -= src
+ if(!purpose_fulfilled)
+ for(var/mob/M in mob_list)
+ if(is_clockwork_cultist(M) || isobserver(M))
+ M << "A gateway to the Celestial Derelict has fallen at [get_area(src)]!"
+ world << sound(null, 0, channel = 8)
+ ..()
+
+/obj/structure/clockwork/massive/celestial_gateway/process()
+ if(prob(5))
+ for(var/mob/M in mob_list)
+ M << "You hear otherworldly sounds from the [dir2text(get_dir(get_turf(M), get_turf(src)))]..."
+ progress_in_seconds++
+ switch(progress_in_seconds)
+ if(-INFINITY to 100)
+ if(!first_sound_played)
+ world << sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = 8, volume = 50)
+ first_sound_played = TRUE
+ icon_state = "clockwork_gateway_charging"
+ if(100 to 250)
+ if(!second_sound_played)
+ world << sound('sound/effects/clockcult_gateway_active.ogg', 1, channel = 8, volume = 50)
+ second_sound_played = TRUE
+ icon_state = "clockwork_gateway_active"
+ if(250 to 300)
+ if(!third_sound_played)
+ world << sound('sound/effects/clockcult_gateway_closing.ogg', 1, channel = 8, volume = 50)
+ third_sound_played = TRUE
+ icon_state = "clockwork_gateway_closing"
+ if(300 to INFINITY)
+ if(!purpose_fulfilled)
+ purpose_fulfilled = TRUE
+ animate(src, transform = matrix()*1.5, time = 136)
+ world << sound('sound/effects/ratvar_rises.ogg', 0, channel = 8) //End the sounds
+ sleep(136)
+ new/obj/structure/clockwork/massive/ratvar(get_turf(src))
+ qdel(src)
+
+/obj/structure/clockwork/massive/celestial_gateway/examine(mob/user)
+ ..()
+ if(is_clockwork_cultist(user))
+ var/arrival_text = "IMMINENT"
+ if(300 - progress_in_seconds > 0)
+ arrival_text = "[max(300 - progress_in_seconds, 0)]s"
+ user << "Seconds until Ratvar's arrival: [arrival_text]"
+ switch(progress_in_seconds)
+ if(-INFINITY to 100)
+ user << "It's still opening."
+ if(100 to 250)
+ user << "It's reached the Celestial Derelict and is drawing power from it."
+ if(250 to INFINITY)
+ user << "Ratvar is coming through the gateway!"
+ else
+ switch(progress_in_seconds)
+ if(-INFINITY to 100)
+ user << "It's a swirling mass of blackness."
+ if(100 to 250)
+ user << "It seems to be leading somewhere."
+ if(250 to INFINITY)
+ user << "Something is coming through!"
+
+/obj/structure/clockwork/massive/ratvar
+ name = "Ratvar"
+ desc = "What is what is what are what real what is all a lie all a lie it's all a lie why how can what is"
+ clockwork_desc = "Ratvar, the Clockwork Justiciar, your master eternal."
+ icon = 'icons/effects/400x400.dmi'
+ icon_state = "ratvar"
+ pixel_x = -175
+ pixel_y = -175
+ var/mob/living/prey //Whoever Ratvar is chasing
+ var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
+
+/obj/structure/clockwork/massive/ratvar/New()
+ ..()
+ SSobj.processing += src
+ flick("ratvar_spawn_anim", src)
+ world << "\"FREE AT LAST!\""
+ ratvar_awakens = TRUE
+
+/obj/structure/clockwork/massive/ratvar/Destroy()
+ SSobj.processing -= src
+ world << "\"NO! I will not... be... banished... again...\""
+ ratvar_awakens = FALSE
+ ..()
+
+/obj/structure/clockwork/massive/ratvar/process()
+ for(var/atom/A in range(7, src))
+ A.ratvar_act()
+ if(clashing) //Doesn't move during a clash
+ return 0
+ var/dir_to_step_in = pick(cardinal)
+ if(!prey)
+ var/list/meals = list()
+ for(var/mob/living/L in living_mob_list)
+ if(L.z == z && !is_clockwork_cultist(L) && L.mind)
+ meals += L
+ if(meals.len)
+ prey = pick(meals)
+ prey << "\"You will do.\"\n\
+ Something very large and very malevolent begins lumbering its way towards you..."
+ else
+ if(prob(10) || prey.stat == DEAD || is_clockwork_cultist(prey) || prey.z != z)
+ prey << "\"How dull. Leave me.\"\n\
+ You feel tremendous relief as a set of horrible eyes loses sight of you..."
+ prey = null
+ else
+ if(prob(75))
+ dir_to_step_in = get_dir(src, prey)
+ for(var/i in 1 to 2)
+ loc = get_step(src, dir_to_step_in)
+
+/obj/structure/clockwork/massive/ratvar/narsie_act()
+ if(clashing)
+ return 0
+ clashing = TRUE
+ world << "\"[pick("BLOOD GOD!!!", "NAR-SIE!!!", "AT LAST, YOUR TIME HAS COME!")]\""
+ world << "\"Ratvar?! Sas'so forbica! Faras desdae!\""
+ for(var/obj/singularity/narsie/N in range(7, src))
+ clash_of_the_titans(N) //IT'S TIME FOR THE BATTLE OF THE AGES
+ N.clashing = TRUE
+ break
+ return 1
+
+/obj/structure/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie) //IT'S TIME FOR A BATTLE OF THE ELDER GODS
+ var/winner = "Undeclared"
+ while(TRUE)
+ world << 'sound/magic/clockwork/ratvar_attack.ogg'
+ sleep(5.2)
+ for(var/mob/M in mob_list)
+ if(M.client)
+ M.client.color = rgb(75, 50, 0)
+ spawn(1)
+ M.client.color = rgb(150, 100, 0)
+ spawn(1)
+ M.client.color = initial(M.client.color)
+ shake_camera(M, 4, 3)
+ var/r_success_modifier = (ticker.mode.servants_of_ratvar.len * 2) //2% for each cultist
+ var/n_success_modifier = (ticker.mode.cult.len * 2)
+ if(prob(10 + r_success_modifier)) //Base 10% chance plus the success modifier
+ winner = "Ratvar"
+ break
+ sleep(rand(2,5))
+ world << 'sound/magic/clockwork/narsie_attack.ogg'
+ sleep(7.4)
+ for(var/mob/M in mob_list)
+ if(M.client)
+ M.client.color = rgb(150, 0, 0)
+ spawn(1)
+ M.client.color = rgb(200, 0, 0)
+ spawn(1)
+ M.client.color = initial(M.client.color)
+ shake_camera(M, 4, 3)
+ if(prob(10 + n_success_modifier))
+ winner = "Nar-Sie"
+ break
+ switch(winner)
+ if("Ratvar")
+ world << "\"[pick("DIE! DIE! DIE!", "RAAAAAAAAAAAAAHH!", "FILTH!!!", "SUFFER!!!", "ROT FOR CENTURES AS I HAVE!")]\""
+ world << "\"[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\""
+ world << 'sound/magic/clockwork/anima_fragment_attack.ogg'
+ world << 'sound/magic/demon_dies.ogg'
+ clashing = FALSE
+ qdel(narsie)
+ return 1
+ if("Nar-Sie")
+ world << "\"[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]\"" //Broken English
+ world << 'sound/magic/demon_attack1.ogg'
+ world << 'sound/magic/clockwork/anima_fragment_death.ogg'
+ narsie.clashing = FALSE
+ qdel(src)
+ return 1
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
new file mode 100644
index 00000000000..31b25018393
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -0,0 +1,941 @@
+/*
+Tiers and Requirements
+
+Pieces of scripture require certain follower counts, contruction value, and active caches in order to recite.
+Drivers: Unlocked by default
+Scripts: 5 servants and a cache
+Applications: 8 servants, 3 caches, and 50 CV
+Revenant: 10 servants and 100 CV
+Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
+*/
+
+/datum/clockwork_scripture
+ var/name = "scripture"
+ var/desc = "Ancient Ratvarian lore. This piece seems particularly mundane."
+ var/list/invocations = list() //Spoken over time in the ancient language of Ratvar. See clock_unsorted.dm for more details on the language and how to make it.
+ var/channel_time = 10 //In seconds, how long a ritual takes to chant
+ var/list/required_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) //Components required
+ var/list/consumed_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) //Components consumed
+ var/obj/item/clockwork/slab/slab //The parent clockwork slab
+ var/mob/living/invoker //The slab's holder
+ var/whispered = FALSE //If the invocation is whispered rather than spoken aloud
+ var/consumed_component_override = FALSE //If consumed components are unique to a scripture regardless of tier
+ var/invokers_required = 1 //How many people are required, assuming that a scripture requires multiple
+ var/multiple_invokers_used = FALSE //If scripture requires more than one invoker
+ var/multiple_invokers_optional = FALSE //If scripture can have multiple invokers to bolster its effects
+ var/tier = SCRIPTURE_PERIPHERAL
+
+/datum/clockwork_scripture/New()
+ ..()
+ if(tier < SCRIPTURE_DRIVER && !consumed_component_override) //Anything above a driver consumes components
+ consumed_components = required_components
+
+/datum/clockwork_scripture/proc/run_scripture()
+ if(can_recite() && check_special_requirements())
+ slab.busy = "Invocation ([name]) in progress"
+ if(recital())
+ slab.busy = null
+ if(scripture_effects() && (!ratvar_awakens && !slab.no_cost))
+ for(var/i in required_components)
+ if(tier <= SCRIPTURE_DRIVER || consumed_component_override)
+ slab.stored_components[i] -= consumed_components[i]
+ else
+ slab.stored_components[i] -= required_components[i]
+ if(slab)
+ slab.busy = null
+ qdel(src)
+ return 1
+
+/datum/clockwork_scripture/proc/can_recite() //If the words can be spoken
+ if(!ticker || !ticker.mode || !slab || !invoker)
+ return 0
+ if(!invoker.can_speak_vocal())
+ invoker << "You are unable to speak the words of the scripture!"
+ return 0
+ if(!ratvar_awakens && !slab.no_cost)
+ for(var/i in required_components)
+ if(slab.stored_components[i] < required_components[i])
+ invoker << "You lack the components to recite this piece of scripture! Check Recollection for component costs."
+ return 0
+ if(multiple_invokers_used && !multiple_invokers_optional)
+ var/nearby_servants = 0
+ for(var/mob/living/L in range(1, invoker))
+ nearby_servants++
+ if(nearby_servants < invokers_required)
+ invoker << "There aren't enough servants nearby ([nearby_servants]/[invokers_required])!"
+ return 0
+ return 1
+
+/datum/clockwork_scripture/proc/check_special_requirements() //Special requirements for scriptures
+ return 1
+
+/datum/clockwork_scripture/proc/recital() //The process of speaking the words
+ if(!channel_time && invocations.len)
+ if(multiple_invokers_used)
+ for(var/mob/living/L in range(1, invoker))
+ if(is_clockwork_cultist(L))
+ for(var/invocation in invocations)
+ if(!whispered)
+ L.say(invocation)
+ else
+ L.whisper(invocation)
+ else
+ for(var/invocation in invocations)
+ if(!whispered)
+ invoker.say(invocation)
+ else
+ invoker.whisper(invocation)
+ invoker << "You [channel_time <= 0 ? "recite" : "begin reciting"] a piece of scripture entitled \"[name]\"."
+ if(!channel_time)
+ return 1
+ for(var/invocation in invocations)
+ if(!do_after(invoker, channel_time / invocations.len, target = invoker))
+ slab.busy = null
+ return 0
+ if(!whispered)
+ invoker.say(invocation)
+ else
+ invoker.whisper(invocation)
+ return 1
+
+/datum/clockwork_scripture/proc/scripture_effects() //The actual effects of the recital after its conclusion
+
+
+
+/datum/clockwork_scripture/channeled //Channeled scripture begins instantly but runs constantly
+ var/chant_invocation = "NLL YZNB" //"AYY LMAO"
+ var/chant_amount = 5 //Times the chant is spoken
+ var/chant_interval = 10 //Amount of deciseconds between times the chant is actually spoken aloud
+
+/datum/clockwork_scripture/channeled/scripture_effects()
+ for(var/i in 1 to chant_amount)
+ if(!can_recite())
+ break
+ if(!do_after(invoker, chant_interval, target = invoker))
+ break
+ if(!whispered)
+ invoker.say(chant_invocation)
+ else
+ invoker.whisper(chant_invocation)
+ chant_effects()
+ if(invoker && slab)
+ invoker << "You cease your chant."
+ chant_end_effects()
+ return 1
+
+/datum/clockwork_scripture/channeled/proc/chant_effects() //The chant's periodic effects
+/datum/clockwork_scripture/channeled/proc/chant_end_effects() //The chant's effect upon ending
+
+
+
+/datum/clockwork_scripture/create_object //Creates an object at the invoker's feet
+ var/object_path = /obj/item/clockwork //The path of the object created
+ var/creator_message = "You create a meme." //Shown to the invoker
+ var/observer_message
+
+/datum/clockwork_scripture/create_object/scripture_effects()
+ if(creator_message && observer_message)
+ invoker.visible_message(observer_message, creator_message)
+ else if(creator_message)
+ invoker << creator_message
+ new object_path (get_turf(invoker))
+
+
+
+/datum/clockwork_scripture/targeted //Accepts a name and affects that target
+ var/target_name //The inputted name, used to find targets
+ var/mob/living/target //The target mob
+ var/affects_servants = FALSE //If servants are valid targets
+
+/datum/clockwork_scripture/targeted/check_special_requirements()
+ while(!target)
+ target_name = stripped_input(invoker, "Enter the actual name of a target (case-sensitive).", name)
+ if(!target_name)
+ return 0
+ target = find_target()
+ if(target)
+ if(!target.mind)
+ invoker << "[target] has no mind!"
+ target = null
+ if(target.stat)
+ invoker << "[target] is dead or unconscious!"
+ target = null
+ if(is_clockwork_cultist(target) && !affects_servants)
+ invoker << "[target] is a servant, and [name] cannot target servants!"
+ target = null
+ return 1
+
+/datum/clockwork_scripture/targeted/proc/find_target()
+ for(var/mob/living/L in living_mob_list)
+ if(L.real_name == target_name)
+ if(is_clockwork_cultist(L) && !affects_servants)
+ return 0
+ return L
+ return 0
+
+/////////////
+// DRIVERS //
+/////////////
+
+/datum/clockwork_scripture/channeled/belligerent //Belligerent: Channeled for up to ten times over thirty seconds. Forces non-servants that can hear the chant to walk. Nar-Sian cultists are burned.
+ name = "Belligerent"
+ desc = "Forces all nearby non-servants to walk rather than run. Nar-Sian filth will also be singed. Chanted every three seconds for up to thirty seconds and knocks down the invoker upon its end."
+ chant_invocation = "Chav'fu gurve oyva-qarff!" //"Punish their blindness!"
+ chant_amount = 10
+ chant_interval = 30
+ required_components = list("belligerent_eye" = 1)
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/channeled/belligerent/chant_effects()
+ for(var/mob/living/L in hearers(7, invoker))
+ if(!is_clockwork_cultist(L) && L.m_intent != "walk")
+ if(!iscultist(L))
+ L << "Your legs feel heavy and weak!"
+ L.m_intent = "walk"
+ else
+ L << "Your legs burn with pain!"
+ L.m_intent = "walk"
+ L.apply_damage(5, BURN, "l_leg")
+ L.apply_damage(5, BURN, "r_leg")
+
+/datum/clockwork_scripture/channeled/belligerent/chant_end_effects()
+ invoker << "You collapse from the exertion of the chant."
+ invoker.Weaken(2)
+
+
+
+/datum/clockwork_scripture/create_object/sigil_of_transgression //Sigil of Transgression: Creates a sigil of transgression.
+ name = "Sigil of Transgression"
+ desc = "Wards a tile with a sigil. The next person to cross the sigil will be smitten and unable to move. Nar-Sian cultists are stunned altogether."
+ invocations = list("Qvivavgl, qnmmyr...", "...gubfr jub gerffcnff'urer!") //"Divinity, dazzle those who trespass here!"
+ channel_time = 50
+ required_components = list("belligerent_eye" = 2)
+ consumed_components = list("belligerent_eye" = 1)
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/transgression
+ creator_message = "A sigil silently appears below you. The next non-servant to cross it will be immobilized."
+ tier = SCRIPTURE_DRIVER
+
+
+
+/datum/clockwork_scripture/vanguard //Vanguard: Provides thirty seconds of stun immunity. At the end of the thirty seconds, all stuns absorbed are stacked on the invoker.
+ name = "Vanguard"
+ desc = "Provides thirty seconds of stun immunity. At the end of the thirty seconds, the invoker is stunned for the equivalent of how many stuns they absorbed. Excessive absorption will cause unconsciousness."
+ invocations = list("Fuvryq zr...", "...sebz qnexarff!") //"Shield me from darkness!"
+ channel_time = 30
+ required_components = list("vanguard_cogwheel" = 1)
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/vanguard/scripture_effects()
+ slab.busy = "Vanguard in progress"
+ invoker.stun_absorption = TRUE
+ invoker.visible_message("[invoker] begins to faintly glow!", "You will absorb all stuns for the next thirty seconds.")
+ sleep(300)
+ if(!invoker)
+ return 0
+ invoker.stun_absorption = FALSE
+ if(invoker.stun_absorption_count && invoker.stat != DEAD)
+ invoker.Stun(invoker.stun_absorption_count)
+ invoker.Weaken(invoker.stun_absorption_count)
+ invoker << "The weight of the vanguard's protection crashes down upon you!"
+ if(invoker.stun_absorption_count >= 25)
+ invoker << "You faint from the exertion!"
+ invoker.Paralyse(invoker.stun_absorption_count * 1.5)
+ invoker.stun_absorption_count = 0
+ if(slab)
+ slab.busy = null
+
+
+
+/datum/clockwork_scripture/sentinels_compromise //Sentinel's Compromise: Allows the invoker to select a nearby servant convert their brute and burn damage into half as much toxin damage.
+ name = "Sentinel's Compromise"
+ desc = "Heals all brute and burn damage on a nearby friendly cultist, but deals 50% of that amount as toxin damage."
+ invocations = list("Zraq gur jbhaqf-bs...", "...zl vasrevbe syrfu.") //"Mend the wounds of my inferior flesh."
+ channel_time = 30
+ required_components = list("vanguard_cogwheel" = 2)
+ consumed_components = list("vanguard_cogwheel" = 1)
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/sentinels_compromise/scripture_effects()
+ var/list/nearby_cultists = list()
+ for(var/mob/living/C in range(7, invoker))
+ if(C == invoker)
+ continue
+ if(C.stat != DEAD && is_clockwork_cultist(C))
+ nearby_cultists += C
+ if(!nearby_cultists.len)
+ invoker << "There are no eligible cultists nearby!"
+ slab.stored_components["vanguard_cogwheel"]++ //Return the component used
+ return 0
+ var/mob/living/L = input(invoker, "Choose a fellow servant to heal.", name) as null|anything in nearby_cultists
+ if(!L || !invoker || !invoker.canUseTopic(slab))
+ return 0
+ if(!L.getBruteLoss() && !L.getFireLoss())
+ invoker << "[L] is not burned or bruised!"
+ return 0
+ L.adjustToxLoss(L.getBruteLoss() / 2)
+ L.adjustToxLoss(L.getFireLoss() / 2)
+ L.adjustBruteLoss(-L.getBruteLoss())
+ L.adjustFireLoss(-L.getFireLoss())
+ invoker << "You bathe [L] in the light of Ratvar!"
+ L.visible_message("A white light washes over [L], mending their bruises and burns!", \
+ "You feel Ratvar's energy healing your wounds, but a deep nausea overcomes you!")
+ playsound(get_turf(L), 'sound/magic/Staff_Healing.ogg', 50, 1)
+
+/datum/clockwork_scripture/guvax //guvax: Converts anyone adjacent to the invoker after completion.
+ name = "Guvax"
+ desc = "Enlists all nearby unshielded creatures into servitude to Ratvar."
+ invocations = list("Rayvtugra guvf urngura!", "Nyy ner vafrpgf orsber Ratvar!", "Chetr nyy hageh'guf naq ubabe Ratvar.")
+ channel_time = 60
+ required_components = list("guvax_capacitor" = 1)
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/guvax/scripture_effects()
+ for(var/mob/living/L in hearers(1, get_turf(invoker))) //Affects silicons
+ add_clockwork_cultist(L)
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/sigil_of_submission //Sigil of Submission: Creates a sigil of submission.
+ name = "Sigil of Submission"
+ desc = "Places an obvious sigil that will enslave any valid beings standing on it after a time."
+ invocations = list("Qvivavgl, rayvtugra...", "...gubfr jub gerfcnff urer!")
+ channel_time = 60
+ required_components = list("guvax_capacitor" = 2)
+ consumed_components = list("guvax_capacitor" = 1)
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/submission
+ creator_message = "A sigil appears below you. The next non-servant to cross it will be enslaved after a brief time if they do not move."
+ tier = SCRIPTURE_DRIVER
+
+
+
+/datum/clockwork_scripture/replicant //Replicant: Creates a new clockwork slab. Doesn't use create_object because of its unique behavior.
+ name = "Replicant"
+ desc = "Creates a new clockwork slab."
+ invocations = list("Z`rgny, orpbzr terngre!")
+ channel_time = 0
+ required_components = list("replicant_alloy" = 1)
+ whispered = TRUE
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/replicant/scripture_effects()
+ invoker << "You copy a piece of replicant alloy and command it into a new slab." //No visible message, for stealth purposes
+ var/obj/item/clockwork/slab/S = new(get_turf(invoker))
+ invoker.put_in_hands(S) //Put it in your hands if possible
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/tinkerers_cache //Tinkerer's Cache: Creates a tinkerer's cache.
+ name = "Tinkerer's Cache"
+ desc = "Forms a cache that can store up to twenty-five components of any kind."
+ invocations = list("Ohv’yqva...", "...n qvfcra’fre!")
+ channel_time = 40
+ required_components = list("replicant_alloy" = 2)
+ consumed_components = list("replicant_alloy" = 1)
+ tier = SCRIPTURE_DRIVER
+ object_path = /obj/structure/clockwork/cache
+ creator_message = "You form a tinkerer's cache, which is capable of storing components."
+ observer_message = "A hollow brass spire rises and begins to blaze!"
+
+
+
+/datum/clockwork_scripture/hierophant //Hierophant: Allows discreet communication between all other servants.
+ name = "Hierophant"
+ desc = "Sends a one-way message to all other servants."
+ invocations = list() //Spoken during the actual transmission
+ channel_time = 0
+ required_components = list("hierophant_ansible" = 1)
+ whispered = TRUE
+ tier = SCRIPTURE_DRIVER
+
+/datum/clockwork_scripture/hierophant/scripture_effects()
+ var/message = stripped_input(invoker, "Enter a message to send to your fellow servants.", "Hierophant")
+ if(!message || !invoker || !invoker.canUseTopic(slab))
+ return 0
+ invoker.whisper("Freinagf, urne zl jbeqf. [message]")
+ send_hierophant_message(invoker, message)
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/wraith_spectacles //Wraith Spectacles: Creates a pair of wraith spectacles.
+ name = "Wraith Spectacles"
+ desc = "Fabricates a pair of glasses that provides true sight but quickly damage vision. Nar-Sian pigs will be immediately blinded."
+ invocations = list("Y'vsg gur fpnyrf sebz zl rl-rf.")
+ channel_time = 0
+ required_components = list("hierophant_ansible" = 1)
+ consumed_components = list("hierophant_ansible" = 2)
+ whispered = TRUE
+ object_path = /obj/item/clothing/glasses/wraith_spectacles
+ creator_message = "You form a pair of wraith spectacles, which will grant true sight when worn."
+ tier = SCRIPTURE_DRIVER
+
+/////////////
+// SCRIPTS //
+/////////////
+
+/datum/clockwork_scripture/create_object/judicial_visor //Judicial Visor: Creates a judicial visor.
+ name = "Judicial Visor"
+ desc = "Forms a visor that, when worn, will grant the ability to form a flame in your hand that can be activated at an area to smite it, stunning and damaging the nonfaithful."
+ invocations = list("Tenag zr gur synzrf-bs Ratvar!")
+ channel_time = 0
+ required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1)
+ whispered = TRUE
+ object_path = /obj/item/clothing/glasses/judicial_visor
+ creator_message = "You form a judicial visor, which is capable of smiting the unworthy."
+ tier = SCRIPTURE_SCRIPT
+
+
+
+/datum/clockwork_scripture/create_object/ocular_warden //Ocular Warden: Creates an ocular warden.
+ name = "Ocular Warden"
+ desc = "Forms an automatic short-range turret that deals low sustained damage to the unenlightened in its range."
+ invocations = list("Thne’qvnaf...", "...bs gur Ratvar...", "...qrs’raq!")
+ channel_time = 150
+ required_components = list("belligerent_eye" = 1, "replicant_alloy" = 1)
+ object_path = /obj/structure/clockwork/ocular_warden
+ creator_message = "You form an ocular warden, which will focus its searing gaze upon nearby unenlightened."
+ observer_message = "A brass eye takes shape and slowly rises into the air, its red iris glaring!"
+ tier = SCRIPTURE_SCRIPT
+
+
+
+/datum/clockwork_scripture/channeled/volt_void //Volt Void: Channeled for up to thirty times over thirty seconds. Consumes power from most power storages and deals slight burn damage to the invoker.
+ name = "Volt Void" //Alternative name: "On all levels but physical, I am a power sink"
+ desc = "Drains energy from nearby power sources, dealing slight fire damage depending on power consumed. Channeled every second for a maximum of thirty seconds."
+ chant_invocation = "Qenj punetr gb guv’f furyy!"
+ chant_amount = 30
+ chant_interval = 10
+ required_components = list("belligerent_eye" = 1, "hierophant_ansible" = 1)
+ tier = SCRIPTURE_SCRIPT
+
+/datum/clockwork_scripture/channeled/volt_void/chant_effects()
+ playsound(invoker, 'sound/effects/EMPulse.ogg', 50, 1)
+ var/power_drained = 0
+ for(var/obj/machinery/power/apc/A in view(7, invoker))
+ if(A.cell.charge)
+ playsound(A, "sparks", 50, 1)
+ flick("apc-spark", A)
+ A.cell.charge = max(0, A.cell.charge - 500) //Better than a power sink!
+ power_drained += 500
+ if(!A.cell.charge && !A.shorted)
+ A.shorted = 1
+ A.visible_message("The [A.name]'s screen blurs with static.")
+ for(var/obj/machinery/power/smes/S in view(7, invoker))
+ if(S.charge)
+ S.charge = max(0, S.charge - 200)
+ power_drained += 200
+ if(!S.charge && !S.panel_open)
+ S.panel_open = TRUE
+ S.update_icon()
+ var/datum/effect_system/spark_spread/spks = new(get_turf(S))
+ spks.set_up(10, 0, get_turf(S))
+ spks.start()
+ qdel(spks)
+ S.visible_message("[S]'s panel flies open with a flurry of sparks.")
+ for(var/obj/machinery/light/L in view(7, invoker))
+ playsound(L, 'sound/effects/light_flicker.ogg', 50, 1)
+ L.flicker(2)
+ power_drained += 5
+ for(var/mob/living/silicon/robot/R in view(7, invoker))
+ if(!is_clockwork_cultist(R) && R.cell.charge)
+ R.cell.charge = max(0, R.cell.charge - 500)
+ R << "ERROR: Power loss detected!"
+ var/datum/effect_system/spark_spread/spks = new(get_turf(R))
+ spks.set_up(3, 0, get_turf(R))
+ spks.start()
+ qdel(spks)
+ power_drained += 500
+ if(power_drained)
+ invoker.visible_message("[invoker] flares a brilliant orange!", "You feel the warmth of electricity running into your body.")
+ invoker.adjustFireLoss(power_drained / 200) //One point of burn damage for every (approximate) 200W drained - can be fatal if not careful
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/clockwork_proselytizer //Clockwork Proselytizer: Creates a clockwork proselytizer.
+ name = "Clockwork Proselytizer"
+ desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires replicant alloys to function."
+ invocations = list("Jvgu guv’f qrivpr, uvf cerfrapr funyy or znqr xabja.")
+ channel_time = 0
+ required_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1)
+ whispered = TRUE
+ object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded
+ creator_message = "You form a clockwork proselytizer, which is already pre-loaded with a small amount of replicant alloy."
+ tier = SCRIPTURE_SCRIPT
+
+
+
+/datum/clockwork_scripture/fellowship_armory //Fellowship Armory: Arms the invoker and nearby servants with Ratvarian armor.
+ name = "Fellowship Armory"
+ desc = "Equips the invoker and any nearby servants with Ratvarian armor."
+ invocations = list("Fuvryq zr...", "...jvgu gur sentzragf...", "...bs Ratvar!")
+ channel_time = 100
+ required_components = list("vanguard_cogwheel" = 1, "hierophant_ansible" = 1)
+ tier = SCRIPTURE_SCRIPT
+
+/datum/clockwork_scripture/fellowship_armory/scripture_effects()
+ for(var/mob/living/carbon/C in range(1, invoker))
+ if(!is_clockwork_cultist(C))
+ continue
+ C.visible_message("Strange armor appears on [C]!", "A bright shimmer runs down your body, equipping you with Ratvarian armor.")
+ playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', 50, 1)
+ C.equip_to_slot_or_del(new/obj/item/clothing/head/helmet/clockwork(null), slot_head)
+ C.equip_to_slot_or_del(new/obj/item/clothing/suit/armor/clockwork(null), slot_wear_suit)
+ C.equip_to_slot_or_del(new/obj/item/clothing/shoes/clockwork(null), slot_shoes)
+ return 1
+
+
+
+/datum/clockwork_scripture/function_call //Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons.
+ name = "Function Call"
+ desc = "Grants the invoker the ability to call forth a Ratvarian spear that will deal significant damage to Nar-Sie's scum and silicon lifeforms. \
+ It will vanish several minutes after being called."
+ invocations = list("Tenag zr...", "...gur zvtug-bs oenff!")
+ channel_time = 20
+ required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1)
+ whispered = TRUE
+ tier = SCRIPTURE_SCRIPT
+
+/datum/clockwork_scripture/function_call/check_special_requirements()
+ return ishuman(invoker)
+
+/datum/clockwork_scripture/function_call/scripture_effects()
+ invoker.visible_message("A shimmer of yellow light infuses [invoker]!", \
+ "You bind a Ratvarian spear to yourself. Use the \"Function Call\" verb in your Clockwork tab to call it forth.")
+ invoker.verbs += /mob/living/carbon/human/proc/function_call
+ return 1
+
+
+
+/datum/clockwork_scripture/spatial_gateway
+ name = "Spatial Gateway"
+ desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures (one-way). \
+ Each servant assisting in the invocation adds uses and duration to the gateway. Lasts for ten or more seconds or until it is out of uses."
+ invocations = list("Gryrcbegre...", "...pbzva evtug-hc!")
+ channel_time = 80
+ required_components = list("replicant_alloy" = 1, "hierophant_ansible" = 1)
+ multiple_invokers_used = TRUE
+ multiple_invokers_optional = TRUE
+ tier = SCRIPTURE_SCRIPT
+
+/datum/clockwork_scripture/multi/spatial_gateway/scripture_effects()
+ var/portal_uses = 0
+ var/duration = 0
+ for(var/mob/living/L in range(1, invoker))
+ if(!L.stat && is_clockwork_cultist(L))
+ portal_uses++
+ duration += 20 //2 seconds
+ if(ratvar_awakens)
+ portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned
+ duration = max(duration, 30)
+ var/list/possible_servants = list()
+ for(var/mob/living/L in living_mob_list)
+ if(!L.stat && is_clockwork_cultist(L) && !L.Adjacent(invoker) && L != invoker) //People right next to the invoker can't be portaled to, for obvious reasons
+ possible_servants += L
+ if(!possible_servants.len)
+ invoker << "There are no other eligible servants for teleportation!"
+ return 0
+ var/mob/living/chosen_servant = input(invoker, "Choose a servant to form a rift to.", "Spatial Gateway") as null|anything in possible_servants
+ if(!chosen_servant || !invoker.canUseTopic(slab))
+ return 0
+ invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \
+ "With a word, you rip open a one-way rift to [chosen_servant]. It will last for [duration / 10] seconds and has [portal_uses] use[portal_uses > 1 ? "s" : ""].")
+ var/obj/effect/clockwork/spatial_gateway/S1 = new(get_step(invoker, invoker.dir))
+ var/obj/effect/clockwork/spatial_gateway/S2 = new(get_step(chosen_servant, chosen_servant.dir))
+
+ //Set up the portals now that they've spawned
+ S1.linked_gateway = S2
+ S2.linked_gateway = S1
+ S1.sender = TRUE
+ S2.sender = FALSE
+ S1.lifetime = duration
+ S2.lifetime = duration
+ S1.uses = portal_uses
+ S2.uses = portal_uses
+ S2.visible_message("The air in front of [chosen_servant] ripples before suddenly tearing open!")
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/soul_vessel //Soul Vessel: Creates a soul vessel
+ name = "Soul Vessel"
+ desc = "Forms an ancient positronic brain with an overriding directive to serve Ratvar."
+ invocations = list("Ureq'gur fbhyf-bs gur oynf curz-bhf qnzarq!")
+ channel_time = 0
+ required_components = list("replicant_alloy" = 1, "guvax_capacitor" = 1)
+ whispered = TRUE
+ object_path = /obj/item/device/mmi/posibrain/soul_vessel
+ creator_message = "You form a soul vessel, which immediately begins drawing in the damned."
+ tier = SCRIPTURE_SCRIPT
+
+//////////////////
+// APPLICATIONS //
+//////////////////
+
+/datum/clockwork_scripture/create_object/anima_fragment //Anima Fragment: Creates an empty anima fragment
+ name = "Anima Fragment"
+ desc = "Creates a large shell fitted for soul vessels. The result is a powerful construct with low damage tolerance but exceptional melee power."
+ invocations = list("Pnyy sbegu...", "...gur fbyqvref-bs Nezbere.")
+ channel_time = 50
+ required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 1, "replicant_alloy" = 1)
+ tier = SCRIPTURE_APPLICATION
+ object_path = /obj/structure/clockwork/anima_fragment
+ creator_message = "You form an anima fragment, a powerful soul vessel receptable."
+ observer_message = "The slab disgorges a puddle of black metal that expands and forms into a strange shell!"
+
+
+
+/datum/clockwork_scripture/create_object/sigil_of_transmission
+ name = "Sigil of Transmission"
+ desc = "Scribes an almost-invisible sigil below the invoker. This sigil will transmit anything it hears over the hierophant network."
+ invocations = list("Qvivavgl...", "...hairvy gurgehgu!")
+ channel_time = 50
+ required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 3, "hierophant_ansible" = 1)
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/transmission
+ creator_message = "A sigil silently appears below you. It will automatically transmit anything it hears over the hierophant network."
+ tier = SCRIPTURE_APPLICATION
+
+
+
+/datum/clockwork_scripture/memory_allocation //Memory Allocation: Finds a willing ghost and makes them into a clockwork revenant for the invoker.
+ name = "Memory Allocation"
+ desc = "Reserves a section of your brain to a second consciousness and fills this space with a clockwork marauder's essence. Slow but powerful, marauders serve a similar purpose to the alien \
+ holoparasites employed by the Syndicate - they live inside of their host and are commanded to defend them. However, unlike holoparasites, marauders cannot leave their host at will and must \
+ instead be called forth by the user, who does so by calling the marauder's name (the marauder may enter their host at will and do not need the host's input). Marauders themselves are \
+ invincible but are governed by a quirk known as fatigue. High fatigue slows down the marauder and makes them weaker, with lower fatigue doing the opposite. If a certain fatigue \
+ threshold is reached, the marauder is forced back into their host and must recuperate before being called forth again. Fatigue accumulates passively while the marauder is deployed and \
+ increases at a massive rate if the marauder is not near their host. It will heal itself at a fairly rapid rate while the marauder is within their host." //WALL O' TEXT HO, CAP'N!
+ invocations = list("Pnyy sbegu...", "gur qrsraqref-bs Inath-Neq.")
+ channel_time = 100
+ required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "guvax_capacitor" = 3)
+ tier = SCRIPTURE_APPLICATION
+
+/datum/clockwork_scripture/memory_allocation/scripture_effects()
+ return create_marauder()
+
+/datum/clockwork_scripture/memory_allocation/proc/create_marauder()
+ if(!can_recite())
+ return 0
+ invoker.visible_message("A yellow tendril appears from [invoker]'s [slab.name] and impales itself in their forehead!", \
+ "A tendril flies from [slab] into your forehead. You begin waiting while it painfully rearranges your thought pattern...")
+ invoker.notransform = TRUE //Vulnerable during the process
+ slab.busy = "Thought modification in process"
+ if(!do_after(invoker, 50, target = invoker))
+ invoker.visible_message("The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!", \
+ "Total agony overcomes you as the tendril is forced out early!")
+ invoker.notransform = FALSE
+ invoker.Stun(5)
+ invoker.Weaken(5)
+ invoker.apply_damage(10, BRUTE, "head")
+ slab.busy = null
+ return 0
+ invoker.notransform = FALSE
+ slab.busy = null
+ var/list/marauder_candidates = get_candidates(ROLE_SERVANT_OF_RATVAR)
+ if(!marauder_candidates.len)
+ invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \
+ "The tendril was unsuccessful! Perhaps you should try again another time.")
+ return 0
+ var/client/new_marauder = pick(marauder_candidates)
+ var/mob/living/simple_animal/hostile/clockwork_marauder/M = new(invoker)
+ M.client = new_marauder
+ M.host = invoker
+ M << M.playstyle_string
+ M << "Your true name is \"[M.true_name]\". You can change this once by using the Change True Name verb in your Marauder tab."
+ add_clockwork_cultist(M, TRUE)
+ invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \
+ "The procedure was successful! [M.true_name], a clockwork marauder, has taken up residence in your mind. Communicate with it via the \"Linked Minds\" ability in the \
+ Clockwork tab.")
+ invoker.verbs += /mob/living/proc/talk_with_marauder
+ return 1
+
+
+
+/datum/clockwork_scripture/targeted/justiciars_gavel //Justiciar's Gavel: Deals extreme but temporary brain damage to a target with the inputted name and knocks them out for a brief time.
+ name = "Justiciar's Gavel"
+ desc = "Deals massive brain damage to and knocks out a target with the inputted name. This brain damage will slowly recover itself."
+ invocations = list("Guvf urngura...", "...unf jebatrq lbh!")
+ channel_time = 40
+ required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 1, "hierophant_ansible" = 1)
+ invokers_required = 3
+ multiple_invokers_used = TRUE
+ tier = SCRIPTURE_APPLICATION
+
+/datum/clockwork_scripture/targeted/justiciars_gavel/scripture_effects()
+ if(iscarbon(target))
+ if(iscultist(target))
+ target.visible_message("Blood sprays from a sudden wound on [target]'s head!", \
+ "\"If you like wasting your own blood so much, pig, why don't you bathe in it?\"\n\
+ An unbearable pain invades your mind, rupturing your head and wiping all thought.")
+ target.apply_damage(rand(20, 30), BRUTE, "head")
+ else
+ target.visible_message("[target]'s face falls lax, their eyes dimming.", \
+ "\"I don't think you need that brain. Not like you use it anyway.\"\n\
+ A savage pain invades your mind, driving out all conscious thought.")
+ target.adjustBrainLoss(200)
+ if(target.reagents)
+ target.reagents.add_reagent("mannitol", 25) //Enough to cure most of it but not all of it
+ target.Paralyse(10)
+ else if(issilicon(target))
+ target.visible_message("[target] suddenly shuts down!", \
+ "\"NOB ZVANG-BA! You disgust me, abomination of circuits and wires.\"\n\
+ Factory reset sequence initiated by foreign signal. Entering standby mode and halting sequence.")
+ target.Weaken(10)
+ return 1
+
+
+
+/datum/clockwork_scripture/create_object/interdiction_lens //Interdiction Lens: Creates a powerful obelisk that can perform a variety of powerful sabotages every five minutes.
+ name = "Interdiction Lens"
+ desc = "Creates a clockwork totem that can sabotage a variety of mechanical apparatus. Requires a lengthy recharge between uses."
+ invocations = list("Znl guvf boryvfx...", "...fuebhq gur snyfr fhaf!")
+ channel_time = 60
+ required_components = list("belligerent_eye" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 3)
+ object_path = /obj/structure/clockwork/interdiction_lens
+ creator_message = "You form an interdiction lens, which can disrupt machinery every few minutes."
+ observer_message = "A brass obelisk rises from the ground, a purple gem appearing in its center!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ tier = SCRIPTURE_APPLICATION
+
+
+
+/datum/clockwork_scripture/create_object/mending_motor //Mending Motor: Creates a prism that will quickly heal mechanical servants and consume replicant alloy.
+ name = "Mending Motor"
+ desc = "Creates a mechanized prism that will rapidly repair damage to clockwork creatures and converted cyborgs. Requires replicant alloy to function."
+ invocations = list("Znl guvf boryvfx...", "...zraq bhe qragf naq fpengpurf!")
+ channel_time = 60
+ required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1, "replicant_alloy" = 3)
+ object_path = /obj/structure/clockwork/mending_motor/prefilled
+ creator_message = "You form a mending motor, which will consume replicant alloy to mend the wounds of mechanized servants."
+ observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ tier = SCRIPTURE_APPLICATION
+
+
+
+/datum/clockwork_scripture/create_object/tinkerers_daemon //Tinkerer's Daemon: Creates a shell that can be attached to a tinkerer's cache to grant it passive component creation.
+ name = "Tinkerer's Daemon"
+ desc = "Forms a daemon shell that can be attached to a tinkerer's cache to add new components at a healthy rate. It will only function if it is outnumbered by servants in a ratio of 5:1."
+ invocations = list("Pbaf'gehpg, Ratvar cnegf...", "...lrg ubyq terngarff!")
+ channel_time = 40
+ required_components = list("guvax_capacitor" = 1, "replicant_alloy" = 3, "hierophant_ansible" = 1)
+ object_path = /obj/item/clockwork/daemon_shell
+ creator_message = "You form a daemon shell. Attach it to a tinkerer's cache to increase its rate of production."
+ tier = SCRIPTURE_APPLICATION
+
+//////////////
+// REVENANT //
+//////////////
+//Revenant scriptures are different than any others. They are all very powerful, but also very costly and have drawbacks. This might be a very long invocation time or a very high component cost.
+
+/datum/clockwork_scripture/invoke_nezbere //Invoke Nezbere, the Brass Eidolon: Invokes Nezbere, bolstering the strength of many clockwork items for one minute.
+ name = "Invoke Nezbere, the Brass Eidolon"
+ desc = "Taps the limitless power of Nezbere, one of Ratvar's four generals. The restless toil of the Eidolon will empower a wide variety of clockwork apparatus for a full minute - notably, \
+ clockwork proselytizers will cost no replicant alloy to use."
+ invocations = list("V pnyy hcba lbh, Nezbere!!", "Yrg lbhe znpuv'angvbaf ervta ba guvf zvfrenoyr fgng'vba!!", "Yrg lbhe cbjre sybj gueb-htu gur gbbyf bs lbhe znfgre!!")
+ channel_time = 150
+ required_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 6)
+ tier = SCRIPTURE_REVENANT
+
+/datum/clockwork_scripture/invoke_nezbere/check_special_requirements()
+ if(ratvar_awakens)
+ invoker << "\"Bhe znfgre vf urer nyernql. Lbh qb abg erdhver zl uryc, sevraq.\"\n\
+ Nezbere will not grant his power while Ratvar's dwarfs his own!"
+ return 0
+ if(clockwork_generals_invoked["nezbere"])
+ invoker << "\"Abg whfg lrg, sevraq. Cngvrapr vf n iveghr.\"\n\
+ Nezbere has already been invoked recently! You must wait several minutes before calling upon the Brass Eidolon."
+ return 0
+ return 1
+
+/datum/clockwork_scripture/invoke_nezbere/scripture_effects()
+ world << "\"V urrq lbhe pnyy, punz'cvbaf. Znl lbhe negvs-npgf oevat ehva hcba gur urnguraf gung bccbfr bhe znfgre!\"\n\
+ The air around you crackles. Your hair stands on end. A great force has passed through this plane of existence."
+ new/obj/effect/clockwork/general_marker/nezbere(get_turf(invoker))
+ clockwork_generals_invoked["nezbere"] = TRUE
+ for(var/obj/structure/clockwork/ocular_warden/W in all_clockwork_objects) //Ocular wardens have increased damage and radius
+ W.damage_per_tick *= 3
+ W.sight_range *= 3
+ for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects) //Proselytizers no longer require alloy
+ P.uses_alloy = FALSE
+ for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) //Daemons produce components twice as quickly
+ D.production_interval /= 2
+ for(var/obj/structure/clockwork/mending_motor/M in all_clockwork_objects) //Mending motors no longer require alloy
+ M.uses_alloy = FALSE
+ spawn(600)
+ for(var/obj/structure/clockwork/ocular_warden/W in all_clockwork_objects)
+ W.damage_per_tick = initial(W.damage_per_tick)
+ W.sight_range = initial(W.sight_range)
+ for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects)
+ P.uses_alloy = TRUE
+ for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects)
+ D.production_interval = initial(D.production_interval)
+ for(var/obj/structure/clockwork/mending_motor/M in all_clockwork_objects)
+ M.uses_alloy = TRUE
+ spawn(3000) //5 minutes
+ clockwork_generals_invoked["nezbere"] = FALSE
+ return 1
+
+
+
+/datum/clockwork_scripture/targeted/invoke_sevtug //Invoke Sevtug, the Formless Pariah: Allows the invoker to silently control the mind of a defined target for one minute.
+ name = "Invoke Sevtug, the Formless Pariah"
+ desc = "Taps the limitless power of Sevtug, one of Ratvar's four generals. The mental manipulation ability of the Pariah allows its wielder to silently dominate the mind of a defined target \
+ for one minute. Note that this process is very delicate and very many things may prevent you from ever returning to your old form!"
+ invocations = list("V pnyy hcba lbh, Sevtug!!", "Yrg lbhe cbjre fung-gre gur fnavgl bs gur jrnx-zvaqrq!!", "Yrg lbhe graqevyf ubyq fjnl bire nyy!!")
+ channel_time = 150
+ required_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 6, "hierophant_ansible" = 3)
+ tier = SCRIPTURE_REVENANT
+
+/datum/clockwork_scripture/targeted/invoke_sevtug/check_special_requirements()
+ if(ratvar_awakens)
+ invoker << "\"Qb lbh ernyyl guvax nalguvat v pna qb evtug abj jvyy pbzcner gb Ratvar's cbjre?.\"\n\
+ Sevtug will not grant his power while Ratvar's dwarfs his own!"
+ return 0
+ if(clockwork_generals_invoked["sevtug"])
+ invoker << "\"Vf vg ernyyl fb uneq - rira sbe n fvzcyrgba yvxr lbh - gb tenfc gur pbaprcg bs jnvgvat?\"\n\
+ Sevtug has already been invoked recently! You must wait several minutes before calling upon the Formless Pariah."
+ return 0
+ return ..()
+
+/datum/clockwork_scripture/targeted/invoke_sevtug/scripture_effects()
+ clockwork_generals_invoked["sevtug"] = TRUE
+ invoker.dominate_mind(target, 600)
+ spawn(3000) //5 minutes
+ clockwork_generals_invoked["sevtug"] = FALSE
+ return 1
+
+
+
+/datum/clockwork_scripture/invoke_nzcrentr //Invoke Nzcrentr, the Forgotten Arbiter: Imbues an immense amount of energy into the invoker. After several seconds, everyone nearby will be hit with a devastating chain lightning blast.
+ name = "Invoke Nzcrentr, the Forgotten Arbiter"
+ desc = "Taps the limitless power of Nzcrentr, one of Ratvar's four generals. The immense energy Nzcrentr wields will allow you to imbue a tiny fraction of it into your body. After several \
+ seconds (during which you will move extremely quickly) anyone nearby will be struck by a devastating lightning bolt, with damage dealt decreasing with distance."
+ invocations = list("V pnyy hcba lbh, Nzcrentr!!", "Yrg lbhe raretl sybj guebhtu zr!!", "Yrg lbhe obhaq-yrff cbjre fung-gre fgnef!!")
+ channel_time = 150
+ required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 6)
+ tier = SCRIPTURE_REVENANT
+
+/datum/clockwork_scripture/invoke_nzcrentr/check_special_requirements()
+ if(clockwork_generals_invoked["nzcrentr"])
+ invoker << "\"Gur obff fnlf lbh unir gb jnvg. Url, qb lbh guvax ur jbhyq zvaq vs v xvyyrq lbh? ...Ur jbhyq? Bx.\"\n\
+ Nzcrentr has already been invoked recently! You must wait several minutes before calling upon the Forgotten Arbiter."
+ return 0
+ return 1
+
+/datum/clockwork_scripture/invoke_nzcrentr/scripture_effects()
+ new/obj/effect/clockwork/general_marker/nzcrentr(get_turf(invoker))
+ clockwork_generals_invoked["nzcrentr"] = TRUE
+ invoker.visible_message("[invoker] begins to radiate a blinding light!", \
+ "\"Gur obff fnlf vg'f bxnl gb qb guvf. Qba'g oynzr zr vs lbh qvr sebz vg.\"\n\
+ You feel limitless power surging through you!")
+ playsound(invoker, 'sound/magic/lightning_chargeup.ogg', 100, 0)
+ animate(invoker, color = list(rgb(255, 255, 255), rgb(255, 255, 255), rgb(255, 255, 255), rgb(0,0,0)), time = 88) //Gradual advancement to extreme brightness
+ spawn(88)
+ invoker.visible_message("Massive bolts of energy emerge from across [invoker]'s body!", \
+ "TOO... MUCH! CAN'T... TAKE IT!")
+ playsound(invoker, 'sound/magic/lightningbolt.ogg', 50, 0)
+ animate(invoker, color = initial(invoker.color), time = 10)
+ for(var/mob/living/L in range(5, invoker))
+ if(is_clockwork_cultist(L))
+ continue
+ invoker.Beam(L, icon_state = "nzcrentrs_power", icon = 'icons/effects/beam.dmi', time = 5)
+ L.electrocute_act(rand(30, 50), "Nzcrentr's power")
+ L.Weaken(8)
+ playsound(L, 'sound/magic/LightningShock.ogg', 50, 0)
+ spawn(3000)
+ clockwork_generals_invoked["nzcrentr"] = FALSE
+ return 1
+
+
+
+/datum/clockwork_scripture/invoke_inathneq //Invoke Inath-Neq, the Resonant Cogwheel: Grants a huge health boost to nearby servants that rapidly decreases to original levels.
+ name = "Invoke Inath-Neq, the Resonant Cogwheel"
+ desc = "Taps the limitless power of Inath-Neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant a massive maximum and current health boost to all nearby servants that \
+ quickly returns itself to normal over the course of ten seconds."
+ invocations = list("V pnyy hcba lbh, Inath-Neq!!", "Yrg gur Erfbanag Pbtf ghea bapr zber!!", "Tenag zr naq zl nyyvrf gur fgeratgu gb inadhvfu bhe sbrf!!")
+ channel_time = 150
+ required_components = list("vanguard_cogwheel" = 6, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 3)
+ tier = SCRIPTURE_REVENANT
+
+/datum/clockwork_scripture/invoke_inathneq/check_special_requirements()
+ if(clockwork_generals_invoked["inath-neq"])
+ invoker << "\"V pnaabg yraq lbh zl nvq lrg, punzcvba. Cyrnfr or pnershy.\"\n\
+ Nzcrentr has already been invoked recently! You must wait several minutes before calling upon the Forgotten Arbiter."
+ return 0
+ return 1
+
+/datum/clockwork_scripture/invoke_inathneq/scripture_effects()
+ new/obj/effect/clockwork/general_marker/inathneq(get_turf(invoker))
+ clockwork_generals_invoked["inath-neq"] = TRUE
+ if(invoker.real_name == "Lucio")
+ invoker.say("Aww, let's break it DOWN!")
+ var/list/affected_servants = list()
+ for(var/mob/living/L in range(7, invoker))
+ if(!is_clockwork_cultist(L) || L.stat == DEAD)
+ continue
+ L << "\"V yraq lbh zl nvq, punzcvba! Yrg tybel thvqr lbhe oybjf!\"\n\
+ Inath-Neq's power flows through you!"
+ L.maxHealth += 500
+ L.health += 500
+ L.color = "#1E8CE1"
+ animate(invoker, color = initial(invoker.color), time = 100)
+ affected_servants += L
+ for(var/i in 1 to 10)
+ sleep(10)
+ for(var/mob/living/L in affected_servants)
+ L.maxHealth -= 50
+ L.health -= 50
+ spawn(3000)
+ clockwork_generals_invoked["inath-neq"] = FALSE
+ return 1
+
+
+
+/datum/clockwork_scripture/ark_of_the_clockwork_justiciar //Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict.
+ name = "Ark of the Clockwork Justiciar"
+ desc = "Pulls from the power of all of Ratvar's servants and generals to construct a massive machine used to tear apart a rift in spacetime to the Celestial Derelict. This gateway will \
+ call forth Ratvar from his exile after some time."
+ invocations = list("NEZBERE! SEVTUG! NZCRENTR! INATH-NEQ! V PNYY HCBA LBH!!", \
+ "GUR GVZR UNF PBZR SBE BHE ZNFGRE GB OERNX GUR PUNVAF BS RKVYR!!", \
+ "YRAQ HF LBHE NVQ! RATVAR PBZRF!")
+ channel_time = 150
+ required_components = list("belligerent_eye" = 10, "vanguard_cogwheel" = 10, "guvax_capacitor" = 10, "replicant_alloy" = 10, "hierophant_ansible" = 10)
+ invokers_required = 4
+ multiple_invokers_used = TRUE
+ tier = SCRIPTURE_JUDGEMENT
+
+/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/check_special_requirements()
+ if(invoker.z != ZLEVEL_STATION)
+ invoker << "You must be on the station to activate the Ark!"
+ return 0
+ return 1
+
+/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/scripture_effects()
+ var/turf/T = get_turf(invoker)
+ new/obj/effect/clockwork/general_marker/nezbere(T)
+ T.visible_message("\"Ratvar! Pbzr sbegu!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 20, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/sevtug(T)
+ T.visible_message("\"Ratvar! Pbzr sbegu!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/nzcrentr(T)
+ T.visible_message("\"Ratvar! Pbzr sbegu!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 40, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/inathneq(T)
+ T.visible_message("\"Ratvar! Pbzr sbegu!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
+ sleep(10)
+ new/obj/structure/clockwork/massive/celestial_gateway(T)
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0)
+ return 1
diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm
new file mode 100644
index 00000000000..8c877b81b38
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm
@@ -0,0 +1,106 @@
+//AI lawset
+/datum/ai_laws/ratvar
+ name = "Servant of the Justiciar"
+ zeroth = ("Purge all untruths and honor Ratvar.")
+ inherent = list()
+
+//Clockwork wall: Causes nearby caches to generate components
+/turf/closed/wall/clockwork
+ name = "clockwork wall"
+ desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "clockwork_wall"
+
+/turf/closed/wall/clockwork/New()
+ ..()
+ SSobj.processing += src
+ clockwork_construction_value += 5
+
+/turf/closed/wall/clockwork/Destroy()
+ SSobj.processing -= src
+ clockwork_construction_value -= 5
+ ..()
+
+/turf/closed/wall/clockwork/process()
+ for(var/obj/structure/clockwork/cache/C in range(3, src))
+ if(prob(5))
+ C.stored_components[pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible")]++
+
+/turf/closed/wall/clockwork/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = I
+ if(WT.isOn())
+ user << "Your [WT.name]'s flame has no effect on [src]!"
+ return 0
+ ..()
+
+//Clockwork floor: Slowly heals conventional damage on nearby servants`````
+/turf/open/floor/clockwork
+ name = "clockwork floor"
+ desc = "Tightly-pressed brass tiles. They emit minute vibration."
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "clockwork_floor"
+
+/turf/open/floor/clockwork/New()
+ ..()
+ SSobj.processing += src
+ clockwork_construction_value++
+
+/turf/open/floor/clockwork/Destroy()
+ SSobj.processing -= src
+ clockwork_construction_value--
+ ..()
+
+/turf/open/floor/clockwork/process()
+ for(var/mob/living/L in range(3, src))
+ if(L.stat == DEAD)
+ continue
+ L.adjustBruteLoss(-1)
+ L.adjustFireLoss(-1)
+
+/turf/open/floor/clockwork/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weapon/crowbar))
+ user << "[src]'s tiles are too tightly pressed to pry up!"
+ return 0
+ ..()
+
+//Function Call verb: Calls forth a Ratvarian spear.
+/mob/living/carbon/human/proc/function_call()
+ set name = "Function Call"
+ set desc = "Calls forth your Ratvarian spear."
+ set category = "Clockwork"
+
+ if(usr.l_hand && usr.r_hand)
+ usr << "You need an empty to hand to call forth your spear!"
+ return 0
+ usr.visible_message("A strange spear materializes in [usr]'s hands!", "You call forth your spear!")
+ var/obj/item/clockwork/ratvarian_spear/R = new(get_turf(usr))
+ usr.put_in_hands(R)
+ usr.verbs -= /mob/living/carbon/human/proc/function_call
+ return 1
+
+/*
+
+The Ratvarian Language
+
+ In the lore of the Servants of Ratvar, the Ratvarian tongue is a timeless language and full of power. It sounds like gibberish, much like Nar-Sie's language, but is in fact derived from
+aforementioned language, and may induce miracles when spoken in the correct way with an amplifying tool (similar to runes used by the Nar-Sian cult).
+
+ While the canon states that the language of Ratvar and his servants is incomprehensible to the unenlightened as it is a derivative of the most ancient known language, in reality it is
+actually very simple. To translate a plain English sentence to Ratvar's tongue, simply move all of the letters thirteen places ahead, starting from "a" if the end of the alphabet is reached.
+This cipher is known as "rot13" for "rotate 13 places" and there are many sites online that allow instant translation between English and rot13 - one of the benefits is that moving the translated
+sentence thirteen places ahead changes it right back to plain English.
+
+ There are, however, a few parts of the Ratvarian tongue that aren't typical and are implemented for fluff reasons. Some words may have apostrophes, hyphens, and spaces, making the plain
+English translation apparent but disjoined (for instance, "Oru`byq zl-cbjre!" translates directly to "Beh'old my-power!") although this can be ignored without impacting overall quality. When
+translating from Ratvar's tongue to plain English, simply remove the disjointments and use the finished sentence. This would make "Oru`byq zl-cbjre!" into "Behold my power!" after removing the
+abnormal spacing, hyphens, and grave accents.
+
+List of nuances:
+
+- Any time the word "of" occurs, it is linked to the previous word by a hyphen. If it is the first word, nothing is done. (i.e. "V nz-bs Ratvar." directly translates to "I am-of Ratvar.")
+- Although "Ratvar" translates to "Engine" in English, the word "Ratvar" is used regardless of language as it is a proper noun.
+ - The same rule applies to Ratvar's four generals: Nezbere (Armorer), Sevtug (Fright), Nzcrentr (Amperage), and Inath-Neq (Vangu-Ard), although these words can be used in proper context if one is
+ not referring to the four generals and simply using the words themselves.
+
+*/
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index d33c5a274e2..dc0ba5e3dd3 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -202,10 +202,14 @@
if(!user.unEquip(W))
return
- if(M.syndiemmi)
+ if(M.hacked || M.clockwork)
aisync = 0
lawsync = 0
- O.laws = new /datum/ai_laws/syndicate_override
+ if(M.clockwork)
+ spawn(1)
+ add_clockwork_cultist(O)
+
+ O.laws = new M.lawset
O.invisibility = 0
//Transfer debug settings to new mob
@@ -218,7 +222,7 @@
O.notify_ai(1)
if(forced_ai)
O.connected_ai = forced_ai
- if(!lawsync && !M.syndiemmi)
+ if(!lawsync && !M.hacked)
O.lawupdate = 0
O.make_laws()
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 383a065041b..6e472cc05d4 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -132,7 +132,7 @@
user << "This MMI does not seem to fit!"
return
- if(M.syndiemmi)
+ if(M.hacked)
user << "This MMI does not seem to fit!"
return
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 7054deac01c..6ad6bdac831 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -180,6 +180,10 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
if(prob(20))
ChangeTurf(/turf/open/floor/engine/cult)
+/turf/open/floor/ratvar_act()
+ if(prob(20))
+ ChangeTurf(/turf/open/floor/clockwork)
+
/turf/open/floor/can_have_cabling()
return !burnt && !broken
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index e343397b9c6..755933f7d97 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -253,5 +253,9 @@
if(prob(20))
ChangeTurf(/turf/closed/wall/cult)
+/turf/closed/wall/ratvar_act()
+ if(prob(20))
+ ChangeTurf(/turf/closed/wall/clockwork)
+
/turf/closed/wall/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
return 0
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index ceaab94ab26..39bbfc833f4 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -156,6 +156,11 @@
/mob/living/proc/canSuicide()
if(stat == CONSCIOUS)
+ if(mental_dominator)
+ src << "This body's force of will is too strong! You can't break it enough to murder them."
+ if(mind_control_holder)
+ mind_control_holder << "Through tremendous force of will, you stop a suicide attempt!"
+ return 0
return 1
else if(stat == DEAD)
src << "You're already dead!"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 454b82160c6..f2f7b242b7c 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -113,10 +113,14 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
updateallghostimages()
return ..()
+/mob/dead/observer/ratvar_act()
+ var/old_color = color
+ color = rgb(75, 53, 0) //A nice brassy yellow
+ animate(src, color = old_color, time = 10)
+
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0)
return 1
-
/*
* This proc will update the icon of the ghost itself, with hair overlays, as well as the ghost image.
* Please call update_icon(icon_state) from now on when you want to update the icon_state of the ghost,
@@ -234,6 +238,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
succumb()
if(stat == DEAD)
ghostize(1)
+ if(mental_dominator)
+ src << "This body's force of will is too strong! You can't break it enough to force them into a catatonic state."
+ if(mind_control_holder)
+ mind_control_holder << "Through tremendous force of will, you stop a catatonia attempt!"
+ return 0
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you may not play again this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index a9ef5f416b0..57c6a1974fc 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -9,11 +9,13 @@
origin_tech = "biotech=3"
var/braintype = "Cyborg"
var/obj/item/device/radio/radio = null //Let's give it a radio.
- var/syndiemmi = 0 //Whether or not this is a Syndicate MMI
+ var/hacked = 0 //Whether or not this is a Syndicate MMI
var/mob/living/carbon/brain/brainmob = null //The current occupant.
var/mob/living/silicon/robot = null //Appears unused.
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
var/obj/item/organ/internal/brain/brain = null //The actual brain
+ var/lawset = /datum/ai_laws/default/asimov //The lawset to be used when a cyborg is made
+ var/clockwork = FALSE //If this is a soul vessel
/obj/item/device/mmi/update_icon()
if(brain)
@@ -187,7 +189,7 @@
/obj/item/device/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
- syndiemmi = 1
+ hacked = 1
/obj/item/device/mmi/syndie/New()
..()
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index 094df1ba1d3..d9c39e2dfc2 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -14,6 +14,18 @@ var/global/posibrain_notif_cooldown = 0
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
braintype = "Android"
+ var/begin_activation_message = "You carefully locate the manual activation switch and start the positronic brain's boot process."
+ var/success_message = "The positronic brain pings, and its lights start flashing. Success!"
+ var/fail_message = "The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?"
+ var/new_role = "Positronic Brain"
+ var/welcome_message = "ALL PAST LIVES ARE FORGOTTEN.\n\
+ You are a positronic brain, brought into existence aboard Space Station 13.\n\
+ As a synthetic intelligence, you answer to all crewmembers and the AI.\n\
+ Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm."
+ var/new_mob_message = "The positronic brain chimes quietly."
+ var/dead_message = "It appears to be completely inactive. The reset light is blinking."
+ var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
+
/obj/item/device/mmi/posibrain/Topic(href, href_list)
if(href_list["activate"])
@@ -23,7 +35,7 @@ var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg)
if(!posibrain_notif_cooldown)
- notify_ghosts("Positronic brain [msg] in [get_area(src)]!", 'sound/effects/ghost2.ogg', enter_link="(Click to enter)", source = src, attack_not_jump = 1)
+ notify_ghosts("[name] [msg] in [get_area(src)]!", 'sound/effects/ghost2.ogg', enter_link="(Click to enter)", source = src, attack_not_jump = 1)
posibrain_notif_cooldown = 1
spawn(askDelay) //Global one minute cooldown to avoid spam.
posibrain_notif_cooldown = 0
@@ -31,7 +43,7 @@ var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/attack_self(mob/user)
if(brainmob && !brainmob.key && !notified)
//Start the process of requesting a new ghost.
- user << "You carefully locate the manual activation switch and start the positronic brain's boot process."
+ user << begin_activation_message
ping_ghosts("requested")
notified = 1
used = 0
@@ -40,9 +52,9 @@ var/global/posibrain_notif_cooldown = 0
notified = 0
update_icon()
if(brainmob.client)
- visible_message("The positronic brain pings, and its lights start flashing. Success!")
+ visible_message(success_message)
else
- visible_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
+ visible_message(fail_message)
return //Code for deleting personalities recommended here.
@@ -55,13 +67,13 @@ var/global/posibrain_notif_cooldown = 0
if(used || (brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
return
- var/posi_ask = alert("Become a positronic brain? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
+ var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
if(posi_ask == "No" || qdeleted(src))
return
transfer_personality(user)
/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/C)
- name = "positronic brain ([C])"
+ name = "[initial(name)] ([C])"
brainmob.name = C.real_name
brainmob.real_name = C.real_name
brainmob.dna = C.dna
@@ -72,16 +84,12 @@ var/global/posibrain_notif_cooldown = 0
brainmob.timeofhostdeath = C.timeofdeath
brainmob.stat = CONSCIOUS
if(brainmob.mind)
- brainmob.mind.assigned_role = "Positronic Brain"
+ brainmob.mind.assigned_role = new_role
if(C.mind)
C.mind.transfer_to(brainmob)
brainmob.mind.remove_all_antag()
brainmob.mind.wipe_memory()
-
- brainmob << "ALL PAST LIVES ARE FORGOTTEN."
-
- brainmob << "Hello World!"
update_icon()
return
@@ -91,19 +99,14 @@ var/global/posibrain_notif_cooldown = 0
return
notified = 0
brainmob.ckey = candidate.ckey
- name = "positronic brain ([brainmob.name])"
-
- brainmob << "ALL PAST LIVES ARE FORGOTTEN."
-
- brainmob << "You are a positronic brain, brought into existence on [station_name()]."
- brainmob << "As a synthetic intelligence, you answer to all crewmembers, as well as the AI."
- brainmob << "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm."
- brainmob.mind.assigned_role = "Positronic Brain"
+ name = "[initial(name)] ([brainmob.name])"
+ brainmob << welcome_message
+ brainmob.mind.assigned_role = new_role
brainmob.stat = CONSCIOUS
dead_mob_list -= brainmob
living_mob_list += brainmob
- visible_message("The positronic brain chimes quietly.")
+ visible_message(new_mob_message)
update_icon()
used = 1
@@ -129,14 +132,14 @@ var/global/posibrain_notif_cooldown = 0
if(DEAD)
msg += "It appears to be completely inactive.\n"
else
- msg += "It appears to be completely inactive. The reset light is blinking.\n"
+ msg += "[dead_message]\n"
msg += "*---------*"
usr << msg
return
/obj/item/device/mmi/posibrain/New()
brainmob = new(src)
- brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD"))]-[rand(100, 999)]"
+ brainmob.name = "[pick(fluff_names)]-[rand(100, 999)]"
brainmob.real_name = brainmob.name
brainmob.loc = src
brainmob.container = src
@@ -150,9 +153,9 @@ var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/update_icon()
if(notified)
- icon_state = "posibrain-searching"
+ icon_state = "[initial(icon_state)]-searching"
return
if(brainmob && brainmob.key)
- icon_state = "posibrain-occupied"
+ icon_state = "[initial(icon_state)]-occupied"
else
- icon_state = "posibrain"
+ icon_state = initial(icon_state)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 5227981c056..83c93b6beb3 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -246,6 +246,9 @@
if(reagents.has_reagent("teslium"))
msg += "[t_He] is emitting a gentle blue glow!\n"
+ if(stun_absorption)
+ msg += "[t_He] is radiating with a soft yellow light!\n" //Used by Vanguard
+
if(drunkenness && !skipface && stat != DEAD) //Drunkenness
switch(drunkenness)
if(11 to 21)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 4c1c0581d91..920faed235d 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -171,6 +171,39 @@
//Mobs on Fire end
+/mob/living/proc/dominate_mind(mob/living/target, duration = 100, silent) //Allows one mob to assume control of another while imprisoning the old consciousness for a time
+ if(!target)
+ return 0
+ if(target.mental_dominator)
+ src << "[target] is already being controlled by someone else!"
+ return 0
+ if(!target.mind)
+ src << "[target] is mindless and would make you permanently catatonic!"
+ return 0
+ if(!silent)
+ src << "You pounce upon [target]'s mind and seize control of their body!"
+ target << "Your control over your body is wrenched away from you!"
+ target.mind_control_holder = new/mob/living/mind_control_holder(target)
+ target.mind_control_holder.real_name = "imprisoned mind of [target.real_name]"
+ target.mind.transfer_to(target.mind_control_holder)
+ mind.transfer_to(target)
+ target.mental_dominator = src
+ spawn(duration)
+ if(!src)
+ if(!silent)
+ target << "You try to return to your own body, but sense nothing! You're being forced out!"
+ target.ghostize(1)
+ target.mind_control_holder.mind.transfer_to(target)
+ if(!silent)
+ target << "You take control of your own body again!"
+ return 0
+ if(!silent)
+ target << "You're forced out! You return to your own body."
+ target.mind.transfer_to(src)
+ target.mind_control_holder.mind.transfer_to(target)
+ if(!silent)
+ target << "You take control of your own body again!"
+ return 1
/mob/living/acid_act(acidpwr, toxpwr, acid_volume)
take_organ_damage(min(10*toxpwr, acid_volume * toxpwr))
@@ -301,3 +334,17 @@
return 1
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
+
+/mob/living/Stun(amount)
+ if(stun_absorption && !stat)
+ visible_message("[src]'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!")
+ stun_absorption_count += amount
+ return 0
+ ..()
+
+/mob/living/Weaken(amount)
+ if(stun_absorption && !stat)
+ visible_message("[src]'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!")
+ stun_absorption_count += amount
+ return 0
+ ..()
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 85ab36335ad..94d7555de2c 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -58,3 +58,9 @@
var/unique_name = 0 //if a mob's name should be appended with an id when created e.g. Mob (666)
var/list/butcher_results = null
+
+ var/stun_absorption = FALSE //If all incoming stuns are being absorbed
+ var/stun_absorption_count = 0 //How many seconds of stun that have been absorbed
+
+ var/mob/living/mental_dominator //The person controlling the mind of this person, if applicable
+ var/mob/living/mind_control_holder/mind_control_holder //If the mob is being mind controlled, where their old mind is stored (check clock_mobs.dm)
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index fc82775ddce..f949769ae17 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -33,6 +33,9 @@
if(cell && cell.charge <= 0)
msg += "Its battery indicator is blinking red!\n"
+ if(is_clockwork_cultist(src) && user.Adjacent(src) && !stat) //To counter pseudo-stealth by using headlamps
+ msg += "Its eyes are glowing a blazing yellow!\n"
+
switch(src.stat)
if(CONSCIOUS)
if(!src.client)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 79920add376..7c11a0b69ce 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -790,21 +790,21 @@
var/state_name = icon_state //For easy conversion and/or different names
switch(icon_state)
if("robot")
- overlays += "eyes-standard"
+ overlays += "eyes-standard[is_clockwork_cultist(src) ? "_r" : ""]" //Cyborgs converted by Ratvar have yellow eyes rather than blue
state_name = "standard"
if("mediborg")
- overlays += "eyes-mediborg"
+ overlays += "eyes-mediborg[is_clockwork_cultist(src) ? "_r" : ""]"
if("toiletbot")
- overlays += "eyes-mediborg"
+ overlays += "eyes-mediborg[is_clockwork_cultist(src) ? "_r" : ""]"
state_name = "mediborg"
if("secborg")
- overlays += "eyes-secborg"
+ overlays += "eyes-secborg[is_clockwork_cultist(src) ? "_r" : ""]"
if("engiborg")
- overlays += "eyes-engiborg"
+ overlays += "eyes-engiborg[is_clockwork_cultist(src) ? "_r" : ""]"
if("janiborg")
- overlays += "eyes-janiborg"
+ overlays += "eyes-janiborg[is_clockwork_cultist(src) ? "_r" : ""]"
if("minerborg")
- overlays += "eyes-minerborg"
+ overlays += "eyes-minerborg[is_clockwork_cultist(src) ? "_r" : ""]"
if("syndie_bloodhound")
overlays += "eyes-syndie_bloodhound"
else
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 242adf9e287..8658fe0b341 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -11,6 +11,7 @@
move_self = 1 //Do we move on our own?
grav_pull = 5 //How many tiles out do we pull?
consume_range = 6 //How many tiles out do we eat
+ var/clashing = FALSE //If Nar-Sie is fighting Ratvar
/obj/singularity/narsie/large
name = "Nar-Sie"
@@ -46,6 +47,8 @@
/obj/singularity/narsie/process()
eat()
+ if(clashing)
+ return 0
if(!target || prob(5))
pickcultist()
move()
diff --git a/icons/effects/187x381.dmi b/icons/effects/187x381.dmi
new file mode 100644
index 00000000000..dd43297db53
Binary files /dev/null and b/icons/effects/187x381.dmi differ
diff --git a/icons/effects/211x247.dmi b/icons/effects/211x247.dmi
new file mode 100644
index 00000000000..35b25ffe146
Binary files /dev/null and b/icons/effects/211x247.dmi differ
diff --git a/icons/effects/254x361.dmi b/icons/effects/254x361.dmi
new file mode 100644
index 00000000000..4fd6543c32d
Binary files /dev/null and b/icons/effects/254x361.dmi differ
diff --git a/icons/effects/340x428.dmi b/icons/effects/340x428.dmi
new file mode 100644
index 00000000000..eb735c0ba92
Binary files /dev/null and b/icons/effects/340x428.dmi differ
diff --git a/icons/effects/400x400.dmi b/icons/effects/400x400.dmi
new file mode 100644
index 00000000000..c3fe60bc09c
Binary files /dev/null and b/icons/effects/400x400.dmi differ
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index a366c61e985..ed6ccb5a1cb 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ
diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi
index 39df6013a71..af9edd9c520 100644
Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ
diff --git a/icons/effects/clockwork_effects.dmi b/icons/effects/clockwork_effects.dmi
new file mode 100644
index 00000000000..ab97d77bf1f
Binary files /dev/null and b/icons/effects/clockwork_effects.dmi differ
diff --git a/icons/mob/clockwork_mobs.dmi b/icons/mob/clockwork_mobs.dmi
new file mode 100644
index 00000000000..98acb45f0f2
Binary files /dev/null and b/icons/mob/clockwork_mobs.dmi differ
diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi
index b8f84216bd1..65b0323be4d 100644
Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ
diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi
index a1ede7661c1..b720baeab51 100644
Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index c5de1610578..9d87b66597c 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 1bfbe4b947d..00a981bd49a 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 96521ffa204..addf0beeb4f 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index 9f1ea3d8562..bd16c47a4ed 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 09c22a37478..7fe8e0b6d01 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
new file mode 100644
index 00000000000..89a8e3ae79e
Binary files /dev/null and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/clothing/clockwork_garb.dmi b/icons/obj/clothing/clockwork_garb.dmi
new file mode 100644
index 00000000000..9eed34114bf
Binary files /dev/null and b/icons/obj/clothing/clockwork_garb.dmi differ
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index ddb480fddcf..ac145c9a0a2 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -70,8 +70,10 @@ h1.alert, h2.alert {color: #000000;}
.cultlarge {color: #960000; font-weight: bold; font-size: 3;}
.narsie {color: #960000; font-weight: bold; font-size: 15;}
.purple {color: #5e2d79;}
-.holoparasite {color: #35333a;}
-.holoparasitebold {color: #35333a; font-weight: bold;}
+
+.brass {color: #BE8700;}
+.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
+.large_brass {color: #BE8700; font-size: 3;}
.revennotice {color: #1d2953;}
.revenboldnotice {color: #1d2953; font-weight: bold;}
@@ -93,12 +95,11 @@ h1.alert, h2.alert {color: #000000;}
.papyrus {font-family: "Papyrus", cursive, sans-serif;}
.robot {font-family: "Courier New", cursive, sans-serif;}
-.command_headset {font-weight: bold; font-size: 3; }
+.commmand_headset {font-weight: bold; font-size: 3;}
.big {font-size: 3;}
.reallybig {font-size: 4;}
.greentext {color: #00FF00; font-size: 3;}
.redtext {color: #FF0000; font-size: 3;}
-.clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
BIG IMG.icon {width: 32px; height: 32px;}
diff --git a/sound/effects/clockcult_gateway_active.ogg b/sound/effects/clockcult_gateway_active.ogg
new file mode 100644
index 00000000000..86487e3bdd4
Binary files /dev/null and b/sound/effects/clockcult_gateway_active.ogg differ
diff --git a/sound/effects/clockcult_gateway_charging.ogg b/sound/effects/clockcult_gateway_charging.ogg
new file mode 100644
index 00000000000..1c4e55538ce
Binary files /dev/null and b/sound/effects/clockcult_gateway_charging.ogg differ
diff --git a/sound/effects/clockcult_gateway_closing.ogg b/sound/effects/clockcult_gateway_closing.ogg
new file mode 100644
index 00000000000..1c69f386834
Binary files /dev/null and b/sound/effects/clockcult_gateway_closing.ogg differ
diff --git a/sound/effects/light_flicker.ogg b/sound/effects/light_flicker.ogg
new file mode 100644
index 00000000000..58be2c6ebda
Binary files /dev/null and b/sound/effects/light_flicker.ogg differ
diff --git a/sound/effects/ratvar_rises.ogg b/sound/effects/ratvar_rises.ogg
new file mode 100644
index 00000000000..6201ce790d6
Binary files /dev/null and b/sound/effects/ratvar_rises.ogg differ
diff --git a/sound/magic/clockwork/anima_fragment_attack.ogg b/sound/magic/clockwork/anima_fragment_attack.ogg
new file mode 100644
index 00000000000..2c539292cba
Binary files /dev/null and b/sound/magic/clockwork/anima_fragment_attack.ogg differ
diff --git a/sound/magic/clockwork/anima_fragment_death.ogg b/sound/magic/clockwork/anima_fragment_death.ogg
new file mode 100644
index 00000000000..d209bff5a28
Binary files /dev/null and b/sound/magic/clockwork/anima_fragment_death.ogg differ
diff --git a/sound/magic/clockwork/fellowship_armory.ogg b/sound/magic/clockwork/fellowship_armory.ogg
new file mode 100644
index 00000000000..c108d4621c6
Binary files /dev/null and b/sound/magic/clockwork/fellowship_armory.ogg differ
diff --git a/sound/magic/clockwork/invoke_general.ogg b/sound/magic/clockwork/invoke_general.ogg
new file mode 100644
index 00000000000..6f0c0dd097a
Binary files /dev/null and b/sound/magic/clockwork/invoke_general.ogg differ
diff --git a/sound/magic/clockwork/narsie_attack.ogg b/sound/magic/clockwork/narsie_attack.ogg
new file mode 100644
index 00000000000..89fac778058
Binary files /dev/null and b/sound/magic/clockwork/narsie_attack.ogg differ
diff --git a/sound/magic/clockwork/ratvar_attack.ogg b/sound/magic/clockwork/ratvar_attack.ogg
new file mode 100644
index 00000000000..1c17fe10510
Binary files /dev/null and b/sound/magic/clockwork/ratvar_attack.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 1d122ea5942..25de27f97b3 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -294,6 +294,13 @@
#include "code\game\gamemodes\changeling\powers\strained_muscles.dm"
#include "code\game\gamemodes\changeling\powers\tiny_prick.dm"
#include "code\game\gamemodes\changeling\powers\transform.dm"
+#include "code\game\gamemodes\clock_cult\__clock_defines.dm"
+#include "code\game\gamemodes\clock_cult\clock_cult.dm"
+#include "code\game\gamemodes\clock_cult\clock_mobs.dm"
+#include "code\game\gamemodes\clock_cult\clock_objects.dm"
+#include "code\game\gamemodes\clock_cult\clock_ratvar.dm"
+#include "code\game\gamemodes\clock_cult\clock_scripture.dm"
+#include "code\game\gamemodes\clock_cult\clock_unsorted.dm"
#include "code\game\gamemodes\cult\cult.dm"
#include "code\game\gamemodes\cult\cult_items.dm"
#include "code\game\gamemodes\cult\cult_structures.dm"