diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm index 12a671b464..6963adae5d 100644 --- a/code/__defines/materials.dm +++ b/code/__defines/materials.dm @@ -3,6 +3,9 @@ #define MAT_STEEL "steel" #define MAT_PLASTIC "plastic" #define MAT_GLASS "glass" +#define MAT_RGLASS "rglass" +#define MAT_PGLASS "borosilicate glass" +#define MAT_RPGLASS "reinforced borosilicate glass" #define MAT_SILVER "silver" #define MAT_GOLD "gold" #define MAT_URANIUM "uranium" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8480b901a0..17d5689784 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -949,4 +949,42 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. /// How are you described if at all when in pockets (or other 'usually not visible' places) /obj/item/proc/pocket_description(mob/haver, mob/examiner) return null // most things are hidden - \ No newline at end of file + +#define CELLS 8 //Amount of cells per row/column in grid +#define CELLSIZE (world.icon_size/CELLS) //Size of a cell in pixels +/* +Automatic alignment of items to an invisible grid, defined by CELLS and CELLSIZE. +Since the grid will be shifted to own a cell that is perfectly centered on the turf, we end up with two 'cell halves' +on edges of each row/column. +Each item defines a center_of_mass, which is the pixel of a sprite where its projected center of mass toward a turf +surface can be assumed. For a piece of paper, this will be in its center. For a bottle, it will be (near) the bottom +of the sprite. +auto_align() will then place the sprite so the defined center_of_mass is at the bottom left corner of the grid cell +closest to where the cursor has clicked on. +Note: This proc can be overwritten to allow for different types of auto-alignment. +*/ + +/obj/item/var/list/center_of_mass = list("x" = 16,"y" = 16) + +/proc/auto_align(obj/item/W, click_parameters) + if(!W.center_of_mass) + W.randpixel_xy() + return + + if(!click_parameters) + return + + var/list/mouse_control = params2list(click_parameters) + + var/mouse_x = text2num(mouse_control["icon-x"]) + var/mouse_y = text2num(mouse_control["icon-y"]) + + if(isnum(mouse_x) && isnum(mouse_y)) + var/cell_x = max(0, min(CELLS-1, round(mouse_x/CELLSIZE))) + var/cell_y = max(0, min(CELLS-1, round(mouse_y/CELLSIZE))) + + W.pixel_x = (CELLSIZE * (0.5 + cell_x)) - W.center_of_mass["x"] + W.pixel_y = (CELLSIZE * (0.5 + cell_y)) - W.center_of_mass["y"] + +#undef CELLS +#undef CELLSIZE \ No newline at end of file diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 9b006ee27f..825459b8f4 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -15,6 +15,7 @@ var/datum/material/reinf_material var/reinforcing = 0 var/applies_material_colour = 1 + var/wall_type = /turf/simulated/wall /obj/structure/girder/New(var/newloc, var/material_key) ..(newloc) @@ -249,7 +250,7 @@ wall_fake = 1 var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall) + Tsrc.ChangeTurf(wall_type) var/turf/simulated/wall/T = get_turf(src) T.set_material(M, reinf_material, girder_material) if(wall_fake) @@ -397,7 +398,7 @@ if(RCD_FLOORWALL) to_chat(user, span("notice", "You finish a wall.")) // This is mostly the same as using on a floor. The girder's material is preserved, however. - T.ChangeTurf(/turf/simulated/wall) + T.ChangeTurf(wall_type) var/turf/simulated/wall/new_T = get_turf(src) // Ref to the wall we just built. // Apparently set_material(...) for walls requires refs to the material singletons and not strings. // This is different from how other material objects with their own set_material(...) do it, but whatever. @@ -412,3 +413,9 @@ qdel(src) return TRUE +/obj/structure/girder/bay + wall_type = /turf/simulated/wall/bay + +/obj/structure/girder/eris + wall_type = /turf/simulated/wall/eris + \ No newline at end of file diff --git a/code/game/objects/structures/wall_frame.dm b/code/game/objects/structures/wall_frame.dm new file mode 100644 index 0000000000..863dd997a2 --- /dev/null +++ b/code/game/objects/structures/wall_frame.dm @@ -0,0 +1,623 @@ +// Basically see-through walls. Used for windows +// If nothing has been built on the low wall, you can climb on it + +/obj/structure/low_wall + name = "low wall" + desc = "A low wall section which serves as the base of windows, amongst other things." + layer = TURF_LAYER + icon = null + icon_state = "frame" + + //atom_flags = ATOM_FLAG_NO_TEMP_CHANGE | ATOM_FLAG_CLIMBABLE | ATOM_FLAG_CAN_BE_PAINTED | ATOM_FLAG_ADJACENT_EXCEPTION + anchored = TRUE + density = TRUE + climbable = TRUE + throwpass = 1 + layer = TABLE_LAYER + + var/icon/frame_masks = 'icons/obj/wall_frame_bay.dmi' + + var/health = 100 + var/stripe_color + //rad_resistance_modifier = 0.5 + + // blend_objects defined on subtypes + noblend_objects = list(/obj/machinery/door/window) + + var/default_material = DEFAULT_WALL_MATERIAL + var/datum/material/material + var/grille_type + +/obj/structure/low_wall/Initialize(var/mapload, var/materialtype) + . = ..() + icon_state = "blank" + var/turf/T = loc + if(!isturf(T) || T.density || T.opacity) + warning("[src] on invalid turf [T] at [x],[y],[z]") + return INITIALIZE_HINT_QDEL + + if(!materialtype) + materialtype = default_material + + material = get_material_by_name(materialtype) + + health = material.integrity + + return INITIALIZE_HINT_LATELOAD + +/obj/structure/low_wall/LateInitialize() + . = ..() + update_connections(1) + update_icon() + +/obj/structure/low_wall/Destroy() + var/turf/location = loc + . = ..() + for(var/obj/structure/low_wall/W in orange(1, location)) + W.update_connections() + W.update_icon() + + +/obj/structure/low_wall/examine(mob/user) + . = ..() + + if(health == material.integrity) + to_chat(user, "It seems to be in fine condition.") + else + var/dam = health / material.integrity + if(dam <= 0.3) + to_chat(user, "It's got a few dents and scratches.") + else if(dam <= 0.7) + to_chat(user, "A few pieces of panelling have fallen off.") + else + to_chat(user, "It's nearly falling to pieces.") + +/obj/structure/low_wall/attackby(var/obj/item/W, var/mob/user, var/hit_modifier, var/click_parameters) + src.add_fingerprint(user) + + // Making grilles (only works on Bay ones currently) + if(istype(W, /obj/item/stack/rods)) + handle_rod_use(user, W) + return + + // Making windows, different per subtype + else if(istype(W, /obj/item/stack/material/glass)) + handle_glass_use(user, W) + return + + // Dismantling the half wall + if(W.is_wrench()) + for(var/obj/structure/S in loc) + if(istype(S, /obj/structure/window)) + to_chat(user, "There is still a window on the low wall!") + return + else if(istype(S, /obj/structure/grille)) + to_chat(user, "There is still a grille on the low wall!") + return + playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) + to_chat(user, "Now disassembling the low wall...") + if(do_after(user, 40, src)) + to_chat(user, "You dissasembled the low wall!") + dismantle() + + // Handle placing things + if(isrobot(user)) + return + + if(W.loc != user) // This should stop mounted modules ending up outside the module. + return + + if(can_place_items() && user.unEquip(W, 0, src.loc) && user.is_preference_enabled(/datum/client_preference/precision_placement)) + auto_align(W, click_parameters) + return 1 + + return ..() + +/obj/structure/low_wall/proc/can_place_items() + for(var/obj/structure/S in loc) + if(S == src) + continue + if(S.density) + return FALSE + return TRUE + +/obj/structure/low_wall/MouseDrop_T(obj/O as obj, mob/user as mob) + if(istype(O, /obj/structure/window)) + var/obj/structure/window/W = O + if(Adjacent(W) && !W.anchored) + to_chat("You hoist [W] up onto [src].") + W.forceMove(loc) + return + if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) + return ..() + if(isrobot(user)) + return + if(can_place_items()) + user.unEquip(O, 0, src.loc) + +/obj/structure/low_wall/proc/handle_rod_use(mob/user, obj/item/stack/rods/R) + if(!grille_type) + to_chat(user, "This type of wall frame doesn't support grilles.") + return + for(var/obj/structure/window/WINDOW in loc) + if(WINDOW.dir == get_dir(src, user)) + to_chat(user, "There is a window in the way.") + return + if(R.get_amount() < 2) + to_chat(user, "You need at least two rods to do this.") + return + to_chat(user, "Assembling grille...") + if(!do_after(user, 1 SECONDS, R, exclusive = TASK_ALL_EXCLUSIVE)) + return + if(!R.use(2)) + return + new grille_type(loc) + return + +/obj/structure/low_wall/proc/handle_glass_use(mob/user, obj/item/stack/material/glass/G) + var/window_type = get_window_build_type(user, G) + if(!window_type) + to_chat(user, "You can't build that type of window on this type of low wall.") + return + for(var/obj/structure/window/WINDOW in loc) + if(WINDOW.dir == get_dir(src, user)) + to_chat(user, "There is already a window here.") + return + if(G.get_amount() < 4) + to_chat(user, "You need at least four sheets of glass to do this.") + return + to_chat(user, "Assembling window...") + if(!do_after(user, 4 SECONDS, G, exclusive = TASK_ALL_EXCLUSIVE)) + return + if(!G.use(2)) + return + new window_type(loc, null, TRUE) + return + +/obj/structure/low_wall/proc/get_window_build_type(mob/user, obj/item/stack/material/glass/G) + return null + +/obj/structure/low_wall/CanPass(atom/movable/mover, turf/target) + if(istype(mover,/obj/item/projectile)) + return TRUE + if(istype(mover) && mover.checkpass(PASSTABLE)) + return TRUE + return FALSE + +// Bay's version +/obj/structure/low_wall/bay/update_icon() + cut_overlays() + + var/image/I + var/main_color = material.icon_colour + for(var/i = 1 to 4) + if(other_connections[i] != "0") + I = image(icon, "frame_other[other_connections[i]]", dir = 1<<(i-1)) + I.color = main_color + else + I = image(icon, "frame[connections[i]]", dir = 1<<(i-1)) + I.color = main_color + add_overlay(I) + + if(stripe_color) + for(var/i = 1 to 4) + if(other_connections[i] != "0") + I = image(icon, "stripe_other[other_connections[i]]", dir = 1<<(i-1)) + else + I = image(icon, "stripe[connections[i]]", dir = 1<<(i-1)) + I.color = stripe_color + add_overlay(I) + +// Eris's version +/obj/structure/low_wall/eris/update_icon() + cut_overlays() + + var/image/I + var/main_color = material.icon_colour + for(var/i = 1 to 4) + I = image(icon, "frame[connections[i]]", dir = 1<<(i-1)) + I.color = main_color + add_overlay(I) + + if(other_connections[i] != "0") + I = image(icon, "frame_other[other_connections[i]]", dir = 1<<(i-1)) + I.plane = ABOVE_OBJ_PLANE + I.layer = ABOVE_WINDOW_LAYER + I.color = main_color + add_overlay(I) + +/obj/structure/low_wall/bullet_act(var/obj/item/projectile/Proj) + var/proj_damage = Proj.get_structure_damage() + var/damage = min(proj_damage, 100) + take_damage(damage) + return + +/obj/structure/low_wall/hitby(AM as mob|obj, var/speed) + ..() + var/tforce = 0 + if(ismob(AM)) // All mobs have a multiplier and a size according to mob_defines.dm + var/mob/I = AM + tforce = I.mob_size * (speed/THROWFORCE_SPEED_DIVISOR) + else + var/obj/O = AM + tforce = O.throwforce * (speed/THROWFORCE_SPEED_DIVISOR) + if (tforce < 15) + return + take_damage(tforce) + +/obj/structure/low_wall/take_damage(damage) + health -= damage + if(health <= 0) + dismantle() + +/obj/structure/low_wall/attack_generic(var/mob/user, var/damage, var/attack_verb) + visible_message("[user] [attack_verb] the [src]!") + user.do_attack_animation(src) + take_damage(damage) + return ..() + +/obj/structure/low_wall/proc/dismantle() + var/stacktype = material?.stack_type + if(stacktype) + new stacktype(get_turf(src), 3) + // If we were violently dismantled + for(var/obj/structure/window/W in loc) + if(W.anchored) + W.shatter() + for(var/obj/structure/grille/G in loc) + if(G.anchored) + G.health = 0 + G.healthcheck() + qdel(src) + +/** + * The two 'real' types + */ +/obj/structure/low_wall/bay + icon = 'icons/obj/wall_frame_bay.dmi' + grille_type = /obj/structure/grille/bay + blend_objects = list(/obj/machinery/door, /turf/simulated/wall/bay) + +/obj/structure/low_wall/bay/reinforced + default_material = MAT_PLASTEEL + +/obj/structure/low_wall/bay/get_window_build_type(mob/user, obj/item/stack/material/glass/G) + switch(G.material.name) + if(MAT_GLASS) + return /obj/structure/window/bay + if(MAT_RGLASS) + return /obj/structure/window/bay/reinforced + if(MAT_PGLASS) + return /obj/structure/window/bay/phoronbasic + if(MAT_RPGLASS) + return /obj/structure/window/bay/phoronreinforced + +/obj/structure/low_wall/eris + icon = 'icons/obj/wall_frame_eris.dmi' + grille_type = null + blend_objects = list(/obj/machinery/door, /turf/simulated/wall/eris) + +/obj/structure/low_wall/eris/reinforced + default_material = MAT_PLASTEEL + +/obj/structure/low_wall/eris/get_window_build_type(mob/user, obj/item/stack/material/glass/G) + switch(G.material.name) + if(MAT_GLASS) + return /obj/structure/window/eris + if(MAT_RGLASS) + return /obj/structure/window/eris/reinforced + if(MAT_PGLASS) + return /obj/structure/window/eris/phoronbasic + if(MAT_RPGLASS) + return /obj/structure/window/eris/phoronreinforced + +/** + * Bay's fancier icon grilles + */ +/obj/structure/grille/bay + icon = 'icons/obj/bay_grille.dmi' + blend_objects = list(/obj/machinery/door, /turf/simulated/wall/bay) // Objects which to blend with + noblend_objects = list(/obj/machinery/door/window) + color = "#666666" + +/obj/structure/grille/bay/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/grille/bay/LateInitialize() + . = ..() + update_connections(1) + update_icon() + +/obj/structure/grille/bay/Destroy() + var/turf/location = loc + . = ..() + for(var/obj/structure/grille/G in orange(1, location)) + G.update_connections() + G.update_icon() + +/obj/structure/grille/bay/update_icon() + var/on_frame = locate(/obj/structure/low_wall/bay) in loc + + cut_overlays() + if(destroyed) + if(on_frame) + icon_state = "broke_onframe" + else + icon_state = "broken" + else + var/image/I + icon_state = "" + if(on_frame) + for(var/i = 1 to 4) + if(other_connections[i] != "0") + I = image(icon, "grille_other_onframe[connections[i]]", dir = 1<<(i-1)) + else + I = image(icon, "grille_onframe[connections[i]]", dir = 1<<(i-1)) + add_overlay(I) + else + for(var/i = 1 to 4) + if(other_connections[i] != "0") + I = image(icon, "grille_other[connections[i]]", dir = 1<<(i-1)) + else + I = image(icon, "grille[connections[i]]", dir = 1<<(i-1)) + add_overlay(I) + +/** + * The window types for both types of short walls + */ +/obj/structure/window/bay + icon = 'icons/obj/bay_window.dmi' + blend_objects = list(/obj/machinery/door, /turf/simulated/wall/bay) + noblend_objects = list(/obj/machinery/door/window) + icon_state = "preview_glass" + basestate = "window" + alpha = 180 + flags = 0 + fulltile = TRUE + maxhealth = 24 + glasstype = /obj/item/stack/material/glass + +/obj/structure/window/bay/Initialize() + . = ..() + var/obj/item/stack/material/glass/G = glasstype + var/datum/material/M = get_material_by_name(initial(G.default_type)) + color = M.icon_colour + return INITIALIZE_HINT_LATELOAD + +/obj/structure/window/bay/LateInitialize() + . = ..() + icon_state = "" + update_icon() + +/obj/structure/window/bay/update_icon() + cut_overlays() + if(!anchored) + connections = list("0","0","0","0") + other_connections = list("0","0","0","0") + else + update_connections() + + var/percent_damage = 0 // Used for icon state of damage layer + var/damage_alpha = 0 // Used for alpha blending of damage layer + if (maxhealth && health < maxhealth) + percent_damage = (maxhealth - health) / maxhealth // Percentage of damage received (Not health remaining) + percent_damage = round(percent_damage, 0.25) // Round to nearest multiple of 25 + damage_alpha = 256 * percent_damage - 1 + + var/img_dir + var/image/I + for(var/i = 1 to 4) + img_dir = 1<<(i-1) + if(other_connections[i] != "0") + I = image(icon, "[basestate]_other_onframe[other_connections[i]]", dir = img_dir) + I.color = color + else + I = image(icon, "[basestate]_onframe[connections[i]]", dir = img_dir) + I.color = color + add_overlay(I) + + if(damage_alpha) + var/image/D + D = image(icon, "window0_damage", dir = img_dir) + D.blend_mode = BLEND_MULTIPLY + D.alpha = damage_alpha + add_overlay(D) + +/obj/structure/window/bay/reinforced + name = "reinforced window" + desc = "It looks rather strong. Might take a few good hits to shatter it." + icon_state = "preview_rglass" + basestate = "rwindow" + maxhealth = 80 + reinf = 1 + maximal_heat = T0C + 750 + damage_per_fire_tick = 2.0 + glasstype = /obj/item/stack/material/glass/reinforced + force_threshold = 6 + +/obj/structure/window/bay/phoronbasic + name = "phoron window" + desc = "A borosilicate alloy window. It seems to be quite strong." + icon_state = "preview_phoron" + shardtype = /obj/item/weapon/material/shard/phoron + glasstype = /obj/item/stack/material/glass/phoronglass + maximal_heat = T0C + 2000 + damage_per_fire_tick = 1.0 + maxhealth = 40.0 + force_threshold = 5 + maxhealth = 80 + +/obj/structure/window/bay/phoronreinforced + name = "reinforced borosilicate window" + desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong." + icon_state = "preview_rphoron" + basestate = "rwindow" + shardtype = /obj/item/weapon/material/shard/phoron + glasstype = /obj/item/stack/material/glass/phoronrglass + reinf = 1 + maximal_heat = T0C + 4000 + damage_per_fire_tick = 1.0 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while. + maxhealth = 160 + force_threshold = 10 + + +/obj/structure/window/eris + icon = 'icons/obj/eris_window.dmi' + blend_objects = list(/obj/machinery/door, /turf/simulated/wall/eris) + noblend_objects = list(/obj/machinery/door/window) + icon_state = "preview_glass" + basestate = "window" + fulltile = TRUE + maxhealth = 24 + alpha = 150 + +/obj/structure/window/eris/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/window/eris/LateInitialize() + . = ..() + icon_state = "" + update_icon() + +/obj/structure/window/eris/update_icon() + cut_overlays() + if(!anchored) + connections = list("0","0","0","0") + other_connections = list("0","0","0","0") + else + update_connections() + + var/img_dir + var/image/I + for(var/i = 1 to 4) + img_dir = 1<<(i-1) + if(other_connections[i] != "0") + I = image(icon, "[basestate][other_connections[i]]", dir = img_dir) + else + I = image(icon, "[basestate][connections[i]]", dir = img_dir) + add_overlay(I) + +/obj/structure/window/eris/reinforced + name = "reinforced window" + desc = "It looks rather strong. Might take a few good hits to shatter it." + icon_state = "preview_rglass" + basestate = "rwindow" + maxhealth = 80 + reinf = 1 + maximal_heat = T0C + 750 + damage_per_fire_tick = 2.0 + glasstype = /obj/item/stack/material/glass/reinforced + force_threshold = 6 + +/obj/structure/window/eris/phoronbasic + name = "phoron window" + desc = "A borosilicate alloy window. It seems to be quite strong." + basestate = "preview_phoron" + icon_state = "pwindow" + shardtype = /obj/item/weapon/material/shard/phoron + glasstype = /obj/item/stack/material/glass/phoronglass + maximal_heat = T0C + 2000 + damage_per_fire_tick = 1.0 + maxhealth = 40.0 + force_threshold = 5 + maxhealth = 80 + +/obj/structure/window/eris/phoronreinforced + name = "reinforced borosilicate window" + desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong." + basestate = "preview_rphoron" + icon_state = "rpwindow" + shardtype = /obj/item/weapon/material/shard/phoron + glasstype = /obj/item/stack/material/glass/phoronrglass + reinf = 1 + maximal_heat = T0C + 4000 + damage_per_fire_tick = 1.0 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while. + maxhealth = 160 + force_threshold = 10 + +/** + * Spawner helpers for mapping these in + */ + +/obj/effect/low_wall_spawner + name = "low wall spawner" + + var/low_wall_type + var/window_type + var/grille_type + + icon = null + +/obj/effect/low_wall_spawner/Initialize() + . = ..() + if(locate(/obj/effect/low_wall_spawner) in oview(0, src)) + warning("Duplicate low wall spawners in [x],[y],[z]!") + return INITIALIZE_HINT_QDEL + + if(low_wall_type) + new low_wall_type(loc) + if(grille_type) + new grille_type(loc) + if(window_type) + new window_type(loc) + + return INITIALIZE_HINT_QDEL + +// Bay types +/obj/effect/low_wall_spawner/bay + icon = 'icons/obj/wall_frame_bay.dmi' + icon_state = "sp_glass" + low_wall_type = /obj/structure/low_wall/bay + window_type = /obj/structure/window/bay + +/obj/effect/low_wall_spawner/bay/rglass + icon_state = "sp_rglass" + window_type = /obj/structure/window/bay/reinforced + +/obj/effect/low_wall_spawner/bay/phoron + icon_state = "sp_phoron" + window_type = /obj/structure/window/bay/phoronbasic + +/obj/effect/low_wall_spawner/bay/rphoron + icon_state = "sp_rphoron" + window_type = /obj/structure/window/bay/phoronreinforced + +/obj/effect/low_wall_spawner/bay/grille + icon = 'icons/obj/wall_frame_bay.dmi' + icon_state = "sp_glass_g" + low_wall_type = /obj/structure/low_wall/bay + grille_type = /obj/structure/grille/bay + window_type = /obj/structure/window/bay + +/obj/effect/low_wall_spawner/bay/grille/rglass + icon_state = "sp_rglass_g" + window_type = /obj/structure/window/bay/reinforced + +/obj/effect/low_wall_spawner/bay/grille/phoron + icon_state = "sp_phoron_g" + window_type = /obj/structure/window/bay/phoronbasic + +/obj/effect/low_wall_spawner/bay/grille/rphoron + icon_state = "sp_rphoron_g" + window_type = /obj/structure/window/bay/phoronreinforced + +// Eris types +/obj/effect/low_wall_spawner/eris + icon = 'icons/obj/wall_frame_eris.dmi' + icon_state = "sp_glass" + low_wall_type = /obj/structure/low_wall/eris + window_type = /obj/structure/window/eris + +/obj/effect/low_wall_spawner/eris/rglass + icon_state = "sp_rglass" + window_type = /obj/structure/window/eris/reinforced + +/obj/effect/low_wall_spawner/eris/phoron + icon_state = "sp_phoron" + window_type = /obj/structure/window/eris/phoronbasic + +/obj/effect/low_wall_spawner/eris/rphoron + icon_state = "sp_rphoron" + window_type = /obj/structure/window/eris/phoronreinforced diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 12922d655a..a6f334a2f8 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -273,12 +273,14 @@ to_chat(user, "You have [state == 1 ? "un" : ""]fastened the window [state ? "from" : "to"] the frame.") else if(reinf && state == 0) anchored = !anchored + update_nearby_tiles(need_rebuild=1) update_nearby_icons() update_verbs() playsound(src, W.usesound, 75, 1) to_chat(user, "You have [anchored ? "" : "un"]fastened the frame [anchored ? "to" : "from"] the floor.") else if(!reinf) anchored = !anchored + update_nearby_tiles(need_rebuild=1) update_nearby_icons() update_verbs() playsound(src, W.usesound, 75, 1) diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index b6193f4942..3c9df506ae 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -51,30 +51,30 @@ var/image/I if(!density) - I = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open") + I = image(wall_masks, "[material.icon_base]fwall_open") I.color = material.icon_colour add_overlay(I) return for(var/i = 1 to 4) - I = image('icons/turf/wall_masks.dmi', "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1)) + I = image(wall_masks, "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1)) I.color = material.icon_colour add_overlay(I) if(reinf_material) if(construction_stage != null && construction_stage < 6) - I = image('icons/turf/wall_masks.dmi', "reinf_construct-[construction_stage]") + I = image(wall_masks, "reinf_construct-[construction_stage]") I.color = reinf_material.icon_colour add_overlay(I) else - if("[reinf_material.icon_reinf]0" in cached_icon_states('icons/turf/wall_masks.dmi')) + if("[reinf_material.icon_reinf]0" in cached_icon_states(wall_masks)) // Directional icon for(var/i = 1 to 4) - I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) + I = image(wall_masks, "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) I.color = reinf_material.icon_colour add_overlay(I) - else - I = image('icons/turf/wall_masks.dmi', reinf_material.icon_reinf) + else if("[reinf_material.icon_reinf]" in cached_icon_states(wall_masks)) + I = image(wall_masks, reinf_material.icon_reinf) I.color = reinf_material.icon_colour add_overlay(I) @@ -104,14 +104,18 @@ if(!material) return var/list/dirs = list() - for(var/turf/simulated/wall/W in orange(src, 1)) + var/inrange = orange(src, 1) + for(var/turf/simulated/wall/W in inrange) if(!W.material) continue if(propagate) W.update_connections() W.update_icon() - if(can_join_with(W)) + if(can_join_with_wall(W)) dirs += get_dir(src, W) + for(var/obj/structure/low_wall/WF in inrange) + if(can_join_with_low_wall(WF)) + dirs += get_dir(src, WF) if(material.icon_base == "hull") // Could be improved... var/additional_dirs = 0 @@ -127,8 +131,7 @@ wall_connections = dirs_to_corner_states(dirs) -/turf/simulated/wall/proc/can_join_with(var/turf/simulated/wall/W) - //VOREStation Edit Start +/turf/simulated/wall/proc/can_join_with_wall(var/turf/simulated/wall/W) //No blending if no material if(!material || !W.material) return 0 @@ -138,5 +141,7 @@ //Also blend if they have the same iconbase if(material.icon_base == W.material.icon_base) return 1 - //VOREStation Edit End return 0 + +/turf/simulated/wall/proc/can_join_with_low_wall(var/obj/structure/low_wall/WF) + return FALSE \ No newline at end of file diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index 880210c6f9..87d440f813 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -372,3 +372,44 @@ /obj/structure/hull_corner/long_horiz/get_dirs_to_test() return list(dir, turn(dir,90), turn(dir,-90)) + + + +// Eris walls +/turf/simulated/wall/eris + icon = 'icons/turf/wall_masks_eris.dmi' + icon_state = "generic" + wall_masks = 'icons/turf/wall_masks_eris.dmi' + +/turf/simulated/wall/eris/can_join_with_low_wall(var/obj/structure/low_wall/WF) + return istype(WF, /obj/structure/low_wall/eris) + +/turf/simulated/wall/eris/r_wall + icon_state = "rgeneric" +/turf/simulated/wall/eris/r_wall/Initialize(mapload) + . = ..(mapload, "plasteel","plasteel") + +// Bay walls +/turf/simulated/wall/bay + icon = 'icons/turf/wall_masks_bay.dmi' + icon_state = "generic" + wall_masks = 'icons/turf/wall_masks_bay.dmi' + + var/stripe_color // Adds a colored stripe to the walls + +/turf/simulated/wall/bay/can_join_with_low_wall(var/obj/structure/low_wall/WF) + return istype(WF, /obj/structure/low_wall/bay) + +/turf/simulated/wall/bay/update_icon() + . = ..() + if(stripe_color) + var/image/I + for(var/i = 1 to 4) + I = image(wall_masks, "stripe[wall_connections[i]]", dir = 1<<(i-1)) + I.color = stripe_color + add_overlay(I) + +/turf/simulated/wall/bay/r_wall + icon_state = "rgeneric" +/turf/simulated/wall/bay/r_wall/Initialize(mapload) + . = ..(mapload, "plasteel","plasteel") diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index be1605e0a9..d0bb6d5640 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -9,6 +9,7 @@ thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall + var/icon/wall_masks = 'icons/turf/wall_masks.dmi' var/damage = 0 var/damage_overlay = 0 var/global/damage_overlays[16] @@ -20,6 +21,7 @@ var/last_state var/construction_stage + // There's basically always going to be wall connections, making this lazy doesn't seem like it'd help much unless you wanted to make it bitflags instead. var/list/wall_connections = list("0", "0", "0", "0") // Walls always hide the stuff below them. diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm index 83cf22271d..07b1af73ff 100644 --- a/code/modules/materials/materials/_materials.dm +++ b/code/modules/materials/materials/_materials.dm @@ -358,9 +358,15 @@ var/list/name_to_material new /datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), new /datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), new /datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), - new /datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) + new /datum/stack_recipe("[display_name] wall girders (standard)", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] wall girders (bay)", /obj/structure/girder/bay, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) ) - + if(icon_base == "solid") // few icons + recipes += new /datum/stack_recipe("[display_name] wall girders (eris)", /obj/structure/girder/eris, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) + recipes += new /datum/stack_recipe_list("low walls",list( + new /datum/stack_recipe("low wall (bay style)", /obj/structure/low_wall/bay, 3, time = 20, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]"), + new /datum/stack_recipe("low wall (eris style)", /obj/structure/low_wall/eris, 3, time = 20, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]") + )) if(hardness>50) recipes += list( new /datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), diff --git a/code/modules/materials/materials/glass.dm b/code/modules/materials/materials/glass.dm index dd1f09821e..1bfffff501 100644 --- a/code/modules/materials/materials/glass.dm +++ b/code/modules/materials/materials/glass.dm @@ -1,5 +1,5 @@ /datum/material/glass - name = "glass" + name = MAT_GLASS stack_type = /obj/item/stack/material/glass flags = MATERIAL_BRITTLE icon_colour = "#00E1FF" @@ -94,7 +94,7 @@ return (hardness > 35) //todo /datum/material/glass/reinforced - name = "rglass" + name = MAT_RGLASS display_name = "reinforced glass" stack_type = /obj/item/stack/material/glass/reinforced flags = MATERIAL_BRITTLE @@ -114,7 +114,7 @@ rod_product = null /datum/material/glass/phoron - name = "borosilicate glass" + name = MAT_PGLASS display_name = "borosilicate glass" stack_type = /obj/item/stack/material/glass/phoronglass flags = MATERIAL_BRITTLE @@ -128,7 +128,7 @@ rod_product = /obj/item/stack/material/glass/phoronrglass /datum/material/glass/phoron/reinforced - name = "reinforced borosilicate glass" + name = MAT_RPGLASS display_name = "reinforced borosilicate glass" stack_type = /obj/item/stack/material/glass/phoronrglass stack_origin_tech = list(TECH_MATERIAL = 5) diff --git a/code/modules/materials/materials/metals/plasteel.dm b/code/modules/materials/materials/metals/plasteel.dm index 0c436efded..8146980057 100644 --- a/code/modules/materials/materials/metals/plasteel.dm +++ b/code/modules/materials/materials/metals/plasteel.dm @@ -1,5 +1,5 @@ /datum/material/plasteel - name = "plasteel" + name = MAT_PLASTEEL stack_type = /obj/item/stack/material/plasteel integrity = 400 melting_point = 6000 @@ -23,5 +23,9 @@ new /datum/stack_recipe("knife grip", /obj/item/weapon/material/butterflyhandle, 4, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]"), new /datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor/dark, 1, 4, 20, recycle_material = "[name]"), new /datum/stack_recipe("roller bed", /obj/item/roller, 5, time = 30, on_floor = 1, recycle_material = "[name]"), - new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10, recycle_material = "[name]") + new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10, recycle_material = "[name]"), + new /datum/stack_recipe_list("reinforced low walls",list( + new /datum/stack_recipe("reinforced low wall (bay style)", /obj/structure/low_wall/bay/reinforced, 3, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]"), + new /datum/stack_recipe("reinforced low wall (eris style)", /obj/structure/low_wall/eris/reinforced, 3, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]") + )), ) \ No newline at end of file diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 6cbf77cd99..349624eb78 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -142,44 +142,5 @@ auto_align(W, click_parameters) return 1 -#define CELLS 8 //Amount of cells per row/column in grid -#define CELLSIZE (world.icon_size/CELLS) //Size of a cell in pixels -/* -Automatic alignment of items to an invisible grid, defined by CELLS and CELLSIZE. -Since the grid will be shifted to own a cell that is perfectly centered on the turf, we end up with two 'cell halves' -on edges of each row/column. -Each item defines a center_of_mass, which is the pixel of a sprite where its projected center of mass toward a turf -surface can be assumed. For a piece of paper, this will be in its center. For a bottle, it will be (near) the bottom -of the sprite. -auto_align() will then place the sprite so the defined center_of_mass is at the bottom left corner of the grid cell -closest to where the cursor has clicked on. -Note: This proc can be overwritten to allow for different types of auto-alignment. -*/ - -/obj/item/var/list/center_of_mass = list("x" = 16,"y" = 16) - -/obj/structure/table/proc/auto_align(obj/item/W, click_parameters) - if(!W.center_of_mass) - W.randpixel_xy() - return - - if(!click_parameters) - return - - var/list/mouse_control = params2list(click_parameters) - - var/mouse_x = text2num(mouse_control["icon-x"]) - var/mouse_y = text2num(mouse_control["icon-y"]) - - if(isnum(mouse_x) && isnum(mouse_y)) - var/cell_x = max(0, min(CELLS-1, round(mouse_x/CELLSIZE))) - var/cell_y = max(0, min(CELLS-1, round(mouse_y/CELLSIZE))) - - W.pixel_x = (CELLSIZE * (0.5 + cell_x)) - W.center_of_mass["x"] - W.pixel_y = (CELLSIZE * (0.5 + cell_y)) - W.center_of_mass["y"] - -#undef CELLS -#undef CELLSIZE - /obj/structure/table/attack_tk() // no telehulk sorry return diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 55d0127661..f428033848 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -28,8 +28,6 @@ var/list/table_icon_cache = list() var/carpeted = 0 var/carpeted_type = /obj/item/stack/tile/carpet - var/item_place = 1 //allows items to be placed on the table, but not on benches. - /obj/structure/table/examine_icon() return icon(icon=initial(icon), icon_state=initial(icon_state)) //Basically the map preview version diff --git a/icons/obj/bay_grille.dmi b/icons/obj/bay_grille.dmi new file mode 100644 index 0000000000..759cec55b4 Binary files /dev/null and b/icons/obj/bay_grille.dmi differ diff --git a/icons/obj/bay_window.dmi b/icons/obj/bay_window.dmi new file mode 100644 index 0000000000..0cc8646beb Binary files /dev/null and b/icons/obj/bay_window.dmi differ diff --git a/icons/obj/eris_window.dmi b/icons/obj/eris_window.dmi new file mode 100644 index 0000000000..d588dd2f07 Binary files /dev/null and b/icons/obj/eris_window.dmi differ diff --git a/icons/obj/wall_frame_bay.dmi b/icons/obj/wall_frame_bay.dmi new file mode 100644 index 0000000000..cfe6ee2d56 Binary files /dev/null and b/icons/obj/wall_frame_bay.dmi differ diff --git a/icons/obj/wall_frame_eris.dmi b/icons/obj/wall_frame_eris.dmi new file mode 100644 index 0000000000..df4643219c Binary files /dev/null and b/icons/obj/wall_frame_eris.dmi differ diff --git a/icons/turf/wall_masks_bay.dmi b/icons/turf/wall_masks_bay.dmi new file mode 100644 index 0000000000..c30daaa21d Binary files /dev/null and b/icons/turf/wall_masks_bay.dmi differ diff --git a/icons/turf/wall_masks_eris.dmi b/icons/turf/wall_masks_eris.dmi new file mode 100644 index 0000000000..6780acaa0c Binary files /dev/null and b/icons/turf/wall_masks_eris.dmi differ diff --git a/vorestation.dme b/vorestation.dme index b5b5664afa..c46057ae61 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1565,6 +1565,7 @@ #include "code\game\objects\structures\trash_pile_vr.dm" #include "code\game\objects\structures\trash_pile_vr_ch.dm" #include "code\game\objects\structures\under_wardrobe.dm" +#include "code\game\objects\structures\wall_frame.dm" #include "code\game\objects\structures\watercloset.dm" #include "code\game\objects\structures\watercloset_vr.dm" #include "code\game\objects\structures\windoor_assembly.dm"