Merge pull request #11368 from VOREStation/Arokha/closetanim
Port of monster860's animated doors to Bay closets
@@ -182,3 +182,10 @@
|
||||
stack_trace("Directional light cone deleted, but not by our component")
|
||||
return QDEL_HINT_LETMELIVE
|
||||
return ..()
|
||||
|
||||
/obj/effect/overlay/closet_door
|
||||
anchored = TRUE
|
||||
plane = FLOAT_PLANE
|
||||
layer = FLOAT_LAYER
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
closet_appearance = null
|
||||
open_sound = 'sound/items/zip.ogg'
|
||||
close_sound = 'sound/items/zip.ogg'
|
||||
door_anim_time = 0 //Unsupported
|
||||
var/item_path = /obj/item/bodybag
|
||||
density = FALSE
|
||||
storage_capacity = (MOB_MEDIUM * 2) - 1
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
closet_appearance = null
|
||||
catalogue_data = list(/datum/category_item/catalogue/information/objects/oldreactor)
|
||||
climbable = FALSE
|
||||
door_anim_time = 0 //Unsupported
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/fuel_assembly/deuterium = 6)
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
|
||||
var/closet_appearance = /decl/closet_appearance // The /decl that defines what decals we end up with, that makes our look unique
|
||||
|
||||
/// Currently animating the door transform
|
||||
var/is_animating_door = FALSE
|
||||
/// Length of time (ds) to animate the door transform
|
||||
var/door_anim_time = 2.0
|
||||
/// Amount to 'squish' the full width of the door by
|
||||
var/door_anim_squish = 0.30
|
||||
/// Virtual angle at which the door is opened to (136 by default, so not a full 180)
|
||||
var/door_anim_angle = 136
|
||||
/// Offset for the door hinge location from centerline
|
||||
var/door_hinge = -6.5
|
||||
/// Our visual object for the closet door
|
||||
var/obj/effect/overlay/closet_door/door_obj
|
||||
|
||||
/obj/structure/closet/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
@@ -66,6 +79,10 @@
|
||||
color = null
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/Destroy()
|
||||
. = ..()
|
||||
qdel_null(door_obj)
|
||||
|
||||
/obj/structure/closet/examine(mob/user)
|
||||
. = ..()
|
||||
if(Adjacent(user) || isobserver(user))
|
||||
@@ -134,7 +151,7 @@
|
||||
playsound(src, open_sound, 15, 1, -3)
|
||||
if(initial(density))
|
||||
density = !density
|
||||
update_icon()
|
||||
animate_door()
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/close()
|
||||
@@ -159,7 +176,7 @@
|
||||
playsound(src, close_sound, 15, 1, -3)
|
||||
if(initial(density))
|
||||
density = !density
|
||||
update_icon()
|
||||
animate_door(TRUE)
|
||||
return 1
|
||||
|
||||
//Cham Projector Exception
|
||||
@@ -214,10 +231,11 @@
|
||||
|
||||
|
||||
/obj/structure/closet/proc/toggle(mob/user as mob)
|
||||
if(is_animating_door)
|
||||
return
|
||||
if(!(opened ? close() : open()))
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
return
|
||||
update_icon()
|
||||
|
||||
// this should probably use dump_contents()
|
||||
/obj/structure/closet/ex_act(severity)
|
||||
@@ -481,8 +499,45 @@
|
||||
spawn(1) qdel(src)
|
||||
return 1
|
||||
|
||||
// Just a generic cabinet for mappers to use
|
||||
/obj/structure/closet/cabinet
|
||||
name = "cabinet"
|
||||
icon = 'icons/obj/closets/bases/cabinet.dmi'
|
||||
closet_appearance = /decl/closet_appearance/cabinet
|
||||
/obj/structure/closet/proc/animate_door(closing = FALSE)
|
||||
if(!door_anim_time)
|
||||
update_icon()
|
||||
return
|
||||
if(!door_obj)
|
||||
door_obj = new
|
||||
vis_contents |= door_obj
|
||||
door_obj.icon = icon
|
||||
door_obj.icon_state = "door_front"
|
||||
is_animating_door = TRUE
|
||||
if(!closing)
|
||||
update_icon()
|
||||
var/num_steps = door_anim_time / world.tick_lag
|
||||
for(var/I in 0 to num_steps)
|
||||
var/angle = door_anim_angle * (closing ? 1 - (I/num_steps) : (I/num_steps))
|
||||
var/matrix/M = get_door_transform(angle)
|
||||
var/door_state = angle >= 90 ? "door_back" : "door_front"
|
||||
var/door_layer = angle >= 90 ? FLOAT_LAYER : ABOVE_MOB_LAYER
|
||||
|
||||
if(I == 0)
|
||||
door_obj.transform = M
|
||||
door_obj.icon_state = door_state
|
||||
door_obj.layer = door_layer
|
||||
else if(I == 1)
|
||||
animate(door_obj, transform = M, icon_state = door_state, layer = door_layer, time = world.tick_lag, flags = ANIMATION_END_NOW)
|
||||
else
|
||||
animate(transform = M, icon_state = door_state, layer = door_layer, time = world.tick_lag)
|
||||
addtimer(CALLBACK(src,.proc/end_door_animation,closing),door_anim_time,TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
/obj/structure/closet/proc/end_door_animation(closing = FALSE)
|
||||
is_animating_door = FALSE
|
||||
if(closing)
|
||||
// There's not really harm in leaving it on, but, one less atom to send to clients to render when lockers are closed
|
||||
vis_contents -= door_obj
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/proc/get_door_transform(angle)
|
||||
var/matrix/M = matrix()
|
||||
M.Translate(-door_hinge, 0)
|
||||
M.Multiply(matrix(cos(angle), 0, 0, -sin(angle) * door_anim_squish, 1, 0))
|
||||
M.Translate(door_hinge, 0)
|
||||
return M
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
var/icon/closed_locked_welded_icon
|
||||
var/icon/closed_unlocked_icon
|
||||
var/icon/closed_unlocked_welded_icon
|
||||
var/icon/door_front_icon
|
||||
var/icon/door_back_icon
|
||||
|
||||
// Create open icon.
|
||||
var/icon/new_icon = new
|
||||
@@ -40,6 +42,10 @@
|
||||
open_icon.Blend(icon(base_icon, "open"), ICON_OVERLAY)
|
||||
open_icon.Blend(color, BLEND_ADD)
|
||||
open_icon.Blend(icon(base_icon, "interior"), ICON_OVERLAY)
|
||||
|
||||
door_back_icon = icon(base_icon, "door_back")
|
||||
door_back_icon.Blend(color, BLEND_ADD)
|
||||
|
||||
if(decal_icon)
|
||||
for(var/thing in decals)
|
||||
var/icon/this_decal_icon = icon(decal_icon, "[thing]_open")
|
||||
@@ -47,6 +53,8 @@
|
||||
open_icon.Blend(this_decal_icon, ICON_OVERLAY)
|
||||
|
||||
// Generate basic closed icons.
|
||||
door_front_icon = icon(base_icon, "door_front")
|
||||
door_front_icon.Blend(color, BLEND_ADD)
|
||||
closed_emagged_icon = icon(base_icon, "base")
|
||||
if(can_lock)
|
||||
closed_emagged_icon.Blend(icon(base_icon, "lock"), ICON_OVERLAY)
|
||||
@@ -56,6 +64,10 @@
|
||||
var/icon/this_decal_icon = icon(decal_icon, thing)
|
||||
this_decal_icon.Blend(decals[thing], BLEND_ADD)
|
||||
closed_emagged_icon.Blend(this_decal_icon, ICON_OVERLAY)
|
||||
door_front_icon.Blend(this_decal_icon, ICON_OVERLAY)
|
||||
|
||||
door_front_icon.AddAlphaMask(icon(base_icon, "door_front")) // Remove pesky 'more than just door' decals
|
||||
|
||||
closed_locked_icon = icon(closed_emagged_icon)
|
||||
closed_unlocked_icon = icon(closed_emagged_icon)
|
||||
|
||||
@@ -83,13 +95,15 @@
|
||||
closed_emagged_welded_icon.Blend(sparks, ICON_OVERLAY)
|
||||
|
||||
// Insert our bevy of icons into the final icon file.
|
||||
new_icon.Insert(open_icon, "open")
|
||||
new_icon.Insert(closed_emagged_icon, "closed_emagged")
|
||||
new_icon.Insert(closed_emagged_welded_icon, "closed_emagged_welded")
|
||||
new_icon.Insert(closed_locked_icon, "closed_locked")
|
||||
new_icon.Insert(closed_locked_welded_icon, "closed_locked_welded")
|
||||
new_icon.Insert(closed_unlocked_icon, "closed_unlocked")
|
||||
new_icon.Insert(closed_unlocked_welded_icon, "closed_unlocked_welded")
|
||||
new_icon.Insert(open_icon, "open")
|
||||
new_icon.Insert(closed_emagged_icon, "closed_emagged")
|
||||
new_icon.Insert(closed_emagged_welded_icon, "closed_emagged_welded")
|
||||
new_icon.Insert(closed_locked_icon, "closed_locked")
|
||||
new_icon.Insert(closed_locked_welded_icon, "closed_locked_welded")
|
||||
new_icon.Insert(closed_unlocked_icon, "closed_unlocked")
|
||||
new_icon.Insert(closed_unlocked_welded_icon, "closed_unlocked_welded")
|
||||
new_icon.Insert(door_front_icon, "door_front")
|
||||
new_icon.Insert(door_back_icon, "door_back")
|
||||
|
||||
// Set icon!
|
||||
icon = new_icon
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
seal_tool = /obj/item/weapon/tool/screwdriver
|
||||
breakout_sound = 'sound/weapons/tablehit1.ogg'
|
||||
closet_appearance = null // Special icon for us
|
||||
door_anim_time = 0 //Unsupported
|
||||
|
||||
/* Graves */
|
||||
/obj/structure/closet/grave
|
||||
@@ -20,6 +21,7 @@
|
||||
max_closets = 1
|
||||
opened = 1
|
||||
closet_appearance = null // Special icon for us
|
||||
door_anim_time = 0 //Unsupported
|
||||
|
||||
/obj/structure/closet/grave/attack_hand(mob/user as mob)
|
||||
if(opened)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/obj/structure/closet/crate/critter
|
||||
name = "critter crate"
|
||||
desc = "A crate which can sustain life for a while."
|
||||
closet_appearance = /decl/closet_appearance/large_crate/critter
|
||||
closet_appearance = /decl/closet_appearance/large_crate/critter
|
||||
door_anim_time = 0 //Unsupported
|
||||
@@ -13,6 +13,7 @@
|
||||
opened = 0
|
||||
sealed = 0 //Don't touch this.
|
||||
health = 100
|
||||
door_anim_time = 0 //Unsupported
|
||||
|
||||
/obj/structure/closet/secure_closet/egg/update_icon()
|
||||
if(opened)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/obj/structure/closet/cabinet
|
||||
name = "cabinet"
|
||||
desc = "Old will forever be in fashion."
|
||||
icon = 'icons/obj/closets/bases/cabinet.dmi'
|
||||
closet_appearance = /decl/closet_appearance/cabinet
|
||||
door_anim_time = 0 //Unsupported
|
||||
|
||||
/obj/structure/closet/acloset
|
||||
name = "strange closet"
|
||||
|
||||
@@ -312,3 +312,4 @@ GLOBAL_LIST_BOILERPLATE(all_brig_closets, /obj/structure/closet/secure_closet/br
|
||||
|
||||
//too small to put a man in
|
||||
large = 0
|
||||
door_anim_time = 0 // Unsupported
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
anchored = TRUE
|
||||
health = 0 //destroying the statue kills the mob within
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
door_anim_time = 0 // Why is this a closet??
|
||||
var/intialTox = 0 //these are here to keep the mob from taking damage from things that logically wouldn't affect a rock
|
||||
var/intialFire = 0 //it's a little sloppy I know but it was this or the GODMODE flag. Lesser of two evils.
|
||||
var/intialBrute = 0
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
anchored = TRUE
|
||||
store_mobs = 0
|
||||
wall_mounted = 1
|
||||
door_anim_time = 0 // Unsupported
|
||||
|
||||
//spawns 2 sets of breathmask, emergency oxy tank and crowbar
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
closet_appearance = /decl/closet_appearance/crate
|
||||
climbable = TRUE
|
||||
dir = 4 //Spawn facing 'forward' by default.
|
||||
door_anim_time = 0 //Unsupported until appropriate sprites are available
|
||||
var/points_per_crate = 5
|
||||
var/rigged = 0
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.5 KiB |