Files
Aurora.3/code/modules/mob/animations.dm
Geeves 98f088d4ea InUs Game-Helm Upgrade (#15684)
* InUs Game-Helm Upgrade

* forgor

* bribed
2023-09-23 10:26:42 +00:00

302 lines
8.2 KiB
Plaintext

/*
adds a dizziness amount to a mob
use this rather than directly changing var/dizziness
since this ensures that the dizzy_process proc is started
currently only humans get dizzy
value of dizziness ranges from 0 to 1000
below 100 is not dizzy
*/
/mob/var/dizziness = 0//Carbon
/mob/var/is_dizzy = 0
/mob/proc/make_dizzy(var/amount)
if(!istype(src, /mob/living/carbon/human)) // for the moment, only humans get dizzy
return
dizziness = min(1000, dizziness + amount) // store what will be new value
// clamped to max 1000
if(dizziness > 100 && !is_dizzy)
spawn(0)
dizzy_process()
/*
dizzy process - wiggles the client's pixel offset over time
spawned from make_dizzy(), will terminate automatically when dizziness gets <100
note dizziness decrements automatically in the mob's Life() proc.
*/
/mob/proc/dizzy_process()
is_dizzy = 1
while(dizziness > 100)
if(client)
var/amplitude = dizziness*(sin(dizziness * 0.044 * world.time) + 1) / 70
client.pixel_x = amplitude * sin(0.008 * dizziness * world.time)
client.pixel_y = amplitude * cos(0.008 * dizziness * world.time)
sleep(1)
//endwhile - reset the pixel offsets to zero
is_dizzy = 0
if(client)
client.pixel_x = 0
client.pixel_y = 0
// jitteriness - copy+paste of dizziness
/mob/var/is_jittery = 0
/mob/var/jitteriness = 0//Carbon
/mob/proc/make_jittery(var/amount)
return
/mob/living/carbon/human/make_jittery(amount)
jitteriness = min(1000, jitteriness + amount) // store what will be new value
// clamped to max 1000
if(jitteriness > 100 && !is_jittery && stat != DEAD && !(status_flags & FAKEDEATH))
spawn(0)
jittery_process()
/mob/proc/jittery_process()
is_jittery = TRUE
while(jitteriness > 100)
var/amplitude = min(4, jitteriness / 100)
pixel_x = old_x + rand(-amplitude, amplitude)
pixel_y = old_y + rand(-amplitude/3, amplitude/3)
if(stat == DEAD || (status_flags & FAKEDEATH))
break
sleep(1)
//endwhile - reset the pixel offsets to zero
is_jittery = FALSE
pixel_x = old_x
pixel_y = old_y
//handles up-down floaty effect in space and zero-gravity
/mob/var/is_floating = FALSE
/mob/proc/update_floating()
if(anchored || buckled_to)
set_floating(FALSE)
return
var/turf/turf = get_turf(src)
if(!turf?.is_hole)
var/area/A = turf.loc
if(istype(A) && A.has_gravity())
set_floating(FALSE)
return
else
var/shoegrip = Check_Shoegrip()
if(shoegrip)
set_floating(FALSE)
return
else
if(CanAvoidGravity())
set_floating(TRUE)
return
else
set_floating(FALSE)
return
set_floating(TRUE)
/mob/proc/set_floating(var/floating_state)
if(buckled_to && is_floating)
stop_floating()
return
if(floating_state && !is_floating)
start_floating()
else if(!floating_state && is_floating)
stop_floating()
/mob/proc/start_floating()
is_floating = TRUE
var/amplitude = 2 //maximum displacement from original position
var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4
var/top = old_y + amplitude
var/bottom = old_y - amplitude
var/half_period = period / 2
var/quarter_period = period / 4
animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up
animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down
animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back
/mob/proc/stop_floating()
animate(src, pixel_y = get_standard_pixel_y(), time = 5, easing = SINE_EASING | EASE_IN) //halt animation
//reset the pixel offsets to defaults
is_floating = FALSE
/atom/movable/proc/do_attack_animation(atom/A, atom/movable/weapon, var/image/attack_image, var/initial_pixel_x = 0, var/initial_pixel_y = 0)
var/pixel_x_diff = 0
var/pixel_y_diff = 0
var/turn_dir = 1
var/direction = get_dir(src, A)
switch(direction)
if(NORTH)
pixel_y_diff = 8
if(SOUTH)
pixel_y_diff = -8
if(EAST)
pixel_x_diff = 8
if(WEST)
pixel_x_diff = -8
if(NORTHEAST)
pixel_x_diff = 8
pixel_y_diff = 8
if(NORTHWEST)
pixel_x_diff = -8
pixel_y_diff = 8
if(SOUTHEAST)
pixel_x_diff = 8
pixel_y_diff = -8
if(SOUTHWEST)
pixel_x_diff = -8
pixel_y_diff = -8
if(direction & NORTH)
pixel_y_diff = 8
turn_dir = rand(50) ? -1 : 1
else if(direction & SOUTH)
pixel_y_diff = -8
turn_dir = rand(50) ? -1 : 1
if(direction & EAST)
pixel_x_diff = 8
else if(direction & WEST)
pixel_x_diff = -8
turn_dir = -1
if(!initial_pixel_x)
initial_pixel_x = initial(pixel_x)
if(!initial_pixel_y)
initial_pixel_y = initial(pixel_y)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = initial_pixel_x, pixel_y = initial_pixel_y, time = 2)
var/matrix/initial_transform = matrix(transform)
var/matrix/rotated_transform = transform.Turn(15 * turn_dir)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform = rotated_transform, time = 2, easing = BACK_EASING | EASE_IN)
animate(pixel_x = initial_pixel_x, pixel_y = initial_pixel_y, transform = initial_transform, time = 2, easing = SINE_EASING)
// either attack_item OR attack_image should be used. if both are used, attack_image will be the one chosen
/mob/do_attack_animation(atom/A, var/atom/attack_item, var/image/attack_image)
var/initial_pixel_x = get_standard_pixel_x()
var/initial_pixel_y = get_standard_pixel_y()
..(A, attack_item, attack_image, initial_pixel_x, initial_pixel_y)
if(is_floating)
addtimer(CALLBACK(src, PROC_REF(start_floating)), 4)
if(attack_item == FIST_ATTACK_ANIMATION) // only play the physical movement
return
// What icon do we use for the attack?
var/image/I
if(attack_image)
I = attack_image
else if(attack_item)
I = image(attack_item.icon, A, attack_item.icon_state, A.layer + 1)
else
if(hand && l_hand) // Attacked with item in left hand.
I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 1)
else if (!hand && r_hand) // Attacked with item in right hand.
I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 1)
else // Attacked with a fist?
return
// Who can see the attack?
var/list/viewing = list()
for (var/mob/M in viewers(A))
if (M.client)
viewing |= M.client
flick_overlay(I, viewing, 5) // 5 ticks/half a second
// Scale the icon.
I.transform *= 0.75
// Set the direction of the icon animation.
var/direction = get_dir(src, A)
if(direction & NORTH)
I.pixel_y = -16
else if(direction & SOUTH)
I.pixel_y = 16
if(direction & EAST)
I.pixel_x = -16
else if(direction & WEST)
I.pixel_x = 16
if(!direction) // Attacked self?!
I.pixel_z = 16
var/matrix/M = new
M.Turn(pick(-20, 20))
// And animate the attack!
animate(I, alpha = 175, pixel_x = initial_pixel_x, pixel_y = initial_pixel_y, pixel_z = 0, time = 2, easing = CUBIC_EASING)
sleep(2)
animate(I, transform = M, time = 1) // apply the fancy matrix
sleep(1)
animate(I, transform = matrix(), time = 1) // back to a default matrix
sleep(1)
animate(I, alpha = 0, time = 1)
/mob/proc/spin(spintime, speed)
spawn()
var/D = dir
while(spintime >= speed)
sleep(speed)
switch(D)
if(NORTH)
D = EAST
if(SOUTH)
D = WEST
if(EAST)
D = SOUTH
if(WEST)
D = NORTH
set_dir(D)
spintime -= speed
return
// Mob Throwing Animation
/mob/proc/animate_throw()
var/ipx = pixel_x
var/ipy = pixel_y
var/mpx = 0
var/mpy = 0
if(dir & NORTH)
mpy += 3
else if(dir & SOUTH)
mpy -= 3
if(dir & EAST)
mpx += 3
else if(dir & WEST)
mpx -= 3
var/new_x = mpx + ipx
var/new_y = mpy + ipy
animate(src, pixel_x = new_x, pixel_y = new_y, time = 0.6, easing = EASE_OUT)
var/matrix/M = matrix(transform)
animate(transform = turn(transform, (mpx - mpy) * 4), time = 0.6, easing = EASE_OUT)
animate(pixel_x = ipx, pixel_y = ipy, time = 0.6, easing = EASE_IN)
animate(transform = M, time = 0.6, easing = EASE_IN)
if(is_floating)
addtimer(CALLBACK(src, PROC_REF(start_floating)), 2.4)
/atom/proc/quick_jitter(var/jitter_time = 5)
set waitfor = 0
jitter_time--
pixel_x = jitter_time ? get_standard_pixel_x() + rand(-3, 3) : get_standard_pixel_x()
pixel_y = jitter_time ? get_standard_pixel_y() + rand(-1, 1) : get_standard_pixel_y()
if(jitter_time)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, quick_jitter), jitter_time), 1)