mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Item Pickup Brush-Up (#64095)
* Item Pickup Brush-Up Moves pickup animation code to items.dm Removes sleep() from the current pickup animation. This affords it 3 decisecond to animate rather then 1 I believe this was causing the pixel shifting to end early. A 3 decisecond delay is more consistent with the initial pr, and I think feels better. Maybe 2 tick is better? or 3 tick without any ending lag? not sure. Adds a drop animation. Hooks it in to items being removed from a player's hands, or items being transfered to a location. This includes when an item is removed from storage Pickup animations have always felt somewhat stilted to me, and while I don't want the shake and long leadup included in the initial pr, I'm not even sure you can tell it's happening sometimes as things are now It's by definition gonna feel a bit different since well, things are changing. I'm open to feedback on the delays here, especilly on the effect for taking things out of your bag. It's not new, but extending the pickup animation by 2 deciseconds really shows it Lemme know what ya think yeah? * Adds a random x bias to pickup/drops on the same tile, I think this will help lesson how crummy that can look Lowers the same tile y shifting significantly, for similar reasons Adds a Scale(0.7) to the end/start of pickup/drop. I think this makes things look just so much nicer * Makes pickup scale slightly more before bouncing back to the size drop uses. starts out smaller anyway * Moves the attack animation to items.dm. Makes it use the attacked atom's plane, which fixes attack animations playing behind mobs. Also makes it offset slightly on the x axis when you're attacking yourself, looks nicer I think
This commit is contained in:
@@ -1181,44 +1181,6 @@
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN, flags = ANIMATION_PARALLEL)
|
||||
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/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)
|
||||
else if(used_item)
|
||||
attack_image = image(icon = used_item, loc = attacked_atom, layer = attacked_atom.layer + 0.1)
|
||||
attack_image.plane = GAME_PLANE
|
||||
|
||||
// Scale the icon.
|
||||
attack_image.transform *= 0.4
|
||||
// The icon should not rotate.
|
||||
attack_image.appearance_flags = APPEARANCE_UI
|
||||
|
||||
// Set the direction of the icon animation.
|
||||
var/direction = get_dir(src, attacked_atom)
|
||||
if(direction & NORTH)
|
||||
attack_image.pixel_y = -12
|
||||
else if(direction & SOUTH)
|
||||
attack_image.pixel_y = 12
|
||||
|
||||
if(direction & EAST)
|
||||
attack_image.pixel_x = -14
|
||||
else if(direction & WEST)
|
||||
attack_image.pixel_x = 14
|
||||
|
||||
if(!direction) // Attacked self?!
|
||||
attack_image.pixel_z = 16
|
||||
|
||||
if(!attack_image)
|
||||
return
|
||||
|
||||
flick_overlay(attack_image, GLOB.clients, 10)
|
||||
|
||||
// And animate the attack!
|
||||
animate(attack_image, alpha = 175, transform = matrix() * 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)
|
||||
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "<option value='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]'>Follow</option>"
|
||||
@@ -1392,37 +1354,6 @@
|
||||
log_admin("[key_name(usr)] has added deadchat control to [src]")
|
||||
message_admins(span_notice("[key_name(usr)] has added deadchat control to [src]"))
|
||||
|
||||
/obj/item/proc/do_pickup_animation(atom/target)
|
||||
set waitfor = FALSE
|
||||
if(!istype(loc, /turf))
|
||||
return
|
||||
var/image/pickup_animation = image(icon = src, loc = loc, layer = layer + 0.1)
|
||||
pickup_animation.plane = GAME_PLANE
|
||||
pickup_animation.transform *= 0.75
|
||||
pickup_animation.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/direction
|
||||
var/to_x = target.base_pixel_x
|
||||
var/to_y = target.base_pixel_y
|
||||
|
||||
if(!QDELETED(current_turf) && !QDELETED(target))
|
||||
direction = get_dir(current_turf, target)
|
||||
if(direction & NORTH)
|
||||
to_y += 32
|
||||
else if(direction & SOUTH)
|
||||
to_y -= 32
|
||||
if(direction & EAST)
|
||||
to_x += 32
|
||||
else if(direction & WEST)
|
||||
to_x -= 32
|
||||
if(!direction)
|
||||
to_y += 16
|
||||
flick_overlay(pickup_animation, GLOB.clients, 6)
|
||||
var/matrix/animation_matrix = new
|
||||
animation_matrix.Turn(pick(-30, 30))
|
||||
animate(pickup_animation, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = animation_matrix, easing = CUBIC_EASING)
|
||||
sleep(1)
|
||||
animate(pickup_animation, alpha = 0, transform = matrix(), time = 1)
|
||||
|
||||
/**
|
||||
* A wrapper for setDir that should only be able to fail by living mobs.
|
||||
|
||||
@@ -691,6 +691,11 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/on_exit_storage(datum/component/storage/concrete/master_storage)
|
||||
. = ..()
|
||||
var/atom/location = master_storage.real_location()
|
||||
do_drop_animation(location)
|
||||
|
||||
/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(hit_atom && !QDELETED(hit_atom))
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
|
||||
@@ -1260,3 +1265,111 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
/// Whether or not this item can be put into a storage item through attackby
|
||||
/obj/item/proc/attackby_storage_insert(datum/component/storage, atom/storage_holder, mob/user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/proc/do_pickup_animation(atom/target)
|
||||
if(!istype(loc, /turf))
|
||||
return
|
||||
var/image/pickup_animation = image(icon = src, loc = loc, layer = layer + 0.1)
|
||||
pickup_animation.plane = GAME_PLANE
|
||||
pickup_animation.transform.Scale(0.75)
|
||||
pickup_animation.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/direction = get_dir(current_turf, target)
|
||||
var/to_x = target.base_pixel_x
|
||||
var/to_y = target.base_pixel_y
|
||||
|
||||
if(direction & NORTH)
|
||||
to_y += 32
|
||||
else if(direction & SOUTH)
|
||||
to_y -= 32
|
||||
if(direction & EAST)
|
||||
to_x += 32
|
||||
else if(direction & WEST)
|
||||
to_x -= 32
|
||||
if(!direction)
|
||||
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(pickup_animation, GLOB.clients, 4)
|
||||
var/matrix/animation_matrix = new
|
||||
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)
|
||||
|
||||
/obj/item/proc/do_drop_animation(atom/moving_from)
|
||||
if(!istype(loc, /turf))
|
||||
return
|
||||
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/direction = get_dir(moving_from, current_turf)
|
||||
var/from_x = moving_from.base_pixel_x
|
||||
var/from_y = moving_from.base_pixel_y
|
||||
|
||||
if(direction & NORTH)
|
||||
from_y -= 32
|
||||
else if(direction & SOUTH)
|
||||
from_y += 32
|
||||
if(direction & EAST)
|
||||
from_x -= 32
|
||||
else if(direction & WEST)
|
||||
from_x += 32
|
||||
if(!direction)
|
||||
from_y += 10
|
||||
from_x += 6 * (prob(50) ? 1 : -1) //6 to the right or left, helps break up the straight upward move
|
||||
|
||||
//We're moving from these chords to our current ones
|
||||
var/old_x = pixel_x
|
||||
var/old_y = pixel_y
|
||||
var/old_alpha = alpha
|
||||
var/matrix/animation_matrix = new
|
||||
animation_matrix.Turn(pick(-30, 30))
|
||||
animation_matrix.Scale(0.7) // Shrink to start, end up normal sized
|
||||
|
||||
pixel_x = from_x
|
||||
pixel_y = from_y
|
||||
alpha = 0
|
||||
transform = animation_matrix
|
||||
|
||||
// This is instant on byond's end, but to our clients this looks like a quick drop
|
||||
animate(src, alpha = old_alpha, pixel_x = old_x, pixel_y = old_y, transform = matrix(), time = 3, easing = CUBIC_EASING)
|
||||
|
||||
/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)
|
||||
else if(used_item)
|
||||
attack_image = image(icon = used_item, loc = attacked_atom, layer = attacked_atom.layer + 0.1)
|
||||
attack_image.plane = attacked_atom.plane
|
||||
|
||||
// Scale the icon.
|
||||
attack_image.transform *= 0.4
|
||||
// The icon should not rotate.
|
||||
attack_image.appearance_flags = APPEARANCE_UI
|
||||
|
||||
// Set the direction of the icon animation.
|
||||
var/direction = get_dir(src, attacked_atom)
|
||||
if(direction & NORTH)
|
||||
attack_image.pixel_y = -12
|
||||
else if(direction & SOUTH)
|
||||
attack_image.pixel_y = 12
|
||||
|
||||
if(direction & EAST)
|
||||
attack_image.pixel_x = -14
|
||||
else if(direction & WEST)
|
||||
attack_image.pixel_x = 14
|
||||
|
||||
if(!direction) // Attacked self?!
|
||||
attack_image.pixel_y = 12
|
||||
attack_image.pixel_x = 5 * (prob(50) ? 1 : -1)
|
||||
|
||||
if(!attack_image)
|
||||
return
|
||||
|
||||
flick_overlay(attack_image, GLOB.clients, 10)
|
||||
// And animate the attack!
|
||||
animate(attack_image, alpha = 175, transform = matrix() * 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)
|
||||
|
||||
@@ -281,13 +281,17 @@
|
||||
*/
|
||||
/mob/proc/dropItemToGround(obj/item/I, force = FALSE, silent = FALSE, invdrop = TRUE)
|
||||
. = doUnEquip(I, force, drop_location(), FALSE, invdrop = invdrop, silent = silent)
|
||||
if(. && I && !(I.item_flags & NO_PIXEL_RANDOM_DROP)) //ensure the item exists and that it was dropped properly.
|
||||
if(!. || !I) //ensure the item exists and that it was dropped properly.
|
||||
return
|
||||
if(!(I.item_flags & NO_PIXEL_RANDOM_DROP))
|
||||
I.pixel_x = I.base_pixel_x + rand(-6, 6)
|
||||
I.pixel_y = I.base_pixel_y + rand(-6, 6)
|
||||
I.do_drop_animation(src)
|
||||
|
||||
//for when the item will be immediately placed in a loc other than the ground
|
||||
/mob/proc/transferItemToLoc(obj/item/I, newloc = null, force = FALSE, silent = TRUE)
|
||||
return doUnEquip(I, force, newloc, FALSE, silent = silent)
|
||||
. = doUnEquip(I, force, newloc, FALSE, silent = silent)
|
||||
I.do_drop_animation(src)
|
||||
|
||||
//visibly unequips I but it is NOT MOVED AND REMAINS IN SRC
|
||||
//item MUST BE FORCEMOVE'D OR QDEL'D
|
||||
|
||||
Reference in New Issue
Block a user