diff --git a/aurorastation.dme b/aurorastation.dme index bb215de7dfd..0ccd32496d8 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -306,6 +306,7 @@ #include "code\datums\looping_sounds\_looping_sound.dm" #include "code\datums\looping_sounds\machinery_sounds.dm" #include "code\datums\looping_sounds\thermal_drill.dm" +#include "code\datums\looping_sounds\revenant_rift.dm" #include "code\datums\observation\_debug.dm" #include "code\datums\observation\destroyed.dm" #include "code\datums\observation\equipped.dm" @@ -895,6 +896,7 @@ #include "code\game\objects\items\weapons\landmines.dm" #include "code\game\objects\items\weapons\manuals.dm" #include "code\game\objects\items\weapons\mop.dm" +#include "code\game\objects\items\weapons\neutralizer.dm" #include "code\game\objects\items\weapons\paint.dm" #include "code\game\objects\items\weapons\paiwire.dm" #include "code\game\objects\items\weapons\policetape.dm" diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index df03ed65000..32350fcba62 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -59,6 +59,7 @@ #define LANGUAGE_CULT "Cult" // NOT CULTISTS! #define LANGUAGE_OCCULT "Occult" #define LANGUAGE_REVENANT "Revenant" +#define LANGUAGE_REVENANT_RIFTSPEAK "Riftspeak" #define LANGUAGE_TERMINATOR "Hephaestus Darkcomms" // HKs. // Lesser-form Languages diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 36741ff7a79..a68e2aa461d 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -90,7 +90,7 @@ return ..() /datum/beam/proc/Draw() - var/Angle = round(Get_Angle(origin.x ? origin : get_turf(origin), target.x ? target : get_turf(target))) + var/Angle = round(Get_Angle(origin.z ? origin : get_turf(origin), target.z ? target : get_turf(target))) var/matrix/rot_matrix = matrix() rot_matrix.Turn(Angle) @@ -183,6 +183,13 @@ var/obj/effect/ebeam/B = beam B.color = COLOR_GRAY40 +// this simplified datum will work with timed beams that are held +/datum/beam/held/get_x_translation_vector() + return (world.icon_size * target_oldloc.x) - (world.icon_size * origin_oldloc.x) + +/datum/beam/held/get_y_translation_vector() + return (world.icon_size * target_oldloc.y) - (world.icon_size * origin_oldloc.y) + /obj/effect/ebeam mouse_opacity = 0 anchored = 1 @@ -197,10 +204,10 @@ owner = null return ..() -/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time = 3) +/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time = 3, beam_datum_type=/datum/beam) if(time >= INFINITY) crash_with("Tried to create beam with infinite time!") return null - var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) + var/datum/beam/newbeam = new beam_datum_type(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) INVOKE_ASYNC(newbeam, /datum/beam/.proc/Start) - return newbeam + return newbeam \ No newline at end of file diff --git a/code/datums/looping_sounds/revenant_rift.dm b/code/datums/looping_sounds/revenant_rift.dm new file mode 100644 index 00000000000..98458f8d222 --- /dev/null +++ b/code/datums/looping_sounds/revenant_rift.dm @@ -0,0 +1,7 @@ +/datum/looping_sound/revenant_rift + start_sound = list('sound/effects/psi/power_feedback.ogg' = 1) + start_length = 8 + mid_sounds = list('sound/ambience/tension/horror.ogg' = 1) + mid_length = 260 + end_sound = list('sound/effects/psi/power_feedback.ogg' = 1) + volume = 80 \ No newline at end of file diff --git a/code/game/antagonist/outsider/revenant.dm b/code/game/antagonist/outsider/revenant.dm index 8391cb89e92..6d1e35e931e 100644 --- a/code/game/antagonist/outsider/revenant.dm +++ b/code/game/antagonist/outsider/revenant.dm @@ -12,7 +12,22 @@ var/datum/antagonist/revenant/revenants = null hard_cap = 12 hard_cap_round = 12 + var/rifts_left = 3 + var/kill_count = 0 + var/obj/effect/portal/revenant/revenant_rift + /datum/antagonist/revenant/New() ..() - revenants = src \ No newline at end of file + revenants = src + +/datum/antagonist/revenant/proc/destroyed_rift() + revenants.revenant_rift = null + revenants.rifts_left-- + if(revenants.rifts_left <= 0) + command_announcement.Announce("Aurora, we aren't detecting any more rift energy signatures. Mop up the rest of the invaders. Good work.", "Bluespace Breach Alert") + +/proc/message_all_revenants(var/message) + for(var/thing in human_mob_list) + if(isrevenant(thing)) + to_chat(thing, message) \ No newline at end of file diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 9a7760bf224..866dec788a9 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -40,6 +40,13 @@ if(does_teleport) teleport(AM) +/obj/effect/portal/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/bluespace_neutralizer)) + user.visible_message("[user] collapses \the [src] with \the [I].", SPAN_NOTICE("You collapse \the [src] with \the [I].")) + qdel(src) + return + return ..() + /obj/effect/portal/attack_hand(mob/user) set waitfor = FALSE @@ -92,7 +99,7 @@ if(next_spawn < world.time) visible_message(SPAN_WARNING("\The [src] spits something out!")) for(var/thing in spawn_things) - var/spawn_path = text2path(thing) + var/spawn_path = thing var/atom/spawned_thing = new spawn_path(get_turf(src)) if(istype(spawned_thing, /obj/item/stack)) @@ -113,33 +120,137 @@ /obj/effect/portal/spawner/metal num_of_spawns = 3 spawn_things = list( - "/obj/item/stack/material/steel" = 10, - "/obj/item/stack/material/plasteel" = 5 - ) + /obj/item/stack/material/steel = 10, + /obj/item/stack/material/plasteel = 5 + ) /obj/effect/portal/spawner/rare_metal num_of_spawns = 4 spawn_things = list( - "/obj/item/stack/material/gold" = 2, - "/obj/item/stack/material/silver" = 2, - "/obj/item/stack/material/uranium" = 2, - "/obj/item/stack/material/diamond" = 1 - ) + /obj/item/stack/material/gold = 2, + /obj/item/stack/material/silver = 2, + /obj/item/stack/material/uranium = 2, + /obj/item/stack/material/diamond = 1 + ) + +/obj/effect/portal/spawner/silver + num_of_spawns = 3 + spawn_things = list( + /obj/item/stack/material/silver = 3 + ) + +/obj/effect/portal/spawner/gold + num_of_spawns = 3 + spawn_things = list( + /obj/item/stack/material/gold = 3 + ) /obj/effect/portal/spawner/phoron num_of_spawns = 3 spawn_things = list( - "/obj/item/stack/material/phoron" = 3 - ) + /obj/item/stack/material/phoron = 3 + ) /obj/effect/portal/spawner/monkey_cube num_of_spawns = 1 spawn_things = list( - "/obj/item/reagent_containers/food/snacks/monkeycube" = 4 - ) + /obj/item/reagent_containers/food/snacks/monkeycube = 4 + ) /obj/effect/portal/spawner/cow // debug but funny so im keeping it num_of_spawns = 1 spawn_things = list( - "/mob/living/simple_animal/cow" = 1 + /mob/living/simple_animal/cow = 1 ) + +#define COLOR_STAGE_FIVE "#163DFF" +#define COLOR_STAGE_FOUR "#0099ff" +#define COLOR_STAGE_THREE "#33eb33" +#define COLOR_STAGE_TWO "#F0FF2B" +#define COLOR_STAGE_ONE "#FF8D23" +#define COLOR_STAGE_ZERO "#FF0000" + +/obj/effect/portal/revenant + name = "bluespace rift" + desc = "A bluespace tear in space, reaching directly to another point within this region. This one looks like a one-way portal to here, don't come too close." + desc_info = "This is a bluespace rift. It is a node wherein revenants can seep into this locale. To destroy it, you must bring a bluespace neutralizer near it." + icon_state = "portal_g" + + does_teleport = FALSE + has_lifespan = FALSE + + color = COLOR_STAGE_FIVE + light_color = COLOR_STAGE_FIVE + light_power = 6 + light_range = 8 + + var/last_color_level = 5 + var/health_timer = 10 MINUTES // you need to reduce the health by standing near it with a neutralizer + var/datum/looping_sound/revenant_rift/soundloop + +/obj/effect/portal/revenant/Initialize(mapload) + . = ..() + if(revenants.revenant_rift) + return INITIALIZE_HINT_QDEL + var/turf/T = get_turf(src) + log_and_message_admins("Revenant Bluespace Rift spawned at \the [get_area(T)]", null, T) + revenants.revenant_rift = src + soundloop = new(list(src), FALSE) + soundloop.start() + +/obj/effect/portal/revenant/Destroy() + revenants.destroyed_rift() + visible_message(FONT_LARGE(SPAN_DANGER("\The [src] collapses!"))) + new /obj/random/highvalue/no_crystal(src) + new /obj/random/highvalue/no_crystal(src) + for(var/thing in contents) + var/obj/O = thing + O.forceMove(get_turf(src)) + O.throw_at_random(FALSE, 3, THROWNOBJ_KNOCKBACK_SPEED) + var/area/A = get_area(src) + message_all_revenants(FONT_LARGE(SPAN_WARNING("The rift keeping us here has been destroyed in [A.name]!"))) + QDEL_NULL(soundloop) + return ..() + +/obj/effect/portal/revenant/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/bluespace_neutralizer)) + to_chat(user, SPAN_WARNING("You need to activate \the [I] and keep it near \the [src] to collapse it.")) + return + return ..() + +/obj/effect/portal/revenant/proc/reduce_health(var/amount = 1) + health_timer -= amount + if(health_timer <= 0) + qdel(src) + return + update_icon() + +/obj/effect/portal/revenant/update_icon() + var/color_level = round((health_timer / 600) / 2) // this should give a value from 0 - 5 + if(color_level == last_color_level) + return + var/area/A = get_area(src) + message_all_revenants(FONT_LARGE(SPAN_WARNING("The rift keeping us here is being attacked in [A.name]!"))) + last_color_level = color_level + switch(color_level) + if(0) + color = COLOR_STAGE_ZERO + if(1) + color = COLOR_STAGE_ONE + if(2) + color = COLOR_STAGE_TWO + if(3) + color = COLOR_STAGE_THREE + if(4) + color = COLOR_STAGE_FOUR + if(5) + color = COLOR_STAGE_FIVE + light_color = color + update_light() + +#undef COLOR_STAGE_FIVE +#undef COLOR_STAGE_FOUR +#undef COLOR_STAGE_THREE +#undef COLOR_STAGE_TWO +#undef COLOR_STAGE_ONE +#undef COLOR_STAGE_ZERO \ No newline at end of file diff --git a/code/game/objects/items/weapons/neutralizer.dm b/code/game/objects/items/weapons/neutralizer.dm new file mode 100644 index 00000000000..6231f91709f --- /dev/null +++ b/code/game/objects/items/weapons/neutralizer.dm @@ -0,0 +1,55 @@ +/obj/item/bluespace_neutralizer + name = "bluespace neutralizer" + desc = "A strange device, supposedly capable of pre-emptively shutting down bluespace portals." + desc_info = "Click on it, or use it in-hand to activate it. Click on any portal-like structure to instantly close it. Stand near a bluespace rift while it's active to start the closing process." + icon = 'icons/obj/contained_items/tools/neutralizer.dmi' + icon_state = "neutralizer" + contained_sprite = TRUE + + var/tethered = FALSE // it needs to tether with the portal before it can start zapping + var/last_zap = 0 + var/active = FALSE + +/obj/item/bluespace_neutralizer/update_icon() + icon_state = "neutralizer[active ? "-a" : ""]" + +/obj/item/bluespace_neutralizer/attack_self(mob/user) + if(!active && !revenants.revenant_rift) + to_chat(user, SPAN_WARNING("\The [src] doesn't detect any large bluespace rifts in the region.")) + return + toggle(user) + +/obj/item/bluespace_neutralizer/proc/toggle(var/mob/user) + active = !active + if(active) + START_PROCESSING(SSprocessing, src) + else + STOP_PROCESSING(SSprocessing, src) + if(user) + to_chat(user, SPAN_NOTICE("You turn \the [src] [active ? "on" : "off"].")) + update_icon() + +/obj/item/bluespace_neutralizer/process() + if(active && !revenants.revenant_rift) + toggle() + return + var/turf/our_turf = get_turf(src) + if(!(our_turf.z == revenants.revenant_rift.z && get_dist(src, revenants.revenant_rift) < 5 && isInSight(src, revenants.revenant_rift))) + tethered = FALSE + return + if(!tethered) + visible_message(SPAN_DANGER("\The [src] tethers with \the [revenants.revenant_rift]!")) + last_zap = world.time + tethered = TRUE + Beam(revenants.revenant_rift, icon_state="n_beam", icon = 'icons/effects/beam.dmi', time=2, maxdistance=5, beam_datum_type=/datum/beam/held) + playsound(get_turf(src), 'sound/magic/Charge.ogg', 70, TRUE, extrarange = 30) + return + revenants.revenant_rift.reduce_health(world.time - last_zap) + last_zap = world.time + Beam(revenants.revenant_rift, icon_state="lightning[rand(1,12)]", icon = 'icons/effects/effects.dmi', time=2, maxdistance=5, beam_datum_type=/datum/beam/held) + playsound(get_turf(src), 'sound/magic/LightningShock.ogg', 50, TRUE, extrarange = 30) + +/obj/item/bluespace_neutralizer/Destroy() + if(active) + STOP_PROCESSING(SSprocessing, src) + return ..() \ No newline at end of file diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index b781621df2d..ded0cdca330 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -1108,6 +1108,21 @@ /obj/item/anomaly_core = 0.5 ) +/obj/random/highvalue/no_crystal + problist = list( + /obj/item/clothing/suit/armor/reactive = 0.5, + /obj/item/clothing/glasses/thermal = 0.5, + /obj/item/gun/projectile/automatic/rifle/shotgun = 0.5, + /obj/random/sword = 0.5, + /obj/item/gun/energy/lawgiver = 0.5, + /obj/item/melee/energy/axe = 0.5, + /obj/item/gun/projectile/automatic/terminator = 0.5, + /obj/item/rig/military = 0.5, + /obj/item/rig/unathi/fancy = 0.5, + /obj/item/rig/vaurca/minimal = 0.5, + /obj/item/anomaly_core = 0.5 + ) + /obj/random/junk name = "random trash" desc = "This is toss." diff --git a/code/modules/ghostroles/spawner/antagonist/revenant.dm b/code/modules/ghostroles/spawner/antagonist/revenant.dm index f3b7f7b9531..9e7e76bb279 100644 --- a/code/modules/ghostroles/spawner/antagonist/revenant.dm +++ b/code/modules/ghostroles/spawner/antagonist/revenant.dm @@ -17,6 +17,13 @@ var/spawn_index = 1 // used to add a numerical identifier to the revenant. increases by 1 per spawn var/has_fired = FALSE + var/first_rift_done = FALSE + +/datum/ghostspawner/revenant/cant_spawn(mob/user) + . = ..() + if(!. && revenants.rifts_left <= 0) + return "The final rift has been closed." + /datum/ghostspawner/revenant/spawn_mob(mob/user) var/turf/T = select_spawnlocation() var/mob/living/carbon/human/revenant/R @@ -34,8 +41,11 @@ R.ckey = user.ckey revenants.add_antagonist(R.mind, TRUE, TRUE, FALSE, TRUE, TRUE) + if(R.client) + to_chat(R, FONT_LARGE(SPAN_CULT("You can now speak with all revenants in the game world by using \"[R.client.prefs.language_prefixes[1]]rs\" before a message."))) if(!has_fired) INVOKE_ASYNC(src, .proc/play_ambience, R) + INVOKE_ASYNC(src, .proc/check_rift) return R @@ -46,4 +56,30 @@ continue M.playsound_simple(get_turf(M), 'sound/ambience/tension/tension.ogg', 75, FALSE) to_chat(M, FONT_LARGE(SPAN_CULT("A faint hum coming from the station walls fills your ears..."))) - has_fired = TRUE \ No newline at end of file + has_fired = TRUE + +/datum/ghostspawner/revenant/proc/check_rift() + if(revenants.revenant_rift || revenants.rifts_left <= 0) + return + var/kills_needed = ((initial(revenants.rifts_left) - revenants.rifts_left) + 1) * 5 + if(revenants.kill_count > kills_needed) + var/turf/rift_turf + var/list/possible_landmarks = list() + for(var/thing in landmarks_list) + var/obj/effect/landmark/landmark = thing + if(landmark.name == "RevenantRift") + possible_landmarks += landmark + if(length(possible_landmarks)) + var/obj/effect/landmark/L = pick(possible_landmarks) + rift_turf = get_turf(L) + if(rift_turf) + new /obj/effect/portal/revenant(rift_turf) + if(!first_rift_done) + command_announcement.Announce("Aurora, we're detecting energy signatures eerily similar to a bluespace rift breach inside your hull. [SScargo.shuttle ? "We're sending you a bluespace neutralizer via the cargo shuttle. " : ""]Locate the rift and shut it down.", "Bluespace Breach Alert") + first_rift_done = TRUE + if(SScargo.shuttle) + var/turf/T = pick_area_turf(pick(SScargo.shuttle.shuttle_area), list(/proc/not_turf_contains_dense_objects)) + if(T) + var/obj/structure/closet/crate/C = new /obj/structure/closet/crate(T) + C.name += " (Neutralizer)" + new /obj/item/bluespace_neutralizer(C) \ No newline at end of file diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index b090e13af08..8ea6c062da7 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -22,6 +22,7 @@ var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word var/machine_understands = TRUE // Whether machines can parse and understand this language var/allow_accents = FALSE + var/always_parse_language = FALSE // forces the language to parse for language keys even when a default is set /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index dba7d88c4e9..b060f549d3d 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -104,4 +104,11 @@ key = "c" syllables = list("grhhg", "ghrohg", "grgugh", "grrhh", "hghh", "rghghh", "gghhh", "ggrh", "aghrh") flags = RESTRICTED - partial_understanding = list(LANGUAGE_TCB = 80) \ No newline at end of file + partial_understanding = list(LANGUAGE_TCB = 80) + always_parse_language = TRUE + +/datum/language/revenant/hivemind + name = LANGUAGE_REVENANT_RIFTSPEAK + desc = "A manner of speaking that allows revenants to talk to eachother no matter the distance." + key = "rs" + flags = RESTRICTED | HIVEMIND \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/outsider/revenant.dm b/code/modules/mob/living/carbon/human/species/outsider/revenant.dm index 9b4c21a9fc7..b1f9d0746ef 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/revenant.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/revenant.dm @@ -101,6 +101,7 @@ if(player_is_antag(H.mind)) var/datum/ghostspawner/revenant/R = SSghostroles.get_spawner(MODE_REVENANT) R.count = max(R.count - 1, 0) + revenants.kill_count++ INVOKE_ASYNC(src, .proc/spawn_gore, get_turf(H)) H.set_death_time(ANIMAL, world.time) for(var/obj/item/I in H) @@ -108,6 +109,8 @@ qdel(H) /datum/species/revenant/proc/spawn_gore(var/turf/T) + var/portal_type = pick(/obj/effect/portal/spawner/silver, /obj/effect/portal/spawner/gold, /obj/effect/portal/spawner/phoron) + new portal_type(T) var/obj/effect/decal/cleanable/blood/gibs/G = new /obj/effect/decal/cleanable/blood/gibs(T) G.basecolor = blood_color G.fleshcolor = flesh_color @@ -119,6 +122,7 @@ ..() H.gender = NEUTER H.universal_understand = TRUE + H.add_language(LANGUAGE_REVENANT_RIFTSPEAK) /datum/species/revenant/get_random_name() return "Revenant" diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 990265b527f..c34a0a6c3e0 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -184,7 +184,7 @@ proc/get_radio_key_from_channel(var/channel) message = formalize_text(message) //parse the language code and consume it - if(!speaking) + if(!speaking || speaking.always_parse_language) speaking = parse_language(message) if(speaking) message = copytext(message,2+length(speaking.key)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index c8eb4c0ff3f..609463baaba 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -140,6 +140,14 @@ return TRUE return FALSE +/proc/isrevenant(A) + if(ishuman(A)) + var/mob/living/carbon/human/H = A + switch(H.get_species()) + if(SPECIES_REVENANT) + return TRUE + return FALSE + /proc/islesserform(A) if(istype(A, /mob/living/carbon/human)) switch(A:get_species()) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 84a6799e34d..c463b6d33d1 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -159,9 +159,12 @@ return all_languages["Noise"] if(length(message) >= 2 && is_language_prefix(prefix)) - var/language_prefix = lowertext(copytext(message, 2 ,3)) + var/language_prefix = lowertext(copytext(message, 2, 4)) var/datum/language/L = language_keys[language_prefix] - if (can_speak(L)) + if(!L) + language_prefix = lowertext(copytext(message, 2, 3)) + L = language_keys[language_prefix] + if(can_speak(L)) return L return null diff --git a/code/modules/research/designs/protolathe/tool_designs.dm b/code/modules/research/designs/protolathe/tool_designs.dm index 3cc1067955f..1ba935a8dce 100644 --- a/code/modules/research/designs/protolathe/tool_designs.dm +++ b/code/modules/research/designs/protolathe/tool_designs.dm @@ -143,4 +143,10 @@ datum/design/item/tool/advanced_light_replacer desc = "The infamously Idris Service Standard refers to this monstrous, self-stabilizing back-mounted utensil and service item holder, not anything professional." req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2) materials = list(DEFAULT_WALL_MATERIAL = 1500, MATERIAL_GLASS = 1500) - build_path = /obj/item/storage/backpack/service \ No newline at end of file + build_path = /obj/item/storage/backpack/service + +/datum/design/item/tool/bluespace_neutralizer + desc = "A state of the art bluespace neutralizer, capable of shutting down any bluespace portal it gets used on. A special mode exists for severe interdimensional breaches, but this is highly unlikely to be necessary." + req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2, TECH_BLUESPACE = 4) + materials = list(DEFAULT_WALL_MATERIAL = 20000, MATERIAL_GLASS = 20000, MATERIAL_SILVER = 20000, MATERIAL_GOLD = 20000, MATERIAL_PHORON = 10000) + build_path = /obj/item/bluespace_neutralizer \ No newline at end of file diff --git a/html/changelogs/geeves-revenant_portals.yml b/html/changelogs/geeves-revenant_portals.yml new file mode 100644 index 00000000000..e6436a11d9e --- /dev/null +++ b/html/changelogs/geeves-revenant_portals.yml @@ -0,0 +1,10 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Revenants now get a global language called Riftspeak, activated with ,rs , that lets them speak to all living revenants at once." + - rscadd: "Killing revenants now open portals that spew out usable materials." + - rscadd: "Killing a number of revenants will cause a bluespace rift to open, which needs to be closed with bluespace neutralizers. Once all the rifts close, revenants can no longer spawn." + - rscadd: "Added bluespace neutralizers, devices that can be used to quickly collapse portals. It can be made at the protolathe under the advanced tools section, needing materials, engineering, and bluespace tech." + - rscadd: "Added new portal sprites from /tg/station." \ No newline at end of file diff --git a/icons/obj/contained_items/tools/neutralizer.dmi b/icons/obj/contained_items/tools/neutralizer.dmi new file mode 100644 index 00000000000..b21fd667ed1 Binary files /dev/null and b/icons/obj/contained_items/tools/neutralizer.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index 4793ac16ef1..ed7a3762445 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm index d2b315ea7e6..69cc0ff28d4 100644 --- a/maps/aurora/aurora-4_mainlevel.dmm +++ b/maps/aurora/aurora-4_mainlevel.dmm @@ -2242,6 +2242,9 @@ "ael" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/generic, +/obj/effect/landmark{ + name = "RevenantRift" + }, /turf/simulated/floor/tiled/old, /area/maintenance/vault) "aem" = ( @@ -40818,6 +40821,9 @@ dir = 4 }, /obj/machinery/hologram/holopad, +/obj/effect/landmark{ + name = "RevenantRift" + }, /turf/simulated/floor/tiled/white, /area/medical/gen_treatment) "btf" = ( @@ -44130,6 +44136,9 @@ icon_state = "1-4" }, /obj/machinery/hologram/holopad, +/obj/effect/landmark{ + name = "RevenantRift" + }, /turf/simulated/floor/carpet/rubber, /area/rnd/misc_lab) "bzM" = ( @@ -59667,6 +59676,23 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/bar) +"cWR" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/tiled, +/area/engineering/foyer) "cXE" = ( /obj/item/device/taperecorder{ pixel_x = 3; @@ -60208,6 +60234,12 @@ }, /turf/simulated/floor/plating, /area/maintenance/bar) +"edU" = ( +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "eeM" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -60333,6 +60365,13 @@ /obj/machinery/firealarm/west, /turf/simulated/floor/reinforced, /area/assembly/chargebay) +"eyb" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/tiled, +/area/quartermaster/lobby) "eye" = ( /obj/structure/window/reinforced{ dir = 8 @@ -61867,6 +61906,16 @@ }, /turf/simulated/floor/plating, /area/maintenance/medbay) +"hAB" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/wood, +/area/maintenance/bar) "hAQ" = ( /obj/structure/table/standard, /obj/effect/decal/cleanable/dirt, @@ -61992,6 +62041,12 @@ }, /turf/simulated/floor/tiled, /area/quartermaster/storage) +"hNs" = ( +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/tiled, +/area/outpost/mining_main/refinery) "hND" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -62615,6 +62670,12 @@ }, /turf/simulated/floor/plating, /area/maintenance/atmos_control) +"jmf" = ( +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/alphadeck) "jnD" = ( /obj/structure/table/wood, /turf/simulated/floor/carpet, @@ -63064,6 +63125,13 @@ }, /turf/simulated/floor/plating, /area/maintenance/vault) +"kzh" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/plating, +/area/maintenance/research_port) "kzl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 @@ -89799,7 +89867,7 @@ bbs tow bPL bQi -bPs +kzh bRp bPs oUD @@ -90001,7 +90069,7 @@ aFK oMh oKJ aLb -aMS +cWR aOI aQq aQq @@ -95980,7 +96048,7 @@ bXc bXs bXs bXZ -bXs +eyb bXs bXs bZk @@ -96261,7 +96329,7 @@ cez cgf cgx cgg -cgg +hNs cgg cgg chH @@ -98511,7 +98579,7 @@ bve bve bve bve -bve +jmf bve bve bve @@ -101374,7 +101442,7 @@ bWa bWo bWa bWa -bWa +edU bWa bWa wVv @@ -106505,7 +106573,7 @@ bEK tYo bRY sOQ -dQv +hAB eGj eGj bUk diff --git a/maps/runtime/runtime-1.dmm b/maps/runtime/runtime-1.dmm index 9f100204793..86db23b067b 100644 --- a/maps/runtime/runtime-1.dmm +++ b/maps/runtime/runtime-1.dmm @@ -1518,6 +1518,15 @@ }, /turf/simulated/floor/plating, /area/maintenance/maintcentral) +"pM" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/obj/effect/landmark{ + name = "RevenantRift" + }, +/turf/simulated/floor/tiled, +/area/storage/primary) "pX" = ( /obj/structure/cable{ d1 = 16; @@ -3461,7 +3470,7 @@ da da dl dc -do +pM dt du dl