$$$$$$$\  $$\                                          $$$$$$\            $$\               
$$  __$$\ $$ |                                        $$  __$$\           \__|              
$$ |  $$ |$$ | $$$$$$\  $$\   $$\  $$$$$$\   $$$$$$\  $$ /  $$ |$$$$$$$\  $$\ $$$$$$\$$$$\  
$$$$$$$  |$$ | \____$$\ $$ |  $$ |$$  __$$\ $$  __$$\ $$$$$$$$ |$$  __$$\ $$ |$$  _$$  _$$\ 
$$  ____/ $$ | $$$$$$$ |$$ |  $$ |$$$$$$$$ |$$ |  \__|$$  __$$ |$$ |  $$ |$$ |$$ / $$ / $$ |
$$ |      $$ |$$  __$$ |$$ |  $$ |$$   ____|$$ |      $$ |  $$ |$$ |  $$ |$$ |$$ | $$ | $$ |
$$ |      $$ |\$$$$$$$ |\$$$$$$$ |\$$$$$$$\ $$ |      $$ |  $$ |$$ |  $$ |$$ |$$ | $$ | $$ |
\__|      \__| \_______| \____$$ | \_______|\__|      \__|  \__|\__|  \__|\__|\__| \__| \__|
                        $$\   $$ |                                                          
                        \$$$$$$  |                                                          
                         \______/                                                           

This is a header for adding new player animations to scripts. These animations can be set 
to play for a limited period of time are then automatically end when they're no longer in use.
This should hopefully reduce the number of situations where animations fight with each other for 
priority or the player gets stuck on a ScriptTile that didn't get properly cleared.
To set up a new animation, declare it at the start of your script like this and then 
call PlayAnim() at points where it should be played:
 
///////////////////////////////////////////////////////////////////////////////////////////

const int TIL_MYANIM = 420;

ffc script PlayerAnimTest
{
	using namespace PlayerAnim;
	void run()
	{
		// This will create a 4-way walking animation with 4 frames 
		// at a speed of 4FPS per frame.
		PlayerAnimDef myAnimation = CreatePlayerAnim(TIL_MYANIM, 4, 4, PADF_4WAY|PADF_WALKANIM);
		while(true)
		{
			// Played animations will last for one frame unless a duration is given.
			PlayAnim(myAnimation);
			Waitframe();
		}
	}
}

///////////////////////////////////////////////////////////////////////////////////////////

/////////////////
//  Functions  //
/////////////////

PlayerAnimDef CreatePlayerAnim(int tile, int numFrames, int aspeed, int flags=0, int priority=0)
 * Creates a new PlayerAnimDef and returns its pointer. For multi directional animations,
 * the four directions will be lined up in a single row of directional animations going:
 * Up, Down, Left, Right, Left-Up, Right-Up, Left-Down, Right-Down
 * 
 * int tile: The first of the animation's tiles
 * int numFrames: The number of sprite frames in the animation (per direction)
 * int aspeed: The speed of the animation in game frames per sprite frame
 * int flags: Sum of the following PADF_ flags ORed together:
 *            PADF_4WAY: The animation is four directional.
 *            PADF_8WAY: The animation is eight directional.
 *            PADF_RESETONNEWDIR: The animation will start over whenever 
 *                                the player's direction changes.
 *            PADF_BSFRAMES: The number of frames is fixed to 3, animating
 *                           in a pattern of 0-1-0-2.
 *            PADF_WALKANIM: The animation only progresses when the player is walking.
 *            PADF_NOINHERITDIR: The animation's facing direction can be set  
 *                               independently of the player's.
 *            PADF_NOLOOP: The animation won't loop when finished.
 *            PADF_STOPONFINISH: The animation will stop playing if it 
 *                               finishes before timing out.
 *            PADF_USELTM: The Link Tile Modifier value will be added to the 
 *                         animation's tiles at the end.
 * int priority: Priority controls which animations can play over each other.
 *               An animation must have greater or equal priority to the current
 *               playing one in order to play. Additionally, if priority is <0,
 *               any Link action that doesn't use standing/walking sprites 
 *               will override it.

PlayerAnimDef CreatePlayerAnimMultiRow(int tile, int numFrames, int aspeed, int flags=0, int priority=0)
 * Same as the above, but multiple directions of animation will be arranged
 * in multiple rows extending down from the first tile.

PlayerAnimDef CreatePlayerAnimFromArray(int[] tiles, int numFrames, int aspeed, int flags=0, int priority=0)
 * Same as the above, but takes an array literal for the tiles. Each index of the array 
 * is the starting tile of a direction going in order.

void PlayAnim(PlayerAnimDef ladef, int frames=1, PlayerAnimationPlayback playbackMode=PLAYBACK_NORMAL, int speedMult=1)
 * Plays an animation using a PlayerAnimDef pointer. This animation will play for a time
 * specified by "frames" before automatically cleaning itself up, refreshing this timer every time
 * the function is called again on the same animation. It can be played with the following modes:
 * 	PLAYBACK_NORMAL: The animation will reset if this animation was not already playing.
 * 	PLAYBACK_NORESET: The animation's playback progress won't reset  even if switching to a new one.
 * 	PLAYBACK_FORCERESET: The animation will start over even if it's already playing.
 * Setting "speedMult" to a value besides 1 will alter the speed the animation plays back at.

void PlayAnimFrame(PlayerAnimDef ladef, int whichFrame, int frames=1)
 * Plays an animation and forces it to a specific frame. 
 * This will also set the animation speed multiplier to 0.

bool AnimFinished()
 * Returns true if the current animation has looped/ended or if there is no animation playing.

bool IsAnyAnimPlaying()
 * Returns true if there's an animation currently playing.

bool IsPlaying(PlayerAnimDef ladef)
 * Returns true if the animation "ladef" is the current playing animation.

int GetCurAnimFrame()
 * Returns the current sprite frame within the current playing animation, or 0 if there is none.

int GetCurAnimTimer()
 * Returns the current game frame within the current playing animation, or 0 if there is none.

int GetCurAnimSpeedMult()
void SetCurAnimSpeedMult(int speed)
 * Get or set the current animation's speed multiplier.

int GetCurAnimDir()
void SetCurAnimDir(int dir)
 * Get or set the current animation's direction.

void FakeAnimWalking()
 * Advance the timer for a walking animation on this frame, even if the player isn't walking.