From f48b604aff97f4a11675dc7d9be7fb3b22091c27 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Fri, 10 Mar 2023 03:39:30 +0100 Subject: [PATCH] [MIRROR] Correct instances of destroying baseturfs in ChangeTurf & Select dimensional anomaly theme [MDB IGNORE] (#19255) * Correct instances of destroying baseturfs in ChangeTurf & Select dimensional anomaly theme * events --------- Co-authored-by: Jacquerel Co-authored-by: lessthnthree Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com> --- .../anomalies/anomalies_dimensional.dm | 8 +- .../anomalies/anomalies_dimensional_themes.dm | 10 +- code/game/turfs/open/_open.dm | 13 ++ code/game/turfs/open/openspace.dm | 8 + code/game/turfs/open/space/space.dm | 8 + .../reactive_armour_dimensional_themes.dm | 3 +- code/modules/events/anomaly/_anomaly.dm | 5 + .../events/anomaly/anomaly_dimensional.dm | 28 +++ .../hostile/megafauna/colossus.dm | 180 ++++++++++++------ .../spells/spell_types/conjure/_conjure.dm | 24 ++- 10 files changed, 208 insertions(+), 79 deletions(-) diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional.dm b/code/game/objects/effects/anomalies/anomalies_dimensional.dm index 86811011f65..b0bfa9ea026 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional.dm @@ -42,10 +42,12 @@ /** * Prepare a new area for transformation into a new theme. + * Optionally pass in the typepath of an anomaly theme to use that one. */ -/obj/effect/anomaly/dimensional/proc/prepare_area() - var/datum/dimension_theme/themes = new() - theme = themes.get_random_theme() +/obj/effect/anomaly/dimensional/proc/prepare_area(new_theme_path) + if (!new_theme_path) + new_theme_path = pick(subtypesof(/datum/dimension_theme)) + theme = new new_theme_path() apply_theme_icon() target_turfs = new() diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm index 478eaebfa66..918f47ffcfb 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional_themes.dm @@ -32,13 +32,6 @@ 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. * @@ -105,7 +98,7 @@ /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) + affected_floor.replace_floor(pick_weight(replace_floors), flags = CHANGETURF_INHERIT_AIR) return TRUE /** @@ -191,6 +184,7 @@ if (!permit_replace_material(thing)) continue thing.set_custom_materials(custom_materials) + thing.update_appearance(updates = UPDATE_ICON) #undef PERMITTED_MATERIAL_REPLACE_TYPES diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index be71cfee659..68239958b9c 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -38,6 +38,19 @@ . = ..() update_visuals() +/** + * Replace an open turf with another open turf while avoiding the pitfall of replacing plating with a floor tile, leaving a hole underneath. + * This replaces the current turf if it is plating and is passed plating, is tile and is passed tile. + * It places the new turf on top of itself if it is plating and is passed a tile. + * It also replaces the turf if it is tile and is passed plating, essentially destroying the over turf. + * Flags argument is passed directly to ChangeTurf or PlaceOnTop + */ +/turf/open/proc/replace_floor(turf/open/new_floor_path, flags) + if (!overfloor_placed && initial(new_floor_path.overfloor_placed)) + PlaceOnTop(new_floor_path, flags = flags) + return + ChangeTurf(new_floor_path, flags = flags) + /turf/open/indestructible name = "floor" desc = "The floor you walk on. It looks near-impervious to damage." diff --git a/code/game/turfs/open/openspace.dm b/code/game/turfs/open/openspace.dm index ba16fc0872c..9e779d5d9c3 100644 --- a/code/game/turfs/open/openspace.dm +++ b/code/game/turfs/open/openspace.dm @@ -154,6 +154,14 @@ return TRUE return FALSE +/turf/open/openspace/replace_floor(turf/open/new_floor_path, flags) + if (!initial(new_floor_path.overfloor_placed)) + ChangeTurf(new_floor_path, flags = flags) + return + // Create plating under tiled floor we try to create directly onto the air + PlaceOnTop(/turf/open/floor/plating, flags = flags) + PlaceOnTop(new_floor_path, flags = flags) + /turf/open/openspace/icemoon name = "ice chasm" baseturfs = /turf/open/openspace/icemoon diff --git a/code/game/turfs/open/space/space.dm b/code/game/turfs/open/space/space.dm index a3dade4b42a..b16534c88fa 100644 --- a/code/game/turfs/open/space/space.dm +++ b/code/game/turfs/open/space/space.dm @@ -302,3 +302,11 @@ set_light(2) else if(!isspaceturf(source) && ispath(path, /turf/open/space)) set_light(0) + +/turf/open/space/replace_floor(turf/open/new_floor_path, flags) + if (!initial(new_floor_path.overfloor_placed)) + ChangeTurf(new_floor_path, flags = flags) + return + // Create plating under tiled floor we try to create directly onto space + PlaceOnTop(/turf/open/floor/plating, flags = flags) + PlaceOnTop(new_floor_path, flags = flags) diff --git a/code/modules/clothing/suits/reactive_armour_dimensional_themes.dm b/code/modules/clothing/suits/reactive_armour_dimensional_themes.dm index cc60c473864..ca5da169630 100644 --- a/code/modules/clothing/suits/reactive_armour_dimensional_themes.dm +++ b/code/modules/clothing/suits/reactive_armour_dimensional_themes.dm @@ -77,7 +77,8 @@ */ /datum/armour_dimensional_theme/proc/convert_turf(turf/to_convert) if (isfloorturf(to_convert)) - to_convert.ChangeTurf(replace_floor, flags = CHANGETURF_INHERIT_AIR) + var/turf/open/open_turf = to_convert + open_turf.replace_floor(replace_floor, flags = CHANGETURF_INHERIT_AIR) else if (iswallturf(to_convert)) to_convert.ChangeTurf(replace_wall) diff --git a/code/modules/events/anomaly/_anomaly.dm b/code/modules/events/anomaly/_anomaly.dm index 4b15ac93c29..0b9a6cebb3b 100644 --- a/code/modules/events/anomaly/_anomaly.dm +++ b/code/modules/events/anomaly/_anomaly.dm @@ -39,8 +39,13 @@ if(anomaly_turf) newAnomaly = new anomaly_path(anomaly_turf) if (newAnomaly) + apply_anomaly_properties(newAnomaly) announce_to_ghosts(newAnomaly) +/// Make any further post-creation modifications to the anomaly +/datum/round_event/anomaly/proc/apply_anomaly_properties(obj/effect/anomaly/new_anomaly) + return + /datum/event_admin_setup/anomaly ///The admin-chosen spawn location. var/turf/spawn_location diff --git a/code/modules/events/anomaly/anomaly_dimensional.dm b/code/modules/events/anomaly/anomaly_dimensional.dm index 30721faa7a0..60d1073cedc 100644 --- a/code/modules/events/anomaly/anomaly_dimensional.dm +++ b/code/modules/events/anomaly/anomaly_dimensional.dm @@ -6,11 +6,39 @@ max_occurrences = 5 weight = 20 description = "This anomaly replaces the materials of the surrounding area." + admin_setup = /datum/event_admin_setup/listed_options/anomaly_dimensional /datum/round_event/anomaly/anomaly_dimensional start_when = 10 announce_when = 3 anomaly_path = /obj/effect/anomaly/dimensional + /// What theme should the anomaly initially apply to the area? + var/anomaly_theme + +/datum/round_event/anomaly/anomaly_dimensional/apply_anomaly_properties(obj/effect/anomaly/dimensional/new_anomaly) + if (!anomaly_theme) + return + new_anomaly.prepare_area(new_theme_path = anomaly_theme) /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") + +/datum/event_admin_setup/listed_options/anomaly_dimensional + input_text = "Select a dimensional anomaly theme?" + normal_run_option = "Random Theme" + ///The admin-chosen spawn location. + var/turf/spawn_location + +/datum/event_admin_setup/listed_options/anomaly_dimensional/get_list() + return subtypesof(/datum/dimension_theme) + +/datum/event_admin_setup/listed_options/anomaly_dimensional/prompt_admins() + . = ..() + if (. == ADMIN_CANCEL_EVENT) + return ADMIN_CANCEL_EVENT + if (tgui_alert(usr, "Spawn anomaly at your current location?", "Anomaly Alert", list("Yes", "No")) == "Yes") + spawn_location = get_turf(usr) + +/datum/event_admin_setup/listed_options/anomaly_dimensional/apply_to_event(datum/round_event/anomaly/anomaly_dimensional/event) + event.spawn_location = spawn_location + event.anomaly_theme = chosen diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 3baa934c55b..a0881633de9 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -336,76 +336,136 @@ new_clown.dress_up_as_job(SSjob.GetJobType(/datum/job/clown)) affected_targets.Add(new_clown) -/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one +/// Transforms the area to look like a new one +/obj/machinery/anomalous_crystal/theme_warp observer_desc = "This crystal warps the area around it to a theme." activation_method = ACTIVATE_TOUCH cooldown_add = 20 SECONDS use_time = 5 SECONDS - var/terrain_theme = "winter" - var/NewTerrainFloors - var/NewTerrainWalls - var/NewTerrainChairs - var/NewTerrainTables - var/list/NewFlora = list() - var/florachance = 8 + var/datum/crystal_warp_theme/terrain_theme /obj/machinery/anomalous_crystal/theme_warp/Initialize(mapload) . = ..() - terrain_theme = pick("lavaland","winter","jungle","ayy lmao") + var/terrain_type = pick(subtypesof(/datum/crystal_warp_theme)) + terrain_theme = new terrain_type() observer_desc = "This crystal changes the area around it to match the theme of \"[terrain_theme]\"." - switch(terrain_theme) - if("lavaland")//Depressurizes the place... and free cult metal, I guess. - NewTerrainFloors = /turf/open/floor/fakebasalt - NewTerrainWalls = /turf/closed/wall/mineral/cult - NewFlora = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) - florachance = 1 - if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway. - NewTerrainFloors = /turf/open/misc/snow/actually_safe - NewTerrainWalls = /turf/closed/wall/mineral/wood - NewTerrainChairs = /obj/structure/chair/wood - NewTerrainTables = /obj/structure/table/glass - NewFlora = list(/obj/structure/flora/grass/green/style_random, /obj/structure/flora/grass/brown/style_random, /obj/structure/flora/grass/both/style_random) - if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows. - NewTerrainFloors = /turf/open/floor/grass - NewTerrainWalls = /turf/closed/wall/mineral/wood - NewTerrainChairs = /obj/structure/chair/wood - NewTerrainTables = /obj/structure/table/wood - NewFlora = list(/obj/structure/flora/bush/sparsegrass/style_random, /obj/structure/flora/bush/ferny/style_random, /obj/structure/flora/bush/leavy/style_random, - /obj/structure/flora/bush/grassy/style_random, /obj/structure/flora/bush/sunny/style_random, /obj/structure/flora/tree/palm/style_random, /mob/living/carbon/human/species/monkey) - florachance = 20 - if("ayy lmao") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos. - NewTerrainFloors = /turf/open/floor/plating/abductor - NewTerrainWalls = /turf/closed/wall/mineral/abductor - NewTerrainChairs = /obj/structure/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline. - NewTerrainTables = /obj/structure/table/abductor - /obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method) - if(..()) - var/area/A = get_area(src) - if(!A.outdoors && !(A in affected_targets)) - for(var/atom/Stuff in A) - if(isturf(Stuff)) - var/turf/T = Stuff - if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) - var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_IGNORE_AIR) - if(prob(florachance) && NewFlora.len && !O.is_blocked_turf(TRUE)) - var/atom/Picked = pick(NewFlora) - new Picked(O) - continue - if(iswallturf(T) && NewTerrainWalls) - T.ChangeTurf(NewTerrainWalls) - continue - if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs) - var/obj/structure/chair/Original = Stuff - var/obj/structure/chair/C = new NewTerrainChairs(Original.loc) - C.setDir(Original.dir) - qdel(Stuff) - continue - if(istype(Stuff, /obj/structure/table) && NewTerrainTables) - new NewTerrainTables(Stuff.loc) - continue - affected_targets += A + . = ..() + if (!.) + return FALSE + var/area/current_area = get_area(src) + if (current_area in affected_targets) + return FALSE + if (terrain_theme.transform_area(current_area)) + affected_targets += current_area + return TRUE + +/// Transforms an area's turfs and objects into a different theme +/datum/crystal_warp_theme + /// Friendly name of theme + var/name = "" + /// Typepath of floor to replace open turfs with + var/floor + /// Typepath of wall to replace closed turfs with + var/wall + /// Typepath of object to replace chairs with + var/chair + /// Typepath of object to replace tables with + var/table + /// Typepath of things to potentially spawn on transformed open turfs + var/list/flora_and_fauna = list() + /// Chance per turf to create the things in the list above + var/flora_and_fauna_chance = 8 + +/// Change appropriate objects in provided area to those matching our theme, and spawn some plants or animals +/datum/crystal_warp_theme/proc/transform_area(area/target_area) + if (target_area.outdoors) + return FALSE + for(var/atom/thing in target_area) + if(isturf(thing)) + replace_turf(thing) + continue + if(chair && istype(thing, /obj/structure/chair)) + replace_object(thing, chair) + continue + if(table && istype(thing, /obj/structure/table)) + replace_object(thing, table) + continue + return TRUE + +/// Replaces a turf with a different themed turf +/datum/crystal_warp_theme/proc/replace_turf(turf/target_turf) + if(isindestructiblefloor(target_turf) || isindestructiblewall(target_turf) || isopenspaceturf(target_turf)) + return + + if(wall && iswallturf(target_turf)) + target_turf.ChangeTurf(wall) + return + + if(!isopenturf(target_turf)) + return + + if(length(flora_and_fauna) && !target_turf.is_blocked_turf(exclude_mobs = TRUE) && prob(flora_and_fauna_chance)) + var/atom/new_flora_and_fauna = pick(flora_and_fauna) + new new_flora_and_fauna(target_turf) + + if(floor) + var/turf/open/open_turf = target_turf + open_turf.replace_floor(floor, flags = CHANGETURF_IGNORE_AIR) + +/// Replaces an object with a different themed object +/datum/crystal_warp_theme/proc/replace_object(atom/original, new_type) + var/atom/new_thing = new new_type(original.loc) + new_thing.setDir(original.dir) + qdel(original) + +// Depressurizes the place... and free cult metal, I guess. +/datum/crystal_warp_theme/lavaland + name = "lavaland" + floor = /turf/open/floor/fakebasalt + wall = /turf/closed/wall/mineral/cult + flora_and_fauna = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) + flora_and_fauna_chance = 1 + +// Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway. +/datum/crystal_warp_theme/winter + name = "winter" + floor = /turf/open/misc/snow/actually_safe + wall = /turf/closed/wall/mineral/wood + chair = /obj/structure/chair/wood + table = /obj/structure/table/glass + flora_and_fauna = list( + /obj/structure/flora/grass/both/style_random, + /obj/structure/flora/grass/brown/style_random, + /obj/structure/flora/grass/green/style_random, + ) + +// Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows. +/datum/crystal_warp_theme/jungle + name = "jungle" + floor = /turf/open/floor/grass + wall = /turf/closed/wall/mineral/wood + chair = /obj/structure/chair/wood + table = /obj/structure/table/wood + flora_and_fauna = list( + /mob/living/carbon/human/species/monkey, + /obj/structure/flora/bush/ferny/style_random, + /obj/structure/flora/bush/grassy/style_random, + /obj/structure/flora/bush/leavy/style_random, + /obj/structure/flora/tree/palm/style_random, + /obj/structure/flora/bush/sparsegrass/style_random, + /obj/structure/flora/bush/sunny/style_random, + ) + flora_and_fauna_chance = 20 + +// Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos. +/datum/crystal_warp_theme/ayylmao + name = "ayy lmao" + floor = /turf/open/floor/mineral/abductor + wall = /turf/closed/wall/mineral/abductor + chair = /obj/structure/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline. + table = /obj/structure/table/abductor /obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with observer_desc = "This crystal generates a projectile when activated." diff --git a/code/modules/spells/spell_types/conjure/_conjure.dm b/code/modules/spells/spell_types/conjure/_conjure.dm index 9483bb57b43..ffab0887111 100644 --- a/code/modules/spells/spell_types/conjure/_conjure.dm +++ b/code/modules/spells/spell_types/conjure/_conjure.dm @@ -34,16 +34,26 @@ to_summon_in -= spawn_place if(ispath(summoned_object_type, /turf)) - spawn_place.ChangeTurf(summoned_object_type, flags = CHANGETURF_INHERIT_AIR) + if(isclosedturf(spawn_place)) + spawn_place.ChangeTurf(summoned_object_type, flags = CHANGETURF_INHERIT_AIR) + return + if(ispath(summoned_object_type, /turf/closed)) + if (spawn_place.overfloor_placed) + spawn_place.ChangeTurf(summoned_object_type, flags = CHANGETURF_INHERIT_AIR) + else + spawn_place.PlaceOnTop(summoned_object_type, flags = CHANGETURF_INHERIT_AIR) + return + var/turf/open/open_turf = spawn_place + open_turf.replace_floor(summoned_object_type, flags = CHANGETURF_INHERIT_AIR) + return - else - var/atom/summoned_object = new summoned_object_type(spawn_place) + var/atom/summoned_object = new summoned_object_type(spawn_place) - summoned_object.flags_1 |= ADMIN_SPAWNED_1 - if(summon_lifespan > 0) - QDEL_IN(summoned_object, summon_lifespan) + summoned_object.flags_1 |= ADMIN_SPAWNED_1 + if(summon_lifespan > 0) + QDEL_IN(summoned_object, summon_lifespan) - post_summon(summoned_object, cast_on) + post_summon(summoned_object, cast_on) /// Called on atoms summoned after they are created, allows extra variable editing and such of created objects /datum/action/cooldown/spell/conjure/proc/post_summon(atom/summoned_object, atom/cast_on)