Table and Crate interactions (#1353)

Inspired partially by complaints about my changes to crates that made them hard to shoot open. This PR adds two main features which interact:

Crates can now be slid under tables, making them easier to stow away. A crate only fits under a table while closed, and can't be opened while under there.

Crates can now be hoisted up ontop of a table, this takes time depending on the mass of the crate. A crate ontop of a table works as normal, and it will also always block shots, making a table the ideal platform for firing an emitter at one.

A table can have a crate both under and ontop of it, allowing two crates to be stored on one tile, at some cost of convenience and effort. The crates have their pixel offsets modified so that both of them can be seen at once.
This commit is contained in:
NanakoAC
2016-12-31 04:18:03 +02:00
committed by skull132
parent 7a4d9fedaa
commit 74f29a6c22
4 changed files with 190 additions and 11 deletions
@@ -10,9 +10,14 @@
climbable = 1
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
var/rigged = 0
var/tablestatus = 0
pass_flags = PASSTABLE
/obj/structure/closet/crate/can_open()
return 1
if (tablestatus != -1)//Can't be opened while under a table
return 1
return 0
/obj/structure/closet/crate/can_close()
return 1
@@ -49,7 +54,7 @@
icon_state = icon_opened
src.opened = 1
pass_flags = 0
return 1
/obj/structure/closet/crate/close()
@@ -74,15 +79,11 @@
icon_state = icon_closed
src.opened = 0
pass_flags = PASSTABLE//Crates can only slide under tables when closed
return 1
/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover,/obj/item/projectile) && prob(50))
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
return 0
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(opened)
@@ -130,6 +131,142 @@
A.ex_act(severity)
qdel(src)
/*
==========================
Table interactions
==========================
*/
/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if (istype(mover, /obj/structure/closet/crate))//Handle interaction with other crates
var/obj/structure/closet/crate/C = mover
if (tablestatus == 1 && C.tablestatus != 1 && !C.opened)//Allow the crate to slide under us if we're ontop of a table
return 1
else if (tablestatus == -1 && C.tablestatus == 1)//Allow it to slide over us if we're underneath a table
return 1
else//Otherwise, block it. Don't allow two crates on the same level of a tile
return 0
if(istype(mover,/obj/item/projectile))
if (tablestatus == 1)//They always block shots on a table
return 0
else if (!tablestatus && prob(15))//Usually will not block shots when lying on the floor
return 0
else return 1
else if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
return 0
/obj/structure/closet/crate/Move(var/turf/destination, dir)
if(..())
if (locate(/obj/structure/table) in destination)
if (tablestatus != 1)
set_tablestatus(-1)//Slide under the table
else
set_tablestatus(0)
/obj/structure/closet/crate/toggle(var/mob/user)
if (!opened && tablestatus == -1)
user << span("warning", "You can't open that while it's under the table")
return 0
else
..()
/obj/structure/closet/crate/proc/set_tablestatus(var/target)
if (tablestatus != target)
tablestatus = target
spawn(3)//Short spawn prevents things popping up where they shouldnt
switch (target)
if (1)
layer = LAYER_ABOVE_TABLE
pixel_y = 8
if (0)
layer = initial(layer)
pixel_y = 0
if (-1)
layer = LAYER_UNDER_TABLE
pixel_y = -4
//For putting on tables
/obj/structure/closet/crate/MouseDrop(atom/over_object)
if (istype(over_object, /obj/structure/table))
put_on_table(over_object, usr)
return 1
else
return ..()
/obj/structure/closet/crate/proc/put_on_table(var/obj/structure/table/table, var/mob/user)
if (!table || !user || (tablestatus == -1))
return
//User must be in reach of the crate
if (!user.Adjacent(src))
user << span("warning", "You need to be closer to the crate!")
return
//One of us has to be near the table
if (!user.Adjacent(table) && !Adjacent(table))
user << span("warning", "Take the crate closer to the table!")
return
for (var/obj/structure/closet/crate/C in get_turf(table))
if (C.tablestatus != -1)
user << span("warning", "There's already a crate on this table!")
return
//Crates are heavy, hauling them onto tables is hard.
//The more stuff thats in it, the longer it takes
//Good place to factor in Strength in future
var/timeneeded = 20
var/success = 0
if (tablestatus == 1 && Adjacent(table))
//Sliding along a tabletop we're already on. Instant and silent
timeneeded = 0
success = 1
else
//Add time based on mass of contents
for (var/obj/O in contents)
timeneeded += 3* O.w_class
for (var/mob/M in contents)
timeneeded += 3* M.mob_size
if (timeneeded > 0)
user.visible_message("[user] starts hoisting [src] onto the [table]", "You start hoisting [src] onto the [table]. This will take about [timeneeded*0.1] seconds")
user.face_atom(src)
if (do_after(user, timeneeded, needhand = 1))
success = 1
if (success == 1)
forceMove(get_turf(table))
set_tablestatus(1)
/*
=====================
Secure Crates
=====================
*/
/obj/structure/closet/crate/secure
desc = "A secure crate."
name = "Secure crate"
@@ -154,7 +291,8 @@
overlays += greenlight
/obj/structure/closet/crate/secure/can_open()
return !locked
if (..())
return !locked
/obj/structure/closet/crate/secure/proc/togglelock(mob/user as mob)
if(src.opened)