diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm index 12a671b4640..6963adae5dc 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 67d580dc245..e6b5479e31f 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -947,4 +947,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 9b006ee27fc..825459b8f46 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 index ba1f7d6c60b..0c20190d423 100644 --- a/code/game/objects/structures/wall_frame.dm +++ b/code/game/objects/structures/wall_frame.dm @@ -11,6 +11,7 @@ //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 @@ -71,34 +72,20 @@ else to_chat(user, "It's nearly falling to pieces.") -/obj/structure/low_wall/attackby(var/obj/item/W, var/mob/user) +/obj/structure/low_wall/attackby(var/obj/item/W, var/mob/user, var/hit_modifier, var/click_parameters) src.add_fingerprint(user) - //grille placing + // Making grilles (only works on Bay ones currently) if(istype(W, /obj/item/stack/rods)) - 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 - var/obj/item/stack/rods/ST = W - if(ST.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, 10, ST, exclusive = TASK_ALL_EXCLUSIVE)) - return - if(!ST.use(2)) - return - new /obj/structure/grille/bay(loc) + handle_rod_use(user, W) return - - //window placing // TODO + + // Making windows, different per subtype else if(istype(W, /obj/item/stack/material/glass)) - new /obj/structure/window/bay(loc, SOUTHWEST, TRUE) - + 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)) @@ -112,25 +99,90 @@ if(do_after(user, 40, src)) to_chat(user, "You dissasembled the low wall!") dismantle() - /* TODO - else if(istype(W, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = W - if(!cutter.slice(user)) - return - playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) - to_chat(user, "Now slicing through the low wall...") - if(do_after(user, 20,src)) - to_chat(user, "You have sliced through 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/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/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 1 + return TRUE if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 + return TRUE + return FALSE // Bay's version /obj/structure/low_wall/bay/update_icon() @@ -198,8 +250,24 @@ 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() - new /obj/item/stack/material/steel(get_turf(src), 3) + 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) /** @@ -213,6 +281,17 @@ /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 @@ -221,6 +300,17 @@ /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 */ diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm index 83cf22271df..09210fc4c8c 100644 --- a/code/modules/materials/materials/_materials.dm +++ b/code/modules/materials/materials/_materials.dm @@ -358,8 +358,13 @@ 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) ) + if(icon_base == "solid") + recipes += list( + 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), + 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) + ) if(hardness>50) recipes += list( diff --git a/code/modules/materials/materials/glass.dm b/code/modules/materials/materials/glass.dm index dd1f09821e9..1bfffff501a 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 0c436efded2..8146980057f 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/materials/materials/metals/steel.dm b/code/modules/materials/materials/metals/steel.dm index ca63d24b9c5..284ffb48e5f 100644 --- a/code/modules/materials/materials/metals/steel.dm +++ b/code/modules/materials/materials/metals/steel.dm @@ -60,6 +60,10 @@ new /datum/stack_recipe("tall filing cabinet", /obj/structure/filingcabinet/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), new /datum/stack_recipe("chest drawer", /obj/structure/filingcabinet/chestdrawer, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), )), + new /datum/stack_recipe_list("low walls",list( + new /datum/stack_recipe("low wall (bay style)", /obj/structure/low_wall/bay, 3, 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, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]") + )), new /datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), new /datum/stack_recipe("bench frame", /obj/structure/table/bench, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), new /datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 6cbf77cd990..349624eb786 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 55d01276612..f4280338489 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