mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-21 21:17:44 +01:00
[MIRROR] Dimensional Anomaly [MDB IGNORE] (#15974)
* Dimensional Anomaly (#69512) About The Pull Request Everyone has been asking: "When will there be an anomaly like the bioscrambler, but for the space station? Please, we need more things which replace objects with different objects from the same typepath." Well I made it and it looked like ass because non-tiling floor and walls look terrible, so then I made this instead. Dimensional.mp4 The "dimensional anomaly" shifts matter into a parallel dimension where objects are made out of something else. Like the Bioscrambler anomaly, it does not expire on its own and only leaves when someone signals it or uses an anomaly remover. When it spawns it picks a "theme" and converts terrain around it until it covers a 7x7 square, then it teleports somewhere else and picks a new theme. A lot of these themes are relatively benign like "meat", "fancy carpet", or "gold". Some of them are kind of annoying like "icebox" because it creates floor which slows you down, or "clown" because bananium is intentionally annoying. Some of them are actively dangerous, mostly "uranium" and "plasma". The main problem this will usually cause for crewmembers is decreasing area security. When it replaces doors it replaces them with ones which don't have any access control, and it will also replace RWalls with normal and much more vulnerable walls which will make breaking and entering significantly easier until someone has taken the time to fix the damage. But also sometimes it will irradiate them, you never know. The fact that sometimes the changes are benign (or provide uncommon materials) and might be happening in places you don't care about access to might encourage people to push their luck and leave it alone until it starts turning the captain's office into a bamboo room or repainting medbay a fetching shade of flammable purple, which I would consider a success. Armour.mp4 If you successfully harvest the anomaly core you can place it into the reactive armour to get Reactive Barricade Armour, which shifts your dimension when you take damage and attempts to place some randomised (not terribly durable) objects between you and hopefully your attacker (it really just picks up to four random unoccupied tiles next to you). If you're EMPed then the changes it make to the environment will often be as unpleasant for you as they are for a pursuer, and significantly more likely to harm both of you rather than just provide obstacles. Other changes: I split anomalies out into their own dmi file, seems to be all the rage lately. I moved the anomaly placing code into a datum instead of the event because I wanted to reuse it but if you have a better idea about where I could have put it let me know. This also fixes a bug where the material spreader component wasn't working when I applied plasma materials to something, the extra whitespace was parsing as another argument for some reason and meant it would runtime. Supermatter delamination was still pointing to Delimber anomalies instead of Bioscrambler. * Dimensional Anomaly * Fixes the upstream merge skew Co-authored-by: Jacquerel <hnevard@gmail.com> Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
#define BIOSCRAMBLER_ANOMALY "bioscrambler_anomaly"
|
||||
#define HALLUCINATION_ANOMALY "hallucination_anomaly"
|
||||
#define VORTEX_ANOMALY "vortex_anomaly"
|
||||
#define DIMENSIONAL_ANOMALY "dimensional_anomaly"
|
||||
|
||||
#define SUPERMATTER_COUNTDOWN_TIME 30 SECONDS
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
/obj/effect/anomaly
|
||||
name = "anomaly"
|
||||
desc = "A mysterious anomaly, seen commonly only in the region of space that the station orbits..."
|
||||
icon_state = "bhole3"
|
||||
icon = 'icons/effects/anomalies.dmi'
|
||||
icon_state = "vortex"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
light_range = 3
|
||||
@@ -24,6 +25,8 @@
|
||||
var/drops_core = TRUE
|
||||
///Do we keep on living forever?
|
||||
var/immortal = FALSE
|
||||
///Do we stay in one place?
|
||||
var/immobile = FALSE
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan, drops_core = TRUE)
|
||||
. = ..()
|
||||
@@ -70,7 +73,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/proc/anomalyEffect(delta_time)
|
||||
if(DT_PROB(ANOMALY_MOVECHANCE, delta_time))
|
||||
if(!immobile && DT_PROB(ANOMALY_MOVECHANCE, delta_time))
|
||||
step(src,pick(GLOB.alldirs))
|
||||
|
||||
/obj/effect/anomaly/proc/detonate()
|
||||
@@ -90,7 +93,6 @@
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/anomaly/attackby(obj/item/weapon, mob/user, params)
|
||||
if(weapon.tool_behaviour == TOOL_ANALYZER)
|
||||
to_chat(user, span_notice("Analyzing... [src]'s unstable field is fluctuating along frequency [format_frequency(aSignal.frequency)], code [aSignal.code]."))
|
||||
@@ -110,6 +112,7 @@
|
||||
|
||||
/obj/effect/anomaly/grav
|
||||
name = "gravitational anomaly"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shield2"
|
||||
density = FALSE
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/grav
|
||||
@@ -197,7 +200,7 @@
|
||||
|
||||
/obj/effect/anomaly/flux
|
||||
name = "flux wave anomaly"
|
||||
icon_state = "electricity2"
|
||||
icon_state = "flux"
|
||||
density = TRUE
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/flux
|
||||
var/canshock = FALSE
|
||||
@@ -320,7 +323,7 @@
|
||||
|
||||
/obj/effect/anomaly/pyro
|
||||
name = "pyroclastic anomaly"
|
||||
icon_state = "mustard"
|
||||
icon_state = "pyroclastic"
|
||||
var/ticks = 0
|
||||
/// How many seconds between each gas release
|
||||
var/releasedelay = 10
|
||||
@@ -366,7 +369,7 @@
|
||||
|
||||
/obj/effect/anomaly/bhole
|
||||
name = "vortex anomaly"
|
||||
icon_state = "bhole3"
|
||||
icon_state = "vortex"
|
||||
desc = "That's a nice station you have there. It'd be a shame if something happened to it."
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/vortex
|
||||
|
||||
@@ -430,7 +433,7 @@
|
||||
|
||||
/obj/effect/anomaly/bioscrambler
|
||||
name = "bioscrambler anomaly"
|
||||
icon_state = "bioscrambler_anomaly"
|
||||
icon_state = "bioscrambler"
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/bioscrambler
|
||||
immortal = TRUE
|
||||
/// Cooldown for every anomaly pulse
|
||||
@@ -502,7 +505,7 @@
|
||||
|
||||
/obj/effect/anomaly/hallucination
|
||||
name = "hallucination anomaly"
|
||||
icon_state = "hallucination_anomaly"
|
||||
icon_state = "hallucination"
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/hallucination
|
||||
/// Time passed since the last effect, increased by delta_time of the SSobj
|
||||
var/ticks = 0
|
||||
@@ -546,4 +549,87 @@
|
||||
)
|
||||
to_chat(near, span_warning(pick(messages)))
|
||||
|
||||
/////////////////////
|
||||
|
||||
/obj/effect/anomaly/dimensional
|
||||
name = "dimensional anomaly"
|
||||
icon_state = "dimensional"
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/dimensional
|
||||
immortal = TRUE
|
||||
immobile = TRUE
|
||||
/// Range of effect, if left alone anomaly will convert a 2(range)+1 squared area.
|
||||
var/range = 3
|
||||
/// List of turfs this anomaly will try to transform before relocating
|
||||
var/list/turf/target_turfs = new()
|
||||
/// Current anomaly 'theme', dictates what tiles to create.
|
||||
var/datum/dimension_theme/theme
|
||||
/// Effect displaying on the anomaly to represent the theme.
|
||||
var/mutable_appearance/theme_icon
|
||||
|
||||
/obj/effect/anomaly/dimensional/Initialize(mapload, new_lifespan, drops_core)
|
||||
. = ..()
|
||||
overlays += mutable_appearance('icons/effects/effects.dmi', "dimensional_overlay")
|
||||
|
||||
animate(src, transform = matrix()*0.85, time = 3, loop = -1)
|
||||
animate(transform = matrix(), time = 3, loop = -1)
|
||||
|
||||
/obj/effect/anomaly/dimensional/anomalyEffect(delta_time)
|
||||
. = ..()
|
||||
transmute_area()
|
||||
|
||||
/**
|
||||
* Transforms a turf in our prepared area.
|
||||
*/
|
||||
/obj/effect/anomaly/dimensional/proc/transmute_area()
|
||||
if (!theme)
|
||||
prepare_area()
|
||||
if (!target_turfs.len)
|
||||
relocate()
|
||||
return
|
||||
|
||||
var/turf/affected_turf = target_turfs[1]
|
||||
new /obj/effect/temp_visual/transmute_tile_flash(affected_turf)
|
||||
theme.apply_theme(affected_turf)
|
||||
target_turfs.Remove(affected_turf)
|
||||
|
||||
/**
|
||||
* Prepare a new area for transformation into a new theme.
|
||||
*/
|
||||
/obj/effect/anomaly/dimensional/proc/prepare_area()
|
||||
var/datum/dimension_theme/themes = new()
|
||||
theme = themes.get_random_theme()
|
||||
apply_theme_icon()
|
||||
|
||||
target_turfs = new()
|
||||
var/list/turfs = spiral_range_turfs(range, src)
|
||||
for (var/turf/turf in turfs)
|
||||
if (theme.can_convert(turf))
|
||||
target_turfs.Add(turf)
|
||||
|
||||
/**
|
||||
* Applies an overlay icon based on the current theme.
|
||||
*/
|
||||
/obj/effect/anomaly/dimensional/proc/apply_theme_icon()
|
||||
overlays -= theme_icon
|
||||
theme_icon = mutable_appearance(theme.icon, theme.icon_state, FLOAT_LAYER - 1, appearance_flags = appearance_flags | RESET_TRANSFORM)
|
||||
theme_icon.blend_mode = BLEND_INSET_OVERLAY
|
||||
overlays += theme_icon
|
||||
|
||||
/**
|
||||
* Moves the anomaly somewhere else and announces it.
|
||||
*/
|
||||
/obj/effect/anomaly/dimensional/proc/relocate()
|
||||
var/datum/anomaly_placer/placer = new()
|
||||
var/area/new_area = placer.findValidArea()
|
||||
var/turf/new_turf = placer.findValidTurf(new_area)
|
||||
|
||||
priority_announce("Dimensional instability relocated. Expected location: [new_area.name].", "Anomaly Alert")
|
||||
src.forceMove(new_turf)
|
||||
prepare_area()
|
||||
|
||||
/obj/effect/temp_visual/transmute_tile_flash
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shield-flash"
|
||||
duration = 3
|
||||
|
||||
#undef ANOMALY_MOVECHANCE
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
|
||||
/**
|
||||
* Datum which describes a theme and replaces turfs and objects in specified locations to match that theme
|
||||
*/
|
||||
/datum/dimension_theme
|
||||
/// An icon to display to represent the theme
|
||||
var/icon/icon
|
||||
/// Icon state to use to represent the theme
|
||||
var/icon_state
|
||||
/// Typepath of custom material to use for objects.
|
||||
var/datum/material/material
|
||||
/// Sound to play when transforming a tile
|
||||
var/sound = 'sound/magic/blind.ogg'
|
||||
/// Weighted list of turfs to replace the floor with.
|
||||
var/list/replace_floors = list(/turf/open/floor/material = 1)
|
||||
/// Typepath of turf to replace walls with.
|
||||
var/turf/replace_walls = /turf/closed/wall/material
|
||||
/// List of weighted lists for object replacement. Key is an original typepath, value is a weighted list of typepaths to replace it with.
|
||||
var/list/replace_objs = list(\
|
||||
/obj/structure/chair = list(/obj/structure/chair/greyscale = 1), \
|
||||
/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/material = 1, /obj/machinery/door/airlock/material/glass = 1), \
|
||||
/obj/structure/table = list(/obj/structure/table/greyscale = 1), \
|
||||
/obj/structure/toilet = list(/obj/structure/toilet/greyscale = 1),)
|
||||
/// Typepath of full-size windows which will replace existing ones
|
||||
/// These need to be separate from replace_objs because we don't want to replace dir windows with full ones and they share typepath
|
||||
var/obj/structure/window/replace_window
|
||||
/// Colour to recolour windows with, replaced by material colour if material was specified.
|
||||
var/window_colour = "#ffffff"
|
||||
|
||||
/datum/dimension_theme/New()
|
||||
if (material)
|
||||
var/datum/material/using_mat = GET_MATERIAL_REF(material)
|
||||
window_colour = using_mat.greyscale_colors
|
||||
|
||||
/**
|
||||
* Returns a subtype of dimensional theme.
|
||||
*/
|
||||
/datum/dimension_theme/proc/get_random_theme()
|
||||
var/subtype = pick(subtypesof(/datum/dimension_theme))
|
||||
return new subtype()
|
||||
|
||||
/**
|
||||
* Applies themed transformation to the provided turf.
|
||||
*
|
||||
* Arguments
|
||||
* * affected_turf - Turf to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/apply_theme(turf/affected_turf)
|
||||
if (!replace_turf(affected_turf))
|
||||
return
|
||||
playsound(affected_turf, sound, 100, TRUE)
|
||||
for (var/obj/object in affected_turf)
|
||||
replace_object(object)
|
||||
if (material)
|
||||
apply_materials(affected_turf)
|
||||
|
||||
/**
|
||||
* Returns true if you actually can transform the provided turf.
|
||||
*
|
||||
* Arguments
|
||||
* * affected_turf - Turf to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/can_convert(turf/affected_turf)
|
||||
if (isspaceturf(affected_turf))
|
||||
return FALSE
|
||||
if (isfloorturf(affected_turf))
|
||||
if (isindestructiblefloor(affected_turf))
|
||||
return FALSE
|
||||
if (affected_turf.holodeck_compatible)
|
||||
return FALSE
|
||||
return replace_floors.len > 0
|
||||
if (iswallturf(affected_turf))
|
||||
if (isindestructiblewall(affected_turf))
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Replaces the provided turf with a different one.
|
||||
*
|
||||
* Arguments
|
||||
* * affected_turf - Turf to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/replace_turf(turf/affected_turf)
|
||||
if (isfloorturf(affected_turf))
|
||||
if (isindestructiblefloor(affected_turf))
|
||||
return FALSE
|
||||
if (affected_turf.holodeck_compatible)
|
||||
return FALSE
|
||||
return transform_floor(affected_turf)
|
||||
|
||||
if (!iswallturf(affected_turf))
|
||||
return FALSE
|
||||
if (isindestructiblewall(affected_turf))
|
||||
return FALSE
|
||||
affected_turf.ChangeTurf(replace_walls)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Replaces the provided floor turf with a different one.
|
||||
*
|
||||
* Arguments
|
||||
* * affected_floor - Floor turf to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/transform_floor(turf/open/floor/affected_floor)
|
||||
if (replace_floors.len == 0)
|
||||
return FALSE
|
||||
affected_floor.ChangeTurf(pick_weight(replace_floors), flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Replaces the provided object with a different one.
|
||||
*
|
||||
* Arguments
|
||||
* * object - Object to replace.
|
||||
*/
|
||||
/datum/dimension_theme/proc/replace_object(obj/object)
|
||||
if (istype(object, /obj/structure/window))
|
||||
transform_window(object)
|
||||
return
|
||||
|
||||
var/replace_path = get_replacement_object_typepath(object)
|
||||
if (!replace_path)
|
||||
return
|
||||
var/obj/new_object = new replace_path(object.loc)
|
||||
new_object.setDir(object.dir)
|
||||
qdel(object)
|
||||
|
||||
/**
|
||||
* Returns the typepath of an object to replace the provided object.
|
||||
*
|
||||
* Arguments
|
||||
* * object - Object to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/get_replacement_object_typepath(obj/object)
|
||||
for (var/type in replace_objs)
|
||||
if (istype(object, type))
|
||||
return pick_weight(replace_objs[type])
|
||||
return
|
||||
|
||||
/**
|
||||
* Replaces a window with a different window and recolours it.
|
||||
* This needs its own function because we only want to replace full tile windows.
|
||||
*
|
||||
* Arguments
|
||||
* * object - Object to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/transform_window(obj/structure/window/window)
|
||||
if (!window.fulltile)
|
||||
return
|
||||
if (!replace_window)
|
||||
window.add_atom_colour(window_colour, FIXED_COLOUR_PRIORITY)
|
||||
return
|
||||
|
||||
var/obj/structure/window/new_window = new replace_window(window.loc)
|
||||
new_window.add_atom_colour(window_colour, FIXED_COLOUR_PRIORITY)
|
||||
qdel(window)
|
||||
|
||||
#define PERMITTED_MATERIAL_REPLACE_TYPES list(\
|
||||
/obj/structure/chair, \
|
||||
/obj/machinery/door/airlock, \
|
||||
/obj/structure/table, \
|
||||
/obj/structure/toilet, \
|
||||
/obj/structure/window, \
|
||||
/obj/structure/sink,)
|
||||
|
||||
/**
|
||||
* Returns true if the provided object can have its material modified.
|
||||
*
|
||||
* Arguments
|
||||
* * object - Object to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/permit_replace_material(obj/object)
|
||||
for (var/type in PERMITTED_MATERIAL_REPLACE_TYPES)
|
||||
if (istype(object, type))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Applies a new custom material to the contents of a provided turf.
|
||||
*
|
||||
* Arguments
|
||||
* * affected_turf - Turf to transform.
|
||||
*/
|
||||
/datum/dimension_theme/proc/apply_materials(turf/affected_turf)
|
||||
var/list/custom_materials = list(GET_MATERIAL_REF(material) = MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
if (istype(affected_turf, /turf/open/floor/material) || istype(affected_turf, /turf/closed/wall/material))
|
||||
affected_turf.set_custom_materials(custom_materials)
|
||||
for (var/obj/thing in affected_turf)
|
||||
if (!permit_replace_material(thing))
|
||||
continue
|
||||
thing.set_custom_materials(custom_materials)
|
||||
|
||||
#undef PERMITTED_MATERIAL_REPLACE_TYPES
|
||||
|
||||
/////////////////////
|
||||
|
||||
/datum/dimension_theme/gold
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
icon_state = "sheet-gold_2"
|
||||
material = /datum/material/gold
|
||||
|
||||
/datum/dimension_theme/plasma
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "gas_alt"
|
||||
material = /datum/material/plasma
|
||||
|
||||
/datum/dimension_theme/clown
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "clown"
|
||||
material = /datum/material/bananium
|
||||
sound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/datum/dimension_theme/radioactive
|
||||
icon = 'icons/obj/ore.dmi'
|
||||
icon_state = "Uranium ore"
|
||||
material = /datum/material/uranium
|
||||
sound = 'sound/items/welder.ogg'
|
||||
|
||||
/datum/dimension_theme/meat
|
||||
icon = 'icons/obj/food/meat.dmi'
|
||||
icon_state = "meat"
|
||||
material = /datum/material/meat
|
||||
sound = 'sound/items/eatfood.ogg'
|
||||
|
||||
/datum/dimension_theme/pizza
|
||||
icon = 'icons/obj/food/pizza.dmi'
|
||||
icon_state = "pizzamargherita"
|
||||
material = /datum/material/pizza
|
||||
sound = 'sound/items/eatfood.ogg'
|
||||
|
||||
/datum/dimension_theme/natural
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "map_flower"
|
||||
window_colour = "#00f7ff"
|
||||
replace_floors = list(/turf/open/floor/grass = 1)
|
||||
replace_walls = /turf/closed/wall/mineral/wood/nonmetal
|
||||
replace_objs = list(\
|
||||
/obj/structure/chair = list(/obj/structure/chair/wood = 3, /obj/structure/chair/wood/wings = 1), \
|
||||
/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/wood = 1, /obj/machinery/door/airlock/wood/glass = 1), \
|
||||
/obj/structure/table = list(/obj/structure/table/wood = 5, /obj/structure/table/wood/fancy = 1),)
|
||||
|
||||
/datum/dimension_theme/bamboo
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "bamboo"
|
||||
replace_floors = list(/turf/open/floor/bamboo = 1)
|
||||
replace_walls = /turf/closed/wall/mineral/bamboo
|
||||
replace_window = /obj/structure/window/paperframe
|
||||
replace_objs = list(\
|
||||
/obj/structure/chair = list(/obj/structure/chair/stool/bamboo = 1), \
|
||||
/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/wood = 1, /obj/machinery/door/airlock/wood/glass = 1), \
|
||||
/obj/structure/table = list(/obj/structure/table/wood = 1),)
|
||||
|
||||
/datum/dimension_theme/icebox
|
||||
icon = 'icons/obj/clothing/shoes.dmi'
|
||||
icon_state = "iceboots"
|
||||
window_colour = "#00f7ff"
|
||||
material = /datum/material/snow
|
||||
replace_floors = list(/turf/open/floor/fake_snow = 10, /turf/open/floor/fakeice/slippery = 1)
|
||||
replace_walls = /turf/closed/wall/mineral/snow
|
||||
|
||||
/datum/dimension_theme/lavaland
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
window_colour = "#860000"
|
||||
replace_floors = list(/turf/open/floor/fakebasalt = 5, /turf/open/floor/fakepit = 1)
|
||||
replace_walls = /turf/closed/wall/mineral/cult
|
||||
replace_objs = list(\
|
||||
/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/external/glass/ruin = 1))
|
||||
|
||||
/datum/dimension_theme/space
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "blessed"
|
||||
window_colour = "#000000"
|
||||
material = /datum/material/glass
|
||||
replace_floors = list(/turf/open/floor/fakespace = 1)
|
||||
replace_walls = /turf/closed/wall/rock/porous
|
||||
replace_objs = list(/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/external/glass/ruin = 1))
|
||||
|
||||
/datum/dimension_theme/glass
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "small"
|
||||
material = /datum/material/glass
|
||||
replace_floors = list(/turf/open/floor/glass = 1)
|
||||
sound = SFX_SHATTER
|
||||
|
||||
/datum/dimension_theme/fancy
|
||||
icon = 'icons/obj/clothing/hats.dmi'
|
||||
icon_state = "fancycrown"
|
||||
replace_walls = /turf/closed/wall/mineral/wood/nonmetal
|
||||
|
||||
#define FANCY_CARPETS list(\
|
||||
/turf/open/floor/eighties, \
|
||||
/turf/open/floor/eighties/red, \
|
||||
/turf/open/floor/carpet/lone/star, \
|
||||
/turf/open/floor/carpet/black, \
|
||||
/turf/open/floor/carpet/blue, \
|
||||
/turf/open/floor/carpet/cyan, \
|
||||
/turf/open/floor/carpet/green, \
|
||||
/turf/open/floor/carpet/orange, \
|
||||
/turf/open/floor/carpet/purple, \
|
||||
/turf/open/floor/carpet/red, \
|
||||
/turf/open/floor/carpet/royalblack, \
|
||||
/turf/open/floor/carpet/royalblue,)
|
||||
|
||||
/datum/dimension_theme/fancy/New()
|
||||
replace_floors = list(pick(FANCY_CARPETS) = 1)
|
||||
replace_objs = list(\
|
||||
/obj/structure/chair = list(/obj/structure/chair/comfy = 1), \
|
||||
/obj/machinery/door/airlock = list(/obj/machinery/door/airlock/wood = 1, /obj/machinery/door/airlock/wood/glass = 1), \
|
||||
/obj/structure/table/wood = list(pick(subtypesof(/obj/structure/table/wood/fancy)) = 1),)
|
||||
|
||||
#undef FANCY_CARPETS
|
||||
|
||||
/datum/dimension_theme/disco
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "lbulb"
|
||||
material = /datum/material/glass
|
||||
replace_floors = list(/turf/open/floor/light = 1)
|
||||
|
||||
/datum/dimension_theme/disco/transform_floor(turf/open/floor/affected_floor)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
var/turf/open/floor/light/disco_floor = affected_floor
|
||||
disco_floor.currentcolor = pick(disco_floor.coloredlights)
|
||||
disco_floor.update_appearance()
|
||||
@@ -331,6 +331,9 @@
|
||||
///How much damage the trap deals when triggered.
|
||||
var/trap_damage = 20
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/prearmed
|
||||
armed = TRUE
|
||||
|
||||
/obj/item/restraints/legcuffs/beartrap/Initialize(mapload)
|
||||
. = ..()
|
||||
update_appearance()
|
||||
|
||||
@@ -776,6 +776,13 @@
|
||||
icon_state = "ice_turf-0"
|
||||
base_icon_state = "ice_turf-0"
|
||||
|
||||
/turf/open/floor/fakeice/slippery
|
||||
desc = "Somehow, it is not melting under these conditions. Must be some very thick ice. Just as slippery too."
|
||||
|
||||
/turf/open/floor/fakeice/slippery/Initialize(mapload)
|
||||
. = ..()
|
||||
MakeSlippery(TURF_WET_PERMAFROST, INFINITY, 0, INFINITY, TRUE)
|
||||
|
||||
/turf/open/floor/fakespace
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "0"
|
||||
|
||||
@@ -1434,6 +1434,16 @@
|
||||
crate_name = "raw bioscrambler anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
/datum/supply_pack/science/raw_dimensional_anomaly
|
||||
name = "Raw Dimensional Anomaly"
|
||||
desc = "The raw core of a dimensional anomaly, ready to be implosion-compressed into a powerful artifact."
|
||||
cost = CARGO_CRATE_VALUE * 10
|
||||
access = ACCESS_ORDNANCE
|
||||
access_view = ACCESS_ORDNANCE
|
||||
contains = list(/obj/item/raw_anomaly_core/dimensional)
|
||||
crate_name = "raw dimensional anomaly"
|
||||
crate_type = /obj/structure/closet/crate/secure/science
|
||||
|
||||
|
||||
/datum/supply_pack/science/robotics
|
||||
name = "Robotics Assembly Crate"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport,
|
||||
/obj/effect/anomaly/bioscrambler = /obj/item/clothing/suit/armor/reactive/bioscrambling,
|
||||
/obj/effect/anomaly/hallucination = /obj/item/clothing/suit/armor/reactive/hallucinating,
|
||||
/obj/effect/anomaly/dimensional = /obj/item/clothing/suit/armor/reactive/barricade,
|
||||
)
|
||||
|
||||
if(istype(weapon, /obj/item/assembly/signaler/anomaly))
|
||||
@@ -454,3 +455,66 @@
|
||||
qdel(picked_user_part)
|
||||
nearby.update_body(TRUE)
|
||||
balloon_alert(nearby, "something has changed about you")
|
||||
|
||||
// When the wearer gets hit, this armor will push people nearby and spawn some blocking objects.
|
||||
/obj/item/clothing/suit/armor/reactive/barricade
|
||||
name = "reactive barricade armor"
|
||||
desc = "An experimental suit of armor that generates barriers from another world when it detects its bearer is in danger."
|
||||
emp_message = span_warning("The reactive armor's dimensional coordinates are scrambled!")
|
||||
cooldown_message = span_danger("The reactive barrier system is still recharging! It fails to activate!")
|
||||
reactivearmor_cooldown_duration = 10 SECONDS
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/barricade/reactive_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
playsound(get_turf(owner),'sound/magic/repulse.ogg', 100, TRUE)
|
||||
owner.visible_message(span_danger("The reactive armor interposes matter from another world between [src] and [attack_text]!"))
|
||||
for (var/atom/movable/target in repulse_targets(owner))
|
||||
repulse(target, owner)
|
||||
|
||||
var/datum/armour_dimensional_theme/theme = new()
|
||||
theme.apply_random(get_turf(owner), dangerous = FALSE)
|
||||
qdel(theme)
|
||||
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Returns a list of all atoms around the source which can be moved away from it.
|
||||
*
|
||||
* Arguments
|
||||
* * source - Thing to try to move things away from.
|
||||
*/
|
||||
/obj/item/clothing/suit/armor/reactive/barricade/proc/repulse_targets(atom/source)
|
||||
var/list/push_targets = list()
|
||||
for (var/atom/movable/nearby_movable in view(1, source))
|
||||
if(nearby_movable == source)
|
||||
continue
|
||||
if(nearby_movable.anchored)
|
||||
continue
|
||||
push_targets += nearby_movable
|
||||
return push_targets
|
||||
|
||||
/**
|
||||
* Pushes something one tile away from the source.
|
||||
*
|
||||
* Arguments
|
||||
* * victim - Thing being moved.
|
||||
* * source - Thing to move it away from.
|
||||
*/
|
||||
/obj/item/clothing/suit/armor/reactive/barricade/proc/repulse(atom/movable/victim, atom/source)
|
||||
var/dist_from_caster = get_dist(victim, source)
|
||||
|
||||
if(dist_from_caster == 0)
|
||||
return
|
||||
|
||||
if (isliving(victim))
|
||||
to_chat(victim, span_userdanger("You're thrown back by a wave of pressure!"))
|
||||
var/turf/throwtarget = get_edge_target_turf(source, get_dir(source, get_step_away(victim, source, 1)))
|
||||
victim.safe_throw_at(throwtarget, 1, 1, source, force = MOVE_FORCE_EXTREMELY_STRONG)
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/barricade/emp_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
owner.visible_message(span_danger("The reactive armor shunts matter from an unstable dimension!"))
|
||||
var/datum/armour_dimensional_theme/theme = new()
|
||||
theme.apply_random(get_turf(owner), dangerous = TRUE)
|
||||
qdel(theme)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return FALSE
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
#define MAX_BARRIERS 4
|
||||
#define MIN_BARRIERS 2
|
||||
|
||||
/***
|
||||
* Datum describing a 'theme' which transforms a 3x3 area's turfs when applied.
|
||||
* It also creates a number of themed barriers in that area.
|
||||
*/
|
||||
/datum/armour_dimensional_theme
|
||||
var/datum/material/material
|
||||
var/turf/replace_floor = /turf/open/floor/material
|
||||
var/turf/replace_wall = /turf/closed/wall/material
|
||||
var/obj/barricade = /obj/structure/table/greyscale
|
||||
var/barricade_anchored = TRUE
|
||||
|
||||
/**
|
||||
* Applies a random dimensional theme effect centered around a provided point.
|
||||
* This will transform floors and walls, as well as creating some themed barriers in that area.
|
||||
*
|
||||
* Arguments
|
||||
* * source - The central turf to apply outwards from.
|
||||
* * dangerous - If true this will pick a 'dangerous' theme.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/apply_random(turf/source, dangerous = FALSE)
|
||||
var/theme_type
|
||||
if (dangerous)
|
||||
theme_type = pick(subtypesof(/datum/armour_dimensional_theme/dangerous))
|
||||
else
|
||||
theme_type = pick(subtypesof(/datum/armour_dimensional_theme/safe))
|
||||
var/datum/armour_dimensional_theme/theme = new theme_type()
|
||||
theme.apply(source)
|
||||
qdel(theme)
|
||||
|
||||
/**
|
||||
* Transforms turfs around a source point into a new themed material.
|
||||
* Also place some barriers in unoccupied areas.
|
||||
*
|
||||
* Arguments
|
||||
* * source - The central turf to apply outwards from.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/apply(turf/source)
|
||||
var/obj/effect/particle_effect/fluid/smoke/poof = new(source)
|
||||
poof.lifetime = 2 SECONDS
|
||||
var/list/target_area = get_target_area(source)
|
||||
for (var/turf/target in target_area)
|
||||
convert_turf(target)
|
||||
place_barriers(source, target_area)
|
||||
|
||||
/**
|
||||
* Returns a list of turfs which it is valid to apply changes to.
|
||||
*
|
||||
* Arguments
|
||||
* * source - The central turf to check outwards from.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/get_target_area(turf/source)
|
||||
var/list/target_area = RANGE_TURFS(1, source)
|
||||
for (var/turf/check_turf as anything in target_area)
|
||||
if (isspaceturf(check_turf))
|
||||
target_area -= check_turf
|
||||
continue
|
||||
if (isindestructiblefloor(check_turf))
|
||||
target_area -= check_turf
|
||||
continue
|
||||
if (isindestructiblewall(check_turf))
|
||||
target_area -= check_turf
|
||||
continue
|
||||
if (check_turf.holodeck_compatible)
|
||||
target_area -= check_turf
|
||||
continue
|
||||
|
||||
return target_area
|
||||
|
||||
/**
|
||||
* Changes a turf into a different turf
|
||||
*
|
||||
* Arguments
|
||||
* * to_convert - Turf to convert.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/convert_turf(turf/to_convert)
|
||||
if (isfloorturf(to_convert))
|
||||
to_convert.ChangeTurf(replace_floor, flags = CHANGETURF_INHERIT_AIR)
|
||||
else if (iswallturf(to_convert))
|
||||
to_convert.ChangeTurf(replace_wall)
|
||||
|
||||
if (material)
|
||||
var/list/custom_materials = list(GET_MATERIAL_REF(material) = MINERAL_MATERIAL_AMOUNT)
|
||||
to_convert.set_custom_materials(custom_materials)
|
||||
|
||||
/**
|
||||
* Places a random amount of themed barriers in unoccupied spaces adjacent to a source tile.
|
||||
*
|
||||
* Arguments
|
||||
* * source - Central tile to place barriers around.
|
||||
* * target_area - Tiles which have had their materials converted, needs further culling to remove dense tiles.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/place_barriers(turf/source, list/target_area)
|
||||
target_area -= source
|
||||
for (var/turf/check_turf as anything in target_area)
|
||||
if (!check_turf.is_blocked_turf(exclude_mobs = TRUE))
|
||||
continue
|
||||
target_area -= check_turf
|
||||
|
||||
var/to_place = rand(MIN_BARRIERS, MAX_BARRIERS)
|
||||
var/list/custom_materials = list()
|
||||
if (material)
|
||||
custom_materials = list(GET_MATERIAL_REF(material) = MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
while (target_area.len > 0 && to_place > 0)
|
||||
var/turf/place_turf = pick(target_area)
|
||||
place_barrier(place_turf, custom_materials)
|
||||
target_area -= place_turf
|
||||
to_place--
|
||||
|
||||
/**
|
||||
* Places a barrier at a specified turf.
|
||||
*
|
||||
* Arguments
|
||||
* * source - Tile to place barrier upon.
|
||||
* * materials - Custom material data to apply to the barrier.
|
||||
*/
|
||||
/datum/armour_dimensional_theme/proc/place_barrier(turf/source, list/materials)
|
||||
var/obj/placed_barricade = new barricade(source)
|
||||
if (barricade_anchored)
|
||||
placed_barricade.anchored = TRUE
|
||||
if (materials.len)
|
||||
placed_barricade.set_custom_materials(materials)
|
||||
|
||||
/// Themes which will largely be probably useful for the user
|
||||
/datum/armour_dimensional_theme/safe
|
||||
|
||||
/datum/armour_dimensional_theme/safe/natural
|
||||
replace_wall = /turf/closed/wall/mineral/wood/nonmetal
|
||||
replace_floor = /turf/open/floor/grass
|
||||
barricade = /obj/structure/barricade/wooden
|
||||
|
||||
/datum/armour_dimensional_theme/safe/snow
|
||||
material = /datum/material/snow
|
||||
replace_wall = /turf/closed/wall/mineral/snow
|
||||
replace_floor = /turf/open/floor/fake_snow
|
||||
barricade = /obj/structure/statue/snow/snowman
|
||||
|
||||
/datum/armour_dimensional_theme/safe/space
|
||||
material = /datum/material/glass
|
||||
replace_wall = /turf/closed/wall/rock/porous
|
||||
replace_floor = /turf/open/floor/fakespace
|
||||
barricade = /obj/machinery/door/airlock/external/glass/ruin
|
||||
|
||||
/datum/armour_dimensional_theme/safe/glass
|
||||
material = /datum/material/glass
|
||||
replace_floor = /turf/open/floor/glass
|
||||
|
||||
/datum/armour_dimensional_theme/safe/secure
|
||||
replace_wall = /turf/closed/wall/mineral/plastitanium/nodiagonal
|
||||
replace_floor = /turf/open/floor/mineral/plastitanium
|
||||
barricade = /obj/structure/holosign/barrier
|
||||
|
||||
/datum/armour_dimensional_theme/safe/meat
|
||||
material = /datum/material/meat
|
||||
|
||||
/// Dangerous themes can potentially impede the user as much as people pursuing them
|
||||
/datum/armour_dimensional_theme/dangerous
|
||||
|
||||
/datum/armour_dimensional_theme/dangerous/clown
|
||||
material = /datum/material/bananium
|
||||
barricade = /obj/item/restraints/legcuffs/beartrap/prearmed
|
||||
barricade_anchored = FALSE
|
||||
|
||||
/datum/armour_dimensional_theme/dangerous/radioactive
|
||||
material = /datum/material/uranium
|
||||
barricade = /obj/structure/statue/uranium/nuke
|
||||
|
||||
/datum/armour_dimensional_theme/dangerous/plasma
|
||||
material = /datum/material/plasma
|
||||
barricade = /obj/structure/statue/plasma/xeno
|
||||
|
||||
/datum/armour_dimensional_theme/dangerous/ice
|
||||
material = /datum/material/snow
|
||||
replace_wall = /turf/closed/wall/mineral/snow
|
||||
replace_floor = /turf/open/floor/fakeice/slippery
|
||||
barricade = /obj/structure/statue/snow/snowlegion
|
||||
|
||||
/datum/armour_dimensional_theme/dangerous/lavaland
|
||||
replace_floor = /turf/open/floor/fakebasalt
|
||||
replace_wall = /turf/closed/wall/mineral/cult
|
||||
|
||||
/// Replace the barrier spawning to instead create weak lava.
|
||||
/datum/armour_dimensional_theme/dangerous/lavaland/place_barrier(turf/source, list/materials)
|
||||
source.ChangeTurf(/turf/open/lava/smooth/weak, flags = CHANGETURF_INHERIT_AIR)
|
||||
|
||||
#undef MAX_BARRIERS
|
||||
#undef MIN_BARRIERS
|
||||
@@ -172,5 +172,5 @@
|
||||
/obj/item/wizard_armour_charge
|
||||
name = "battlemage shield charges"
|
||||
desc = "A powerful rune that will increase the number of hits a suit of battlemage armour can take before failing.."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "electricity2"
|
||||
icon = 'icons/effects/anomalies.dmi'
|
||||
icon_state = "flux"
|
||||
|
||||
@@ -10,48 +10,20 @@
|
||||
|
||||
/datum/round_event/anomaly
|
||||
var/area/impact_area
|
||||
var/datum/anomaly_placer/placer = new()
|
||||
var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux
|
||||
announce_when = 1
|
||||
|
||||
|
||||
/datum/round_event/anomaly/proc/findEventArea()
|
||||
var/static/list/allowed_areas
|
||||
if(!allowed_areas)
|
||||
//Places that shouldn't explode
|
||||
var/static/list/safe_area_types = typecacheof(list(
|
||||
/area/station/ai_monitored/turret_protected/ai,
|
||||
/area/station/ai_monitored/turret_protected/ai_upload,
|
||||
/area/station/engineering,
|
||||
/area/station/solars,
|
||||
/area/station/holodeck,
|
||||
/area/shuttle,
|
||||
/area/station/maintenance,
|
||||
/area/icemoon,
|
||||
))
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
var/static/list/unsafe_area_subtypes = typecacheof(list(/area/station/engineering/break_room))
|
||||
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
if (length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
/datum/round_event/anomaly/setup()
|
||||
impact_area = findEventArea()
|
||||
if(!impact_area)
|
||||
CRASH("No valid areas for anomaly found.")
|
||||
var/list/turf_test = (get_area_turfs(impact_area) - typesof(/turf/open/lava))
|
||||
if(!turf_test.len)
|
||||
CRASH("Anomaly : No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
impact_area = placer.findValidArea()
|
||||
|
||||
/datum/round_event/anomaly/announce(fake)
|
||||
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/start()
|
||||
var/turf/T = pick((get_area_turfs(impact_area) - typesof(/turf/open/lava)))
|
||||
var/turf/anomaly_turf = placer.findValidTurf(impact_area)
|
||||
var/newAnomaly
|
||||
if(T)
|
||||
newAnomaly = new anomaly_path(T)
|
||||
if(anomaly_turf)
|
||||
newAnomaly = new anomaly_path(anomaly_turf)
|
||||
if (newAnomaly)
|
||||
announce_to_ghosts(newAnomaly)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/datum/round_event_control/anomaly/anomaly_dimensional
|
||||
name = "Anomaly: Dimensional"
|
||||
typepath = /datum/round_event/anomaly/anomaly_dimensional
|
||||
|
||||
min_players = 10
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
description = "This anomaly replaces the materials of the surrounding area."
|
||||
|
||||
/datum/round_event/anomaly/anomaly_dimensional
|
||||
start_when = 10
|
||||
announce_when = 3
|
||||
anomaly_path = /obj/effect/anomaly/dimensional
|
||||
|
||||
/datum/round_event/anomaly/anomaly_dimensional/announce(fake)
|
||||
priority_announce("Localized dimensional instability detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
@@ -0,0 +1,75 @@
|
||||
/datum/anomaly_placer
|
||||
var/static/list/allowed_areas
|
||||
|
||||
/**
|
||||
* Returns an area which is safe to place an anomaly inside.
|
||||
*/
|
||||
/datum/anomaly_placer/proc/findValidArea()
|
||||
if(!allowed_areas)
|
||||
generateAllowedAreas()
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
if (!length(possible_areas))
|
||||
CRASH("No valid areas for anomaly found.")
|
||||
|
||||
var/area/landing_area = pick(possible_areas)
|
||||
var/list/turf_test = get_area_turfs(landing_area)
|
||||
if(!turf_test.len)
|
||||
CRASH("Anomaly : No valid turfs found for [landing_area] - [landing_area.type]")
|
||||
|
||||
return landing_area
|
||||
|
||||
/**
|
||||
* Returns a turf which is safe to place an anomaly on.
|
||||
*
|
||||
* Arguments
|
||||
* * target_area - Area to return a turf from.
|
||||
*/
|
||||
/datum/anomaly_placer/proc/findValidTurf(area/target_area)
|
||||
var/list/valid_turfs = list()
|
||||
for (var/turf/try_turf as anything in get_area_turfs(target_area))
|
||||
if (!is_valid_destination(try_turf))
|
||||
continue
|
||||
valid_turfs += try_turf
|
||||
|
||||
if (!valid_turfs.len)
|
||||
CRASH("Dimensional anomaly attempted to reach invalid location [target_area].")
|
||||
|
||||
return pick(valid_turfs)
|
||||
|
||||
/**
|
||||
* Returns true if the provided turf is valid to place an anomaly on.
|
||||
*
|
||||
* Arguments
|
||||
* * tested - Turf to try landing on.
|
||||
*/
|
||||
/datum/anomaly_placer/proc/is_valid_destination(turf/tested)
|
||||
if (isspaceturf(tested))
|
||||
return FALSE
|
||||
if (tested.is_blocked_turf(exclude_mobs = TRUE))
|
||||
return FALSE
|
||||
if (islava(tested))
|
||||
return FALSE
|
||||
if (ischasm(tested))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Populates the allowed areas list.
|
||||
*/
|
||||
/datum/anomaly_placer/proc/generateAllowedAreas()
|
||||
//Places that shouldn't explode
|
||||
var/static/list/safe_area_types = typecacheof(list(
|
||||
/area/station/ai_monitored/turret_protected/ai,
|
||||
/area/station/ai_monitored/turret_protected/ai_upload,
|
||||
/area/station/engineering,
|
||||
/area/station/solars,
|
||||
/area/station/holodeck,
|
||||
/area/shuttle,
|
||||
/area/station/maintenance,
|
||||
/area/icemoon,
|
||||
))
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
var/static/list/unsafe_area_subtypes = typecacheof(list(/area/station/engineering/break_room))
|
||||
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
@@ -96,8 +96,8 @@
|
||||
//jaunter tunnel
|
||||
/obj/effect/portal/jaunt_tunnel
|
||||
name = "jaunt tunnel"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "bhole3"
|
||||
icon = 'icons/effects/anomalies.dmi'
|
||||
icon_state = "vortex"
|
||||
desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon."
|
||||
mech_sized = TRUE //save your ripley
|
||||
innate_accuracy_penalty = 6
|
||||
|
||||
@@ -415,6 +415,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
new /obj/effect/anomaly/bhole(local_turf, 20, FALSE)
|
||||
if(BIOSCRAMBLER_ANOMALY)
|
||||
new /obj/effect/anomaly/bioscrambler(local_turf, null, FALSE)
|
||||
if(DIMENSIONAL_ANOMALY)
|
||||
new /obj/effect/anomaly/dimensional(local_turf, null, FALSE)
|
||||
|
||||
/obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 4000, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1500, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null)
|
||||
if(QDELETED(zapstart))
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
/// Spawns anomalies all over the station. Half instantly, the other half over time.
|
||||
/datum/sm_delam/proc/effect_anomaly(obj/machinery/power/supermatter_crystal/sm)
|
||||
var/anomalies = 10
|
||||
var/list/anomaly_types = list(GRAVITATIONAL_ANOMALY = 55, HALLUCINATION_ANOMALY = 45, DELIMBER_ANOMALY = 35, FLUX_ANOMALY = 25, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1)
|
||||
var/list/anomaly_types = list(GRAVITATIONAL_ANOMALY = 55, HALLUCINATION_ANOMALY = 45, DIMENSIONAL_ANOMALY = 35, BIOSCRAMBLER_ANOMALY = 35, FLUX_ANOMALY = 25, PYRO_ANOMALY = 5, VORTEX_ANOMALY = 1)
|
||||
var/list/anomaly_places = GLOB.generic_event_spawns
|
||||
|
||||
// Spawns this many anomalies instantly. Spawns the rest with callbacks.
|
||||
|
||||
@@ -73,3 +73,9 @@
|
||||
desc = "The neutralized core of a hallucination anomaly. It seems to be moving, but it's probably your imagination. It'd probably be valuable for research."
|
||||
icon_state = "hallucination_core"
|
||||
anomaly_type = /obj/effect/anomaly/hallucination
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dimensional
|
||||
name = "\improper dimensional anomaly core"
|
||||
desc = "The neutralized core of a dimensional anomaly. Objects reflected on its surface don't look quite right. It'd probably be valuable for research."
|
||||
icon_state = "dimensional_core"
|
||||
anomaly_type = /obj/effect/anomaly/dimensional
|
||||
|
||||
@@ -62,6 +62,12 @@
|
||||
anomaly_type = /obj/item/assembly/signaler/anomaly/bioscrambler
|
||||
icon_state = "rawcore_bioscrambler"
|
||||
|
||||
/obj/item/raw_anomaly_core/dimensional
|
||||
name = "raw dimensional core"
|
||||
desc = "The raw core of a dimensional anomaly, vibrating with infinite potential."
|
||||
anomaly_type = /obj/item/assembly/signaler/anomaly/dimensional
|
||||
icon_state = "rawcore_dimensional"
|
||||
|
||||
/obj/item/raw_anomaly_core/random/Initialize(mapload)
|
||||
. = ..()
|
||||
var/path = pick(subtypesof(/obj/item/raw_anomaly_core))
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 958 KiB After Width: | Height: | Size: 914 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 27 KiB |
@@ -1525,6 +1525,7 @@
|
||||
#include "code\game\objects\objs.dm"
|
||||
#include "code\game\objects\structures.dm"
|
||||
#include "code\game\objects\effects\anomalies.dm"
|
||||
#include "code\game\objects\effects\anomaly_dimensional_themes.dm"
|
||||
#include "code\game\objects\effects\blessing.dm"
|
||||
#include "code\game\objects\effects\bump_teleporter.dm"
|
||||
#include "code\game\objects\effects\contraband.dm"
|
||||
@@ -2875,6 +2876,7 @@
|
||||
#include "code\modules\clothing\suits\lasertag.dm"
|
||||
#include "code\modules\clothing\suits\moth.dm"
|
||||
#include "code\modules\clothing\suits\reactive_armour.dm"
|
||||
#include "code\modules\clothing\suits\reactive_armour_dimensional_themes.dm"
|
||||
#include "code\modules\clothing\suits\shirt.dm"
|
||||
#include "code\modules\clothing\suits\straightjacket.dm"
|
||||
#include "code\modules\clothing\suits\toggles.dm"
|
||||
@@ -2929,9 +2931,11 @@
|
||||
#include "code\modules\events\anomaly.dm"
|
||||
#include "code\modules\events\anomaly_bioscrambler.dm"
|
||||
#include "code\modules\events\anomaly_bluespace.dm"
|
||||
#include "code\modules\events\anomaly_dimensional.dm"
|
||||
#include "code\modules\events\anomaly_flux.dm"
|
||||
#include "code\modules\events\anomaly_grav.dm"
|
||||
#include "code\modules\events\anomaly_hallucination.dm"
|
||||
#include "code\modules\events\anomaly_placer.dm"
|
||||
#include "code\modules\events\anomaly_pyro.dm"
|
||||
#include "code\modules\events\anomaly_vortex.dm"
|
||||
#include "code\modules\events\aurora_caelus.dm"
|
||||
|
||||
Reference in New Issue
Block a user