diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index cc8104f98b..d505f69ac9 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -42,6 +42,8 @@
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
+#define STATUS_EFFECT_GEISTRACKER /datum/status_effect/geis_tracker //if you're using geis, this tracks that and keeps you from using scripture
+
#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 2c651b7738..02e7d0f515 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -139,6 +139,20 @@
if(owner.m_intent == MOVE_INTENT_WALK)
owner.toggle_move_intent()
+/datum/status_effect/geis_tracker
+ id = "geis_tracker"
+ duration = -1
+ alert_type = null
+ var/obj/structure/destructible/clockwork/geis_binding/binding
+
+/datum/status_effect/geis_tracker/on_creation(mob/living/new_owner, obj/structure/destructible/clockwork/geis_binding/new_binding)
+ . = ..()
+ if(.)
+ binding = new_binding
+
+/datum/status_effect/geis_tracker/tick()
+ if(QDELETED(binding))
+ qdel(src)
/datum/status_effect/maniamotor
id = "maniamotor"
diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
index 31a98f572f..507c673921 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
@@ -11,9 +11,21 @@
var/stat_affected = CONSCIOUS
var/sigil_name = "Sigil"
var/resist_string = "glows blinding white" //string for when a null rod blocks its effects, "glows [resist_string]"
+ var/list/component_refund = list()
/obj/effect/clockwork/sigil/attackby(obj/item/I, mob/living/user, params)
- if(I.force && !is_servant_of_ratvar(user))
+ if(is_servant_of_ratvar(user))
+ if(istype(I, /obj/item/clockwork/slab))
+ user.visible_message("[user] starts to dispel [src]...", "You start to dispel [src]...")
+ if(do_after(user, 20, target = src))
+ user.visible_message("[user] dispels [src]!", "You dispel [src]!")
+ for(var/i in component_refund)
+ if(component_refund[i])
+ for(var/r in 1 to component_refund[i])
+ generate_cache_component(i, src)
+ qdel(src)
+ return 1
+ else if(I.force)
user.visible_message("[user] scatters [src] with [I]!", "You scatter [src] with [I]!")
qdel(src)
return 1
@@ -63,6 +75,7 @@
light_power = 1
light_color = "#FAE48C"
sigil_name = "Sigil of Transgression"
+ component_refund = list(HIEROPHANT_ANSIBLE = 1)
/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
var/target_flashed = L.flash_act()
@@ -94,27 +107,33 @@
light_color = "#FAE48C"
stat_affected = UNCONSCIOUS
resist_string = "glows faintly yellow"
+ sigil_name = "Sigil of Submission"
+ component_refund = list(GEIS_CAPACITOR = 1)
var/convert_time = 80
var/delete_on_finish = TRUE
- sigil_name = "Sigil of Submission"
var/glow_type = /obj/effect/temp_visual/ratvar/sigil/submission
/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
+ if(istype(L.buckled, /obj/structure/destructible/clockwork/geis_binding))
+ if(is_servant_of_ratvar(L.pulledby))
+ L.pulledby.stop_pulling()
+ if(is_servant_of_ratvar(L.buckled.pulledby))
+ L.buckled.pulledby.stop_pulling()
L.visible_message("[src] begins to glow a piercing magenta!", "You feel something start to invade your mind...")
var/oldcolor = color
- animate(src, color = "#AF0AAF", time = convert_time, flags_1 = ANIMATION_END_NOW)
+ animate(src, color = "#AF0AAF", time = convert_time, flags = ANIMATION_END_NOW)
var/obj/effect/temp_visual/ratvar/sigil/glow
if(glow_type)
glow = new glow_type(get_turf(src))
animate(glow, alpha = 255, time = convert_time)
var/I = 0
- while(I < convert_time && get_turf(L) == get_turf(src))
+ while(I < convert_time && !QDELETED(L) && get_turf(L) == get_turf(src))
I++
sleep(1)
- if(get_turf(L) != get_turf(src))
+ if(QDELETED(L) || get_turf(L) != get_turf(src))
if(glow)
qdel(glow)
- animate(src, color = oldcolor, time = 20, flags_1 = ANIMATION_END_NOW)
+ animate(src, color = oldcolor, time = 20, flags = ANIMATION_END_NOW)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 20)
visible_message("[src] slowly stops glowing!")
return
@@ -136,7 +155,7 @@
to_chat(M, "[message] you!")
else
to_chat(M, "[message] [L.real_name]!")
- animate(src, color = oldcolor, time = 20, flags_1 = ANIMATION_END_NOW)
+ animate(src, color = oldcolor, time = 20, flags = ANIMATION_END_NOW)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 20)
visible_message("[src] slowly stops glowing!")
@@ -152,6 +171,7 @@
light_color = "#EC8A2D"
resist_string = "glows faintly"
sigil_name = "Sigil of Transmission"
+ component_refund = list(HIEROPHANT_ANSIBLE = 1)
affects_servants = TRUE
var/power_charge = 0 //starts with no power
var/drain_range = 14
@@ -296,6 +316,7 @@
stat_affected = DEAD
resist_string = "glows shimmering yellow"
sigil_name = "Vitality Matrix"
+ component_refund = list(VANGUARD_COGWHEEL = 1)
var/revive_cost = 150
var/sigil_active = FALSE
var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets
@@ -314,7 +335,7 @@
if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active)
return
visible_message("[src] begins to glow bright blue!")
- animate(src, alpha = 255, time = 10, flags_1 = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay.
+ animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay.
sleep(10)
//as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality
while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || GLOB.clockwork_vitality))) && get_turf(L) == get_turf(src))
@@ -380,4 +401,4 @@
animation_number = initial(animation_number)
sigil_active = FALSE
visible_message("[src] slowly stops glowing!")
- animate(src, alpha = initial(alpha), time = 10, flags_1 = ANIMATION_END_NOW)
+ animate(src, alpha = initial(alpha), time = 10, flags = ANIMATION_END_NOW)
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
index 74d9112fc4..fb3a0c3de2 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
@@ -24,15 +24,10 @@
//For the Geis scripture; binds a target to convert.
/obj/effect/proc_holder/slab/geis
ranged_mousepointer = 'icons/effects/geis_target.dmi'
- var/obj/structure/destructible/clockwork/geis_binding/binding //we always have a reference to the binding
- var/obj/structure/destructible/clockwork/geis_binding/pulled_binding //we use this to see if we're pulling it or not
-
-/obj/effect/proc_holder/slab/geis/remove_ranged_ability(msg)
- ..()
- binding = null
- pulled_binding = null
/obj/effect/proc_holder/slab/geis/InterceptClickOn(mob/living/caller, params, atom/target)
+ if(..())
+ return TRUE
var/turf/T = ranged_ability_user.loc
if(!isturf(T))
return TRUE
@@ -40,20 +35,6 @@
var/target_is_binding = istype(target, /obj/structure/destructible/clockwork/geis_binding)
if((target_is_binding || isliving(target)) && ranged_ability_user.Adjacent(target))
- if(in_progress || ..())
- var/mob/living/L = target
- if(!pulled_binding)
- if(target == binding || (isliving(target) && L.buckled == binding))
- pulled_binding = binding
- ranged_ability_user.start_pulling(binding)
- remove_mousepointer(ranged_ability_user.client)
- ranged_mousepointer = 'icons/effects/geis_target_remove.dmi'
- add_mousepointer(ranged_ability_user.client)
- else if(target == pulled_binding || (isliving(target) && L.buckled == pulled_binding))
- ranged_ability_user.visible_message("[ranged_ability_user] dispels [pulled_binding]!", "You dispel the binding!")
- binding.take_damage(obj_integrity)
- remove_ranged_ability()
- return TRUE
if(target_is_binding)
var/obj/structure/destructible/clockwork/geis_binding/GB = target
GB.repair_and_interrupt()
@@ -80,42 +61,19 @@
add_logs(ranged_ability_user, L, "rebound with Geis")
successful = TRUE
else
- in_progress = TRUE
clockwork_say(ranged_ability_user, text2ratvar("Be bound, heathen!"))
- remove_mousepointer(ranged_ability_user.client)
- ranged_mousepointer = 'icons/effects/geis_target_remove.dmi'
- add_mousepointer(ranged_ability_user.client)
add_logs(ranged_ability_user, L, "bound with Geis")
- playsound(target, 'sound/magic/blink.ogg', 50, TRUE, frequency = 0.5)
+ playsound(target, 'sound/magic/blink.ogg', 50, TRUE, -4, frequency = 0.5)
if(slab.speed_multiplier >= 0.5) //excuse my debug...
ranged_ability_user.notransform = TRUE
- addtimer(CALLBACK(src, .proc/reset_user_notransform, ranged_ability_user), 5) //stop us moving for a little bit so we don't break the binding immediately
+ addtimer(CALLBACK(src, .proc/reset_user_notransform, ranged_ability_user), 4) //stop us moving for a little bit so we don't break the binding immediately
if(L.buckled)
L.buckled.unbuckle_mob(target, TRUE)
- binding = new(get_turf(target))
+ var/obj/structure/destructible/clockwork/geis_binding/binding = new(get_turf(target))
binding.setDir(target.dir)
binding.buckle_mob(target, TRUE)
- pulled_binding = binding
ranged_ability_user.start_pulling(binding)
- slab.busy = "sustaining Geis"
- slab.flags_1 |= NODROP_1
- while(!QDELETED(binding) && !QDELETED(ranged_ability_user))
- if(ranged_ability_user.pulling == binding)
- pulled_binding = binding
- if(ranged_ability_user.client && ranged_ability_user.client.mouse_pointer_icon == 'icons/effects/geis_target.dmi')
- remove_mousepointer(ranged_ability_user.client)
- ranged_mousepointer = 'icons/effects/geis_target_remove.dmi'
- add_mousepointer(ranged_ability_user.client)
- else //if we're not pulling it, swap our mousepointer
- pulled_binding = null
- if(ranged_ability_user.client && ranged_ability_user.client.mouse_pointer_icon == 'icons/effects/geis_target_remove.dmi')
- remove_mousepointer(ranged_ability_user.client)
- ranged_mousepointer = 'icons/effects/geis_target.dmi'
- add_mousepointer(ranged_ability_user.client)
- sleep(1)
- if(!QDELETED(slab))
- slab.flags_1 &= ~NODROP_1
- in_progress = FALSE
+ ranged_ability_user.apply_status_effect(STATUS_EFFECT_GEISTRACKER, binding)
successful = TRUE
remove_ranged_ability()
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index 382aaec10d..318d3e243d 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -57,6 +57,9 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(slab.busy)
to_chat(invoker, "[slab] refuses to work, displaying the message: \"[slab.busy]!\"")
return FALSE
+ if(invoker.has_status_effect(STATUS_EFFECT_GEISTRACKER))
+ to_chat(invoker, "[slab] refuses to work, displaying the message: \"Sustaining Geis!\"")
+ return FALSE
slab.busy = "Invocation ([name]) in progress"
if(GLOB.ratvar_awakens)
channel_time *= 0.5 //if ratvar has awoken, half channel time and no cost
diff --git a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
index 734ea8eb17..029fd552e2 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
@@ -2,8 +2,8 @@
/obj/structure/destructible/clockwork/geis_binding
name = "glowing ring"
desc = "A flickering, glowing purple ring around a target."
- clockwork_desc = "A binding ring around a target, preventing them from taking action while they're being converted."
- max_integrity = 25
+ clockwork_desc = "A binding ring around a target, preventing them from taking action."
+ max_integrity = 20
light_range = 2
light_power = 0.8
light_color = "#AF0AAF"
@@ -18,6 +18,8 @@
can_buckle = TRUE
buckle_lying = 0
var/mob_layer = MOB_LAYER
+ var/last_mob_health = 0
+ var/apply_time = 0
/obj/structure/destructible/clockwork/geis_binding/Initialize(mapload, obj/item/clockwork/slab/the_slab)
. = ..()
@@ -33,21 +35,39 @@
icon_state = "geisbinding"
/obj/structure/destructible/clockwork/geis_binding/process()
+ var/tick_damage = 1
+ if(locate(/obj/effect/clockwork/sigil/submission) in loc)
+ tick_damage *= 0.5
if(LAZYLEN(buckled_mobs))
for(var/V in buckled_mobs)
var/mob/living/L = V
if(is_servant_of_ratvar(L)) //servants are freed automatically
take_damage(obj_integrity)
return
- var/tick_damage = 1
- if(!is_servant_of_ratvar(pulledby))
- tick_damage++
+ if(last_mob_health > L.health)
+ tick_damage += last_mob_health - L.health
+ last_mob_health = L.health
+ if(L.layer != mob_layer)
+ mob_layer = L.layer
+ layer = mob_layer - 0.01
+ cut_overlays()
+ add_overlay(mutable_appearance('icons/effects/clockwork_effects.dmi', "geisbinding_top", mob_layer + 0.01))
+ break
take_damage(tick_damage, sound_effect = FALSE)
- playsound(src, 'sound/effects/empulse.ogg', tick_damage * 20, TRUE)
+ playsound(src, 'sound/effects/empulse.ogg', tick_damage * 40, TRUE, -4)
/obj/structure/destructible/clockwork/geis_binding/attack_hand(mob/living/user)
return
+/obj/structure/destructible/clockwork/geis_binding/attackby(obj/item/I, mob/user, params)
+ if(is_servant_of_ratvar(user) && istype(I, /obj/item/clockwork/slab))
+ user.visible_message("[user] starts to dispel [src]...", "You start to dispel [src]...")
+ if(do_after(user, 30, target = src))
+ user.visible_message("[user] dispels [src]!", "You dispel [src]!")
+ take_damage(obj_integrity)
+ return 1
+ return ..()
+
/obj/structure/destructible/clockwork/geis_binding/emp_act(severity)
new /obj/effect/temp_visual/emp(loc)
qdel(src)
@@ -56,16 +76,22 @@
..()
if(M.buckled == src)
desc = "A flickering, glowing purple ring around [M]."
- clockwork_desc = "A binding ring around [M], preventing [M.p_them()] from taking action while [M.p_theyre()] being converted."
+ clockwork_desc = "A binding ring around [M], preventing [M.p_them()] from taking action."
icon_state = "geisbinding"
mob_layer = M.layer
- layer = M.layer - 0.01
- add_overlay(mutable_appearance('icons/effects/clockwork_effects.dmi', "geisbinding_top", M.layer + 0.01))
+ layer = mob_layer - 0.01
+ add_overlay(mutable_appearance('icons/effects/clockwork_effects.dmi', "geisbinding_top", mob_layer + 0.01))
+ last_mob_health = M.health
+ apply_time = world.time
for(var/obj/item/I in M.held_items)
M.dropItemToGround(I)
for(var/i in M.get_empty_held_indexes())
var/obj/item/geis_binding/B = new(M)
M.put_in_hands(B, i)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(!C.handcuffed)
+ C.handcuffed = new /obj/item/restraints/handcuffs/energy/clock(C)
M.regenerate_icons()
M.visible_message("A [name] appears around [M]!", "A [name] appears around you!")
repair_and_interrupt()
@@ -79,8 +105,17 @@
animate(G, transform = matrix()*2, alpha = 0, time = 8, easing = EASE_OUT)
animate(T, transform = matrix()*2, alpha = 0, time = 8, easing = EASE_OUT)
M.visible_message("[src] snaps into glowing pieces and dissipates!")
+ M.AdjustStun(-130 + (apply_time - world.time), 1, 1) //remove exactly as much stun as was applied
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.silent = max(C.silent - 7, 0)
for(var/obj/item/geis_binding/GB in M.held_items)
M.dropItemToGround(GB, TRUE)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(istype(C.handcuffed, /obj/item/restraints/handcuffs/energy/clock))
+ QDEL_NULL(C.handcuffed)
+ C.update_handcuffed()
/obj/structure/destructible/clockwork/geis_binding/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src, 'sound/effects/empulse.ogg', 50, 1)
@@ -130,3 +165,10 @@
/obj/item/geis_binding/pre_attackby(atom/target, mob/living/user, params)
return FALSE
+
+/obj/item/restraints/handcuffs/energy/clock
+ name = "glowing rings"
+ desc = "Flickering rings preventing you from holding items."
+ icon = 'icons/effects/clockwork_effects.dmi'
+ icon_state = "geisbinding_full"
+ flags_1 = NODROP_1|ABSTRACT_1|DROPDEL_1
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 3b5af86147..0c70ee63c8 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -5,7 +5,7 @@
play_attack_sound(damage_amount, damage_type, damage_flag)
if(!(resistance_flags & INDESTRUCTIBLE) && obj_integrity > 0)
damage_amount = run_obj_armor(damage_amount, damage_type, damage_flag, attack_dir)
- if(damage_amount >= 1)
+ if(damage_amount >= 0.1)
. = damage_amount
obj_integrity = max(obj_integrity - damage_amount, 0)
if(obj_integrity <= 0)