Adds a new Odyssey map: Decrepit Shipyard (#21500)

## About PR

Adds an industrial themed away site for Odyssey scenarios. The map
starts with a shuttle, broken by a randomized destruction feature.
Actors or the crew may choose to repair it to make it fly once more

### Detailed Changelog
<details><summary>Details</summary>
<p>

- Added a new map_effect, randomized destruction. It comes with two
varieties and different impact ranges. The way it work is the effect
chooses a random amount of turfs in the area it's placed on, and calls
`ex_act` on applicable contents in the turf.
- Added unused sprites for low railing and documented relevant functions
in the existing code.
- Made it so when a railing has an open end that doesn't connect to
anywhere, it'll apply an end cap, making it look more smooth.
- Added ceiling lattices.
- Adjusted unit tests to avoid conflicts that may occur with ceiling
lattices.
- Fixed a bug where the Odyssey subsystem repeatedly added lastly loaded
z-level to the scenario z-levels, instead of all relevant levels to the
site. This was causing issues in Odyssey maps with shuttles.
- Fixed hydrogen tank not using its sprite. Also recoloured the tank to
match modern hydrogen canister colour.
- Fixed `/obj/machinery/door/airlock/maintenance` not using its intended
appearance.

</p>
</details> 

## Images

<img width="4128" height="2528" alt="StrongDMM-2025-11-10 21 33 47"
src="https://github.com/user-attachments/assets/09d8b671-457c-4ec5-88ac-e503641a0531"
/>
<img width="3424" height="2016" alt="StrongDMM-2025-11-10 21 34 27"
src="https://github.com/user-attachments/assets/943b8529-7f2a-41db-a7be-e57d5d30ead7"
/>
<img width="1312" height="800" alt="StrongDMM-2025-11-10 21 34 52"
src="https://github.com/user-attachments/assets/f665800a-367b-466e-a16e-a6f0b122e3bd"
/>
<img width="997" height="999" alt="Screenshot_54"
src="https://github.com/user-attachments/assets/c06667c6-0dfc-4dc4-af67-821f36ad2933"
/>
<img width="997" height="1001" alt="Screenshot_55"
src="https://github.com/user-attachments/assets/848a2847-9eb0-450a-87e9-08c371aaf78a"
/>
<img width="998" height="992" alt="Screenshot_61"
src="https://github.com/user-attachments/assets/e6174cb5-d4d6-4afc-82ab-bbf412eda607"
/>
<img width="998" height="990" alt="Screenshot_63"
src="https://github.com/user-attachments/assets/cc838bdc-9e22-4aed-ad16-0f8722442b8a"
/>
This commit is contained in:
Kano
2025-12-24 13:17:24 +00:00
committed by GitHub
parent dc783e0f2d
commit 22e1d93b39
27 changed files with 170476 additions and 40 deletions
@@ -0,0 +1,54 @@
// Place purely decorative objects here that doesn't fall under any specific category (legal fake objects).
ABSTRACT_TYPE(/obj/structure/decor)
name = "base type"
anchored = TRUE
layer = STRUCTURE_LAYER
// ---- Ladders
/obj/structure/decor/fluff_ladder
name = "ladder"
icon = 'icons/obj/structures.dmi'
icon_state = "ladder01"
/obj/structure/decor/fluff_ladder/up
icon_state = "ladder10"
/obj/structure/decor/fluff_ladder/tall
icon_state = "ladder11"
// ---- Suspension cable
/obj/structure/decor/suspension_cable
name = "suspension cable"
desc = "A lightweight, high-strength cable designed for robotic suspension."
icon = 'icons/obj/power_cond_white.dmi'
color = "#B6B64B"
layer = ABOVE_HUMAN_LAYER
/obj/structure/decor/suspension_cable/right
icon_state = "8-9"
/obj/structure/decor/suspension_cable/left
icon_state = "4-5"
// ---- Suspension bar
/obj/structure/decor/suspension_bar
name = "suspension bar"
desc = "A rigid bar that holds or supports other components."
icon = 'icons/atmos/pipes.dmi'
icon_state = "intact"
color = "#444444"
layer = ABOVE_HUMAN_LAYER
// ---- Ship guns
/obj/structure/decor/fluff_francisca
name = "compact francisca rotary gun"
desc = "While this piece of metal resembles a Francisca-series rotary gun manufactured by Kumar Arms, it appears to have undergone some modifications. \
It also doesn't seem to be complete."
icon = 'icons/obj/machinery/ship_guns/francisca_compact.dmi'
icon_state = "weapon_base"
density = TRUE
+30 -3
View File
@@ -35,9 +35,7 @@
/obj/structure/lattice/Initialize()
. = ..()
for(var/obj/structure/lattice/LAT in loc)
if(LAT == src)
continue
if(check_for_duplicates())
stack_trace("multiple lattices found in ([loc.x], [loc.y], [loc.z])")
return INITIALIZE_HINT_QDEL
@@ -59,6 +57,13 @@
qdel(src)
return
/obj/structure/lattice/proc/check_for_duplicates()
for(var/obj/structure/lattice/found_lattice in get_turf(src))
if(found_lattice == src || istype(found_lattice, /obj/structure/lattice/ceiling))
continue
return TRUE
return FALSE
/obj/structure/lattice/attackby(obj/item/attacking_item, mob/user)
if (istype(attacking_item, /obj/item/stack/tile/floor))
var/turf/T = get_turf(src)
@@ -79,6 +84,28 @@
qdel(src)
return
/obj/structure/lattice/ceiling
layer = ABOVE_ABOVE_HUMAN_LAYER
canSmoothWith = list(
/obj/structure/lattice/ceiling,
/turf/simulated/wall,
/turf/simulated/mineral,
/turf/unsimulated/wall,
/obj/structure/grille,
/turf/unsimulated/mineral/asteroid
)
/obj/structure/lattice/ceiling/Initialize()
. = ..()
AddComponent(/datum/component/large_transparency, 0, 0, 0, 0)
/obj/structure/lattice/ceiling/check_for_duplicates()
for(var/obj/structure/lattice/ceiling/found_lattice in get_turf(src))
if(found_lattice == src)
continue
return TRUE
return FALSE
/obj/structure/lattice/catwalk
name = "catwalk"
desc = "A catwalk for easier EVA maneuvering."
+17 -6
View File
@@ -64,6 +64,9 @@
. = ..()
update_icon()
/obj/structure/railing/mapped/no_density/low
icon_state = "railing0-0"
/obj/structure/railing/New(var/newloc, var/material_key = DEFAULT_WALL_MATERIAL)
material = material_key // Converted to datum in initialize().
..(newloc)
@@ -136,31 +139,31 @@
for(var/obj/structure/railing/R in get_turf(src))
if((R.dir == Lturn) && R.anchored)
neighbor_status |= 32
neighbor_status |= 32 // neighbor is making a left turn on the same tile
if(UpdateNeighbors)
R.update_icon(0)
if((R.dir == Rturn) && R.anchored)
neighbor_status |= 2
neighbor_status |= 2 // neighbor is making a right turn on the same tile
if(UpdateNeighbors)
R.update_icon(0)
for(var/obj/structure/railing/R in get_step(src, Lturn))
if((R.dir == src.dir) && R.anchored)
neighbor_status |= 16
neighbor_status |= 16 // neighbor is in our left, in the same line
if(UpdateNeighbors)
R.update_icon(0)
for(var/obj/structure/railing/R in get_step(src, Rturn))
if((R.dir == src.dir) && R.anchored)
neighbor_status |= 1
neighbor_status |= 1 // neighbor is in our right, in the same line
if (UpdateNeighbors)
R.update_icon(0)
for(var/obj/structure/railing/R in get_step(src, (Lturn + src.dir)))
if((R.dir == Rturn) && R.anchored)
neighbor_status |= 64
neighbor_status |= 64 // neighbor is in our diagonal left, making a longer turn
if (UpdateNeighbors)
R.update_icon(0)
for(var/obj/structure/railing/R in get_step(src, (Rturn + src.dir)))
if((R.dir == Lturn) && R.anchored)
neighbor_status |= 4
neighbor_status |= 4 // neighbor is in our diagonal right, making a longer turn
if (UpdateNeighbors)
R.update_icon(0)
@@ -177,8 +180,10 @@
icon_state = "railing1-[density]"
if(neighbor_status & 32)
AddOverlays(image(icon, "corneroverlay[density]"))
if((neighbor_status & 16) || !(neighbor_status & 32) || (neighbor_status & 64))
AddOverlays(image(icon, "frontoverlay_l[density]"))
if(!(neighbor_status & 2) || (neighbor_status & 1) || (neighbor_status & 4))
AddOverlays(image(icon, "frontoverlay_r[density]"))
if(neighbor_status & 4)
@@ -195,6 +200,12 @@
pix_offset_y = 32
AddOverlays(image(icon, "mcorneroverlay[density]", pixel_x = pix_offset_x, pixel_y = pix_offset_y))
if(!(neighbor_status & 16) && !(neighbor_status & 64) && !(neighbor_status & 32)) // Left endcap, we have no connections in left
AddOverlays(image(icon, "frontend_l[density]"))
if(!(neighbor_status & 1) && !(neighbor_status & 4) && !(neighbor_status & 2)) // Right endcap, we have no connections in right
AddOverlays(image(icon, "frontend_r[density]"))
/obj/structure/railing/verb/flip() // This will help push railing to remote places, such as open space turfs
set name = "Flip Railing"
set category = "Object"