[NO GBP] Fixing more issues with sand (you can make sand walls again, also ghost glass sheets?) (#93215)

## About The Pull Request
Apparently wall construction code is snowflaked and indented as fuck
(and the same goes for door assemblies). I'm not bothering refactoring
everything with them, only to reduce the indentation, changing a couple
vars and overall making it easier to work with them later. This includes
wall construction not being hardcoded to sheets but include the
possibility to use other kind of stacks as well (if you don't count the
snowflake interaction with iron rods). In layman's terms, this means you
can make walls made out of sand (distinct from sandstone) again.

Also I've done some small changes to the materials storage, so that it
can eject ores too if the material doesn't have a sheet type.

Also, I've been told there may be issues with broken, uninteractable
(probably not properly initialized) glass sheets beside the ORM. I'm not
100% sure about the deets, but it may have something to do with spawning
the glass on the same turf the ORM is listening to, when smelting sand,
causing some race conditions, so let's spawn it in nullspace

## Why It's Good For The Game
While I'm sure there may be more elegant solutions (just take a look at
the wall and door construction code, they both use text2path oh god!),
I'm just here to make things a lil' cleaner and be done with issues with
the fact that sand is made of sand.

## Changelog

🆑
fix: You can once again make sand walls.
fix: Deconstructing an autolathe with sand in it should now drop sand.
/🆑
This commit is contained in:
Ghom
2025-10-02 19:12:11 +03:00
committed by GitHub
parent bdb51942a8
commit a28575aa82
15 changed files with 362 additions and 343 deletions
+56 -56
View File
@@ -212,63 +212,63 @@
electronics = null
ae.forceMove(src.loc)
else if(istype(W, /obj/item/stack/sheet) && (!glass || !mineral))
var/obj/item/stack/sheet/G = W
if(G)
if(G.get_amount() >= 1)
if(!noglass)
if(!glass)
if(istype(G, /obj/item/stack/sheet/rglass) || istype(G, /obj/item/stack/sheet/glass))
playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE)
user.visible_message(span_notice("[user] adds [G.name] to the airlock assembly."), \
span_notice("You start to install [G.name] into the airlock assembly..."))
if(do_after(user, 4 SECONDS, target = src))
if(G.get_amount() < 1 || glass)
return
if(G.type == /obj/item/stack/sheet/rglass)
to_chat(user, span_notice("You install [G.name] windows into the airlock assembly."))
heat_proof_finished = 1 //reinforced glass makes the airlock heat-proof
name = "near finished heat-proofed window airlock assembly"
else
to_chat(user, span_notice("You install regular glass windows into the airlock assembly."))
name = "near finished window airlock assembly"
G.use(1)
glass = TRUE
if(!nomineral && !mineral)
if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype)
var/M = G.sheettype
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
if(!ispath(mineralassembly))
to_chat(user, span_warning("You cannot add [G] to [src]!"))
return
if(G.get_amount() >= 2)
playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE)
user.visible_message(span_notice("[user] adds [G.name] to the airlock assembly."), \
span_notice("You start to install [G.name] into the airlock assembly..."))
if(do_after(user, 4 SECONDS, target = src))
if(G.get_amount() < 2 || mineral)
return
to_chat(user, span_notice("You install [M] plating into the airlock assembly."))
G.use(2)
var/obj/structure/door_assembly/MA = new mineralassembly(loc)
if(MA.noglass && glass) //in case the new door doesn't support glass. prevents the new one from reverting to a normal airlock after being constructed.
var/obj/item/stack/sheet/dropped_glass
if(heat_proof_finished)
dropped_glass = new /obj/item/stack/sheet/rglass(drop_location())
heat_proof_finished = FALSE
else
dropped_glass = new /obj/item/stack/sheet/glass(drop_location())
glass = FALSE
to_chat(user, span_notice("As you finish, a [dropped_glass.singular_name] falls out of [MA]'s frame."))
transfer_assembly_vars(src, MA, TRUE)
else
to_chat(user, span_warning("You need at least two sheets add a mineral cover!"))
else
to_chat(user, span_warning("You cannot add [G] to [src]!"))
else if(istype(W, /obj/item/stack/sheet))
var/obj/item/stack/sheet/sheet = W
if(!glass && (istype(sheet, /obj/item/stack/sheet/rglass) || istype(sheet, /obj/item/stack/sheet/glass)))
if(noglass)
to_chat(user, span_warning("You cannot add [sheet] to [src]!"))
return
playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE)
user.visible_message(span_notice("[user] adds [sheet.name] to the airlock assembly."), \
span_notice("You start to install [sheet.name] into the airlock assembly..."))
if(do_after(user, 4 SECONDS, target = src))
if(sheet.get_amount() < 1 || glass)
return
if(sheet.type == /obj/item/stack/sheet/rglass)
to_chat(user, span_notice("You install [sheet.name] windows into the airlock assembly."))
heat_proof_finished = 1 //reinforced glass makes the airlock heat-proof
name = "near finished heat-proofed window airlock assembly"
else
to_chat(user, span_warning("You cannot add [G] to [src]!"))
to_chat(user, span_notice("You install regular glass windows into the airlock assembly."))
name = "near finished window airlock assembly"
sheet.use(1)
glass = TRUE
return
if(istype(sheet, /obj/item/stack/sheet/mineral) && sheet.construction_path_type)
if(nomineral || mineral)
to_chat(user, span_warning("You cannot add [sheet] to [src]!"))
return
var/M = sheet.construction_path_type
var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]")
if(!ispath(mineralassembly))
to_chat(user, span_warning("You cannot add [sheet] to [src]!"))
return
if(sheet.get_amount() < 2)
to_chat(user, span_warning("You need at least two sheets add a mineral cover!"))
return
playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE)
user.visible_message(span_notice("[user] adds [sheet.name] to the airlock assembly."), \
span_notice("You start to install [sheet.name] into the airlock assembly..."))
if(!do_after(user, 4 SECONDS, target = src) || sheet.get_amount() < 2 || mineral)
return
to_chat(user, span_notice("You install [M] plating into the airlock assembly."))
sheet.use(2)
var/obj/structure/door_assembly/MA = new mineralassembly(loc)
if(MA.noglass && glass) //in case the new door doesn't support glass. prevents the new one from reverting to a normal airlock after being constructed.
var/obj/item/stack/sheet/dropped_glass
if(heat_proof_finished)
dropped_glass = new /obj/item/stack/sheet/rglass(drop_location())
heat_proof_finished = FALSE
else
dropped_glass = new /obj/item/stack/sheet/glass(drop_location())
glass = FALSE
to_chat(user, span_notice("As you finish, a [dropped_glass.singular_name] falls out of [MA]'s frame."))
transfer_assembly_vars(src, MA, TRUE)
else if((W.tool_behaviour == TOOL_SCREWDRIVER) && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER )
user.visible_message(span_notice("[user] finishes the airlock."), \
+250 -240
View File
@@ -44,12 +44,7 @@
. += span_notice("[src] is designed for tram usage. Deconstructed with a screwdriver!")
/obj/structure/girder/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
var/platingmodifier = 1
if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
platingmodifier = 0.7
if(next_beep <= world.time)
next_beep = world.time + 10
playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
add_fingerprint(user)
if(istype(W, /obj/item/gun/energy/plasmacutter))
@@ -64,9 +59,14 @@
if(!QDELETED(M))
M.add_fingerprint(user)
qdel(src)
return
if(isstack(W))
var/obj/item/stack/stack = W
if(!stack.usable_for_construction)
balloon_alert(user, "can't make walls with it!")
return
else if(isstack(W))
if(iswallturf(loc) || (locate(/obj/structure/falsewall) in src.loc.contents))
balloon_alert(user, "wall already present!")
return
@@ -78,245 +78,255 @@
balloon_alert(user, "need tram floors!")
return
if(istype(W, /obj/item/stack/rods))
var/obj/item/stack/rods/rod = W
var/amount = construction_cost[rod.type]
if(state == GIRDER_DISPLACED)
if(rod.get_amount() < amount)
balloon_alert(user, "need [amount] rods!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(rod.get_amount() < amount)
return
rod.use(amount)
var/obj/structure/falsewall/iron/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
return
else if(state == GIRDER_REINF)
balloon_alert(user, "need plasteel sheet!")
return
else
if(rod.get_amount() < amount)
balloon_alert(user, "need [amount] rods!")
return
balloon_alert(user, "adding rods...")
if(do_after(user, 4 SECONDS, target = src))
if(rod.get_amount() < amount)
return
rod.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/mineral/iron)
transfer_fingerprints_to(T)
qdel(src)
return
make_wall(stack, user)
return
if(!istype(W, /obj/item/stack/sheet))
return
var/obj/item/stack/sheet/sheets = W
if(istype(sheets, /obj/item/stack/sheet/iron))
var/amount = construction_cost[/obj/item/stack/sheet/iron]
if(state == GIRDER_DISPLACED)
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 20*platingmodifier, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/falsewall/F = new (loc)
transfer_fingerprints_to(F)
qdel(src)
return
else if(state == GIRDER_REINF)
balloon_alert(user, "need plasteel sheet!")
return
else if(state == GIRDER_TRAM)
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/tram/alt/iron/tram_wall = new(loc)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
else
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 40*platingmodifier, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall)
transfer_fingerprints_to(T)
qdel(src)
return
if(istype(sheets, /obj/item/stack/sheet/titaniumglass) && state == GIRDER_TRAM)
var/amount = construction_cost[/obj/item/stack/sheet/titaniumglass]
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding panel...")
if (do_after(user, 2 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/tram/tram_wall = new(loc)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
if(istype(sheets, /obj/item/stack/sheet/plasteel))
var/amount = construction_cost[/obj/item/stack/sheet/plasteel]
if(state == GIRDER_DISPLACED)
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/falsewall/reinforced/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
return
else if(state == GIRDER_REINF)
amount = 1 // hur dur let's make plasteel have different construction amounts 4norasin
if(sheets.get_amount() < amount)
return
balloon_alert(user, "adding plating...")
if(do_after(user, 50*platingmodifier, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/r_wall)
transfer_fingerprints_to(T)
qdel(src)
return
else
amount = 1 // hur dur x2
if(sheets.get_amount() < amount)
return
balloon_alert(user, "reinforcing frame...")
if(do_after(user, 60*platingmodifier, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/girder/reinforced/R = new (loc)
transfer_fingerprints_to(R)
qdel(src)
return
if(istype(sheets, /obj/item/stack/sheet/mineral/plastitanium))
if(state == GIRDER_REINF)
if(sheets.get_amount() < 1)
return
balloon_alert(user, "adding plating...")
if(do_after(user, 50*platingmodifier, target = src))
if(sheets.get_amount() < 1)
return
sheets.use(1)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/r_wall/plastitanium)
transfer_fingerprints_to(T)
qdel(src)
return
// No return here because generic material construction handles making normal plastitanium walls
if(!sheets.has_unique_girder && sheets.material_type)
if(istype(src, /obj/structure/girder/reinforced))
balloon_alert(user, "need plasteel or plastitanium!")
return
var/M = sheets.sheettype
var/amount = construction_cost["exotic_material"]
if(state == GIRDER_TRAM)
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
var/tram_wall_type = text2path("/obj/structure/tram/alt/[M]")
if(!tram_wall_type)
balloon_alert(user, "need titanium glass or mineral!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
var/obj/structure/tram/tram_wall
tram_wall = new tram_wall_type(loc)
sheets.use(amount)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
if(state == GIRDER_DISPLACED)
var/falsewall_type = text2path("/obj/structure/falsewall/[M]")
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/obj/structure/falsewall/falsewall
if(falsewall_type)
falsewall = new falsewall_type (loc)
else
var/obj/structure/falsewall/material/mat_falsewall = new(loc)
var/list/material_list = list()
material_list[GET_MATERIAL_REF(sheets.material_type)] = SHEET_MATERIAL_AMOUNT * 2
if(material_list)
mat_falsewall.set_custom_materials(material_list)
falsewall = mat_falsewall
transfer_fingerprints_to(falsewall)
qdel(src)
return
else
if(sheets.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(sheets.get_amount() < amount)
return
sheets.use(amount)
var/turf/T = get_turf(src)
if(sheets.walltype)
T.place_on_top(sheets.walltype)
else
var/turf/newturf = T.place_on_top(/turf/closed/wall/material)
var/list/material_list = list()
material_list[GET_MATERIAL_REF(sheets.material_type)] = SHEET_MATERIAL_AMOUNT * 2
if(material_list)
newturf.set_custom_materials(material_list)
transfer_fingerprints_to(T)
qdel(src)
return
add_hiddenprint(user)
else if(istype(W, /obj/item/pipe))
if(istype(W, /obj/item/pipe))
var/obj/item/pipe/P = W
if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
if(!user.transfer_item_to_turf(P, drop_location()))
return
balloon_alert(user, "inserted pipe")
else
return ..()
return
return ..()
/obj/structure/girder/proc/make_wall(obj/item/stack/stack, mob/user)
var/speed_modifier = 1
if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
speed_modifier = 0.7
if(next_beep <= world.time)
next_beep = world.time + 10
playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
if(istype(stack, /obj/item/stack/rods))
var/obj/item/stack/rods/rod = stack
var/amount = construction_cost[rod.type]
if(state == GIRDER_DISPLACED)
if(rod.get_amount() < amount)
balloon_alert(user, "need [amount] rods!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(rod.get_amount() < amount)
return
rod.use(amount)
var/obj/structure/falsewall/iron/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
return
if(state == GIRDER_REINF)
balloon_alert(user, "need plasteel sheet!")
return
if(rod.get_amount() < amount)
balloon_alert(user, "need [amount] rods!")
return
balloon_alert(user, "adding rods...")
if(do_after(user, 4 SECONDS, target = src))
if(rod.get_amount() < amount)
return
rod.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/mineral/iron)
transfer_fingerprints_to(T)
qdel(src)
return
if(istype(stack, /obj/item/stack/sheet/iron))
var/amount = construction_cost[/obj/item/stack/sheet/iron]
if(state == GIRDER_DISPLACED)
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 20 * speed_modifier, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/falsewall/F = new (loc)
transfer_fingerprints_to(F)
qdel(src)
return
else if(state == GIRDER_REINF)
balloon_alert(user, "need plasteel sheet!")
return
else if(state == GIRDER_TRAM)
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/tram/alt/iron/tram_wall = new(loc)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
else
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 40 * speed_modifier, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall)
transfer_fingerprints_to(T)
qdel(src)
return
if(istype(stack, /obj/item/stack/sheet/titaniumglass) && state == GIRDER_TRAM)
var/amount = construction_cost[/obj/item/stack/sheet/titaniumglass]
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding panel...")
if (do_after(user, 2 SECONDS, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/tram/tram_wall = new(loc)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
if(istype(stack, /obj/item/stack/sheet/plasteel))
var/amount = construction_cost[/obj/item/stack/sheet/plasteel]
if(state == GIRDER_DISPLACED)
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/falsewall/reinforced/FW = new (loc)
transfer_fingerprints_to(FW)
qdel(src)
return
else if(state == GIRDER_REINF)
amount = 1 // hur dur let's make plasteel have different construction amounts 4norasin
if(stack.get_amount() < amount)
return
balloon_alert(user, "adding plating...")
if(do_after(user, 50 * speed_modifier, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/r_wall)
transfer_fingerprints_to(T)
qdel(src)
return
else
amount = 1 // hur dur x2
if(stack.get_amount() < amount)
return
balloon_alert(user, "reinforcing frame...")
if(do_after(user, 60 * speed_modifier, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/girder/reinforced/R = new (loc)
transfer_fingerprints_to(R)
qdel(src)
return
if(istype(stack, /obj/item/stack/sheet/mineral/plastitanium))
if(state == GIRDER_REINF)
if(stack.get_amount() < 1)
return
balloon_alert(user, "adding plating...")
if(do_after(user, 50 * speed_modifier, target = src))
if(stack.get_amount() < 1)
return
stack.use(1)
var/turf/T = get_turf(src)
T.place_on_top(/turf/closed/wall/r_wall/plastitanium)
transfer_fingerprints_to(T)
qdel(src)
return
// No return here because generic material construction handles making normal plastitanium walls
if(!stack.has_unique_girder && stack.material_type)
if(istype(src, /obj/structure/girder/reinforced))
balloon_alert(user, "need plasteel or plastitanium!")
return
var/material
if(istype(stack, /obj/item/stack/sheet))
var/obj/item/stack/sheet/sheet = stack
material = sheet.construction_path_type
var/amount = construction_cost["exotic_material"]
if(state == GIRDER_TRAM)
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
var/tram_wall_type = text2path("/obj/structure/tram/alt/[material]")
if(!tram_wall_type)
balloon_alert(user, "need titanium glass or mineral!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(stack.get_amount() < amount)
return
var/obj/structure/tram/tram_wall
tram_wall = new tram_wall_type(loc)
stack.use(amount)
transfer_fingerprints_to(tram_wall)
qdel(src)
return
if(state == GIRDER_DISPLACED)
var/falsewall_type = text2path("/obj/structure/falsewall/[material]")
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "concealing entrance...")
if(do_after(user, 2 SECONDS, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/obj/structure/falsewall/falsewall
if(falsewall_type)
falsewall = new falsewall_type (loc)
else
var/obj/structure/falsewall/material/mat_falsewall = new(loc)
var/list/material_list = list()
material_list[GET_MATERIAL_REF(stack.material_type)] = SHEET_MATERIAL_AMOUNT * 2
if(material_list)
mat_falsewall.set_custom_materials(material_list)
falsewall = mat_falsewall
transfer_fingerprints_to(falsewall)
qdel(src)
return
else
if(stack.get_amount() < amount)
balloon_alert(user, "need [amount] sheets!")
return
balloon_alert(user, "adding plating...")
if (do_after(user, 4 SECONDS, target = src))
if(stack.get_amount() < amount)
return
stack.use(amount)
var/turf/T = get_turf(src)
if(stack.walltype)
T.place_on_top(stack.walltype)
else
var/turf/newturf = T.place_on_top(/turf/closed/wall/material)
var/list/material_list = list()
material_list[GET_MATERIAL_REF(stack.material_type)] = SHEET_MATERIAL_AMOUNT * 2
if(material_list)
newturf.set_custom_materials(material_list)
transfer_fingerprints_to(T)
qdel(src)
return
// Screwdriver behavior for girders
/obj/structure/girder/screwdriver_act(mob/user, obj/item/tool)