#include "stdafx.h" #include "SkillExecuter.h" #include "SkillManager.h" #include "ObjectManager.h" #include "WorldManager.h" #include "Hero.h" #include "monster.h" #include "protocol.h" #include "skillscript.h" #include "TotemScript.h" #include "GameUIManager.h" #include "SkillWindow.h" #include "ItemManager.h" #include "chatmanager.h" #include "GameResourceManager.h" #include "QuickManager.h" #include "UICursor.h" #include "CastingBar.h" #include "DuelManager.h" #include "PVPManager.h" #include "PartyManager.h" #include "PartyUnionManager.h" #include "rangecheck.h" #include "TutorialManager.h" #include "CheatManager.h" ////////////////////////////////////////////////////////////////////////// unsigned int cAttackPattern::GetAttackFlag() { bool newPattern = false; if( mPatternIdx < 0 || mPatternIdx > 2 ) newPattern = true; if( mProgressIdx > 5 ) newPattern = true; if( newPattern == true ) { /// »õ·Î »ý¼º unsigned int r = ::rand()%1000; if( r < 330 ) mPatternIdx = 0; else if( r < 660 ) mPatternIdx = 1; else mPatternIdx = 2; mProgressIdx = 0; } else { if( mPattern[mPatternIdx][mProgressIdx] == -1 ) { /// »õ·Î »ý¼º unsigned int r = ::rand()%1000; if( r < 330 ) mPatternIdx = 0; else if( r < 660 ) mPatternIdx = 1; else mPatternIdx = 2; mProgressIdx = 0; } } int curIdx = mPattern[mPatternIdx][mProgressIdx]; if( mOldAttackIdx == curIdx ) { mProgressIdx++; if( mProgressIdx > 5 ) { assert(0); } } mOldAttackIdx = mPattern[mPatternIdx][mProgressIdx]; mProgressIdx++; return (unsigned int)mOldAttackIdx; } ////////////////////////////////////////////////////////////////////////// cSkillExecuter* cSkillExecuter::mpExec = NULL; cSkillExecuter::cSkillExecuter() { mpExec = this; mChargeSkill.mChargeType = eCharge_None; mChargeSkill.mSkillIdx = 0; mChargeSkill.mSkillStep = 0; mChargeSkill.mSkillRange = FLT_MAX; mAttackTarget.index = 0; mAttackTarget.type = eOBJECTTYPE_NONE; mpCurrentHeroSkillObject = 0; } cSkillExecuter::~cSkillExecuter() { } void cSkillExecuter::Close() { mChargeSkill.mChargeType = eCharge_None; mChargeSkill.mSkillIdx = 0; mChargeSkill.mSkillStep = 0; mChargeSkill.mSkillRange = FLT_MAX; mAttackTarget.index = 0; mAttackTarget.type = eOBJECTTYPE_NONE; mpCurrentHeroSkillObject = 0; } bool cSkillExecuter::AutoAttack( cBaseObject* pTarget ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return true; if( pTarget == 0 ) return false; if( HERO->IsTransformMonster() ) { unsigned long skillIdx = GenerateTransMonsAttackIdx(); if( skillIdx > eMONSTERATTACK_NORMAL2 ) return true; return AutoAttack_TransMon( skillIdx, pTarget ); } /// ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsCantSkill( NORMAL_ATTACK_SKILL ) == true ) return false; /// targetÀÇ »óÅ üũ.. unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_PLAYER: { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetState() == eOBJECT_STATE_DIE ) return false; /// ÀûÀÎÁö ¿©ºÎ ÆÇ´Ü if( DUELMAN->IsDuelEnemy( pPlayer ) != true && PVPMAN->IsEnableAttack( pPlayer ) != true ) return false; } break; case eOBJECTTYPE_MONSTER: { cMonster* pMon = (cMonster*)pTarget; if( pMon->GetState() == eOBJECT_STATE_DIE ) return false; if( PVPMAN && PVPMAN->IsEnableBattle() ) { if( ((cMonster*)pTarget)->GetPvPTeamType() != ePVPDM_TEAMTYPE_MAX && ((cMonster*)pTarget)->GetPvPTeamType() == HERO->GetPVPTeam() ) return false; } } break; default: return false; } /// ±âº» °ø°Ý À妽º »êÁ¤ - ¹«±â, °ø°Ý À妽º ChargeOn( NORMAL_ATTACK_SKILL, 0 ); /// °ø°Ý °Å¸® üũ - ÈÄ󸮱â HERO->AfterAttack( pTarget ); return true; } bool cSkillExecuter::ExecuteAttack( cBaseObject* pTarget ) { HERO->SetWaitMoveFlag( eWAITMOVE_NONE ); ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif /// 080508 PKH Á¤Áö »óÅÂÀ϶§ ÀϹݰø°Ý ÇÏ¸é ¿¡´Ï¸ÞÀ̼ÇÀÌ ¹Ù²¸¼­ üũ if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL || HERO->GetState() == ePLAYER_STATE_RUSH ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; if( pTarget == 0 ) return false; if( HERO->IsTransformMonster() ) { unsigned long skillIdx = GenerateTransMonsAttackIdx(); if( skillIdx > eMONSTERATTACK_NORMAL2 ) return false; return ExecuteAttack_TransMon( skillIdx, pTarget ); } /// ÇöÀç º¸À¯ Target°ú °°Àº TargetÀ» °ø°ÝÇÏ´Â °æ¿ì cBaseObject* pBeforeTarget = OBJECTMAN->GetObject( &mAttackTarget ); if( pTarget == pBeforeTarget ) { /// cooltime check if( SKILLMAN->IsUsedKeepSkill( NORMAL_ATTACK_SKILL, 0 ) == false ) return false; } else { /// target window ¹× hero Ÿ°Ù ¼³Á¤ HERO->SetTargetObject( pTarget->GetObjectType(), pTarget->GetObjectID() ); } sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_Attack && p->mTarget.index == pTarget->GetObjectID() ) return false; /// targetÀÇ »óÅ üũ.. unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_PLAYER: { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetState() == eOBJECT_STATE_DIE ) return false; /// ÀûÀÎÁö ¿©ºÎ ÆÇ´Ü if( DUELMAN->IsDuelEnemy( pPlayer ) != true && PVPMAN->IsEnableAttack( pPlayer ) != true ) return false; } break; case eOBJECTTYPE_MONSTER: { cMonster* pMon = (cMonster*)pTarget; if( pMon->GetState() == eOBJECT_STATE_DIE ) return false; if( PVPMAN && PVPMAN->IsEnableBattle() ) { if( ((cMonster*)pTarget)->GetPvPTeamType() != ePVPDM_TEAMTYPE_MAX && ((cMonster*)pTarget)->GetPvPTeamType() == HERO->GetPVPTeam() ) return false; } } break; default: return false; } /// ±âº» °ø°Ý À妽º »êÁ¤ - ¹«±â, °ø°Ý À妽º ChargeOn( NORMAL_ATTACK_SKILL, 0 ); /// °ø°Ý °Å¸® üũ - ÈÄ󸮱â HERO->AfterAttack( pTarget ); ResetAttackFlag(); mAttackTarget.index = pTarget->GetObjectID(); mAttackTarget.type = pTarget->GetObjectType(); return true; } /// Ÿ°ÙÀ» ±âÁØÀ¸·Î ÇÑ ½ºÅ³¿¡ »ç¿ë void cSkillExecuter::ExecuteSkill( unsigned long skillIdx, unsigned char skillStep, cBaseObject* pTarget ) { if( HERO->IsTransformMonster() ) { ExecuteSkill_TransMon( skillIdx, pTarget ); return; } HERO->SetWaitMoveFlag( eWAITMOVE_NONE ); ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return; #endif /// 080508 PKH Á¤Áö »óÅÂÀ϶§ ÀϹݰø°Ý ÇÏ¸é ¿¡´Ï¸ÞÀ̼ÇÀÌ ¹Ù²¸¼­ üũ if( HERO->GetState() == eOBJECT_STATE_DIE ) return; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL || HERO->GetState() == ePLAYER_STATE_RUSH ) return; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return; } /// ½ºÅ³ Á¤º¸¸¦ ȹµæÇÑ´Ù. sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return; } if( pInfo->mShotType == eSHOTTYPE_AURA ) { cSkillWindow* pSkillWindow = GAMEUI->GetSkillWindow(); if( pSkillWindow == 0 ) { assert(0); return; } unsigned long uniqueIdx = pSkillWindow->GetAuraUniqueIdx( skillIdx ); if( uniqueIdx ) { MSG_REQ_INFLUENCE_AURA_DELETE msg; msg.Category = NM_SKILL; msg.Protocol = NM_SKILL_INFLUENCE_AURA_DELETE_REQ; msg.mUniqueIdx = uniqueIdx; msg.mSkillClassIdx = skillIdx; NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) ); return; } } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return; if( skillIdx < NORMAL_ATTACK_SKILL_MAX ) { assert(0); return; } /// »ç¿ë °¡´É ¿©ºÎ üũ if( IsPossibleUseSkill( skillIdx, skillStep ) == false ) return; /// ij½ºÆÃ¹Ù º¸À̱â if( pInfo->mShotType == eSHOTTYPE_CASTING ) { cCastingBar* pWin = (cCastingBar*)UIMAN->FindNodeByID( eUIID_GAME_CASTINGBAR ); if( pWin && pWin->IsVisible() ) { if( HERO->IsReadyUseSkill() ) return; } } /// bool targetCheck = true; if( pTarget == 0 ) pTarget = HERO->GetTargetObject(); if( pInfo->mBoundType == eBOUNDTYPE_FIELD ) { FieldSkillOn( skillIdx, skillStep ); return; } else if( pInfo->mBoundType == eBOUNDTYPE_SELF_NOTARGET ) { /// active targetCheck = false; } else if( pInfo->mBoundType == eBOUNDTYPE_AUTOFIELD ) { ExecuteAutoPos( skillIdx, skillStep ); return; } else if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { if( pInfo->mApplyType == eAPPLYTYPE_SELF || pInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) pTarget = HERO; else if( pInfo->mApplyType == eAPPLYTYPE_BUDDY || pInfo->mApplyType == eAPPLYTYPE_PARTY || pInfo->mApplyType == eAPPLYTYPE_BUFF_PARTY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_PARTY ) { if( pTarget == 0 ) pTarget = HERO; } targetCheck = true; } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ /// (¾µ¼ö ÀÖ´ÂÁö¸¦ üũÇϱâ À§ÇØ ÀÚ±â Àڽſ¡°Ô ¾²´Â °æ¿ì¸¸ üũ, Ÿ°ÙÀÌ ÇÊ¿äÇÑ °æ¿ì¿¡´Â chargeOnÀ» À§ÇØ skip ) if( pInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyBuffType( pInfo->mApplyValueType ) == false ) return; } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyDeBuffType( pInfo->mApplyValueType ) == false ) return; } break; } } if( targetCheck ) { /// Àû¿ë Ÿ°ÙÀÌ ¾Æ´Ñ °æ¿ì charge if( IsPossibleUseSkillTarget( skillIdx, pTarget ) == false ) { ChargeOn( skillIdx, skillStep ); return; } /// cBaseObject* pBeforeTarget = OBJECTMAN->GetObject( &mAttackTarget ); if( pTarget == pBeforeTarget ) { /// cooltime check if( SKILLMAN->IsUsedKeepSkill( skillIdx, skillStep ) == false ) return; } sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseTargetSkill && p->mExData1 == skillIdx && p->mExData2 == skillStep && p->mTarget.index == pTarget->GetObjectID() ) return; } /// ½ºÅ³ ¹ßµ¿ ChargeOn( skillIdx, skillStep ); HERO->AfterUseSkill( pTarget ); if( pTarget ) mAttackTarget = *(pTarget->GetTargetInfo()); } /// BOUNDTYPE = eBOUNDTYPE_FIELD »ç¿ë void cSkillExecuter::ExecuteSkill( unsigned long skillIdx, unsigned char skillStep, NiPoint3 applyPos ) { if( HERO->IsTransformMonster() ) { ExecuteSkill_TransMon( skillIdx, applyPos ); return; } HERO->SetWaitMoveFlag( eWAITMOVE_NONE ); ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return; #endif if( HERO->GetState() == eOBJECT_STATE_DIE ) return; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL || HERO->GetState() == ePLAYER_STATE_RUSH ) return; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return; if( skillIdx < NORMAL_ATTACK_SKILL_MAX ) { assert(0); return; } sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return; } if( pInfo->mShotType == eSHOTTYPE_CASTING ) { cCastingBar* pWin = (cCastingBar*)UIMAN->FindNodeByID( eUIID_GAME_CASTINGBAR ); if( pWin && pWin->IsVisible() ) { if( HERO->IsReadyUseSkill() ) return; } } /// »ç¿ë °¡´É ¿©ºÎ üũ if( IsPossibleUseSkill( skillIdx, skillStep ) == false ) return; if( pInfo->mBoundType != eBOUNDTYPE_FIELD ) return; sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseFieldSkill && p->mExData1 == skillIdx && p->mExData2 == skillStep ) return; ChargeOn( skillIdx, skillStep ); HERO->AfterUseSkill( applyPos ); } void cSkillExecuter::ExecuteAutoPos( unsigned long skillIdx, unsigned char skillStep ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return; #endif sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return; } if( pInfo->mBoundType != eBOUNDTYPE_AUTOFIELD ) { assert(0); return; } if( SKILLMAN->IsUsedKeepSkill( skillIdx, skillStep ) == false ) return; if( pInfo->mStepCount <= skillStep ) { assert(0); return; } float range = pInfo->mpSetpInfoArray[skillStep].mTargetDist; mChargeSkill.mSkillRange = HERO->CalcStatusSkillRange( range, pInfo->mRangeType, skillIdx < NORMAL_ATTACK_SKILL_MAX ); NiPoint3 heroPos = HERO->GetPos(); NiPoint3 applyPos = heroPos + HERO->GetDesireDir() * mChargeSkill.mSkillRange; /// ÁÂÇ¥°¡ À̵¿ ºÒ°¡ Áö¿ªÀ̸é Àç°è»ê unsigned long divideCnt = 10; float divideRange = mChargeSkill.mSkillRange / (float)divideCnt; cRangeCheck rangecheck( mChargeSkill.mSkillRange ); for( unsigned long i = 0; i <= divideCnt ; ++i ) { NiPoint3 divPos = heroPos + ( HERO->GetDesireDir() * ( mChargeSkill.mSkillRange - ( divideRange * i ) ) ); WORLDMAN->CalcHeight( &divPos.z, divPos.x, divPos.y ); if( rangecheck.IsRange( heroPos, divPos ) == true ) { applyPos = divPos; break; } } WORLDMAN->EnableRayGet( heroPos, applyPos ); WORLDMAN->CalcHeight( &applyPos.z, applyPos.x, applyPos.y ); sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseFieldSkill && p->mExData1 == skillIdx && p->mExData2 == skillStep ) return; ChargeOn( skillIdx, skillStep ); HERO->AfterUseSkill( applyPos ); } bool cSkillExecuter::IsPossibleUseSkill( unsigned long skillIdx, unsigned char skillStep ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->IsTransformMonster() ) return IsPossibleUseSkill_TransMon( skillIdx ); if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL || HERO->GetState() == ePLAYER_STATE_RUSH ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; if( HERO->IsJumping() == true ) return false; sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return false; } /// TODO : º¸À¯ ½ºÅ³ÀÎÁö üũ ¹× ÄðŸÀÓ Ã¼Å© if( SKILLMAN->IsUsedKeepSkill( skillIdx, skillStep ) == false ) return false; if( pInfo->mStepCount <= skillStep ) { assert(0); return false; } sPlayerSkillStepInfo* pStepInfo = &pInfo->mpSetpInfoArray[skillStep]; /// ¼Ò¸ð ¾ÆÀÌÅÛ º¸À¯ ¿©ºÎ üũ if( pInfo->mUseItem ) { /// Àκ¥ üũ sItemCount* p = ITEMMAN->GetItemCount( pInfo->mUseItem ); unsigned int count = ( p ) ? p->bag : 0; if( count < pStepInfo->mUseItemCount ) return false; } if( TUTORIALMAN->IsTutorialMode() == false ) { if( HERO->GetLevel() < pStepInfo->mPlayerLevel ) return false; } /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ if( pInfo->mUseEquipment ) { eWEAPON_STATE weaponState = HERO->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) return false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) return false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) return false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) return false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) return false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) return false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) return false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) return false; break; case eEQUIPTYPE_CLOTH: if( HERO->GetArmorSets() != ARMOR_SETS_ROBES ) return false; break; case eEQUIPTYPE_LIGHTARMOR: if( HERO->GetArmorSets() != ARMOR_SETS_LIGHT ) return false; break; case eEQUIPTYPE_HEAVYARMOR: if( HERO->GetArmorSets() != ARMOR_SETS_HEAVY ) return false; break; } } /// »ç¿ë »óŰ¡ ¸Â´ÂÁö üũ if( pInfo->mUseState ) { switch( pInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // hp up { unsigned long hp = HERO->GetHP(); unsigned long maxHP = HERO->GetMaxHP(); if( maxHP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue > (hp * 100 / maxHP) ) return false; } break; case eSKILL_USE_STATE_HP_PER_DOWN: // hp down { unsigned long hp = HERO->GetHP(); unsigned long maxHP = HERO->GetMaxHP(); if( maxHP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue < (hp * 100 / maxHP) ) return false; } break; case eSKILL_USE_STATE_MP_PER_UP: // mp up { unsigned long mp = HERO->GetMP(); unsigned long maxMP = HERO->GetMaxMP(); if( maxMP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue > (mp * 100 / maxMP) ) return false; } break; case eSKILL_USE_STATE_MP_PER_DOWN: // mp down { unsigned long mp = HERO->GetMP(); unsigned long maxMP = HERO->GetMaxMP(); if( maxMP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue < (mp * 100 / maxMP) ) return false; } break; case eSKILL_USE_STATE_SELF_BUFF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) return false; } break; case eSKILL_USE_STATE_SELF_DEBUFF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) return false; } break; default: { assert(0); return false; } } } /// ¼Ò¸ð HP, MP üũ if( HERO->GetHP() < pStepInfo->mUseHP ) { return false; } unsigned long totalUseMP = HERO->CalcUseMPExt( pStepInfo->mUseMP ); if( HERO->GetMP() < totalUseMP ) { CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 6001 ) ); return false; } if( pStepInfo->mUseMPPer > 0 ) { unsigned long currentUseMP = HERO->GetOriMpMax(); currentUseMP = (unsigned long)((currentUseMP * pStepInfo->mUseMPPer) / 100); unsigned long totalUseMP = HERO->CalcUseMPExt( currentUseMP ); if( HERO->GetMP() < totalUseMP ) return false; } // if( pInfo->mBoundType == eBOUNDTYPE_FIELD ) // return true; return true; } bool cSkillExecuter::IsPossibleUseSkillTarget( unsigned long skillIdx, cBaseObject* pTarget ) { if( HERO->IsTransformMonster() ) return IsPossibleUseSkillTarget_TransMon( skillIdx, pTarget ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return false; } /// ½ºÅ³ »ç¿ë Á¶°Ç üũ if( IsPossibleApplyValueType( skillIdx, pTarget ) == false ) return false; /// Ÿ°ÙÀÌ ¾ø¾îµµ ¹ßµ¿ÇÏ´Â ½ºÅ³ /// 1. Ÿ°ÙÀÌ ÀÚ±â ÀÚ½ÅÀÎ °æ¿ì /// 2. Ÿ°ÙÀÌ ¾ø´Â ¹üÀ§ ½ºÅ³ÀÎ °æ¿ì /// ±× ¿Ü´Â ¸ðµÎ ¹ßµ¿ ºÒ°¡ if( pInfo->mApplyType != eAPPLYTYPE_SELF && pInfo->mApplyType != eAPPLYTYPE_BUFF_SELF && pInfo->mApplyType != eAPPLYTYPE_DEBUFF_SELF && pInfo->mBoundType != eBOUNDTYPE_SELF_NOTARGET ) { if( pTarget == 0 ) return false; if( pInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { if( pTarget->GetState() == eOBJECT_STATE_DIE ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { /// ÀûÀÎÁö ¾Æ±ºÀÎÁö ±¸ºÐ if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return false; return true; } } return false; } else { if( pTarget->GetState() == eOBJECT_STATE_DIE ) { return false; } } unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_HERO: { if( pInfo->mApplyType == eAPPLYTYPE_ENEMY || pInfo->mApplyType == eAPPLYTYPE_BUFF_ENEMY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_ENEMY ) return false; } break; case eOBJECTTYPE_MONSTER: { if( pInfo->mApplyType != eAPPLYTYPE_ENEMY && pInfo->mApplyType != eAPPLYTYPE_BUFF_ENEMY && pInfo->mApplyType != eAPPLYTYPE_DEBUFF_ENEMY ) return false; if( PVPMAN && PVPMAN->IsEnableBattle() ) { if( ((cMonster*)pTarget)->GetPvPTeamType() != ePVPDM_TEAMTYPE_MAX && ((cMonster*)pTarget)->GetPvPTeamType() == HERO->GetPVPTeam() ) return false; } } break; case eOBJECTTYPE_PLAYER: { if( pInfo->mApplyType == eAPPLYTYPE_PARTY || pInfo->mApplyType == eAPPLYTYPE_BUFF_PARTY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_PARTY ) { if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return false; if( PARTYMAN->IsHeroParty( pTarget->GetObjectID()) || PARTYUNIONMAN->IsHeroParty( pTarget->GetObjectID() )) return true; return false; } else if( pInfo->mApplyType == eAPPLYTYPE_BUDDY ) { /// Àû±ºÀ̳Ä? if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return false; } else if( pInfo->mApplyType == eAPPLYTYPE_ENEMY || pInfo->mApplyType == eAPPLYTYPE_BUFF_ENEMY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_ENEMY ) { if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return true; return false; } else if( pInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { if( PVPMAN->IsEnableBattle() ) return false; } } break; default: return false; } } return true; } bool cSkillExecuter::IsRushUseSkill( unsigned long skillIdx, unsigned char skillStep ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->IsTransformMonster() ) return false; if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL || HERO->GetState() == ePLAYER_STATE_RUSH ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; if( HERO->IsJumping() == true ) return false; sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return false; } if( pInfo->mStepCount <= skillStep ) { assert(0); return false; } sPlayerSkillStepInfo* pStepInfo = &pInfo->mpSetpInfoArray[skillStep]; /// ¼Ò¸ð ¾ÆÀÌÅÛ º¸À¯ ¿©ºÎ üũ if( pInfo->mUseItem ) { /// Àκ¥ üũ sItemCount* p = ITEMMAN->GetItemCount( pInfo->mUseItem ); unsigned int count = ( p ) ? p->bag : 0; if( count < pStepInfo->mUseItemCount ) return false; } if( TUTORIALMAN->IsTutorialMode() == false ) { if( HERO->GetLevel() < pStepInfo->mPlayerLevel ) return false; } /// ³» Àåºñ°¡ ¸Â´ÂÁö üũ if( pInfo->mUseEquipment ) { eWEAPON_STATE weaponState = HERO->GetWeaponState(); /// Âø¿ë Àåºñ üũ switch( pInfo->mUseEquipment ) { case eEQUIPTYPE_SWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) return false; break; case eEQUIPTYPE_LONGSWORD: if( weaponState != eWEAPON_STATE_LONGSWORD ) return false; break; case eEQUIPTYPE_DOUBLESWORD: if( weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SHORTSWORD: if( weaponState != eWEAPON_STATE_SHORTSWORD ) return false; break; case eEQUIPTYPE_GUN: if( weaponState != eWEAPON_STATE_GUN ) return false; break; case eEQUIPTYPE_STAFF: if( weaponState != eWEAPON_STATE_STAFF ) return false; break; case eEQUIPTYPE_SHIELD: if( weaponState != eWEAPON_STATE_SHEILD && weaponState != eWEAPON_STATE_SWORD_SHEILD ) return false; break; case eEQUIPTYPE_SWORD_LONGSWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD ) return false; break; case eEQUIPTYPE_SWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD: if( weaponState != eWEAPON_STATE_SWORD && weaponState != eWEAPON_STATE_SWORD_SHEILD && weaponState != eWEAPON_STATE_LONGSWORD && weaponState != eWEAPON_STATE_DOUBLESWORD ) return false; break; case eEQUIPTYPE_SHORTSWORD_GUN: if( weaponState != eWEAPON_STATE_SHORTSWORD && weaponState != eWEAPON_STATE_GUN ) return false; break; case eEQUIPTYPE_CLOTH: if( HERO->GetArmorSets() != ARMOR_SETS_ROBES ) return false; break; case eEQUIPTYPE_LIGHTARMOR: if( HERO->GetArmorSets() != ARMOR_SETS_LIGHT ) return false; break; case eEQUIPTYPE_HEAVYARMOR: if( HERO->GetArmorSets() != ARMOR_SETS_HEAVY ) return false; break; } } /// »ç¿ë »óŰ¡ ¸Â´ÂÁö üũ if( pInfo->mUseState ) { switch( pInfo->mUseState ) { case eSKILL_USE_STATE_HP_PER_UP: // hp up { unsigned long hp = HERO->GetHP(); unsigned long maxHP = HERO->GetMaxHP(); if( maxHP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue > (hp * 100 / maxHP) ) return false; } break; case eSKILL_USE_STATE_HP_PER_DOWN: // hp down { unsigned long hp = HERO->GetHP(); unsigned long maxHP = HERO->GetMaxHP(); if( maxHP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue < (hp * 100 / maxHP) ) return false; } break; case eSKILL_USE_STATE_MP_PER_UP: // mp up { unsigned long mp = HERO->GetMP(); unsigned long maxMP = HERO->GetMaxMP(); if( maxMP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue > (mp * 100 / maxMP) ) return false; } break; case eSKILL_USE_STATE_MP_PER_DOWN: // mp down { unsigned long mp = HERO->GetMP(); unsigned long maxMP = HERO->GetMaxMP(); if( maxMP == 0 ) { assert(0); return false; } if( pStepInfo->mUseStateValue < (mp * 100 / maxMP) ) return false; } break; case eSKILL_USE_STATE_SELF_BUFF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyBuffType( pStepInfo->mUseStateValue ) == false ) return false; } break; case eSKILL_USE_STATE_SELF_DEBUFF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ if( HERO->IsHaveApplyDeBuffType( pStepInfo->mUseStateValue ) == false ) return false; } break; default: { assert(0); return false; } } } /// ¼Ò¸ð HP, MP üũ if( HERO->GetHP() < pStepInfo->mUseHP ) { return false; } unsigned long totalUseMP = HERO->CalcUseMPExt( pStepInfo->mUseMP ); if( HERO->GetMP() < totalUseMP ) { CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 6001 ) ); return false; } if( pStepInfo->mUseMPPer > 0 ) { unsigned long currentUseMP = HERO->GetOriMpMax(); currentUseMP = (unsigned long)((currentUseMP * pStepInfo->mUseMPPer) / 100); unsigned long totalUseMP = HERO->CalcUseMPExt( currentUseMP ); if( HERO->GetMP() < totalUseMP ) return false; } // if( pInfo->mBoundType == eBOUNDTYPE_FIELD ) // return true; return true; } void cSkillExecuter::ChargeOn( unsigned long skillIdx, unsigned char skillstep ) { if( IsSkillCharge() ) { ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); return; } /// if( HERO->IsTransformMonster() ) { ChargeOn_TransMon( skillIdx ); return; } if( skillIdx < NORMAL_ATTACK_SKILL_MAX ) { unsigned int state = (unsigned int)HERO->GetWeaponState(); if( state > eWEAPON_STATE_MAX ) state -= eWEAPON_STATE_SHEILD; unsigned int flag = 0;//mAttackPattern.GetAttackFlag(); mChargeSkill.mSkillIdx = flag*10 + state + 1; mChargeSkill.mSkillStep = 0; } else { mChargeSkill.mSkillIdx = skillIdx; mChargeSkill.mSkillStep = skillstep; } sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( mChargeSkill.mSkillIdx ); assert(pInfo); if( SKILLMAN->IsUsedKeepSkill( skillIdx, skillstep ) == false ) { return; } /// error check if( pInfo->mStepCount <= skillstep ) { assert(0); return; } /// skill stepÀº ȹµæÇÑ´Ù. Ãß°¡ÇØ¾ß ÇÑ´Ù. float range = pInfo->mpSetpInfoArray[skillstep].mTargetDist; /// 080225 PKH ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® mChargeSkill.mSkillRange = HERO->CalcStatusSkillRange( range, pInfo->mRangeType, mChargeSkill.mSkillIdx < NORMAL_ATTACK_SKILL_MAX ); /// Äü½½·Ô ½ºÅ³¿¡ Â÷Áö ¼¼ÆÃ QUICKMAN->SetCharge( skillIdx, true ); CURSOR->SetCursor( eCURSOR_SKILL ); mChargeSkill.mChargeType = eCharge_Target; } void cSkillExecuter::ChargeOff( unsigned long skillIdx, unsigned char skillStep ) { /// if( HERO->IsTransformMonster() ) { ChargeOff_TransMon( skillIdx ); return; } if( mChargeSkill.mSkillIdx != skillIdx && mChargeSkill.mSkillStep != skillStep ) return; mChargeSkill.mChargeType = eCharge_None; mChargeSkill.mSkillIdx = 0; mChargeSkill.mSkillStep = 0; /// Äü½½·Ô ½ºÅ³¿¡ Â÷Áö ¼¼ÆÃ QUICKMAN->SetCharge( skillIdx, false ); CURSOR->SetCursor( eCURSOR_DEFAULT ); } bool cSkillExecuter::IsSkillCharge() { if( mChargeSkill.mChargeType == eCharge_None ) return false; if( HERO->IsTransformMonster() ) { if( mChargeSkill.mSkillIdx < eMONSTERATTACK_SKILL1 ) return false; } else { if( mChargeSkill.mSkillIdx < NORMAL_ATTACK_SKILL_MAX ) return false; } return true; } sChargeInfo cSkillExecuter::GetChargeSkill() { /// if( HERO->IsTransformMonster() ) return mChargeSkill; if( mChargeSkill.mSkillIdx < NORMAL_ATTACK_SKILL_MAX ) { unsigned int state = (unsigned int)HERO->GetWeaponState(); if( state > eWEAPON_STATE_MAX ) state -= eWEAPON_STATE_SHEILD; unsigned int flag = mAttackPattern.GetAttackFlag(); unsigned long skillIdx = flag*10 + state + 1; if( skillIdx != mChargeSkill.mSkillIdx ) { /// ¹«±â°¡ ±³Ã¼µÈ °æ¿ì´Â »çÁ¤°Å¸® Àç°è»ê mChargeSkill.mSkillIdx = skillIdx; mChargeSkill.mSkillStep = 0; sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( mChargeSkill.mSkillIdx ); assert(pInfo); if( pInfo->mStepCount == 0 ) { assert(0); } float range = pInfo->mpSetpInfoArray[0].mTargetDist; /// 080225 PKH ½ºÅ³+¾ÆÀÌÅÛ+È¿°ú »ç°Å¸® mChargeSkill.mSkillRange = HERO->CalcStatusSkillRange( range, pInfo->mRangeType, true ); } } return mChargeSkill; } /// unsigned long cSkillExecuter::GenerateTransMonsAttackIdx() { unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); /// monster skill unsigned long rd = ::rand() % mTotalMonsterAttackPer; sMonsterSkillScript* info = NULL; /// ±âº» °ø°ÝÁß¿¡ Á¶°ÇÀ» ¸¸Á·ÇÏ´Â °ÍÀ» ¸®ÅÏÇÑ´Ù. for( unsigned int i=0;iGetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)i ); if( info == 0 ) continue; unsigned long totalUseMP = HERO->CalcUseMPExt( info->mUseMP ); if( totalUseMP > HERO->GetMP() ) continue; sKeepSkill* keep = SKILLMAN->GetCoolTimeMon( i ); if( keep && keep->mRestTime != 0 && keep->mRestTime != ULONG_MAX ) { rd = 0; continue; } return i; } } /// ¾Æ¹«°Íµµ ¼±ÅõÇÁö ¾ÊÀº°æ¿ì ±âº»°ø°Ý1¿¡ ´ëÇÑ Ã¼Å©·Î º¸Á¤ info = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, eMONSTERATTACK_NORMAL1 ); if( info ) { unsigned long totalUseMP = HERO->CalcUseMPExt( info->mUseMP ); if( totalUseMP < HERO->GetMP() ) { sKeepSkill* keep = SKILLMAN->GetCoolTimeMon( eMONSTERATTACK_NORMAL1 ); if( keep && (keep->mRestTime == 0 || keep->mRestTime == ULONG_MAX) ) { return eMONSTERATTACK_NORMAL1; } } } return eMONSTERATTACK_MAX; } void cSkillExecuter::ChargeOn_TransMon( unsigned long skillIdx ) { if( skillIdx >= eMONSTERATTACK_MAX ) { assert(0); return; } mChargeSkill.mChargeType = eCharge_Target; mChargeSkill.mSkillIdx = skillIdx; mChargeSkill.mSkillRange = mMonsterAttackInfo[skillIdx].mRange; CURSOR->SetCursor( eCURSOR_SKILL ); QUICKMAN->SetMonCharge( skillIdx, true ); } void cSkillExecuter::ChargeOff_TransMon( unsigned long skillIdx ) { if( mChargeSkill.mChargeType == eCharge_None ) return; if( skillIdx >= eMONSTERATTACK_MAX ) { assert(0); return; } if( mChargeSkill.mSkillIdx != skillIdx ) return; mChargeSkill.mSkillIdx = 0; mChargeSkill.mSkillStep = 0; mChargeSkill.mChargeType = eCharge_None; CURSOR->SetCursor( eCURSOR_DEFAULT ); QUICKMAN->SetMonCharge( skillIdx, false ); } void cSkillExecuter::SetMonsterSkillInfo( unsigned long monsterClassIdx ) { mTotalMonsterAttackPer = 0; sMonsterSkillScript* info; for( unsigned int i=0;iGetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)i ); if( info == 0 ) continue; mMonsterAttackInfo[i].mUsePer = info->mSkillUsePer; mMonsterAttackInfo[i].mRange = info->mTargetDist; if( i < eMONSTERATTACK_SKILL1 ) mTotalMonsterAttackPer += mMonsterAttackInfo[i].mUsePer; } } bool cSkillExecuter::IsPossibleUseSkill_TransMon( unsigned long skillIdx ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); if( monsterClassIdx == 0 ) return false; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return false; /// TODO : º¸À¯ ½ºÅ³ÀÎÁö üũ ¹× ÄðŸÀÓ Ã¼Å© if( SKILLMAN->IsUsedMonsterSkill( skillIdx ) == false ) return false; /// ¼Ò¸ð MP üũ unsigned long totalUseMP = HERO->CalcUseMPExt( pInfo->mUseMP ); if( HERO->GetMP() < totalUseMP) { CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 6001 ) ); return false; } // if( pInfo->mBoundType == eBOUNDTYPE_FIELD ) // return true; return true; } bool cSkillExecuter::IsPossibleUseSkillTarget_TransMon( unsigned long skillIdx, cBaseObject* pTarget ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); if( monsterClassIdx == 0 ) return false; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return false; /// Ÿ°ÙÀÌ ¾ø¾îµµ ¹ßµ¿ÇÏ´Â ½ºÅ³ /// 1. Ÿ°ÙÀÌ ÀÚ±â ÀÚ½ÅÀÎ °æ¿ì /// 2. Ÿ°ÙÀÌ ¾ø´Â ¹üÀ§ ½ºÅ³ÀÎ °æ¿ì /// ±× ¿Ü´Â ¸ðµÎ ¹ßµ¿ ºÒ°¡ if( pInfo->mApplyType != eAPPLYTYPE_SELF && pInfo->mApplyType != eAPPLYTYPE_BUFF_SELF && pInfo->mApplyType != eAPPLYTYPE_DEBUFF_SELF && pInfo->mBoundType != eBOUNDTYPE_SELF_NOTARGET ) { if( pTarget == 0 ) return false; if( pInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { if( pTarget->GetState() == eOBJECT_STATE_DIE ) { if( pTarget->GetObjectType() == eOBJECTTYPE_PLAYER ) { /// ÀûÀÎÁö ¾Æ±ºÀÎÁö ±¸ºÐ if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) != true && PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) != true ) return false; return true; } } return false; } else { if( pTarget->GetState() == eOBJECT_STATE_DIE ) { return false; } } unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_HERO: { if( pInfo->mApplyType == eAPPLYTYPE_ENEMY || pInfo->mApplyType == eAPPLYTYPE_BUFF_ENEMY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_ENEMY ) return false; } break; case eOBJECTTYPE_MONSTER: { if( pInfo->mApplyType != eAPPLYTYPE_ENEMY && pInfo->mApplyType != eAPPLYTYPE_BUFF_ENEMY && pInfo->mApplyType != eAPPLYTYPE_DEBUFF_ENEMY ) return false; if( PVPMAN && PVPMAN->IsEnableBattle() ) { if( ((cMonster*)pTarget)->GetPvPTeamType() != ePVPDM_TEAMTYPE_MAX && ((cMonster*)pTarget)->GetPvPTeamType() == HERO->GetPVPTeam() ) return false; } } break; case eOBJECTTYPE_PLAYER: { if( pInfo->mApplyType == eAPPLYTYPE_PARTY || pInfo->mApplyType == eAPPLYTYPE_BUFF_PARTY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_PARTY ) { if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return false; if( PARTYMAN->IsHeroParty( pTarget->GetObjectID()) || PARTYUNIONMAN->IsHeroParty( pTarget->GetObjectID() ) ) return true; return false; } else if( pInfo->mApplyType == eAPPLYTYPE_BUDDY ) { /// Àû±ºÀ̳Ä? if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return false; } else if( pInfo->mApplyType == eAPPLYTYPE_ENEMY || pInfo->mApplyType == eAPPLYTYPE_BUFF_ENEMY || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_ENEMY ) { if( DUELMAN->IsDuelEnemy( (cPlayer*)pTarget ) || PVPMAN->IsEnableAttack( (cPlayer*)pTarget ) ) return true; return false; } else if( pInfo->mApplyType == eAPPLYTYPE_DIEBUDDY ) { if( PVPMAN->IsEnableBattle() ) return false; } } break; default: return false; } } return true; } bool cSkillExecuter::AutoAttack_TransMon( unsigned long skillIdx, cBaseObject* pTarget ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif /// ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsCantSkill( skillIdx ) == true ) return false; /// targetÀÇ »óÅ üũ.. unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_PLAYER: { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetState() == eOBJECT_STATE_DIE ) return false; /// ÀûÀÎÁö ¿©ºÎ ÆÇ´Ü if( DUELMAN->IsDuelEnemy( pPlayer ) != true && PVPMAN->IsEnableAttack( pPlayer ) != true ) return false; } break; case eOBJECTTYPE_MONSTER: { cMonster* pMon = (cMonster*)pTarget; if( pMon->GetState() == eOBJECT_STATE_DIE ) return false; if( PVPMAN && PVPMAN->IsEnableBattle() ) { if( ((cMonster*)pTarget)->GetPvPTeamType() != ePVPDM_TEAMTYPE_MAX && ((cMonster*)pTarget)->GetPvPTeamType() == HERO->GetPVPTeam() ) return false; } } break; default: return false; } /// ±âº» °ø°Ý À妽º »êÁ¤ - ¹«±â, °ø°Ý À妽º ChargeOn( skillIdx, 0 ); /// °ø°Ý °Å¸® üũ - ÈÄ󸮱â HERO->AfterAttack( pTarget ); return true; } bool cSkillExecuter::ExecuteAttack_TransMon( unsigned long skillIdx, cBaseObject* pTarget ) { #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->IsCantSkill( skillIdx ) == true ) return false; /// target window ¹× hero Ÿ°Ù ¼³Á¤ HERO->SetTargetObject( pTarget->GetObjectType(), pTarget->GetObjectID() ); sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_Attack && p->mTarget.index == pTarget->GetObjectID() ) return false; /// targetÀÇ »óÅ üũ.. unsigned char type = pTarget->GetObjectType(); switch( type ) { case eOBJECTTYPE_PLAYER: { cPlayer* pPlayer = (cPlayer*)pTarget; if( pPlayer->GetState() == eOBJECT_STATE_DIE ) return false; /// ÀûÀÎÁö ¿©ºÎ ÆÇ´Ü if( DUELMAN->IsDuelEnemy( pPlayer ) != true && PVPMAN->IsEnableAttack( pPlayer ) != true ) return false; } break; case eOBJECTTYPE_MONSTER: { cMonster* pMon = (cMonster*)pTarget; if( pMon->GetState() == eOBJECT_STATE_DIE ) return false; } break; default: return false; } /// ±âº» °ø°Ý À妽º »êÁ¤ - ¹«±â, °ø°Ý À妽º ChargeOn( skillIdx, 0 ); /// °ø°Ý °Å¸® üũ - ÈÄ󸮱â HERO->AfterAttack( pTarget ); ResetAttackFlag(); mAttackTarget.index = pTarget->GetObjectID(); mAttackTarget.type = pTarget->GetObjectType(); return true; } bool cSkillExecuter::ExecuteSkill_TransMon( unsigned long skillIdx, cBaseObject* pTarget ) { HERO->SetWaitMoveFlag( eWAITMOVE_NONE ); ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); if( monsterClassIdx == 0 ) return false; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return false; /// »ç¿ë °¡´É ¿©ºÎ üũ if( IsPossibleUseSkill( skillIdx, 0 ) == false ) return false; /// bool targetCheck = true; if( pTarget == 0 ) pTarget = HERO->GetTargetObject(); if( pInfo->mBoundType == eBOUNDTYPE_FIELD ) { /// field base skill FieldSkillOn_TransMon( monsterClassIdx, skillIdx ); return true; } else if( pInfo->mBoundType == eBOUNDTYPE_AUTOFIELD ) { return ExecuteAutoPos_TransMon( skillIdx ); } else if( pInfo->mBoundType == eBOUNDTYPE_SELF_NOTARGET ) { /// active targetCheck = false; } else if( pInfo->mBoundType == eBOUNDTYPE_NONE ) { if( pInfo->mApplyType == eAPPLYTYPE_SELF || pInfo->mApplyType == eAPPLYTYPE_BUFF_SELF || pInfo->mApplyType == eAPPLYTYPE_DEBUFF_SELF ) pTarget = HERO; targetCheck = true; } if( targetCheck ) { /// Àû¿ë Ÿ°ÙÀÌ ¾Æ´Ñ °æ¿ì charge if( IsPossibleUseSkillTarget( skillIdx, pTarget) == false ) { ChargeOn( skillIdx, 0 ); return false; } sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseTargetSkill && p->mExData1 == skillIdx && p->mTarget.index == pTarget->GetObjectID() ) return false; } /// ½ºÅ³ ¹ßµ¿ ChargeOn( skillIdx, 0 ); HERO->AfterUseSkill( pTarget ); if( pTarget ) mAttackTarget = *(pTarget->GetTargetInfo()); return true; } bool cSkillExecuter::ExecuteSkill_TransMon( unsigned long skillIdx, NiPoint3 applyPos ) { HERO->SetWaitMoveFlag( eWAITMOVE_NONE ); ChargeOff( mChargeSkill.mSkillIdx, mChargeSkill.mSkillStep ); #ifdef _GMTOOL if( CHEATMAN->GetHideMode() == true ) return false; #endif if( HERO->GetState() == eOBJECT_STATE_DIE ) return false; if( HERO->GetState() == eOBJECT_STATE_PUSHPULL ) return false; if( HERO->GetState() == eOBJECT_STATE_STOP ) { if( HERO->GetStopFlag() != eSTOP_NPCSPEECH ) return false; } /// ¼­¹ö·ÎºÎÅÍ ¹«±â±³Ã¼¿Ï·á ¸Þ¼¼Áö ¹Þ±âÀü±îÁö ½ºÅ³ »ç¿ë ºÒ°¡ if( HERO->IsWeaponChanging() == true ) return false; unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); if( monsterClassIdx == 0 ) return false; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return false; /// »ç¿ë °¡´É ¿©ºÎ üũ if( IsPossibleUseSkill( skillIdx, 0 ) == false ) return false; if( pInfo->mBoundType != eBOUNDTYPE_FIELD ) return false; sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseFieldSkill && p->mExData1 == skillIdx ) return false; ChargeOn( skillIdx, 0 ); HERO->AfterUseSkill( applyPos ); return true; } bool cSkillExecuter::ExecuteAutoPos_TransMon( unsigned long skillIdx ) { unsigned long monsterClassIdx = HERO->GetTransMonsterClassIdx(); if( monsterClassIdx == 0 ) return false; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return false; if( pInfo->mBoundType != eBOUNDTYPE_AUTOFIELD ) return false; mChargeSkill.mSkillRange = HERO->CalcStatusSkillRange( pInfo->mTargetDist, pInfo->mRangeType, skillIdx < eMONSTERATTACK_SKILL1 ); NiPoint3 heroPos = HERO->GetPos(); NiPoint3 applyPos = heroPos + HERO->GetDesireDir() * mChargeSkill.mSkillRange; /// ÁÂÇ¥°¡ À̵¿ ºÒ°¡ Áö¿ªÀ̸é Àç°è»ê unsigned long divideCnt = 10; float divideRange = mChargeSkill.mSkillRange / (float)divideCnt; cRangeCheck rangecheck( mChargeSkill.mSkillRange ); for( unsigned long i = 0; i <= divideCnt ; ++i ) { NiPoint3 divPos = heroPos + ( HERO->GetDesireDir() * ( mChargeSkill.mSkillRange - ( divideRange * i ) ) ); WORLDMAN->CalcHeight( &divPos.z, divPos.x, divPos.y ); if( rangecheck.IsRange( heroPos, divPos ) == true ) { applyPos = divPos; break; } } WORLDMAN->EnableRayGet( heroPos, applyPos ); WORLDMAN->CalcHeight( &applyPos.z, applyPos.x, applyPos.y ); sAfterAction* p = HERO->GetCurrentAfterAction(); if( p->mActionType == eAfterAction_UseFieldSkill && p->mExData1 == skillIdx ) return false; ChargeOn( skillIdx, 0 ); HERO->AfterUseSkill( applyPos ); return true; } void cSkillExecuter::FieldSkillOn( unsigned long skillIdx, unsigned char skillStep ) { if( HERO->IsTransformMonster() == true ) return; if( IsPossibleUseSkill( skillIdx, skillStep ) == false ) return; sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return; } if( SKILLMAN->IsUsedKeepSkill( skillIdx, skillStep ) == false ) return; if( pInfo->mStepCount <= skillStep ) { assert(0); return; } sPlayerSkillStepInfo* pStepInfo = &pInfo->mpSetpInfoArray[skillStep]; if( pInfo->mType == eSKILLTYPE_TOTEM ) { sTotemScript* totemInfo = TOTEMSCRIPT->GetTotemInfo( pStepInfo->mInfulenceIdx ); if( totemInfo == 0 ) { assert(0); HERO->SetFieldEffRadius( (float)pStepInfo->mBoundDist1 ); } else { HERO->SetFieldEffRadius( (float)totemInfo->mApplyRange1 ); } } else HERO->SetFieldEffRadius( (float)pStepInfo->mBoundDist1 ); ChargeOn( skillIdx, skillStep ); mChargeSkill.mChargeType = eCharge_Field; ::SetCursor(NULL); } void cSkillExecuter::FieldSkillOn_TransMon( unsigned long monsterClassIdx, unsigned long skillIdx ) { if( HERO->IsTransformMonster() == false ) return; if( IsPossibleUseSkill( skillIdx, 0 ) == false ) return; sMonsterSkillScript* pInfo = SKILLSCRIPT->GetMonsterSkillInfo( monsterClassIdx, (eMONSTERATTACK_TYPE)skillIdx ); if( pInfo == 0 ) return; HERO->SetFieldEffRadius( (float)pInfo->mBoundDist1 ); ChargeOn( skillIdx, 0 ); mChargeSkill.mChargeType = eCharge_Field; } bool cSkillExecuter::IsPossibleApplyValueType( unsigned long skillIdx, cBaseObject* pTarget ) { sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx ); if( pInfo == 0 ) { assert(0); return false; } /// ƯÁ¤ È¿°ú°¡ °É·ÁÀÖ´Â ´ë»óÀ¸·Î ½ºÅ³À» »ç¿ëÇß´ÂÁö üũ if( pInfo->mApplyValueType != eSTATUSPLUS_NONE ) { switch( pInfo->mApplyType ) { case eAPPLYTYPE_BUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return HERO->IsHaveApplyBuffType( pInfo->mApplyValueType ); } break; case eAPPLYTYPE_DEBUFF_SELF: { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return HERO->IsHaveApplyDeBuffType( pInfo->mApplyValueType ); } break; case eAPPLYTYPE_BUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return pTarget->IsHaveApplyBuffType( pInfo->mApplyValueType ); } else return false; } break; case eAPPLYTYPE_DEBUFF_ENEMY: { /// Ÿ°Ù Á¶°Ç üũ if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return pTarget->IsHaveApplyDeBuffType( pInfo->mApplyValueType ); } else return false; } break; case eAPPLYTYPE_BUFF_PARTY: { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return pTarget->IsHaveApplyBuffType( pInfo->mApplyValueType ); } else return false; } break; case eAPPLYTYPE_DEBUFF_PARTY: { if( pTarget ) { /// º¸À¯ÁßÀÎ È¿°ú¿¡¼­ ÇØ´ç È¿°ú°¡ ÀÖ´ÂÁö üũ return pTarget->IsHaveApplyDeBuffType( pInfo->mApplyValueType ); } else return false; } break; default: assert(0); return false; }//end switch( pSkillInfo->mApplyType ) } return true; }