diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 3c050c1819..78c6944075 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -339,6 +339,23 @@ proc return 1 #undef SIGN +/proc/flick_overlay(image/I, list/show_to, duration, gc_after) + for(var/client/C in show_to) + C.images += I + spawn(duration) + if(gc_after) + qdel(I) + for(var/client/C in show_to) + C.images -= I + +/proc/flick_overlay_view(image/I, atom/target, duration, gc_after) //wrapper for the above, flicks to everyone who can see the target atom + var/list/viewing = list() + for(var/m in viewers(target)) + var/mob/M = m + if(M.client) + viewing += M.client + flick_overlay(I, viewing, duration, gc_after) + proc/isInSight(var/atom/A, var/atom/B) var/turf/Aturf = get_turf(A) var/turf/Bturf = get_turf(B) diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 1ff49edba2..34b32d5873 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -442,4 +442,5 @@ SUBSYSTEM_DEF(garbage) /image/Destroy() ..() - return QDEL_HINT_HARDDEL_NOW + loc = null + return QDEL_HINT_QUEUE diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index 71559fed0e..07047c36df 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -98,6 +98,12 @@ var/list/_client_preferences_by_type enabled_description = "Show" disabled_description = "Hide" +/datum/client_preference/attack_icons + description ="Attack icons" + key = "ATTACK_ICONS" + enabled_description = "Show" + disabled_description = "Hide" + /datum/client_preference/show_typing_indicator description ="Typing indicator" key = "SHOW_TYPING" diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index 5ba954106b..9074357afa 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -140,39 +140,86 @@ note dizziness decrements automatically in the mob's Life() proc. //reset the pixel offsets to zero is_floating = 0 -/atom/movable/proc/do_attack_animation(mob/M) +/atom/movable/proc/do_attack_animation(atom/A) var/pixel_x_diff = 0 var/pixel_y_diff = 0 - var/direction = get_dir(src, M) - 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 - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = old_x, pixel_y = old_y, time = 2) + var/direction = get_dir(src, A) + if(direction & NORTH) + pixel_y_diff = 8 + else if(direction & SOUTH) + pixel_y_diff = -8 -/mob/do_attack_animation(atom/A) + if(direction & EAST) + pixel_x_diff = 8 + else if(direction & WEST) + pixel_x_diff = -8 + + var/default_pixel_x = initial(pixel_x) + var/default_pixel_y = initial(pixel_y) + var/mob/mob = src + if(istype(mob)) + default_pixel_x = mob.default_pixel_x + default_pixel_y = mob.default_pixel_y + + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) + animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) + +/mob/living/do_attack_animation(atom/A) ..() is_floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. + // What icon do we use for the attack? + var/obj/used_item + if(hand && l_hand) // Attacked with item in left hand. + used_item = l_hand + else if (!hand && r_hand) // Attacked with item in right hand. + used_item = r_hand + + //Couldn't find an item, do they have a sprite specified (like animal claw stuff?) + if(!used_item && !(attack_icon && attack_icon_state)) + return FALSE //Didn't find an item, not doing animation. + + var/image/I + + if(used_item) //Found an in-hand item to animate + I = image(used_item.icon, A, used_item.icon_state, A.layer + 1) + //Color the icon + I.color = used_item.color + // Scale the icon. + I.transform *= 0.75 + else //They had a hardcoded one specified + I = image(attack_icon, A, attack_icon_state, A.layer + 1) + I.dir = dir + + //Check for clients with pref enabled + var/list/viewing = list() + for(var/m in viewers(A)) + var/mob/M = m + var/client/C = M.client + if(C && C.is_preference_enabled(/datum/client_preference/attack_icons)) + viewing += M.client + flick_overlay(I, viewing, 5, TRUE) // 5 ticks/half a second + + // 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 + + // And animate the attack! + animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) + return TRUE //Found an item, doing item attack animation. + /mob/proc/spin(spintime, speed) spawn() var/D = dir diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 6f30174ea1..13ee25a50a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -23,6 +23,8 @@ var/icon_gib = "generic_gib" // The iconstate for being gibbed, optional. Defaults to a generic gib animation. var/icon_rest = null // The iconstate for resting, optional var/image/modifier_overlay = null // Holds overlays from modifiers. + attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim + attack_icon_state = "slash" //Just the default //Mob talking settings universal_speak = 0 // Can all mobs in the entire universe understand this one? diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 1f7fb2d64d..cc446a0488 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -219,6 +219,15 @@ var/get_rig_stats = 0 //Moved from computer.dm + var/hud_typing = 0 //Typing indicator stuff. var/typing //Simple mobs use this variable. - var/obj/effect/decal/typing_indicator \ No newline at end of file + var/obj/effect/decal/typing_indicator + + var/low_priority = FALSE //Skip processing life() if there's just no players on this Z-level + + var/default_pixel_x = 0 //For offsetting mobs + var/default_pixel_y = 0 + + var/attack_icon //Icon to use when attacking w/o anything in-hand + var/attack_icon_state //State for above diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index adcd4fbee2..1bbb1d7d76 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ