Files
2022-10-26 12:25:11 +08:00

198 lines
5.5 KiB
C++

//------------------------------------------------------------------------------
// StateEventJump.cpp
// (C) 2005 Webzen Sunstudio
//------------------------------------------------------------------------------
#include "SunClientPrecompiledHeader.h"
#include "statebase.h"
#include "StateEventJump.h"
#include "character.h"
#include "monster.h"
// 중력가속도
const int GRAVITY = 20;
// 점프하는 높이
const float UP_HEIGHT = 2.5f;
const int X_ACCELERATION = 20;
//------------------------------------------------------------------------------
/**
*/
StateEventJump::StateEventJump(void)
{
}
//------------------------------------------------------------------------------
/**
*/
StateEventJump::~StateEventJump(void)
{
}
//------------------------------------------------------------------------------
/**
점프는 MOVE 로 반드시 돌아가야한다.
죽지도 않아요~
*/
BOOL StateEventJump::CanTransite(Object* pOwner, DWORD CurTime, StateBase* pToTransiteState)
{
return TRUE;
}
//------------------------------------------------------------------------------
/**
*/
STATECHANGE::TYPE StateEventJump::OnStart(Object* pOwner, DWORD CurTime)
{
Character* pChr = (Character*)pOwner;
pChr->SetFreeMove(TRUE);
ATTACK_JUMP_INFO * pAttackJump = &pChr->m_AttackJumpInfo;
// 공격 애니메이션 세팅
WzID animationID = pChr->GetCurrentAttackJumpAnimation();
assert(animationID);
pChr->SetAnimation( "J001" );
pAttackJump->m_dwTotalTime =
pChr->GetCurrentAction()->EVENT_JUMP.dwEndTime -
pChr->GetCurrentAction()->EVENT_JUMP.dwStartTime;
// 아래로 내려가야 하는 높이
pAttackJump->m_fDestHeight =
pChr->GetCurrentAction()->EVENT_JUMP.vDestPos.wvPos.z -
pChr->GetCurrentAction()->EVENT_JUMP.vCurPos.wvPos.z;
// 목적지 좌표와 현재 좌표간의 차이
pAttackJump->m_vDist =
pChr->GetCurrentAction()->EVENT_JUMP.vDestPos.wvPos -
pChr->GetCurrentAction()->EVENT_JUMP.vCurPos.wvPos;
// 캐릭터 방향 설정
pChr->SetAngle( Math_GetAngleFromVector(&pAttackJump->m_vDist), TRUE );
if (UP_HEIGHT == 0 && pAttackJump->m_fDestHeight == 0)
{
return STATECHANGE::FAILED;
}
// 점프를 시작할 때의 초기 속도
float fDestLength = VectorLength( &pAttackJump->m_vDist );
float fUpHeight = max( UP_HEIGHT, pAttackJump->m_fDestHeight );
pAttackJump->m_fVelocity_Y = sqrt( 2 * GRAVITY * fUpHeight );
if( pAttackJump->m_fDestHeight >= UP_HEIGHT )
{
pAttackJump->m_fVelocity_X = fDestLength * GRAVITY / pAttackJump->m_fVelocity_Y;
}
else
{
pAttackJump->m_fVelocity_X = fDestLength * GRAVITY /
(
pAttackJump->m_fVelocity_Y +
sqrt( pAttackJump->m_fVelocity_Y * pAttackJump->m_fVelocity_Y - 2*GRAVITY*pAttackJump->m_fDestHeight )
);
}
return STATECHANGE::SUCCESS;
}
//------------------------------------------------------------------------------
/**
*/
STATEPROCESS::TYPE StateEventJump::OnProcess(Object* pOwner, DWORD CurTime,DWORD dwTick)
{
STATEPROCESS::TYPE ret = STATEPROCESS::HOLD;
Character* pChr = (Character*)pOwner;
ATTACK_JUMP_INFO * pAttackJump = &pChr->m_AttackJumpInfo;
float fRet = 0.f;
DWORD dwRunTime = g_CurTime - pChr->GetCurrentAction()->EVENT_JUMP.dwStartTime ;
float fMoveRate = (float)dwRunTime / (float)pChr->m_AttackJumpInfo.m_dwTotalTime;
if (fMoveRate >= 1.0f)
{
fMoveRate = 1.0f;
}
// 평면(x,y)상으로 이동한 거리
float fMoveLength = VectorLength( &( pAttackJump->m_vDist * fMoveRate ) );
float fVecLength = VectorLength( &pAttackJump->m_vDist );
// fMoveLength를 기준으로 현재 높이 값을 계산한다.
float fResult_Delta_Z =
( 2*pAttackJump->m_fVelocity_X*pAttackJump->m_fVelocity_Y-GRAVITY*fMoveLength ) /
( 2*pAttackJump->m_fVelocity_X*pAttackJump->m_fVelocity_X ) * fMoveLength;
// 최종적인 현재 좌표를 셋팅한다.
WzVector vResultPos;
vResultPos =
pChr->GetCurrentAction()->EVENT_JUMP.vCurPos.wvPos + pAttackJump->m_vDist * fMoveRate;
vResultPos.z = fResult_Delta_Z + pChr->GetCurrentAction()->EVENT_JUMP.vCurPos.wvPos.z;
float fTotalFrame = pChr->GetTotalFrame();
if (fMoveRate <= 0.2f)
{
float fNewFrame = (fTotalFrame * 0.5f) * (fMoveRate / 0.2f);
pChr->SetCurrentFrame(fNewFrame);
pChr->ProcessAnimation(0);
}
else if (fMoveRate >= 0.8f)
{
if (pChr->IsKindOfObject(MONSTER_OBJECT) )
{
pChr->SetAnimation("J002",FALSE);
}
float fNewFrame = (fTotalFrame * 0.5f) * (1.0f + (fMoveRate - 0.8f) / 0.2f);
pChr->SetCurrentFrame(fNewFrame);
pChr->ProcessAnimation(0);
}
else
{
if (pChr->IsKindOfObject(MONSTER_OBJECT) )
{
pChr->SetAnimation("N007",TRUE);
}
pChr->ProcessAnimation(dwTick);
}
pChr->ProcessInterpolation(dwTick);
// process interpolation 다음에renderpart위치를 set하므로 유효하다.
pChr->GetBasePart()->SetPosition(vResultPos);
if (fMoveRate >= 1.0f)
{
pChr->SetPosition(pChr->GetCurrentAction()->EVENT_JUMP.vDestPos.wvPos,pChr->GetCurrentAction()->EVENT_JUMP.vDestPos.wTile);
pChr->SetInterpolatePosition();
pChr->SetVisiblePos(pChr->GetCurrentAction()->EVENT_JUMP.vDestPos.wvPos);
if (pChr->ProcessNextAction())
{
return STATEPROCESS::SUSPEND;
}
else
{
return STATEPROCESS::END;
}
}
return ret;
}
//------------------------------------------------------------------------------
/**
*/
STATECHANGE::TYPE StateEventJump::OnEnd(Object* pOwner, DWORD CurTime)
{
Character* pChr = (Character*)pOwner;
pChr->SetJumpFlag(FALSE);
pChr->m_fHeight = 0.0f;
return STATECHANGE::SUCCESS;
}