HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Reverse Animation

01-04-2009, 08:11 AM#1
fX_
**Updated:**
fixed some leaks and removed redundant stuff. dunno why they were missed...
Added a feature for running follow-up stuff to be ran after animation is played. See "C" trigger in script for example implementation.
Also fixed an error in calculation of run time of the reverse naimation, I think.

A function that runs animations in reverse for units.
See http://www.wc3campaigns.net/showpost...1&postcount=88 for information on which this system is dependent.

Requires TimerUtils (Source: http://wc3campaigns.net/showthread.php?t=101322).

SCRIPT:
Collapse JASS:
library ReverseAnimation requires TimerUtils

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //  ReverseAnimation
    //====================================================================================================================
    //  Firstly, this script requires TimerUtils (by Vexorian @ [url]www.wc3campaigns.net):[/url]
    //          [url]http://wc3campaigns.net/showthread.php?t=101322[/url]
    //
    //  Background Info:
    //   [url]http://www.wc3campaigns.net/showpost.php?p=1017121&postcount=88[/url]
    //
    //  function SetUnitAnimationReverse takes:
    //
    //      unit u - animation of which reverse animation is played;
    //      integer index - animation index of the animation to be played;
    //      real animTime - the natural duration of the animation to be played. This can be referred to in the preview
    //                      window in the bottom-left part of the World Editor interface (it is the real value enclosed
    //                      in parenthesis);
    //      real runSpeed - the speed at which the animation to be played in reverse will be ran.
    //      boolean resetAnim - indicates to the system if it should set the unit's animation to "stand" after playing the
    //                          reverse animation.
    //
    //  function SetUnitAnimationReverseFollowed takes all of the above and:
    //      FollowUpFunc func - function to be ran after the animation is played. Expressed as a function interface
    //                          (see below). Takes an data object arguement pertaining to relevant stuff that must be
    //                          passed.
    //      integer data - a struct that is the above data object.
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//  -- Configuration --

    globals
        private constant real PREP_INTERVAL_DURATION = 0.03
    endglobals

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//  -- User Functions --

    private keyword ReverseAnimation

    function SetUnitAnimationReverse takes unit u, integer index, real animTime, real runSpeed, boolean resetAnim returns boolean
        return ReverseAnimation.Prepare(u, index, animTime, runSpeed, resetAnim, 0, 0)
    endfunction

    function SetUnitAnimationReverseFollowed takes unit u, integer index, real animTime, real runSpeed, boolean resetAnim, FollowUpFunc func, integer data returns boolean
        return ReverseAnimation.Prepare(u, index, animTime, runSpeed, resetAnim, func, data)
    endfunction

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII//
//  -- Script Operation Functions --

    function interface FollowUpFunc takes integer data returns nothing

    private struct ReverseAnimation

        private unit u
        private integer intAnimIndex
        private real rAnimTime
        private real rRunSpeed
        private boolean boolResetAnim
        private FollowUpFunc func
        private integer data

        public static method Prepare takes unit u, integer index, real animTime, real runSpeed, boolean resetAnim, FollowUpFunc func, integer data returns boolean
            local ReverseAnimation new = 0
            local timer TIM = null

            if u != null and index > 0 and runSpeed > 0.00 then
                set new = .allocate()
                set new.u = u
                set new.intAnimIndex = index
                set new.rAnimTime = animTime
                set new.rRunSpeed = -runSpeed
                set new.boolResetAnim = resetAnim
                set new.func = func
                set new.data = data

                call SetUnitTimeScale(u, animTime/PREP_INTERVAL_DURATION)
                call SetUnitAnimationByIndex(u, index)
                set TIM = NewTimer()
                call SetTimerData(TIM, integer(new))
                call TimerStart(TIM, PREP_INTERVAL_DURATION, false, function ReverseAnimation.Play)

                set TIM = null
                return true
            endif

            return false
        endmethod

        public static method Play takes nothing returns nothing
            local timer TIM = GetExpiredTimer()
            local ReverseAnimation INST = GetTimerData(TIM)

            call SetUnitTimeScale(INST.u, INST.rRunSpeed)
            call TimerStart(TIM, INST.rAnimTime/-INST.rRunSpeed, false, function ReverseAnimation.End)

            set TIM = null
        endmethod

        public static method End takes nothing returns nothing
            local timer TIM = GetExpiredTimer()
            local ReverseAnimation INST = GetTimerData(TIM)

            call SetUnitTimeScale(INST.u, 1.00)
            if INST.boolResetAnim then
                call SetUnitAnimation(INST.u, "stand")
            endif
            if INST.func != 0 then
                call INST.func.execute(INST.data)
            endif

            set INST.u = null
            call INST.destroy()
            call ReleaseTimer(TIM)
            set TIM = null
        endmethod

    endstruct

endlibrary
Attached Files
File type: w3xReverseAnimation.w3x (22.0 KB)
01-04-2009, 04:20 PM#2
Ammorth
I think he means to rename the file name to something more convenient.
01-04-2009, 07:24 PM#3
Rising_Dusk
This is actually an interesting script. The biggest problem I see with it is that a unit must actually play the animation and be caught before it ends, which can be a real pain to manage. I will toy with your testmap and see what you have come up with, though.

EDIT:
In the future, make sure your testmaps are actually compiled properly and playable. Also, please, for the love of God, name them something relevant. asdasfd is not suitable at all.

EDIT:
Okay, that was kind of neat, it worked sufficiently and in all cases that SetUnitAnimation() would. Good job there. However, my biggest concern is that you're playing with and destroying timers. You should incorporate TimerUtils into your library so as to avert that. This is important.
01-04-2009, 11:26 PM#4
fX_
So it is ok but I need to rework how the waiting works?

Can I use something CSSafety-ish instead of TimerUtils? - 'coz I know how it works and I do not how TimerUtils does...

EDIT: I was able to compile it...
01-05-2009, 01:37 AM#5
Rising_Dusk
Quote:
Originally Posted by fX_
EDIT: I was able to compile it...
Your testmap as you originally had it would not start because the map was improperly compiled. That is to what I refer.
Quote:
Originally Posted by fX_
Can I use something CSSafety-ish instead of TimerUtils? - 'coz I know how it works and I do not how TimerUtils does...
CSSafety is deprecated. We use TimerUtils now. There are likely other fixes necessary as well, but the resident Development Director will elaborate when he finds the time.
01-06-2009, 08:51 AM#6
Pyrogasm
Sweet. Nice to know my results got used for something :D
01-06-2009, 03:31 PM#7
Tide-Arc Ephemera
Had this been in plain Jass, I'd be using this... EVERYWHERE.
01-06-2009, 11:09 PM#8
Pyrogasm
It's able to be converted. Want me to do it for you?
01-07-2009, 04:59 AM#9
Tide-Arc Ephemera
That would be super special awesome, please.
01-07-2009, 05:10 AM#10
Pyrogasm
Give me a day or so and I can probably do it. Gamecache for-the-win.
01-07-2009, 05:41 AM#11
Ammorth
Quote:
Originally Posted by Pyrogasm
Give me a day or so and I can probably do it. Gamecache for-the-win.
no need, just use the same style of coding that vJass parses to (look at my multibars system for an example of how I did it).
01-07-2009, 05:59 AM#12
Pyrogasm
Ah, arrays. Right.
01-07-2009, 07:02 AM#13
Rising_Dusk
Quote:
Originally Posted by Tide-Arc-Ephemera
Had this been in plain Jass, I'd be using this... EVERYWHERE.
Had you been up to date with WC3 modding, this would be a nonissue.
01-07-2009, 02:43 PM#14
Tide-Arc Ephemera
Had I had a job or other source of income and the ability to get my own computer which is suitable for what I need, being 1.2-3 thousand AUD, you'd be right.
01-07-2009, 05:15 PM#15
Rising_Dusk
...Or you could, you know, just compile vJass externally like Pyro does... What a novel idea. Oo