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

519 lines
14 KiB
C++

#include "SunClientPrecompiledHeader.h"
#include "ProjectileBase.h"
#include "ObjectManager.h"
#include "Character.h"
#include "Camera.h"
#include "GlobalFunc.h"
cTargetPosition::cTargetPosition()
: m_Rotate(c_ZeroVector)
, m_Scale(c_UnitVector)
, m_Position(c_ZeroVector)
, m_OffsetPosition(c_ZeroVector)
, m_Type(nProjectile::TRACE_TYPE_NONE)
, m_Trace(FALSE)
, m_PositionType(eSKILLEFFECT_POS_NONE)
, m_BoneIndex(-1)
, m_TargetObjectKey(INVALID_OBJECT_KEY)
, m_SyncTargetAngle(FALSE)
{
}
void cTargetPosition::SetPosition( const WzVector& Position )
{
m_Type = nProjectile::TRACE_TYPE_NONE;
m_Trace = FALSE;
m_Position = Position;
}
void cTargetPosition::SetTargetBonePosition( DWORD TargetObjectKey, eSKILLEFFECT_POS PositionType, int BoneIndex, BOOL Trace )
{
m_Type = nProjectile::TRACE_TYPE_BONE;
m_Trace = Trace;
m_TargetObjectKey = TargetObjectKey;
m_PositionType = PositionType;
m_BoneIndex = BoneIndex;
}
void cTargetPosition::SetTargetVisiblePosition( DWORD TargetObjectKey, BOOL Trace )
{
m_Type = nProjectile::TRACE_TYPE_TARGET_VISIBLE_POSITION;
m_TargetObjectKey = TargetObjectKey;
m_Trace = Trace;
}
void cTargetPosition::SetTargetArrowPosition( DWORD TargetObjectKey, BOOL Trace )
{
m_Type = nProjectile::TRACE_TYPE_TARGET_ARROW_POSITION;
m_TargetObjectKey = TargetObjectKey;
m_Trace = Trace;
}
void cTargetPosition::SetTargetTopPosition( DWORD TargetObjectKey, BOOL Trace )
{
m_Type = nProjectile::TRACE_TYPE_TARGET_TOP_POSITION;
m_TargetObjectKey = TargetObjectKey;
m_Trace = Trace;
}
void cTargetPosition::SetArrowPosition( const WzVector& Position, DWORD TargetObjectKey, BOOL Trace )
{
m_Type = nProjectile::TRACE_TYPE_ARROW;
m_TargetObjectKey = TargetObjectKey;
m_Trace = Trace;
}
BOOL cTargetPosition::UpdatePosition()
{
if( m_Type == nProjectile::TRACE_TYPE_NONE )
return TRUE;
if( m_TargetObjectKey == 0 || m_TargetObjectKey == INVALID_OBJECT_KEY )
{
return TRUE;
}
Character* pTarget = (Character*)g_ObjectManager.GetObject( m_TargetObjectKey );
if( pTarget == NULL )
return FALSE;
if( m_Type == nProjectile::TRACE_TYPE_TARGET_ARROW_POSITION )
{
m_Position = pTarget->GetArrowTargetPos();
m_Position += m_OffsetPosition;
}
else if( m_Type == nProjectile::TRACE_TYPE_TARGET_VISIBLE_POSITION )
{
m_Position = pTarget->GetVisiblePos();
m_Position += m_OffsetPosition;
}
else if( m_Type == nProjectile::TRACE_TYPE_TARGET_TOP_POSITION )
{
m_Position = pTarget->GetVisiblePos();
m_Position.z += pTarget->GetHeight();
m_Position += m_OffsetPosition;
}
else if( m_Type == nProjectile::TRACE_TYPE_BONE )
{
if( m_PositionType == eSKILLEFFECT_POS_BONE_INDEX )
{
m_Position = pTarget->GetBonePos( m_BoneIndex );
m_Position += m_OffsetPosition;
}
else if( m_PositionType == eSKILLEFFECT_POS_RHAND ||
m_PositionType == eSKILLEFFECT_POS_LHAND ||
m_PositionType == eSKILLEFFECT_POS_WEAPON )
{
m_Position = pTarget->GetSkillEffectPos( m_PositionType, m_BoneIndex );
m_Position += m_OffsetPosition;
WzVector vDest,vTemp;
vDest = m_Position + pTarget->GetDirection()*10.0f;
vDest = vDest - m_Position;
vTemp = vDest;
vTemp.z = 0.0f;
float fLength;
if (vTemp.x == 0.0f && vTemp.y == 0.0f)
{
fLength = 0.0f;
}
else
{
fLength = VectorLength(&vTemp);
}
float fArrowAngleX = -atan2(vDest.z,fLength);
float fArrowAngleZ = Math_GetAngleFromVector(&vDest);
m_Rotate.x = fArrowAngleX;
m_Rotate.y = 0.0f;
m_Rotate.z = fArrowAngleZ;
m_Scale = c_UnitVector;
}
else
{
// ġ
m_Position = pTarget->GetSkillEffectPos( m_PositionType, m_BoneIndex );
m_Position += m_OffsetPosition;
m_Rotate.y = 0.0f;
m_Rotate.z = pTarget->GetAngle();;
m_Rotate.x = pTarget->GetAngleX();
}
}
if( m_SyncTargetAngle == TRUE )
{
m_Rotate.y = 0.0f;
m_Rotate.z = pTarget->GetAngle();
m_Rotate.x = pTarget->GetAngleX();
}
if( m_Trace == FALSE )
{
m_TargetObjectKey = INVALID_OBJECT_KEY;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cProjectileHit::cProjectileHit()
{
m_IsDamageProcessed = FALSE;
m_OwnerObjectKey = 0;
m_AttackSerial = 0;
m_HitEffectID = 0;
m_IsCameraShakeHit = FALSE;
m_DamageTime = 0;
m_IsAddNextAttackSerial = FALSE;
m_CameraViberationType = Camera::VIBE_TYPE_VERTICAL;
m_CameraViberationTime = 50.f;
m_CameraViberationPower = 0.07f;
}
void cProjectileHit::SetHitData( DWORD AttackObjectKey, DWORD AttackSerial, WzID EffectID, BOOL CameraShake, DWORD MaxWaitTime, BOOL IsAddNextAttackSerial )
{
m_OwnerObjectKey = AttackObjectKey;
m_AttackSerial = AttackSerial;
m_IsCameraShakeHit = CameraShake;
m_DamageTime = MaxWaitTime;
m_HitEffectID = EffectID;
m_IsAddNextAttackSerial = IsAddNextAttackSerial;
}
void cProjectileHit::Process()
{
if( m_DamageTime != 0 )
{
if( GetCurrentDamageTickTime() >= m_DamageTime )
{
_ProcessDamage();
}
}
}
void cProjectileHit::Destroy()
{
_ProcessDamage();
}
void cProjectileHit::SetCameraShakeType( Camera::VIBE_TYPE ViberationType, float ViberationTime, float ViberationPower )
{
m_IsCameraShakeHit = TRUE;
m_CameraViberationType = ViberationType;
m_CameraViberationTime = ViberationTime;
m_CameraViberationPower = ViberationPower;
}
void cProjectileHit::_ProcessDamage()
{
if( m_IsDamageProcessed == TRUE )
return;
m_IsDamageProcessed = TRUE;
if( m_OwnerObjectKey != 0 )
{
if( Object* pObject = (Object*)g_ObjectManager.GetObject( m_OwnerObjectKey ) )
{
if( pObject->IsKindOfObject( CHARACTER_OBJECT ) )
{
Character* pCharacter = (Character*)pObject;
pCharacter->ProcessAttackResult_Group( m_AttackSerial );
if( m_IsAddNextAttackSerial )
{
pCharacter->AddNextAttackSerial();
}
}
}
}
if( m_IsCameraShakeHit == TRUE )
{
g_Camera.SetVibeType( m_CameraViberationType );
g_Camera.StartVibration( m_CameraViberationTime, m_CameraViberationPower );
m_IsCameraShakeHit = FALSE;
}
if( m_HitEffectID != 0 )
{
GlobalFunc::CreateEffectBeUpToOption( m_HitEffectID, GetDamageEffectPosition(), 0, 0 );
m_HitEffectID = 0;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cProjectileTarget::cProjectileTarget()
{
}
void cProjectileTarget::Process()
{
m_PositionData.UpdatePosition();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cProjectileBezier::cProjectileBezier()
: m_Type(TYPE_DUAL_CONTROL)
, m_TargetObjectKey(INVALID_OBJECT_KEY)
{
}
void cProjectileBezier::SetBezierCourseSingleControl( const WzVector& StartPosition, const WzVector& ControlPoint, DWORD TargetObjectKey )
{
m_Type = TYPE_TRACE_OBJECT_SINGLE_CONTROL;
m_StartPosition = StartPosition;
m_CurvePosition1 = ControlPoint;
m_TargetObjectKey = TargetObjectKey;
}
void cProjectileBezier::SetBezierCourseSingleControl( const WzVector& StartPosition, const WzVector& TargetPosition, const WzVector& ControlPoint1 )
{
m_Type = TYPE_SINGLE_CONTROL;
m_StartPosition = StartPosition;
m_TargetPosition = TargetPosition;
m_CurvePosition1 = ControlPoint1;
}
void cProjectileBezier::SetBezierCourse( const WzVector& StartPosition, const WzVector& TargetPosition, const WzVector& ControlPoint1, const WzVector& ControlPoint2 )
{
m_Type = TYPE_DUAL_CONTROL;
m_StartPosition = StartPosition;
m_TargetPosition = TargetPosition;
m_CurvePosition1 = ControlPoint1;
m_CurvePosition2 = ControlPoint2;
}
void cProjectileBezier::SetPosition( const WzVector& StartPosition, const WzVector& TargetPosition, float Height1, float Height2 )
{
m_Type = TYPE_DUAL_CONTROL;
m_StartPosition = StartPosition;
m_TargetPosition = TargetPosition;
m_CurvePosition1 = StartPosition;
m_CurvePosition2 = TargetPosition;
m_CurvePosition1.z += Height1;
m_CurvePosition2.z += Height2;
}
void _CalcBezierCurvePosition( float fRate, const WzVector& p0, const WzVector& p1, const WzVector& p2, OUT WzVector& result )
{
//조절점 1개인 베지어 기저식
result = (p0 * (1.0f - fRate) * (1.0f - fRate) + p1* (1.0f - fRate) * fRate*2.0f + p2 * fRate * fRate);
};
void _CalcBezierCurvePosition( float fRate, const WzVector& p0, const WzVector& p1, const WzVector& p2, const WzVector& p3, OUT WzVector& result )
{
result =
p0 * ((1.0f - fRate) * (1.0f - fRate) * (1.0f - fRate)) +
p1 * fRate * 3.0f * ((1.0f - fRate) * (1.0f - fRate)) +
p2 * 3.0f * fRate * fRate * (1.0f - fRate) +
p3 * (fRate*fRate*fRate);
};
void _CalcArrowPosition( const WzVector& StartPosition, const WzVector& TargetPosition, float fRate, OUT WzVector& Position )
{
Position = StartPosition * (1.0f - fRate) + TargetPosition * (fRate);
}
void _CalcDirectionRotate( const WzVector& StartPosition, const WzVector& TargetPosition, OUT WzVector& Rotate )
{
WzVector vDest = TargetPosition - StartPosition;
float fLength;
if ( vDest.x == 0.0f && vDest.y == 0.0f )
{
fLength = 0.0f;
}
else
{
WzVector vTemp = vDest;
vTemp.z = 0.0f;
fLength = VectorLength(&vTemp);
}
float fArrowAngleX = -atan2(vDest.z,fLength);
float fArrowAngleZ = Math_GetAngleFromVector(&vDest);
Rotate.x = fArrowAngleX;
Rotate.y = 0.0f;
Rotate.z = fArrowAngleZ;
}
void cProjectileBezier::Process()
{
float fRate = GetArrowMoveTimeRate();
//베지어 기저식
if( m_Type == TYPE_DUAL_CONTROL )
{
_CalcBezierCurvePosition( fRate, m_StartPosition, m_CurvePosition1, m_CurvePosition2, m_TargetPosition, m_CurrentPosition );
_CalcDirectionRotate( m_StartPosition, m_TargetPosition, m_CurrentRotate );
}
else if( m_Type == TYPE_SINGLE_CONTROL )
{
_CalcBezierCurvePosition( fRate, m_StartPosition, m_CurvePosition1, m_TargetPosition, m_CurrentPosition );
_CalcDirectionRotate( m_StartPosition, m_TargetPosition, m_CurrentRotate );
}
else if( m_Type == TYPE_TRACE_OBJECT_SINGLE_CONTROL )
{
if( Character* pTarget = (Character*)g_ObjectManager.GetObject( m_TargetObjectKey ) )
{
WzVector TargetPosition = pTarget->GetArrowTargetPos();
_CalcBezierCurvePosition( fRate, m_StartPosition, m_CurvePosition1, TargetPosition, m_CurrentPosition );
_CalcDirectionRotate( m_StartPosition, TargetPosition, m_CurrentRotate );
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cProjectileArrow::cProjectileArrow()
{
}
void cProjectileArrow::Process()
{
m_TargetPosition.UpdatePosition();
// UpdateProjectionPosition
float fRate = GetArrowMoveTimeRate();
_CalcArrowPosition( m_StartPosition, m_TargetPosition.GetPosition(), GetArrowMoveTimeRate(), m_ArrowPosition );
_CalcDirectionRotate( m_StartPosition, m_TargetPosition.GetPosition(), m_ArrowRotate );
m_ArrowScale = c_UnitVector;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cProjectileBase::cProjectileBase()
: m_IsActived(FALSE)
, m_Delay(0)
, m_LifeTime(0)
, m_ActiveDelay(0)
, m_RemainTime(0)
{
}
BOOL cProjectileBase::Process( DWORD dwTick )
{
m_Delay += dwTick;
BOOL Result = IsTimeout();
if( Result == TRUE )
return TRUE;
if( m_IsActived == FALSE )
{
if( m_Delay >= m_ActiveDelay )
{
m_IsActived = TRUE;
}
}
return FALSE;
}
float cProjectileBase::GetMovingTimeRate()
{
if( m_IsActived == FALSE )
{
return 0.0f;
}
return m_LifeTime > 0 ? min((float)((float)(m_Delay-m_ActiveDelay) / (float)m_LifeTime), 1.0f ) : 0.0f;
}
float cProjectileBase::GetTotalLifeTimeRate()
{
if( m_IsActived == FALSE )
{
return 0.0f;
}
return m_LifeTime > 0 ? min((float)((float)(m_Delay-m_ActiveDelay) / (float)(m_LifeTime+m_RemainTime) ), 1.0f ) : 0.0f;
}
//float cProjectileBase::GetLifeTimeRate()
//{
// if( m_IsActived == FALSE )
// {
// return 0.0f;
// }
//
// return m_LifeTime > 0 ? min((float)((float)(m_Delay-m_ActiveDelay) / (float)m_LifeTime), 1.0f ) : 0.0f;
//}
BOOL cProjectileBase::IsTimeout()
{
if( m_IsActived == FALSE )
return FALSE;
if( m_Delay - m_ActiveDelay >= m_LifeTime+m_RemainTime )
return TRUE;
return FALSE;
}
DWORD cProjectileBase::GetCurrentTickTime()
{
if( m_IsActived == FALSE )
return 0;
return m_Delay - m_ActiveDelay;
}
void cProjectileBase::SetRemainTime( DWORD RemainTime )
{
m_RemainTime = RemainTime;
}
void cProjectileBase::SetActiveDelayTime( DWORD ActiveDelayTime )
{
m_ActiveDelay = ActiveDelayTime;
}
void cProjectileBase::SetLifeTime( DWORD LifeTime )
{
m_LifeTime = LifeTime;
}