⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skill.cpp

📁 奇迹世界 部分源代码奇迹世界 部分源代码奇迹世界 部分源代码
💻 CPP
字号:
#include "stdafx.h"
#include "Skill.h"
#include "SkillInfoParser.h"
#include "NPC.h"
#include "Field.h"
#include "Character.h"
#include "Player.h"
#include "AITypes.h"
#include "PublicMath.h"
#include "FieldInfo.h"
#include <Struct.h>
#include <PacketStruct_CG.h>
#include <Const.h>
#include "Ability.h"
#include "AbilityFactory.h"
#include "StatusManager.h"

RESULTMSG Skill::m_ResultMsg[MAX_TARGET_NUM];
RESULTMSG Skill::m_ResultEffectMsg[5];

Skill::Skill() : m_pOwnerChar(NULL), m_dwExecuteTick(0), m_pBaseSkillInfo(NULL), m_wInterval(0), m_bySkillAttribution(0)
{
}

VOID Skill::Init( Character* pOwnerChar, SkillInfo* pSkillInfo, void* pBaseSkillInfo )
{
	m_pOwnerChar = pOwnerChar;
	m_bEndExecute = TRUE;
	memset(&m_SkillInfo, 0x00, sizeof(SkillInfo) );
	memcpy( &m_SkillInfo, pSkillInfo, sizeof(SkillInfo) );
	m_pBaseSkillInfo = (SkillScriptInfo*)pBaseSkillInfo;
	
	m_bTempApply = TRUE;
	m_iSkillAttackPower = 0;
	m_fSkillPercentDamage = 0;
	m_listAbilitys.clear();

	// 胶懦 加己 汲沥
	SetAttribution();

	// ExecuteInterval 悸泼
	SetExecuteInterval();

	// ExecuteTick 悸泼
	m_dwExecuteTick = GetTickCount() + GetExecuteInterval();
}

SLOTCODE Skill::GetSkillCode()
{ 
	return m_pBaseSkillInfo->m_SkillCode; 
}

eSKILL Skill::GetSkillClassCode()
{ 
	return (eSKILL)m_pBaseSkillInfo->m_SkillClassCode; 
}

eSKILL_TYPE	Skill::GetSkillType()	
{ 
	return (eSKILL_TYPE)m_pBaseSkillInfo->m_bySkillType; 
}

VOID Skill::SetAttribution()
{
	switch( GetSkillClassCode() )
	{
	case eSKILL_DOUBLE_ATTACK:	case eSKILL_AIRBLOW:	case eSKILL_BATTLERHONE:
		m_bySkillAttribution |= SKILL_ATTRIBUTION_INVISIBLE;
		m_bySkillAttribution |= SKILL_ATTRIBUTION_TARGETFLYING;
		break;
	case eSKILL_ILLUSION_DANCE:
		m_bySkillAttribution |= SKILL_ATTRIBUTION_INVISIBLE;
		m_bySkillAttribution |= SKILL_ATTRIBUTION_TARGETSTOP;
		break;
	case eSKILL_BLOOD_RAIN:
		m_bySkillAttribution |= SKILL_ATTRIBUTION_INVISIBLE;
		break;
	}
}

BOOL Skill::CheckMainTarget()
{
	if( !m_pField ) 
	{
		SUNLOG( eCRITICAL_LOG, "[Skill::CheckMainTarget] Field is NULL!" );
		return FALSE;
	}

	// 家券胶懦篮 皋牢鸥百捞 绝促.
	if( m_pBaseSkillInfo->m_byTarget == SKILL_TARGET_SUMMON )
		return TRUE;

	// 皋牢鸥百 谅钎甫 汲沥茄促.
	if( m_pBaseSkillInfo->m_byTarget == SKILL_TARGET_ME )
	{
		m_SkillInfo.m_dwMainTargetKey = m_pOwnerChar->GetObjectKey();
		m_SkillInfo.m_wvMainTargetPos = m_SkillInfo.m_wvCurPos;
	}
	else if( m_pBaseSkillInfo->m_byTarget == SKILL_TARGET_AREA )
	{
	}
	else if( m_pBaseSkillInfo->m_byAttRangeform != SRF_PIERCE )		// 包烹胶懦牢 版快 m_wvMainTargetPos阑 弊措肺 敬促.
	{
		Character *pMainTarget = m_pField->FindCharacter( m_SkillInfo.m_dwMainTargetKey );
		if( pMainTarget )
		{
			pMainTarget->GetPos( &m_SkillInfo.m_wvMainTargetPos );
		}
	}

	// 皋牢鸥百俊 措秦 胶懦 荤芭府甫 眉农茄促.
	BOOL bSkillRangeCheck = m_pOwnerChar->CheckSkillRange( m_SkillInfo.m_wvMainTargetPos, m_pBaseSkillInfo->m_wSkillRange/10.0f );
	if( !bSkillRangeCheck )		return FALSE;

	return TRUE;
}

BOOL Skill::ParamInitialize()
{
	m_pField = m_pOwnerChar->GetField();
	if( !m_pField ) 
	{
		SUNLOG( eCRITICAL_LOG, "[Skill::ParamInitialize] Field is NULL!" );
		return FALSE;
	}

	// 颇扼固磐 汲沥
	m_byNumberOfTargets = 0;
	m_byHitTargetCount = 0;
	m_byEffectCount = 0;
	memset( m_ResultMsg, 0, sizeof(RESULTMSG)*MAX_TARGET_NUM );
	memset( m_ResultEffectMsg, 0, sizeof(RESULTMSG)*5 );
	memset( m_pTarget, 0, sizeof(Character*)*MAX_TARGET_NUM );

	return TRUE;
}

VOID Skill::CommonExecute()
{
	// 敲饭捞绢狼 HP, MP甫 皑家矫挪促.
	m_pOwnerChar->DecreaseHP( m_pBaseSkillInfo->m_wHPSpend );
	m_pOwnerChar->DecreaseMP( m_pBaseSkillInfo->m_wMPSpend );

	// 胶懦 备荤吝 嘎瘤 臼档废 秦具 窍绰 版快 厚怜阑 波霖促.
	if( GetAttribution() & SKILL_ATTRIBUTION_INVISIBLE )
	{
		m_pOwnerChar->GetStatusManager()->AllocStatus( eCHAR_STATE_ETC_DISABLE_VISION, BASE_EXPIRE_TIME_INFINITY, 0 );
	}

	// Ability 殿废
	BASE_ABILITYINFO * pAbilityInfo = NULL ;
	m_pBaseSkillInfo->SetFirst();
	while( pAbilityInfo = m_pBaseSkillInfo->GetNext() )
	{
		// Ability 积己
		Ability	*pNewAbility = AbilityFactory::Instance()->AllocAbility();
		pNewAbility->Init( this, pAbilityInfo );

		// List俊 眠啊
		m_listAbilitys.push_back( pNewAbility );
	}
}

VOID Skill::CommonRelease()
{
	// 敲饭捞绢啊 胶懦 备荤吝 阁胶磐狼 矫具俊辑 荤扼瘤绰 胶懦老 版快 Vision 加己阑 难霖促.
	if( GetAttribution() & SKILL_ATTRIBUTION_INVISIBLE )
	{
		m_pOwnerChar->GetStatusManager()->Remove( eCHAR_STATE_ETC_DISABLE_VISION );
	}

	// 且寸茄 Ability甫 馆券秦霖促.
	for( ABILITY_LIST_ITER it = m_listAbilitys.begin(); it != m_listAbilitys.end(); ++it )
	{
		Ability *pAbility = *it;
		AbilityFactory::Instance()->FreeAbility( pAbility );
	}
	m_listAbilitys.clear();
}

BYTE Skill::FindTargets( Character **pTargetArray )
{
	if( !m_pField ) 
	{
		SUNLOG( eCRITICAL_LOG, "[Skill::FindTargets] Field is NULL!" );
		return 0;
	}

	BYTE byNumberOfTargets = 0;

	// 窜老 鸥百俊霸 荤侩窍绰 胶懦牢 版快 鸥百阑 八祸窍瘤 臼绊 皋牢鸥百栏肺 悸泼茄促.
	if( m_pBaseSkillInfo->m_byAttRangeform == SRF_FOWARD_ONE )
	{
		Character *pMainTarget = m_pField->FindCharacter( m_SkillInfo.m_dwMainTargetKey );
		if( pMainTarget )
		{
			byNumberOfTargets = 1;
			pTargetArray[0] = pMainTarget;
		}
	}
	// 家券胶懦篮 鸥百阑 备窍瘤 臼绰促.
	else if( m_pBaseSkillInfo->m_byTarget == SKILL_TARGET_SUMMON )
	{
	}
	// 鸥百捞 绝捞 谅钎父 乐绰 胶懦牢 版快 鸥百阑 备窍瘤 臼绰促.
	else if( m_pBaseSkillInfo->m_byAttRangeform == SRF_AREA_POSITION )
	{
	}
	else
	{
		// 唱吝俊 绊妨秦杭 巴!!!
		eSKILL_TARGET_TYPE eTargetType = SKILL_TARGET_NONE;	// (eSKILL_TARGET_TYPE)m_pBaseSkillInfo->m_byTarget;
		/////////////////////////////////////////////////

		// 乔绢胶 局肺快 绢呼府萍狼 版快 鸥百荐 力茄捞 吧赴促.(包烹荐 力茄)
		int iCountLimit = MAX_TARGET_NUM;
		DWORD dwExceptTargetKey = 0;

		BASE_ABILITYINFO *pAbilityInfo = m_pBaseSkillInfo->GetAbilityInfo( eABILITY_PIERCE_ARROW );
		if( pAbilityInfo )
		{
			// MainTarget阑 霉锅掳 鸥百栏肺 伙绰促.
			Character *pMainTarget = m_pField->FindCharacter( m_SkillInfo.m_dwMainTargetKey );
			if( pMainTarget )
			{
				byNumberOfTargets = 1;
				pTargetArray[0] = pMainTarget;
				dwExceptTargetKey = m_SkillInfo.m_dwMainTargetKey;
				eTargetType = SKILL_TARGET_ENEMY;
			}
			iCountLimit = pAbilityInfo->m_iOption2 - 1;
		}

		// 鸥百府胶飘甫 备茄促.
		byNumberOfTargets += m_pField->FindTargetsByAttacker( eTargetType, m_pOwnerChar, &pTargetArray[byNumberOfTargets], 
			m_SkillInfo.m_wvMainTargetPos, 0, m_pBaseSkillInfo->m_byAttRangeform, 
			m_pBaseSkillInfo->m_wSkillArea/10.0f, iCountLimit, dwExceptTargetKey );
	}

	return byNumberOfTargets;
}

BOOL Skill::ExecuteAbilities( Character *pTarget, RESULTMSG &sResultMsg )
{ 
	if( !pTarget )	return FALSE;

	SKILL_RESULT_BASE *pResultMsg = (SKILL_RESULT_BASE*)sResultMsg.m_byMsg;
	sResultMsg.m_wSize = pResultMsg->GetSize();
	pResultMsg->m_dwTargetKey = pTarget->GetObjectKey();
	m_SkillInfo.m_bySkillEffect = 0;

	WORD wMsgSize = 0;	int iAbilityIndex = 0;
	BYTE *pMsg =(BYTE*)pResultMsg + sizeof(SKILL_RESULT_BASE) ;
	for( ABILITY_LIST_ITER it = m_listAbilitys.begin(); it != m_listAbilitys.end(); ++it, iAbilityIndex++ )
	{
		Ability *pAbility = *it;

		// Ability甫 惯悼矫懦 炼扒捞 己赋窍绰瘤 眉农
		if( !pAbility->CanExecute( m_pOwnerChar, pTarget, m_SkillInfo.m_dwMainTargetKey, m_SkillInfo.m_wvMainTargetPos ) )
			continue;

		// Ability 瓤苞啊 己傍窍搁 搬苞备炼眉甫 盲款促.
		pAbility->SetSkillAttackPower( m_iSkillAttackPower );
		pAbility->SetSkillPercentDamage( m_fSkillPercentDamage );
		if( pAbility->Execute( iAbilityIndex, pTarget, pMsg, wMsgSize ) )
		{
			pMsg += wMsgSize;
			sResultMsg.m_wSize += wMsgSize;

			++pResultMsg->m_byAbilityNum;

			m_iSkillAttackPower += pAbility->GetSkillAttackPower();
			m_fSkillPercentDamage += pAbility->GetSkillPercentDamage();

			// 夸芭 柳楼 窍靛内爹烙 ばぬ
			// 绢呼府萍俊 蝶扼辑 绢冻锭绰 茄鸥百俊霸父 胶懦傍拜仿 +啊 利侩登绊
			// 绢冻锭绰 葛电 鸥百俊 措秦辑 胶懦傍拜仿 +啊 利侩登绢具 窍绰单... 绢录搁 亮阑鳖??
			if( m_bTempApply )	m_bTempApply = pAbility->IsTempApply();	
		}
	}

	// 鸥百 茄疙茄抛父 利侩窍绰 芭扼搁 促澜鸥百傈俊 檬扁拳茄促.
	if( m_bTempApply )
	{
		m_iSkillAttackPower = 0;
		m_fSkillPercentDamage = 0;
	}
	pResultMsg->m_bySkillEffect = m_SkillInfo.m_bySkillEffect;

	return pResultMsg->m_byAbilityNum;
}

BYTE Skill::ExecuteEffectAbilities( RESULTMSG *pResultMsg )
{ 
	// 漂沥 鸥百捞 绝绰 绢呼府萍狼 版快 咯扁辑 贸府茄促.
	WORD wMsgSize = 0;	int iHitCount = 0;	int iAbilityIndex = 0;
	for( ABILITY_LIST_ITER it = m_listAbilitys.begin(); it != m_listAbilitys.end(); ++it, iAbilityIndex++ )
	{
		Ability *pAbility = *it;
		BYTE byRangeType = pAbility->GetBaseAbilityInfo()->m_byRangeType;

		// 家券, Effect 绢呼府萍牢瘤 眉农茄促.
		if( byRangeType == SKILL_ABILITY_FIELD )
		{
			// Ability 瓤苞啊 己傍窍搁 搬苞备炼眉甫 盲款促.
			if( pAbility->ExecuteEffect( iAbilityIndex, pResultMsg[iHitCount].m_byMsg, wMsgSize ) )
			{
				pResultMsg[iHitCount].m_wSize += wMsgSize;
				++iHitCount;
			}
		}
		else if( byRangeType == SKILL_ABILITY_SUMMON )
		{
			if( pAbility->ExecuteEffect( iAbilityIndex, pResultMsg[iHitCount].m_byMsg, wMsgSize ) )
			{
				++iHitCount;
			}
		}
	}

	return iHitCount;
}

VOID Skill::Broadcast_Instant_Result()
{
	if( !m_pField )		
	{
		SUNLOG( eCRITICAL_LOG, "[Skill::Broadcast_Instant_Result] Field is NULL!" );
		return;
	}

	// 咀记 沥焊
	MSG_CG_SKILL_ACTION_INSTANT_RESULT_BRD actionMsg;
	actionMsg.m_byCategory				= CG_SKILL;
	actionMsg.m_byProtocol				= CG_SKILL_ACTION_INSTANT_RESULT_BRD;
	actionMsg.m_SkillCode				= m_SkillInfo.m_SkillCode;
	actionMsg.m_dwClientSerial			= m_SkillInfo.m_dwClientSerial;
	actionMsg.m_dwAttackerKey			= m_pOwnerChar->GetObjectKey();
	actionMsg.m_dwPrimaryTargetKey		= m_SkillInfo.m_dwMainTargetKey;
	actionMsg.m_wvMainTargetPos			= m_SkillInfo.m_wvMainTargetPos;
	actionMsg.m_wvCurPos				= m_SkillInfo.m_wvCurPos;
	actionMsg.m_wvDestPos				= m_SkillInfo.m_wvDestPos;
	actionMsg.m_dwAttackerHP			= m_pOwnerChar->GetHP();
	actionMsg.m_dwAttackerMP			= m_pOwnerChar->GetMP();
	actionMsg.m_byNumberOfTargets		= m_byHitTargetCount;
	actionMsg.m_byNumberOfFieldEffect	= m_byEffectCount;

	// 沥焊甸阑 窍唱肺 钦媚辑 焊辰促.
	BYTE *pMsg[ 1 + MAX_TARGET_NUM + 5 ];
	WORD wSize[ 1 + MAX_TARGET_NUM + 5 ];

	pMsg[0] = (BYTE*)&actionMsg;
	wSize[0] = (WORD)actionMsg.GetSize();

	for( int i = 0; i < m_byHitTargetCount; i++ )
	{
		pMsg[1+i] = m_ResultMsg[i].m_byMsg;
		wSize[1+i] = m_ResultMsg[i].m_wSize;
	}

	for( i = 0; i < m_byEffectCount; i++ )
	{
		pMsg[1+m_byHitTargetCount+i] = m_ResultEffectMsg[i].m_byMsg;
		wSize[1+m_byHitTargetCount+i] = m_ResultEffectMsg[i].m_wSize;
	}

	m_pOwnerChar->SendExPacketAround( 1 + m_byHitTargetCount + m_byEffectCount, pMsg, wSize );
}

VOID Skill::Broadcast_Delayed_Result()
{
	if( !m_pField )		
	{
		SUNLOG( eCRITICAL_LOG, "[Skill::Broadcast_Delayed_Result] Field is NULL!" );
		return;
	}

	// 咀记 沥焊
	MSG_CG_SKILL_ACTION_DELAY_RESULT_BRD actionMsg;
	actionMsg.m_byCategory				= CG_SKILL;
	actionMsg.m_byProtocol				= CG_SKILL_ACTION_DELAY_RESULT_BRD;
	actionMsg.m_SkillCode				= m_SkillInfo.m_SkillCode;
	actionMsg.m_dwClientSerial			= m_SkillInfo.m_dwClientSerial;
	actionMsg.m_dwAttackerKey			= m_pOwnerChar->GetObjectKey();
	actionMsg.m_dwPrimaryTargetKey		= m_SkillInfo.m_dwMainTargetKey;
	actionMsg.m_wvMainTargetPos			= m_SkillInfo.m_wvMainTargetPos;
	actionMsg.m_dwAttackerHP			= m_pOwnerChar->GetHP();
	actionMsg.m_dwAttackerMP			= m_pOwnerChar->GetMP();
	actionMsg.m_byNumberOfTargets		= m_byHitTargetCount;
	actionMsg.m_byNumberOfFieldEffect	= m_byEffectCount;

	// 沥焊甸阑 窍唱肺 钦媚辑 焊辰促.
	BYTE *pMsg[ 1 + MAX_TARGET_NUM + 5 ];
	WORD wSize[ 1 + MAX_TARGET_NUM + 5 ];

	pMsg[0] = (BYTE*)&actionMsg;
	wSize[0] = (WORD)actionMsg.GetSize();

	for( int i = 0; i < m_byHitTargetCount; i++ )
	{
		pMsg[1+i] = m_ResultMsg[i].m_byMsg;
		wSize[1+i] = m_ResultMsg[i].m_wSize;
	}

	for( i = 0; i < m_byEffectCount; i++ )
	{
		pMsg[1+m_byHitTargetCount+i] = m_ResultEffectMsg[i].m_byMsg;
		wSize[1+m_byHitTargetCount+i] = m_ResultEffectMsg[i].m_wSize;
	}

	m_pOwnerChar->SendExPacketAround( 1 + m_byHitTargetCount + m_byEffectCount, pMsg, wSize );
}


VOID Skill::SendAIMessage( Character *pTarget, DAMAGETYPE wDamage )
{
	// 傍拜寸茄 NPC俊霸 AIMessage甫 朝赴促.
	AI_MSG_ATTACKED AIAttackedMsg;
	AIAttackedMsg.dwAttackerKey = m_pOwnerChar->GetObjectKey();
	AIAttackedMsg.wDamage = wDamage;
	pTarget->SendAIMessage( &AIAttackedMsg, sizeof(AIAttackedMsg) );

	// NPC啊 傍吝栏肺 哆绰 胶懦老 版快 Flying Message甫 朝赴促.
	if( GetAttribution() & SKILL_ATTRIBUTION_TARGETFLYING )
	{
		AI_MSG_FLYING flyMsg;
		flyMsg.dwFlyingTick = GetExecuteInterval();
		pTarget->SendAIMessage( &flyMsg, sizeof(flyMsg) );
	}

	// 鸥百阑 肛苗初绰 胶懦老 版快
	if( GetAttribution() & SKILL_ATTRIBUTION_TARGETSTOP )
	{
		AI_MSG_KNOCKDOWN downMsg;
		downMsg.dwKnockDownTick = GetExecuteInterval();
		pTarget->SendAIMessage( &downMsg, sizeof(downMsg) );
	}
}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -