diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm
index 68f45f5472..421d03cf9d 100644
--- a/_maps/map_files/generic/City_of_Cogs.dmm
+++ b/_maps/map_files/generic/City_of_Cogs.dmm
@@ -300,6 +300,10 @@
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism,
/turf/open/indestructible/reebe_void,
/area/reebe)
+"bj" = (
+/obj/structure/destructible/clockwork/eminence_spire,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
(1,1,1) = {"
aa
@@ -31739,7 +31743,7 @@ aj
aj
ai
aj
-aj
+az
aj
ai
aj
@@ -31996,7 +32000,7 @@ aj
aj
ap
aj
-az
+aj
aj
ap
aj
@@ -32253,7 +32257,7 @@ aj
aj
ai
aj
-aj
+bj
aj
ai
aj
diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm
index fe804c44f9..d51dbfd047 100644
--- a/code/__DEFINES/clockcult.dm
+++ b/code/__DEFINES/clockcult.dm
@@ -1,9 +1,9 @@
-//component id defines
-#define BELLIGERENT_EYE "belligerent_eye"
-#define VANGUARD_COGWHEEL "vanguard_cogwheel"
-#define GEIS_CAPACITOR "geis_capacitor"
+//component id defines; sometimes these may not make sense in regards to their use in scripture but important ones are bright
+#define BELLIGERENT_EYE "belligerent_eye" //Use this for offensive and damaging scripture!
+#define VANGUARD_COGWHEEL "vanguard_cogwheel" //Use this for defensive and healing scripture!
+#define GEIS_CAPACITOR "geis_capacitor" //Use this for niche scripture!
#define REPLICANT_ALLOY "replicant_alloy"
-#define HIEROPHANT_ANSIBLE "hierophant_ansible"
+#define HIEROPHANT_ANSIBLE "hierophant_ansible" //Use this for construction-related scripture!
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual)
@@ -69,6 +69,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
//Objective text define
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
+//Eminence defines
+#define SUPERHEATED_CLOCKWORK_WALL_LIMIT 20 //How many walls can be superheated at once
+
//misc clockcult stuff
#define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power
@@ -86,3 +89,5 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define MARAUDER_SCRIPTURE_SCALING_TIME 50 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
+
+#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 77425e14dd..da25d34880 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -144,6 +144,8 @@
#define iscameramob(A) (istype(A, /mob/camera))
+#define iseminence(A) (istype(A, /mob/camera/eminence))
+
//Objects
#define isobj(A) istype(A, /obj) //override the byond proc because it returns true on children of /atom/movable that aren't objs
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 6fb7b08611..9ec23fa966 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1507,3 +1507,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
else
return "\[[url_encode(thing.tag)]\]"
return "\ref[input]"
+
+//Returns a list of all servants of Ratvar and observers.
+/proc/servants_and_ghosts()
+ . = list()
+ for(var/V in GLOB.player_list)
+ if(is_servant_of_ratvar(V) || isobserver(V))
+ . += V
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index da2fae9882..0006d72d3b 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -388,23 +388,15 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
desc = "CHETR
NYY
HAGEHUGF-NAQ-UBABE
RATVAR."
else
var/servants = 0
- var/validservants = 0
var/list/textlist
for(var/mob/living/L in GLOB.alive_mob_list)
if(is_servant_of_ratvar(L))
servants++
- if(ishuman(L) || issilicon(L))
- validservants++
- if(servants > 1)
- if(validservants > 1)
- textlist = list("[servants] Servants, [validservants] of which count towards scripture.
")
- else
- textlist = list("[servants] Servants, [validservants ? "[validservants] of which counts":"none of which count"] towards scripture.
")
- else
- textlist = list("[servants] Servant, who [validservants ? "counts":"does not count"] towards scripture.
")
- for(var/i in SSticker.scripture_states)
- if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff
- textlist += "[i] Scripture: [SSticker.scripture_states[i] ? "UNLOCKED":"LOCKED"]
"
+ textlist = list("[SSticker.mode.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
")
+ textlist += "There are currently [servants] servant[servants > 1 ? "s" : ""] of Ratvar.
"
+ for(var/i in SSticker.scripture_states)
+ if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff
+ textlist += "[i] Scripture: [SSticker.scripture_states[i] ? "UNLOCKED":"LOCKED"]
"
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(G)
var/time_info = G.get_arrival_time(FALSE)
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 63900d0f89..61bd9bb496 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -44,10 +44,10 @@ Credit where due:
// PROCS //
///////////
-/proc/is_servant_of_ratvar(mob/living/M)
+/proc/is_servant_of_ratvar(mob/M)
return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT)
-/proc/is_eligible_servant(mob/living/M)
+/proc/is_eligible_servant(mob/M)
if(!istype(M))
return FALSE
if(M.mind)
@@ -61,11 +61,11 @@ Credit where due:
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
return FALSE
- if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
+ if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab) || istype(M, /mob/camera/eminence))
return TRUE
return FALSE
-/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
+/proc/add_servant_of_ratvar(mob/L, silent = FALSE)
if(!L || !L.mind)
return
var/update_type = ANTAG_DATUM_CLOCKCULT
@@ -73,7 +73,7 @@ Credit where due:
update_type = ANTAG_DATUM_CLOCKCULT_SILENT
. = L.mind.add_antag_datum(update_type)
-/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
+/proc/remove_servant_of_ratvar(mob/L, silent = FALSE)
if(!L || !L.mind)
return
var/datum/antagonist/clockcult/clock_datum = L.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT)
@@ -88,6 +88,7 @@ Credit where due:
///////////////
/datum/game_mode
+ var/datum/mind/eminence //The clockwork Eminence
var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar
var/clockwork_explanation = "Defend the Ark of the Clockwork Justiciar and free Ratvar." //The description of the current objective
@@ -176,7 +177,7 @@ Credit where due:
if(!S.forceMove(get_turf(L)))
qdel(S)
if(S && !QDELETED(S))
- to_chat(L, "There is a paper in your backpack! Read it!")
+ to_chat(L, "There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.")
to_chat(L, "[slot] is a clockwork slab, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \
as a servant, you can find a concise tutorial in the Recollection category of its interface.")
to_chat(L, "If you want more information, you can find a wiki link here! https://tgstation13.org/wiki/Clockwork_Cult")
@@ -202,11 +203,12 @@ Credit where due:
return //Doesn't end until the round does
/datum/game_mode/clockwork_cult/generate_report()
- return "We have lost contact with multiple stations in your sector. They have gone dark and do not respond to all transmissions, although they appear intact and the crew's life \
- signs remain uninterrupted. Those that have managed to send a transmission or have had some of their crew escape tell tales of a machine cult creating sapient automatons and seeking \
- to brainwash the crew to summon their god, Ratvar. If evidence of this cult is dicovered aboard your station, extreme caution and extreme vigilance must be taken going forward, and \
- all resources should be devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will \
- prevent conversion altogether."
+ return "Bluespace monitors near your sector have detected a continuous stream of patterned fluctuations since the station was completed. It is most probable that a powerful entity \
+ from a very far distance away is using to the station as a vector to cross that distance through bluespace. The theoretical power required for this would be monumental, and if \
+ the entity is hostile, it would need to rely on a single central power source - disrupting or destroying that power source would be the best way to prevent said entity from causing \
+ harm to company personnel or property.
Keep a sharp on any crew that appear to be oddly-dressed or using what appear to be magical powers, as these crew may be defectors \
+ working for this entity and utilizing highly-advanced technology to cross the great distance at will. If they should turn out to be a credible threat, the task falls on you and \
+ your crew to dispatch it in a timely manner."
/datum/game_mode/proc/auto_declare_completion_clockwork_cult()
var/text = ""
@@ -224,9 +226,11 @@ Credit where due:
for(var/i in SSticker.scripture_states)
if(i != SCRIPTURE_DRIVER)
text += "
[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED"
+ if(SSticker.mode.eminence)
+ text += "
The Eminence was: [printplayer(SSticker.mode.eminence)]"
if(servants_of_ratvar.len)
text += "
Ratvar's servants were:"
- for(var/datum/mind/M in servants_of_ratvar)
+ for(var/datum/mind/M in servants_of_ratvar - SSticker.mode.eminence)
text += printplayer(M)
to_chat(world, text)
@@ -246,14 +250,14 @@ Credit where due:
/datum/outfit/servant_of_ratvar
name = "Servant of Ratvar"
uniform = /obj/item/clothing/under/chameleon/ratvar
- shoes = /obj/item/clothing/shoes/workboots
+ shoes = /obj/item/clothing/shoes/sneakers/black
back = /obj/item/storage/backpack
ears = /obj/item/device/radio/headset
gloves = /obj/item/clothing/gloves/color/yellow
belt = /obj/item/storage/belt/utility/servant
backpack_contents = list(/obj/item/storage/box/engineer = 1, \
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1)
- id = /obj/item/card/id
+ id = /obj/item/device/pda
var/plasmaman //We use this to determine if we should activate internals in post_equip()
/datum/outfit/servant_of_ratvar/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
@@ -265,7 +269,8 @@ Credit where due:
plasmaman = TRUE
/datum/outfit/servant_of_ratvar/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- var/obj/item/card/id/W = H.wear_id
+ var/obj/item/card/id/W = new(H)
+ var/obj/item/device/pda/PDA = H.wear_id
W.assignment = "Assistant"
W.access += ACCESS_MAINT_TUNNELS
W.registered_name = H.real_name
@@ -273,8 +278,15 @@ Credit where due:
if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that
H.internal = H.get_item_for_held_index(2)
H.update_internals_hud_icon(1)
+ PDA.owner = H.real_name
+ PDA.ownjob = "Assistant"
+ PDA.update_label()
+ PDA.id_check(H, W)
H.sec_hud_set_ID()
+
+//This paper serves as a quick run-down to the cult as well as a changelog to refer to.
+//Check strings/clockwork_cult_changelog.txt for the changelog, and update it when you can!
/obj/item/paper/servant_primer
name = "The Ark And You: A Primer On Servitude"
color = "#DAAA18"
@@ -304,14 +316,19 @@ Credit where due:
\
Things that have changed:
\
\
- - Scripture no longer requires components, and instead uses power.
\
- - Added a 5-minute grace period for the crew to prepare for the assault when the Ark activates.
\
- - Script and Application scriptures can now be unlocked with enough power.
\
- - Added the Hateful Manacles scripture, which handcuffs targets!
\
+ CLOCKCULTCHANGELOG\
\
\
Good luck!"
+/obj/item/paper/servant_primer/Initialize()
+ . = ..()
+ var/changelog = world.file2list("strings/clockwork_cult_changelog.txt")
+ var/changelog_contents = ""
+ for(var/entry in changelog)
+ changelog_contents += "[entry]"
+ info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents)
+
/obj/item/paper/servant_primer/examine(mob/user)
if(!is_servant_of_ratvar(user) && !isobserver(user))
to_chat(user, "You can't understand any of the words on [src].")
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
index c6f3f0f7f3..0b94d34ab1 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
@@ -43,7 +43,9 @@
//changes construction value
/proc/change_construction_value(amount)
- GLOB.clockwork_construction_value += amount
+ if(!SSticker.current_state != GAME_STATE_PLAYING) //This is primarily so that structures added pre-roundstart don't contribute to construction value
+ return
+ GLOB.clockwork_construction_value = max(0, GLOB.clockwork_construction_value + amount)
/proc/can_recite_scripture(mob/living/L, can_potentially)
return (is_servant_of_ratvar(L) && (can_potentially || (L.stat == CONSCIOUS && L.can_speak_vocal())) && (GLOB.ratvar_awakens || (ishuman(L) || issilicon(L))))
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
index 4ca8f7f35b..45065cd757 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
@@ -65,8 +65,13 @@
/obj/item/restraints/handcuffs/clockwork
name = "replicant manacles"
+<<<<<<< HEAD
desc = "Cold, heavy manacles made out of some strange black metal."
origin_tech = "materials=2;magnets=5"
+=======
+ desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid."
+ icon_state = "brass_manacles"
+>>>>>>> 32c68a6... Clockwork Cult Defenses Patch - Leader role, traps and wiring, hulk and mech soft-counters, +more (#32935)
flags_1 = DROPDEL_1
/obj/item/restraints/handcuffs/clockwork/dropped(mob/user)
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
index 70aeaa6520..0111567122 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
@@ -1,23 +1,31 @@
/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 you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant."
+ clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.
\
+ It can be used to link traps and triggers by attacking them with the slab. Keep in mind that traps linked with one another will activate in tandem!"
+
icon_state = "dread_ipad"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand
+
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
+
var/busy //If the slab is currently being used by something
var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks
var/speed_multiplier = 1 //multiples how fast this slab recites scripture
var/selected_scripture = SCRIPTURE_DRIVER
- var/recollecting = FALSE //if we're looking at fancy recollection
var/obj/effect/proc_holder/slab/slab_ability //the slab's current bound ability, for certain scripture
+
+ var/recollecting = FALSE //if we're looking at fancy recollection
+ var/recollection_category = "Default"
+
var/list/quickbound = list(/datum/clockwork_scripture/abscond, \
/datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index
var/maximum_quickbound = 5 //how many quickbound scriptures we can have
- var/recollection_category = "Default"
+
+ var/obj/structure/destructible/clockwork/trap/linking //If we're linking traps together, which ones we're doing
/obj/item/clockwork/slab/internal //an internal motor for mobs running scripture
name = "scripture motor"
@@ -34,8 +42,7 @@
add_servant_of_ratvar(user)
/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator
- clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\
- Hitting a slab, a Servant with a slab, or a cache will transfer this slab's components into the target, the target's slab, or the global cache, respectively."
+ clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture."
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
/datum/clockwork_scripture/create_object/stargazer)
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
@@ -46,7 +53,7 @@
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
- /datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra)
+ /datum/clockwork_scripture/create_object/vitality_matrix)
/obj/item/clockwork/slab/cyborg/security //twoscriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker)
@@ -153,6 +160,11 @@
return 0
access_display(user)
+/obj/item/clockwork/slab/AltClick(mob/living/user)
+ if(is_servant_of_ratvar(user) && linking)
+ linking = null
+ to_chat(user, "Object link canceled.")
+
/obj/item/clockwork/slab/proc/access_display(mob/living/user)
if(!is_servant_of_ratvar(user))
return FALSE
@@ -410,7 +422,10 @@
data["tier_info"] = "Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached.."
data["selected"] = selected_scripture
-
+ data["scripturecolors"] = "Scriptures in yellow are related to construction and building.
\
+ Scriptures in red are related to attacking and offense.
\
+ Scriptures in blue are related to healing and defense.
\
+ Scriptures in purple are niche but still important!"
generate_all_scripture()
data["scripture"] = list()
diff --git a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
index 4f6485310b..d6b2ddce0d 100644
--- a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
@@ -184,7 +184,7 @@
sleep(13)
name = "judicial explosion"
var/targetsjudged = 0
- playsound(src, 'sound/effects/explosionfar.ogg', 100, 1, 1, 1)
+ playsound(src, 'sound/effects/explosion_distant.ogg', 100, 1, 1, 1)
set_light(0)
for(var/mob/living/L in range(1, src))
if(is_servant_of_ratvar(L))
diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
new file mode 100644
index 0000000000..cc91feeb98
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
@@ -0,0 +1,264 @@
+//The Eminence is a unique mob that functions like the leader of the cult. It's incorporeal but can interact with the world in several ways.
+/mob/camera/eminence
+ name = "\the Emininence"
+ real_name = "\the Eminence"
+ desc = "The leader-elect of the servants of Ratvar."
+ icon = 'icons/effects/clockwork_effects.dmi'
+ icon_state = "eminence"
+ mouse_opacity = MOUSE_OPACITY_OPAQUE
+ move_on_shuttle = TRUE
+ see_in_dark = 8
+ invisibility = INVISIBILITY_OBSERVER
+ layer = FLY_LAYER
+ faction = list("ratvar")
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ var/static/superheated_walls = 0
+
+/mob/camera/eminence/Initialize()
+ if(SSticker.mode.eminence)
+ return INITIALIZE_HINT_QDEL
+ . = ..()
+
+/mob/camera/eminence/Destroy(force)
+ if(!force && mind && SSticker.mode.eminence == mind)
+ return QDEL_HINT_LETMELIVE
+ return ..()
+
+/mob/camera/eminence/CanPass(atom/movable/mover, turf/target)
+ return TRUE
+
+/mob/camera/eminence/Move(NewLoc, direct)
+ var/OldLoc = loc
+ if(NewLoc && !istype(NewLoc, /turf/open/indestructible/reebe_void))
+ forceMove(get_turf(NewLoc))
+ Moved(OldLoc, direct)
+ if(GLOB.ratvar_awakens)
+ for(var/turf/T in range(5, src))
+ if(prob(166 - (get_dist(src, T) * 33)))
+ T.ratvar_act() //Causes moving to leave a swath of proselytized area behind the Eminence
+
+/mob/camera/eminence/Login()
+ ..()
+ add_servant_of_ratvar(src, TRUE)
+ to_chat(src, "You have been selected as the Eminence!")
+ to_chat(src, "As the Eminence, you lead the servants. Anything you say will be heard by the entire cult.")
+ to_chat(src, "Though you can move through walls, you're also incorporeal, and largely can't interact with the world except for a few ways.")
+ to_chat(src, "Additionally, unless the herald's beacon is activated, you can't understand any speech while away from Reebe.")
+ SSticker.mode.eminence = mind
+ eminence_help()
+ for(var/V in actions)
+ var/datum/action/A = V
+ A.Remove(src) //So we get rid of duplicate actions; this also removes Hierophant network, since our say() goes across it anyway
+ var/datum/action/innate/eminence/E
+ for(var/V in subtypesof(/datum/action/innate/eminence))
+ E = new V
+ E.Grant(src)
+
+/mob/camera/eminence/say(message)
+ message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
+ if(!message)
+ return
+ log_talk(src, "[key_name(src)] : [message]", LOGSAY)
+ if(GLOB.ratvar_awakens)
+ visible_message("You feel light slam into your mind and form words: \"[capitalize(message)]\"")
+ playsound(src, 'sound/machines/clockcult/ark_scream.ogg', 50, FALSE)
+ hierophant_message("The Eminence: \"[message]\"")
+
+/mob/camera/eminence/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
+ if(z == ZLEVEL_CITYOFCOGS || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything
+ to_chat(src, message)
+ return
+ to_chat(src, "[speaker] says something, but you can't understand any of it...")
+
+/mob/camera/eminence/ClickOn(atom/A, params)
+ var/list/modifiers = params2list(params)
+ if(modifiers["shift"])
+ A.examine(src)
+ return
+ if(modifiers["alt"] && istype(A, /turf/closed/wall/clockwork))
+ superheat_wall(A)
+ return
+ if(modifiers["middle"] || modifiers["ctrl"])
+ issue_command(A)
+ return
+ if(GLOB.ark_of_the_clockwork_justiciar == A)
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
+ if(G.recalling)
+ return
+ if(!G.recalls_remaining)
+ to_chat(src, "The Ark can no longer recall!")
+ return
+ if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity)
+ return
+ G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH
+ else if(istype(A, /obj/structure/destructible/clockwork/trap/trigger))
+ var/obj/structure/destructible/clockwork/trap/trigger/T = A
+ T.visible_message("[T] clunks as it's activated remotely.")
+ to_chat(src, "You activate [T].")
+ T.activate()
+
+/mob/camera/eminence/ratvar_act()
+ name = "\improper Radiance"
+ real_name = "\improper Radiance"
+ desc = "The light, forgotten."
+ transform = matrix() * 2
+ invisibility = SEE_INVISIBLE_MINIMUM
+
+/mob/camera/eminence/proc/issue_command(atom/movable/A)
+ var/list/commands
+ var/atom/movable/command_location
+ if(A == src)
+ commands = list("Defend the Ark!", "Advance!", "Retreat!", "Generate Power", "Build Defenses (Bottom-Up)", "Build Defenses (Top-Down)")
+ else
+ command_location = A
+ commands = list("Rally Here", "Regroup Here", "Avoid This Area", "Reinforce This Area")
+ if(istype(A, /obj/structure/destructible/clockwork/powered))
+ var/obj/structure/destructible/clockwork/powered/P = A
+ if(!can_access_clockwork_power(P))
+ commands += "Power This Structure"
+ if(P.obj_integrity < P.max_integrity)
+ commands += "Repair This Structure"
+ var/roma_invicta = input(src, "Choose a command to issue to your cult!", "Issue Commands") as null|anything in commands
+ if(!roma_invicta)
+ return
+ var/command_text = ""
+ var/marker_icon
+ switch(roma_invicta)
+ if("Rally Here")
+ command_text = "The Eminence orders an offensive rally at [command_location] to the GETDIR!"
+ marker_icon = "eminence_rally"
+ if("Regroup Here")
+ command_text = "The Eminence orders a regroup to [command_location] to the GETDIR!"
+ marker_icon = "eminence_rally"
+ if("Avoid This Area")
+ command_text = "The Eminence has designated the area to your GETDIR as dangerous and to be avoided!"
+ marker_icon = "eminence_avoid"
+ if("Reinforce This Area")
+ command_text = "The Eminence orders the defense and fortification of the area to your GETDIR!"
+ marker_icon = "eminence_reinforce"
+ if("Power This Structure")
+ command_text = "[command_location] to your GETDIR has no power! Turn it on and make sure there's a sigil of transmission nearby!"
+ marker_icon = "eminence_unlimited_power"
+ if("Repair This Structure")
+ command_text = "The Eminence orders that [command_location] to your GETDIR should be repaired ASAP!"
+ marker_icon = "eminence_repair"
+ if("Defend the Ark!")
+ command_text = "The Eminence orders immediate defense of the Ark!"
+ if("Advance!")
+ command_text = "The Eminence commands you push forward!"
+ if("Retreat!")
+ command_text = "The Eminence has sounded the retreat! Fall back!"
+ if("Generate Power")
+ command_text = "The Eminence orders more power! Build power generations on the station!"
+ if("Build Defenses (Bottom-Up)")
+ command_text = "The Eminence orders that defenses should be built starting from the bottom of Reebe!"
+ if("Build Defenses (Top-Down)")
+ command_text = "The Eminence orders that defenses should be built starting from the top of Reebe!"
+ if(marker_icon)
+ new/obj/effect/temp_visual/ratvar/command_point(get_turf(A), marker_icon)
+ for(var/mob/M in servants_and_ghosts())
+ to_chat(M, "[replacetext(command_text, "GETDIR", dir2text(get_dir(M, command_location)))]")
+ M.playsound_local(M, 'sound/machines/clockcult/eminence_command.ogg', 75, FALSE, pressure_affected = FALSE)
+ else
+ hierophant_message("[command_text]")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/eminence_command.ogg', 75, FALSE, pressure_affected = FALSE)
+
+/mob/camera/eminence/proc/superheat_wall(turf/closed/wall/clockwork/wall)
+ if(!istype(wall))
+ return
+ if(superheated_walls >= SUPERHEATED_CLOCKWORK_WALL_LIMIT && !wall.heated)
+ to_chat(src, "You're exerting all of your power superheating this many walls already! Cool some down first!")
+ return
+ wall.turn_up_the_heat()
+ if(wall.heated)
+ superheated_walls++
+ to_chat(src, "You superheat [wall]. Superheated walls: [superheated_walls]/[SUPERHEATED_CLOCKWORK_WALL_LIMIT]")
+ else
+ superheated_walls--
+ to_chat(src, "You cool [wall]. Superheated walls: [superheated_walls]/[SUPERHEATED_CLOCKWORK_WALL_LIMIT]")
+
+/mob/camera/eminence/proc/eminence_help()
+ to_chat(src, "You can make use of certain shortcuts to perform different actions:")
+ to_chat(src, "Alt-Click a clockwork wall to superheat or cool it down. \
+ Superheated walls can't be destroyed by hulks or mechs and are much slower to deconstruct, and are marked by a bright red glow. \
+ This lasts indefinitely, but only [SUPERHEATED_CLOCKWORK_WALL_LIMIT] clockwork walls can be superheated at once.")
+ to_chat(src, "Interact with the Ark to initiate an emergency recall that teleports all servants directly to its location after a short delay. \
+ This can only be used a single time, or twice if the herald's beacon was activated,")
+ to_chat(src, "Middle or Ctrl-Click anywhere to allow you to issue a variety of contextual commands to your cult. Different objects allow for different \
+ commands. Doing this on yourself will provide commands that tell the entire cult a goal.")
+
+
+//Eminence actions below this point
+/datum/action/innate/eminence
+ name = "Eminence Action"
+ desc = "You shouldn't see this. File a bug report!"
+ icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
+ background_icon_state = "bg_clock"
+ buttontooltipstyle = "clockcult"
+
+/datum/action/innate/eminence/IsAvailable()
+ if(!iseminence(owner))
+ qdel(src)
+ return
+ return ..()
+
+//Lists available powers
+/datum/action/innate/eminence/power_list
+ name = "Eminence Powers"
+ desc = "Forgot what you can do? This refreshes you on your powers as Eminence."
+ button_icon_state = "eminence_rally"
+
+/datum/action/innate/eminence/power_list/Activate()
+ var/mob/camera/eminence/E = owner
+ E.eminence_help()
+
+//Returns to the Ark
+/datum/action/innate/eminence/ark_jump
+ name = "Return to Ark"
+ desc = "Warps you to the Ark."
+ button_icon_state = "Abscond"
+
+/datum/action/innate/eminence/ark_jump/Activate()
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
+ if(G)
+ owner.forceMove(get_turf(G))
+ owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE)
+ flash_color(owner, flash_color = "#AF0AAF", flash_time = 25)
+ else
+ to_chat(owner, "There is no Ark!")
+
+//Warps to the Station
+/datum/action/innate/eminence/station_jump
+ name = "Warp to Station"
+ desc = "Warps to Space Station 13. You cannot hear anything while there!"
+ button_icon_state = "warp_down"
+
+/datum/action/innate/eminence/station_jump/Activate()
+ if(owner.z == ZLEVEL_CITYOFCOGS)
+ owner.forceMove(get_turf(pick(GLOB.generic_event_spawns)))
+ owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE)
+ flash_color(owner, flash_color = "#AF0AAF", flash_time = 25)
+ else
+ to_chat(owner, "You're already on the station!")
+
+//A quick-use button for recalling the servants to the Ark
+/datum/action/innate/eminence/mass_recall
+ name = "Mass Recall"
+ desc = "Initiates a mass recall, warping all servants to the Ark after a short delay. This can only be used once."
+ button_icon_state = "Spatial Gateway"
+
+/datum/action/innate/eminence/mass_recall/IsAvailable()
+ . = ..()
+ if(.)
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
+ if(G)
+ return G.recalls_remaining && !G.recalling
+ return FALSE
+
+/datum/action/innate/eminence/mass_recall/Activate()
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
+ if(G && !G.recalling && G.recalls_remaining)
+ if(alert(owner, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(owner) || QDELETED(G) || !G.obj_integrity)
+ return
+ G.initiate_mass_recall()
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
index bcb9d1d1df..5aa626bac5 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
@@ -3,6 +3,70 @@
//////////////////
+//Sigil of Transmission: Creates a sigil of transmission that can drain and store power for clockwork structures.
+/datum/clockwork_scripture/create_object/sigil_of_transmission
+ descname = "Powers Nearby Structures - Important!"
+ name = "Sigil of Transmission"
+ desc = "Places a sigil that can drain and will store energy to power clockwork structures."
+ invocations = list("Divinity...", "...power our creations!")
+ channel_time = 70
+ power_cost = 200
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/transmission
+ creator_message = "A sigil silently appears below you. It will automatically power clockwork structures near it and will drain power when activated."
+ usage_tip = "Cyborgs can charge from this sigil by remaining over it for 5 seconds."
+ tier = SCRIPTURE_APPLICATION
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 1
+ quickbind = TRUE
+ quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures."
+
+
+//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
+/datum/clockwork_scripture/create_object/mania_motor
+ descname = "Powered Structure, Area Denial"
+ name = "Mania Motor"
+ desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion."
+ invocations = list("May this transmitter...", "...break the will of all who oppose us!")
+ channel_time = 80
+ power_cost = 750
+ object_path = /obj/structure/destructible/clockwork/powered/mania_motor
+ creator_message = "You form a mania motor, which causes minor damage and negative mental effects in non-Servants."
+ observer_message = "A two-pronged machine rises from the ground!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ usage_tip = "It will also cure hallucinations and brain damage in nearby Servants."
+ tier = SCRIPTURE_APPLICATION
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 2
+ quickbind = TRUE
+ quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
+
+
+//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
+/datum/clockwork_scripture/create_object/clockwork_obelisk
+ descname = "Powered Structure, Teleportation Hub"
+ name = "Clockwork Obelisk"
+ desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk."
+ invocations = list("May this obelisk...", "...take us to all places!")
+ channel_time = 80
+ power_cost = 300
+ object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk
+ creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways."
+ observer_message = "A brass obelisk appears hanging in midair!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ usage_tip = "Producing a gateway has a high power cost. Gateways to or between clockwork obelisks receive double duration and uses."
+ tier = SCRIPTURE_APPLICATION
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 3
+ quickbind = TRUE
+ quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power."
+
+
//Clockwork Marauder: Creates a construct shell for a clockwork marauder, a well-rounded frontline fighter.
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
descname = "Well-Rounded Combat Construct"
@@ -16,7 +80,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
- sort_priority = 1
+ sort_priority = 4
quickbind = TRUE
quickbind_desc = "Creates a clockwork marauder, used for frontline combat."
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
@@ -59,67 +123,3 @@
time_since_last_marauder = world.time //So that it can't be spammed to make the marauder exclusion plummet; this emulates "ticking"
recent_marauders = max(0, recent_marauders - marauders_to_exclude)
scaled_recital_time = min(recent_marauders * MARAUDER_SCRIPTURE_SCALING_TIME, MARAUDER_SCRIPTURE_SCALING_MAX)
-
-
-//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
-/datum/clockwork_scripture/create_object/mania_motor
- descname = "Powered Structure, Area Denial"
- name = "Mania Motor"
- desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion."
- invocations = list("May this transmitter...", "...break the will of all who oppose us!")
- channel_time = 80
- power_cost = 750
- object_path = /obj/structure/destructible/clockwork/powered/mania_motor
- creator_message = "You form a mania motor, which causes minor damage and negative mental effects in non-Servants."
- observer_message = "A two-pronged machine rises from the ground!"
- invokers_required = 2
- multiple_invokers_used = TRUE
- usage_tip = "It will also cure hallucinations and brain damage in nearby Servants."
- tier = SCRIPTURE_APPLICATION
- one_per_tile = TRUE
- primary_component = GEIS_CAPACITOR
- sort_priority = 2
- quickbind = TRUE
- quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
-
-
-//Sigil of Transmission: Creates a sigil of transmission that can drain and store power for clockwork structures.
-/datum/clockwork_scripture/create_object/sigil_of_transmission
- descname = "Structure Power Generator & Battery"
- name = "Sigil of Transmission"
- desc = "Places a sigil that can drain and will store energy to power clockwork structures."
- invocations = list("Divinity...", "...power our creations!")
- channel_time = 70
- power_cost = 200
- whispered = TRUE
- object_path = /obj/effect/clockwork/sigil/transmission
- creator_message = "A sigil silently appears below you. It will automatically power clockwork structures near it and will drain power when activated."
- usage_tip = "Cyborgs can charge from this sigil by remaining over it for 5 seconds."
- tier = SCRIPTURE_APPLICATION
- one_per_tile = TRUE
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 3
- quickbind = TRUE
- quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures."
-
-
-//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
-/datum/clockwork_scripture/create_object/clockwork_obelisk
- descname = "Powered Structure, Teleportation Hub"
- name = "Clockwork Obelisk"
- desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk."
- invocations = list("May this obelisk...", "...take us to all places!")
- channel_time = 80
- power_cost = 300
- object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk
- creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways."
- observer_message = "A brass obelisk appears hanging in midair!"
- invokers_required = 2
- multiple_invokers_used = TRUE
- usage_tip = "Producing a gateway has a high power cost. Gateways to or between clockwork obelisks receive double duration and uses."
- tier = SCRIPTURE_APPLICATION
- one_per_tile = TRUE
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 4
- quickbind = TRUE
- quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power."
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
index 93d203aba0..8275e4d20e 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
@@ -2,27 +2,52 @@
// DRIVERS //
/////////////
-//Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal.
-/datum/clockwork_scripture/ranged_ability/hateful_manacles
- descname = "Handcuffs"
- name = "Hateful Manacles"
- desc = "Forms replicant manacles around a target's wrists that function like handcuffs."
- invocations = list("Shackle the heretic!", "Break them in body and spirit!")
- channel_time = 15
- power_cost = 25
- whispered = TRUE
- usage_tip = "The manacles are about as strong as zipties, and break when removed."
+
+//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight.
+/datum/clockwork_scripture/create_object/stargazer
+ descname = "Generates Power From Starlight - Important!"
+ name = "Stargazer"
+ desc = "Forms a weak structure that generates power every second while within three tiles of starlight."
+ invocations = list("Capture their inferior light for us!")
+ channel_time = 50
+ power_cost = 50
+ object_path = /obj/structure/destructible/clockwork/stargazer
+ creator_message = "You form a stargazer, which will generate power near starlight."
+ observer_message = "A large lantern-shaped machine forms!"
+ usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!"
tier = SCRIPTURE_DRIVER
- primary_component = BELLIGERENT_EYE
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
sort_priority = 1
- ranged_type = /obj/effect/proc_holder/slab/hateful_manacles
- slab_overlay = "hateful_manacles"
- ranged_message = "You charge the clockwork slab with divine energy.\n\
- Left-click a target within melee range to shackle!\n\
- Click your slab to cancel."
- timeout_time = 200
quickbind = TRUE
- quickbind_desc = "Applies handcuffs to a struck target."
+ quickbind_desc = "Creates a stargazer, which generates power when near starlight."
+
+/datum/clockwork_scripture/create_object/stargazer/check_special_requirements()
+ var/area/A = get_area(invoker)
+ if(A.outdoors || A.map_name == "Space" || !A.blob_allowed)
+ to_chat(invoker, "Stargazers can't be built off-station.")
+ return
+ return ..()
+
+
+//Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power.
+/datum/clockwork_scripture/create_object/integration_cog
+ descname = "APC Power Siphoner"
+ name = "Integration Cog"
+ desc = "Fabricates an integration cog, which can be used on an open APC to replace its innards and passively siphon its power."
+ invocations = list("Take that which sustains them!")
+ channel_time = 10
+ power_cost = 10
+ whispered = TRUE
+ object_path = /obj/item/clockwork/integration_cog
+ creator_message = "You form an integration cog, which can be inserted into an open APC to passively siphon power."
+ usage_tip = "Tampering isn't visible unless the APC is opened."
+ tier = SCRIPTURE_DRIVER
+ space_allowed = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 2
+ quickbind = TRUE
+ quickbind_desc = "Creates an integration cog, which can be used to siphon power from an open APC."
//Sigil of Transgression: Creates a sigil of transgression, which briefly stuns and applies Belligerent to the first non-servant to cross it.
@@ -39,12 +64,78 @@
usage_tip = "The sigil does not silence its victim, and is generally used to soften potential converts or would-be invaders."
tier = SCRIPTURE_DRIVER
one_per_tile = TRUE
- primary_component = BELLIGERENT_EYE
- sort_priority = 2
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 3
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Transgression, which will briefly stun and slow the next non-Servant to cross it."
+//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
+/datum/clockwork_scripture/create_object/sigil_of_submission
+ descname = "Trap, Conversion"
+ name = "Sigil of Submission"
+ desc = "Places a luminous sigil that will convert any non-Servants that remain on it for 8 seconds."
+ invocations = list("Divinity, enlighten...", "...those who trespass here!")
+ channel_time = 60
+ power_cost = 125
+ whispered = TRUE
+ object_path = /obj/effect/clockwork/sigil/submission
+ creator_message = "A luminous sigil appears below you. Any non-Servants to cross it will be converted after 8 seconds if they do not move."
+ usage_tip = "This is the primary conversion method, though it will not penetrate mindshield implants."
+ tier = SCRIPTURE_DRIVER
+ one_per_tile = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 4
+ quickbind = TRUE
+ quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it."
+
+
+//Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target.
+/datum/clockwork_scripture/ranged_ability/kindle
+ descname = "Short-Range Single-Target Stun"
+ name = "Kindle"
+ desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light."
+ invocations = list("Divinity, show them your light!")
+ whispered = TRUE
+ channel_time = 30
+ power_cost = 125
+ usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration."
+ tier = SCRIPTURE_DRIVER
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 5
+ slab_overlay = "volt"
+ ranged_type = /obj/effect/proc_holder/slab/kindle
+ ranged_message = "You charge the clockwork slab with divine energy.\n\
+ Left-click a target within melee range to stun!\n\
+ Click your slab to cancel."
+ timeout_time = 150
+ quickbind = TRUE
+ quickbind_desc = "Stuns and mutes a target from a short range."
+
+
+//Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal.
+/datum/clockwork_scripture/ranged_ability/hateful_manacles
+ descname = "Handcuffs"
+ name = "Hateful Manacles"
+ desc = "Forms replicant manacles around a target's wrists that function like handcuffs."
+ invocations = list("Shackle the heretic!", "Break them in body and spirit!")
+ channel_time = 15
+ power_cost = 25
+ whispered = TRUE
+ usage_tip = "The manacles are about as strong as zipties, and break when removed."
+ tier = SCRIPTURE_DRIVER
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 6
+ ranged_type = /obj/effect/proc_holder/slab/hateful_manacles
+ slab_overlay = "hateful_manacles"
+ ranged_message = "You charge the clockwork slab with divine energy.\n\
+ Left-click a target within melee range to shackle!\n\
+ Click your slab to cancel."
+ timeout_time = 200
+ quickbind = TRUE
+ quickbind_desc = "Applies handcuffs to a struck target."
+
+
//Vanguard: Provides twenty seconds of stun immunity. At the end of the twenty seconds, 25% of all stuns absorbed are applied to the invoker.
/datum/clockwork_scripture/vanguard
descname = "Self Stun Immunity"
@@ -57,7 +148,7 @@
usage_tip = "You cannot reactivate Vanguard while still shielded by it."
tier = SCRIPTURE_DRIVER
primary_component = VANGUARD_COGWHEEL
- sort_priority = 3
+ sort_priority = 7
quickbind = TRUE
quickbind_desc = "Allows you to temporarily absorb stuns. All stuns absorbed will affect you when disabled."
@@ -89,7 +180,7 @@
usage_tip = "The Compromise is very fast to invoke, and will remove holy water from the target Servant."
tier = SCRIPTURE_DRIVER
primary_component = VANGUARD_COGWHEEL
- sort_priority = 4
+ sort_priority = 8
quickbind = TRUE
quickbind_desc = "Allows you to convert a Servant's brute, burn, and oxygen damage to half toxin damage.
Click your slab to disable."
slab_overlay = "compromise"
@@ -101,7 +192,7 @@
//Abscond: Used to return to Reebe.
/datum/clockwork_scripture/abscond
- descname = "Return to Reebe"
+ descname = "Return to Reebe - Important!"
name = "Abscond"
desc = "Yanks you through space, returning you to home base."
invocations = list("As we bid farewell, and return to the stars...", "...we shall find our way home.")
@@ -113,7 +204,7 @@
usage_tip = "This can't be used while on Reebe, for obvious reasons."
tier = SCRIPTURE_DRIVER
primary_component = GEIS_CAPACITOR
- sort_priority = 5
+ sort_priority = 9
quickbind = TRUE
quickbind_desc = "Returns you to Reebe."
@@ -153,52 +244,9 @@
animate(invoker.client, color = initial(invoker.client.color), time = 10)
-//Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target.
-/datum/clockwork_scripture/ranged_ability/kindle
- descname = "Short-Range Single-Target Stun"
- name = "Kindle"
- desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light."
- invocations = list("Divinity, show them your light!")
- whispered = TRUE
- channel_time = 30
- power_cost = 125
- usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration."
- tier = SCRIPTURE_DRIVER
- primary_component = GEIS_CAPACITOR
- sort_priority = 6
- slab_overlay = "volt"
- ranged_type = /obj/effect/proc_holder/slab/kindle
- ranged_message = "You charge the clockwork slab with divine energy.\n\
- Left-click a target within melee range to stun!\n\
- Click your slab to cancel."
- timeout_time = 150
- quickbind = TRUE
- quickbind_desc = "Stuns and mutes a target from a short range."
-
-
-//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
-/datum/clockwork_scripture/create_object/sigil_of_submission
- descname = "Trap, Conversion"
- name = "Sigil of Submission"
- desc = "Places a luminous sigil that will convert any non-Servants that remain on it for 8 seconds."
- invocations = list("Divinity, enlighten...", "...those who trespass here!")
- channel_time = 60
- power_cost = 125
- whispered = TRUE
- object_path = /obj/effect/clockwork/sigil/submission
- creator_message = "A luminous sigil appears below you. Any non-Servants to cross it will be converted after 8 seconds if they do not move."
- usage_tip = "This is the primary conversion method, though it will not penetrate mindshield implants."
- tier = SCRIPTURE_DRIVER
- one_per_tile = TRUE
- primary_component = GEIS_CAPACITOR
- sort_priority = 6
- quickbind = TRUE
- quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it."
-
-
//Replicant: Creates a new clockwork slab.
/datum/clockwork_scripture/create_object/replicant
- descname = "New Clockwork Slab"
+ descname = "New Clockwork Slab - Important!"
name = "Replicant"
desc = "Creates a new clockwork slab."
invocations = list("Metal, become greater!")
@@ -210,59 +258,12 @@
usage_tip = "This is inefficient as a way to produce components, as the slab produced must be held by someone with no other slabs to produce components."
tier = SCRIPTURE_DRIVER
space_allowed = TRUE
- primary_component = REPLICANT_ALLOY
- sort_priority = 7
+ primary_component = GEIS_CAPACITOR
+ sort_priority = 10
quickbind = TRUE
quickbind_desc = "Creates a new Clockwork Slab."
-//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight.
-/datum/clockwork_scripture/create_object/stargazer
- descname = "Necessary Structure, Generates Power From Starlight"
- name = "Stargazer"
- desc = "Forms a weak structure that generates power every second while within three tiles of starlight."
- invocations = list("Capture their inferior light for us!")
- channel_time = 50
- power_cost = 50
- object_path = /obj/structure/destructible/clockwork/stargazer
- creator_message = "You form a stargazer, which will generate power near starlight."
- observer_message = "A large lantern-shaped machine forms!"
- usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!"
- tier = SCRIPTURE_DRIVER
- one_per_tile = TRUE
- primary_component = REPLICANT_ALLOY
- sort_priority = 8
- quickbind = TRUE
- quickbind_desc = "Creates a stargazer, which generates power when near starlight."
-
-/datum/clockwork_scripture/create_object/stargazer/check_special_requirements()
- var/area/A = get_area(invoker)
- if(A.outdoors || A.map_name == "Space" || !A.blob_allowed)
- to_chat(invoker, "Stargazers can't be built off-station.")
- return
- return ..()
-
-
-//Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power.
-/datum/clockwork_scripture/create_object/integration_cog
- descname = "APC Power Siphoner"
- name = "Integration Cog"
- desc = "Fabricates an integration cog, which can be used on an open APC to replace its innards and passively siphon its power."
- invocations = list("Take that which sustains them!")
- channel_time = 10
- power_cost = 10
- whispered = TRUE
- object_path = /obj/item/clockwork/integration_cog
- creator_message = "You form an integration cog, which can be inserted into an open APC to passively siphon power."
- usage_tip = "Tampering isn't visible unless the APC is opened."
- tier = SCRIPTURE_DRIVER
- space_allowed = TRUE
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 9
- quickbind = TRUE
- quickbind_desc = "Creates an integration cog, which can be used to siphon power from an open APC."
-
-
//Wraith Spectacles: Creates a pair of wraith spectacles, which grant xray vision but damage vision slowly.
/datum/clockwork_scripture/create_object/wraith_spectacles
descname = "Limited Xray Vision Glasses"
@@ -277,7 +278,7 @@
usage_tip = "\"True sight\" means that you are able to see through walls and in darkness."
tier = SCRIPTURE_DRIVER
space_allowed = TRUE
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 10
+ primary_component = GEIS_CAPACITOR
+ sort_priority = 11
quickbind = TRUE
quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss."
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
index a172f4ca41..09cfeb99d3 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
@@ -2,6 +2,27 @@
// SCRIPTS //
/////////////
+
+//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures.
+/datum/clockwork_scripture/create_object/replica_fabricator
+ descname = "Creates Brass and Converts Objects - Important!"
+ name = "Replica Fabricator"
+ desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function."
+ invocations = list("With this device...", "...his presence shall be made known.")
+ channel_time = 20
+ power_cost = 250
+ whispered = TRUE
+ object_path = /obj/item/clockwork/replica_fabricator
+ creator_message = "You form a replica fabricator."
+ usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
+ tier = SCRIPTURE_SCRIPT
+ space_allowed = TRUE
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 1
+ quickbind = TRUE
+ quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants."
+
+
//Ocular Warden: Creates an ocular warden, which defends a small area near it.
/datum/clockwork_scripture/create_object/ocular_warden
descname = "Structure, Turret"
@@ -17,8 +38,8 @@
tier = SCRIPTURE_SCRIPT
one_per_tile = TRUE
space_allowed = TRUE
- primary_component = BELLIGERENT_EYE
- sort_priority = 1
+ primary_component = HIEROPHANT_ANSIBLE
+ sort_priority = 2
quickbind = TRUE
quickbind_desc = "Creates an Ocular Warden, which will automatically attack nearby unrestrained non-Servants that can see it."
@@ -29,26 +50,6 @@
return ..()
-//Judicial Visor: Creates a judicial visor, which can smite an area.
-/datum/clockwork_scripture/create_object/judicial_visor
- descname = "Delayed Area Knockdown Glasses"
- name = "Judicial Visor"
- desc = "Creates a visor that can smite an area, applying Belligerent and briefly stunning. The smote area will explode after 3 seconds."
- invocations = list("Grant me the flames of Engine!")
- channel_time = 10
- power_cost = 400
- whispered = TRUE
- object_path = /obj/item/clothing/glasses/judicial_visor
- creator_message = "You form a judicial visor, which is capable of smiting a small area."
- usage_tip = "The visor has a thirty-second cooldown once used."
- tier = SCRIPTURE_SCRIPT
- space_allowed = TRUE
- primary_component = BELLIGERENT_EYE
- sort_priority = 2
- quickbind = TRUE
- quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning."
-
-
//Vitality Matrix: Creates a sigil which will drain health from nonservants and can use that health to heal or even revive servants.
/datum/clockwork_scripture/create_object/vitality_matrix
descname = "Trap, Damage to Healing"
@@ -64,147 +65,35 @@
usage_tip = "The sigil will be consumed upon reviving a Servant."
tier = SCRIPTURE_SCRIPT
one_per_tile = TRUE
- primary_component = VANGUARD_COGWHEEL
+ primary_component = HIEROPHANT_ANSIBLE
sort_priority = 3
quickbind = TRUE
quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it."
-//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies
-/datum/clockwork_scripture/channeled/mending_mantra
- descname = "Channeled, Area Healing and Repair"
- name = "Mending Mantra"
- desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed. Channeled every two seconds for a maximum of twenty seconds."
- chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!")
- chant_amount = 10
- chant_interval = 20
- power_cost = 1000
- usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
- tier = SCRIPTURE_SCRIPT
- primary_component = VANGUARD_COGWHEEL
- sort_priority = 4
- quickbind = TRUE
- quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.
Maximum 10 chants."
- var/heal_attempts = 4
- var/heal_amount = 2.5
- var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
- var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
- "Ah, child, it's okay now.", "Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
- "If you die, you will be remembered.")
- var/static/list/heal_target_typecache = typecacheof(list(
- /obj/structure/destructible/clockwork,
- /obj/machinery/door/airlock/clockwork,
- /obj/machinery/door/window/clockwork,
- /obj/structure/window/reinforced/clockwork,
- /obj/structure/table/reinforced/brass))
- var/static/list/ratvarian_armor_typecache = typecacheof(list(
- /obj/item/clothing/suit/armor/clockwork,
- /obj/item/clothing/head/helmet/clockwork,
- /obj/item/clothing/gloves/clockwork,
- /obj/item/clothing/shoes/clockwork))
-
-/datum/clockwork_scripture/channeled/mending_mantra/chant_effects(chant_number)
- var/turf/T
- for(var/atom/movable/M in range(7, invoker))
- if(isliving(M))
- if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
- var/mob/living/simple_animal/S = M
- if(S.health == S.maxHealth || S.stat == DEAD)
- continue
- T = get_turf(M)
- for(var/i in 1 to heal_attempts)
- if(S.health < S.maxHealth)
- S.adjustHealth(-heal_amount)
- new /obj/effect/temp_visual/heal(T, "#1E8CE1")
- if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else if(issilicon(M))
- var/mob/living/silicon/S = M
- if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
- continue
- T = get_turf(M)
- for(var/i in 1 to heal_attempts)
- if(S.health < S.maxHealth)
- S.heal_ordered_damage(heal_amount, damage_heal_order)
- new /obj/effect/temp_visual/heal(T, "#1E8CE1")
- if(i == heal_attempts && S.health >= S.maxHealth)
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else
- to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.health == H.maxHealth || H.stat == DEAD || !is_servant_of_ratvar(H))
- continue
- T = get_turf(M)
- var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn
- var/obj/item/I = H.get_item_by_slot(slot_wear_suit)
- if(is_type_in_typecache(I, ratvarian_armor_typecache))
- heal_ticks++
- I = H.get_item_by_slot(slot_head)
- if(is_type_in_typecache(I, ratvarian_armor_typecache))
- heal_ticks++
- I = H.get_item_by_slot(slot_gloves)
- if(is_type_in_typecache(I, ratvarian_armor_typecache))
- heal_ticks++
- I = H.get_item_by_slot(slot_shoes)
- if(is_type_in_typecache(I, ratvarian_armor_typecache))
- heal_ticks++
- if(heal_ticks)
- for(var/i in 1 to heal_ticks)
- if(H.health < H.maxHealth)
- H.heal_ordered_damage(heal_amount, damage_heal_order)
- new /obj/effect/temp_visual/heal(T, "#1E8CE1")
- if(i == heal_ticks && H.health >= H.maxHealth)
- to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else
- to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"")
- break
- else if(is_type_in_typecache(M, heal_target_typecache))
- var/obj/structure/destructible/clockwork/C = M
- if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
- continue
- T = get_turf(M)
- for(var/i in 1 to heal_attempts)
- if(C.obj_integrity < C.max_integrity)
- C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity)
- C.update_icon()
- new /obj/effect/temp_visual/heal(T, "#1E8CE1")
- else
- break
- new /obj/effect/temp_visual/ratvar/mending_mantra(get_turf(invoker))
- return TRUE
-
-
-//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures.
-/datum/clockwork_scripture/create_object/replica_fabricator
- descname = "Replaces Objects with Ratvarian Versions"
- name = "Replica Fabricator"
- desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function."
- invocations = list("With this device...", "...his presence shall be made known.")
- channel_time = 20
- power_cost = 250
+//Judicial Visor: Creates a judicial visor, which can smite an area.
+/datum/clockwork_scripture/create_object/judicial_visor
+ descname = "Delayed Area Knockdown Glasses"
+ name = "Judicial Visor"
+ desc = "Creates a visor that can smite an area, applying Belligerent and briefly stunning. The smote area will explode after 3 seconds."
+ invocations = list("Grant me the flames of Engine!")
+ channel_time = 10
+ power_cost = 400
whispered = TRUE
- object_path = /obj/item/clockwork/replica_fabricator
- creator_message = "You form a replica fabricator."
- usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
+ object_path = /obj/item/clothing/glasses/judicial_visor
+ creator_message = "You form a judicial visor, which is capable of smiting a small area."
+ usage_tip = "The visor has a thirty-second cooldown once used."
tier = SCRIPTURE_SCRIPT
space_allowed = TRUE
- primary_component = REPLICANT_ALLOY
- sort_priority = 5
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 4
quickbind = TRUE
- quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants."
+ quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning."
//Clockwork Arnaments: Grants the invoker the ability to call forth a Ratvarian spear and clockwork armor.
/datum/clockwork_scripture/clockwork_arnaments
- descname = "Summonable Armor and Weapons"
+ descname = "Summonable Armor and Weapons - Important!"
name = "Clockwork Arnaments"
desc = "Allows the invoker to summon clockwork armor and a Ratvarian spear at will. The spear's attacks will generate Vitality, used for healing."
invocations = list("Grant me arnaments...", "...from the forge of Armorer!")
@@ -213,8 +102,8 @@
whispered = TRUE
usage_tip = "Throwing the spear at a mob will do massive damage and knock them down, but break the spear. You will need to wait for 30 seconds before resummoning it."
tier = SCRIPTURE_SCRIPT
- primary_component = REPLICANT_ALLOY
- sort_priority = 6
+ primary_component = VANGUARD_COGWHEEL
+ sort_priority = 5
quickbind = TRUE
quickbind_desc = "Permanently binds clockwork armor and a Ratvarian spear to you."
@@ -312,8 +201,8 @@
multiple_invokers_optional = TRUE
usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
tier = SCRIPTURE_SCRIPT
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 9
+ primary_component = GEIS_CAPACITOR
+ sort_priority = 6
quickbind = TRUE
quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
diff --git a/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm b/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm
new file mode 100644
index 0000000000..63c0182f7f
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm
@@ -0,0 +1,86 @@
+//No, not that kind.
+/obj/structure/destructible/clockwork/trap
+ name = "base clockwork trap"
+ desc = "You shouldn't see this. File a bug report!"
+ clockwork_desc = "A trap that shouldn't exist, and you should report this as a bug."
+ var/list/wired_to
+
+/obj/structure/destructible/clockwork/trap/Initialize()
+ . = ..()
+ wired_to = list()
+
+/obj/structure/destructible/clockwork/trap/Destroy()
+ for(var/V in wired_to)
+ var/obj/structure/destructible/clockwork/trap/T = V
+ T.wired_to -= src
+ return ..()
+
+/obj/structure/destructible/clockwork/trap/examine(mob/user)
+ ..()
+ if(is_servant_of_ratvar(user) || isobserver(user))
+ to_chat(user, "It's wired to:")
+ if(!wired_to.len)
+ to_chat(user, "Nothing.")
+ else
+ for(var/V in wired_to)
+ var/obj/O = V
+ var/distance = get_dist(src, O)
+ to_chat(user, "[O] ([distance == 0 ? "same tile" : "[distance] tiles [dir2text(get_dir(src, O))]"])")
+
+/obj/structure/destructible/clockwork/trap/wrench_act(mob/living/user, obj/item/wrench)
+ if(!is_servant_of_ratvar(user))
+ return ..()
+ to_chat(user, "You break down the delicate components of [src] into brass.")
+ playsound(src, wrench.usesound, 50, TRUE)
+ new/obj/item/stack/tile/brass(get_turf(src))
+ qdel(src)
+ return TRUE
+
+/obj/structure/destructible/clockwork/trap/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/clockwork/slab) && is_servant_of_ratvar(user))
+ var/obj/item/clockwork/slab/F = I
+ if(!F.linking)
+ to_chat(user, "Beginning link. Alt-click the slab to cancel, or use it on another trap object to link the two.")
+ F.linking = src
+ else
+ if(F.linking in wired_to)
+ to_chat(user, "These two objects are already connected!")
+ return
+ if(F.linking.z != z)
+ to_chat(user, "You'd need a much tougher slab to link two objects in different sectors.")
+ return
+ to_chat(user, "You link [F.linking] with [src].")
+ wired_to += F.linking
+ F.linking.wired_to += src
+ F.linking = null
+ return
+ ..()
+
+/obj/structure/destructible/clockwork/trap/wirecutter_act(mob/living/user, obj/item/wirecutters)
+ if(!is_servant_of_ratvar(user))
+ return
+ if(!wired_to.len)
+ to_chat(user, "[src] has no connections!")
+ return
+ to_chat(user, "You sever all connections to [src].")
+ playsound(src, wirecutters.usesound, 50, TRUE)
+ for(var/V in wired_to)
+ var/obj/structure/destructible/clockwork/trap/T = V
+ T.wired_to -= src
+ wired_to -= T
+ return TRUE
+
+/obj/structure/destructible/clockwork/trap/proc/activate()
+
+//These objects send signals to normal traps to activate
+/obj/structure/destructible/clockwork/trap/trigger
+ name = "base trap trigger"
+ max_integrity = 5
+ break_message = "The trigger breaks apart!"
+ density = FALSE
+
+/obj/structure/destructible/clockwork/trap/trigger/activate()
+ for(var/obj/structure/destructible/clockwork/trap/T in wired_to)
+ if(istype(T, /obj/structure/destructible/clockwork/trap/trigger)) //Triggers don't go off multiple times
+ continue
+ T.activate()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
index 0f13ac66ac..63fea1eeb6 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
@@ -26,6 +26,9 @@
var/fourth_sound_played = FALSE
var/obj/effect/clockwork/overlay/gateway_glow/glow
var/obj/effect/countdown/clockworkgate/countdown
+ var/last_scream = 0
+ var/recalls_remaining = 1
+ var/recalling
/obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize()
. = ..()
@@ -34,7 +37,21 @@
GLOB.ark_of_the_clockwork_justiciar = src
START_PROCESSING(SSprocessing, src)
-/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
+ . = ..()
+ if(.)
+ flick("clockwork_gateway_damaged", glow)
+ playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
+ if(last_scream < world.time)
+ audible_message("An unearthly screaming sound resonates throughout Reebe!")
+ for(var/V in GLOB.player_list)
+ var/mob/M = V
+ if(M.z == z || is_servant_of_ratvar(M) || isobserver(M))
+ M.playsound_local(M, 'sound/machines/clockcult/ark_scream.ogg', 100, FALSE, pressure_affected = FALSE)
+ hierophant_message("The Ark is taking damage!")
+ last_scream = world.time + ARK_SCREAM_COOLDOWN
+
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time) //WE'RE LEAVING TOGETHEEEEEEEEER
if(!ark_time)
ark_time = 30 //minutes
initial_activation_delay = ark_time * 60
@@ -58,13 +75,17 @@
active = TRUE
priority_announce("Massive [Gibberish("bluespace", 100)] anomaly detected on all frequencies. All crew are directed to \
@!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \
- not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare." : ""]", \
+ not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare for an attack on [station_name()]." : ""]", \
"Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg')
set_security_level("delta")
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
if(ishuman(M.current))
M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
+ for(var/V in GLOB.brass_recipes)
+ var/datum/stack_recipe/R = V
+ if(R.title == "wall gear")
+ R.time *= 2 //Building walls becomes slower when the Ark activates
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/open_portal(turf/T)
new/obj/effect/clockwork/city_of_cogs_rift(T)
@@ -83,6 +104,25 @@
seconds_until_activation = 0
SSshuttle.registerHostileEnvironment(src)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/initiate_mass_recall()
+ recalling = TRUE
+ sound_to_playing_players('sound/machines/clockcult/ark_recall.ogg', 75, FALSE)
+ hierophant_message("The Eminence has initiated a mass recall! You are being transported to the Ark!")
+ addtimer(CALLBACK(src, .proc/mass_recall), 100)
+
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/mass_recall()
+ for(var/V in SSticker.mode.servants_of_ratvar)
+ var/datum/mind/M = V
+ if(!M.current.stat)
+ M.current.forceMove(get_turf(src))
+ M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
+ M.current.clear_fullscreen("flash", 5)
+ playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, FALSE)
+ recalls_remaining--
+ recalling = FALSE
+ transform = matrix() * 2
+ animate(src, transform = matrix() * 0.5, time = 30, flags = ANIMATION_END_NOW)
+
/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
STOP_PROCESSING(SSprocessing, src)
SSshuttle.clearHostileEnvironment(src)
@@ -117,6 +157,9 @@
countdown.stop()
visible_message("[src] begins to pulse uncontrollably... you might want to run!")
sound_to_playing_players(volume = 50, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_disrupted.ogg'))
+ for(var/mob/M in GLOB.player_list)
+ if(M.z == z || is_servant_of_ratvar(M))
+ M.playsound_local(M, 'sound/machines/clockcult/ark_deathrattle.ogg', 100, FALSE, pressure_affected = FALSE)
make_glow()
glow.icon_state = "clockwork_gateway_disrupted"
resistance_flags |= INDESTRUCTIBLE
diff --git a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm
new file mode 100644
index 0000000000..8d4e936658
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm
@@ -0,0 +1,126 @@
+//Used to nominate oneself or ghosts for the role of Eminence.
+/obj/structure/destructible/clockwork/eminence_spire
+ name = "eminence spire"
+ desc = "A hulking machine made of powerful alloy, with three small obelisks and a huge plate in the center."
+ clockwork_desc = "This spire is used to become the Eminence, who functions as an invisible leader of the cult. Activate it to nominate yourself or propose that the Eminence should be \
+ selected from available ghosts. Once an Eminence is selected, they can't normally be changed."
+ icon_state = "tinkerers_daemon"
+ break_message = "The spire screeches with crackling power and collapses into scrap!"
+ max_integrity = 400
+ var/mob/eminence_nominee
+ var/selection_timer //Timer ID; this is canceled if the vote is canceled
+ var/kingmaking
+
+/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user)
+ if(!is_servant_of_ratvar(user))
+ to_chat(user, "You can tell how powerful [src] is; you know better than to touch it.")
+ return
+ if(kingmaking)
+ return
+ if(SSticker.mode.eminence)
+ to_chat(user, "There's already an Eminence!")
+ return
+ if(!GLOB.servants_active)
+ to_chat(user, "The Ark isn't active!")
+ return
+ if(eminence_nominee) //This could be one large proc, but is split into three for ease of reading
+ if(eminence_nominee == user)
+ cancelation(user)
+ else
+ objection(user)
+ else
+ nomination(user)
+
+/obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user)
+ if(!IsAdminGhost(user))
+ return
+ if(SSticker.mode.eminence)
+ to_chat(user, "There's already an Eminence - too late!")
+ return
+ if(!GLOB.servants_active)
+ to_chat(user, "The Ark must be active first!")
+ return
+ if(alert(user, "Become the Eminence using admin?", "Become Eminence", "Yes", "No") != "Yes")
+ return
+ message_admins("Admin [key_name_admin(user)] directly became the Eminence of the cult!")
+ log_admin("Admin [key_name(user)] made themselves the Eminence.")
+ var/mob/camera/eminence/eminence = new(get_turf(src))
+ eminence.key = user.key
+ hierophant_message("Ratvar has directly assigned the Eminence!")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
+
+/obj/structure/destructible/clockwork/eminence_spire/proc/nomination(mob/living/nominee) //A user is nominating themselves or ghosts to become Eminence
+ var/nomination_choice = alert(nominee, "Who would you like to nominate?", "Eminence Nomination", "Nominate Yourself", "Nominate Ghosts", "Cancel")
+ if(!is_servant_of_ratvar(nominee) || !nominee.canUseTopic(src) || eminence_nominee)
+ return
+ switch(nomination_choice)
+ if("Cancel")
+ return
+ if("Nominate Yourself")
+ eminence_nominee = nominee
+ hierophant_message("[nominee] nominates themselves as the Eminence! You may object by interacting with the eminence spire. The vote will otherwise pass in 30 seconds.")
+ if("Nominate Ghosts")
+ eminence_nominee = "ghosts"
+ hierophant_message("[nominee] proposes selecting an Eminence from ghosts! You may object by interacting with the eminence spire. The vote will otherwise pass in 30 seconds.")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/ocularwarden-target.ogg', 50, FALSE)
+ selection_timer = addtimer(CALLBACK(src, .proc/kingmaker), 300, TIMER_STOPPABLE)
+
+/obj/structure/destructible/clockwork/eminence_spire/proc/objection(mob/living/wright)
+ if(alert(wright, "Object to the selection of [eminence_nominee] as Eminence?", "Objection!", "Object", "Cancel") == "Cancel" || !is_servant_of_ratvar(wright) || !wright.canUseTopic(src) || !eminence_nominee)
+ return
+ hierophant_message("[wright] objects to the nomination of [eminence_nominee]! The eminence spire has been reset.")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE)
+ eminence_nominee = null
+ deltimer(selection_timer)
+
+/obj/structure/destructible/clockwork/eminence_spire/proc/cancelation(mob/living/cold_feet)
+ if(alert(cold_feet, "Cancel your nomination?", "Cancel Nomination", "Withdraw Nomination", "Cancel") == "Cancel" || !is_servant_of_ratvar(cold_feet) || !cold_feet.canUseTopic(src) || !eminence_nominee)
+ return
+ hierophant_message("[eminence_nominee] has withdrawn their nomination! The eminence spire has been reset.")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE)
+ eminence_nominee = null
+ deltimer(selection_timer)
+
+/obj/structure/destructible/clockwork/eminence_spire/proc/kingmaker()
+ if(!eminence_nominee)
+ return
+ if(ismob(eminence_nominee))
+ if(!eminence_nominee.client || !eminence_nominee.mind)
+ hierophant_message("[eminence_nominee] somehow lost their sentience! The eminence spire has been reset.")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE)
+ eminence_nominee = null
+ return
+ playsound(eminence_nominee, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE)
+ eminence_nominee.visible_message("A blast of white-hot light flows into [eminence_nominee], vaporizing them in an instant!", \
+ "allthelightintheuniverseflowing.into.YOU")
+ for(var/obj/item/I in eminence_nominee)
+ eminence_nominee.dropItemToGround(I)
+ var/mob/camera/eminence/eminence = new(get_turf(src))
+ eminence_nominee.mind.transfer_to(eminence)
+ eminence_nominee.dust()
+ hierophant_message("[eminence_nominee] has ascended into the Eminence!")
+ else if(eminence_nominee == "ghosts")
+ kingmaking = TRUE
+ hierophant_message("The eminence spire is now selecting a ghost to be the Eminence...")
+ var/list/candidates = pollGhostCandidates("Would you like to play as the servants' Eminence?", "Servant of Ratvar", null, ROLE_SERVANT_OF_RATVAR, poll_time = 100)
+ kingmaking = FALSE
+ if(!candidates.len)
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE)
+ hierophant_message("No ghosts accepted the offer! The eminence spire has been reset.")
+ eminence_nominee = null
+ return
+ visible_message("A blast of white-hot light spirals from [src] in waves!")
+ playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE)
+ var/mob/camera/eminence/eminence = new(get_turf(src))
+ eminence_nominee = pick(candidates)
+ eminence.key = eminence_nominee.key
+ hierophant_message("A ghost has ascended into the Eminence!")
+ for(var/mob/M in servants_and_ghosts())
+ M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
+ eminence_nominee = null
diff --git a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm
index 9f18ff1669..2be948d7ca 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm
@@ -106,3 +106,4 @@
H.set_species(/datum/species/golem/clockwork/no_scrap)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
G.grace_period = FALSE //no grace period if we've declared war
+ G.recalls_remaining++
diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm
new file mode 100644
index 0000000000..4d11cc5f39
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm
@@ -0,0 +1,14 @@
+//Lever: Do I really need to explain this?
+/obj/structure/destructible/clockwork/trap/trigger/lever
+ name = "lever"
+ desc = "A fancy lever made of wood and capped with brass."
+ clockwork_desc = "A fancy lever.that activates when pulled."
+ max_integrity = 75
+ icon_state = "lever"
+
+/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user)
+ user.visible_message("[user] pulls [src]!", "You pull [src]. It clicks, then lifts back upwards.")
+ if(wired_to.len)
+ audible_message("You hear gears clanking.")
+ playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
+ activate()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm
new file mode 100644
index 0000000000..f6a7b8e347
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm
@@ -0,0 +1,26 @@
+//Pressure sensor: Activates when stepped on.
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor
+ name = "pressure sensor"
+ desc = "A thin plate of brass, barely visible but clearly distinct."
+ clockwork_desc = "A trigger that will activate when a non-servant runs across it."
+ max_integrity = 25
+ icon_state = "pressure_sensor"
+ alpha = 80
+ layer = LOW_ITEM_LAYER
+
+/obj/structure/destructible/clockwork/trap/trigger/Initialize()
+ . = ..()
+ for(var/obj/structure/destructible/clockwork/trap/T in get_turf(src))
+ if(!istype(T, /obj/structure/destructible/clockwork/trap/trigger))
+ wired_to += T
+ T.wired_to += src
+ to_chat(usr, "[src] automatically links with [T] beneath it.")
+
+/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/Crossed(atom/movable/AM)
+ if(isliving(AM) && !is_servant_of_ratvar(AM))
+ var/mob/living/L = AM
+ if(L.stat || L.m_intent == MOVE_INTENT_WALK || L.lying)
+ return
+ audible_message("*click*")
+ playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE)
+ activate()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm
new file mode 100644
index 0000000000..68e8cc00e8
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm
@@ -0,0 +1,27 @@
+//Repeater: Activates every second.
+/obj/structure/destructible/clockwork/trap/trigger/repeater
+ name = "repeater"
+ desc = "A small black prism with a gem in the center."
+ clockwork_desc = "A repeater that will send an activation signal every second."
+ max_integrity = 15 //Fragile!
+ icon_state = "repeater"
+
+/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user)
+ if(!is_servant_of_ratvar(user))
+ return
+ if(!isprocessing)
+ START_PROCESSING(SSprocessing, src)
+ to_chat(user, "You activate [src].")
+ icon_state = "[icon_state]_on"
+ else
+ STOP_PROCESSING(SSprocessing, src)
+ to_chat(user, "You halt [src]'s ticking.")
+ icon_state = initial(icon_state)
+
+/obj/structure/destructible/clockwork/trap/trigger/repeater/process()
+ activate()
+ playsound(src, 'sound/items/screwdriver2.ogg', 25, FALSE)
+
+/obj/structure/destructible/clockwork/trap/trigger/repeater/Destroy()
+ STOP_PROCESSING(SSprocessing, src)
+ return ..()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm
new file mode 100644
index 0000000000..d79ca88ecb
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm
@@ -0,0 +1,106 @@
+//Non-servants standing over this will get spikes through the feet, immobilizing them until they're freed.
+/obj/structure/destructible/clockwork/trap/brass_skewer
+ name = "brass skewer"
+ desc = "A deadly brass spike, cleverly concealed in the floor. You think you should be safe if you disarm whatever's meant to set it off."
+ clockwork_desc = "A barbaric but undeniably effective weapon: a spear through the chest. It immobilizes anyone unlucky enough to step on it and keeps them in place until they get help.."
+ icon_state = "brass_skewer"
+ break_message = "The skewer snaps in two!"
+ max_integrity = 40
+ density = FALSE
+ can_buckle = TRUE
+ buckle_prevents_pull = TRUE
+ buckle_lying = FALSE
+ var/wiggle_wiggle
+ var/mutable_appearance/impale_overlay //This is applied to any mob impaled so that they visibly have the skewer coming through their chest
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/Initialize()
+ . = ..()
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ if(buckled_mobs && buckled_mobs.len)
+ var/mob/living/L = buckled_mobs[1]
+ L.Knockdown(100)
+ L.visible_message("[L] is maimed as the skewer shatters while still in their body!")
+ L.adjustBruteLoss(15)
+ unbuckle_mob(L)
+ return ..()
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/process()
+ if(density)
+ if(buckled_mobs.len)
+ var/mob/living/spitroast = buckled_mobs[1]
+ spitroast.adjustBruteLoss(0.1)
+
+/obj/structure/destructible/clockwork/trap/attackby(obj/item/I, mob/living/user, params)
+ if(user in buckled_mobs)
+ to_chat(user, "You can't reach!")
+ return
+ ..()
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/bullet_act(obj/item/projectile/P)
+ if(buckled_mobs.len)
+ var/mob/living/L = buckled_mobs[1]
+ return L.bullet_act(P)
+ return ..()
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/activate()
+ if(density)
+ return
+ var/mob/living/carbon/squirrel = locate() in get_turf(src)
+ if(squirrel)
+ squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \
+ "A massive brass spike rams through your chest, hoisting you into the air!")
+ squirrel.emote("scream")
+ playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE)
+ playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE)
+ squirrel.apply_damage(20, BRUTE, "chest")
+ mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off
+ buckle_mob(squirrel, TRUE)
+ else
+ visible_message("A massive brass spike erupts from the ground!")
+ playsound(src, 'sound/machines/clockcult/brass_skewer.ogg', 75, FALSE)
+ icon_state = "[initial(icon_state)]_extended"
+ density = TRUE //Skewers are one-use only
+ desc = "A vicious brass spike protruding from the ground like a stala[pick("gm", "ct")]ite. It makes you sick to look at." //is stalagmite the ground one? or the ceiling one? who can ever remember?
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/user_buckle_mob()
+ return
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/post_buckle_mob(mob/living/L)
+ if(L in buckled_mobs)
+ L.pixel_y = 3
+ impale_overlay = mutable_appearance('icons/obj/clockwork_objects.dmi', "brass_skewer_pokeybit", ABOVE_MOB_LAYER)
+ add_overlay(impale_overlay)
+ else
+ L.pixel_y = initial(L.pixel_y)
+ L.cut_overlay(impale_overlay)
+
+/obj/structure/destructible/clockwork/trap/brass_skewer/user_unbuckle_mob(mob/living/skewee, mob/living/user)
+ if(user == skewee)
+ if(wiggle_wiggle)
+ return
+ user.visible_message("[user] starts wriggling off of [src]!", \
+ "You start agonizingly working your way off of [src]...")
+ wiggle_wiggle = TRUE
+ if(!do_after(user, 300, target = user))
+ user.visible_message("[user] slides back down [src]!")
+ user.emote("scream")
+ user.apply_damage(10, BRUTE, "chest")
+ playsound(user, 'sound/misc/desceration-03.ogg', 50, TRUE)
+ wiggle_wiggle = FALSE
+ return
+ wiggle_wiggle = FALSE
+ else
+ user.visible_message("You start tenderly lifting [user] off of [src]...", \
+ "You start tenderly lifting [user] off of [src]...")
+ if(!do_after(user, 60, target = skewee))
+ skewee.visible_message("[skewee] painfully slides back down [src].")
+ skewee.emote("moan")
+ return
+ skewee.visible_message("[skewee] comes free of [src] with a squelching pop!", \
+ "You come free of [src]!")
+ skewee.Knockdown(30)
+ playsound(skewee, 'sound/misc/desceration-03.ogg', 50, TRUE)
+ unbuckle_mob(skewee)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm
new file mode 100644
index 0000000000..6aede1592e
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm
@@ -0,0 +1,23 @@
+//This doesn't function like a "trap" in of itself, but obscures vision when active.
+/obj/structure/destructible/clockwork/trap/steam_vent
+ name = "steam vent"
+ desc = "Some wired slats embedded in the floor. They feel warm to the touch."
+ icon_state = "steam_vent_0"
+ clockwork_desc = "When active, these vents will billow out clouds of excess steam from Reebe, obscuring vision."
+ break_message = "The vent snaps and collapses!"
+ max_integrity = 100
+ density = FALSE
+
+/obj/structure/destructible/clockwork/trap/steam_vent/activate()
+ opacity = !opacity
+ icon_state = "steam_vent_[opacity]"
+ if(opacity)
+ playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, TRUE)
+
+ else
+ playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
+
+/obj/structure/destructible/clockwork/trap/steam_vent/Crossed(atom/movable/AM)
+ if(isliving(AM) && opacity)
+ var/mob/living/L = AM
+ L.adjust_fire_stacks(-1) //It's wet!
diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm
index 49e962eba2..d9861d827d 100644
--- a/code/game/objects/effects/temporary_visuals/clockcult.dm
+++ b/code/game/objects/effects/temporary_visuals/clockcult.dm
@@ -253,3 +253,17 @@
. = ..()
animate(src, alpha = 255, time = 50)
+//Used by the Eminence to coordinate the cult
+/obj/effect/temp_visual/ratvar/command_point
+ name = "command marker"
+ desc = "An area of importance marked by the Eminence."
+ icon = 'icons/mob/actions/actions_clockcult.dmi'
+ icon_state = "eminence"
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ resistance_flags = INDESTRUCTIBLE
+ layer = MASSIVE_OBJ_LAYER
+ duration = 300
+
+/obj/effect/temp_visual/ratvar/command_point/Initialize(mapload, appearance)
+ . = ..()
+ icon_state = appearance
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 88bccfe204..c22cbbc0bc 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -333,7 +333,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
* Brass
*/
GLOBAL_LIST_INIT(brass_recipes, list ( \
- new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
null,
new/datum/stack_recipe("pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
@@ -342,7 +342,14 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE) \
+ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
+ null,
+ new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
+ null,
+ new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/tile/brass
diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm
index bb45e2df20..4d48c86934 100644
--- a/code/game/turfs/simulated/wall/misc_walls.dm
+++ b/code/game/turfs/simulated/wall/misc_walls.dm
@@ -56,6 +56,7 @@
sheet_amount = 1
girder_type = /obj/structure/destructible/clockwork/wall_gear
baseturf = /turf/open/floor/clockwork/reebe
+ var/heated
var/obj/effect/clockwork/overlay/wall/realappearence
/turf/closed/wall/clockwork/Initialize()
@@ -110,6 +111,36 @@
for(var/i in 1 to 3)
new/obj/item/clockwork/alloy_shards/small(src)
+/turf/closed/wall/clockwork/attack_hulk(mob/living/user, does_attack_animation = 0)
+ ..()
+ if(heated)
+ to_chat(user, "The wall is searing hot to the touch!")
+ user.adjustFireLoss(5)
+ playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE)
+
+/turf/closed/wall/clockwork/mech_melee_attack(obj/mecha/M)
+ ..()
+ if(heated)
+ to_chat(M.occupant, "The wall's intense heat completely reflects your [M.name]'s attack!")
+ M.take_damage(20, BURN)
+
+/turf/closed/wall/clockwork/proc/turn_up_the_heat()
+ if(!heated)
+ name = "superheated [name]"
+ visible_message("[src] sizzles with heat!")
+ playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE)
+ heated = TRUE
+ hardness = -100 //Lower numbers are tougher, so this makes the wall essentially impervious to smashing
+ slicing_duration = 150
+ animate(realappearence, color = "#FFC3C3", time = 5)
+ else
+ name = initial(name)
+ visible_message("[src] cools down.")
+ heated = FALSE
+ hardness = initial(hardness)
+ slicing_duration = initial(slicing_duration)
+ animate(realappearence, color = initial(realappearence.color), time = 25)
+
/turf/closed/wall/vault
icon = 'icons/turf/walls.dmi'
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index ffbeb1f503..de5d38e0bb 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -962,7 +962,7 @@
playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE)
var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc)
H.setDir(dir)
- dust()
+ qdel(src)
/mob/living/simple_animal/parrot/Poly/ghost
name = "The Ghost of Poly"
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index 102fc01000..644d2a0860 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ
diff --git a/icons/effects/clockwork_effects.dmi b/icons/effects/clockwork_effects.dmi
index fa3bfa36e6..5d6082dc2b 100644
Binary files a/icons/effects/clockwork_effects.dmi and b/icons/effects/clockwork_effects.dmi differ
diff --git a/icons/mob/actions/actions_clockcult.dmi b/icons/mob/actions/actions_clockcult.dmi
index 19fd68f836..4aad4ba569 100644
Binary files a/icons/mob/actions/actions_clockcult.dmi and b/icons/mob/actions/actions_clockcult.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
index 561359959b..784c0f55eb 100644
Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ
diff --git a/sound/machines/clockcult/ark_damage.ogg b/sound/machines/clockcult/ark_damage.ogg
new file mode 100644
index 0000000000..40ccfc6219
Binary files /dev/null and b/sound/machines/clockcult/ark_damage.ogg differ
diff --git a/sound/machines/clockcult/ark_deathrattle.ogg b/sound/machines/clockcult/ark_deathrattle.ogg
new file mode 100644
index 0000000000..916ff0429e
Binary files /dev/null and b/sound/machines/clockcult/ark_deathrattle.ogg differ
diff --git a/sound/machines/clockcult/ark_recall.ogg b/sound/machines/clockcult/ark_recall.ogg
new file mode 100644
index 0000000000..a38a0b765b
Binary files /dev/null and b/sound/machines/clockcult/ark_recall.ogg differ
diff --git a/sound/machines/clockcult/ark_scream.ogg b/sound/machines/clockcult/ark_scream.ogg
new file mode 100644
index 0000000000..acdc7c85db
Binary files /dev/null and b/sound/machines/clockcult/ark_scream.ogg differ
diff --git a/sound/machines/clockcult/brass_skewer.ogg b/sound/machines/clockcult/brass_skewer.ogg
new file mode 100644
index 0000000000..927bf9b275
Binary files /dev/null and b/sound/machines/clockcult/brass_skewer.ogg differ
diff --git a/sound/machines/clockcult/eminence_command.ogg b/sound/machines/clockcult/eminence_command.ogg
new file mode 100644
index 0000000000..59a4e3f26d
Binary files /dev/null and b/sound/machines/clockcult/eminence_command.ogg differ
diff --git a/sound/machines/clockcult/eminence_selected.ogg b/sound/machines/clockcult/eminence_selected.ogg
new file mode 100644
index 0000000000..6d1175faf7
Binary files /dev/null and b/sound/machines/clockcult/eminence_selected.ogg differ
diff --git a/strings/clockwork_cult_changelog.txt b/strings/clockwork_cult_changelog.txt
new file mode 100644
index 0000000000..b5d2ca10e3
--- /dev/null
+++ b/strings/clockwork_cult_changelog.txt
@@ -0,0 +1,7 @@
+Added the Eminence, a leader role that servants can become by interacting with the new eminence spire structure in Reebe.
+Scripture has been re-colored in the slab interface to show its niche at a glance.
+Added traps, including the brass skewer and steam vent.
+Added trap triggers, including the pressure sensor, lever, and repeater.
+Traps and trap triggers can be linked by using your clockwork slab on them. Traps chained to each other will cause those traps to activate as well.
+You can instantly remove traps you misplace by using a wrench on them.
+Mending Mantra has been removed.
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index e8b81cbbb8..d78d24b53e 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -556,13 +556,16 @@
#include "code\game\gamemodes\clock_cult\clock_items\wraith_spectacles.dm"
#include "code\game\gamemodes\clock_cult\clock_items\clock_weapons\_call_weapon.dm"
#include "code\game\gamemodes\clock_cult\clock_items\clock_weapons\ratvarian_spear.dm"
+#include "code\game\gamemodes\clock_cult\clock_mobs\_eminence.dm"
#include "code\game\gamemodes\clock_cult\clock_mobs\clockwork_marauder.dm"
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_applications.dm"
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_cyborg.dm"
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_drivers.dm"
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_scripts.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\_trap_object.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\ark_of_the_clockwork_justicar.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\clockwork_obelisk.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\eminence_spire.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\heralds_beacon.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\mania_motor.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\ocular_warden.dm"
@@ -570,6 +573,11 @@
#include "code\game\gamemodes\clock_cult\clock_structures\stargazer.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\taunting_trail.dm"
#include "code\game\gamemodes\clock_cult\clock_structures\wall_gear.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\lever.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\pressure_sensor.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\repeater.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\traps\brass_skewer.dm"
+#include "code\game\gamemodes\clock_cult\clock_structures\traps\steam_vent.dm"
#include "code\game\gamemodes\cult\cult.dm"
#include "code\game\gamemodes\cult\cult_comms.dm"
#include "code\game\gamemodes\cult\cult_items.dm"
diff --git a/tgui/src/interfaces/clockwork_slab.ract b/tgui/src/interfaces/clockwork_slab.ract
index af429cc904..48f6ae02f6 100644
--- a/tgui/src/interfaces/clockwork_slab.ract
+++ b/tgui/src/interfaces/clockwork_slab.ract
@@ -22,6 +22,9 @@
Scripts
Applications
{{{data.tier_info}}}
+
+
+ {{{data.scripturecolors}}}
{{#each data.scripture}}