From 7e0dc8a88b32a703b3beaee85d65be95309882f2 Mon Sep 17 00:00:00 2001 From: Sparky Date: Wed, 26 Jun 2024 11:09:20 +0100 Subject: [PATCH] Various Tent Fixes (#19509) - bugfix: "Fixed tents not allowing assembly/disassembly by someone who was interrupted." - bugfix: "Fixed tents having invisible walls inside of them." - bugfix: "Fixed ghosts being unable to see inside tents." - bugfix: "Fixed tent sprites to be 3/4th compliant." - bugfix: "Fixed tent roofs not disappering when you disassemble one you are inside of." - bugfix: "Fixed tent canvas not having a description." - bugfix: "Fixed pre-fabricated tents not being disassembleable." --- code/game/objects/items/camping.dm | 83 +++++++++++++++++++++----- code/game/objects/structures/large.dm | 4 +- html/changelogs/tent-fixes.yml | 12 ++++ icons/obj/item/camping.dmi | Bin 4984 -> 8612 bytes icons/obj/item/tent_decals.dmi | Bin 731 -> 731 bytes 5 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 html/changelogs/tent-fixes.yml diff --git a/code/game/objects/items/camping.dm b/code/game/objects/items/camping.dm index 5dd66b6e1be..6661ace8e8e 100644 --- a/code/game/objects/items/camping.dm +++ b/code/game/objects/items/camping.dm @@ -21,21 +21,27 @@ . = ..() var/list/roofs = list() for(var/obj/structure/component/tent_canvas/C in grouped_structures) + var/perspective_fix = FALSE // Used to make E/W facing even tents have similar perspective to odd ones if(dir & (NORTH | SOUTH)) if(C.x == x1 || C.x == x2) - C.icon_state = "canvas_dir" + C.icon_state = "canvas_[get_location(C)]" var/mid = Mean(x1, x2) if(C.x < mid) C.dir = WEST else C.dir = EAST else + var/width = y2 - y1 if(C.y == y1 || C.y == y2) - C.icon_state = "canvas_dir" + C.icon_state = "canvas_[get_location(C)]" + if(C.y == y2) //Upper wall + C.layer = ABOVE_TILE_LAYER var/mid = Mean(y1, y2) if(C.y < mid) C.dir = SOUTH else + if(ISODD(width) && C.y == Ceil(mid)) // `width` is actually 1 less than the width, so we need to check if this is odd + perspective_fix = TRUE C.dir = NORTH var/obj/structure/component/tent_canvas/roof/roof = new /obj/structure/component/tent_canvas/roof(C.loc) roofs += roof @@ -43,7 +49,10 @@ roof.dir = C.dir if(decal && C.x == x1 && C.y == y1) roof.AddOverlays(overlay_image('icons/obj/item/tent_decals.dmi', decal, flags=RESET_COLOR)) - roof.icon_state = "roof_[get_roof_type(C)]" + roof.icon_state = "roof_[get_location(C)]" + if(perspective_fix) + roof.AddOverlays(overlay_image(roof.icon, "[roof.icon_state]_p")) + grouped_structures += roofs /datum/large_structure/tent/structure_entered(turf/entry_point, atom/movable/entering) @@ -65,27 +74,54 @@ roof_plane.alpha = 255 /** - * Determines roof state over each canvas structure - * Returns `edge` for structures on the edge of the tent, so they don't cover the walls - * Returns `mid` for structures in the centre of the tent, for odd number widths + * Determines the state to use for each section of the tent + * Returns `edge` for structures on the edge of the tent + * Returns `entrance_top` for structures acting as an entrance, at the north/east of the tent + * Returns `entrance_bot` for structures acting as an entrance, at the south/west of the tent + * Returns `edge_entrance_top` for structures on the edge of the tent, and acting as an entrance, at the north/east of the tent + * Returns `edge_entrance_bot` for structures on the edge of the tent, and acting as an entrance, at the south/west of the tent + * Returns `mid` for structures in the exact centre of the tent, for odd number widths + * Returns `mid_entrance_top` for structures in the exact centre of the tent, for odd number widths, acting as an entrance, at the north/east of the tent + * Returns `mid_entrance_bot` for structures in the exact centre of the tent, for odd number widths, acting as an entrance, at the south/west of the tent * Otherwise returns `norm` for other structures */ -/datum/large_structure/tent/proc/get_roof_type(var/obj/structure/component/tent_canvas/canvas) +/datum/large_structure/tent/proc/get_location(var/obj/structure/component/tent_canvas/canvas) var/edge1 var/edge2 - var/axis + var/side_coord + var/top_coord + var/top_edge + var/bot_edge if(dir & (NORTH | SOUTH)) edge1 = x1 edge2 = x2 - axis = canvas.x + side_coord = canvas.x + top_edge = y2 + bot_edge = y1 + top_coord = canvas.y else edge1 = y1 edge2 = y2 - axis = canvas.y - if(axis == edge1 || axis == edge2) + side_coord = canvas.y + top_edge = x2 + bot_edge = x1 + top_coord = canvas.x + if(side_coord == edge1 || side_coord == edge2) + if(top_coord == top_edge) + return "edge_entrance_top" + else if(top_coord == bot_edge) + return "edge_entrance_bot" return "edge" - else if(axis == Mean(edge1, edge2)) + else if(side_coord == Mean(edge1, edge2)) + if(top_coord == top_edge) + return "mid_entrance_top" + else if(top_coord == bot_edge) + return "mid_entrance_bot" return "mid" + else if(top_coord == top_edge) + return "entrance_top" + else if(top_coord == bot_edge) + return "entrance_bot" return "norm" /obj/item/tent @@ -191,6 +227,8 @@ /obj/structure/component/tent_canvas name = "tent canvas" + desc = "The fabric and poles which make up the wall of a tent. Not air-tight, but able to keep out the weather, and very cozy." + desc_info = "Drag this to yourself to begin disassembly. This will take some time, in 4 stages. Others can start working on the other stages by dragging it, or other sections, to themselves as well." icon = 'icons/obj/item/camping.dmi' icon_state = "canvas" item_state = "canvas" @@ -202,7 +240,7 @@ /obj/structure/component/tent_canvas/CanPass(atom/movable/mover, turf/target, height, air_group) . = ..() - if(icon_state == "canvas") + if(icon_state in list("canvas", "canvas_mid", "canvas_entrance_top", "canvas_entrace_bot")) return TRUE //Non-directional, always allow passage if(get_dir(loc, target) & dir) return !density @@ -210,7 +248,7 @@ /obj/structure/component/tent_canvas/CheckExit(atom/movable/O, turf/target) . = ..() - if(icon_state == "canvas") + if(icon_state in list("canvas", "canvas_mid", "canvas_entrance_top", "canvas_entrace_bot")) return TRUE //Non-directional, always allow passage if(get_dir(O.loc, target) & dir) return !density @@ -218,13 +256,26 @@ /obj/structure/component/tent_canvas/MouseDrop(over_object, src_location, over_location) ..() - if(use_check(usr) || !Adjacent(usr)) + if(use_check(usr, USE_ALLOW_NON_ADJACENT) || (get_dist(usr, src) > 1)) // use_check() can't check for adjacency due to density issues, so we check range as well return part_of.disassemble(2 SECONDS, usr, src) +/obj/structure/component/tent_canvas/Destroy() //When we're destroyed, make sure we return the roof plane to anyone inside + for(var/mob/M in loc) + var/atom/movable/renderer/roofs/roof_plane = M.renderers["[ROOF_PLANE]"] + if(roof_plane) + roof_plane.alpha = 255 + return ..() + /obj/structure/component/tent_canvas/roof plane = ROOF_PLANE +/obj/structure/component/tent_canvas/roof/CanPass(atom/movable/mover, turf/target, height, air_group) + return TRUE + +/obj/structure/component/tent_canvas/roof/CheckExit(atom/movable/O, turf/target) + return TRUE + //Pre-fabricated tents for mapping /obj/effect/tent name = "Pre-frabricated expedition tent" @@ -240,6 +291,8 @@ tent_item.setup_my_tent(dir, get_turf(src)) tent.get_target_turfs(null, TRUE) tent.build_structures() + for(var/stage in tent.stages) + tent.stages[stage] = STAGE_ASSEMBLED qdel(tent_item) qdel(src) diff --git a/code/game/objects/structures/large.dm b/code/game/objects/structures/large.dm index 8bb9d198ea3..4cf789c827c 100644 --- a/code/game/objects/structures/large.dm +++ b/code/game/objects/structures/large.dm @@ -78,6 +78,7 @@ stages[stage_to_do] = STAGE_PROGRESS if(!do_after(user, time_per_structure * LAZYLEN(target_turfs))) stages[stage_to_do] = STAGE_DISASSEMBLED + interacting -= user return user.visible_message(SPAN_NOTICE("\The [user] finishes assembling the [stage_to_do].")) stages[stage_to_do] = STAGE_ASSEMBLED @@ -127,6 +128,7 @@ stages[stage_to_do] = STAGE_PROGRESS if(!do_after(user, time_per_structure * LAZYLEN(grouped_structures))) stages[stage_to_do] = STAGE_ASSEMBLED + interacting -= user return FALSE user.visible_message(SPAN_NOTICE("\The [user] finishes disassembling the [stage_to_do].")) stages[stage_to_do] = STAGE_DISASSEMBLED @@ -147,7 +149,7 @@ return TRUE /datum/large_structure/proc/structure_entered(var/turf/entry_point, var/atom/movable/entering) - if(!isliving(entering)) + if(!(isliving(entering) || isobserver(entering))) return FALSE RegisterSignal(entering, COMSIG_MOVABLE_MOVED, PROC_REF(mob_moved), override = TRUE) return TRUE diff --git a/html/changelogs/tent-fixes.yml b/html/changelogs/tent-fixes.yml new file mode 100644 index 00000000000..9fa1c012cf9 --- /dev/null +++ b/html/changelogs/tent-fixes.yml @@ -0,0 +1,12 @@ +author: Sparky_hotdog + +delete-after: True + +changes: + - bugfix: "Fixed tents not allowing assembly/disassembly by someone who was interrupted." + - bugfix: "Fixed tents having invisible walls inside of them." + - bugfix: "Fixed ghosts being unable to see inside tents." + - bugfix: "Fixed tent sprites to be 3/4th compliant." + - bugfix: "Fixed tent roofs not disappering when you disassemble one you are inside of." + - bugfix: "Fixed tent canvas not having a description." + - bugfix: "Fixed pre-fabricated tents not being disassembleable." diff --git a/icons/obj/item/camping.dmi b/icons/obj/item/camping.dmi index 0f3a84ea3053d628d050d7cf09d96eb93679fecb..234de453729c790fd88b1c3a4ddcc07d3a03c145 100644 GIT binary patch literal 8612 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 literal 4984 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