From 9bc534f3d65cd272e3a6f32bc72840c3478cbacf Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Mon, 8 Jul 2024 13:24:36 -0700 Subject: [PATCH] Variable Door Delay + Timer Based Animations (#84631) ## About The Pull Request ### Variable Door Delay Door opening/closing delay times are currently static, but many doors do not have animations that FIT the actual timings. It would be better if subtypes cound declare how long each animation takes, and how long it takes for opening to say, become passable and such. Let's do that. ### Timer Based Animations Currently all doors use flick() to do their animations. This is fine right NOW, but fucks with walleniong because we have to split most things into segments to make layering work. So rather then flick let's use client timers and update_icon_state to achive our effects, alongside a proc that lets us do other effects (like sound) on playing an animation ## Why It's Good For The Game Door behavior and visuals better match up, wallening compatability upstreaming. ## Changelog :cl: add: Most door animations now better line up with when they are/are not passable. /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/__DEFINES/door.dm | 18 +++ code/datums/wires/airlock.dm | 2 +- code/game/machinery/doors/airlock.dm | 48 ++++++-- code/game/machinery/doors/door.dm | 113 ++++++++++++++---- code/game/machinery/doors/firedoor.dm | 37 ++++-- code/game/machinery/doors/passworddoor.dm | 42 +++++-- code/game/machinery/doors/poddoor.dm | 44 +++++-- code/game/machinery/doors/shutters.dm | 18 +++ code/game/machinery/doors/windowdoor.dm | 58 ++++++--- code/game/objects/items/puzzle_pieces.dm | 12 ++ .../ruins/icemoonruin_code/library.dm | 12 ++ icons/obj/doors/blastdoor.dmi | Bin 2654 -> 2662 bytes icons/obj/doors/doorfireglass.dmi | Bin 10216 -> 10234 bytes icons/obj/doors/doormorgue.dmi | Bin 2344 -> 2444 bytes icons/obj/doors/puzzledoor/danger.dmi | Bin 1478 -> 1530 bytes icons/obj/doors/puzzledoor/default.dmi | Bin 1513 -> 1570 bytes icons/obj/doors/puzzledoor/wood.dmi | Bin 2512 -> 2605 bytes icons/obj/doors/shutters.dmi | Bin 18204 -> 18213 bytes icons/obj/doors/shutters_radiation.dmi | Bin 18358 -> 18363 bytes icons/obj/doors/shutters_window.dmi | Bin 41099 -> 41106 bytes icons/obj/doors/windoor.dmi | Bin 65358 -> 65370 bytes tgstation.dme | 1 + 22 files changed, 325 insertions(+), 80 deletions(-) create mode 100644 code/__DEFINES/door.dm diff --git a/code/__DEFINES/door.dm b/code/__DEFINES/door.dm new file mode 100644 index 00000000000..198d38a3af6 --- /dev/null +++ b/code/__DEFINES/door.dm @@ -0,0 +1,18 @@ +// Door animation defines +#define DOOR_OPENING_ANIMATION "opening" +#define DOOR_CLOSING_ANIMATION "closing" +#define DOOR_DENY_ANIMATION "deny" + +// Door animation STEP defines +// These are used to mark points in the animtion when things in game should change +#define DOOR_OPENING_PASSABLE "opening_passable" +#define DOOR_OPENING_FINISHED "opening_finished" +#define DOOR_CLOSING_UNPASSABLE "closing_unpassable" +#define DOOR_CLOSING_FINISHED "closing_finished" + +#define AIRLOCK_OPENING_TRANSPARENT "airlock_opening_transparent" +#define AIRLOCK_OPENING_PASSABLE "airlock_opening_passable" +#define AIRLOCK_OPENING_FINISHED "airlock_opening_finished" +#define AIRLOCK_CLOSING_OPAQUE "airlock_closing_opaque" +#define AIRLOCK_CLOSING_UNPASSABLE "airlock_closing_unpassable" +#define AIRLOCK_CLOSING_FINISHED "airlock_closing_finished" diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 8049f08d8dc..584e862eb5d 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -126,7 +126,7 @@ A.update_appearance() if(WIRE_IDSCAN) // Pulse to disable emergency access and flash the red lights. if(A.hasPower() && A.density) - A.do_animate("deny") + A.run_animation(DOOR_DENY_ANIMATION) if(A.emergency) A.emergency = FALSE A.update_appearance() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 67f069c062c..33465809f42 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -591,13 +591,13 @@ floorlight.pixel_y = 0 . += floorlight -/obj/machinery/door/airlock/do_animate(animation) +/obj/machinery/door/airlock/run_animation(animation) switch(animation) - if("opening") + if(DOOR_OPENING_ANIMATION) update_icon(ALL, AIRLOCK_OPENING) - if("closing") + if(DOOR_OPENING_ANIMATION) update_icon(ALL, AIRLOCK_CLOSING) - if("deny") + if(DOOR_DENY_ANIMATION) if(!machine_stat) update_icon(ALL, AIRLOCK_DENY) playsound(src,doorDeni,50,FALSE,3) @@ -607,6 +607,28 @@ if(airlock_state == AIRLOCK_DENY) update_icon(ALL, AIRLOCK_CLOSED) +/obj/machinery/door/airlock/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 0.6 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 0.6 SECONDS + +/obj/machinery/door/airlock/animation_segment_delay(animation) + switch(animation) + if(AIRLOCK_OPENING_TRANSPARENT) + return 0.1 SECONDS + if(AIRLOCK_OPENING_PASSABLE) + return 0.5 SECONDS + if(AIRLOCK_OPENING_FINISHED) + return 0.6 SECONDS + if(AIRLOCK_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(AIRLOCK_CLOSING_OPAQUE) + return 0.5 SECONDS + if(AIRLOCK_CLOSING_FINISHED) + return 0.6 SECONDS + /obj/machinery/door/airlock/examine(mob/user) . = ..() if(closeOtherId) @@ -1234,18 +1256,21 @@ SEND_SIGNAL(src, COMSIG_AIRLOCK_OPEN, forced) operating = TRUE update_icon(ALL, AIRLOCK_OPENING, TRUE) - sleep(0.1 SECONDS) + var/transparent_delay = animation_segment_delay(AIRLOCK_OPENING_TRANSPARENT) + sleep(transparent_delay) set_opacity(0) if(multi_tile) filler.set_opacity(FALSE) update_freelook_sight() - sleep(0.4 SECONDS) + var/passable_delay = animation_segment_delay(AIRLOCK_OPENING_PASSABLE) - transparent_delay + sleep(passable_delay) set_density(FALSE) if(multi_tile) filler.set_density(FALSE) flags_1 &= ~PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, FALSE) - sleep(0.1 SECONDS) + var/open_delay = animation_segment_delay(AIRLOCK_OPENING_FINISHED) - transparent_delay - passable_delay + sleep(open_delay) layer = OPEN_DOOR_LAYER update_icon(ALL, AIRLOCK_OPEN, TRUE) operating = FALSE @@ -1314,14 +1339,16 @@ filler.density = TRUE flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) - sleep(0.1 SECONDS) + var/unpassable_delay = animation_segment_delay(AIRLOCK_CLOSING_UNPASSABLE) + sleep(unpassable_delay) if(!air_tight) set_density(TRUE) if(multi_tile) filler.density = TRUE flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) - sleep(0.4 SECONDS) + var/opaque_delay = animation_segment_delay(AIRLOCK_CLOSING_OPAQUE) - unpassable_delay + sleep(opaque_delay) if(dangerous_close) crush() if(visible && !glass) @@ -1329,7 +1356,8 @@ if(multi_tile) filler.set_opacity(TRUE) update_freelook_sight() - sleep(0.1 SECONDS) + var/close_delay = animation_segment_delay(AIRLOCK_CLOSING_FINISHED) - unpassable_delay - opaque_delay + sleep(close_delay) update_icon(ALL, AIRLOCK_CLOSED, 1) operating = FALSE delayed_close_requested = FALSE diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index b1fec07f422..9298859b64b 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -3,7 +3,7 @@ name = "door" desc = "It opens and closes." icon = 'icons/obj/doors/doorint.dmi' - icon_state = "door1" + icon_state = "door_closed" base_icon_state = "door" opacity = TRUE density = TRUE @@ -24,6 +24,8 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.1 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.2 + /// The animation we're currently playing, if any + var/animation var/visible = TRUE var/operating = FALSE var/glass = FALSE @@ -252,7 +254,7 @@ if(requiresID() && check_access(I)) open() else - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) return /obj/machinery/door/Move() @@ -282,7 +284,7 @@ else if(requiresID() && allowed(user)) open() else - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) /obj/machinery/door/attack_hand(mob/user, list/modifiers) . = ..() @@ -310,7 +312,7 @@ close() return TRUE if(density) - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) /obj/machinery/door/allowed(mob/M) if(emergency) @@ -405,24 +407,67 @@ INVOKE_ASYNC(src, PROC_REF(open)) /obj/machinery/door/update_icon_state() - icon_state = "[base_icon_state][density]" - return ..() - -/obj/machinery/door/proc/do_animate(animation) + . = ..() switch(animation) - if("opening") + if(DOOR_OPENING_ANIMATION) if(panel_open) - flick("o_doorc0", src) + icon_state = "o_door_opening" else - flick("doorc0", src) - if("closing") + icon_state = "door_opening" + if(DOOR_CLOSING_ANIMATION) if(panel_open) - flick("o_doorc1", src) + icon_state = "o_door_closing" else - flick("doorc1", src) - if("deny") + icon_state = "door_closing" + if(DOOR_DENY_ANIMATION) if(!machine_stat) - flick("door_deny", src) + icon_state = "door_deny" + else + icon_state = "[base_icon_state]_[density ? "closed" : "open"]" + +/obj/machinery/door/update_overlays() + . = ..() + if(panel_open) + . += mutable_appearance(icon, "panel_open") + +/// Returns the delay to use for the passed in animation +/// We'll do our cleanup once the delay runs out +/obj/machinery/door/proc/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 0.6 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 0.6 SECONDS + if(DOOR_DENY_ANIMATION) + return 0.3 SECONDS + +/// Returns the time required to hit particular points in an animation +/// Used to manage delays for opening/closing and such +/obj/machinery/door/proc/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.5 SECONDS + if(DOOR_OPENING_FINISHED) + return 0.6 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 0.6 SECONDS + +/// Override this to do misc tasks on animation start +/obj/machinery/door/proc/animation_effects(animation) + return + +/// Used to start a new animation +/// Accepts the animation to start as an arg +/obj/machinery/door/proc/run_animation(animation) + set_animation(animation) + addtimer(CALLBACK(src, PROC_REF(set_animation), null), animation_length(animation), TIMER_UNIQUE|TIMER_OVERRIDE) + +// React to our animation changing +/obj/machinery/door/proc/set_animation(animation) + src.animation = animation + update_appearance() /// Public proc that simply handles opening the door. Returns TRUE if the door was opened, FALSE otherwise. /// Use argument "forced" in conjunction with try_to_force_door_open if you want/need additional checks depending on how sorely you need the door opened. @@ -433,12 +478,14 @@ return FALSE operating = TRUE use_energy(active_power_usage) - do_animate("opening") + run_animation(DOOR_OPENING_ANIMATION) set_opacity(0) - SLEEP_NOT_DEL(0.5 SECONDS) + var/passable_delay = animation_segment_delay(DOOR_OPENING_PASSABLE) + SLEEP_NOT_DEL(passable_delay) set_density(FALSE) flags_1 &= ~PREVENT_CLICK_UNDER_1 - SLEEP_NOT_DEL(0.5 SECONDS) + var/open_delay = animation_segment_delay(DOOR_OPENING_FINISHED) - passable_delay + SLEEP_NOT_DEL(open_delay) layer = initial(layer) update_appearance() set_opacity(0) @@ -470,12 +517,14 @@ operating = TRUE - do_animate("closing") + run_animation(DOOR_CLOSING_ANIMATION) layer = closingLayer - SLEEP_NOT_DEL(0.5 SECONDS) + var/unpassable_delay = animation_segment_delay(DOOR_CLOSING_UNPASSABLE) + SLEEP_NOT_DEL(unpassable_delay) set_density(TRUE) flags_1 |= PREVENT_CLICK_UNDER_1 - SLEEP_NOT_DEL(0.5 SECONDS) + var/close_delay = animation_segment_delay(DOOR_CLOSING_FINISHED) - unpassable_delay + SLEEP_NOT_DEL(close_delay) update_appearance() if(visible && !glass) set_opacity(1) @@ -556,6 +605,26 @@ /obj/machinery/door/get_dumping_location() return null +/obj/machinery/door/morgue/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.5 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 1.5 SECONDS + if(DOOR_DENY_ANIMATION) + return 0.1 SECONDS + +/obj/machinery/door/morgue/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 1.4 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.5 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 1.5 SECONDS + /obj/machinery/door/proc/lock() return diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 30deaef9183..1de24c94a02 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -609,16 +609,37 @@ if(active) addtimer(CALLBACK(src, PROC_REF(correct_state)), 2 SECONDS, TIMER_UNIQUE) -/obj/machinery/door/firedoor/do_animate(animation) - switch(animation) - if("opening") - flick("[base_icon_state]_opening", src) - if("closing") - flick("[base_icon_state]_closing", src) - /obj/machinery/door/firedoor/update_icon_state() . = ..() - icon_state = "[base_icon_state]_[density ? "closed" : "open"]" + switch(animation) + if(DOOR_OPENING_ANIMATION) + icon_state = "[base_icon_state]_opening" + if(DOOR_CLOSING_ANIMATION) + icon_state = "[base_icon_state]_closing" + if(DOOR_DENY_ANIMATION) + icon_state = "[base_icon_state]_deny" + else + icon_state = "[base_icon_state]_[density ? "closed" : "open"]" + +/obj/machinery/door/firedoor/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.2 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 1.2 SECONDS + if(DOOR_DENY_ANIMATION) + return 0.3 SECONDS + +/obj/machinery/door/firedoor/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 1.0 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.2 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 1.2 SECONDS /obj/machinery/door/firedoor/update_overlays() . = ..() diff --git a/code/game/machinery/doors/passworddoor.dm b/code/game/machinery/doors/passworddoor.dm index df8f7fa936a..bccc243381b 100644 --- a/code/game/machinery/doors/passworddoor.dm +++ b/code/game/machinery/doors/passworddoor.dm @@ -62,22 +62,44 @@ if(access_bypass || ask_for_pass(user)) open() else - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) /obj/machinery/door/password/update_icon_state() . = ..() - icon_state = density ? "closed" : "open" - -/obj/machinery/door/password/do_animate(animation) + //Deny animation would be nice to have. switch(animation) - if("opening") - flick("opening", src) + if(DOOR_OPENING_ANIMATION) + icon_state = "opening" + if(DOOR_CLOSING_ANIMATION) + icon_state = "closing" + else + icon_state = density ? "closed" : "open" + +/obj/machinery/door/password/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.1 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 1.1 SECONDS + +/obj/machinery/door/password/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.5 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.1 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 1.1 SECONDS + +/obj/machinery/door/password/animation_effects(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) playsound(src, door_open, 50, TRUE) - if("closing") - flick("closing", src) + if(DOOR_CLOSING_ANIMATION) playsound(src, door_close, 50, TRUE) - if("deny") - //Deny animation would be nice to have. + if(DOOR_DENY_ANIMATION) playsound(src, door_deny, 30, TRUE) /obj/machinery/door/password/proc/ask_for_pass(mob/user) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 5e90d9dac18..ab18a63361c 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -211,18 +211,42 @@ return FALSE return ..() -/obj/machinery/door/poddoor/do_animate(animation) - switch(animation) - if("opening") - flick("opening", src) - playsound(src, animation_sound, 50, TRUE) - if("closing") - flick("closing", src) - playsound(src, animation_sound, 50, TRUE) - /obj/machinery/door/poddoor/update_icon_state() . = ..() - icon_state = density ? "closed" : "open" + switch(animation) + if(DOOR_OPENING_ANIMATION) + icon_state = "opening" + if(DOOR_CLOSING_ANIMATION) + icon_state = "closing" + if(DOOR_DENY_ANIMATION) + icon_state = "deny" + else + icon_state = density ? "closed" : "open" + +/obj/machinery/door/poddoor/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.1 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 1.1 SECONDS + +/obj/machinery/door/poddoor/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.5 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.1 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 1.1 SECONDS + +/obj/machinery/door/poddoor/animation_effects(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + playsound(src, animation_sound, 50, TRUE) + if(DOOR_CLOSING_ANIMATION) + playsound(src, animation_sound, 50, TRUE) /obj/machinery/door/poddoor/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) if(density & !(resistance_flags & INDESTRUCTIBLE)) diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 0df6024ca82..56e2f5a9743 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -11,6 +11,24 @@ recipe_type = /datum/crafting_recipe/shutters animation_sound = 'sound/machines/shutter.ogg' +/obj/machinery/door/poddoor/shutters/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.388 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 1.388 SECONDS + +/obj/machinery/door/poddoor/shutters/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.76 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.388 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.152 SECONDS + if(DOOR_CLOSING_FINISHED) + return 1.388 SECONDS + /obj/machinery/door/poddoor/shutters/preopen icon_state = "open" density = FALSE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 828177f90a8..0c897c68096 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -76,7 +76,15 @@ /obj/machinery/door/window/update_icon_state() . = ..() - icon_state = "[base_state][density ? null : "open"]" + switch(animation) + if(DOOR_OPENING_ANIMATION) + icon_state = "[base_state]opening" + if(DOOR_CLOSING_ANIMATION) + icon_state = "[base_state]closing" + if(DOOR_DENY_ANIMATION) + icon_state = "[base_state]deny" + else + icon_state = "[base_state][density ? null : "open"]" if(hasPower() && unres_sides) set_light(l_range = 2, l_power = 1) @@ -84,6 +92,24 @@ set_light(l_range = 0) +/obj/machinery/door/window/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 0.9 SECONDS + if(DOOR_CLOSING_ANIMATION) + return 0.9 SECONDS + +/obj/machinery/door/window/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.7 SECONDS + if(DOOR_OPENING_FINISHED) + return 0.9 SECONDS + if(DOOR_CLOSING_UNPASSABLE) + return 0.2 SECONDS + if(DOOR_CLOSING_FINISHED) + return 0.9 SECONDS + /obj/machinery/door/window/update_overlays() . = ..() @@ -135,7 +161,7 @@ if(allowed(occupant)) open_and_close() return - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) return if(!SSticker) return @@ -159,7 +185,7 @@ open_and_close() else - do_animate("deny") + run_animation(DOOR_DENY_ANIMATION) return @@ -218,11 +244,13 @@ if(!operating) //in case of emag operating = TRUE - do_animate("opening") + run_animation(DOOR_OPENING_ANIMATION) playsound(src, 'sound/machines/windowdoor.ogg', 100, TRUE) - icon_state ="[base_state]open" - sleep(1 SECONDS) + var/passable_delay = animation_segment_delay(DOOR_OPENING_PASSABLE) + sleep(passable_delay) set_density(FALSE) + var/open_delay = animation_segment_delay(DOOR_OPENING_FINISHED) - passable_delay + sleep(open_delay) air_update_turf(TRUE, FALSE) update_freelook_sight() @@ -261,14 +289,15 @@ return FALSE operating = TRUE - do_animate("closing") + run_animation(DOOR_CLOSING_ANIMATION) playsound(src, 'sound/machines/windowdoor.ogg', 100, TRUE) - icon_state = base_state - + var/unpassable_delay = animation_segment_delay(DOOR_CLOSING_UNPASSABLE) + sleep(unpassable_delay) set_density(TRUE) air_update_turf(TRUE, TRUE) update_freelook_sight() - sleep(1 SECONDS) + var/close_delay = animation_segment_delay(DOOR_CLOSING_FINISHED) - unpassable_delay + sleep(close_delay) operating = FALSE return TRUE @@ -439,15 +468,6 @@ else to_chat(user, span_warning("The door's motors resist your efforts to force it!")) -/obj/machinery/door/window/do_animate(animation) - switch(animation) - if("opening") - flick("[base_state]opening", src) - if("closing") - flick("[base_state]closing", src) - if("deny") - flick("[base_state]deny", src) - /obj/machinery/door/window/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index 847254d2785..7e7076e842c 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -86,6 +86,18 @@ puzzle_id = null //honestly these cant be closed anyway and im not fucking around with door code anymore INVOKE_ASYNC(src, PROC_REF(try_puzzle_open), null) +/obj/machinery/door/puzzle/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.0 SECONDS + +/obj/machinery/door/puzzle/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 0.8 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.0 SECONDS + /obj/machinery/door/puzzle/Bumped(atom/movable/AM) return !density && ..() diff --git a/code/modules/mapfluff/ruins/icemoonruin_code/library.dm b/code/modules/mapfluff/ruins/icemoonruin_code/library.dm index 1de9ce2dc72..2f3b6381f04 100644 --- a/code/modules/mapfluff/ruins/icemoonruin_code/library.dm +++ b/code/modules/mapfluff/ruins/icemoonruin_code/library.dm @@ -5,6 +5,18 @@ puzzle_id = "library" open_message = "The door opens with a loud creak." +/obj/machinery/door/puzzle/keycard/library/animation_length(animation) + switch(animation) + if(DOOR_OPENING_ANIMATION) + return 1.2 SECONDS + +/obj/machinery/door/puzzle/keycard/library/animation_segment_delay(animation) + switch(animation) + if(DOOR_OPENING_PASSABLE) + return 1.0 SECONDS + if(DOOR_OPENING_FINISHED) + return 1.2 SECONDS + /obj/item/keycard/library name = "golden key" desc = "A dull, golden key." diff --git a/icons/obj/doors/blastdoor.dmi b/icons/obj/doors/blastdoor.dmi index 9457690cda365a95f35394da068bc7705453ea77..9c7bec103cefa175f85f47a337d68a0a157231dd 100644 GIT binary patch delta 63 zcmV-F0Kos=6y_ALFaZIQlQ98qEQE_QCqKUctQ>AsenDy;6^+7fjv=bkQ&Vs$Q&w>G Va{&hl0Q2ihu7HNT(ipon+RQA7FqxR diff --git a/icons/obj/doors/doorfireglass.dmi b/icons/obj/doors/doorfireglass.dmi index 250b5ca833a89c25b9b224511fa2b108e225319c..83156ae4351e1ba3ec6125e61ab6e5546dcc3a47 100644 GIT binary patch delta 8648 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 delta 8654 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 delta 2294 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 delta 1267 zcmVYDx6#x&ULPIS>T?haG z1anD5K~!jg?U>Pa;vf))Nodm8YB5%$TitDa|Cd|{0S1@>X%DAf$c4w#kCIQ40ROPl zsc9Rcwaw{Nn={4vQ-?J^_o&R7;$7GG&wtND-w*0@ke|K!-tkr2)aGpAFE5IlPsLwe zhi=uhwfQX2uT9&$ZS41T->pPjn@a()U9ZQb?cR6h>$qNT=K<<+*7DVMJ?;;>O~+~Z zcG!=y18-|{DZsYl9_z3l%>XsI7BGK=9S#RKKt(Q}fs{Zq-@}@mwIXFG2dK<_fqy^8 zpo3^@bJl*G&*u;0=P8cc^G92oO99Tg>i~OM6!?_tdsvlA0sh68 z4$*tc)c|$56p-(!=@70|XEi`w&VOoeHu=p+q&5q+l-A{P22vf=FR07!L7?u5=Y|uJ z$eiiw^7%+co?4k2fYZGDIhO+DxqTS)09Cn+X1p6-Rbq+Li{wphuEHtrRBlu0ZP4j$ z{v7)5Nr%g-oXznS4X+?xSLEzbA9&OUit_#Djj;{M6;*A6azkB@Z`22N?|+Q#NUo@A zJCqx0dwi!pFdZ42NUo@A6Uq%WJ=|VUu$y@T5f20c9trHhc5E)1J5oV`nEL`D4+UI( zpdjBz0v<;M07nH%>jRj8NX-D?Hwk3&y~Ke4 zAjf9FaeM{}>jUvK06F#yIF3I9h4q0Mdv5{c3-#Ut#{mUzL1}#;S_eFitOJ0f>p*dR zAY2K39lBC9A{pA0IpNZS_Sj{d;IUa(Q$PA-Do&|ea1k2z+0(RldCn%_s96Zr-S3@@YBI? zTEOmxm;l_(Pyxq(EPrso1mKaXrhv}xgn-HSl)%DCfhO||xOh$rh|~-$JS8AfGhhY0 zQ#%k483Bir*L3%d=Hs427U%+xgz;Z&s)dz?fu=$>t0e{Pr0{?OXGQShg0L=IF z1wJzZpBVv_-~IHiuMhKmNOcd#(d%cpeFjv1C)NR*?}>H5azY@<)mz}|1Ncg4^F1M8 zIU$hbY8|-T!)7E>n~}-)siioz8EH-nxcWe122uhGCj~U81^8VE+;AeQ`V7qZJ#{9O z96ypdo)pN=07R!x#U|g6#HrYDboia+qyVT7V7UO~do&j~jt;+Ze7Ig!7P(#r@Yz4= d1NTuM_z!~H8xI3Y_WJ+;002ovPDHLkV1nIfQ|$l% diff --git a/icons/obj/doors/puzzledoor/default.dmi b/icons/obj/doors/puzzledoor/default.dmi index 49a920613958008c10019315bfa2132b04169bbf..685fc448bdee0a2312b958b6443590f1e51dd271 100644 GIT binary patch delta 1291 zcmV+m1@!vq3!)5=!~vC&#bZ1rUQSLfBf|M?bnOudbL_z6Nann#_*d_{^jeHv;#*p!l7-4ytmq27dW9Q0`RrJFLpJfczz? z0%lx4m_(SRN3C21&o?Cx`zQY8%-gnSH?+;e#=q_Q-hYQRxtoE|wvXHRNBjg8xfYPSJzj7)>`VuBxe++*4^L0~y?H&P zudaitTt_pxJN$muf9<7tJv-5(b&t8!uE>kexm zURUJed_Ium_jZ3NMBJ+Kd~c{}Ey_KO6_7*fE5P{xE|BN@Tp;D80OXheaz0Q9C`Ldr z0*VpH&j(Ne#Rw=yKrsUFfuRsc9w-n2z)^v~34uJG|DOV24d};qMDx!0T*7O0L=HE zLV?I3jRJvZ)C*+i11`Qp0hsSSg#wX78U+H+s2A|(14Di;r(K`#|8t zK2V$w6gz)mlJAk75O8!S^gN&cxJJ_Rfm|TX_oV>jm_Xo!Kyf~h3#9qJ6o4EP2%Hco z&IhX9jHs_5KOevzNEGuxqL>E~%P9eWJ}^21V*-GaGcYC)&Id4oBH!mX!<3gdL%=Zs z?0jJJAjF2u_lBCbLAj@)0&)m_1$I8LeG~%Z=PZBU8*17X<(`6y$RUgs<@rD=kmvhc zAmyb1;Hbd)eBgXO@IL1Qf@{_DKi6D-&o?Sz_Ntig@k=LhR=~w)R3PMggt`$1PW5er z$8iFR5m1bPnj)YW0mTTYBL(aO10~>YCbWR#w17Md9J>Z)%o><6YhcQ+z{cm|iNzX( zd{2KEczyzb@}bQbgnUmJcuosU`4!mwj!yx|_xJ#T69Ojx^8zNn7un4T#C(qr5I7+q zrwG{mPRu~e_xJ#T69Ojt@d87>#{^=&#|H?U5Kz+u?o50}#s~SH9)ROh1n$vK*us22 zDlp0?2$=j%ZA3ob69Y`(69i0tCj>&iCkB6*z$XZp{7wjjd`}E8f%5|TX40a&K)e}I z*PiBPr1Lv1;PO2^0MB^=IVRx3B|QMoj}hqKNnkbKJRky_u7963pg+O(5fRw-?==HD zzvBWi-{Y4~;!_0b=6|kL&;MMjp8r{a+WDVpe*vg&oGs&qfF%F`002ovPDHLkV1gat BW&Z#G delta 1234 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 delta 1694 zcmbW2c{tR09LHzsaXgM`rOCOa(h55fIooliP0oy&Sj;0uO0GtZ%;c9WiY>>OqLHJ7 z8BFd5H8zv87+0cUGOomCMlwTV#@e2;YioC(XaD>>-}m!+zdoOTzNK5b#{3pJ8Qs+sNAD*SELPh=AN*vmV_1;6*ZyviIr0%6YZRj z4oOitg3CbcD+k~Mu9iQXX>>cnFH*n3#BY*_h&L%~xXHP+Q7DRqn2mSQA?Bm4tN;Zn z#&~+ltmQqNM~xOr$jGRAMK-F{IGvx+UChTP$iPf}-A4M@g$o?>6Y9*udW`X1YBI+@ zM@LaI&Wh&U$6-zp(u9Ynkr9q6fc zHt=$W;$$5xdCgjHK?V%M=Hv)0 zV!&x?SX+(6z-JI=o2Cz9af9oj_Agnlf*@u=sCB%)y05a7PBn0U*BI3HnWxoOF?)4MN4 zGc{ow1<0?a(aZ+>tD=Q>qXbO%t#z2llI1y#Y#g~f_}t01-Zrw8Q`Z3`%D9a{*JpIT zi_Z7K&_h`|yL+<-GBTeFcSSXj?XiJQ7lO`0RP=~?N*qQ(e+(nIJs>&;cnfibsCfOR zkeq-EgyktMcAl(%Mxfj2G;F@GU;v=<_)$QD*b)<~P=^_)m|n0sezu~t2`kLxS=Pce z>JMh}NEFo?Sw-awV-6hVKF%<$_WK9IL3H`Wc^g+q@S|_-AI?+wrC0dj#}vjnk$wxS zbxf^SNsk(O1%@ zRvw3#UJv$@n58llI-iU|X|;z&D6^g6)84Awr3{LdE2U zZDMsdzD`&9?w)v8-C-N)9G9SsbY+W~Z98B%$69ZMKd2P@a~0RbKqeNk@$~Sn{5S^5 zTX8KROV8~Cx$`B@utWV7#n%{g-8}}E`r%gYi&+?Y{^vwHAdCMO$l!haf0zJ1Ra_;p zAjNd0RYA?qf+PU|Z8ojE|3^4SXsWsHE)(%bNZ_hjxt=w3hDcg1j`1n~5k92*2@ZTZ z2WfT=$$pAdF@zw7$4HGgNrnNc`E?9Y%5a>HOW=U9O;~cFlvlyavU4fZ+nk^@`)cno zwde3`EnKEQz1fnC{QTbB6^q SP-gX;0UbHyXic#?e))GjonL|g diff --git a/icons/obj/doors/shutters.dmi b/icons/obj/doors/shutters.dmi index 1cc727cdbf7a4d12616dc6516f6f32cc6a815177..5fd2b2a8213d5f86a4d6d87859ff9c8fd95a9ffa 100644 GIT binary patch delta 65 zcmV-H0KWg6jsc~P0g!e9n2~pKE&yGYlb>Gzbc-Rv{rLr{c|+a(*d1?(8cC@sxRfa? Xxca$(BOd_jlX%R~8k|G34gn5Ez)T#~ delta 56 zcmV-80LTBOjscvG0g!e9kCAtBC72*wonMfeH#A+1-N}Zi5t5pMOPR8QtDg%vq5+ux ObJiYzJ6f|B0S-pLQW!4) diff --git a/icons/obj/doors/shutters_radiation.dmi b/icons/obj/doors/shutters_radiation.dmi index 2e70b24a4aa2aacbb463e9099d48ccd5a58e86ae..37b8cf72cbca0a1ce1ecdbcc478e1901683a7bc1 100644 GIT binary patch delta 50 zcmV-20L}llj{&=n0gz__myu|IAE3)}^79K&-46U`} IvjPFMMl7EdKL7v# delta 45 zcmV+|0Mh@vj{&xi0gz__l96bD8WSB8)G!z-?&eZfaP@NmM>PP2pma9OG`gO%2LZH3 Dn4=Np diff --git a/icons/obj/doors/shutters_window.dmi b/icons/obj/doors/shutters_window.dmi index fcf8af5b94fd79e775ef385d4c8e4a0d930d90c5..b86fe675366c133f787600f0e045e158b8fa1dce 100644 GIT binary patch delta 187 zcmV;s07Uv`NL{vJ;Q)>OOOuto_0wlAuQ-r0?1nou@~k}W pemWH?C$hfxk50lr_sh!u+es;!zDC`(^Z?SDc+Atv_Fu8e!Jpt-UrGP~ delta 180 zcmV;l089Up!2*lH0+1wsoqAMQbVOxyV{&P5bZKvH004NL)se9Z!Y~+w=loA`w5ycb z7IeuXDUzXmhhTo&Kut;#6yM&#K?I$}<>25OzT-+9`lBA922EFv$psIIuBu7goXs;N z+J?l;ZkqG6q--)nqBt!fu`Nhg7ZW5p66a_xoFK7%VPR$O{PdY8Yjz|oFXj%3x@z~E ipGNmS?*FXA%KqCSCHhf84VoTgS##Di1YRYv(ZQdf-n%q&-5uKdLrhcK0b6?vt?}|L?yGozL4t}a4JoWia8ktu zHKY)eph8jHA%!GNW(kp*5Dkj()LMy3AvLe5S^L?K6o*lFViE``oBuG`U~Sb^HduS> zT48-Rlaihkg>e{75p+|ivl;O*M0BSwSI+(#2+#dhoU-QzD^8g|hZU#H&f-q#udkcQ zic{v|vdA@-SB2JpW+x-F$Llxc^DPz9L delta 397 zcmV;80doG@{sYeb1CS(tVtQ0qbVOxyV{&P5bZKvH004NLt(3cNgD@0^XZ#dL$%?7~ zX`6+mBB~gYS3nd_uoZ%lO^SH?4oF;5LmZ5lkp2tyr=Kl+9lygf1gDVvqL7Ri;KTlH zN35Eq6$KwWmsk{8MyvKkR&j;k!zPbvR-~MZD3%g$KY6orH^fSRnULVao>&(V-%x@N zF0oR~;|6^2Y;QKfQ71S96J9DUQId1XicGEj>_5r1o$hhR5xm4gtBaRd7;i>uoBF*J5hZx_Y{6$#G?3YO952nEZiDMP_Bst2)Cnzk*$C|E{KIOdVW zZ?%`N(yIyF`L|n4?gEY0yBhWBD9tr%VjpPN zSoRCxAN1=qFF`-B8?aAuo?L4_WmhR@k9|<~O>}Bqc&DBPeNbPwx_8O1wKLCL_PgTn rWDCc00Kq9Fe{sI2Ee6{MIsgD507*naRCt{1y?<~N*O~XTtpTn5T>`mx diff --git a/tgstation.dme b/tgstation.dme index 5663065a768..2ea00d40eba 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -84,6 +84,7 @@ #include "code\__DEFINES\DNA.dm" #include "code\__DEFINES\dna_infuser_defines.dm" #include "code\__DEFINES\do_afters.dm" +#include "code\__DEFINES\door.dm" #include "code\__DEFINES\drone.dm" #include "code\__DEFINES\dye_keys.dm" #include "code\__DEFINES\dynamic.dm"