[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 1ebefe4d05..a85245e9d0 100644
--- a/code/modules/antagonists/clockcult/clock_scripture.dm
+++ b/code/modules/antagonists/clockcult/clock_scripture.dm
@@ -3,8 +3,9 @@ Tiers and Requirements
Pieces of scripture require certain follower counts, contruction value, and active caches in order to recite.
Drivers: Unlocked by default
-Scripts: 5 servants and a cache
-Applications: 8 servants, 3 caches, and 100 CV
+Scripts: 35k power or one convert
+Applications: 50k or three converts
+Judgement 5 converts
*/
/datum/clockwork_scripture
@@ -129,11 +130,11 @@ Applications: 8 servants, 3 caches, and 100 CV
SEND_SOUND(invoker, sound('sound/magic/clockwork/invoke_general.ogg'))
return TRUE
-/datum/clockwork_scripture/proc/check_offstation_penalty()
+/datum/clockwork_scripture/proc/check_offstation_penalty()//don't cast spells away from the station
var/turf/T = get_turf(invoker)
if(!T || (!is_centcom_level(T.z) && !is_station_level(T.z) && !is_mining_level(T.z) && !is_reebe(T.z)))
- channel_time *= 2
- power_cost *= 2
+ channel_time *= 3
+ power_cost *= 3
return TRUE
/datum/clockwork_scripture/proc/check_special_requirements() //Special requirements for scriptures, checked multiple times during invocation
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
index ffe9ecfa80..cbf3bdaa38 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
@@ -1,5 +1,5 @@
//////////////////
-// APPLICATIONS //
+// APPLICATIONS // For various structures and base building, as well as advanced power generation.
//////////////////
@@ -23,6 +23,37 @@
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures."
+//Prolonging Prism: Creates a prism that will delay the shuttle at a power cost
+/datum/clockwork_scripture/create_object/prolonging_prism
+ descname = "Powered Structure, Delay Emergency Shuttles"
+ name = "Prolonging Prism"
+ desc = "Creates a mechanized prism which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
+ invocations = list("May this prism...", "...grant us time to enact his will!")
+ channel_time = 80
+ power_cost = 300
+ object_path = /obj/structure/destructible/clockwork/powered/prolonging_prism
+ creator_message = "
You form a prolonging prism, which will delay the arrival of an emergency shuttle at a massive power cost."
+ observer_message = "
An onyx prism forms in midair and sprouts tendrils to support itself!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ usage_tip = "The power cost to delay a shuttle increases based on the number of times activated."
+ tier = SCRIPTURE_APPLICATION
+ one_per_tile = TRUE
+ primary_component = VANGUARD_COGWHEEL
+ sort_priority = 4
+ important = TRUE
+ quickbind = TRUE
+ quickbind_desc = "Creates a Prolonging Prism, which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
+
+/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ to_chat(invoker, "
\"It is too late to construct one of these, champion.\"")
+ return FALSE
+ var/turf/T = get_turf(invoker)
+ if(!T || !is_station_level(T.z))
+ to_chat(invoker, "
\"You must be on the station to construct one of these, champion.\"")
+ return FALSE
+ return ..()
//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
@@ -44,6 +75,7 @@
sort_priority = 2
quickbind = TRUE
quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
+ requires_full_power = TRUE
//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.
@@ -67,6 +99,64 @@
quickbind = TRUE
quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power."
+//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."
+ 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.
\
+ If it remains close to you, you will gradually regain health up to a low amount, but it will die if it goes too far from you."
+ invocations = list("Fright's will...", "...call forth...")
+ channel_time = 100
+ power_cost = 8000
+ usage_tip = "guardians are useful as personal bodyguards and frontline warriors."
+ tier = SCRIPTURE_APPLICATION
+ primary_component = GEIS_CAPACITOR
+ sort_priority = 5
+
+/datum/clockwork_scripture/memory_allocation/check_special_requirements()
+ for(var/mob/living/simple_animal/hostile/clockwork/marauder/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
+ return TRUE
+
+/datum/clockwork_scripture/memory_allocation/scripture_effects()
+ return create_guardian()
+
+/datum/clockwork_scripture/memory_allocation/proc/create_guardian()
+ invoker.visible_message("
A purple tendril appears from [invoker]'s [slab.name] and impales itself in [invoker.p_their()] forehead!", \
+ "
A tendril flies from [slab] into your forehead. You begin waiting while it painfully rearranges your thought pattern...")
+ //invoker.notransform = TRUE //Vulnerable during the process
+ slab.busy = "Thought Modification in progress"
+ if(!do_after(invoker, 50, target = invoker))
+ invoker.visible_message("
The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!", \
+ "
Total agony overcomes you as the tendril is forced out early!")
+ invoker.Knockdown(100)
+ invoker.apply_damage(50, BRUTE, "head")//Sevtug leaves a gaping hole in your face if interrupted.
+ slab.busy = null
+ return FALSE
+ clockwork_say(invoker, text2ratvar("...the mind made..."))
+ //invoker.notransform = FALSE
+ slab.busy = "Guardian Selection in progress"
+ if(!check_special_requirements())
+ return FALSE
+ to_chat(invoker, "
The tendril shivers slightly as it selects a guardian...")
+ var/list/marauder_candidates = pollGhostCandidates("Do you want to play as the clockwork guardian of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 50, POLL_IGNORE_HOLOPARASITE)
+ if(!check_special_requirements())
+ return FALSE
+ if(!marauder_candidates.len)
+ invoker.visible_message("
The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!", \
+ "
The tendril was unsuccessful! Perhaps you should try again another time.")
+ return 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)
+ 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!", \
+ "
[M.true_name], a clockwork guardian, has taken up residence in your mind. Communicate with it via the \"Linked Minds\" action button.")
+ return TRUE
//Clockwork Marauder: Creates a construct shell for a clockwork marauder, a well-rounded frontline fighter.
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
@@ -81,7 +171,7 @@
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = BELLIGERENT_EYE
- sort_priority = 4
+ sort_priority = 6
quickbind = TRUE
quickbind_desc = "Creates a clockwork marauder, used for frontline combat."
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
@@ -117,14 +207,13 @@
/datum/clockwork_scripture/create_object/summon_arbiter
descname = "Powerful Assault Mech"
name = "Summon Neovgre, the Anima Bulwark"
- desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
- mech with superior defensive and offensive capabilities. It will \
+ desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \
steadily regenerate HP and triple its regeneration speed while standing \
on a clockwork tile. It will automatically draw power from nearby sigils of \
transmission should the need arise. Its Arbiter laser cannon can decimate foes \
from a range and is capable of smashing through any barrier presented to it. \
- Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
- in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
+ Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \
+ in you cannot leave and when it is destroyed it will explode catastrophically, with you inside."
invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
power_cost = 75000 //75 KW
@@ -134,7 +223,7 @@
object_path = /obj/mecha/combat/neovgre
tier = SCRIPTURE_APPLICATION
primary_component = BELLIGERENT_EYE
- sort_priority = 2
+ sort_priority = 7
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_cyborg.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm
index 819dfac72e..3dacecf6b4 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm
@@ -1,5 +1,5 @@
/////////////////
-// CYBORG ONLY //
+// CYBORG ONLY // Cyborgs only, fleshed ones.
/////////////////
//Linked Vanguard: grants Vanguard to the invoker and a target
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
index 6349ecb581..c4b1913832 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
@@ -1,5 +1,5 @@
/////////////
-// DRIVERS //
+// DRIVERS // Starter spells
/////////////
//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight.
@@ -97,7 +97,7 @@
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 = 20 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
+ channel_time = 10 // I think making kindle channel a third of the time less is a good make up for the fact that it silences people for such a little amount of time.
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
@@ -113,7 +113,6 @@
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"
@@ -192,43 +191,39 @@
Click your slab to cancel."
+/*//commenting this out until its reworked to actually do random teleports
//Abscond: Used to return to Reebe.
/datum/clockwork_scripture/abscond
- descname = "Return to Reebe"
+ descname = "Safety warp, teleports you somewhere random. moderately high power cost to use."
name = "Abscond"
- desc = "Yanks you through space, returning you to home base."
+ desc = "Yanks you through space, putting you in hopefully a safe location."
invocations = list("As we bid farewell, and return to the stars...", "...we shall find our way home.")
whispered = TRUE
- channel_time = 50
- power_cost = 5
- special_power_text = "POWERCOST to bring pulled creature"
- special_power_cost = ABSCOND_ABDUCTION_COST
+ channel_time = 3.5
+ power_cost = 10000
usage_tip = "This can't be used while on Reebe, for obvious reasons."
tier = SCRIPTURE_DRIVER
primary_component = GEIS_CAPACITOR
sort_priority = 9
important = TRUE
quickbind = TRUE
- quickbind_desc = "Returns you to Reebe."
+ quickbind_desc = "Teleports you somewhere random, or to an active Ark if one exists. Use in emergencies."
var/client_color
requires_full_power = TRUE
/datum/clockwork_scripture/abscond/check_special_requirements()
if(is_reebe(invoker.z))
- to_chat(invoker, "
You're already at Reebe.")
+ to_chat(invoker, "
You're at Reebe, attempting to warp in the void could cause you to share your masters fate of banishment!.")
return
if(!isturf(invoker.loc))
- to_chat(invoker, "
You must be visible to return!")
+ to_chat(invoker, "
You must be visible to warp!")
return
return TRUE
/datum/clockwork_scripture/abscond/recital()
- client_color = invoker.client.color
- animate(invoker.client, color = "#AF0AAF", time = 50)
. = ..()
/datum/clockwork_scripture/abscond/scripture_effects()
- var/mob/living/pulled_mob = (invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)) ? invoker.pulling : null
var/turf/T
if(GLOB.ark_of_the_clockwork_justiciar)
T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH)
@@ -237,21 +232,12 @@
if(!do_teleport(invoker, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
return
invoker.visible_message("
[invoker] flickers and phases out of existence!", \
- "
You feel a dizzying sense of vertigo as you're yanked back to Reebe!")
+ "
You feel a dizzying sense of vertigo as you're yanked through the fabric of reality!")
T.visible_message("
[invoker] flickers and phases into existence!")
playsound(invoker, 'sound/magic/magic_missile.ogg', 50, TRUE)
playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE)
do_sparks(5, TRUE, invoker)
- do_sparks(5, TRUE, T)
- if(pulled_mob && do_teleport(pulled_mob, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
- adjust_clockwork_power(-special_power_cost)
- invoker.start_pulling(pulled_mob) //forcemove resets pulls, so we need to re-pull
- if(invoker.client)
- animate(invoker.client, color = client_color, time = 25)
-
-/datum/clockwork_scripture/abscond/scripture_fail()
- if(invoker && invoker.client)
- animate(invoker.client, color = client_color, time = 10)
+ do_sparks(5, TRUE, T)*/
//Replicant: Creates a new clockwork slab.
@@ -265,7 +251,7 @@
whispered = TRUE
object_path = /obj/item/clockwork/slab
creator_message = "
You copy a piece of replicant alloy and command it into a new slab."
- 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."
+ usage_tip = "This is inefficient as a way to produce power, as the slab produced must be held by someone with no other slabs to produce any."
tier = SCRIPTURE_DRIVER
space_allowed = TRUE
primary_component = GEIS_CAPACITOR
@@ -293,3 +279,50 @@
sort_priority = 11
quickbind = TRUE
quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss."
+
+//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk.
+/datum/clockwork_scripture/spatial_gateway
+ descname = "Teleport Gate"
+ name = "Spatial Gateway"
+ desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
+ Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
+ invocations = list("Spatial Gateway...", "...activate!")
+ channel_time = 30
+ power_cost = 400
+ whispered = TRUE
+ multiple_invokers_used = TRUE
+ multiple_invokers_optional = TRUE
+ usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
+ tier = SCRIPTURE_DRIVER
+ primary_component = GEIS_CAPACITOR
+ sort_priority = 9
+ quickbind = TRUE
+ quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
+
+/datum/clockwork_scripture/spatial_gateway/check_special_requirements()
+ if(!isturf(invoker.loc))
+ to_chat(invoker, "
You must not be inside an object to use this scripture!")
+ return FALSE
+ var/other_servants = 0
+ for(var/mob/living/L in GLOB.alive_mob_list)
+ if(is_servant_of_ratvar(L) && !L.stat && L != invoker)
+ other_servants++
+ for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
+ if(O.anchored)
+ other_servants++
+ if(!other_servants)
+ to_chat(invoker, "
There are no other conscious servants or anchored clockwork obelisks!")
+ return FALSE
+ return TRUE
+
+/datum/clockwork_scripture/spatial_gateway/scripture_effects()
+ var/portal_uses = 0
+ var/duration = 0
+ for(var/mob/living/L in range(1, invoker))
+ if(!L.stat && is_servant_of_ratvar(L))
+ portal_uses++
+ duration += 40 //4 seconds
+ if(GLOB.ratvar_awakens)
+ portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned
+ duration = max(duration, 100)
+ return slab.procure_gateway(invoker, duration, portal_uses)
\ No newline at end of file
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm
new file mode 100644
index 0000000000..5075840e76
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_judgement.dm
@@ -0,0 +1,44 @@
+///////////////
+// JUDGEMENT // For the big game changing things. TODO: Summonable generals, just need mob sprites for them.
+///////////////
+
+//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, summoning ratvar.
+/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar
+ descname = "Structure, Win Condition"
+ name = "Ark of the Clockwork Justiciar"
+ desc = "Tears apart a rift in spacetime to Reebe, the Celestial Derelict, using a massive amount of power.\n\
+ This gateway will, after some time, call forth Ratvar from his exile and massively empower all scriptures and tools."
+ invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! WE CALL UPON YOU!!", \
+ "THE TIME HAS COME FOR OUR MASTER TO BREAK THE CHAINS OF EXILE!!", \
+ "LEND US YOUR AID! ENGINE COMES!!")
+ channel_time = 150
+ power_cost = 70000 //70 KW. It's literally the thing wrenching the god out of another dimension why wouldn't it be costly.
+ invokers_required = 6
+ multiple_invokers_used = TRUE
+ object_path = /obj/structure/destructible/clockwork/massive/celestial_gateway
+ creator_message = "
The Ark swirls into existance before you with the help of the Generals. After all this time, he shall, finally, be free"
+ 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
+ requires_full_power = TRUE
+
+/datum/clockwork_scripture/create_object/ark_of_the_clockwork_justiciar/check_special_requirements()
+ if(!slab.no_cost)
+ if(GLOB.ratvar_awakens)
+ to_chat(invoker, "
\"I am already here, there is no point in that.\"")
+ return FALSE
+ for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in GLOB.all_clockwork_objects)
+ var/area/gate_area = get_area(G)
+ to_chat(invoker, "
There is already an Ark at [gate_area.map_name]!")
+ return FALSE
+ var/area/A = get_area(invoker)
+ var/turf/T = get_turf(invoker)
+ if(!T || !is_station_level(T.z) || istype(A, /area/shuttle) || !A.blob_allowed)
+ to_chat(invoker, "
You must be on the station to activate the Ark!")
+ return FALSE
+ if(GLOB.clockwork_gateway_activated)
+ to_chat(invoker, "
Ratvar's recent banishment renders him too weak to be wrung forth from Reebe!")
+ return FALSE
+ return ..()
+
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
index d22a2f69b7..d96765d536 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
@@ -1,5 +1,5 @@
/////////////
-// SCRIPTS //
+// SCRIPTS // Various miscellanious spells for offense/defense/construction.
/////////////
@@ -217,53 +217,6 @@
weapon_type = /obj/item/clockwork/weapon/ratvarian_spear
-//Spatial Gateway: Allows the invoker to teleport themselves and any nearby allies to a conscious servant or clockwork obelisk.
-/datum/clockwork_scripture/spatial_gateway
- descname = "Teleport Gate"
- name = "Spatial Gateway"
- desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
- Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
- invocations = list("Spatial Gateway...", "...activate!")
- channel_time = 80
- power_cost = 400
- multiple_invokers_used = TRUE
- 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 = GEIS_CAPACITOR
- sort_priority = 9
- quickbind = TRUE
- quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
-
-/datum/clockwork_scripture/spatial_gateway/check_special_requirements()
- if(!isturf(invoker.loc))
- to_chat(invoker, "
You must not be inside an object to use this scripture!")
- return FALSE
- var/other_servants = 0
- for(var/mob/living/L in GLOB.alive_mob_list)
- if(is_servant_of_ratvar(L) && !L.stat && L != invoker)
- other_servants++
- for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
- if(O.anchored)
- other_servants++
- if(!other_servants)
- to_chat(invoker, "
There are no other conscious servants or anchored clockwork obelisks!")
- return FALSE
- return TRUE
-
-/datum/clockwork_scripture/spatial_gateway/scripture_effects()
- var/portal_uses = 0
- var/duration = 0
- for(var/mob/living/L in range(1, invoker))
- if(!L.stat && is_servant_of_ratvar(L))
- portal_uses++
- duration += 40 //4 seconds
- if(GLOB.ratvar_awakens)
- portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned
- duration = max(duration, 100)
- return slab.procure_gateway(invoker, duration, portal_uses)
-
-
//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"
@@ -487,3 +440,26 @@
invoker.light_range = 0
invoker.update_light()
return ..()
+
+//Belligerent: Channeled for up to fifteen times over thirty seconds. Forces non-servants that can hear the chant to walk, doing minor damage. Nar-Sian cultists are burned.
+/datum/clockwork_scripture/channeled/belligerent
+ descname = "Channeled, Area Slowdown"
+ name = "Belligerent"
+ desc = "Forces all nearby non-servants to walk rather than run, doing minor damage. Chanted every two seconds for up to thirty seconds."
+ chant_invocations = list("Punish their blindness!", "Take time, make slow!", "Kneel before The Justiciar!", "Halt their charges!", "Cease the tides!")
+ chant_amount = 15
+ chant_interval = 20
+ channel_time = 20
+ power_cost = 300
+ usage_tip = "Useful for crowd control in a populated area and disrupting mass movement."
+ tier = SCRIPTURE_DRIVER
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 1
+ quickbind = TRUE
+ quickbind_desc = "Forces nearby non-Servants to walk, doing minor damage with each chant.
Maximum 15 chants."
+
+/datum/clockwork_scripture/channeled/belligerent/chant_effects(chant_number)
+ for(var/mob/living/carbon/C in hearers(7, invoker))
+ C.apply_status_effect(STATUS_EFFECT_BELLIGERENT)
+ new /obj/effect/temp_visual/ratvar/belligerent(get_turf(invoker))
+ return TRUE
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 297856f531..7478d45b08 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
@@ -1,5 +1,3 @@
-#define ARK_GRACE_PERIOD 300 //In seconds, how long the crew has before the Ark truly "begins"
-
/proc/clockwork_ark_active() //A helper proc so the Ark doesn't have to be typecast every time it's checked; returns null if there is no Ark and its active var otherwise
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(!G)
@@ -11,7 +9,7 @@
name = "\improper Ark of the Clockwork Justicar"
desc = "A massive, hulking amalgamation of parts. It seems to be maintaining a very unstable bluespace anomaly."
clockwork_desc = "Nezbere's magnum opus: a hulking clockwork machine capable of combining bluespace and steam power to summon Ratvar. Once activated, \
- its instability will cause one-way bluespace rifts to open across the station to the City of Cogs, so be prepared to defend it at all costs."
+ its instability will alert the entire area, so be prepared to defend it at all costs."
max_integrity = 500
mouse_opacity = MOUSE_OPACITY_OPAQUE
icon = 'icons/effects/clockwork_effects.dmi'
@@ -22,9 +20,8 @@
immune_to_servant_attacks = TRUE
var/active = FALSE
var/progress_in_seconds = 0 //Once this reaches GATEWAY_RATVAR_ARRIVAL, it's game over
- var/grace_period = ARK_GRACE_PERIOD //This exists to allow the crew to gear up and prepare for the invasion
- var/initial_activation_delay = -1 //How many seconds the Ark will have initially taken to activate
- var/seconds_until_activation = -1 //How many seconds until the Ark activates; if it should never activate, set this to -1
+ var/initial_activation_delay = 5 //How many seconds the Ark will have initially taken to activate
+ var/seconds_until_activation = 5 //How many seconds until the Ark activates; if it should never activate, set this to -1
var/purpose_fulfilled = FALSE
var/first_sound_played = FALSE
var/second_sound_played = FALSE
@@ -38,10 +35,21 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize()
. = ..()
+ INVOKE_ASYNC(src, .proc/spawn_animation)
glow = new(get_turf(src))
if(!GLOB.ark_of_the_clockwork_justiciar)
GLOB.ark_of_the_clockwork_justiciar = src
- START_PROCESSING(SSprocessing, src)
+
+/obj/structure/destructible/clockwork/massive/celestial_gateway/on_attack_hand(mob/user, act_intent, unarmed_attack_flags)
+ if(!active && is_servant_of_ratvar(user) && user.canUseTopic(src, !issilicon(user), NO_DEXTERY))
+ if(alert(user, "Are you sure you want to activate the ark? Once enabled, there will be no turning back.", "Enabling the ark", "Activate!", "Cancel") == "Activate!")
+ if(active)
+ return
+ log_game("[key_name(user)] has activated an Ark of the Clockwork Justicar at [COORD(src)].")
+ START_PROCESSING(SSprocessing, src)
+ SSshuttle.registerHostileEnvironment(src)
+ else
+ to_chat(user, "
You decide against activating the ark.. for now.")
/obj/structure/destructible/clockwork/massive/celestial_gateway/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -49,7 +57,7 @@
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!")
+ audible_message("
An unearthly screaming sound resonates throughout the area!")
for(var/V in GLOB.player_list)
var/mob/M = V
var/turf/T = get_turf(M)
@@ -60,31 +68,19 @@
/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
- seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes
+ ark_time = 5 //5 minutes
for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects)
C.infinite_resources = FALSE
GLOB.servants_active = TRUE
SSshuttle.registerHostileEnvironment(src)
-/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/cry_havoc()
- visible_message("
[src] shudders and roars to life, its parts beginning to whirr and screech!")
- hierophant_message("
The Ark is activating! You will be transported there soon!")
- for(var/mob/M in GLOB.player_list)
- var/turf/T = get_turf(M)
- if(is_servant_of_ratvar(M) || isobserver(M) || (T && T.z == z))
- M.playsound_local(M, 'sound/magic/clockwork/ark_activation_sequence.ogg', 30, FALSE, pressure_affected = FALSE)
- addtimer(CALLBACK(src, .proc/let_slip_the_dogs), 300)
-
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/let_slip_the_dogs()
- spawn_animation()
first_sound_played = TRUE
active = TRUE
+ visible_message("
[src] shudders and roars to life, its parts beginning to whirr and screech!")
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 for an attack on [station_name()]." : ""]", \
- "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg')
+ not a drill.", "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation_sequence.ogg')
set_security_level("delta")
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
@@ -92,15 +88,6 @@
continue
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)
- continue
- if(R.title == "wall gear")
- R.time *= 2 //Building walls becomes slower when the Ark activates
- mass_recall()
- recalls_remaining++ //So it doesn't use up a charge
-
var/turf/T = get_turf(src)
var/list/open_turfs = list()
for(var/turf/open/OT in orange(1, T))
@@ -110,14 +97,35 @@
for(var/mob/living/L in T)
L.forceMove(pick(open_turfs))
-/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/open_portal(turf/T)
- new/obj/effect/clockwork/city_of_cogs_rift(T)
-
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/spawn_animation()
- hierophant_message("
The Ark has activated! [grace_period ? "You have [round(grace_period / 60)] minutes until the crew invades! " : ""]Defend it at all costs!", FALSE, src)
- sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
- seconds_until_activation = 0
- SSshuttle.registerHostileEnvironment(src)
+ var/turf/T = get_turf(src)
+ new/obj/effect/clockwork/general_marker/inathneq(T)
+ hierophant_message("
\"[text2ratvar("Engine, come forth and show your servants your mercy")]!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/sevtug(T)
+ hierophant_message("
\"[text2ratvar("Engine, come forth and show this station your decorating skills")]!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 45, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/nezbere(T)
+ hierophant_message("
\"[text2ratvar("Engine, come forth and shine your light across this realm")]!!\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 60, 0)
+ sleep(10)
+ new/obj/effect/clockwork/general_marker/nzcrentr(T)
+ hierophant_message("
\"[text2ratvar("Engine, come forth")].\"")
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0)
+ sleep(10)
+ playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0)
+ var/list/open_turfs = list()
+ for(var/turf/open/OT in orange(1, T))
+ if(!is_blocked_turf(OT, TRUE))
+ open_turfs |= OT
+ if(open_turfs.len)
+ for(var/mob/living/L in T)
+ L.forceMove(pick(open_turfs))
+ glow = new(get_turf(src))
+ var/area/gate_area = get_area(src)
+ hierophant_message("
An Ark of the Clockwork Justicar has been created in [gate_area.map_name]!", FALSE, src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/initiate_mass_recall()
recalling = TRUE
@@ -141,35 +149,22 @@
transform = matrix() * 2
animate(src, transform = matrix() * 0.5, time = 30, flags = ANIMATION_END_NOW)
-/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
+obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
STOP_PROCESSING(SSprocessing, src)
+ if(!purpose_fulfilled)
+ var/area/gate_area = get_area(src)
+ hierophant_message("
An Ark of the Clockwork Justicar has fallen at [gate_area.map_name]!")
+ send_to_playing_players(sound(null, 0, channel = CHANNEL_JUSTICAR_ARK))
+ var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED
SSshuttle.clearHostileEnvironment(src)
- if(!purpose_fulfilled && istype(SSticker.mode, /datum/game_mode/clockwork_cult))
- hierophant_message("
The Ark has fallen!")
- sound_to_playing_players(null, channel = CHANNEL_JUSTICAR_ARK)
- SSticker.force_ending = TRUE //rip
+ if(!was_stranded && !purpose_fulfilled)
+ priority_announce("Massive energy anomaly no longer on short-range scanners, bluespace distortions still detected.","Central Command Higher Dimensional Affairs")
if(glow)
qdel(glow)
glow = null
if(countdown)
qdel(countdown)
countdown = null
- for(var/mob/L in GLOB.player_list)
- var/turf/T = get_turf(L)
- if(T && T.z == z)
- var/atom/movable/target = L
- if(isobj(L.loc))
- target = L.loc
- target.forceMove(get_turf(pick(GLOB.generic_event_spawns)))
- L.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
- L.clear_fullscreen("flash", 30)
- if(isliving(L))
- var/mob/living/LI = L
- LI.Stun(50)
- for(var/obj/effect/clockwork/city_of_cogs_rift/R in GLOB.all_clockwork_objects)
- qdel(R)
- if(GLOB.ark_of_the_clockwork_justiciar == src)
- GLOB.ark_of_the_clockwork_justiciar = null
. = ..()
/obj/structure/destructible/clockwork/massive/celestial_gateway/deconstruct(disassembled = TRUE)
@@ -203,8 +198,6 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE)
if(seconds_until_activation)
. = seconds_until_activation
- else if(grace_period)
- . = grace_period
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
. = round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1)
if(deciseconds)
@@ -213,8 +206,6 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
if(seconds_until_activation)
return "[get_arrival_time()][s_on_time ? "S" : ""]"
- if(grace_period)
- return "[get_arrival_time()][s_on_time ? "S" : ""]"
. = "IMMINENT"
if(!obj_integrity)
. = "DETONATING"
@@ -229,17 +220,14 @@
if(!active)
. += "
Time until the Ark's activation: [DisplayTimeText(get_arrival_time())]"
else
- if(grace_period)
- . += "
Crew grace period time remaining: [DisplayTimeText(get_arrival_time())]"
- else
- . += "
Time until Ratvar's arrival: [DisplayTimeText(get_arrival_time())]"
- switch(progress_in_seconds)
- if(-INFINITY to GATEWAY_REEBE_FOUND)
- . += "
The Ark is feeding power into the bluespace field."
- if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
- . += "
The field is ripping open a copy of itself in Ratvar's prison."
- if(GATEWAY_RATVAR_COMING to INFINITY)
- . += "
With the bluespace field established, Ratvar is preparing to come through!"
+ . += "
Time until Ratvar's arrival: [DisplayTimeText(get_arrival_time())]"
+ switch(progress_in_seconds)
+ if(-INFINITY to GATEWAY_REEBE_FOUND)
+ . += "
The Ark is feeding power into the bluespace field."
+ if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
+ . += "
The field is ripping open a copy of itself in Ratvar's prison."
+ if(GATEWAY_RATVAR_COMING to INFINITY)
+ . += "
With the bluespace field established, Ratvar is preparing to come through!"
else
if(!active)
. += "
Whatever it is, it doesn't seem to be active."
@@ -253,20 +241,14 @@
. += "
The anomaly is stable! Something is coming through!"
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
- if(seconds_until_activation == -1) //we never do anything
- return
adjust_clockwork_power(2.5) //Provides weak power generation on its own
if(seconds_until_activation)
if(!countdown)
countdown = new(src)
countdown.start()
seconds_until_activation--
- if(!GLOB.script_scripture_unlocked && initial_activation_delay * 0.5 > seconds_until_activation)
- GLOB.script_scripture_unlocked = TRUE
- hierophant_message("
The Ark is halfway prepared. Script scripture is now available!")
if(!seconds_until_activation)
- cry_havoc()
- seconds_until_activation = -1 //we'll set this after cry_havoc()
+ let_slip_the_dogs()
return
if(!first_sound_played || prob(7))
for(var/mob/M in GLOB.player_list)
@@ -285,6 +267,9 @@
if(!step_away(O, src, 2) || get_dist(O, src) < 2)
O.take_damage(50, BURN, "bomb")
O.update_icon()
+
+ conversion_pulse() //Converts the nearby area into clockcult-style
+
for(var/V in GLOB.player_list)
var/mob/M = V
var/turf/T = get_turf(M)
@@ -292,29 +277,24 @@
M.forceMove(get_step(src, SOUTH))
M.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
M.clear_fullscreen("flash", 5)
- if(grace_period)
- grace_period--
- return
progress_in_seconds += GATEWAY_SUMMON_RATE
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
if(!second_sound_played)
- for(var/V in GLOB.generic_event_spawns)
- addtimer(CALLBACK(src, .proc/open_portal, get_turf(V)), rand(100, 600))
sound_to_playing_players('sound/magic/clockwork/invoke_general.ogg', 30, FALSE)
- sound_to_playing_players(volume = 20, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
+ sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE))
second_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_charging"
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
if(!third_sound_played)
- sound_to_playing_players(volume = 25, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE))
+ sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE))
third_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_active"
if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL)
if(!fourth_sound_played)
- sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE))
+ sound_to_playing_players(volume = 70, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE))
fourth_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_closing"
@@ -334,7 +314,6 @@
GLOB.clockwork_gateway_activated = TRUE
var/turf/T = SSmapping.get_station_center()
new /obj/structure/destructible/clockwork/massive/ratvar(T)
- SSticker.force_ending = TRUE
var/x0 = T.x
var/y0 = T.y
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
@@ -349,6 +328,17 @@
T.ratvar_act(dist)
CHECK_TICK
+//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse()
+ var/convert_dist = 1 + (round(FLOOR(progress_in_seconds, 15) * 0.067))
+ for(var/t in RANGE_TURFS(convert_dist, loc))
+ var/turf/T = t
+ if(!T)
+ continue
+ var/dist = cheap_hypotenuse(T.x, T.y, x, y)
+ if(dist < convert_dist)
+ T.ratvar_act(FALSE, TRUE, 3)
+
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
if(!IsAdminGhost(user))
@@ -361,9 +351,9 @@
if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
message_admins("
Admin [key_name_admin(user)] started the Ark's countdown!")
log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!")
- to_chat(user, "
The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
+ to_chat(user, "The gamemode is now being treated as clockwork cult, and the Ark is counting down from 5 \
minutes. You will need to create servant players yourself.")
- final_countdown(35)
+ final_countdown(5)
diff --git a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
index f87f96b240..2b4b797b4d 100644
--- a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm
@@ -41,6 +41,11 @@
affected += try_use_power(MIN_CLOCKCULT_POWER*4)
return affected
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Destroy()
+ for(var/obj/effect/clockwork/spatial_gateway/SG in loc)
+ SG.ex_act(EXPLODE_DEVASTATE)
+ return ..()
+
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
@@ -48,7 +53,7 @@
if(!is_servant_of_ratvar(user) || !can_access_clockwork_power(src, hierophant_cost) || !anchored)
to_chat(user, "You place your hand on [src], but it doesn't react.")
return
- var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
+ var/choice = alert(user,"You place your hand on [src]...",,"Hierophant Broadcast","Spatial Gateway","Cancel") //Will create a stable gateway instead if between two obelisks one of which is onstation and the other on reebe
switch(choice)
if("Hierophant Broadcast")
if(active)
@@ -96,7 +101,7 @@
if(!anchored)
return
var/obj/effect/clockwork/spatial_gateway/SG = locate(/obj/effect/clockwork/spatial_gateway) in loc
- if(SG && SG.timerid) //it's a valid gateway, we're active
+ if(SG && (SG.timerid || SG.is_stable)) //it's a valid gateway, we're active
icon_state = active_icon
density = FALSE
active = TRUE
diff --git a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
index 77a629145d..5302153b9c 100644
--- a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
@@ -27,9 +27,6 @@
if(C.clock_team.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)
diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
index 44c7f78380..f8a3afbf91 100644
--- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
@@ -1,3 +1,5 @@
+
+
//Used to "declare war" against the station. The servants' equipment will be permanently supercharged, and the Ark given extra time to prepare.
//This will send an announcement to the station, meaning that they will be warned very early in advance about the impending attack.
/obj/structure/destructible/clockwork/heralds_beacon
@@ -108,5 +110,4 @@
to_chat(H, "The beacon's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!")
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/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm
new file mode 100644
index 0000000000..73488d736a
--- /dev/null
+++ b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm
@@ -0,0 +1,134 @@
+//Prolonging Prism: A prism that consumes power to delay the shuttle
+/obj/structure/destructible/clockwork/powered/prolonging_prism
+ name = "prolonging prism"
+ desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
+ clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle."
+ icon_state = "prolonging_prism_inactive"
+ active_icon = "prolonging_prism"
+ inactive_icon = "prolonging_prism_inactive"
+ unanchored_icon = "prolonging_prism_unwrenched"
+ construction_value = 20
+ max_integrity = 125
+ break_message = "The prism falls to the ground with a heavy thud!"
+ debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
+ /obj/item/clockwork/alloy_shards/medium = 1, \
+ /obj/item/clockwork/alloy_shards/large = 1, \
+ /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
+ var/static/power_refund = 250
+ var/static/delay_cost = 2000 //Updated power values for new-newclock. Easier to activate and sustain, you are quite literally pointing the entire station towards you as opposed to blood-delay after all.
+ var/static/delay_cost_increase = 1000
+ var/static/delay_remaining = 0
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user)
+ . = ..()
+ if(is_servant_of_ratvar(user) || isobserver(user))
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ . += "An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used."
+ else
+ var/efficiency = get_efficiency_mod(TRUE)
+ . += "It requires at least [DisplayPower(get_delay_cost())] of power to attempt to delay the arrival of an emergency shuttle by [2 * efficiency] minutes."
+ . += "This cost increases by [DisplayPower(delay_cost_increase)] for every previous activation."
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
+ if(active)
+ if(bad_effects)
+ try_use_power(MIN_CLOCKCULT_POWER*4)
+ visible_message("[src] emits an airy chuckling sound and falls dark!")
+ toggle()
+ return TRUE
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/on_attack_hand(mob/living/user)
+ if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ to_chat(user, "You break [src] apart, refunding some of the power used.")
+ adjust_clockwork_power(power_refund)
+ take_damage(max_integrity)
+ return 0
+ if(active)
+ return 0
+ var/turf/T = get_turf(src)
+ if(!T || !is_station_level(T.z))
+ to_chat(user, "[src] must be on the station to function!")
+ return 0
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL)
+ to_chat(user, "No emergency shuttles are attempting to arrive at the station!")
+ return 0
+ if(!try_use_power(get_delay_cost()))
+ to_chat(user, "[src] needs more power to function!")
+ return 0
+ delay_cost += delay_cost_increase
+ delay_remaining += PRISM_DELAY_DURATION
+ toggle(0, user)
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
+ var/turf/own_turf = get_turf(src)
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
+ forced_disable(FALSE)
+ return
+ . = ..()
+ var/delay_amount = 40
+ delay_remaining -= delay_amount
+ var/efficiency = get_efficiency_mod()
+ SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency))
+ var/highest_y
+ var/highest_x
+ var/lowest_y
+ var/lowest_x
+ var/list/prism_turfs = list()
+ for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home")))
+ prism_turfs[t] = TRUE
+ var/turf/T = t
+ if(!highest_y || T.y > highest_y)
+ highest_y = T.y
+ if(!highest_x || T.x > highest_x)
+ highest_x = T.x
+ if(!lowest_y || T.y < lowest_y)
+ lowest_y = T.y
+ if(!lowest_x || T.x < lowest_x)
+ lowest_x = T.x
+ var/mean_y = LERP(lowest_y, highest_y, 0.5)
+ var/mean_x = LERP(lowest_x, highest_x, 0.5)
+ if(prob(50))
+ mean_y = CEILING(mean_y, 1)
+ else
+ mean_y = FLOOR(mean_y, 1) //Yes, I know round(mean_y) does the same, just left as FLOOR for consistancy sake
+ if(prob(50))
+ mean_x = CEILING(mean_x, 1)
+ else
+ mean_x = FLOOR(mean_x, 1)
+ var/turf/semi_random_center_turf = locate(mean_x, mean_y, z)
+ for(var/t in getline(src, semi_random_center_turf))
+ prism_turfs[t] = TRUE
+ var/placement_style = prob(50)
+ for(var/t in prism_turfs)
+ var/turf/T = t
+ if(placement_style)
+ if(ISODD(T.x + T.y))
+ seven_random_hexes(T, efficiency)
+ else if(prob(50 * efficiency))
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
+ else
+ if(ISEVEN(T.x + T.y))
+ seven_random_hexes(T, efficiency)
+ else if(prob(50 * efficiency))
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
+ CHECK_TICK //we may be going over a hell of a lot of turfs
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
+ return FLOOR(delay_cost, MIN_CLOCKCULT_POWER)
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency)
+ var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7")
+ var/mutable_appearance/hex_combo
+ for(var/n in hex_states) //BUILD ME A HEXAGON
+ if(prob(50 * efficiency))
+ if(!hex_combo)
+ hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
+ else
+ hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER))
+ if(hex_combo) //YOU BUILT A HEXAGON
+ hex_combo.pixel_x = -16
+ hex_combo.pixel_y = -16
+ hex_combo.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ hex_combo.plane = GAME_PLANE
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo)
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 c17885315f..73ae89a19b 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
@@ -101,8 +101,8 @@
return
clashing = TRUE
GLOB.cult_narsie.clashing = TRUE
- to_chat(world, "\"YOU.\"")
- to_chat(world, "\"Ratvar?!\"")
+ to_chat(world, "\"[pick("YOU.", "BLOOD GOD!!", "FACE ME, COWARD!")]\"")
+ to_chat(world, "\"[pick("Ratvar?! How?!", "YOU. BANISHED ONCE. KILLED NOW.", "SCRAP HEAP!!")]\"")
clash_of_the_titans(GLOB.cult_narsie) // >:(
return TRUE
@@ -137,15 +137,16 @@
base_victory_chance *= 2 //The clash has a higher chance of resolving each time both gods attack one another
switch(winner)
if("Ratvar")
- send_to_playing_players("\"[pick("DIE.", "ROT.")]\"\n\
+ send_to_playing_players("\"[pick("DIE.", "ROT FOR CENTURIES, AS I HAVE!.","PERISH, HEATHEN.", "DIE, MONSTER, YOU DON'T BELONG IN THIS WORLD.")]\"\n\
\"[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"") //Nar'Sie get out
sound_to_playing_players('sound/magic/clockwork/anima_fragment_attack.ogg')
- sound_to_playing_players('sound/magic/demon_dies.ogg', 50)
+ sound_to_playing_players('sound/magic/abomscream.ogg', 50)
clashing = FALSE
qdel(narsie)
if("Nar'Sie")
- send_to_playing_players("\"[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]\"") //Broken English
- sound_to_playing_players('sound/magic/demon_attack1.ogg')
- sound_to_playing_players('sound/magic/clockwork/anima_fragment_death.ogg', 62)
+ send_to_playing_players("\"[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]\"\n\
+ \"[pick("NO, YOUR SHADOWS SHALL NO-", "ZNL GUR FGERNZF BS GVZR PNEEL ZL RKVFG-", "MY LIGHT CANNO-")]\"")
+ sound_to_playing_players('sound/magic/demon_attack1.ogg', 50)
+ sound_to_playing_players('sound/machines/clockcult/ratvar_scream.ogg', 80)
narsie.clashing = FALSE
qdel(src)
diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm
index 19144d67c9..ff012e556a 100644
--- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm
+++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm
@@ -167,10 +167,10 @@
return
if(last_man_standing)
if(syndicate)
- to_chat(owner.current," All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. ")
+ to_chat(owner.current,"All the suspected agents are dead, and no more is required of you. Die a glorious death, agent.")
+ replace_escape_objective(owner)
else
- to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.")
- replace_escape_objective(owner)
+ to_chat(owner.current,"All the other agents are dead. You have done us all a great service and shall be honorably exiled upon returning to base.")
/datum/antagonist/traitor/internal_affairs/proc/iaa_process()
if(owner&&owner.current&&owner.current.stat!=DEAD)
@@ -193,7 +193,7 @@
if(syndicate)
fail_msg += " You no longer have permission to die. "
else
- fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated."
+ fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to great shame."
reinstate_escape_objective(owner)
last_man_standing = FALSE
to_chat(owner.current, fail_msg)
@@ -226,18 +226,20 @@
add_objective(escape_objective)
/datum/antagonist/traitor/internal_affairs/proc/greet_iaa()
- var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
+ var/crime = pick("distribution of contraband" , "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
to_chat(owner.current, "You are the [special_role].")
if(syndicate)
- to_chat(owner.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.")
- to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.")
- to_chat(owner.current, " You have been provided with a standard uplink to accomplish your task. ")
- to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.")
+ to_chat(owner.current, "GREAT LEADER IS DEAD. NANOTRASEN MUST FALL.")
+ to_chat(owner.current, "Your have infiltrated this vessel to cause chaos and assassinate targets known to have conspired against the Syndicate.")
+ to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.")
+ to_chat(owner.current, "You have been provided with a standard uplink to accomplish your task. ")
+ to_chat(owner.current, "By no means reveal that you are a Syndicate agent. By no means reveal that your targets are being hunted.")
else
- to_chat(owner.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.")
- to_chat(owner.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.")
- to_chat(owner.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.")
+ to_chat(owner.current, "CAUTION: Your legal status as a citizen of NanoTrasen will be permanently revoked upon completion of your first contract.")
+ to_chat(owner.current, "Your target has been suspected of [crime], and must be removed from this plane.")
+ to_chat(owner.current, "While you have a license to kill, you are to eliminate your targets with no collateral or unrelated deaths.")
+ to_chat(owner.current, "For the sake of plausable deniability, you have been equipped with captured Syndicate equipment via uplink.")
to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.")
to_chat(owner.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.")
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 746bd3458a..49256b490d 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -257,10 +257,8 @@
if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed)
to_chat(our_guy, "You stumble a bit on your untied shoelaces!")
- if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove)
- addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
-
+ our_guy.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
+ our_guy.Stagger(SHOVE_OFFBALANCE_DURATION) //yes, same.
if(26 to 1000)
wiser = FALSE
if(wiser)
diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm
index 78fddbd989..328b4c391c 100644
--- a/code/modules/hydroponics/grown/replicapod.dm
+++ b/code/modules/hydroponics/grown/replicapod.dm
@@ -29,6 +29,28 @@
create_reagents(volume, INJECTABLE | DRAWABLE)
+/obj/item/seeds/replicapod/pre_attack(obj/machinery/hydroponics/I)
+ if(istype(I, /obj/machinery/hydroponics))
+ if(!I.myseed)
+ START_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/seeds/replicapod/proc/check_mind_orbiting(atom/A)
+ for(var/mob/M in A.orbiters?.orbiters)
+ if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == DEAD && !M.suiciding && isobserver(M))
+ return TRUE
+ return FALSE
+
+/obj/item/seeds/replicapod/process()
+ var/obj/machinery/hydroponics/parent = loc
+ if(parent.harvest != 1)
+ return
+ if (check_mind_orbiting(parent))
+ icon_harvest = "replicapod-orbit"
+ else
+ icon_harvest = "replicapod-harvest"
+ parent.update_icon_plant()
+
/obj/item/seeds/replicapod/on_reagent_change(changetype)
if(changetype == ADD_REAGENT)
var/datum/reagent/blood/B = reagents.has_reagent(/datum/reagent/blood)
@@ -59,8 +81,11 @@
/obj/item/seeds/replicapod/get_analyzer_text()
var/text = ..()
+ var/obj/machinery/hydroponics/parent = loc
if(contains_sample)
text += "\n It contains a blood sample!"
+ if (parent && istype(parent) && check_mind_orbiting(parent))
+ text += "\n The soul is ready to enter the body."
return text
@@ -115,7 +140,7 @@
features["mcolor"] = "#59CE00"
for(var/V in quirks)
new V(podman)
- podman.hardset_dna(null,null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
+ podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance()
else //else, one packet of seeds. maybe two
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 145db1be1e..b402260611 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1040,12 +1040,6 @@
return TRUE
return FALSE
-/mob/living/carbon/human/proc/clear_shove_slowdown()
- remove_movespeed_modifier(/datum/movespeed_modifier/shove)
- var/active_item = get_active_held_item()
- if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
- visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE)
-
/mob/living/carbon/human/updatehealth()
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 6e703fdbd7..dc7fe86aca 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1492,11 +1492,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
if(!SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
- damage *= 1.5
+ damage *= 1.2
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
- damage *= 0.5
+ damage *= 0.8
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
- damage *= 0.25
+ damage *= 0.8
//END OF CITADEL CHANGES
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
@@ -1935,11 +1935,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.visible_message("[user.name] shoves [target.name]!",
"[user.name] shoves you!", null, COMBAT_MESSAGE_RANGE, null,
user, "You shove [target.name]!")
+ target.Stagger(SHOVE_STAGGER_DURATION)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
- if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
- target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
+ if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!",
@@ -1947,12 +1947,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
- addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("[target.name] drops \the [target_held_item]!!",
"You drop \the [target_held_item]!!", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
+ target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index fb71693534..89321082c9 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -139,7 +139,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
- if(G.get_moles(/datum/gas/oxygen, 1))
+ if(!G.get_moles(/datum/gas/oxygen, 1))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 0029300936..87fd0cf609 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -500,6 +500,15 @@
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
return S
+///////////////////////////////// OFF BALANCE/SHOVIES ////////////////////////
+/mob/living/proc/ShoveOffBalance(amount)
+ var/datum/status_effect/off_balance/B = has_status_effect(STATUS_EFFECT_OFF_BALANCE)
+ if(B)
+ B.duration = max(world.time + amount, B.duration)
+ else if(amount > 0)
+ B = apply_status_effect(STATUS_EFFECT_OFF_BALANCE, amount)
+ return B
+
///////////////////////////////// FROZEN /////////////////////////////////////
/mob/living/proc/IsFrozen()
diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm
index a2176ca95e..d17767bb1f 100644
--- a/code/modules/movespeed/modifiers/mobs.dm
+++ b/code/modules/movespeed/modifiers/mobs.dm
@@ -78,9 +78,6 @@
blacklisted_movetypes = FLOATING
variable = TRUE
-/datum/movespeed_modifier/shove
- multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH
-
/datum/movespeed_modifier/human_carry
variable = TRUE
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 1159f0a405..ba51eb3bef 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -38,6 +38,8 @@
#define APC_CHARGING 1
#define APC_FULLY_CHARGED 2
+#define MAXIMUM_COG_REGAIN 100 //How much charge drained by an integration cog can be priority-recharged in one processing-tick
+
// the Area Power Controller (APC), formerly Power Distribution Unit (PDU)
// one per area, needs wire connection to power network through a terminal
@@ -94,6 +96,7 @@
var/mob/living/silicon/ai/occupier = null
var/transfer_in_progress = FALSE //Is there an AI being transferred out of us?
var/obj/item/clockwork/integration_cog/integration_cog //Is there a cog siphoning power?
+ var/cog_drained = 0 //How much of the cell's charge was drained by an integration cog, recovering this amount takes priority over the normal APC cell recharge calculations, but comes after powering Essentials.
var/longtermpower = 10
var/auto_name = 0
var/failure_timer = 0
@@ -499,6 +502,7 @@
cell.forceMove(T)
cell.update_icon()
cell = null
+ cog_drained = 0 //No more cell means no more averting celldrain
charging = APC_NOT_CHARGING
update_icon()
return
@@ -701,7 +705,7 @@
START_PROCESSING(SSfastprocess, W)
playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, FALSE)
opened = APC_COVER_CLOSED
- locked = FALSE
+ locked = TRUE //Clockies get full APC access on cogged APCs, but they can't lock or unlock em unless they steal some ID to give all of them APC access, soo this is pretty much just QoL for them and makes cogs a tiny bit more stealthy
update_icon()
return
else if(panel_open && !opened && is_wire_tool(W))
@@ -1311,6 +1315,11 @@
cur_used -= lastused_light
lighting_satisfied = TRUE
+ //If drained by an integration cog: Forcefully avert as much of the powerdrain as possible, though a maximum of MAXIMUM_COG_REGAIN
+ if(cur_excess && cog_drained && cell)
+ var/cog_regain = cell.give(min(min(cog_drained, cur_excess), MAXIMUM_COG_REGAIN))
+ cur_excess -= cog_regain
+ cog_drained = max(0, cog_drained - cog_regain)
// next: take from or charge to the cell, depending on how much is left
if(cell && !shorted)
@@ -1573,6 +1582,8 @@
#undef APC_UPOVERLAY_LOCKED
#undef APC_UPOVERLAY_OPERATING
+#undef MAXIMUM_COG_REGAIN
+
/*Power module, used for APC construction*/
/obj/item/electronics/apc
name = "power control module"
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 64fe786219..ba4870903e 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -375,7 +375,6 @@
log_combat(user, target, "shoved", "into [src] (disposal bin)")
return TRUE
-
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index 440e6cb03b..0076f584e9 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -1,4 +1,4 @@
-#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
+#define SYNDICATE_CHALLENGE_TIMER 9000 // 15 minutes
/obj/machinery/computer/shuttle/syndicate
name = "syndicate shuttle terminal"
@@ -21,8 +21,8 @@
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
if(href_list["move"])
var/obj/item/circuitboard/computer/syndicate_shuttle/board = circuit
- if(board.challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
- to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - world.time)] more to allow them to prepare.")
+ if(board.challenge && ((world.time - SSticker.round_start_time) < SYNDICATE_CHALLENGE_TIMER))
+ to_chat(usr, "You've issued a combat challenge to the station! You've got to give them at least [DisplayTimeText(SYNDICATE_CHALLENGE_TIMER - (world.time - SSticker.round_start_time))] more to allow them to prepare.")
return 0
board.moved = TRUE
..()
diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm
index d40e2fcbda..fbeaee8939 100644
--- a/code/modules/uplink/uplink_items/uplink_bundles.dm
+++ b/code/modules/uplink/uplink_items/uplink_bundles.dm
@@ -50,7 +50,7 @@
Combines with all martial arts, but the user will be unable to bring themselves to use guns, nor remove the armbands."
item = /obj/item/storage/box/syndie_kit/northstar
cost = 20
- exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/suits/infiltrator_bundle
name = "Insidious Infiltration Gear Case"
@@ -117,7 +117,7 @@
you will receive. May contain discontinued and/or exotic items."
item = /obj/item/storage/box/syndicate
cost = 20
- exclude_modes = list(/datum/game_mode/nuclear)
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/traitor/internal_affairs)
cant_discount = TRUE
/datum/uplink_item/bundles_TC/surplus
@@ -127,7 +127,7 @@
item = /obj/structure/closet/crate
cost = 20
player_minimum = 25
- exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
cant_discount = TRUE
var/starting_crate_value = 50
@@ -163,7 +163,7 @@
/datum/uplink_item/bundles_TC/reroll
name = "Renegotiate Contract"
- desc = "Selecting this will inform the syndicate that you wish to change employers. Can only be done once; no take-backs."
+ desc = "Selecting this will inform your employers that you wish for new objectives. Can only be done once; no take-backs."
item = /obj/effect/gibspawner/generic
cost = 0
cant_discount = TRUE
@@ -184,6 +184,7 @@
item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech
cost = 0
cant_discount = TRUE
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U)
var/list/uplink_items = U.uplink_items
diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm
index 7d96390115..e068094776 100644
--- a/code/modules/uplink/uplink_items/uplink_dangerous.dm
+++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm
@@ -21,7 +21,7 @@
item = /obj/item/storage/box/syndie_kit/revolver
cost = 13
surplus = 50
- exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/rawketlawnchair
name = "84mm Rocket Propelled Grenade Launcher"
@@ -112,7 +112,7 @@
item = /obj/item/dualsaber
player_minimum = 25
cost = 16
- exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/doublesword/get_discount()
return pick(4;0.8,2;0.65,1;0.5)
@@ -123,7 +123,7 @@
pocketed when inactive. Activating it produces a loud, distinctive noise."
item = /obj/item/melee/transforming/energy/sword/saber
cost = 8
- exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/shield
name = "Energy Shield"
@@ -141,7 +141,7 @@
However, due to the size of the blade and obvious nature of the sheath, the weapon stands out as being obviously nefarious."
item = /obj/item/storage/belt/sabre/rapier
cost = 8
- exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/flamethrower
name = "Flamethrower"
@@ -180,7 +180,7 @@
refundable = TRUE
cant_discount = TRUE
surplus = 0
- exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
player_minimum = 25
restricted = TRUE
refund_path = /obj/item/guardiancreator/tech/choose/traitor
@@ -211,6 +211,7 @@
deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks."
item = /obj/item/melee/powerfist
cost = 8
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/dangerous/sniper
name = "Sniper Rifle"
@@ -250,4 +251,4 @@
darts effective at incapacitating a target."
item = /obj/item/gun/ballistic/automatic/toy/pistol/riot
cost = 3
- surplus = 10
\ No newline at end of file
+ surplus = 10
diff --git a/code/modules/uplink/uplink_items/uplink_explosives.dm b/code/modules/uplink/uplink_items/uplink_explosives.dm
index c52651fee9..6cc1c9fe05 100644
--- a/code/modules/uplink/uplink_items/uplink_explosives.dm
+++ b/code/modules/uplink/uplink_items/uplink_explosives.dm
@@ -58,6 +58,7 @@
item = /obj/item/storage/backpack/duffelbag/syndie/x4
cost = 4 //
cant_discount = TRUE
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/clown_bomb_clownops
name = "Clown Bomb"
@@ -123,6 +124,7 @@
be defused, and some crew may attempt to do so."
item = /obj/item/sbeacondrop/bomb
cost = 11
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/syndicate_detonator
name = "Syndicate Detonator"
@@ -140,7 +142,7 @@
in addition to dealing high amounts of damage to nearby personnel."
item = /obj/item/grenade/syndieminibomb
cost = 6
- exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/explosives/tearstache
name = "Teachstache Grenade"
diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm
index 859c8c0bd7..b8eaf41371 100644
--- a/code/modules/uplink/uplink_items/uplink_roles.dm
+++ b/code/modules/uplink/uplink_items/uplink_roles.dm
@@ -30,6 +30,7 @@
item = /obj/item/gun/blastcannon
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist.
restricted_roles = list("Research Director", "Scientist")
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/alientech
name = "Alien Research Disk"
@@ -100,6 +101,7 @@
player_minimum = 20
refundable = TRUE
restricted_roles = list("Chaplain")
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/arcane_tome
name = "Arcane Tome"
@@ -109,6 +111,7 @@
player_minimum = 20
refundable = TRUE
restricted_roles = list("Chaplain")
+ exclude_modes = list(/datum/game_mode/traitor/internal_affairs)
/datum/uplink_item/role_restricted/explosive_hot_potato
name = "Exploding Hot Potato"
diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm
index c60d4ef177..ff6d66a483 100644
--- a/code/modules/uplink/uplink_items/uplink_stealth.dm
+++ b/code/modules/uplink/uplink_items/uplink_stealth.dm
@@ -65,6 +65,16 @@
surplus = 0
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
+/datum/uplink_item/stealthy_weapons/martialartsthree
+ name = "Krav Maga Scroll"
+ desc = "This scroll contains the secrets of an ancient martial arts technique. You will gain special unarmed attacks for \
+ stealthy takedowns."
+ item = /obj/item/book/granter/martial/krav_maga
+ cost = 16
+ player_minimum = 25
+ surplus = 0
+ include_modes = list(/datum/game_mode/traitor/internal_affairs)
+
/datum/uplink_item/stealthy_weapons/crossbow
name = "Miniature Energy Crossbow"
desc = "A short bow mounted across a tiller in miniature. Small enough to \
diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm
index beaf6bb873..69635007c9 100644
--- a/code/modules/vending/cartridge.dm
+++ b/code/modules/vending/cartridge.dm
@@ -10,6 +10,7 @@
/obj/item/cartridge/security = 10,
/obj/item/cartridge/janitor = 10,
/obj/item/cartridge/signal/toxins = 10,
+ /obj/item/cartridge/roboticist = 10,
/obj/item/pda/heads = 10)
premium = list(/obj/item/cartridge/captain = 2,
/obj/item/cartridge/quartermaster = 2)
diff --git a/config/config.txt b/config/config.txt
index d6d0097c21..46f9a0cdc4 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -525,3 +525,7 @@ FAIL2TOPIC_RULE_NAME _dd_fail2topic
## Enable automatic profiling - Byond 513.1506 and newer only.
#AUTO_PROFILE
+
+## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL.
+## More API details can be found here: https://centcom.melonmesa.com
+CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search
diff --git a/html/changelog.html b/html/changelog.html
index b87a49f7f2..b72721fcdd 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -50,6 +50,49 @@
-->
+
02 August 2020
+
Auris456852 updated:
+
+ - Added B.O.O.P. Remote Control cartridges to the PTech.
+
+
Hatterhat updated:
+
+ - Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor to durathread levels, craft in the crafting menu.
+
+
KeRSedChaplain updated:
+
+ - The belligerent scripture and a brass multitool, and a new marauder variant which act similar to holoparasites/guardian spirits.
+ - Removed the abductor teleport consoles they get, removes abscond for the time being as I've not seen much use for it other than just spamming it and hoping you end up in the armory.
+ - moved around scriptures to make the cult work better as being based around the station, makes the Ark scream more often and work as a summonable object, clockwork armor now has a flat 0 defense up to 10 instead of negatives against laser damage. Makes the Ark work better in a station based setting, as well as the Heralds beacon in case It works for the mode.
+ - added powerloaderstep.ogg for Neovgre
+ - changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
+
+
MrJWhit updated:
+
+ - Adjusts abductor spawntext
+
+
Seris02 updated:
+
+
dapnee updated:
+
+ - fixed active turfs on wizard ruin and space hermit, fixed missing APC's and added a light on Delta
+
+
ike709 and bobbahbrown updated:
+
+ - Admins can now see your bans on (some) other servers.
+
+
kappa-sama updated:
+
+ - chaplain cultists being able to convert people to full clockwork cult status
+
+
timothyteakettle updated:
+
+ - combat mode now has weaker buffs in terms of damage dealt and took for being or not being in the mode
+ - damage debuff for laying down has been decreased from 0.5x to 0.7x
+
+
01 August 2020
dapnee updated:
@@ -60,6 +103,7 @@
silicons updated:
- toy shotguns no longer need 2 hands to fire
+ - being on fire works again.
timothyteakettle updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 26f91f06ed..a3a5724548 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -26658,5 +26658,41 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
AIR alarm, arrivals no longer has active atmos tiles.
silicons:
- tweak: toy shotguns no longer need 2 hands to fire
+ - bugfix: being on fire works again.
timothyteakettle:
- bugfix: monkeys no longer continuously bleed everywhere
+2020-08-02:
+ Auris456852:
+ - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech.
+ Hatterhat:
+ - rscadd: Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor
+ to durathread levels, craft in the crafting menu.
+ KeRSedChaplain:
+ - rscadd: The belligerent scripture and a brass multitool, and a new marauder variant
+ which act similar to holoparasites/guardian spirits.
+ - rscdel: Removed the abductor teleport consoles they get, removes abscond for the
+ time being as I've not seen much use for it other than just spamming it and
+ hoping you end up in the armory.
+ - tweak: moved around scriptures to make the cult work better as being based around
+ the station, makes the Ark scream more often and work as a summonable object,
+ clockwork armor now has a flat 0 defense up to 10 instead of negatives against
+ laser damage. Makes the Ark work better in a station based setting, as well
+ as the Heralds beacon in case It works for the mode.
+ - soundadd: added powerloaderstep.ogg for Neovgre
+ - tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi'
+ MrJWhit:
+ - tweak: Adjusts abductor spawntext
+ Seris02:
+ - bugfix: fixed replica pods
+ dapnee:
+ - bugfix: fixed active turfs on wizard ruin and space hermit, fixed missing APC's
+ and added a light on Delta
+ ike709 and bobbahbrown:
+ - rscadd: Admins can now see your bans on (some) other servers.
+ kappa-sama:
+ - bugfix: chaplain cultists being able to convert people to full clockwork cult
+ status
+ timothyteakettle:
+ - tweak: combat mode now has weaker buffs in terms of damage dealt and took for
+ being or not being in the mode
+ - tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x
diff --git a/html/changelogs/AutoChangeLog-pr-12912.yml b/html/changelogs/AutoChangeLog-pr-12912.yml
new file mode 100644
index 0000000000..9f98509351
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12912.yml
@@ -0,0 +1,4 @@
+author: "Linzolle"
+delete-after: True
+changes:
+ - bugfix: "uv penlight no longer invisible"
diff --git a/html/changelogs/AutoChangeLog-pr-12925.yml b/html/changelogs/AutoChangeLog-pr-12925.yml
new file mode 100644
index 0000000000..5e38656352
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12925.yml
@@ -0,0 +1,5 @@
+author: "silicons"
+delete-after: True
+changes:
+ - rscadd: "shoves have been buffed to apply a status effect rather than a 0.85 movespeed modifier, meaning repeatedly shoving someone now renews the debuff"
+ - balance: "shoves now stagger for 3.5 seconds."
diff --git a/html/changelogs/AutoChangeLog-pr-12983.yml b/html/changelogs/AutoChangeLog-pr-12983.yml
new file mode 100644
index 0000000000..ca87590c23
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12983.yml
@@ -0,0 +1,4 @@
+author: "silicons"
+delete-after: True
+changes:
+ - tweak: "war operatives now actually time 20 minutes since roundstart to depart instead of 15."
diff --git a/html/changelogs/AutoChangeLog-pr-12999.yml b/html/changelogs/AutoChangeLog-pr-12999.yml
new file mode 100644
index 0000000000..c2358348fd
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12999.yml
@@ -0,0 +1,4 @@
+author: "KeRSedChaplain"
+delete-after: True
+changes:
+ - bugfix: "fixed clockwork guardians being able to reflect ranged weapons"
diff --git a/icons/mob/clockwork_mobs.dmi b/icons/mob/clockwork_mobs.dmi
index 5985adf12d..54690f6cac 100644
Binary files a/icons/mob/clockwork_mobs.dmi and b/icons/mob/clockwork_mobs.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
index 1948bb605c..ae919d85a4 100644
Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/clothing/reinf_kits.dmi b/icons/obj/clothing/reinf_kits.dmi
new file mode 100644
index 0000000000..3b23d53342
Binary files /dev/null and b/icons/obj/clothing/reinf_kits.dmi differ
diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi
index c93865ca77..5415f47528 100644
Binary files a/icons/obj/hydroponics/growing.dmi and b/icons/obj/hydroponics/growing.dmi differ
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index c3ca67eeae..0e262895fd 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index f1a8cf3c02..0a457777c2 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/sound/machines/clockcult/ratvar_scream.ogg b/sound/machines/clockcult/ratvar_scream.ogg
new file mode 100644
index 0000000000..5c0c0a0d63
Binary files /dev/null and b/sound/machines/clockcult/ratvar_scream.ogg differ
diff --git a/sound/magic/abomscream.ogg b/sound/magic/abomscream.ogg
new file mode 100644
index 0000000000..4f450e05f7
Binary files /dev/null and b/sound/magic/abomscream.ogg differ
diff --git a/sound/mecha/neostep1.ogg b/sound/mecha/neostep1.ogg
new file mode 100644
index 0000000000..ce7f51ad23
Binary files /dev/null and b/sound/mecha/neostep1.ogg differ
diff --git a/sound/mecha/neostep2.ogg b/sound/mecha/neostep2.ogg
new file mode 100644
index 0000000000..e828d9eadd
Binary files /dev/null and b/sound/mecha/neostep2.ogg differ
diff --git a/sound/mecha/powerloader_step.ogg b/sound/mecha/powerloader_step.ogg
new file mode 100644
index 0000000000..af427df865
Binary files /dev/null and b/sound/mecha/powerloader_step.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 8a7149a1ba..e0a2276e13 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -232,6 +232,7 @@
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\blob_overmind.dm"
#include "code\_onclick\hud\blobbernauthud.dm"
+#include "code\_onclick\hud\clockwork_marauder.dm"
#include "code\_onclick\hud\constructs.dm"
#include "code\_onclick\hud\credits.dm"
#include "code\_onclick\hud\devil.dm"
@@ -377,6 +378,7 @@
#include "code\datums\explosion.dm"
#include "code\datums\forced_movement.dm"
#include "code\datums\holocall.dm"
+#include "code\datums\http.dm"
#include "code\datums\hud.dm"
#include "code\datums\mind.dm"
#include "code\datums\mutable_appearance.dm"
@@ -972,6 +974,7 @@
#include "code\game\objects\items\AI_modules.dm"
#include "code\game\objects\items\airlock_painter.dm"
#include "code\game\objects\items\apc_frame.dm"
+#include "code\game\objects\items\armor_kits.dm"
#include "code\game\objects\items\balls.dm"
#include "code\game\objects\items\binoculars.dm"
#include "code\game\objects\items\blueprints.dm"
@@ -1543,6 +1546,7 @@
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_applications.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_cyborg.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_drivers.dm"
+#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_judgement.dm"
#include "code\modules\antagonists\clockcult\clock_scriptures\scripture_scripts.dm"
#include "code\modules\antagonists\clockcult\clock_structures\_trap_object.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ark_of_the_clockwork_justicar.dm"
@@ -1551,6 +1555,7 @@
#include "code\modules\antagonists\clockcult\clock_structures\heralds_beacon.dm"
#include "code\modules\antagonists\clockcult\clock_structures\mania_motor.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ocular_warden.dm"
+#include "code\modules\antagonists\clockcult\clock_structures\prolonging_prism.dm"
#include "code\modules\antagonists\clockcult\clock_structures\ratvar_the_clockwork_justicar.dm"
#include "code\modules\antagonists\clockcult\clock_structures\reflector.dm"
#include "code\modules\antagonists\clockcult\clock_structures\stargazer.dm"