/* Tables and Racks * Contains: * Tables * Wooden tables * Reinforced tables * Racks */ /* * Tables */ /obj/structure/table name = "table" desc = "A square piece of metal standing on four metal legs. It can not move." icon = 'icons/obj/smooth_structures/table.dmi' icon_state = "table" density = 1 anchored = 1.0 layer = 2.8 throwpass = 1 //You can throw objects over this, despite it's density.") climbable = 1 var/parts = /obj/item/weapon/table_parts var/flipped = 0 var/health = 100 var/busy = 0 smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) /obj/structure/table/New() ..() for(var/obj/structure/table/T in src.loc) if(T != src) qdel(T) if(flipped) update_icon() /obj/structure/table/proc/destroy() new parts(loc) density = 0 qdel(src) /obj/structure/table/update_icon() if(smooth && !flipped) icon_state = "" smooth_icon(src) smooth_icon_neighbors(src) if(flipped) clear_smooth_overlays() var/type = 0 var/subtype = null 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) type++ if(type == 1) subtype = direction == turn(dir,90) ? "-" : "+" 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][type == 1 ? subtype : ""]" return 1 /obj/structure/table/ex_act(severity) switch(severity) if(1.0) qdel(src) return if(2.0) if(prob(50)) qdel(src) return if(3.0) if(prob(25)) destroy() else return /obj/structure/table/blob_act() if(prob(75)) destroy() /obj/structure/table/attack_alien(mob/living/user) user.do_attack_animation(src) visible_message("[user] slices [src] apart!") destroy() /obj/structure/table/mech_melee_attack(obj/mecha/M) visible_message("[M] smashes [src] apart!") destroy() /obj/structure/table/attack_animal(mob/living/simple_animal/user) if(user.environment_smash) user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") destroy() /obj/structure/table/attack_hand(mob/living/user) if(HULK in user.mutations) user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) destroy() else ..() if(climber) climber.Weaken(2) climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table") /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(ismob(mover)) var/mob/M = mover if(M.flying) return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 if(locate(/obj/structure/table) in get_turf(mover)) return 1 if(flipped) if(get_dir(loc, target) == dir) return !density else return 1 return 0 /obj/structure/table/CanAStarPass(ID, dir, caller) . = !density if(ismovableatom(caller)) var/atom/movable/mover = caller . = . || mover.checkpass(PASSTABLE) //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 = flipped ? get_turf(src) : get_step(loc, get_dir(from, loc)) 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) 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!") destroy() 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) 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 if(!user.drop_item()) return if(O.loc != src.loc) step(O, get_dir(O, src)) return /obj/structure/table/proc/tablepush(obj/item/I, mob/user) if(get_dist(src, user) < 2) var/obj/item/weapon/grab/G = I if(G.affecting.buckled) to_chat(user, "[G.affecting] is buckled to [G.affecting.buckled]!") return 0 if(G.state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return 0 if(!G.confirm()) return 0 G.affecting.forceMove(get_turf(src)) G.affecting.Weaken(2) G.affecting.visible_message("[G.assailant] pushes [G.affecting] onto [src].", \ "[G.assailant] pushes [G.affecting] onto [src].") add_logs(G.affecting, G.assailant, "pushed onto a table") qdel(I) return 1 qdel(I) /obj/structure/table/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/grab)) tablepush(W, user) return if(istype(W, /obj/item/weapon/wrench)) user.visible_message("[user] is disassembling \a [src].", "You start disassembling \the [src].") playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 50, target = src)) playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) destroy() return if(isrobot(user)) return if(istype(W, /obj/item/weapon/melee/energy/blade)) var/datum/effect/system/spark_spread/spark_system = new /datum/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) for(var/mob/O in viewers(user, 4)) O.show_message("\blue The [src] was sliced apart by [user]!", 1, "\red You hear [src] coming apart.", 2) destroy() return if(!(W.flags & ABSTRACT)) if(user.drop_item()) W.Move(loc) var/list/click_params = params2list(params) //Center the icon where the user clicked. if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) 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) return 0 T = locate() in get_step(src.loc,direction) if(!T || T.flipped) return 1 if(istype(T,/obj/structure/table/reinforced/)) var/obj/structure/table/reinforced/R = T if(R.status == 2) 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 = null set src in oview(1) if(!can_touch(usr) || ismouse(usr)) return if(!flip(get_cardinal_dir(usr,src))) to_chat(usr, "It won't budge.") return usr.visible_message("[usr] flips \the [src]!") if(climbable) structure_shaken() return /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(!unflip()) to_chat(usr, "It won't budge.") return /obj/structure/table/proc/flip(var/direction) if(flipped) return 0 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) dir = direction if(dir != NORTH) layer = 5 flipped = 1 smooth = SMOOTH_FALSE flags |= ON_BORDER for(var/D in list(turn(direction, 90), turn(direction, -90))) if(locate(/obj/structure/table,get_step(src,D))) var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D)) T.flip(direction) update_icon() return 1 /obj/structure/table/proc/unflip() if(!flipped) return 0 var/can_flip = 1 for(var/mob/A in oview(src,0))//src.loc) if(istype(A)) can_flip = 0 if(!can_flip) return 0 verbs -=/obj/structure/table/proc/do_put verbs +=/obj/structure/table/verb/do_flip layer = initial(layer) flipped = 0 smooth = initial(smooth) flags &= ~ON_BORDER for(var/D in list(turn(dir, 90), turn(dir, -90))) if(locate(/obj/structure/table,get_step(src,D))) var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D)) T.unflip() update_icon() return 1 /* * Wooden tables */ /obj/structure/table/woodentable name = "wooden table" desc = "Do not apply fire to this. Rumour says it burns easily." icon = 'icons/obj/smooth_structures/wood_table.dmi' icon_state = "wood_table" parts = /obj/item/weapon/table_parts/wood health = 50 canSmoothWith = list(/obj/structure/table/woodentable, /obj/structure/table/woodentable/poker) var/canPokerize = 1 /obj/structure/table/woodentable/attackby(obj/item/I as obj, mob/user as mob, params) if(canPokerize && istype(I, /obj/item/stack/tile/grass)) var/obj/item/stack/tile/grass/gr = I gr.use(1) new /obj/structure/table/woodentable/poker( src.loc ) qdel(src) visible_message("[user] adds the grass to the wooden table") return 1 else return ..() return 1 /obj/structure/table/woodentable/poker //No specialties, Just a mapping object. name = "gambling table" desc = "A seedy table for seedy dealings in seedy places." icon = 'icons/obj/smooth_structures/poker_table.dmi' icon_state = "pokertable" canSmoothWith = list(/obj/structure/table/woodentable/poker, /obj/structure/table/woodentable) canPokerize = 0 /obj/structure/table/woodentable/poker/destroy() new /obj/item/stack/tile/grass(loc) ..() /obj/structure/glasstable_frame name = "glass table frame" desc = "A metal frame for a glass table." icon = 'icons/obj/structures.dmi' icon_state = "glass_table_frame" density = 1 /obj/structure/glasstable_frame/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = I if(G.amount >= 2) to_chat(user, "You start to add the glass to \the [src].") if(do_after(user, 10, target = src)) G.use(2) to_chat(user, "You add the glass to \the [src].") playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) new /obj/structure/table/glass(loc) qdel(src) else to_chat(user, "You don't have enough glass! You need at least 2 sheets.") return if(iswrench(I)) to_chat(user, "You start to deconstruct \the [src].") playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) if(do_after(user, 10, target = src)) playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1) to_chat(user, "You dismantle \the [src].") new /obj/item/stack/sheet/metal(loc) new /obj/item/stack/sheet/metal(loc) qdel(src) /obj/structure/table/glass name = "glass table" desc = "Looks fragile. You should totally flip it. It is begging for it." icon = 'icons/obj/smooth_structures/glass_table.dmi' icon_state = "glass_table" parts = /obj/item/weapon/table_parts/glass health = 10 canSmoothWith = null /obj/structure/table/glass/flip(var/direction) collapse() /obj/structure/table/glass/proc/collapse() //glass table collapse is called twice in this code, more efficent to just have a proc src.visible_message("\The [src] shatters, and the frame collapses!", "You hear metal collapsing and glass shattering.") playsound(src.loc, "shatter", 50, 1) destroy(1) /obj/structure/table/glass/destroy(dirty) if(dirty) new /obj/item/weapon/shard(loc) new /obj/item/weapon/shard(loc) else new /obj/item/stack/sheet/glass(loc, 2) ..() /obj/structure/table/glass/tablepush(obj/item/I, mob/user) if(..()) collapse() /* * Reinforced tables */ /obj/structure/table/reinforced name = "reinforced table" desc = "A version of the four legged table. It is stronger." icon = 'icons/obj/smooth_structures/reinforced_table.dmi' icon_state = "r_table" health = 200 var/status = 2 parts = /obj/item/weapon/table_parts/reinforced canSmoothWith = list(/obj/structure/table/reinforced, /obj/structure/table) /obj/structure/table/reinforced/flip(var/direction) if(status == 2) return 0 else return ..() /obj/structure/table/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) if(src.status == 2) to_chat(user, "\blue Now weakening the reinforced table") playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) if(do_after(user, 50, target = src)) if(!src || !WT.isOn()) return to_chat(user, "\blue Table weakened") src.status = 1 else to_chat(user, "\blue Now strengthening the reinforced table") playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) if(do_after(user, 50, target = src)) if(!src || !WT.isOn()) return to_chat(user, "\blue Table strengthened") src.status = 2 return return if(istype(W, /obj/item/weapon/wrench)) if(src.status == 2) return ..() /* * Racks */ /obj/structure/rack name = "rack" desc = "Different from the Middle Ages version." icon = 'icons/obj/objects.dmi' icon_state = "rack" density = 1 anchored = 1.0 throwpass = 1 //You can throw objects over this, despite it's density. var/parts = /obj/item/weapon/rack_parts var/health = 5 /obj/structure/rack/proc/destroy() new parts(loc) density = 0 qdel(src) /obj/structure/rack/ex_act(severity) switch(severity) if(1.0) qdel(src) if(2.0) qdel(src) if(prob(50)) new /obj/item/weapon/rack_parts(src.loc) if(3.0) if(prob(25)) qdel(src) new /obj/item/weapon/rack_parts(src.loc) /obj/structure/rack/blob_act() if(prob(75)) qdel(src) return else if(prob(50)) new /obj/item/weapon/rack_parts(src.loc) qdel(src) return /obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(air_group || (height==0)) return 1 if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 else return 0 /obj/structure/rack/CanAStarPass(ID, dir, caller) . = !density if(ismovableatom(caller)) var/atom/movable/mover = caller . = . || mover.checkpass(PASSTABLE) /obj/structure/rack/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 if(!user.drop_item()) return if(O.loc != src.loc) step(O, get_dir(O, src)) return /obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) new /obj/item/weapon/rack_parts( src.loc ) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) qdel(src) return if(isrobot(user)) return if(!(W.flags & ABSTRACT)) if(user.drop_item()) W.Move(loc) return /obj/structure/rack/attack_hand(mob/user) if(HULK in user.mutations) visible_message("[user] smashes [src] apart!") user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) destroy() else user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) playsound(loc, 'sound/items/dodgeball.ogg', 80, 1) user.visible_message("[user] kicks [src].", \ "You kick [src].") health -= rand(1,2) healthcheck() /obj/structure/rack/mech_melee_attack(obj/mecha/M) visible_message("[M] smashes [src] apart!") destroy() /obj/structure/rack/attack_alien(mob/living/user) user.do_attack_animation(src) visible_message("[user] slices [src] apart!") destroy() /obj/structure/rack/attack_animal(mob/living/simple_animal/user) if(user.environment_smash) user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") destroy() /obj/structure/rack/attack_tk() // no telehulk sorry return /obj/structure/rack/proc/healthcheck() if(health <= 0) destroy() /obj/structure/rack/skeletal_bar name = "skeletal minibar" desc = "Made with the skulls of the fallen." icon = 'icons/obj/stationobjs.dmi' icon_state = "minibar" /obj/structure/rack/skeletal_bar/left icon_state = "minibar_left" /obj/structure/rack/skeletal_bar/right icon_state = "minibar_right"