[MIRROR] Stabilizes code that flicks overlays to view/all clients [MDB IGNORE] (#22601)

* Stabilizes code that flicks overlays to view/all clients (#76937)

## About The Pull Request

Rather then using images and displaying them with client.images, we can
instead simply make an object, give it the passed in image/MA's
appearance, and then vis_contents it where we want.

If you want to animate things, you can just use the atom we return from
the proc call.

This ends up costing about 25% of the best case scenario (one guy
online)
It will save more time with more users, but it also allows us to avoid
the hypersuffering that is passing GLOB.clients into the flick proc. So
I think I'm happy enough with this.

For context, here's average per call cost for flick_overlay_view() right
now.
It winds between 5e-5 and 1e-4. With these changes we should pretty
consistently hit the low end of this, because none of our work really
varies all that much.

![flick_avg](https://github.com/tgstation/tgstation/assets/58055496/3483e022-9cc5-490a-be5e-eb79f4e2110b)

(I was using sswardrobe for this, but it ends up being a lot slower so
like, why yaknow)
```
/atom/movable/flick_visual
        New: 3.65625ms
        Provide: 7.4375ms
        Qdel: 9.4375ms
        Stash: 9.46875ms
```

## Why It's Good For The Game

Using our tools should not make your code eat cpu time for no reason.
Hearers is expensive, iterating clients is expensive, let's not be
expensive.

* Stabilizes code that flicks overlays to view/all clients

* Not every client needs to see this

* and these could be using SECONDS

* grr DM

* Convert these modular files to seconds too

* Update dance_machine.dm

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-07-20 18:59:09 -04:00
committed by GitHub
co-authored by LemonInTheDark Giz
parent d9c9533383
commit 8782f19258
23 changed files with 118 additions and 94 deletions
+33 -10
View File
@@ -139,8 +139,7 @@
for(var/client/remove_from in hide_from)
remove_from.images -= image_to_remove
///Add an image to a list of clients and calls a proc to remove it after a duration
/// Add an image to a list of clients and calls a proc to remove it after a duration
/proc/flick_overlay_global(image/image_to_show, list/show_to, duration)
if(!show_to || !length(show_to) || !image_to_show)
return
@@ -148,7 +147,7 @@
add_to.images += image_to_show
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_image_from_clients), image_to_show, show_to), duration, TIMER_CLIENT_TIME)
/// Flicks a certain overlay onto an atom, handling icon_state strings
///Flicks a certain overlay onto an atom, handling icon_state strings
/atom/proc/flick_overlay(image_to_show, list/show_to, duration, layer)
var/image/passed_image = \
istext(image_to_show) \
@@ -157,13 +156,37 @@
flick_overlay_global(passed_image, show_to, duration)
/// flicks an overlay to anyone who can view this atom
/atom/proc/flick_overlay_view(image_to_show, duration)
var/list/viewing = list()
for(var/mob/viewer as anything in viewers(src))
if(viewer.client)
viewing += viewer.client
flick_overlay(image_to_show, viewing, duration)
/**
* Helper atom that copies an appearance and exists for a period
*/
/atom/movable/flick_visual
/// Takes the passed in MA/icon_state, mirrors it onto ourselves, and displays that in world for duration seconds
/// Returns the displayed object, you can animate it and all, but you don't own it, we'll delete it after the duration
/atom/proc/flick_overlay_view(mutable_appearance/display, duration)
if(!display)
return null
var/mutable_appearance/passed_appearance = \
istext(display) \
? mutable_appearance(icon, display, layer) \
: display
// If you don't give it a layer, we assume you want it to layer on top of this atom
// Because this is vis_contents, we need to set the layer manually (you can just set it as you want on return if this is a problem)
if(passed_appearance.layer == FLOAT_LAYER)
passed_appearance.layer = layer + 0.1
// This is faster then pooling. I promise
var/atom/movable/flick_visual/visual = new()
visual.appearance = passed_appearance
// I hate /area
var/atom/movable/lies_to_children = src
lies_to_children.vis_contents += visual
QDEL_IN_CLIENT_TIME(visual, duration)
return visual
/area/flick_overlay_view(mutable_appearance/display, duration)
return
///Get active players who are playing in the round
/proc/get_active_player_count(alive_check = FALSE, afk_check = FALSE, human_check = FALSE)
+1 -1
View File
@@ -310,7 +310,7 @@ SUBSYSTEM_DEF(wardrobe)
initial_callbacks[/obj/item/organ] = play_with
play_with = new /list(WARDROBE_CALLBACK_REMOVE)
play_with[WARDROBE_CALLBACK_REMOVE] = CALLBACK(null, TYPE_PROC_REF(/obj/item/storage/box/survival,wardrobe_removal))
play_with[WARDROBE_CALLBACK_REMOVE] = CALLBACK(null, TYPE_PROC_REF(/obj/item/storage/box/survival, wardrobe_removal))
initial_callbacks[/obj/item/storage/box/survival] = play_with
/datum/controller/subsystem/wardrobe/proc/load_outfits()
+1 -1
View File
@@ -60,7 +60,7 @@
///overlays managed by [update_overlays][/atom/proc/update_overlays] to prevent removing overlays that weren't added by the same proc. Single items are stored on their own, not in a list.
var/list/managed_overlays
/// Lazylist of all images (hopefully attached to us) to update when we change z levels
/// Lazylist of all images (or atoms, I'm sorry) (hopefully attached to us) to update when we change z levels
/// You will need to manage adding/removing from this yourself, but I'll do the updating for you
var/list/image/update_on_z
+1 -1
View File
@@ -1169,7 +1169,7 @@
if(update_on_z)
// I so much wish this could be somewhere else. alas, no.
for(var/image/update in update_on_z)
for(var/image/update as anything in update_on_z)
SET_PLANE(update, PLANE_TO_TRUE(update.plane), new_turf)
if(update_overlays_on_z)
// This EVEN more so
+2 -2
View File
@@ -250,8 +250,8 @@
if(next_beep <= world.time)
next_beep = world.time + (2 SECONDS)
playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE)
var/image/alarm_image = image(icon, src, "alarm_light", layer+1)
flick_overlay_view(alarm_image, 2 SECONDS)
var/mutable_appearance/alarm_display = mutable_appearance(icon, "alarm_light")
flick_overlay_view(alarm_display, 2 SECONDS)
set_scanline("alarm", 2 SECONDS)
/obj/machinery/scanner_gate/can_interact(mob/user)
+11 -11
View File
@@ -1436,7 +1436,7 @@
if(!istype(loc, /turf))
return
source = loc
var/image/pickup_animation = image(icon = src, loc = source, layer = layer + 0.1)
var/image/pickup_animation = image(icon = src)
SET_PLANE(pickup_animation, GAME_PLANE, source)
pickup_animation.transform.Scale(0.75)
pickup_animation.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
@@ -1457,13 +1457,13 @@
to_y += 10
pickup_animation.pixel_x += 6 * (prob(50) ? 1 : -1) //6 to the right or left, helps break up the straight upward move
flick_overlay_global(pickup_animation, GLOB.clients, 4)
var/matrix/animation_matrix = new(pickup_animation.transform)
var/atom/movable/flick_visual/pickup = source.flick_overlay_view(pickup_animation, 0.4 SECONDS)
var/matrix/animation_matrix = new(pickup.transform)
animation_matrix.Turn(pick(-30, 30))
animation_matrix.Scale(0.65)
animate(pickup_animation, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = animation_matrix, easing = CUBIC_EASING)
animate(alpha = 0, transform = matrix().Scale(0.7), time = 1)
animate(pickup, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 0.3 SECONDS, transform = animation_matrix, easing = CUBIC_EASING)
animate(alpha = 0, transform = matrix().Scale(0.7), time = 0.1 SECONDS)
/obj/item/proc/do_drop_animation(atom/moving_from)
if(!istype(loc, /turf))
@@ -1510,9 +1510,9 @@
/atom/movable/proc/do_item_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item)
var/image/attack_image
if(visual_effect_icon)
attack_image = image('icons/effects/effects.dmi', attacked_atom, visual_effect_icon, attacked_atom.layer + 0.1)
attack_image = image(icon = 'icons/effects/effects.dmi', icon_state = visual_effect_icon)
else if(used_item)
attack_image = image(icon = used_item, loc = attacked_atom, layer = attacked_atom.layer + 0.1)
attack_image = image(icon = used_item)
attack_image.plane = attacked_atom.plane + 1
// Scale the icon.
@@ -1539,12 +1539,12 @@
if(!attack_image)
return
flick_overlay_global(attack_image, GLOB.clients, 10)
var/atom/movable/flick_visual/attack = attacked_atom.flick_overlay_view(attack_image, 1 SECONDS)
var/matrix/copy_transform = new(transform)
// And animate the attack!
animate(attack_image, alpha = 175, transform = copy_transform.Scale(0.75), pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
animate(time = 1)
animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT)
animate(attack, alpha = 175, transform = copy_transform.Scale(0.75), pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 0.3 SECONDS)
animate(time = 0.1 SECONDS)
animate(alpha = 0, time = 0.3 SECONDS, easing = CIRCULAR_EASING|EASE_OUT)
/// Common proc used by painting tools like spraycans and palettes that can access the entire 24 bits color space.
/obj/item/proc/pick_painting_tool_color(mob/user, default_color)
@@ -165,16 +165,16 @@
//laser pointer image
icon_state = "pointer_[pointer_icon_state]"
var/image/I = image('icons/obj/weapons/guns/projectiles.dmi',targloc,pointer_icon_state,10)
var/mutable_appearance/laser = mutable_appearance('icons/obj/weapons/guns/projectiles.dmi', pointer_icon_state, 10)
var/list/modifiers = params2list(params)
if(modifiers)
if(LAZYACCESS(modifiers, ICON_X))
I.pixel_x = (text2num(LAZYACCESS(modifiers, ICON_X)) - 16)
laser.pixel_x = (text2num(LAZYACCESS(modifiers, ICON_X)) - 16)
if(LAZYACCESS(modifiers, ICON_Y))
I.pixel_y = (text2num(LAZYACCESS(modifiers, ICON_Y)) - 16)
laser.pixel_y = (text2num(LAZYACCESS(modifiers, ICON_Y)) - 16)
else
I.pixel_x = target.pixel_x + rand(-5,5)
I.pixel_y = target.pixel_y + rand(-5,5)
laser.pixel_x = target.pixel_x + rand(-5,5)
laser.pixel_y = target.pixel_y + rand(-5,5)
if(outmsg)
to_chat(user, outmsg)
@@ -190,7 +190,7 @@
to_chat(user, span_warning("[src]'s battery is overused, it needs time to recharge!"))
recharge_locked = TRUE
targloc.flick_overlay_view(I, 10)
targloc.flick_overlay_view(laser, 1 SECONDS)
icon_state = "pointer"
/obj/item/laser_pointer/process(seconds_per_tick)
@@ -81,18 +81,19 @@
/// Does the MGS ! animation
/atom/proc/do_alert_animation()
var/image/alert_image = image('icons/obj/storage/closet.dmi', src, "cardboard_special", layer+1)
SET_PLANE_EXPLICIT(alert_image, ABOVE_LIGHTING_PLANE, src)
flick_overlay_view(alert_image, 0.8 SECONDS)
alert_image.alpha = 0
animate(alert_image, pixel_z = 32, alpha = 255, time = 0.5 SECONDS, easing = ELASTIC_EASING)
var/mutable_appearance/alert = mutable_appearance('icons/obj/storage/closet.dmi', "cardboard_special")
SET_PLANE_EXPLICIT(alert, ABOVE_LIGHTING_PLANE, src)
var/atom/movable/flick_visual/exclamation = flick_overlay_view(alert, 1 SECONDS)
exclamation.alpha = 0
animate(exclamation, pixel_z = 32, alpha = 255, time = 0.5 SECONDS, easing = ELASTIC_EASING)
// We use this list to update plane values on parent z change, which is why we need the timer too
// I'm sorry :(
LAZYADD(update_on_z, alert_image)
addtimer(CALLBACK(src, PROC_REF(forget_alert_image), alert_image), 0.8 SECONDS)
LAZYADD(update_on_z, exclamation)
// Intentionally less time then the flick so we don't get weird shit
addtimer(CALLBACK(src, PROC_REF(forget_alert), exclamation), 0.8 SECONDS, TIMER_CLIENT_TIME)
/atom/proc/forget_alert_image(image/alert_image)
LAZYREMOVE(update_on_z, alert_image)
/atom/proc/forget_alert(atom/movable/flick_visual/exclamation)
LAZYREMOVE(update_on_z, exclamation)
/obj/structure/closet/cardboard/metal
name = "large metal box"
@@ -105,9 +105,9 @@
if(!has_buckled_mobs())
end_workout()
return FALSE
var/image/workout_icon = new(icon, src, "[base_icon_state]-o", ABOVE_MOB_LAYER)
workout_icon.plane = GAME_PLANE_UPPER
flick_overlay_view(workout_icon, 8)
var/mutable_appearance/workout = mutable_appearance(icon, "[base_icon_state]-o", ABOVE_MOB_LAYER)
SET_PLANE_EXPLICIT(workout, GAME_PLANE_UPPER, src)
flick_overlay_view(workout, 0.8 SECONDS)
flick("[base_icon_state]-u", src)
var/mob/living/user = buckled_mobs[1]
animate(user, pixel_y = pixel_shift_y, time = 4)
+1 -1
View File
@@ -708,7 +708,7 @@
/turf/closed/mineral/gibtonite/proc/countdown(notify_admins = FALSE)
set waitfor = FALSE
while(istype(src, /turf/closed/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineralAmt >= 1)
flick_overlay_view(image('icons/turf/smoothrocks.dmi', src, "rock_Gibtonite_active"), 5) //makes the animation pulse one time per tick
flick_overlay_view(mutable_appearance('icons/turf/smoothrocks.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER + 0.1), 0.5 SECONDS) //makes the animation pulse one time per tick
det_time--
sleep(0.5 SECONDS)
if(istype(src, /turf/closed/mineral/gibtonite))
@@ -129,10 +129,10 @@
/datum/status_effect/fire_blasted/on_apply()
if(owner.on_fire && animate_duration > 0 SECONDS)
var/image/warning_sign = image(icon = 'icons/effects/effects.dmi', icon_state = "blessed", layer = BELOW_MOB_LAYER, loc = owner)
owner.flick_overlay_view(warning_sign, initial(duration))
warning_sign.alpha = 50
animate(warning_sign, alpha = 255, time = animate_duration)
var/mutable_appearance/warning_sign = mutable_appearance('icons/effects/effects.dmi', "blessed", BELOW_MOB_LAYER)
var/atom/movable/flick_visual/warning = owner.flick_overlay_view(warning_sign, initial(duration))
warning.alpha = 50
animate(warning, alpha = 255, time = animate_duration)
return TRUE
+2 -2
View File
@@ -861,9 +861,9 @@
// Beakers, bottles, buckets, etc.
if(reagent_source.is_drainable())
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
var/image/splash_animation = image('icons/effects/effects.dmi', src, "splash_hydroponics")
var/mutable_appearance/splash_animation = mutable_appearance('icons/effects/effects.dmi', "splash_hydroponics")
splash_animation.color = mix_color_from_reagents(reagent_source.reagents.reagent_list)
flick_overlay_global(splash_animation, GLOB.clients, 1.1 SECONDS)
flick_overlay_view(splash_animation, 1.1 SECONDS)
if(visi_msg)
visible_message(span_notice("[visi_msg]."))
+5 -5
View File
@@ -518,13 +518,13 @@
*/
/mob/living/proc/do_slap_animation(atom/slapped)
do_attack_animation(slapped, no_effect=TRUE)
var/image/gloveimg = image('icons/effects/effects.dmi', slapped, "slapglove", slapped.layer + 0.1)
gloveimg.pixel_y = 10 // should line up with head
gloveimg.pixel_x = 10
flick_overlay_global(gloveimg, GLOB.clients, 10)
var/mutable_appearance/glove_appearance = mutable_appearance('icons/effects/effects.dmi', "slapglove")
glove_appearance.pixel_y = 10 // should line up with head
glove_appearance.pixel_x = 10
var/atom/movable/flick_visual/glove = slapped.flick_overlay_view(glove_appearance, 1 SECONDS)
// And animate the attack!
animate(gloveimg, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = 10, pixel_z = 0, time = 3)
animate(glove, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = 10, pixel_z = 0, time = 3)
animate(time = 1)
animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT)
@@ -35,7 +35,7 @@
/mob/living/simple_animal/hostile/guardian/protector/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(. > 0 && toggle)
var/image/flash_overlay = new('icons/effects/effects.dmi', src, "shield-flash", layer+0.01, dir = pick(GLOB.cardinals))
var/image/flash_overlay = new('icons/effects/effects.dmi', src, "shield-flash", dir = pick(GLOB.cardinals))
flash_overlay.color = guardian_color
flick_overlay_view(flash_overlay, 0.5 SECONDS)
@@ -71,13 +71,13 @@
return FALSE
adjustHealth(maxHealth * BLOBMOB_BLOBBERNAUT_HEALTH_DECAY * damagesources * seconds_per_tick) //take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both
var/image/image = new('icons/mob/nonhuman-player/blob.dmi', src, "nautdamage", MOB_LAYER+0.01)
image.appearance_flags = RESET_COLOR
var/mutable_appearance/healing = mutable_appearance('icons/mob/nonhuman-player/blob.dmi', "nautdamage", MOB_LAYER+0.01)
healing.appearance_flags = RESET_COLOR
if(overmind)
image.color = overmind.blobstrain.complementary_color
healing.color = overmind.blobstrain.complementary_color
flick_overlay_view(image, 8)
flick_overlay_view(healing, 0.8 SECONDS)
/mob/living/simple_animal/hostile/blob/blobbernaut/AttackingTarget()
. = ..()
+6 -6
View File
@@ -143,11 +143,11 @@
playsound(target, 'sound/effects/slosh.ogg', 25, TRUE)
var/image/splash_animation = image('icons/effects/effects.dmi', target, "splash")
var/mutable_appearance/splash_animation = mutable_appearance('icons/effects/effects.dmi', "splash")
if(isturf(target))
splash_animation = image('icons/effects/effects.dmi', target, "splash_floor")
splash_animation.icon_state = "splash_floor"
splash_animation.color = mix_color_from_reagents(reagents.reagent_list)
flick_overlay_global(splash_animation, GLOB.clients, 1.0 SECONDS)
target.flick_overlay_view(splash_animation, 1 SECONDS)
for(var/datum/reagent/reagent as anything in reagents.reagent_list)
reagent_text += "[reagent] ([num2text(reagent.volume)]),"
@@ -249,11 +249,11 @@
playsound(target, 'sound/effects/slosh.ogg', 25, TRUE)
var/image/splash_animation = image('icons/effects/effects.dmi', target, "splash")
var/mutable_appearance/splash_animation = mutable_appearance('icons/effects/effects.dmi', "splash")
if(isturf(target))
splash_animation = image('icons/effects/effects.dmi', target, "splash_floor")
splash_animation.icon_state = "splash_floor"
splash_animation.color = mix_color_from_reagents(reagents.reagent_list)
flick_overlay_global(splash_animation, GLOB.clients, 1.0 SECONDS)
target.flick_overlay_view(splash_animation, 1.0 SECONDS)
reagents.clear_reagents()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -137,7 +137,7 @@
/// Dispel the sigil and delete itself
/obj/structure/destructible/clockwork/sigil/proc/dispel()
animate(src, transform = matrix() * 1.5, alpha = 0, time = 3)
animate(src, transform = matrix() * 1.5, alpha = 0, time = 0.3 SECONDS)
QDEL_IN(src, 0.3 SECONDS)
#undef SIGIL_INVOCATION_ALPHA
+4 -4
View File
@@ -456,12 +456,12 @@
var/image/gloveimg = image('icons/effects/effects.dmi', slapped, "slapglove", slapped.layer + 0.1)
gloveimg.pixel_y = -5
gloveimg.pixel_x = 0
flick_overlay(gloveimg, GLOB.clients, 10)
flick_overlay_view(gloveimg, 1 SECONDS)
// And animate the attack!
animate(gloveimg, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = -5, pixel_z = 0, time = 3)
animate(time = 1)
animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT)
animate(gloveimg, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = -5, pixel_z = 0, time = 0.3 SECONDS)
animate(time = 0.1 SECONDS)
animate(alpha = 0, time = 0.3 SECONDS, easing = CIRCULAR_EASING|EASE_OUT)
//Froggie Revolution
/datum/emote/living/warble
@@ -319,7 +319,7 @@
)
say(message = pick(spin_messages))
spinning = TRUE
animate(src, color = "#ff6666", 10)
animate(src, color = "#ff6666", 1 SECONDS)
SLEEP_CHECK_DEATH(5, src)
var/list/spinningturfs = list()
var/current_angle = 360
@@ -348,7 +348,7 @@
if(!spinning)
break
sleep(0.75) //addtimer(CALLBACK(src, PROC_REF(convince_zonespace_to_let_me_use_sleeps)), 2 WEEKS)
animate(src, color = initial(color), 3)
animate(src, color = initial(color), 0.3 SECONDS)
sleep(1)
spinning = FALSE
@@ -365,7 +365,7 @@
"COME ON!!",
)
say(message = pick(charge_messages))
animate(src, color = "#ff6666", 3)
animate(src, color = "#ff6666", 0.3 SECONDS)
SLEEP_CHECK_DEATH(4, src)
face_atom(target)
minimum_distance = 0
@@ -379,7 +379,7 @@
minimum_distance = initial(minimum_distance)
chargetiles = 0
playsound(src, 'modular_skyrat/modules/gladiator/Clang_cut.ogg', 75, 0)
animate(src, color = initial(color), 5)
animate(src, color = initial(color), 0.5 SECONDS)
update_phase()
sleep(CEILING(MARKED_ONE_STUN_DURATION * modifier, 1))
stunned = FALSE
@@ -339,41 +339,41 @@
if (1 to 15)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(0,1)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (16 to 30)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(1,-1)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (31 to 45)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(-1,-1)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (46 to 60)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(-1,1)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (61 to 75)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(1,0)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
M.setDir(turn(M.dir, 90))
switch (M.dir)
if (NORTH)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(0,3)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (SOUTH)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(0,-3)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (EAST)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(3,0)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
if (WEST)
initial_matrix = matrix(M.transform)
initial_matrix.Translate(-3,0)
animate(M, transform = initial_matrix, time = 1, loop = 0)
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
sleep(0.1 SECONDS)
M.lying_fix()
@@ -431,7 +431,7 @@
M.lying_fix()
/mob/living/proc/lying_fix()
animate(src, transform = null, time = 1, loop = 0)
animate(src, transform = null, time = 0.1 SECONDS, loop = 0)
lying_prev = 0
/obj/machinery/jukebox/proc/dance_over()
@@ -118,25 +118,25 @@
if(user.loc != src.loc)
return
if(!QDELETED(src))
animate(user, pixel_x = -6, pixel_y = 0, time = 10)
animate(user, pixel_x = -6, pixel_y = 0, time = 1 SECONDS)
sleep(2 SECONDS)
user.dir = 4
if(!QDELETED(src))
animate(user, pixel_x = -6, pixel_y = 24, time = 10)
animate(user, pixel_x = -6, pixel_y = 24, time = 1 SECONDS)
sleep(1.2 SECONDS)
src.layer = 4.01 //move the pole infront for now. better to move the pole, because the character moved behind people sitting above otherwise
if(!QDELETED(src))
animate(user, pixel_x = 6, pixel_y = 12, time = 5)
animate(user, pixel_x = 6, pixel_y = 12, time = 0.5 SECONDS)
user.dir = 8
sleep(0.6 SECONDS)
if(!QDELETED(src))
animate(user, pixel_x = -6, pixel_y = 4, time = 5)
animate(user, pixel_x = -6, pixel_y = 4, time = 0.5 SECONDS)
user.dir = 4
src.layer = 4 // move it back.
sleep(0.6 SECONDS)
if(!QDELETED(src))
user.dir = 1
animate(user, pixel_x = 0, pixel_y = 0, time = 3)
animate(user, pixel_x = 0, pixel_y = 0, time = 0.3 SECONDS)
sleep(0.6 SECONDS)
if(!QDELETED(src))
user.do_jitter_animation()
@@ -86,9 +86,9 @@
if(display_message)
to_chat(user, span_notice("You pull the [magazine_wording] out of \the [src]."))
update_appearance()
animate(src, transform = turn(matrix(), 120), time = 2, loop = 1) //Le johnny robohand again
animate(transform = turn(matrix(), 240), time = 2)
animate(transform = null, time = 2)
animate(src, transform = turn(matrix(), 120), time = 0.2 SECONDS, loop = 1) //Le johnny robohand again
animate(transform = turn(matrix(), 240), time = 0.2 SECONDS)
animate(transform = null, time = 0.2 SECONDS)
//Magazine stuff