Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
587 lines
21 KiB
C++
587 lines
21 KiB
C++
// SkillSystem.cpp: implementation of the CSkillSystem class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//#include <crtdbg.h>
|
|
#include "ClientMain.h"
|
|
#include "CharacterControl.h"
|
|
#include "GUITextEdit.h"
|
|
#include "SkillSystem.h"
|
|
#include "WinInput.h"
|
|
|
|
#include "Skill\SkillMgr.h"
|
|
|
|
CSkillSystem g_SkillSystem;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CSkillSystem::CSkillSystem()
|
|
{
|
|
|
|
}
|
|
|
|
CSkillSystem::~CSkillSystem()
|
|
{
|
|
|
|
}
|
|
|
|
void CSkillSystem::AddSkill(CSkillNode *lpSkillNode)
|
|
{
|
|
m_lstSkillNode.push_back(lpSkillNode);
|
|
}
|
|
|
|
void CSkillSystem::Update()
|
|
{
|
|
int snum = CSceneManager::m_EffectManager.GetScriptNum();
|
|
int bActive;
|
|
vector<CSkillNode *>::iterator it;
|
|
CSkillNode *lpSkillNode;
|
|
|
|
for(int scnt = 0; scnt < snum; scnt++)
|
|
{
|
|
bActive = CSceneManager::m_EffectManager.ProcessScript(scnt);
|
|
|
|
if(bActive == 2)// S - M - E 구조의 Script 일때 target의 몸에 충돌하는 순간
|
|
{
|
|
/* char *esf_name = NULL;
|
|
esf_name = CSceneManager::m_EffectManager.GetEsfName(scnt);
|
|
if(esf_name != NULL) { //화살 꽃히는 효과를 위한 것
|
|
if(strstr(esf_name,"arrow_normal")!= NULL) {
|
|
for(int cChr = 0; cChr < g_CharacterData.m_lstCharData.num; cChr++) {
|
|
if(!g_CharacterData.m_lstCharData[cChr]->m_lpChrModel) continue;
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_bCharDead) continue;
|
|
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_dwChrID == lpSkillNode->m_dwTargetChrID)
|
|
{
|
|
g_CharacterData.m_lstCharData[cChr]->AddArrow("CHEST",CSceneManager::m_EffectManager.m_lstScript[scnt]->GetExt4Quat());
|
|
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
for(it = m_lstSkillNode.begin(); it != m_lstSkillNode.end();)
|
|
{
|
|
if(CSceneManager::m_EffectManager.CheckScript(scnt, (*it)->m_lpEffectIndex))
|
|
{
|
|
|
|
//대거 파이어 관련 박히는 effect setting(추후 삭제한뒤 effect script 안에 들어가야 할 것임)
|
|
char *esf_name = NULL;
|
|
esf_name = CSceneManager::m_EffectManager.GetEsfName(scnt);
|
|
if(esf_name != NULL) { //화살 꽃히는 효과를 위한 것
|
|
|
|
int arrow_value = -1;
|
|
|
|
if(strstr(esf_name,"A_Dfire1.esf")!= NULL) {
|
|
arrow_value = 1;
|
|
}
|
|
else if(strstr(esf_name,"A_Dfire2.esf")!= NULL) {
|
|
arrow_value = 2;
|
|
}
|
|
else if(strstr(esf_name,"A_Dfire3.esf")!= NULL) {
|
|
arrow_value = 3;
|
|
}
|
|
else if(strstr(esf_name,"A_Dfire4.esf")!= NULL) {
|
|
arrow_value = 4;
|
|
}
|
|
else if(strstr(esf_name,"A_Dfire5.esf")!= NULL) {
|
|
arrow_value = 5;
|
|
}
|
|
|
|
if(arrow_value >0) {
|
|
for(int cChr = 0; cChr < g_CharacterData.m_lstCharData.num; cChr++) {
|
|
if(!g_CharacterData.m_lstCharData[cChr]->m_lpChrModel) continue;
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_bCharDead) continue;
|
|
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_dwChrID == (*it)->m_dwTargetChrID)
|
|
{
|
|
g_CharacterData.m_lstCharData[cChr]->AddArrow("CHEST",CSceneManager::m_EffectManager.m_lstScript[scnt]->GetExt4Quat(),arrow_value);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
////////////////
|
|
lpSkillNode = (*it);
|
|
|
|
if(lpSkillNode->m_wNumAttackCount == 0)
|
|
{
|
|
if(lpSkillNode->m_wSkill == AtType::Bow || lpSkillNode->m_wSkill == AtType::CrossBow) { //활
|
|
for(int cChr = 0; cChr < g_CharacterData.m_lstCharData.num; cChr++) {
|
|
if(!g_CharacterData.m_lstCharData[cChr]->m_lpChrModel) continue;
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_bCharDead) continue;
|
|
|
|
if(g_CharacterData.m_lstCharData[cChr]->m_dwChrID == lpSkillNode->m_dwTargetChrID)
|
|
{
|
|
g_CharacterData.m_lstCharData[cChr]->AddArrow("CHEST",CSceneManager::m_EffectManager.m_lstScript[scnt]->GetExt4Quat());
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL bGod = TRUE;
|
|
BOOL bCanDead = FALSE;
|
|
if(lpSkillNode->m_wSkill & 0x8000)
|
|
{
|
|
const Skill::ProtoType *lpSkillProtoType = g_SkillMgr.GetSkillProtoType(lpSkillNode->m_wSkill);
|
|
|
|
if(lpSkillProtoType)
|
|
{
|
|
if(lpSkillProtoType->m_eTargetType == Skill::Target::FRIEND ||
|
|
lpSkillProtoType->m_eTargetType == Skill::Target::FRIEND_EXCEPT_SELF)
|
|
{
|
|
bGod = FALSE;
|
|
}
|
|
|
|
if(lpSkillProtoType->m_eTargetType == Skill::Target::DEAD_ENEMY ||
|
|
lpSkillProtoType->m_eTargetType == Skill::Target::DEAD_FRIEND)
|
|
{
|
|
bCanDead = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(lpSkillNode->m_wSkill == 0x9502 || lpSkillNode->m_wSkill == 0x9506)
|
|
{ // 탄환소비
|
|
unsigned short wAmmo = 4003;
|
|
CItemInstance *lpItem = g_ClientMain.m_csStatus.GetInventoryItemfromID(wAmmo);
|
|
|
|
if(lpItem)
|
|
{
|
|
g_ClientMain.m_Network.m_pSocket->CharUseItem(g_ClientMain.m_dwMyChrID, g_ClientMain.m_dwMyChrID, &lpItem->m_lpItemBase->GetPos());
|
|
// 패킷을 보낸다.
|
|
g_CharacterData.MakeSkillAttackInfo(lpSkillNode->m_dwTargetChrID, lpSkillNode->m_wSkill, lpSkillNode->m_wSkillGrade, lpSkillNode->m_cLevel, lpSkillNode->m_wNumAttack, bGod, bCanDead);
|
|
}
|
|
} else
|
|
{
|
|
// 패킷을 보낸다.
|
|
g_CharacterData.MakeSkillAttackInfo(lpSkillNode->m_dwTargetChrID, lpSkillNode->m_wSkill, lpSkillNode->m_wSkillGrade, lpSkillNode->m_cLevel, lpSkillNode->m_wNumAttack, bGod, bCanDead);
|
|
if(lpSkillNode->m_wSkill == AtType::Bow || lpSkillNode->m_wSkill == AtType::CrossBow)
|
|
{
|
|
g_ClientMain.m_Network.m_nsNetworkStateforCastObject = NS_NOWAITING;
|
|
}
|
|
}
|
|
}
|
|
lpSkillNode->m_wNumAttackCount++;
|
|
|
|
if(lpSkillNode->m_wNumAttack <= lpSkillNode->m_wNumAttackCount)
|
|
{
|
|
it = m_lstSkillNode.erase(it);
|
|
delete lpSkillNode;
|
|
} else
|
|
{
|
|
it++;
|
|
}
|
|
|
|
break;
|
|
} else
|
|
{
|
|
it++;
|
|
}
|
|
}
|
|
} else if(bActive == 0)
|
|
{
|
|
for(it = m_lstSkillNode.begin(); it != m_lstSkillNode.end();)
|
|
{
|
|
if(CSceneManager::m_EffectManager.CheckNullScript((*it)->m_lpEffectIndex))
|
|
{
|
|
lpSkillNode = (*it);
|
|
it = m_lstSkillNode.erase(it);
|
|
delete lpSkillNode;
|
|
} else
|
|
{
|
|
it++;
|
|
}
|
|
}
|
|
|
|
vector<LPEffectNode>::iterator itEffect;
|
|
LPEffectNode lpEffect;
|
|
for(itEffect = m_lstEffect.begin(); itEffect != m_lstEffect.end();)
|
|
{
|
|
if(CSceneManager::m_EffectManager.CheckNullScript((*itEffect)->m_lpEffect))
|
|
{
|
|
lpEffect = (*itEffect);
|
|
itEffect = m_lstEffect.erase(itEffect);
|
|
delete lpEffect;
|
|
} else
|
|
{
|
|
itEffect++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(g_CharacterData.m_nFocusCharacter == -1) return;
|
|
|
|
int nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_SHOT);
|
|
if(nResult)
|
|
{
|
|
if(g_ClientMain.m_lpInterface->m_dwRangedWeaponTargetChrID != 0xFFFFFFFF)
|
|
{
|
|
BOOL bAttackable = FALSE;
|
|
if(g_ClientMain.m_csStatus.m_lstEquipment[Item::EquipmentPos::WEAPON_HAND1 + g_ClientMain.m_csStatus.m_cWeaponPos])
|
|
{
|
|
unsigned long dwType = g_ClientMain.m_csStatus.m_lstEquipment[Item::EquipmentPos::WEAPON_HAND1 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType();
|
|
if(g_ClientMain.m_csStatus.m_lstEquipment[Item::EquipmentPos::SHIELD_HAND1 + g_ClientMain.m_csStatus.m_cWeaponPos])
|
|
{
|
|
unsigned long dwArrowType = g_ClientMain.m_csStatus.m_lstEquipment[Item::EquipmentPos::SHIELD_HAND1 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType();
|
|
|
|
switch(dwType)
|
|
{
|
|
case Item::CItemType::BOW:
|
|
if(dwArrowType == Item::CItemType::ARROW)
|
|
{
|
|
lpSkillNode = new CSkillNode;
|
|
lpSkillNode->Create(g_ClientMain.m_lpInterface->m_dwRangedWeaponTargetChrID, 0, AtType::Bow, 0, 0);
|
|
}
|
|
break;
|
|
|
|
case Item::CItemType::CROSSBOW:
|
|
if(dwArrowType == Item::CItemType::BOLT)
|
|
{
|
|
lpSkillNode = new CSkillNode;
|
|
lpSkillNode->Create(g_ClientMain.m_lpInterface->m_dwRangedWeaponTargetChrID, 0, AtType::CrossBow, 0, 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_JUSTSTART);
|
|
if(nResult && g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo)
|
|
{
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_2.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
|
|
nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_JUST);
|
|
if(g_DeviceInput.GetIsRightMouseDown())
|
|
{
|
|
if(nResult && g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo)
|
|
{
|
|
const Skill::ProtoType *lpSkill = g_SkillMgr.GetSkillProtoType(g_ClientMain.m_csStatus.m_lpQuickSelected->GetProtoTypeID());
|
|
if(lpSkill)
|
|
{
|
|
if(lpSkill->m_bGauge)
|
|
{
|
|
lpSkill = &lpSkill[g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount];
|
|
|
|
unsigned long dwMotion;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->SetMotionString(&dwMotion, (char *)lpSkill->m_szCastingFileName);
|
|
|
|
if(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwUpperChrAction + 1 == dwMotion)
|
|
// if(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwUpperChrAction - (g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount - 1) == dwMotion)
|
|
{
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_3.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
|
|
// 쓴 스킬과 지금 선택된게 같은 스킬일때 클리어
|
|
g_CharacterData.m_bComboSuccess = TRUE;
|
|
} else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount = 0;
|
|
|
|
if(g_CharacterData.m_lpButtonNormal)
|
|
{
|
|
CSceneManager::m_EffectManager.DeleteInterfaceScript(g_CharacterData.m_lpButtonNormal);
|
|
g_CharacterData.m_lpButtonNormal = NULL;
|
|
g_CharacterData.m_bComboSuccess = FALSE;
|
|
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_4.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount = 0;
|
|
|
|
if(g_CharacterData.m_lpButtonNormal)
|
|
{
|
|
CSceneManager::m_EffectManager.DeleteInterfaceScript(g_CharacterData.m_lpButtonNormal);
|
|
g_CharacterData.m_lpButtonNormal = NULL;
|
|
g_CharacterData.m_bComboSuccess = FALSE;
|
|
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_4.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount = 0;
|
|
|
|
if(g_CharacterData.m_lpButtonNormal)
|
|
{
|
|
CSceneManager::m_EffectManager.DeleteInterfaceScript(g_CharacterData.m_lpButtonNormal);
|
|
g_CharacterData.m_lpButtonNormal = NULL;
|
|
g_CharacterData.m_bComboSuccess = FALSE;
|
|
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_4.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount = 0;
|
|
|
|
if(g_CharacterData.m_lpButtonNormal)
|
|
{
|
|
CSceneManager::m_EffectManager.DeleteInterfaceScript(g_CharacterData.m_lpButtonNormal);
|
|
g_CharacterData.m_lpButtonNormal = NULL;
|
|
g_CharacterData.m_bComboSuccess = FALSE;
|
|
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_4.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
}
|
|
}
|
|
|
|
nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_JUSTEND);
|
|
if(nResult)
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwSkillComboCount = 0;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bSkillCombo = FALSE;
|
|
|
|
if(g_CharacterData.m_lpButtonNormal)
|
|
{
|
|
CSceneManager::m_EffectManager.DeleteInterfaceScript(g_CharacterData.m_lpButtonNormal);
|
|
g_CharacterData.m_lpButtonNormal = NULL;
|
|
g_CharacterData.m_bComboSuccess = FALSE;
|
|
|
|
CEffScript *test_script;
|
|
// _ASSERTE(_CrtCheckMemory());
|
|
test_script = new CEffScript;
|
|
test_script->SetInterfaceSet(true);
|
|
test_script->GetScriptBinData("inter_fasthit_button_4.esf");
|
|
CSceneManager::m_EffectManager.AddInterfaceScript(test_script);
|
|
}
|
|
}
|
|
|
|
static bool bAttack;
|
|
nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_HIT);
|
|
if(nResult)
|
|
{
|
|
bAttack = FALSE;
|
|
lpSkillNode = GetNormalSkillNode();
|
|
if(!lpSkillNode)
|
|
{
|
|
// 일반 공격
|
|
lpSkillNode = new CSkillNode;
|
|
lpSkillNode->Create(0, 0, 0, 0, 0);
|
|
}
|
|
|
|
if(!lpSkillNode->m_bFirstAttack)
|
|
{
|
|
// 처음 공격 일때 패킷을 보낸다.
|
|
float fAttackRotation[6];
|
|
fAttackRotation[0]=-55.0f;
|
|
fAttackRotation[1]=30.0f;
|
|
fAttackRotation[2]=-10.0f;
|
|
fAttackRotation[3]=-10.0f;
|
|
fAttackRotation[4]=-10.0f;
|
|
fAttackRotation[5]=-10.0f;
|
|
|
|
float fAttackRate[6];
|
|
fAttackRate[0]=0.0f;
|
|
fAttackRate[1]=0.0f;
|
|
fAttackRate[2]=0.0f;
|
|
fAttackRate[3]=20.0f;
|
|
fAttackRate[4]=20.0f;
|
|
fAttackRate[5]=20.0f;
|
|
|
|
BOOL bGod = TRUE;
|
|
if(lpSkillNode->m_wSkill & 0x8000)
|
|
{
|
|
const Skill::ProtoType *lpSkillProtoType = g_SkillMgr.GetSkillProtoType(lpSkillNode->m_wSkill);
|
|
|
|
if(lpSkillProtoType)
|
|
{
|
|
if(lpSkillProtoType->m_eTargetType == Skill::Target::FRIEND ||
|
|
lpSkillProtoType->m_eTargetType == Skill::Target::FRIEND_EXCEPT_SELF)
|
|
{
|
|
bGod = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
bAttack = g_CharacterData.MakeAttackInfo(lpSkillNode->m_wSkill, lpSkillNode->m_wSkillGrade, lpSkillNode->m_cLevel,
|
|
lpSkillNode->m_wNumAttack, fAttackRotation[g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo],
|
|
fAttackRate[g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo], lpSkillNode->m_bAngle, bGod);
|
|
}
|
|
else
|
|
{
|
|
g_CharacterData.MakeVisualAttackInfo();
|
|
}
|
|
lpSkillNode->m_wNumAttackCount += nResult;
|
|
|
|
if(bAttack) lpSkillNode->m_bFirstAttack = TRUE;
|
|
|
|
/* if(g_ClientMain.GetChangeWeapon())
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
g_ClientMain.m_bChangeWeapon = FALSE;
|
|
} else
|
|
{
|
|
if(bAttack && !(lpSkillNode->m_wSkill & 0x8000) && (g_DeviceInput.GetIsLeftMousePress() || g_CharacterData.m_bAutoTargetAttack)) // 타이밍이 맞았을때
|
|
{
|
|
//CSceneManager::AddDelayTimer(m_lstCharData[m_nFocusCharacter].m_lpChrModel, 3);
|
|
// 계속 콤보가 누적된다.
|
|
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
|
|
{
|
|
if(++g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo >= g_CharacterData.m_dwMaxCombo)
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
} else
|
|
{
|
|
if( g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK2 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK3 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK4 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK5 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK6)
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction = CA_WAIT;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwUpperChrAction = CA_WAIT;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bUpperAble = TRUE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bLowerAble = TRUE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bUpperAnimating = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bLowerAnimating = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
}
|
|
}*/
|
|
|
|
if(lpSkillNode->m_wNumAttack <= lpSkillNode->m_wNumAttackCount || lpSkillNode->m_wSkill == 0x9305)
|
|
{
|
|
// 공격 수가 끝났을 때 스킬 노드를 없앤다.
|
|
for(it = m_lstSkillNode.begin(); it != m_lstSkillNode.end(); it++)
|
|
{
|
|
if((*it) == lpSkillNode) break;
|
|
}
|
|
|
|
it = m_lstSkillNode.erase(it);
|
|
delete lpSkillNode;
|
|
}
|
|
}
|
|
|
|
nResult = CSceneManager::GetCharacterEvent(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel, EVENT_CANCEL);
|
|
if(nResult)
|
|
{
|
|
if(g_ClientMain.GetChangeWeapon())
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
g_ClientMain.m_bChangeWeapon = FALSE;
|
|
} else
|
|
{
|
|
if(bAttack && (g_DeviceInput.GetIsLeftMousePress() || g_CharacterData.m_bAutoTargetAttack)) // 타이밍이 맞았을때
|
|
{
|
|
//CSceneManager::AddDelayTimer(m_lstCharData[m_nFocusCharacter].m_lpChrModel, 3);
|
|
// 계속 콤보가 누적된다.
|
|
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
|
|
{
|
|
if(++g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo >= g_CharacterData.m_dwMaxCombo)
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
} else
|
|
{
|
|
if( g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK2 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK3 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK4 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK5 ||
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_ATTACK6)
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction = CA_WAIT;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwUpperChrAction = CA_WAIT;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bUpperAble = TRUE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bLowerAble = TRUE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bUpperAnimating = FALSE;
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_bLowerAnimating = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwAttackCombo = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
vector<LPEffectNode>::iterator itEffect;
|
|
for(itEffect = m_lstEffect.begin(); itEffect != m_lstEffect.end(); itEffect++)
|
|
{
|
|
/* if(CSceneManager::m_EffectManager.CheckNullScript((*itEffect)->m_lpEffect))
|
|
{
|
|
LPEffectNode lpEffect = (*itEffect);
|
|
itEffect = m_lstEffect.erase(itEffect);
|
|
delete lpEffect;
|
|
} else
|
|
{*/
|
|
CCreature *lpCreature = g_CharacterData.GetCreature(g_ClientMain.m_dwMyChrID);
|
|
if(lpCreature)
|
|
{
|
|
(*itEffect)->m_lpEffect->SetStartPos(lpCreature->m_vecPos.x, lpCreature->m_vecPos.y, lpCreature->m_vecPos.z);
|
|
}
|
|
|
|
if((*itEffect)->m_dwTargetID != 0xFFFFFFFF)
|
|
{
|
|
lpCreature = g_CharacterData.GetCreature((*itEffect)->m_dwTargetID);
|
|
if(lpCreature)
|
|
{
|
|
(*itEffect)->m_lpEffect->SetEndPos(lpCreature->m_vecPos.x, lpCreature->m_vecPos.y, lpCreature->m_vecPos.z);
|
|
}
|
|
}
|
|
/*
|
|
itEffect++;
|
|
}*/
|
|
}
|
|
}
|
|
|
|
CSkillNode * CSkillSystem::GetNormalSkillNode()
|
|
{
|
|
vector<CSkillNode *>::iterator it;
|
|
for(it = m_lstSkillNode.begin(); it != m_lstSkillNode.end(); it++)
|
|
{
|
|
// if(!((*it)->m_wSkill & 0x8000)) return (*it);
|
|
if((*it)->m_bMelee || (*it)->m_wSkill == 0x9407) return (*it);
|
|
}
|
|
|
|
return NULL;
|
|
}
|