diff --git a/baystation12.dme b/baystation12.dme index e7a6e232030..75e3fabb6c0 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -117,6 +117,7 @@ #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\supply.dm" #include "code\controllers\Processes\ticker.dm" +#include "code\controllers\Processes\turf.dm" #include "code\controllers\Processes\vote.dm" #include "code\controllers\ProcessScheduler\core\_define.dm" #include "code\controllers\ProcessScheduler\core\_stubs.dm" @@ -268,12 +269,17 @@ #include "code\game\gamemodes\cult\cult.dm" #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm" +#include "code\game\gamemodes\cult\hell_universe.dm" #include "code\game\gamemodes\cult\ritual.dm" #include "code\game\gamemodes\cult\runes.dm" #include "code\game\gamemodes\cult\talisman.dm" #include "code\game\gamemodes\cult\cultify\mob.dm" #include "code\game\gamemodes\cult\cultify\obj.dm" #include "code\game\gamemodes\cult\cultify\turf.dm" +#include "code\game\gamemodes\endgame\endgame.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\blob.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\portal.dm" +#include "code\game\gamemodes\endgame\supermatter_cascade\universe.dm" #include "code\game\gamemodes\events\black_hole.dm" #include "code\game\gamemodes\events\clang.dm" #include "code\game\gamemodes\events\dust.dm" @@ -1252,6 +1258,7 @@ #include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm" #include "code\modules\mob\living\simple_animal\friendly\tomato.dm" #include "code\modules\mob\living\simple_animal\hostile\alien.dm" +#include "code\modules\mob\living\simple_animal\hostile\bat.dm" #include "code\modules\mob\living\simple_animal\hostile\bear.dm" #include "code\modules\mob\living\simple_animal\hostile\carp.dm" #include "code\modules\mob\living\simple_animal\hostile\creature.dm" @@ -1369,6 +1376,7 @@ #include "code\modules\power\rust\virtual_particle_catcher.dm" #include "code\modules\power\sensors\powernet_sensor.dm" #include "code\modules\power\sensors\sensor_monitoring.dm" +#include "code\modules\power\singularity\act.dm" #include "code\modules\power\singularity\collector.dm" #include "code\modules\power\singularity\containment_field.dm" #include "code\modules\power\singularity\emitter.dm" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 45618f2ffce..bc06c3d239c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -27,6 +27,11 @@ if(A.name == N) return A return 0 + +/proc/get_area_master(const/O) + var/area/A = get_area(O) + if (isarea(A)) + return A.master /proc/in_range(source, user) if(get_dist(source, user) <= 1) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 50c08172e1d..7484d016b6c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -54,6 +54,12 @@ var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) var/list/datum/visualnet/visual_nets = list() var/datum/visualnet/camera/cameranet = new() var/datum/visualnet/cult/cultnet = new() + +// Runes +var/global/list/rune_list = new() +var/global/list/escape_list = list() +var/global/list/endgame_exits = list() +var/global/list/endgame_safespawns = list() ////////////////////////// /////Initial Building///// ////////////////////////// diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 69f46a4c9aa..900e89e7e75 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -48,6 +48,11 @@ #define ui_monkey_mask "5:14,1:5" //monkey #define ui_monkey_back "6:14,1:5" //monkey +#define ui_construct_health "15:00,7:15" //same height as humans, hugging the right border +#define ui_construct_purge "15:00,6:15" +#define ui_construct_fire "14:16,8:13" //above health, slightly to the left +#define ui_construct_pull "14:28,2:10" //above the zone_sel icon + //Lower right, persistant menu #define ui_dropbutton "11:22,1:5" #define ui_drop_throw "14:28,2:7" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 01ead8282c6..466a9e28754 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -249,7 +249,11 @@ datum/hud/New(mob/owner) robot_hud() else if(isobserver(mymob)) ghost_hud() + else + mymob.instantiate_hud(src) +/mob/proc/instantiate_hud(var/datum/hud/HUD) + return //Triggered when F12 is pressed (Unless someone changed something in the DMF) /mob/verb/button_pressed_F12(var/full = 0 as null) diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index 3f785d8a83b..5dd1b542cfa 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -101,3 +101,59 @@ mymob.client.screen += src.adding return + +/mob/living/simple_animal/construct/instantiate_hud(var/datum/hud/HUD) + HUD.construct_hud() + +/datum/hud/proc/construct_hud() + var/constructtype + + if(istype(mymob,/mob/living/simple_animal/construct/armoured) || istype(mymob,/mob/living/simple_animal/construct/behemoth)) + constructtype = "juggernaut" + else if(istype(mymob,/mob/living/simple_animal/construct/builder)) + constructtype = "artificer" + else if(istype(mymob,/mob/living/simple_animal/construct/wraith)) + constructtype = "wraith" + else if(istype(mymob,/mob/living/simple_animal/construct/harvester)) + constructtype = "harvester" + + mymob.flash = new /obj/screen() + mymob.flash.icon = 'icons/mob/screen1.dmi' + mymob.flash.icon_state = "blank" + mymob.flash.name = "flash" + mymob.flash.screen_loc = "1,1 to 15,15" + mymob.flash.layer = 17 + + if(constructtype) + mymob.fire = new /obj/screen() + mymob.fire.icon = 'icons/mob/screen1_construct.dmi' + mymob.fire.icon_state = "fire0" + mymob.fire.name = "fire" + mymob.fire.screen_loc = ui_construct_fire + + mymob.healths = new /obj/screen() + mymob.healths.icon = 'icons/mob/screen1_construct.dmi' + mymob.healths.icon_state = "[constructtype]_health0" + mymob.healths.name = "health" + mymob.healths.screen_loc = ui_construct_health + + mymob.pullin = new /obj/screen() + mymob.pullin.icon = 'icons/mob/screen1_construct.dmi' + mymob.pullin.icon_state = "pull0" + mymob.pullin.name = "pull" + mymob.pullin.screen_loc = ui_construct_pull + + mymob.zone_sel = new /obj/screen/zone_sel() + mymob.zone_sel.icon = 'icons/mob/screen1_construct.dmi' + mymob.zone_sel.overlays.len = 0 + mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]") + + mymob.purged = new /obj/screen() + mymob.purged.icon = 'icons/mob/screen1_construct.dmi' + mymob.purged.icon_state = "purge0" + mymob.purged.name = "purged" + mymob.purged.screen_loc = ui_construct_purge + + mymob.client.screen = null + + mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged, mymob.flash) diff --git a/code/controllers/Processes/turf.dm b/code/controllers/Processes/turf.dm new file mode 100644 index 00000000000..c1efac52f97 --- /dev/null +++ b/code/controllers/Processes/turf.dm @@ -0,0 +1,9 @@ +var/global/list/processing_turfs = list() + +/datum/controller/process/turf/setup() + name = "turf" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/turf/doWork() + for(var/turf/unsimulated/wall/supermatter/SM in processing_turfs) + SM.process() diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm index efa2a226b1f..6eeecef90de 100644 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ b/code/controllers/_DynamicAreaLighting_TG.dm @@ -323,6 +323,7 @@ turf/proc/shift_to_subarea() A.SetLightLevel(level, color_light) A.contents += src // move the turf into the area + universe.OnTurfTick(src) // Dedicated lighting sublevel for space turfs // helps us depower things in space, remove space fire alarms, diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 33dfc36f7f7..4f55d3e4063 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -114,6 +114,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle priority_announcement.Announce("The scheduled crew transfer has been cancelled.") /datum/emergency_shuttle_controller/proc/can_call() + if (!universe.OnShuttleCall(null)) + return 0 if (deny_shuttle) return 0 if (shuttle.moving_status != SHUTTLE_IDLE || !shuttle.location) //must be idle at centcom diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm index 8fd4f3cd808..3f5d65d21da 100644 --- a/code/game/antagonist/station/cultist.dm +++ b/code/game/antagonist/station/cultist.dm @@ -24,6 +24,7 @@ var/datum/antagonist/cultist/cult flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE max_antags = 200 // No upper limit. max_antags_round = 200 + var/allow_narsie = 1 var/datum/mind/sacrifice_target var/list/startwords = list("blood","join","self","hell") diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index e59ad21e84f..cbd3f221a32 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -2025,6 +2025,7 @@ area/space/atmosalert() luminosity = 1 lighting_use_dynamic = 0 requires_power = 0 + ambience = list() var/sound/mysound = null New() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 960a75d4fb5..5944587cc78 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -229,6 +229,9 @@ its easier to just keep the beam vertical. /atom/proc/fire_act() return + +/atom/proc/melt() + return /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 517c8728ed9..185dc99ebd2 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -92,6 +92,7 @@ density = 1 unacidable = 1 anchored = 1.0 + var/spawnable = null /obj/effect/gateway/Bumped(mob/M as mob|obj) spawn(0) @@ -102,3 +103,73 @@ spawn(0) return return + +/obj/effect/gateway/active + luminosity=5 + l_color="#ff0000" + spawnable=list( + /mob/living/simple_animal/hostile/scarybat, + /mob/living/simple_animal/hostile/creature, + /mob/living/simple_animal/hostile/faithless + ) + +/obj/effect/gateway/active/cult + luminosity=5 + l_color="#ff0000" + spawnable=list( + /mob/living/simple_animal/hostile/scarybat/cult, + /mob/living/simple_animal/hostile/creature/cult, + /mob/living/simple_animal/hostile/faithless/cult + ) + +/obj/effect/gateway/active/cult/cultify() + return + +/obj/effect/gateway/active/New() + spawn(rand(30,60) SECONDS) + var/t = pick(spawnable) + new t(src.loc) + qdel(src) + +/obj/effect/gateway/active/Crossed(var/atom/A) + if(!istype(A, /mob/living)) + return + + var/mob/living/M = A + + if(M.stat != DEAD) + if(M.monkeyizing) + return + if(M.has_brain_worms()) + return //Borer stuff - RR + + if(iscultist(M)) return + if(!ishuman(M) && !isrobot(M)) return + + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.overlays.len = 0 + M.invisibility = 101 + + if(istype(M, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/Robot = M + if(Robot.mmi) + del(Robot.mmi) + else + for(var/obj/item/W in M) + if(istype(W, /obj/item/weapon/implant)) + qdel(W) + continue + W.layer = initial(W.layer) + W.loc = M.loc + W.dropped(M) + + var/mob/living/new_mob = new /mob/living/simple_animal/corgi(A.loc) + new_mob.a_intent = I_HURT + if(M.mind) + M.mind.transfer_to(new_mob) + else + new_mob.key = M.key + + new_mob << "Your form morphs into that of a corgi." //Because we don't have cluwnes diff --git a/code/game/gamemodes/cult/cultify/mob.dm b/code/game/gamemodes/cult/cultify/mob.dm index 15233dc43b9..a7d275b1775 100644 --- a/code/game/gamemodes/cult/cultify/mob.dm +++ b/code/game/gamemodes/cult/cultify/mob.dm @@ -1,3 +1,8 @@ +/mob + //thou shall always be able to see the Geometer of Blood + var/image/narsimage = null + var/image/narglow = null + /mob/proc/cultify() return @@ -26,3 +31,33 @@ cult.harvested += G.mind else dust() + +/mob/proc/see_narsie(var/obj/machinery/singularity/narsie/large/N, var/dir) + if(N.chained) + if(narsimage) + del(narsimage) + del(narglow) + return + if((N.z == src.z)&&(get_dist(N,src) <= (N.consume_range+10)) && !(N in view(src))) + if(!narsimage) //Create narsimage + narsimage = image('icons/obj/narsie.dmi',src.loc,"narsie",9,1) + narsimage.mouse_opacity = 0 + if(!narglow) //Create narglow + narglow = image('icons/obj/narsie.dmi',narsimage.loc,"glow-narsie",LIGHTING_LAYER+2,1) + narglow.mouse_opacity = 0 + //Else if no dir is given, simply send them the image of narsie + var/new_x = 32 * (N.x - src.x) + N.pixel_x + var/new_y = 32 * (N.y - src.y) + N.pixel_y + narsimage.pixel_x = new_x + narsimage.pixel_y = new_y + narglow.pixel_x = new_x + narglow.pixel_y = new_y + narsimage.loc = src.loc + narglow.loc = src.loc + //Display the new narsimage to the player + src << narsimage + src << narglow + else + if(narsimage) + del(narsimage) + del(narglow) diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm index 188f5cb5b01..bc0a7238690 100644 --- a/code/game/gamemodes/cult/cultify/obj.dm +++ b/code/game/gamemodes/cult/cultify/obj.dm @@ -52,12 +52,10 @@ new I(loc) ..() -/obj/machinery/power/apc/cultify() - return - /obj/machinery/atmospherics/cultify() if(src.invisibility != INVISIBILITY_MAXIMUM) src.invisibility = INVISIBILITY_MAXIMUM + density = 0 /obj/machinery/cooking/cultify() new /obj/structure/cult/talisman(loc) @@ -84,10 +82,20 @@ del(c_animation) qdel(src) +/obj/machinery/door/firedoor/cultify() + qdel(src) + /obj/machinery/light/cultify() new /obj/structure/cult/pylon(loc) qdel(src) +/obj/machinery/mech_sensor/cultify() + qdel(src) + +/obj/machinery/power/apc/cultify() + if(src.invisibility != INVISIBILITY_MAXIMUM) + src.invisibility = INVISIBILITY_MAXIMUM + /obj/machinery/vending/cultify() new /obj/structure/cult/forge(loc) qdel(src) diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm new file mode 100644 index 00000000000..2a2499bb45e --- /dev/null +++ b/code/game/gamemodes/cult/hell_universe.dm @@ -0,0 +1,101 @@ +/* + +In short: + * Random area alarms + * All areas jammed + * Random gateways spawning hellmonsters (and turn people into cluwnes if ran into) + * Broken APCs/Fire Alarms + * Scary music + * Random tiles changing to culty tiles. + +*/ +/datum/universal_state/hell + name = "Hell Rising" + desc = "OH FUCK OH FUCK OH FUCK" + + decay_rate = 5 // 5% chance of a turf decaying on lighting update/airflow (there's no actual tick for turfs) + +/datum/universal_state/hell/OnShuttleCall(var/mob/user) + return 1 + /* + if(user) + user << "All you hear on the frequency is static and panicked screaming. There will be no shuttle call today." + return 0 + */ + +/datum/universal_state/hell/DecayTurf(var/turf/T) + if(!T.holy) + T.cultify() + for(var/obj/machinery/light/L in T.contents) + new /obj/structure/cult/pylon(L.loc) + qdel(L) + return + + +/datum/universal_state/hell/OnTurfChange(var/turf/T) + var/turf/space/spess = T + if(istype(spess)) + spess.overlays += "hell01" + +// Apply changes when entering state +/datum/universal_state/hell/OnEnter() + set background = 1 + escape_list = get_area_turfs(locate(/area/hallway/secondary/exit)) + + //Separated into separate procs for profiling + AreaSet() + OverlaySet() + MiscSet() + APCSet() + KillMobs() + AmbientSet() + + runedec += 9000 //basically removing the rune cap + +/datum/universal_state/hell/proc/AreaSet() + for(var/area/ca in world) + var/area/A = ca.master + if(!istype(A,/area) || A.name=="Space") + continue + + // Reset all alarms. + A.fire = null + A.atmos = 1 + A.atmosalm = 0 + A.poweralm = 1 + A.party = null + + A.updateicon() + +/datum/universal_state/hell/proc/OverlaySet() + var/image/I = image("icon" = 'icons/turf/space.dmi', "icon_state" = "hell01", "layer" = 10) + for(var/turf/space/spess in world) + spess.overlays += I + +/datum/universal_state/hell/proc/AmbientSet() + for(var/turf/T in world) + if(istype(T, /turf/space)) continue + T.update_lumcount(1, 255, 0, 0, 0) + +/datum/universal_state/hell/proc/MiscSet() + for(var/turf/simulated/floor/T in world) + if(!T.holy && prob(1)) + new /obj/effect/gateway/active/cult(T) + + for (var/obj/machinery/firealarm/alm in machines) + if (!(alm.stat & BROKEN)) + alm.ex_act(2) + +/datum/universal_state/hell/proc/APCSet() + for (var/obj/machinery/power/apc/APC in machines) + if (!(APC.stat & BROKEN) && !istype(APC.area,/area/turret_protected/ai)) + APC.chargemode = 0 + if(APC.cell) + APC.cell.charge = 0 + APC.emagged = 1 + APC.queue_icon_update() + +/datum/universal_state/hell/proc/KillMobs() + for(var/mob/living/simple_animal/M in mob_list) + if(M && !M.client) + M.stat = DEAD diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 7024f025d36..9f99945837e 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -33,6 +33,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa"," var/word1 var/word2 var/word3 + var/image/blood_image var/list/converting = list() // Places these combos are mentioned: this file - twice in the rune code, once in imbued tome, once in tome's HTML runes.dm - in the imbue rune code. If you change a combination - dont forget to change it everywhere. @@ -66,10 +67,21 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa"," // join hide technology - stun rune. Rune color: bright pink. New() ..() - var/image/blood = image(loc = src) - blood.override = 1 + blood_image = image(loc = src) + blood_image.override = 1 for(var/mob/living/silicon/ai/AI in player_list) - AI.client.images += blood + if(AI.client) + AI.client.images += blood_image + rune_list.Add(src) + + Del() + for(var/mob/living/silicon/ai/AI in player_list) + if(AI.client) + AI.client.images -= blood_image + qdel(blood_image) + blood_image = null + rune_list.Remove(src) + ..() examine(mob/user) ..() diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 46bca99bc6e..6f64faca59b 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -180,6 +180,9 @@ var/list/sacrificed = list() /////////////////////////////////////////FOURTH RUNE tearreality() + if(!cult.allow_narsie) + return fizzle() + var/list/cultists = new() for(var/mob/M in range(1,src)) if(iscultist(M) && !M.stat) diff --git a/code/game/gamemodes/endgame/endgame.dm b/code/game/gamemodes/endgame/endgame.dm new file mode 100644 index 00000000000..ed1167dfe74 --- /dev/null +++ b/code/game/gamemodes/endgame/endgame.dm @@ -0,0 +1,68 @@ +/********************** + * ENDGAME STUFF + **********************/ + + // Universal State + // Handles stuff like space icon_state, constants, etc. + // Essentially a policy manager. Once shit hits the fan, this changes its policies. + // Called by master controller. + + // Default shit. +/datum/universal_state + // Just for reference, for now. + // Might eventually add an observatory job. + var/name = "Normal" + var/desc = "Nothing seems awry." + + // Sets world.turf, replaces all turfs of type /turf/space. + var/space_type = /turf/space + + // Replaces all turfs of type /turf/space/transit + var/transit_space_type = /turf/space/transit + + // Chance of a floor or wall getting damaged [0-100] + // Simulates stuff getting broken due to molecular bonds decaying. + var/decay_rate = 0 + +// Actually decay the turf. +/datum/universal_state/proc/DecayTurf(var/turf/T) + if(istype(T,/turf/simulated/wall)) + var/turf/simulated/wall/W=T + W.melt() + return + if(istype(T,/turf/simulated/floor)) + var/turf/simulated/floor/F=T + // Burnt? + if(!F.burnt) + F.burn_tile() + else + F.ReplaceWithLattice() + return + +// Return 0 to cause shuttle call to fail. +/datum/universal_state/proc/OnShuttleCall(var/mob/user) + return 1 + +// Processed per tick +/datum/universal_state/proc/OnTurfTick(var/turf/T) + if(decay_rate && prob(decay_rate)) + DecayTurf(T) + +// Apply changes when exiting state +/datum/universal_state/proc/OnExit() + // Does nothing by default + +// Apply changes when entering state +/datum/universal_state/proc/OnEnter() + // Does nothing by default + +// Apply changes to a new turf. +/datum/universal_state/proc/OnTurfChange(var/turf/NT) + return + +/proc/SetUniversalState(var/newstate,var/on_exit=1, var/on_enter=1) + if(on_exit) + universe.OnExit() + universe = new newstate + if(on_enter) + universe.OnEnter() diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm new file mode 100644 index 00000000000..139045291f1 --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -0,0 +1,117 @@ +// QUALITY COPYPASTA +/turf/unsimulated/wall/supermatter + name = "Bluespace" + desc = "THE END IS right now actually." + + icon = 'icons/turf/space.dmi' + icon_state = "bluespace" + + //luminosity = 5 + //l_color="#0066FF" + layer = LIGHTING_LAYER+1 + + var/spawned=0 // DIR mask + var/next_check=0 + var/list/avail_dirs = list(NORTH,SOUTH,EAST,WEST) + +/turf/unsimulated/wall/supermatter/New() + ..() + processing_turfs.Add(src) + next_check = world.time+5 SECONDS + +/turf/unsimulated/wall/supermatter/Destroy() + processing_turfs.Remove(src) + ..() + +/turf/unsimulated/wall/supermatter/proc/process() + // Only check infrequently. + if(next_check>world.time) return + + // No more available directions? Shut down process(). + if(avail_dirs.len==0) + processing_objects.Remove(src) + return 1 + + // We're checking, reset the timer. + next_check = world.time+5 SECONDS + + // Choose a direction. + var/pdir = pick(avail_dirs) + avail_dirs -= pdir + var/turf/T=get_step(src,pdir) + + // EXPAND + if(!istype(T,type)) + // Do pretty fadeout animation for 1s. + new /obj/effect/overlay/bluespacify(T) + spawn(10) + // Nom. + for(var/atom/movable/A in T) + if(A) + if(istype(A,/mob/living)) + del(A) + else if(istype(A,/mob)) // Observers, AI cameras. + continue + qdel(A) + T.ChangeTurf(type) + + if((spawned & (NORTH|SOUTH|EAST|WEST)) == (NORTH|SOUTH|EAST|WEST)) + processing_turfs -= src + return + +/turf/unsimulated/wall/supermatter/attack_generic(mob/user as mob) + return attack_hand(user) + +/turf/unsimulated/wall/supermatter/attack_robot(mob/user as mob) + if(Adjacent(user)) + return attack_hand(user) + else + user << "What the fuck are you doing?" + return + +// /vg/: Don't let ghosts fuck with this. +/turf/unsimulated/wall/supermatter/attack_ghost(mob/user as mob) + user.examinate(src) + +/turf/unsimulated/wall/supermatter/attack_ai(mob/user as mob) + return user.examinate(src) + +/turf/unsimulated/wall/supermatter/attack_hand(mob/user as mob) + user.visible_message("\The [user] reaches out and touches \the [src]... And then blinks out of existance.",\ + "You reach out and touch \the [src]. Everything immediately goes quiet. Your last thought is \"That was not a wise decision.\"",\ + "You hear an unearthly noise.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + Consume(user) + +/turf/unsimulated/wall/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) + user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ + "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ + "Everything suddenly goes silent.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + user.drop_from_inventory(W) + Consume(W) + + +/turf/unsimulated/wall/supermatter/Bumped(atom/AM as mob|obj) + if(istype(AM, /mob/living)) + AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.",\ + "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ + "You hear an unearthly noise as a wave of heat washes over you.") + else + AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.",\ + "You hear a loud crack as you are washed with a wave of heat.") + + playsound(src, 'sound/effects/supermatter.ogg', 50, 1) + + Consume(AM) + + +/turf/unsimulated/wall/supermatter/proc/Consume(var/mob/living/user) + if(istype(user,/mob/dead/observer)) + return + + del(user) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm new file mode 100644 index 00000000000..9d3f12b0214 --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -0,0 +1,81 @@ +/*** EXIT PORTAL ***/ + +/obj/machinery/singularity/narsie/large/exit + name = "Bluespace Rift" + desc = "NO TIME TO EXPLAIN, JUMP IN" + icon = 'icons/obj/rift.dmi' + icon_state = "rift" + + move_self = 0 + announce=0 + narnar=0 + + layer=LIGHTING_LAYER+2 // ITS SO BRIGHT + + consume_range = 6 + +/obj/machinery/singularity/narsie/large/exit/New() + ..() + processing_objects.Add(src) + +/obj/machinery/singularity/narsie/large/exit/update_icon() + overlays = 0 + +/obj/machinery/singularity/narsie/large/exit/process() + for(var/mob/M in player_list) + if(M.client) + M.see_rift(src) + eat() + +/obj/machinery/singularity/narsie/large/exit/acquire(var/mob/food) + return + +/obj/machinery/singularity/narsie/large/exit/consume(const/atom/A) + if(!(A.singuloCanEat())) + return 0 + + if (istype(A, /mob/living/)) + do_teleport(A, pick(endgame_safespawns)) //dead-on precision + else if (isturf(A)) + var/turf/T = A + var/dist = get_dist(T, src) + if (dist <= consume_range && T.density) + T.density = 0 + + for (var/atom/movable/AM in T.contents) + if (AM == src) // This is the snowflake. + continue + + if (dist <= consume_range) + consume(AM) + continue + + if (dist > consume_range) + if (101 == AM.invisibility) + continue + + spawn (0) + AM.singularity_pull(src, src.current_size) + + +/mob + //thou shall always be able to see the rift + var/image/riftimage = null + +/mob/proc/see_rift(var/obj/machinery/singularity/narsie/large/exit/R) + if((R.z == src.z) && (get_dist(R,src) <= (R.consume_range+10)) && !(R in view(src))) + if(!riftimage) + riftimage = image('icons/obj/rift.dmi',src.loc,"rift",LIGHTING_LAYER+2,1) + riftimage.mouse_opacity = 0 + + var/new_x = 32 * (R.x - src.x) + R.pixel_x + var/new_y = 32 * (R.y - src.y) + R.pixel_y + riftimage.pixel_x = new_x + riftimage.pixel_y = new_y + riftimage.loc = src.loc + + src << riftimage + + else + if(riftimage) + del(riftimage) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm new file mode 100644 index 00000000000..1b5ceb87e82 --- /dev/null +++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm @@ -0,0 +1,140 @@ + +/datum/universal_state/supermatter_cascade + name = "Supermatter Cascade" + desc = "Unknown harmonance affecting universal substructure, converting nearby matter to supermatter." + + decay_rate = 5 // 5% chance of a turf decaying on lighting update/airflow (there's no actual tick for turfs) + +/datum/universal_state/supermatter_cascade/OnShuttleCall(var/mob/user) + if(user) + user << "All you hear on the frequency is static and panicked screaming. There will be no shuttle call today." + return 0 + +/datum/universal_state/supermatter_cascade/OnTurfChange(var/turf/T) + var/turf/space/spess = T + if(istype(spess)) + spess.overlays += "end01" + +/datum/universal_state/supermatter_cascade/DecayTurf(var/turf/T) + if(istype(T,/turf/simulated/wall)) + var/turf/simulated/wall/W=T + W.melt() + return + if(istype(T,/turf/simulated/floor)) + var/turf/simulated/floor/F=T + // Burnt? + if(!F.burnt) + F.burn_tile() + else + if(!istype(F,/turf/simulated/floor/plating)) + F.break_tile_to_plating() + return + +// Apply changes when entering state +/datum/universal_state/supermatter_cascade/OnEnter() + set background = 1 + world << "You are blinded by a brilliant flash of energy." + + world << sound('sound/effects/cascade.ogg') + + for(var/mob/M in player_list) + flick("e_flash", M.flash) + + if(emergency_shuttle.can_recall()) + priority_announcement.Announce("The emergency shuttle has returned due to bluespace distortion.") + emergency_shuttle.recall() + + AreaSet() + OverlaySet() + MiscSet() + APCSet() + AmbientSet() + + // Disable Nar-Sie. + cult.allow_narsie = 0 + PlayerSet() + + new /obj/machinery/singularity/narsie/large/exit(pick(endgame_exits)) + spawn(rand(30,60) SECONDS) + var/txt = {" +There's been a galaxy-wide electromagnetic pulse. All of our systems are heavily damaged and many personnel are dead or dying. We are seeing increasing indications of the universe itself beginning to unravel. + +[station_name()], you are the only facility nearby a bluespace rift, which is near your research outpost. You are hereby directed to enter the rift using all means necessary, quite possibly as the last of your species alive. + +You have five minutes before the universe collapses. Good l\[\[###!!!- + +AUTOMATED ALERT: Link to [command_name()] lost."} + priority_announcement.Announce(txt,"SUPERMATTER CASCADE DETECTED") + sleep(5 MINUTES) + ticker.declare_completion() + ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic + + world << "Resetting in 30 seconds!" + + feedback_set_details("end_error","Universe ended") + + if(blackbox) + blackbox.save_all_data_to_sql() + + sleep(300) + log_game("Rebooting due to universal collapse") + world.Reboot() + return + +/datum/universal_state/supermatter_cascade/proc/AreaSet() + for(var/area/ca in world) + var/area/A=ca.master + if(A.z in config.admin_levels) + continue + if(!istype(A,/area) || istype(A,/area/space)) + continue + + // Reset all alarms. + A.fire = null + A.atmos = 1 + A.atmosalm = 0 + A.poweralm = 1 + + // Slap on random alerts + if(prob(25)) + switch(rand(1,4)) + if(1) + A.fire=1 + if(2) + A.atmosalm=1 + + A.updateicon() + +/datum/universal_state/supermatter_cascade/proc/OverlaySet() + for(var/turf/space/spess in world) + spess.overlays += "end01" + +/datum/universal_state/supermatter_cascade/proc/AmbientSet() + for(var/turf/T in world) + if(istype(T, /turf/space)) continue + if(!(T.z in config.admin_levels)) + T.update_lumcount(1, 160, 255, 0, 0) + +/datum/universal_state/supermatter_cascade/proc/MiscSet() + for (var/obj/machinery/firealarm/alm in world) + if (!(alm.stat & BROKEN)) + alm.ex_act(2) + +/datum/universal_state/supermatter_cascade/proc/APCSet() + for (var/obj/machinery/power/apc/APC in world) + if (!(APC.stat & BROKEN)) + APC.chargemode = 0 + if(APC.cell) + APC.cell.charge = 0 + APC.emagged = 1 + APC.queue_icon_update() + +/datum/universal_state/supermatter_cascade/proc/PlayerSet() + for(var/datum/mind/M in player_list) + if(!istype(M.current,/mob/living)) + continue + if(M.current.stat!=2) + M.current.Weaken(10) + flick("e_flash", M.current.flash) + + clear_antag_roles(M) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 96385b5dfc2..4fc43a02591 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -428,6 +428,10 @@ if ((!( ticker ) || !emergency_shuttle.location())) return + if(!universe.OnShuttleCall(usr)) + user << "Cannot establish a bluespace connection." + return + if(deathsquad.deployed) user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c275d8f7287..d62f6c37b0e 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -36,10 +36,10 @@ if(damage >= 10) if(src.density) visible_message("\The [user] forces \the [src] open!") - open() + open(1) else visible_message("\The [user] forces \the [src] closed!") - close() + close(1) else visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") return @@ -776,7 +776,7 @@ About the new airlock wires panel: user << "\blue The airlock's motors resist your efforts to force it." else if(locked) user << "\blue The airlock's bolts prevent it from being forced." - else if( !welded && !operating ) + else if(density) spawn(0) open(1) else @@ -825,11 +825,8 @@ About the new airlock wires panel: return /obj/machinery/door/airlock/open(var/forced=0) - if(!can_open()) + if(!can_open(forced)) return 0 - if(!forced) - if( !arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) ) - return 0 use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people if(istype(src, /obj/machinery/door/airlock/glass)) playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) @@ -839,7 +836,11 @@ About the new airlock wires panel: src.closeOther.close() return ..() -/obj/machinery/door/airlock/can_open() +/obj/machinery/door/airlock/can_open(var/forced=0) + if(!forced) + if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + return 0 + if(locked || welded) return 0 return ..() diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 900b6b09f06..406ef8611e8 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -388,9 +388,8 @@ return -/obj/machinery/door/proc/open() - if(!can_open()) return - if(!operating) operating = 1 +/obj/machinery/door/proc/open(var/forced = 0) + if(!can_open(forced)) return do_animate("opening") icon_state = "door0" @@ -414,8 +413,8 @@ /obj/machinery/door/proc/next_close_time() return world.time + (normalspeed ? 150 : 5) -/obj/machinery/door/proc/close() - if(!can_close()) +/obj/machinery/door/proc/close(var/forced = 0) + if(!can_close(forced)) return operating = 1 diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 28a4ad2cc27..da25e6f2cc9 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -79,6 +79,14 @@ xeno_spawn += loc del(src) + if("endgame_exit") + endgame_safespawns += loc + del(src) + + if("bluespacerift") + endgame_exits += loc + del(src) + landmarks_list += src return 1 diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index a5715624bb4..6dd26f7774c 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -2,7 +2,7 @@ name = "overlay" unacidable = 1 var/i_attached//Added for possible image attachments to objects. For hallucinations and the like. - + /obj/effect/overlay/Destroy() PlaceInPool(src) return 1 //cancels the GCing @@ -35,4 +35,10 @@ /obj/effect/overlay/coconut name = "Coconuts" icon = 'icons/misc/beach.dmi' - icon_state = "coconuts" \ No newline at end of file + icon_state = "coconuts" + +/obj/effect/overlay/bluespacify + name = "Bluespace" + icon = 'icons/turf/space.dmi' + icon_state = "bluespacify" + layer = LIGHTING_LAYER diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 1e3f67fb07c..dda21468a48 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -22,6 +22,11 @@ /obj/structure/grille/meteorhit(var/obj/M) del(src) +/obj/structure/grille/update_icon() + if(destroyed) + icon_state = "[initial(icon_state)]-b" + else + icon_state = initial(icon_state) /obj/structure/grille/Bumped(atom/user) if(ismob(user)) shock(user, 70) @@ -165,9 +170,9 @@ /obj/structure/grille/proc/healthcheck() if(health <= 0) if(!destroyed) - icon_state = "brokengrille" density = 0 destroyed = 1 + update_icon() new /obj/item/stack/rods(loc) else @@ -226,5 +231,3 @@ if(air_group) return 0 //Make sure air doesn't drain ..() - - diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 9546bf9ba1b..dcecf46ad60 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -12,6 +12,8 @@ /turf/simulated/New() ..() + if(istype(loc, /area/chapel)) + holy = 1 levelupdate() /turf/simulated/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor="#A10808") diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 969b872caf6..e19fadf863b 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -106,6 +106,20 @@ //Damage +/turf/simulated/wall/melt() + if(mineral == "diamond") + return + + src.ChangeTurf(/turf/simulated/floor/plating) + + var/turf/simulated/floor/F = src + if(!F) + return + F.burn_tile() + F.icon_state = "wall_thermite" + visible_message("\The [src] spontaneously combusts!.") //!!OH SHIT!! + return + /turf/simulated/wall/proc/take_damage(dam) if(dam) damage = max(0, damage + dam) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 884c5c5dbe9..2fd89bb8769 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -245,4 +245,7 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = spawn (0) if ((A && A.loc)) A.loc.Entered(A) - return \ No newline at end of file + return + +/turf/space/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0) + return ..(N, tell_universe, 1) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c500b055c24..1bc058ef6df 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -29,6 +29,9 @@ // Flick animation var/atom/movable/overlay/c_animation = null + // holy water + var/holy = 0 + /turf/New() ..() for(var/atom/movable/AM as mob|obj in src) @@ -197,7 +200,7 @@ del L //Creates a new turf -/turf/proc/ChangeTurf(var/turf/N) +/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0) if (!N) return @@ -241,9 +244,9 @@ //W.Assimilate_Air() W.lighting_lumcount += old_lumcount - - if(W.lighting_lumcount) - W.UpdateAffectingLights() + if((old_lumcount != W.lighting_lumcount) || (loc.name != "Space" && force_lighting_update)) + W.lighting_changed = 1 + lighting_controller.changed_turfs += W if(old_fire) fire = old_fire @@ -251,6 +254,9 @@ if (istype(W,/turf/simulated/floor)) W.RemoveLattice() + if(tell_universe) + universe.OnTurfChange(W) + if(air_master) air_master.mark_for_update(src) @@ -268,13 +274,16 @@ var/turf/W = new N( locate(src.x, src.y, src.z) ) W.lighting_lumcount += old_lumcount - if(old_lumcount != W.lighting_lumcount) + if((old_lumcount != W.lighting_lumcount) || (loc.name != "Space" && force_lighting_update)) W.lighting_changed = 1 lighting_controller.changed_turfs += W if(old_fire) old_fire.RemoveFire() + if(tell_universe) + universe.OnTurfChange(W) + if(air_master) air_master.mark_for_update(src) diff --git a/code/global.dm b/code/global.dm index c7a17381276..0cc3d3f51ce 100644 --- a/code/global.dm +++ b/code/global.dm @@ -30,6 +30,8 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called // 3: AI satellite. // 5: Empty space. +var/global/datum/universal_state/universe = new + var/global/list/global_map = null //var/global/list/global_map = list(list(1,5),list(4,3)) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 96b7a7c2445..46fd659d813 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -670,6 +670,16 @@ var/global/floorIsLava = 0 if(check_rights(R_SERVER,0)) dat += "Toggle bomb cap
" + if(check_rights(R_SERVER|R_FUN,0)) + dat += {" +
+ Final Solutions
+ (Warning, these will end the round!)
+
+ Summon Nar-Sie
+ Start a Supermatter Cascade
+ "} + dat += "
" if(check_rights(R_DEBUG,0)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 6fd38bb5814..43ea750f7a5 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2257,6 +2257,33 @@ feedback_add_details("admin_secrets_fun_used","OO") only_one() message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)") + + if("togglenarsie") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","NA") + var/choice = input("How do you wish for narsie to interact with her surroundings?") in list("CultStation13", "Nar-Singulo") + if(choice == "CultStation13") + message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"CultStation13\".") + narsie_behaviour = "CultStation13" + if(choice == "Nar-Singulo") + message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"Nar-Singulo\".") + narsie_behaviour = "Nar-Singulo" + if("hellonearth") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","NS") + var/choice = input("You sure you want to end the round and summon narsie at your location? Misuse of this could result in removal of flags or halarity.") in list("PRAISE SATAN", "Cancel") + if(choice == "PRAISE SATAN") + new /obj/machinery/singularity/narsie/large(get_turf(usr)) + message_admins("[key_name_admin(usr)] has summoned narsie and brought about a new realm of suffering.") + if("supermattercascade") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","SC") + var/choice = input("You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or halarity.") in list("NO TIME TO EXPLAIN", "Cancel") + if(choice == "NO TIME TO EXPLAIN") + explosion(get_turf(usr), 8, 16, 24, 32, 1) + new /turf/unsimulated/wall/supermatter(get_turf(usr)) + SetUniversalState(/datum/universal_state/supermatter_cascade) + message_admins("[key_name_admin(usr)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(usr)]") if(usr) log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]") if (ok) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7b5f7401351..850bd531dfa 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -29,6 +29,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images var/image/ghostimage = null //this mobs ghost image, for deleting and stuff var/ghostvision = 1 //is the ghost able to see things humans can't? var/seedarkness = 1 + incorporeal_move = 1 /mob/dead/observer/New(mob/body) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF @@ -193,29 +194,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly. announce_ghost_joinleave(ghost) - -/mob/dead/observer/Move(NewLoc, direct) - following = null - set_dir(direct) - if(NewLoc) - loc = NewLoc - for(var/obj/effect/step_trigger/S in NewLoc) - S.Crossed(src) - - return - loc = get_turf(src) //Get out of closets and such as a ghost - if((direct & NORTH) && y < world.maxy) - y++ - else if((direct & SOUTH) && y > 1) - y-- - if((direct & EAST) && x < world.maxx) - x++ - else if((direct & WEST) && x > 1) - x-- - - for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb - S.Crossed(src) - /mob/dead/observer/can_use_hands() return 0 /mob/dead/observer/is_active() return 0 @@ -316,11 +294,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!thearea) return var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - L+=T + var/holyblock = 0 + + if(usr.invisibility <= SEE_INVISIBLE_LIVING || (usr.mind in cult.current_antagonists)) + for(var/turf/T in get_area_turfs(thearea.type)) + if(!T.holy) + L+=T + else + holyblock = 1 + else + for(var/turf/T in get_area_turfs(thearea.type)) + L+=T if(!L || !L.len) - usr << "No area available." + if(holyblock) + usr << "This area has been entirely made into sacred grounds, you cannot enter it while you are in this plane of existence!" + else + usr << "No area available." usr.loc = pick(L) following = null @@ -336,7 +326,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp // This is the ghost's follow verb with an argument /mob/dead/observer/proc/ManualFollow(var/atom/movable/target) - if(target && target != src) + if(!target) + return + + var/turf/targetloc = get_turf(target) + if(check_holy(targetloc)) + usr << "You cannot follow a mob standing on holy grounds!" + return + if(target != src) if(following && following == target) return following = target @@ -351,6 +348,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp loc = T sleep(15) +/mob/proc/check_holy(var/turf/T) + return 0 + +/mob/dead/observer/check_holy(var/turf/T) + if(check_rights(R_ADMIN|R_FUN, 0, src)) + return 0 + + return (T && T.holy) && (invisibility <= SEE_INVISIBLE_LIVING || (mind in cult.current_antagonists)) + /mob/dead/observer/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" set name = "Jump to Mob" @@ -393,6 +399,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set hidden = 1 src << "\red You are dead! You have no mind to store memory!" +/mob/dead/observer/Post_Incorpmove() + following = null + /mob/dead/observer/verb/analyze_air() set name = "Analyze Air" set category = "Ghost" diff --git a/code/modules/mob/freelook/mask/update_triggers.dm b/code/modules/mob/freelook/mask/update_triggers.dm index a02aa864a67..d80527a2fa2 100644 --- a/code/modules/mob/freelook/mask/update_triggers.dm +++ b/code/modules/mob/freelook/mask/update_triggers.dm @@ -34,7 +34,7 @@ // Arise! cultnet.updateVisibility(src, 0) -/mob/living/death() +/mob/living/death(gibbed, deathmessage="seizes up and falls limp...") if(..()) // If true, the mob went from living to dead (assuming everyone has been overriding as they should...) cultnet.updateVisibility(src) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 3771bc135e7..8a01f86774b 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -22,9 +22,6 @@ var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. - //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. - var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas. - var/t_phoron = null var/t_oxygen = null var/t_sl_gas = null diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index b5b6808bac9..5336cd873f3 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -1,9 +1,7 @@ /mob/living/silicon/ai/Login() //ThisIsDumb(TM) TODO: tidy this up ¬_¬ ~Carn ..() - for(var/obj/effect/rune/rune in world) - var/image/blood = image(loc = rune) - blood.override = 1 - client.images += blood + for(var/obj/effect/rune/rune in rune_list) + client.images += rune.blood_image regenerate_icons() flash = new /obj/screen() flash.icon_state = "blank" diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm index 2aa5054dc73..43ebfd9a499 100644 --- a/code/modules/mob/living/simple_animal/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm @@ -5,8 +5,8 @@ speak_emote = list("hisses") emote_hear = list("wails","screeches") response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" + response_disarm = "flailed at" + response_harm = "punched" icon_dead = "shade_dead" speed = -1 a_intent = I_HURT @@ -14,7 +14,7 @@ status_flags = CANPUSH universal_speak = 0 universal_understand = 1 - attack_sound = 'sound/weapons/punch1.ogg' + attack_sound = 'sound/weapons/spiderlunge.ogg' min_oxy = 0 max_oxy = 0 min_tox = 0 @@ -24,7 +24,7 @@ min_n2 = 0 max_n2 = 0 minbodytemp = 0 - show_stat_health = 0 + show_stat_health = 1 faction = "cult" supernatural = 1 var/nullblock = 0 @@ -44,8 +44,9 @@ add_language("Cult") add_language("Occult") for(var/spell in construct_spells) - spell_list += new spell(src) + src.add_spell(new spell, "const_spell_ready") updateicon() + add_glow() /mob/living/simple_animal/construct/death() new /obj/item/weapon/ectoplasm (src.loc) @@ -99,7 +100,7 @@ mob_size = 20 speed = 3 environment_smash = 2 - attack_sound = 'sound/weapons/punch3.ogg' + attack_sound = 'sound/weapons/heavysmash.ogg' status_flags = 0 resistance = 10 construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser) @@ -150,7 +151,7 @@ speed = -1 environment_smash = 1 see_in_dark = 7 - attack_sound = 'sound/weapons/bladeslice.ogg' + attack_sound = 'sound/weapons/rapidslice.ogg' construct_spells = list(/spell/targeted/ethereal_jaunt/shift) @@ -167,14 +168,14 @@ icon_living = "artificer" maxHealth = 50 health = 50 - response_harm = "viciously beats" + response_harm = "viciously beaten" harm_intent_damage = 5 melee_damage_lower = 5 melee_damage_upper = 5 attacktext = "rammed" speed = 0 - environment_smash = 2 - attack_sound = 'sound/weapons/punch2.ogg' + environment_smash = 1 + attack_sound = 'sound/weapons/rapidslice.ogg' construct_spells = list(/spell/aoe_turf/conjure/construct/lesser, /spell/aoe_turf/conjure/wall, /spell/aoe_turf/conjure/floor, @@ -196,14 +197,14 @@ maxHealth = 750 health = 750 speak_emote = list("rumbles") - response_harm = "harmlessly punches" + response_harm = "harmlessly punched" harm_intent_damage = 0 melee_damage_lower = 50 melee_damage_upper = 50 attacktext = "brutally crushed" speed = 5 environment_smash = 2 - attack_sound = 'sound/weapons/punch4.ogg' + attack_sound = 'sound/weapons/heavysmash.ogg' resistance = 10 var/energy = 0 var/max_energy = 1000 @@ -224,7 +225,7 @@ health = 150 melee_damage_lower = 25 melee_damage_upper = 25 - attacktext = "violently stabs" + attacktext = "violently stabbed" speed = -1 environment_smash = 1 see_in_dark = 7 @@ -235,3 +236,99 @@ /spell/aoe_turf/knock/harvester, /spell/rune_write ) + +////////////////Glow////////////////// +/mob/living/simple_animal/construct/proc/add_glow() + overlays = 0 + var/overlay_layer = LIGHTING_LAYER+1 + if(layer != MOB_LAYER) + overlay_layer=TURF_LAYER+0.2 + + overlays += image(icon,"glow-[icon_state]",overlay_layer) + +////////////////HUD////////////////////// + +/mob/living/simple_animal/construct/Life() + . = ..() + if(.) + if(fire) + if(fire_alert) fire.icon_state = "fire1" + else fire.icon_state = "fire0" + if(pullin) + if(pulling) pullin.icon_state = "pull1" + else pullin.icon_state = "pull0" + + if(purged) + if(purge > 0) purged.icon_state = "purge1" + else purged.icon_state = "purge0" + + silence_spells(purge) + +/mob/living/simple_animal/construct/armoured/Life() + ..() + if(healths) + switch(health) + if(250 to INFINITY) healths.icon_state = "juggernaut_health0" + if(208 to 249) healths.icon_state = "juggernaut_health1" + if(167 to 207) healths.icon_state = "juggernaut_health2" + if(125 to 166) healths.icon_state = "juggernaut_health3" + if(84 to 124) healths.icon_state = "juggernaut_health4" + if(42 to 83) healths.icon_state = "juggernaut_health5" + if(1 to 41) healths.icon_state = "juggernaut_health6" + else healths.icon_state = "juggernaut_health7" + + +/mob/living/simple_animal/construct/behemoth/Life() + ..() + if(healths) + switch(health) + if(750 to INFINITY) healths.icon_state = "juggernaut_health0" + if(625 to 749) healths.icon_state = "juggernaut_health1" + if(500 to 624) healths.icon_state = "juggernaut_health2" + if(375 to 499) healths.icon_state = "juggernaut_health3" + if(250 to 374) healths.icon_state = "juggernaut_health4" + if(125 to 249) healths.icon_state = "juggernaut_health5" + if(1 to 124) healths.icon_state = "juggernaut_health6" + else healths.icon_state = "juggernaut_health7" + +/mob/living/simple_animal/construct/builder/Life() + ..() + if(healths) + switch(health) + if(50 to INFINITY) healths.icon_state = "artificer_health0" + if(42 to 49) healths.icon_state = "artificer_health1" + if(34 to 41) healths.icon_state = "artificer_health2" + if(26 to 33) healths.icon_state = "artificer_health3" + if(18 to 25) healths.icon_state = "artificer_health4" + if(10 to 17) healths.icon_state = "artificer_health5" + if(1 to 9) healths.icon_state = "artificer_health6" + else healths.icon_state = "artificer_health7" + + + +/mob/living/simple_animal/construct/wraith/Life() + ..() + if(healths) + switch(health) + if(75 to INFINITY) healths.icon_state = "wraith_health0" + if(62 to 74) healths.icon_state = "wraith_health1" + if(50 to 61) healths.icon_state = "wraith_health2" + if(37 to 49) healths.icon_state = "wraith_health3" + if(25 to 36) healths.icon_state = "wraith_health4" + if(12 to 24) healths.icon_state = "wraith_health5" + if(1 to 11) healths.icon_state = "wraith_health6" + else healths.icon_state = "wraith_health7" + + +/mob/living/simple_animal/construct/harvester/Life() + ..() + if(healths) + switch(health) + if(150 to INFINITY) healths.icon_state = "harvester_health0" + if(125 to 149) healths.icon_state = "harvester_health1" + if(100 to 124) healths.icon_state = "harvester_health2" + if(75 to 99) healths.icon_state = "harvester_health3" + if(50 to 74) healths.icon_state = "harvester_health4" + if(25 to 49) healths.icon_state = "harvester_health5" + if(1 to 24) healths.icon_state = "harvester_health6" + else healths.icon_state = "harvester_health7" diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm new file mode 100644 index 00000000000..2bd3c8984a1 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/bat.dm @@ -0,0 +1,76 @@ +/mob/living/simple_animal/hostile/scarybat + name = "space bats" + desc = "A swarm of cute little blood sucking bats that looks pretty upset." + icon = 'icons/mob/bats.dmi' + icon_state = "bat" + icon_living = "bat" + icon_dead = "bat_dead" + icon_gib = "bat_dead" + speak_chance = 0 + turns_per_move = 3 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + speed = 4 + maxHealth = 20 + health = 20 + + harm_intent_damage = 8 + melee_damage_lower = 10 + melee_damage_upper = 10 + attacktext = "bites" + attack_sound = 'sound/weapons/bite.ogg' + + //Space carp aren't affected by atmos. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + environment_smash = 1 + + faction = "scarybat" + var/mob/living/owner + +/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob) + ..() + if(istype(L)) + owner = L + +/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0) + return ..() //No drifting in space for space carp! //original comments do not steal + +/mob/living/simple_animal/hostile/scarybat/FindTarget() + . = ..() + if(.) + emote("flutters towards [.]") + +/mob/living/simple_animal/hostile/scarybat/Found(var/atom/A)//This is here as a potential override to pick a specific target if available + if(istype(A) && A == owner) + return 0 + return ..() + +/mob/living/simple_animal/hostile/scarybat/AttackingTarget() + . =..() + var/mob/living/L = . + if(istype(L)) + if(prob(15)) + L.Stun(1) + L.visible_message("\the [src] scares \the [L]!") + +/mob/living/simple_animal/hostile/scarybat/cult + faction = "cult" + supernatural = 1 + +/mob/living/simple_animal/hostile/scarybat/cult/cultify() + return + +/mob/living/simple_animal/hostile/scarybat/cult/Life() + ..() + check_horde() diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm index 07ad06619ab..3ae0876903f 100644 --- a/code/modules/mob/living/simple_animal/hostile/creature.dm +++ b/code/modules/mob/living/simple_animal/hostile/creature.dm @@ -13,4 +13,26 @@ attacktext = "chomped" attack_sound = 'sound/weapons/bite.ogg' faction = "creature" - speed = 4 \ No newline at end of file + speed = 4 + +/mob/living/simple_animal/hostile/creature/cult + faction = "cult" + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + supernatural = 1 + +/mob/living/simple_animal/hostile/creature/cult/cultify() + return + +/mob/living/simple_animal/hostile/creature/cult/Life() + ..() + check_horde() diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index b1cc2067f4c..44d9c5d1ac4 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -47,3 +47,13 @@ if(prob(12)) L.Weaken(3) L.visible_message("\the [src] knocks down \the [L]!") + +/mob/living/simple_animal/hostile/faithless/cult + faction = "cult" + +/mob/living/simple_animal/hostile/faithless/cult/cultify() + return + +/mob/living/simple_animal/hostile/faithless/cult/Life() + ..() + check_horde() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 73ff6eab5dd..bb4616bbe8e 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -14,6 +14,9 @@ stop_automated_movement_when_pulled = 0 var/destroy_surroundings = 1 + var/shuttletarget = null + var/enroute = 0 + /mob/living/simple_animal/hostile/proc/FindTarget() var/atom/T = null @@ -113,11 +116,11 @@ /mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7) var/list/L = hearers(src, dist) - + for (var/obj/mecha/M in mechas_list) if (get_dist(src, M) <= dist) L += M - + return L /mob/living/simple_animal/hostile/death() @@ -206,3 +209,40 @@ var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir)) if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) obstacle.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext) + + +/mob/living/simple_animal/hostile/proc/check_horde() + if(emergency_shuttle.shuttle.location) + if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway + if(!shuttletarget || (get_dist(src, shuttletarget) >= 2)) + shuttletarget = pick(escape_list) + enroute = 1 + stop_automated_movement = 1 + spawn() + if(!src.stat) + horde() + + if(get_dist(src, shuttletarget) <= 2) //The monster reached the escape hallway + enroute = 0 + stop_automated_movement = 0 + +/mob/living/simple_animal/hostile/proc/horde() + var/turf/T = get_step_to(src, shuttletarget) + for(var/atom/A in T) + if(istype(A,/obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/D = A + D.open(1) + else if(istype(A,/obj/structure/mineral_door)) + var/obj/structure/mineral_door/D = A + if(D.density) + D.Open() + else if(istype(A,/obj/structure/cult/pylon)) + A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) + else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/table/rack)) + A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) + Move(T) + FindTarget() + if(!target_mob || enroute) + spawn(10) + if(!src.stat) + horde() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 6e8c1a7257d..067a9bd8fe6 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -39,6 +39,7 @@ var/maxbodytemp = 350 var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp + var/fire_alert = 0 //Atmos effect - Yes, you can make creatures that require phoron or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage var/min_oxy = 5 @@ -78,6 +79,7 @@ return /mob/living/simple_animal/Life() + ..() //Health if(stat == DEAD) @@ -191,9 +193,13 @@ //Atmos effect if(bodytemperature < minbodytemp) + fire_alert = 2 adjustBruteLoss(cold_damage_per_tick) else if(bodytemperature > maxbodytemp) + fire_alert = 1 adjustBruteLoss(heat_damage_per_tick) + else + fire_alert = 0 if(!atmos_suitable) adjustBruteLoss(unsuitable_atoms_damage) @@ -313,10 +319,10 @@ if(statpanel("Status") && show_stat_health) stat(null, "Health: [round((health / maxHealth) * 100)]%") -/mob/living/simple_animal/death() +/mob/living/simple_animal/death(gibbed, deathmessage="") icon_state = icon_dead density = 0 - return ..(deathmessage = "no message") + return ..() /mob/living/simple_animal/ex_act(severity) if(!blinded) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 8e22962f21e..792517c6d05 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -87,6 +87,8 @@ var/lying = 0 var/lying_prev = 0 var/canmove = 1 + //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. + var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas. var/lastpuke = 0 var/unacidable = 0 var/small = 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index baf1d299687..905b8d0f70e 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -170,17 +170,19 @@ /client/Move(n, direct) + if(!mob) + return // Moved here to avoid nullrefs below if(mob.control_object) Move_object(direct) - if(isobserver(mob)) return mob.Move(n,direct) + if(mob.incorporeal_move) + Process_Incorpmove(direct) + return if(moving) return 0 if(world.time < move_delay) return - if(!mob) return - if(locate(/obj/effect/stop/, mob.loc)) for(var/obj/effect/stop/S in mob.loc) if(S.victim == mob) @@ -364,13 +366,15 @@ ///Allows mobs to run though walls /client/proc/Process_Incorpmove(direct) var/turf/mobloc = get_turf(mob) - if(!isliving(mob)) - return - var/mob/living/L = mob - switch(L.incorporeal_move) + + switch(mob.incorporeal_move) if(1) - L.loc = get_step(L, direct) - L.dir = direct + var/turf/T = get_step(mob, direct) + if(mob.check_holy(T)) + mob << "You cannot get past holy grounds while you are in this plane of existence!" + else + mob.loc = get_step(mob, direct) + mob.dir = direct if(2) if(prob(50)) var/locx @@ -398,21 +402,35 @@ return else return - L.loc = locate(locx,locy,mobloc.z) + mob.loc = locate(locx,locy,mobloc.z) spawn(0) var/limit = 2//For only two trailing shadows. - for(var/turf/T in getline(mobloc, L.loc)) + for(var/turf/T in getline(mobloc, mob.loc)) spawn(0) - anim(T,L,'icons/mob/mob.dmi',,"shadow",,L.dir) + anim(T,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir) limit-- if(limit<=0) break else spawn(0) - anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,L.dir) - L.loc = get_step(L, direct) - L.dir = direct + anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir) + mob.loc = get_step(mob, direct) + mob.dir = direct + // Crossed is always a bit iffy + for(var/obj/S in mob.loc) + if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam)) + S.Crossed(mob) + + var/area/A = get_area_master(mob) + if(A) + A.Entered(mob) + if(isturf(mob.loc)) + var/turf/T = mob.loc + T.Entered(mob) + mob.Post_Incorpmove() return 1 +/mob/proc/Post_Incorpmove() + return ///Process_Spacemove ///Called by /client/Move() diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm new file mode 100644 index 00000000000..5b0303c9b53 --- /dev/null +++ b/code/modules/power/singularity/act.dm @@ -0,0 +1,138 @@ +#define I_SINGULO "singulo" + +/atom/proc/singularity_act() + return + +/atom/proc/singularity_pull() + return + +/mob/living/singularity_act() + investigate_log("has been consumed by a singularity", I_SINGULO) + gib() + return 20 + +/mob/living/singularity_pull(S) + step_towards(src, S) + +/mob/living/carbon/human/singularity_act() + var/gain = 20 + if(mind) + if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer")) + gain = 100 + if(mind.assigned_role == "Assistant") + gain = rand(0, 300) + investigate_log(I_SINGULO,"has been consumed by a singularity", I_SINGULO) + gib() + return gain + +/mob/living/carbon/human/singularity_pull(S, current_size) + if(current_size >= STAGE_THREE) + var/list/handlist = list(l_hand, r_hand) + for(var/obj/item/hand in handlist) + if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && u_equip(hand)) + step_towards(hand, src) + src << "The [S] pulls \the [hand] from your grip!" + apply_effect(current_size * 3, IRRADIATE) + if(shoes) + if(shoes.flags & NOSLIP) return 0 + ..() + +/obj/singularity_act() + ex_act(1) + if(src) + spawn(0) + qdel(src) + return 2 + +/obj/singularity_pull(S, current_size) + if(anchored) + if(current_size >= STAGE_FIVE) + step_towards(src, S) + else + step_towards(src, S) + +/obj/effect/beam/singularity_pull() + return + +/obj/effect/overlay/singularity_pull() + return + +/obj/item/singularity_pull(S, current_size) + spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously + if(current_size >= STAGE_FOUR) + //throw_at(S, 14, 3) + step_towards(src,S) + sleep(1) + step_towards(src,S) + else if(current_size > STAGE_ONE) + step_towards(src,S) + else ..() + +/obj/machinery/atmospherics/pipe/singularity_pull() + return + +/obj/machinery/power/supermatter/shard/singularity_act() + qdel(src) + return 5000 + +/obj/machinery/power/supermatter/singularity_act() + var/prints = "" + if(src.fingerprintshidden) + prints = ", all touchers : " + src.fingerprintshidden + + SetUniversalState(/datum/universal_state/supermatter_cascade) + log_admin("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].") + message_admins("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].") + spawn(0) + qdel(src) + return 50000 + +/obj/item/projectile/beam/emitter/singularity_pull() + return + +/obj/item/weapon/storage/backpack/holding/singularity_act(S, current_size) + var/dist = max((current_size - 2), 1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + return 1000 + +/turf/singularity_act(S, current_size) + if(intact) + for(var/obj/O in contents) + if(O.level != 1) + continue + if(O.invisibility == 101) + O.singularity_act(src, current_size) + ChangeTurf(/turf/space) + return 2 + +/turf/simulated/wall/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(75)) + dismantle_wall() + return + if(current_size == STAGE_FOUR) + if(prob(30)) + dismantle_wall() + +/turf/simulated/wall/r_wall/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(30)) + dismantle_wall() + +/turf/space/singularity_act() + return + +/******************* +* Nar-Sie Act/Pull * +*******************/ +/atom/proc/singuloCanEat() + return 1 + +/mob/dead/singuloCanEat() + return 0 + +/mob/eye/singuloCanEat() + return 0 + +/mob/new_player/singuloCanEat() + return 0 diff --git a/code/modules/power/singularity/investigate.dm b/code/modules/power/singularity/investigate.dm index 63c54c0e541..c0c62616ed3 100644 --- a/code/modules/power/singularity/investigate.dm +++ b/code/modules/power/singularity/investigate.dm @@ -1,4 +1,4 @@ /area/engineering/power_alert(var/alarming) if (alarming) investigate_log("has a power alarm!","singulo") - ..() \ No newline at end of file + ..() diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 01e671c1ec2..0fc454b9fb0 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -1,90 +1,285 @@ var/global/narsie_behaviour = "CultStation13" var/global/narsie_cometh = 0 var/global/list/narsie_list = list() - -/obj/machinery/singularity/narsie //Moving narsie to a child object of the singularity so it can be made to function differently. --NEO +/obj/machinery/singularity/narsie //Moving narsie to its own file for the sake of being clearer name = "Nar-Sie" desc = "Your mind begins to bubble and ooze as it tries to comprehend what it sees." - icon = 'icons/obj/magic_terror.dmi' - pixel_x = -89 - pixel_y = -85 - current_size = 9 //It moves/eats like a max-size singulo, aside from range. --NEO - contained = 0 //Are we going to move around? - dissipate = 0 //Do we lose energy over time? - move_self = 1 //Do we move on our own? + icon = 'icons/obj/narsie.dmi' + icon_state = "narsie-small" + pixel_x = -236 + pixel_y = -256 + + current_size = 9 //It moves/eats like a max-size singulo, aside from range. --NEO. + contained = 0 // Are we going to move around? + dissipate = 0 // Do we lose energy over time? grav_pull = 10 //How many tiles out do we pull? consume_range = 3 //How many tiles out do we eat - var/last_boom = 0 + + +/obj/machinery/singularity/narsie/New() + ..() + narsie_list.Add(src) + +/obj/machinery/singularity/narsie/Destroy() + narsie_list.Remove(src) + ..() /obj/machinery/singularity/narsie/large name = "Nar-Sie" icon = 'icons/obj/narsie.dmi' + icon_state = "narsie"//mobs perceive the geometer of blood through their see_narsie proc + // Pixel stuff centers Narsie. pixel_x = -236 pixel_y = -256 + luminosity = 1 + l_color = "#3e0000" + current_size = 12 - move_self = 1 //Do we move on our own? - consume_range = 12 //How many tiles out do we eat + consume_range = 12 // How many tiles out do we eat. + var/announce=1 + var/narnar = 1 /obj/machinery/singularity/narsie/large/New() ..() - narsie_list.Add(src) - world << "NAR-SIE HAS RISEN" + if(announce) + world << "[uppertext(name)] HAS RISEN" + world << sound('sound/effects/wind/wind_5_1.ogg') + if(emergency_shuttle && emergency_shuttle.can_call()) emergency_shuttle.call_evac() emergency_shuttle.launch_time = 0 // Cannot recall -/obj/machinery/singularity/narsie/large/Destroy() - narsie_list.Remove(src) - ..() + if(narnar) + SetUniversalState(/datum/universal_state/hell) + narsie_cometh = 1 /obj/machinery/singularity/narsie/process() eat() - if(!target || prob(5)) + + if (!target || prob(5)) pickcultist() + move() - if(prob(25)) + + if (prob(25)) mezzer() -/obj/machinery/singularity/narsie/consume(var/atom/A) //Has its own consume proc because it doesn't need energy and I don't want BoHs to explode it. --NEO - if(is_type_in_list(A, uneatable)) - return 0 - if (istype(A,/mob/living))//Mobs get gibbed - A:gib() - else if(istype(A,/obj)) - var/obj/O = A - machines -= O - processing_objects -= O - O.loc = null - else if(isturf(A)) - var/turf/T = A - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.consume(O) - A:ChangeTurf(/turf/space) - if(last_boom + 100 < world.time && prob(5)) - explosion(loc, -1, -1, -1, 1, 0) //Since we're not exploding everything in consume() toss out an explosion effect every now and again - last_boom = world.time - return +/obj/machinery/singularity/narsie/large/eat() + set background = BACKGROUND_ENABLED -/obj/machinery/singularity/narsie/ex_act() //No throwing bombs at it either. --NEO + for (var/turf/A in orange(consume_range, src)) + consume(A) + +/obj/machinery/singularity/narsie/mezzer() + for(var/mob/living/carbon/M in oviewers(8, src)) + if(M.stat == CONSCIOUS) + if(M.status_flags & GODMODE) + continue + if(!iscultist(M)) + M << " You feel your sanity crumble away in an instant as you gaze upon [src.name]..." + M.apply_effect(3, STUN) + + +/obj/machinery/singularity/narsie/large/Bump(atom/A) + if(!narnar) return + if(isturf(A)) + narsiewall(A) + else if(istype(A, /obj/structure/cult)) + qdel(A) + +/obj/machinery/singularity/narsie/large/Bumped(atom/A) + if(!narnar) return + if(isturf(A)) + narsiewall(A) + else if(istype(A, /obj/structure/cult)) + qdel(A) + +/obj/machinery/singularity/narsie/move(var/force_move = 0) + if(!move_self) + return 0 + + var/movement_dir = pick(alldirs - last_failed_movement) + + if(force_move) + movement_dir = force_move + + if(target && prob(60)) + movement_dir = get_dir(src,target) + + spawn(0) + step(src, movement_dir) + spawn(1) + step(src, movement_dir) + return 1 + +/obj/machinery/singularity/narsie/large/move(var/force_move = 0) + if(!move_self) + return 0 + + var/movement_dir = pick(alldirs - last_failed_movement) + + if(force_move) + movement_dir = force_move + + if(target && prob(60)) + movement_dir = get_dir(src,target) + spawn(0) + step(src, movement_dir) + narsiefloor(get_turf(loc)) + for(var/mob/M in player_list) + if(M.client) + M.see_narsie(src,movement_dir) + spawn(10) + step(src, movement_dir) + narsiefloor(get_turf(loc)) + for(var/mob/M in player_list) + if(M.client) + M.see_narsie(src,movement_dir) + return 1 + +/obj/machinery/singularity/narsie/proc/narsiefloor(var/turf/T)//leaving "footprints" + if(!(istype(T, /turf/simulated/wall/cult)||istype(T, /turf/space))) + if(T.icon_state != "cult-narsie") + T.desc = "something that goes beyond your understanding went this way" + T.icon_state = "cult-narsie" + T.luminosity = 1 + +/obj/machinery/singularity/narsie/proc/narsiewall(var/turf/T) + T.desc = "An opening has been made on that wall, but who can say if what you seek truly lies on the other side?" + T.icon = 'icons/turf/walls.dmi' + T.icon_state = "cult-narsie" + T.opacity = 0 + T.density = 0 + luminosity = 1 + +/obj/machinery/singularity/narsie/large/consume(const/atom/A) //Has its own consume proc because it doesn't need energy and I don't want BoHs to explode it. --NEO +//NEW BEHAVIOUR + if(narsie_behaviour == "CultStation13") + //MOB PROCESSING + new_narsie(A) + +//OLD BEHAVIOUR + else if(narsie_behaviour == "Nar-Singulo") + old_narsie(A) + +/obj/machinery/singularity/narsie/proc/new_narsie(const/atom/A) + if (istype(A, /mob/) && (get_dist(A, src) <= 7)) + var/mob/M = A + + if(M.status_flags & GODMODE) + return 0 + + M.cultify() + +//ITEM PROCESSING + else if (istype(A, /obj/)) + var/obj/O = A + O.cultify() + +//TURF PROCESSING + else if (isturf(A)) + var/dist = get_dist(A, src) + + for (var/atom/movable/AM in A.contents) + if (dist <= consume_range) + consume(AM) + continue + + if (dist <= consume_range && !istype(A, /turf/space)) + var/turf/T = A + if(T.holy) + T.holy = 0 //Nar-Sie doesn't give a shit about sacred grounds. + T.cultify() + +/obj/machinery/singularity/narsie/proc/old_narsie(const/atom/A) + if(!(A.singuloCanEat())) + return 0 + + if (istype(A, /mob/living/)) + var/mob/living/C2 = A + + if(C2.status_flags & GODMODE) + return 0 + + C2.dust() // Changed from gib(), just for less lag. + + else if (istype(A, /obj/)) + qdel(A) + + if (A) + qdel(A) + else if (isturf(A)) + var/dist = get_dist(A, src) + + for (var/atom/movable/AM2 in A.contents) + if (AM2 == src) // This is the snowflake. + continue + + if (dist <= consume_range) + consume(AM2) + continue + + if (dist <= consume_range && !istype(A, /turf/space)) + var/turf/T2 = A + T2.ChangeTurf(/turf/space) + +/obj/machinery/singularity/narsie/consume(const/atom/A) //This one is for the small ones. + if(!(A.singuloCanEat())) + return 0 + + if (istype(A, /mob/living/)) + var/mob/living/C2 = A + + if(C2.status_flags & GODMODE) + return 0 + + C2.dust() // Changed from gib(), just for less lag. + + else if (istype(A, /obj/)) + qdel(A) + + if (A) + qdel(A) + else if (isturf(A)) + var/dist = get_dist(A, src) + + for (var/atom/movable/AM2 in A.contents) + if (AM2 == src) // This is the snowflake. + continue + + if (dist <= consume_range) + consume(AM2) + continue + + if (dist > consume_range) + if(!(AM2.singuloCanEat())) + continue + + if (101 == AM2.invisibility) + continue + + spawn (0) + AM2.singularity_pull(src, src.current_size) + + if (dist <= consume_range && !istype(A, /turf/space)) + var/turf/T2 = A + T2.ChangeTurf(/turf/space) + +/obj/machinery/singularity/narsie/ex_act(severity) //No throwing bombs at it either. --NEO return /obj/machinery/singularity/narsie/proc/pickcultist() //Narsie rewards his cultists with being devoured first, then picks a ghost to follow. --NEO var/list/cultists = list() - if(cult && cult.current_antagonists.len) - for(var/datum/mind/cult_nh_mind in cult.current_antagonists) - if(!cult_nh_mind.current) - continue - if(cult_nh_mind.current.stat) - continue - var/turf/pos = get_turf(cult_nh_mind.current) - if(pos.z != src.z) - continue - cultists += cult_nh_mind.current + for(var/datum/mind/cult_nh_mind in cult.current_antagonists) + if(!cult_nh_mind.current) + continue + if(cult_nh_mind.current.stat) + continue + var/turf/pos = get_turf(cult_nh_mind.current) + if(pos.z != src.z) + continue + cultists += cult_nh_mind.current if(cultists.len) acquire(pick(cultists)) return @@ -112,22 +307,51 @@ var/global/list/narsie_list = list() return //no living humans, follow a ghost instead. -/obj/machinery/singularity/narsie/proc/acquire(var/mob/food) - target << "\blue NAR-SIE HAS LOST INTEREST IN YOU" +/obj/machinery/singularity/narsie/proc/acquire(const/mob/food) + var/capname = uppertext(name) + + target << "[capname] HAS LOST INTEREST IN YOU." target = food - if(ishuman(target)) - target << "\red NAR-SIE HUNGERS FOR YOUR SOUL" + + if (ishuman(target)) + target << "[capname] HUNGERS FOR YOUR SOUL." else - target << "\red NAR-SIE HAS CHOSEN YOU TO LEAD HIM TO HIS NEXT MEAL" + target << "[capname] HAS CHOSEN YOU TO LEAD HIM TO HIS NEXT MEAL." -//Wizard narsie +/obj/machinery/singularity/narsie/on_capture() + chained = 1 + move_self = 0 + icon_state ="narsie-small-chains" +/obj/machinery/singularity/narsie/on_release() + chained = 0 + move_self = 1 + icon_state ="narsie-small" + +/obj/machinery/singularity/narsie/large/on_capture() + chained = 1 + move_self = 0 + icon_state ="narsie-chains" + for(var/mob/M in mob_list)//removing the client image of nar-sie while it is chained + if(M.client) + M.see_narsie(src) + +/obj/machinery/singularity/narsie/large/on_release() + chained = 0 + move_self = 1 + icon_state ="narsie" + +/obj/machinery/singularity/narsie/cultify() + return + +/** + * Wizard narsie. + */ /obj/machinery/singularity/narsie/wizard grav_pull = 0 /obj/machinery/singularity/narsie/wizard/eat() - set background = 1 - for(var/atom/X in orange(consume_range,src)) - if(isturf(X) || istype(X, /atom/movable)) - consume(X) - return + set background = BACKGROUND_ENABLED + + for (var/turf/T in trange(consume_range, src)) + consume(T) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index a2901ac270b..aa8e85017c4 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -1,10 +1,5 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 -var/global/list/uneatable = list( - /turf/space, - /obj/effect/overlay - ) - /obj/machinery/singularity/ name = "gravitational singularity" desc = "A gravitational singularity." @@ -16,6 +11,7 @@ var/global/list/uneatable = list( luminosity = 6 unacidable = 1 //Don't comment this out. use_power = 0 + var/current_size = 1 var/allowed_size = 1 var/contained = 1 //Are we going to move around? @@ -26,102 +22,108 @@ var/global/list/uneatable = list( var/dissipate_strength = 1 //How much energy do we lose? var/move_self = 1 //Do we move on our own? var/grav_pull = 4 //How many tiles out do we pull? - var/consume_range = 0 //How many tiles out do we eat - var/event_chance = 15 //Prob for event each tick - var/target = null //its target. moves towards the target if it has one - var/last_failed_movement = 0//Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing - var/teleport_del = 0 + var/consume_range = 0 //How many tiles out do we eat. + var/event_chance = 15 //Prob for event each tick. + var/target = null //Its target. Moves towards the target if it has one. + var/last_failed_movement = 0 //Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing. var/last_warning + var/chained = 0//Adminbus chain-grab + /obj/machinery/singularity/New(loc, var/starting_energy = 50, var/temp = 0) //CARN: admin-alert for chuckle-fuckery. admin_investigate_setup() + energy = starting_energy + + if (temp) + spawn (temp) + qdel(src) - src.energy = starting_energy - if(temp) - spawn(temp) - del(src) ..() for(var/obj/machinery/power/singularity_beacon/singubeacon in machines) if(singubeacon.active) target = singubeacon break - return - /obj/machinery/singularity/attack_hand(mob/user as mob) consume(user) return 1 - /obj/machinery/singularity/blob_act(severity) return - /obj/machinery/singularity/ex_act(severity) + if(current_size == STAGE_SUPER)//IT'S UNSTOPPABLE + return switch(severity) if(1.0) if(prob(25)) - del(src) + investigate_log("has been destroyed by an explosion.", I_SINGULO) + qdel(src) return else energy += 50 if(2.0 to 3.0) energy += round((rand(20,60)/2),1) return - return +/obj/machinery/singularity/bullet_act(obj/item/projectile/P) + return 0 //Will there be an impact? Who knows. Will we see it? No. /obj/machinery/singularity/Bump(atom/A) consume(A) - return - /obj/machinery/singularity/Bumped(atom/A) consume(A) - return - /obj/machinery/singularity/process() eat() dissipate() check_energy() - if(current_size >= 3) + if (current_size >= STAGE_THREE) move() pulse() - if(prob(event_chance))//Chance for it to run a special event TODO:Come up with one or two more that fit + + if (prob(event_chance)) //Chance for it to run a special event TODO: Come up with one or two more that fit. event() + +/obj/machinery/singularity/attack_ai() //To prevent ais from gibbing themselves when they click on one. return - -/obj/machinery/singularity/attack_ai() //to prevent ais from gibbing themselves when they click on one. - return - - /obj/machinery/singularity/proc/admin_investigate_setup() last_warning = world.time var/count = locate(/obj/machinery/containment_field) in orange(30, src) - if(!count) message_admins("A singulo has been created without containment fields active ([x],[y],[z])",1) - investigate_log("was created. [count?"":"No containment fields were active"]","singulo") + + if (!count) + message_admins("A singulo has been created without containment fields active ([x], [y], [z] - JMP).") + + investigate_log("was created. [count ? "" : "No containment fields were active."]", I_SINGULO) /obj/machinery/singularity/proc/dissipate() - if(!dissipate) + if (!dissipate) return + if(dissipate_track >= dissipate_delay) - src.energy -= dissipate_strength + energy -= dissipate_strength dissipate_track = 0 else dissipate_track++ +/obj/machinery/singularity/proc/expand(var/force_size = 0, var/growing = 1) + if(current_size == STAGE_SUPER)//if this is happening, this is an error + message_admins("expand() was called on a super singulo. This should not happen. Contact a coder immediately!") + return + var/temp_allowed_size = allowed_size -/obj/machinery/singularity/proc/expand(var/force_size = 0) - var/temp_allowed_size = src.allowed_size - if(force_size) + if (force_size) temp_allowed_size = force_size - switch(temp_allowed_size) - if(1) - current_size = 1 + + switch (temp_allowed_size) + if (STAGE_ONE) + name = "gravitational singularity" + desc = "A gravitational singularity." + current_size = STAGE_ONE icon = 'icons/obj/singularity.dmi' icon_state = "singularity_s1" pixel_x = 0 @@ -131,8 +133,14 @@ var/global/list/uneatable = list( dissipate_delay = 10 dissipate_track = 0 dissipate_strength = 1 - if(3)//1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them - current_size = 3 + overlays = 0 + if(chained) + overlays = "chain_s1" + visible_message("The singularity has shrunk to a rather pitiful size.") + if (STAGE_TWO) //1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them. + name = "gravitational singularity" + desc = "A gravitational singularity." + current_size = STAGE_TWO icon = 'icons/effects/96x96.dmi' icon_state = "singularity_s3" pixel_x = -32 @@ -142,9 +150,18 @@ var/global/list/uneatable = list( dissipate_delay = 5 dissipate_track = 0 dissipate_strength = 5 - if(5) - if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2))) - current_size = 5 + overlays = 0 + if(chained) + overlays = "chain_s3" + if(growing) + visible_message("The singularity noticeably grows in size.") + else + visible_message("The singularity has shrunk to a less powerful size.") + if (STAGE_THREE) + if ((check_turfs_in(1, 2)) && (check_turfs_in(2, 2)) && (check_turfs_in(4, 2)) && (check_turfs_in(8, 2))) + name = "gravitational singularity" + desc = "A gravitational singularity." + current_size = STAGE_THREE icon = 'icons/effects/160x160.dmi' icon_state = "singularity_s5" pixel_x = -64 @@ -154,9 +171,18 @@ var/global/list/uneatable = list( dissipate_delay = 4 dissipate_track = 0 dissipate_strength = 20 - if(7) - if((check_turfs_in(1,3))&&(check_turfs_in(2,3))&&(check_turfs_in(4,3))&&(check_turfs_in(8,3))) - current_size = 7 + overlays = 0 + if(chained) + overlays = "chain_s5" + if(growing) + visible_message("The singularity expands to a reasonable size.") + else + visible_message("The singularity has returned to a safe size.") + if(STAGE_FOUR) + if ((check_turfs_in(1, 3)) && (check_turfs_in(2, 3)) && (check_turfs_in(4, 3)) && (check_turfs_in(8, 3))) + name = "gravitational singularity" + desc = "A gravitational singularity." + current_size = STAGE_FOUR icon = 'icons/effects/224x224.dmi' icon_state = "singularity_s7" pixel_x = -96 @@ -166,123 +192,100 @@ var/global/list/uneatable = list( dissipate_delay = 10 dissipate_track = 0 dissipate_strength = 10 - if(9)//this one also lacks a check for gens because it eats everything - current_size = 9 + overlays = 0 + if(chained) + overlays = "chain_s7" + if(growing) + visible_message("The singularity expands to a dangerous size.") + else + visible_message("Miraculously, the singularity reduces in size, and can be contained.") + if(STAGE_FIVE) //This one also lacks a check for gens because it eats everything. + name = "gravitational singularity" + desc = "A gravitational singularity." + current_size = STAGE_FIVE icon = 'icons/effects/288x288.dmi' icon_state = "singularity_s9" pixel_x = -128 pixel_y = -128 grav_pull = 10 consume_range = 4 + dissipate = 0 //It cant go smaller due to e loss. + overlays = 0 + if(chained) + overlays = "chain_s9" + if(growing) + visible_message("The singularity has grown out of control!") + else + visible_message("The singularity miraculously reduces in size and loses its supermatter properties.") + if(STAGE_SUPER)//SUPERSINGULO + name = "super gravitational singularity" + desc = "A gravitational singularity with the properties of supermatter. It has the power to destroy worlds." + current_size = STAGE_SUPER + icon = 'icons/effects/352x352.dmi' + icon_state = "singularity_s11"//uh, whoever drew that, you know that black holes are supposed to look dark right? What's this, the clown's singulo? + pixel_x = -160 + pixel_y = -160 + grav_pull = 16 + consume_range = 5 dissipate = 0 //It cant go smaller due to e loss - if(current_size == allowed_size) - investigate_log("grew to size [current_size]","singulo") + event_chance = 25 //Events will fire off more often. + if(chained) + overlays = "chain_s9" + visible_message("You witness the creation of a destructive force that cannot possibly be stopped by human hands.") + + if (current_size == allowed_size) + investigate_log("grew to size [current_size].", I_SINGULO) return 1 - else if(current_size < (--temp_allowed_size)) + else if (current_size < (--temp_allowed_size) && current_size != STAGE_SUPER) expand(temp_allowed_size) else return 0 - /obj/machinery/singularity/proc/check_energy() - if(energy <= 0) - del(src) + if (energy <= 0) + investigate_log("collapsed.", I_SINGULO) + qdel(src) return 0 - switch(energy)//Some of these numbers might need to be changed up later -Mport - if(1 to 199) - allowed_size = 1 - if(200 to 499) - allowed_size = 3 - if(500 to 999) - allowed_size = 5 - if(1000 to 1999) - allowed_size = 7 - if(2000 to INFINITY) - allowed_size = 9 - if(current_size != allowed_size) - expand() + + switch (energy) //Some of these numbers might need to be changed up later -Mport. + if (1 to 199) + allowed_size = STAGE_ONE + if (200 to 499) + allowed_size = STAGE_TWO + if (500 to 999) + allowed_size = STAGE_THREE + if (1000 to 1999) + allowed_size = STAGE_FOUR + if(2000 to 49999) + allowed_size = STAGE_FIVE + if(50000 to INFINITY) + allowed_size = STAGE_SUPER + + if (current_size != allowed_size && current_size != STAGE_SUPER) + expand(null, current_size > allowed_size) return 1 - /obj/machinery/singularity/proc/eat() - set background = 1 - // Let's just make this one loop. - for(var/atom/X in orange(grav_pull,src)) + set background = BACKGROUND_ENABLED + + for(var/atom/X in orange(grav_pull, src)) var/dist = get_dist(X, src) - // Movable atoms only - if(dist > consume_range && istype(X, /atom/movable)) - if(is_type_in_list(X, uneatable)) continue - if(((X) &&(!X:anchored) && (!istype(X,/mob/living/carbon/human)))|| (src.current_size >= 9)) - step_towards(X,src) - else if(istype(X,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = X - if(istype(H.shoes,/obj/item/clothing/shoes/magboots)) - var/obj/item/clothing/shoes/magboots/M = H.shoes - if(M.magpulse) - continue - step_towards(H,src) - // Turf and movable atoms - else if(dist <= consume_range && (isturf(X) || istype(X, /atom/movable))) - consume(X) - return - - -/obj/machinery/singularity/proc/consume(var/atom/A) - var/gain = 0 - if(is_type_in_list(A, uneatable)) - return 0 - if (istype(A,/mob/living))//Mobs get gibbed - gain = 20 - if(istype(A,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = A - if(H.mind) - - if((H.mind.assigned_role == "Station Engineer") || (H.mind.assigned_role == "Chief Engineer") ) - gain = 100 - - if(H.mind.assigned_role == "Clown") - gain = rand(-300, 300) // HONK - - spawn() - A:gib() - sleep(1) - else if(istype(A,/obj/)) - - if (istype(A,/obj/item/weapon/storage/backpack/holding)) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) + var/obj/machinery/singularity/S = src + if(!istype(src)) return + if(dist > consume_range) + X.singularity_pull(S, current_size) + else if(dist <= consume_range) + consume(X) - if(istype(A, /obj/machinery/singularity))//Welp now you did it - var/obj/machinery/singularity/S = A - src.energy += (S.energy/2)//Absorb most of it - del(S) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) - return//Quits here, the obj should be gone, hell we might be + //for (var/turf/T in trange(grav_pull, src)) //TODO: Create a similar trange for orange to prevent snowflake of self check. + // consume(T) - if((teleport_del) && (!istype(A, /obj/machinery)))//Going to see if it does not lag less to tele items over to Z 2 - var/obj/O = A - O.x = 2 - O.y = 2 - O.z = 2 - else - A.ex_act(1.0) - if(A) del(A) - gain = 2 - else if(isturf(A)) - var/turf/T = A - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.consume(O) - T.ChangeTurf(/turf/space) - gain = 2 - src.energy += gain return +/obj/machinery/singularity/proc/consume(const/atom/A) + src.energy += A.singularity_act(src, current_size) + return /obj/machinery/singularity/proc/move(var/force_move = 0) if(!move_self) @@ -311,7 +314,6 @@ var/global/list/uneatable = list( last_failed_movement = movement_dir return 0 - /obj/machinery/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0) if(!direction) return 0 @@ -328,6 +330,8 @@ var/global/list/uneatable = list( steps = 4 if(9) steps = 5 + if(11) + steps = 6 else steps = step var/list/turfs = list() @@ -364,34 +368,38 @@ var/global/list/uneatable = list( return 0 return 1 +/obj/machinery/singularity/proc/can_move(const/turf/T) + if (!isturf(T)) + return 0 -/obj/machinery/singularity/proc/can_move(var/turf/T) - if(!T) + if ((locate(/obj/machinery/containment_field) in T) || (locate(/obj/machinery/shieldwall) in T)) return 0 - if((locate(/obj/machinery/containment_field) in T)||(locate(/obj/machinery/shieldwall) in T)) - return 0 - else if(locate(/obj/machinery/field_generator) in T) + else if (locate(/obj/machinery/field_generator) in T) var/obj/machinery/field_generator/G = locate(/obj/machinery/field_generator) in T - if(G && G.active) + + if (G && G.active) return 0 - else if(locate(/obj/machinery/shieldwallgen) in T) + else if (locate(/obj/machinery/shieldwallgen) in T) var/obj/machinery/shieldwallgen/S = locate(/obj/machinery/shieldwallgen) in T - if(S && S.active) + + if (S && S.active) return 0 return 1 - /obj/machinery/singularity/proc/event() - var/numb = pick(1,2,3,4,5,6) - switch(numb) - if(1)//EMP + var/numb = pick(1, 2, 3, 4, 5, 6) + + switch (numb) + if (1) //EMP. emp_area() - if(2,3)//tox damage all carbon mobs in area + if (2, 3) //Tox damage all carbon mobs in area. toxmob() - if(4)//Stun mobs who lack optic scanners + if (4) //Stun mobs who lack optic scanners. mezzer() else return 0 + if(current_size == 11) + smwave() return 1 @@ -405,6 +413,8 @@ var/global/list/uneatable = list( radiation = round(((src.energy-150)/50)*5,1) radiationmin = round((radiation/5),1)// for(var/mob/living/M in view(toxrange, src.loc)) + if(M.status_flags & GODMODE) + continue M.apply_effect(rand(radiationmin,radiation), IRRADIATE) toxdamage = (toxdamage - (toxdamage*M.getarmor(null, "rad"))) M.apply_effect(toxdamage, TOX) @@ -415,28 +425,70 @@ var/global/list/uneatable = list( for(var/mob/living/carbon/M in oviewers(8, src)) if(istype(M, /mob/living/carbon/brain)) //Ignore brains continue - + if(M.status_flags & GODMODE) + continue if(M.stat == CONSCIOUS) if (istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(istype(H.glasses,/obj/item/clothing/glasses/meson)) - H << "\blue You look directly into The [src.name], good thing you had your protective eyewear on!" + if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != 11) + H << "You look directly into The [src.name], good thing you had your protective eyewear on!" return - M << "\red You look directly into The [src.name] and feel weak." + else + H << "You look directly into The [src.name], but your eyewear does absolutely nothing to protect you from it!" + M << "You look directly into The [src.name] and feel [current_size == 11 ? "helpless" : "weak"]." M.apply_effect(3, STUN) for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] stares blankly at The []!", M, src), 1) - return - + O.show_message(text("[] stares blankly at The []!", M, src), 1) /obj/machinery/singularity/proc/emp_area() - empulse(src, 8, 10) - return + if(current_size != 11) + empulse(src, 8, 10) + else + empulse(src, 12, 16) +/obj/machinery/singularity/proc/smwave() + for(var/mob/living/M in view(10, src.loc)) + if(prob(67)) + M.apply_effect(rand(energy), IRRADIATE) + M << "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat." + M << "Miraculously, it fails to kill you." + else + M << "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat." + M << "You don't even have a moment to react as you are reduced to ashes by the intense radiation." + M.dust() + return /obj/machinery/singularity/proc/pulse() - for(var/obj/machinery/power/rad_collector/R in rad_collectors) - if(get_dist(R, src) <= 15) // Better than using orange() every process + if (get_dist(R, src) <= 15) //Better than using orange() every process. R.receive_pulse(energy) - return + +/obj/machinery/singularity/proc/on_capture() + chained = 1 + overlays = 0 + move_self = 0 + switch (current_size) + if(1) + overlays += image('icons/obj/singularity.dmi',"chain_s1") + if(3) + overlays += image('icons/effects/96x96.dmi',"chain_s3") + if(5) + overlays += image('icons/effects/160x160.dmi',"chain_s5") + if(7) + overlays += image('icons/effects/224x224.dmi',"chain_s7") + if(9) + overlays += image('icons/effects/288x288.dmi',"chain_s9") + +/obj/machinery/singularity/proc/on_release() + chained = 0 + overlays = 0 + move_self = 1 + +/obj/machinery/singularity/singularity_act(S, size) + if(current_size <= size) + var/gain = (energy/2) + var/dist = max((current_size - 2), 1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + spawn(0) + qdel(src) + return gain diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 2a73fd5786f..44ee2987c42 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -156,6 +156,8 @@ datum else if(istype(self.data["donor"], /mob/living/carbon/alien)) var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1) if(B) B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" + if(volume >= 5 && !istype(T.loc, /area/chapel)) //blood desanctifies non-chapel tiles + T.holy = 0 return /* Must check the transfering of reagents and their data first. They all can point to one disease datum. @@ -289,6 +291,12 @@ datum holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls. return + reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + T.holy = 1 + return + lube name = "Space Lube" id = "lube" diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index 6cdf0c3e91d..587b5d93428 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -332,29 +332,7 @@ defer_powernet_rebuild = 1 // Let's just make this one loop. for(var/atom/X in orange(pull_radius,src)) - // Movable atoms only - if(istype(X, /atom/movable)) - if(is_type_in_list(X, uneatable)) continue - if(((X) && (!istype(X,/mob/living/carbon/human)))) - step_towards(X,src) - if(istype(X, /obj)) //unanchored objects pulled twice as fast - var/obj/O = X - if(!O.anchored) - step_towards(X,src) - else - step_towards(X,src) - if(istype(X, /obj/structure/window)) //shatter windows - var/obj/structure/window/W = X - W.ex_act(2.0) - else if(istype(X,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = X - if(istype(H.shoes,/obj/item/clothing/shoes/magboots)) - var/obj/item/clothing/shoes/magboots/M = H.shoes - if(M.magpulse) - step_towards(H,src) //step just once with magboots - continue - step_towards(H,src) //step twice - step_towards(H,src) + X.singularity_pull(src, STAGE_FIVE) if(defer_powernet_rebuild != 2) defer_powernet_rebuild = 0 diff --git a/code/setup.dm b/code/setup.dm index e5c82424776..38836d54d52 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -909,3 +909,11 @@ var/list/be_special_flags = list( #define Sp_HOLDVAR "holdervar" ///////WIZ END///////// + +//singularity defines +#define STAGE_ONE 1 +#define STAGE_TWO 3 +#define STAGE_THREE 5 +#define STAGE_FOUR 7 +#define STAGE_FIVE 9 +#define STAGE_SUPER 11 diff --git a/icons/effects/352x352.dmi b/icons/effects/352x352.dmi new file mode 100644 index 00000000000..de15d61dd9b Binary files /dev/null and b/icons/effects/352x352.dmi differ diff --git a/icons/mob/bats.dmi b/icons/mob/bats.dmi new file mode 100644 index 00000000000..74466935077 Binary files /dev/null and b/icons/mob/bats.dmi differ diff --git a/icons/mob/screen1_construct.dmi b/icons/mob/screen1_construct.dmi new file mode 100644 index 00000000000..67a37ccd738 Binary files /dev/null and b/icons/mob/screen1_construct.dmi differ diff --git a/icons/obj/magic_terror.dmi b/icons/obj/magic_terror.dmi deleted file mode 100644 index 025e164ccd3..00000000000 Binary files a/icons/obj/magic_terror.dmi and /dev/null differ diff --git a/icons/obj/narsie.dmi b/icons/obj/narsie.dmi index 940b0941762..73df7c31d18 100644 Binary files a/icons/obj/narsie.dmi and b/icons/obj/narsie.dmi differ diff --git a/icons/obj/rift.dmi b/icons/obj/rift.dmi new file mode 100644 index 00000000000..85b7510386c Binary files /dev/null and b/icons/obj/rift.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index 859c6e7681a..c3fdbcdb333 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi index 9f15fbbe63a..30d0d1428a5 100644 Binary files a/icons/turf/space.dmi and b/icons/turf/space.dmi differ diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm index 3259c44b427..e0ba7543f2a 100644 --- a/maps/exodus-2.dmm +++ b/maps/exodus-2.dmm @@ -1756,7 +1756,7 @@ "HN" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/unsimulated/beach/sand,/area/beach) "HO" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/unsimulated/beach/sand,/area/beach) "HP" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/beach) -"HQ" = (/obj/structure/bed/chair,/turf/unsimulated/beach/sand,/area/beach) +"HQ" = (/obj/structure/bed/chair{dir = 1},/obj/item/clothing/glasses/thermal/plain/monocle,/obj/item/clothing/head/pirate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station) "HR" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/beach) "HS" = (/obj/item/clothing/head/collectable/paper,/turf/unsimulated/beach/sand,/area/beach) "HT" = (/turf/unsimulated/floor{icon_state = "sandwater"},/area/beach) @@ -2090,7 +2090,7 @@ "Oj" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) "Ok" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/item/weapon/crowbar,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) "Ol" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) -"Om" = (/obj/structure/bed/chair{dir = 1},/obj/item/clothing/glasses/thermal/plain/monocle,/obj/item/clothing/head/pirate,/turf/simulated/shuttle/floor{icon_state ="floor4"},/area/shuttle/skipjack/station) +"Om" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) "On" = (/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) "Oo" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) "Op" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) @@ -2121,6 +2121,7 @@ "OO" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/crossbow,/obj/item/stack/rods{amount = 10},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station) "OP" = (/obj/structure/table/rack,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/grenade/spawnergrenade,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station) "OQ" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/glasses/thermal/plain/monocle,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"OR" = (/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) "OS" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) "OT" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/simulated/floor,/area/tdome) "OU" = (/obj/structure/table/woodentable,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) @@ -2301,7 +2302,7 @@ mumumumumumumumumuaMaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmt mumumumumumumumumuaMaMaMaMaMKYKQKQKZaMaMaMKYaMaMaMaMaMKZaMaMaMKYKQKQKZaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHNODgDgDgDgEoDaCPCPCPCPCPCPCPCPCPDGDSDSLaEqLbLcCNEtDVDVDVEwExDVDVEyCNaMaMaMaMaMaMaMEAEBEBAtNQEaNREbNPAtEBEBBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mumumumumumuaMaMaMaMaMaMaMaMMHLfMLMHaMaMaMLgMOMIMIMIMJLkaMaMaMMHNnLmMHaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgECNuDrEDEEEFEGEGEGEHEHEHEIEJLnELEMEHEHEHCNCNCNNvDVDVEwEPEQExERESCNaMaMaMaMaMaMaMETEVEVBVDYDZEaNtNsEAEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mumumumumumuaMaMaMaMaMaMaMaMLsMpMwLsaMaMKYLsLrMmMnMoLrLsKZaMaMLsMGMFLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgEDEXEYEZEZEZEZEHFaFbFcFdFeFfFgFbFaEHCNCNCNCNCNCNNrFiNqFkERESCNaMaMaMaMaMaMaMaMaMaMETATEUEUEUATEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -mumumumumumuaMaMaMaMaMaMaMaMLsOoOuLsaMaMLgMfMaOhOmOhMaMeLkaMaMLsOfOgLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHFlDgEDEXEYEYEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMLsOoOuLsaMaMLgMfMaOhHQOhMaMeLkaMaMLsOfOgLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHFlDgEDEXEYEYEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mumumumumumuaMaMaMaMaMaMaMaMLyOeLpLoLpLpLXOdMaMaMaMaMaOcLyLpLpLoLpNBLXaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgEDEXEYEYEYEZEZEZEZEHFvFbFvFdFeFfFvFbFvEHFwDVDVDVDVMqDVDVDVDVDVFyFzaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mumumumumumuaMaMaMaMaMaMaMaMLsMsMrMuMtMvLsOLMaMaMaMaMaOLLsMyMxMBMzMsLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHEDEXEYEYEYEYEYEYEYEYEHFAFbFbFdFeFfFbFbFBEHFCFDFEFFMCCNDVDVDVDVDVFHFIaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM mumumuaMaMaMaMaMaMaMaMaMaMaMLsMsMDMDMDMELsOwOGOHMbOwOGOHLsOKMDMDMKMsLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHEHFJFKFKFdFeFfFLFLFMEHFNFOFPFQFRCNFSFTFUFVFWFXCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM @@ -2323,13 +2324,13 @@ mumumumuaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmt mumumumuaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHOSEHHbHbHbHbHbEHGBGCGCGCGCGCGCHcGCGCGCGCGCGDGBEHHbHbHbHbHbEHOSEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGYGYGYGU mumumumuaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFJHiFbEHGzGzGzGzGzEHGxGxGxGxGxGxOTHlOTGxGxGxGxGyGxEHGEGEGEGEGEEHFbHnFMEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGYGYGYGU mumuaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHFbEHEHEHEHEHEHEHHoHpHpHpHpHpHqHrHoHpHpHpHpHsHoEHEHEHEHEHEHEHFbEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYHtHhGYGYGYGYGYGYGYGYGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFbFbFeFeFeFeFeEHHoHoHuHoHuHoHoHvHwHoHuHoHuHxHoEHFeFeFeFeFeFbFbEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU -mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHFeMNHoHoHoHyHyHyHoHoHoHyHyHyHyHyHoMNFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYHzHAGYGYGYGYGYGYGYGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHHBHBHBHCHDHEHFHoHGHHHIHJHKHLHMEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYHNHOGYGYGYHtGYHPGYGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFbFbFeFeFeFeFeEHHoHoHuHoHuHoHoHvHwHoHuHoHuHxHoEHFeFeFeFeFeFbFbEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYORORGYGYGYGYGYGYGYGYGYGYGYGYGU +mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHFeMNHoHoHoHyHyHyHoHoHoHyHyHyHyHyHoMNFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYORHzHAORGYGYGYGYGYGYGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHHBHBHBHCHDHEHFHoHGHHHIHJHKHLHMEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYORHNHOORGYGYHtGYHPGYGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYORORGYGYGYGYGYGYGYGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYHhGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYHtHhGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYHQGYHQGYHQGYHRGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYOmGYOmGYOmGYHRGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYHSGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTHTGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHUHVHVHVHVHVHVHVHVHVHVHVHVHVHVHVHVHVHVHVHU diff --git a/maps/exodus-5.dmm b/maps/exodus-5.dmm index 22732bb0b88..239b3b0674e 100644 --- a/maps/exodus-5.dmm +++ b/maps/exodus-5.dmm @@ -815,7 +815,7 @@ "pI" = (/obj/structure/disposalpipe/segment,/turf/unsimulated/mask,/area/mine/unexplored) "pJ" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) "pK" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) -"pL" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) +"pL" = (/obj/structure/table,/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) "pM" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/dock) "pN" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) "pO" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_a) @@ -1600,6 +1600,9 @@ "EN" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating/airless,/area/space) "EO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) "EP" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"EQ" = (/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"ER" = (/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"ES" = (/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1647,11 +1650,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababiLiKiKiJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaJaJaJaJaJababababababababiMeOeOdHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababaJiNiOiPaJaJaJaJaJaJaGaGaGaGiQiRaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaababababababababaJjbiTiUiViWaKaKaKiSaiiZjfaiiYeOaijaiZaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaababababababababaJjbERiUiViWaKaKaKiSaiiZjfaiiYeOaijaiZaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababaAaAaAaAjpjhiTjrjgjdjdjdmraijojmjnjkjljijjjcaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaababababaAaAaNaOaAaJaJaJaJaKaKaLaLaMaiaiaiaiaIaHaiaiaiaGazazazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahagafaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababaAaBaCaDaEaFasaraqapawavauataiakajaiaoanaiamayaUaxamazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbmblaeaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababaAaWbobpaAbnbAbgbBbAbybxaubzaibubwbvbrbqbtbsbjbhbhfJazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbmblaeaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababaAaWbobpaAbnbAbgbBbAbybxaubzaibubwbvbrbqbtbsbjpLbhfJazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPaRaQaSaeaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababaAaWaTbiaAaVbgbfbebdbbbcbbbaaGaGaGaGaZaYaiaXbjbhbhdvazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkdldleubWbVblaeaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababaeaeaeaeaeaeaeaeaeabababaAaWcmcnaAclbYbXcabZcccbcecdcgcfchaGcjcickamamiXamjeazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadQdRdSdTbDbCbEaeaeababababababababababababababababababababababababababababababababababababababababababababababababababalalalaeaeaeaeaeaeaeaebTaGaGaGaGaGaGbUaGaGaGaGbFaGaGbIbHbGbLbKbJaGbPbObNbMbRbSbQbRazalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1663,7 +1666,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefcfdfeffeUeTeWeVeYeXfaeZfbcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaeAereseyezeresevewepeqeneneneoeoeoeoeoeSeReQePeOeNeMaGfqfpeJeIaieHeFeGeDeEeCaGaGeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahSfchbfcfEfEdJheeUcrekhdcrfahccrabababababababababababababababababababababababababababababababababababababababababababababababdXaaaaaaaaaagMgPgQgNgOgTgQgRgSgWgXgUgVhaeogYgZgweogxeRgBgAgDgCgEaGgGgFgIgHaiaigJaiaiaieReRgKeBeBeBeBgLeBeBeBeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaegugvfEgsgtfEcpgqeTgrgpgocrcrcrcrcrcrababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaagngbgcgcgcgcgdgegfggghgigjgkeoglgmfVfUfTeIfXfWeReRfYfweReReJeIgafZfKfLfIlzeReRfMeBfOfPeBfNfRfSfQeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeiCiBhRfEgtiDffiGeUiFcriIiHcrhOhKbCiEcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaagngQgQgQhWgQhVhUgQibgXhZiahYeogmhXihigijiiidicifieilieimieikieieieirisitiuinioipiqixiyiziAivhAiweBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeiCiBhRfEgtiDffiGeUiFcriIiHcrhOhKbCiEcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaagngQgQgQhWgQhVhUgQibgXhZiahYeogmhXihigijiiidicifieilieimieikieieieirisitiuinioipiqixiyiziAivEQiweBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeababcrfFhLhPhQhRhThNeThOafbChKcrhOhLhKhMcrababababababababababababababababababababababababababababababababababalalalalalalababababababkDkEaaaaaahrgQgQhihjhfhggRhhhnhohphqhkeohlhmhHeoeohGhGhFhuhEhxhuhJhuhIhwhwhwhwhxhuhvhththseBhChDeBhBhzhAhyeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaecrcrcrcrcrcrfGeUnWhLeUgqnUhOhOeVeYiIcrhOcpeknVcrababababababababababababababababababababababababababababababababalalalgygygygyalalalababsEgygyaaaaaaaanwereseynwnwnwnwnwpMnwnununueopJeonSnTnRhGsesjhunMnKnLnInJnGnHkmkmkmnFhunEnChtnBlulululurVnznyfQeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaecrmPeUhRoEcriCoDiBcrgrcroGoHoFcrbClLiFmOcpeleUcrabababababababababababababababababababababababababababababababalalgygygygygygygygyalalabgygyaaaaaaaaaaaaaaaeaekBohogoflnoeodocqOoanZnYqhoqorosrIrfrvhuopokollDkmnGoiojkmkmmghuoCozhtoBoAovoulueBeBeBeBeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1674,7 +1677,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababcrkPcrkNekkOhTkMcphKcreUekcrkLkJkJkKcradababababababababababababababababababababababababababababalalgygygyprgygygygygygygygygygyaeaaaaaaaaaaaaaeaeaekBkBkCkFkBkBkGlhkGkBkIeoowpBpCkokpmFkshukVkvkwkYkukzkAlckyknkmhuhththtababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababcrkPcrhTcpbVljeUekgocrkPcrcrhOeUkJkKlkadababababababababababababababababababababababababababababalpSpTgypUpSpQgygygygygygygygygytjaaaaaaaaaaaetjtjtjgygyqdqeqfkBmllglfkBlieogylrlAhGkSkTkTkUlUkWkXkUlVkZlalblXleldlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababcrkPcrcrcrcrcrcrcrcrcrkPcrphbCeUbCkKpiadababababababababababababababababababababababababababababalpSgygygypSpQgygygygygygygyqwqCpjsWsWsWsWsWsWpoqwqCgygygygygykBplpnpmkBpkgygygygyhGpApxpykUpwpupvkUptpqpslbpppEpDlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLaaaaaaaaaaqLababababababababababababababcrkPkPkPkPkPkPkPkPkPkPkPcrhOeUiFeUiEcradababababababababababababababababababababababababababababalgygygygyqMqNgygygygygygygygyrWqPqPqPqPqPqPqPqPrWgygygygygygykBpHrUkGkBpFrigygygyhGpXkTkTkUpWpOtykUpRpLtllbpNpKsIlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLaaaaaaaaaaqLababababababababababababababcrkPkPkPkPkPkPkPkPkPkPkPcrhOeUiFeUiEcradababababababababababababababababababababababababababababalgygygygyqMqNgygygygygygygygyrWqPqPqPqPqPqPqPqPrWgygygygygygykBpHrUkGkBpFrigygygyhGpXkTkTkUpWpOtykUpREStllbpNpKsIlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababcrcrcrcrcrcrcrcrcrcrcrcrcrcrmjrOoMcrcradababababababababababababababababababababababababababababalgygygygygygygygygygygygygyqwqCrdrerererererereqwqCgygygygygygypBrSpCpdpcpeoVoVoVoToUsyoZkUoWoOoPkUoNoRoSlboQpbpalbabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababadadadcrkJkJeUcradadababababababababababababababababababababababababababababalpSpTgygygygygygygygygygyaaaaaaaaaaaaaaaaalalalalalalalalgygygygygygypBpgpCgygyalhGhGhGhGkUkUkUkUkUpfpfpflblblblblbabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababadadadcroJoIoJcradabababababababababababababababababababababababababababababalpSgygygygygygygygygygygyaaaaaaaaaaaaaaaaalalalababababalalalalalalalgyjHgygyalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/sound/effects/cascade.ogg b/sound/effects/cascade.ogg new file mode 100644 index 00000000000..9de7b01b0cd Binary files /dev/null and b/sound/effects/cascade.ogg differ diff --git a/sound/effects/supermatter.ogg b/sound/effects/supermatter.ogg new file mode 100644 index 00000000000..83081a5e9bf Binary files /dev/null and b/sound/effects/supermatter.ogg differ diff --git a/sound/weapons/heavysmash.ogg b/sound/weapons/heavysmash.ogg new file mode 100644 index 00000000000..609e20fd967 Binary files /dev/null and b/sound/weapons/heavysmash.ogg differ diff --git a/sound/weapons/rapidslice.ogg b/sound/weapons/rapidslice.ogg new file mode 100644 index 00000000000..a428c18efe2 Binary files /dev/null and b/sound/weapons/rapidslice.ogg differ diff --git a/sound/weapons/spiderlunge.ogg b/sound/weapons/spiderlunge.ogg new file mode 100644 index 00000000000..fc2d91e079d Binary files /dev/null and b/sound/weapons/spiderlunge.ogg differ