forked from metin2/client
992 lines
25 KiB
C++
992 lines
25 KiB
C++
|
#include "StdAfx.h"
|
|||
|
#include "PythonPlayer.h"
|
|||
|
#include "PythonTextTail.h"
|
|||
|
#include "PythonNetworkStream.h"
|
|||
|
#include "InstanceBase.h"
|
|||
|
#include "PythonChat.h"
|
|||
|
#include "PythonGuild.h"
|
|||
|
#include "../GameLib/ItemManager.h"
|
|||
|
|
|||
|
void CPythonPlayer::ClearAffects()
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "ClearAffects", Py_BuildValue("()"));
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::SetAffect(UINT uAffect)
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "SetAffect", Py_BuildValue("(i)", uAffect));
|
|||
|
|
|||
|
/////
|
|||
|
|
|||
|
DWORD dwSkillIndex;
|
|||
|
if (!AffectIndexToSkillIndex(uAffect, &dwSkillIndex))
|
|||
|
return;
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData))
|
|||
|
return;
|
|||
|
|
|||
|
if (!pSkillData->IsToggleSkill())
|
|||
|
return;
|
|||
|
|
|||
|
DWORD dwSkillSlotIndex;
|
|||
|
if (!GetSkillSlotIndex(dwSkillIndex, &dwSkillSlotIndex))
|
|||
|
return;
|
|||
|
|
|||
|
__ActivateSkillSlot(dwSkillSlotIndex);
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::ResetAffect(UINT uAffect)
|
|||
|
{
|
|||
|
// 2004.07.17.myevan.<2E><>ų <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "ResetAffect", Py_BuildValue("(i)", uAffect));
|
|||
|
|
|||
|
DWORD dwSkillIndex;
|
|||
|
if (!AffectIndexToSkillIndex(uAffect, &dwSkillIndex))
|
|||
|
return;
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData))
|
|||
|
return;
|
|||
|
|
|||
|
if (!pSkillData->IsToggleSkill())
|
|||
|
return;
|
|||
|
|
|||
|
DWORD dwSkillSlotIndex;
|
|||
|
if (!GetSkillSlotIndex(dwSkillIndex, &dwSkillSlotIndex))
|
|||
|
return;
|
|||
|
|
|||
|
__DeactivateSkillSlot(dwSkillSlotIndex);
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::FindSkillSlotIndexBySkillIndex(DWORD dwSkillIndex, DWORD * pdwSkillSlotIndex)
|
|||
|
{
|
|||
|
for (int i = 0; i < SKILL_MAX_NUM; ++i)
|
|||
|
{
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[i];
|
|||
|
if (dwSkillIndex == rkSkillInst.dwIndex)
|
|||
|
{
|
|||
|
*pdwSkillSlotIndex = i;
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::ChangeCurrentSkillNumberOnly(DWORD dwSlotIndex)
|
|||
|
{
|
|||
|
if (dwSlotIndex >= SKILL_MAX_NUM)
|
|||
|
return;
|
|||
|
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex];
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData))
|
|||
|
return;
|
|||
|
|
|||
|
if (!pSkillData->IsCanUseSkill())
|
|||
|
return;
|
|||
|
|
|||
|
if (!__IsRightButtonSkillMode())
|
|||
|
{
|
|||
|
if (!__IsTarget())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET"));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
ClickSkillSlot(dwSlotIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_dwcurSkillSlotIndex = dwSlotIndex;
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "ChangeCurrentSkill", Py_BuildValue("(i)", dwSlotIndex));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::ClickSkillSlot(DWORD dwSlotIndex)
|
|||
|
{
|
|||
|
if (dwSlotIndex >= SKILL_MAX_NUM)
|
|||
|
return;
|
|||
|
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex];
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData))
|
|||
|
return;
|
|||
|
|
|||
|
if (CPythonSkill::SKILL_TYPE_GUILD == pSkillData->byType)
|
|||
|
{
|
|||
|
UseGuildSkill(dwSlotIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!pSkillData->IsCanUseSkill())
|
|||
|
return;
|
|||
|
|
|||
|
if (pSkillData->IsStandingSkill())
|
|||
|
{
|
|||
|
if (pSkillData->IsToggleSkill())
|
|||
|
{
|
|||
|
if (IsSkillActive(dwSlotIndex))
|
|||
|
{
|
|||
|
CInstanceBase * pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return;
|
|||
|
if (pkInstMain->IsUsingSkill())
|
|||
|
return;
|
|||
|
|
|||
|
CPythonNetworkStream::Instance().SendUseSkillPacket(rkSkillInst.dwIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
__UseSkill(dwSlotIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (m_dwcurSkillSlotIndex == dwSlotIndex)
|
|||
|
{
|
|||
|
__UseSkill(m_dwcurSkillSlotIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!__IsRightButtonSkillMode())
|
|||
|
{
|
|||
|
__UseSkill(dwSlotIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_dwcurSkillSlotIndex = dwSlotIndex;
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "ChangeCurrentSkill", Py_BuildValue("(i)", dwSlotIndex));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckSkillUsable(DWORD dwSlotIndex)
|
|||
|
{
|
|||
|
CInstanceBase * pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return false;
|
|||
|
|
|||
|
if (dwSlotIndex >= SKILL_MAX_NUM)
|
|||
|
return false;
|
|||
|
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex];
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData))
|
|||
|
return false;
|
|||
|
|
|||
|
if (pkInstMain->IsMountingHorse())
|
|||
|
{
|
|||
|
if (!pSkillData->IsHorseSkill())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_HORSE_SKILL"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (pSkillData->IsHorseSkill())
|
|||
|
{
|
|||
|
if (!pkInstMain->IsMountingHorse())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "HAVE_TO_RIDE"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 2004.07.26.levites - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿡<EFBFBD><EBBFA1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
// NOTE : <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿡<EFBFBD><EBBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>մϴ<D5B4> - [levites]
|
|||
|
if (pSkillData->IsAttackSkill())
|
|||
|
{
|
|||
|
if (pkInstMain->IsInSafe())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE"));
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// NOTE : <20>нú<D0BD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>մϴ<D5B4> - [levites]
|
|||
|
if (!pSkillData->IsCanUseSkill())
|
|||
|
return false;
|
|||
|
// if (CPythonSkill::SKILL_TYPE_PASSIVE == pSkillData->byType)
|
|||
|
// return false;
|
|||
|
|
|||
|
// NOTE : [Only Assassin] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> üũ <20>մϴ<D5B4>.
|
|||
|
if (pSkillData->IsNeedEmptyBottle())
|
|||
|
{
|
|||
|
if (!__HasItem(27995))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_EMPTY_BOTTLE"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// NOTE : [Only Assassin] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> üũ <20>մϴ<D5B4>.
|
|||
|
if (pSkillData->IsNeedPoisonBottle())
|
|||
|
{
|
|||
|
if (!__HasItem(27996))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_POISON_BOTTLE"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// NOTE : <20><><EFBFBD><EFBFBD> <20><><EFBFBD>϶<EFBFBD><CFB6><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>մϴ<D5B4>.
|
|||
|
if (pkInstMain->IsFishingMode())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "REMOVE_FISHING_ROD"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// NOTE : <20><><EFBFBD><EFBFBD> üũ
|
|||
|
if (m_sysIsLevelLimit)
|
|||
|
{
|
|||
|
if (rkSkillInst.iLevel <= 0)
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_YET_LEARN"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// NOTE : <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> üũ
|
|||
|
if (!pSkillData->CanUseWeaponType(pkInstMain->GetWeaponType()))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_MATCHABLE_WEAPON"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (!pSkillData->IsHorseSkill()) // HORSE <20><>ų <20>߿<EFBFBD> ȭ<><C8AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><>ų<EFBFBD><C5B3> <20>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
if (__CheckShortArrow(rkSkillInst, *pSkillData))
|
|||
|
return false;
|
|||
|
|
|||
|
// NOTE : Ȱ<><C8B0> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> ȭ<><C8AD> <20><><EFBFBD><EFBFBD> üũ
|
|||
|
if (pSkillData->IsNeedBow())
|
|||
|
{
|
|||
|
if (!__HasEnoughArrow())
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (__CheckDashAffect(*pkInstMain))
|
|||
|
{
|
|||
|
if (!pSkillData->IsChargeSkill())
|
|||
|
{
|
|||
|
if (__CheckRestSkillCoolTime(dwSlotIndex))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (__CheckRestSkillCoolTime(dwSlotIndex))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (__CheckShortLife(rkSkillInst, *pSkillData))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_ENOUGH_HP"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (__CheckShortMana(rkSkillInst, *pSkillData))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_ENOUGH_SP"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckShortArrow(TSkillInstance & rkSkillInst, CPythonSkill::TSkillData& rkSkillData)
|
|||
|
{
|
|||
|
if (!rkSkillData.IsNeedBow())
|
|||
|
return false;
|
|||
|
|
|||
|
if (__HasEnoughArrow())
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckShortMana(TSkillInstance& rkSkillInst, CPythonSkill::TSkillData& rkSkillData)
|
|||
|
{
|
|||
|
extern const DWORD c_iSkillIndex_Summon;
|
|||
|
if (c_iSkillIndex_Summon == rkSkillInst.dwIndex)
|
|||
|
return false;
|
|||
|
|
|||
|
int iNeedSP = rkSkillData.GetNeedSP(rkSkillInst.fcurEfficientPercentage);
|
|||
|
int icurSP = GetStatus(POINT_SP);
|
|||
|
|
|||
|
// NOTE : ToggleSkill <20><> <20>ƴѵ<C6B4> <20>Ҹ<EFBFBD> SP <20><> 0 <20>̴<EFBFBD>.
|
|||
|
if (!rkSkillData.IsToggleSkill())
|
|||
|
{
|
|||
|
if (iNeedSP == 0)
|
|||
|
{
|
|||
|
CPythonChat::Instance().AppendChat(CHAT_TYPE_INFO, "!!! Find strange game data. Please reinstall metin2.");
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (rkSkillData.CanUseIfNotEnough())
|
|||
|
{
|
|||
|
if (icurSP <= 0)
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (-1 != iNeedSP)
|
|||
|
if (iNeedSP > icurSP)
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckShortLife(TSkillInstance& rkSkillInst, CPythonSkill::TSkillData& rkSkillData)
|
|||
|
{
|
|||
|
if (!rkSkillData.IsUseHPSkill())
|
|||
|
return false;
|
|||
|
|
|||
|
DWORD dwNeedHP = rkSkillData.GetNeedSP(rkSkillInst.fcurEfficientPercentage);
|
|||
|
if (dwNeedHP <= GetStatus(POINT_HP))
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckRestSkillCoolTime(DWORD dwSlotIndex)
|
|||
|
{
|
|||
|
if (!m_sysIsCoolTime)
|
|||
|
return false;
|
|||
|
|
|||
|
if (dwSlotIndex >= SKILL_MAX_NUM)
|
|||
|
return false;
|
|||
|
|
|||
|
float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_playerStatus.aSkill[dwSlotIndex].fLastUsedTime;
|
|||
|
if (fElapsedTime >= m_playerStatus.aSkill[dwSlotIndex].fCoolTime)
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckDashAffect(CInstanceBase& rkInstMain)
|
|||
|
{
|
|||
|
return rkInstMain.IsAffect(CInstanceBase::AFFECT_DASH);
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::__UseCurrentSkill()
|
|||
|
{
|
|||
|
__UseSkill(m_dwcurSkillSlotIndex);
|
|||
|
}
|
|||
|
|
|||
|
DWORD CPythonPlayer::__GetSkillTargetRange(CPythonSkill::TSkillData& rkSkillData)
|
|||
|
{
|
|||
|
return rkSkillData.GetTargetRange() + GetStatus(POINT_BOW_DISTANCE)*100;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__ProcessEnemySkillTargetRange(CInstanceBase& rkInstMain, CInstanceBase& rkInstTarget, CPythonSkill::TSkillData& rkSkillData, DWORD dwSkillSlotIndex)
|
|||
|
{
|
|||
|
DWORD dwSkillTargetRange=__GetSkillTargetRange(rkSkillData);
|
|||
|
float fSkillTargetRange = float(dwSkillTargetRange);
|
|||
|
if (fSkillTargetRange <= 0.0f)
|
|||
|
return true;
|
|||
|
|
|||
|
// #0000806: [M2EU] <20><><EFBFBD>濡<EFBFBD><E6BFA1> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD>ѱ<EFBFBD>) źȯ<C5BA><C8AF> <20><>ų <20><><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>
|
|||
|
float fTargetDistance = rkInstMain.GetDistance(&rkInstTarget);
|
|||
|
|
|||
|
extern bool IS_HUGE_RACE(unsigned int vnum);
|
|||
|
if (IS_HUGE_RACE(rkInstTarget.GetRace()))
|
|||
|
{
|
|||
|
fTargetDistance -= 200.0f; // TEMP: <20>ϴ<EFBFBD> <20>ϵ<EFBFBD> <20>ڵ<EFBFBD> ó<><C3B3>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> <20><><EFBFBD>Ǿ <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD><D8BE><EFBFBD>
|
|||
|
}
|
|||
|
|
|||
|
if (fTargetDistance >= fSkillTargetRange)
|
|||
|
{
|
|||
|
if (rkSkillData.IsChargeSkill())
|
|||
|
{
|
|||
|
if (!__IsReservedUseSkill(dwSkillSlotIndex))
|
|||
|
__SendUseSkill(dwSkillSlotIndex, 0);
|
|||
|
}
|
|||
|
|
|||
|
__ReserveUseSkill(rkInstTarget.GetVirtualID(), dwSkillSlotIndex, dwSkillTargetRange);
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 2004.07.05.myevan. <20>ý<EFBFBD>ź<EFBFBD><C5BA> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ°<D6B4> üũ
|
|||
|
TPixelPosition kPPosTarget;
|
|||
|
rkInstTarget.NEW_GetPixelPosition(&kPPosTarget);
|
|||
|
|
|||
|
IBackground& rkBG=IBackground::Instance();
|
|||
|
if (rkBG.IsBlock(kPPosTarget.x, kPPosTarget.y))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_APPROACH"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CanUseSkill()
|
|||
|
{
|
|||
|
CInstanceBase* pkInstMain=NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return false;
|
|||
|
|
|||
|
if (IsObserverMode())
|
|||
|
return false;
|
|||
|
|
|||
|
// Fix me
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ. <20>¸<EFBFBD><C2B8><EFBFBD>ų<EFBFBD><C5B3><EFBFBD><EFBFBD> 20 <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> Ÿ<><C5B8> <20>¸<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20>ϵ<EFBFBD> <20>ڵ<EFBFBD>...
|
|||
|
// <20><><EFBFBD>߿<EFBFBD> <20>ð<EFBFBD> <20><><EFBFBD><EFBFBD> can use skill üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|||
|
if (pkInstMain->IsMountingHorse() && (GetSkillGrade(109) < 1 && GetSkillLevel(109) < 20))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return pkInstMain->CanUseSkill();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
bool CPythonPlayer::__UseSkill(DWORD dwSlotIndex)
|
|||
|
{
|
|||
|
// PrivateShop
|
|||
|
if (IsOpenPrivateShop())
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
if (!__CanUseSkill())
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (dwSlotIndex >= SKILL_MAX_NUM)
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) It's not available skill slot number", dwSlotIndex);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex];
|
|||
|
|
|||
|
if (__CheckSpecialSkill(rkSkillInst.dwIndex))
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData))
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) There is no skill data", dwSlotIndex);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (pSkillData->IsToggleSkill())
|
|||
|
{
|
|||
|
if (IsSkillActive(dwSlotIndex))
|
|||
|
{
|
|||
|
CPythonNetworkStream::Instance().SendUseSkillPacket(rkSkillInst.dwIndex, dwSlotIndex);
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!__CheckSkillUsable(dwSlotIndex))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
CInstanceBase * pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) There is no main player", dwSlotIndex);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (pkInstMain->IsUsingSkill())
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
CInstanceBase * pkInstTarget = NULL;
|
|||
|
|
|||
|
// NOTE : Ÿ<><C5B8><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
if (pSkillData->IsNeedTarget() ||
|
|||
|
pSkillData->CanChangeDirection() ||
|
|||
|
pSkillData->IsAutoSearchTarget())
|
|||
|
{
|
|||
|
if (pSkillData->IsNeedCorpse())
|
|||
|
pkInstTarget=__GetDeadTargetInstancePtr();
|
|||
|
else
|
|||
|
pkInstTarget=__GetAliveTargetInstancePtr();
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
|
|||
|
if (!pkInstTarget)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD>ϰ<EFBFBD>..
|
|||
|
__ChangeTargetToPickedInstance();
|
|||
|
|
|||
|
// <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EEB3BD>.
|
|||
|
if (pSkillData->IsNeedCorpse())
|
|||
|
pkInstTarget=__GetDeadTargetInstancePtr();
|
|||
|
else
|
|||
|
pkInstTarget=__GetAliveTargetInstancePtr();
|
|||
|
}
|
|||
|
|
|||
|
if (pkInstTarget)
|
|||
|
{
|
|||
|
if (pSkillData->IsOnlyForAlliance())
|
|||
|
{
|
|||
|
if (pkInstMain == pkInstTarget)
|
|||
|
{
|
|||
|
if (!pSkillData->CanUseForMe())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_USE_SELF"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (!pkInstMain->IsAttackableInstance(*pkInstTarget) && pkInstTarget->IsPC())
|
|||
|
{
|
|||
|
DWORD dwSkillRange = __GetSkillTargetRange(*pSkillData);
|
|||
|
|
|||
|
if (dwSkillRange > 0)
|
|||
|
{
|
|||
|
float fDistance=pkInstMain->GetDistance(pkInstTarget);
|
|||
|
if (fDistance>=float(dwSkillRange))
|
|||
|
{
|
|||
|
__ReserveUseSkill(pkInstTarget->GetVirtualID(), dwSlotIndex, dwSkillRange);
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pSkillData->CanUseForMe())
|
|||
|
{
|
|||
|
pkInstTarget = pkInstMain;
|
|||
|
Tracef(" [ALERT] <20><><EFBFBD>ῡ<EFBFBD><E1BFA1> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE>־ <20>ڽſ<DABD><C5BF>Է<EFBFBD> <20>缳<EFBFBD><E7BCB3>\n");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_ALLIANCE"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pkInstTarget->IsInSafe())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_ATTACK_ENEMY_IN_SAFE_AREA"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (pkInstMain->IsAttackableInstance(*pkInstTarget))
|
|||
|
{
|
|||
|
if (!__ProcessEnemySkillTargetRange(*pkInstMain, *pkInstTarget, *pSkillData, dwSlotIndex))
|
|||
|
return false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_ATTACK"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pkInstMain->SetFlyTargetInstance(*pkInstTarget);
|
|||
|
|
|||
|
if (pkInstMain != pkInstTarget)
|
|||
|
{
|
|||
|
if (pkInstMain->IsFlyTargetObject())
|
|||
|
{
|
|||
|
pkInstMain->NEW_LookAtFlyTarget();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pkInstMain->NEW_LookAtDestInstance(*pkInstTarget);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pSkillData->IsAutoSearchTarget())
|
|||
|
{
|
|||
|
if (pkInstMain->NEW_GetFrontInstance(&pkInstTarget, 2000.0f))
|
|||
|
{
|
|||
|
SetTarget(pkInstTarget->GetVirtualID());
|
|||
|
if (!__ProcessEnemySkillTargetRange(*pkInstMain, *pkInstTarget, *pSkillData, dwSlotIndex))
|
|||
|
return false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (pSkillData->CanUseForMe())
|
|||
|
{
|
|||
|
pkInstTarget = pkInstMain;
|
|||
|
pkInstMain->SetFlyTargetInstance(*pkInstMain);
|
|||
|
Tracef(" [ALERT] Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD> <20>÷<EFBFBD><C3B7>̾<CCBE><EEBFA1> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>\n");
|
|||
|
}
|
|||
|
else if (pSkillData->IsNeedCorpse())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_CORPSE"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (pSkillData->CanChangeDirection())
|
|||
|
{
|
|||
|
DWORD dwPickedActorID;
|
|||
|
TPixelPosition kPPosPickedGround;
|
|||
|
|
|||
|
if (pkInstTarget && pkInstTarget!=pkInstMain)
|
|||
|
{
|
|||
|
pkInstMain->NEW_LookAtDestInstance(*pkInstTarget);
|
|||
|
}
|
|||
|
else if (__GetPickedActorID(&dwPickedActorID))
|
|||
|
{
|
|||
|
CInstanceBase* pkInstVictim=NEW_FindActorPtr(dwPickedActorID);
|
|||
|
if (pkInstVictim)
|
|||
|
pkInstMain->NEW_LookAtDestInstance(*pkInstVictim);
|
|||
|
}
|
|||
|
else if (__GetPickedGroundPos(&kPPosPickedGround))
|
|||
|
{
|
|||
|
pkInstMain->NEW_LookAtDestPixelPosition(kPPosPickedGround);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::__UseSkill(%d) - ȭ<><C8AD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؾ<EFBFBD><D8BE><EFBFBD>", dwSlotIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>ݼ<EFBFBD> ó<><C3B3>
|
|||
|
DWORD dwTargetMaxCount = pSkillData->GetTargetCount(rkSkillInst.fcurEfficientPercentage);
|
|||
|
DWORD dwRange = __GetSkillTargetRange(*pSkillData);
|
|||
|
if (dwTargetMaxCount>0 && pkInstTarget)
|
|||
|
{
|
|||
|
DWORD dwTargetCount=1;
|
|||
|
std::vector<CInstanceBase*> kVct_pkInstTarget;
|
|||
|
|
|||
|
if (pSkillData->IsFanRange())
|
|||
|
{
|
|||
|
if (pkInstMain->NEW_GetInstanceVectorInFanRange(float(dwRange), *pkInstTarget, &kVct_pkInstTarget))
|
|||
|
{
|
|||
|
std::vector<CInstanceBase*>::iterator i;
|
|||
|
for (i=kVct_pkInstTarget.begin(); i!=kVct_pkInstTarget.end(); ++i)
|
|||
|
{
|
|||
|
if (dwTargetCount>=dwTargetMaxCount)
|
|||
|
break;
|
|||
|
|
|||
|
CInstanceBase* pkInstEach=*i;
|
|||
|
|
|||
|
if (pkInstTarget!=pkInstEach && !pkInstEach->IsDead())
|
|||
|
{
|
|||
|
pkInstMain->AddFlyTargetInstance(*pkInstEach);
|
|||
|
CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(pkInstEach->GetVirtualID(), pkInstEach->GetGraphicThingInstanceRef().OnGetFlyTargetPosition());
|
|||
|
|
|||
|
dwTargetCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (pSkillData->IsCircleRange())
|
|||
|
{
|
|||
|
if (pkInstMain->NEW_GetInstanceVectorInCircleRange(float(dwRange), &kVct_pkInstTarget))
|
|||
|
{
|
|||
|
std::vector<CInstanceBase*>::iterator i;
|
|||
|
for (i=kVct_pkInstTarget.begin(); i!=kVct_pkInstTarget.end(); ++i)
|
|||
|
{
|
|||
|
if (dwTargetCount>=dwTargetMaxCount)
|
|||
|
break;
|
|||
|
|
|||
|
CInstanceBase* pkInstEach=*i;
|
|||
|
|
|||
|
if (pkInstTarget!=pkInstEach && !pkInstEach->IsDead())
|
|||
|
{
|
|||
|
pkInstMain->AddFlyTargetInstance(*pkInstEach);
|
|||
|
CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(pkInstEach->GetVirtualID(), pkInstEach->GetGraphicThingInstanceRef().OnGetFlyTargetPosition());
|
|||
|
|
|||
|
dwTargetCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (dwTargetCount<dwTargetMaxCount)
|
|||
|
{
|
|||
|
while (dwTargetCount<dwTargetMaxCount)
|
|||
|
{
|
|||
|
TPixelPosition kPPosDst;
|
|||
|
pkInstMain->NEW_GetRandomPositionInFanRange(*pkInstTarget, &kPPosDst);
|
|||
|
|
|||
|
kPPosDst.x=kPPosDst.x;
|
|||
|
kPPosDst.y=-kPPosDst.y;
|
|||
|
|
|||
|
pkInstMain->AddFlyTargetPosition(kPPosDst);
|
|||
|
CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(0, kPPosDst);
|
|||
|
|
|||
|
dwTargetCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/////
|
|||
|
// NOTE : <20>ָ<EFBFBD><D6B8><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>س<EFBFBD><D8B3><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20><>ų<EFBFBD><C5B3> <20><><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD> - [levites]
|
|||
|
__ClearReservedAction();
|
|||
|
/////
|
|||
|
|
|||
|
if (!pSkillData->IsNoMotion())
|
|||
|
{
|
|||
|
DWORD dwMotionIndex = pSkillData->GetSkillMotionIndex(rkSkillInst.iGrade);
|
|||
|
DWORD dwLoopCount = pSkillData->GetMotionLoopCount(rkSkillInst.fcurEfficientPercentage);
|
|||
|
if (!pkInstMain->NEW_UseSkill(rkSkillInst.dwIndex, dwMotionIndex, dwLoopCount, pSkillData->IsMovingSkill() ? true : false))
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::__UseSkill(%d) - pkInstMain->NEW_UseSkill - ERROR", dwSlotIndex);
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DWORD dwTargetVID=pkInstTarget ? pkInstTarget->GetVirtualID() : 0;
|
|||
|
|
|||
|
__SendUseSkill(dwSlotIndex, dwTargetVID);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::__SendUseSkill(DWORD dwSkillSlotIndex, DWORD dwTargetVID)
|
|||
|
{
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex];
|
|||
|
|
|||
|
CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance();
|
|||
|
rkNetStream.SendUseSkillPacket(rkSkillInst.dwIndex, dwTargetVID);
|
|||
|
|
|||
|
__RunCoolTime(dwSkillSlotIndex);
|
|||
|
}
|
|||
|
|
|||
|
BYTE CPythonPlayer::__GetSkillType(DWORD dwSkillSlotIndex)
|
|||
|
{
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex];
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pkSkillData;
|
|||
|
CPythonSkill& rkPythonSkill = CPythonSkill::Instance();
|
|||
|
if (!rkPythonSkill.GetSkillData(rkSkillInst.dwIndex, &pkSkillData))
|
|||
|
{
|
|||
|
//TraceError("CPythonPlayer::__GetSkillType(dwSkillSlotIndex=%d) - NOT CHECK", dwSkillSlotIndex);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
return pkSkillData->GetType();
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::__RunCoolTime(DWORD dwSkillSlotIndex)
|
|||
|
{
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex];
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pkSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pkSkillData))
|
|||
|
{
|
|||
|
TraceError("CPythonPlayer::__SendUseSkill(dwSkillSlotIndex=%d) - NOT CHECK", dwSkillSlotIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CPythonSkill::TSkillData& rkSkillData=*pkSkillData;
|
|||
|
|
|||
|
rkSkillInst.fCoolTime = rkSkillData.GetSkillCoolTime(rkSkillInst.fcurEfficientPercentage);
|
|||
|
rkSkillInst.fLastUsedTime = CTimer::Instance().GetCurrentSecond();
|
|||
|
|
|||
|
int iSpd = 100 - GetStatus(POINT_CASTING_SPEED);
|
|||
|
if (iSpd > 0)
|
|||
|
iSpd = 100 + iSpd;
|
|||
|
else if (iSpd < 0)
|
|||
|
iSpd = 10000 / (100 - iSpd);
|
|||
|
else
|
|||
|
iSpd = 100;
|
|||
|
|
|||
|
rkSkillInst.fCoolTime = rkSkillInst.fCoolTime * iSpd / 100;
|
|||
|
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "RunUseSkillEvent", Py_BuildValue("(if)", dwSkillSlotIndex, rkSkillInst.fCoolTime));
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__HasEnoughArrow()
|
|||
|
{
|
|||
|
CItemData * pItemData;
|
|||
|
if (CItemManager::Instance().GetItemDataPointer(GetItemIndex(TItemPos(INVENTORY, c_Equipment_Arrow)), &pItemData))
|
|||
|
if (CItemData::ITEM_TYPE_WEAPON == pItemData->GetType())
|
|||
|
if (CItemData::WEAPON_ARROW == pItemData->GetSubType())
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShotError", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW"));
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__HasItem(DWORD dwItemID)
|
|||
|
{
|
|||
|
for (int i = 0; i < c_Inventory_Count; ++i)
|
|||
|
{
|
|||
|
if (dwItemID == GetItemIndex(TItemPos (INVENTORY, i)))
|
|||
|
return true;
|
|||
|
}
|
|||
|
for (int i = 0; i < c_DragonSoul_Inventory_Count; ++i)
|
|||
|
{
|
|||
|
if (dwItemID == GetItemIndex(TItemPos (DRAGON_SOUL_INVENTORY, i)))
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
extern const DWORD c_iSkillIndex_Tongsol;
|
|||
|
extern const DWORD c_iSkillIndex_Fishing;
|
|||
|
extern const DWORD c_iSkillIndex_Mining;
|
|||
|
extern const DWORD c_iSkillIndex_Making;
|
|||
|
extern const DWORD c_iSkillIndex_Combo;
|
|||
|
extern const DWORD c_iSkillIndex_Language1;
|
|||
|
extern const DWORD c_iSkillIndex_Language2;
|
|||
|
extern const DWORD c_iSkillIndex_Language3;
|
|||
|
extern const DWORD c_iSkillIndex_Polymorph;
|
|||
|
|
|||
|
void CPythonPlayer::UseGuildSkill(DWORD dwSkillSlotIndex)
|
|||
|
{
|
|||
|
CInstanceBase* pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return;
|
|||
|
if (!pkInstMain->CanUseSkill())
|
|||
|
return;
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
if (dwSkillSlotIndex >= SKILL_MAX_NUM)
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::UseGuildSkill(dwSkillSlotIndex=%d) It's not available skill slot number", dwSkillSlotIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex];
|
|||
|
|
|||
|
DWORD dwSkillIndex = rkSkillInst.dwIndex;
|
|||
|
|
|||
|
CPythonSkill::TSkillData * pSkillData;
|
|||
|
if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData))
|
|||
|
return;
|
|||
|
|
|||
|
if (__CheckRestSkillCoolTime(dwSkillSlotIndex))
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME"));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (pSkillData->IsOnlyForGuildWar())
|
|||
|
{
|
|||
|
if (!CPythonGuild::Instance().IsDoingGuildWar())
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_GUILD_WAR"));
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DWORD dwMotionIndex = pSkillData->GetSkillMotionIndex();
|
|||
|
if (!pkInstMain->NEW_UseSkill(dwSkillIndex, dwMotionIndex, 1, false))
|
|||
|
{
|
|||
|
Tracenf("CPythonPlayer::UseGuildSkill(%d) - pkInstMain->NEW_UseSkill - ERROR", dwSkillIndex);
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
CPythonNetworkStream::Instance().SendGuildUseSkillPacket(dwSkillIndex, 0);
|
|||
|
__RunCoolTime(dwSkillSlotIndex);
|
|||
|
}
|
|||
|
|
|||
|
void CPythonPlayer::SetComboSkillFlag(BOOL bFlag)
|
|||
|
{
|
|||
|
DWORD dwSlotIndex;
|
|||
|
if (!GetSkillSlotIndex(c_iSkillIndex_Combo, &dwSlotIndex))
|
|||
|
{
|
|||
|
Tracef("CPythonPlayer::SetComboSkillFlag(killIndex=%d) - Can't Find Slot Index\n", c_iSkillIndex_Combo);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
int iLevel = GetSkillLevel(dwSlotIndex);
|
|||
|
if (iLevel <= 0)
|
|||
|
{
|
|||
|
Tracef("CPythonPlayer::SetComboSkillFlag(skillIndex=%d, skillLevel=%d) - Invalid Combo Skill Level\n", c_iSkillIndex_Combo, iLevel);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
iLevel = MIN(iLevel, 2);
|
|||
|
|
|||
|
CInstanceBase* pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return;
|
|||
|
|
|||
|
if (bFlag)
|
|||
|
{
|
|||
|
pkInstMain->SetComboType(iLevel);
|
|||
|
__ActivateSkillSlot(dwSlotIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pkInstMain->SetComboType(0);
|
|||
|
__DeactivateSkillSlot(dwSlotIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool CPythonPlayer::__CheckSpecialSkill(DWORD dwSkillIndex)
|
|||
|
{
|
|||
|
CInstanceBase* pkInstMain = NEW_GetMainActorPtr();
|
|||
|
if (!pkInstMain)
|
|||
|
return false;
|
|||
|
|
|||
|
// Fishing
|
|||
|
if (c_iSkillIndex_Fishing == dwSkillIndex)
|
|||
|
{
|
|||
|
if (pkInstMain->IsFishingMode())
|
|||
|
{
|
|||
|
NEW_Fishing();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "EQUIP_FISHING_ROD"));
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// Combo
|
|||
|
else if (c_iSkillIndex_Combo == dwSkillIndex)
|
|||
|
{
|
|||
|
DWORD dwSlotIndex;
|
|||
|
if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex))
|
|||
|
return false;
|
|||
|
|
|||
|
int iLevel = GetSkillLevel(dwSlotIndex);
|
|||
|
if (iLevel > 0)
|
|||
|
{
|
|||
|
CPythonNetworkStream::Instance().SendUseSkillPacket(dwSkillIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_YET_LEARN"));
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|