DragonNest/GameCommon/MAWalkMovement.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

2057 lines
60 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Stdafx.h"
#include "MAWalkMovement.h"
#include "EtMatrixEx.h"
#include "DnWorld.h"
#include "DnActionBase.h"
#include "DnActor.h"
#include "VelocityFunc.h"
#include "MAActorRenderBase.h"
#include "PerfCheck.h"
#include "EtTestCollision.h"
#include "navigationcell.h"
#include "navigationmesh.h"
#include "navigationpath.h"
#ifndef _GAMESERVER
#include "EtDecal.h"
#endif
#if defined(_DEBUG) || defined(_RDEBUG)
#define _USE_COLLISION_DEBUG 0
#else
#define _USE_COLLISION_DEBUG 0
#endif
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
MAWalkMovement::MAWalkMovement()
: m_vMovement( 0.f, 0.f )
, m_vJumpMovement( 0.f, 0.f )
, m_vJumpXVector( 0.f, 0.f, 0.f )
, m_vJumpZVector( 0.f, 0.f, 0.f )
, m_vVelocity( 0.f, 0.f, 0.f )
, m_vVelocityResist( -30.f, -30.f, -30.f )
, m_vLastVelocity( 0.f, 0.f, 0.f )
, m_vMoveVectorX( 0.f, 0.f, 0.f )
, m_vMoveVectorZ( 0.f, 0.f, 0.f )
, m_vMovePos( 0.f, 0.f, 0.f )
, m_vMagnetDir( 0.f, 0.f )
, m_vTargetLookVec( 0.f, 0.f )
, m_vLastVelocityValue( 0.f, 0.f, 0.f )
, m_fMoveYDistancePerSec( 0.0f )
, m_fLeftMoveYDistance( 0.0f )
, m_bAppliedYDistance( false )
, m_bMaintainYDistanceOnArriveDestPosition( false )
, m_bOnDrop(false)
, m_bOnFall(false)
, m_bOnStop(false)
, m_fDropVelocity(0.0f)
, m_fNaviTargetMinDistance(0.0f)
, m_nNaviType(0)
{
m_fLimitDgrees = 90.f;
m_PrevLocalTime = 0;
m_fJumpMoveSpeed = 0.f;
m_fTargetMinDistance = 0.f;
m_bRefreshZVector = false;
m_fMagnetLength = 0.f;
m_fAngleAssist = 0.f;
m_bEnableNaviMode = false;
m_bFloorForceVelocity = false;
m_bLastFloorForceVelocity = false;
m_bFloorCollision = false;
m_LastLookTargetTime = 0;
m_bDebugRenderAttr = false;
// m_fLastHeight = 0.f;
#ifndef _GAMESERVER
m_fLastMoveDelta = 0.f;
memset( m_fLastMoveLength, 0, sizeof(m_fLastMoveLength) );
m_nLastMoveCount = 0;
#endif
#ifdef PRE_MOD_NAVIGATION_PATH
m_bAutoMoving = false;
#endif // PRE_MOD_NAVIGATION_PATH
}
MAWalkMovement::~MAWalkMovement()
{
}
bool Compare_CollisionOrder( SCollisionInfo &a, SCollisionInfo &b )
{
return a.CollisionNormal.y < b.CollisionNormal.y;
}
EtVector2 g_DirVector[4] =
{
EtVector2( -0.707107f, 0.707107f ),
EtVector2( 0.707107f, 0.707107f ),
EtVector2( 0.707107f, -0.707107f ),
EtVector2( -0.707107f, -0.707107f )
};
void GetCheckDirctionVector( const int nIndex, EtVector2 & etVector )
{
if( 0 == nIndex )
{
etVector = EtVector2( -0.707107f, 0.707107f );
}
else if( 1 == nIndex )
{
etVector = EtVector2( 0.707107f, 0.707107f );
}
else if( 2 == nIndex )
{
etVector = EtVector2( 0.707107f, -0.707107f );
}
else if( 3 == nIndex )
{
etVector = EtVector2( -0.707107f, -0.707107f );
}
}
bool MAWalkMovement::CheckDiagonalBlock( float fX, float fY )
{
char cAttr = INSTANCE(CDnWorld).GetAttribute( fX, fY );
int nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( fX, fY );
if( nBlockSize == 0 ) return false;
float fWorldX, fWorldY;
INSTANCE(CDnWorld).CalcWorldBasePos( fX, fY, fWorldX, fWorldY );
int nX = int(fWorldX) / nBlockSize;
int nY = int(fWorldY) / nBlockSize;
float fTempX = fWorldX - ( nX * nBlockSize );
float fTempY = fWorldY - ( nY * nBlockSize );
if( cAttr & 0x10 )
{
if( fTempX + fTempY > nBlockSize ) return false;
}
if( cAttr & 0x20 )
{
if( fTempX > fTempY ) return false;
}
if( cAttr & 0x40 )
{
if( fTempX + fTempY < nBlockSize ) return false;
}
if( cAttr & 0x80 )
{
if( fTempX < fTempY ) return false;
}
return true;
}
bool MAWalkMovement::CheckMovableBlock( char cAttr )
{
if( cAttr == 0 ) return true;
if( ( cAttr & 0xf0 ) != 0 ) return true;
return false;
}
void MAWalkMovement::ProcessCommon( LOCAL_TIME LocalTime, float fDelta )
{
m_bOnDrop = m_bOnFall = m_bOnStop = false;
m_fDropVelocity = 0.f;
m_pActor->SetPrevPosition( m_pMatExWorld->m_vPosition );
EtVector3 vPrevPos = m_pMatExWorld->m_vPosition;
EtVector3 vPrevVel = m_vVelocity;
EtVector2 vAniDistance( 0.f, 0.f );
EtVector3 *vDist = m_pActor->GetAniDistance();
if( m_pActor->GetState() & CDnActorState::Move &&
false == (m_pActor->GetState() & CDnActorState::IgnoreBackMoveSpeed) ) {
EtVector2 vApplyMoveSpeed( 0.f, 0.f );
if( m_pActor->GetMoveSpeed() == 0 || fDelta == 0.f ) {
vApplyMoveSpeed.x = vDist->x;
vApplyMoveSpeed.y = vDist->z;
}
else {
float fMoveSpeed = m_pActor->GetMoveSpeed() * fDelta;
vApplyMoveSpeed.x = ( ( 1.f / fDelta ) * vDist->x ) / 300.f;
vApplyMoveSpeed.y = ( ( 1.f / fDelta ) * vDist->z ) / 300.f;
vApplyMoveSpeed *= fMoveSpeed;
}
vAniDistance += EtVector2( m_vMoveVectorX.x, m_vMoveVectorX.z ) * vApplyMoveSpeed.x;
vAniDistance += EtVector2( m_vMoveVectorZ.x, m_vMoveVectorZ.z ) * vApplyMoveSpeed.y;
}
else {
vAniDistance += EtVector2( m_pMatExWorld->m_vXAxis.x, m_pMatExWorld->m_vXAxis.z ) * vDist->x;
vAniDistance += EtVector2( m_pMatExWorld->m_vZAxis.x, m_pMatExWorld->m_vZAxis.z ) * vDist->z;
}
m_vMovement += vAniDistance;
// Look ó<><C3B3>
if( m_hLookTarget )
{
EtVector2 vLook;
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
EtVector3 vTargetPosition = m_hLookTarget->FindAutoTargetPos();
vLook.x = vTargetPosition.x - m_pMatExWorld->m_vPosition.x;
vLook.y = vTargetPosition.z - m_pMatExWorld->m_vPosition.z;
#else
vLook.x = m_hLookTarget->GetPosition()->x - m_pMatExWorld->m_vPosition.x;
vLook.y = m_hLookTarget->GetPosition()->z - m_pMatExWorld->m_vPosition.z;
#endif
if( EtVec2LengthSq( &vLook ) > 0.f )
{
EtVec2Normalize( &vLook, &vLook );
float fDot = EtVec2Dot( &vLook, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
float fAngle = EtToDegree( EtAcos( fDot ) );
bool bForceLook = true;
if( fAngle > m_pActor->GetRotateAngleSpeed() * fDelta ) bForceLook = false;
m_pActor->Look( vLook, bForceLook );
if( bForceLook )
OnEndLook();
m_LastLookTargetTime = LocalTime;
}
}
if ( m_bEnableNaviMode )
{
if( !m_WayPointList.empty() && m_WayPointId != m_WayPointList.end() )
{
m_vMovePos = (*m_WayPointId).Position;
}
else
{
m_bEnableNaviMode = false;
}
}
// Ÿ<><C5B8> <20>̵<EFBFBD> ó<><C3B3>
else if( m_hMoveTarget )
{
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
m_vMovePos = m_hMoveTarget->FindAutoTargetPos();
#else
m_vMovePos = *m_hMoveTarget->GetPosition();
#endif
}
// Look ó<><C3B3>
if( EtVec2LengthSq( &m_vTargetLookVec ) > 0.f ) {
float fDot = D3DXVec2Dot( &m_vTargetLookVec, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
float fAngle = EtToDegree( EtAcos(fDot) );
float fAngleSpeed = m_pActor->GetRotateAngleSpeed() * fDelta;
if( fAngle > fAngleSpeed ) {
EtVector3 vCrossVec;
D3DXVec3Cross( &vCrossVec, &EtVec2toVec3( m_vTargetLookVec ), &m_pMatExWorld->m_vZAxis );
if( vCrossVec.y > 0.f )
m_pMatExWorld->RotateYaw( fAngleSpeed );
else m_pMatExWorld->RotateYaw( -fAngleSpeed );
fDot = D3DXVec2Dot( &m_vTargetLookVec, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
fAngle = EtToDegree( EtAcos(fDot) );
if( fAngle <= fAngleSpeed ) {
m_pMatExWorld->m_vZAxis = EtVec2toVec3( m_vTargetLookVec );
m_pMatExWorld->MakeUpCartesianByZAxis();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
}
else {
m_pMatExWorld->m_vZAxis = EtVec2toVec3( m_vTargetLookVec );
m_pMatExWorld->MakeUpCartesianByZAxis();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD> ó<><C3B3>
if( EtVec3LengthSq( &m_vMovePos ) > 0.f ) {
EtVector3 vTemp = m_vMovePos - m_pMatExWorld->m_vPosition;
vTemp.y = 0.f;
float fLength = EtVec3Length( &vTemp );
if( !m_hMoveTarget ) {
if( m_pActor->GetMoveSpeed() > 0.f )
m_fTargetMinDistance = m_pActor->GetMoveSpeed() * fDelta;
else m_fTargetMinDistance = EtVec2Length( &m_vMovement );
if( m_fTargetMinDistance == 0.f ) {
m_fTargetMinDistance = EtVec3Length( m_pActor->GetAniDistance() );
}
m_fTargetMinDistance += 1.f;
}
if( fLength <= m_fTargetMinDistance || !m_pActor->IsMove() )
{
if( !m_hMoveTarget && fLength <= m_fTargetMinDistance ) {
EtVec3Normalize( &vTemp, &vTemp );
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * fLength;
}
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
#ifdef PRE_MOD_NAVIGATION_PATH
// <20>ڵ<EFBFBD><DAB5>̵<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׺<EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
if( ( m_bAutoMoving ||m_bEnableNaviMode ) && !m_WayPointList.empty() )
{
WayPointID CurrentWayPointID = m_WayPointId;
m_WayPointId++;
if ( m_WayPointId == m_WayPointList.end() )
{
m_bOnStop = true;
m_bEnableNaviMode = false;
m_bAutoMoving = false;
}
else
{
if( m_bAutoMoving )
OnAutoMoving( (EtVector3)(*m_WayPointId).Position, (EtVector3)(*CurrentWayPointID).Position );
else if( m_bEnableNaviMode )
OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
}
}
else
{
m_bOnStop = true;
m_bEnableNaviMode = false;
m_bAutoMoving = false;
}
#else // PRE_MOD_NAVIGATION_PATH
// <20>׺<EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
if( m_bEnableNaviMode && !m_WayPointList.empty() )
{
m_WayPointId++;
if ( m_WayPointId == m_WayPointList.end() )
{
m_bOnStop = true;
m_bEnableNaviMode = false;
}
else OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
}
else
{
m_bOnStop = true;
m_bEnableNaviMode = false;
}
#endif // PRE_MOD_NAVIGATION_PATH
}
else {
EtVec3Normalize( &vTemp, &vTemp );
if( m_bRefreshZVector ) {
m_vMoveVectorZ = vTemp;
if( EtVec2LengthSq( &m_vTargetLookVec ) == 0.f ) {
m_pMatExWorld->m_vZAxis = vTemp;
}
else m_vTargetLookVec = EtVec3toVec2( vTemp );
m_pMatExWorld->MakeUpCartesianByZAxis();
}
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * ( m_pActor->GetMoveSpeed() * fDelta );
#ifndef _GAMESERVER
if( m_pActor->GetMoveSpeed() > 0 ) {
m_fLastMoveDelta += fDelta;
if( m_fLastMoveDelta >= FORCE_REVISION_DELTA ) {
m_fLastMoveDelta -= FORCE_REVISION_DELTA;
m_nLastMoveCount++;
if( m_nLastMoveCount == FORCE_REVISION_HISTORY_COUNT ) {
float fTemp = fLength;
for( int n=0; n<FORCE_REVISION_HISTORY_COUNT; n++ ) fTemp += m_fLastMoveLength[n];
fTemp /= ( FORCE_REVISION_HISTORY_COUNT + 1 );
bool bValidDiff = false;
float fOffsetSpeed = m_pActor->GetMoveSpeed() / 15.f;
if( abs( fTemp - fLength ) < fOffsetSpeed ) {
bValidDiff = true;
for( int n=0; n<FORCE_REVISION_HISTORY_COUNT; n++ )
if( abs( m_fLastMoveLength[n] - fTemp ) > fOffsetSpeed ) bValidDiff = false;
}
if( bValidDiff && !( m_pActor->IsPlayerActor() && (m_pActor->GetMySmartPtr() == CDnActor::s_hLocalActor ) ) ) {
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * fLength;
m_pMatExWorld->m_vPosition.y = vPrevPos.y = m_vMovePos.y;
m_pActor->SetPrevPosition( vPrevPos );
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
// OnStop( m_pMatEx->m_vPosition );
m_bOnStop = true;
m_bEnableNaviMode = false;
}
else {
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
}
}
m_fLastMoveLength[m_nLastMoveCount] = fLength;
}
}
#endif
}
}
// Magnet ó<><C3B3>
if( m_fMagnetLength > 0.f ) {
float fSpeed = (float)m_pActor->GetMoveSpeed();
if( fSpeed == 0.f ) fSpeed = 300.f;
float fMagnetMove = fSpeed * fDelta;
if( m_fMagnetLength - fMagnetMove <= 0.f ) fMagnetMove = m_fMagnetLength;
m_vMovement += m_vMagnetDir * fMagnetMove;
m_fMagnetLength -= fMagnetMove;
if( m_fMagnetLength <= 0.f ) {
m_vMagnetDir = EtVector2( 0.f, 0.f );
m_fMagnetLength = 0.f;
}
}
// Velocity ó<><C3B3>
EtVector3 vVelocity = EtVector3( 0.f, 0.f, 0.f );
m_vLastVelocityValue = EtVector3( 0.f, 0.f, 0.f );
if( m_vVelocity.z ) {
float fTemp = m_vVelocity.z;
float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX;
float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f;
float fTemp2 = m_vVelocity.z;
m_vLastVelocityValue.z = CalcMovement( fTemp2, 1.f, fMax, fMin, m_vVelocityResist.z );
vVelocity += m_vVelocityZVector * CalcMovement( m_vVelocity.z, fDelta, fMax, fMin, m_vVelocityResist.z );
if( m_vVelocity.z * fTemp <= 0.f ) m_vVelocity.z = 0.f;
}
if( m_vVelocity.x ) {
float fTemp = m_vVelocity.x;
float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX;
float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f;
float fTemp2 = m_vVelocity.x;
m_vLastVelocityValue.x = CalcMovement( fTemp2, 1.f, fMax, fMin, m_vVelocityResist.x );
vVelocity += m_vVelocityXVector * CalcMovement( m_vVelocity.x, fDelta, fMax, fMin, m_vVelocityResist.x );
if( m_vVelocity.x * fTemp <= 0.f ) m_vVelocity.x = 0.f;
}
m_vMovement += EtVector2( vVelocity.x, vVelocity.z );
m_fAngleAssist = 0.f;
if( EtVec2Length( &m_vMovement ) > 0.f )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD>
EtVector3 vTempPos = m_pMatExWorld->m_vPosition;
vTempPos.x += m_vMovement.x;
vTempPos.z += m_vMovement.y;
vTempPos.y = INSTANCE(CDnWorld).GetHeight( vTempPos );
if( ( m_pActor->GetAddHeight() == 0.f && m_pMatExWorld->m_vPosition.y == INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition ) ) || m_pMatExWorld->m_vPosition.y <= vTempPos.y )
{
EtVector3 vMoveNor, vDirNor;
EtVec3Normalize( &vMoveNor, &EtVector3( m_vMovement.x, vTempPos.y - m_pMatExWorld->m_vPosition.y, m_vMovement.y ) );
EtVec3Normalize( &vDirNor, &EtVector3( m_vMovement.x, 0.f, m_vMovement.y ) );
m_fAngleAssist = EtVec3Dot( &vMoveNor, &vDirNor );
m_vMovement *= m_fAngleAssist;
}
}
// <20>̵<EFBFBD> ó<><C3B3>
EtVector3 vTemp = m_pMatExWorld->m_vPosition;
vTemp.x += m_vMovement.x - ( vAniDistance.x * m_fAngleAssist );
vTemp.z += m_vMovement.y - ( vAniDistance.y * m_fAngleAssist );
vTemp.y += vVelocity.y;
m_pActor->SetStaticPosition( vTemp );
m_pMatExWorld->m_vPosition.x += m_vMovement.x;
m_pMatExWorld->m_vPosition.z += m_vMovement.y;
m_pMatExWorld->m_vPosition.y += vVelocity.y;
// <20><><EFBFBD><EFBFBD> ó<><C3B3>
float fCurVelocity = 0.f;
float fHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition ) + m_pActor->GetAddHeight();
if( m_vVelocity.y )
{
float fTemp2 = m_vVelocity.y;
m_vLastVelocityValue.y = CalcMovement( fTemp2, 1.f, FLT_MAX, -FLT_MAX, m_vVelocityResist.y );
m_pMatExWorld->m_vPosition.y += CalcMovement( m_vVelocity.y, fDelta, FLT_MAX, -FLT_MAX, m_vVelocityResist.y );
if( m_vVelocity.y == 0.f )
m_vVelocity.y += 0.0000001f;
if( EtVec2LengthSq( &m_vJumpMovement ) > 0.f )
{
EtVector2 vVec = m_vJumpMovement * ( m_fJumpMoveSpeed * fDelta );
m_pMatExWorld->m_vPosition += m_vJumpXVector * vVec.x;
m_pMatExWorld->m_vPosition += m_vJumpZVector * vVec.y;
}
if( m_pMatExWorld->m_vPosition.y <= fHeight )
{
fCurVelocity = m_vVelocity.y - ( ( m_pMatExWorld->m_vPosition.y - fHeight ) * fDelta );
m_vVelocity.y = 0.f;
if( m_pActor->GetAddHeight() == 0.f )
m_bFloorForceVelocity = false;
m_bOnDrop = true;
m_bLastFloorForceVelocity = m_bFloorForceVelocity;
if( m_pActor->GetAddHeight() == 0.f )
m_pMatExWorld->m_vPosition.y = fHeight;
m_bFloorForceVelocity = false;
}
else
{
m_bOnFall = true;
}
}
m_fDropVelocity = fCurVelocity;
// #48950 MoveY <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Y <20><> <20>̵<EFBFBD> ó<><C3B3>
if( m_fMoveYDistancePerSec != 0.0f )
{
float fMoveDistance = m_fMoveYDistancePerSec * fDelta;
m_pMatExWorld->m_vPosition.y += fMoveDistance;
if( 0.0f < fMoveDistance )
m_fLeftMoveYDistance -= fMoveDistance;
else
m_fLeftMoveYDistance += fMoveDistance;
// <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>Ѿ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD> <20><><EFBFBD><EFBFBD>.
if( m_fLeftMoveYDistance < 0.0f )
{
if( 0.0f < fMoveDistance )
m_pMatExWorld->m_vPosition.y -= (fMoveDistance + m_fLeftMoveYDistance);
else
m_pMatExWorld->m_vPosition.y += (fMoveDistance - m_fLeftMoveYDistance);
ResetMoveYDistance();
if( true == m_bMaintainYDistanceOnArriveDestPosition )
{
m_bAppliedYDistance = true;
m_bMaintainYDistanceOnArriveDestPosition = false;
}
}
}
#ifdef _WORK
if( !( GetAsyncKeyState( VK_CONTROL ) < 0 ) )
#endif
ProcessBlock( *m_pActor->GetPrevPosition() );
#ifdef _GAMESERVER
if( m_pActor->IsPlayerActor() ) {
EtVector2 vTemp2 = EtVector2( vPrevPos.x, vPrevPos.z ) - EtVector2( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.z );
AniDistStruct Struct;
Struct.Time = LocalTime;
Struct.fDist = EtVec2Length( &vTemp2 ) * ( 1.f / fDelta );
m_VecAniDistList.push_back( Struct );
m_fAverageAniDist = FLT_MIN;
for( DWORD i=0; i<m_VecAniDistList.size(); i++ ) {
if( LocalTime - m_VecAniDistList[i].Time > 1000 ) {
m_VecAniDistList.erase( m_VecAniDistList.begin() + i );
i--;
continue;
}
if( m_VecAniDistList[i].fDist > m_fAverageAniDist )
m_fAverageAniDist = m_VecAniDistList[i].fDist;
}
}
#endif
}
void MAWalkMovement::PostProcess( LOCAL_TIME LocalTime )
{
if( m_bOnStop ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnStop( m_pMatExWorld->m_vPosition );
#else
OnStop( m_pMatExWorld->m_vPosition );
#endif
}
if( m_bOnDrop ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnDrop( m_fDropVelocity );
#else
OnDrop( m_fDropVelocity );
#endif
}
if( m_bOnFall ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnFall( m_vVelocity.y );
#else
OnFall( m_vVelocity.y );
#endif
}
m_PrevLocalTime = LocalTime;
m_vMovement = EtVector2( 0.f, 0.f );
}
bool MAWalkMovement::IsMovableBlock( CDnWorld* pWorld, EtVector3 &vPos )
{
char cAttr = pWorld->GetAttribute( vPos.x, vPos.z );
int nBlockSize = pWorld->GetAttributeBlockSize( vPos.x, vPos.z );
float fWorldX, fWorldY;
pWorld->CalcWorldBasePos( vPos.x, vPos.z, fWorldX, fWorldY );
float fBlockX = fmodf( fWorldX, (float)nBlockSize );
float fBlockY = fmodf( fWorldY, (float)nBlockSize );
if( (( cAttr & 0x0f ) != 1 && ( cAttr & 0x0f ) != 2) ) {
return true;
}
bool bMovable = false;
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
switch( cHiAttr ) {
case 1:
bMovable = fBlockX + fBlockY < nBlockSize;
break;
case 2:
bMovable = fBlockX < fBlockY;
break;
case 4:
bMovable = fBlockX + fBlockY > nBlockSize;
break;
case 8:
bMovable = fBlockX > fBlockY;
break;
}
return bMovable;
}
void MAWalkMovement::ProcessBlock( EtVector3 vPrevPos )
{
EtVector2 vMove;
vMove.x = m_pMatExWorld->m_vPosition.x - vPrevPos.x;
vMove.y = m_pMatExWorld->m_vPosition.z - vPrevPos.z;
EtVector2 vPos(vPrevPos.x, vPrevPos.z);
EtVector2 vAttrPos = vPos;
char cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
int nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
float fWorldX, fWorldY;
INSTANCE(CDnWorld).CalcWorldBasePos( vPos.x, vPos.y, fWorldX, fWorldY );
float fBlockX = fmodf( fWorldX, (float)nBlockSize );
float fBlockY = fmodf( fWorldY, (float)nBlockSize );
#if (_USE_COLLISION_DEBUG)
std::vector< int > debugAttr;
std::vector< EtVector2 > debugPos;
std::vector< EtVector2 > debugBlock;
std::vector< EtVector2 > debugBlockNext;
std::vector< EtVector2 > debugMove;
std::vector< EtVector2 > debugAttrPos;
std::vector< int > debugCode;
#endif
int nDebugCode = -1;
int nStep = 0;
int nSlideType = 0;
if( EtVec2LengthSq(&vMove) > 2000.0f * 2000.0f ) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD> 20 <20><><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB><EFBFBD> <20>̵<EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>.
nStep = 101;
}
bool bBreakLoop = false;
do
{
nStep++;
if( nStep > 100 ) { // <20>̷<EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵȴ<C8B5>.
OutputDebug("Unknown Collision Error. Loop count exceed.\n");
vPos = EtVector2(vPrevPos.x, vPrevPos.z);
break;
}
if( EtVec2LengthSq(&vMove) <= 0.001f ) {
break;
}
float fBlockNextX = fBlockX + vMove.x;
float fBlockNextY = fBlockY + vMove.y;
#if (_USE_COLLISION_DEBUG)
debugAttr.push_back( cAttr );
debugPos.push_back( vPos);
debugBlock.push_back( EtVector2(fBlockX, fBlockY));
debugBlockNext.push_back( EtVector2(fBlockNextX, fBlockNextY));
debugMove.push_back( vMove );
debugAttrPos.push_back( EtVector2(vAttrPos.x/50.f, vAttrPos.y/50.f));
#endif
// <20><EFBFBD><EBB0A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>˾Ƴ<CBBE><C6B3><EFBFBD>.
int DirIndices[2][2] = {{7,5},{1,3}};
int BitX = (vMove.x >= 0 ? 1 : 0);
int BitY = (vMove.y >= 0 ? 1 : 0);
float fDirX = BitX * nBlockSize - fBlockX;
float fDirY = BitY * nBlockSize - fBlockY;
int nCollideDir = DirIndices[BitX][BitY] + ((fDirX * vMove.y - fDirY * vMove.x > 0 ) ? 1 : -1);
nCollideDir = (nCollideDir>>1)&3; // 0 2 4 6 8 -> 0 1 2 3
float fDa = 0.f;
float fDb = 0.f;
int nIndex = -1;
bool bCollideBlock = (( cAttr & 0x0f ) == 1 || ( cAttr & 0x0f ) == 2); // 0x01, 0x02 <20><> <20>浹üũ
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
if( bCollideBlock ) {
switch( cHiAttr ) {
case 1:
if( nCollideDir == 1 || nCollideDir == 2 ) {
fDa = fBlockX + fBlockY - nBlockSize;
fDb = fBlockNextX + fBlockNextY - nBlockSize;
nIndex = 0;
}
break;
case 2:
if( nCollideDir == 0 || nCollideDir == 1) {
fDa = fBlockX - fBlockY;
fDb = fBlockNextX - fBlockNextY;
nIndex = 1;
}
break;
case 4:
if( nCollideDir == 0 || nCollideDir == 3 ) {
fDa = nBlockSize - fBlockX - fBlockY;
fDb = nBlockSize - fBlockNextX - fBlockNextY;
nIndex = 2;
}
break;
case 8:
if( nCollideDir == 2 || nCollideDir == 3 ) {
fDa = fBlockY - fBlockX;
fDb = fBlockNextY - fBlockNextX;
nIndex = 3;
}
break;
}
}
float fDiagEpsilon = 0.01f;
float fEpsilon = fDiagEpsilon * 1.4142f;
if( fDa <= 0.f && fDb > 0) { // <20><EFBFBD><EBB0A2> <20><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ٲ<EFBFBD> <20><><EFBFBD><EFBFBD>
nDebugCode = 1;
float fRatio = (-fDa-fDiagEpsilon) / (fDb-fDa);
vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1,(1 - fRatio));
// g_DirVector<6F><72><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϹǷ<CFB9> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޾Ƽ<DEBE> ó<><C3B3><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
//vMove = g_DirVector[ nIndex ] * D3DXVec2Dot( &g_DirVector[ nIndex ], &vMove );
EtVector2 vCheckDirVector;
GetCheckDirctionVector( nIndex, vCheckDirVector );
vMove = vCheckDirVector * D3DXVec2Dot( &vCheckDirVector, &vMove );
if( nSlideType == 2 ) { // <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> ó<><C3B3> <20>ѹ<EFBFBD><D1B9>̻<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>. <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20>ɸ<EFBFBD><C9B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
vMove = EtVector2(0,0);
}
nSlideType = 1;
// <20><><EFBFBD><EFBFBD> <20>Ѿ<D1BE><EEB0A1><EFBFBD><EFBFBD> üũ
if( fBlockX+vMove.x < 0.f || fBlockX+vMove.x > nBlockSize ||
fBlockY+vMove.y < 0.f || fBlockY+vMove.y > nBlockSize )
{
bool bDiagDirA = vMove.x+vMove.y > 0.f;
bool bDiagDirB = vMove.x-vMove.y > 0.f;
if( (cHiAttr == 2 && !bDiagDirB ) || (cHiAttr==1 && !bDiagDirA) ) {
vAttrPos.x -= nBlockSize;
fBlockX += nBlockSize;
}
else if( (cHiAttr ==4 && bDiagDirB ) || (cHiAttr==8 && bDiagDirA ) ) {
vAttrPos.x += nBlockSize;
fBlockX -= nBlockSize;
}
else if( (cHiAttr==1 && bDiagDirB ) || (cHiAttr==8 && !bDiagDirA) ) {
vAttrPos.y -= nBlockSize;
fBlockY += nBlockSize;
}
else if( (cHiAttr==2 && bDiagDirA ) || (cHiAttr==4 && !bDiagDirB ) ) {
vAttrPos.y += nBlockSize;
fBlockY -= nBlockSize;
}
else {
ASSERT( false );
}
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
}
else
{
bBreakLoop = true;
}
}
// <20>׸<EFBFBD> <20><><EFBFBD><EFBFBD> <20><20><> <20><><EFBFBD><EFBFBD> (<28>ۿ<EFBFBD><DBBF><EFBFBD> <20><> <20><><EFBFBD>츸) <20>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD>
else if( bCollideBlock && cHiAttr == 0 && (fBlockX < 0 || fBlockX >= nBlockSize || fBlockY < 0 || fBlockY >= nBlockSize) ) {
int OutDirIndices[2][2] = {{7,5},{1,3}};
int OutBitX = (vMove.x > 0.f) ? 0 : 1;
int OutBitY = (vMove.y > 0.f) ? 0 : 1;
float fOutDirX = OutBitX * nBlockSize - fBlockX;
float fOutDirY = OutBitY * nBlockSize - fBlockY;
int nOutCollideDir = OutDirIndices[OutBitX][OutBitY] + ((fOutDirX * vMove.y - fOutDirY * vMove.x > 0 ) ? -1 : 1);
nOutCollideDir = (nOutCollideDir>>1)&3; // 0 2 4 6 8 -> 0 1 2 3
nDebugCode = nOutCollideDir;
if( nOutCollideDir == 2 ) {
float fLocalDa = fBlockY - nBlockSize;
float fLocalDb = fBlockNextY - nBlockSize;
if( fLocalDa >= 0 && fLocalDb <= fEpsilon )
{
ASSERT( fLocalDa >= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (fLocalDa-fEpsilon) / (fLocalDa - fLocalDb);
if(fLocalDa>fEpsilon) vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
if(fLocalDa>fEpsilon) fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1, (1.f - fRatio ));
vMove.y = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextX >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX -= nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextX < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX += nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 0 ) {
float fLocalDa = fBlockY;
float fLocalDb = fBlockNextY;
if( fLocalDa <= 0 && fLocalDb >= -fEpsilon)
{
ASSERT( fLocalDa <= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (-fLocalDa-fEpsilon) / (fLocalDb - fLocalDa);
if(-fLocalDa>fEpsilon) vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
if(-fLocalDa>fEpsilon) fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1, (1.f - fRatio ));
vMove.y = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextX >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX -= nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextX < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX += nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 3 ) {
float fLocalDa = fBlockX;
float fLocalDb = fBlockNextX;
if( (fLocalDa <= 0 && fLocalDb >= -fEpsilon) )
{
ASSERT( fLocalDa <= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (-fLocalDa-fEpsilon) / (fLocalDb - fLocalDa);
vPos.x += vMove.x * fRatio;
if(-fLocalDa>fEpsilon) vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
if(-fLocalDa>fEpsilon) fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min( 1, (1.f - fRatio ));
vMove.x = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextY >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x -= nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX += nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextY < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX += nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 1 ) {
float fLocalDa = fBlockX - nBlockSize;
float fLocalDb = fBlockNextX - nBlockSize ;
if( fLocalDa >= 0 && fLocalDb <= fEpsilon )
{
ASSERT( fLocalDa >= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (fLocalDa-fEpsilon) / (fLocalDa - fLocalDb);
vPos.x += vMove.x * fRatio;
if(fLocalDa>fEpsilon) vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
if(fLocalDa>fEpsilon) fBlockY += vMove.y * fRatio;
ASSERT((vPos.x==vPos.x&&vPos.y==vPos.y));
vMove *= min(1, (1.f - fRatio ));
vMove.x = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextY >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX -= nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextY < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x += nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX -= nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
}
else { // <20>׿<EFBFBD><D7BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ
if( fBlockNextX < 0 || fBlockNextX >= nBlockSize || fBlockNextY < 0 || fBlockNextY >= nBlockSize ) {
switch( nCollideDir )
{
case 0:
vAttrPos.y -= nBlockSize;
fBlockY += nBlockSize;
break;
case 1:
vAttrPos.x += nBlockSize;
fBlockX -= nBlockSize;
break;
case 2:
vAttrPos.y += nBlockSize;
fBlockY -= nBlockSize;
break;
case 3:
vAttrPos.x -= nBlockSize;
fBlockX += nBlockSize;
break;
}
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
nDebugCode = 255;
// continue to next step
}
else {
bBreakLoop = true;
}
}
#if( _USE_COLLISION_DEBUG )
debugCode.push_back( nDebugCode );
#endif
if( bBreakLoop ) {
vPos.x += vMove.x;
vPos.y += vMove.y;
ASSERT((vPos.x==vPos.x&&vPos.y==vPos.y));
}
}while( !bBreakLoop );
m_pMatExWorld->m_vPosition.x = vPos.x;
m_pMatExWorld->m_vPosition.z = vPos.y;
bool bClash = true;
char cAttr2 = INSTANCE(CDnWorld).GetAttribute( m_pMatExWorld->m_vPosition );
if( ( cAttr2 & 0x0f ) == 1 || ( cAttr2 & 0x0f ) == 2 ) {
char cHiAttr = ( cAttr2 & 0xf0 ) >> 4;
if( cHiAttr != 0 )
{
if( !CheckDiagonalBlock( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.z ) ) bClash = false;
}
else bClash = false;
}
if( bClash == false )
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
}
else {
if( ( cAttr & 0x0f ) == 2 && EtVec3LengthSq( &( m_pMatExWorld->m_vPosition - vPrevPos ) ) > 0.f ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnClash( m_pMatExWorld->m_vPosition, eCFCT_None ); // note by kalliste : <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٴ<EFBFBD><D9B4><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> None<6E><65><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> NoFloor <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
#else
OnClash( m_pMatExWorld->m_vPosition, eCFCT_None );
#endif
}
}
}
void MAWalkMovement::ProcessProp( EtVector3 vPrevPos )
{
m_bFloorCollision = false;
if( m_pActor->GetObjectHandle() )
{
#ifdef _GAMESERVER // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD>ʿ<EFBFBD> <20><><EFBFBD> ũ<><C5A9> <20>Ѵ<EFBFBD>.
const float fMinMove = 20.0f;
#else
const float fMinMove = 5.0f;
#endif
EtVector3 vDiffNormal;
float fLength;
vDiffNormal = m_pMatExWorld->m_vPosition - vPrevPos;
fLength = EtVec3Length( &vDiffNormal );
if( fLength <= fMinMove )
{
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vPrevPos, m_bFloorCollision );
}
else
{
EtVector3 vTemp = m_pMatExWorld->m_vPosition;
vDiffNormal /= fLength;
int nCount = 0;
EtVector3 vCurPrevPos = vPrevPos;
while( fLength > 0.0f )
{
if( fLength > fMinMove )
{
m_pMatExWorld->m_vPosition = vCurPrevPos + fMinMove * vDiffNormal;
fLength -= fMinMove;
}
else
{
m_pMatExWorld->m_vPosition = vCurPrevPos + fLength * vDiffNormal;
fLength = 0.0f;
}
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vCurPrevPos, m_bFloorCollision );
m_pActor->GetObjectHandle()->Update( *m_pMatExWorld );
vCurPrevPos = m_pMatExWorld->m_vPosition;
nCount++;
#ifdef _GAMESERVER
if( nCount == 50 )
#else
if( nCount == 200 )
#endif
{
m_pMatExWorld->m_vPosition = vCurPrevPos;
break;
}
}
}
}
if( m_bFloorCollision ) {
if( m_pActor->GetAddHeight() < 0.f ) m_bFloorCollision = false;
}
if( m_bFloorCollision == false )
{
if( m_pActor->GetAddHeight() != 0.f )
{
if( m_vVelocity.y == 0.f )
{
m_vVelocity.y = -1.f;
m_vVelocityResist.y = -20.f;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_bFloorForceVelocity = true;
}
}
m_pActor->SetAddHeight( 0.f );
}
if( m_bFloorCollision == false && m_vVelocity.y == 0.f )
{
#ifdef PRE_FIX_FALL_PROP_COLLISION
m_vVelocity.y = -1.f;
m_vVelocityResist.y = -20.f;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_bFloorForceVelocity = true;
#else
float fHeight = INSTANCE(CDnWorld).GetHeightWithProp( EtVector3( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.y + 100.f, m_pMatExWorld->m_vPosition.z ) );
float fCurHeight = fHeight + m_pActor->GetAddHeight();
m_pMatExWorld->m_vPosition.y = fCurHeight;
#endif
}
}
void MAWalkMovement::Process( LOCAL_TIME LocalTime, float fDelta )
{
// m_fLastHeight = m_pMatEx->m_vPosition.y;
ProcessCommon( LocalTime, fDelta );
#ifndef _GAMESERVER
DebugRenderAttr();
#endif
EtVector3 vPrevPos = *m_pActor->GetPrevPosition();
ProcessProp( vPrevPos );
PostProcess( LocalTime );
}
void MAWalkMovement::ProcessCollision( CDnActor *pActor, EtObjectHandle hObject, const EtVector3 &vPrevPos, bool &bFloorCollision )
{
#ifdef _WORK
if( GetAsyncKeyState( VK_CONTROL ) < 0 ) return;
#endif
int nLoop, i;
float fMoveDist;
EtVector3 vMoveDir;
DNVector(SCollisionResponse) &vecResult = m_vecResult;
vecResult.clear();
vMoveDir = m_pMatExWorld->m_vPosition - vPrevPos;
fMoveDist = EtVec3Length( &vMoveDir );
if( fMoveDist == 0.0f ) {
return;
}
vMoveDir /= fMoveDist;
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <20>ö<EFBFBD><C3B6><EFBFBD> <20><> <20>ֳ<EFBFBD> üũ.
bool bIsClimb = CheckClimb( hObject, vPrevPos, vecResult, bFloorCollision );
if( bIsClimb )
{
float fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
return;
}
if( fMoveDist <= 0.0f )
{
if( m_pActor->GetAddHeight() > 0.f )
bFloorCollision = true;
return;
}
for( nLoop = 0; nLoop < 5; nLoop++ )
{
SCollisionResponse CurResponse;
CurResponse.fContactTime = FLT_MAX;
for( i = 0; i < ( int )vecResult.size(); i++ )
{
EtVector3 vCurNormal = vecResult[ i ].vNormal;
// <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EBB8BB> ũ<>Ⱑ 1.0<EFBFBD><EFBFBD> <20>ȵǸ<C8B5> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> <20>ĺ<EFBFBD><C4BA><EFBFBD> <20><><EFBFBD><EFBFBD><EEB0A1> <20><><EFBFBD><EFBFBD>
/* if( EtVec3LengthSq( &vCurNormal ) <= 0.5f )
{
continue;
}*/
if( EtVec3Dot( &vCurNormal, &vMoveDir ) > 0.0f ) // <20><><EFBFBD>dz븻<C7B3><EBB8BB> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
continue;
}
if( vecResult[ i ].fContactTime < CurResponse.fContactTime )
{
CurResponse = vecResult[ i ];
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5>Ҹ<EFBFBD><D2B8><EFBFBD> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD> <20><>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if( CurResponse.fContactTime == FLT_MAX )
{
// m_pMatEx->m_vPosition = vPrevPos;
break;
}
bool bStopSlide = false;
bool bIsWall = true;
if( EtVec3Dot( &CurResponse.vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.707106f ) // 45<34><35> üũ
{
if( vMoveDir.y < -0.9999f ) // <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȹ̲<C8B9><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
bStopSlide = true;
}
bIsWall = false;
bFloorCollision = true;
}
else if( EtVec3Dot( &CurResponse.vNormal, &EtVector3( 0.0f, -1.0f, 0.0f ) ) > 0.707106f ) // 45<34><35> õ<><C3B5>üũ
{
bIsWall = false;
}
if( !bStopSlide )
{
EtVector3 vSlideDir;
float fWeight;
CalcSlide( vSlideDir, fWeight, CurResponse.vNormal, vMoveDir );
if( ( bIsWall ) && ( vSlideDir.y > 0.0f ) && ( vMoveDir.y <= 0.0f ) ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.. vMoveDir.y > 0.0f Ŀ<><C4BF> <20><><EFBFBD><EFBFBD> <20>϶<EFBFBD><CFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> <20>Ͼ<CFBE><EEB3AA> <20>Ѵ<EFBFBD>.
{
EtVector3 vWallNormal;
vWallNormal = CurResponse.vNormal;
vWallNormal.y = 0.0f;
EtVec3Normalize( &vWallNormal, &vWallNormal );
CalcSlide( vSlideDir, fWeight, vWallNormal, vMoveDir );
}
else if( ( bIsWall ) && ( vSlideDir.y < 0.0f ) ) // <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ִ<EFBFBD>ä<EFBFBD><C3A4> <20><> ū <20><>ü<EFBFBD><C3BC> <20>Ʒ<EFBFBD><C6B7><EFBFBD> <20>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> <20>ȵȴ<C8B5>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ϸ<EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD> <20>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
{
if( m_pActor->GetState() & CDnActorState::Move && (m_pActor->GetState() & CDnActorState::Air) == false )
{
EtVector3 vWallNormal;
vWallNormal = CurResponse.vNormal;
vWallNormal.y = 0.0f;
EtVec3Normalize( &vWallNormal, &vWallNormal );
CalcSlide( vSlideDir, fWeight, vWallNormal, vMoveDir );
}
}
vMoveDir = vSlideDir;
fMoveDist *= fWeight;
m_pMatExWorld->m_vPosition = vPrevPos + vMoveDir * fMoveDist;
}
vecResult.clear();
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
for( i = ( int )vecResult.size() - 1; i >= 0; i-- )
{
if( EtVec3Dot( &vecResult[ i ].vNormal, &CurResponse.vNormal ) > 0.996194f ) // <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 5<><35> <20><><EFBFBD><EFBFBD> <20>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȳ<EFBFBD><C8B3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><>ŵ
{
vecResult.erase( vecResult.begin() + i );
}
}
}
if( vecResult.empty() )
{
break;
}
}
if( nLoop == 5 )
{
if( bFloorCollision )
{
float fLandHeight;
fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
if( m_pMatExWorld->m_vPosition.y > fLandHeight )
{
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
}
m_pMatExWorld->m_vPosition = vPrevPos;
}
else // <20>ٴڰ<D9B4> <20><EFBFBD><E6B5B9> <20>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x,z<><7A> Previous<75><73> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>. <20>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> slide <20>ϸ鼭 <20>̵<EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
// <20>ٴڰ<D9B4> <20><EFBFBD><E6B5B9> <20>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>浹 üũ<C3BC>غ<EFBFBD><D8BA><EFBFBD> y<><79> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> y<><79> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>ٲ<EFBFBD><D9B2><EFBFBD>
vecResult.clear();
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
for( i = 0; i < ( int )vecResult.size(); i++ )
{
// <20><><EFBFBD><EFBFBD><EFBFBD>̿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if( EtVec3Dot( &vecResult[ i ].vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.087155f )
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
bFloorCollision = true;
break;
}
}
}
}
}
else
{
float fLandHeight;
fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
if( fLandHeight > m_pMatExWorld->m_vPosition.y )
{
m_pMatExWorld->m_vPosition.y = fLandHeight;
}
else if( bFloorCollision )
{
// <20>ٴ<EFBFBD> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20>Ͼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ǽ<EFBFBD>.. y<><79><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
// <20>׷<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> <20>ٴ<EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><EFBFBD> y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
if( m_pMatExWorld->m_vPosition.y < vPrevPos.y )
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
}
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
}
}
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnClash( m_pMatExWorld->m_vPosition, bFloorCollision ? eCFCT_Floor : eCFCT_NoFloor );
#else
OnClash( m_pMatExWorld->m_vPosition, bFloorCollision ? eCFCT_Floor : eCFCT_NoFloor );
#endif
char cAttr = INSTANCE(CDnWorld).GetAttribute( m_pMatExWorld->m_vPosition );
if( ( cAttr & 0x0f ) == 1 || ( cAttr & 0x0f ) == 2 ) // 0x01, 0x02 <20><> <20>浹üũ
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
}
}
}
bool MAWalkMovement::CheckClimb( EtObjectHandle hObject, const EtVector3 &vPrevPos, DNVector(SCollisionResponse) &vecResult, bool &bFloorCollision )
{
int i;
float fMinContactTime;;
SCollisionResponse Response;
const float fClimbBasis = MAX_CLIMB_HEIGHT;
SCollisionPrimitive *pFloor;
pFloor = NULL;
fMinContactTime = 1.0f;
for( i = 0; i < ( int )vecResult.size(); i++ )
{
if( EtVec3Dot( &vecResult[ i ].vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.707106f )
{
hObject->CEtCollisionEntity::FindCollision( *vecResult[ i ].pCollisionPrimitive, EtVector3( 0.0f, -fClimbBasis, 0.0f ), Response, true );
if( ( Response.fContactTime >= 0.0f ) && ( fMinContactTime > Response.fContactTime ) )
{
fMinContactTime = Response.fContactTime;
pFloor = vecResult[ i ].pCollisionPrimitive;
}
}
}
if( fMinContactTime != 1.0f )
{
float fMoveHeight;
fMoveHeight = ( 1.0f - fMinContactTime ) * fClimbBasis;
if( fMoveHeight - ( vPrevPos.y - m_pMatExWorld->m_vPosition.y ) <= MAX_CLIMB_HEIGHT )
{
DNVector(SCollisionResponse) &vecClimbResult = m_vecResult;
vecClimbResult.clear();
bFloorCollision = true;
m_pMatExWorld->m_vPosition.y += fMoveHeight;
hObject->FindCollision( *m_pMatExWorld, vecClimbResult );
for( i = 0; i < ( int )vecClimbResult.size(); i++ )
{
if( vecClimbResult[ i ].pCollisionPrimitive != pFloor )
{
break;
}
}
if( i < ( int )vecClimbResult.size() )
{
m_pMatExWorld->m_vPosition.y -= fMoveHeight;
return false;
}
bFloorCollision = true;
return true;
}
}
return false;
}
void MAWalkMovement::CalcSlide( EtVector3 &SlideDir, float &fWeight, EtVector3 &CollisionNormal, EtVector3 &MoveDir )
{
EtVector3 WallCross;
EtVec3Cross( &WallCross, &CollisionNormal, &MoveDir );
EtVec3Normalize( &WallCross, &WallCross );
EtVec3Cross( &SlideDir, &WallCross, &CollisionNormal );
EtVec3Normalize( &SlideDir, &SlideDir );
fWeight = fabs( EtVec3Dot( &SlideDir, &MoveDir ) );
}
void MAWalkMovement::PushAndCollisionCheck( EtVector3 &vPush )
{
EtVector3 vPrevPos;
bool bFloorCollision;
vPrevPos = m_pMatExWorld->m_vPosition;
m_pMatExWorld->m_vPosition += vPush;
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vPrevPos, bFloorCollision );
}
void MAWalkMovement::SetLimitDgrees( float fDgrees )
{
m_fLimitDgrees = fDgrees;
}
void MAWalkMovement::MoveZ( float fSpeed )
{
m_vMovement += EtVector2( m_vMoveVectorZ.x, m_vMoveVectorZ.z ) * fSpeed;
}
void MAWalkMovement::MoveX( float fSpeed )
{
m_vMovement += EtVector2( m_vMoveVectorX.x, m_vMoveVectorX.z ) * fSpeed;
}
void MAWalkMovement::SetMoveVectorX( EtVector3 &vVec )
{
m_vMoveVectorX = vVec;
}
void MAWalkMovement::SetMoveVectorZ( EtVector3 &vVec )
{
m_vMoveVectorZ = vVec;
}
void MAWalkMovement::Jump( float fPower, EtVector2 &vVec )
{
m_vLastVelocity.y = fPower;
m_vVelocity.y += fPower;
m_vJumpMovement = vVec;
m_vJumpXVector = m_vMoveVectorX;
m_vJumpZVector = m_vMoveVectorZ;
m_fJumpMoveSpeed = (float)m_pActor->GetMoveSpeed();
m_bFloorForceVelocity = false;
}
void MAWalkMovement::MoveJumpX( float fSpeed )
{
if( m_vJumpMovement.x > 0.f && fSpeed > 0.f ) return;
if( m_vJumpMovement.x < 0.f && fSpeed < 0.f ) return;
if( fSpeed > 0.f ) fSpeed = -fSpeed;
m_fJumpMoveSpeed += fSpeed;
if( m_fJumpMoveSpeed < 0.f ) m_fJumpMoveSpeed = 0.f;
}
void MAWalkMovement::MoveJumpZ( float fSpeed )
{
if( m_vJumpMovement.y > 0.f && fSpeed > 0.f ) return;
if( m_vJumpMovement.y < 0.f && fSpeed < 0.f ) return;
if( fSpeed > 0.f ) fSpeed = -fSpeed;
m_fJumpMoveSpeed += fSpeed;
if( m_fJumpMoveSpeed < 0.f ) m_fJumpMoveSpeed = 0.f;
}
void MAWalkMovement::SetVelocityByMoveVector( EtVector3 &vVec )
{
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
// <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> <20>ö<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߻<EFBFBD><DFBB><EFBFBD> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20>ִ<EFBFBD>.
// <20><><EFBFBD><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD> <20>ұ<EFBFBD><D2B1>ϰ<EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> OnDrop<6F><70> OnFall, m_bFloorCollision<6F><6E> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>÷<EFBFBD> <20>ٲ<EFBFBD><D9B2><20><><EFBFBD><EFBFBD> <20>ڵ尡 <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD>.
// (<28><><EFBFBD><EFBFBD> <20><><EFBFBD>̱⿣ <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>´<EFBFBD>.)
// <20><> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> <20>ͼ<EFBFBD> m_vVelocity<74><79> y<><79><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD>,
// <20>ٴڿ<D9B4> <20>ִ<EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD> <20>հ<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <20>׷<EFBFBD><D7B7><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> y<><79> 0<>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD>̿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ°Ŷ<C2B0><C5B6><EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> m_vVelocity.y <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20>ϰڴ<CFB0>.
// <20>̰Ͱ<CCB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׻<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴°<CCB4> VelocityResist<73><74><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD>ش<EFBFBD>.
// <20>Ʒ<EFBFBD> m_vLastVelocity<74><79> <20><><EFBFBD>̴µ<CCB4><C2B5><EFBFBD> <20><><EFBFBD>°<EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ŵ.
bool bKeepVelocityY = false;
float fKeepVelocityY = 0.0f;
if( m_bLastFloorForceVelocity && vVec.y == 0.0f )
{
bKeepVelocityY = true;
fKeepVelocityY = m_vVelocity.y;
}
#endif
m_vVelocity = vVec;
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
if( bKeepVelocityY ) m_vVelocity.y = fKeepVelocityY;
#endif
m_vVelocityXVector = m_vMoveVectorX;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vVelocityZVector = m_vMoveVectorZ;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity = vVec;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocity( EtVector3 &vVec )
{
m_vVelocity = vVec;
m_vVelocityXVector = m_pMatExWorld->m_vXAxis;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vVelocityZVector = m_pMatExWorld->m_vZAxis;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity = vVec;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocityX( float fPower )
{
m_vVelocity.x = fPower;
m_vVelocityXVector = m_pMatExWorld->m_vXAxis;
m_vLastVelocity.x = fPower;
}
void MAWalkMovement::SetVelocityY( float fPower )
{
m_vVelocity.y = fPower;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity.y = fPower;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocityZ( float fPower )
{
m_vVelocity.z = fPower;
m_vVelocityZVector = m_pMatExWorld->m_vZAxis;
m_vLastVelocity.z = fPower;
}
void MAWalkMovement::SetResistance( EtVector3 &vVec )
{
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
bool bKeepVelocityResistY = false;
float fKeepVelocityResistY = 0.0f;
if( m_bLastFloorForceVelocity && vVec.y == 0.0f )
{
bKeepVelocityResistY = true;
fKeepVelocityResistY = m_vVelocityResist.y;
}
#endif
m_vVelocityResist = vVec;
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
if( bKeepVelocityResistY ) m_vVelocityResist.y = fKeepVelocityResistY;
#endif
}
void MAWalkMovement::SetResistanceX( float fPower )
{
m_vVelocityResist.x = fPower;
}
void MAWalkMovement::SetResistanceY( float fPower )
{
m_vVelocityResist.y = fPower;
}
void MAWalkMovement::SetResistanceZ( float fPower )
{
m_vVelocityResist.z = fPower;
}
void MAWalkMovement::MovePos( EtVector3 &vPos, bool bRefreshZVec )
{
m_bEnableNaviMode = false;
m_vMovePos = vPos;
m_bRefreshZVector = bRefreshZVec;
if( bRefreshZVec ) {
m_vTargetLookVec.x = vPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
#ifndef _GAMESERVER
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
#endif
}
void MAWalkMovement::MoveTarget( DnActorHandle &hActor, float fMinDistance )
{
m_hMoveTarget = hActor;
m_fTargetMinDistance = fMinDistance;
m_bRefreshZVector = true;
m_bEnableNaviMode = false;
}
DnActorHandle MAWalkMovement::GetMoveTarget()
{
return m_hMoveTarget;
}
void MAWalkMovement::MoveTargetNavi( DnActorHandle &hActor, float fMinDistance, const char* szActionName )
{
MoveTargetNavi( *hActor->GetPosition(), fMinDistance, szActionName );
if( m_bEnableNaviMode )
{
m_hNaviTarget = hActor;
m_nNaviType = NaviType::eTarget;
}
}
void MAWalkMovement::MoveTargetNavi( EtVector3& vTargetPos, float fMinDistance, const char* szActionName )
{
m_fNaviTargetMinDistance = fMinDistance;
m_szNaviTargetActionName = szActionName;
m_hLookTarget.Identity();
m_WayPointList.clear();
m_fTargetMinDistance = fMinDistance;
m_bEnableNaviMode = false;
m_nNaviType = NaviType::eMax;
m_bRefreshZVector = true;
EtVector3 vStartPos = this->m_pMatExWorld->m_vPosition;
EtVector3 vEndPos = vTargetPos;
if( m_bRefreshZVector )
{
m_vTargetLookVec.x = vTargetPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vTargetPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
CEtWorldGrid* pGrid = INSTANCE(CDnWorld).GetGrid();
if( pGrid == NULL )
return;
NavigationMesh* pNaviMesh = pGrid->GetNavMesh(vStartPos);
if( pNaviMesh == NULL )
return;
NavigationCell* pStartCell = pNaviMesh->FindClosestCell( vStartPos );
NavigationCell* pEndCell = pNaviMesh->FindClosestCell( vEndPos );
if ( !pStartCell || !pEndCell )
return;
NavigationPath naviPath;
pNaviMesh->BuildNavigationPath( naviPath, pStartCell, vStartPos, pEndCell, vEndPos );
WAYPOINT_LIST& fur_waypoint_list = naviPath.LineOfSightWayPointList();
if( fur_waypoint_list.empty() )
return;
m_WayPointList = fur_waypoint_list;
m_WayPointId = m_WayPointList.begin();
m_WayPointId++; // <20><>÷<EFBFBD><C3B7>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
m_bEnableNaviMode = true;
m_nNaviType = NaviType::ePosition;
}
#ifdef PRE_MOD_NAVIGATION_PATH
void MAWalkMovement::AutoMoving( EtVector3& vTargetPos, float fMinDistance, const char* szActionName, bool bGeneratePath )
{
m_fNaviTargetMinDistance = fMinDistance;
m_szNaviTargetActionName = szActionName;
m_hLookTarget.Identity();
m_WayPointList.clear();
m_fTargetMinDistance = fMinDistance;
m_bEnableNaviMode = false;
m_nNaviType = NaviType::eMax;
m_bRefreshZVector = true;
EtVector3 vStartPos = this->m_pMatExWorld->m_vPosition;
EtVector3 vEndPos = vTargetPos;
if( m_bRefreshZVector )
{
m_vTargetLookVec.x = vTargetPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vTargetPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
CEtWorldGrid* pGrid = INSTANCE(CDnWorld).GetGrid();
if( pGrid == NULL )
return;
NavigationMesh* pNaviMesh = pGrid->GetNavMesh(vStartPos);
if( pNaviMesh == NULL )
return;
NavigationCell* pStartCell = pNaviMesh->FindClosestCell( vStartPos );
NavigationCell* pEndCell = pNaviMesh->FindClosestCell( vEndPos );
// <20>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>޽<EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD>
if ( !pStartCell || !pEndCell )
return;
if( bGeneratePath )
GenerateAutoMovingPath( pNaviMesh, pStartCell, pEndCell, vStartPos, vEndPos );
m_bEnableNaviMode = true;
m_nNaviType = NaviType::ePosition;
}
// Solve the Catmull-Rom parametric equation for a given time(t) and vector quadruple (p1,p2,p3,p4)
EtVector3 Eq(float t, const EtVector3& p1, const EtVector3& p2, const EtVector3& p3, const EtVector3& p4)
{
float t2 = t * t;
float t3 = t2 * t;
float b1 = static_cast<float>( .5 * ( -t3 + 2*t2 - t) );
float b2 = static_cast<float>( .5 * ( 3*t3 - 5*t2 + 2) );
float b3 = static_cast<float>( .5 * (-3*t3 + 4*t2 + t) );
float b4 = static_cast<float>( .5 * ( t3 - t2 ) );
return (p1*b1 + p2*b2 + p3*b3 + p4*b4);
}
EtVector3 GetInterpolatedSplinePoint(std::vector<EtVector3>& vecList, float t)
{
float delta_t = 1.0f / static_cast<float>(vecList.size() - 1);
// Find out in which interval we are on the spline
int p = (int)(t / delta_t);
// Compute local control point indices
#define BOUNDS(pp) { if (pp < 0) pp = 0; else if (pp >= static_cast<int>( vecList.size() )) pp = static_cast<int>( vecList.size() ) - 1; }
int p0 = p - 1; BOUNDS(p0);
int p1 = p; BOUNDS(p1);
int p2 = p + 1; BOUNDS(p2);
int p3 = p + 2; BOUNDS(p3);
// Relative (local) time
float lt = (t - delta_t*(float)p) / delta_t;
// Interpolate
return Eq(lt, vecList[p0], vecList[p1], vecList[p2], vecList[p3]);
}
void MAWalkMovement::GenerateAutoMovingPath( NavigationMesh* pNaviMesh, NavigationCell* pStartCell, NavigationCell* pEndCell, EtVector3& vStartPos, EtVector3& vEndPos )
{
if( pNaviMesh == NULL || pStartCell == NULL || pEndCell == NULL )
return;
NavigationPath naviPath;
pNaviMesh->BuildNavigationPath( naviPath, pStartCell, vStartPos, pEndCell, vEndPos );
WAYPOINT_LIST& fur_waypoint_list = naviPath.LineOfSightWayPointList();
m_LOSWayPointList.clear();
std::list<WAYPOINT>::iterator iter1 = fur_waypoint_list.begin();
for( ; iter1 != fur_waypoint_list.end(); iter1++ )
m_LOSWayPointList.push_back( (*iter1) );
if( fur_waypoint_list.size() < 2 ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Pass
return;
// <20><><EFBFBD>̴<EFBFBD> <20>κи<CEBA> <20>ɰ<EFBFBD><C9B0><EFBFBD> <20>ȭ
WAYPOINT_LIST waypointlist;
int nInnerNodeCount = static_cast<int>( fur_waypoint_list.size() ) - 2; // <20><><EFBFBD>۰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><>
std::list<WAYPOINT>::iterator iterCurrent = fur_waypoint_list.begin();
// <20><><EFBFBD>ŵǴ<C5B5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
waypointlist.push_back( *iterCurrent ); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
iterCurrent++; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
for( int i=0; i<nInnerNodeCount; i++, iterCurrent++ )
{
std::list<WAYPOINT>::iterator iterPrev = iterCurrent;
iterPrev--;
std::list<WAYPOINT>::iterator iterNext = iterCurrent;
iterNext++;
std::vector<EtVector3> tempvectorlist;
EtVector3 vecTarget = (*iterPrev).Position - (*iterCurrent).Position; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E2BAA4>
float fLength = EtVec3Length( &vecTarget );
float fPointLength = 0.0f;
if( fLength > 800.0f ) // 8m<38><6D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>յ<EFBFBD> 4m<34><6D> 5<><35> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ɰ<EFBFBD>
fPointLength = 400.0f;
else // 8m<38><6D> <20><><EFBFBD><EFBFBD> <20>ʴ´ٸ<C2B4> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɰ<EFBFBD>
fPointLength = fLength / 2.0f;
EtVector3 vecNormal;
EtVec3Normalize( &vecNormal, &vecTarget );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * fPointLength ) );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * ( fPointLength / 2.0f ) ) );
tempvectorlist.push_back( (*iterCurrent).Position );
vecTarget = (*iterNext).Position - (*iterCurrent).Position; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E2BAA4>
fLength = EtVec3Length( &vecTarget );
if( fLength > 800.0f ) // 8m<38><6D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>յ<EFBFBD> 4m<34><6D> 5<><35> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ɰ<EFBFBD>
fPointLength = 400.0f;
else // 8m<38><6D> <20><><EFBFBD><EFBFBD> <20>ʴ´ٸ<C2B4> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɰ<EFBFBD>
fPointLength = fLength / 2.0f;
EtVec3Normalize( &vecNormal, &vecTarget );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * ( fPointLength / 2.0f ) ) );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * fPointLength ) );
if( tempvectorlist.size() == 0 )
continue;
// <20><20><><EFBFBD><EFBFBD>
WAYPOINT_LIST interpolationlist;
int nDivide = 40;
for( int j=0; j<nDivide; j++ )
{
WAYPOINT waypoint;
float fTime = static_cast<float>(j) / static_cast<float>(nDivide);
waypoint.Position = GetInterpolatedSplinePoint( tempvectorlist, fTime );
waypointlist.push_back( waypoint );
}
}
std::list<WAYPOINT>::iterator iterEnd = fur_waypoint_list.end();
iterEnd--;
waypointlist.push_back( *iterEnd ); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EEBCB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>޽<EFBFBD><DEBD>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> <20>˻<EFBFBD><CBBB>Ͽ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EEB6BB> <20>ؾ<EFBFBD><D8BE>ұ<EFBFBD>??????
m_WayPointList = waypointlist;
m_WayPointId = m_WayPointList.begin();
}
#endif // PRE_MOD_NAVIGATION_PATH
void MAWalkMovement::MoveToWorld( EtVector2 &vVec )
{
m_vMovement += vVec;
}
void MAWalkMovement::ResetMove()
{
m_hMoveTarget.Identity();
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
m_vMagnetDir = EtVector2( 0.f, 0.f );
m_fMagnetLength = 0.f;
m_bEnableNaviMode = false;
}
void MAWalkMovement::Look( EtVector2 &vVec, bool bForceRotate )
{
if( bForceRotate ) {
if( EtVec2LengthSq( &vVec ) > 0.f ) {
m_pMatExWorld->m_vZAxis = EtVector3( vVec.x, 0.f, vVec.y );
EtVec3Normalize( &m_pMatExWorld->m_vZAxis, &m_pMatExWorld->m_vZAxis );
m_pMatExWorld->MakeUpCartesianByZAxis();
}
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
else {
m_vTargetLookVec = vVec;
}
}
EtVector3 *MAWalkMovement::GetLookDir()
{
return &m_pMatExWorld->m_vZAxis;
}
void MAWalkMovement::LookTarget( DnActorHandle &hActor )
{
m_hLookTarget = hActor;
if ( m_hLookTarget )
{
OnBeginLook();
}
else
{
OnEndLook();
}
}
void MAWalkMovement::ResetLook()
{
m_hLookTarget.Identity();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
DnActorHandle MAWalkMovement::GetLookTarget()
{
return m_hLookTarget;
}
void MAWalkMovement::SetMagnetDir( EtVector2 &vPos )
{
m_vMagnetDir = vPos;
}
void MAWalkMovement::SetMagnetLength( float fLength )
{
m_fMagnetLength = fLength;
}
EtVector3 *MAWalkMovement::GetVelocity()
{
return &m_vVelocity;
}
EtVector3 *MAWalkMovement::GetResistance()
{
return &m_vVelocityResist;
}
EtVector3 *MAWalkMovement::GetLastVelocity()
{
return &m_vLastVelocity;
}
EtVector3 *MAWalkMovement::GetVelocityValue()
{
return &m_vLastVelocityValue;
}
void MAWalkMovement::SetMagnetPosition( EtVector3 &vPos )
{
EtVector2 vMagnet;
float fHeightDiff = vPos.y - m_pMatExWorld->m_vPosition.y;
vMagnet.x = vPos.x - m_pMatExWorld->m_vPosition.x;
vMagnet.y = vPos.z - m_pMatExWorld->m_vPosition.z;
float fAberraionLength = EtVec2Length( &vMagnet );
if( ( fAberraionLength > 1.f && fAberraionLength < 200.f ) && fHeightDiff < 200.f ) {
SetMagnetLength( fAberraionLength );
EtVec2Normalize( &vMagnet, &vMagnet );
SetMagnetDir( vMagnet );
}
else {
m_pActor->SetPosition( vPos );
}
}
void MAWalkMovement::SetMoveYDistancePerSec( float fMoveYDistancePerSec, float fWholeMoveYDistance, bool bMaintainYDistanceOnArriveDestPosition )
{
if( (0.0f < m_fMoveYDistancePerSec && 0.0f < fMoveYDistancePerSec) ||
(0.0f > m_fMoveYDistancePerSec && 0.0f > fMoveYDistancePerSec) )
return;
// <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
m_fMoveYDistancePerSec = fMoveYDistancePerSec;
// <20><> <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>ǹ<EFBFBD><C7B9>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
_ASSERT( 0.0f < fWholeMoveYDistance );
m_fLeftMoveYDistance = fWholeMoveYDistance;
m_bAppliedYDistance = true;
// <20><>ǥ<EFBFBD><C7A5> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD>ŭ <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD> <20><> Y <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ߴٴ<DFB4> <20>÷<EFBFBD><C3B7><EFBFBD> m_bAppliedYDistance <20><>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD>.
// <20><> <20>÷<EFBFBD><C3B7>׷<EFBFBD> <20><><EFBFBD>߿<EFBFBD> WalkMovementNavi <20><><EFBFBD><EFBFBD> <20>ٴڰ<D9B4><DAB0><EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD>ߴ<EFBFBD> <20><>ƾ<EFBFBD><C6BE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MoveY <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٷ<EFBFBD> <20>ٽ<EFBFBD> <20>ٴڿ<D9B4> <20>ٰ<EFBFBD> <20>ȴ<EFBFBD>.
m_bMaintainYDistanceOnArriveDestPosition = bMaintainYDistanceOnArriveDestPosition;
}
void MAWalkMovement::ResetMoveYDistance( void )
{
m_fMoveYDistancePerSec = 0.0f;
m_fLeftMoveYDistance = 0.0f;
m_bAppliedYDistance = false;
}
#ifndef _GAMESERVER
void MAWalkMovement::DebugRenderAttr()
{
#if defined(_DEBUG) || defined(_RDEBUG)
if( !m_bDebugRenderAttr ) {
return;
}
static EtTextureHandle hTexture, hTextureDiagonal;
if(!hTexture) {
hTexture = EternityEngine::LoadTexture(CEtResourceMng::GetInstance().GetFullName("Attr.dds").c_str() );
hTextureDiagonal = EternityEngine::LoadTexture(CEtResourceMng::GetInstance().GetFullName("AttrDiagonal.dds").c_str() );
}
for( int y = -5; y <= 5; y++)
for( int x = -5; x <= 5; x++)
{
float fX = ((int)(m_pMatExWorld->m_vPosition.x / 50.f)+x)*50.f+25.f;
float fZ = ((int)(m_pMatExWorld->m_vPosition.z / 50.f)+y)*50.f+25.f;
char cAttr = INSTANCE(CDnWorld).GetAttribute( EtVector3(fX,0,fZ) );
if( cAttr & 0x3 ) {
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
EtDecalHandle hDecal = (new CEtDecal)->GetMySmartPtr();
float fAngle = 0.f;
if( cHiAttr == 0 ) {
hDecal->Initialize(hTexture, fX, fZ, 25.f, 0.f, 0.f, 0.f, EtColor(1,1,1,1) );
}
else {
if( cHiAttr == 1 ) fAngle = 0.f;
if( cHiAttr == 2 ) fAngle = 90.f;
if( cHiAttr == 4 ) fAngle = 180.f;
if( cHiAttr == 8 ) fAngle = 270.f;
hDecal->Initialize( hTextureDiagonal, fX, fZ, 25.f, 0.f, 0.f, fAngle, EtColor(1,1,1,1) );
}
}
}
#endif
}
#endif