📄 skillinfo.cpp
字号:
// SkillInfo.cpp: implementation of the CSkillInfo class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SkillInfo.h"
#include "SkillObjectFactory.h"
#ifdef _MAPSERVER_
#include "SkillObject_server.h"
#include "CharMove.h"
#else
#include "SkillObject_Client.h"
#include "ActionTarget.h"
#include "GameIn.h"
#include "Hero.h"
#include "MoveManager.h"
#include "ObjectStateManager.h"
#include "ChatManager.h"
#include "BattleSystem_client.h"
#include "ObjectManager.h"
#include "SkillManager_client.h"
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSkillInfo::CSkillInfo()
{
}
CSkillInfo::~CSkillInfo()
{
PTRLISTSEARCHSTART(m_SkillObjectPool,CSkillObject*,pSObj)
delete pSObj;
PTRLISTSEARCHEND;
m_SkillObjectPool.RemoveAll();
}
BOOL CSkillInfo::InitSkillInfo(CMHFile* pFile)
{
ASSERT(pFile->IsInited());
ASSERT(pFile->IsEOF() == FALSE);
memset(&m_SkillInfo,0,sizeof(m_SkillInfo));
m_SkillInfo.SkillIdx = pFile->GetWord();
pFile->GetString(m_SkillInfo.SkillName);
m_SkillInfo.SkillTooltipIdx = pFile->GetWord();
m_SkillInfo.RestrictLevel = pFile->GetWord();
m_SkillInfo.LowImage = pFile->GetInt();
m_SkillInfo.HighImage = pFile->GetInt();
m_SkillInfo.SkillKind = pFile->GetWord();
m_SkillInfo.WeaponKind = pFile->GetWord();
m_SkillInfo.SkillRange = pFile->GetWord();
m_SkillInfo.TargetKind = pFile->GetWord();
m_SkillInfo.TargetRange = pFile->GetWord();
m_SkillInfo.TargetAreaIdx = pFile->GetWord();
m_SkillInfo.TargetAreaPivot = pFile->GetWord();
m_SkillInfo.TargetAreaFix = pFile->GetWord();
m_SkillInfo.MoveTargetArea = pFile->GetWord();
m_SkillInfo.MoveTargetAreaDirection = pFile->GetWord();
m_SkillInfo.MoveTargetAreaVelocity = pFile->GetFloat();
m_SkillInfo.Duration = pFile->GetDword();
m_SkillInfo.Interval = pFile->GetWord();
m_SkillInfo.DelaySingleEffect = pFile->GetWord();
m_SkillInfo.ComboNum = pFile->GetWord();
m_SkillInfo.Life = pFile->GetWord();
m_SkillInfo.BindOperator = pFile->GetWord();
m_SkillInfo.EffectStartTime = pFile->GetWord();
m_SkillInfo.EffectStart = FindEffectNum(pFile->GetString());
m_SkillInfo.EffectUse = FindEffectNum(pFile->GetString());
m_SkillInfo.EffectSelf = FindEffectNum(pFile->GetString());
m_SkillInfo.EffectMapObjectCreate = FindEffectNum(pFile->GetString());
m_SkillInfo.EffectMineOperate = FindEffectNum(pFile->GetString());
m_SkillInfo.DelayTime = pFile->GetWord();
m_SkillInfo.FatalDamage = pFile->GetWord();
for(int n=0;n<12;++n)
m_SkillInfo.NeedExp[n] = pFile->GetExpPoint();
pFile->GetWord(m_SkillInfo.NeedNaeRyuk,12);
m_SkillInfo.Attrib = pFile->GetWord();
m_SkillInfo.NegativeResultTargetType = pFile->GetWord();
m_SkillInfo.TieUpType = pFile->GetWord();
m_SkillInfo.ChangeSpeedType = pFile->GetWord();
m_SkillInfo.ChangeSpeedRate = pFile->GetWord();
m_SkillInfo.Dispel = pFile->GetWord();
m_SkillInfo.PositiveResultTargetType = pFile->GetWord();
m_SkillInfo.Immune = pFile->GetWord();
m_SkillInfo.AIObject = pFile->GetWord();
m_SkillInfo.MineCheckRange = pFile->GetWord();
m_SkillInfo.MineCheckStartTime = pFile->GetWord();
m_SkillInfo.CounterDodgeKind = pFile->GetWord();
m_SkillInfo.CounterEffect = FindEffectNum(pFile->GetString());
WORD AdditiveAttr;
WORD temp[12];
// if(m_SkillInfo.SkillIdx == 903)
// {
// int a=0;
// }
for(n=0;n<6;++n)
{
AdditiveAttr = pFile->GetWord();
ySWITCH(AdditiveAttr)
yCASE(0) pFile->GetWord(temp,12);
yCASE(11) pFile->GetFloat(m_SkillInfo.FirstPhyAttack,12);
yCASE(12) pFile->GetFloat(m_SkillInfo.UpPhyAttack,12);
yCASE(13) pFile->GetWord(m_SkillInfo.FirstAttAttackMin,12);
yCASE(14) pFile->GetWord(m_SkillInfo.FirstAttAttackMax,12);
yCASE(15) pFile->GetWord(m_SkillInfo.ContinueAttAttack,12);
yCASE(20) pFile->GetFloat(m_SkillInfo.CounterPhyAttack,12);
yCASE(21) pFile->GetFloat(m_SkillInfo.CounterAttAttack,12);
yCASE(22) pFile->GetFloat(m_SkillInfo.UpPhyDefence,12);
yCASE(23) pFile->GetFloat(m_SkillInfo.UpAttDefence,12);
yCASE(24) pFile->GetWord(m_SkillInfo.UpMaxNaeRyuk,12);
yCASE(25) pFile->GetWord(m_SkillInfo.UpMaxLife,12);
yCASE(26) pFile->GetWord(m_SkillInfo.ContinueRecoverNaeRyuk,12);
yCASE(27) pFile->GetWord(m_SkillInfo.FirstRecoverNaeRyuk,12);
yCASE(28) pFile->GetWord(m_SkillInfo.ContinueRecoverLife,12);
yCASE(29) pFile->GetWord(m_SkillInfo.FirstRecoverLife,12);
yCASE(30) pFile->GetFloat(m_SkillInfo.CounterDodgeRate,12);
yCASE(31) pFile->GetFloat(m_SkillInfo.CriticalRate,12);
yCASE(32) pFile->GetFloat(m_SkillInfo.StunRate,12);
yCASE(33) pFile->GetWord(m_SkillInfo.StunTime,12);
yCASE(34) pFile->GetWord(m_SkillInfo.UpMaxShield,12);
yCASE(35) pFile->GetWord(m_SkillInfo.AmplifiedPowerPhy,12);
yCASE(36) pFile->GetFloat(m_SkillInfo.VampiricLife,12);
yCASE(37) pFile->GetFloat(m_SkillInfo.VampiricNaeryuk,12);
yCASE(38) pFile->GetFloat(m_SkillInfo.RecoverStateAbnormal,12);
yCASE(39) pFile->GetFloat(m_SkillInfo.DispelAttackFeelRate,12);
yCASE(41) pFile->GetWord(m_SkillInfo.DownMaxLife,12);
yCASE(42) pFile->GetWord(m_SkillInfo.DownMaxNaeRyuk,12);
yCASE(43) pFile->GetWord(m_SkillInfo.DownMaxShield,12);
yCASE(44) pFile->GetFloat(m_SkillInfo.DownPhyDefence,12);
yCASE(45) pFile->GetFloat(m_SkillInfo.DownAttDefence,12);
yCASE(46) pFile->GetFloat(m_SkillInfo.DownPhyAttack,12);
yCASE(47) pFile->GetDword(m_SkillInfo.SkillAdditionalTime,12);
yCASE(48) pFile->GetWord(m_SkillInfo.AmplifiedPowerAtt,12);
yCASE(49) pFile->GetFloat(m_SkillInfo.AmplifiedPowerAttRate,12);
yCASE(50) pFile->GetFloat(m_SkillInfo.FirstAttAttack,12);
yCASE(51) pFile->GetFloat(m_SkillInfo.ContinueAttAttackRate,12);
yENDSWITCH
}
return TRUE;
}
#define SKILLDUMMYCHECK 0x74
BOOL CSkillInfo::InitDummySkillInfo(CSkillInfo* pOriginalSkillInfo)
{
memcpy(&m_SkillInfo,&pOriginalSkillInfo->m_SkillInfo,sizeof(SKILLINFO));
char* p = (char*)&m_SkillInfo;
for(int n=0;n<sizeof(SKILLINFO);++n)
{
p[n] ^= SKILLDUMMYCHECK;
}
return TRUE;
}
BOOL CSkillInfo::CheckOriginal(CSkillInfo* pSkillInfo)
{
char* pOriginal = (char*)&pSkillInfo->m_SkillInfo;
char* pDummy = (char*)&m_SkillInfo;
for(int n=0;n<sizeof(SKILLINFO);++n)
{
if(pOriginal[n] != ( pDummy[n] ^ SKILLDUMMYCHECK ))
return FALSE;
}
return TRUE;
}
#ifdef _MAPSERVER_
#include "Battle.h"
#include "Player.h"
BOOL CSkillInfo::IsExcutableSkillState(CObject* pObject,int SkillLevel)
{
if(pObject->GetLevel() < m_SkillInfo.RestrictLevel)
{
// 饭骇捞 何练窍咯 公傍阑 矫傈窍角 荐 绝嚼聪促.
return FALSE;
}
if(pObject->IsInSpecialState(eSpecialState_Stun) == TRUE)
return FALSE;
if(pObject->GetState() != eObjectState_None &&
pObject->GetState() != eObjectState_Move &&
pObject->GetState() != eObjectState_TiedUp_CanSkill )
return FALSE;
if(pObject->GetObjectKind() == eObjectKind_Player)
{
if( ((CPlayer*)pObject)->GetDelayGroup()->CheckDelay(CDelayGroup::eDK_Skill,GetSkillIndex()) != 0)
return FALSE;
}
WORD NeedNaeRyuk = GetNeedNaeRyuk(SkillLevel);
if(NeedNaeRyuk)
{
if(pObject->GetNaeRyuk() < NeedNaeRyuk)
{
return FALSE;
}
pObject->ReduceNaeRyuk(NeedNaeRyuk);
if( pObject->GetObjectKind() == eObjectKind_Player &&
g_pServerSystem->GetMap()->IsVillage() == FALSE &&
pObject->GetBattle()->GetBattleKind() != eBATTLE_KIND_VIMUSTREET)
((CPlayer*)pObject)->AddExpPointToMugong(GetSkillIndex(),NeedNaeRyuk);
}
/*
if( pObject->GetLevel() < m_SkillInfo.RestrictLevel &&
m_SkillInfo.ComboNum != SKILL_COMBO_NUM ) // 老窜公傍篮 饭骇力茄 猾促.
return FALSE;
*/
return TRUE;
}
BOOL CSkillInfo::IsInSkillRange(CObject* pObject,VECTOR3* pTargetPos,float TargetRadius)
{
VECTOR3* p1 = CCharMove::GetPosition(pObject);
VECTOR3* p2 = pTargetPos;
p1->y = p2->y = 0;
// 傍拜磊客 嘎绰 逞狼 鸥百芭府甫 猾促.
float dist = CalcDistanceXZ(p1,p2) - TargetRadius;
float addRange = 0;
if(m_SkillInfo.ComboNum != SKILL_COMBO_NUM &&
(m_SkillInfo.WeaponKind == WP_AMGI || m_SkillInfo.WeaponKind == WP_GUNG)) // 霓焊啊 酒聪搁 胶湃俊 蝶扼辑 荤沥芭府 疵绢巢
addRange = pObject->GetAddAttackRange();
// 傍拜磊啊 敲饭捞绢 捞搁 荤沥芭府甫 100疵妨霖促. (坷瞒 绊妨)
if(pObject->GetObjectKind() == eObjectKind_Player)
dist -= 100;
if(m_SkillInfo.SkillRange+addRange < dist) // 辑滚绰
return FALSE;
return TRUE;
}
BOOL CSkillInfo::ComboTest(CObject* pObject)
{
return TRUE;
}
BOOL CSkillInfo::CheckEvade(MAINTARGET* pMainTarget)
{
return FALSE;
}
#else
BOOL CSkillInfo::IsExcutableSkillState(CHero* pHero,int SkillLevel)
{
if(pHero->GetLevel() < m_SkillInfo.RestrictLevel)
{
// 饭骇捞 何练窍咯 公傍阑 矫傈窍角 荐 绝嚼聪促.
return FALSE;
}
/*
if(pHero->IsSkillCooling() == TRUE)
{
// 酿鸥烙捞 场唱具 公傍阑 促矫 矫傈窍角荐 乐嚼聪促.
return FALSE;
}
*/
if(pHero->GetDelayGroup()->CheckDelay(CDelayGroup::eDK_Skill,GetSkillIndex()) != 0)
return FALSE;
if( m_SkillInfo.WeaponKind != 0 )
{
if( pHero->GetWeaponEquipType() != m_SkillInfo.WeaponKind )
{
CHATMGR->AddMsg( CTC_SYSMSG, CHATMGR->GetChatMsg(151) );
return FALSE;
}
}
#ifndef _TESTCLIENT_
if( pHero->GetNaeRyuk() < GetNeedNaeRyuk(SkillLevel) ) // 郴仿八荤
{
CHATMGR->AddMsg( CTC_SYSMSG, CHATMGR->GetChatMsg(401) );
return FALSE;
}
#endif
if( pHero->IsInSpecialState(eSpecialState_Stun) == TRUE)
return FALSE;
if( pHero->GetState() != eObjectState_None &&
pHero->GetState() != eObjectState_Move &&
pHero->GetState() != eObjectState_TiedUp_CanSkill ) {
if( pHero->GetState() != eObjectState_SkillSyn &&
pHero->GetState() != eObjectState_SkillUsing &&
pHero->GetState() != eObjectState_SkillBinding &&
pHero->GetState() != eObjectState_SkillStart &&
pHero->GetState() != eObjectState_SkillDelay )
{
// CHATMGR->AddMsg( CTC_SYSMSG, CHATMGR->GetChatMsg(141) );
pHero->DisableAutoAttack();
}
return FALSE;
}
// 饭骇 力茄
if( pHero->GetLevel() < m_SkillInfo.RestrictLevel &&
m_SkillInfo.ComboNum != SKILL_COMBO_NUM) // 老窜 公傍篮 饭骇 力茄 绝澜
return FALSE;
//if PeaceMode == TRUE then Can't Attack
//KES 阜澜.. 乞拳葛靛矫浚 磊悼栏肺 傈捧葛靛肺 官操绢辑 傍拜!
// if(pHero->GetCharacterTotalInfo()->bPeace == TRUE)
// {
//// CHATMGR->AddMsg( CTC_SYSMSG, CHATMGR->GetChatMsg(142) );
// return FALSE;
// }
return TRUE;
}
BOOL CSkillInfo::IsInSkillRange(CHero* pHero,CActionTarget* pTarget)
{
VECTOR3 p1;
pHero->GetPosition(&p1);
VECTOR3* p2 = pTarget->GetTargetPosition();
VECTOR3 hpos;
pHero->GetPosition(&hpos);
if(p2 == NULL)
return FALSE;
p1.y = p2->y = 0;
// 傍拜磊客 嘎绰 逞狼 鸥百芭府甫 猾促.
float dist = CalcDistanceXZ(&p1,p2) - pTarget->GetRadius();
float addRange = 0;
if( m_SkillInfo.ComboNum != SKILL_COMBO_NUM &&
(m_SkillInfo.WeaponKind == WP_AMGI || m_SkillInfo.WeaponKind == WP_GUNG)) // 霓焊啊 酒聪搁 胶湃俊 蝶扼辑 荤沥芭府 疵绢巢
addRange = pHero->GetAddAttackRange();
if(m_SkillInfo.SkillRange+addRange < dist)
return FALSE;
return TRUE;
}
BOOL CSkillInfo::ComboTest(CHero* pHero)
{
#ifdef _TESTCLIENT_
return TRUE;
#endif
DWORD curcombo = pHero->GetCurComboNum();
if( m_SkillInfo.ComboNum == SKILL_COMBO_NUM &&
curcombo != SKILL_COMBO_NUM )
return TRUE;
if( m_SkillInfo.ComboNum == curcombo +1 )
return TRUE;
return FALSE;
}
void CSkillInfo::SendMsgToServer(CHero* pOperator,CActionTarget* pTarget)
{
MSG_SKILL_START_SYN msg;
MAINTARGET MainTarget;
pTarget->GetMainTarget(&MainTarget);
msg.InitMsg(GetSkillIndex(),&MainTarget,pOperator->GetAngleDeg(),pOperator->GetID());
pTarget->GetTargetArray(&msg.TargetList);
NETWORK->Send(&msg,msg.GetMsgLength());
}
BOOL CSkillInfo::IsValidTarget(CHero* pHero,CActionTarget* pTarget)
{
CBattle* pBattle = BATTLESYSTEM->GetBattle(pHero);
CObject* pTargetObj = NULL;
if(pTarget->GetTargetID() != 0)
pTargetObj = OBJECTMGR->GetObject(pTarget->GetTargetID());
if(pTargetObj == NULL)
return TRUE;
if( pTargetObj->GetObjectKind() == eObjectKind_Npc )
return FALSE;
if( m_SkillInfo.FirstPhyAttack[11] != 0 ||
m_SkillInfo.FirstAttAttackMin[11] != 0 ||
m_SkillInfo.FirstAttAttackMax[11] != 0 ) // 霉傍拜捞 乐栏搁
{
if( pBattle->IsEnemy(pHero,pTargetObj) == FALSE )
return FALSE;
}
return TRUE;
}
BOOL CSkillInfo::ConvertTargetToSkill(CHero* pHero,CActionTarget* pTarget)
{
if(GetSkillInfo()->TargetKind == 1) // 磊脚
{
pTarget->SetOneTarget(pHero);
return TRUE;
}
else if(GetSkillInfo()->TargetKind == 0) // 惑措
{
pTarget->SetOneTarget(NULL);
return TRUE;
}
else
{
return TRUE;
}
}
#endif
CSkillObject* CSkillInfo::GetSkillObject()
{
CSkillObject* pSObj;
if(m_SkillObjectPool.GetCount() == 0)
pSObj = CSkillObjectFactory::MakeNewSkillObject(this);
else
pSObj = (CSkillObject*)m_SkillObjectPool.RemoveTail();
return pSObj;
}
void CSkillInfo::ReleaseSkillObject(CSkillObject* pSObj,int kind)
{
PTRLISTSEARCHSTART(m_SkillObjectPool,CSkillObject*,pPreObj)
if(pSObj == pPreObj)
{
return;
}
PTRLISTSEARCHEND
#ifdef _MAPSERVER_
pSObj->releaseKind = kind;
#endif
m_SkillObjectPool.AddHead(pSObj);
}
VECTOR3* CSkillInfo::GetTargetAreaPivotPos(VECTOR3* pOperatorPos,VECTOR3* pTargetPos)
{
if(IsTargetAreaFitToHero())
return pOperatorPos;
else
return pTargetPos;
}
BOOL CSkillInfo::IsMultipleTargetSkill()
{
if( m_SkillInfo.TargetRange != 0 ||
m_SkillInfo.TargetAreaIdx != 0)
return TRUE;
else
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -