diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index e80717935b4..3686a6ccda2 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -105,10 +105,10 @@ This file's folder contains: S.show_laws() return 1 -/proc/send_hierophant_message(mob/user, message) +/proc/send_hierophant_message(mob/user, message, large) if(!user || !message || !ticker || !ticker.mode) return 0 - var/parsed_message = "Servant [user.name == user.real_name ? user.name : "[user.real_name] (as [user.name])"]: \"[message]\"" + var/parsed_message = "Servant [user.name == user.real_name ? user.name : "[user.real_name] (as [user.name])"]: \"[message]\"" for(var/M in mob_list) if(isobserver(M)) var/link = FOLLOW_LINK(M, user) diff --git a/code/game/gamemodes/clock_cult/clock_items.dm b/code/game/gamemodes/clock_cult/clock_items.dm index a345926ccbe..b19fea97dcd 100644 --- a/code/game/gamemodes/clock_cult/clock_items.dm +++ b/code/game/gamemodes/clock_cult/clock_items.dm @@ -239,51 +239,51 @@ drivers += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ \ Component Cost: \ - [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \ - [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \ - [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \ - [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \ - [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
\ + [req_comps["belligerent_eye"] ? "[req_comps["belligerent_eye"]] belligerent eyes" : ""] \ + [req_comps["vanguard_cogwheel"] ? "[req_comps["vanguard_cogwheel"]] vanguard cogwheels" : ""] \ + [req_comps["guvax_capacitor"] ? "[req_comps["guvax_capacitor"]] guvax capacitors" : ""] \ + [req_comps["replicant_alloy"] ? "[req_comps["replicant_alloy"]] replicant alloys" : "no"] \ + [req_comps["hierophant_ansible"] ? "[req_comps["hierophant_ansible"]] hierophant ansibles" : "no"]
\ Tip: [initial(S.usage_tip)]
" if(SCRIPTURE_SCRIPT) scripts += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ \ Component Cost: \ - [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \ - [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \ - [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \ - [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \ - [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
\ + [req_comps["belligerent_eye"] ? "[req_comps["belligerent_eye"]] belligerent eyes" : ""] \ + [req_comps["vanguard_cogwheel"] ? "[req_comps["vanguard_cogwheel"]] vanguard cogwheels" : ""] \ + [req_comps["guvax_capacitor"] ? "[req_comps["guvax_capacitor"]] guvax capacitors" : ""] \ + [req_comps["replicant_alloy"] ? "[req_comps["replicant_alloy"]] replicant alloys" : "no"] \ + [req_comps["hierophant_ansible"] ? "[req_comps["hierophant_ansible"]] hierophant ansibles" : "no"]
\ Tip: [initial(S.usage_tip)]
" if(SCRIPTURE_APPLICATION) applications += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ \ Component Cost: \ - [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \ - [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \ - [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \ - [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \ - [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
\ + [req_comps["belligerent_eye"] ? "[req_comps["belligerent_eye"]] belligerent eyes" : ""] \ + [req_comps["vanguard_cogwheel"] ? "[req_comps["vanguard_cogwheel"]] vanguard cogwheels" : ""] \ + [req_comps["guvax_capacitor"] ? "[req_comps["guvax_capacitor"]] guvax capacitors" : ""] \ + [req_comps["replicant_alloy"] ? "[req_comps["replicant_alloy"]] replicant alloys" : "no"] \ + [req_comps["hierophant_ansible"] ? "[req_comps["hierophant_ansible"]] hierophant ansibles" : "no"]
\ Tip: [initial(S.usage_tip)]
" if(SCRIPTURE_REVENANT) revenant += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ \ Component Cost: \ - [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \ - [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \ - [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \ - [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \ - [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
\ + [req_comps["belligerent_eye"] ? "[req_comps["belligerent_eye"]] belligerent eyes" : ""] \ + [req_comps["vanguard_cogwheel"] ? "[req_comps["vanguard_cogwheel"]] vanguard cogwheels" : ""] \ + [req_comps["guvax_capacitor"] ? "[req_comps["guvax_capacitor"]] guvax capacitors" : ""] \ + [req_comps["replicant_alloy"] ? "[req_comps["replicant_alloy"]] replicant alloys" : "no"] \ + [req_comps["hierophant_ansible"] ? "[req_comps["hierophant_ansible"]] hierophant ansibles" : "no"]
\ Tip: [initial(S.usage_tip)]
" if(SCRIPTURE_JUDGEMENT) judgement += "
[initial(S.name)]: [initial(S.desc)]
Invocation Time: [initial(S.channel_time) / 10] seconds
\ \ Component Cost: \ - [req_comps["belligerent_eye"] ? req_comps["belligerent_eye"] : "No"] belligerent eyes, \ - [req_comps["vanguard_cogwheel"] ? req_comps["vanguard_cogwheel"] : "no"] vanguard cogwheels, \ - [req_comps["guvax_capacitor"] ? req_comps["guvax_capacitor"] : "no"] guvax capacitors, \ - [req_comps["replicant_alloy"] ? req_comps["replicant_alloy"] : "no"] replicant alloys, and \ - [req_comps["hierophant_ansible"] ? req_comps["hierophant_ansible"] : "no"] hierophant ansibles.
\ + [req_comps["belligerent_eye"] ? "[req_comps["belligerent_eye"]] belligerent eyes" : ""] \ + [req_comps["vanguard_cogwheel"] ? "[req_comps["vanguard_cogwheel"]] vanguard cogwheels" : ""] \ + [req_comps["guvax_capacitor"] ? "[req_comps["guvax_capacitor"]] guvax capacitors" : ""] \ + [req_comps["replicant_alloy"] ? "[req_comps["replicant_alloy"]] replicant alloys" : "no"] \ + [req_comps["hierophant_ansible"] ? "[req_comps["hierophant_ansible"]] hierophant ansibles" : "no"]
\ Tip: [initial(S.usage_tip)]
" text_to_add += "[drivers]
[scripts]
[applications]
[revenant]
[judgement]
" text_to_add += "
Purge all untruths and honor Ratvar.
" @@ -896,6 +896,13 @@ cultist_message = "\"Try not to lose your mind - I'll need it. Heh heh...\"" servant_of_ratvar_messages = list("\"Disgusting.\"", "\"Well, aren't you an inquisitive fellow?\"", "A foul presence pervades your mind, then vanishes.", "\"The fact that Ratvar has to depend on simpletons like you is appalling.\"") +/obj/item/clockwork/component/guvax_capacitor/antennae + name = "mania motor antennae" + desc = "A pair of dented antennae. They constantly emit a static hiss." + icon_state = "mania_motor_antennae" + cultist_message = "Your head is filled with a burst of static." + servant_of_ratvar_messages = list("\"Jub oebxr guvf.\"", "\"Qvq lbh oernx gurfr bss LBHEFRYS?\"", "\"Jul qvq jr tvir guvf gb fhpu fvzcyrgbaf, naljnl?\"", "\"Ng yrnfg jr pna hfr gur'fr sbe fbzrguvat - hayvxr lbh.\"") + /obj/item/clockwork/component/replicant_alloy name = "replicant alloy" desc = "A seemingly strong but very malleable chunk of metal. It seems as though it wants to be molded into something greater." diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 83ba73c05aa..e7649330467 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -140,6 +140,13 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed var/object_path = /obj/item/clockwork //The path of the object created var/creator_message = "You create a meme." //Shown to the invoker var/observer_message + var/one_per_tile = FALSE + +/datum/clockwork_scripture/create_object/check_special_requirements() + if(one_per_tile && (locate(object_path) in get_turf(invoker))) + invoker << "You can only place one of this object on each tile!" + return 0 + return 1 /datum/clockwork_scripture/create_object/scripture_effects() if(creator_message && observer_message) @@ -221,6 +228,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed creator_message = "A sigil silently appears below you. The next non-servant to cross it will be immobilized." usage_tip = "The sigil, while fairly powerful in its stun, does not induce muteness in its victim." tier = SCRIPTURE_DRIVER + one_per_tile = TRUE @@ -329,6 +337,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed creator_message = "A sigil appears below you. The next non-servant to cross it will be enslaved after a brief time if they do not move." usage_tip = "This should not be your 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_DRIVER + one_per_tile = TRUE @@ -363,6 +372,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed observer_message = "A hollow brass spire rises and begins to blaze!" usage_tip = "Slabs will draw components from the global cache before the slab's own repositories, making caches very efficient." tier = SCRIPTURE_DRIVER + one_per_tile = TRUE @@ -371,8 +381,8 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed desc = "Fabricates a pair of glasses that provides true sight but quickly damage vision." invocations = list("Y'vsg gur fpnyrf sebz zl rl-rf.") channel_time = 0 - required_components = list("hierophant_ansible" = 1) - consumed_components = list("hierophant_ansible" = 2) + required_components = list("hierophant_ansible" = 2) + consumed_components = list("hierophant_ansible" = 1) whispered = TRUE object_path = /obj/item/clothing/glasses/wraith_spectacles creator_message = "You form a pair of wraith spectacles, which will grant true sight when worn." @@ -408,18 +418,22 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed observer_message = "A brass eye takes shape and slowly rises into the air, its red iris glaring!" usage_tip = "Although powerful, the warden is very weak and should optimally be placed behind barricades." tier = SCRIPTURE_SCRIPT + one_per_tile = TRUE /datum/clockwork_scripture/channeled/volt_void //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. name = "Volt Void" //Alternative name: "On all levels but physical, I am a power sink" - desc = "Drains energy from nearby power sources, dealing slight fire damage depending on power consumed. Channeled every second for a maximum of thirty seconds." + desc = "Drains energy from nearby power sources, dealing if the total power consumed is above a threshhold. Channeled every second for a maximum of thirty seconds." chant_invocation = "Qenj punetr gb guv’f furyy!" chant_amount = 30 chant_interval = 10 required_components = list("belligerent_eye" = 1, "hierophant_ansible" = 1) - usage_tip = "Very powerful against cyborgs and can drain a power cell in seconds." + 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 + var/total_power_drained = 0 + var/power_damage_threshhold = 2000 + var/augument_damage_threshhold = 5000 /datum/clockwork_scripture/channeled/volt_void/chant_effects() playsound(invoker, 'sound/effects/EMPulse.ogg', 50, 1) @@ -428,15 +442,15 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed if(A.cell.charge) playsound(A, "sparks", 50, 1) flick("apc-spark", A) + power_drained += min(A.cell.charge, 500) A.cell.charge = max(0, A.cell.charge - 500) //Better than a power sink! - power_drained += 500 if(!A.cell.charge && !A.shorted) A.shorted = 1 A.visible_message("The [A.name]'s screen blurs with static.") for(var/obj/machinery/power/smes/S in view(7, invoker)) if(S.charge) - S.charge = max(0, S.charge - 200) - power_drained += 200 + power_drained += min(S.charge, 500) + S.charge = max(0, S.charge - 500) if(!S.charge && !S.panel_open) S.panel_open = TRUE S.update_icon() @@ -445,22 +459,46 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed spks.start() qdel(spks) S.visible_message("[S]'s panel flies open with a flurry of sparks.") + for(var/obj/item/weapon/stock_parts/cell/C in view(7, invoker)) + if(C.charge) + power_drained += min(C.charge, 100) + C.charge = C.use(max(0, C.charge - 100)) for(var/obj/machinery/light/L in view(7, invoker)) playsound(L, 'sound/effects/light_flicker.ogg', 50, 1) L.flicker(2) - power_drained += 5 + power_drained += 25 for(var/mob/living/silicon/robot/R in view(7, invoker)) if(!is_servant_of_ratvar(R) && R.cell.charge) + power_drained += min(R.cell.charge, 500) R.cell.charge = max(0, R.cell.charge - 500) R << "ERROR: Power loss detected!" var/datum/effect_system/spark_spread/spks = new(get_turf(R)) spks.set_up(3, 0, get_turf(R)) spks.start() - qdel(spks) - power_drained += 500 - if(power_drained) + 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("[ST] flares a brilliant orange!") + 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("[invoker] flares a brilliant orange!", "You feel the warmth of electricity running into your body.") - invoker.adjustFireLoss(power_drained / 200) //One point of burn damage for every (approximate) 200W drained - can be fatal if not careful + 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 || total_power_drained < augument_damage_threshhold) //if ratvar is alive, it won't damage and will always heal augumented limbs + BP.heal_damage(power_damage, power_damage, 1) //heals one point of burn and brute for every ~100W drained on augumented limbs + else + BP.take_damage(0, power_damage) + 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 1 @@ -504,7 +542,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/function_call //Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons. name = "Function Call" desc = "Grants the invoker the ability to call forth a powerful Ratvarian spear that will deal significant damage to Nar-Sie's dogs in addition to silicon lifeforms. \ - It will vanish several minutes after being called." + It will vanish five minutes after being called." invocations = list("Tenag zr...", "...gur zvtug-bs oenff!") channel_time = 20 required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1) @@ -535,16 +573,18 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed required_components = list("replicant_alloy" = 1, "hierophant_ansible" = 1) multiple_invokers_used = TRUE multiple_invokers_optional = TRUE - usage_tip = "The gateway is strictly one-way and will only allow things through the invoker's portal." + usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." tier = SCRIPTURE_SCRIPT /datum/clockwork_scripture/spatial_gateway/check_special_requirements() var/other_servants = 0 for(var/mob/living/L in living_mob_list) - if(L.z == invoker.z && is_servant_of_ratvar(L) && !L.stat != DEAD) + if(is_servant_of_ratvar(L) && !L.stat != DEAD) other_servants++ + for(var/obj/structure/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects) + other_servants++ if(!other_servants) - invoker << "There are no other conscious servants on your z-level!" + invoker << "There are no other servants or clockwork obelisks!" return 0 return 1 @@ -558,25 +598,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed if(ratvar_awakens) portal_uses = max(portal_uses, 100) //Very powerful if Ratvar has been summoned duration = max(duration, 30) - var/list/possible_servants = list() - for(var/mob/living/L in living_mob_list) - if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && L != invoker) //People right next to the invoker can't be portaled to, for obvious reasons - possible_servants += L - if(!possible_servants.len) - invoker << "There are no other eligible servants for teleportation!" - return 0 - var/mob/living/chosen_servant = input(invoker, "Choose a servant to form a rift to.", "Spatial Gateway") as null|anything in possible_servants - if(!chosen_servant || !invoker.canUseTopic(slab)) - return 0 - invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ - "With a word, you rip open a one-way rift to [chosen_servant]. It will last for [duration / 10] seconds and has [portal_uses] use[portal_uses > 1 ? "s" : ""].") - var/obj/effect/clockwork/spatial_gateway/S1 = new(get_step(invoker, invoker.dir)) - var/obj/effect/clockwork/spatial_gateway/S2 = new(get_step(chosen_servant, chosen_servant.dir)) - - //Set up the portals now that they've spawned - S1.setup_gateway(S2, duration, portal_uses) - S2.visible_message("The air in front of [chosen_servant] ripples before suddenly tearing open!") - return 1 + invoker.procure_gateway(invoker, duration, portal_uses) @@ -594,11 +616,11 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed -/datum/clockwork_scripture/break_will //Break Will: Deals minor brain damage and destroys the loyalty implants of nearby humans - name = "Break Will" +/datum/clockwork_scripture/dementia_doctrine //Dementia Doctrine: Deals minor brain damage and destroys the loyalty implants of nearby humans + name = "Dementia Doctrine" desc = "Deals minor brain damage and disables loyalty implants of everyone adjacent to the invoker." - invocations = list("Lbh ner jrnx.", "Lbh ner nyernql qrnq.", "Gurl jba'g fnir lbh.") - channel_time = 30 + invocations = list("Lbh ner jrnx.", "Lbh jvyy or uvf.", "Gurl jba'g fnir lbh - gurl'yy xvyy lbh.") + channel_time = 20 required_components = list("belligerent_eye" = 1, "guvax_capacitor" = 1) usage_tip = "Extremely fast invocation time." tier = SCRIPTURE_SCRIPT @@ -607,10 +629,10 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed for(var/mob/living/carbon/human/H in range(1, invoker)) if(is_servant_of_ratvar(H)) continue + H.adjustBrainLoss(10) if(isloyal(H)) H.visible_message("[H] visibly trembles!", \ - "The words invoke a horrible fear deep in your being. Your loyalty to Nanotrasen falls away as you see how weak they truly are.") - H.adjustBrainLoss(5) + "Ohg jr pna cerirag gun'g. Jr pna znxr lbh zvar-naq-uvf.") for(var/obj/item/weapon/implant/loyalty/L in H) if(L.implanted) qdel(L) @@ -636,16 +658,32 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/create_object/sigil_of_transmission name = "Sigil of Transmission" - desc = "Scribes an almost-invisible sigil below the invoker. This sigil will transmit anything it hears over the hierophant network." - invocations = list("Qvivavgl...", "...hairvy gurgehgu!") + desc = "Scribes a sigil beneath the invoker which stores power to power clockwork structures." + invocations = list("Qvivavgl...", "punetr gurznpuvarf!") + channel_time = 50 + required_components = list("belligerent_eye" = 1, "replicant_alloy" = 2, "hierophant_ansible" = 2) + whispered = TRUE + object_path = /obj/effect/clockwork/sigil/transmission + creator_message = "A sigil silently appears below you. It will automatically power clockwork structures adjecent to it." + usage_tip = "Can be recharged by using Volt Void while standing on it." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + + + +/datum/clockwork_scripture/create_object/vitality_matrix + 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("Qvivavgl...", "fgrny gur've yvsr...", "sbe guv'f furyy!") channel_time = 50 required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 3, "hierophant_ansible" = 1) whispered = TRUE - object_path = /obj/effect/clockwork/sigil/transmission - creator_message = "A sigil silently appears below you. It will automatically transmit anything it hears over the hierophant network." - usage_tip = "Useful for eavesdropping or monitoring certain areas." + object_path = /obj/effect/clockwork/sigil/vitality + creator_message = "A vitality matrix appears below you. It will drain life from non-servants and heal servants that cross it." + usage_tip = "To revive a servant, the sigil must have 50 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 /datum/clockwork_scripture/memory_allocation //Memory Allocation: Finds a willing ghost and makes them into a clockwork marauders for the invoker. @@ -748,32 +786,69 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/create_object/interdiction_lens //Interdiction Lens: Creates a powerful obelisk that can perform a variety of powerful sabotages every five minutes. name = "Interdiction Lens" desc = "Creates a clockwork totem that can sabotage a variety of mechanical apparatus. Requires a lengthy recharge between uses." - invocations = list("Znl guvf boryvfx...", "...fuebhq gur snyfr fhaf!") + invocations = list("Znl guvf gbgrz...", "...fuebhq gur snyfr fhaf!") channel_time = 60 required_components = list("belligerent_eye" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 3) - object_path = /obj/structure/clockwork/interdiction_lens + object_path = /obj/structure/clockwork/powered/interdiction_lens creator_message = "You form an interdiction lens, which can disrupt machinery every few minutes." observer_message = "A brass obelisk rises from the ground, a purple gem appearing in its center!" invokers_required = 2 multiple_invokers_used = TRUE usage_tip = "Can disrupt telecommunications, disable all cameras, or disable all cyborgs." tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE /datum/clockwork_scripture/create_object/mending_motor //Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures and consume replicant alloy. name = "Mending Motor" - desc = "Creates a mechanized prism that will rapidly repair damage to clockwork creatures, converted cyborgs, and clockwork structures. Requires replicant alloy to function." - invocations = list("Znl guvf boryvfx...", "...zraq bhe qragf naq fpengpurf!") + 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("Znl guvf cevfz...", "...zraq bhe qragf naq fpengpurf!") channel_time = 60 required_components = list("vanguard_cogwheel" = 1, "guvax_capacitor" = 1, "replicant_alloy" = 3) - object_path = /obj/structure/clockwork/mending_motor/prefilled - creator_message = "You form a mending motor, which will consume replicant alloy to mend the wounds of mechanized servants." + object_path = /obj/structure/clockwork/powered/mending_motor/prefilled + creator_message = "You form a mending motor, which will consume power or replicant alloy to mend the wounds of mechanized servants." observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!" invokers_required = 2 multiple_invokers_used = TRUE - usage_tip = "Powerful healing but somewhat inefficient." + usage_tip = "Powerful healing but power use is very inefficient, and its alloy use is little better." tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + + + +/datum/clockwork_scripture/create_object/clockwork_obelisk //Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk. + name = "Clockwork Obelisk" + desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spacial Gateway to any living servant or clockwork obelisk." + invocations = list("Znl guvf boryvfx...", "...gnxr hf gb nyy cynprf!") + channel_time = 60 + required_components = list("guvax_capacitor" = 1, "replicant_alloy" = 3, "hierophant_ansible" = 1) + object_path = /obj/structure/clockwork/powered/clockwork_obelisk + creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spacial Gateways." + observer_message = "A brass obelisk appears handing in midair!" + 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 + + + +/datum/clockwork_scripture/create_object/mania_motor //Mania Motor: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk. + 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("Znl guvf genafzvggre...", "...oernx gur jvyy bs nyy jub bccbfr hf!") + channel_time = 60 + required_components = list("guvax_capacitor" = 1, "replicant_alloy" = 3, "hierophant_ansible" = 1) + object_path = /obj/structure/clockwork/powered/mania_motor + creator_message = "You form a mania motor which will cause brain damage and hallucinations in nearby humans while active." + observer_message = "A two-pronged machine rises from the ground!" + invokers_required = 2 + multiple_invokers_used = TRUE + usage_tip = "Eligible human servants next to the motor will be converted at an additonal power cost. It will also cure hallucinations and brain damage in nearby servants." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + @@ -800,18 +875,19 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed invocations = list("V pnyy hcba lbh, Nezbere!!", "Yrg lbhe znpuv'angvbaf ervta ba guvf zvfrenoyr fgng'vba!!", "Yrg lbhe cbjre sybj gueb-htu gur gbbyf bs lbhe znfgre!!") channel_time = 150 required_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 mending motors will require no alloy." + 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, and clockwork obelisks will all require no power." tier = SCRIPTURE_REVENANT /datum/clockwork_scripture/invoke_nezbere/check_special_requirements() - if(ratvar_awakens) - invoker << "\"Bhe znfgre vf urer nyernql. Lbh qb abg erdhver zl uryc, sevraq.\"\n\ - Nezbere will not grant his power while Ratvar's dwarfs his own!" - return 0 if(clockwork_generals_invoked["nezbere"]) invoker << "\"Abg whfg lrg, sevraq. Cngvrapr vf n iveghr.\"\n\ Nezbere has already been invoked recently! You must wait several minutes before calling upon the Brass Eidolon." return 0 + if(ratvar_awakens) + invoker << "\"Bhe znfgre vf urer nyernql. Lbh qb abg erdhver zl uryc, sevraq.\"\n\ + Nezbere will not grant his power while Ratvar's dwarfs his own!" + return 0 return 1 /datum/clockwork_scripture/invoke_nezbere/scripture_effects() @@ -825,8 +901,8 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed P.uses_alloy = FALSE for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) //Daemons produce components twice as quickly D.production_interval /= 2 - for(var/obj/structure/clockwork/mending_motor/M in all_clockwork_objects) //Mending motors no longer require alloy - M.uses_alloy = FALSE + for(var/obj/structure/clockwork/powered/M in all_clockwork_objects) //Powered clockwork structures no longer need power + M.needs_power = FALSE spawn(600) for(var/obj/structure/clockwork/ocular_warden/W in all_clockwork_objects) W.damage_per_tick = initial(W.damage_per_tick) @@ -835,8 +911,8 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed P.uses_alloy = TRUE for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) D.production_interval = initial(D.production_interval) - for(var/obj/structure/clockwork/mending_motor/M in all_clockwork_objects) - M.uses_alloy = TRUE + for(var/obj/structure/clockwork/powered/M in all_clockwork_objects) + M.needs_power = TRUE spawn(3000) //5 minutes clockwork_generals_invoked["nezbere"] = FALSE return 1 @@ -854,14 +930,14 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed tier = SCRIPTURE_REVENANT /datum/clockwork_scripture/targeted/invoke_sevtug/check_special_requirements() - if(ratvar_awakens) - invoker << "\"Qb lbh ernyyl guvax nalguvat v pna qb evtug abj jvyy pbzcner gb Ratvar's cbjre?.\"\n\ - Sevtug will not grant his power while Ratvar's dwarfs his own!" - return 0 if(clockwork_generals_invoked["sevtug"]) - invoker << "\"Vf vg ernyyl fb uneq - rira sbe n fvzcyrgba yvxr lbh - gb tenfc gur pbaprcg bs jnvgvat?\"\n\ + invoker << "\"Vf vg ernyyl fb uneq - rira sbe n fvzcyrgba yvxr lbh - gb tenfc gur pbaprcg bs jnvgvat?\"\n\ Sevtug has already been invoked recently! You must wait several minutes before calling upon the Formless Pariah." return 0 + if(ratvar_awakens) + invoker << "\"Qb lbh ernyyl guvax nalguvat v pna qb evtug abj jvyy pbzcner gb Ratvar's cbjre?.\"\n\ + Sevtug will not grant his power while Ratvar's dwarfs his own!" + return 0 return ..() /datum/clockwork_scripture/targeted/invoke_sevtug/scripture_effects() @@ -876,7 +952,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/invoke_nzcrentr //Invoke Nzcrentr, the Forgotten Arbiter: Imbues an immense amount of energy into the invoker. After several seconds, everyone nearby will be hit with a devastating chain lightning blast. name = "Invoke Nzcrentr, the Forgotten Arbiter" 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 (during which you will move extremely quickly) anyone nearby will be struck by a devastating lightning bolt." + seconds, anyone nearby will be struck by a devastating lightning bolt." invocations = list("V pnyy hcba lbh, Nzcrentr!!", "Yrg lbhe raretl sybj guebhtu zr!!", "Yrg lbhe obhaq-yrff cbjre fung-gre fgnef!!") channel_time = 150 required_components = list("belligerent_eye" = 3, "guvax_capacitor" = 3, "replicant_alloy" = 3, "hierophant_ansible" = 6) @@ -885,7 +961,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/invoke_nzcrentr/check_special_requirements() if(clockwork_generals_invoked["nzcrentr"]) - invoker << "\"Gur obff fnlf lbh unir gb jnvg. Url, qb lbh guvax ur jbhyq zvaq vs v xvyyrq lbh? ...Ur jbhyq? Bx.\"\n\ + invoker << "\"Gur obff fnlf lbh unir gb jnvg. Url, qb lbh guvax ur jbhyq zvaq vs v xvyyrq lbh? ...Ur jbhyq? Bx.\"\n\ Nzcrentr has already been invoked recently! You must wait several minutes before calling upon the Forgotten Arbiter." return 0 return 1 @@ -894,20 +970,29 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed new/obj/effect/clockwork/general_marker/nzcrentr(get_turf(invoker)) clockwork_generals_invoked["nzcrentr"] = TRUE invoker.visible_message("[invoker] begins to radiate a blinding light!", \ - "\"Gur obff fnlf vg'f bxnl gb qb guvf. Qba'g oynzr zr vs lbh qvr sebz vg.\"\n\ + "\"Gur obff fnlf vg'f bxnl gb qb guvf. Qba'g oynzr zr vs lbh qvr sebz vg.\"\n \ You feel limitless power surging through you!") 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 spawn(88) invoker.visible_message("Massive bolts of energy emerge from across [invoker]'s body!", \ - "TOO... MUCH! CAN'T... TAKE IT!") + "\"V gbyq lbh lbh jbhyqa'g or noyr gb unaqyr vg.\"\n \ + TOO... MUCH! CAN'T... TAKE IT!") playsound(invoker, 'sound/magic/lightningbolt.ogg', 50, 0) animate(invoker, color = initial(invoker.color), time = 10) for(var/mob/living/L in range(5, invoker)) if(is_servant_of_ratvar(L)) continue - invoker.Beam(L, icon_state = "nzcrentrs_power", icon = 'icons/effects/beam.dmi', time = 5) - L.electrocute_act(rand(30, 50), "Nzcrentr's power") + invoker.Beam(L, icon_state = "nzcrentrs_power", icon = 'icons/effects/beam.dmi', time = 6) + if(iscarbon(L)) + L.electrocute_act(rand(30, 50), "Nzcrentr's power") + else + L.adjustFireLoss(rand(30, 50)) + L.visible_message( + "[src] was shocked by Nzcrentr's power!", \ + "You feel a powerful shock coursing through your body!", \ + "You hear a heavy electrical crack." \ + ) L.Weaken(8) playsound(L, 'sound/magic/LightningShock.ogg', 50, 0) spawn(3000) @@ -928,7 +1013,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/invoke_inathneq/check_special_requirements() if(clockwork_generals_invoked["inath-neq"]) - invoker << "\"V pnaabg yraq lbh zl nvq lrg, punzcvba. Cyrnfr or pnershy.\"\n\ + invoker << "\"V pnaabg yraq lbh zl nvq lrg, punzcvba. Cyrnfr or pnershy.\"\n\ Inath-Neq has already been invoked recently! You must wait several minutes before calling upon the Resonant Cogwheel." return 0 return 1 @@ -942,7 +1027,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed for(var/mob/living/L in range(7, invoker)) if(!is_servant_of_ratvar(L) || L.stat == DEAD) continue - L << "\"V yraq lbh zl nvq, punzcvba! Yrg tybel thvqr lbhe oybjf!\"\n\ + L << "\"V yraq lbh zl nvq, punzcvba! Yrg tybel thvqr lbhe oybjf!\"\n\ Inath-Neq's power flows through you!" L.maxHealth += 500 L.health += 500 @@ -991,19 +1076,19 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed /datum/clockwork_scripture/ark_of_the_clockwork_justiciar/scripture_effects() var/turf/T = get_turf(invoker) new/obj/effect/clockwork/general_marker/nezbere(T) - T.visible_message("\"Ratvar! Pbzr sbegu!\"") + T.visible_message("\"Ratvar, pbzr sbegu naq fuvar lbhe yvtug npebff guvf ernyz!\"") playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 20, 0) sleep(10) new/obj/effect/clockwork/general_marker/sevtug(T) - T.visible_message("\"Ratvar! Pbzr sbegu!\"") + T.visible_message("\"Ratvar, pbzr sbegu naq fubj guvf fgngvba lbhe qrpbengvat fxvyyf!\"") playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, 0) sleep(10) new/obj/effect/clockwork/general_marker/nzcrentr(T) - T.visible_message("\"Ratvar! Pbzr sbegu!\"") + T.visible_message("\"Ratvar, pbzr sbegu.\"") playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 40, 0) sleep(10) new/obj/effect/clockwork/general_marker/inathneq(T) - T.visible_message("\"Ratvar! Pbzr sbegu!\"") + T.visible_message("\"Ratvar, pbzr sbegu naq fubj lbhe freinagf lbhe zrepl!\"") playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 50, 0) sleep(10) new/obj/structure/clockwork/massive/celestial_gateway(T) diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index 0efe0f3dcf4..a836857ccfd 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -327,28 +327,342 @@ else return ..() -/obj/structure/clockwork/interdiction_lens //Interdiction lens: A powerful artifact that can massively disrupt electronics. Five-minute cooldown between uses. +/obj/structure/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/clockwork/powered/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + var/powered = total_accessable_power() + user << "It has access to [powered]W of power." + +/obj/structure/clockwork/powered/Destroy() + SSfastprocess.processing -= src + SSobj.processing -= src + return ..() + +/obj/structure/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/clockwork/powered/proc/toggle(fast_process, mob/living/user) + if(user) + if(!is_servant_of_ratvar(user)) + return 0 + user.visible_message("[user] [active ? "dis" : "en"]ables [src].", "You [active ? "dis" : "en"]able [src].") + active = !active + if(active) + icon_state = active_icon + if(fast_process) + SSfastprocess.processing |= src + else + SSobj.processing |= src + else + icon_state = inactive_icon + SSfastprocess.processing -= src + SSobj.processing -= src + + +/obj/structure/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/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 >= 50) + power += apccharge + return power + +/obj/structure/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/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power + if(!needs_power) + return 1 + if(amount <= 0) + return 0 + var/power = total_accessable_power() + if(!power || power < amount) + return 0 + return use_power(amount) + +/obj/structure/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 >= 50) + for(var/S in sigils_in_range) + var/obj/effect/clockwork/sigil/transmission/T = S + if(T.modify_charge(50)) + sigilpower -= 50 + amount -= 50 + var/apcpower = accessable_apc_power() + while(apcpower >= 50 && amount >= 50) + if(target_apc.cell.use(50)) + apcpower -= 50 + amount -= 50 + else + apcpower = 0 + if(amount) + return 0 + else + return 1 + + +/obj/structure/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 + break_message = "The prism collapses with a heavy thud!" + var/stored_alloy = 0 //250W = 1 alloy + var/max_alloy = 50000 + +/obj/structure/clockwork/powered/mending_motor/prefilled + stored_alloy = 5000 //starts with 20 alloy + +/obj/structure/clockwork/powered/mending_motor/total_accessable_power() + . = ..() + . += accessable_alloy_power() + +/obj/structure/clockwork/powered/mending_motor/proc/accessable_alloy_power() + return stored_alloy + +/obj/structure/clockwork/powered/mending_motor/use_power(amount) + var/alloypower = accessable_alloy_power() + while(alloypower >= 50 && amount >= 50) + stored_alloy -= 50 + alloypower -= 50 + amount -= 50 + return ..() + +/obj/structure/clockwork/powered/mending_motor/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + user << "It has [stored_alloy*0.004]/[max_alloy*0.004] units of replicant alloy, which is equivalent to [stored_alloy]W/[max_alloy]W of power." + +/obj/structure/clockwork/powered/mending_motor/process() + if(!..()) + visible_message("[src] emits an airy chuckling sound and falls dark!") + toggle() + return + for(var/atom/movable/M in range(5, src)) + if(istype(M, /mob/living/simple_animal/hostile/clockwork_marauder)) + var/mob/living/simple_animal/hostile/clockwork_marauder/E = M + if((E.health == E.maxHealth && !E.fatigue) || E.stat) + continue + if(!try_use_power(150)) + break + E.adjustBruteLoss(-E.maxHealth) //Instant because marauders don't usually take health damage + E.fatigue = max(0, E.fatigue - 15) + else if(istype(M, /mob/living/simple_animal/hostile/anima_fragment)) + var/mob/living/simple_animal/hostile/anima_fragment/F = M + if(F.health == F.maxHealth || F.stat) + continue + if(!try_use_power(200)) + break + F.adjustBruteLoss(-15) + else if(istype(M, /obj/structure/clockwork)) + var/obj/structure/clockwork/C = M + if(C.health == C.max_health) + continue + if(!try_use_power(250)) + break + C.health = min(C.health + 15, C.max_health) + 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(300)) + break + S.adjustBruteLoss(-15) + S.adjustFireLoss(-15) + return 1 + +/obj/structure/clockwork/powered/mending_motor/attack_hand(mob/living/user) + if(user.canUseTopic(src, be_close = 1)) + if(!total_accessable_power() < 300) + user << "[src] needs more power or replicant alloy to function!" + return 0 + toggle(0, user) + +/obj/structure/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 + 2500 > max_alloy) + user << "[src] is too full to accept any more alloy!" + return 0 + user.whisper("Genafzhgr vagb jngre.") + user.visible_message("[user] liquifies [I] and pours it onto [src].", \ + "You liquify [src] and pour it onto [src], transferring the alloy into its reserves.") + stored_alloy = stored_alloy + 2500 + user.drop_item() + qdel(I) + return 1 + else + return ..() + + +/obj/structure/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 + break_message = "The antenna break off, leaving a pile of shards!" + debris = list(/obj/item/clockwork/component/guvax_capacitor/antennae, /obj/item/clockwork/alloy_shards) + var/mania_messages = list("\"Tb ahgf.\"", "\"Gnxr n penpx ng penml.\"", "\"Znxr n ovq sbe vafnavgl.\"", "\"Trg xbbxl.\"", "\"Zbir gbjneqf znavn.\"", "\"Orpbzr orjvyqrerq.\"", "\"Jnk jvyq.\"", \ + "\"Tb ebhaq gur oraq.\"", "\"Ynaq va yhanpl.\"", "\"Gel qrzragvn.\"", "\"Fgevir gb trg n fperj ybbfr.\"") + var/compel_messages = list("\"Pbzr pybfre.\"", "\"Nccebnpu gur genafzvggre.\"", "\"Gbhpu gur nagraanr.\"", "\"V nyjnlf unir gb qrny jvgu vqvbgf. Zbir gbjneqf gur znavn zbgbe.\"", \ + "\"Nqinapr sbejneq naq cynpr lbhe urnq orgjrra gur nagraanr - gung'f nyy vg'f tbbq sbe.\"", "\"Vs lbh jrer fznegre, lbh'q or bire urer nyernql.\"", "\"Zbir SBEJNEQ, lbh sbby.\"") + var/mania_cost = 150 + +/obj/structure/clockwork/powered/mania_motor/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + user << "It requires 150W of power to run, and 450W of power to convert humans adjecent to it." + +/obj/structure/clockwork/powered/mania_motor/process() + if(!..()) + visible_message("[src] hums loudly, then the sockets at its base fall dark!") + playsound(src, 'sound/effects/screech.ogg', 20, 1) + toggle(0) + return + if(try_use_power(mania_cost)) + for(var/mob/living/carbon/human/H in range(10, src)) + if(!is_servant_of_ratvar(H)) + var/distance = get_dist(get_turf(src), get_turf(H)) + var/divided_distance = distance ? 100/distance : 100 + if(distance >= 4 && prob(divided_distance)) + H << "[pick(mania_messages)]" + switch(distance) + if(0 to 1) //how did you get someone on top of it + if(try_use_power(150)) + if(is_eligible_servant(H) && try_use_power(300)) + H << "\"Lbh ner zvar-naq-uvf, abj.\"" + add_servant_of_ratvar(H) + else if(H.getBrainLoss() >= H.maxHealth && !H.stat) + H.Paralyse(10) + H <<"\"Lbh jba'g qb. Tb gb fyrrc juvyr V gryy gurfr avgjvgf ubj gb pbaireg lbh.\"" + else + H.adjustBrainLoss(100) + else + visible_message("[src]'s antennae fizzle quietly.") + playsound(src, 'sound/effects/light_flicker.ogg', 50, 1) + if(2 to 3) + if(prob(divided_distance)) + if(prob(divided_distance)) + H << "[pick(mania_messages)]" + else + H << "[pick(compel_messages)]" + H.adjustBrainLoss(divided_distance) + H.adjust_drugginess(divided_distance) + H.hallucination += divided_distance + if(4 to 5) + H.adjustBrainLoss(rand(10, 20)) + H.adjust_drugginess(rand(30, 40)) + H.hallucination += rand(30, 40) + if(6 to 7) + H.adjustBrainLoss(rand(5, 10)) + if(prob(100/distance)) + H.adjust_drugginess(rand(20, 30)) + else + H.hallucination += rand(20, 30) + if(8 to 9) + H.adjustBrainLoss(rand(1, 5)) + if(prob(100/distance)) + H.adjust_drugginess(rand(10, 20)) + else + H.hallucination += rand(10, 20) + if(10) + if(prob(100/distance)) + H.adjust_drugginess(rand(5, 10)) + else + H.hallucination += rand(5, 10) + else + if(H.getBrainLoss() || H.hallucination || H.druggy) + H.adjustBrainLoss(-H.getBrainLoss()) //heals + H.hallucination = 0 + H.adjust_drugginess(-H.druggy) + else + visible_message("[src] hums loudly, then the sockets at its base fall dark!") + playsound(src, 'sound/effects/screech.ogg', 20, 1) + toggle(0) + return + +/obj/structure/clockwork/powered/mania_motor/attack_hand(mob/living/user) + if(user.canUseTopic(src, be_close = 1)) + if(!total_accessable_power() < mania_cost) + user << "[src] needs more power to function!" + return 0 + toggle(0, user) + +/obj/structure/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that can massively disrupt electronics. Five-minute cooldown between uses. name = "interdiction lens" desc = "An ominous, double-pronged brass obelisk. There's a strange gemstone clasped between the pincers." clockwork_desc = "A powerful obelisk that can devastate certain electronics. It needs to recharge between uses." icon_state = "interdiction_lens" construction_value = 25 + active_icon = "interdiction_lens_inactive" + inactive_icon = "interdiction_lens" break_message = "The lens flares a blinding violet before shattering!" break_sound = 'sound/effects/Glassbr3.ogg' - var/recharging = FALSE //If the lens is still recharging its energy + var/recharging = 0 //world.time when the lens was last used + var/recharge_time = 3000 //time, in deciseconds, the lens needs to recharge; 5 minutes by default + var/disrupt_cost = 1000 //how much power to use -/obj/structure/clockwork/interdiction_lens/examine(mob/user) +/obj/structure/clockwork/powered/interdiction_lens/examine(mob/user) ..() - user << "Its gemstone [recharging ? "has been breached by writhing tendrils of blackness that cover the obelisk" : "vibrates in place and thrums with power"]," + user << "Its gemstone [recharging >= world.time ? "has been breached by writhing tendrils of blackness that cover the obelisk" \ + : "vibrates in place and thrums with power"]." -/obj/structure/clockwork/interdiction_lens/attack_hand(mob/living/user) +/obj/structure/clockwork/powered/interdiction_lens/attack_hand(mob/living/user) if(user.canUseTopic(src)) disrupt(user) -/obj/structure/clockwork/interdiction_lens/proc/disrupt(mob/living/user) +/obj/structure/clockwork/powered/interdiction_lens/process() + if(..() && recharging < world.time) //if we have power and have finished charging + visible_message("The writhing tendrils return to the gemstone, which begins to glow with power.") + flick("[initial(icon_state)]_recharged", src) + toggle() + +/obj/structure/clockwork/powered/interdiction_lens/proc/disrupt(mob/living/user) if(!user || !is_servant_of_ratvar(user)) return 0 - if(recharging) + if(!total_accessable_power() < disrupt_cost) + user << "[src] needs more power to function!" + return 0 + if(active || recharging >= world.time) user << "As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back." return 0 user.visible_message("[user] places their hand on [src]' gemstone...", "You place your hand on the gemstone...") @@ -356,11 +670,13 @@ if(!user.canUseTopic(src) || !target) user.visible_message("[user] pulls their hand back.", "On second thought, maybe not right now.") return 0 + if(!try_use_power(disrupt_cost)) + user.visible_message("The len flickers once, but nothing happens.", "The lens lacks the power to activate.") + return 0 user.visible_message("Violet tendrils engulf [user]'s arm as the gemstone glows with furious energy!", \ "A mass of violet tendrils cover your arm as [src] unleashes a blast of power!") user.notransform = TRUE icon_state = "[initial(icon_state)]_active" - recharging = TRUE sleep(30) switch(target) if("Disrupt Telecommunications") @@ -369,14 +685,14 @@ M << "You sense a strange force pass through you..." H.visible_message("The lights on [H] flare a blinding yellow before falling dark!") H.emp_act(1) - if("Disable Cameras") - for(var/obj/machinery/camera/C in cameranet.cameras) - C.emp_act(1) - for(var/mob/living/silicon/ai/A in living_mob_list) - A << "Massive energy surge detected. All cameras offline." - A << 'sound/machines/warning-buzzer.ogg' + if("Disable Cameras") + for(var/obj/machinery/camera/C in cameranet.cameras) + C.emp_act(1) + for(var/mob/living/silicon/ai/A in living_mob_list) + A << "Massive energy surge detected. All cameras offline." + A << 'sound/machines/warning-buzzer.ogg' if("Disable Cyborgs") - for(var/mob/living/silicon/robot/R in living_mob_list) //Doesn't include AIs, for obvious reasons + for(var/mob/living/silicon/robot/R in living_mob_list) if(is_servant_of_ratvar(R) || R.stat) //Doesn't affect already-offline cyborgs continue R.visible_message("[R] shuts down with no warning!", \ @@ -386,120 +702,59 @@ user.visible_message("The tendrils around [user]'s arm turn to an onyx black and wither away!", \ "The tendrils around your arm turn a horrible black and sting your skin before they shrivel away.") user.notransform = FALSE - if(!src) - return 0 + recharging = world.time + recharge_time flick("[initial(icon_state)]_discharged", src) - icon_state = "[initial(icon_state)]_recharging" - spawn(3000) //5 minutes - if(!src) - return 0 - visible_message("The writhing tendrils return to the gemstone, which begins to glow with power.") - flick("[initial(icon_state)]_recharged", src) - icon_state = initial(icon_state) - recharging = FALSE + toggle() return 1 -/obj/structure/clockwork/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" +/obj/structure/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 - break_message = "The prism collapses with a heavy thud!" - var/stored_alloy = 0 - var/max_alloy = 150 - var/uses_alloy = TRUE - var/active = TRUE + break_message = "The obelisk breaks apart in midair!" + debris = list(/obj/item/clockwork/alloy_shards) + var/hierophant_cost = 50 //how much it costs to broadcast with large text + var/gateway_cost = 2000 //how much it costs to open a gateway -/obj/structure/clockwork/mending_motor/prefilled - stored_alloy = 30 - -/obj/structure/clockwork/mending_motor/New() +/obj/structure/clockwork/powered/clockwork_obelisk/New() ..() - SSobj.processing += src - toggle() //Toggles off as soon as it's created, but starts online for reasons + toggle(1) -/obj/structure/clockwork/mending_motor/Destroy() - SSobj.processing -= src - ..() - -/obj/structure/clockwork/mending_motor/examine(mob/user) - ..() - if(is_servant_of_ratvar(user) || isobserver(user)) - user << "It has [stored_alloy]/[max_alloy] units of replicant alloy." - -/obj/structure/clockwork/mending_motor/process() - if(!active) - return 0 - if(!stored_alloy && uses_alloy) - visible_message("[src] emits an airy chuckling sound and falls dark!") - toggle() - return 0 - for(var/atom/movable/M in range(5, src)) - if(istype(M, /mob/living/simple_animal/hostile/anima_fragment)) - var/mob/living/simple_animal/hostile/anima_fragment/F = M - if(F.health == F.maxHealth || F.stat) - continue - F.adjustBruteLoss(-15) - if(uses_alloy) - stored_alloy = max(0, stored_alloy - 2) - else if(istype(M, /mob/living/simple_animal/hostile/clockwork_marauder)) - var/mob/living/simple_animal/hostile/clockwork_marauder/E = M - if((E.health == E.maxHealth && !E.fatigue) || E.stat) - continue - E.adjustBruteLoss(-E.maxHealth) //Instant because marauders don't usually take health damage - E.fatigue = max(0, E.fatigue - 15) - if(uses_alloy) - stored_alloy = max(0, stored_alloy - 2) - else if(istype(M, /mob/living/silicon)) - var/mob/living/silicon/S = M - if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S)) - continue - S.adjustBruteLoss(-25) - S.adjustFireLoss(-25) - if(uses_alloy) - stored_alloy = max(0, stored_alloy - 5) //Much higher cost because silicons are much more useful - else if(istype(M, /obj/structure/clockwork)) - var/obj/structure/clockwork/C = M - if(C.health == C.max_health) - continue - C.health = min(C.health + 10, C.max_health) - if(uses_alloy) - stored_alloy = max(0, stored_alloy - 1) - return 1 - -/obj/structure/clockwork/mending_motor/attack_hand(mob/living/user) - if(user.canUseTopic(src)) //Unnecessary? - if(!stored_alloy) - user << "[src] needs more replicant alloy to function!" - return 0 - toggle(user) - -/obj/structure/clockwork/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 + 10 > max_alloy) - user << "[src] is too full to accept any more alloy!" - return 0 - user.whisper("Genafzhgr vagb jngre.") - user.visible_message("[user] liquifies [I] and pours it onto [src].", \ - "You liquify [src] and pour it onto [src], which transfers the alloy into its reserves.") - stored_alloy = min(max(0, stored_alloy + 10), max_alloy) - user.drop_item() - qdel(I) - return 1 +/obj/structure/clockwork/powered/clockwork_obelisk/process() + if(locate(/obj/effect/clockwork/spatial_gateway) in loc) + icon_state = active_icon + density = 0 else - return ..() + icon_state = inactive_icon + density = 1 + +/obj/structure/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user) + if(!total_accessable_power() < hierophant_cost) + user << "You place your hand on the obelisk, but it doesn't react." + return + var/choice = alert(user,"You place your hand on the obelisk...",,"Hierophant Broadcast","Spacial Gateway","Cancel") + switch(choice) + if("Hierophant Broadcast") + var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "") + if(user.canUseTopic(src, be_close = 1)) + if(try_use_power(hierophant_cost)) + send_hierophant_message(user, input, 1) + else + user << "The obelisk lacks the power to broadcast!" + if("Spacial Gateway") + if(total_accessable_power() >= gateway_cost) + if(procure_gateway(user, 100, 5, 1)) + user.say("Fcnpvny tngrjnl, npgvingr!") + try_use_power(gateway_cost) + else + user << "The obelisk lacks the power to open a gateway!" + if("Cancel") + return -/obj/structure/clockwork/mending_motor/proc/toggle(mob/living/user) - if(user) - if(!is_servant_of_ratvar(user)) - return 0 - user.visible_message("[user] [active ? "dis" : "en"]ables [src].", "You [active ? "dis" : "en"]able [src].") - active = !active - if(active) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]_inactive" /obj/structure/clockwork/wall_gear name = "massive gear" @@ -599,7 +854,7 @@ qdel(src) //set up a gateway with another gateway -/obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, uses, two_way) +/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 @@ -612,8 +867,8 @@ gatewayB.sender = FALSE lifetime = set_duration gatewayB.lifetime = set_duration - uses = uses - gatewayB.uses = uses + uses = set_uses + gatewayB.uses = set_uses return 1 /obj/effect/clockwork/spatial_gateway/examine(mob/user) @@ -672,7 +927,7 @@ 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, uses - 1) + linked_gateway.uses = max(0, linked_gateway.uses - 1) spawn(10) if(!uses) qdel(src) @@ -700,7 +955,7 @@ icon = 'icons/effects/340x428.dmi' icon_state = "nezbere" pixel_x = -154 - pixel_y = -192 + pixel_y = -198 /obj/effect/clockwork/general_marker/sevtug name = "Sevtug, the Formless Pariah" @@ -708,8 +963,8 @@ 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 = -113 - pixel_y = -131 + pixel_x = -89 + pixel_y = -107 /obj/effect/clockwork/general_marker/nzcrentr name = "Nzcrentr, the Forgotten Arbiter" @@ -718,8 +973,8 @@ insane. Nzcrentr seeks out any and all sentient life to slaughter it for sport." icon = 'icons/effects/254x361.dmi' icon_state = "nzcrentr" - pixel_x = -110 - pixel_y = -163 + pixel_x = -111 + pixel_y = -164 /obj/effect/clockwork/general_marker/inathneq name = "Inath-Neq, the Resonant Cogwheel" @@ -730,8 +985,9 @@ 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 = -91 - pixel_y = -199 + pixel_x = -77 + pixel_y = -174 + /obj/effect/clockwork/sigil //Sigils: Rune-like markings on the ground with various effects. name = "sigil" @@ -741,6 +997,7 @@ layer = LOW_OBJ_LAYER alpha = 50 var/affects_servants = FALSE + var/affects_stat = FALSE /obj/effect/clockwork/sigil/attack_hand(mob/user) if(iscarbon(user) && !user.stat && user.a_intent == "harm") @@ -753,7 +1010,7 @@ ..() if(isliving(AM)) var/mob/living/L = AM - if(!L.stat) + if(!L.stat || affects_stat) if(!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && affects_servants)) sigil_effects(L) return 1 @@ -780,7 +1037,7 @@ L.adjustBruteLoss(10) L.Weaken(5) L.Stun(5) - PoolOrNew(/obj/effect/overlay/temp/ratvar/transgression, get_turf(src)) + PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/transgression, get_turf(src)) qdel(src) return 1 @@ -794,7 +1051,7 @@ /obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L) visible_message("[src] begins to glow a piercing magenta!") - animate(src, color = "#EE54DE", time = 30) + animate(src, color = "#AF0AAF", time = 30) var/I = 0 while(I < 30 && get_turf(L) == get_turf(src)) I++ @@ -823,27 +1080,118 @@ /obj/effect/clockwork/sigil/transmission name = "suspicious sigil" - desc = "A barely-visible sigil. Things seem a bit quieter around it." - clockwork_desc = "A sigil that will listen for and transmit anything it hears." + 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 = "#6F6E5F" + color = "#EC8A2D" alpha = 75 - flags = HEAR - languages = ALL + var/power_charge = 4000 //starts with 4000W by default + +/obj/effect/clockwork/sigil/transmission/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + user << "It is storing [power_charge]W of power." /obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L) - for(var/mob/M in mob_list) - if(is_servant_of_ratvar(M) || isobserver(M)) - M << "Sigil of Transmission in [get_area(src)] crossed by [L.name]." - return 0 + if(power_charge) + L << "You feel a slight, static shock." + return 1 -/obj/effect/clockwork/sigil/transmission/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) - if(!message || !speaker) +/obj/effect/clockwork/sigil/transmission/New() + ..() + alpha = min(75 + power_charge*0.02, 255) + +/obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount) + if(power_charge - amount < 0) return 0 - var/parsed_message = "(Sigil of Tranmission in [get_area(src)]): [message]" - for(var/M in mob_list) - if(isobserver(M)) - var/link = FOLLOW_LINK(M, speaker) - M << "[link] [parsed_message]" - else if(is_servant_of_ratvar(M)) - M << parsed_message + 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 + affects_stat = TRUE + var/vitality = 0 + var/base_revive_cost = 25 + var/sigil_active = FALSE + +/obj/effect/clockwork/sigil/vitality/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + user << "It is storing [vitality] units of vitality." + user << "It requires at least [base_revive_cost] units of vitality to revive dead servants, in addition to any damage the servant has." + +/obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L) + if(L.suiciding || sigil_active || !is_servant_of_ratvar(L) && L.stat == DEAD) + return 0 + visible_message("[src] begins to glow bright blue!") + 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((!is_servant_of_ratvar(L) && L.stat != DEAD || (is_servant_of_ratvar(L) && vitality)) && get_turf(L) == get_turf(src)) + PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src)) + if(!is_servant_of_ratvar(L)) + var/vitality_drained = L.adjustToxLoss(4) + 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(vitality >= revival_cost) + L.revive(1, 1) + L.visible_message("[L] suddenly gets back up, their mouth dripping blue ichor!", "\"Lbh jvyy or bxnl, puvyq.\"") + vitality -= revival_cost + break + if(!total_damage) + break + var/vitality_for_cycle = min(vitality, 8) + + if(clone_to_heal && vitality_for_cycle) + var/healing = min(vitality_for_cycle, clone_to_heal) + vitality_for_cycle -= healing + L.adjustCloneLoss(-healing) + vitality -= 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 -= 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 -= 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 -= 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 -= healing + sleep(8) + + sigil_active = FALSE + animate(src, alpha = initial(alpha), time = 30) + visible_message("[src] slowly stops glowing!") diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm index 336ee93fcdb..5652e5b0be0 100644 --- a/code/game/gamemodes/clock_cult/clock_unsorted.dm +++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm @@ -13,6 +13,59 @@ usr.verbs -= /mob/living/carbon/human/proc/function_call return 1 +//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/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects) + if(!O.Adjacent(invoker)) //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 + if(O != src && (O.z <= ZLEVEL_SPACEMAX)) + 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) //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 + if(L.z <= ZLEVEL_SPACEMAX) + possible_targets[resultkey] = L + + if(!possible_targets.len) + invoker << "There are no other eligible targets for a Spacial Gateway!" + 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(!target || !invoker.canUseTopic(src, be_close = 1)) + return 0 + var/istargetobelisk = istype(target, /obj/structure/clockwork/powered/clockwork_obelisk) + if(istargetobelisk) + gateway_uses *= 2 + time_duration *= 2 + invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ + "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" : ""].") + var/obj/effect/clockwork/spatial_gateway/S1 = new(istype(src, /obj/structure/clockwork/powered/clockwork_obelisk) ? src.loc : get_step(invoker, invoker.dir)) + var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? target.loc : get_step(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("The air in front of [target] ripples before suddenly tearing open!") + return 1 + /* The Ratvarian Language diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 7b41f65a6a7..81e194a4454 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -184,19 +184,27 @@ pixel_y = -16 pixel_x = -16 -/obj/effect/overlay/temp/ratvar/transgression +/obj/effect/overlay/temp/ratvar/sigil + name = "glowing circle" icon = 'icons/effects/clockwork_effects.dmi' icon_state = "sigildull" + +/obj/effect/overlay/temp/ratvar/sigil/transgression color = "#FAE48C" layer = ABOVE_MOB_LAYER duration = 40 -/obj/effect/overlay/temp/ratvar/transgression/New() +/obj/effect/overlay/temp/ratvar/sigil/transgression/New() ..() var/oldtransform = transform animate(src, transform = matrix()*2, time = 5) animate(transform = oldtransform, alpha = 0, time = 25) +/obj/effect/overlay/temp/ratvar/sigil/vitality + color = "#1E8CE1" + icon_state = "sigilactiveoverlay" + layer = BELOW_MOB_LAYER + /obj/effect/overlay/temp/revenant name = "spooky lights" diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 7ecb3f6683f..a486fe94c7a 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -47,7 +47,7 @@ return -10 /mob/living/carbon/alien/adjustToxLoss(amount) - return + return 0 /mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire if(amount > 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2acca7c0b47..14e3adc45d1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -300,6 +300,7 @@ Sorry Giacom. Please don't be mad :( toxloss = Clamp(toxloss + amount, 0, maxHealth*2) if(updating_health) updatehealth() + return amount /mob/living/proc/setToxLoss(amount, updating_health=1) if(status_flags & GODMODE) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 4cf73cc7294..e55d8e2bf6f 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -113,13 +113,11 @@ //Cannot remove negative damage (i.e. apply damage) /obj/item/bodypart/proc/heal_damage(brute, burn, robotic) - if(robotic && status != ORGAN_ROBOTIC) // This makes organic limbs not heal when the proc is in Robotic mode. - brute = max(0, brute - 3) - burn = max(0, burn - 3) + if(robotic && status != ORGAN_ROBOTIC) //This makes organic limbs not heal when the proc is in Robotic mode. + return - if(!robotic && status == ORGAN_ROBOTIC) // This makes robolimbs not healable by chems. - brute = max(0, brute - 3) - burn = max(0, burn - 3) + if(!robotic && status == ORGAN_ROBOTIC) //This makes robolimbs not healable by chems. + return brute_dam = max(brute_dam - brute, 0) burn_dam = max(burn_dam - burn, 0) diff --git a/icons/effects/clockwork.dmi b/icons/effects/clockwork.dmi new file mode 100644 index 00000000000..ae4461cb211 Binary files /dev/null and b/icons/effects/clockwork.dmi differ diff --git a/icons/effects/clockwork_effects.dmi b/icons/effects/clockwork_effects.dmi index fbc158cef3f..d5d66801cee 100644 Binary files a/icons/effects/clockwork_effects.dmi and b/icons/effects/clockwork_effects.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 329346ad0a8..9391c0bc7b4 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index c27f5c38893..a8170ac623c 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -76,6 +76,16 @@ h1.alert, h2.alert {color: #000000;} .brass {color: #BE8700;} .heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;} .large_brass {color: #BE8700; font-size: 3;} +.big_brass {color: #BE8700; font-size: 3; font-weight: bold; font-style: italic;} +.alloy {color: #42474D;} +.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;} +.large_alloy {color: #42474D; font-size: 3;} +.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;} +.sevtug_small {color: #AF0AAF;} +.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;} +.inathneq_small {color: #1E8CE1;} +.nzcrentr {color: #FAE48C; font-weight: bold; font-style: italic;} +.nzcrentr_small {color: #FAE48C;} .revennotice {color: #1d2953;} .revenboldnotice {color: #1d2953; font-weight: bold;}