Senior Member
|
06-30-2019
, 20:19
Re: [HELP] Player Model Animation Sometimes Stops
|
#7
|
Quote:
Originally Posted by HamletEagle
I forgot to mention I know for a fact the module works, because I used it for some private work.
|
It works replacing the Player_SetAnimation Orpheu hook, but still freezes for me unless I move so the custom anim can play the rest. Here's what I have so far:
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))
{
if(get_param(3) > 0) g_anim_gait[user] = get_param(3);
else g_anim_gait[user] = pev(user, pev_gaitsequence);
if(get_param(2) > 0) g_anim_seq[user] = get_param(2);
else g_anim_seq[user] = pev(user, pev_sequence);
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;
}
*/
public OnSetAnimation(user, anim)
{
if(!is_user_alive(user) || !FBitSet(isAnimating, user) || PlayerAnim:anim == PLAYER_DIE)
return PLUGIN_CONTINUE
if(pev(user, pev_waterlevel ) > 1)
return PLUGIN_CONTINUE
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);
return PLUGIN_HANDLED
}
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 PLUGIN_HANDLED
}
// 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)
{
set_pev(user, pev_sequence, seq);
set_pev(user, pev_gaitsequence, gait);
set_pev(user, pev_frame, 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 );
}
It might be related to the fact that I'm trying to animate only the upper half of the player model. What I'm trying to do is playing the reload anim when the player attaches/detaches the silencer. At first it does its thing but the legs are just standing even while I'm moving. So I used pev(user, pev_gaitsequence) to try and update the lower half but it doesn't update in real time. Like if I was standing and took off the silencer and crouched mid way the legs would go thru the floor...
__________________
|
|