Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
@@ -1,248 +0,0 @@
//The gateway to Reebe, from which Ratvar emerges.
/obj/structure/destructible/clockwork/massive/celestial_gateway
name = "Gateway to the Celestial Derelict"
desc = "A massive, thrumming rip in spacetime."
clockwork_desc = "A portal to the Celestial Derelict. Massive and intimidating, it is the only thing that can both transport Ratvar and withstand the massive amount of energy he emits."
obj_integrity = 600
max_integrity = 600
mouse_opacity = 2
icon = 'icons/effects/clockwork_effects.dmi'
icon_state = "nothing"
density = FALSE
invisibility = INVISIBILITY_MAXIMUM
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
can_be_repaired = FALSE
var/progress_in_seconds = 0 //Once this reaches GATEWAY_RATVAR_ARRIVAL, it's game over
var/purpose_fulfilled = FALSE
var/first_sound_played = FALSE
var/second_sound_played = FALSE
var/third_sound_played = FALSE
var/ratvar_portal = TRUE //if the gateway actually summons ratvar or just produces a hugeass conversion burst
var/obj/effect/clockwork/overlay/gateway_glow/glow
var/obj/effect/countdown/clockworkgate/countdown
/obj/structure/destructible/clockwork/massive/celestial_gateway/New()
..()
addtimer(src, "spawn_animation", 0)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/spawn_animation()
var/turf/T = get_turf(src)
var/objective_is_gateway = (ticker && ticker.mode && ticker.mode.clockwork_objective == CLOCKCULT_GATEWAY)
new/obj/effect/clockwork/general_marker/inathneq(T)
if(objective_is_gateway)
hierophant_message("<span class='inathneq'>\"[text2ratvar("Engine, come forth and show your servants your mercy")]!\"</span>")
else
hierophant_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)
new/obj/effect/clockwork/general_marker/sevtug(T)
if(objective_is_gateway)
hierophant_message("<span class='sevtug'>\"[text2ratvar("Engine, come forth and show this station your decorating skills")]!\"</span>")
else
hierophant_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)
new/obj/effect/clockwork/general_marker/nezbere(T)
if(objective_is_gateway)
hierophant_message("<span class='nezbere'>\"[text2ratvar("Engine, come forth and shine your light across this realm")]!!\"</span>")
else
hierophant_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)
new/obj/effect/clockwork/general_marker/nzcrentr(T)
if(objective_is_gateway)
hierophant_message("<span class='nzcrentr'>\"[text2ratvar("Engine, come forth")].\"</span>")
else
hierophant_message("<span class='nzcrentr'>\"[text2ratvar("We will show all Engine's power")].\"</span>")
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0)
sleep(10)
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 100, 0)
var/list/open_turfs = list()
for(var/turf/open/OT in orange(1, T))
if(!is_blocked_turf(OT))
open_turfs |= OT
if(open_turfs.len)
for(var/mob/living/L in T)
L.forceMove(pick(open_turfs))
resistance_flags &= ~INDESTRUCTIBLE
density = TRUE
invisibility = 0
glow = new(get_turf(src))
countdown = new(src)
countdown.start()
var/area/gate_area = get_area(src)
hierophant_message("<span class='large_brass'><b>A gateway to the Celestial Derelict has been created in [gate_area.map_name]!</b></span>", FALSE, src)
if(!objective_is_gateway)
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)
SSshuttle.registerHostileEnvironment(src)
START_PROCESSING(SSprocessing, src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
STOP_PROCESSING(SSprocessing, src)
if(!purpose_fulfilled)
var/area/gate_area = get_area(src)
hierophant_message("<span class='large_brass'><b>A gateway to the Celestial Derelict has fallen at [gate_area.map_name]!</b></span>")
send_to_playing_players(sound(null, 0, channel = 8))
var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED
SSshuttle.clearHostileEnvironment(src)
if(!was_stranded && !purpose_fulfilled && second_sound_played)
priority_announce("Massive energy anomaly no longer on short-range scanners.","Anomaly Alert")
if(glow)
qdel(glow)
glow = null
if(countdown)
qdel(countdown)
countdown = null
. = ..()
/obj/structure/destructible/clockwork/massive/celestial_gateway/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
if(!disassembled)
resistance_flags |= INDESTRUCTIBLE
countdown.stop()
visible_message("<span class='userdanger'>The [src] begins to pulse uncontrollably... you might want to run!</span>")
send_to_playing_players(sound('sound/effects/clockcult_gateway_disrupted.ogg', 0, channel = 8, volume = 50))
make_glow()
glow.icon_state = "clockwork_gateway_disrupted"
resistance_flags |= INDESTRUCTIBLE
sleep(27)
explosion(src, 1, 3, 8, 8)
qdel(src)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/make_glow()
if(!glow)
glow = PoolOrNew(/obj/effect/clockwork/overlay/gateway_glow, get_turf(src))
glow.linked = src
/obj/structure/destructible/clockwork/massive/celestial_gateway/ex_act(severity)
var/damage = max((obj_integrity * 0.70) / severity, 100) //requires multiple bombs to take down
take_damage(damage, BRUTE, "bomb", 0)
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
. = "IMMINENT"
if(!obj_integrity)
. = "DETONATING"
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
. = "[round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 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 player_list)
if(M && !isnewplayer(M))
M << "<span class='warning'><b>You hear otherworldly sounds from the [dir2text(get_dir(get_turf(M), get_turf(src)))]...</span>"
if(!obj_integrity)
return 0
for(var/t in RANGE_TURFS(1, loc))
if(iswallturf(t))
var/turf/closed/wall/W = t
W.dismantle_wall()
else if(t && (isclosedturf(t) || !is_blocked_turf(t)))
var/turf/T = t
T.ChangeTurf(/turf/open/floor/clockwork)
for(var/obj/O in orange(1, src))
if(!istype(O, /obj/effect) && O.density)
if(!step_away(O, src, 2) || get_dist(O, src) < 2)
O.take_damage(50, BURN, "bomb")
O.update_icon()
progress_in_seconds += GATEWAY_SUMMON_RATE
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
if(!first_sound_played)
send_to_playing_players(sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = 8, volume = 30))
first_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_charging"
if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING)
if(!second_sound_played)
var/area/gate_area = get_area(src)
priority_announce("Massive energy anomaly detected on short-range scanners. Location: [gate_area.map_name].", "Anomaly Alert")
send_to_playing_players(sound('sound/effects/clockcult_gateway_active.ogg', 1, channel = 8, volume = 35))
second_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_active"
if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL)
if(!third_sound_played)
send_to_playing_players(sound('sound/effects/clockcult_gateway_closing.ogg', 1, channel = 8, volume = 40))
third_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_closing"
if(GATEWAY_RATVAR_ARRIVAL to INFINITY)
if(!purpose_fulfilled)
countdown.stop()
resistance_flags |= INDESTRUCTIBLE
purpose_fulfilled = TRUE
make_glow()
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
send_to_playing_players(sound('sound/effects/ratvar_rises.ogg', 0, channel = 8)) //End the sounds
sleep(125)
make_glow()
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
var/turf/startpoint = get_turf(src)
QDEL_IN(src, 3)
clockwork_gateway_activated = TRUE
if(ratvar_portal)
sleep(3)
new/obj/structure/destructible/clockwork/massive/ratvar(startpoint)
else
addtimer(SSshuttle.emergency, "request", 0, TIMER_NORMAL, null, 0) //call the shuttle immediately
sleep(3)
send_to_playing_players("<span class='ratvar'>\"[text2ratvar("Behold")]!\"</span>\n<span class='inathneq_large'>\"[text2ratvar("See Engine's mercy")]!\"</span>\n\
<span class='sevtug_large'>\"[text2ratvar("Observe Engine's design skills")]!\"</span>\n<span class='nezbere_large'>\"[text2ratvar("Behold Engine's light")]!!\"</span>\n\
<span class='nzcrentr_large'>\"[text2ratvar("Gaze upon Engine's power")]!\"</span>")
send_to_playing_players('sound/magic/clockwork/invoke_general.ogg')
var/x0 = startpoint.x
var/y0 = startpoint.y
for(var/I in spiral_range_turfs(255, startpoint))
var/turf/T = I
if(!T)
continue
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0)
if(dist < 100)
dist = TRUE
else
dist = FALSE
T.ratvar_act(dist)
CHECK_TICK
for(var/mob/living/silicon/robot/R in silicon_mobs)
if(R && R.stat != DEAD && !is_servant_of_ratvar(R))
add_servant_of_ratvar(R)
for(var/i in ai_list)
var/mob/living/silicon/ai/A = i
if(A && A.stat != DEAD && !is_servant_of_ratvar(A))
add_servant_of_ratvar(A)
for(var/I in all_clockwork_mobs)
var/mob/M = I
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!")))
//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 = BELOW_OPEN_DOOR_LAYER
@@ -1,48 +0,0 @@
//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] is inactive! Turn it on or capture a mind first.</span>"
return 0
if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind))
user << "<span class='warning'>[S]'s trapped consciousness 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)
A.fully_replace_character_name(null, "[initial(A.name)] ([S.brainmob.name])")
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."
@@ -1,95 +0,0 @@
//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"
unanchored_icon = "obelisk_unwrenched"
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
/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/can_be_unfasten_wrench(mob/user)
if(active)
user << "<span class='warning'>[src] is currently sustaining a gateway!</span>"
return FAILED_UNFASTEN
return ..()
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/forced_disable(bad_effects)
var/affected = 0
for(var/obj/effect/clockwork/spatial_gateway/SG in loc)
SG.ex_act(1)
affected++
if(bad_effects)
affected += try_use_power(MIN_CLOCKCULT_POWER*2)
return affected
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
if(!is_servant_of_ratvar(user) || total_accessable_power() < hierophant_cost || !anchored)
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(active)
user << "<span class='warning'>The obelisk is sustaining a gateway and cannot broadcast!</span>"
return
if(!user.can_speak_vocal())
user << "<span class='warning'>You cannot speak through the obelisk!</span>"
return
var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "")
if(!is_servant_of_ratvar(user) || !input || !user.canUseTopic(src, !issilicon(user)))
return
if(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
if(!user.can_speak_vocal())
user << "<span class='warning'>You cannot speak through the obelisk!</span>"
return
clockwork_say(user, text2ratvar("Hierophant Broadcast, activate! [html_decode(input)]"))
titled_hierophant_message(user, input, "big_brass", "large_brass")
if("Spatial Gateway")
if(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(!user.can_speak_vocal())
user << "<span class='warning'>You need to be able to speak to open a gateway!</span>"
return
if(procure_gateway(user, round(100 * get_efficiency_mod(), 1), round(5 * get_efficiency_mod(), 1), 1) && !active)
clockwork_say(user, text2ratvar("Spatial Gateway, activate!"))
else
return_power(gateway_cost)
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/process()
if(!anchored)
return
if(locate(/obj/effect/clockwork/spatial_gateway) in loc)
icon_state = active_icon
density = 0
active = TRUE
else
icon_state = inactive_icon
density = 1
active = FALSE
@@ -1,120 +0,0 @@
//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 or the area's APC."
icon_state = "interdiction_lens"
construction_value = 20
active_icon = "interdiction_lens_active"
inactive_icon = "interdiction_lens"
unanchored_icon = "interdiction_lens_unwrenched"
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
var/static/list/rage_messages = list("...", "Disgusting.", "Die.", "Foul.", "Worthless.", "Mortal.", "Unfit.", "Weak.", "Fragile.", "Useless.", "Leave my sight!")
/obj/structure/destructible/clockwork/powered/interdiction_lens/examine(mob/user)
..()
user << "<span class='[recharging > world.time ? "neovgre_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='neovgre_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, !issilicon(user)))
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/forced_disable(bad_effects)
if(disabled)
return FALSE
if(!active)
toggle(0)
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
return TRUE
/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
var/unconverted_ai = FALSE
var/efficiency = get_efficiency_mod()
var/rage_modifier = get_efficiency_mod(TRUE)
for(var/i in ai_list)
var/mob/living/silicon/ai/AI = i
if(AI && AI.stat != DEAD && !is_servant_of_ratvar(AI))
unconverted_ai = TRUE
for(var/M in atoms_to_test)
var/atom/movable/A = M
if(!A || qdeleted(A) || A == target_apc)
continue
power_drained += (A.power_drain(TRUE) * efficiency)
if(prob(1 * rage_modifier))
A << "<span class='neovgre'>\"[text2ratvar(pick(rage_messages))]\"</span>"
if(prob(100 * (efficiency * efficiency)))
if(istype(A, /obj/machinery/camera) && unconverted_ai)
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 * efficiency, 1, interdiction_range-7, 1)
if(!successfulprocess)
forced_disable()
@@ -1,152 +0,0 @@
//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"
unanchored_icon = "mania_motor_unwrenched"
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/geis_capacitor/antennae = 1)
var/mania_cost = 200
var/convert_attempt_cost = 500
var/convert_cost = 500
var/static/list/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/static/list/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/static/list/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/static/list/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/forced_disable(bad_effects)
if(active)
if(bad_effects)
try_use_power(MIN_CLOCKCULT_POWER*2)
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()
return TRUE
/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user)
if(user.canUseTopic(src, !issilicon(user)) && 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)
/obj/structure/destructible/clockwork/powered/mania_motor/toggle(fast_process, mob/living/user)
. = ..()
if(active)
SetLuminosity(2, 1)
else
SetLuminosity(0)
/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
var/efficiency = get_efficiency_mod()
for(var/mob/living/carbon/human/H in view(1, src))
if(is_servant_of_ratvar(H) || H.null_rod_check())
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)
H.Paralyse(5)
else if(!H.stat)
if(H.getBrainLoss() >= 100)
H.Paralyse(5)
H << "<span class='sevtug'>\"[text2ratvar(pick(convert_messages))]\"</span>"
else
H.adjustBrainLoss(100 * efficiency)
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 * efficiency) - targetbrainloss) //got too close had brain eaten
H.adjust_drugginess(Clamp(7 * efficiency, 0, 100 - H.druggy))
H.hallucination = min(H.hallucination + (7 * efficiency), 100)
H.dizziness = min(H.dizziness + (3 * efficiency), 45)
H.confused = min(H.confused + (3 * efficiency), 45)
if(4 to 5)
if(targetbrainloss <= 50)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(5 * efficiency, 0, 80 - H.druggy))
H.hallucination = min(H.hallucination + (5 * efficiency), 80)
H.dizziness = min(H.dizziness + (2 * efficiency), 30)
H.confused = min(H.confused + (2 * efficiency), 30)
if(6 to 7)
if(targetbrainloss <= 30)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 60 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 60)
H.dizziness = min(H.dizziness + (2 * efficiency), 15)
H.confused = min(H.confused + (2 * efficiency), 15)
if(8 to 9)
if(targetbrainloss <= 10)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 40 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 40)
if(10 to INFINITY)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 20 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 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 * efficiency) - targetbrainloss)
H.adjust_drugginess(Clamp(10 * efficiency, 0, 150 - H.druggy))
H.hallucination = min(H.hallucination + (10 * efficiency), 150)
H.dizziness = min(H.dizziness + (5 * efficiency), 60)
H.confused = min(H.confused + (5 * efficiency), 60)
else
forced_disable(FALSE)
@@ -1,146 +0,0 @@
//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"
unanchored_icon = "mending_motor_unwrenched"
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/heal_attempts = 4
var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
"Ah, child, it's okay now.")
var/static/list/heal_failure_messages = list("Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
"If you die, you will be remembered.")
var/static/list/mending_motor_typecache = typecacheof(list(
/obj/structure/destructible/clockwork,
/obj/machinery/door/airlock/clockwork,
/obj/machinery/door/window/clockwork,
/obj/structure/window/reinforced/clockwork,
/obj/structure/table/reinforced/brass))
/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 at least <b>[MIN_CLOCKCULT_POWER]W</b> to attempt to repair clockwork mobs, structures, or converted silicons.</span>"
/obj/structure/destructible/clockwork/powered/mending_motor/forced_disable(bad_effects)
if(active)
if(bad_effects)
try_use_power(MIN_CLOCKCULT_POWER*2)
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
toggle()
return TRUE
/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
if(user.canUseTopic(src, !issilicon(user)) && is_servant_of_ratvar(user))
if(total_accessable_power() < MIN_CLOCKCULT_POWER)
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/mending_motor/process()
var/efficiency = get_efficiency_mod()
for(var/atom/movable/M in range(7, src))
var/turf/T
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
T = get_turf(M)
var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
var/is_marauder = istype(E)
if(E.health == E.maxHealth || E.stat == DEAD || (is_marauder && !E.fatigue))
continue
for(var/i in 1 to heal_attempts)
if(E.health < E.maxHealth || (is_marauder && E.fatigue))
if(try_use_power(MIN_CLOCKCULT_POWER))
E.adjustHealth(-(8 * efficiency))
PoolOrNew(/obj/effect/overlay/temp/heal, list(T, "#1E8CE1"))
else
E << "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>"
break
else
E << "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>"
break
else if(is_type_in_typecache(M, mending_motor_typecache))
T = get_turf(M)
var/obj/structure/destructible/clockwork/C = M
if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
continue
for(var/i in 1 to heal_attempts)
if(C.obj_integrity < C.max_integrity)
if(try_use_power(MIN_CLOCKCULT_POWER))
C.obj_integrity = min(C.obj_integrity + (8 * efficiency), C.max_integrity)
if(C == src)
efficiency = get_efficiency_mod()
C.update_icon()
PoolOrNew(/obj/effect/overlay/temp/heal, list(T, "#1E8CE1"))
else
break
else
break
else if(issilicon(M))
T = get_turf(M)
var/mob/living/silicon/S = M
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
continue
for(var/i in 1 to heal_attempts)
if(S.health < S.maxHealth)
if(try_use_power(MIN_CLOCKCULT_POWER))
S.adjustBruteLoss(-(5 * efficiency))
S.adjustFireLoss(-(3 * efficiency))
PoolOrNew(/obj/effect/overlay/temp/heal, list(T, "#1E8CE1"))
else
S << "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>"
break
else
S << "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>"
break
. = ..()
if(. < MIN_CLOCKCULT_POWER)
forced_disable(FALSE)
@@ -1,123 +0,0 @@
//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"
unanchored_icon = "ocular_warden_unwrenched"
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.7
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/hulk_damage()
return 25
/obj/structure/destructible/clockwork/ocular_warden/can_be_unfasten_wrench(mob/user)
if(anchored)
if(obj_integrity <= max_integrity * 0.25)
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
return FAILED_UNFASTEN
else
for(var/obj/structure/destructible/clockwork/ocular_warden/W in orange(3, src))
user << "<span class='neovgre'>You sense another ocular warden too near this location. Activating this one this close would cause them to fight.</span>"
return FAILED_UNFASTEN
return SUCCESSFUL_UNFASTEN
/obj/structure/destructible/clockwork/ocular_warden/ratvar_act()
..()
if(ratvar_awakens)
damage_per_tick = 10
sight_range = 6
else
damage_per_tick = initial(damage_per_tick)
sight_range = initial(sight_range)
/obj/structure/destructible/clockwork/ocular_warden/process()
if(!anchored)
lose_target()
return
var/list/validtargets = acquire_nearby_targets()
if(target)
if(!(target in validtargets))
lose_target()
else
if(isliving(target))
var/mob/living/L = target
if(!L.null_rod_check())
if(isrevenant(L))
var/mob/living/simple_animal/revenant/R = L
if(R.revealed)
R.unreveal_time += 2
else
R.reveal(10)
L.adjustFireLoss((!iscultist(L) ? damage_per_tick : damage_per_tick * 2) * get_efficiency_mod()) //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 * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
PoolOrNew(/obj/effect/overlay/temp/ratvar/ocular_warden, get_turf(target))
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(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()
else if(!is_servant_of_ratvar(L) && !L.stat && L.mind && !L.restrained() && !(L.buckled && (L.lying || istype(L.buckled, /obj/structure/destructible/clockwork/geis_binding))) && \
!(L.disabilities & BLIND) && !L.null_rod_check())
. += L
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
@@ -1,145 +0,0 @@
//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/O in all_clockwork_objects)
O.ratvar_act()
START_PROCESSING(SSobj, src)
send_to_playing_players("<span class='ratvar'>\"[text2ratvar("ONCE AGAIN MY LIGHT SHALL SHINE ACROSS THIS PATHETIC REALM")]!!\"</span>")
send_to_playing_players('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, TIMER_NORMAL, null, 0.1)
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
ratvar_awakens--
for(var/obj/O in all_clockwork_objects)
O.ratvar_act()
STOP_PROCESSING(SSobj, src)
send_to_playing_players("<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)
send_to_playing_players('sound/magic/clockwork/ratvar_attack.ogg')
sleep(5.2)
for(var/mob/M in mob_list)
if(!isnewplayer(M))
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))
send_to_playing_players('sound/magic/clockwork/narsie_attack.ogg')
sleep(7.4)
for(var/mob/M in mob_list)
if(!isnewplayer(M))
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")
send_to_playing_players("<span class='heavy_brass'><font size=5>\"[pick("DIE! DIE! DIE!", "FILTH!!!", "SUFFER!!!", text2ratvar("ROT FOR CENTURIES AS I HAVE!!"))]\"</font></span>\n\
<span class='cult'><font size=5>\"<b>[pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")]\"</b></font></span>") //nar-sie get out
send_to_playing_players('sound/magic/clockwork/anima_fragment_attack.ogg')
send_to_playing_players('sound/magic/demon_dies.ogg')
clashing = FALSE
qdel(narsie)
if("Nar-Sie")
send_to_playing_players("<span class='cult'><font size=5>\"<b>[pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")]</b>\"</font></span>") //Broken English
send_to_playing_players('sound/magic/demon_attack1.ogg')
send_to_playing_players('sound/magic/clockwork/anima_fragment_death.ogg')
narsie.clashing = FALSE
qdel(src)
@@ -1,102 +0,0 @@
//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"
unanchored_icon = "tinkerers_cache_unwrenched"
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++
update_slab_info()
SetLuminosity(2,1)
/obj/structure/destructible/clockwork/cache/Destroy()
clockwork_caches--
update_slab_info()
STOP_PROCESSING(SSobj, src)
if(linkedwall)
linkedwall.linkedcache = null
linkedwall = null
return ..()
/obj/structure/destructible/clockwork/cache/process()
if(!anchored)
if(linkedwall)
linkedwall.linkedcache = null
linkedwall = null
return
for(var/turf/closed/wall/clockwork/C in range(4, src))
if(!C.linkedcache && !linkedwall)
C.linkedcache = src
linkedwall = C
wall_generation_cooldown = world.time + (CACHE_PRODUCTION_TIME * get_efficiency_mod(TRUE))
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 * get_efficiency_mod(TRUE))
generate_cache_component(null, src)
playsound(linkedwall, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1)
visible_message("<span class='warning'>Something cl[pick("ank", "ink", "unk", "ang")]s around inside of [src]...</span>")
/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
if(!anchored)
user << "<span class='warning'>[src] needs to be secured to place [C] into it!</span>"
else
clockwork_component_cache[C.component_id]++
update_slab_info()
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
if(!anchored)
user << "<span class='warning'>[src] needs to be secured to offload your slab's components into it!</span>"
else
for(var/i in S.stored_components)
clockwork_component_cache[i] += S.stored_components[i]
S.stored_components[i] = 0
update_slab_info()
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(!anchored)
user << "<span class='warning'>[src] needs to be secured to remove Replicant Alloy from it!</span>"
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]--
update_slab_info()
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 a component every <b>[round((CACHE_PRODUCTION_TIME * 0.1) * get_efficiency_mod(TRUE), 0.1)]</b> seconds!</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>"
@@ -1,165 +0,0 @@
//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"
unanchored_icon = "tinkerers_daemon_unwrenched"
max_integrity = 100
obj_integrity = 100
construction_value = 20
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>[round((production_cooldown*0.1) * get_efficiency_mod(TRUE), 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/forced_disable(bad_effects)
if(active)
if(bad_effects)
try_use_power(MIN_CLOCKCULT_POWER*2)
visible_message("<span class='warning'>[src] shuts down with a horrible grinding noise!</span>")
playsound(src, 'sound/magic/clockwork/anima_fragment_attack.ogg', 50, 1)
else
visible_message("<span class='warning'>[src] shuts down!</span>")
toggle()
return TRUE
/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(!anchored)
user << "<span class='warning'>[src] needs to be secured to the floor before it can be activated!</span>"
return FALSE
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)
user << "<span class='nezbere'>\"There are too few servants for this daemon to work.\"</span>"
return
if(!clockwork_caches)
user << "<span class='nezbere'>\"You require a cache for this daemon to operate. Get to it.\"</span>"
return
var/min_power_usable = 0
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))
if(total_accessable_power() < min_power_usable)
user << "<span class='nezbere'>\"You need more power to activate this daemon, friend.\"</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]
servants = 0
for(var/mob/living/L in living_mob_list)
if(is_servant_of_ratvar(L))
servants++
if(!is_servant_of_ratvar(user) || !user.canUseTopic(src, !issilicon(user)) || active || !clockwork_caches || servants * 0.2 < clockwork_daemons)
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 after being off
SetLuminosity(2, 1)
else
cut_overlays()
SetLuminosity(0)
/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
forced_disable(FALSE)
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)
generate_cache_component(component_to_generate, src)
production_time = world.time + (production_cooldown * get_efficiency_mod(TRUE)) //go on cooldown
visible_message("<span class='warning'>[src] hums as it produces a [get_component_name(component_to_generate)].</span>")
else
forced_disable(FALSE) //we shouldn't actually ever get here, as we should cancel out way before this
@@ -1,76 +0,0 @@
//A massive gear, effectively a girder for clocks.
/obj/structure/destructible/clockwork/wall_gear
name = "massive gear"
icon_state = "wall_gear"
unanchored_icon = "wall_gear"
climbable = TRUE
max_integrity = 150
obj_integrity = 150
layer = BELOW_OBJ_LAYER
construction_value = 3
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
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/New()
..()
PoolOrNew(/obj/effect/overlay/temp/ratvar/gear, get_turf(src))
/obj/structure/destructible/clockwork/wall_gear/emp_act(severity)
return
/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/weapon/screwdriver))
if(anchored)
user << "<span class='warning'>[src] needs to be unsecured to disassemble it!</span>"
else
playsound(src, I.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] starts to disassemble [src].</span>", "<span class='notice'>You start to disassemble [src]...</span>")
if(do_after(user, 40*I.toolspeed, target = src) && !anchored)
user << "<span class='notice'>You disassemble [src].</span>"
deconstruct(TRUE)
return 1
else if(istype(I, /obj/item/stack/tile/brass))
var/obj/item/stack/tile/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/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT) && disassembled)
new /obj/item/stack/tile/brass(loc, 3)
return ..()