diff --git a/baystation12.dme b/baystation12.dme index a1074dc190..42f98251f3 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -629,7 +629,6 @@ #include "code\game\objects\items\weapons\stunbaton.dm" #include "code\game\objects\items\weapons\surgery_tools.dm" #include "code\game\objects\items\weapons\swords_axes_etc.dm" -#include "code\game\objects\items\weapons\table_rack_parts.dm" #include "code\game\objects\items\weapons\tape.dm" #include "code\game\objects\items\weapons\teleportation.dm" #include "code\game\objects\items\weapons\tools.dm" @@ -718,7 +717,6 @@ #include "code\game\objects\structures\noticeboard.dm" #include "code\game\objects\structures\safe.dm" #include "code\game\objects\structures\signs.dm" -#include "code\game\objects\structures\tables_racks.dm" #include "code\game\objects\structures\tank_dispenser.dm" #include "code\game\objects\structures\target_stake.dm" #include "code\game\objects\structures\transit_tubes.dm" @@ -1646,6 +1644,12 @@ #include "code\modules\surgery\robolimbs.dm" #include "code\modules\surgery\slimes.dm" #include "code\modules\surgery\surgery.dm" +#include "code\modules\tables\flipping.dm" +#include "code\modules\tables\interactions.dm" +#include "code\modules\tables\presets.dm" +#include "code\modules\tables\rack.dm" +#include "code\modules\tables\tables.dm" +#include "code\modules\tables\update_triggers.dm" #include "code\modules\vehicles\cargo_train.dm" #include "code\modules\vehicles\train.dm" #include "code\modules\vehicles\vehicle.dm" diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm index 630877eb11..fd239df50f 100644 --- a/code/game/gamemodes/cult/cultify/obj.dm +++ b/code/game/gamemodes/cult/cultify/obj.dm @@ -149,8 +149,12 @@ ..() /obj/structure/table/cultify() - new /obj/structure/table/woodentable(loc) - ..() + // Make it a wood-reinforced wooden table. + // There are cult materials available, but it'd make the table non-deconstructable with how holotables work. + // Could possibly use a new material var for holographic-ness? + material = name_to_material["wood"] + reinforced = name_to_material["wood"] + update_desc() + update_connections(1) + update_icon() -/obj/structure/table/woodentable/cultify() - return diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index a4d9e631e8..bbb8e32736 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -20,6 +20,7 @@ var/created_window = /obj/structure/window/basic var/is_reinforced = 0 var/list/construction_options = list("One Direction", "Full Window") + sheettype = "glass" /obj/item/stack/sheet/glass/cyborg name = "glass synthesizer" diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 46415bb8af..1e6fd887f5 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -134,6 +134,7 @@ obj/item/stack/sheet/mineral/iron/New() icon_state = "sheet-plastic" origin_tech = "materials=3" perunit = 2000 + sheettype = "plastic" /obj/item/stack/sheet/mineral/plastic/New() ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 1fefeca1ab..bf35253b08 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -31,8 +31,8 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \ ), 2), \ null, \ - new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts, 2), \ - new/datum/stack_recipe("rack parts", /obj/item/weapon/table_parts/rack), \ + new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("metal baseball bat", /obj/item/weapon/twohanded/baseballbat/metal, 10, time = 20, one_per_turf = 0, on_floor = 1), \ new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1), \ null, \ @@ -163,6 +163,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ singular_name = "wood plank" icon_state = "sheet-wood" origin_tech = "materials=1;biotech=1" + sheettype = "wood" /obj/item/stack/sheet/wood/cyborg name = "wood synthesizer" diff --git a/code/game/objects/items/weapons/table_rack_parts.dm b/code/game/objects/items/weapons/table_rack_parts.dm deleted file mode 100644 index 8437a5e29f..0000000000 --- a/code/game/objects/items/weapons/table_rack_parts.dm +++ /dev/null @@ -1,101 +0,0 @@ -// Table parts and rack parts - -/obj/item/weapon/table_parts - name = "table parts" - desc = "Parts of a table. Poor table." - gender = PLURAL - icon = 'icons/obj/items.dmi' - icon_state = "table_parts" - matter = list(DEFAULT_WALL_MATERIAL = 3750) - flags = CONDUCT - attack_verb = list("slammed", "bashed", "battered", "bludgeoned", "thrashed", "whacked") - - var/build_type = /obj/structure/table - var/alter_type = /obj/item/weapon/table_parts/reinforced - var/alter_with = /obj/item/stack/rods - var/alter_cost = 4 - var/list/stack_types = list(/obj/item/stack/sheet/metal) - -/obj/item/weapon/table_parts/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - for(var/material_type in stack_types) - new material_type(get_turf(user)) - qdel(src) - return - else - if(alter_type && alter_with && istype(W,alter_with)) - var/obj/item/stack/R = W - if (R.use(alter_cost)) - var/obj/item/new_parts = new alter_type (get_turf(loc)) - user << "You modify \the [name] into \a [new_parts]." - qdel(src) - else - user << "You need at least [alter_cost] sheets to reinforce the [name]." - return - ..() - -/obj/item/weapon/table_parts/attack_self(mob/user as mob) - if(locate(/obj/structure/table) in user.loc) - user << "There is already a table here." - return - - new build_type( user.loc ) - user.drop_item() - qdel(src) - return - -/obj/item/weapon/table_parts/reinforced - name = "reinforced table parts" - desc = "Hard table parts. Well... harder." - icon = 'icons/obj/items.dmi' - icon_state = "reinf_tableparts" - matter = list(DEFAULT_WALL_MATERIAL = 7500) - flags = CONDUCT - - stack_types = list(/obj/item/stack/sheet/metal, /obj/item/stack/rods) - build_type = /obj/structure/table/reinforced - alter_type = null - alter_with = null - alter_cost = null - -/obj/item/weapon/table_parts/wood - name = "wooden table parts" - desc = "Keep away from fire." - icon_state = "wood_tableparts" - flags = null - - stack_types = list(/obj/item/stack/sheet/wood) - build_type = /obj/structure/table/woodentable - alter_type = /obj/item/weapon/table_parts/gambling - alter_with = /obj/item/stack/tile/carpet - alter_cost = 1 - -/obj/item/weapon/table_parts/gambling - name = "gambling table parts" - desc = "Keep away from security." - icon_state = "gamble_tableparts" - flags = null - - stack_types = list(/obj/item/stack/tile/carpet,/obj/item/stack/sheet/wood) - build_type = /obj/structure/table/gamblingtable - alter_type = null - alter_with = null - alter_cost = null - -/obj/item/weapon/table_parts/gambling/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/crowbar)) - new /obj/item/stack/tile/carpet( get_turf(loc) ) - new /obj/item/weapon/table_parts/wood( get_turf(loc) ) - user << "You pry the carpet out of the table." - qdel(src) - ..() - -/obj/item/weapon/table_parts/rack - name = "rack parts" - desc = "Parts of a rack." - icon_state = "rack_parts" - stack_types = list(/obj/item/stack/sheet/metal) - build_type = /obj/structure/table/rack - alter_type = null - alter_with = null - alter_cost = null \ No newline at end of file diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm deleted file mode 100644 index f206bfc11f..0000000000 --- a/code/game/objects/structures/tables_racks.dm +++ /dev/null @@ -1,558 +0,0 @@ -// Tables and racks. - -/obj/structure/table - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "table" - density = 1 - anchored = 1 - layer = 2.8 - throwpass = 1 - climbable = 1 - breakable = 1 - parts = /obj/item/weapon/table_parts - - var/flipped = 0 - var/health = 100 - -/obj/structure/table/woodentable - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily." - icon_state = "wood_table" - parts = /obj/item/weapon/table_parts/wood - health = 50 - -/obj/structure/table/gamblingtable - name = "gambling table" - desc = "A curved wooden table with a thin carpet of green fabric." - icon_state = "gamble_table" - parts = /obj/item/weapon/table_parts/gambling - health = 50 - -/obj/structure/table/reinforced - icon_state = "reinf_table" - health = 200 - parts = /obj/item/weapon/table_parts/reinforced - -/obj/structure/table/rack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - health = 100 - parts = /obj/item/weapon/table_parts/rack - flipped = -1 //Cannot flip. - -/obj/structure/table/examine() - ..() - if(health > 100) - usr << "This one looks like it has been reinforced." - -/obj/structure/table/proc/update_adjacent() - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(locate(/obj/structure/table,get_step(src,direction))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - T.update_icon() - -/obj/structure/table/New() - ..() - for(var/obj/structure/table/T in src.loc) - if(T != src) - qdel(T) - update_icon() - update_adjacent() - -/obj/structure/table/Destroy() - update_adjacent() - ..() - -/obj/structure/table/update_icon() - - if(health > 100) - name = "reinforced [initial(name)]" - - spawn(2) //So it properly updates when deleting - - if(flipped == 1) - var/type = 0 - var/tabledirs = 0 - for(var/direction in list(turn(dir,90), turn(dir,-90)) ) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - if (T && T.flipped == 1 && T.dir == src.dir) - type++ - tabledirs |= direction - var/base = "table" - if (istype(src, /obj/structure/table/woodentable)) - base = "wood" - if (istype(src, /obj/structure/table/reinforced)) - base = "rtable" - - icon_state = "[base]flip[type]" - if (type==1) - if (tabledirs & turn(dir,90)) - icon_state = icon_state+"-" - if (tabledirs & turn(dir,-90)) - icon_state = icon_state+"+" - return 1 - - var/dir_sum = 0 - for(var/direction in list(1,2,4,8,5,6,9,10)) - var/skip_sum = 0 - for(var/obj/structure/window/W in src.loc) - if(W.dir == direction) //So smooth tables don't go smooth through windows - skip_sum = 1 - continue - var/inv_direction //inverse direction - switch(direction) - if(1) - inv_direction = 2 - if(2) - inv_direction = 1 - if(4) - inv_direction = 8 - if(8) - inv_direction = 4 - if(5) - inv_direction = 10 - if(6) - inv_direction = 9 - if(9) - inv_direction = 6 - if(10) - inv_direction = 5 - for(var/obj/structure/window/W in get_step(src,direction)) - if(W.dir == inv_direction) //So smooth tables don't go smooth through windows when the window is on the other table's tile - skip_sum = 1 - continue - if(!skip_sum) //means there is a window between the two tiles in this direction - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - if(T && T.flipped == 0) // This should let us ignore racks for table icons/flipping. Should. - if(direction <5) - dir_sum += direction - else - if(direction == 5) //This permits the use of all table directions. (Set up so clockwise around the central table is a higher value, from north) - dir_sum += 16 - if(direction == 6) - dir_sum += 32 - if(direction == 8) //Aherp and Aderp. Jezes I am stupid. -- SkyMarshal - dir_sum += 8 - if(direction == 10) - dir_sum += 64 - if(direction == 9) - dir_sum += 128 - - var/table_type = 0 //stand_alone table - if(dir_sum%16 in cardinal) - table_type = 1 //endtable - dir_sum %= 16 - if(dir_sum%16 in list(3,12)) - table_type = 2 //1 tile thick, streight table - if(dir_sum%16 == 3) //3 doesn't exist as a dir - dir_sum = 2 - if(dir_sum%16 == 12) //12 doesn't exist as a dir. - dir_sum = 4 - if(dir_sum%16 in list(5,6,9,10)) - if(locate(/obj/structure/table,get_step(src.loc,dir_sum%16))) - table_type = 3 //full table (not the 1 tile thick one, but one of the 'tabledir' tables) - else - table_type = 2 //1 tile thick, corner table (treated the same as streight tables in code later on) - dir_sum %= 16 - if(dir_sum%16 in list(13,14,7,11)) //Three-way intersection - table_type = 5 //full table as three-way intersections are not sprited, would require 64 sprites to handle all combinations. TOO BAD -- SkyMarshal - switch(dir_sum%16) //Begin computation of the special type tables. --SkyMarshal - if(7) - if(dir_sum == 23) - table_type = 6 - dir_sum = 8 - else if(dir_sum == 39) - dir_sum = 4 - table_type = 6 - else if(dir_sum == 55 || dir_sum == 119 || dir_sum == 247 || dir_sum == 183) - dir_sum = 4 - table_type = 3 - else - dir_sum = 4 - if(11) - if(dir_sum == 75) - dir_sum = 5 - table_type = 6 - else if(dir_sum == 139) - dir_sum = 9 - table_type = 6 - else if(dir_sum == 203 || dir_sum == 219 || dir_sum == 251 || dir_sum == 235) - dir_sum = 8 - table_type = 3 - else - dir_sum = 8 - if(13) - if(dir_sum == 29) - dir_sum = 10 - table_type = 6 - else if(dir_sum == 141) - dir_sum = 6 - table_type = 6 - else if(dir_sum == 189 || dir_sum == 221 || dir_sum == 253 || dir_sum == 157) - dir_sum = 1 - table_type = 3 - else - dir_sum = 1 - if(14) - if(dir_sum == 46) - dir_sum = 1 - table_type = 6 - else if(dir_sum == 78) - dir_sum = 2 - table_type = 6 - else if(dir_sum == 110 || dir_sum == 254 || dir_sum == 238 || dir_sum == 126) - dir_sum = 2 - table_type = 3 - else - dir_sum = 2 //These translate the dir_sum to the correct dirs from the 'tabledir' icon_state. - if(dir_sum%16 == 15) - table_type = 4 //4-way intersection, the 'middle' table sprites will be used. - - if(istype(src,/obj/structure/table/reinforced)) - switch(table_type) - if(0) - icon_state = "reinf_table" - if(1) - icon_state = "reinf_1tileendtable" - if(2) - icon_state = "reinf_1tilethick" - if(3) - icon_state = "reinf_tabledir" - if(4) - icon_state = "reinf_middle" - if(5) - icon_state = "reinf_tabledir2" - if(6) - icon_state = "reinf_tabledir3" - else if(istype(src,/obj/structure/table/woodentable)) - switch(table_type) - if(0) - icon_state = "wood_table" - if(1) - icon_state = "wood_1tileendtable" - if(2) - icon_state = "wood_1tilethick" - if(3) - icon_state = "wood_tabledir" - if(4) - icon_state = "wood_middle" - if(5) - icon_state = "wood_tabledir2" - if(6) - icon_state = "wood_tabledir3" - else if(istype(src,/obj/structure/table/gamblingtable)) - switch(table_type) - if(0) - icon_state = "gamble_table" - if(1) - icon_state = "gamble_1tileendtable" - if(2) - icon_state = "gamble_1tilethick" - if(3) - icon_state = "gamble_tabledir" - if(4) - icon_state = "gamble_middle" - if(5) - icon_state = "gamble_tabledir2" - if(6) - icon_state = "gamble_tabledir3" - else - switch(table_type) - if(0) - icon_state = "table" - if(1) - icon_state = "table_1tileendtable" - if(2) - icon_state = "table_1tilethick" - if(3) - icon_state = "tabledir" - if(4) - icon_state = "table_middle" - if(5) - icon_state = "tabledir2" - if(6) - icon_state = "tabledir3" - if (dir_sum in list(1,2,4,8,5,6,9,10)) - set_dir(dir_sum) - else - set_dir(2) - -/obj/structure/table/attack_tk() // no telehulk sorry - return - -/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - if(istype(mover,/obj/item/projectile)) - return (check_cover(mover,target)) - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - if(locate(/obj/structure/table) in get_turf(mover)) - return 1 - if (flipped == 1) - if (get_dir(loc, target) == dir) - return !density - else - return 1 - return 0 - -//checks if projectile 'P' from turf 'from' can hit whatever is behind the table. Returns 1 if it can, 0 if bullet stops. -/obj/structure/table/proc/check_cover(obj/item/projectile/P, turf/from) - var/turf/cover - if(flipped==1) - cover = get_turf(src) - else if(flipped==0) - cover = get_step(loc, get_dir(from, loc)) - if(!cover) - return 1 - if (get_dist(P.starting, loc) <= 1) //Tables won't help you if people are THIS close - return 1 - if (get_turf(P.original) == cover) - var/chance = 20 - if (ismob(P.original)) - var/mob/M = P.original - if (M.lying) - chance += 20 //Lying down lets you catch less bullets - if(flipped==1) - if(get_dir(loc, from) == dir) //Flipped tables catch mroe bullets - chance += 20 - else - return 1 //But only from one side - if(prob(chance)) - health -= P.damage/2 - if (health > 0) - visible_message("[P] hits \the [src]!") - return 0 - else - visible_message("[src] breaks down!") - qdel(src) - return 1 - return 1 - -/obj/structure/table/CheckExit(atom/movable/O as mob|obj, target as turf) - if(istype(O) && O.checkpass(PASSTABLE)) - return 1 - if (flipped==1) - if (get_dir(loc, target) == dir) - return !density - else - return 1 - return 1 - -/obj/structure/table/MouseDrop_T(obj/O as obj, mob/user as mob) - - if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) - return ..() - if(isrobot(user)) - return - user.drop_item() - if (O.loc != src.loc) - step(O, get_dir(O, src)) - return - - -/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob) - if (!W) return - - // Handle harm intent grabbing/tabling. - if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) - var/obj/item/weapon/grab/G = W - if (istype(G.affecting, /mob/living)) - var/mob/living/M = G.affecting - if (G.state < 2) - if(user.a_intent == I_HURT) - if (prob(15)) M.Weaken(5) - M.apply_damage(8,def_zone = "head") - visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") - playsound(src.loc, 'sound/weapons/tablehit1.ogg', 50, 1) - else - user << "You need a better grip to do that!" - return - else - G.affecting.loc = src.loc - G.affecting.Weaken(5) - visible_message("[G.assailant] puts [G.affecting] on \the [src].") - qdel(W) - return - - // Handle dissembly. - if (istype(W, /obj/item/weapon/wrench)) - if(health > 100) - user << "\The [src] is too well constructed to be collapsed. Weaken it first." - return - user << "You locate the bolts and begin disassembling \the [src]..." - playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) - if(do_after(user,50)) - qdel(src) - return - - // Handle weakening. - if (istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn()) - if(initial(health)>100) - if(WT.remove_fuel(0, user)) - if(src.health>100) - user << "You start weakening \the [src]..." - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - if(!do_after(user, 50) || !src || health<100 || !WT.isOn()) - return - user << "You have weakened \the [src]." - health -= 100 - else if(src.health <= 100) - user << "You start strengthening \the [src]..." - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - if(!do_after(user, 50) || !src || health > 100 || !WT.isOn()) - return - user << "You have strengthened \the [src]." - health += 100 - update_icon() - else - user << "\The [src] is too flimsy to be reinforced or weakened." - return - - - // Handle dismantling or placing things on the table from here on. - if(isrobot(user)) - return - - if(W.loc != user) // This should stop mounted modules ending up outside the module. - return - - if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user.visible_message("The [src] was sliced apart by [user]!") - qdel(src) - - user.drop_item(src.loc) - return - -/obj/structure/table/proc/straight_table_check(var/direction) - var/obj/structure/table/T - for(var/angle in list(-90,90)) - T = locate() in get_step(src.loc,turn(direction,angle)) - if(T && T.flipped == 0) - return 0 - T = locate() in get_step(src.loc,direction) - if (!T || T.flipped == 1) - return 1 - if (istype(T,/obj/structure/table/reinforced/)) - var/obj/structure/table/reinforced/R = T - if (R.health > 100) - return 0 - return T.straight_table_check(direction) - -/obj/structure/table/verb/do_flip() - set name = "Flip table" - set desc = "Flips a non-reinforced table" - set category = "Object" - set src in oview(1) - - if (!can_touch(usr) || ismouse(usr)) - return - - if(flipped < 0 || !flip(get_cardinal_dir(usr,src))) - usr << "It won't budge." - return - - usr.visible_message("[usr] flips \the [src]!") - - if(climbable) - structure_shaken() - - return - -/obj/structure/table/proc/unflipping_check(var/direction) - - for(var/mob/M in oview(src,0)) - return 0 - - var/obj/occupied = turf_is_crowded() - if(occupied) - usr << "There's \a [occupied] in the way." - return 0 - - var/list/L = list() - if(direction) - L.Add(direction) - else - L.Add(turn(src.dir,-90)) - L.Add(turn(src.dir,90)) - for(var/new_dir in L) - var/obj/structure/table/T = locate() in get_step(src.loc,new_dir) - if(T) - if(T.flipped == 1 && T.dir == src.dir && !T.unflipping_check(new_dir)) - return 0 - return 1 - -/obj/structure/table/proc/do_put() - set name = "Put table back" - set desc = "Puts flipped table back" - set category = "Object" - set src in oview(1) - - if (!can_touch(usr)) - return - - if (!unflipping_check()) - usr << "It won't budge." - return - unflip() - -/obj/structure/table/proc/flip(var/direction) - if( !straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90)) ) - return 0 - - verbs -=/obj/structure/table/verb/do_flip - verbs +=/obj/structure/table/proc/do_put - - var/list/targets = list(get_step(src,dir),get_step(src,turn(dir, 45)),get_step(src,turn(dir, -45))) - for (var/atom/movable/A in get_turf(src)) - if (!A.anchored) - spawn(0) - A.throw_at(pick(targets),1,1) - - set_dir(direction) - if(dir != NORTH) - layer = 5 - climbable = 0 //flipping tables allows them to be used as makeshift barriers - flipped = 1 - flags |= ON_BORDER - for(var/D in list(turn(direction, 90), turn(direction, -90))) - var/obj/structure/table/T = locate() in get_step(src,D) - if(T && T.flipped == 0) - T.flip(direction) - update_icon() - update_adjacent() - - return 1 - -/obj/structure/table/proc/unflip() - verbs -=/obj/structure/table/proc/do_put - verbs +=/obj/structure/table/verb/do_flip - - layer = initial(layer) - flipped = 0 - climbable = initial(climbable) - flags &= ~ON_BORDER - for(var/D in list(turn(dir, 90), turn(dir, -90))) - var/obj/structure/table/T = locate() in get_step(src.loc,D) - if(T && T.flipped == 1 && T.dir == src.dir) - T.unflip() - update_icon() - update_adjacent() - - return 1 - -// No need to handle any of this, racks are not contiguous.. -/obj/structure/table/rack/update_icon() - return -/obj/structure/table/rack/update_adjacent() - return \ No newline at end of file diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index b463ec4209..6e5c4c4c5a 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -1,5 +1,8 @@ // Holographic Items! +// Holographic tables are in code/modules/tables/presets.dm +// Holographic racks are in code/modules/tables/rack.dm + /turf/simulated/floor/holofloor/ thermal_conductivity = 0 @@ -40,36 +43,6 @@ return // HOLOFLOOR DOES NOT GIVE A FUCK -/obj/structure/table/holotable - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "table" - density = 1 - anchored = 1.0 - layer = 2.8 - throwpass = 1 //You can throw objects over this, despite it's density. - -/obj/structure/table/holotable/attack_hand(mob/user as mob) - return // HOLOTABLE DOES NOT GIVE A FUCK - - -/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - user << "It's a holotable! There are no bolts!" - return - - if(isrobot(user)) - return - - ..() - -/obj/structure/table/woodentable/holotable - name = "table" - desc = "A square piece of wood standing on four wooden legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "wood_table" - /obj/structure/holostool name = "stool" desc = "Apply butt." @@ -371,22 +344,6 @@ for(var/mob/M in currentarea) M << "FIGHT!" -//Holorack - -/obj/structure/table/rack/holorack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - -/obj/structure/table/rack/holorack/attack_hand(mob/user as mob) - return - -/obj/structure/table/rack/holorack/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - user << "It's a holorack! You can't unwrench it!" - return - //Holocarp /mob/living/simple_animal/hostile/carp/holodeck diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 04e8d485ba..55d51c772f 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -149,6 +149,14 @@ var/list/name_to_material stack_type = /obj/item/stack/sheet/mineral/iron icon_colour = "#5C5454" +/material/wood + name = "wood" + stack_type = /obj/item/stack/sheet/wood + icon_colour = "#824B28" + integrity = 25 + icon_base = "solid" + explosion_resistance = 2 + /material/cult name = "cult" display_name = "disturbing stone" @@ -167,4 +175,4 @@ var/list/name_to_material display_name = "human remains" /material/cult/reinf/place_dismantled_product(var/turf/target) - new /obj/effect/decal/remains/human(target) + new /obj/effect/decal/remains/human(target) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 5634cda9b6..7452514f17 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -17,8 +17,6 @@ /obj/item/weapon/module/power_control, /obj/item/weapon/stock_parts, /obj/item/frame, - /obj/item/weapon/table_parts, - /obj/item/weapon/table_parts/rack, /obj/item/weapon/camera_assembly, /obj/item/weapon/tank, /obj/item/weapon/circuitboard, diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index cc58a7ce1c..c04857e972 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -238,7 +238,7 @@ D.Open() else if(istype(A,/obj/structure/cult/pylon)) A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) - else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/table/rack)) + else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille)) A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) Move(T) FindTarget() diff --git a/code/modules/tables/flipping.dm b/code/modules/tables/flipping.dm new file mode 100644 index 0000000000..1714d390b4 --- /dev/null +++ b/code/modules/tables/flipping.dm @@ -0,0 +1,116 @@ + +/obj/structure/table/proc/straight_table_check(var/direction) + var/obj/structure/table/T + for(var/angle in list(-90,90)) + T = locate() in get_step(src.loc,turn(direction,angle)) + if(T && T.flipped == 0 && T.material == material) + return 0 + T = locate() in get_step(src.loc,direction) + if (!T || T.flipped == 1 || T.material != material) + return 1 + if(T.health > 100) + return 0 + return T.straight_table_check(direction) + +/obj/structure/table/verb/do_flip() + set name = "Flip table" + set desc = "Flips a non-reinforced table" + set category = "Object" + set src in oview(1) + + if (!can_touch(usr) || ismouse(usr)) + return + + if(flipped < 0 || !flip(get_cardinal_dir(usr,src))) + usr << "It won't budge." + return + + usr.visible_message("[usr] flips \the [src]!") + + if(climbable) + structure_shaken() + + return + +/obj/structure/table/proc/unflipping_check(var/direction) + + for(var/mob/M in oview(src,0)) + return 0 + + var/obj/occupied = turf_is_crowded() + if(occupied) + usr << "There's \a [occupied] in the way." + return 0 + + var/list/L = list() + if(direction) + L.Add(direction) + else + L.Add(turn(src.dir,-90)) + L.Add(turn(src.dir,90)) + for(var/new_dir in L) + var/obj/structure/table/T = locate() in get_step(src.loc,new_dir) + if(T && T.material == material) + if(T.flipped == 1 && T.dir == src.dir && !T.unflipping_check(new_dir)) + return 0 + return 1 + +/obj/structure/table/proc/do_put() + set name = "Put table back" + set desc = "Puts flipped table back" + set category = "Object" + set src in oview(1) + + if (!can_touch(usr)) + return + + if (!unflipping_check()) + usr << "It won't budge." + return + unflip() + +/obj/structure/table/proc/flip(var/direction) + if( !straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90)) ) + return 0 + + verbs -=/obj/structure/table/verb/do_flip + verbs +=/obj/structure/table/proc/do_put + + var/list/targets = list(get_step(src,dir),get_step(src,turn(dir, 45)),get_step(src,turn(dir, -45))) + for (var/atom/movable/A in get_turf(src)) + if (!A.anchored) + spawn(0) + A.throw_at(pick(targets),1,1) + + set_dir(direction) + if(dir != NORTH) + layer = 5 + climbable = 0 //flipping tables allows them to be used as makeshift barriers + flipped = 1 + flags |= ON_BORDER + for(var/D in list(turn(direction, 90), turn(direction, -90))) + var/obj/structure/table/T = locate() in get_step(src,D) + if(T && T.flipped == 0 && T.material == material && material) + T.flip(direction) + update_connections(1) + update_icon() + + return 1 + +/obj/structure/table/proc/unflip() + verbs -=/obj/structure/table/proc/do_put + verbs +=/obj/structure/table/verb/do_flip + + layer = initial(layer) + flipped = 0 + climbable = initial(climbable) + flags &= ~ON_BORDER + for(var/D in list(turn(dir, 90), turn(dir, -90))) + var/obj/structure/table/T = locate() in get_step(src.loc,D) + if(T && T.flipped == 1 && T.dir == src.dir && T.material == material && material) + T.unflip() + + update_connections(1) + update_icon() + + return 1 \ No newline at end of file diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm new file mode 100644 index 0000000000..4ada40596e --- /dev/null +++ b/code/modules/tables/interactions.dm @@ -0,0 +1,122 @@ + +/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group || (height==0)) return 1 + if(istype(mover,/obj/item/projectile)) + return (check_cover(mover,target)) + if(istype(mover) && mover.checkpass(PASSTABLE)) + return 1 + if(locate(/obj/structure/table) in get_turf(mover)) + return 1 + if (flipped == 1) + if (get_dir(loc, target) == dir) + return !density + else + return 1 + return 0 + +//checks if projectile 'P' from turf 'from' can hit whatever is behind the table. Returns 1 if it can, 0 if bullet stops. +/obj/structure/table/proc/check_cover(obj/item/projectile/P, turf/from) + var/turf/cover + if(flipped==1) + cover = get_turf(src) + else if(flipped==0) + cover = get_step(loc, get_dir(from, loc)) + if(!cover) + return 1 + if (get_dist(P.starting, loc) <= 1) //Tables won't help you if people are THIS close + return 1 + if (get_turf(P.original) == cover) + var/chance = 20 + if (ismob(P.original)) + var/mob/M = P.original + if (M.lying) + chance += 20 //Lying down lets you catch less bullets + if(flipped==1) + if(get_dir(loc, from) == dir) //Flipped tables catch mroe bullets + chance += 20 + else + return 1 //But only from one side + if(prob(chance)) + health -= P.damage/2 + if (health > 0) + visible_message("[P] hits \the [src]!") + return 0 + else + visible_message("[src] breaks down!") + break_to_parts() + return 1 + return 1 + +/obj/structure/table/CheckExit(atom/movable/O as mob|obj, target as turf) + if(istype(O) && O.checkpass(PASSTABLE)) + return 1 + if (flipped==1) + if (get_dir(loc, target) == dir) + return !density + else + return 1 + return 1 + + +/obj/structure/table/MouseDrop_T(obj/O as obj, mob/user as mob) + + if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) + return ..() + if(isrobot(user)) + return + user.drop_item() + if (O.loc != src.loc) + step(O, get_dir(O, src)) + return + + +/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob) + if (!W) return + + // Handle harm intent grabbing/tabling. + if(istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) + var/obj/item/weapon/grab/G = W + if (istype(G.affecting, /mob/living)) + var/mob/living/M = G.affecting + if (G.state < 2) + if(user.a_intent == I_HURT) + if (prob(15)) M.Weaken(5) + M.apply_damage(8,def_zone = "head") + visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") + playsound(src.loc, 'sound/weapons/tablehit1.ogg', 50, 1) + else + user << "You need a better grip to do that!" + return + else + G.affecting.loc = src.loc + G.affecting.Weaken(5) + visible_message("[G.assailant] puts [G.affecting] on \the [src].") + qdel(W) + return + + // Handle dismantling or placing things on the table from here on. + if(isrobot(user)) + return + + if(W.loc != user) // This should stop mounted modules ending up outside the module. + return + + if(istype(W, /obj/item/weapon/melee/energy/blade)) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src.loc) + spark_system.start() + playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) + playsound(src.loc, "sparks", 50, 1) + user.visible_message("\The [src] was sliced apart by [user]!") + break_to_parts() + return + + if(!material) + user << "There's nothing to put \the [W] on! Try adding plating to \the [src] first." + return + + user.drop_item(src.loc) + return + +/obj/structure/table/attack_tk() // no telehulk sorry + return diff --git a/code/modules/tables/presets.dm b/code/modules/tables/presets.dm new file mode 100644 index 0000000000..481897c48d --- /dev/null +++ b/code/modules/tables/presets.dm @@ -0,0 +1,110 @@ +var/global/material/material_holographic_steel = null +var/global/material/material_holographic_wood = null + +/obj/structure/table + + standard + icon_state = "plain_preview" + color = "#666666" + New() + material = name_to_material[DEFAULT_WALL_MATERIAL] + ..() + + reinforced + icon_state = "reinf_preview" + color = "#666666" + New() + material = name_to_material[DEFAULT_WALL_MATERIAL] + reinforced = name_to_material[DEFAULT_WALL_MATERIAL] + ..() + + woodentable + icon_state = "plain_preview" + color = "#824B28" + New() + material = name_to_material["wood"] + ..() + + gamblingtable + icon_state = "gamble_preview" + New() + material = name_to_material["wood"] + carpeted = 1 + ..() + + glass + icon_state = "plain_preview" + color = "#00E1FF" + alpha = 77 // 0.3 * 255 + New() + material = name_to_material["glass"] + ..() + + holotable + icon_state = "holo_preview" + color = "#666666" + New() + if(!material_holographic_steel) + material_holographic_steel = new /material/steel + material_holographic_steel.stack_type = null // Tables with null-stacktype materials cannot be deconstructed + material = material_holographic_steel + ..() + + woodentable/holotable + icon_state = "holo_preview" + New() + if(!material_holographic_wood) + material_holographic_wood = new /material/wood + material_holographic_wood.stack_type = null // Tables with null-stacktype materials cannot be deconstructed + material = material_holographic_wood + ..() + +/* + +/obj/structure/table/holotable + name = "table" + desc = "A square piece of metal standing on four metal legs. It can not move." + icon = 'icons/obj/structures.dmi' + icon_state = "table" + density = 1 + anchored = 1.0 + layer = 2.8 + throwpass = 1 //You can throw objects over this, despite it's density. + +/obj/structure/table/holotable/attack_hand(mob/user as mob) + return // HOLOTABLE DOES NOT GIVE A FUCK + + +/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/wrench)) + user << "It's a holotable! There are no bolts!" + return + + if(isrobot(user)) + return + + ..() + +/obj/structure/table/woodentable/holotable + name = "table" + desc = "A square piece of wood standing on four wooden legs. It can not move." + icon = 'icons/obj/structures.dmi' + icon_state = "wood_table" + + +/obj/structure/table/rack/holorack + name = "rack" + desc = "Different from the Middle Ages version." + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + +/obj/structure/table/rack/holorack/attack_hand(mob/user as mob) + return + +/obj/structure/table/rack/holorack/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/wrench)) + user << "It's a holorack! You can't unwrench it!" + return + + +*/ diff --git a/code/modules/tables/rack.dm b/code/modules/tables/rack.dm new file mode 100644 index 0000000000..bd3ee6ce55 --- /dev/null +++ b/code/modules/tables/rack.dm @@ -0,0 +1,26 @@ +/obj/structure/table/rack + name = "rack" + desc = "Different from the Middle Ages version." + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + can_plate = 0 + can_reinforce = 0 + flipped = -1 + +/obj/structure/table/rack/New() + ..() + verbs -= /obj/structure/table/verb/do_flip + verbs -= /obj/structure/table/proc/do_put + +/obj/structure/table/rack/update_connections() + return + +/obj/structure/table/rack/update_desc() + return + +/obj/structure/table/rack/update_icon() + return + +/obj/structure/table/rack/holorack/dismantle(obj/item/weapon/wrench/W, mob/user) + user << "You cannot dismantle \the [src]." + return diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm new file mode 100644 index 0000000000..1b389323f9 --- /dev/null +++ b/code/modules/tables/tables.dm @@ -0,0 +1,337 @@ + + +/obj/structure/table + name = "table frame" + icon = 'icons/obj/tables.dmi' + icon_state = "frame" + desc = "It's a table, for putting things on. Or standing on, if you really want to." + density = 1 + anchored = 1 + climbable = 1 + var/flipped = 0 + var/maxhealth = 10 + var/health = 10 + + // For racks. + var/can_reinforce = 1 + var/can_plate = 1 + + var/material/material = null + var/material/reinforced = null + + // Gambling tables. I'd prefer reinforced with carpet/felt/cloth/whatever, but AFAIK it's either harder or impossible to get /obj/item/stack/sheet of those. + // Convert if/when you can easily get stacks of these. + var/carpeted = 0 + + var/list/connections = list("nw0", "ne0", "sw0", "se0") + +/obj/structure/table/proc/update_material() + var/old_maxhealth = maxhealth + if(!material) + maxhealth = 10 + else + maxhealth = material.integrity / 2 + + if(reinforced) + maxhealth += reinforced.integrity / 2 + + health += maxhealth - old_maxhealth + +/obj/structure/table/New() + ..() + // One table per turf. + for(var/obj/structure/table/T in loc) + if(T != src) + // There's another table here that's not us, break to metal. + // break_to_parts calls qdel(src) + break_to_parts(full_return = 1) + return + +/obj/structure/table/initialize() + ..() + // reset color/alpha, since they're set for nice map previews + color = "#ffffff" + alpha = 255 + update_connections(1) + update_icon() + update_desc() + +/obj/structure/table/Destroy() + material = null + update_connections(1) // Update tables around us to ignore us (material=null forces no connections) + for(var/obj/structure/table/T in oview(src, 1)) + T.update_icon() + ..() + +/obj/structure/table/attackby(obj/item/weapon/W, mob/user) + + if(reinforced && istype(W, /obj/item/weapon/screwdriver)) + remove_reinforced(W, user) + if(!reinforced) + update_desc() + update_icon() + return 1 + + if(!reinforced && material && istype(W, /obj/item/weapon/wrench)) + remove_material(W, user) + if(!material) + update_connections(1) + update_icon() + return 1 + + if(!reinforced && !material && istype(W, /obj/item/weapon/wrench)) + dismantle(W, user) + return 1 + + if(!material && can_plate && istype(W, /obj/item/stack/sheet)) + material = common_material_add(W, user, "plat") + if(material) + update_connections(1) + update_icon() + return 1 + + return ..() + +/obj/structure/table/MouseDrop_T(obj/item/stack/sheet/what) + if(can_reinforce && isliving(usr) && (!usr.stat) && istype(what) && usr.get_active_hand() == what && Adjacent(usr)) + reinforce_table(what, usr) + else + return ..() + +/obj/structure/table/proc/reinforce_table(obj/item/stack/sheet/S, mob/user) + if(reinforced) + user << "\The [src] is already reinforced!" + return + + if(!can_reinforce) + user << "\The [src] cannot be reinforced!" + + reinforced = common_material_add(S, user, "reinforc") + if(reinforced) + update_desc() + update_icon() + +/obj/structure/table/proc/update_desc() + if(material) + name = "[material.display_name] table" + else + name = "table frame" + + if(reinforced) + name = "reinforced [name]" + desc = "[initial(desc)] This one seems to be reinforced with [reinforced.display_name]." + else + desc = initial(desc) + +// Returns the material to set the table to. +/obj/structure/table/proc/common_material_add(obj/item/stack/sheet/S, mob/user, verb) // Verb is actually verb without 'e' or 'ing', which is added. Works for 'plate'/'plating' and 'reinforce'/'reinforcing'. + var/material/M = name_to_material[S.sheettype] + if(!istype(M)) + user << "You cannot [verb]e \the [src] with \the [S]." + return null + user << "You begin [verb]ing \the [src] with [M.display_name]." + if(!do_after(user, 20) || !S.use(1)) + return null + user.visible_message("\The [user] [verb]es \the [src] with [M.display_name].", "You finish [verb]ing \the [src].") + return M + +// Returns the material to set the table to. +/obj/structure/table/proc/common_material_remove(mob/user, material/M, delay, what, type_holding) + if(!M.stack_type) + user << "You are unable to remove the [what] from this table!" + return M + + user.visible_message("\The [user] begins removing the [type_holding] holding \the [src]'s [M.display_name] [what] in place.", + "You begin removing the [type_holding] holding \the [src]'s [M.display_name] [what] in place.") + if(!do_after(user, 40)) + return M + user.visible_message("\The [user] removes the [M.display_name] [what] from \the [src].", + "You remove the [M.display_name] [what] from \the [src].") + new M.stack_type(src.loc) + return null + +/obj/structure/table/proc/remove_reinforced(obj/item/weapon/screwdriver/S, mob/user) + reinforced = common_material_remove(user, reinforced, 40, "reinforcements", "screws") + +/obj/structure/table/proc/remove_material(obj/item/weapon/wrench/W, mob/user) + material = common_material_remove(user, material, 20, "plating", "bolts") + +/obj/structure/table/proc/dismantle(obj/item/weapon/wrench/W, mob/user) + user.visible_message("\The [user] begins dismantling \the [src].", + "You begin dismantling \the [src].") + if(!do_after(user, 20)) + return + user.visible_message("\The [user] dismantles \the [src].", + "You dismantle \the [src].") + new /obj/item/stack/sheet/metal(src.loc) + +/obj/structure/table/proc/break_to_parts(full_return = 0) + if(reinforced && reinforced.stack_type && (full_return || prob(25))) + new reinforced.stack_type(src.loc) + if(material && material.stack_type && (full_return || prob(50))) + new material.stack_type(src.loc) + if(full_return || prob(50)) + new /obj/item/stack/sheet/metal(src.loc) + qdel(src) + return + +/obj/structure/table/update_icon() + if(flipped != 1) + icon_state = "blank" + overlays.Cut() + + // Base frame shape. Mostly done for glass/diamond tables, where this is visible. + for(var/n in connections) + overlays += n + + // Standard table image + if(material) + for(var/n in connections) + var/image/I = image(icon, "[material.icon_base]_[n]") + I.color = material.icon_colour + I.alpha = 255 * material.opacity + overlays += I + + // Reinforcements + if(reinforced) + for(var/n in connections) + var/image/I = image(icon, "[reinforced.icon_reinf]_[n]") + I.color = reinforced.icon_colour + I.alpha = 255 * reinforced.opacity + overlays += I + + if(carpeted) + for(var/n in connections) + overlays += "carpet_[n]" + else + overlays.Cut() + var/type = 0 + var/tabledirs = 0 + for(var/direction in list(turn(dir,90), turn(dir,-90)) ) + var/obj/structure/table/T = locate(/obj/structure/table ,get_step(src,direction)) + if (T && T.flipped == 1 && T.dir == src.dir && T.material == material) + type++ + tabledirs |= direction + + type = "[type]" + if (type=="1") + if (tabledirs & turn(dir,90)) + type += "-" + if (tabledirs & turn(dir,-90)) + type += "+" + + icon_state = "flip[type]" + if(material) + var/image/I = image(icon, "[material.icon_base]_flip[type]") + I.color = material.icon_colour + I.alpha = 255 * material.opacity + overlays += I + name = "[material.display_name] table" + else + name = "table frame" + + if(reinforced) + var/image/I = image(icon, "[reinforced.icon_reinf]_flip[type]") + I.color = reinforced.icon_colour + I.alpha = 255 * reinforced.opacity + overlays += I + + if(carpeted) + for(var/n in connections) + overlays += "carpet_flip[type]" + +// set propagate if you're updating a table that should update tables around it too, for example if it's a new table or something important has changed (like material). +/obj/structure/table/proc/update_connections(propagate=0) + if(!material) + connections = list("nw0", "ne0", "sw0", "se0") + + if(propagate) + for(var/obj/structure/table/T in oview(src, 1)) + T.update_connections() + return + + var/list/blocked_dirs = list() + for(var/obj/structure/window/W in get_turf(src)) + if(W.is_fulltile()) + connections = list("nw0", "ne0", "sw0", "se0") + return + blocked_dirs |= W.dir + + for(var/D in list(NORTH, SOUTH, EAST, WEST) - blocked_dirs) + var/turf/T = get_step(src, D) + for(var/obj/structure/window/W in T) + if(W.is_fulltile() || W.dir == reverse_dir[D]) + blocked_dirs |= D + break + else + if(W.dir != D) // it's off to the side + blocked_dirs |= W.dir|D // blocks the diagonal + + for(var/D in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) - blocked_dirs) + var/turf/T = get_step(src, D) + + for(var/obj/structure/window/W in T) + if(W.is_fulltile() || W.dir & reverse_dir[D]) + blocked_dirs |= D + break + + // Blocked cardinals block the adjacent diagonals too. Prevents weirdness with tables. + for(var/x in list(NORTH, SOUTH)) + for(var/y in list(EAST, WEST)) + if((x in blocked_dirs) || (y in blocked_dirs)) + blocked_dirs |= x|y + + var/list/connection_dirs = list() + + for(var/obj/structure/table/T in oview(src, 1)) + var/T_dir = get_dir(src, T) + if(T_dir in blocked_dirs) continue + if(material == T.material && flipped == T.flipped) + connection_dirs |= T_dir + if(propagate) + spawn(0) + T.update_connections() + T.update_icon() + + connections = dirs_to_corner_states(connection_dirs) + +#define CORNER_NONE 0 +#define CORNER_EASTWEST 1 +#define CORNER_DIAGONAL 2 +#define CORNER_NORTHSOUTH 4 + +/proc/dirs_to_corner_states(list/dirs) + if(!istype(dirs)) return + + var/NE = CORNER_NONE + var/NW = CORNER_NONE + var/SE = CORNER_NONE + var/SW = CORNER_NONE + + if(NORTH in dirs) + NE |= CORNER_NORTHSOUTH + NW |= CORNER_NORTHSOUTH + if(SOUTH in dirs) + SW |= CORNER_NORTHSOUTH + SE |= CORNER_NORTHSOUTH + if(EAST in dirs) + SE |= CORNER_EASTWEST + NE |= CORNER_EASTWEST + if(WEST in dirs) + NW |= CORNER_EASTWEST + SW |= CORNER_EASTWEST + if(NORTHWEST in dirs) + NW |= CORNER_DIAGONAL + if(NORTHEAST in dirs) + NE |= CORNER_DIAGONAL + if(SOUTHEAST in dirs) + SE |= CORNER_DIAGONAL + if(SOUTHWEST in dirs) + SW |= CORNER_DIAGONAL + + return list("ne[NE]", "se[SE]", "sw[SW]", "nw[NW]") + +#undef CORNER_NONE +#undef CORNER_EASTWEST +#undef CORNER_DIAGONAL +#undef CORNER_NORTHSOUTH \ No newline at end of file diff --git a/code/modules/tables/update_triggers.dm b/code/modules/tables/update_triggers.dm new file mode 100644 index 0000000000..a90e3eeb8a --- /dev/null +++ b/code/modules/tables/update_triggers.dm @@ -0,0 +1,22 @@ +/obj/structure/window/New() + ..() + for(var/obj/structure/table/T in view(src, 1)) + T.update_connections() + T.update_icon() + +/obj/structure/window/Destroy() + var/oldloc = loc + loc=null + for(var/obj/structure/table/T in view(oldloc, 1)) + T.update_connections() + T.update_icon() + loc=oldloc + ..() + +/obj/structure/window/Move() + var/oldloc = loc + . = ..() + if(loc != oldloc) + for(var/obj/structure/table/T in view(oldloc, 1) | view(loc, 1)) + T.update_connections() + T.update_icon() \ No newline at end of file diff --git a/icons/obj/tables.dmi b/icons/obj/tables.dmi new file mode 100644 index 0000000000..429969fc86 Binary files /dev/null and b/icons/obj/tables.dmi differ