567 lines
No EOL
18 KiB
C++
567 lines
No EOL
18 KiB
C++
#include "StdAfx.h"
|
|
#include "DnShockInfectionBlow.h"
|
|
#include "EtActionSignal.h"
|
|
#include "DnProjectile.h"
|
|
|
|
#if _GAMESERVER
|
|
#include "DnGameServerManager.h"
|
|
|
|
#else
|
|
#include "DnLocalPlayerActor.h"
|
|
#include "DnInterface.h"
|
|
#include "DnMainDlg.h"
|
|
|
|
#endif
|
|
|
|
#define SHOCK_INFECTION_ACTION_NAME "Skill_ShockInfection"
|
|
|
|
|
|
#if !defined( USE_BOOST_MEMPOOL )
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
#endif // #if !defined( USE_BOOST_MEMPOOL )
|
|
|
|
CDnShockInfectionBlow::CDnShockInfectionBlow( DnActorHandle hActor, const char* szValue ) : CDnBlow( hActor )
|
|
#ifdef _GAMESERVER
|
|
, m_dwCoolTime(0)
|
|
, m_LastActivateTime( 0 )
|
|
#else
|
|
, m_pLocalPlayerActor( NULL )
|
|
#endif // #ifdef _GAMESERVER
|
|
{
|
|
m_StateBlow.emBlowIndex = STATE_BLOW::BLOW_168;
|
|
SetValue( szValue );
|
|
|
|
m_fHitApplyPercent = 0.0f;
|
|
m_fLimitRadius = 0.0f;
|
|
m_fShockProb = 0.0f;
|
|
m_nShockDurationTime = 0;
|
|
|
|
SecureZeroMemory( &m_ProjectileSignalInfo, sizeof(m_ProjectileSignalInfo) );
|
|
|
|
// 인자가 총 4개임.
|
|
// 감전확률;감전지속시간;범위;발사체 히트 시그널에 적용할 데미지%
|
|
string strValue( szValue );
|
|
|
|
// 스트링을 공백단위로 분할한 후
|
|
std::vector<string> vlTokens;
|
|
TokenizeA( strValue, vlTokens, ";" );
|
|
bool bValidArgument = (4 == (int)vlTokens.size());
|
|
_ASSERT( bValidArgument && "감전 전이 상태효과 인자 셋팅이 잘못 되었습니다." );
|
|
|
|
if( bValidArgument )
|
|
{
|
|
string& strShockProb = vlTokens.at( 0 );
|
|
string& strShockDuration = vlTokens.at( 1 );
|
|
string& strRadius = vlTokens.at( 2 );
|
|
string& strProjectileHitSignalPercent = vlTokens.at( 3 );
|
|
|
|
m_fShockProb = (float)atof( strShockProb.c_str() );
|
|
m_nShockDurationTime = (int)atoi( strShockDuration.c_str() );
|
|
m_fLimitRadius = (float)atof( strRadius.c_str() );
|
|
m_fHitApplyPercent = (float)atof( strProjectileHitSignalPercent.c_str() );
|
|
|
|
//// 우선 테스트용.
|
|
//m_fShockProb = 1.0f;
|
|
//m_nShockDurationTime = 100000;
|
|
//m_fLimitRadius = 1000.0f;
|
|
//m_fHitApplyPercent = 1.0f;
|
|
////////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
// 감전 전이에서 사용할 발사체 시그널 정보를 미리 약속해둔 액션에서 발사체 정보를 꺼내온다.
|
|
// 이 상태효과는 self 로 추가되는 것이기 때문에 m_hActor 에서 얻어오면 된다.
|
|
CDnActionBase::ActionElementStruct* pActionElement = m_hActor->GetElement( SHOCK_INFECTION_ACTION_NAME );
|
|
bool bValid = false;
|
|
if( pActionElement )
|
|
{
|
|
if( false == pActionElement->pVecSignalList.empty() )
|
|
{
|
|
CEtActionSignal* pSignal = pActionElement->pVecSignalList.front();
|
|
if( STE_Projectile == pSignal->GetSignalIndex() )
|
|
{
|
|
#ifdef PRE_FIX_MEMOPT_SIGNALH
|
|
CopyShallow_ProjectileStruct(m_ProjectileSignalInfo, static_cast<ProjectileStruct*>(pSignal->GetData()));
|
|
#else
|
|
m_ProjectileSignalInfo = *static_cast<ProjectileStruct*>(pSignal->GetData());
|
|
#endif
|
|
|
|
#ifdef _GAMESERVER
|
|
// 감전 상태 효과
|
|
m_AddtionalSE.nID = STATE_BLOW::BLOW_043;
|
|
m_AddtionalSE.ApplyType = CDnSkill::ApplyTarget;
|
|
m_AddtionalSE.nDurationTime = m_nShockDurationTime;
|
|
m_AddtionalSE.szValue = "1.0";
|
|
#else
|
|
// 상태효과 이펙트 붙이고 말고를 이 클래스에서직접 컨트롤 한다.
|
|
UseTableDefinedGraphicEffect( false );
|
|
#endif // #ifdef _GAMESERVER
|
|
|
|
bValid = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 리소스 셋팅이 잘못되어 상태효과 바로 종료됨.
|
|
if( false == bValid )
|
|
{
|
|
SetState( STATE_BLOW::STATE_END );
|
|
}
|
|
|
|
//m_fRate = 1.0f;
|
|
//m_fLimitRadius = 1000.0f;
|
|
//m_nDurationTime = 5000;
|
|
//m_fHitApplyPercent = 1.0f;
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//m_OffSet = EtVector3(0.0f, 0.0f, 0.0f);
|
|
//m_Direction = EtVector3(0.0f, 0.0f, 1.0f);
|
|
//m_DestPos = EtVector3(0.0f, 0.0f, 0.0f);
|
|
|
|
//m_nOrbitType = CDnProjectile::Homing;
|
|
//m_nTargetType = CDnProjectile::Target;
|
|
//m_VelocityType = CDnProjectile::Accell;
|
|
//m_fProjectileSpeed = 1000.0f;
|
|
//m_nProjectileValidTime = 5000;
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//memset(&m_ProjectileSignalInfo, 0, sizeof(m_ProjectileSignalInfo));
|
|
|
|
//m_ProjectileSignalInfo.nWeaponTableID = 2000;
|
|
//m_ProjectileSignalInfo.nProjectileIndex = -1;
|
|
//m_ProjectileSignalInfo.nOrbitType = CDnProjectile::Homing;
|
|
//m_ProjectileSignalInfo.nTargetType = CDnProjectile::Target;
|
|
//m_ProjectileSignalInfo.nDestroyOrbitType = CDnProjectile::Instantly;
|
|
//m_ProjectileSignalInfo.bTraceHitTarget = FALSE;
|
|
|
|
//m_ProjectileSignalInfo.vOffset = &m_OffSet;
|
|
//m_ProjectileSignalInfo.vDirection = &m_Direction;
|
|
//m_ProjectileSignalInfo.vDestPosition = &m_DestPos;
|
|
|
|
//// 감전 상태 효과
|
|
//m_AddtionalSE.nID = STATE_BLOW::BLOW_043;
|
|
//m_AddtionalSE.ApplyType = CDnSkill::ApplyTarget;
|
|
//m_AddtionalSE.nDurationTime = m_nDurationTime;
|
|
//m_AddtionalSE.szValue = "1.0;1.0";
|
|
|
|
//m_bCreateProjectile = false;
|
|
|
|
#ifdef _GAMESERVER
|
|
AddCallBackType( SB_ONTARGETHIT );
|
|
#endif
|
|
}
|
|
|
|
CDnShockInfectionBlow::~CDnShockInfectionBlow(void)
|
|
{
|
|
|
|
}
|
|
|
|
void CDnShockInfectionBlow::OnBegin( LOCAL_TIME LocalTime, float fDelta )
|
|
{
|
|
#ifdef _GAMESERVER
|
|
// 쿨타임을 부모 스킬의 정보를 그대로 활용한다.
|
|
if( m_ParentSkillInfo.hSkillUser )
|
|
{
|
|
DnSkillHandle hParentSkill = m_ParentSkillInfo.hSkillUser->FindSkill( m_ParentSkillInfo.iSkillID );
|
|
m_dwCoolTime = DWORD(hParentSkill->GetDelayTime() * 1000.0f);
|
|
}
|
|
#else
|
|
m_pLocalPlayerActor = dynamic_cast<CDnLocalPlayerActor*>( m_hActor.GetPointer() );
|
|
if( !m_hParentSkillForCoolTime && m_pLocalPlayerActor )
|
|
{
|
|
m_hParentSkillForCoolTime = CDnSkill::CreateSkill( m_hActor, m_ParentSkillInfo.iSkillID,
|
|
#if defined(PRE_FIX_NEXTSKILLINFO)
|
|
m_ParentSkillInfo.nSkillLevel);
|
|
#else
|
|
m_ParentSkillInfo.iSkillLevelID - m_ParentSkillInfo.iSkillLevelIDOffset + 1 );
|
|
#endif // PRE_FIX_NEXTSKILLINFO
|
|
}
|
|
#endif
|
|
|
|
__super::OnBegin(LocalTime, fDelta);
|
|
}
|
|
|
|
void CDnShockInfectionBlow::Process( LOCAL_TIME LocalTime, float fDelta )
|
|
{
|
|
CDnBlow::Process( LocalTime, fDelta );
|
|
|
|
#ifdef _GAMESERVER
|
|
#else
|
|
if( m_pLocalPlayerActor )
|
|
{
|
|
// 쿨타임 진행.
|
|
m_hParentSkillForCoolTime->Process( LocalTime, fDelta );
|
|
}
|
|
#endif // _GAMESERVER
|
|
|
|
//if (m_bCreateProjectile)
|
|
//{
|
|
// CreateProjectile();
|
|
// m_bCreateProjectile = false;
|
|
//}
|
|
//OutputDebug( "CDnFireBurnBlow::Process, Value:%2.2f (HP : %d ) \n", m_fValue, m_hActor->GetHP());
|
|
}
|
|
|
|
//void CDnShockInfectionBlow::DoShockInfection( DnActorHandle hTargetActor )
|
|
//{
|
|
//#ifdef _GAMESERVER
|
|
// m_LastActivateTime = m_hActor->GetLocalTime();
|
|
// CreateProjectileOnServer( hTargetActor );
|
|
////#else
|
|
//// CreateProjectileOnClient();
|
|
//#endif
|
|
//}
|
|
|
|
#if defined(_GAMESERVER)
|
|
void CDnShockInfectionBlow::DoShockInfection( DnActorHandle hHitTargetActor )
|
|
{
|
|
if( !hHitTargetActor )
|
|
return;
|
|
|
|
m_LastActivateTime = m_hActor->GetLocalTime();
|
|
|
|
DNVector(DnActorHandle) vlActorsInRange;
|
|
if (!hHitTargetActor->ScanActor( hHitTargetActor->GetRoom(), *hHitTargetActor->GetPosition(), m_fLimitRadius, vlActorsInRange ))
|
|
return;
|
|
|
|
// 우선 제일 가까운 액터 선택.. 추후에 다른 규칙이 들어간다면 그렇게 처리한다.
|
|
float fShortestDistanceSQ = FLT_MAX;
|
|
DnActorHandle hActorToInfection;
|
|
DWORD dwNumActors = (DWORD)vlActorsInRange.size();
|
|
for( DWORD dwActor = 0; dwActor < dwNumActors; ++dwActor )
|
|
{
|
|
DnActorHandle hActor = vlActorsInRange.at( dwActor );
|
|
if( false == (hActor->IsShow() && hActor->IsProcess()) )
|
|
continue;
|
|
|
|
// 같은 액터 말고
|
|
if( hActor == hHitTargetActor )
|
|
continue;
|
|
|
|
// npc 액터는 제외
|
|
if( hActor->IsNpcActor() )
|
|
continue;
|
|
|
|
// 다른 팀인 경우만..
|
|
if( hActor->GetTeam() != m_hActor->GetTeam())
|
|
{
|
|
EtVector3 vDistance = (*m_hActor->GetPosition()) - (*hActor->GetPosition());
|
|
|
|
float fLengthSQ = EtVec3LengthSq( &vDistance );
|
|
if( fLengthSQ < fShortestDistanceSQ )
|
|
{
|
|
fShortestDistanceSQ = fLengthSQ;
|
|
hActorToInfection = hActor;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if( hActorToInfection )
|
|
{
|
|
ProjectileStruct* pProjectileSignalInfo = &m_ProjectileSignalInfo;
|
|
|
|
// 프로젝타일 발사 관련 기타 설정들.
|
|
DnSkillHandle hSkill = m_hActor->FindSkill( m_ParentSkillInfo.iSkillID );
|
|
if( !hSkill )
|
|
return;
|
|
|
|
MatrixEx Cross = *m_hActor->GetMatEx();
|
|
Cross.m_vPosition.y += m_hActor->GetHeight() / 2.0f;
|
|
|
|
CDnProjectile *pProjectile = new CDnProjectile( GetRoom(), m_hActor );
|
|
|
|
pProjectile->SetPierce( pProjectileSignalInfo->bPierce == TRUE ? true : false );
|
|
pProjectile->SetMaxHitCount( pProjectileSignalInfo->nMaxHitCount );
|
|
|
|
if( pProjectileSignalInfo->nWeaponTableID > 0 )
|
|
{
|
|
if( pProjectileSignalInfo->nProjectileIndex != -1 )
|
|
{
|
|
DnWeaponHandle hWeapon = CDnWeapon::GetSmartPtr( (CMultiRoom*)g_pGameServerManager->GetRootRoom(), pProjectileSignalInfo->nProjectileIndex );
|
|
if( hWeapon ) *(CDnWeapon*)pProjectile = *hWeapon.GetPointer();
|
|
}
|
|
}
|
|
|
|
int nLength = pProjectile->GetWeaponLength();
|
|
if( pProjectileSignalInfo->bIncludeMainWeaponLength )
|
|
{
|
|
DnWeaponHandle hWeapon = m_hActor->GetWeapon(0);
|
|
if ( hWeapon )
|
|
nLength += hWeapon->GetWeaponLength();
|
|
}
|
|
|
|
// 감전 전이가 잘 되도록 최소한 범위값 만큼의 사거리를 준다.
|
|
if( nLength < (int)m_fLimitRadius )
|
|
nLength = (int)m_fLimitRadius;
|
|
|
|
pProjectile->SetWeaponLength( nLength );
|
|
|
|
pProjectile->SetWeaponType( (CDnWeapon::WeaponTypeEnum)( pProjectile->GetWeaponType() | CDnWeapon::Projectile ) );
|
|
|
|
pProjectile->SetSpeed( pProjectileSignalInfo->fSpeed );
|
|
|
|
pProjectile->SetTargetPosition( *hActorToInfection->GetPosition() );
|
|
pProjectile->SetTargetActor( hActorToInfection );
|
|
|
|
pProjectile->Initialize( Cross, static_cast<CDnProjectile::OrbitTypeEnum>(pProjectileSignalInfo->nOrbitType),
|
|
static_cast<CDnProjectile::DestroyOrbitTypeEnum>(pProjectileSignalInfo->nDestroyOrbitType),
|
|
static_cast<CDnProjectile::TargetTypeEnum>(pProjectileSignalInfo->nTargetType) );
|
|
pProjectile->SetValidTime( pProjectileSignalInfo->nValidTime );
|
|
pProjectile->SetVelocityType( static_cast<CDnProjectile::VelocityTypeEnum>(pProjectileSignalInfo->VelocityType) );
|
|
|
|
pProjectile->SetParentSkill( hSkill );
|
|
|
|
//m_ParentSkillInfo.hPrevAttacker = m_hActor;
|
|
CDnSkill::SkillInfo ParentSkillInfo = m_ParentSkillInfo;
|
|
|
|
char szBuff[128] = {0, };
|
|
_snprintf_s(szBuff, _countof(szBuff), _TRUNCATE, "%d", 402 );
|
|
ParentSkillInfo.szEffectOutputIDToClient = szBuff;
|
|
|
|
// 발사체의 shooter 는 이 상태효과를 가진 액터이고 감전 대상은 적군이므로 이렇게 보내줘야 클라이언트에서 이펙트가 제대로 붙는다.
|
|
// 이 상태효과를 사용하는 주체는 self 로 이 상태효과를 갖고 있다.
|
|
ParentSkillInfo.eTargetType = CDnSkill::TargetTypeEnum::Enemy;
|
|
pProjectile->SetParentSkillInfo( ParentSkillInfo );
|
|
pProjectile->FromSkill( true );
|
|
|
|
pProjectile->SetHitApplyPercent( m_fHitApplyPercent );
|
|
|
|
// 감전 상태 효과 추가..
|
|
pProjectile->AddStateEffect( m_AddtionalSE );
|
|
|
|
boost::shared_ptr<CDnState> pActorStateSnapshotToPass = boost::shared_ptr<CDnState>(new CDnState);
|
|
*pActorStateSnapshotToPass = *static_cast<CDnState*>( m_ParentSkillInfo.hSkillUser.GetPointer() );
|
|
pActorStateSnapshotToPass->SetAttackMMax( m_hActor->GetAttackMMaxWithoutSkill() );
|
|
pActorStateSnapshotToPass->SetAttackMMin( m_hActor->GetAttackMMinWithoutSkill() );
|
|
pProjectile->SetShooterStateSnapshot( pActorStateSnapshotToPass );
|
|
pProjectile->PostInitialize();
|
|
|
|
#if defined(PRE_FIX_65287)
|
|
|
|
float fFinalDamageRate = 0.0f;
|
|
if (m_hActor && m_hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_050))
|
|
{
|
|
DNVector(DnBlowHandle) vlhBlows;
|
|
m_hActor->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_050, vlhBlows );
|
|
int iNumBlow = (int)vlhBlows.size();
|
|
for( int i = 0; i < iNumBlow; ++i )
|
|
{
|
|
fFinalDamageRate += vlhBlows[i]->GetFloatValue();
|
|
}
|
|
}
|
|
|
|
pProjectile->SetShooterFinalDamageRate(fFinalDamageRate);
|
|
#endif // PRE_FIX_65287
|
|
|
|
|
|
// 근처에 가까운 대상에게 발사체를 보내도록 클라에 패킷을 보내준다.
|
|
// 대상은 서버에서 선택된 액터로.
|
|
BYTE pBuffer[ 128 ] = { 0 };
|
|
CPacketCompressStream Stream( pBuffer, 128 );
|
|
|
|
DWORD dwTargetActorUniqueID = hHitTargetActor->GetUniqueID();
|
|
DWORD dwActorToInfection = hActorToInfection->GetUniqueID();
|
|
int nBlowID = GetBlowID();
|
|
|
|
Stream.Write( &dwTargetActorUniqueID, sizeof(dwTargetActorUniqueID) );
|
|
Stream.Write( &dwActorToInfection, sizeof(dwActorToInfection) );
|
|
Stream.Write( &nBlowID, sizeof(nBlowID) );
|
|
//Stream.Write( &m_bCreateProjectile, sizeof(m_bCreateProjectile));
|
|
|
|
m_hActor->Send( eActor::SC_SHOCK_INFECTION, &Stream );
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
void CDnShockInfectionBlow::DoShockInfection( DnActorHandle hHitTargetActor, DnActorHandle hActorToInfection )
|
|
{
|
|
if( hHitTargetActor && hActorToInfection )
|
|
{
|
|
// 서버에서 쿨타임 패링이 성공했을 경우 따로 패킷으로 보내와서 호출된다.
|
|
// 로컬 클라이언트일때만 쿨타임 보여주면 된다.
|
|
if( m_pLocalPlayerActor )
|
|
{
|
|
// 쿨타임만 진행시켜줌. 화면 표시용
|
|
m_hParentSkillForCoolTime->OnBeginCoolTime();
|
|
if( m_hParentSkillForCoolTime->HasCoolTime() )
|
|
{
|
|
CDnMainDlg *pMainDlg = (CDnMainDlg*)GetInterface().GetMainBarDialog();
|
|
if( pMainDlg )
|
|
{
|
|
pMainDlg->AddPassiveSkill( m_hParentSkillForCoolTime );
|
|
}
|
|
}
|
|
}
|
|
|
|
// 프로젝타일 발사 관련 기타 설정들.
|
|
CDnProjectile* pProjectile = CDnProjectile::CreateProjectile( m_hActor,
|
|
*hHitTargetActor->GetMatEx(), &m_ProjectileSignalInfo,
|
|
EtVector3( 0.0f, 0.0f, 0.0f), hActorToInfection );
|
|
}
|
|
}
|
|
#endif // _GAMESERVER
|
|
|
|
|
|
void CDnShockInfectionBlow::OnEnd( LOCAL_TIME LocalTime, float fDelta )
|
|
{
|
|
__super::OnEnd(LocalTime, fDelta);
|
|
|
|
}
|
|
|
|
#if defined(_GAMESERVER)
|
|
void CDnShockInfectionBlow::OnTargetHit( DnActorHandle hTargetActor )
|
|
{
|
|
if (!m_hActor)
|
|
return;
|
|
|
|
if (!hTargetActor || hTargetActor->IsDie())
|
|
return;
|
|
|
|
if (hTargetActor->IsImmuned(m_StateBlow.emBlowIndex))
|
|
return;
|
|
|
|
// 현재 적용되고 있는 내 액션의 히트 시그널 정보를 얻어온다.
|
|
CDnDamageBase::SHitParam* pHitParameter = m_hActor->GetHitParam();
|
|
|
|
// 적용되는 구간의 기준은 히트시그널의 구간과 일치한다.
|
|
// 한번 쿨타임에 하나의 히트시그널에 적용된다.
|
|
// first hit 플래그가 켜져 있다면 이 히트 시그널이 처음으로 hit 된 것이므로
|
|
// 쿨타임을 돌려주기 시작한다. 다음 FirstHit 플래그가 올 때는 쿨타임 간격을
|
|
// 체크해서 해당 간격만큼 시간이 지나지 않았다면 감전 전이를 시키지 않도록 한다.
|
|
bool bNowActivate = true;
|
|
if( pHitParameter->bFirstHit )
|
|
{
|
|
LOCAL_TIME NowLocalTime = m_hActor->GetLocalTime();
|
|
if( NowLocalTime - m_LastActivateTime < m_dwCoolTime )
|
|
{
|
|
bNowActivate = false;
|
|
}
|
|
}
|
|
|
|
if( bNowActivate )
|
|
{
|
|
//감전 상태가 아니면 스킵..
|
|
if (!hTargetActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_043))
|
|
return;
|
|
|
|
//빛 속성 공격이 아니면 스킵
|
|
CDnDamageBase::SHitParam* pHitParam = hTargetActor->GetHitParam();
|
|
if( NULL == pHitParam ||
|
|
CDnState::Light != pHitParam->HasElement )
|
|
return;
|
|
|
|
//확률 계산..
|
|
bool bExecuteable = rand() % 10000 <= (m_fShockProb * 10000.0f);
|
|
if (!bExecuteable)
|
|
return;
|
|
|
|
DoShockInfection( hTargetActor );
|
|
}
|
|
|
|
//이 상태효과의 m_bCreateProjectile를 바꾸는 패킷을 보낸다..
|
|
//m_bCreateProjectile = true;
|
|
}
|
|
#endif // _GAMESERVER
|
|
|
|
#if defined(PRE_ADD_PREFIX_SYSTE_RENEW)
|
|
void CDnShockInfectionBlow::AddStateEffectValue(const char* szOrigValue, const char* szAddValue, std::string& szNewValue)
|
|
{
|
|
char szBuff[128] = {0, };
|
|
|
|
//필요한 변수
|
|
float fShockProb[2] = {0.0f, };
|
|
int nShockDuration[2] = { 0, };
|
|
float fLimitRadius[2] = { 0.0f, };
|
|
float fHitApplyPercent[2] = { 0.0f, };
|
|
|
|
// 인자가 총 4개임.
|
|
// 감전확률;감전지속시간;범위;발사체 히트 시그널에 적용할 데미지%
|
|
std::string strValue( szOrigValue );
|
|
|
|
// 스트링을 공백단위로 분할한 후
|
|
std::vector<string> vlTokens[2];
|
|
TokenizeA( strValue, vlTokens[0], ";" );
|
|
|
|
if( (int)vlTokens[0].size() == 4 )
|
|
{
|
|
fShockProb[0] = (float)atof( vlTokens[0][0].c_str() );
|
|
nShockDuration[0] = (int)atoi( vlTokens[0][1].c_str() );
|
|
fLimitRadius[0] = (float)atof( vlTokens[0][2].c_str() );
|
|
fHitApplyPercent[0] = (float)atof( vlTokens[0][3].c_str() );
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
strValue = szAddValue;
|
|
TokenizeA( strValue, vlTokens[1], ";" );
|
|
|
|
if( (int)vlTokens[1].size() == 4 )
|
|
{
|
|
fShockProb[1] = (float)atof( vlTokens[1][0].c_str() );
|
|
nShockDuration[1] = (int)atoi( vlTokens[1][1].c_str() );
|
|
fLimitRadius[1] = (float)atof( vlTokens[1][2].c_str() );
|
|
fHitApplyPercent[1] = (float)atof( vlTokens[1][3].c_str() );
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
float fResultShockProb = fShockProb[0] + fShockProb[1];
|
|
int nResultShockDuration = max(nShockDuration[0], nShockDuration[1]);
|
|
float fResultLimitRadius = max(fLimitRadius[0], fLimitRadius[1]);
|
|
float fResultHitApplyPrecent = fHitApplyPercent[0] + fHitApplyPercent[1];
|
|
|
|
sprintf_s(szBuff, "%f;%d;%f;%f", fResultShockProb, nResultShockDuration, fResultLimitRadius, fResultHitApplyPrecent);
|
|
|
|
szNewValue = szBuff;
|
|
}
|
|
|
|
void CDnShockInfectionBlow::RemoveStateEffectValue(const char* szOrigValue, const char* szAddValue, std::string& szNewValue)
|
|
{
|
|
char szBuff[128] = {0, };
|
|
|
|
//필요한 변수
|
|
float fShockProb[2] = {0.0f, };
|
|
int nShockDuration[2] = { 0, };
|
|
float fLimitRadius[2] = { 0.0f, };
|
|
float fHitApplyPercent[2] = { 0.0f, };
|
|
|
|
// 인자가 총 4개임.
|
|
// 감전확률;감전지속시간;범위;발사체 히트 시그널에 적용할 데미지%
|
|
std::string strValue( szOrigValue );
|
|
|
|
// 스트링을 공백단위로 분할한 후
|
|
std::vector<string> vlTokens[2];
|
|
TokenizeA( strValue, vlTokens[0], ";" );
|
|
|
|
if( (int)vlTokens[0].size() == 4 )
|
|
{
|
|
fShockProb[0] = (float)atof( vlTokens[0][0].c_str() );
|
|
nShockDuration[0] = (int)atoi( vlTokens[0][1].c_str() );
|
|
fLimitRadius[0] = (float)atof( vlTokens[0][2].c_str() );
|
|
fHitApplyPercent[0] = (float)atof( vlTokens[0][3].c_str() );
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
strValue = szAddValue;
|
|
TokenizeA( strValue, vlTokens[1], ";" );
|
|
|
|
if( (int)vlTokens[1].size() == 4 )
|
|
{
|
|
fShockProb[1] = (float)atof( vlTokens[1][0].c_str() );
|
|
nShockDuration[1] = (int)atoi( vlTokens[1][1].c_str() );
|
|
fLimitRadius[1] = (float)atof( vlTokens[1][2].c_str() );
|
|
fHitApplyPercent[1] = (float)atof( vlTokens[1][3].c_str() );
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
float fResultShockProb = fShockProb[0] - fShockProb[1];
|
|
int nResultShockDuration = min(nShockDuration[0], nShockDuration[1]);
|
|
float fResultLimitRadius = min(fLimitRadius[0], fLimitRadius[1]);
|
|
float fResultHitApplyPrecent = fHitApplyPercent[0] - fHitApplyPercent[1];
|
|
|
|
sprintf_s(szBuff, "%f;%d;%f;%f", fResultShockProb, nResultShockDuration, fResultLimitRadius, fResultHitApplyPrecent);
|
|
|
|
szNewValue = szBuff;
|
|
}
|
|
#endif // PRE_ADD_PREFIX_SYSTE_RENEW
|