////////////////////////// // CLOCKWORK STRUCTURES // ////////////////////////// /obj/structure/clockwork name = "meme structure" desc = "Some frog or something, the fuck?" var/clockwork_desc //Shown to servants when they examine icon = 'icons/obj/clockwork_objects.dmi' icon_state = "rare_pepe" anchored = 1 density = 1 opacity = 0 layer = BELOW_OBJ_LAYER var/max_health = 100 //All clockwork structures have health that can be removed via attacks var/health = 100 var/repair_amount = 5 //how much a proselytizer can repair each cycle var/can_be_repaired = TRUE //if a proselytizer can repair it at all var/takes_damage = TRUE //If the structure can be damaged var/break_message = "The frog isn't a meme after all!" //The message shown when a structure breaks var/break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks var/list/debris = list(/obj/item/clockwork/alloy_shards) //Parts left behind when a structure breaks var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station /obj/structure/clockwork/New() ..() clockwork_construction_value += construction_value all_clockwork_objects += src /obj/structure/clockwork/Destroy() clockwork_construction_value -= construction_value all_clockwork_objects -= src return ..() /obj/structure/clockwork/proc/destroyed() if(!takes_damage) return 0 for(var/I in debris) new I (get_turf(src)) visible_message(break_message) playsound(src, break_sound, 50, 1) qdel(src) return 1 /obj/structure/clockwork/burn() SSobj.burning -= src if(takes_damage) playsound(src, 'sound/items/Welder.ogg', 100, 1) visible_message("[src] is warped by the heat!") take_damage(rand(50, 100), BURN) /obj/structure/clockwork/proc/take_damage(amount, damage_type) if(!amount || !damage_type || !damage_type in list(BRUTE, BURN)) return 0 if(takes_damage) health = max(0, health - amount) if(!health) destroyed() return 1 return 0 /obj/structure/clockwork/narsie_act() if(take_damage(rand(25, 50), BRUTE) && src) //if we still exist var/previouscolor = color color = "#960000" animate(src, color = previouscolor, time = 8) /obj/structure/clockwork/ex_act(severity) var/damage = 0 switch(severity) if(1) damage = max_health //100% max health lost if(2) damage = max_health * rand(0.5, 0.7) //50-70% max health lost if(3) damage = max_health * rand(0.1, 0.3) //10-30% max health lost if(damage) take_damage(damage, BRUTE) /obj/structure/clockwork/examine(mob/user) var/can_see_clockwork = is_servant_of_ratvar(user) || isobserver(user) if(can_see_clockwork && clockwork_desc) desc = clockwork_desc ..() desc = initial(desc) if(takes_damage) var/servant_message = "It is at [health]/[max_health] integrity" var/other_message = "It seems pristine and undamaged" var/heavily_damaged = FALSE var/healthpercent = (health/max_health) * 100 if(healthpercent >= 100) other_message = "It seems pristine and undamaged" else if(healthpercent >= 50) other_message = "It looks slightly dented" else if(healthpercent >= 25) other_message = "It appears heavily damaged" heavily_damaged = TRUE else if(healthpercent >= 0) other_message = "It's falling apart" heavily_damaged = TRUE user << "[can_see_clockwork ? "[servant_message]":"[other_message]"][heavily_damaged ? "!":"."]" /obj/structure/clockwork/bullet_act(obj/item/projectile/P) . = ..() visible_message("[src] is hit by \a [P]!") playsound(src, P.hitsound, 50, 1) take_damage(P.damage, P.damage_type) /obj/structure/clockwork/proc/attack_generic(mob/user, damage = 0, damage_type = BRUTE) //used by attack_alien, attack_animal, and attack_slime user.do_attack_animation(src) user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] smashes into [src]!") take_damage(damage, damage_type) /obj/structure/clockwork/attack_alien(mob/living/user) playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1) attack_generic(user, 15) /obj/structure/clockwork/attack_animal(mob/living/simple_animal/M) if(!M.melee_damage_upper) return playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) attack_generic(M, M.melee_damage_upper, M.melee_damage_type) /obj/structure/clockwork/attack_slime(mob/living/simple_animal/slime/user) if(!user.is_adult) return playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) attack_generic(user, rand(10, 15)) /obj/structure/clockwork/attacked_by(obj/item/I, mob/living/user) . = ..() if(I.force && takes_damage) playsound(src, I.hitsound, 50, 1) take_damage(I.force, I.damtype) /obj/structure/clockwork/mech_melee_attack(obj/mecha/M) if(..()) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) take_damage(M.force, M.damtype) /obj/structure/clockwork/cache //Tinkerer's cache: Stores components for later use. name = "tinkerer's cache" desc = "A large brass spire with a flaming hole in its center." clockwork_desc = "A brass container capable of storing a large amount of components.\n\ Shares components with all other caches and will gradually generate components if near a Clockwork Wall." icon_state = "tinkerers_cache" construction_value = 10 break_message = "The cache's fire winks out before it falls in on itself!" max_health = 80 health = 80 var/wall_generation_cooldown var/wall_found = FALSE //if we've found a wall and finished our windup delay /obj/structure/clockwork/cache/New() ..() START_PROCESSING(SSobj, src) clockwork_caches++ set_light(2,1) /obj/structure/clockwork/cache/Destroy() clockwork_caches-- STOP_PROCESSING(SSobj, src) return ..() /obj/structure/clockwork/cache/destroyed() if(takes_damage) for(var/I in src) var/atom/movable/A = I A.forceMove(get_turf(src)) //drop any daemons we have return ..() /obj/structure/clockwork/cache/process() for(var/turf/closed/wall/clockwork/C in orange(1, src)) if(!wall_found) wall_found = TRUE wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME visible_message("[src] starts to whirr in the presence of [C]...") break if(wall_generation_cooldown <= world.time) wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME generate_cache_component() playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1) visible_message("Something clunks around inside of [src]...") break /obj/structure/clockwork/cache/attackby(obj/item/I, mob/living/user, params) if(!is_servant_of_ratvar(user)) return ..() if(istype(I, /obj/item/clockwork/component)) var/obj/item/clockwork/component/C = I clockwork_component_cache[C.component_id]++ user << "You add [C] to [src]." user.drop_item() qdel(C) return 1 else if(istype(I, /obj/item/clockwork/slab)) var/obj/item/clockwork/slab/S = I clockwork_component_cache["belligerent_eye"] += S.stored_components["belligerent_eye"] clockwork_component_cache["vanguard_cogwheel"] += S.stored_components["vanguard_cogwheel"] clockwork_component_cache["guvax_capacitor"] += S.stored_components["guvax_capacitor"] clockwork_component_cache["replicant_alloy"] += S.stored_components["replicant_alloy"] clockwork_component_cache["hierophant_ansible"] += S.stored_components["hierophant_ansible"] S.stored_components["belligerent_eye"] = 0 S.stored_components["vanguard_cogwheel"] = 0 S.stored_components["guvax_capacitor"] = 0 S.stored_components["replicant_alloy"] = 0 S.stored_components["hierophant_ansible"] = 0 user.visible_message("[user] empties [S] into [src].", "You offload your slab's components into [src].") return 1 else if(istype(I, /obj/item/clockwork/daemon_shell)) var/component_type switch(alert(user, "Will this daemon produce a specific type of component or produce randomly?.", , "Specific Type", "Random Component")) if("Specific Type") switch(input(user, "Choose a component type.", name) as null|anything in list("Belligerent Eyes", "Vanguard Cogwheels", "Guvax Capacitors", "Replicant Alloys", "Hierophant Ansibles")) if("Belligerent Eyes") component_type = "belligerent_eye" if("Vanguard Cogwheels") component_type = "vanguard_cogwheel" if("Guvax Capacitors") component_type = "guvax_capacitor" if("Replicant Alloys") component_type = "replicant_alloy" if("Hierophant Ansibles") component_type = "hierophant_ansibles" if(!user || !user.canUseTopic(src) || !user.canUseTopic(I)) return 0 var/obj/item/clockwork/tinkerers_daemon/D = new(src) D.cache = src D.specific_component = component_type user.visible_message("[user] spins the cogwheel on [I] and puts it into [src].", \ "You activate the daemon and put it into [src]. It will now produce a component every twenty seconds.") user.drop_item() qdel(I) return 1 else return ..() /obj/structure/clockwork/cache/attack_hand(mob/user) if(!is_servant_of_ratvar(user)) return 0 var/list/possible_components = list() if(clockwork_component_cache["belligerent_eye"]) possible_components += "Belligerent Eye" if(clockwork_component_cache["vanguard_cogwheel"]) possible_components += "Vanguard Cogwheel" if(clockwork_component_cache["guvax_capacitor"]) possible_components += "Guvax Capacitor" if(clockwork_component_cache["replicant_alloy"]) possible_components += "Replicant Alloy" if(clockwork_component_cache["hierophant_ansible"]) possible_components += "Hierophant Ansible" if(!possible_components.len) user << "[src] is empty!" return 0 var/component_to_withdraw = input(user, "Choose a component to withdraw.", name) as null|anything in possible_components if(!user || !user.canUseTopic(src) || !component_to_withdraw) return 0 var/obj/item/clockwork/component/the_component switch(component_to_withdraw) if("Belligerent Eye") if(clockwork_component_cache["belligerent_eye"]) the_component = new/obj/item/clockwork/component/belligerent_eye(get_turf(src)) clockwork_component_cache["belligerent_eye"]-- if("Vanguard Cogwheel") if(clockwork_component_cache["vanguard_cogwheel"]) the_component = new/obj/item/clockwork/component/vanguard_cogwheel(get_turf(src)) clockwork_component_cache["vanguard_cogwheel"]-- if("Guvax Capacitor") if(clockwork_component_cache["guvax_capacitor"]) the_component = new/obj/item/clockwork/component/guvax_capacitor(get_turf(src)) clockwork_component_cache["guvax_capacitor"]-- if("Replicant Alloy") if(clockwork_component_cache["replicant_alloy"]) the_component = new/obj/item/clockwork/component/replicant_alloy(get_turf(src)) clockwork_component_cache["replicant_alloy"]-- if("Hierophant Ansible") if(clockwork_component_cache["hierophant_ansible"]) the_component = new/obj/item/clockwork/component/hierophant_ansible(get_turf(src)) clockwork_component_cache["hierophant_ansible"]-- if(the_component) user.visible_message("[user] withdraws [the_component] from [src].", "You withdraw [the_component] from [src].") user.put_in_hands(the_component) return 1 /obj/structure/clockwork/cache/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) user << "Stored components:" user << "Belligerent Eyes: [clockwork_component_cache["belligerent_eye"]]" user << "Vanguard Cogwheels: [clockwork_component_cache["vanguard_cogwheel"]]" user << "Guvax Capacitors: [clockwork_component_cache["guvax_capacitor"]]" user << "Replicant Alloys: [clockwork_component_cache["replicant_alloy"]]" user << "Hierophant Ansibles: [clockwork_component_cache["hierophant_ansible"]]" /obj/structure/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with. name = "ocular warden" desc = "A large brass eye with tendrils trailing below it and a wide red iris." clockwork_desc = "A stalwart turret that will deal sustained damage to any non-faithful it sees." icon_state = "ocular_warden" health = 25 max_health = 25 construction_value = 15 layer = HIGH_OBJ_LAYER break_message = "The warden's eye gives a glare of utter hate before falling dark!" debris = list(/obj/item/clockwork/component/belligerent_eye/blind_eye) burn_state = LAVA_PROOF var/damage_per_tick = 3 var/sight_range = 3 var/mob/living/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/clockwork/ocular_warden/New() ..() START_PROCESSING(SSfastprocess, src) /obj/structure/clockwork/ocular_warden/Destroy() STOP_PROCESSING(SSfastprocess, src) return ..() /obj/structure/clockwork/ocular_warden/examine(mob/user) ..() user << "[target ? "It's fixated on [target]!" : "Its gaze is wandering aimlessly."]" /obj/structure/clockwork/ocular_warden/process() var/list/validtargets = acquire_nearby_targets() if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned damage_per_tick = 10 sight_range = 5 if(target) if(!(target in validtargets)) lose_target() else if(!target.null_rod_check()) target.adjustFireLoss(!iscultist(target) ? damage_per_tick : damage_per_tick * 2) //Nar-Sian cultists take additional damage if(ratvar_awakens && target) target.adjust_fire_stacks(damage_per_tick) target.IgniteMob() setDir(get_dir(get_turf(src), get_turf(target))) if(!target) if(validtargets.len) target = pick(validtargets) visible_message("[src] swivels to face [target]!") target << "\"I SEE YOU!\"\n[src]'s gaze [ratvar_awakens ? "melts you alive" : "burns you"]!" if(target.null_rod_check() && !ratvar_awakens) target << "Your artifact glows hotly against you, protecting you from the warden's gaze!" else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes if(prob(50)) visible_message("[src][pick(idle_messages)]") else setDir(pick(cardinal))//Random rotation /obj/structure/clockwork/ocular_warden/proc/acquire_nearby_targets() . = list() for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind if(!is_servant_of_ratvar(L) && !L.stat && L.mind && !(L.disabilities & BLIND) && !L.null_rod_check()) . += L /obj/structure/clockwork/ocular_warden/proc/lose_target() if(!target) return 0 target = null visible_message("[src] settles and seems almost disappointed.") return 1 /obj/structure/clockwork/shell construction_value = 0 anchored = 0 density = 0 takes_damage = FALSE burn_state = LAVA_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/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 << "[S] hasn't trapped a spirit! Turn it on first." return 0 if(S.brainmob && (!S.brainmob.client || !S.brainmob.mind)) user << "[S]'s trapped spirit appears inactive!" return 0 user.visible_message("[user] places [S] in [src], where it fuses to the shell.", "You place [S] in [src], fusing it to the shell.") var/mob/living/simple_animal/A = new mobtype(get_turf(src)) A.visible_message("[src][spawn_message]") S.brainmob.mind.transfer_to(A) add_servant_of_ratvar(A, TRUE) user.drop_item() qdel(S) qdel(src) return 1 else return ..() /obj/structure/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/clockwork/shell/fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct. name = "fragment shell" desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power." clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct." icon_state = "anime_fragment" mobtype = /mob/living/simple_animal/hostile/clockwork/fragment spawn_message = " whirs and rises from the ground on a flickering jet of reddish fire." /obj/structure/clockwork/wall_gear name = "massive gear" icon_state = "wall_gear" climbable = TRUE max_health = 50 health = 50 desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it." clockwork_desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, just climb over it, or proselytize it into replicant alloy." break_message = "The gear breaks apart into shards of alloy!" debris = list(/obj/item/clockwork/alloy_shards) /obj/structure/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 return ..() /obj/structure/clockwork/wall_gear/examine(mob/user) ..() user << "[src] is [anchored ? "secured to the floor":"mobile, and not secured"]." /////////////////////// // CLOCKWORK EFFECTS // /////////////////////// /obj/effect/clockwork name = "meme machine" desc = "Still don't know what it is." var/clockwork_desc = "A fabled artifact from beyond the stars. Contains concentrated meme essence." //Shown to clockwork cultists instead of the normal description icon = 'icons/effects/clockwork_effects.dmi' icon_state = "ratvars_flame" anchored = 1 density = 0 opacity = 0 burn_state = LAVA_PROOF /obj/effect/clockwork/New() ..() all_clockwork_objects += src /obj/effect/clockwork/Destroy() all_clockwork_objects -= src return ..() /obj/effect/clockwork/examine(mob/user) if((is_servant_of_ratvar(user) || isobserver(user)) && clockwork_desc) desc = clockwork_desc ..() desc = initial(desc) /obj/effect/clockwork/judicial_marker //Judicial marker: Created by the judicial visor. After three seconds, stuns any non-servants nearby and damages Nar-Sian cultists. name = "judicial marker" desc = "You get the feeling that you shouldn't be standing here." clockwork_desc = "A sigil that will soon erupt and smite any unenlightened nearby." icon = 'icons/effects/96x96.dmi' pixel_x = -32 pixel_y = -32 layer = BELOW_MOB_LAYER var/mob/user /obj/effect/clockwork/judicial_marker/New(loc, caster) ..() user = caster playsound(src, 'sound/magic/MAGIC_MISSILE.ogg', 50, 1, 1, 1) flick("judicial_marker", src) addtimer(src, "burstanim", 16, FALSE) /obj/effect/clockwork/judicial_marker/proc/burstanim() layer = ABOVE_ALL_MOB_LAYER flick("judicial_explosion", src) addtimer(src, "judicialblast", 13, FALSE) /obj/effect/clockwork/judicial_marker/proc/judicialblast() var/targetsjudged = 0 playsound(src, 'sound/effects/explosionfar.ogg', 100, 1, 1, 1) for(var/mob/living/L in range(1, src)) if(is_servant_of_ratvar(L)) continue if(L.null_rod_check()) var/obj/item/I = L.null_rod_check() L.visible_message("Strange energy flows into [L]'s [I.name]!", \ "Your [I.name] shields you from [src]!") continue if(!iscultist(L)) L.visible_message("[L] is struck by a judicial explosion!", \ "[!issilicon(L) ? "An unseen force slams you into the ground!" : "ERROR: Motor servos disabled by external source!"]") L.Weaken(8) else L.visible_message("[L] is struck by a judicial explosion!", \ "\"Keep an eye out, filth.\"\nA burst of heat crushes you against the ground!") L.Weaken(4) //half the stun, but sets cultists on fire L.adjust_fire_stacks(2) L.IgniteMob() targetsjudged++ L.adjustBruteLoss(10) user << "[targetsjudged ? "Successfully judged [targetsjudged]":"Judged no"] heretic[!targetsjudged || targetsjudged > 1 ? "s":""]." QDEL_IN(src, 3) //so the animation completes properly /obj/effect/clockwork/judicial_marker/ex_act(severity) return /obj/effect/clockwork/spatial_gateway //Spatial gateway: A usually one-way rift to another location. name = "spatial gateway" desc = "A gently thrumming tear in reality." clockwork_desc = "A gateway in reality." icon_state = "spatial_gateway" density = 1 var/sender = TRUE //If this gateway is made for sending, not receiving var/both_ways = FALSE var/lifetime = 25 //How many deciseconds this portal will last var/uses = 1 //How many objects or mobs can go through the portal var/obj/effect/clockwork/spatial_gateway/linked_gateway //The gateway linked to this one /obj/effect/clockwork/spatial_gateway/New() ..() spawn(1) if(!linked_gateway) qdel(src) return 0 if(both_ways) clockwork_desc = "A gateway in reality. It can both send and receive objects." else clockwork_desc = "A gateway in reality. It can only [sender ? "send" : "receive"] objects." QDEL_IN(src, lifetime) //set up a gateway with another gateway /obj/effect/clockwork/spatial_gateway/proc/setup_gateway(obj/effect/clockwork/spatial_gateway/gatewayB, set_duration, set_uses, two_way) if(!gatewayB || !set_duration || !uses) return 0 linked_gateway = gatewayB gatewayB.linked_gateway = src if(two_way) both_ways = TRUE gatewayB.both_ways = TRUE else sender = TRUE gatewayB.sender = FALSE gatewayB.density = FALSE lifetime = set_duration gatewayB.lifetime = set_duration uses = set_uses gatewayB.uses = set_uses return 1 /obj/effect/clockwork/spatial_gateway/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) user << "It has [uses] uses remaining." /obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user) if(user.pulling && user.a_intent == "grab" && isliving(user.pulling)) var/mob/living/L = user.pulling if(L.buckled || L.anchored || L.has_buckled_mobs()) return 0 user.visible_message("[user] shoves [L] into [src]!", "You shove [L] into [src]!") user.stop_pulling() pass_through_gateway(L) return 1 if(!user.canUseTopic(src)) return 0 user.visible_message("[user] climbs through [src]!", "You brace yourself and step through [src]...") pass_through_gateway(user) return 1 /obj/effect/clockwork/spatial_gateway/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/weapon/nullrod)) user.visible_message("[user] dispels [src] with [I]!", "You close [src] with [I]!") qdel(linked_gateway) qdel(src) return 1 if(istype(I, /obj/item/clockwork/slab)) user << "\"I don't think you want to drop your slab into that\".\n\"If you really want to, try throwing it.\"" return 1 if(user.drop_item()) user.visible_message("[user] drops [I] into [src]!", "You drop [I] into [src]!") pass_through_gateway(I) ..() /obj/effect/clockwork/spatial_gateway/Bumped(atom/A) ..() if(isliving(A) || istype(A, /obj/item)) pass_through_gateway(A) /obj/effect/clockwork/spatial_gateway/proc/pass_through_gateway(atom/movable/A) if(!linked_gateway) qdel(src) return 0 if(!sender) visible_message("[A] bounces off of [src]!") return 0 if(!uses) return 0 if(isliving(A)) var/mob/living/user = A user << "You pass through [src] and appear elsewhere!" linked_gateway.visible_message("A shape appears in [linked_gateway] before emerging!") playsound(src, 'sound/effects/EMPulse.ogg', 50, 1) playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1) transform = matrix() * 1.5 animate(src, transform = matrix() / 1.5, time = 10) linked_gateway.transform = matrix() * 1.5 animate(linked_gateway, transform = matrix() / 1.5, time = 10) A.forceMove(get_turf(linked_gateway)) uses = max(0, uses - 1) linked_gateway.uses = max(0, linked_gateway.uses - 1) spawn(10) if(!uses) qdel(src) qdel(linked_gateway) return 1 /obj/effect/clockwork/general_marker name = "general marker" desc = "Some big guy. For you." clockwork_desc = "One of Ratvar's generals." alpha = 200 layer = MASSIVE_OBJ_LAYER /obj/effect/clockwork/general_marker/New() ..() playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, 0) animate(src, alpha = 0, time = 10) QDEL_IN(src, 10) /obj/effect/clockwork/general_marker/nezbere name = "Nezbere, the Brass Eidolon" desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you." clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain." icon = 'icons/effects/340x428.dmi' icon_state = "nezbere" pixel_x = -154 pixel_y = -198 /obj/effect/clockwork/general_marker/sevtug name = "Sevtug, the Formless Pariah" desc = "A sinister cloud of purple energy. Looking at it gives you a headache." clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies." icon = 'icons/effects/211x247.dmi' icon_state = "sevtug" pixel_x = -89 pixel_y = -107 /obj/effect/clockwork/general_marker/nzcrentr name = "Nzcrentr, the Forgotten Arbiter" desc = "A terrifying war machine crackling with limitless energy." clockwork_desc = "One of Ratvar's four generals. Nzcrentr is the result of Neovgre - Nezbere's finest war machine, commandeerable only be a mortal - fusing with its pilot and driving her \ insane. Nzcrentr seeks out any and all sentient life to slaughter it for sport." icon = 'icons/effects/254x361.dmi' icon_state = "nzcrentr" pixel_x = -111 pixel_y = -164 /obj/effect/clockwork/general_marker/inathneq name = "Inath-Neq, the Resonant Cogwheel" desc = "A humanoid form blazing with blue fire. It radiates an aura of kindness and caring." clockwork_desc = "One of Ratvar's four generals. Before her current form, Inath-Neq was a powerful warrior priestess commanding the Resonant Cogs, a sect of Ratvarian warriors renowned for \ their prowess. After a lost battle with Nar-Sian cultists, Inath-Neq was struck down and stated in her dying breath, \ \"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-Neq an eternal body and \ merged her soul with those of the Cogs slain with her on the battlefield." icon = 'icons/effects/187x381.dmi' icon_state = "inath-neq" pixel_x = -77 pixel_y = -174 /obj/effect/clockwork/sigil //Sigils: Rune-like markings on the ground with various effects. name = "sigil" desc = "A strange set of markings drawn on the ground." clockwork_desc = "A sigil of some purpose." icon_state = "sigil" layer = LOW_OBJ_LAYER alpha = 50 burn_state = FIRE_PROOF burntime = 1 var/affects_servants = FALSE var/stat_affected = CONSCIOUS /obj/effect/clockwork/sigil/attack_hand(mob/user) if(iscarbon(user) && !user.stat && (!is_servant_of_ratvar(user) || (is_servant_of_ratvar(user) && user.a_intent == "harm"))) user.visible_message("[user] stamps out [src]!", "You stomp on [src], scattering it into thousands of particles.") qdel(src) return 1 ..() /obj/effect/clockwork/sigil/Crossed(atom/movable/AM) ..() if(isliving(AM)) var/mob/living/L = AM if(L.stat <= stat_affected) if((!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && affects_servants)) && L.mind) if(L.null_rod_check()) var/obj/item/I = L.null_rod_check() L.visible_message("[L]'s [I.name] protects them from [src]'s effects!", "Your [I.name] protects you!") return sigil_effects(L) return 1 /obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L) /obj/effect/clockwork/sigil/transgression //Sigil of Transgression: Stuns and flashes the first non-servant to walk on it. Nar-Sian cultists are damaged and knocked down for about twice the stun name = "dull sigil" desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground." icon = 'icons/effects/clockwork_effects.dmi' clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down." icon_state = "sigildull" color = "#FAE48C" /obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L) var/target_flashed = L.flash_eyes() for(var/mob/living/M in viewers(5, src)) if(!is_servant_of_ratvar(M) && M != L) M.flash_eyes() if(iscultist(L)) L << "\"Watch your step, wretch.\"" L.adjustBruteLoss(10) L.Weaken(4) L.visible_message("[src] appears around [L] in a burst of light!", \ "[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!") L.Stun(3) PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/transgression, get_turf(src)) qdel(src) return 1 /obj/effect/clockwork/sigil/submission //Sigil of Submission: After a short time, converts any non-servant standing on it. Knocks down and silences them for five seconds afterwards. name = "ominous sigil" desc = "A luminous golden sigil. Something about it really bothers you." clockwork_desc = "A sigil that will enslave the first person to cross it, provided they remain on it for five seconds." icon_state = "sigilsubmission" color = "#FAE48C" alpha = 125 stat_affected = UNCONSCIOUS var/convert_time = 50 var/glow_light = 2 //soft light var/glow_falloff = 1 var/delete_on_finish = TRUE var/sigil_name = "Sigil of Submission" var/glow_type /obj/effect/clockwork/sigil/submission/New() ..() set_light(glow_light,glow_falloff) /obj/effect/clockwork/sigil/submission/proc/post_channel(mob/living/L) /obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L) visible_message("[src] begins to glow a piercing magenta!") animate(src, color = "#AF0AAF", time = convert_time) var/obj/effect/overlay/temp/ratvar/sigil/glow if(glow_type) glow = PoolOrNew(glow_type, get_turf(src)) animate(glow, alpha = 255, time = convert_time) var/I = 0 while(I < convert_time && get_turf(L) == get_turf(src)) I++ sleep(1) if(get_turf(L) != get_turf(src)) if(glow) qdel(glow) animate(src, color = initial(color), time = 20) visible_message("[src] slowly stops glowing!") return 0 post_channel(L) if(is_eligible_servant(L)) L << "\"You belong to me now.\"" add_servant_of_ratvar(L) L.Weaken(3) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with L.Stun(3) if(iscarbon(L)) var/mob/living/carbon/C = L C.silent += 5 var/message = "[sigil_name] in [get_area(src)] [is_servant_of_ratvar(L) ? "successfully converted" : "failed to convert"]" for(var/M in mob_list) if(isobserver(M)) var/link = FOLLOW_LINK(M, L) M << "[link] [message] [L.real_name]!" else if(is_servant_of_ratvar(M)) if(M == L) M << "[message] you!" else M << "[message] [L.real_name]!" if(delete_on_finish) qdel(src) else animate(src, color = initial(color), time = 20) visible_message("[src] slowly stops glowing!") return 1 /obj/effect/clockwork/sigil/submission/accession //Sigil of Accession: After a short time, converts any non-servant standing on it though implants. Knocks down and silences them for five seconds afterwards. name = "terrifying sigil" desc = "A luminous brassy sigil. Something about it makes you want to flee." clockwork_desc = "A sigil that will enslave any person who crosses it, provided they remain on it for five seconds. \n\ It can convert a mindshielded target once before disppearing, but can convert any number of non-implanted targets." icon_state = "sigiltransgression" color = "#A97F1B" alpha = 200 glow_light = 4 //bright light glow_falloff = 3 delete_on_finish = FALSE sigil_name = "Sigil of Accession" glow_type = /obj/effect/overlay/temp/ratvar/sigil/accession /obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L) if(isloyal(L)) delete_on_finish = TRUE L.visible_message("[L] visibly trembles!", \ "Lbh jvyy or zvar-naq-uvf. Guvf chal gevaxrg jvyy abg fgbc zr.") for(var/obj/item/weapon/implant/mindshield/M in L) if(M.implanted) qdel(M) /obj/effect/clockwork/sigil/transmission name = "suspicious sigil" desc = "A glowing orange sigil. The air around it feels staticky." clockwork_desc = "A sigil that will serve as a battery for clockwork structures. Use Volt Void while standing on it to charge it." icon_state = "sigiltransmission" color = "#EC8A2D" alpha = 50 var/power_charge = 2500 //starts with 2500W 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) if(power_charge) L << "You feel a slight, static shock." return 1 /obj/effect/clockwork/sigil/transmission/New() ..() alpha = min(initial(alpha) + power_charge*0.02, 255) /obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount) if(power_charge - amount < 0) return 0 power_charge -= amount alpha = min(initial(alpha) + power_charge*0.02, 255) return 1 /obj/effect/clockwork/sigil/vitality name = "comforting sigil" desc = "A faint blue sigil. Looking at it makes you feel protected." clockwork_desc = "A sigil that will drain non-servants that remain on it. Servants that remain on it will be healed if it has any vitality drained." icon_state = "sigilvitality" color = "#123456" alpha = 75 affects_servants = TRUE stat_affected = DEAD var/vitality = 0 var/base_revive_cost = 20 var/sigil_active = FALSE var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets /obj/effect/clockwork/sigil/vitality/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) user << "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(L && (!is_servant_of_ratvar(L) && L.stat != DEAD || (is_servant_of_ratvar(L) && vitality)) && get_turf(L) == get_turf(src)) if(animation_number >= 4) PoolOrNew(/obj/effect/overlay/temp/ratvar/sigil/vitality, get_turf(src)) animation_number = 0 animation_number++ if(!is_servant_of_ratvar(L)) var/vitality_drained = L.adjustToxLoss(1.5) if(vitality_drained) vitality += vitality_drained else break else var/clone_to_heal = L.getCloneLoss() var/tox_to_heal = L.getToxLoss() var/burn_to_heal = L.getFireLoss() var/brute_to_heal = L.getBruteLoss() var/oxy_to_heal = L.getOxyLoss() var/total_damage = clone_to_heal + tox_to_heal + burn_to_heal + brute_to_heal + oxy_to_heal if(L.stat == DEAD) var/revival_cost = base_revive_cost + total_damage - oxy_to_heal //ignores oxygen damage var/mob/dead/observer/ghost = L.get_ghost(TRUE) if(ghost) if(vitality >= revival_cost) ghost.reenter_corpse() L.revive(1, 1) playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1) L.visible_message("[L] suddenly gets back up, their mouth dripping blue ichor!", "\"Lbh jvyy or bxnl, puvyq.\"") vitality -= revival_cost break else break if(!total_damage) break var/vitality_for_cycle = min(vitality, 3) if(clone_to_heal && vitality_for_cycle) var/healing = min(vitality_for_cycle, clone_to_heal) vitality_for_cycle -= healing L.adjustCloneLoss(-healing) vitality -= 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(2) animation_number = initial(animation_number) sigil_active = FALSE animate(src, alpha = initial(alpha), time = 20) visible_message("[src] slowly stops glowing!")