Sorry about that. It's kinda embarrassing but here it is:
PHP Code:
#include <amxmodx>
#include <fakemeta>
#include <orpheu>
#include <orpheu_stocks>
#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "author"
#define TASKID_ANIMRESET 773413
new seqInitiation, isAnimating, shouldStopAnimation, unStuckMe; // PLAYER BITWISE VARS
new g_anim_seq[33], g_anim_gait[33];
// MACROS
#define SetBits(%1,%2) (%1 |= 1 << (%2 & 31))
#define ClearBits(%1,%2) (%1 &= ~( 1 << (%2 & 31)))
#define FBitSet(%1,%2) (%1 & 1 << (%2 & 31))
enum PlayerAnim
{
PLAYER_IDLE,
PLAYER_WALK,
PLAYER_JUMP,
PLAYER_SUPERJUMP,
PLAYER_DIE,
PLAYER_ATTACK1,
PLAYER_ATTACK1_RIGHT,
PLAYER_SMALL_FLINCH,
PLAYER_LARGE_FLINCH,
PLAYER_RELOAD,
PLAYER_HOLDBOMB
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
OrpheuRegisterHook(OrpheuGetFunction("SetAnimation", "CBasePlayer"), "Player_SetAnimation", OrpheuHookPre);
}
public plugin_natives()
{
register_library("playeranim");
register_native("playeranim_start", "Player_Anim_Start");
register_native("playeranim_reset", "Player_Anim_Reset");
}
public Player_Anim_Start(plugin, param)
{
new user = get_param(1);
if(task_exists(TASKID_ANIMRESET + user))
return
g_anim_seq[user] = get_param(2);
g_anim_gait[user] = get_param(3);
new Float:anim_time = get_param_f(4);
if(anim_time > 0)
set_task(anim_time, "Task_Anim_Reset", TASKID_ANIMRESET + user);
SetBits(isAnimating, user);
ClearBits(seqInitiation, user);
}
public Task_Anim_Reset(taskid)
{
new user = taskid - TASKID_ANIMRESET;
ClearBits(isAnimating, user);
SetBits(unStuckMe, user);
}
public Player_Anim_Reset(plugin, param)
{
new user = get_param(1);
ClearBits(isAnimating, user);
SetBits(unStuckMe, user);
if(task_exists(TASKID_ANIMRESET + user))
remove_task(TASKID_ANIMRESET + user);
}
public OrpheuHookReturn:Player_SetAnimation(const user, const anim)
{
if(!is_user_alive(user) || !FBitSet(isAnimating, user) || PlayerAnim:anim == PLAYER_DIE)
return OrpheuIgnored;
if(pev(user, pev_waterlevel ) > 1)
return OrpheuIgnored;
if(!FBitSet(seqInitiation, user))
{
// It needs to initiniate one time the animation.
// The engine will do what it needs to increse the frame and such.
InitiateSequence (user, g_anim_seq[user], g_anim_gait[user]);
SetBits(seqInitiation, user);
}
else
{
new playerMoving = IsMoving(user);
new shouldUpdate = playerMoving ^ FBitSet(shouldStopAnimation, user);
if(shouldUpdate)
{
playerMoving ? SetBits(shouldStopAnimation, user) : ClearBits(shouldStopAnimation, user);
UpdateAnimationState(user, .animationState = playerMoving);
}
}
return OrpheuSupercede;
}
// Update the animation state.
// Basically if it needs to be stopped or resumed.
// @param player The player's index.
// @param animationState 0 - stop the animation, 1 - resume it.
UpdateAnimationState ( const user, const animationState )
{
set_pev(user, pev_framerate, float(animationState));
}
// Initialize the animation.
// So the engine will do the job properly automatically.
// @param player The player's index.
// @param sequence The sequence to be initiated.
InitiateSequence(const user, seq, gait)
{
if(gait > 0) set_pev(user, pev_gaitsequence, gait);
if(seq > 0) set_pev(user, pev_sequence, seq);
set_pev(user, pev_frame, 0);
set_pev(user, pev_blending_0, 0);
set_pev(user, pev_blending_1, 0);
ResetSequenceInfo(user);
}
stock bool:IsMoving(const user)
{
#define Length2D(%0) (floatsqroot (%0[0] * %0[0] + %0[1] * %0[1]))
static Float:velocity[3];
pev(user, pev_velocity, velocity);
return Length2D(velocity) > 0;
}
// Reset the sequence properly before be initiated.
// @param player The player's index.
stock ResetSequenceInfo(const user)
{
static OrpheuFunction:handleResetSequenceInfo;
if ( !handleResetSequenceInfo )
handleResetSequenceInfo = OrpheuGetFunction( "ResetSequenceInfo", "CBaseAnimating" );
OrpheuCall( handleResetSequenceInfo, user );
}
I got it from ArkShine's Prone Position. I converted it into something that any plugin can call upon to play animations. Since I'm still not familiar with Orpheu I don't know half of the things I'm doing...