mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 21:18:37 +01:00
Splits various massive clockwork cult code files up into various folders (#21177)
* Splits various massive clockwork cult code files up into various folders * JUST1C4R * 4BSURD * this is faintly horrifying to look at * that's right i don't need to double it, just to swap the order
This commit is contained in:
@@ -17,14 +17,17 @@ Game-wise, clockwork slabs will generate components over time, with more powerfu
|
||||
|
||||
This file's folder contains:
|
||||
clock_cult.dm: Core gamemode files.
|
||||
clock_items.dm: Items (excluding the proselytizer).
|
||||
clock_machines.dm: Machinery like the mending motor.
|
||||
clock_mobs.dm: Hostile and benign clockwork creatures.
|
||||
clock_proselytizer: The clockwork proselytizer and all of its special interactions.
|
||||
clock_ratvar.dm: The Ark of the Clockwork Justiciar and Ratvar himself. Important enough to have his own file.
|
||||
clock_scripture.dm: Scripture and rites.
|
||||
clock_structures.dm: Structures and effects
|
||||
clock_unsorted.dm: Anything else with no place to be
|
||||
clock_effect.dm: The base clockwork effect code.
|
||||
- Effect files are in game/gamemodes/clock_cult/clock_effects/
|
||||
clock_item.dm: The base clockwork item code.
|
||||
- Item files are in game/gamemodes/clock_cult/clock_items/
|
||||
clock_mobs.dm: Hostile clockwork creatures.
|
||||
clock_scripture.dm: The base Scripture code.
|
||||
- Scripture files are in game/gamemodes/clock_cult/clock_scripture/
|
||||
clock_structure.dm: The base clockwork structure code, including clockwork machines.
|
||||
- Structure files, and Ratvar, are in game/gamemodes/clock_cult/clock_structures/
|
||||
|
||||
game/gamemodes/clock_cult/clock_helpers/ contains several helper procs, including the Ratvarian language.
|
||||
|
||||
clockcult defines are in __DEFINES/clockcult.dm
|
||||
|
||||
@@ -47,19 +50,19 @@ Credit where due:
|
||||
|
||||
/proc/is_eligible_servant(mob/living/M)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
return FALSE
|
||||
if(M.mind)
|
||||
if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
|
||||
return 0
|
||||
return FALSE
|
||||
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
if(iscultist(M) || isconstruct(M) || M.isloyal())
|
||||
return 0
|
||||
return FALSE
|
||||
if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
|
||||
var/update_type = /datum/antagonist/clockcultist
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//The base clockwork effect. Can have an alternate desc and will show up in the list of clockwork objects.
|
||||
/obj/effect/clockwork
|
||||
name = "meme machine"
|
||||
desc = "Still don't know what it is."
|
||||
var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
icon_state = "ratvars_flame"
|
||||
anchored = 1
|
||||
density = 0
|
||||
opacity = 0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/clockwork/New()
|
||||
..()
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/effect/clockwork/Destroy()
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/examine(mob/user)
|
||||
if((is_servant_of_ratvar(user) || isobserver(user)) && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
@@ -0,0 +1,46 @@
|
||||
//an "overlay" used by clockwork walls and floors to appear normal to mesons.
|
||||
/obj/effect/clockwork/overlay
|
||||
mouse_opacity = 0
|
||||
var/atom/linked
|
||||
|
||||
/obj/effect/clockwork/overlay/examine(mob/user)
|
||||
if(linked)
|
||||
linked.examine(user)
|
||||
|
||||
/obj/effect/clockwork/overlay/ex_act()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/overlay/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/overlay/Destroy()
|
||||
if(linked)
|
||||
linked = null
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
/obj/effect/clockwork/overlay/wall
|
||||
name = "clockwork wall"
|
||||
icon = 'icons/turf/walls/clockwork_wall.dmi'
|
||||
icon_state = "clockwork_wall"
|
||||
canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
|
||||
smooth = SMOOTH_TRUE
|
||||
layer = CLOSED_TURF_LAYER
|
||||
|
||||
/obj/effect/clockwork/overlay/wall/New()
|
||||
..()
|
||||
queue_smooth_neighbors(src)
|
||||
addtimer(GLOBAL_PROC, "queue_smooth", 1, FALSE, src)
|
||||
|
||||
/obj/effect/clockwork/overlay/wall/Destroy()
|
||||
queue_smooth_neighbors(src)
|
||||
..()
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/obj/effect/clockwork/overlay/floor
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "clockwork_floor"
|
||||
layer = TURF_LAYER
|
||||
|
||||
/obj/effect/clockwork/overlay/floor/bloodcult //this is used by BLOOD CULT, it shouldn't use such a path...
|
||||
icon_state = "cult"
|
||||
@@ -0,0 +1,329 @@
|
||||
//Sigils: Rune-like markings on the ground with various effects.
|
||||
/obj/effect/clockwork/sigil
|
||||
name = "sigil"
|
||||
desc = "A strange set of markings drawn on the ground."
|
||||
clockwork_desc = "A sigil of some purpose."
|
||||
icon_state = "sigil"
|
||||
layer = LOW_OBJ_LAYER
|
||||
alpha = 50
|
||||
resistance_flags = NONE
|
||||
var/affects_servants = FALSE
|
||||
var/stat_affected = CONSCIOUS
|
||||
var/resist_string = "glows blinding white" //string for when a null rod blocks its effects, "glows [resist_string]"
|
||||
|
||||
/obj/effect/clockwork/sigil/attackby(obj/item/I, mob/living/user, params)
|
||||
if(I.force && !is_servant_of_ratvar(user))
|
||||
user.visible_message("<span class='warning'>[user] scatters [src] with [I]!</span>", "<span class='danger'>You scatter [src] with [I]!</span>")
|
||||
qdel(src)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/attack_hand(mob/user)
|
||||
if(iscarbon(user) && !user.stat && (!is_servant_of_ratvar(user) || (is_servant_of_ratvar(user) && user.a_intent == "harm")))
|
||||
user.visible_message("<span class='warning'>[user] stamps out [src]!</span>", "<span class='danger'>You stomp on [src], scattering it into thousands of particles.</span>")
|
||||
qdel(src)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/ex_act(severity)
|
||||
visible_message("<span class='warning'>[src] scatters into thousands of particles.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/clockwork/sigil/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.stat <= stat_affected)
|
||||
if((!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && affects_servants)) && L.mind)
|
||||
if(L.null_rod_check())
|
||||
var/obj/item/I = L.null_rod_check()
|
||||
L.visible_message("<span class='warning'>[L]'s [I.name] [resist_string], protecting them from [src]'s effects!</span>", \
|
||||
"<span class='userdanger'>Your [I.name] [resist_string], protecting you!</span>")
|
||||
return
|
||||
sigil_effects(L)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L)
|
||||
|
||||
|
||||
//Sigil of Transgression: Stuns the first non-servant to walk on it and flashes all nearby non_servants. Nar-Sian cultists are damaged and knocked down for a longer stun
|
||||
/obj/effect/clockwork/sigil/transgression
|
||||
name = "dull sigil"
|
||||
desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down."
|
||||
icon_state = "sigildull"
|
||||
color = "#FAE48C"
|
||||
|
||||
/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
|
||||
var/target_flashed = L.flash_act()
|
||||
for(var/mob/living/M in viewers(5, src))
|
||||
if(!is_servant_of_ratvar(M) && M != L)
|
||||
M.flash_act()
|
||||
if(iscultist(L))
|
||||
L << "<span class='heavy_brass'>\"Watch your step, wretch.\"</span>"
|
||||
L.adjustBruteLoss(10)
|
||||
L.Weaken(7)
|
||||
L.visible_message("<span class='warning'>[src] appears around [L] in a burst of light!</span>", \
|
||||
"<span class='userdanger'>[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!</span>")
|
||||
L.Stun(5)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/transgression, get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
|
||||
//Sigil of Submission: After a short time, converts any non-servant standing on it. Knocks down and silences them for five seconds afterwards.
|
||||
/obj/effect/clockwork/sigil/submission
|
||||
name = "ominous sigil"
|
||||
desc = "A luminous golden sigil. Something about it really bothers you."
|
||||
clockwork_desc = "A sigil that will enslave the first person to cross it, provided they remain on it for seven seconds."
|
||||
icon_state = "sigilsubmission"
|
||||
color = "#FAE48C"
|
||||
alpha = 125
|
||||
stat_affected = UNCONSCIOUS
|
||||
resist_string = "glows faintly yellow"
|
||||
var/convert_time = 70
|
||||
var/glow_light = 2 //soft light
|
||||
var/glow_falloff = 1
|
||||
var/delete_on_finish = TRUE
|
||||
var/sigil_name = "Sigil of Submission"
|
||||
var/glow_type
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/New()
|
||||
..()
|
||||
SetLuminosity(glow_light,glow_falloff)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/proc/post_channel(mob/living/L)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
|
||||
L.visible_message("<span class='warning'>[src] begins to glow a piercing magenta!</span>", "<span class='sevtug'>You feel something start to invade your mind...</span>")
|
||||
animate(src, color = "#AF0AAF", time = convert_time)
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/glow
|
||||
if(glow_type)
|
||||
glow = PoolOrNew(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))
|
||||
I++
|
||||
sleep(1)
|
||||
if(get_turf(L) != get_turf(src))
|
||||
if(glow)
|
||||
qdel(glow)
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 0
|
||||
post_channel(L)
|
||||
if(is_eligible_servant(L))
|
||||
L << "<span class='heavy_brass'>\"You belong to me now.\"</span>"
|
||||
add_servant_of_ratvar(L)
|
||||
L.Weaken(3) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with
|
||||
L.Stun(3)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.silent += 5
|
||||
var/message = "[sigil_name] in [get_area(src)] <span class='sevtug'>[is_servant_of_ratvar(L) ? "successfully converted" : "failed to convert"]</span>"
|
||||
for(var/M in mob_list)
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, L)
|
||||
M << "[link] <span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
else if(is_servant_of_ratvar(M))
|
||||
if(M == L)
|
||||
M << "<span class='heavy_brass'>[message] you!</span>"
|
||||
else
|
||||
M << "<span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
if(delete_on_finish)
|
||||
qdel(src)
|
||||
else
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 1
|
||||
|
||||
|
||||
//Sigil of Accession: After a short time, converts any non-servant standing on it though implants. Knocks down and silences them for five seconds afterwards.
|
||||
/obj/effect/clockwork/sigil/submission/accession
|
||||
name = "terrifying sigil"
|
||||
desc = "A luminous brassy sigil. Something about it makes you want to flee."
|
||||
clockwork_desc = "A sigil that will enslave any person who crosses it, provided they remain on it for seven seconds. \n\
|
||||
It can convert a mindshielded target once before disppearing, but can convert any number of non-implanted targets."
|
||||
icon_state = "sigiltransgression"
|
||||
color = "#A97F1B"
|
||||
alpha = 200
|
||||
glow_light = 4 //bright light
|
||||
glow_falloff = 3
|
||||
delete_on_finish = FALSE
|
||||
sigil_name = "Sigil of Accession"
|
||||
glow_type = /obj/effect/overlay/temp/ratvar/sigil/accession
|
||||
resist_string = "glows bright orange"
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L)
|
||||
if(L.isloyal())
|
||||
var/mob/living/carbon/C = L
|
||||
delete_on_finish = TRUE
|
||||
C.visible_message("<span class='warning'>[C] visibly trembles!</span>", \
|
||||
"<span class='sevtug'>[text2ratvar("You will be mine and his. This puny trinket will not stop me.")]</span>")
|
||||
for(var/obj/item/weapon/implant/mindshield/M in C.implants)
|
||||
qdel(M)
|
||||
|
||||
|
||||
//Sigil of Transmission: Stores power for clockwork machinery, serving as a battery.
|
||||
/obj/effect/clockwork/sigil/transmission
|
||||
name = "suspicious sigil"
|
||||
desc = "A glowing orange sigil. The air around it feels staticky."
|
||||
clockwork_desc = "A sigil that will serve as a battery for clockwork structures. Use Volt Void while standing on it to charge it."
|
||||
icon_state = "sigiltransmission"
|
||||
color = "#EC8A2D"
|
||||
alpha = 50
|
||||
resist_string = "glows faintly"
|
||||
var/power_charge = REPLICANT_ALLOY_POWER //starts with REPLICANT_ALLOY_POWER by default
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/ex_act(severity)
|
||||
if(severity == 3)
|
||||
modify_charge(-500)
|
||||
visible_message("<span class='warning'>[src] flares a brilliant orange!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[power_charge ? "brass":"alloy"]'>It is storing <b>[power_charge]W</b> of power.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L)
|
||||
if(power_charge)
|
||||
L << "<span class='brass'>You feel a slight, static shock.</span>"
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/New()
|
||||
..()
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount)
|
||||
if(power_charge - amount < 0)
|
||||
return 0
|
||||
power_charge -= amount
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
return 1
|
||||
|
||||
|
||||
//Vitality Matrix: Drains health from non-servants to heal or even revive servants.
|
||||
/obj/effect/clockwork/sigil/vitality
|
||||
name = "comforting sigil"
|
||||
desc = "A faint blue sigil. Looking at it makes you feel protected."
|
||||
clockwork_desc = "A sigil that will drain non-servants that remain on it. Servants that remain on it will be healed if it has any vitality drained."
|
||||
icon_state = "sigilvitality"
|
||||
color = "#123456"
|
||||
alpha = 75
|
||||
affects_servants = TRUE
|
||||
stat_affected = DEAD
|
||||
resist_string = "glows shimmering yellow"
|
||||
var/vitality = 0
|
||||
var/base_revive_cost = 20
|
||||
var/sigil_active = FALSE
|
||||
var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[vitality ? "inathneq_small":"alloy"]'>It is storing <b>[ratvar_awakens ? "INFINITE":"[vitality]"]</b> units of vitality.</span>"
|
||||
user << "<span class='inathneq_small'>It requires at least <b>[base_revive_cost]</b> units of vitality to revive dead servants, in addition to any damage the servant has.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L)
|
||||
if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active)
|
||||
return 0
|
||||
visible_message("<span class='warning'>[src] begins to glow bright blue!</span>")
|
||||
animate(src, alpha = 255, time = 10)
|
||||
sleep(10)
|
||||
sigil_active = TRUE
|
||||
//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) && vitality)) && get_turf(L) == get_turf(src))
|
||||
if(animation_number >= 4)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src))
|
||||
animation_number = 0
|
||||
animation_number++
|
||||
if(!is_servant_of_ratvar(L))
|
||||
var/vitality_drained = 0
|
||||
if(L.stat == DEAD)
|
||||
vitality_drained = L.maxHealth
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/vitality/V = PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src))
|
||||
animate(V, alpha = 0, transform = matrix()*2, time = 8)
|
||||
playsound(L, 'sound/magic/WandODeath.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] collapses in on [L.p_them()]self as [src] flares bright blue!</span>")
|
||||
L << "<span class='inathneq_large'>\"[text2ratvar("Your life will not be wasted.")]\"</span>"
|
||||
for(var/obj/item/W in L)
|
||||
if(!L.unEquip(W))
|
||||
qdel(W)
|
||||
L.dust()
|
||||
else
|
||||
vitality_drained = L.adjustToxLoss(1.5)
|
||||
if(vitality_drained)
|
||||
vitality += vitality_drained
|
||||
else
|
||||
break
|
||||
else
|
||||
var/clone_to_heal = L.getCloneLoss()
|
||||
var/tox_to_heal = L.getToxLoss()
|
||||
var/burn_to_heal = L.getFireLoss()
|
||||
var/brute_to_heal = L.getBruteLoss()
|
||||
var/oxy_to_heal = L.getOxyLoss()
|
||||
var/total_damage = clone_to_heal + tox_to_heal + burn_to_heal + brute_to_heal + oxy_to_heal
|
||||
if(L.stat == DEAD)
|
||||
var/revival_cost = base_revive_cost + total_damage - oxy_to_heal //ignores oxygen damage
|
||||
if(ratvar_awakens)
|
||||
revival_cost = 0
|
||||
var/mob/dead/observer/ghost = L.get_ghost(TRUE)
|
||||
if(ghost)
|
||||
if(vitality >= revival_cost)
|
||||
ghost.reenter_corpse()
|
||||
L.revive(1, 1)
|
||||
playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] suddenly gets back up, [L.p_their()] mouth dripping blue ichor!</span>", \
|
||||
"<span class='inathneq'>\"[text2ratvar("You will be okay, child.")]\"</span>")
|
||||
vitality -= revival_cost
|
||||
break
|
||||
else
|
||||
break
|
||||
if(!total_damage)
|
||||
break
|
||||
var/vitality_for_cycle = min(vitality, 3)
|
||||
var/vitality_used = 0
|
||||
if(ratvar_awakens)
|
||||
vitality_for_cycle = 3
|
||||
|
||||
if(clone_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, clone_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustCloneLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(tox_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, tox_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustToxLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(burn_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, burn_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustFireLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(brute_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, brute_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustBruteLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(oxy_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, oxy_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustOxyLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(!ratvar_awakens)
|
||||
vitality -= vitality_used
|
||||
sleep(2)
|
||||
|
||||
animation_number = initial(animation_number)
|
||||
sigil_active = FALSE
|
||||
animate(src, alpha = initial(alpha), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
@@ -0,0 +1,57 @@
|
||||
//massive markers for Revenant and Judgement scripture.
|
||||
/obj/effect/clockwork/general_marker
|
||||
name = "general marker"
|
||||
desc = "Some big guy. For you."
|
||||
clockwork_desc = "One of Ratvar's generals."
|
||||
alpha = 200
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
|
||||
/obj/effect/clockwork/general_marker/New()
|
||||
..()
|
||||
animate(src, alpha = 0, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/clockwork/general_marker/inathneq
|
||||
name = "Inath-neq, the Resonant Cogwheel"
|
||||
desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring."
|
||||
clockwork_desc = "One of Ratvar's four generals. Before her current form, Inath-neq was a powerful warrior priestess commanding the Resonant Cogs, a sect of Ratvarian warriors renowned for \
|
||||
their prowess. After a lost battle with Nar-Sian cultists, Inath-neq was struck down and stated in her dying breath, \
|
||||
\"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-neq an eternal body and \
|
||||
merged her soul with those of the Cogs slain with her on the battlefield."
|
||||
icon = 'icons/effects/187x381.dmi'
|
||||
icon_state = "inath-neq"
|
||||
pixel_x = -77
|
||||
pixel_y = -174
|
||||
|
||||
/obj/effect/clockwork/general_marker/nezbere
|
||||
name = "Nezbere, the Brass Eidolon"
|
||||
desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you."
|
||||
clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain, and his loyalty to Ratvar knows no bounds. \
|
||||
It is said that Ratvar once asked him to destroy the plans for a weapon Nezbere had made that could have harmed him and Nezbere responded by not only destroying the plans, \
|
||||
but by taking his own life so that the device could never be replicated. Nezbere's zealotry is unmatched."
|
||||
icon = 'icons/effects/340x428.dmi'
|
||||
icon_state = "nezbere"
|
||||
pixel_x = -154
|
||||
pixel_y = -198
|
||||
|
||||
/obj/effect/clockwork/general_marker/sevtug
|
||||
name = "Sevtug, the Formless Pariah"
|
||||
desc = "A sinister cloud of purple energy. Looking at it gives you a headache."
|
||||
clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies. Sevtug serves Ratvar loyally out of a hope that one day, he will \
|
||||
be able to use a moment of weakness in the Justicar to usurp him, but such a day will never come. And so, he serves with dedication, if not necessarily any sort of decorum, never aware he is \
|
||||
the one being made a fool of."
|
||||
icon = 'icons/effects/211x247.dmi'
|
||||
icon_state = "sevtug"
|
||||
pixel_x = -89
|
||||
pixel_y = -107
|
||||
|
||||
/obj/effect/clockwork/general_marker/nzcrentr
|
||||
name = "Nzcrentr, the Eternal Thunderbolt"
|
||||
desc = "A terrifying spiked construct crackling with limitless energy."
|
||||
clockwork_desc = "One of Ratvar's four generals. Before becoming one of Ratvar's generals, Nzcrentr sook out any and all sentient life to slaughter it for sport. \
|
||||
Nzcrentr was coerced by Ratvar into entering a shell constructed by Nezbere, ostensibly made to grant Nzcrentr more power. In reality, the shell was made to trap and control it. \
|
||||
Nzcrentr now serves loyally, though even one of Nezbere's finest creations was not enough to totally eliminate its will."
|
||||
icon = 'icons/effects/254x361.dmi'
|
||||
icon_state = "nzcrentr"
|
||||
pixel_x = -111
|
||||
pixel_y = -164
|
||||
@@ -0,0 +1,186 @@
|
||||
//Spatial gateway: A usually one-way rift to another location.
|
||||
/obj/effect/clockwork/spatial_gateway
|
||||
name = "spatial gateway"
|
||||
desc = "A gently thrumming tear in reality."
|
||||
clockwork_desc = "A gateway in reality."
|
||||
icon_state = "spatial_gateway"
|
||||
density = 1
|
||||
var/sender = TRUE //If this gateway is made for sending, not receiving
|
||||
var/both_ways = FALSE
|
||||
var/lifetime = 25 //How many deciseconds this portal will last
|
||||
var/uses = 1 //How many objects or mobs can go through the portal
|
||||
var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/New()
|
||||
..()
|
||||
addtimer(src, "check_setup", 1)
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/proc/check_setup()
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return
|
||||
if(both_ways)
|
||||
clockwork_desc = "A gateway in reality. It can both send and receive objects."
|
||||
else
|
||||
clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects."
|
||||
QDEL_IN(src, lifetime)
|
||||
|
||||
//set up a gateway with another gateway
|
||||
/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way)
|
||||
if(!gatewayB || !set_duration || !uses)
|
||||
return FALSE
|
||||
linked_gateway = gatewayB
|
||||
gatewayB.linked_gateway = src
|
||||
if(two_way)
|
||||
both_ways = TRUE
|
||||
gatewayB.both_ways = TRUE
|
||||
else
|
||||
sender = TRUE
|
||||
gatewayB.sender = FALSE
|
||||
gatewayB.density = FALSE
|
||||
lifetime = set_duration
|
||||
gatewayB.lifetime = set_duration
|
||||
uses = set_uses
|
||||
gatewayB.uses = set_uses
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>It has [uses] uses remaining.</span>"
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user)
|
||||
if(linked_gateway)
|
||||
user.forceMove(get_turf(linked_gateway))
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user)
|
||||
if(!uses)
|
||||
return FALSE
|
||||
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(L.buckled || L.anchored || L.has_buckled_mobs())
|
||||
return FALSE
|
||||
user.visible_message("<span class='warning'>[user] shoves [L] into [src]!</span>", "<span class='danger'>You shove [L] into [src]!</span>")
|
||||
user.stop_pulling()
|
||||
pass_through_gateway(L)
|
||||
return TRUE
|
||||
if(!user.canUseTopic(src))
|
||||
return FALSE
|
||||
user.visible_message("<span class='warning'>[user] climbs through [src]!</span>", "<span class='danger'>You brace yourself and step through [src]...</span>")
|
||||
pass_through_gateway(user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/weapon/nullrod))
|
||||
user.visible_message("<span class='warning'>[user] dispels [src] with [I]!</span>", "<span class='danger'>You close [src] with [I]!</span>")
|
||||
qdel(linked_gateway)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
if(istype(I, /obj/item/clockwork/slab))
|
||||
user << "<span class='heavy_brass'>\"I don't think you want to drop your slab into that\".\n\"If you really want to, try throwing it.\"</span>"
|
||||
return TRUE
|
||||
if(user.drop_item() && uses)
|
||||
user.visible_message("<span class='warning'>[user] drops [I] into [src]!</span>", "<span class='danger'>You drop [I] into [src]!</span>")
|
||||
pass_through_gateway(I)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/ex_act(severity)
|
||||
if(severity == 1 && uses)
|
||||
uses = 0
|
||||
visible_message("<span class='warning'>[src] is disrupted!</span>")
|
||||
animate(src, alpha = 0, transform = matrix()*2, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
linked_gateway.uses = 0
|
||||
linked_gateway.visible_message("<span class='warning'>[linked_gateway] is disrupted!</span>")
|
||||
animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 10)
|
||||
QDEL_IN(linked_gateway, 10)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/Bumped(atom/A)
|
||||
..()
|
||||
if(isliving(A) || istype(A, /obj/item))
|
||||
pass_through_gateway(A)
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A)
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
if(!sender)
|
||||
visible_message("<span class='warning'>[A] bounces off of [src]!</span>")
|
||||
return FALSE
|
||||
if(!uses)
|
||||
return FALSE
|
||||
if(isliving(A))
|
||||
var/mob/living/user = A
|
||||
user << "<span class='warning'><b>You pass through [src] and appear elsewhere!</b></span>"
|
||||
linked_gateway.visible_message("<span class='warning'>A shape appears in [linked_gateway] before emerging!</span>")
|
||||
playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
transform = matrix() * 1.5
|
||||
animate(src, transform = matrix() / 1.5, time = 10)
|
||||
linked_gateway.transform = matrix() * 1.5
|
||||
animate(linked_gateway, transform = matrix() / 1.5, time = 10)
|
||||
A.forceMove(get_turf(linked_gateway))
|
||||
uses = max(0, uses - 1)
|
||||
linked_gateway.uses = max(0, linked_gateway.uses - 1)
|
||||
addtimer(src, "check_uses", 10)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/proc/check_uses()
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
qdel(linked_gateway)
|
||||
|
||||
//This proc creates and sets up a gateway from invoker input.
|
||||
/atom/movable/proc/procure_gateway(mob/living/invoker, time_duration, gateway_uses, two_way)
|
||||
var/list/possible_targets = list()
|
||||
var/list/teleportnames = list()
|
||||
var/list/duplicatenamecount = list()
|
||||
|
||||
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
|
||||
if(!O.Adjacent(invoker) && O != src && (O.z <= ZLEVEL_SPACEMAX)) //don't list obelisks that we're next to
|
||||
var/area/A = get_area(O)
|
||||
var/locname = initial(A.name)
|
||||
var/resultkey = "[locname] [O.name]"
|
||||
if(resultkey in teleportnames) //why the fuck did you put two obelisks in the same area
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = O
|
||||
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && L != invoker && (L.z <= ZLEVEL_SPACEMAX)) //People right next to the invoker can't be portaled to, for obvious reasons
|
||||
var/resultkey = "[L.name] ([L.real_name])"
|
||||
if(resultkey in teleportnames)
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = L
|
||||
|
||||
if(!possible_targets.len)
|
||||
invoker << "<span class='warning'>There are no other eligible targets for a Spatial Gateway!</span>"
|
||||
return FALSE
|
||||
var/input_target_key = input(invoker, "Choose a target to form a rift to.", "Spatial Gateway") as null|anything in possible_targets
|
||||
var/atom/movable/target = possible_targets[input_target_key]
|
||||
if(!src || !target || !invoker || !invoker.canUseTopic(src, BE_CLOSE) || !is_servant_of_ratvar(invoker) || (istype(src, /obj/item) && invoker.get_active_held_item() != src))
|
||||
return FALSE //if any of the involved things no longer exist, the invoker is stunned, too far away to use the object, or does not serve ratvar, or if the object is an item and not in the mob's active hand, fail
|
||||
var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
|
||||
if(istargetobelisk)
|
||||
gateway_uses *= 2
|
||||
time_duration *= 2
|
||||
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
|
||||
"<span class='brass'>With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [time_duration / 10] seconds and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].</span>")
|
||||
var/obj/effect/clockwork/spatial_gateway/S1 = new(istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
|
||||
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
|
||||
|
||||
//Set up the portals now that they've spawned
|
||||
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
|
||||
S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
|
||||
return TRUE
|
||||
@@ -0,0 +1,118 @@
|
||||
//generates a component in the global component cache, either random based on lowest or a specific component
|
||||
/proc/generate_cache_component(specific_component_id)
|
||||
if(specific_component_id)
|
||||
clockwork_component_cache[specific_component_id]++
|
||||
else
|
||||
var/component_to_generate = get_weighted_component_id()
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
|
||||
//returns a chosen component id based on the lowest amount of that component in the global cache, the global cache plus the slab if there are caches, or the slab if there are no caches.
|
||||
/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab)
|
||||
. = list()
|
||||
if(storage_slab)
|
||||
if(clockwork_caches)
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache[i] + storage_slab.stored_components[i]), 1)
|
||||
else
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*storage_slab.stored_components[i], 1)
|
||||
else
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache[i], 1)
|
||||
. = pickweight(.)
|
||||
|
||||
//returns a component name from a component id
|
||||
/proc/get_component_name(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "Belligerent Eye"
|
||||
if("vanguard_cogwheel")
|
||||
return "Vanguard Cogwheel"
|
||||
if("guvax_capacitor")
|
||||
return "Guvax Capacitor"
|
||||
if("replicant_alloy")
|
||||
return "Replicant Alloy"
|
||||
if("hierophant_ansible")
|
||||
return "Hierophant Ansible"
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component id from a component name
|
||||
/proc/get_component_id(name)
|
||||
switch(name)
|
||||
if("Belligerent Eye")
|
||||
return "belligerent_eye"
|
||||
if("Vanguard Cogwheel")
|
||||
return "vanguard_cogwheel"
|
||||
if("Guvax Capacitor")
|
||||
return "guvax_capacitor"
|
||||
if("Replicant Alloy")
|
||||
return "replicant_alloy"
|
||||
if("Hierophant Ansible")
|
||||
return "hierophant_ansible"
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component spanclass from a component id
|
||||
/proc/get_component_span(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "neovgre"
|
||||
if("vanguard_cogwheel")
|
||||
return "inathneq"
|
||||
if("guvax_capacitor")
|
||||
return "sevtug"
|
||||
if("replicant_alloy")
|
||||
return "nezbere"
|
||||
if("hierophant_ansible")
|
||||
return "nzcrentr"
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component color from a component id
|
||||
/proc/get_component_color(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "#6E001A"
|
||||
if("vanguard_cogwheel")
|
||||
return "#1E8CE1"
|
||||
if("guvax_capacitor")
|
||||
return "#AF0AAF"
|
||||
if("replicant_alloy")
|
||||
return "#42474D"
|
||||
if("hierophant_ansible")
|
||||
return "#DAAA18"
|
||||
else
|
||||
return "#BE8700"
|
||||
|
||||
//returns a type for a floating component animation from a component id
|
||||
/proc/get_component_animation_type(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return /obj/effect/overlay/temp/ratvar/component
|
||||
if("vanguard_cogwheel")
|
||||
return /obj/effect/overlay/temp/ratvar/component/cogwheel
|
||||
if("guvax_capacitor")
|
||||
return /obj/effect/overlay/temp/ratvar/component/capacitor
|
||||
if("replicant_alloy")
|
||||
return /obj/effect/overlay/temp/ratvar/component/alloy
|
||||
if("hierophant_ansible")
|
||||
return /obj/effect/overlay/temp/ratvar/component/ansible
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a type for a component from a component id
|
||||
/proc/get_component_type(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return /obj/item/clockwork/component/belligerent_eye
|
||||
if("vanguard_cogwheel")
|
||||
return /obj/item/clockwork/component/vanguard_cogwheel
|
||||
if("guvax_capacitor")
|
||||
return /obj/item/clockwork/component/guvax_capacitor
|
||||
if("replicant_alloy")
|
||||
return /obj/item/clockwork/component/replicant_alloy
|
||||
if("hierophant_ansible")
|
||||
return /obj/item/clockwork/component/hierophant_ansible
|
||||
else
|
||||
return null
|
||||
@@ -0,0 +1,47 @@
|
||||
//Sends a string to all servants and optionally ghosts, who will get a follow link to whatever is provided as the target.
|
||||
/proc/hierophant_message(message, servantsonly, atom/target)
|
||||
if(!message)
|
||||
return FALSE
|
||||
for(var/M in mob_list)
|
||||
if(!servantsonly && isobserver(M))
|
||||
if(target)
|
||||
var/link = FOLLOW_LINK(M, target)
|
||||
M << "[link] [message]"
|
||||
else
|
||||
M << message
|
||||
else if(is_servant_of_ratvar(M))
|
||||
M << message
|
||||
return TRUE
|
||||
|
||||
//Sends a titled message from a mob to all servants of ratvar and ghosts.
|
||||
/proc/titled_hierophant_message(mob/user, message, name_span = "heavy_brass", message_span = "brass", user_title = "Servant")
|
||||
if(!user || !message)
|
||||
return FALSE
|
||||
var/parsed_message = "<span class='[name_span]'>[user_title ? "[user_title] ":""][findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: \
|
||||
</span><span class='[message_span]'>\"[message]\"</span>"
|
||||
hierophant_message(parsed_message, FALSE, user)
|
||||
return TRUE
|
||||
|
||||
//Hierophant Network action, allows a servant with it to communicate to other servants.
|
||||
/datum/action/innate/hierophant
|
||||
name = "Hierophant Network"
|
||||
desc = "Allows you to communicate with other Servants."
|
||||
button_icon_state = "hierophant"
|
||||
background_icon_state = "bg_clock"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
|
||||
buttontooltipstyle = "clockcult"
|
||||
var/title = "Servant"
|
||||
var/span_for_name = "heavy_brass"
|
||||
var/span_for_message = "brass"
|
||||
|
||||
/datum/action/innate/hierophant/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/hierophant/Activate()
|
||||
var/input = stripped_input(usr, "Please enter a message to send to other servants.", "Hierophant Network", "")
|
||||
if(!input || !IsAvailable())
|
||||
return
|
||||
|
||||
titled_hierophant_message(owner, input, span_for_name, span_for_message, title)
|
||||
+11
-150
@@ -1,153 +1,4 @@
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer //Clockwork proselytizer (yes, that's a real word): Converts applicable objects to Ratvarian variants.
|
||||
name = "clockwork proselytizer"
|
||||
desc = "An odd, L-shaped device that hums with energy."
|
||||
clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires liquified Replicant Alloy to function."
|
||||
icon_state = "clockwork_proselytizer"
|
||||
w_class = 3
|
||||
force = 5
|
||||
flags = NOBLUDGEON
|
||||
var/stored_alloy = 0 //Requires this to function; each chunk of replicant alloy provides REPLICANT_ALLOY_UNIT
|
||||
var/max_alloy = REPLICANT_ALLOY_UNIT * 10
|
||||
var/uses_alloy = TRUE
|
||||
var/metal_to_alloy = FALSE
|
||||
var/repairing = null //what we're currently repairing, if anything
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/preloaded
|
||||
stored_alloy = REPLICANT_WALL_MINUS_FLOOR+REPLICANT_WALL_TOTAL
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab
|
||||
name = "scarab proselytizer"
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires liquified Replicant Alloy to function."
|
||||
metal_to_alloy = TRUE
|
||||
item_state = "nothing"
|
||||
w_class = 1
|
||||
var/debug = FALSE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user)
|
||||
if(!debug && !isdrone(user))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/debug
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant."
|
||||
uses_alloy = FALSE
|
||||
debug = TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>Can be used to convert walls, floors, windows, airlocks, windoors, and grilles to clockwork variants.</span>"
|
||||
user << "<span class='brass'>Can also form some objects into Replicant Alloy, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.</span>"
|
||||
if(metal_to_alloy)
|
||||
user << "<span class='alloy'>It can convert rods, metal, and plasteel to liquified replicant alloy at a low rate.</span>"
|
||||
if(uses_alloy)
|
||||
user << "<span class='alloy'>It has <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy stored.</span>"
|
||||
user << "<span class='alloy'>Use it on a Tinkerer's Cache, strike it with Replicant Alloy, or attack Replicant Alloy with it to add additional liquified alloy.</span>"
|
||||
user << "<span class='alloy'>Use it in-hand to remove stored liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src] [stored_alloy ? "Lacks enough":"Contains no"] alloy to reform[stored_alloy ? "":" any"] into solidified alloy!</span>"
|
||||
return
|
||||
modify_stored_alloy(-REPLICANT_ALLOY_UNIT)
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
new/obj/item/clockwork/component/replicant_alloy(user.loc)
|
||||
user << "<span class='brass'>You force [stored_alloy ? "some":"all"] of the alloy in [src]'s compartments to reform and solidify. \
|
||||
It now contains <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(-REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src]'s replicant alloy compartments are full!</span>"
|
||||
return 0
|
||||
modify_stored_alloy(REPLICANT_ALLOY_UNIT)
|
||||
playsound(user, 'sound/machines/click.ogg', 50, 1)
|
||||
clockwork_say(user, text2ratvar("Transmute into fuel."), TRUE)
|
||||
user << "<span class='brass'>You force [I] to liquify and pour it into [src]'s compartments. It now contains <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy.</span>"
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/afterattack(atom/target, mob/living/user, proximity_flag, params)
|
||||
if(!target || !user || !proximity_flag)
|
||||
return 0
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
proselytize(target, user)
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_alloy(amount)
|
||||
if(can_use_alloy(RATVAR_ALLOY_CHECK)) //Ratvar makes it free
|
||||
amount = 0
|
||||
stored_alloy = Clamp(stored_alloy + amount, 0, max_alloy)
|
||||
return 1
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/can_use_alloy(amount)
|
||||
if(amount == RATVAR_ALLOY_CHECK)
|
||||
if(ratvar_awakens || !uses_alloy)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
if(stored_alloy - amount < 0)
|
||||
return FALSE
|
||||
if(stored_alloy - amount > max_alloy)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user)
|
||||
if(!target || !user)
|
||||
return 0
|
||||
var/target_type = target.type
|
||||
var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list
|
||||
if(!islist(proselytize_values))
|
||||
if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
|
||||
user << "<span class='warning'>[target] cannot be proselytized!</span>"
|
||||
return 0
|
||||
if(repairing)
|
||||
user << "<span class='warning'>You are currently repairing [repairing] with [src]!</span>"
|
||||
return 0
|
||||
if(!uses_alloy)
|
||||
proselytize_values["alloy_cost"] = 0
|
||||
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"]))
|
||||
if(stored_alloy - proselytize_values["alloy_cost"] < 0)
|
||||
user << "<span class='warning'>You need <b>[proselytize_values["alloy_cost"]]</b> liquified alloy to proselytize [target]!</span>"
|
||||
else if(stored_alloy - proselytize_values["alloy_cost"] > max_alloy)
|
||||
user << "<span class='warning'>You have too much liquified alloy stored to proselytize [target]!</span>"
|
||||
return 0
|
||||
|
||||
if(can_use_alloy(RATVAR_ALLOY_CHECK)) //Ratvar makes it faster
|
||||
proselytize_values["operation_time"] *= 0.5
|
||||
|
||||
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
|
||||
playsound(target, 'sound/machines/click.ogg', 50, 1)
|
||||
if(proselytize_values["operation_time"] && !do_after(user, proselytize_values["operation_time"], target = target))
|
||||
return 0
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"])) //Check again to prevent bypassing via spamclick
|
||||
return 0
|
||||
if(!target || target.type != target_type)
|
||||
return 0
|
||||
if(repairing)
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user]'s [name] disgorges a chunk of metal and shapes it over what's left of [target]!</span>", \
|
||||
"<span class='brass'>You proselytize [target].</span>")
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
var/new_thing_type = proselytize_values["new_obj_type"]
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.ChangeTurf(new_thing_type)
|
||||
else
|
||||
if(proselytize_values["dir_in_new"])
|
||||
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"])
|
||||
else
|
||||
var/atom/A = new new_thing_type(get_turf(target))
|
||||
A.setDir(proselytize_values["spawn_dir"])
|
||||
qdel(target)
|
||||
modify_stored_alloy(-proselytize_values["alloy_cost"])
|
||||
return 1
|
||||
//For the clockwork proselytizer, this proc exists to make it easy to customize what the proselytizer does when hitting something.
|
||||
|
||||
//if a valid target, returns an associated list in this format;
|
||||
//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "alloy_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE)
|
||||
@@ -157,6 +8,7 @@
|
||||
/atom/proc/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Turf conversion
|
||||
/turf/closed/wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "alloy_cost" = REPLICANT_WALL_TOTAL, "spawn_dir" = SOUTH)
|
||||
|
||||
@@ -185,6 +37,7 @@
|
||||
return FALSE
|
||||
return list("operation_time" = 100, "new_obj_type" = /turf/closed/wall/clockwork, "alloy_cost" = REPLICANT_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
//Metal conversion
|
||||
/obj/item/stack/rods/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(get_amount() >= 10)
|
||||
var/sheets_to_make = round(get_amount() * 0.1)
|
||||
@@ -218,6 +71,7 @@
|
||||
user << "<span class='warning'>You need at least 10 sheets of plasteel to convert into brass.</span>"
|
||||
return TRUE
|
||||
|
||||
//Brass directly to alloy; scarab only
|
||||
/obj/item/stack/sheet/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(!proselytizer.metal_to_alloy)
|
||||
return FALSE
|
||||
@@ -225,6 +79,7 @@
|
||||
var/prosel_time = -amount*1
|
||||
return list("operation_time" = -prosel_time, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = prosel_cost, "spawn_dir" = SOUTH)
|
||||
|
||||
//Airlock conversion
|
||||
/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/doortype = /obj/machinery/door/airlock/clockwork
|
||||
if(glass)
|
||||
@@ -234,6 +89,7 @@
|
||||
/obj/machinery/door/airlock/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Window conversion
|
||||
/obj/structure/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/windowtype = /obj/structure/window/reinforced/clockwork
|
||||
var/new_dir = TRUE
|
||||
@@ -249,12 +105,14 @@
|
||||
/obj/structure/window/reinforced/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Windoor conversion
|
||||
/obj/machinery/door/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "alloy_cost" = REPLICANT_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
|
||||
|
||||
/obj/machinery/door/window/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Grille conversion
|
||||
/obj/structure/grille/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/grilletype = /obj/structure/grille/ratvar
|
||||
var/prosel_time = 15
|
||||
@@ -266,6 +124,7 @@
|
||||
/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Hitting a clockwork structure will try to repair it.
|
||||
/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(proselytizer.repairing) //no spamclicking for fast repairs, bucko
|
||||
@@ -319,6 +178,7 @@
|
||||
"<span class='alloy'>You finish repairing [src]. It is now at <b>[obj_integrity]/[max_integrity]</b> integrity.</span>")
|
||||
return
|
||||
|
||||
//Hitting a tinkerer's cache will try to fill the proselytizer with alloy after trying to repair.
|
||||
/obj/structure/destructible/clockwork/cache/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = ..()
|
||||
if(proselytizer.can_use_alloy(RATVAR_ALLOY_CHECK) || proselytizer.stored_alloy + REPLICANT_ALLOY_UNIT > proselytizer.max_alloy)
|
||||
@@ -341,6 +201,7 @@
|
||||
"<span class='brass'>You finish filling [proselytizer] with liquified alloy. It now contains <b>[proselytizer.stored_alloy]/[proselytizer.max_alloy]</b> units of liquified alloy.</span>")
|
||||
return
|
||||
|
||||
//Convert shards, wall gears, and replicant alloy directly to liquid alloy
|
||||
/obj/structure/destructible/clockwork/wall_gear/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 10, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = -REPLICANT_GEAR, "spawn_dir" = SOUTH)
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
The Ratvarian Language
|
||||
In the lore of the Servants of Ratvar, the Ratvarian tongue is a timeless language and full of power. It sounds like gibberish, much like Nar-Sie's language, but is in fact derived from
|
||||
aforementioned language, and may induce miracles when spoken in the correct way with an amplifying tool (similar to runes used by the Nar-Sian cult).
|
||||
|
||||
While the canon states that the language of Ratvar and his servants is incomprehensible to the unenlightened as it is a derivative of the most ancient known language, in reality it is
|
||||
actually very simple. To translate a plain English sentence to Ratvar's tongue, simply move all of the letters thirteen places ahead, starting from "a" if the end of the alphabet is reached.
|
||||
This cipher is known as "rot13" for "rotate 13 places" and there are many sites online that allow instant translation between English and rot13 - one of the benefits is that moving the translated
|
||||
sentence thirteen places ahead changes it right back to plain English.
|
||||
|
||||
There are, however, a few parts of the Ratvarian tongue that aren't typical and are implemented for fluff reasons. Some words may have graves, or hyphens (prefix and postfix), making the plain
|
||||
English translation apparent but disjoined (for instance, "Orubyq zl-cbjre!" translates directly to "Behold my-power!") although this can be ignored without impacting overall quality. When
|
||||
translating from Ratvar's tongue to plain English, simply remove the disjointments and use the finished sentence. This would make "Orubyq zl-cbjre!" into "Behold my power!" after removing the
|
||||
abnormal spacing, hyphens, and grave accents.
|
||||
|
||||
List of nuances:
|
||||
- Any time the WORD "of" occurs, it is linked to the previous word by a hyphen. (i.e. "V nz-bs Ratvar." directly translates to "I am-of Ratvar.")
|
||||
- Any time "th", followed by any two letters occurs, you add a grave (`) between those two letters, i.e; "Thi`s"
|
||||
- In the same vein, any time "ti", followed by one letter occurs, you add a grave (`) between "i" and the letter, i.e; "Ti`me"
|
||||
- Whereever "te" or "et" appear and there is another letter next to the e(i.e; "m"etal, greate"r"), add a hyphen between "e" and the letter, i.e; "M-etal", "Greate-r"
|
||||
- Where "gua" appears, add a hyphen between "gu" and "a", i.e "Gu-ard"
|
||||
- Where the WORD "and" appears it is linked to all surrounding words by hyphens, i.e; "Sword-and-shield"
|
||||
- Where the WORD "to" appears, it is linked to the following word by a hyphen, i.e; "to-use"
|
||||
- Where the WORD "my" appears, it is linked to the following word by a hyphen, i.e; "my-light"
|
||||
- Although "Ratvar" translates to "Engine" in English, the word "Ratvar" is used regardless of language as it is a proper noun.
|
||||
- The same rule applies to Ratvar's four generals: Nezbere (Armorer), Sevtug (Fright), Nzcrentr (Amperage), and Inath-neq (Vangu-Ard), although these words can be used in proper context if one is
|
||||
not referring to the four generals and simply using the words themselves.
|
||||
*/
|
||||
|
||||
//Regexes used to alter english to ratvarian style
|
||||
#define RATVAR_OF_MATCH regex("(\\w)\\s(\[oO]\[fF])","g")
|
||||
#define RATVAR_OF_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_GUA_MATCH regex("(\[gG]\[uU])(\[aA])","g")
|
||||
#define RATVAR_GUA_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TH_MATCH regex("(\[tT]\[hH]\\w)(\\w)","g")
|
||||
#define RATVAR_TH_REPLACEMENT "$1`$2"
|
||||
#define RATVAR_TI_MATCH regex("(\[tT]\[iI])(\\w)","g")
|
||||
#define RATVAR_TI_REPLACEMENT "$1`$2"
|
||||
#define RATVAR_ET_MATCH regex("(\\w)(\[eE]\[tT])","g")
|
||||
#define RATVAR_ET_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g")
|
||||
#define RATVAR_TE_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])","g")
|
||||
#define RATVAR_PRE_AND_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])\\s(\\w)","g")
|
||||
#define RATVAR_POST_AND_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g")
|
||||
#define RATVAR_TO_REPLACEMENT "$1$2-$3"
|
||||
#define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g")
|
||||
#define RATVAR_MY_REPLACEMENT "$1$2-$3"
|
||||
|
||||
//Regexes used to remove ratvarian styling from english
|
||||
#define REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH regex("(\\w)-(\[aA]\[nN]\[dD])","g") //specifically structured to support -emphasis-, including with -and-
|
||||
#define REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT "$1 $2"
|
||||
#define REVERSE_RATVAR_HYPHEN_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])-(\\w)","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT "$1 $2"
|
||||
#define REVERSE_RATVAR_HYPHEN_TO_MY_MATCH regex("(\[tTmM]\[oOyY])-","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT "$1 "
|
||||
#define REVERSE_RATVAR_HYPHEN_TE_MATCH regex("(\[tT]\[eE])-","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT "$1"
|
||||
#define REVERSE_RATVAR_HYPHEN_ET_MATCH regex("-(\[eE]\[tT])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT "$1"
|
||||
#define REVERSE_RATVAR_HYPHEN_GUA_MATCH regex("(\[gG]\[uU])-(\[aA])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT "$1$2"
|
||||
#define REVERSE_RATVAR_HYPHEN_OF_MATCH regex("-(\[oO]\[fF])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT " $1"
|
||||
|
||||
|
||||
/proc/text2ratvar(text) //Takes english and applies ratvarian styling rules (and rot13) to it
|
||||
var/ratvarian = replacetext(text, RATVAR_OF_MATCH, RATVAR_OF_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_GUA_MATCH, RATVAR_GUA_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TH_MATCH, RATVAR_TH_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TI_MATCH, RATVAR_TI_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_ET_MATCH, RATVAR_ET_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TE_MATCH, RATVAR_TE_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_PRE_AND_MATCH, RATVAR_PRE_AND_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_POST_AND_MATCH, RATVAR_POST_AND_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TO_MATCH, RATVAR_TO_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_MY_MATCH, RATVAR_MY_REPLACEMENT)
|
||||
return rot13(ratvarian)
|
||||
|
||||
/proc/ratvar2text(ratvarian) //Reverts ravarian styling and rot13 in text.
|
||||
var/text = replacetext(rot13(ratvarian), "`", "")
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT)
|
||||
return text
|
||||
|
||||
//Causes the mob or AM in question to speak a message; it assumes that the message is already translated to ratvar speech using text2ratvar()
|
||||
/proc/clockwork_say(atom/movable/AM, message, whisper=FALSE)
|
||||
var/list/spans = list(SPAN_ROBOT)
|
||||
|
||||
var/old_languages_spoken = AM.languages_spoken
|
||||
AM.languages_spoken = HUMAN //anyone who can understand HUMAN will hear weird shitty ratvar speak, otherwise it'll get starred out
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!whisper)
|
||||
L.say(message, "clock", spans)
|
||||
else
|
||||
L.whisper(message)
|
||||
else
|
||||
AM.say(message)
|
||||
AM.languages_spoken = old_languages_spoken
|
||||
@@ -0,0 +1,37 @@
|
||||
//returns a list of scriptures and if they're unlocked or not
|
||||
/proc/scripture_unlock_check()
|
||||
var/servants = 0
|
||||
var/unconverted_ai_exists = FALSE
|
||||
for(var/mob/living/M in living_mob_list)
|
||||
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
|
||||
servants++
|
||||
else if(isAI(M))
|
||||
unconverted_ai_exists = TRUE
|
||||
. = list(SCRIPTURE_DRIVER = TRUE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_REVENANT = FALSE, SCRIPTURE_JUDGEMENT = FALSE)
|
||||
//Drivers: always unlocked
|
||||
.[SCRIPTURE_SCRIPT] = (servants >= 5 && clockwork_caches >= 1)
|
||||
//Script: 5 or more non-brain servants and 1+ clockwork caches
|
||||
.[SCRIPTURE_APPLICATION] = (servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 100)
|
||||
//Application: 8 or more non-brain servants, 3+ clockwork caches, and at least 100 CV
|
||||
.[SCRIPTURE_REVENANT] = (servants >= 10 && clockwork_caches >= 4 && clockwork_construction_value >= 200)
|
||||
//Revenant: 10 or more non-brain servants, 4+ clockwork caches, and at least 200 CV
|
||||
.[SCRIPTURE_JUDGEMENT] = (servants >= 12 && clockwork_caches >= 5 && clockwork_construction_value >= 300 && !unconverted_ai_exists)
|
||||
//Judgement: 12 or more non-brain servants, 5+ clockwork caches, at least 300 CV, and there are no living, non-servant ais
|
||||
|
||||
//reports to servants when scripture is locked or unlocked
|
||||
/proc/scripture_unlock_alert(list/previous_states)
|
||||
. = scripture_unlock_check()
|
||||
for(var/i in .)
|
||||
if(.[i] != previous_states[i])
|
||||
hierophant_message("<span class='large_brass'><i>Hierophant Network:</i> <b>[i] Scripture has been [.[i] ? "un":""]locked.</b></span>")
|
||||
|
||||
//changes construction value
|
||||
/proc/change_construction_value(amount)
|
||||
clockwork_construction_value += amount
|
||||
|
||||
//throws the no cache alert if there are no caches and clears it otherwise
|
||||
/proc/cache_check(mob/M)
|
||||
if(!clockwork_caches)
|
||||
M.throw_alert("nocache", /obj/screen/alert/clockwork/nocache)
|
||||
else
|
||||
M.clear_alert("nocache")
|
||||
@@ -0,0 +1,150 @@
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer //Clockwork proselytizer (yes, that's a real word): Converts applicable objects to Ratvarian variants.
|
||||
name = "clockwork proselytizer"
|
||||
desc = "An odd, L-shaped device that hums with energy."
|
||||
clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires liquified Replicant Alloy to function."
|
||||
icon_state = "clockwork_proselytizer"
|
||||
w_class = 3
|
||||
force = 5
|
||||
flags = NOBLUDGEON
|
||||
var/stored_alloy = 0 //Requires this to function; each chunk of replicant alloy provides REPLICANT_ALLOY_UNIT
|
||||
var/max_alloy = REPLICANT_ALLOY_UNIT * 10
|
||||
var/uses_alloy = TRUE
|
||||
var/metal_to_alloy = FALSE
|
||||
var/repairing = null //what we're currently repairing, if anything
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/preloaded
|
||||
stored_alloy = REPLICANT_WALL_MINUS_FLOOR+REPLICANT_WALL_TOTAL
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab
|
||||
name = "scarab proselytizer"
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires liquified Replicant Alloy to function."
|
||||
metal_to_alloy = TRUE
|
||||
item_state = "nothing"
|
||||
w_class = 1
|
||||
var/debug = FALSE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user)
|
||||
if(!debug && !isdrone(user))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/scarab/debug
|
||||
clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant."
|
||||
uses_alloy = FALSE
|
||||
debug = TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>Can be used to convert walls, floors, windows, airlocks, windoors, and grilles to clockwork variants.</span>"
|
||||
user << "<span class='brass'>Can also form some objects into Replicant Alloy, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.</span>"
|
||||
if(metal_to_alloy)
|
||||
user << "<span class='alloy'>It can convert rods, metal, and plasteel to liquified replicant alloy at a low rate.</span>"
|
||||
if(uses_alloy)
|
||||
user << "<span class='alloy'>It has <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy stored.</span>"
|
||||
user << "<span class='alloy'>Use it on a Tinkerer's Cache, strike it with Replicant Alloy, or attack Replicant Alloy with it to add additional liquified alloy.</span>"
|
||||
user << "<span class='alloy'>Use it in-hand to remove stored liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src] [stored_alloy ? "Lacks enough":"Contains no"] alloy to reform[stored_alloy ? "":" any"] into solidified alloy!</span>"
|
||||
return
|
||||
modify_stored_alloy(-REPLICANT_ALLOY_UNIT)
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
new/obj/item/clockwork/component/replicant_alloy(user.loc)
|
||||
user << "<span class='brass'>You force [stored_alloy ? "some":"all"] of the alloy in [src]'s compartments to reform and solidify. \
|
||||
It now contains <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy.</span>"
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user) && uses_alloy)
|
||||
if(!can_use_alloy(-REPLICANT_ALLOY_UNIT))
|
||||
user << "<span class='warning'>[src]'s replicant alloy compartments are full!</span>"
|
||||
return 0
|
||||
modify_stored_alloy(REPLICANT_ALLOY_UNIT)
|
||||
playsound(user, 'sound/machines/click.ogg', 50, 1)
|
||||
clockwork_say(user, text2ratvar("Transmute into fuel."), TRUE)
|
||||
user << "<span class='brass'>You force [I] to liquify and pour it into [src]'s compartments. It now contains <b>[stored_alloy]/[max_alloy]</b> units of liquified alloy.</span>"
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/afterattack(atom/target, mob/living/user, proximity_flag, params)
|
||||
if(!target || !user || !proximity_flag)
|
||||
return 0
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
proselytize(target, user)
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_alloy(amount)
|
||||
if(can_use_alloy(RATVAR_ALLOY_CHECK)) //Ratvar makes it free
|
||||
amount = 0
|
||||
stored_alloy = Clamp(stored_alloy + amount, 0, max_alloy)
|
||||
return 1
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/can_use_alloy(amount)
|
||||
if(amount == RATVAR_ALLOY_CHECK)
|
||||
if(ratvar_awakens || !uses_alloy)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
if(stored_alloy - amount < 0)
|
||||
return FALSE
|
||||
if(stored_alloy - amount > max_alloy)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user)
|
||||
if(!target || !user)
|
||||
return 0
|
||||
var/target_type = target.type
|
||||
var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list
|
||||
if(!islist(proselytize_values))
|
||||
if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
|
||||
user << "<span class='warning'>[target] cannot be proselytized!</span>"
|
||||
return 0
|
||||
if(repairing)
|
||||
user << "<span class='warning'>You are currently repairing [repairing] with [src]!</span>"
|
||||
return 0
|
||||
if(!uses_alloy)
|
||||
proselytize_values["alloy_cost"] = 0
|
||||
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"]))
|
||||
if(stored_alloy - proselytize_values["alloy_cost"] < 0)
|
||||
user << "<span class='warning'>You need <b>[proselytize_values["alloy_cost"]]</b> liquified alloy to proselytize [target]!</span>"
|
||||
else if(stored_alloy - proselytize_values["alloy_cost"] > max_alloy)
|
||||
user << "<span class='warning'>You have too much liquified alloy stored to proselytize [target]!</span>"
|
||||
return 0
|
||||
|
||||
if(can_use_alloy(RATVAR_ALLOY_CHECK)) //Ratvar makes it faster
|
||||
proselytize_values["operation_time"] *= 0.5
|
||||
|
||||
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
|
||||
playsound(target, 'sound/machines/click.ogg', 50, 1)
|
||||
if(proselytize_values["operation_time"] && !do_after(user, proselytize_values["operation_time"], target = target))
|
||||
return 0
|
||||
if(!can_use_alloy(proselytize_values["alloy_cost"])) //Check again to prevent bypassing via spamclick
|
||||
return 0
|
||||
if(!target || target.type != target_type)
|
||||
return 0
|
||||
if(repairing)
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user]'s [name] disgorges a chunk of metal and shapes it over what's left of [target]!</span>", \
|
||||
"<span class='brass'>You proselytize [target].</span>")
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
var/new_thing_type = proselytize_values["new_obj_type"]
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.ChangeTurf(new_thing_type)
|
||||
else
|
||||
if(proselytize_values["dir_in_new"])
|
||||
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"])
|
||||
else
|
||||
var/atom/A = new new_thing_type(get_turf(target))
|
||||
A.setDir(proselytize_values["spawn_dir"])
|
||||
qdel(target)
|
||||
modify_stored_alloy(-proselytize_values["alloy_cost"])
|
||||
return 1
|
||||
@@ -1,676 +0,0 @@
|
||||
////////////////////////
|
||||
// CLOCKWORK MACHINES //
|
||||
////////////////////////
|
||||
//not-actually-machines
|
||||
|
||||
/obj/structure/destructible/clockwork/powered
|
||||
var/obj/machinery/power/apc/target_apc
|
||||
var/active = FALSE
|
||||
var/needs_power = TRUE
|
||||
var/active_icon = null //icon_state while process() is being called
|
||||
var/inactive_icon = null //icon_state while process() isn't being called
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
var/powered = total_accessable_power()
|
||||
user << "<span class='[powered ? "brass":"alloy"]'>It has access to <b>[powered == INFINITY ? "INFINITY":"[powered]"]W</b> of power.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/Destroy()
|
||||
SSfastprocess.processing -= src
|
||||
SSobj.processing -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/process()
|
||||
var/powered = total_accessable_power()
|
||||
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/toggle(fast_process, mob/living/user)
|
||||
if(user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] [active ? "dis" : "en"]ables [src].</span>", "<span class='brass'>You [active ? "dis" : "en"]able [src].</span>")
|
||||
active = !active
|
||||
if(active)
|
||||
icon_state = active_icon
|
||||
if(fast_process)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
if(fast_process)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return INFINITY //oh yeah we've got power why'd you ask
|
||||
|
||||
var/power = 0
|
||||
power += accessable_apc_power()
|
||||
power += accessable_sigil_power()
|
||||
return power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/accessable_apc_power()
|
||||
var/power = 0
|
||||
var/area/A = get_area(src)
|
||||
var/area/targetAPCA
|
||||
for(var/obj/machinery/power/apc/APC in apcs_list)
|
||||
var/area/APCA = get_area(APC)
|
||||
if(APCA == A)
|
||||
target_apc = APC
|
||||
if(target_apc)
|
||||
targetAPCA = get_area(target_apc)
|
||||
if(targetAPCA != A)
|
||||
target_apc = null
|
||||
else if(target_apc.cell)
|
||||
var/apccharge = target_apc.cell.charge
|
||||
if(apccharge >= MIN_CLOCKCULT_POWER)
|
||||
power += apccharge
|
||||
return power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/accessable_sigil_power()
|
||||
var/power = 0
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
power += T.power_charge
|
||||
return power
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return 1
|
||||
if(amount <= 0)
|
||||
return 0
|
||||
var/power = total_accessable_power()
|
||||
if(!power || power < amount)
|
||||
return 0
|
||||
return use_power(amount)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
|
||||
var/sigilpower = accessable_sigil_power()
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
while(sigilpower && amount >= MIN_CLOCKCULT_POWER)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= MIN_CLOCKCULT_POWER && T.modify_charge(MIN_CLOCKCULT_POWER))
|
||||
sigilpower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
var/apcpower = accessable_apc_power()
|
||||
while(apcpower >= MIN_CLOCKCULT_POWER && amount >= MIN_CLOCKCULT_POWER)
|
||||
if(target_apc.cell.use(MIN_CLOCKCULT_POWER))
|
||||
apcpower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
target_apc.update()
|
||||
target_apc.update_icon()
|
||||
else
|
||||
apcpower = 0
|
||||
if(amount)
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
|
||||
if(amount <= 0)
|
||||
return 0
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
if(!sigils_in_range.len)
|
||||
return 0
|
||||
while(amount >= MIN_CLOCKCULT_POWER)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= MIN_CLOCKCULT_POWER && T.modify_charge(-MIN_CLOCKCULT_POWER))
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
return 1
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
|
||||
name = "interdiction lens"
|
||||
desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
|
||||
clockwork_desc = "A powerful totem that constantly drains nearby electronics and funnels the power drained into nearby Sigils of Transmission."
|
||||
icon_state = "interdiction_lens"
|
||||
construction_value = 25
|
||||
active_icon = "interdiction_lens_active"
|
||||
inactive_icon = "interdiction_lens"
|
||||
break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
|
||||
break_sound = 'sound/effects/Glassbr3.ogg'
|
||||
var/recharging = 0 //world.time when the lens was last used
|
||||
var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
|
||||
var/disabled = FALSE //if it's actually usable
|
||||
var/interdiction_range = 14 //how large an area it drains and disables in
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='[recharging > world.time ? "nezbere_small":"brass"]'>Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
|
||||
: "vibrates in place and thrums with power"].</span>"
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nezbere_small'>If it fails to drain any electronics, it will disable itself for <b>[round(recharge_time/600, 1)]</b> minutes.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
|
||||
..()
|
||||
if(active)
|
||||
SetLuminosity(4,2)
|
||||
else
|
||||
SetLuminosity(0)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(disabled)
|
||||
user << "<span class='warning'>As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back.</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/process()
|
||||
if(recharging > world.time)
|
||||
return
|
||||
if(disabled)
|
||||
visible_message("<span class='warning'>The writhing tendrils return to the gemstone, which begins to glow with power!</span>")
|
||||
flick("interdiction_lens_recharged", src)
|
||||
disabled = FALSE
|
||||
toggle(0)
|
||||
else
|
||||
var/successfulprocess = FALSE
|
||||
var/power_drained = 0
|
||||
var/list/atoms_to_test = list()
|
||||
for(var/A in spiral_range_turfs(interdiction_range, src))
|
||||
var/turf/T = A
|
||||
for(var/M in T)
|
||||
atoms_to_test |= M
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
for(var/M in atoms_to_test)
|
||||
var/atom/movable/A = M
|
||||
if(!A || qdeleted(A))
|
||||
continue
|
||||
power_drained += A.power_drain(TRUE)
|
||||
|
||||
if(istype(A, /obj/machinery/camera))
|
||||
var/obj/machinery/camera/C = A
|
||||
if(C.isEmpProof() || !C.status)
|
||||
continue
|
||||
successfulprocess = TRUE
|
||||
if(C.emped)
|
||||
continue
|
||||
C.emp_act(1)
|
||||
else if(istype(A, /obj/item/device/radio))
|
||||
var/obj/item/device/radio/O = A
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
O.emp_act(1)
|
||||
else if((isliving(A) && !is_servant_of_ratvar(A)) || istype(A, /obj/structure/closet) || istype(A, /obj/item/weapon/storage)) //other things may have radios in them but we don't care
|
||||
for(var/obj/item/device/radio/O in A.GetAllContents())
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
O.emp_act(1)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
if(power_drained && power_drained >= MIN_CLOCKCULT_POWER && return_power(power_drained))
|
||||
successfulprocess = TRUE
|
||||
playsound(src, 'sound/items/PSHOOM.ogg', 50, 1, interdiction_range-7, 1)
|
||||
|
||||
if(!successfulprocess)
|
||||
visible_message("<span class='warning'>The gemstone suddenly turns horribly dark, writhing tendrils covering it!</span>")
|
||||
recharging = world.time + recharge_time
|
||||
flick("interdiction_lens_discharged", src)
|
||||
icon_state = "interdiction_lens_inactive"
|
||||
SetLuminosity(2,1)
|
||||
disabled = TRUE
|
||||
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
|
||||
name = "mending motor"
|
||||
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
|
||||
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
|
||||
icon_state = "mending_motor_inactive"
|
||||
active_icon = "mending_motor"
|
||||
inactive_icon = "mending_motor_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 125
|
||||
obj_integrity = 125
|
||||
break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/small = 5, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 1, \
|
||||
/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/component/vanguard_cogwheel = 1)
|
||||
var/stored_alloy = 0
|
||||
var/max_alloy = REPLICANT_ALLOY_POWER * 10
|
||||
var/mob_cost = 200
|
||||
var/structure_cost = 250
|
||||
var/cyborg_cost = 300
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/prefilled
|
||||
stored_alloy = REPLICANT_ALLOY_POWER //starts with 1 replicant alloy's worth of power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/total_accessable_power()
|
||||
. = ..()
|
||||
if(. != INFINITY)
|
||||
. += accessable_alloy_power()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/proc/accessable_alloy_power()
|
||||
return stored_alloy
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/use_power(amount)
|
||||
var/alloypower = accessable_alloy_power()
|
||||
while(alloypower >= MIN_CLOCKCULT_POWER && amount >= MIN_CLOCKCULT_POWER)
|
||||
stored_alloy -= MIN_CLOCKCULT_POWER
|
||||
alloypower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='alloy'>It contains <b>[stored_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]/[max_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]</b> units of liquified alloy, \
|
||||
which is equivalent to <b>[stored_alloy]W/[max_alloy]W</b> of power.</span>"
|
||||
user << "<span class='inathneq_small'>It requires <b>[mob_cost]W</b> to heal clockwork mobs, <b>[structure_cost]W</b> for clockwork structures, and <b>[cyborg_cost]W</b> for cyborgs.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/process()
|
||||
if(..() < mob_cost)
|
||||
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
|
||||
toggle()
|
||||
return
|
||||
for(var/atom/movable/M in range(5, src))
|
||||
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
var/mob/living/simple_animal/hostile/clockwork/W = M
|
||||
var/fatigued = FALSE
|
||||
if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder))
|
||||
var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
|
||||
if(E.fatigue)
|
||||
fatigued = TRUE
|
||||
if((!fatigued && W.health == W.maxHealth) || W.stat)
|
||||
continue
|
||||
if(!try_use_power(mob_cost))
|
||||
break
|
||||
W.adjustHealth(-20)
|
||||
else if(istype(M, /obj/structure/destructible/clockwork))
|
||||
var/obj/structure/destructible/clockwork/C = M
|
||||
if(C.obj_integrity == C.max_integrity)
|
||||
continue
|
||||
if(!try_use_power(structure_cost))
|
||||
break
|
||||
C.obj_integrity = min(C.obj_integrity + 20, C.max_integrity)
|
||||
else if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
|
||||
continue
|
||||
if(!try_use_power(cyborg_cost))
|
||||
break
|
||||
S.adjustBruteLoss(-20)
|
||||
S.adjustFireLoss(-10)
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(total_accessable_power() < mob_cost)
|
||||
user << "<span class='warning'>[src] needs more power or replicant alloy to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
|
||||
if(stored_alloy + REPLICANT_ALLOY_POWER > max_alloy)
|
||||
user << "<span class='warning'>[src] is too full to accept any more alloy!</span>"
|
||||
return 0
|
||||
playsound(user, 'sound/machines/click.ogg', 50, 1)
|
||||
clockwork_say(user, text2ratvar("Transmute into fuel."), TRUE)
|
||||
user << "<span class='brass'>You force [I] to liquify and pour it into [src]'s compartments. \
|
||||
It now contains <b>[stored_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]/[max_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]</b> units of liquified alloy.</span>"
|
||||
stored_alloy = stored_alloy + REPLICANT_ALLOY_POWER
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
|
||||
name = "mania motor"
|
||||
desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
|
||||
clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
|
||||
icon_state = "mania_motor_inactive"
|
||||
active_icon = "mania_motor"
|
||||
inactive_icon = "mania_motor_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 80
|
||||
obj_integrity = 80
|
||||
break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/small = 3, \
|
||||
/obj/item/clockwork/component/guvax_capacitor/antennae = 1)
|
||||
var/mania_cost = 200
|
||||
var/convert_attempt_cost = 200
|
||||
var/convert_cost = 200
|
||||
|
||||
var/mania_messages = list("\"Go nuts.\"", "\"Take a crack at crazy.\"", "\"Make a bid for insanity.\"", "\"Get kooky.\"", "\"Move towards mania.\"", "\"Become bewildered.\"", "\"Wax wild.\"", \
|
||||
"\"Go round the bend.\"", "\"Land in lunacy.\"", "\"Try dementia.\"", "\"Strive to get a screw loose.\"")
|
||||
var/compel_messages = list("\"Come closer.\"", "\"Approach the transmitter.\"", "\"Touch the antennae.\"", "\"I always have to deal with idiots. Move towards the mania motor.\"", \
|
||||
"\"Advance forward and place your head between the antennae - that's all it's good for.\"", "\"If you were smarter, you'd be over here already.\"", "\"Move FORWARD, you fool.\"")
|
||||
var/convert_messages = list("\"You won't do. Go to sleep while I tell these nitwits how to convert you.\"", "\"You are insufficient. I must instruct these idiots in the art of conversion.\"", \
|
||||
"\"Oh of course, someone we can't convert. These servants are fools.\"", "\"How hard is it to use a Sigil, anyway? All it takes is dragging someone onto it.\"", \
|
||||
"\"How do they fail to use a Sigil of Accession, anyway?\"", "\"Why is it that all servants are this inept?\"", "\"It's quite likely you'll be stuck here for a while.\"")
|
||||
var/close_messages = list("\"Well, you can't reach the motor from THERE, you moron.\"", "\"Interesting location. I'd prefer if you went somewhere you could ACTUALLY TOUCH THE ANTENNAE!\"", \
|
||||
"\"Amazing. You somehow managed to wedge yourself somewhere you can't actually reach the motor from.\"", "\"Such a show of idiocy is unparalleled. Perhaps I should put you on display?\"", \
|
||||
"\"Did you do this on purpose? I can't imagine you doing so accidentally. Oh, wait, I can.\"", "\"How is it that such smart creatures can still do something AS STUPID AS THIS!\"")
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='sevtug_small'>It requires <b>[mania_cost]W</b> to run, and <b>[convert_attempt_cost + convert_cost]W</b> to convert humans adjecent to it.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/process()
|
||||
if(try_use_power(mania_cost))
|
||||
var/turf/T = get_turf(src)
|
||||
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
|
||||
for(var/mob/living/carbon/human/H in view(1, src))
|
||||
if(is_servant_of_ratvar(H))
|
||||
continue
|
||||
if(H.Adjacent(src) && try_use_power(convert_attempt_cost))
|
||||
if(is_eligible_servant(H) && try_use_power(convert_cost))
|
||||
H << "<span class='sevtug'>\"[text2ratvar("You are mine and his, now.")]\"</span>"
|
||||
H.playsound_local(T, hum, 80, 1)
|
||||
add_servant_of_ratvar(H)
|
||||
else if(!H.stat)
|
||||
if(H.getBrainLoss() >= 100)
|
||||
H.Paralyse(5)
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(convert_messages))]</span>"
|
||||
else
|
||||
H.adjustBrainLoss(100)
|
||||
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
for(var/mob/living/carbon/human/H in range(10, src))
|
||||
if(is_servant_of_ratvar(H))
|
||||
if(H.getBrainLoss() || H.hallucination || H.druggy || H.dizziness || H.confused)
|
||||
H.adjustBrainLoss(-H.getBrainLoss()) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
|
||||
H.hallucination = 0
|
||||
H.adjust_drugginess(-H.druggy)
|
||||
H.dizziness = 0
|
||||
H.confused = 0
|
||||
else if(!H.null_rod_check() && H.stat == CONSCIOUS)
|
||||
var/distance = get_dist(T, get_turf(H))
|
||||
var/falloff_distance = min((110) - distance * 10, 80)
|
||||
var/sound_distance = falloff_distance * 0.5
|
||||
var/targetbrainloss = H.getBrainLoss()
|
||||
if(distance >= 4 && prob(falloff_distance * 0.5))
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
H.playsound_local(T, hum, sound_distance, 1)
|
||||
switch(distance)
|
||||
if(2 to 3)
|
||||
if(prob(falloff_distance * 0.5))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
else
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(compel_messages))]</span>"
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(50 - targetbrainloss) //got too close had brain eaten
|
||||
H.adjust_drugginess(Clamp(7, 0, 100 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 7, 100)
|
||||
H.dizziness = min(H.dizziness + 3, 45)
|
||||
H.confused = min(H.confused + 3, 45)
|
||||
if(4 to 5)
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(5, 0, 80 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 5, 80)
|
||||
H.dizziness = min(H.dizziness + 2, 30)
|
||||
H.confused = min(H.confused + 2, 30)
|
||||
if(6 to 7)
|
||||
if(targetbrainloss <= 30)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(2, 0, 60 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 60)
|
||||
H.dizziness = min(H.dizziness + 2, 15)
|
||||
H.confused = min(H.confused + 2, 15)
|
||||
if(8 to 9)
|
||||
if(targetbrainloss <= 10)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(2, 0, 40 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 40)
|
||||
if(10 to INFINITY)
|
||||
H.adjust_drugginess(Clamp(2, 0, 20 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 20)
|
||||
else //if it's a distance of 1 and they can't see it/aren't adjacent or they're on top of it(how'd they get on top of it and still trigger this???)
|
||||
if(prob(falloff_distance * 0.5))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(compel_messages))]</span>"
|
||||
else if(prob(falloff_distance * 0.5))
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(close_messages))]</span>"
|
||||
else
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
if(targetbrainloss <= 99)
|
||||
H.adjustBrainLoss(99 - targetbrainloss)
|
||||
H.adjust_drugginess(Clamp(10, 0, 150 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 10, 150)
|
||||
H.dizziness = min(H.dizziness + 5, 60)
|
||||
H.confused = min(H.confused + 5, 60)
|
||||
|
||||
else
|
||||
visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
|
||||
playsound(src, 'sound/effects/screech.ogg', 40, 1)
|
||||
toggle(0)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(!total_accessable_power() >= mania_cost)
|
||||
user << "<span class='warning'>[src] needs more power to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk
|
||||
name = "clockwork obelisk"
|
||||
desc = "A large brass obelisk hanging in midair."
|
||||
clockwork_desc = "A powerful obelisk that can send a message to all servants or open a gateway to a target servant or clockwork obelisk."
|
||||
icon_state = "obelisk_inactive"
|
||||
active_icon = "obelisk"
|
||||
inactive_icon = "obelisk_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 150
|
||||
obj_integrity = 150
|
||||
break_message = "<span class='warning'>The obelisk falls to the ground, undamaged!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
|
||||
/obj/item/clockwork/component/hierophant_ansible/obelisk = 1)
|
||||
var/hierophant_cost = MIN_CLOCKCULT_POWER //how much it costs to broadcast with large text
|
||||
var/gateway_cost = 2000 //how much it costs to open a gateway
|
||||
var/gateway_active = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/New()
|
||||
..()
|
||||
toggle(1)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nzcrentr_small'>It requires <b>[hierophant_cost]W</b> to broadcast over the Hierophant Network, and <b>[gateway_cost]W</b> to open a Spatial Gateway.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/process()
|
||||
if(locate(/obj/effect/clockwork/spatial_gateway) in loc)
|
||||
icon_state = active_icon
|
||||
density = 0
|
||||
gateway_active = TRUE
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
density = 1
|
||||
gateway_active = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
|
||||
if(!is_servant_of_ratvar(user) || !total_accessable_power() >= hierophant_cost)
|
||||
user << "<span class='warning'>You place your hand on the obelisk, but it doesn't react.</span>"
|
||||
return
|
||||
var/choice = alert(user,"You place your hand on the obelisk...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
|
||||
switch(choice)
|
||||
if("Hierophant Broadcast")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "")
|
||||
if(!input || !user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
if(!try_use_power(hierophant_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to broadcast!</span>"
|
||||
return
|
||||
clockwork_say(user, text2ratvar("Hierophant Broadcast, activate!"))
|
||||
titled_hierophant_message(user, input, "big_brass", "large_brass")
|
||||
if("Spatial Gateway")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is already sustaining a gateway!</span>"
|
||||
return
|
||||
if(!try_use_power(gateway_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to open a gateway!</span>"
|
||||
return
|
||||
if(procure_gateway(user, 100, 5, 1) && !gateway_active)
|
||||
clockwork_say(user, text2ratvar("Spatial Gateway, activate!"))
|
||||
else
|
||||
return_power(gateway_cost)
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon
|
||||
name = "tinkerer's daemon"
|
||||
desc = "A strange machine with three small brass obelisks attached to it."
|
||||
clockwork_desc = "An efficient machine that can rapidly produce components at a small power cost. It will only function if outnumbered by servants at a rate to 5:1."
|
||||
icon_state = "tinkerers_daemon"
|
||||
active_icon = "tinkerers_daemon"
|
||||
inactive_icon = "tinkerers_daemon"
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
break_message = "<span class='warning'>The daemon shatters into millions of pieces!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 2, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 4, \
|
||||
/obj/item/clockwork/alloy_shards/small = 6)
|
||||
var/image/daemon_glow
|
||||
var/image/component_glow
|
||||
var/component_id_to_produce
|
||||
var/production_time = 0 //last time we produced a component
|
||||
var/production_cooldown = 120
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/New()
|
||||
..()
|
||||
clockwork_daemons++
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/Destroy()
|
||||
clockwork_daemons--
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(active)
|
||||
if(component_id_to_produce)
|
||||
user << "<span class='[get_component_span(component_id_to_produce)]_small'>It is currently producing [get_component_name(component_id_to_produce)][component_id_to_produce != "replicant_alloy" ? "s":""].</span>"
|
||||
else
|
||||
user << "<span class='brass'>It is currently producing random components.</span>"
|
||||
user << "<span class='nezbere_small'>It will produce a component every <b>[production_cooldown*0.1]</b> seconds and requires at least the following power for each component type:</span>"
|
||||
for(var/i in clockwork_component_cache)
|
||||
user << "<span class='[get_component_span(i)]_small'><i>[get_component_name(i)]:</i> <b>[get_component_cost(i)]W</b> <i>([clockwork_component_cache[i]] exist[clockwork_component_cache[i] == 1 ? "s" : ""])</i></span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/attack_hand(mob/living/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
user << "<span class='warning'>You place your hand on the daemon, but nothing happens.</span>"
|
||||
return
|
||||
if(active)
|
||||
toggle(0, user)
|
||||
else
|
||||
if(!clockwork_caches)
|
||||
user << "<span class='warning'>There are no clockwork caches! Activating this daemon would be a waste of power.</span>"
|
||||
return
|
||||
var/choice = alert(user,"Activate Daemon...",,"Specific Component","Random Component","Cancel")
|
||||
switch(choice)
|
||||
if("Specific Component")
|
||||
var/list/components = list()
|
||||
for(var/i in clockwork_component_cache)
|
||||
components["[get_component_name(i)] ([get_component_cost(i)]W)"] = i
|
||||
var/input_component = input(user, "Choose a component type.", name) as null|anything in components
|
||||
component_id_to_produce = components[input_component]
|
||||
if(!user.canUseTopic(src, BE_CLOSE) || active)
|
||||
return
|
||||
if(!component_id_to_produce)
|
||||
user << "<span class='warning'>You decide not to select a component and activate the daemon.</span>"
|
||||
return
|
||||
if(total_accessable_power() < get_component_cost(component_id_to_produce))
|
||||
user << "<span class='warning'>There is too little power to produce this type of component!</span>"
|
||||
return
|
||||
toggle(0, user)
|
||||
if("Random Component")
|
||||
component_id_to_produce = null
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/toggle(fast_process, mob/living/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
var/component_color = get_component_color(component_id_to_produce)
|
||||
if(!daemon_glow)
|
||||
daemon_glow = new('icons/obj/clockwork_objects.dmi', "tinkerglow")
|
||||
daemon_glow.color = component_color
|
||||
add_overlay(daemon_glow)
|
||||
if(!component_glow)
|
||||
component_glow = new('icons/obj/clockwork_objects.dmi', "t_[component_id_to_produce ? component_id_to_produce :"random_component"]")
|
||||
else
|
||||
component_glow.icon_state = "t_[component_id_to_produce ? component_id_to_produce :"random_component"]"
|
||||
component_glow.color = component_color
|
||||
add_overlay(component_glow)
|
||||
production_time = world.time + production_cooldown //don't immediately produce when turned on afteer being off
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/proc/get_component_cost(id)
|
||||
return max(MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER * (1 + round(clockwork_component_cache[id] * 0.2)))
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/process()
|
||||
var/servants = 0
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(is_servant_of_ratvar(L))
|
||||
servants++
|
||||
. = ..()
|
||||
var/min_power_usable = 0
|
||||
if(!component_id_to_produce)
|
||||
for(var/i in clockwork_component_cache)
|
||||
if(!min_power_usable)
|
||||
min_power_usable = get_component_cost(i)
|
||||
else
|
||||
min_power_usable = min(min_power_usable, get_component_cost(i))
|
||||
else
|
||||
min_power_usable = get_component_cost(component_id_to_produce)
|
||||
if(!clockwork_caches || servants * 0.2 < clockwork_daemons || . < min_power_usable) //if we don't have enough to produce the lowest or what we chose to produce, cancel out
|
||||
visible_message("<span class='warning'>[src] shuts down!</span>")
|
||||
toggle()
|
||||
return
|
||||
if(production_time <= world.time)
|
||||
var/component_to_generate = component_id_to_produce
|
||||
if(!component_to_generate)
|
||||
component_to_generate = get_weighted_component_id() //more likely to generate components that we have less of
|
||||
if(!try_use_power(get_component_cost(component_to_generate)))
|
||||
component_to_generate = null
|
||||
if(!component_id_to_produce)
|
||||
for(var/i in clockwork_component_cache)
|
||||
if(try_use_power(get_component_cost(i))) //if we fail but are producing random, try and get a different component to produce
|
||||
component_to_generate = i
|
||||
break
|
||||
if(component_to_generate)
|
||||
PoolOrNew(get_component_animation_type(component_to_generate), get_turf(src))
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
production_time = world.time + production_cooldown //go on cooldown
|
||||
visible_message("<span class='warning'>[src] hums as it produces a [get_component_name(component_to_generate)].</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src] shuts down!</span>") //we shouldn't actually ever get here, as we should cancel out way before this
|
||||
toggle()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
||||
//////////////////
|
||||
// APPLICATIONS //
|
||||
//////////////////
|
||||
|
||||
//Sigil of Accession: Creates a sigil of accession, which is like a sigil of submission, but can convert any number of non-implanted targets and up to one implanted target.
|
||||
/datum/clockwork_scripture/create_object/sigil_of_accession
|
||||
descname = "Permenant Conversion Trap"
|
||||
name = "Sigil of Accession"
|
||||
desc = "Places a luminous sigil much like a Sigil of Submission, but it will remain even after successfully converting a non-implanted target. \
|
||||
It will penetrate mindshield implants once before disappearing."
|
||||
invocations = list("Divinity, enslave...", "...all who trespass here!")
|
||||
channel_time = 70
|
||||
required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 1, "hierophant_ansible" = 1)
|
||||
consumed_components = list("belligerent_eye" = 2, "guvax_capacitor" = 1, "hierophant_ansible" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/effect/clockwork/sigil/submission/accession
|
||||
prevent_path = /obj/effect/clockwork/sigil/submission
|
||||
creator_message = "<span class='brass'>A luminous sigil appears below you. All non-servants to cross it will be enslaved after a brief time if they do not move.</span>"
|
||||
usage_tip = "It will remain after converting a target, unless that target has a mindshield implant, which it will break to convert them, but consume itself in the process."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 1
|
||||
|
||||
|
||||
//Vitality Matrix: Creates a sigil which will drain health from nonservants and can use that health to heal or even revive servants.
|
||||
/datum/clockwork_scripture/create_object/vitality_matrix
|
||||
descname = "Damage Trap"
|
||||
name = "Vitality Matrix"
|
||||
desc = "Scribes a sigil beneath the invoker which drains life from any living non-servants that cross it. Servants that cross it, however, will be healed based on how much it drained from non-servants. \
|
||||
Dead servants can be revived by this sigil if it has enough stored vitality."
|
||||
invocations = list("Divinity...", "...steal their life...", "...for these shells!")
|
||||
channel_time = 70
|
||||
required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 3, "hierophant_ansible" = 1)
|
||||
consumed_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 2, "hierophant_ansible" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/effect/clockwork/sigil/vitality
|
||||
creator_message = "<span class='brass'>A vitality matrix appears below you. It will drain life from non-servants and heal servants that cross it.</span>"
|
||||
usage_tip = "To revive a servant, the sigil must have 20 vitality plus the target servant's non-oxygen damage. It will still heal dead servants if it lacks the vitality to outright revive them."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 2
|
||||
|
||||
|
||||
//Memory Allocation: Finds a willing ghost and makes them into a clockwork marauders for the invoker.
|
||||
/datum/clockwork_scripture/memory_allocation
|
||||
descname = "Guardian"
|
||||
name = "Memory Allocation"
|
||||
desc = "Allocates part of your consciousness to a Clockwork Marauder, a vigilent fighter that lives within you, able to be \
|
||||
called forth by Speaking its True Name or if you become exceptionally low on health.<br> \
|
||||
It gains Fatigue as it is attacked, weakening it. Marauders cannot move too far from their hosts, \
|
||||
and will gain Fatigue at an increasing rate as they grow farther away. At maximum Fatigue, the marauder is forced to return to you and will be unable to manifest until its Fatigue is at zero."
|
||||
invocations = list("Fright's will...", "...call forth...")
|
||||
channel_time = 100
|
||||
required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "guvax_capacitor" = 3)
|
||||
consumed_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "guvax_capacitor" = 2)
|
||||
usage_tip = "Marauders are useful as personal bodyguards and frontline warriors, although they do little damage."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
sort_priority = 3
|
||||
|
||||
/datum/clockwork_scripture/memory_allocation/check_special_requirements()
|
||||
for(var/mob/living/simple_animal/hostile/clockwork/marauder/M in living_mob_list)
|
||||
if(M.host == invoker)
|
||||
invoker << "<span class='warning'>You can only house one marauder at a time!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/memory_allocation/scripture_effects()
|
||||
return create_marauder()
|
||||
|
||||
/datum/clockwork_scripture/memory_allocation/proc/create_marauder()
|
||||
invoker.visible_message("<span class='warning'>A yellow tendril appears from [invoker]'s [slab.name] and impales itself in [invoker.p_their()] forehead!</span>", \
|
||||
"<span class='heavy_brass'>A tendril flies from [slab] into your forehead. You begin waiting while it painfully rearranges your thought pattern...</span>")
|
||||
invoker.notransform = TRUE //Vulnerable during the process
|
||||
slab.busy = "Thought modification in process"
|
||||
if(!do_after(invoker, 50, target = invoker))
|
||||
invoker.visible_message("<span class='warning'>The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!</span>", \
|
||||
"<span class='heavy_brass'>Total agony overcomes you as the tendril is forced out early!</span>")
|
||||
invoker.notransform = FALSE
|
||||
invoker.Stun(5)
|
||||
invoker.Weaken(5)
|
||||
invoker.apply_damage(10, BRUTE, "head")
|
||||
slab.busy = null
|
||||
return FALSE
|
||||
clockwork_say(invoker, text2ratvar("...the mind made..."))
|
||||
invoker.notransform = FALSE
|
||||
slab.busy = null
|
||||
if(!check_special_requirements())
|
||||
return FALSE
|
||||
invoker << "<span class='warning'>The tendril shivers slightly as it selects a marauder...</span>"
|
||||
var/list/marauder_candidates = pollCandidates("Do you want to play as the clockwork marauder of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 100)
|
||||
if(!check_special_requirements())
|
||||
return FALSE
|
||||
if(!marauder_candidates.len)
|
||||
invoker.visible_message("<span class='warning'>The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!</span>", \
|
||||
"<span class='warning'>The tendril was unsuccessful! Perhaps you should try again another time.</span>")
|
||||
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/M = new(invoker)
|
||||
M.key = theghost.key
|
||||
M.host = invoker
|
||||
M << M.playstyle_string
|
||||
M << "<b>Your true name is \"[M.true_name]\". You can change this <i>once</i> by using the Change True Name verb in your Marauder tab.</b>"
|
||||
add_servant_of_ratvar(M, TRUE)
|
||||
invoker.visible_message("<span class='warning'>The tendril retracts from [invoker]'s head, sealing the entry wound as it does so!</span>", \
|
||||
"<span class='heavy_brass'>The procedure was successful! [M.true_name], a clockwork marauder, has taken up residence in your mind. Communicate with it via the \"Linked Minds\" ability in the \
|
||||
Clockwork tab.</span>")
|
||||
invoker.verbs += /mob/living/proc/talk_with_marauder
|
||||
return TRUE
|
||||
|
||||
|
||||
//Anima Fragment: Creates an empty anima fragment, which produces an anima fragment that moves at extreme speed and does high damage.
|
||||
/datum/clockwork_scripture/create_object/anima_fragment
|
||||
descname = "Fast Soul Vessel Shell"
|
||||
name = "Anima Fragment"
|
||||
desc = "Creates a large shell fitted for soul vessels. Adding an active soul vessel to it results in a powerful construct with decent health, notable melee power, \
|
||||
and exceptional speed, though taking damage will temporarily slow it down."
|
||||
invocations = list("Call forth...", "...the soldiers of Armorer.")
|
||||
channel_time = 80
|
||||
required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "replicant_alloy" = 3)
|
||||
consumed_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "replicant_alloy" = 2)
|
||||
object_path = /obj/structure/destructible/clockwork/shell/fragment
|
||||
creator_message = "<span class='brass'>You form an anima fragment, a powerful soul vessel receptable.</span>"
|
||||
observer_message = "<span class='warning'>The slab disgorges a puddle of black metal that expands and forms into a strange shell!</span>"
|
||||
usage_tip = "Useless without a soul vessel and should not be created without one."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
sort_priority = 4
|
||||
|
||||
|
||||
//Sigil of Transmission: Creates a sigil of transmission that can store power for clockwork structures.
|
||||
/datum/clockwork_scripture/create_object/sigil_of_transmission
|
||||
descname = "Structure Battery"
|
||||
name = "Sigil of Transmission"
|
||||
desc = "Scribes a sigil beneath the invoker which stores power to power clockwork structures."
|
||||
invocations = list("Divinity...", "...power our creations!")
|
||||
channel_time = 70
|
||||
required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1, "hierophant_ansible" = 3)
|
||||
consumed_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1, "hierophant_ansible" = 2)
|
||||
whispered = TRUE
|
||||
object_path = /obj/effect/clockwork/sigil/transmission
|
||||
creator_message = "<span class='brass'>A sigil silently appears below you. It will automatically power clockwork structures adjecent to it.</span>"
|
||||
usage_tip = "Can be recharged by using Volt Void while standing on it."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 5
|
||||
|
||||
|
||||
//Interdiction Lens: Creates a powerful totem that disables radios and cameras and drains power into nearby sigils of transmission.
|
||||
/datum/clockwork_scripture/create_object/interdiction_lens
|
||||
descname = "Structure, Disables Machinery"
|
||||
name = "Interdiction Lens"
|
||||
desc = "Creates a clockwork totem that sabotages nearby machinery and funnels drained power into nearby Sigils of Transmission."
|
||||
invocations = list("May this totem...", "...shroud the false suns!")
|
||||
channel_time = 80
|
||||
required_components = list("belligerent_eye" = 4, "replicant_alloy" = 1, "hierophant_ansible" = 1)
|
||||
consumed_components = list("belligerent_eye" = 3, "replicant_alloy" = 1, "hierophant_ansible" = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/interdiction_lens
|
||||
creator_message = "<span class='brass'>You form an interdiction lens, which disrupts cameras and radios and drains power.</span>"
|
||||
observer_message = "<span class='warning'>A brass totem rises from the ground, a purple gem appearing in its center!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "If it fails to funnel power into a nearby Sigil of Transmission and fails to disable even one thing, it will disable itself for two minutes."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 6
|
||||
|
||||
|
||||
//Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures and consume power or replicant alloy.
|
||||
/datum/clockwork_scripture/create_object/mending_motor
|
||||
descname = "Structure, Repairs Other Structures"
|
||||
name = "Mending Motor"
|
||||
desc = "Creates a mechanized prism that will rapidly repair damage to clockwork creatures, converted cyborgs, and clockwork structures. Requires replicant alloy or power to function."
|
||||
invocations = list("May this prism...", "...mend our dents and scratches!")
|
||||
channel_time = 80
|
||||
required_components = list("vanguard_cogwheel" = 4, "guvax_capacitor" = 1, "replicant_alloy" = 1)
|
||||
consumed_components = list("vanguard_cogwheel" = 3, "guvax_capacitor" = 1, "replicant_alloy" = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/mending_motor/prefilled
|
||||
creator_message = "<span class='brass'>You form a mending motor, which will consume power or replicant alloy to mend the wounds of mechanized servants.</span>"
|
||||
observer_message = "<span class='warning'>An onyx prism forms in midair and sprouts tendrils to support itself!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Powerful healing but power use is very inefficient, and its alloy use is little better."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 7
|
||||
|
||||
|
||||
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
|
||||
/datum/clockwork_scripture/create_object/mania_motor
|
||||
descname = "Structure, Area Denial"
|
||||
name = "Mania Motor"
|
||||
desc = "Creates a mania motor which will cause brain damage and hallucinations in nearby non-servant humans. It will also try to convert humans directly adjecent to the motor."
|
||||
invocations = list("May this transmitter...", "...break the will of all who oppose us!")
|
||||
channel_time = 80
|
||||
required_components = list("guvax_capacitor" = 4, "replicant_alloy" = 1, "hierophant_ansible" = 1)
|
||||
consumed_components = list("guvax_capacitor" = 3, "replicant_alloy" = 1, "hierophant_ansible" = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/mania_motor
|
||||
creator_message = "<span class='brass'>You form a mania motor which will cause brain damage and hallucinations in nearby humans while active.</span>"
|
||||
observer_message = "<span class='warning'>A two-pronged machine rises from the ground!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Eligible human servants next to the motor will be converted at an additional power cost. It will also cure hallucinations and brain damage in nearby servants."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 8
|
||||
|
||||
|
||||
//Tinkerer's Daemon: Creates an efficient machine that rapidly produces components at a power cost.
|
||||
/datum/clockwork_scripture/create_object/tinkerers_daemon
|
||||
descname = "Structure, Component Generator"
|
||||
name = "Tinkerer's Daemon"
|
||||
desc = "Creates a tinkerer's daemon which can rapidly collect components. It will only function if it has sufficient power, is outnumbered by servants by a ratio of 5:1, and there is at least one existing cache."
|
||||
invocations = list("May this generator...", "...collect Engine parts that yet hold greatness!")
|
||||
channel_time = 80
|
||||
required_components = list("belligerent_eye" = 1, "guvax_capacitor" = 1, "replicant_alloy" = 4)
|
||||
consumed_components = list("belligerent_eye" = 1, "guvax_capacitor" = 1, "replicant_alloy" = 3)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/tinkerers_daemon
|
||||
creator_message = "<span class='brass'>You form a tinkerer's daemon which can rapidly collect components at a power cost.</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Vital to your success!"
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 9
|
||||
|
||||
/datum/clockwork_scripture/create_object/tinkerers_daemon/check_special_requirements()
|
||||
var/servants = 0
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(is_servant_of_ratvar(L))
|
||||
servants++
|
||||
if(servants * 0.2 < clockwork_daemons)
|
||||
invoker << "<span class='nezbere'>\"Daemons are already disabled, making more of them would be a waste.\"</span>"
|
||||
return FALSE
|
||||
if(servants * 0.2 < clockwork_daemons+1)
|
||||
invoker << "<span class='nezbere'>\"This daemon would be useless, friend.\"</span>"
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
|
||||
/datum/clockwork_scripture/create_object/clockwork_obelisk
|
||||
descname = "Structure, Teleportation Hub"
|
||||
name = "Clockwork Obelisk"
|
||||
desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living servant or clockwork obelisk."
|
||||
invocations = list("May this obelisk...", "...take us to all places!")
|
||||
channel_time = 80
|
||||
required_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 4)
|
||||
consumed_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 3)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk
|
||||
creator_message = "<span class='brass'>You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways.</span>"
|
||||
observer_message = "<span class='warning'>A brass obelisk appears handing in midair!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Producing a gateway has a high power cost. Gateways to or between clockwork obelisks recieve double duration and uses."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 10
|
||||
@@ -0,0 +1,279 @@
|
||||
/////////////
|
||||
// DRIVERS //
|
||||
/////////////
|
||||
|
||||
//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!")
|
||||
chant_amount = 15
|
||||
chant_interval = 20
|
||||
required_components = list("belligerent_eye" = 1)
|
||||
usage_tip = "Useful for crowd control in a populated area and disrupting mass movement."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 1
|
||||
var/noncultist_damage = 2 //damage per chant to noncultists
|
||||
var/cultist_damage = 8 //damage per chant to non-walking cultists
|
||||
|
||||
/datum/clockwork_scripture/channeled/belligerent/chant_effects(chant_number)
|
||||
for(var/mob/living/carbon/C in hearers(7, invoker))
|
||||
var/number_legs = C.get_num_legs()
|
||||
if(!is_servant_of_ratvar(C) && !C.null_rod_check() && number_legs) //you have legs right
|
||||
C.apply_damage(noncultist_damage * 0.5, BURN, "l_leg")
|
||||
C.apply_damage(noncultist_damage * 0.5, BURN, "r_leg")
|
||||
if(C.m_intent != "walk")
|
||||
if(!iscultist(C))
|
||||
C << "<span class='warning'>Your leg[number_legs > 1 ? "s shiver":" shivers"] with pain!</span>"
|
||||
else //Cultists take extra burn damage
|
||||
C << "<span class='warning'>Your leg[number_legs > 1 ? "s burn":" burns"] with pain!</span>"
|
||||
C.apply_damage(cultist_damage * 0.5, BURN, "l_leg")
|
||||
C.apply_damage(cultist_damage * 0.5, BURN, "r_leg")
|
||||
C.m_intent = "walk"
|
||||
|
||||
|
||||
//Judicial Visor: Creates a judicial visor, which can smite an area.
|
||||
/datum/clockwork_scripture/create_object/judicial_visor
|
||||
descname = "Delayed Area Stun Glasses"
|
||||
name = "Judicial Visor"
|
||||
desc = "Forms a visor that, when worn, will grant the ability to smite an area, stunning, muting, and damaging the nonfaithful. \
|
||||
Cultists of Nar-Sie will be set on fire, though they will be stunned for half the time."
|
||||
invocations = list("Grant me the flames of Engine!")
|
||||
channel_time = 10
|
||||
required_components = list("belligerent_eye" = 2)
|
||||
consumed_components = list("belligerent_eye" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/item/clothing/glasses/judicial_visor
|
||||
creator_message = "<span class='brass'>You form a judicial visor, which is capable of smiting the unworthy.</span>"
|
||||
usage_tip = "The visor has a thirty-second cooldown once used, and the marker it creates has a delay of 3 seconds before exploding."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
space_allowed = TRUE
|
||||
sort_priority = 2
|
||||
|
||||
|
||||
//Vanguard: Provides twenty seconds of stun immunity. At the end of the twenty seconds, 25% of all stuns absorbed are applied to the invoker.
|
||||
/datum/clockwork_scripture/vanguard
|
||||
descname = "Self Stun Immunity"
|
||||
name = "Vanguard"
|
||||
desc = "Provides twenty seconds of stun immunity. At the end of the twenty seconds, the invoker is stunned for the equivalent of 25% of all stuns they absorbed. \
|
||||
Excessive absorption will cause unconsciousness."
|
||||
invocations = list("Shield me...", "...from darkness!")
|
||||
channel_time = 30
|
||||
required_components = list("vanguard_cogwheel" = 1)
|
||||
usage_tip = "You cannot reactivate Vanguard while still shielded by it."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 3
|
||||
|
||||
/datum/clockwork_scripture/vanguard/check_special_requirements()
|
||||
if(islist(invoker.stun_absorption) && invoker.stun_absorption["vanguard"] && invoker.stun_absorption["vanguard"]["end_time"] > world.time)
|
||||
invoker << "<span class='warning'>You are already shielded by a Vanguard!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/vanguard/scripture_effects()
|
||||
invoker.apply_status_effect(STATUS_EFFECT_VANGUARD)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Sentinel's Compromise: Allows the invoker to select a nearby servant convert their brute and burn damage into half as much toxin damage.
|
||||
/datum/clockwork_scripture/sentinels_compromise
|
||||
descname = "Convert Brute/Burn to Half Toxin"
|
||||
name = "Sentinel's Compromise"
|
||||
desc = "Heals all brute and burn damage on a nearby living, friendly servant, but deals 50% of the damage they had as toxin damage."
|
||||
invocations = list("Mend the wounds of...", "...my inferior flesh.")
|
||||
channel_time = 30
|
||||
required_components = list("vanguard_cogwheel" = 2)
|
||||
consumed_components = list("vanguard_cogwheel" = 1)
|
||||
usage_tip = "The Compromise is very fast to invoke."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 4
|
||||
|
||||
/datum/clockwork_scripture/sentinels_compromise/scripture_effects()
|
||||
var/list/nearby_cultists = list()
|
||||
for(var/mob/living/C in range(7, invoker))
|
||||
if(C.stat != DEAD && is_servant_of_ratvar(C) && (C.getBruteLoss() || C.getFireLoss()))
|
||||
nearby_cultists += C
|
||||
if(!nearby_cultists.len)
|
||||
invoker << "<span class='warning'>There are no eligible servants nearby!</span>"
|
||||
return FALSE
|
||||
var/mob/living/L = input(invoker, "Choose a fellow servant to heal.", name) as null|anything in nearby_cultists
|
||||
if(!L || !invoker || !slab || qdeleted(slab) || !invoker.canUseTopic(slab) || !invoker.get_active_held_item() != slab || L.stat == DEAD)
|
||||
return FALSE
|
||||
var/brutedamage = L.getBruteLoss()
|
||||
var/burndamage = L.getFireLoss()
|
||||
var/totaldamage = brutedamage + burndamage
|
||||
if(!totaldamage)
|
||||
invoker << "<span class='warning'>[L] is not burned or bruised!</span>"
|
||||
return FALSE
|
||||
L.adjustToxLoss(totaldamage * 0.5)
|
||||
L.adjustBruteLoss(-brutedamage)
|
||||
L.adjustFireLoss(-burndamage)
|
||||
var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
|
||||
var/targetturf = get_turf(L)
|
||||
for(var/i in 1 to healseverity)
|
||||
PoolOrNew(/obj/effect/overlay/temp/heal, list(targetturf, "#1E8CE1"))
|
||||
invoker << "<span class='brass'>You bathe [L] in Inath-neq's power!</span>"
|
||||
L.visible_message("<span class='warning'>A blue light washes over [L], mending [L.p_their()] bruises and burns!</span>", \
|
||||
"<span class='heavy_brass'>You feel Inath-neq's power healing your wounds, but a deep nausea overcomes you!</span>")
|
||||
playsound(targetturf, 'sound/magic/Staff_Healing.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Guvax: Converts anyone adjacent to the invoker after completion, but gets gradually slower as the cult gets more dominant.
|
||||
/datum/clockwork_scripture/guvax
|
||||
descname = "Melee Area Convert"
|
||||
name = "Guvax"
|
||||
desc = "Enlists all nearby living unshielded creatures into servitude to Ratvar. Also purges holy water from nearby Servants."
|
||||
invocations = list("Enlighten this heathen!", "All are insects before Engine!", "Purge all untruths and honor Engine.")
|
||||
channel_time = 50
|
||||
required_components = list("guvax_capacitor" = 1)
|
||||
usage_tip = "Only works on those in melee range and does not penetrate mindshield implants. Much more efficient than a Sigil of Submission at low Servant amounts."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 5
|
||||
|
||||
/datum/clockwork_scripture/guvax/run_scripture()
|
||||
var/servants = 0
|
||||
for(var/mob/living/M in living_mob_list)
|
||||
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
|
||||
servants++
|
||||
if(servants > 5)
|
||||
servants -= 5
|
||||
channel_time = min(channel_time + servants*10, 200) //if above 5 servants, is much slower
|
||||
return ..()
|
||||
|
||||
/datum/clockwork_scripture/guvax/scripture_effects()
|
||||
for(var/mob/living/L in hearers(1, get_turf(invoker))) //Affects silicons
|
||||
if(!is_servant_of_ratvar(L))
|
||||
if(L.stat != DEAD)
|
||||
add_servant_of_ratvar(L)
|
||||
else
|
||||
if(L.reagents && L.reagents.has_reagent("holywater"))
|
||||
L.reagents.remove_reagent("holywater", 1000)
|
||||
L << "<span class='heavy_brass'>Ratvar's light flares, banishing the darkness. Your devotion remains intact!</span>"
|
||||
return TRUE
|
||||
|
||||
|
||||
//Taunting Tirade: Channeled for up to five times over thirty seconds. Confuses non-servants that can hear it and allows movement for a brief time after each chant.
|
||||
/datum/clockwork_scripture/channeled/taunting_tirade
|
||||
descname = "Channeled, Mobile Area Confusion"
|
||||
name = "Taunting Tirade"
|
||||
desc = "Weakens, confuses and dizzies all nearby non-servants with a short invocation, then allows movement for five seconds. Chanted every second for up to thirty seconds."
|
||||
chant_invocations = list("Hostiles on my back!", "Enemies on my trail!", "Gonna try and shake my tail.", "Bogeys on my six!")
|
||||
chant_amount = 5
|
||||
chant_interval = 10
|
||||
required_components = list("guvax_capacitor" = 2)
|
||||
consumed_components = list("guvax_capacitor" = 1)
|
||||
usage_tip = "Useful for fleeing attackers, as few will be able to follow someone using this scripture."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 6
|
||||
var/flee_time = 47 //allow fleeing for 5 seconds
|
||||
var/grace_period = 3 //very short grace period so you don't have to stop immediately
|
||||
var/datum/progressbar/progbar
|
||||
|
||||
/datum/clockwork_scripture/channeled/taunting_tirade/chant_effects(chant_number)
|
||||
for(var/mob/living/L in hearers(7, invoker))
|
||||
if(!is_servant_of_ratvar(L) && !L.null_rod_check())
|
||||
L.confused = min(L.confused + 20, 100)
|
||||
L.dizziness = min(L.dizziness + 20, 100)
|
||||
L.Weaken(1)
|
||||
invoker.visible_message("<span class='warning'>[invoker] is suddenly covered with a thin layer of dark purple smoke!</span>")
|
||||
invoker.color = "#AF0AAF"
|
||||
animate(invoker, color = initial(invoker.color), time = flee_time+grace_period)
|
||||
if(chant_number != chant_amount) //if this is the last chant, we don't have a movement period because the chant is over
|
||||
var/endtime = world.time + flee_time
|
||||
var/starttime = world.time
|
||||
progbar = new(invoker, flee_time, invoker)
|
||||
progbar.bar.color = "#AF0AAF"
|
||||
animate(progbar.bar, color = initial(progbar.bar.color), time = flee_time+grace_period)
|
||||
while(world.time < endtime)
|
||||
sleep(1)
|
||||
progbar.update(world.time - starttime)
|
||||
qdel(progbar)
|
||||
sleep(grace_period)
|
||||
|
||||
/datum/clockwork_scripture/channeled/taunting_tirade/chant_end_effects()
|
||||
qdel(progbar)
|
||||
|
||||
|
||||
//Replicant: Creates a new clockwork slab. Doesn't use create_object because of its unique behavior.
|
||||
/datum/clockwork_scripture/replicant
|
||||
descname = "New Clockwork Slab"
|
||||
name = "Replicant"
|
||||
desc = "Creates a new clockwork slab."
|
||||
invocations = list("Metal, become greater!")
|
||||
channel_time = 10
|
||||
required_components = list("replicant_alloy" = 1)
|
||||
whispered = TRUE
|
||||
usage_tip = "This is inefficient as a way to produce components, as the slab produced must be held by someone with no other slabs to produce components."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
sort_priority = 7
|
||||
|
||||
/datum/clockwork_scripture/replicant/scripture_effects()
|
||||
invoker << "<span class='brass'>You copy a piece of replicant alloy and command it into a new slab.</span>" //No visible message, for stealth purposes
|
||||
var/obj/item/clockwork/slab/S = new(get_turf(invoker))
|
||||
invoker.put_in_hands(S) //Put it in your hands if possible
|
||||
return TRUE
|
||||
|
||||
|
||||
//Tinkerer's Cache: Creates a tinkerer's cache, allowing global component storage.
|
||||
/datum/clockwork_scripture/create_object/tinkerers_cache
|
||||
descname = "Necessary, Shares Components"
|
||||
name = "Tinkerer's Cache"
|
||||
desc = "Forms a cache that can store an infinite amount of components. All caches are linked and will provide components to slabs."
|
||||
invocations = list("Constructing...", "...a cache!")
|
||||
channel_time = 50
|
||||
required_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 2, "hierophant_ansible" = 0)
|
||||
consumed_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 1, "hierophant_ansible" = 0)
|
||||
object_path = /obj/structure/destructible/clockwork/cache
|
||||
creator_message = "<span class='brass'>You form a tinkerer's cache, which is capable of storing components, which will automatically be used by slabs.</span>"
|
||||
observer_message = "<span class='warning'>A hollow brass spire rises and begins to blaze!</span>"
|
||||
usage_tip = "Slabs will draw components from the global cache after the slab's own repositories, making caches very efficient."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 8
|
||||
|
||||
/datum/clockwork_scripture/create_object/tinkerers_cache/New()
|
||||
var/cache_cost_increase = min(round(clockwork_caches*0.2), 5)
|
||||
for(var/i in required_components)
|
||||
if(i != "replicant_alloy")
|
||||
required_components[i] += cache_cost_increase
|
||||
for(var/i in consumed_components)
|
||||
if(i != "replicant_alloy")
|
||||
consumed_components[i] += cache_cost_increase
|
||||
return ..()
|
||||
|
||||
|
||||
//Wraith Spectacles: Creates a pair of wraith spectacles, which grant xray vision but damage vision slowly.
|
||||
/datum/clockwork_scripture/create_object/wraith_spectacles
|
||||
descname = "Xray Vision Glasses"
|
||||
name = "Wraith Spectacles"
|
||||
desc = "Fabricates a pair of glasses that provides true sight but quickly damage vision, eventually causing blindness if worn for too long."
|
||||
invocations = list("Show the truth of this world to me!")
|
||||
channel_time = 10
|
||||
required_components = list("hierophant_ansible" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/item/clothing/glasses/wraith_spectacles
|
||||
creator_message = "<span class='brass'>You form a pair of wraith spectacles, which will grant true sight when worn.</span>"
|
||||
usage_tip = "\"True sight\" means that you are able to see through walls and in darkness."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
space_allowed = TRUE
|
||||
sort_priority = 9
|
||||
|
||||
|
||||
//Sigil of Transgression: Creates a sigil of transgression, which stuns the first nonservant to cross it.
|
||||
/datum/clockwork_scripture/create_object/sigil_of_transgression
|
||||
descname = "Stun Trap"
|
||||
name = "Sigil of Transgression"
|
||||
desc = "Wards a tile with a sigil. The next person to cross the sigil will be smitten and unable to move. Nar-Sian cultists are stunned altogether."
|
||||
invocations = list("Divinity, dazzle...", "...those who tresspass here!")
|
||||
channel_time = 50
|
||||
required_components = list("hierophant_ansible" = 2)
|
||||
consumed_components = list("hierophant_ansible" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/effect/clockwork/sigil/transgression
|
||||
creator_message = "<span class='brass'>A sigil silently appears below you. The next non-servant to cross it will be immobilized.</span>"
|
||||
usage_tip = "The sigil, while fairly powerful in its stun, does not induce muteness in its victim."
|
||||
tier = SCRIPTURE_DRIVER
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 10
|
||||
@@ -0,0 +1,108 @@
|
||||
///////////////
|
||||
// JUDGEMENT //
|
||||
///////////////
|
||||
|
||||
//Ark of the Clockwork Justiciar: Creates a Gateway to the Celestial Derelict, either summoning ratvar or proselytizing everything.
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar
|
||||
descname = "Win Condition"
|
||||
name = "Ark of the Clockwork Justiciar"
|
||||
desc = "Pulls from the power of all of Ratvar's servants and generals to construct a massive machine used to tear apart a rift in spacetime to the Celestial Derelict. This gateway will \
|
||||
call forth Ratvar from his exile after some time."
|
||||
invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! I 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
|
||||
required_components = list("belligerent_eye" = 10, "vanguard_cogwheel" = 10, "guvax_capacitor" = 10, "replicant_alloy" = 10, "hierophant_ansible" = 10)
|
||||
consumed_components = list("belligerent_eye" = 10, "vanguard_cogwheel" = 10, "guvax_capacitor" = 10, "replicant_alloy" = 10, "hierophant_ansible" = 10)
|
||||
invokers_required = 5
|
||||
multiple_invokers_used = TRUE
|
||||
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_JUDGEMENT
|
||||
sort_priority = 1
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/New()
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective != CLOCKCULT_GATEWAY)
|
||||
invocations = list("ARMORER! FRIGHT! AMPERAGE! VANGUARD! I CALL UPON YOU!!", \
|
||||
"THIS STATION WILL BE A BEACON OF HOPE IN THE DARKNESS OF SPACE!!", \
|
||||
"HELP US MAKE THIS SHOW ENGINE'S GLORY!!")
|
||||
..()
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/check_special_requirements()
|
||||
if(!slab.no_cost)
|
||||
if(ratvar_awakens)
|
||||
invoker << "<span class='big_brass'>\"I am already here, idiot.\"</span>"
|
||||
return FALSE
|
||||
for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in all_clockwork_objects)
|
||||
var/area/gate_area = get_area(G)
|
||||
invoker << "<span class='userdanger'>There is already a gateway at [gate_area.map_name]!</span>"
|
||||
return FALSE
|
||||
var/area/A = get_area(invoker)
|
||||
var/turf/T = get_turf(invoker)
|
||||
if(!T || T.z != ZLEVEL_STATION || istype(A, /area/shuttle))
|
||||
invoker << "<span class='warning'>You must be on the station to activate the Ark!</span>"
|
||||
return FALSE
|
||||
if(clockwork_gateway_activated)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective != CLOCKCULT_GATEWAY)
|
||||
invoker << "<span class='nezbere'>\"Look upon his works. Is it not glorious?\"</span>"
|
||||
else
|
||||
invoker << "<span class='warning'>Ratvar's recent banishment renders him too weak to be wrung forth from Reebe!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/ark_of_the_clockwork_justiciar/scripture_effects()
|
||||
var/turf/T = get_turf(invoker)
|
||||
new/obj/effect/clockwork/general_marker/inathneq(T)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective == CLOCKCULT_GATEWAY)
|
||||
T.visible_message("<span class='inathneq'>\"[text2ratvar("Engine, come forth and show your servants your mercy!")]\"</span>")
|
||||
else
|
||||
T.visible_message("<span class='inathneq'>\"[text2ratvar("We will show all the mercy of Engine!")]\"</span>")
|
||||
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0)
|
||||
sleep(10)
|
||||
if(!check_special_requirements())
|
||||
return FALSE
|
||||
new/obj/effect/clockwork/general_marker/sevtug(T)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective == CLOCKCULT_GATEWAY)
|
||||
T.visible_message("<span class='sevtug'>\"[text2ratvar("Engine, come forth and show this station your decorating skills!")]\"</span>")
|
||||
else
|
||||
T.visible_message("<span class='sevtug'>\"[text2ratvar("We will show all Engine's decorating skills.")]\"</span>")
|
||||
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 45, 0)
|
||||
sleep(10)
|
||||
if(!check_special_requirements())
|
||||
return FALSE
|
||||
new/obj/effect/clockwork/general_marker/nezbere(T)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective == CLOCKCULT_GATEWAY)
|
||||
T.visible_message("<span class='nezbere'>\"[text2ratvar("Engine, come forth and shine your light across this realm!!")]\"</span>")
|
||||
else
|
||||
T.visible_message("<span class='nezbere'>\"[text2ratvar("We will show all Engine's light!!")]\"</span>")
|
||||
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 60, 0)
|
||||
sleep(10)
|
||||
if(!check_special_requirements())
|
||||
return FALSE
|
||||
new/obj/effect/clockwork/general_marker/nzcrentr(T)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective == CLOCKCULT_GATEWAY)
|
||||
T.visible_message("<span class='nzcrentr'>\"[text2ratvar("Engine, come forth.")]\"</span>")
|
||||
else
|
||||
T.visible_message("<span class='nezbere'>\"[text2ratvar("We will show all Engine's power!")]\"</span>")
|
||||
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0)
|
||||
sleep(10)
|
||||
if(check_special_requirements())
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/CG = new/obj/structure/destructible/clockwork/massive/celestial_gateway(T)
|
||||
if(ticker && ticker.mode && ticker.mode.clockwork_objective != CLOCKCULT_GATEWAY)
|
||||
CG.ratvar_portal = FALSE
|
||||
hierophant_message("<span class='big_brass'>This newly constructed gateway will not free Ratvar, \
|
||||
and will instead simply proselytize and convert everything and everyone on the station.</span>", TRUE)
|
||||
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0)
|
||||
var/list/open_turfs = list()
|
||||
for(var/turf/open/OT in orange(1, T))
|
||||
var/list/dense_objects = list()
|
||||
for(var/obj/O in OT)
|
||||
if(O.density && !O.CanPass(invoker, OT, 5))
|
||||
dense_objects |= O
|
||||
if(!dense_objects.len)
|
||||
open_turfs |= OT
|
||||
if(open_turfs.len)
|
||||
for(var/mob/living/L in T)
|
||||
L.forceMove(pick(open_turfs)) //shove living mobs off of the gate's new location
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -0,0 +1,228 @@
|
||||
//////////////
|
||||
// REVENANT //
|
||||
//////////////
|
||||
|
||||
//Invoke Inath-neq, the Resonant Cogwheel: Grants invulnerability and stun immunity to everyone nearby for 15 seconds.
|
||||
/datum/clockwork_scripture/invoke_inathneq
|
||||
descname = "Area Invuln"
|
||||
name = "Invoke Inath-neq, the Resonant Cogwheel"
|
||||
desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all servants in range for fifteen seconds."
|
||||
invocations = list("I call upon you, Vanguard!!", "Let the Resonant Cogs turn once more!!", "Grant me and my allies the strength to vanquish our foes!!")
|
||||
channel_time = 150
|
||||
required_components = list("vanguard_cogwheel" = 6, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 3)
|
||||
consumed_components = list("vanguard_cogwheel" = 6, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 3)
|
||||
usage_tip = "Those affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity."
|
||||
tier = SCRIPTURE_REVENANT
|
||||
sort_priority = 2
|
||||
var/total_duration = 150
|
||||
|
||||
/datum/clockwork_scripture/invoke_inathneq/check_special_requirements()
|
||||
if(!slab.no_cost && clockwork_generals_invoked["inath-neq"] > world.time)
|
||||
invoker << "<span class='inathneq'>\"[text2ratvar("I cannot lend you my aid yet, champion. Please be careful.")]\"</span>\n\
|
||||
<span class='warning'>Inath-neq has already been invoked recently! You must wait several minutes before calling upon the Resonant Cogwheel.</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/invoke_inathneq/scripture_effects()
|
||||
new/obj/effect/clockwork/general_marker/inathneq(get_turf(invoker))
|
||||
hierophant_message("<span class='inathneq'>[text2ratvar("Vanguard: \"I lend you my aid, champions! Let glory guide your blows!")]\"</span>", FALSE, invoker)
|
||||
clockwork_generals_invoked["inath-neq"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
|
||||
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
|
||||
if(invoker.real_name == "Lucio")
|
||||
clockwork_say(invoker, text2ratvar("Aww, let's break it DOWN!!"))
|
||||
for(var/mob/living/L in range(7, invoker))
|
||||
if(!is_servant_of_ratvar(L) || L.stat == DEAD)
|
||||
continue
|
||||
L.apply_status_effect(STATUS_EFFECT_INATHNEQS_ENDOWMENT)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Invoke Nezbere, the Brass Eidolon: Invokes Nezbere, bolstering the strength of many clockwork items for one minute.
|
||||
/datum/clockwork_scripture/invoke_nezbere
|
||||
descname = "Structure Buff"
|
||||
name = "Invoke Nezbere, the Brass Eidolon"
|
||||
desc = "Taps the limitless power of Nezbere, one of Ratvar's four generals. The restless toil of the Eidolon will empower a wide variety of clockwork apparatus for a full minute - notably, \
|
||||
clockwork proselytizers will cost no replicant alloy to use."
|
||||
invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!")
|
||||
channel_time = 150
|
||||
required_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 6)
|
||||
consumed_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 6)
|
||||
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
|
||||
and interdiction lenses, mending motors, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
|
||||
tier = SCRIPTURE_REVENANT
|
||||
sort_priority = 3
|
||||
invokers_required = 3
|
||||
multiple_invokers_used = TRUE
|
||||
|
||||
/datum/clockwork_scripture/invoke_nezbere/check_special_requirements()
|
||||
if(!slab.no_cost && clockwork_generals_invoked["nezbere"] > world.time)
|
||||
invoker << "<span class='nezbere'>\"[text2ratvar("Not just yet, friend. Patience is a virtue.")]\"</span>\n\
|
||||
<span class='warning'>Nezbere has already been invoked recently! You must wait several minutes before calling upon the Brass Eidolon.</span>"
|
||||
return FALSE
|
||||
if(!slab.no_cost && ratvar_awakens)
|
||||
invoker << "<span class='nezbere'>\"[text2ratvar("Our master is here already. You do not require my help, friend.")]\"</span>\n\
|
||||
<span class='warning'>Nezbere will not grant his power while Ratvar's dwarfs his own!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/invoke_nezbere/scripture_effects()
|
||||
new/obj/effect/clockwork/general_marker/nezbere(get_turf(invoker))
|
||||
hierophant_message("<span class='nezbere'>[text2ratvar("Armorer: \"I heed your call, champions. May your artifacts bring ruin upon the heathens that oppose our master!")]\"</span>", FALSE, invoker)
|
||||
clockwork_generals_invoked["nezbere"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
|
||||
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
|
||||
for(var/obj/structure/destructible/clockwork/ocular_warden/W in all_clockwork_objects) //Ocular wardens have increased damage and radius
|
||||
W.damage_per_tick *= 1.5
|
||||
W.sight_range *= 2
|
||||
for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects) //Proselytizers no longer require alloy
|
||||
P.uses_alloy = FALSE
|
||||
for(var/obj/structure/destructible/clockwork/powered/M in all_clockwork_objects) //Powered clockwork structures no longer need power
|
||||
M.needs_power = FALSE
|
||||
if(istype(M, /obj/structure/destructible/clockwork/powered/tinkerers_daemon)) //Daemons produce components twice as quickly
|
||||
var/obj/structure/destructible/clockwork/powered/tinkerers_daemon/D = M
|
||||
D.production_time *= 0.5
|
||||
spawn(600)
|
||||
for(var/obj/structure/destructible/clockwork/ocular_warden/W in all_clockwork_objects)
|
||||
W.damage_per_tick = initial(W.damage_per_tick)
|
||||
W.sight_range = initial(W.sight_range)
|
||||
for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects)
|
||||
P.uses_alloy = initial(P.uses_alloy)
|
||||
for(var/obj/structure/destructible/clockwork/powered/M in all_clockwork_objects)
|
||||
M.needs_power = initial(M.needs_power)
|
||||
if(istype(M, /obj/structure/destructible/clockwork/powered/tinkerers_daemon))
|
||||
var/obj/structure/destructible/clockwork/powered/tinkerers_daemon/D = M
|
||||
D.production_time = initial(D.production_time)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Invoke Sevtug, the Formless Pariah: Causes massive global hallucinations, braindamage, confusion, and dizziness to all humans on the same zlevel.
|
||||
/datum/clockwork_scripture/invoke_sevtug
|
||||
descname = "Global Hallucination"
|
||||
name = "Invoke Sevtug, the Formless Pariah"
|
||||
desc = "Taps the limitless power of Sevtug, one of Ratvar's four generals. The mental manipulation ability of the Pariah allows its wielder to cause mass hallucinations and confusion \
|
||||
for all non-servant humans on the same z-level as them. The power of this scripture falls off somewhat with distance, and certain things may reduce its effects."
|
||||
invocations = list("I call upon you, Fright!!", "Let your power shatter the sanity of the weak-minded!!", "Let your tendrils hold sway over all!!")
|
||||
channel_time = 150
|
||||
required_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 6, "hierophant_ansible" = 3)
|
||||
consumed_components = list("belligerent_eye" = 3, "vanguard_cogwheel" = 3, "guvax_capacitor" = 6, "hierophant_ansible" = 3)
|
||||
usage_tip = "Causes brain damage, hallucinations, confusion, and dizziness in massive amounts."
|
||||
tier = SCRIPTURE_REVENANT
|
||||
sort_priority = 4
|
||||
invokers_required = 3
|
||||
multiple_invokers_used = TRUE
|
||||
var/list/mindbreaksayings = list("\"Oh, great. I get to shatter some minds.\"", "\"More minds to crush.\"", \
|
||||
"\"Really, this is almost boring.\"", "\"None of these minds have anything interesting in them.\"", "\"Maybe I can instill a little bit of terror in this one.\"", \
|
||||
"\"What a waste of my power.\"", "\"I'm sure I could just control these minds instead, but they never ask.\"")
|
||||
|
||||
/datum/clockwork_scripture/invoke_sevtug/check_special_requirements()
|
||||
if(!slab.no_cost && clockwork_generals_invoked["sevtug"] > world.time)
|
||||
invoker << "<span class='sevtug'>\"[text2ratvar("Is it really so hard - even for a simpleton like you - to grasp the concept of waiting?")]\"</span>\n\
|
||||
<span class='warning'>Sevtug has already been invoked recently! You must wait several minutes before calling upon the Formless Pariah.</span>"
|
||||
return FALSE
|
||||
if(!slab.no_cost && ratvar_awakens)
|
||||
invoker << "<span class='sevtug'>\"[text2ratvar("Do you really think anything I can do right now will compare to Engine's power?")]\"</span>\n\
|
||||
<span class='warning'>Sevtug will not grant his power while Ratvar's dwarfs his own!</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/invoke_sevtug/scripture_effects()
|
||||
new/obj/effect/clockwork/general_marker/sevtug(get_turf(invoker))
|
||||
hierophant_message("<span class='sevtug'>[text2ratvar("Fright: \"I heed your call, idiots. Get going and use this chance while it lasts!")]\"</span>", FALSE, invoker)
|
||||
clockwork_generals_invoked["sevtug"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
|
||||
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
|
||||
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
|
||||
var/turf/T = get_turf(invoker)
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
if(H.z == invoker.z && !is_servant_of_ratvar(H))
|
||||
var/distance = 0
|
||||
distance += get_dist(T, get_turf(H))
|
||||
var/messaged = FALSE
|
||||
var/visualsdistance = max(150 - distance, 5)
|
||||
var/minordistance = max(200 - distance*2, 5)
|
||||
var/majordistance = max(150 - distance*3, 5)
|
||||
if(H.null_rod_check())
|
||||
visualsdistance = round(visualsdistance * 0.25)
|
||||
minordistance = round(minordistance * 0.25)
|
||||
majordistance = round(majordistance * 0.25)
|
||||
H << "<span class='sevtug'>[text2ratvar("Oh, a void weapon. How annoying, I may as well not bother.")]</span>\n\
|
||||
<span class='warning'>Your holy weapon glows a faint orange in an attempt to defend your mind!</span>"
|
||||
messaged = TRUE
|
||||
if(H.isloyal())
|
||||
visualsdistance = round(visualsdistance * 0.5) //half effect for shielded targets
|
||||
minordistance = round(minordistance * 0.5)
|
||||
majordistance = round(majordistance * 0.5)
|
||||
if(!messaged)
|
||||
H << "<span class='sevtug'>[text2ratvar("Oh, look, a mindshield. Cute, I suppose I'll humor it.")]</span>"
|
||||
messaged = TRUE
|
||||
if(!messaged && prob(visualsdistance))
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(mindbreaksayings))]</span>"
|
||||
H.playsound_local(T, hum, visualsdistance, 1)
|
||||
flash_color(H, flash_color="#AF0AAF", flash_time=visualsdistance*10)
|
||||
H.set_drugginess(visualsdistance + H.druggy)
|
||||
H.dizziness = minordistance + H.dizziness
|
||||
H.hallucination = minordistance + H.hallucination
|
||||
H.confused = majordistance + H.confused
|
||||
H.setBrainLoss(majordistance + H.getBrainLoss())
|
||||
return TRUE
|
||||
|
||||
|
||||
//Invoke Nzcrentr, the Eternal Thunderbolt: Imbues an immense amount of energy into the invoker. After several seconds, everyone near the invoker will be hit with a devastating lightning blast.
|
||||
/datum/clockwork_scripture/invoke_nzcrentr
|
||||
descname = "Lightning Blast"
|
||||
name = "Invoke Nzcrentr, the Eternal Thunderbolt"
|
||||
desc = "Taps the limitless power of Nzcrentr, one of Ratvar's four generals. The immense energy Nzcrentr wields will allow you to imbue a tiny fraction of it into your body. After several \
|
||||
seconds, anyone near you will be struck by a devastating lightning bolt."
|
||||
invocations = list("I call upon you, Amperage!!", "Let your energy flow through me!!", "Let your boundless power shatter stars!!")
|
||||
channel_time = 150
|
||||
required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 6)
|
||||
consumed_components = list("belligerent_eye" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 6)
|
||||
usage_tip = "Struck targets will also be knocked down for about sixteen seconds."
|
||||
tier = SCRIPTURE_REVENANT
|
||||
sort_priority = 5
|
||||
|
||||
/datum/clockwork_scripture/invoke_nzcrentr/check_special_requirements()
|
||||
if(!slab.no_cost && clockwork_generals_invoked["nzcrentr"] > world.time)
|
||||
invoker << "<span class='nzcrentr'>\"[text2ratvar("The boss says you have to wait. Hey, do you think he would mind if I killed you? ...He would? Ok.")]\"</span>\n\
|
||||
<span class='warning'>Nzcrentr has already been invoked recently! You must wait several minutes before calling upon the Forgotten Arbiter.</span>"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/invoke_nzcrentr/scripture_effects()
|
||||
new/obj/effect/clockwork/general_marker/nzcrentr(get_turf(invoker))
|
||||
clockwork_generals_invoked["nzcrentr"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
|
||||
hierophant_message("<span class='nzcrentr'>[text2ratvar("Amperage: \"[invoker.real_name] has called forth my power. Hope they do not shatter under it!")]\"</span>", FALSE, invoker)
|
||||
invoker.visible_message("<span class='warning'>[invoker] begins to radiate a blinding light!</span>", \
|
||||
"<span class='nzcrentr'>\"[text2ratvar("The boss says it's okay to do this. Don't blame me if you die from it.")]\"</span>\n \
|
||||
<span class='userdanger'>You feel limitless power surging through you!</span>")
|
||||
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
|
||||
playsound(invoker, 'sound/magic/lightning_chargeup.ogg', 100, 0)
|
||||
animate(invoker, color = list(rgb(255, 255, 255), rgb(255, 255, 255), rgb(255, 255, 255), rgb(0,0,0)), time = 88) //Gradual advancement to extreme brightness
|
||||
sleep(88)
|
||||
if(invoker)
|
||||
invoker.visible_message("<span class='warning'>Massive bolts of energy emerge from across [invoker]'s body!</span>", \
|
||||
"<span class='nzcrentr'>\"[text2ratvar("I told you you wouldn't be able to handle it.")]\"</span>\n \
|
||||
<span class='userdanger'>TOO... MUCH! CAN'T... TAKE IT!</span>")
|
||||
playsound(invoker, 'sound/magic/lightningbolt.ogg', 100, 0)
|
||||
if(invoker.stat == CONSCIOUS)
|
||||
animate(invoker, color = initial(invoker.color), time = 10)
|
||||
for(var/mob/living/L in view(7, invoker))
|
||||
if(is_servant_of_ratvar(L))
|
||||
continue
|
||||
invoker.Beam(L, icon_state = "nzcrentrs_power", time = 10)
|
||||
var/randdamage = rand(40, 60)
|
||||
if(iscarbon(L))
|
||||
L.electrocute_act(randdamage, "Nzcrentr's power", 1, randdamage)
|
||||
else
|
||||
L.adjustFireLoss(randdamage)
|
||||
L.visible_message(
|
||||
"<span class='danger'>[L] was shocked by Nzcrentr's power!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
L.Weaken(8)
|
||||
playsound(L, 'sound/magic/LightningShock.ogg', 50, 1)
|
||||
else
|
||||
playsound(invoker, 'sound/magic/Disintegrate.ogg', 50, 1)
|
||||
invoker.gib()
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
@@ -0,0 +1,292 @@
|
||||
/////////////
|
||||
// SCRIPTS //
|
||||
/////////////
|
||||
|
||||
//Ocular Warden: Creates an ocular warden, which defends a small area near it.
|
||||
/datum/clockwork_scripture/create_object/ocular_warden
|
||||
descname = "Turret"
|
||||
name = "Ocular Warden"
|
||||
desc = "Forms an automatic short-range turret that deals low sustained damage to the unenlightened in its range."
|
||||
invocations = list("Guardians...", "...of the Engine...", "...defend us!")
|
||||
channel_time = 120
|
||||
required_components = list("belligerent_eye" = 2, "replicant_alloy" = 1)
|
||||
consumed_components = list("belligerent_eye" = 1, "replicant_alloy" = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/ocular_warden
|
||||
creator_message = "<span class='brass'>You form an ocular warden, which will focus its searing gaze upon nearby unenlightened.</span>"
|
||||
observer_message = "<span class='warning'>A brass eye takes shape and slowly rises into the air, its red iris glaring!</span>"
|
||||
usage_tip = "Although powerful, the warden is very weak and should optimally be placed behind barricades."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
one_per_tile = TRUE
|
||||
space_allowed = TRUE
|
||||
sort_priority = 1
|
||||
|
||||
/datum/clockwork_scripture/create_object/ocular_warden/check_special_requirements()
|
||||
for(var/obj/structure/destructible/clockwork/ocular_warden/W in range(3, invoker))
|
||||
invoker << "<span class='alloy'>You sense another ocular warden too near this location. Placing another this close would cause them to fight.</span>" //fluff message
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
//Cogscarab: Creates an empty cogscarab shell, which produces a cogscarab dedicated to maintaining and defending the cult.
|
||||
/datum/clockwork_scripture/create_object/cogscarab
|
||||
descname = "Constructor Soul Vessel Shell"
|
||||
name = "Cogscarab"
|
||||
desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer."
|
||||
invocations = list("Call forth...", "...the workers of Armorer.")
|
||||
channel_time = 60
|
||||
required_components = list("belligerent_eye" = 2, "hierophant_ansible" = 1)
|
||||
consumed_components = list("belligerent_eye" = 1, "hierophant_ansible" = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/shell/cogscarab
|
||||
creator_message = "<span class='brass'>You form a cogscarab, a constructor soul vessel receptable.</span>"
|
||||
observer_message = "<span class='warning'>The slab disgorges a puddle of black metal that contracts and forms into a strange shell!</span>"
|
||||
usage_tip = "Useless without a soul vessel and should not be created without one."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
sort_priority = 2
|
||||
|
||||
|
||||
//Fellowship Armory: Arms the invoker and nearby servants with Ratvarian armor.
|
||||
/datum/clockwork_scripture/fellowship_armory
|
||||
descname = "Area Servant Armor"
|
||||
name = "Fellowship Armory"
|
||||
desc = "Equips the invoker and any nearby servants with Ratvarian armor. This armor provides high melee resistance but a weakness to lasers. \
|
||||
It grows faster to invoke with more nearby servants."
|
||||
invocations = list("Shield me...", "...with the...", "... fragments of Engine!")
|
||||
channel_time = 110 //effectively 100 because it counts the invoker
|
||||
required_components = list("vanguard_cogwheel" = 2, "replicant_alloy" = 1)
|
||||
consumed_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1)
|
||||
usage_tip = "Before using, advise adjacent allies to remove their helmets, external suits, gloves, and shoes."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
multiple_invokers_used = TRUE
|
||||
multiple_invokers_optional = TRUE
|
||||
sort_priority = 4
|
||||
|
||||
/datum/clockwork_scripture/fellowship_armory/run_scripture()
|
||||
for(var/mob/living/L in range(1, invoker))
|
||||
if(is_servant_of_ratvar(L) && L.can_speak_vocal())
|
||||
channel_time = max(channel_time - 10, 0)
|
||||
return ..()
|
||||
|
||||
/datum/clockwork_scripture/fellowship_armory/scripture_effects()
|
||||
for(var/mob/living/L in range(1, invoker))
|
||||
if(!is_servant_of_ratvar(L))
|
||||
continue
|
||||
L.visible_message("<span class='warning'>Strange armor appears on [L]!</span>", "<span class='heavy_brass'>A bright shimmer runs down your body, equipping you with Ratvarian armor.</span>")
|
||||
playsound(L, 'sound/magic/clockwork/fellowship_armory.ogg', 50, 1)
|
||||
L.equip_to_slot_or_del(new/obj/item/clothing/head/helmet/clockwork(null), slot_head)
|
||||
L.equip_to_slot_or_del(new/obj/item/clothing/suit/armor/clockwork(null), slot_wear_suit)
|
||||
L.equip_to_slot_or_del(new/obj/item/clothing/gloves/clockwork(null), slot_gloves)
|
||||
L.equip_to_slot_or_del(new/obj/item/clothing/shoes/clockwork(null), slot_shoes)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
|
||||
/datum/clockwork_scripture/create_object/sigil_of_submission
|
||||
descname = "Conversion Trap"
|
||||
name = "Sigil of Submission"
|
||||
desc = "Places a luminous sigil that will enslave any valid beings standing on it after a time."
|
||||
invocations = list("Divinity, enlighten...", "...those who trespass here!")
|
||||
channel_time = 60
|
||||
required_components = list("belligerent_eye" = 1, "guvax_capacitor" = 2)
|
||||
consumed_components = list("belligerent_eye" = 1, "guvax_capacitor" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/effect/clockwork/sigil/submission
|
||||
creator_message = "<span class='brass'>A luminous sigil appears below you. The next non-servant to cross it will be enslaved after a brief time if they do not move.</span>"
|
||||
usage_tip = "This is not a primary conversion method - use Guvax for that. It is advantageous as a trap, however, as it will transmit the name of the newly-converted."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
one_per_tile = TRUE
|
||||
sort_priority = 5
|
||||
|
||||
|
||||
//Soul Vessel: Creates a soul vessel, which can seek a ghost or be used on the uncovered head of a dead or dying human to take their brain.
|
||||
/datum/clockwork_scripture/create_object/soul_vessel
|
||||
descname = "Clockwork Posibrain"
|
||||
name = "Soul Vessel"
|
||||
desc = "Forms an ancient positronic brain with an overriding directive to serve Ratvar."
|
||||
invocations = list("Herd the souls of...", "...the blasphemous damned!")
|
||||
channel_time = 30
|
||||
required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 2)
|
||||
consumed_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/item/device/mmi/posibrain/soul_vessel
|
||||
creator_message = "<span class='brass'>You form a soul vessel, which can be used in-hand to attract spirits, or used on an unconscious or dead human to extract their consciousness.</span>"
|
||||
usage_tip = "The vessel can be used as a teleport target for Spatial Gateway, though it is generally better-used by placing it in a shell."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
space_allowed = TRUE
|
||||
sort_priority = 6
|
||||
|
||||
|
||||
//Clockwork Proselytizer: Creates a clockwork proselytizer, used to convert objects and repair clockwork structures.
|
||||
/datum/clockwork_scripture/create_object/clockwork_proselytizer
|
||||
descname = "Necessary, Converts Objects"
|
||||
name = "Clockwork Proselytizer"
|
||||
desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires replicant alloys to function."
|
||||
invocations = list("With this device...", "...his presence shall be made known.")
|
||||
channel_time = 20
|
||||
required_components = list("guvax_capacitor" = 1, "replicant_alloy" = 2)
|
||||
consumed_components = list("guvax_capacitor" = 1, "replicant_alloy" = 1)
|
||||
whispered = TRUE
|
||||
object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded
|
||||
creator_message = "<span class='brass'>You form a clockwork proselytizer, which is already pre-loaded with a small amount of replicant alloy.</span>"
|
||||
usage_tip = "Clockwork walls cause adjacent tinkerer's caches to generate components passively, making them a vital tool. Clockwork floors heal servants standing on them."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
space_allowed = TRUE
|
||||
sort_priority = 7
|
||||
|
||||
|
||||
//Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons.
|
||||
/datum/clockwork_scripture/function_call
|
||||
descname = "Summonable Spear"
|
||||
name = "Function Call"
|
||||
desc = "Grants the invoker the ability to call forth a powerful Ratvarian spear every three minutes. The spear will deal significant damage to Nar-Sie's dogs and silicon lifeforms, but will \
|
||||
vanish three minutes after being summoned."
|
||||
invocations = list("Grant me...", "...the might of brass!")
|
||||
channel_time = 20
|
||||
required_components = list("replicant_alloy" = 2, "hierophant_ansible" = 1)
|
||||
consumed_components = list("replicant_alloy" = 1, "hierophant_ansible" = 1)
|
||||
whispered = TRUE
|
||||
usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage and stun them, but break the spear."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
sort_priority = 8
|
||||
|
||||
/datum/clockwork_scripture/function_call/check_special_requirements()
|
||||
for(var/datum/action/innate/function_call/F in invoker.actions)
|
||||
invoker << "<span class='warning'>You have already bound a Ratvarian spear to yourself!</span>"
|
||||
return FALSE
|
||||
return invoker.can_hold_items()
|
||||
|
||||
/datum/clockwork_scripture/function_call/scripture_effects()
|
||||
invoker.visible_message("<span class='warning'>A shimmer of yellow light infuses [invoker]!</span>", \
|
||||
"<span class='brass'>You bind a Ratvarian spear to yourself. Use the \"Function Call\" action button to call it forth.</span>")
|
||||
var/datum/action/innate/function_call/F = new()
|
||||
F.Grant(invoker)
|
||||
return TRUE
|
||||
|
||||
//Function Call action: Calls forth a Ratvarian spear once every 3 minutes.
|
||||
/datum/action/innate/function_call
|
||||
name = "Function Call"
|
||||
desc = "Allows you to summon a Ratvarian spear to fight enemies."
|
||||
button_icon_state = "ratvarian_spear"
|
||||
background_icon_state = "bg_clock"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
|
||||
buttontooltipstyle = "clockcult"
|
||||
var/cooldown = 0
|
||||
var/base_cooldown = 1800
|
||||
|
||||
/datum/action/innate/function_call/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner) || cooldown > world.time)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/function_call/Activate()
|
||||
if(!owner.get_empty_held_indexes())
|
||||
usr << "<span class='warning'>You need an empty to hand to call forth your spear!</span>"
|
||||
return FALSE
|
||||
owner.visible_message("<span class='warning'>A strange spear materializes in [owner]'s hands!</span>", "<span class='brass'>You call forth your spear!</span>")
|
||||
var/obj/item/clockwork/ratvarian_spear/R = new(get_turf(usr))
|
||||
owner.put_in_hands(R)
|
||||
if(!ratvar_awakens)
|
||||
owner << "<span class='warning'>Your spear begins to break down in this plane of existence. You can't use it for long!</span>"
|
||||
addtimer(R, "break_spear", base_cooldown, FALSE)
|
||||
cooldown = base_cooldown + world.time
|
||||
owner.update_action_buttons_icon()
|
||||
addtimer(src, "update_actions", base_cooldown, FALSE)
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/function_call/proc/update_actions()
|
||||
if(owner)
|
||||
owner.update_action_buttons_icon()
|
||||
|
||||
|
||||
//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
|
||||
required_components = list("vanguard_cogwheel" = 1, "hierophant_ansible" = 2)
|
||||
consumed_components = list("vanguard_cogwheel" = 1, "hierophant_ansible" = 1)
|
||||
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
|
||||
sort_priority = 9
|
||||
|
||||
/datum/clockwork_scripture/spatial_gateway/check_special_requirements()
|
||||
if(!isturf(invoker.loc))
|
||||
invoker << "<span class='warning'>You must not be inside an object to use this scripture!</span>"
|
||||
return FALSE
|
||||
var/other_servants = 0
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(is_servant_of_ratvar(L) && !L.stat != DEAD)
|
||||
other_servants++
|
||||
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
|
||||
other_servants++
|
||||
if(!other_servants)
|
||||
invoker << "<span class='warning'>There are no other servants or clockwork obelisks!</span>"
|
||||
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(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)
|
||||
|
||||
|
||||
//Volt Void: Channeled for up to thirty times over thirty seconds. Consumes power from most power storages and deals slight burn damage to the invoker.
|
||||
/datum/clockwork_scripture/channeled/volt_void
|
||||
descname = "Channeled, Area Power Drain"
|
||||
name = "Volt Void" //Alternative name: "On all levels but physical, I am a power sink"
|
||||
desc = "Drains energy from nearby power sources, dealing burn damage if the total power consumed is above a threshhold. Channeled every second for a maximum of thirty seconds."
|
||||
chant_invocations = list("Draw charge to this shell!")
|
||||
chant_amount = 30
|
||||
chant_interval = 10
|
||||
required_components = list("guvax_capacitor" = 1, "hierophant_ansible" = 2)
|
||||
consumed_components = list("guvax_capacitor" = 1, "hierophant_ansible" = 1)
|
||||
usage_tip = "If standing on a Sigil of Transmission, will transfer power to it. Augumented limbs will also be healed unless above a very high threshhold."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
sort_priority = 10
|
||||
var/total_power_drained = 0
|
||||
var/power_damage_threshhold = 3000
|
||||
var/augument_damage_threshhold = 6000
|
||||
|
||||
/datum/clockwork_scripture/channeled/volt_void/chant_effects(chant_number)
|
||||
playsound(invoker, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
var/power_drained = 0
|
||||
for(var/atom/movable/A in view(7, invoker))
|
||||
power_drained += A.power_drain(TRUE)
|
||||
var/obj/effect/clockwork/sigil/transmission/ST = locate(/obj/effect/clockwork/sigil/transmission) in get_turf(invoker)
|
||||
if(ST && power_drained >= 50)
|
||||
var/sigil_drain = 0
|
||||
while(power_drained >= 50)
|
||||
ST.modify_charge(-50)
|
||||
power_drained -= 50
|
||||
sigil_drain += 10
|
||||
power_drained += sigil_drain //readd part of the power given to the sigil to the power drained this cycle
|
||||
ST.visible_message("<span class='warning'>[ST] flares a brilliant orange!</span>")
|
||||
total_power_drained += power_drained
|
||||
if(power_drained >= 100 && total_power_drained >= power_damage_threshhold)
|
||||
var/power_damage = power_drained * 0.01
|
||||
invoker.visible_message("<span class='warning'>[invoker] flares a brilliant orange!</span>", "<span class='warning'>You feel the warmth of electricity running into your body.</span>")
|
||||
if(ishuman(invoker))
|
||||
var/mob/living/carbon/human/H = invoker
|
||||
for(var/X in H.bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(ratvar_awakens || (BP.status == BODYPART_ROBOTIC && total_power_drained < augument_damage_threshhold)) //if ratvar is alive, it won't damage and will always heal augumented limbs
|
||||
if(BP.heal_damage(power_damage, power_damage, 1, 0)) //heals one point of burn and brute for every ~100W drained on augumented limbs
|
||||
H.update_damage_overlays()
|
||||
else
|
||||
if(BP.receive_damage(0, power_damage))
|
||||
H.update_damage_overlays()
|
||||
else if(isanimal(invoker))
|
||||
var/mob/living/simple_animal/A = invoker
|
||||
A.adjustHealth(-power_damage) //if a simple animal is using volt void, just heal it
|
||||
return TRUE
|
||||
@@ -0,0 +1,200 @@
|
||||
//The base clockwork structure. Can have an alternate desc and will show up in the list of clockwork objects.
|
||||
/obj/structure/destructible/clockwork
|
||||
name = "meme structure"
|
||||
desc = "Some frog or something, the fuck?"
|
||||
var/clockwork_desc //Shown to servants when they examine
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "rare_pepe"
|
||||
anchored = 1
|
||||
density = 1
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/repair_amount = 5 //how much a proselytizer can repair each cycle
|
||||
var/can_be_repaired = TRUE //if a proselytizer can repair it at all
|
||||
break_message = "<span class='warning'>The frog isn't a meme after all!</span>" //The message shown when a structure breaks
|
||||
break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 2, \
|
||||
/obj/item/clockwork/alloy_shards/small = 3) //Parts left behind when a structure breaks
|
||||
var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station
|
||||
|
||||
/obj/structure/destructible/clockwork/New()
|
||||
..()
|
||||
change_construction_value(construction_value)
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/structure/destructible/clockwork/Destroy()
|
||||
change_construction_value(-construction_value)
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/narsie_act()
|
||||
if(take_damage(rand(25, 50), BRUTE) && src) //if we still exist
|
||||
var/previouscolor = color
|
||||
color = "#960000"
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
|
||||
/obj/structure/destructible/clockwork/examine(mob/user)
|
||||
var/can_see_clockwork = is_servant_of_ratvar(user) || isobserver(user)
|
||||
if(can_see_clockwork && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
if(!(resistance_flags & INDESTRUCTIBLE))
|
||||
var/t_It = p_they(TRUE)
|
||||
var/t_is = p_are()
|
||||
var/servant_message = "[t_It] [t_is] at <b>[obj_integrity]/[max_integrity]</b> integrity"
|
||||
var/heavily_damaged = FALSE
|
||||
var/healthpercent = (obj_integrity/max_integrity) * 100
|
||||
if(healthpercent < 50)
|
||||
heavily_damaged = TRUE
|
||||
if(can_see_clockwork)
|
||||
user << "<span class='[heavily_damaged ? "alloy":"brass"]'>[servant_message][heavily_damaged ? "!":"."]</span>"
|
||||
|
||||
|
||||
//for the ark and Ratvar
|
||||
/obj/structure/destructible/clockwork/massive
|
||||
name = "massive construct"
|
||||
desc = "A very large construction."
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
density = FALSE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/New()
|
||||
..()
|
||||
poi_list += src
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/Destroy()
|
||||
poi_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
|
||||
//the base clockwork machinery, which is not actually machines, but happens to use power
|
||||
/obj/structure/destructible/clockwork/powered
|
||||
var/obj/machinery/power/apc/target_apc
|
||||
var/active = FALSE
|
||||
var/needs_power = TRUE
|
||||
var/active_icon = null //icon_state while process() is being called
|
||||
var/inactive_icon = null //icon_state while process() isn't being called
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
var/powered = total_accessable_power()
|
||||
user << "<span class='[powered ? "brass":"alloy"]'>It has access to <b>[powered == INFINITY ? "INFINITY":"[powered]"]W</b> of power.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/Destroy()
|
||||
SSfastprocess.processing -= src
|
||||
SSobj.processing -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/process()
|
||||
var/powered = total_accessable_power()
|
||||
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/toggle(fast_process, mob/living/user)
|
||||
if(user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return FALSE
|
||||
user.visible_message("<span class='notice'>[user] [active ? "dis" : "en"]ables [src].</span>", "<span class='brass'>You [active ? "dis" : "en"]able [src].</span>")
|
||||
active = !active
|
||||
if(active)
|
||||
icon_state = active_icon
|
||||
if(fast_process)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
if(fast_process)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return INFINITY //oh yeah we've got power why'd you ask
|
||||
|
||||
var/power = 0
|
||||
power += accessable_apc_power()
|
||||
power += accessable_sigil_power()
|
||||
return power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/accessable_apc_power()
|
||||
var/power = 0
|
||||
var/area/A = get_area(src)
|
||||
var/area/targetAPCA
|
||||
for(var/obj/machinery/power/apc/APC in apcs_list)
|
||||
var/area/APCA = get_area(APC)
|
||||
if(APCA == A)
|
||||
target_apc = APC
|
||||
if(target_apc)
|
||||
targetAPCA = get_area(target_apc)
|
||||
if(targetAPCA != A)
|
||||
target_apc = null
|
||||
else if(target_apc.cell)
|
||||
var/apccharge = target_apc.cell.charge
|
||||
if(apccharge >= MIN_CLOCKCULT_POWER)
|
||||
power += apccharge
|
||||
return power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/accessable_sigil_power()
|
||||
var/power = 0
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
power += T.power_charge
|
||||
return power
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
|
||||
if(!needs_power || ratvar_awakens)
|
||||
return 1
|
||||
if(amount <= 0)
|
||||
return FALSE
|
||||
var/power = total_accessable_power()
|
||||
if(!power || power < amount)
|
||||
return FALSE
|
||||
return use_power(amount)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
|
||||
var/sigilpower = accessable_sigil_power()
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
while(sigilpower && amount >= MIN_CLOCKCULT_POWER)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= MIN_CLOCKCULT_POWER && T.modify_charge(MIN_CLOCKCULT_POWER))
|
||||
sigilpower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
var/apcpower = accessable_apc_power()
|
||||
while(apcpower >= MIN_CLOCKCULT_POWER && amount >= MIN_CLOCKCULT_POWER)
|
||||
if(target_apc.cell.use(MIN_CLOCKCULT_POWER))
|
||||
apcpower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
target_apc.update()
|
||||
target_apc.update_icon()
|
||||
else
|
||||
apcpower = 0
|
||||
if(amount)
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
|
||||
if(amount <= 0)
|
||||
return FALSE
|
||||
var/list/sigils_in_range = list()
|
||||
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
|
||||
sigils_in_range |= T
|
||||
if(!sigils_in_range.len)
|
||||
return FALSE
|
||||
while(amount >= MIN_CLOCKCULT_POWER)
|
||||
for(var/S in sigils_in_range)
|
||||
var/obj/effect/clockwork/sigil/transmission/T = S
|
||||
if(amount >= MIN_CLOCKCULT_POWER && T.modify_charge(-MIN_CLOCKCULT_POWER))
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
return TRUE
|
||||
@@ -1,928 +0,0 @@
|
||||
//////////////////////////
|
||||
// CLOCKWORK STRUCTURES //
|
||||
//////////////////////////
|
||||
|
||||
/obj/structure/destructible/clockwork
|
||||
name = "meme structure"
|
||||
desc = "Some frog or something, the fuck?"
|
||||
var/clockwork_desc //Shown to servants when they examine
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "rare_pepe"
|
||||
anchored = 1
|
||||
density = 1
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/repair_amount = 5 //how much a proselytizer can repair each cycle
|
||||
var/can_be_repaired = TRUE //if a proselytizer can repair it at all
|
||||
break_message = "<span class='warning'>The frog isn't a meme after all!</span>" //The message shown when a structure breaks
|
||||
break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 2, \
|
||||
/obj/item/clockwork/alloy_shards/small = 3) //Parts left behind when a structure breaks
|
||||
var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station
|
||||
|
||||
/obj/structure/destructible/clockwork/New()
|
||||
..()
|
||||
change_construction_value(construction_value)
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/structure/destructible/clockwork/Destroy()
|
||||
change_construction_value(-construction_value)
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/narsie_act()
|
||||
if(take_damage(rand(25, 50), BRUTE) && src) //if we still exist
|
||||
var/previouscolor = color
|
||||
color = "#960000"
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
|
||||
/obj/structure/destructible/clockwork/examine(mob/user)
|
||||
var/can_see_clockwork = is_servant_of_ratvar(user) || isobserver(user)
|
||||
if(can_see_clockwork && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
if(!(resistance_flags & INDESTRUCTIBLE))
|
||||
var/t_It = p_they(TRUE)
|
||||
var/t_is = p_are()
|
||||
var/servant_message = "[t_It] [t_is] at <b>[obj_integrity]/[max_integrity]</b> integrity"
|
||||
var/heavily_damaged = FALSE
|
||||
var/healthpercent = (obj_integrity/max_integrity) * 100
|
||||
if(healthpercent < 50)
|
||||
heavily_damaged = TRUE
|
||||
if(can_see_clockwork)
|
||||
user << "<span class='[heavily_damaged ? "alloy":"brass"]'>[servant_message][heavily_damaged ? "!":"."]</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/cache //Tinkerer's cache: Stores components for later use.
|
||||
name = "tinkerer's cache"
|
||||
desc = "A large brass spire with a flaming hole in its center."
|
||||
clockwork_desc = "A brass container capable of storing a large amount of components.\n\
|
||||
Shares components with all other caches and will gradually generate components if near a Clockwork Wall."
|
||||
icon_state = "tinkerers_cache"
|
||||
construction_value = 10
|
||||
break_message = "<span class='warning'>The cache's fire winks out before it falls in on itself!</span>"
|
||||
max_integrity = 80
|
||||
obj_integrity = 80
|
||||
var/wall_generation_cooldown
|
||||
var/turf/closed/wall/clockwork/linkedwall //if we've got a linked wall and are producing
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
clockwork_caches++
|
||||
SetLuminosity(2,1)
|
||||
for(var/i in all_clockwork_mobs)
|
||||
cache_check(i)
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/Destroy()
|
||||
clockwork_caches--
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(linkedwall)
|
||||
linkedwall.linkedcache = null
|
||||
linkedwall = null
|
||||
for(var/i in all_clockwork_mobs)
|
||||
cache_check(i)
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
for(var/I in src)
|
||||
var/atom/movable/A = I
|
||||
A.forceMove(get_turf(src)) //drop any daemons we have
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/process()
|
||||
for(var/turf/closed/wall/clockwork/C in view(4, src))
|
||||
if(!C.linkedcache && !linkedwall)
|
||||
C.linkedcache = src
|
||||
linkedwall = C
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
visible_message("<span class='warning'>[src] starts to whirr in the presence of [C]...</span>")
|
||||
break
|
||||
if(linkedwall && wall_generation_cooldown <= world.time)
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
var/component_to_generate = get_weighted_component_id()
|
||||
PoolOrNew(get_component_animation_type(component_to_generate), get_turf(src))
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1)
|
||||
visible_message("<span class='warning'>Something clunks around inside of [src]...</span>")
|
||||
break
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
if(istype(I, /obj/item/clockwork/component))
|
||||
var/obj/item/clockwork/component/C = I
|
||||
clockwork_component_cache[C.component_id]++
|
||||
user << "<span class='notice'>You add [C] to [src].</span>"
|
||||
user.drop_item()
|
||||
qdel(C)
|
||||
return 1
|
||||
else if(istype(I, /obj/item/clockwork/slab))
|
||||
var/obj/item/clockwork/slab/S = I
|
||||
for(var/i in S.stored_components)
|
||||
clockwork_component_cache[i] += S.stored_components[i]
|
||||
S.stored_components[i] = 0
|
||||
user.visible_message("<span class='notice'>[user] empties [S] into [src].</span>", "<span class='notice'>You offload your slab's components into [src].</span>")
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/attack_hand(mob/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return 0
|
||||
if(!clockwork_component_cache["replicant_alloy"])
|
||||
user << "<span class='warning'>There is no Replicant Alloy in the global component cache!</span>"
|
||||
return 0
|
||||
clockwork_component_cache["replicant_alloy"]--
|
||||
var/obj/item/clockwork/component/replicant_alloy/A = new(get_turf(src))
|
||||
user.visible_message("<span class='notice'>[user] withdraws [A] from [src].</span>", "<span class='notice'>You withdraw [A] from [src].</span>")
|
||||
user.put_in_hands(A)
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(linkedwall)
|
||||
user << "<span class='brass'>It is linked and will generate components!</span>"
|
||||
user << "<b>Stored components:</b>"
|
||||
for(var/i in clockwork_component_cache)
|
||||
user << "<span class='[get_component_span(i)]_small'><i>[get_component_name(i)][i != "replicant_alloy" ? "s":""]:</i> <b>[clockwork_component_cache[i]]</b></span>"
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
|
||||
name = "ocular warden"
|
||||
desc = "A large brass eye with tendrils trailing below it and a wide red iris."
|
||||
clockwork_desc = "A fragile turret that will deal sustained damage to any non-faithful it sees."
|
||||
icon_state = "ocular_warden"
|
||||
obj_integrity = 25
|
||||
max_integrity = 25
|
||||
construction_value = 15
|
||||
layer = HIGH_OBJ_LAYER
|
||||
break_message = "<span class='warning'>The warden's eye gives a glare of utter hate before falling dark!</span>"
|
||||
debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye = 1)
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/damage_per_tick = 2.5
|
||||
var/sight_range = 3
|
||||
var/atom/movable/target
|
||||
var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.")
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/New()
|
||||
..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='brass'>[target ? "<b>It's fixated on [target]!</b>" : "Its gaze is wandering aimlessly."]</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/process()
|
||||
var/list/validtargets = acquire_nearby_targets()
|
||||
if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned
|
||||
damage_per_tick = 10
|
||||
sight_range = 5
|
||||
if(target)
|
||||
if(!(target in validtargets))
|
||||
lose_target()
|
||||
else
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.null_rod_check())
|
||||
L.adjustFireLoss(!iscultist(L) ? damage_per_tick : damage_per_tick * 2) //Nar-Sian cultists take additional damage
|
||||
if(ratvar_awakens && L)
|
||||
L.adjust_fire_stacks(damage_per_tick)
|
||||
L.IgniteMob()
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.take_damage(damage_per_tick, BURN, "melee", 1, get_dir(src, M)) //does about half of standard damage to mechs * whatever their fire armor is
|
||||
|
||||
setDir(get_dir(get_turf(src), get_turf(target)))
|
||||
if(!target)
|
||||
if(validtargets.len)
|
||||
target = pick(validtargets)
|
||||
visible_message("<span class='warning'>[src] swivels to face [target]!</span>")
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L << "<span class='heavy_brass'>\"I SEE YOU!\"</span>\n<span class='userdanger'>[src]'s gaze [ratvar_awakens ? "melts you alive" : "burns you"]!</span>"
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.occupant << "<span class='heavy_brass'>\"I SEE YOU!\"</span>" //heeeellooooooo, person in mech.
|
||||
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
|
||||
if(prob(50))
|
||||
visible_message("<span class='notice'>[src][pick(idle_messages)]</span>")
|
||||
else
|
||||
setDir(pick(cardinal))//Random rotation
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/proc/acquire_nearby_targets()
|
||||
. = list()
|
||||
for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind
|
||||
var/obj/item/weapon/storage/book/bible/B = L.bible_check()
|
||||
if(!is_servant_of_ratvar(L) && !L.stat && L.mind && !(L.disabilities & BLIND) && !L.null_rod_check() && !B)
|
||||
. += L
|
||||
else if(B)
|
||||
if(!(B.resistance_flags & ON_FIRE))
|
||||
L << "<span class='warning'>Your [B.name] bursts into flames!</span>"
|
||||
for(var/obj/item/weapon/storage/book/bible/BI in L.GetAllContents())
|
||||
if(!(BI.resistance_flags & ON_FIRE))
|
||||
BI.fire_act()
|
||||
for(var/N in mechas_list)
|
||||
var/obj/mecha/M = N
|
||||
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant) && (M in view(sight_range, src)))
|
||||
. += M
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/proc/lose_target()
|
||||
if(!target)
|
||||
return 0
|
||||
target = null
|
||||
visible_message("<span class='warning'>[src] settles and seems almost disappointed.</span>")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/shell
|
||||
construction_value = 0
|
||||
anchored = 0
|
||||
density = 0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/mobtype = /mob/living/simple_animal/hostile/clockwork
|
||||
var/spawn_message = " is an error and you should yell at whoever spawned this shell."
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/device/mmi/posibrain/soul_vessel))
|
||||
if(!is_servant_of_ratvar(user))
|
||||
..()
|
||||
return 0
|
||||
var/obj/item/device/mmi/posibrain/soul_vessel/S = I
|
||||
if(!S.brainmob)
|
||||
user << "<span class='warning'>[S] hasn't trapped a spirit! Turn it on first.</span>"
|
||||
return 0
|
||||
if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind))
|
||||
user << "<span class='warning'>[S]'s trapped spirit appears inactive!</span>"
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] places [S] in [src], where it fuses to the shell.</span>", "<span class='brass'>You place [S] in [src], fusing it to the shell.</span>")
|
||||
var/mob/living/simple_animal/A = new mobtype(get_turf(src))
|
||||
A.visible_message("<span class='brass'>[src][spawn_message]</span>")
|
||||
S.brainmob.mind.transfer_to(A)
|
||||
user.drop_item()
|
||||
qdel(S)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/cogscarab
|
||||
name = "cogscarab shell"
|
||||
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
|
||||
icon_state = "clockdrone_shell"
|
||||
mobtype = /mob/living/simple_animal/drone/cogscarab
|
||||
spawn_message = "'s eyes blink open, glowing bright red."
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct.
|
||||
name = "fragment shell"
|
||||
desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct."
|
||||
icon_state = "anime_fragment"
|
||||
mobtype = /mob/living/simple_animal/hostile/clockwork/fragment
|
||||
spawn_message = " whirs and rises from the ground on a flickering jet of reddish fire."
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear
|
||||
name = "massive gear"
|
||||
icon_state = "wall_gear"
|
||||
climbable = TRUE
|
||||
max_integrity = 50
|
||||
obj_integrity = 50
|
||||
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
|
||||
clockwork_desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, just climb over it, or proselytize it into replicant alloy."
|
||||
break_message = "<span class='warning'>The gear breaks apart into shards of alloy!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 4, \
|
||||
/obj/item/clockwork/alloy_shards/small = 2) //slightly more debris than the default, totals 26 alloy
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/displaced
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
default_unfasten_wrench(user, I, 10)
|
||||
return 1
|
||||
else if(istype(I, /obj/item/stack/sheet/brass))
|
||||
var/obj/item/stack/sheet/brass/W = I
|
||||
if(W.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one brass sheet to do this!</span>"
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(iswallturf(T))
|
||||
user << "<span class='warning'>There is already a wall present!</span>"
|
||||
return
|
||||
if(!isfloorturf(T))
|
||||
user << "<span class='warning'>A floor must be present to build a [anchored ? "false ":""]wall!</span>"
|
||||
return
|
||||
if(locate(/obj/structure/falsewall) in T.contents)
|
||||
user << "<span class='warning'>There is already a false wall present!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start adding [W] to [src]...</span>"
|
||||
if(do_after(user, 20, target = src))
|
||||
var/brass_floor = FALSE
|
||||
if(istype(T, /turf/open/floor/clockwork)) //if the floor is already brass, costs less to make(conservation of masssssss)
|
||||
brass_floor = TRUE
|
||||
if(W.use(2 - brass_floor))
|
||||
if(anchored)
|
||||
T.ChangeTurf(/turf/closed/wall/clockwork)
|
||||
else
|
||||
T.ChangeTurf(/turf/open/floor/clockwork)
|
||||
new /obj/structure/falsewall/brass(T)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need more brass to make a [anchored ? "false ":""]wall!</span>"
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='notice'>[src] is [anchored ? "":"not "]secured to the floor.</span>"
|
||||
|
||||
///////////////////////
|
||||
// CLOCKWORK EFFECTS //
|
||||
///////////////////////
|
||||
|
||||
/obj/effect/clockwork
|
||||
name = "meme machine"
|
||||
desc = "Still don't know what it is."
|
||||
var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
icon_state = "ratvars_flame"
|
||||
anchored = 1
|
||||
density = 0
|
||||
opacity = 0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/clockwork/New()
|
||||
..()
|
||||
all_clockwork_objects += src
|
||||
|
||||
/obj/effect/clockwork/Destroy()
|
||||
all_clockwork_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/examine(mob/user)
|
||||
if((is_servant_of_ratvar(user) || isobserver(user)) && clockwork_desc)
|
||||
desc = clockwork_desc
|
||||
..()
|
||||
desc = initial(desc)
|
||||
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway //Spatial gateway: A usually one-way rift to another location.
|
||||
name = "spatial gateway"
|
||||
desc = "A gently thrumming tear in reality."
|
||||
clockwork_desc = "A gateway in reality."
|
||||
icon_state = "spatial_gateway"
|
||||
density = 1
|
||||
var/sender = TRUE //If this gateway is made for sending, not receiving
|
||||
var/both_ways = FALSE
|
||||
var/lifetime = 25 //How many deciseconds this portal will last
|
||||
var/uses = 1 //How many objects or mobs can go through the portal
|
||||
var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/New()
|
||||
..()
|
||||
spawn(1)
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(both_ways)
|
||||
clockwork_desc = "A gateway in reality. It can both send and receive objects."
|
||||
else
|
||||
clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects."
|
||||
QDEL_IN(src, lifetime)
|
||||
|
||||
//set up a gateway with another gateway
|
||||
/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way)
|
||||
if(!gatewayB || !set_duration || !uses)
|
||||
return 0
|
||||
linked_gateway = gatewayB
|
||||
gatewayB.linked_gateway = src
|
||||
if(two_way)
|
||||
both_ways = TRUE
|
||||
gatewayB.both_ways = TRUE
|
||||
else
|
||||
sender = TRUE
|
||||
gatewayB.sender = FALSE
|
||||
gatewayB.density = FALSE
|
||||
lifetime = set_duration
|
||||
gatewayB.lifetime = set_duration
|
||||
uses = set_uses
|
||||
gatewayB.uses = set_uses
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='brass'>It has [uses] uses remaining.</span>"
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user)
|
||||
if(linked_gateway)
|
||||
user.forceMove(get_turf(linked_gateway))
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user)
|
||||
if(!uses)
|
||||
return 0
|
||||
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(L.buckled || L.anchored || L.has_buckled_mobs())
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user] shoves [L] into [src]!</span>", "<span class='danger'>You shove [L] into [src]!</span>")
|
||||
user.stop_pulling()
|
||||
pass_through_gateway(L)
|
||||
return 1
|
||||
if(!user.canUseTopic(src))
|
||||
return 0
|
||||
user.visible_message("<span class='warning'>[user] climbs through [src]!</span>", "<span class='danger'>You brace yourself and step through [src]...</span>")
|
||||
pass_through_gateway(user)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/weapon/nullrod))
|
||||
user.visible_message("<span class='warning'>[user] dispels [src] with [I]!</span>", "<span class='danger'>You close [src] with [I]!</span>")
|
||||
qdel(linked_gateway)
|
||||
qdel(src)
|
||||
return 1
|
||||
if(istype(I, /obj/item/clockwork/slab))
|
||||
user << "<span class='heavy_brass'>\"I don't think you want to drop your slab into that\".\n\"If you really want to, try throwing it.\"</span>"
|
||||
return 1
|
||||
if(user.drop_item() && uses)
|
||||
user.visible_message("<span class='warning'>[user] drops [I] into [src]!</span>", "<span class='danger'>You drop [I] into [src]!</span>")
|
||||
pass_through_gateway(I)
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/ex_act(severity)
|
||||
if(severity == 1 && uses)
|
||||
uses = 0
|
||||
visible_message("<span class='warning'>[src] is disrupted!</span>")
|
||||
animate(src, alpha = 0, transform = matrix()*2, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
linked_gateway.uses = 0
|
||||
linked_gateway.visible_message("<span class='warning'>[linked_gateway] is disrupted!</span>")
|
||||
animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 10)
|
||||
QDEL_IN(linked_gateway, 10)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/Bumped(atom/A)
|
||||
..()
|
||||
if(isliving(A) || istype(A, /obj/item))
|
||||
pass_through_gateway(A)
|
||||
|
||||
/obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A)
|
||||
if(!linked_gateway)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(!sender)
|
||||
visible_message("<span class='warning'>[A] bounces off of [src]!</span>")
|
||||
return 0
|
||||
if(!uses)
|
||||
return 0
|
||||
if(isliving(A))
|
||||
var/mob/living/user = A
|
||||
user << "<span class='warning'><b>You pass through [src] and appear elsewhere!</b></span>"
|
||||
linked_gateway.visible_message("<span class='warning'>A shape appears in [linked_gateway] before emerging!</span>")
|
||||
playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
transform = matrix() * 1.5
|
||||
animate(src, transform = matrix() / 1.5, time = 10)
|
||||
linked_gateway.transform = matrix() * 1.5
|
||||
animate(linked_gateway, transform = matrix() / 1.5, time = 10)
|
||||
A.forceMove(get_turf(linked_gateway))
|
||||
uses = max(0, uses - 1)
|
||||
linked_gateway.uses = max(0, linked_gateway.uses - 1)
|
||||
spawn(10)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
qdel(linked_gateway)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/overlay
|
||||
mouse_opacity = 0
|
||||
var/atom/linked
|
||||
|
||||
/obj/effect/clockwork/overlay/examine(mob/user)
|
||||
if(linked)
|
||||
linked.examine(user)
|
||||
|
||||
/obj/effect/clockwork/overlay/ex_act()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/overlay/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
/obj/effect/clockwork/overlay/Destroy()
|
||||
if(linked)
|
||||
linked = null
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
/obj/effect/clockwork/overlay/wall
|
||||
name = "clockwork wall"
|
||||
icon = 'icons/turf/walls/clockwork_wall.dmi'
|
||||
icon_state = "clockwork_wall"
|
||||
canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
|
||||
smooth = SMOOTH_TRUE
|
||||
layer = CLOSED_TURF_LAYER
|
||||
|
||||
/obj/effect/clockwork/overlay/wall/New()
|
||||
..()
|
||||
queue_smooth_neighbors(src)
|
||||
addtimer(GLOBAL_PROC, "queue_smooth", 1, FALSE, src)
|
||||
|
||||
/obj/effect/clockwork/overlay/wall/Destroy()
|
||||
queue_smooth_neighbors(src)
|
||||
..()
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/obj/effect/clockwork/overlay/floor
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "clockwork_floor"
|
||||
layer = TURF_LAYER
|
||||
|
||||
/obj/effect/clockwork/overlay/floor/bloodcult //this is used by BLOOD CULT, it shouldn't use such a path...
|
||||
icon_state = "cult"
|
||||
|
||||
/obj/effect/clockwork/general_marker
|
||||
name = "general marker"
|
||||
desc = "Some big guy. For you."
|
||||
clockwork_desc = "One of Ratvar's generals."
|
||||
alpha = 200
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
|
||||
/obj/effect/clockwork/general_marker/New()
|
||||
..()
|
||||
animate(src, alpha = 0, time = 10)
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/clockwork/general_marker/ex_act()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/clockwork/general_marker/nezbere
|
||||
name = "Nezbere, the Brass Eidolon"
|
||||
desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you."
|
||||
clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain."
|
||||
icon = 'icons/effects/340x428.dmi'
|
||||
icon_state = "nezbere"
|
||||
pixel_x = -154
|
||||
pixel_y = -198
|
||||
|
||||
/obj/effect/clockwork/general_marker/sevtug
|
||||
name = "Sevtug, the Formless Pariah"
|
||||
desc = "A sinister cloud of purple energy. Looking at it gives you a headache."
|
||||
clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies."
|
||||
icon = 'icons/effects/211x247.dmi'
|
||||
icon_state = "sevtug"
|
||||
pixel_x = -89
|
||||
pixel_y = -107
|
||||
|
||||
/obj/effect/clockwork/general_marker/nzcrentr
|
||||
name = "Nzcrentr, the Eternal Thunderbolt"
|
||||
desc = "A terrifying spiked construct crackling with limitless energy."
|
||||
clockwork_desc = "One of Ratvar's four generals. Before becoming one of Ratvar's generals, Nzcrentr sook out any and all sentient life to slaughter it for sport. \
|
||||
Nzcrentr was coerced by Ratvar into entering a shell constructed by Nezbere, ostensibly made to grant Nzcrentr more power. In reality, the shell was made to trap and control it. \
|
||||
Nzcrentr now serves loyally, though even one of Nezbere's finest creations was not enough to totally eliminate its will."
|
||||
icon = 'icons/effects/254x361.dmi'
|
||||
icon_state = "nzcrentr"
|
||||
pixel_x = -111
|
||||
pixel_y = -164
|
||||
|
||||
/obj/effect/clockwork/general_marker/inathneq
|
||||
name = "Inath-neq, the Resonant Cogwheel"
|
||||
desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring."
|
||||
clockwork_desc = "One of Ratvar's four generals. Before her current form, Inath-neq was a powerful warrior priestess commanding the Resonant Cogs, a sect of Ratvarian warriors renowned for \
|
||||
their prowess. After a lost battle with Nar-Sian cultists, Inath-neq was struck down and stated in her dying breath, \
|
||||
\"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-neq an eternal body and \
|
||||
merged her soul with those of the Cogs slain with her on the battlefield."
|
||||
icon = 'icons/effects/187x381.dmi'
|
||||
icon_state = "inath-neq"
|
||||
pixel_x = -77
|
||||
pixel_y = -174
|
||||
|
||||
|
||||
/obj/effect/clockwork/sigil //Sigils: Rune-like markings on the ground with various effects.
|
||||
name = "sigil"
|
||||
desc = "A strange set of markings drawn on the ground."
|
||||
clockwork_desc = "A sigil of some purpose."
|
||||
icon_state = "sigil"
|
||||
layer = LOW_OBJ_LAYER
|
||||
alpha = 50
|
||||
resistance_flags = NONE
|
||||
var/affects_servants = FALSE
|
||||
var/stat_affected = CONSCIOUS
|
||||
var/resist_string = "glows blinding white" //string for when a null rod blocks its effects, "glows [resist_string]"
|
||||
|
||||
/obj/effect/clockwork/sigil/attackby(obj/item/I, mob/living/user, params)
|
||||
if(I.force && !is_servant_of_ratvar(user))
|
||||
user.visible_message("<span class='warning'>[user] scatters [src] with [I]!</span>", "<span class='danger'>You scatter [src] with [I]!</span>")
|
||||
qdel(src)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/attack_hand(mob/user)
|
||||
if(iscarbon(user) && !user.stat && (!is_servant_of_ratvar(user) || (is_servant_of_ratvar(user) && user.a_intent == "harm")))
|
||||
user.visible_message("<span class='warning'>[user] stamps out [src]!</span>", "<span class='danger'>You stomp on [src], scattering it into thousands of particles.</span>")
|
||||
qdel(src)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/ex_act(severity)
|
||||
visible_message("<span class='warning'>[src] scatters into thousands of particles.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/clockwork/sigil/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.stat <= stat_affected)
|
||||
if((!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && affects_servants)) && L.mind)
|
||||
if(L.null_rod_check())
|
||||
var/obj/item/I = L.null_rod_check()
|
||||
L.visible_message("<span class='warning'>[L]'s [I.name] [resist_string], protecting them from [src]'s effects!</span>", \
|
||||
"<span class='userdanger'>Your [I.name] [resist_string], protecting you!</span>")
|
||||
return
|
||||
sigil_effects(L)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L)
|
||||
|
||||
/obj/effect/clockwork/sigil/transgression //Sigil of Transgression: Stuns and flashes the first non-servant to walk on it. Nar-Sian cultists are damaged and knocked down for a longer stun
|
||||
name = "dull sigil"
|
||||
desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down."
|
||||
icon_state = "sigildull"
|
||||
color = "#FAE48C"
|
||||
|
||||
/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
|
||||
var/target_flashed = L.flash_act()
|
||||
for(var/mob/living/M in viewers(5, src))
|
||||
if(!is_servant_of_ratvar(M) && M != L)
|
||||
M.flash_act()
|
||||
if(iscultist(L))
|
||||
L << "<span class='heavy_brass'>\"Watch your step, wretch.\"</span>"
|
||||
L.adjustBruteLoss(10)
|
||||
L.Weaken(7)
|
||||
L.visible_message("<span class='warning'>[src] appears around [L] in a burst of light!</span>", \
|
||||
"<span class='userdanger'>[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!</span>")
|
||||
L.Stun(5)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/transgression, get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/submission //Sigil of Submission: After a short time, converts any non-servant standing on it. Knocks down and silences them for five seconds afterwards.
|
||||
name = "ominous sigil"
|
||||
desc = "A luminous golden sigil. Something about it really bothers you."
|
||||
clockwork_desc = "A sigil that will enslave the first person to cross it, provided they remain on it for seven seconds."
|
||||
icon_state = "sigilsubmission"
|
||||
color = "#FAE48C"
|
||||
alpha = 125
|
||||
stat_affected = UNCONSCIOUS
|
||||
resist_string = "glows faintly yellow"
|
||||
var/convert_time = 70
|
||||
var/glow_light = 2 //soft light
|
||||
var/glow_falloff = 1
|
||||
var/delete_on_finish = TRUE
|
||||
var/sigil_name = "Sigil of Submission"
|
||||
var/glow_type
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/New()
|
||||
..()
|
||||
SetLuminosity(glow_light,glow_falloff)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/proc/post_channel(mob/living/L)
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L)
|
||||
L.visible_message("<span class='warning'>[src] begins to glow a piercing magenta!</span>", "<span class='sevtug'>You feel something start to invade your mind...</span>")
|
||||
animate(src, color = "#AF0AAF", time = convert_time)
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/glow
|
||||
if(glow_type)
|
||||
glow = PoolOrNew(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))
|
||||
I++
|
||||
sleep(1)
|
||||
if(get_turf(L) != get_turf(src))
|
||||
if(glow)
|
||||
qdel(glow)
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 0
|
||||
post_channel(L)
|
||||
if(is_eligible_servant(L))
|
||||
L << "<span class='heavy_brass'>\"You belong to me now.\"</span>"
|
||||
add_servant_of_ratvar(L)
|
||||
L.Weaken(3) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with
|
||||
L.Stun(3)
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.silent += 5
|
||||
var/message = "[sigil_name] in [get_area(src)] <span class='sevtug'>[is_servant_of_ratvar(L) ? "successfully converted" : "failed to convert"]</span>"
|
||||
for(var/M in mob_list)
|
||||
if(isobserver(M))
|
||||
var/link = FOLLOW_LINK(M, L)
|
||||
M << "[link] <span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
else if(is_servant_of_ratvar(M))
|
||||
if(M == L)
|
||||
M << "<span class='heavy_brass'>[message] you!</span>"
|
||||
else
|
||||
M << "<span class='heavy_brass'>[message] [L.real_name]!</span>"
|
||||
if(delete_on_finish)
|
||||
qdel(src)
|
||||
else
|
||||
animate(src, color = initial(color), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession //Sigil of Accession: After a short time, converts any non-servant standing on it though implants. Knocks down and silences them for five seconds afterwards.
|
||||
name = "terrifying sigil"
|
||||
desc = "A luminous brassy sigil. Something about it makes you want to flee."
|
||||
clockwork_desc = "A sigil that will enslave any person who crosses it, provided they remain on it for seven seconds. \n\
|
||||
It can convert a mindshielded target once before disppearing, but can convert any number of non-implanted targets."
|
||||
icon_state = "sigiltransgression"
|
||||
color = "#A97F1B"
|
||||
alpha = 200
|
||||
glow_light = 4 //bright light
|
||||
glow_falloff = 3
|
||||
delete_on_finish = FALSE
|
||||
sigil_name = "Sigil of Accession"
|
||||
glow_type = /obj/effect/overlay/temp/ratvar/sigil/accession
|
||||
resist_string = "glows bright orange"
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L)
|
||||
if(L.isloyal())
|
||||
var/mob/living/carbon/C = L
|
||||
delete_on_finish = TRUE
|
||||
C.visible_message("<span class='warning'>[C] visibly trembles!</span>", \
|
||||
"<span class='sevtug'>[text2ratvar("You will be mine and his. This puny trinket will not stop me.")]</span>")
|
||||
for(var/obj/item/weapon/implant/mindshield/M in C.implants)
|
||||
qdel(M)
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission
|
||||
name = "suspicious sigil"
|
||||
desc = "A glowing orange sigil. The air around it feels staticky."
|
||||
clockwork_desc = "A sigil that will serve as a battery for clockwork structures. Use Volt Void while standing on it to charge it."
|
||||
icon_state = "sigiltransmission"
|
||||
color = "#EC8A2D"
|
||||
alpha = 50
|
||||
resist_string = "glows faintly"
|
||||
var/power_charge = REPLICANT_ALLOY_POWER //starts with REPLICANT_ALLOY_POWER by default
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/ex_act(severity)
|
||||
if(severity == 3)
|
||||
modify_charge(-500)
|
||||
visible_message("<span class='warning'>[src] flares a brilliant orange!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[power_charge ? "brass":"alloy"]'>It is storing <b>[power_charge]W</b> of power.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L)
|
||||
if(power_charge)
|
||||
L << "<span class='brass'>You feel a slight, static shock.</span>"
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/New()
|
||||
..()
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount)
|
||||
if(power_charge - amount < 0)
|
||||
return 0
|
||||
power_charge -= amount
|
||||
alpha = min(initial(alpha) + power_charge*0.02, 255)
|
||||
return 1
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality
|
||||
name = "comforting sigil"
|
||||
desc = "A faint blue sigil. Looking at it makes you feel protected."
|
||||
clockwork_desc = "A sigil that will drain non-servants that remain on it. Servants that remain on it will be healed if it has any vitality drained."
|
||||
icon_state = "sigilvitality"
|
||||
color = "#123456"
|
||||
alpha = 75
|
||||
affects_servants = TRUE
|
||||
stat_affected = DEAD
|
||||
resist_string = "glows shimmering yellow"
|
||||
var/vitality = 0
|
||||
var/base_revive_cost = 20
|
||||
var/sigil_active = FALSE
|
||||
var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='[vitality ? "inathneq_small":"alloy"]'>It is storing <b>[ratvar_awakens ? "INFINITE":"[vitality]"]</b> units of vitality.</span>"
|
||||
user << "<span class='inathneq_small'>It requires at least <b>[base_revive_cost]</b> units of vitality to revive dead servants, in addition to any damage the servant has.</span>"
|
||||
|
||||
/obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L)
|
||||
if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active)
|
||||
return 0
|
||||
visible_message("<span class='warning'>[src] begins to glow bright blue!</span>")
|
||||
animate(src, alpha = 255, time = 10)
|
||||
sleep(10)
|
||||
sigil_active = TRUE
|
||||
//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) && vitality)) && get_turf(L) == get_turf(src))
|
||||
if(animation_number >= 4)
|
||||
PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src))
|
||||
animation_number = 0
|
||||
animation_number++
|
||||
if(!is_servant_of_ratvar(L))
|
||||
var/vitality_drained = 0
|
||||
if(L.stat == DEAD)
|
||||
vitality_drained = L.maxHealth
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/vitality/V = PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src))
|
||||
animate(V, alpha = 0, transform = matrix()*2, time = 8)
|
||||
playsound(L, 'sound/magic/WandODeath.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] collapses in on [L.p_them()]self as [src] flares bright blue!</span>")
|
||||
L << "<span class='inathneq_large'>\"[text2ratvar("Your life will not be wasted.")]\"</span>"
|
||||
for(var/obj/item/W in L)
|
||||
if(!L.unEquip(W))
|
||||
qdel(W)
|
||||
L.dust()
|
||||
else
|
||||
vitality_drained = L.adjustToxLoss(1.5)
|
||||
if(vitality_drained)
|
||||
vitality += vitality_drained
|
||||
else
|
||||
break
|
||||
else
|
||||
var/clone_to_heal = L.getCloneLoss()
|
||||
var/tox_to_heal = L.getToxLoss()
|
||||
var/burn_to_heal = L.getFireLoss()
|
||||
var/brute_to_heal = L.getBruteLoss()
|
||||
var/oxy_to_heal = L.getOxyLoss()
|
||||
var/total_damage = clone_to_heal + tox_to_heal + burn_to_heal + brute_to_heal + oxy_to_heal
|
||||
if(L.stat == DEAD)
|
||||
var/revival_cost = base_revive_cost + total_damage - oxy_to_heal //ignores oxygen damage
|
||||
if(ratvar_awakens)
|
||||
revival_cost = 0
|
||||
var/mob/dead/observer/ghost = L.get_ghost(TRUE)
|
||||
if(ghost)
|
||||
if(vitality >= revival_cost)
|
||||
ghost.reenter_corpse()
|
||||
L.revive(1, 1)
|
||||
playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] suddenly gets back up, [L.p_their()] mouth dripping blue ichor!</span>", \
|
||||
"<span class='inathneq'>\"[text2ratvar("You will be okay, child.")]\"</span>")
|
||||
vitality -= revival_cost
|
||||
break
|
||||
else
|
||||
break
|
||||
if(!total_damage)
|
||||
break
|
||||
var/vitality_for_cycle = min(vitality, 3)
|
||||
var/vitality_used = 0
|
||||
if(ratvar_awakens)
|
||||
vitality_for_cycle = 3
|
||||
|
||||
if(clone_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, clone_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustCloneLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(tox_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, tox_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustToxLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(burn_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, burn_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustFireLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(brute_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, brute_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustBruteLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(oxy_to_heal && vitality_for_cycle)
|
||||
var/healing = min(vitality_for_cycle, oxy_to_heal)
|
||||
vitality_for_cycle -= healing
|
||||
L.adjustOxyLoss(-healing)
|
||||
vitality_used += healing
|
||||
|
||||
if(!ratvar_awakens)
|
||||
vitality -= vitality_used
|
||||
sleep(2)
|
||||
|
||||
animation_number = initial(animation_number)
|
||||
sigil_active = FALSE
|
||||
animate(src, alpha = initial(alpha), time = 20)
|
||||
visible_message("<span class='warning'>[src] slowly stops glowing!</span>")
|
||||
+24
-191
@@ -1,21 +1,3 @@
|
||||
/obj/structure/destructible/clockwork/massive //For objects that are typically very large
|
||||
name = "massive construct"
|
||||
desc = "A very large construction."
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
density = FALSE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/New()
|
||||
..()
|
||||
poi_list += src
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/Destroy()
|
||||
poi_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/singularity_pull(S, current_size)
|
||||
return
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway //The gateway to Reebe, from which Ratvar emerges
|
||||
name = "Gateway to the Celestial Derelict"
|
||||
desc = "A massive, thrumming rip in spacetime."
|
||||
@@ -88,6 +70,28 @@
|
||||
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
|
||||
. = "[round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE * 0.5), 0), 1)][s_on_time ? "S":""]"
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/examine(mob/user)
|
||||
icon_state = "spatial_gateway" //cheat wildly by pretending to have an icon
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='big'><b>Seconds until [ratvar_portal ? "Ratvar's arrival":"Proselytization"]:</b> [get_arrival_text(TRUE)]</span>"
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='heavy_brass'>It's still opening.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='heavy_brass'>It's reached the Celestial Derelict and is drawing power from it.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='heavy_brass'>[ratvar_portal ? "Ratvar is coming through the gateway":"The gateway is glowing with massed power"]!</span>"
|
||||
else
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='warning'>It's a swirling mass of blackness.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='warning'>It seems to be leading somewhere.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='boldwarning'>[ratvar_portal ? "Something is coming through":"It's glowing brightly"]!</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
|
||||
if(!progress_in_seconds || prob(7))
|
||||
for(var/M in mob_list)
|
||||
@@ -154,181 +158,10 @@
|
||||
if(M.stat == CONSCIOUS)
|
||||
clockwork_say(M, text2ratvar(pick("Purge all untruths and honor Engine!", "All glory to Engine's light!", "Engine's power is unmatched!")))
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/examine(mob/user)
|
||||
icon_state = "spatial_gateway" //cheat wildly by pretending to have an icon
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='big'><b>Seconds until [ratvar_portal ? "Ratvar's arrival":"Proselytization"]:</b> [get_arrival_text(TRUE)]</span>"
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='heavy_brass'>It's still opening.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='heavy_brass'>It's reached the Celestial Derelict and is drawing power from it.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='heavy_brass'>[ratvar_portal ? "Ratvar is coming through the gateway":"The gateway is glowing with massed power"]!</span>"
|
||||
else
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
user << "<span class='warning'>It's a swirling mass of blackness.</span>"
|
||||
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
|
||||
user << "<span class='warning'>It seems to be leading somewhere.</span>"
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
user << "<span class='boldwarning'>[ratvar_portal ? "Something is coming through":"It's glowing brightly"]!</span>"
|
||||
|
||||
/obj/effect/clockwork/overlay/gateway_glow //the actual appearance of the Gateway to the Celestial Derelict; an object so the edges of the gate can be clicked through.
|
||||
//the actual appearance of the Gateway to the Celestial Derelict; an object so the edges of the gate can be clicked through.
|
||||
/obj/effect/clockwork/overlay/gateway_glow
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "clockwork_gateway_charging"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
layer = MASSIVE_OBJ_LAYER
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar
|
||||
name = "Ratvar, the Clockwork Justiciar"
|
||||
desc = "<span class='userdanger'>What is what is what are what real what is all a lie all a lie it's all a lie why how can what is</span>"
|
||||
clockwork_desc = "<span class='large_brass'><b><i>Ratvar, the Clockwork Justiciar, your master eternal.</i></b></span>"
|
||||
icon = 'icons/effects/512x512.dmi'
|
||||
icon_state = "ratvar"
|
||||
pixel_x = -235
|
||||
pixel_y = -248
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
appearance_flags = 0
|
||||
var/atom/prey //Whatever Ratvar is chasing
|
||||
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
|
||||
var/proselytize_range = 10
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/New()
|
||||
..()
|
||||
ratvar_awakens++
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
START_PROCESSING(SSobj, src)
|
||||
world << "<span class='ratvar'>\"[text2ratvar("ONCE AGAIN MY LIGHT SHALL SHINE ACROSS THIS PATHETIC REALM")]!!\"</span>"
|
||||
world << 'sound/effects/ratvar_reveal.ogg'
|
||||
var/image/alert_overlay = image('icons/effects/clockwork_effects.dmi', "ratvar_alert")
|
||||
var/area/A = get_area(src)
|
||||
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
|
||||
addtimer(SSshuttle.emergency, "request", 50, FALSE, null, 0.1)
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
|
||||
ratvar_awakens--
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
world << "<span class='heavy_brass'><font size=6>\"NO! I will not... be...</font> <font size=5>banished...</font> <font size=4>again...\"</font></span>"
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
|
||||
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
|
||||
if(alertresult == "No" || !O)
|
||||
return 0
|
||||
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
|
||||
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
|
||||
R.key = O.key
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
|
||||
var/turf/T = get_turf(A)
|
||||
forceMove(T)
|
||||
T.ratvar_act()
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
|
||||
return clashing
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/process()
|
||||
if(clashing) //I'm a bit occupied right now, thanks
|
||||
return
|
||||
for(var/I in circlerangeturfs(src, proselytize_range))
|
||||
var/turf/T = I
|
||||
T.ratvar_act()
|
||||
for(var/I in circleviewturfs(src, round(proselytize_range * 0.5)))
|
||||
var/turf/T = I
|
||||
T.ratvar_act(1)
|
||||
var/dir_to_step_in = pick(cardinal)
|
||||
if(!prey)
|
||||
for(var/obj/singularity/narsie/N in poi_list)
|
||||
if(N.z == z)
|
||||
prey = N
|
||||
break
|
||||
if(!prey) //In case there's a Nar-Sie
|
||||
var/list/meals = list()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z == z && !is_servant_of_ratvar(L) && L.mind)
|
||||
meals += L
|
||||
if(meals.len)
|
||||
prey = pick(meals)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"You will do.\"</font></span>\n\
|
||||
<span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>"
|
||||
prey << 'sound/effects/ratvar_reveal.ogg'
|
||||
else
|
||||
if(prob(10) || is_servant_of_ratvar(prey) || prey.z != z)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\
|
||||
<span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>"
|
||||
prey = null
|
||||
else
|
||||
dir_to_step_in = get_dir(src, prey) //Unlike Nar-Sie, Ratvar ruthlessly chases down his target
|
||||
step(src, dir_to_step_in)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/narsie_act()
|
||||
if(clashing)
|
||||
return 0
|
||||
clashing = TRUE
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("BLOOD GOD!!!", "NAR-SIE!!!", "AT LAST, YOUR TIME HAS COME!")]\"</font></span>"
|
||||
world << "<span class='cult'><font size=5>\"<b>Ratvar?! How?!</b>\"</font></span>"
|
||||
for(var/obj/singularity/narsie/N in range(15, src))
|
||||
if(N.clashing)
|
||||
continue
|
||||
N.clashing = TRUE
|
||||
clash_of_the_titans(N) //IT'S TIME FOR THE BATTLE OF THE AGES
|
||||
break
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
|
||||
var/winner = "Undeclared"
|
||||
var/base_victory_chance = 1
|
||||
while(TRUE)
|
||||
world << 'sound/magic/clockwork/ratvar_attack.ogg'
|
||||
sleep(5.2)
|
||||
for(var/mob/M in mob_list)
|
||||
flash_color(M, flash_color="#966400", flash_time=1)
|
||||
shake_camera(M, 4, 3)
|
||||
var/ratvar_chance = min(ticker.mode.servants_of_ratvar.len, 50)
|
||||
var/narsie_chance = ticker.mode.cult.len
|
||||
for(var/mob/living/simple_animal/hostile/construct/harvester/C in player_list)
|
||||
narsie_chance++
|
||||
ratvar_chance = rand(base_victory_chance, ratvar_chance)
|
||||
narsie_chance = rand(base_victory_chance, min(narsie_chance, 50))
|
||||
if(ratvar_chance > narsie_chance)
|
||||
winner = "Ratvar"
|
||||
break
|
||||
sleep(rand(2,5))
|
||||
world << 'sound/magic/clockwork/narsie_attack.ogg'
|
||||
sleep(7.4)
|
||||
for(var/mob/M in mob_list)
|
||||
flash_color(M, flash_color="#C80000", flash_time=1)
|
||||
shake_camera(M, 4, 3)
|
||||
if(narsie_chance > ratvar_chance)
|
||||
winner = "Nar-Sie"
|
||||
break
|
||||
base_victory_chance *= 2 //The clash has a higher chance of resolving each time both gods attack one another
|
||||
switch(winner)
|
||||
if("Ratvar")
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("DIE! DIE! DIE!", "FILTH!!!", "SUFFER!!!", text2ratvar("ROT FOR CENTURIES AS I HAVE!!"))]\"</font></span>" //nar-sie get out
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"</b></font></span>"
|
||||
world << 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
world << 'sound/magic/demon_dies.ogg'
|
||||
clashing = FALSE
|
||||
qdel(narsie)
|
||||
return 1
|
||||
if("Nar-Sie")
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>" //Broken English
|
||||
world << 'sound/magic/demon_attack1.ogg'
|
||||
world << 'sound/magic/clockwork/anima_fragment_death.ogg'
|
||||
narsie.clashing = FALSE
|
||||
qdel(src)
|
||||
return 1
|
||||
@@ -0,0 +1,47 @@
|
||||
//Useless on their own, these shells can create powerful constructs.
|
||||
/obj/structure/destructible/clockwork/shell
|
||||
construction_value = 0
|
||||
anchored = 0
|
||||
density = 0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/mobtype = /mob/living/simple_animal/hostile/clockwork
|
||||
var/spawn_message = " is an error and you should yell at whoever spawned this shell."
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/device/mmi/posibrain/soul_vessel))
|
||||
if(!is_servant_of_ratvar(user))
|
||||
..()
|
||||
return 0
|
||||
var/obj/item/device/mmi/posibrain/soul_vessel/S = I
|
||||
if(!S.brainmob)
|
||||
user << "<span class='warning'>[S] hasn't trapped a spirit! Turn it on first.</span>"
|
||||
return 0
|
||||
if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind))
|
||||
user << "<span class='warning'>[S]'s trapped spirit appears inactive!</span>"
|
||||
return 0
|
||||
user.visible_message("<span class='notice'>[user] places [S] in [src], where it fuses to the shell.</span>", "<span class='brass'>You place [S] in [src], fusing it to the shell.</span>")
|
||||
var/mob/living/simple_animal/A = new mobtype(get_turf(src))
|
||||
A.visible_message("<span class='brass'>[src][spawn_message]</span>")
|
||||
S.brainmob.mind.transfer_to(A)
|
||||
user.drop_item()
|
||||
qdel(S)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/cogscarab
|
||||
name = "cogscarab shell"
|
||||
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
|
||||
icon_state = "clockdrone_shell"
|
||||
mobtype = /mob/living/simple_animal/drone/cogscarab
|
||||
spawn_message = "'s eyes blink open, glowing bright red."
|
||||
|
||||
/obj/structure/destructible/clockwork/shell/fragment
|
||||
name = "fragment shell"
|
||||
desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power."
|
||||
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct."
|
||||
icon_state = "anime_fragment"
|
||||
mobtype = /mob/living/simple_animal/hostile/clockwork/fragment
|
||||
spawn_message = " whirs and rises from the ground on a flickering jet of reddish fire."
|
||||
@@ -0,0 +1,69 @@
|
||||
//Clockwork Obelisk: Can broadcast a message at a small power cost or outright open a spatial gateway at a massive power cost.
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk
|
||||
name = "clockwork obelisk"
|
||||
desc = "A large brass obelisk hanging in midair."
|
||||
clockwork_desc = "A powerful obelisk that can send a message to all servants or open a gateway to a target servant or clockwork obelisk."
|
||||
icon_state = "obelisk_inactive"
|
||||
active_icon = "obelisk"
|
||||
inactive_icon = "obelisk_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 150
|
||||
obj_integrity = 150
|
||||
break_message = "<span class='warning'>The obelisk falls to the ground, undamaged!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
|
||||
/obj/item/clockwork/component/hierophant_ansible/obelisk = 1)
|
||||
var/hierophant_cost = MIN_CLOCKCULT_POWER //how much it costs to broadcast with large text
|
||||
var/gateway_cost = 2000 //how much it costs to open a gateway
|
||||
var/gateway_active = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/New()
|
||||
..()
|
||||
toggle(1)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nzcrentr_small'>It requires <b>[hierophant_cost]W</b> to broadcast over the Hierophant Network, and <b>[gateway_cost]W</b> to open a Spatial Gateway.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/process()
|
||||
if(locate(/obj/effect/clockwork/spatial_gateway) in loc)
|
||||
icon_state = active_icon
|
||||
density = 0
|
||||
gateway_active = TRUE
|
||||
else
|
||||
icon_state = inactive_icon
|
||||
density = 1
|
||||
gateway_active = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
|
||||
if(!is_servant_of_ratvar(user) || !total_accessable_power() >= hierophant_cost)
|
||||
user << "<span class='warning'>You place your hand on the obelisk, but it doesn't react.</span>"
|
||||
return
|
||||
var/choice = alert(user,"You place your hand on the obelisk...",,"Hierophant Broadcast","Spatial Gateway","Cancel")
|
||||
switch(choice)
|
||||
if("Hierophant Broadcast")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "")
|
||||
if(!input || !user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
|
||||
return
|
||||
if(!try_use_power(hierophant_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to broadcast!</span>"
|
||||
return
|
||||
clockwork_say(user, text2ratvar("Hierophant Broadcast, activate!"))
|
||||
titled_hierophant_message(user, input, "big_brass", "large_brass")
|
||||
if("Spatial Gateway")
|
||||
if(gateway_active)
|
||||
user << "<span class='warning'>The obelisk is already sustaining a gateway!</span>"
|
||||
return
|
||||
if(!try_use_power(gateway_cost))
|
||||
user << "<span class='warning'>The obelisk lacks the power to open a gateway!</span>"
|
||||
return
|
||||
if(procure_gateway(user, 100, 5, 1) && !gateway_active)
|
||||
clockwork_say(user, text2ratvar("Spatial Gateway, activate!"))
|
||||
else
|
||||
return_power(gateway_cost)
|
||||
@@ -0,0 +1,96 @@
|
||||
//Interdiction Lens: A powerful artifact that constantly disrupts electronics and drains power but, if it fails to find something to disrupt, turns off.
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens
|
||||
name = "interdiction lens"
|
||||
desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
|
||||
clockwork_desc = "A powerful totem that constantly drains nearby electronics and funnels the power drained into nearby Sigils of Transmission."
|
||||
icon_state = "interdiction_lens"
|
||||
construction_value = 25
|
||||
active_icon = "interdiction_lens_active"
|
||||
inactive_icon = "interdiction_lens"
|
||||
break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
|
||||
break_sound = 'sound/effects/Glassbr3.ogg'
|
||||
var/recharging = 0 //world.time when the lens was last used
|
||||
var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
|
||||
var/disabled = FALSE //if it's actually usable
|
||||
var/interdiction_range = 14 //how large an area it drains and disables in
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='[recharging > world.time ? "nezbere_small":"brass"]'>Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
|
||||
: "vibrates in place and thrums with power"].</span>"
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='nezbere_small'>If it fails to drain any electronics, it will disable itself for <b>[round(recharge_time/600, 1)]</b> minutes.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
|
||||
..()
|
||||
if(active)
|
||||
SetLuminosity(4,2)
|
||||
else
|
||||
SetLuminosity(0)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(disabled)
|
||||
user << "<span class='warning'>As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back.</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/interdiction_lens/process()
|
||||
if(recharging > world.time)
|
||||
return
|
||||
if(disabled)
|
||||
visible_message("<span class='warning'>The writhing tendrils return to the gemstone, which begins to glow with power!</span>")
|
||||
flick("interdiction_lens_recharged", src)
|
||||
disabled = FALSE
|
||||
toggle(0)
|
||||
else
|
||||
var/successfulprocess = FALSE
|
||||
var/power_drained = 0
|
||||
var/list/atoms_to_test = list()
|
||||
for(var/A in spiral_range_turfs(interdiction_range, src))
|
||||
var/turf/T = A
|
||||
for(var/M in T)
|
||||
atoms_to_test |= M
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
for(var/M in atoms_to_test)
|
||||
var/atom/movable/A = M
|
||||
if(!A || qdeleted(A))
|
||||
continue
|
||||
power_drained += A.power_drain(TRUE)
|
||||
|
||||
if(istype(A, /obj/machinery/camera))
|
||||
var/obj/machinery/camera/C = A
|
||||
if(C.isEmpProof() || !C.status)
|
||||
continue
|
||||
successfulprocess = TRUE
|
||||
if(C.emped)
|
||||
continue
|
||||
C.emp_act(1)
|
||||
else if(istype(A, /obj/item/device/radio))
|
||||
var/obj/item/device/radio/O = A
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
O.emp_act(1)
|
||||
else if((isliving(A) && !is_servant_of_ratvar(A)) || istype(A, /obj/structure/closet) || istype(A, /obj/item/weapon/storage)) //other things may have radios in them but we don't care
|
||||
for(var/obj/item/device/radio/O in A.GetAllContents())
|
||||
successfulprocess = TRUE
|
||||
if(O.emped || !O.on)
|
||||
continue
|
||||
O.emp_act(1)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
if(power_drained && power_drained >= MIN_CLOCKCULT_POWER && return_power(power_drained))
|
||||
successfulprocess = TRUE
|
||||
playsound(src, 'sound/items/PSHOOM.ogg', 50, 1, interdiction_range-7, 1)
|
||||
|
||||
if(!successfulprocess)
|
||||
visible_message("<span class='warning'>The gemstone suddenly turns horribly dark, writhing tendrils covering it!</span>")
|
||||
recharging = world.time + recharge_time
|
||||
flick("interdiction_lens_discharged", src)
|
||||
icon_state = "interdiction_lens_inactive"
|
||||
SetLuminosity(2,1)
|
||||
disabled = TRUE
|
||||
@@ -0,0 +1,135 @@
|
||||
//Mania Motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor
|
||||
name = "mania motor"
|
||||
desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
|
||||
clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
|
||||
icon_state = "mania_motor_inactive"
|
||||
active_icon = "mania_motor"
|
||||
inactive_icon = "mania_motor_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 80
|
||||
obj_integrity = 80
|
||||
break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/small = 3, \
|
||||
/obj/item/clockwork/component/guvax_capacitor/antennae = 1)
|
||||
var/mania_cost = 200
|
||||
var/convert_attempt_cost = 200
|
||||
var/convert_cost = 200
|
||||
|
||||
var/mania_messages = list("\"Go nuts.\"", "\"Take a crack at crazy.\"", "\"Make a bid for insanity.\"", "\"Get kooky.\"", "\"Move towards mania.\"", "\"Become bewildered.\"", "\"Wax wild.\"", \
|
||||
"\"Go round the bend.\"", "\"Land in lunacy.\"", "\"Try dementia.\"", "\"Strive to get a screw loose.\"")
|
||||
var/compel_messages = list("\"Come closer.\"", "\"Approach the transmitter.\"", "\"Touch the antennae.\"", "\"I always have to deal with idiots. Move towards the mania motor.\"", \
|
||||
"\"Advance forward and place your head between the antennae - that's all it's good for.\"", "\"If you were smarter, you'd be over here already.\"", "\"Move FORWARD, you fool.\"")
|
||||
var/convert_messages = list("\"You won't do. Go to sleep while I tell these nitwits how to convert you.\"", "\"You are insufficient. I must instruct these idiots in the art of conversion.\"", \
|
||||
"\"Oh of course, someone we can't convert. These servants are fools.\"", "\"How hard is it to use a Sigil, anyway? All it takes is dragging someone onto it.\"", \
|
||||
"\"How do they fail to use a Sigil of Accession, anyway?\"", "\"Why is it that all servants are this inept?\"", "\"It's quite likely you'll be stuck here for a while.\"")
|
||||
var/close_messages = list("\"Well, you can't reach the motor from THERE, you moron.\"", "\"Interesting location. I'd prefer if you went somewhere you could ACTUALLY TOUCH THE ANTENNAE!\"", \
|
||||
"\"Amazing. You somehow managed to wedge yourself somewhere you can't actually reach the motor from.\"", "\"Such a show of idiocy is unparalleled. Perhaps I should put you on display?\"", \
|
||||
"\"Did you do this on purpose? I can't imagine you doing so accidentally. Oh, wait, I can.\"", "\"How is it that such smart creatures can still do something AS STUPID AS THIS!\"")
|
||||
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='sevtug_small'>It requires <b>[mania_cost]W</b> to run, and <b>[convert_attempt_cost + convert_cost]W</b> to convert humans adjecent to it.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/process()
|
||||
if(try_use_power(mania_cost))
|
||||
var/turf/T = get_turf(src)
|
||||
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
|
||||
for(var/mob/living/carbon/human/H in view(1, src))
|
||||
if(is_servant_of_ratvar(H))
|
||||
continue
|
||||
if(H.Adjacent(src) && try_use_power(convert_attempt_cost))
|
||||
if(is_eligible_servant(H) && try_use_power(convert_cost))
|
||||
H << "<span class='sevtug'>\"[text2ratvar("You are mine and his, now.")]\"</span>"
|
||||
H.playsound_local(T, hum, 80, 1)
|
||||
add_servant_of_ratvar(H)
|
||||
else if(!H.stat)
|
||||
if(H.getBrainLoss() >= 100)
|
||||
H.Paralyse(5)
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(convert_messages))]</span>"
|
||||
else
|
||||
H.adjustBrainLoss(100)
|
||||
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
for(var/mob/living/carbon/human/H in range(10, src))
|
||||
if(is_servant_of_ratvar(H))
|
||||
if(H.getBrainLoss() || H.hallucination || H.druggy || H.dizziness || H.confused)
|
||||
H.adjustBrainLoss(-H.getBrainLoss()) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
|
||||
H.hallucination = 0
|
||||
H.adjust_drugginess(-H.druggy)
|
||||
H.dizziness = 0
|
||||
H.confused = 0
|
||||
else if(!H.null_rod_check() && H.stat == CONSCIOUS)
|
||||
var/distance = get_dist(T, get_turf(H))
|
||||
var/falloff_distance = min((110) - distance * 10, 80)
|
||||
var/sound_distance = falloff_distance * 0.5
|
||||
var/targetbrainloss = H.getBrainLoss()
|
||||
if(distance >= 4 && prob(falloff_distance * 0.5))
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
H.playsound_local(T, hum, sound_distance, 1)
|
||||
switch(distance)
|
||||
if(2 to 3)
|
||||
if(prob(falloff_distance * 0.5))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
else
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(compel_messages))]</span>"
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(50 - targetbrainloss) //got too close had brain eaten
|
||||
H.adjust_drugginess(Clamp(7, 0, 100 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 7, 100)
|
||||
H.dizziness = min(H.dizziness + 3, 45)
|
||||
H.confused = min(H.confused + 3, 45)
|
||||
if(4 to 5)
|
||||
if(targetbrainloss <= 50)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(5, 0, 80 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 5, 80)
|
||||
H.dizziness = min(H.dizziness + 2, 30)
|
||||
H.confused = min(H.confused + 2, 30)
|
||||
if(6 to 7)
|
||||
if(targetbrainloss <= 30)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(2, 0, 60 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 60)
|
||||
H.dizziness = min(H.dizziness + 2, 15)
|
||||
H.confused = min(H.confused + 2, 15)
|
||||
if(8 to 9)
|
||||
if(targetbrainloss <= 10)
|
||||
H.adjustBrainLoss(1)
|
||||
H.adjust_drugginess(Clamp(2, 0, 40 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 40)
|
||||
if(10 to INFINITY)
|
||||
H.adjust_drugginess(Clamp(2, 0, 20 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 2, 20)
|
||||
else //if it's a distance of 1 and they can't see it/aren't adjacent or they're on top of it(how'd they get on top of it and still trigger this???)
|
||||
if(prob(falloff_distance * 0.5))
|
||||
if(prob(falloff_distance))
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(compel_messages))]</span>"
|
||||
else if(prob(falloff_distance * 0.5))
|
||||
H << "<span class='sevtug'>[text2ratvar(pick(close_messages))]</span>"
|
||||
else
|
||||
H << "<span class='sevtug_small'>[text2ratvar(pick(mania_messages))]</span>"
|
||||
if(targetbrainloss <= 99)
|
||||
H.adjustBrainLoss(99 - targetbrainloss)
|
||||
H.adjust_drugginess(Clamp(10, 0, 150 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + 10, 150)
|
||||
H.dizziness = min(H.dizziness + 5, 60)
|
||||
H.confused = min(H.confused + 5, 60)
|
||||
|
||||
else
|
||||
visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
|
||||
playsound(src, 'sound/effects/screech.ogg', 40, 1)
|
||||
toggle(0)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE) && is_servant_of_ratvar(user))
|
||||
if(!total_accessable_power() >= mania_cost)
|
||||
user << "<span class='warning'>[src] needs more power to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
@@ -0,0 +1,105 @@
|
||||
//Mending Motor: A prism that consumes replicant alloy or power to repair nearby mechanical servants at a quick rate.
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor
|
||||
name = "mending motor"
|
||||
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
|
||||
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
|
||||
icon_state = "mending_motor_inactive"
|
||||
active_icon = "mending_motor"
|
||||
inactive_icon = "mending_motor_inactive"
|
||||
construction_value = 20
|
||||
max_integrity = 125
|
||||
obj_integrity = 125
|
||||
break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/small = 5, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 1, \
|
||||
/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/component/vanguard_cogwheel = 1)
|
||||
var/stored_alloy = 0
|
||||
var/max_alloy = REPLICANT_ALLOY_POWER * 10
|
||||
var/mob_cost = 200
|
||||
var/structure_cost = 250
|
||||
var/cyborg_cost = 300
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/prefilled
|
||||
stored_alloy = REPLICANT_ALLOY_POWER //starts with 1 replicant alloy's worth of power
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/total_accessable_power()
|
||||
. = ..()
|
||||
if(. != INFINITY)
|
||||
. += accessable_alloy_power()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/proc/accessable_alloy_power()
|
||||
return stored_alloy
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/use_power(amount)
|
||||
var/alloypower = accessable_alloy_power()
|
||||
while(alloypower >= MIN_CLOCKCULT_POWER && amount >= MIN_CLOCKCULT_POWER)
|
||||
stored_alloy -= MIN_CLOCKCULT_POWER
|
||||
alloypower -= MIN_CLOCKCULT_POWER
|
||||
amount -= MIN_CLOCKCULT_POWER
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
user << "<span class='alloy'>It contains <b>[stored_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]/[max_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]</b> units of liquified alloy, \
|
||||
which is equivalent to <b>[stored_alloy]W/[max_alloy]W</b> of power.</span>"
|
||||
user << "<span class='inathneq_small'>It requires <b>[mob_cost]W</b> to heal clockwork mobs, <b>[structure_cost]W</b> for clockwork structures, and <b>[cyborg_cost]W</b> for cyborgs.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/process()
|
||||
if(..() < mob_cost)
|
||||
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
|
||||
toggle()
|
||||
return
|
||||
for(var/atom/movable/M in range(5, src))
|
||||
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
var/mob/living/simple_animal/hostile/clockwork/W = M
|
||||
var/fatigued = FALSE
|
||||
if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder))
|
||||
var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
|
||||
if(E.fatigue)
|
||||
fatigued = TRUE
|
||||
if((!fatigued && W.health == W.maxHealth) || W.stat)
|
||||
continue
|
||||
if(!try_use_power(mob_cost))
|
||||
break
|
||||
W.adjustHealth(-20)
|
||||
else if(istype(M, /obj/structure/destructible/clockwork))
|
||||
var/obj/structure/destructible/clockwork/C = M
|
||||
if(C.obj_integrity == C.max_integrity)
|
||||
continue
|
||||
if(!try_use_power(structure_cost))
|
||||
break
|
||||
C.obj_integrity = min(C.obj_integrity + 20, C.max_integrity)
|
||||
else if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
|
||||
continue
|
||||
if(!try_use_power(cyborg_cost))
|
||||
break
|
||||
S.adjustBruteLoss(-20)
|
||||
S.adjustFireLoss(-10)
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(total_accessable_power() < mob_cost)
|
||||
user << "<span class='warning'>[src] needs more power or replicant alloy to function!</span>"
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
|
||||
if(stored_alloy + REPLICANT_ALLOY_POWER > max_alloy)
|
||||
user << "<span class='warning'>[src] is too full to accept any more alloy!</span>"
|
||||
return 0
|
||||
playsound(user, 'sound/machines/click.ogg', 50, 1)
|
||||
clockwork_say(user, text2ratvar("Transmute into fuel."), TRUE)
|
||||
user << "<span class='brass'>You force [I] to liquify and pour it into [src]'s compartments. \
|
||||
It now contains <b>[stored_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]/[max_alloy*CLOCKCULT_POWER_TO_ALLOY_MULTIPLIER]</b> units of liquified alloy.</span>"
|
||||
stored_alloy = stored_alloy + REPLICANT_ALLOY_POWER
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
@@ -0,0 +1,90 @@
|
||||
//Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
|
||||
/obj/structure/destructible/clockwork/ocular_warden
|
||||
name = "ocular warden"
|
||||
desc = "A large brass eye with tendrils trailing below it and a wide red iris."
|
||||
clockwork_desc = "A fragile turret that will deal sustained damage to any non-faithful it sees."
|
||||
icon_state = "ocular_warden"
|
||||
obj_integrity = 25
|
||||
max_integrity = 25
|
||||
construction_value = 15
|
||||
layer = HIGH_OBJ_LAYER
|
||||
break_message = "<span class='warning'>The warden's eye gives a glare of utter hate before falling dark!</span>"
|
||||
debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye = 1)
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/damage_per_tick = 2.5
|
||||
var/sight_range = 3
|
||||
var/atom/movable/target
|
||||
var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.")
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/New()
|
||||
..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='brass'>[target ? "<b>It's fixated on [target]!</b>" : "Its gaze is wandering aimlessly."]</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/process()
|
||||
var/list/validtargets = acquire_nearby_targets()
|
||||
if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned
|
||||
damage_per_tick = 10
|
||||
sight_range = 5
|
||||
if(target)
|
||||
if(!(target in validtargets))
|
||||
lose_target()
|
||||
else
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.null_rod_check())
|
||||
L.adjustFireLoss(!iscultist(L) ? damage_per_tick : damage_per_tick * 2) //Nar-Sian cultists take additional damage
|
||||
if(ratvar_awakens && L)
|
||||
L.adjust_fire_stacks(damage_per_tick)
|
||||
L.IgniteMob()
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.take_damage(damage_per_tick, BURN, "melee", 1, get_dir(src, M)) //does about half of standard damage to mechs * whatever their fire armor is
|
||||
|
||||
setDir(get_dir(get_turf(src), get_turf(target)))
|
||||
if(!target)
|
||||
if(validtargets.len)
|
||||
target = pick(validtargets)
|
||||
visible_message("<span class='warning'>[src] swivels to face [target]!</span>")
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L << "<span class='heavy_brass'>\"I SEE YOU!\"</span>\n<span class='userdanger'>[src]'s gaze [ratvar_awakens ? "melts you alive" : "burns you"]!</span>"
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.occupant << "<span class='heavy_brass'>\"I SEE YOU!\"</span>" //heeeellooooooo, person in mech.
|
||||
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
|
||||
if(prob(50))
|
||||
visible_message("<span class='notice'>[src][pick(idle_messages)]</span>")
|
||||
else
|
||||
setDir(pick(cardinal))//Random rotation
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/proc/acquire_nearby_targets()
|
||||
. = list()
|
||||
for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind
|
||||
var/obj/item/weapon/storage/book/bible/B = L.bible_check()
|
||||
if(!is_servant_of_ratvar(L) && !L.stat && L.mind && !(L.disabilities & BLIND) && !L.null_rod_check() && !B)
|
||||
. += L
|
||||
else if(B)
|
||||
if(!(B.resistance_flags & ON_FIRE))
|
||||
L << "<span class='warning'>Your [B.name] bursts into flames!</span>"
|
||||
for(var/obj/item/weapon/storage/book/bible/BI in L.GetAllContents())
|
||||
if(!(BI.resistance_flags & ON_FIRE))
|
||||
BI.fire_act()
|
||||
for(var/N in mechas_list)
|
||||
var/obj/mecha/M = N
|
||||
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant) && (M in view(sight_range, src)))
|
||||
. += M
|
||||
|
||||
/obj/structure/destructible/clockwork/ocular_warden/proc/lose_target()
|
||||
if(!target)
|
||||
return 0
|
||||
target = null
|
||||
visible_message("<span class='warning'>[src] settles and seems almost disappointed.</span>")
|
||||
return 1
|
||||
@@ -0,0 +1,143 @@
|
||||
//Ratvar himself. Impossible to damage by most standard means, He will dominate the station and all upon it.
|
||||
/obj/structure/destructible/clockwork/massive/ratvar
|
||||
name = "Ratvar, the Clockwork Justiciar"
|
||||
desc = "<span class='userdanger'>What is what is what are what real what is all a lie all a lie it's all a lie why how can what is</span>"
|
||||
clockwork_desc = "<span class='large_brass'><b><i>Ratvar, the Clockwork Justiciar, your master eternal.</i></b></span>"
|
||||
icon = 'icons/effects/512x512.dmi'
|
||||
icon_state = "ratvar"
|
||||
pixel_x = -235
|
||||
pixel_y = -248
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
appearance_flags = 0
|
||||
var/atom/prey //Whatever Ratvar is chasing
|
||||
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
|
||||
var/proselytize_range = 10
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/New()
|
||||
..()
|
||||
ratvar_awakens++
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
START_PROCESSING(SSobj, src)
|
||||
world << "<span class='ratvar'>\"[text2ratvar("ONCE AGAIN MY LIGHT SHALL SHINE ACROSS THIS PATHETIC REALM")]!!\"</span>"
|
||||
world << 'sound/effects/ratvar_reveal.ogg'
|
||||
var/image/alert_overlay = image('icons/effects/clockwork_effects.dmi', "ratvar_alert")
|
||||
var/area/A = get_area(src)
|
||||
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
|
||||
addtimer(SSshuttle.emergency, "request", 50, FALSE, null, 0.1)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
|
||||
ratvar_awakens--
|
||||
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
|
||||
R.update_force()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
world << "<span class='heavy_brass'><font size=6>\"NO! I will not... be...</font> <font size=5>banished...</font> <font size=4>again...\"</font></span>"
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
|
||||
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
|
||||
if(alertresult == "No" || !O)
|
||||
return 0
|
||||
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
|
||||
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
|
||||
R.key = O.key
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
|
||||
var/turf/T = get_turf(A)
|
||||
forceMove(T)
|
||||
T.ratvar_act()
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
|
||||
return clashing
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/process()
|
||||
if(clashing) //I'm a bit occupied right now, thanks
|
||||
return
|
||||
for(var/I in circlerangeturfs(src, proselytize_range))
|
||||
var/turf/T = I
|
||||
T.ratvar_act()
|
||||
for(var/I in circleviewturfs(src, round(proselytize_range * 0.5)))
|
||||
var/turf/T = I
|
||||
T.ratvar_act(1)
|
||||
var/dir_to_step_in = pick(cardinal)
|
||||
if(!prey)
|
||||
for(var/obj/singularity/narsie/N in poi_list)
|
||||
if(N.z == z)
|
||||
prey = N
|
||||
break
|
||||
if(!prey) //In case there's a Nar-Sie
|
||||
var/list/meals = list()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z == z && !is_servant_of_ratvar(L) && L.mind)
|
||||
meals += L
|
||||
if(meals.len)
|
||||
prey = pick(meals)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"You will do.\"</font></span>\n\
|
||||
<span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>"
|
||||
prey << 'sound/effects/ratvar_reveal.ogg'
|
||||
else
|
||||
if(prob(10) || is_servant_of_ratvar(prey) || prey.z != z)
|
||||
prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\
|
||||
<span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>"
|
||||
prey = null
|
||||
else
|
||||
dir_to_step_in = get_dir(src, prey) //Unlike Nar-Sie, Ratvar ruthlessly chases down his target
|
||||
step(src, dir_to_step_in)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/narsie_act()
|
||||
if(clashing)
|
||||
return FALSE
|
||||
clashing = TRUE
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("BLOOD GOD!!!", "NAR-SIE!!!", "AT LAST, YOUR TIME HAS COME!")]\"</font></span>"
|
||||
world << "<span class='cult'><font size=5>\"<b>Ratvar?! How?!</b>\"</font></span>"
|
||||
for(var/obj/singularity/narsie/N in range(15, src))
|
||||
if(N.clashing)
|
||||
continue
|
||||
N.clashing = TRUE
|
||||
clash_of_the_titans(N) //IT'S TIME FOR THE BATTLE OF THE AGES
|
||||
break
|
||||
return TRUE
|
||||
|
||||
//Put me in Reebe, will you? Ratvar has found and is going to fucking murder Nar-Sie
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
|
||||
var/winner = "Undeclared"
|
||||
var/base_victory_chance = 1
|
||||
while(src && narsie)
|
||||
world << 'sound/magic/clockwork/ratvar_attack.ogg'
|
||||
sleep(5.2)
|
||||
for(var/mob/M in mob_list)
|
||||
flash_color(M, flash_color="#966400", flash_time=1)
|
||||
shake_camera(M, 4, 3)
|
||||
var/ratvar_chance = min(ticker.mode.servants_of_ratvar.len, 50)
|
||||
var/narsie_chance = ticker.mode.cult.len
|
||||
for(var/mob/living/simple_animal/hostile/construct/harvester/C in player_list)
|
||||
narsie_chance++
|
||||
ratvar_chance = rand(base_victory_chance, ratvar_chance)
|
||||
narsie_chance = rand(base_victory_chance, min(narsie_chance, 50))
|
||||
if(ratvar_chance > narsie_chance)
|
||||
winner = "Ratvar"
|
||||
break
|
||||
sleep(rand(2,5))
|
||||
world << 'sound/magic/clockwork/narsie_attack.ogg'
|
||||
sleep(7.4)
|
||||
for(var/mob/M in mob_list)
|
||||
flash_color(M, flash_color="#C80000", flash_time=1)
|
||||
shake_camera(M, 4, 3)
|
||||
if(narsie_chance > ratvar_chance)
|
||||
winner = "Nar-Sie"
|
||||
break
|
||||
base_victory_chance *= 2 //The clash has a higher chance of resolving each time both gods attack one another
|
||||
switch(winner)
|
||||
if("Ratvar")
|
||||
world << "<span class='heavy_brass'><font size=5>\"[pick("DIE! DIE! DIE!", "FILTH!!!", "SUFFER!!!", text2ratvar("ROT FOR CENTURIES AS I HAVE!!"))]\"</font></span>" //nar-sie get out
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"</b></font></span>"
|
||||
world << 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
world << 'sound/magic/demon_dies.ogg'
|
||||
clashing = FALSE
|
||||
qdel(narsie)
|
||||
if("Nar-Sie")
|
||||
world << "<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>" //Broken English
|
||||
world << 'sound/magic/demon_attack1.ogg'
|
||||
world << 'sound/magic/clockwork/anima_fragment_death.ogg'
|
||||
narsie.clashing = FALSE
|
||||
qdel(src)
|
||||
@@ -0,0 +1,89 @@
|
||||
//Tinkerer's cache: Stores components for later use.
|
||||
/obj/structure/destructible/clockwork/cache
|
||||
name = "tinkerer's cache"
|
||||
desc = "A large brass spire with a flaming hole in its center."
|
||||
clockwork_desc = "A brass container capable of storing a large amount of components.\n\
|
||||
Shares components with all other caches and will gradually generate components if near a Clockwork Wall."
|
||||
icon_state = "tinkerers_cache"
|
||||
construction_value = 10
|
||||
break_message = "<span class='warning'>The cache's fire winks out before it falls in on itself!</span>"
|
||||
max_integrity = 80
|
||||
obj_integrity = 80
|
||||
var/wall_generation_cooldown
|
||||
var/turf/closed/wall/clockwork/linkedwall //if we've got a linked wall and are producing
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
clockwork_caches++
|
||||
SetLuminosity(2,1)
|
||||
for(var/i in all_clockwork_mobs)
|
||||
cache_check(i)
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/Destroy()
|
||||
clockwork_caches--
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(linkedwall)
|
||||
linkedwall.linkedcache = null
|
||||
linkedwall = null
|
||||
for(var/i in all_clockwork_mobs)
|
||||
cache_check(i)
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/process()
|
||||
for(var/turf/closed/wall/clockwork/C in view(4, src))
|
||||
if(!C.linkedcache && !linkedwall)
|
||||
C.linkedcache = src
|
||||
linkedwall = C
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
visible_message("<span class='warning'>[src] starts to whirr in the presence of [C]...</span>")
|
||||
break
|
||||
if(linkedwall && wall_generation_cooldown <= world.time)
|
||||
wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME
|
||||
var/component_to_generate = get_weighted_component_id()
|
||||
PoolOrNew(get_component_animation_type(component_to_generate), get_turf(src))
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1)
|
||||
visible_message("<span class='warning'>Something clunks around inside of [src]...</span>")
|
||||
break
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return ..()
|
||||
if(istype(I, /obj/item/clockwork/component))
|
||||
var/obj/item/clockwork/component/C = I
|
||||
clockwork_component_cache[C.component_id]++
|
||||
user << "<span class='notice'>You add [C] to [src].</span>"
|
||||
user.drop_item()
|
||||
qdel(C)
|
||||
return 1
|
||||
else if(istype(I, /obj/item/clockwork/slab))
|
||||
var/obj/item/clockwork/slab/S = I
|
||||
for(var/i in S.stored_components)
|
||||
clockwork_component_cache[i] += S.stored_components[i]
|
||||
S.stored_components[i] = 0
|
||||
user.visible_message("<span class='notice'>[user] empties [S] into [src].</span>", "<span class='notice'>You offload your slab's components into [src].</span>")
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/attack_hand(mob/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
return 0
|
||||
if(!clockwork_component_cache["replicant_alloy"])
|
||||
user << "<span class='warning'>There is no Replicant Alloy in the global component cache!</span>"
|
||||
return 0
|
||||
clockwork_component_cache["replicant_alloy"]--
|
||||
var/obj/item/clockwork/component/replicant_alloy/A = new(get_turf(src))
|
||||
user.visible_message("<span class='notice'>[user] withdraws [A] from [src].</span>", "<span class='notice'>You withdraw [A] from [src].</span>")
|
||||
user.put_in_hands(A)
|
||||
return 1
|
||||
|
||||
/obj/structure/destructible/clockwork/cache/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(linkedwall)
|
||||
user << "<span class='brass'>It is linked and will generate components!</span>"
|
||||
user << "<b>Stored components:</b>"
|
||||
for(var/i in clockwork_component_cache)
|
||||
user << "<span class='[get_component_span(i)]_small'><i>[get_component_name(i)][i != "replicant_alloy" ? "s":""]:</i> <b>[clockwork_component_cache[i]]</b></span>"
|
||||
@@ -0,0 +1,130 @@
|
||||
//Tinkerer's Daemon: A machine that rapidly produces components at a power cost.
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon
|
||||
name = "tinkerer's daemon"
|
||||
desc = "A strange machine with three small brass obelisks attached to it."
|
||||
clockwork_desc = "An efficient machine that can rapidly produce components at a small power cost. It will only function if outnumbered by servants at a rate to 5:1."
|
||||
icon_state = "tinkerers_daemon"
|
||||
active_icon = "tinkerers_daemon"
|
||||
inactive_icon = "tinkerers_daemon"
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
break_message = "<span class='warning'>The daemon shatters into millions of pieces!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 2, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 4, \
|
||||
/obj/item/clockwork/alloy_shards/small = 6)
|
||||
var/image/daemon_glow
|
||||
var/image/component_glow
|
||||
var/component_id_to_produce
|
||||
var/production_time = 0 //last time we produced a component
|
||||
var/production_cooldown = 120
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/New()
|
||||
..()
|
||||
clockwork_daemons++
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/Destroy()
|
||||
clockwork_daemons--
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(active)
|
||||
if(component_id_to_produce)
|
||||
user << "<span class='[get_component_span(component_id_to_produce)]_small'>It is currently producing [get_component_name(component_id_to_produce)][component_id_to_produce != "replicant_alloy" ? "s":""].</span>"
|
||||
else
|
||||
user << "<span class='brass'>It is currently producing random components.</span>"
|
||||
user << "<span class='nezbere_small'>It will produce a component every <b>[production_cooldown*0.1]</b> seconds and requires at least the following power for each component type:</span>"
|
||||
for(var/i in clockwork_component_cache)
|
||||
user << "<span class='[get_component_span(i)]_small'><i>[get_component_name(i)]:</i> <b>[get_component_cost(i)]W</b> <i>([clockwork_component_cache[i]] exist[clockwork_component_cache[i] == 1 ? "s" : ""])</i></span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/attack_hand(mob/living/user)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
user << "<span class='warning'>You place your hand on the daemon, but nothing happens.</span>"
|
||||
return
|
||||
if(active)
|
||||
toggle(0, user)
|
||||
else
|
||||
if(!clockwork_caches)
|
||||
user << "<span class='warning'>There are no clockwork caches! Activating this daemon would be a waste of power.</span>"
|
||||
return
|
||||
var/choice = alert(user,"Activate Daemon...",,"Specific Component","Random Component","Cancel")
|
||||
switch(choice)
|
||||
if("Specific Component")
|
||||
var/list/components = list()
|
||||
for(var/i in clockwork_component_cache)
|
||||
components["[get_component_name(i)] ([get_component_cost(i)]W)"] = i
|
||||
var/input_component = input(user, "Choose a component type.", name) as null|anything in components
|
||||
component_id_to_produce = components[input_component]
|
||||
if(!user.canUseTopic(src, BE_CLOSE) || active)
|
||||
return
|
||||
if(!component_id_to_produce)
|
||||
user << "<span class='warning'>You decide not to select a component and activate the daemon.</span>"
|
||||
return
|
||||
if(total_accessable_power() < get_component_cost(component_id_to_produce))
|
||||
user << "<span class='warning'>There is too little power to produce this type of component!</span>"
|
||||
return
|
||||
toggle(0, user)
|
||||
if("Random Component")
|
||||
component_id_to_produce = null
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/toggle(fast_process, mob/living/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
var/component_color = get_component_color(component_id_to_produce)
|
||||
if(!daemon_glow)
|
||||
daemon_glow = new('icons/obj/clockwork_objects.dmi', "tinkerglow")
|
||||
daemon_glow.color = component_color
|
||||
add_overlay(daemon_glow)
|
||||
if(!component_glow)
|
||||
component_glow = new('icons/obj/clockwork_objects.dmi', "t_[component_id_to_produce ? component_id_to_produce :"random_component"]")
|
||||
else
|
||||
component_glow.icon_state = "t_[component_id_to_produce ? component_id_to_produce :"random_component"]"
|
||||
component_glow.color = component_color
|
||||
add_overlay(component_glow)
|
||||
production_time = world.time + production_cooldown //don't immediately produce when turned on afteer being off
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/proc/get_component_cost(id)
|
||||
return max(MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER * (1 + round(clockwork_component_cache[id] * 0.2)))
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/process()
|
||||
var/servants = 0
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(is_servant_of_ratvar(L))
|
||||
servants++
|
||||
. = ..()
|
||||
var/min_power_usable = 0
|
||||
if(!component_id_to_produce)
|
||||
for(var/i in clockwork_component_cache)
|
||||
if(!min_power_usable)
|
||||
min_power_usable = get_component_cost(i)
|
||||
else
|
||||
min_power_usable = min(min_power_usable, get_component_cost(i))
|
||||
else
|
||||
min_power_usable = get_component_cost(component_id_to_produce)
|
||||
if(!clockwork_caches || servants * 0.2 < clockwork_daemons || . < min_power_usable) //if we don't have enough to produce the lowest or what we chose to produce, cancel out
|
||||
visible_message("<span class='warning'>[src] shuts down!</span>")
|
||||
toggle()
|
||||
return
|
||||
if(production_time <= world.time)
|
||||
var/component_to_generate = component_id_to_produce
|
||||
if(!component_to_generate)
|
||||
component_to_generate = get_weighted_component_id() //more likely to generate components that we have less of
|
||||
if(!try_use_power(get_component_cost(component_to_generate)))
|
||||
component_to_generate = null
|
||||
if(!component_id_to_produce)
|
||||
for(var/i in clockwork_component_cache)
|
||||
if(try_use_power(get_component_cost(i))) //if we fail but are producing random, try and get a different component to produce
|
||||
component_to_generate = i
|
||||
break
|
||||
if(component_to_generate)
|
||||
PoolOrNew(get_component_animation_type(component_to_generate), get_turf(src))
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
production_time = world.time + production_cooldown //go on cooldown
|
||||
visible_message("<span class='warning'>[src] hums as it produces a [get_component_name(component_to_generate)].</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src] shuts down!</span>") //we shouldn't actually ever get here, as we should cancel out way before this
|
||||
toggle()
|
||||
@@ -0,0 +1,56 @@
|
||||
//A massive gear, effectively a girder for clocks.
|
||||
/obj/structure/destructible/clockwork/wall_gear
|
||||
name = "massive gear"
|
||||
icon_state = "wall_gear"
|
||||
climbable = TRUE
|
||||
max_integrity = 50
|
||||
obj_integrity = 50
|
||||
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
|
||||
clockwork_desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, just climb over it, or proselytize it into replicant alloy."
|
||||
break_message = "<span class='warning'>The gear breaks apart into shards of alloy!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 4, \
|
||||
/obj/item/clockwork/alloy_shards/small = 2) //slightly more debris than the default, totals 26 alloy
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/displaced
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/examine(mob/user)
|
||||
..()
|
||||
user << "<span class='notice'>[src] is [anchored ? "":"not "]secured to the floor.</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
default_unfasten_wrench(user, I, 10)
|
||||
return 1
|
||||
else if(istype(I, /obj/item/stack/sheet/brass))
|
||||
var/obj/item/stack/sheet/brass/W = I
|
||||
if(W.get_amount() < 1)
|
||||
user << "<span class='warning'>You need one brass sheet to do this!</span>"
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(iswallturf(T))
|
||||
user << "<span class='warning'>There is already a wall present!</span>"
|
||||
return
|
||||
if(!isfloorturf(T))
|
||||
user << "<span class='warning'>A floor must be present to build a [anchored ? "false ":""]wall!</span>"
|
||||
return
|
||||
if(locate(/obj/structure/falsewall) in T.contents)
|
||||
user << "<span class='warning'>There is already a false wall present!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start adding [W] to [src]...</span>"
|
||||
if(do_after(user, 20, target = src))
|
||||
var/brass_floor = FALSE
|
||||
if(istype(T, /turf/open/floor/clockwork)) //if the floor is already brass, costs less to make(conservation of masssssss)
|
||||
brass_floor = TRUE
|
||||
if(W.use(2 - brass_floor))
|
||||
if(anchored)
|
||||
T.ChangeTurf(/turf/closed/wall/clockwork)
|
||||
else
|
||||
T.ChangeTurf(/turf/open/floor/clockwork)
|
||||
new /obj/structure/falsewall/brass(T)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need more brass to make a [anchored ? "false ":""]wall!</span>"
|
||||
return 1
|
||||
return ..()
|
||||
@@ -1,372 +0,0 @@
|
||||
//sends messages via hierophant
|
||||
/proc/titled_hierophant_message(mob/user, message, name_span = "heavy_brass", message_span = "brass", user_title = "Servant")
|
||||
if(!user || !message || !ticker || !ticker.mode)
|
||||
return 0
|
||||
var/parsed_message = "<span class='[name_span]'>[user_title ? "[user_title] ":""][findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: \
|
||||
</span><span class='[message_span]'>\"[message]\"</span>"
|
||||
hierophant_message(parsed_message, FALSE, user)
|
||||
return 1
|
||||
|
||||
/proc/hierophant_message(message, servantsonly, atom/target) //sends a generic message to all servants and optionally observers
|
||||
if(!message || !ticker || !ticker.mode)
|
||||
return 0
|
||||
for(var/M in mob_list)
|
||||
if(!servantsonly && isobserver(M))
|
||||
if(target)
|
||||
var/link = FOLLOW_LINK(M, target)
|
||||
M << "[link] [message]"
|
||||
else
|
||||
M << message
|
||||
else if(is_servant_of_ratvar(M))
|
||||
M << message
|
||||
|
||||
//Hierophant Network action, allows a servant with it to communicate
|
||||
/datum/action/innate/hierophant
|
||||
name = "Hierophant Network"
|
||||
desc = "Allows you to communicate with other Servants."
|
||||
button_icon_state = "hierophant"
|
||||
background_icon_state = "bg_clock"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
|
||||
buttontooltipstyle = "clockcult"
|
||||
var/title = "Servant"
|
||||
var/span_for_name = "heavy_brass"
|
||||
var/span_for_message = "brass"
|
||||
|
||||
/datum/action/innate/hierophant/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/hierophant/Activate()
|
||||
var/input = stripped_input(usr, "Please enter a message to send to other servants.", "Hierophant Network", "")
|
||||
if(!input || !IsAvailable())
|
||||
return
|
||||
|
||||
titled_hierophant_message(owner, input, span_for_name, span_for_message, title)
|
||||
|
||||
//Function Call action: Calls forth a Ratvarian spear once every 3 minutes
|
||||
/datum/action/innate/function_call
|
||||
name = "Function Call"
|
||||
desc = "Allows you to summon a Ratvarian spear to fight enemies."
|
||||
button_icon_state = "ratvarian_spear"
|
||||
background_icon_state = "bg_clock"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
|
||||
buttontooltipstyle = "clockcult"
|
||||
var/cooldown = 0
|
||||
var/base_cooldown = 1800
|
||||
|
||||
/datum/action/innate/function_call/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner) || cooldown > world.time)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/function_call/Activate()
|
||||
if(!owner.get_empty_held_indexes())
|
||||
usr << "<span class='warning'>You need an empty to hand to call forth your spear!</span>"
|
||||
return 0
|
||||
owner.visible_message("<span class='warning'>A strange spear materializes in [owner]'s hands!</span>", "<span class='brass'>You call forth your spear!</span>")
|
||||
var/obj/item/clockwork/ratvarian_spear/R = new(get_turf(usr))
|
||||
owner.put_in_hands(R)
|
||||
if(!ratvar_awakens)
|
||||
owner << "<span class='warning'>Your spear begins to break down in this plane of existence. You can't use it for long!</span>"
|
||||
addtimer(R, "break_spear", base_cooldown, FALSE)
|
||||
cooldown = base_cooldown + world.time
|
||||
owner.update_action_buttons_icon()
|
||||
addtimer(src, "update_actions", base_cooldown, FALSE)
|
||||
return 1
|
||||
|
||||
/datum/action/innate/function_call/proc/update_actions()
|
||||
if(owner)
|
||||
owner.update_action_buttons_icon()
|
||||
|
||||
//allows a mob to select a target to gate to
|
||||
/atom/movable/proc/procure_gateway(mob/living/invoker, time_duration, gateway_uses, two_way)
|
||||
var/list/possible_targets = list()
|
||||
var/list/teleportnames = list()
|
||||
var/list/duplicatenamecount = list()
|
||||
|
||||
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
|
||||
if(!O.Adjacent(invoker) && O != src && (O.z <= ZLEVEL_SPACEMAX)) //don't list obelisks that we're next to
|
||||
var/area/A = get_area(O)
|
||||
var/locname = initial(A.name)
|
||||
var/resultkey = "[locname] [O.name]"
|
||||
if(resultkey in teleportnames) //why the fuck did you put two obelisks in the same area
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = O
|
||||
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && L != invoker && (L.z <= ZLEVEL_SPACEMAX)) //People right next to the invoker can't be portaled to, for obvious reasons
|
||||
var/resultkey = "[L.name] ([L.real_name])"
|
||||
if(resultkey in teleportnames)
|
||||
duplicatenamecount[resultkey]++
|
||||
resultkey = "[resultkey] ([duplicatenamecount[resultkey]])"
|
||||
else
|
||||
teleportnames.Add(resultkey)
|
||||
duplicatenamecount[resultkey] = 1
|
||||
possible_targets[resultkey] = L
|
||||
|
||||
if(!possible_targets.len)
|
||||
invoker << "<span class='warning'>There are no other eligible targets for a Spatial Gateway!</span>"
|
||||
return 0
|
||||
var/input_target_key = input(invoker, "Choose a target to form a rift to.", "Spatial Gateway") as null|anything in possible_targets
|
||||
var/atom/movable/target = possible_targets[input_target_key]
|
||||
if(!src || !target || !invoker || !invoker.canUseTopic(src, BE_CLOSE) || !is_servant_of_ratvar(invoker) || (istype(src, /obj/item) && invoker.get_active_held_item() != src))
|
||||
return 0 //if any of the involved things no longer exist, the invoker is stunned, too far away to use the object, or does not serve ratvar, or if the object is an item and not in the mob's active hand, fail
|
||||
var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
|
||||
if(istargetobelisk)
|
||||
gateway_uses *= 2
|
||||
time_duration *= 2
|
||||
invoker.visible_message("<span class='warning'>The air in front of [invoker] ripples before suddenly tearing open!</span>", \
|
||||
"<span class='brass'>With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [time_duration / 10] seconds and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].</span>")
|
||||
var/obj/effect/clockwork/spatial_gateway/S1 = new(istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
|
||||
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
|
||||
|
||||
//Set up the portals now that they've spawned
|
||||
S1.setup_gateway(S2, time_duration, gateway_uses, two_way)
|
||||
S2.visible_message("<span class='warning'>The air in front of [target] ripples before suddenly tearing open!</span>")
|
||||
return 1
|
||||
|
||||
/proc/scripture_unlock_check() //returns a list of scriptures and if they're unlocked or not
|
||||
var/servants = 0
|
||||
var/unconverted_ai_exists = FALSE
|
||||
for(var/mob/living/M in living_mob_list)
|
||||
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
|
||||
servants++
|
||||
else if(isAI(M))
|
||||
unconverted_ai_exists = TRUE
|
||||
. = list(SCRIPTURE_DRIVER = TRUE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_REVENANT = FALSE, SCRIPTURE_JUDGEMENT = FALSE)
|
||||
//Drivers: always unlocked
|
||||
.[SCRIPTURE_SCRIPT] = (servants >= 5 && clockwork_caches >= 1)
|
||||
//Script: 5 or more non-brain servants and 1+ clockwork caches
|
||||
.[SCRIPTURE_APPLICATION] = (servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 100)
|
||||
//Application: 8 or more non-brain servants, 3+ clockwork caches, and at least 100 CV
|
||||
.[SCRIPTURE_REVENANT] = (servants >= 10 && clockwork_caches >= 4 && clockwork_construction_value >= 200)
|
||||
//Revenant: 10 or more non-brain servants, 4+ clockwork caches, and at least 200 CV
|
||||
.[SCRIPTURE_JUDGEMENT] = (servants >= 12 && clockwork_caches >= 5 && clockwork_construction_value >= 300 && !unconverted_ai_exists)
|
||||
//Judgement: 12 or more non-brain servants, 5+ clockwork caches, at least 300 CV, and there are no living, non-servant ais
|
||||
|
||||
/proc/scripture_unlock_alert(list/previous_states) //reports to servants when scripture is locked or unlocked
|
||||
. = scripture_unlock_check()
|
||||
for(var/i in .)
|
||||
if(.[i] != previous_states[i])
|
||||
hierophant_message("<span class='large_brass'><i>Hierophant Network:</i> <b>[i] Scripture has been [.[i] ? "un":""]locked.</b></span>")
|
||||
|
||||
/proc/change_construction_value(amount)
|
||||
clockwork_construction_value += amount
|
||||
|
||||
/proc/get_component_name(id) //returns a component name from a component id
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "Belligerent Eye"
|
||||
if("vanguard_cogwheel")
|
||||
return "Vanguard Cogwheel"
|
||||
if("guvax_capacitor")
|
||||
return "Guvax Capacitor"
|
||||
if("replicant_alloy")
|
||||
return "Replicant Alloy"
|
||||
if("hierophant_ansible")
|
||||
return "Hierophant Ansible"
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/get_component_span(id) //returns a component spanclass from a component id
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "neovgre"
|
||||
if("vanguard_cogwheel")
|
||||
return "inathneq"
|
||||
if("guvax_capacitor")
|
||||
return "sevtug"
|
||||
if("replicant_alloy")
|
||||
return "nezbere"
|
||||
if("hierophant_ansible")
|
||||
return "nzcrentr"
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/get_component_color(id) //returns a component color from a component id
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return "#6E001A"
|
||||
if("vanguard_cogwheel")
|
||||
return "#1E8CE1"
|
||||
if("guvax_capacitor")
|
||||
return "#AF0AAF"
|
||||
if("replicant_alloy")
|
||||
return "#42474D"
|
||||
if("hierophant_ansible")
|
||||
return "#DAAA18"
|
||||
else
|
||||
return "#BE8700"
|
||||
|
||||
/proc/get_component_id(name) //returns a component id from a component name
|
||||
switch(name)
|
||||
if("Belligerent Eye")
|
||||
return "belligerent_eye"
|
||||
if("Vanguard Cogwheel")
|
||||
return "vanguard_cogwheel"
|
||||
if("Guvax Capacitor")
|
||||
return "guvax_capacitor"
|
||||
if("Replicant Alloy")
|
||||
return "replicant_alloy"
|
||||
if("Hierophant Ansible")
|
||||
return "hierophant_ansible"
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/get_component_animation_type(id)
|
||||
switch(id)
|
||||
if("belligerent_eye")
|
||||
return /obj/effect/overlay/temp/ratvar/component
|
||||
if("vanguard_cogwheel")
|
||||
return /obj/effect/overlay/temp/ratvar/component/cogwheel
|
||||
if("guvax_capacitor")
|
||||
return /obj/effect/overlay/temp/ratvar/component/capacitor
|
||||
if("replicant_alloy")
|
||||
return /obj/effect/overlay/temp/ratvar/component/alloy
|
||||
if("hierophant_ansible")
|
||||
return /obj/effect/overlay/temp/ratvar/component/ansible
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/generate_cache_component(specific_component_id) //generates a component in the global component cache, either random based on lowest or a specific component
|
||||
if(specific_component_id)
|
||||
clockwork_component_cache[specific_component_id]++
|
||||
else
|
||||
var/component_to_generate = get_weighted_component_id()
|
||||
clockwork_component_cache[component_to_generate]++
|
||||
|
||||
/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab) //returns a chosen component id based on the lowest amount of that component
|
||||
. = list()
|
||||
if(storage_slab)
|
||||
if(clockwork_caches)
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache[i] + storage_slab.stored_components[i]), 1)
|
||||
else
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*storage_slab.stored_components[i], 1)
|
||||
else
|
||||
for(var/i in clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache[i], 1)
|
||||
. = pickweight(.)
|
||||
|
||||
/proc/clockwork_say(atom/movable/AM, message, whisper=FALSE)
|
||||
// When servants invoke ratvar's power, they speak in ways that non
|
||||
// servants do not comprehend.
|
||||
// Our ratvarian chants are stored in their ratvar forms
|
||||
|
||||
var/list/spans = list(SPAN_ROBOT)
|
||||
|
||||
var/old_languages_spoken = AM.languages_spoken
|
||||
AM.languages_spoken = HUMAN //anyone who can understand HUMAN will hear weird shitty ratvar speak, otherwise it'll get starred out
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!whisper)
|
||||
L.say(message, "clock", spans)
|
||||
else
|
||||
L.whisper(message)
|
||||
else
|
||||
AM.say(message)
|
||||
AM.languages_spoken = old_languages_spoken
|
||||
|
||||
/proc/cache_check(mob/M)
|
||||
if(!clockwork_caches)
|
||||
M.throw_alert("nocache", /obj/screen/alert/clockwork/nocache)
|
||||
else
|
||||
M.clear_alert("nocache")
|
||||
|
||||
/*
|
||||
The Ratvarian Language
|
||||
In the lore of the Servants of Ratvar, the Ratvarian tongue is a timeless language and full of power. It sounds like gibberish, much like Nar-Sie's language, but is in fact derived from
|
||||
aforementioned language, and may induce miracles when spoken in the correct way with an amplifying tool (similar to runes used by the Nar-Sian cult).
|
||||
|
||||
While the canon states that the language of Ratvar and his servants is incomprehensible to the unenlightened as it is a derivative of the most ancient known language, in reality it is
|
||||
actually very simple. To translate a plain English sentence to Ratvar's tongue, simply move all of the letters thirteen places ahead, starting from "a" if the end of the alphabet is reached.
|
||||
This cipher is known as "rot13" for "rotate 13 places" and there are many sites online that allow instant translation between English and rot13 - one of the benefits is that moving the translated
|
||||
sentence thirteen places ahead changes it right back to plain English.
|
||||
|
||||
There are, however, a few parts of the Ratvarian tongue that aren't typical and are implemented for fluff reasons. Some words may have graves, or hyphens (prefix and postfix), making the plain
|
||||
English translation apparent but disjoined (for instance, "Orubyq zl-cbjre!" translates directly to "Behold my-power!") although this can be ignored without impacting overall quality. When
|
||||
translating from Ratvar's tongue to plain English, simply remove the disjointments and use the finished sentence. This would make "Orubyq zl-cbjre!" into "Behold my power!" after removing the
|
||||
abnormal spacing, hyphens, and grave accents.
|
||||
|
||||
List of nuances:
|
||||
- Any time the WORD "of" occurs, it is linked to the previous word by a hyphen. (i.e. "V nz-bs Ratvar." directly translates to "I am-of Ratvar.")
|
||||
- Any time "th", followed by any two letters occurs, you add a grave (`) between those two letters, i.e; "Thi`s"
|
||||
- In the same vein, any time "ti", followed by one letter occurs, you add a grave (`) between "i" and the letter, i.e; "Ti`me"
|
||||
- Whereever "te" or "et" appear and there is another letter next to the e(i.e; "m"etal, greate"r"), add a hyphen between "e" and the letter, i.e; "M-etal", "Greate-r"
|
||||
- Where "gua" appears, add a hyphen between "gu" and "a", i.e "Gu-ard"
|
||||
- Where the WORD "and" appears it is linked to all surrounding words by hyphens, i.e; "Sword-and-shield"
|
||||
- Where the WORD "to" appears, it is linked to the following word by a hyphen, i.e; "to-use"
|
||||
- Where the WORD "my" appears, it is linked to the following word by a hyphen, i.e; "my-light"
|
||||
- Although "Ratvar" translates to "Engine" in English, the word "Ratvar" is used regardless of language as it is a proper noun.
|
||||
- The same rule applies to Ratvar's four generals: Nezbere (Armorer), Sevtug (Fright), Nzcrentr (Amperage), and Inath-neq (Vangu-Ard), although these words can be used in proper context if one is
|
||||
not referring to the four generals and simply using the words themselves.
|
||||
*/
|
||||
|
||||
//Regexes used to alter english to ratvarian style
|
||||
#define RATVAR_OF_MATCH regex("(\\w)\\s(\[oO]\[fF])","g")
|
||||
#define RATVAR_OF_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_GUA_MATCH regex("(\[gG]\[uU])(\[aA])","g")
|
||||
#define RATVAR_GUA_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TH_MATCH regex("(\[tT]\[hH]\\w)(\\w)","g")
|
||||
#define RATVAR_TH_REPLACEMENT "$1`$2"
|
||||
#define RATVAR_TI_MATCH regex("(\[tT]\[iI])(\\w)","g")
|
||||
#define RATVAR_TI_REPLACEMENT "$1`$2"
|
||||
#define RATVAR_ET_MATCH regex("(\\w)(\[eE]\[tT])","g")
|
||||
#define RATVAR_ET_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g")
|
||||
#define RATVAR_TE_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])","g")
|
||||
#define RATVAR_PRE_AND_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])\\s(\\w)","g")
|
||||
#define RATVAR_POST_AND_REPLACEMENT "$1-$2"
|
||||
#define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g")
|
||||
#define RATVAR_TO_REPLACEMENT "$1$2-$3"
|
||||
#define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g")
|
||||
#define RATVAR_MY_REPLACEMENT "$1$2-$3"
|
||||
|
||||
//Regexes used to remove ratvarian styling from english
|
||||
#define REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH regex("(\\w)-(\[aA]\[nN]\[dD])","g") //specifically structured to support -emphasis-, including with -and-
|
||||
#define REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT "$1 $2"
|
||||
#define REVERSE_RATVAR_HYPHEN_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])-(\\w)","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT "$1 $2"
|
||||
#define REVERSE_RATVAR_HYPHEN_TO_MY_MATCH regex("(\[tTmM]\[oOyY])-","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT "$1 "
|
||||
#define REVERSE_RATVAR_HYPHEN_TE_MATCH regex("(\[tT]\[eE])-","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT "$1"
|
||||
#define REVERSE_RATVAR_HYPHEN_ET_MATCH regex("-(\[eE]\[tT])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT "$1"
|
||||
#define REVERSE_RATVAR_HYPHEN_GUA_MATCH regex("(\[gG]\[uU])-(\[aA])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT "$1$2"
|
||||
#define REVERSE_RATVAR_HYPHEN_OF_MATCH regex("-(\[oO]\[fF])","g")
|
||||
#define REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT " $1"
|
||||
|
||||
|
||||
/proc/text2ratvar(text) //Takes english and applies ratvarian styling rules (and rot13) to it
|
||||
var/ratvarian = replacetext(text, RATVAR_OF_MATCH, RATVAR_OF_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_GUA_MATCH, RATVAR_GUA_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TH_MATCH, RATVAR_TH_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TI_MATCH, RATVAR_TI_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_ET_MATCH, RATVAR_ET_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TE_MATCH, RATVAR_TE_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_PRE_AND_MATCH, RATVAR_PRE_AND_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_POST_AND_MATCH, RATVAR_POST_AND_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_TO_MATCH, RATVAR_TO_REPLACEMENT)
|
||||
ratvarian = replacetext(ratvarian, RATVAR_MY_MATCH, RATVAR_MY_REPLACEMENT)
|
||||
return rot13(ratvarian)
|
||||
|
||||
/proc/ratvar2text(ratvarian) //Reverts ravarian styling and rot13 in text.
|
||||
var/text = replacetext(rot13(ratvarian), "`", "")
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT)
|
||||
text = replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT)
|
||||
return text
|
||||
@@ -324,7 +324,7 @@
|
||||
|
||||
|
||||
/mob/living/ratvar_act()
|
||||
if(!add_servant_of_ratvar(src) && !is_servant_of_ratvar(src))
|
||||
if(!is_servant_of_ratvar(src) && !add_servant_of_ratvar(src))
|
||||
src << "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>"
|
||||
adjustFireLoss(35)
|
||||
if(src)
|
||||
|
||||
+31
-8
@@ -348,22 +348,45 @@
|
||||
#include "code\game\gamemodes\changeling\powers\tiny_prick.dm"
|
||||
#include "code\game\gamemodes\changeling\powers\transform.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_cult.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_effect.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_item.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_machines.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_mobs.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_powerdrain.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_ratvar.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scripture.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_unsorted.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clock_armor.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structure.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_effects\clock_overlay.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_effects\clock_sigils.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_effects\general_markers.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_effects\spatial_gateway.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\clock_powerdrain.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\component_helpers.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\hierophant_network.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\proselytizer_helpers.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\ratvarian_language.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_helpers\scripture_checks.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clock_components.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clock_proselytizer.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clock_slab.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clockwork_armor.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clockwork_proselytizer.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\clockwork_slab.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\judicial_visor.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\ratvarian_spear.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\soul_vessel.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_items\wraith_spectacles.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_applications.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_drivers.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_judgement.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_revenant.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_scripts.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\ark_of_the_clockwork_justicar.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\clock_shells.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\clockwork_obelisk.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\interdiction_lens.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\mania_motor.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\mending_motor.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\ocular_warden.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\ratvar_the_clockwork_justicar.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\tinkerers_cache.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\tinkerers_daemon.dm"
|
||||
#include "code\game\gamemodes\clock_cult\clock_structures\wall_gear.dm"
|
||||
#include "code\game\gamemodes\cult\cult.dm"
|
||||
#include "code\game\gamemodes\cult\cult_comms.dm"
|
||||
#include "code\game\gamemodes\cult\cult_items.dm"
|
||||
|
||||
Reference in New Issue
Block a user