diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm
index 9ef765aa28..aba6569fd9 100644
--- a/_maps/map_files/generic/City_of_Cogs.dmm
+++ b/_maps/map_files/generic/City_of_Cogs.dmm
@@ -80,10 +80,6 @@
},
/turf/open/floor/clockwork/reebe,
/area/reebe/city_of_cogs)
-"az" = (
-/obj/structure/destructible/clockwork/eminence_spire,
-/turf/open/floor/clockwork/reebe,
-/area/reebe/city_of_cogs)
"aA" = (
/obj/machinery/door/airlock/clockwork/brass{
name = "Infirmary"
@@ -168,21 +164,6 @@
/obj/effect/clockwork/sigil/transmission,
/turf/open/floor/clockwork/reebe,
/area/reebe/city_of_cogs)
-"ew" = (
-/obj/structure/table/reinforced/brass,
-/obj/item/clockwork/construct_chassis/cogscarab{
- pixel_y = 20
- },
-/obj/item/clockwork/construct_chassis/cogscarab{
- pixel_x = -7;
- pixel_y = 6
- },
-/obj/item/clockwork/construct_chassis/cogscarab{
- pixel_x = 7;
- pixel_y = 6
- },
-/turf/open/floor/clockwork/reebe,
-/area/reebe/city_of_cogs)
"hY" = (
/obj/item/clockwork/alloy_shards/pinion_lock,
/turf/open/floor/clockwork/reebe,
@@ -208,10 +189,6 @@
/obj/item/storage/belt/utility/servant,
/turf/open/floor/clockwork/reebe,
/area/reebe/city_of_cogs)
-"vx" = (
-/obj/effect/clockwork/sigil/transmission,
-/turf/open/floor/clockwork/reebe,
-/area/reebe/city_of_cogs)
"wV" = (
/obj/item/clockwork/alloy_shards/large,
/turf/open/indestructible/reebe_void/spawning/lattices,
@@ -244,6 +221,10 @@
/obj/item/clockwork/alloy_shards/small,
/turf/open/indestructible/reebe_void/spawning/lattices,
/area/reebe)
+"Ox" = (
+/obj/structure/destructible/clockwork/eminence_spire,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
"OB" = (
/obj/item/clockwork/component/geis_capacitor/fallen_armor,
/turf/open/floor/clockwork/reebe,
@@ -32770,7 +32751,7 @@ ae
ae
ag
ah
-ew
+aL
aj
aj
aj
@@ -33284,8 +33265,8 @@ ab
ab
ae
ai
-az
-vx
+Ox
+aj
aj
aj
aE
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index faffea0e6e..ea48671d82 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -59,6 +59,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
//Human sub-species
#define isabductor(A) (is_species(A, /datum/species/abductor))
#define isgolem(A) (is_species(A, /datum/species/golem))
+#define isclockworkgolem(A) (is_species(A, /datum/species/golem/clockwork/no_scrap))
#define islizard(A) (is_species(A, /datum/species/lizard))
#define isplasmaman(A) (is_species(A, /datum/species/plasmaman))
#define ispodperson(A) (is_species(A, /datum/species/pod))
diff --git a/code/_onclick/hud/clockwork_marauder.dm b/code/_onclick/hud/clockwork_marauder.dm
index 09f85db574..b1b24cc58b 100644
--- a/code/_onclick/hud/clockwork_marauder.dm
+++ b/code/_onclick/hud/clockwork_marauder.dm
@@ -3,7 +3,7 @@
var/obj/screen/blockchance
var/obj/screen/counterchance
-/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner)
+/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/guardian/owner)
..()
var/obj/screen/using
@@ -24,7 +24,7 @@
hosthealth = null
return ..()
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud()
+/mob/living/simple_animal/hostile/clockwork/guardian/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style))
@@ -37,8 +37,8 @@
desc = "Emerge or Return."
/obj/screen/marauder/emerge/Click()
- if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian))
- var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr
+ if(istype(usr, /mob/living/simple_animal/hostile/clockwork/guardian))
+ var/mob/living/simple_animal/hostile/clockwork/guardian/G = usr
if(G.is_in_host())
G.try_emerge()
else
diff --git a/code/datums/skills/modifiers/job.dm b/code/datums/skills/modifiers/job.dm
index e989ab11e3..e751fbf120 100644
--- a/code/datums/skills/modifiers/job.dm
+++ b/code/datums/skills/modifiers/job.dm
@@ -34,3 +34,6 @@
/datum/skill_modifier/job/level/wiring/basic
level_mod = JOB_SKILL_BASIC
+
+/datum/skill_modifier/job/level/dwarfy/blacksmithing
+ target_skills = /datum/skill/level/dwarfy/blacksmithing
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index b868fb54c0..34370faa0a 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -144,7 +144,7 @@
to_chat(L, "\"You belong to me now.\"")
if(!GLOB.application_scripture_unlocked)
GLOB.application_scripture_unlocked = TRUE
- hierophant_message("With the conversion of a new servant the Ark's power grows. Application scriptures are now available.")
+ hierophant_message("With the conversion of a new servant the Hierophant Network's power grows. Application scriptures are now available.")
if(add_servant_of_ratvar(L))
L.log_message("conversion was done with a [sigil_name]", LOG_ATTACK, color="BE8700")
if(iscarbon(L))
diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm
index 58ee73ef5b..2b2720dea3 100644
--- a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm
+++ b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm
@@ -196,4 +196,68 @@
CL.visible_message("[CL] materialises out of thin air!")
new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2)
+//summons a soul vessel, which is the clockwork cult version of a soul shard. It acts like a posibrain and, as long as the target has a brain, a soul shard.
+/datum/clockwork_rite/soul_vessel
+ name = "Rite of the Vessel" //The name of the rite
+ desc = "This rite is used to summon a soul vessel, a special posibrain that makes whoever has their brain put into it loyal to the Justiciar.,\
+ When put into a cyborg shell, the created cyborg will automatically be a servant of Ratvar."
+ required_ingredients = list(/obj/item/stack/cable_coil, /obj/item/stock_parts/cell/, /obj/item/organ/cyberimp)
+ power_cost = 2500 //These things are pretty strong, I won't lie
+ requires_full_power = TRUE
+ cast_time = 50
+ limit = INFINITE
+ rite_cast_sound = 'sound/magic/summon_guns.ogg'
+
+/datum/clockwork_rite/soul_vessel/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ . = ..()
+ if(!.)
+ return FALSE
+ var/obj/item/mmi/posibrain/soul_vessel/SV = new /obj/item/mmi/posibrain/soul_vessel(T)
+ SV.visible_message("[SV] materalizes out of thin air!")
+ new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2)
+
+
+/datum/clockwork_rite/cyborg_transform
+ name = "Rite of the Divine Form"
+ desc = "This rite is used to ascend into a cyborg, gaining unique scripture and a loadout that depends on which module is chosen. Consult the wiki for details on each cyborg module's loadout. Mutually exclusive to Enhanced Form."
+ required_ingredients = list(/obj/item/mmi/posibrain, /obj/item/stack/cable_coil, /obj/item/stock_parts/cell/super, /obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/l_leg/robot)
+ power_cost = 20000
+ requires_human = TRUE
+ requires_full_power = FALSE
+ cast_time = 100
+ limit = INFINITE
+ rite_cast_sound = 'sound/magic/disable_tech.ogg'
+
+/datum/clockwork_rite/cyborg_transform/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(isclockworkgolem(target))
+ return FALSE
+ target.visible_message("The robotic parts magnetize to [target], the new frame's eyes glowing in a brilliant yellow!")
+ var/mob/living/silicon/robot/R = target.Robotize()
+ R.cell = new /obj/item/stock_parts/cell/super(R)//takes one to use the rite to begin with
+ new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2)
+
+/datum/clockwork_rite/golem_transform
+ name = "Rite of the Enhanced Form"
+ desc = "This rite is used to shed one's flesh to become a clockwork automaton, becoming immune to many environmental hazards as well as being more resilient to incoming damage. Mutually exclusive to Divine Form."
+ required_ingredients = list(/obj/item/mmi/posibrain, /obj/item/stock_parts/cell/super, /obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/l_leg/robot)
+ power_cost = 20000
+ requires_human = TRUE
+ requires_full_power = FALSE
+ cast_time = 100
+ limit = INFINITE
+ rite_cast_sound = 'sound/magic/disable_tech.ogg'
+
+
+/datum/clockwork_rite/golem_transform/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target)
+ . = ..()
+ if(!.)
+ return FALSE
+ target.visible_message("The robotic parts magnetize to [target], the humanoid shape's eye glowing with an inner flame!")
+ to_chat(target, "The rite's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!")
+ target.set_species(/datum/species/golem/clockwork/no_scrap)
+ new /obj/effect/temp_visual/ratvar/sigil/transmission(T,2)
+
#undef INFINITE
diff --git a/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm b/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm
index b0259c460e..99d1142990 100644
--- a/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm
+++ b/code/modules/antagonists/clockcult/clock_helpers/fabrication_helpers.dm
@@ -350,3 +350,22 @@
// Winter coat
/obj/item/clothing/suit/hooded/wintercoat/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal
return list("operation_time" = 30, "new_obj_type" = /obj/item/clothing/suit/hooded/wintercoat/ratvar, "power_cost" = POWER_METAL * 4, "spawn_dir" = SOUTH)
+
+//tools
+/obj/item/crowbar/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //1 metal rod each
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/crowbar/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
+
+/obj/item/screwdriver/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/screwdriver/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
+
+/obj/item/weldingtool/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/weldingtool/experimental/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
+
+/obj/item/wirecutters/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/wirecutters/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
+
+/obj/item/wrench/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/wrench/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
+
+/obj/item/multitool/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 2, "new_obj_type" = /obj/item/multitool/advanced/brass, "power_cost" = POWER_ROD * 1, "spawn_dir" = SOUTH)
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_augments.dm b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm
index 2131aa7160..ff19e8891b 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_augments.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_augments.dm
@@ -5,7 +5,7 @@
name = "clock-themed arm-mounted implant"
var/clockwork_desc = "According to Ratvar, this really shouldn't exist. Tell Him about this immediately."
syndicate_implant = TRUE
- icon_state = "clock_arm_implant"
+ icon_state = "toolkit_implant"
/obj/item/organ/cyberimp/arm/clockwork/ui_action_click()
if(is_servant_of_ratvar(owner) || (obj_flags & EMAGGED)) //If you somehow manage to steal a clockie's implant AND have an emag AND manage to get it implanted for yourself, good on ya!
diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
index dfda2bf152..d9938316b6 100644
--- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
@@ -251,7 +251,9 @@
var/mob/camera/eminence/E = owner
E.eminence_help()
+
/*
+
//Returns to the Ark - Commented out and replaced with obelisk_jump
/datum/action/innate/eminence/ark_jump
name = "Return to Ark"
@@ -265,7 +267,7 @@
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!")
+ to_chat(owner, "There is no Ark!")
*/
//Warps to a chosen Obelisk
diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm
new file mode 100644
index 0000000000..5060f516c7
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm
@@ -0,0 +1,432 @@
+//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture.
+/mob/living/simple_animal/hostile/clockwork/guardian
+ name = "clockwork guardian"
+ desc = "A slow, armored clockwork machine, blazing with magenta flames. It's armed with a gladius and shield, and stands ready by its master."
+ icon_state = "clockwork_guardian"
+ health = 300
+ maxHealth = 300
+ speed = 1
+ obj_damage = 40
+ melee_damage_lower = 20//ranged attacks are the way to go for fighting these
+ melee_damage_upper = 20
+ attack_verb_continuous = "slashes"
+ attack_verb_simple = "slash"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ weather_immunities = list("lava")
+ movement_type = FLYING
+ AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_-
+ loot = list(/obj/structure/destructible/clockwork/taunting_trail)
+ var/true_name = "Meme Master 69" //Required to call forth the guardian
+ var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort")
+ var/mob/living/host //The mob that the guardian is living inside of
+ var/recovering = FALSE //If the guardian is recovering from recalling
+ var/blockchance = 17 //chance to block attacks entirely
+ var/counterchance = 30 //chance to counterattack after blocking
+ var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order
+ light_color = "#AF0AAF"
+ light_range = 2
+ light_power = 1.1
+ playstyle_string = "You are a clockwork guardian, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \
+ and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \
+ Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use The Hierophant Network to communicate silently with your master and their allies, \
+ but can only exit if your master calls your true name or if they are exceptionally damaged. \
+ \n\n\
+ Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \
+ fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar."
+
+/mob/living/simple_animal/hostile/clockwork/guardian/Initialize()
+ . = ..()
+ true_name = pick(possible_true_names)
+
+/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(seconds, times_fired)
+ ..()
+ if(is_in_host())
+ if(!is_servant_of_ratvar(host))
+ emerge_from_host(FALSE, TRUE)
+ unbind_from_host()
+ return
+ if(!GLOB.ratvar_awakens && host.stat == DEAD)
+ death()
+ return
+ if(GLOB.ratvar_awakens)
+ adjustHealth(-50)
+ else
+ adjustHealth(-10)
+ if(!recovering)
+ heal_host() //also heal our host if inside of them and we aren't recovering
+ else if(health == maxHealth)
+ to_chat(src, "Your strength has returned. You can once again come forward!")
+ to_chat(host, "Your guardian is now strong enough to come forward again!")
+ recovering = FALSE
+ else
+ if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill
+ adjustHealth(-5)
+ heal_host()
+ else if(host)
+ if(!is_servant_of_ratvar(host))
+ unbind_from_host()
+ return
+ if(host.stat == DEAD)
+ adjustHealth(50)
+ to_chat(src, "Your host is dead!")
+ return
+ if(z && host.z && z == host.z)
+ switch(get_dist(get_turf(src), get_turf(host)))
+ if(2)
+ adjustHealth(-1)
+ if(3)
+ //EQUILIBRIUM
+ if(4)
+ adjustHealth(1)
+ if(5)
+ adjustHealth(3)
+ if(6)
+ adjustHealth(6)
+ if(7)
+ adjustHealth(9)
+ if(8 to INFINITY)
+ adjustHealth(15)
+ to_chat(src, "You're too far from your host and rapidly taking damage!")
+ else //right next to or on top of host
+ adjustHealth(-2)
+ heal_host() //gradually heal host if nearby and host is very weak
+ else //well then, you're not even in the same zlevel
+ adjustHealth(15)
+ to_chat(src, "You're too far from your host and rapidly taking damage!")
+
+/mob/living/simple_animal/hostile/clockwork/guardian/death(gibbed)
+ emerge_from_host(FALSE, TRUE)
+ unbind_from_host()
+ visible_message("[src]'s equipment fades into a purple mist as the flames within sputter and dissipate.", \
+ "Your equipment fades away. You feel a moment of confusion before your fragile form is annihilated.")
+ . = ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/Stat()
+ ..()
+ if(statpanel("Status"))
+ stat(null, "Current True Name: [true_name]")
+ stat(null, "Host: [host ? host : "NONE"]")
+ if(host)
+ var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
+ if(iscarbon(host))
+ resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
+ stat(null, "Host Health: [resulthealth]%")
+ if(GLOB.ratvar_awakens)
+ stat(null, "You are [recovering ? "un" : ""]able to deploy!")
+ else
+ if(resulthealth > GUARDIAN_EMERGE_THRESHOLD)
+ stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!")
+ else
+ stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!")
+ stat(null, "You do [melee_damage_upper] damage on melee attacks.")
+
+/mob/living/simple_animal/hostile/clockwork/guardian/Process_Spacemove(movement_dir = 0)
+ return 1
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/bind_to_host(mob/living/new_host)
+ if(!new_host)
+ return FALSE
+ host = new_host
+ var/datum/action/innate/summon_guardian/SG = new()
+ SG.linked_guardian = src
+ SG.Grant(host)
+ var/datum/action/innate/linked_minds/LM = new()
+ LM.linked_guardian = src
+ LM.Grant(host)
+ return TRUE
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/unbind_from_host()
+ if(host)
+ for(var/datum/action/innate/summon_guardian/SG in host.actions)
+ qdel(SG)
+ for(var/datum/action/innate/linked_minds/LM in host.actions)
+ qdel(LM)
+ host = null
+ return TRUE
+ return FALSE
+
+//DAMAGE and FATIGUE
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/heal_host()
+ if(!host)
+ return
+ var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
+ if(iscarbon(host))
+ resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
+ if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD)
+ new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF")
+ host.heal_ordered_damage(4, damage_heal_order)
+
+/mob/living/simple_animal/hostile/clockwork/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ if(amount > 0)
+ for(var/mob/living/L in view(2, src))
+ if(L.is_holding_item_of_type(/obj/item/nullrod))
+ to_chat(src, "The presence of a brandished holy artifact weakens your armor!")
+ amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage
+ break
+ . = ..()
+ if(src && updating_health)
+ update_health_hud()
+ update_stats()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/update_health_hud()
+ if(hud_used && hud_used.healths)
+ if(istype(hud_used, /datum/hud))
+ var/datum/hud/marauder/G = hud_used
+ var/resulthealth
+ if(host)
+ if(iscarbon(host))
+ resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%"
+ else
+ resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%"
+ else
+ resulthealth = "NONE"
+ G.hosthealth.maptext = "
HOST
[resulthealth]
"
+ hud_used.healths.maptext = "[round((health / maxHealth) * 100, 0.5)]%"
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/update_stats()
+ if(GLOB.ratvar_awakens)
+ speed = 0
+ melee_damage_lower = 20
+ melee_damage_upper = 20
+ attack_verb_continuous = "devastates"
+ else
+ var/healthpercent = (health/maxHealth) * 100
+ switch(healthpercent)
+ if(100 to 70) //Bonuses to speed and damage at high health
+ speed = 0
+ melee_damage_lower = 16
+ melee_damage_upper = 16
+ attack_verb_continuous = "viciously slashes"
+ if(70 to 40)
+ speed = initial(speed)
+ melee_damage_lower = initial(melee_damage_lower)
+ melee_damage_upper = initial(melee_damage_upper)
+ attack_verb_continuous = initial(attack_verb_continuous)
+ if(40 to 30) //Damage decrease, but not speed
+ speed = initial(speed)
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ attack_verb_continuous = "lightly slashes"
+ if(30 to 20) //Speed decrease
+ speed = 2
+ melee_damage_lower = 8
+ melee_damage_upper = 8
+ attack_verb_continuous = "lightly slashes"
+ if(20 to 10) //Massive speed decrease and weak melee attacks
+ speed = 3
+ melee_damage_lower = 6
+ melee_damage_upper = 6
+ attack_verb_continuous = "weakly slashes"
+ if(10 to 0) //We are super weak and going to die
+ speed = 4
+ melee_damage_lower = 4
+ melee_damage_upper = 4
+ attack_verb_continuous = "taps"
+
+//ATTACKING, BLOCKING, and COUNTERING
+
+/mob/living/simple_animal/hostile/clockwork/guardian/AttackingTarget()
+ if(is_in_host())
+ return FALSE
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/bullet_act(obj/item/projectile/Proj)
+ if(blockOrCounter(null, Proj))
+ return
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum)
+ if(blockOrCounter(null, AM))
+ return
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attack_animal(mob/living/simple_animal/M)
+ if(istype(M, /mob/living/simple_animal/hostile/clockwork/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attack_paw(mob/living/carbon/monkey/M)
+ if(!blockOrCounter(M, M))
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attack_alien(mob/living/carbon/alien/humanoid/M)
+ if(!blockOrCounter(M, M))
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attack_slime(mob/living/simple_animal/slime/M)
+ if(!blockOrCounter(M, M))
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attack_hand(mob/living/carbon/human/M)
+ if(!blockOrCounter(M, M))
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I))
+ return ..()
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/blockOrCounter(mob/target, atom/textobject)
+ if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance
+ blockchance = 90
+ counterchance = 90
+ if(prob(blockchance))
+ . = TRUE
+ if(target)
+ target.do_attack_animation(src)
+ target.DelayNextAction(CLICK_CD_MELEE)
+ blockchance = initial(blockchance)
+ playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang
+ visible_message("
[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!", \
+ "
You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!")
+ if(target && Adjacent(target))
+ if(prob(counterchance))
+ counterchance = initial(counterchance)
+ var/previousattack_verb_continuous = attack_verb_continuous
+ attack_verb_continuous = "counters"
+ UnarmedAttack(target)
+ attack_verb_continuous = previousattack_verb_continuous
+ else
+ counterchance = min(counterchance + initial(counterchance), 100)
+ else
+ blockchance = min(blockchance + initial(blockchance), 100)
+ if(GLOB.ratvar_awakens)
+ blockchance = 90
+ counterchance = 90
+
+//COMMUNICATION and EMERGENCE
+/*
+/mob/living/simple_animal/hostile/clockwork/guardian/handle_inherent_channels(message, message_mode)
+ if(host && (is_in_host() || message_mode == MODE_BINARY))
+ guardian_comms(message)
+ return TRUE
+ return ..()
+*/
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/guardian_comms(message)
+ var/name_part = "
[src] ([true_name])"
+ message = "
\"[message]\"" //Processed output
+ to_chat(src, "[name_part]
: [message]")
+ to_chat(host, "[name_part]
: [message]")
+ for(var/M in GLOB.mob_list)
+ if(isobserver(M))
+ var/link = FOLLOW_LINK(M, src)
+ to_chat(M, "[link] [name_part]
(to [findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]): [message] ")
+ return TRUE
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/return_to_host()
+ if(is_in_host())
+ return FALSE
+ if(!host)
+ to_chat(src, "
You don't have a host!")
+ return FALSE
+ var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
+ if(iscarbon(host))
+ resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
+ host.visible_message("
[host]'s skin flashes magenta!", "
You feel [true_name]'s consciousness settle in your mind.")
+ visible_message("
[src] suddenly disappears!", "
You return to [host].")
+ forceMove(host)
+ if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth)
+ recovering = TRUE
+ to_chat(src, "
You have weakened and will need to recover before manifesting again!")
+ to_chat(host, "
[true_name] has weakened and will need to recover before manifesting again!")
+ return TRUE
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/try_emerge()
+ if(!host)
+ to_chat(src, "
You don't have a host!")
+ return FALSE
+ if(!GLOB.ratvar_awakens)
+ var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
+ if(iscarbon(host))
+ resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
+ if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails
+ to_chat(src, "
Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!")
+ return FALSE
+ return emerge_from_host(FALSE)
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return
+ if(!is_in_host())
+ return FALSE
+ if(!force && recovering)
+ if(hostchosen)
+ to_chat(host, "
[true_name] is too weak to come forth!")
+ else
+ to_chat(host, "
[true_name] tries to emerge to protect you, but it's too weak!")
+ to_chat(src, "
You try to come forth, but you're too weak!")
+ return FALSE
+ if(!force)
+ if(hostchosen) //guardian approved
+ to_chat(host, "
Your words echo with power as [true_name] emerges from your body!")
+ else
+ to_chat(host, "
[true_name] emerges from your body to protect you!")
+ forceMove(host.loc)
+ visible_message("
[host]'s skin glows red as [name] emerges from their body!", "
You exit the safety of [host]'s body!")
+ return TRUE
+
+/mob/living/simple_animal/hostile/clockwork/guardian/get_alt_name()
+ return " ([text2ratvar(true_name)])"
+
+/mob/living/simple_animal/hostile/clockwork/guardian/proc/is_in_host() //Checks if the guardian is inside of their host
+ return host && loc == host
+
+//HOST ACTIONS
+
+//Summon guardian action: Calls forth or recalls your guardian
+/datum/action/innate/summon_guardian
+ name = "Force Guardian to Emerge/Recall"
+ desc = "Allows you to force your clockwork guardian to emerge or recall as required."
+ button_icon_state = "clockwork_marauder"
+ background_icon_state = "bg_clock"
+ check_flags = AB_CHECK_CONSCIOUS
+ buttontooltipstyle = "clockcult"
+ var/mob/living/simple_animal/hostile/clockwork/guardian/linked_guardian
+ var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me")
+ var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat")
+
+/datum/action/innate/summon_guardian/IsAvailable()
+ if(!linked_guardian)
+ return FALSE
+ if(isliving(owner))
+ var/mob/living/L = owner
+ if(!L.can_speak_vocal() || L.stat)
+ return FALSE
+ return ..()
+
+/datum/action/innate/summon_guardian/Activate()
+ if(linked_guardian.is_in_host())
+ clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!"))
+ linked_guardian.emerge_from_host(TRUE)
+ else
+ clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!"))
+ linked_guardian.return_to_host()
+ return TRUE
+
+//Linked Minds action: talks to your guardian
+/datum/action/innate/linked_minds
+ name = "Linked Minds"
+ desc = "Allows you to silently communicate with your guardian."
+ button_icon_state = "linked_minds"
+ background_icon_state = "bg_clock"
+ check_flags = AB_CHECK_CONSCIOUS
+ buttontooltipstyle = "clockcult"
+ var/mob/living/simple_animal/hostile/clockwork/guardian/linked_guardian
+
+/datum/action/innate/linked_minds/IsAvailable()
+ if(!linked_guardian)
+ return FALSE
+ return ..()
+
+/datum/action/innate/linked_minds/Activate()
+ var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy")
+ if(!owner || !message)
+ return FALSE
+ if(!linked_guardian)
+ to_chat(owner, "
Your guardian seems to have been destroyed!")
+ return FALSE
+ var/name_part = "
Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]"
+ message = "
\"[message]\"" //Processed output
+ to_chat(owner, "[name_part]
: [message]")
+ to_chat(linked_guardian, "[name_part]
: [message]")
+ for(var/M in GLOB.mob_list)
+ if(isobserver(M))
+ var/link = FOLLOW_LINK(M, src)
+ to_chat(M, "[link] [name_part]
(to [linked_guardian] ([linked_guardian.true_name])): [message]")
+ return TRUE
diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
index 76c9db7231..d58608652c 100644
--- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm
@@ -123,437 +123,3 @@
#undef MARAUDER_SLOWDOWN_PERCENTAGE
#undef MARAUDER_SHIELD_REGEN_TIME
-
-//Clockwork guardian: Slow but with high damage, resides inside of a servant. Created via the Memory Allocation scripture.
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian
- name = "clockwork guardian"
- desc = "A stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield and stands ready by its master."
- icon_state = "clockwork_marauder"
- health = 300
- maxHealth = 300
- speed = 1
- obj_damage = 40
- melee_damage_lower = 12
- melee_damage_upper = 12
- attack_verb_continuous = "slashes"
- attack_verb_simple = "slash"
- attack_sound = 'sound/weapons/bladeslice.ogg'
- weather_immunities = list("lava")
- movement_type = FLYING
- AIStatus = AI_OFF //this has to be manually set so that the guardian doesn't start bashing the host, how annoying -_-
- loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
- max_shield_health = 0
- shield_health = 0
- var/true_name = "Meme Master 69" //Required to call forth the guardian
- var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort")
- var/mob/living/host //The mob that the guardian is living inside of
- var/recovering = FALSE //If the guardian is recovering from recalling
- var/blockchance = 17 //chance to block attacks entirely
- var/counterchance = 30 //chance to counterattack after blocking
- var/static/list/damage_heal_order = list(OXY, BURN, BRUTE, TOX) //we heal our host's damage in this order
- light_range = 2
- light_power = 1.1
- playstyle_string = "
You are a clockwork guardian, a living extension of Sevtug's will. As a guardian, you are somewhat slow, but may block attacks, \
- and have a chance to also counter blocked melee attacks for extra damage, in addition to being immune to extreme temperatures and pressures. \
- Your primary goal is to serve the creature that you are now a part of, as well as The Clockwork Justiciar, Ratvar. You can use The Hierophant Network to communicate silently with your master and their allies, \
- but can only exit if your master calls your true name or if they are exceptionally damaged. \
- \n\n\
- Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \
- fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar."
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Initialize()
- . = ..()
- true_name = pick(possible_true_names)
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/BiologicalLife(seconds, times_fired)
- ..()
- if(is_in_host())
- if(!is_servant_of_ratvar(host))
- emerge_from_host(FALSE, TRUE)
- unbind_from_host()
- return
- if(!GLOB.ratvar_awakens && host.stat == DEAD)
- death()
- return
- if(GLOB.ratvar_awakens)
- adjustHealth(-50)
- else
- adjustHealth(-10)
- if(!recovering)
- heal_host() //also heal our host if inside of them and we aren't recovering
- else if(health == maxHealth)
- to_chat(src, "Your strength has returned. You can once again come forward!")
- to_chat(host, "Your guardian is now strong enough to come forward again!")
- recovering = FALSE
- else
- if(GLOB.ratvar_awakens) //If Ratvar is alive, guardians don't need a host and are downright impossible to kill
- adjustHealth(-5)
- heal_host()
- else if(host)
- if(!is_servant_of_ratvar(host))
- unbind_from_host()
- return
- if(host.stat == DEAD)
- adjustHealth(50)
- to_chat(src, "Your host is dead!")
- return
- if(z && host.z && z == host.z)
- switch(get_dist(get_turf(src), get_turf(host)))
- if(2)
- adjustHealth(-1)
- if(3)
- //EQUILIBRIUM
- if(4)
- adjustHealth(1)
- if(5)
- adjustHealth(3)
- if(6)
- adjustHealth(6)
- if(7)
- adjustHealth(9)
- if(8 to INFINITY)
- adjustHealth(15)
- to_chat(src, "You're too far from your host and rapidly taking damage!")
- else //right next to or on top of host
- adjustHealth(-2)
- heal_host() //gradually heal host if nearby and host is very weak
- else //well then, you're not even in the same zlevel
- adjustHealth(15)
- to_chat(src, "You're too far from your host and rapidly taking damage!")
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/death(gibbed)
- emerge_from_host(FALSE, TRUE)
- unbind_from_host()
- visible_message("[src]'s equipment clatters lifelessly to the ground as the red flames within dissipate.", \
- "Your equipment falls away. You feel a moment of confusion before your fragile form is annihilated.")
- . = ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Stat()
- ..()
- if(statpanel("Status"))
- stat(null, "Current True Name: [true_name]")
- stat(null, "Host: [host ? host : "NONE"]")
- if(host)
- var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
- if(iscarbon(host))
- resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
- stat(null, "Host Health: [resulthealth]%")
- if(GLOB.ratvar_awakens)
- stat(null, "You are [recovering ? "un" : ""]able to deploy!")
- else
- if(resulthealth > GUARDIAN_EMERGE_THRESHOLD)
- stat(null, "You are [recovering ? "unable to deploy" : "able to deploy on hearing your True Name"]!")
- else
- stat(null, "You are [recovering ? "unable to deploy" : "able to deploy to protect your host"]!")
- stat(null, "You do [melee_damage_upper] damage on melee attacks.")
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/Process_Spacemove(movement_dir = 0)
- return 1
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/bind_to_host(mob/living/new_host)
- if(!new_host)
- return FALSE
- host = new_host
- var/datum/action/innate/summon_guardian/SG = new()
- SG.linked_guardian = src
- SG.Grant(host)
- var/datum/action/innate/linked_minds/LM = new()
- LM.linked_guardian = src
- LM.Grant(host)
- return TRUE
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/unbind_from_host()
- if(host)
- for(var/datum/action/innate/summon_guardian/SG in host.actions)
- qdel(SG)
- for(var/datum/action/innate/linked_minds/LM in host.actions)
- qdel(LM)
- host = null
- return TRUE
- return FALSE
-
-//DAMAGE and FATIGUE
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/heal_host()
- if(!host)
- return
- var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
- if(iscarbon(host))
- resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
- if(GLOB.ratvar_awakens || resulthealth <= GUARDIAN_EMERGE_THRESHOLD)
- new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF")
- host.heal_ordered_damage(4, damage_heal_order)
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- if(amount > 0)
- for(var/mob/living/L in view(2, src))
- if(L.is_holding_item_of_type(/obj/item/nullrod))
- to_chat(src, "The presence of a brandished holy artifact weakens your armor!")
- amount *= 4 //if a wielded null rod is nearby, it takes four times the health damage
- break
- . = ..()
- if(src && updating_health)
- update_health_hud()
- update_stats()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/update_health_hud()
- if(hud_used && hud_used.healths)
- if(istype(hud_used, /datum/hud/marauder))
- var/datum/hud/marauder/G = hud_used
- var/resulthealth
- if(host)
- if(iscarbon(host))
- resulthealth = "[round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)]%"
- else
- resulthealth = "[round((host.health / host.maxHealth) * 100, 0.5)]%"
- else
- resulthealth = "NONE"
- G.hosthealth.maptext = "HOST
[resulthealth]
"
- hud_used.healths.maptext = "[round((health / maxHealth) * 100, 0.5)]%"
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/update_stats()
- if(GLOB.ratvar_awakens)
- speed = 0
- melee_damage_lower = 20
- melee_damage_upper = 20
- attack_verb_continuous = "devastates"
- else
- var/healthpercent = (health/maxHealth) * 100
- switch(healthpercent)
- if(100 to 70) //Bonuses to speed and damage at high health
- speed = 0
- melee_damage_lower = 16
- melee_damage_upper = 16
- attack_verb_continuous = "viciously slashes"
- if(70 to 40)
- speed = initial(speed)
- melee_damage_lower = initial(melee_damage_lower)
- melee_damage_upper = initial(melee_damage_upper)
- attack_verb_continuous = initial(attack_verb_continuous)
- if(40 to 30) //Damage decrease, but not speed
- speed = initial(speed)
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_verb_continuous = "lightly slashes"
- if(30 to 20) //Speed decrease
- speed = 2
- melee_damage_lower = 8
- melee_damage_upper = 8
- attack_verb_continuous = "lightly slashes"
- if(20 to 10) //Massive speed decrease and weak melee attacks
- speed = 3
- melee_damage_lower = 6
- melee_damage_upper = 6
- attack_verb_continuous = "weakly slashes"
- if(10 to 0) //We are super weak and going to die
- speed = 4
- melee_damage_lower = 4
- melee_damage_upper = 4
- attack_verb_continuous = "taps"
-
-//ATTACKING, BLOCKING, and COUNTERING
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/AttackingTarget()
- if(is_in_host())
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/bullet_act(obj/item/projectile/Proj)
- if(blockOrCounter(null, Proj))
- return
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/hitby(atom/movable/AM, skipcatch, hitpush, blocked, atom/movable/AM, datum/thrownthing/throwingdatum)
- if(blockOrCounter(null, AM))
- return
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_animal(mob/living/simple_animal/M)
- if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder/guardian) || !blockOrCounter(M, M)) //we don't want infinite blockcounter loops if fighting another guardian
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_paw(mob/living/carbon/monkey/M)
- if(!blockOrCounter(M, M))
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_alien(mob/living/carbon/alien/humanoid/M)
- if(!blockOrCounter(M, M))
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_slime(mob/living/simple_animal/slime/M)
- if(!blockOrCounter(M, M))
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attack_hand(mob/living/carbon/human/M)
- if(!blockOrCounter(M, M))
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/nullrod) || !blockOrCounter(user, I))
- return ..()
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/blockOrCounter(mob/target, atom/textobject)
- if(GLOB.ratvar_awakens) //if ratvar has woken, we block nearly everything at a very high chance
- blockchance = 90
- counterchance = 90
- if(prob(blockchance))
- . = TRUE
- if(target)
- target.do_attack_animation(src)
- target.DelayNextAction(CLICK_CD_MELEE)
- blockchance = initial(blockchance)
- playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 30, 1, 0, 1) //clang
- visible_message("[src] blocks [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!", \
- "You block [target && isitem(textobject) ? "[target]'s [textobject.name]":"\the [textobject]"]!")
- if(target && Adjacent(target))
- if(prob(counterchance))
- counterchance = initial(counterchance)
- var/previousattack_verb_continuous = attack_verb_continuous
- attack_verb_continuous = "counters"
- UnarmedAttack(target)
- attack_verb_continuous = previousattack_verb_continuous
- else
- counterchance = min(counterchance + initial(counterchance), 100)
- else
- blockchance = min(blockchance + initial(blockchance), 100)
- if(GLOB.ratvar_awakens)
- blockchance = 90
- counterchance = 90
-
-//COMMUNICATION and EMERGENCE
-/*
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/handle_inherent_channels(message, message_mode)
- if(host && (is_in_host() || message_mode == MODE_BINARY))
- guardian_comms(message)
- return TRUE
- return ..()
-*/
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/guardian_comms(message)
- var/name_part = "[src] ([true_name])"
- message = "\"[message]\"" //Processed output
- to_chat(src, "[name_part]: [message]")
- to_chat(host, "[name_part]: [message]")
- for(var/M in GLOB.mob_list)
- if(isobserver(M))
- var/link = FOLLOW_LINK(M, src)
- to_chat(M, "[link] [name_part] (to [findtextEx(host.name, host.real_name) ? "[host.name]" : "[host.real_name] (as [host.name])"]): [message] ")
- return TRUE
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/return_to_host()
- if(is_in_host())
- return FALSE
- if(!host)
- to_chat(src, "You don't have a host!")
- return FALSE
- var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
- if(iscarbon(host))
- resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
- host.visible_message("[host]'s skin flashes crimson!", "You feel [true_name]'s consciousness settle in your mind.")
- visible_message("[src] suddenly disappears!", "You return to [host].")
- forceMove(host)
- if(resulthealth > GUARDIAN_EMERGE_THRESHOLD && health != maxHealth)
- recovering = TRUE
- to_chat(src, "You have weakened and will need to recover before manifesting again!")
- to_chat(host, "[true_name] has weakened and will need to recover before manifesting again!")
- return TRUE
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/try_emerge()
- if(!host)
- to_chat(src, "You don't have a host!")
- return FALSE
- if(!GLOB.ratvar_awakens)
- var/resulthealth = round((host.health / host.maxHealth) * 100, 0.5)
- if(iscarbon(host))
- resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
- if(host.stat != DEAD && resulthealth > GUARDIAN_EMERGE_THRESHOLD) //if above 20 health, fails
- to_chat(src, "Your host must be at [GUARDIAN_EMERGE_THRESHOLD]% or less health to emerge like this!")
- return FALSE
- return emerge_from_host(FALSE)
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/emerge_from_host(hostchosen, force) //Notice that this is a proc rather than a verb - guardians can NOT exit at will, but they CAN return
- if(!is_in_host())
- return FALSE
- if(!force && recovering)
- if(hostchosen)
- to_chat(host, "[true_name] is too weak to come forth!")
- else
- to_chat(host, "[true_name] tries to emerge to protect you, but it's too weak!")
- to_chat(src, "You try to come forth, but you're too weak!")
- return FALSE
- if(!force)
- if(hostchosen) //guardian approved
- to_chat(host, "Your words echo with power as [true_name] emerges from your body!")
- else
- to_chat(host, "[true_name] emerges from your body to protect you!")
- forceMove(host.loc)
- visible_message("[host]'s skin glows red as [name] emerges from their body!", "You exit the safety of [host]'s body!")
- return TRUE
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/get_alt_name()
- return " ([text2ratvar(true_name)])"
-
-/mob/living/simple_animal/hostile/clockwork/marauder/guardian/proc/is_in_host() //Checks if the guardian is inside of their host
- return host && loc == host
-
-//HOST ACTIONS
-
-//Summon guardian action: Calls forth or recalls your guardian
-/datum/action/innate/summon_guardian
- name = "Force Guardian to Emerge/Recall"
- desc = "Allows you to force your clockwork guardian to emerge or recall as required."
- button_icon_state = "clockwork_marauder"
- background_icon_state = "bg_clock"
- check_flags = AB_CHECK_CONSCIOUS
- buttontooltipstyle = "clockcult"
- var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian
- var/list/defend_phrases = list("Defend me", "Come forth", "Assist me", "Protect me", "Give aid", "Help me")
- var/list/return_phrases = list("Return", "Return to me", "Your job is done", "You have served", "Come back", "Retreat")
-
-/datum/action/innate/summon_guardian/IsAvailable()
- if(!linked_guardian)
- return FALSE
- if(isliving(owner))
- var/mob/living/L = owner
- if(!L.can_speak_vocal() || L.stat)
- return FALSE
- return ..()
-
-/datum/action/innate/summon_guardian/Activate()
- if(linked_guardian.is_in_host())
- clockwork_say(owner, text2ratvar("[pick(defend_phrases)], [linked_guardian.true_name]!"))
- linked_guardian.emerge_from_host(TRUE)
- else
- clockwork_say(owner, text2ratvar("[pick(return_phrases)], [linked_guardian.true_name]!"))
- linked_guardian.return_to_host()
- return TRUE
-
-//Linked Minds action: talks to your guardian
-/datum/action/innate/linked_minds
- name = "Linked Minds"
- desc = "Allows you to silently communicate with your guardian."
- button_icon_state = "linked_minds"
- background_icon_state = "bg_clock"
- check_flags = AB_CHECK_CONSCIOUS
- buttontooltipstyle = "clockcult"
- var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/linked_guardian
-
-/datum/action/innate/linked_minds/IsAvailable()
- if(!linked_guardian)
- return FALSE
- return ..()
-
-/datum/action/innate/linked_minds/Activate()
- var/message = stripped_input(owner, "Enter a message to tell your guardian.", "Telepathy")
- if(!owner || !message)
- return FALSE
- if(!linked_guardian)
- to_chat(owner, "Your guardian seems to have been destroyed!")
- return FALSE
- var/name_part = "Servant [findtextEx(owner.name, owner.real_name) ? "[owner.name]" : "[owner.real_name] (as [owner.name])"]"
- message = "\"[message]\"" //Processed output
- to_chat(owner, "[name_part]: [message]")
- to_chat(linked_guardian, "[name_part]: [message]")
- for(var/M in GLOB.mob_list)
- if(isobserver(M))
- var/link = FOLLOW_LINK(M, src)
- to_chat(M, "[link] [name_part] (to [linked_guardian] ([linked_guardian.true_name])): [message]")
- return TRUE
diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm
index aa0f7f03fa..6922c7cd81 100644
--- a/code/modules/antagonists/clockcult/clock_scripture.dm
+++ b/code/modules/antagonists/clockcult/clock_scripture.dm
@@ -5,7 +5,7 @@ Pieces of scripture require certain follower counts, contruction value, and acti
Drivers: Unlocked by default
Scripts: 35k power or one convert
Applications: 50k or three converts
-Judgement 5 converts
+Judgement 80k power or nine converts
*/
/datum/clockwork_scripture
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
index 77dc174238..85450dc152 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
@@ -18,7 +18,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 1
+ sort_priority = 2
important = TRUE
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures."
@@ -72,7 +72,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 2
+ sort_priority = 5
quickbind = TRUE
quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
requires_full_power = TRUE
@@ -101,7 +101,7 @@
//Memory Allocation: Finds a willing ghost and makes them into a clockwork guardian for the invoker.
/datum/clockwork_scripture/memory_allocation
- descname = "Personal Guardian, A Peice Of Your Mind."
+ descname = "Personal Guardian housed in the brain."
name = "Memory Allocation"
desc = "Allocates part of your consciousness to a Clockwork Guardian, a variant of Marauder that lives within you, able to be \
called forth by Speaking its True Name or if you become exceptionally low on health.
\
@@ -109,13 +109,13 @@
invocations = list("Fright's will...", "...call forth...")
channel_time = 100
power_cost = 8000
- usage_tip = "guardians are useful as personal bodyguards and frontline warriors."
+ usage_tip = "Guardians are useful as personal bodyguards and frontline warriors."
tier = SCRIPTURE_APPLICATION
primary_component = GEIS_CAPACITOR
- sort_priority = 5
+ sort_priority = 6
/datum/clockwork_scripture/memory_allocation/check_special_requirements()
- for(var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M in GLOB.all_clockwork_mobs)
+ for(var/mob/living/simple_animal/hostile/clockwork/guardian/M in GLOB.all_clockwork_mobs)
if(M.host == invoker)
to_chat(invoker, "You can only house one guardian at a time!")
return FALSE
@@ -151,7 +151,7 @@
return FALSE
clockwork_say(invoker, text2ratvar("...sword and shield!"))
var/mob/dead/observer/theghost = pick(marauder_candidates)
- var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/M = new(invoker)
+ var/mob/living/simple_animal/hostile/clockwork/guardian/M = new(invoker)
M.key = theghost.key
M.bind_to_host(invoker)
invoker.visible_message("The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \
@@ -171,7 +171,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
- sort_priority = 6
+ sort_priority = 7
quickbind = TRUE
quickbind_desc = "Creates a clockwork marauder, used for frontline combat."
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
@@ -223,7 +223,7 @@
object_path = /obj/mecha/combat/neovgre
tier = SCRIPTURE_APPLICATION
primary_component = BELLIGERENT_EYE
- sort_priority = 7
+ sort_priority = 8
creator_message = "Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come."
/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm
index 5075840e76..ea10725489 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm
@@ -20,7 +20,7 @@
usage_tip = "The gateway is completely vulnerable to attack during its five-minute duration. It will periodically give indication of its general position to everyone on the station \
as well as being loud enough to be heard throughout the entire sector. Defend it with your life!"
tier = SCRIPTURE_APPLICATION
- sort_priority = 8
+ sort_priority = 1
requires_full_power = TRUE
/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements()
diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
index 3b507fb57c..a481415cf5 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
@@ -81,7 +81,7 @@
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.", "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation_sequence.ogg')
- set_security_level("delta")
+ set_security_level("Delta")
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
if(!M || !M.current)
diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
index 28901ea0b2..24ad1af88a 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -29,8 +29,9 @@
sound_to_playing_players('sound/effects/ratvar_reveal.ogg')
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [get_area_name(src)] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
- INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 10, null, FALSE, 0)
SSpersistence.station_was_destroyed = TRUE
+ INVOKE_ASYNC(src, .proc/purge_the_heresy)
+
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
GLOB.ratvar_awakens--
@@ -151,3 +152,34 @@
sound_to_playing_players('sound/machines/clockcult/ratvar_scream.ogg', 80)
narsie.clashing = FALSE
qdel(src)
+
+
+/obj/structure/destructible/clockwork/massive/ratvar/proc/purge_the_heresy()
+ sleep(50)
+ priority_announce("Massive energy surge detected. Closest matching threat: Incoming supernova. All crew are advised to evacuate NAN lightyears away from blast zone","Central Command Higher Dimensional Affairs", 'sound/misc/airraid.ogg')
+ sleep(300)
+ priority_announce("Gravitational anomalies detected on the station. [Gibberish("There is no additional dat", 100)]-BZZZZZT.","Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ratvar_announce1.ogg')
+ sleep(80)
+ sound_to_playing_players('sound/magic/clockwork/ratvar_announce2.ogg', 70)
+ send_to_playing_players("\"COME, ALL THOSE FAITHFUL! WITNESS THE RAYS OF JUSTICE CAST UPON THE HERETICS!\"")
+ sleep(50)
+ SSshuttle.registerHostileEnvironment(src)
+ SSshuttle.lockdown = TRUE
+ sleep(250)
+ if(QDELETED(src))
+ priority_announce("Energy signal no longer detected.","Central Command Higher Dimensional Affairs")
+ return
+ sound_to_playing_players('sound/magic/clockwork/ark_activation_sequence.ogg', 80) //if this isn't lessened in volume it peaks for some reason
+ addtimer(CALLBACK(GLOBAL_PROC, /proc/clockcult_ending_helper), 300)
+
+/proc/clockcult_ending_helper()
+ for(var/mob/M in GLOB.mob_list)
+ if(M.client)
+ SEND_SOUND(M, sound('sound/magic/clockwork/ratvar_attack.ogg'))
+ SEND_SOUND(M, sound('sound/magic/clockwork/ratvarfire.ogg'))
+ if(!is_servant_of_ratvar(M) && isliving(M))
+ var/mob/living/L = M
+ L.fire_stacks = INFINITY
+ L.IgniteMob()
+ sleep(50)
+ SSticker.force_ending = 1
diff --git a/code/modules/antagonists/clockcult/clock_structures/reflector.dm b/code/modules/antagonists/clockcult/clock_structures/reflector.dm
index c91e9dd918..e734429524 100644
--- a/code/modules/antagonists/clockcult/clock_structures/reflector.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/reflector.dm
@@ -1,7 +1,7 @@
/obj/structure/destructible/clockwork/reflector
name = "reflector"
- desc = "A large lantern-shaped machine made of thin brass. It looks fragile."
- clockwork_desc = "A lantern-shaped generator that produces power when near starlight."
+ desc = "A large mirror-like structure made of thin brass on one side. It looks fragile."
+ clockwork_desc = "A large mirror-like structure made of thin brass on one side. It can redirect laser fire on one side"
icon_state = "reflector"
unanchored_icon = "reflector_unwrenched"
max_integrity = 40
diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm
index b935258c27..efea8ed771 100644
--- a/code/modules/antagonists/clockcult/clockcult.dm
+++ b/code/modules/antagonists/clockcult/clockcult.dm
@@ -5,7 +5,7 @@
antagpanel_category = "Clockcult"
job_rank = ROLE_SERVANT_OF_RATVAR
antag_moodlet = /datum/mood_event/cult
- skill_modifiers = list(/datum/skill_modifier/job/level/wiring)
+ skill_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/level/dwarfy/blacksmithing)
var/datum/action/innate/hierophant/hierophant_network = new
threat = 3
var/datum/team/clockcult/clock_team
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index 77893225fa..bbdf41ff48 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -83,7 +83,7 @@
if(choice == "Yes" && IsAvailable())
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C.cult_team)
- to_chat(owner, "Do you not alreaady lead yourself?")
+ to_chat(owner, "Do you not already lead yourself?")
return
pollCultists(owner,C.cult_team)
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 75aff774ce..fba6ecd40c 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -625,7 +625,7 @@
say_mod = "clicks"
limbs_id = "clockgolem"
info_text = "As a Clockwork Golem, you are faster than other types of golems, and are capable of using guns. On death, you will break down into scrap."
- species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL,ROBOTIC_LIMBS)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
@@ -667,6 +667,10 @@
/datum/species/golem/clockwork/no_scrap //These golems are created through the herald's beacon and leave normal corpses on death.
id = "clockwork golem servant"
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOSTOMACH,NOLIVER,NOGENITALS,NOAROUSAL,NOTRANSSTING,ROBOTIC_LIMBS,HAS_BONE)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_NOHUNGER,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
armor = 15 //Balance reasons make this armor weak
no_equip = list()
nojumpsuit = FALSE
@@ -675,6 +679,8 @@
dangerous_existence = TRUE
random_eligible = FALSE
info_text = "As a Clockwork Golem Servant, you are faster than other types of golems, and are capable of using guns." //warcult golems leave a corpse
+ gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
+
/datum/species/golem/cloth
name = "Cloth Golem"
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 8e39dc5234..486a0acf4e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -514,10 +514,21 @@
/mob/living/ratvar_act()
if(status_flags & GODMODE)
return
- if(stat != DEAD && !is_servant_of_ratvar(src))
+ if(stat == DEAD || is_servant_of_ratvar(src))
+ return
+ if(is_eligible_servant(src))
+ add_servant_of_ratvar(src)
+ to_chat(src, "Ratvar's influence invades your mind, praise the Justiciar!")
+ else
to_chat(src, "A blinding light boils you alive! Run!")
adjust_fire_stacks(20)
+ adjustFireLoss(35)
IgniteMob()
+ if(iscultist(src))
+ to_chat(src, "You resist Ratvar's influence... but not all of it! Run!")
+ adjustFireLoss(35)
+ if(src && reagents)
+ reagents.add_reagent(/datum/reagent/fuel/holyoil, 5)
return FALSE
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 5b5292a020..0ebbce53cf 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -80,6 +80,9 @@
SSshuttle.lockdown = TRUE
SSpersistence.station_was_destroyed = TRUE
sleep(600)
+ if(QDELETED(src))
+ priority_announce("Accausal event alert rescinded. Eldritch presence no longer reading on sensors. Solution package disarmed. Reccomend immediate evacuation","Central Command Higher Dimensional Affairs")
+ return
if(resolved == FALSE)
resolved = TRUE
sound_to_playing_players('sound/machines/alarm.ogg')
diff --git a/icons/mob/actions/actions_clockcult.dmi b/icons/mob/actions/actions_clockcult.dmi
index 92d6f98e73..d4f5c4ed6f 100644
Binary files a/icons/mob/actions/actions_clockcult.dmi and b/icons/mob/actions/actions_clockcult.dmi differ
diff --git a/icons/mob/clockwork_mobs.dmi b/icons/mob/clockwork_mobs.dmi
index 54690f6cac..b43f7f958e 100644
Binary files a/icons/mob/clockwork_mobs.dmi and b/icons/mob/clockwork_mobs.dmi differ
diff --git a/icons/mob/inhands/antag/clockwork_righthand.dmi b/icons/mob/inhands/antag/clockwork_righthand.dmi
index 64ee6199a7..c813c83634 100644
Binary files a/icons/mob/inhands/antag/clockwork_righthand.dmi and b/icons/mob/inhands/antag/clockwork_righthand.dmi differ
diff --git a/sound/magic/clockwork/ratvar_announce.ogg b/sound/magic/clockwork/ratvar_announce.ogg
new file mode 100644
index 0000000000..6f997108c9
Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce.ogg differ
diff --git a/sound/magic/clockwork/ratvar_announce1.ogg b/sound/magic/clockwork/ratvar_announce1.ogg
new file mode 100644
index 0000000000..08308cb1cd
Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce1.ogg differ
diff --git a/sound/magic/clockwork/ratvar_announce2.ogg b/sound/magic/clockwork/ratvar_announce2.ogg
new file mode 100644
index 0000000000..54a49c75c7
Binary files /dev/null and b/sound/magic/clockwork/ratvar_announce2.ogg differ
diff --git a/sound/magic/clockwork/ratvarfire.ogg b/sound/magic/clockwork/ratvarfire.ogg
new file mode 100644
index 0000000000..4b8a9be10a
Binary files /dev/null and b/sound/magic/clockwork/ratvarfire.ogg differ
diff --git a/sound/weapons/neovgre_laser.ogg b/sound/weapons/neovgre_laser.ogg
index da97117ae8..c36e54fe87 100644
Binary files a/sound/weapons/neovgre_laser.ogg and b/sound/weapons/neovgre_laser.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 7879a87e32..b15633366e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1617,6 +1617,7 @@
#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_shield.dm"
#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_spear.dm"
#include "code\modules\antagonists\clockcult\clock_mobs\_eminence.dm"
+#include "code\modules\antagonists\clockcult\clock_mobs\clockwork_guardian.dm"
#include "code\modules\antagonists\clockcult\clock_mobs\clockwork_marauder.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_applications.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_cyborg.dm"