Files
Client/GameTools/NeoRylClient/SkillNode.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
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>
2025-11-29 20:17:20 +09:00

338 lines
11 KiB
C++

// SkillNode.cpp: implementation of the CSkillNode class.
//
//////////////////////////////////////////////////////////////////////
//#include <crtdbg.h>
#include "ClientMain.h"
#include "CharacterControl.h"
#include "SkillNode.h"
#include "SkillSystem.h"
#include "Skill\SkillMgr.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSkillNode::CSkillNode()
{
m_lpButtonNormal = NULL;
m_lpButtonDown = NULL;
m_lpButtonSuccess = NULL;
}
CSkillNode::~CSkillNode()
{
}
void CSkillNode::Create(unsigned long dwChrID, unsigned char cSuccess, unsigned short wSkill, unsigned short wSkillGrade, unsigned long dwCastingTick)
{
if(wSkill & 0x8000) // ½ºÅ³ÀÎÁö ¾Æ´ÑÁö ±¸ºÐ
{
const Skill::ProtoType *lpSkillTypeTemp = g_SkillMgr.GetSkillProtoType(wSkill);
const Skill::ProtoType *lpSkillType = &lpSkillTypeTemp[wSkillGrade];
const Skill::ProtoType *lpSkillTypeforStartMP = lpSkillType;
if(lpSkillType)
{
if(Skill::Type::INSTANCE == lpSkillType->m_eSkillType)
{
m_cLevel = (unsigned char)dwCastingTick;
} else
{
unsigned long dwLevelTick = lpSkillType->m_LevelTick * ((500 - ((g_ClientMain.m_csStatus.m_Info.DEX + g_ClientMain.m_csStatus.m_lAddDEX) - 20)) / 500.0f);
m_cLevel = dwCastingTick / dwLevelTick;
}
if(g_ClientMain.m_csStatus.m_Info.MP < lpSkillTypeforStartMP->m_StartMP + lpSkillType->m_LevelMP * m_cLevel)
{
for(int i = wSkillGrade; i >= 0; i--)
{
if(g_ClientMain.m_csStatus.m_Info.MP >= lpSkillTypeforStartMP->m_StartMP)
{
wSkillGrade = i;
lpSkillType = &lpSkillTypeTemp[wSkillGrade];
m_cLevel = (g_ClientMain.m_csStatus.m_Info.MP - lpSkillTypeforStartMP->m_StartMP) / lpSkillType->m_LevelMP;
break;
}
}
}
m_cSuccess = cSuccess;
m_dwTargetChrID = dwChrID;
if(lpSkillType->m_eTargetType == Skill::Target::MELEE) m_bMelee = TRUE; else m_bMelee = FALSE;
CEffScript *test_script;
////////// skil ///////////
CEffScript *skill_name;
char skill[256]={0};
char *skill_ptr = NULL;
bool skill_nameuse = true;
if(strstr("A_Firing",lpSkillType->m_szEffectFileName) != NULL) //Firing Àº skill name Ãâ·Â X
skill_nameuse = false;
// _ASSERTE(_CrtCheckMemory());
test_script = new CEffScript;
if(skill_nameuse == true) {
// _ASSERTE(_CrtCheckMemory());
skill_name = new CEffScript;
strcpy(skill,lpSkillType->m_szEffectFileName);
skill_ptr = strrchr(skill,'.');
(*skill_ptr) = '_';skill_ptr++;
(*skill_ptr) = 'n';skill_ptr++;
(*skill_ptr) = 'a';skill_ptr++;
(*skill_ptr) = 'm';skill_ptr++;
(*skill_ptr) = 'e';skill_ptr++;
(*skill_ptr) = '.';skill_ptr++;
(*skill_ptr) = 'e';skill_ptr++;
(*skill_ptr) = 's';skill_ptr++;
(*skill_ptr) = 'f';skill_ptr++;
(*skill_ptr) = '\0';skill_ptr++;
}
//////////////////////
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
{
test_script->SetSkillInfo(g_ClientMain.m_csStatus.m_Info.Sex, g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType());
} else
{
test_script->SetSkillInfo(g_ClientMain.m_csStatus.m_Info.Sex, 0);
}
if(skill_nameuse == true) {
skill_name->SetInterfaceSet(true);
skill_name->GetScriptBinData(skill);
}
test_script->GetScriptBinData((char *)lpSkillType->m_szEffectFileName);
// ½ºÅ³ »ç¿ë½Ã Ÿ°Ý ÀÌÆÑÆ® ó¸®
if(wSkill == 0x8603) // chain action
g_CharacterData.m_SkillAttackValue = lpSkillType->m_cStrikeNum; //Hit Count Setting
test_script->SetStartPos(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.x,
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.y,
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.z);
if(m_dwTargetChrID != 0xFFFFFFFF)
{
vector3 *vecPos = g_CharacterData.GetFindChrPos(m_dwTargetChrID);
if(vecPos) test_script->SetEndPos((D3DXVECTOR3 *)vecPos, 1);
// ij¸¯ÅÍ ¼¼ÆÃ
CCreature *target_chr = g_CharacterData.GetCreature(m_dwTargetChrID);
test_script->SetChr(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel,
target_chr->m_lpChrModel);
} else
{
if(m_bMelee)
{
float fChrDir = g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_fDirection;
fChrDir = -fChrDir;
fChrDir -= FLOAT_PHI / 2.0f;
vector3 vecChrToward;
vecChrToward.x = cosf(fChrDir);
vecChrToward.z = sinf(fChrDir);
vecChrToward.y = 0.0f;
vecChrToward.Normalize();
vecChrToward *= 50.0f;
vector3 vecEnd = g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos + vecChrToward;
test_script->SetEndPos((D3DXVECTOR3 *)&vecEnd, 1);
}
}
float fChrDir = g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_fDirection;
fChrDir = -fChrDir;
fChrDir -= FLOAT_PHI / 2.0f;
vector3 vecChrToward;
vecChrToward.x = cosf(fChrDir);
vecChrToward.z = sinf(fChrDir);
vecChrToward.y = 0.0f;
vecChrToward.Normalize();
test_script->SetChrFwd(-vecChrToward.x, -vecChrToward.y, -vecChrToward.z);
test_script->SetPlayer(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter],g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwChrID);
m_lpEffectIndex = CSceneManager::m_EffectManager.AddEffScript(test_script); // ÀÌÆåÆ® ½ºÅ©¸³Æ®¸¦ ÀÐÀ¸¸é ³ª¿À´Â À妽º
if(skill_nameuse == true) {
skill_name->m_InterfacePos[0] += 0.0f;
skill_name->m_InterfacePos[1] += 310.0f;
CSceneManager::m_EffectManager.AddInterfaceScript(skill_name);
}
m_bAngle = TRUE;
m_wSkill = wSkill;
m_wSkillGrade = wSkillGrade;
m_wNumAttack = lpSkillType->m_cStrikeNum;
m_wNumAttackCount = 0;
vector3 *vecPos;
if(m_dwTargetChrID != 0xFFFFFFFF)
{
vecPos = g_CharacterData.GetFindChrPos(m_dwTargetChrID);
} else
{
vecPos = &g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos;
}
CastObject pCastObject;
pCastObject.m_wTypeID = g_ClientMain.m_csStatus.m_lpQuickSelected->GetProtoTypeID();
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
{
pCastObject.m_cObjectType = g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType();
} else
{
pCastObject.m_cObjectType = 0;
}
pCastObject.m_cObjectLevel = wSkillGrade;
pCastObject.m_DstPos.fPointX = vecPos->x;
pCastObject.m_DstPos.fPointY = vecPos->y;
pCastObject.m_DstPos.fPointZ = vecPos->z;
List<DWORD> SendCharacterList;
g_CharacterData.GetSendCharacterAroundList(SendCharacterList);
for(int i=0;i<SendCharacterList.num;i++)
{
g_ClientMain.m_Network.m_pSocket->RegistInstanceUDPList(SendCharacterList[i]);
}
g_ClientMain.m_Network.m_pSocket->CharCastObjectInfo(g_ClientMain.m_dwMyChrID, m_dwTargetChrID, pCastObject);
g_SkillSystem.AddSkill(this);
g_ClientMain.SetSkillCoolDown(wSkillGrade, lpSkillType->m_cEndCoolDown);
if(lpSkillType->m_cEndScript)
{
LPEffectNode lpEffect;
lpEffect = new EffectNode;
lpEffect->m_lpEffect = m_lpEffectIndex;
lpEffect->m_dwTargetID = m_dwTargetChrID;
g_SkillSystem.m_lstEffect.push_back(lpEffect);
}
}
} else if(wSkill == AtType::Bow || wSkill == AtType::CrossBow)
{
// Ȱ / ¼®±Ã °ø°Ý
m_cLevel = 0;
m_cSuccess = cSuccess;
m_dwTargetChrID = dwChrID;
m_wSkill = wSkill;
m_wSkillGrade = wSkillGrade;
m_wNumAttack = 1;
m_wNumAttackCount = 0;
m_bAngle = TRUE;
m_bMelee = FALSE;
CEffScript *test_script;
// _ASSERTE(_CrtCheckMemory());
test_script = new CEffScript;
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
{
test_script->SetSkillInfo(g_ClientMain.m_csStatus.m_Info.Sex, g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType());
} else
{
test_script->SetSkillInfo(g_ClientMain.m_csStatus.m_Info.Sex, 0);
}
test_script->GetScriptBinData("arrow_normal.esf");
test_script->SetStartPos(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.x,
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.y,
g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos.z);
if(m_dwTargetChrID != 0xFFFFFFFF)
{
vector3 *vecPos = g_CharacterData.GetFindChrPos(m_dwTargetChrID);
if(vecPos) test_script->SetEndPos((D3DXVECTOR3 *)vecPos, 1);
// ij¸¯ÅÍ ¼¼ÆÃ
CCreature *target_chr = g_CharacterData.GetCreature(m_dwTargetChrID);
test_script->SetChr(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel,
target_chr->m_lpChrModel);
}
float fChrDir = g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_fDirection;
fChrDir = -fChrDir;
fChrDir -= FLOAT_PHI / 2.0f;
vector3 vecChrToward;
vecChrToward.x = cosf(fChrDir);
vecChrToward.z = sinf(fChrDir);
vecChrToward.y = 0.0f;
vecChrToward.Normalize();
test_script->SetChrFwd(-vecChrToward.x, -vecChrToward.y, -vecChrToward.z);
m_lpEffectIndex = CSceneManager::m_EffectManager.AddEffScript(test_script); // ÀÌÆåÆ® ½ºÅ©¸³Æ®¸¦ ÀÐÀ¸¸é ³ª¿À´Â À妽º
vector3 *vecPos;
if(m_dwTargetChrID != 0xFFFFFFFF)
{
vecPos = g_CharacterData.GetFindChrPos(m_dwTargetChrID);
} else
{
vecPos = &g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_vecPos;
}
CastObject pCastObject;
pCastObject.m_wTypeID = wSkill;
if(g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos])
{
pCastObject.m_cObjectType = g_ClientMain.m_csStatus.m_lstEquipment[11 + g_ClientMain.m_csStatus.m_cWeaponPos]->GetItemType();
} else
{
pCastObject.m_cObjectType = 0;
}
pCastObject.m_cObjectLevel = wSkillGrade;
pCastObject.m_DstPos.fPointX = vecPos->x;
pCastObject.m_DstPos.fPointY = vecPos->y;
pCastObject.m_DstPos.fPointZ = vecPos->z;
List<DWORD> SendCharacterList;
g_CharacterData.GetSendCharacterAroundList(SendCharacterList);
for(int i=0;i<SendCharacterList.num;i++)
{
g_ClientMain.m_Network.m_pSocket->RegistInstanceUDPList(SendCharacterList[i]);
}
g_ClientMain.m_Network.m_pSocket->CharCastObjectInfo(g_ClientMain.m_dwMyChrID, m_dwTargetChrID, pCastObject);
g_SkillSystem.AddSkill(this);
} else
{
// ÀÏ¹Ý °ø°Ý
m_cLevel = 0;
m_cSuccess = cSuccess;
m_dwTargetChrID = dwChrID;
// m_nEffectIndex // ÀÌÆåÆ® ½ºÅ©¸³Æ®¸¦ ÀÐÀ¸¸é ³ª¿À´Â À妽º
m_wSkill = wSkill;
m_wSkillGrade = wSkillGrade;
if(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_JUMPATTACK)
{
const char *strMotionSheet = g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_lpChrModel->GetCurrentMotionSheetName();
if(strMotionSheet && !strcmp(strMotionSheet, "CLASS_ROGUE"))
m_wNumAttack = 2;
else
m_wNumAttack = 1;
m_bAngle = FALSE;
} else if(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_JUMPATTACK2)
{
m_wNumAttack = 4;
m_bAngle = FALSE;
} else if(g_CharacterData.m_lstCharData[g_CharacterData.m_nFocusCharacter]->m_dwLowerChrAction == CA_JUMPATTACK3)
{
m_wNumAttack = 3;
m_bAngle = FALSE;
} else
{
m_wNumAttack = 1;
m_bAngle = TRUE;
}
m_wNumAttackCount = 0;
m_bMelee = TRUE;
g_SkillSystem.AddSkill(this);
}
m_bFirstAttack = FALSE;
}