#include "SunClientPrecompiledHeader.h" #include "SkillEffectFunc.h" #include "GlobalFunc.h" #include "SkillInfoParser.h" #include "SkillEffectInfoParser.h" #include "Character.h" #include "Player.h" #include "ProjectileManagerEx.h" #include "InterfaceManager.h" #include "Camera.h" #include #ifdef _NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL #include "State/StateBase.h" #include "State/SkillStateHpSuction.h" #include "State/SkillState.h" #endif //_NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL namespace SkillEffectFunc { HANDLE AddSkillEffectEfftct( Character* pTarget, WzID EffectID ) { HANDLE hHandle = GlobalFunc::CreateEffectBeUpToOption( EffectID, pTarget->GetVisiblePos(), pTarget->GetScale(), pTarget->GetObjectKey());//!loop ÀÌÆåÆ® ¾²Áö ¸»°Í if( CEffectBody* pBody = g_pEffectManager->GetEffectPtrHandle(hHandle) ) { // ¹ß»çü¿Í´Â ´Ù¸£°Ô ij¸¯ÅÍÀÇ °¢µµ¿Í ½ºÄÉÀϵîÀ» Á÷Á¢ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù WzVector vRot; vRot.y = 0.0f; vRot.z = pTarget->GetAngle(); vRot.x = pTarget->GetAngleX(); WzVector vScale; vScale.x = 1.0f; vScale.y = 1.0f; vScale.z = 1.0f; pBody->SetResultMatrix( pTarget->GetVisiblePos(), vRot, vScale); } return hHandle; } DWORD AddSkillEffectProjectile( Character* pTarget, WzID EffectID ) { cTargetPosition Position; Position.SetTargetVisiblePosition( pTarget->GetObjectKey(), TRUE ); cProjectileBase* pProjectile = g_ProjectileManagerEx.CreateEffect( pTarget->GetObjectKey(), EffectID, 10000, Position ); return pProjectile->GetKey(); } void AddCameraVibration( Character* pCharacter, float fTime, Camera::VIBE_TYPE VibeType /*= VIBE_TYPE_ALL*/, float fPower /*= 0.05f */) { if ( pCharacter == (Character *)g_pHero) { g_Camera.SetVibeType( VibeType ); g_Camera.StartVibration( fTime, fPower ); } } //------------------------------------------------------------------------------ /** ½ºÅ³ »ç¿ë °á°ú ÀÌÆåÆ®¸¦ Ãâ·Â ÇÑ´Ù.ÁÖ·Î ¹öÇÁ °è¿­ */ DWORD AddSkillEffectProjectile( Character* pTarget, EffectInfo* pEffectInfo, BOOL bSyncAngle ) { if( pEffectInfo->m_wzidEffectCode.id == StrToWzID("NULL") ) return 0; cTargetPosition Position; Position.SetTargetBonePosition( pTarget->GetObjectKey(), pEffectInfo->m_dwPositionType, pEffectInfo->m_wBoneIndex, pEffectInfo->m_bChase ); Position.SetSyncTargetAngle( bSyncAngle ); cProjectileBase* pProjectile = g_ProjectileManagerEx.CreateEffect( pTarget->GetObjectKey(), pEffectInfo->m_wzidEffectCode.id, pEffectInfo->m_dwLifeTime, Position ); return pProjectile->GetKey(); } DWORD CreateDirtyStartSkillEffect( DWORD dwSkillClassCode, Character* pCharacter ) { // ½ºÅ³ ½ÃÀ۽à ī¸Þ¶ó Èçµå´Â °Íµé switch( dwSkillClassCode ) { case eSKILL_WILD_SPIRITS: case eSKILL_VITAL_AMPLYFY: case eSKILL_SPIRIT_RECHARGE: case kSkillSPRecovery: case eSKILL_TAUNT: case eSKILL_THORNS_SKIN: AddCameraVibration( pCharacter, 100 ); break; case eSKILL_DARK_FORCE: AddCameraVibration( pCharacter, 30 ); break; } // ÀÌÆåÆ® switch (dwSkillClassCode) { case eSKILL_DEADLY_STRIKE: AddSkillEffectEfftct( pCharacter, StrToWzID("H005") ); break; case eSKILL_DEATH_DIVIDE: AddSkillEffectEfftct( pCharacter, StrToWzID("H510") ); break; case eSKILL_SWORDDANCING: AddSkillEffectEfftct( pCharacter, StrToWzID("H500") ); break; case eSKILL_ARCANE_BLADE: AddSkillEffectEfftct( pCharacter, StrToWzID("H340") ); break; case eSKILL_THORNS_SKIN: AddSkillEffectEfftct( pCharacter, StrToWzID("A012") ); AddSkillEffectEfftct( pCharacter, StrToWzID("H006") ); break; } // ÀÌÆåÆ® (¹ß»çü) switch (dwSkillClassCode) { case eSKILL_SACRED_FIRE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k600") ); case eSKILL_ACCRUCY_SPIRIT: return AddSkillEffectProjectile( pCharacter, StrToWzID("k560") ); case eSKILL_MAGIC_FORCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k570") ); case eSKILL_NATURAL_ATTACK: return AddSkillEffectProjectile( pCharacter, StrToWzID("k550") ); case eSKILL_MIGHT_POWER: return AddSkillEffectProjectile( pCharacter, StrToWzID("k490") ); case eSKILL_MANA_RECOVERY: return AddSkillEffectProjectile( pCharacter, StrToWzID("k580") ); case eSKILL_FOCUS: return AddSkillEffectProjectile( pCharacter, StrToWzID("k530") ); case eSKILL_ESSENSE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k510") ); case eSKILL_THORNS_SKIN: return AddSkillEffectProjectile( pCharacter, StrToWzID("I440") ); case kSkillSPRecovery: return AddSkillEffectProjectile( pCharacter, StrToWzID("I490") ); case eSKILL_RAPID_ATTACK: return AddSkillEffectProjectile( pCharacter, StrToWzID("H560") ); case eSKILL_ICE_FORCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k540") ); case eSKILL_BLAZE_FORCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k520") ); case eSKILL_MANA_REACHARGE: return AddSkillEffectProjectile( pCharacter, StrToWzID("k500") ); case eSKILL_MIGHTY_SPIRIT: return AddSkillEffectProjectile( pCharacter, StrToWzID("k480") ); case eSKILL_MARK_OF_SPIRIT_POWER: return AddSkillEffectProjectile( pCharacter, StrToWzID("H430") ); case eSKILL_MARK_OF_FACTION: return AddSkillEffectProjectile( pCharacter, StrToWzID("J520") ); case eSKILL_MARK_OF_SYMPHONY: return AddSkillEffectProjectile( pCharacter, StrToWzID("J530") ); case eSKILL_UNLIMIT_FORCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("H580") ); case eSKILL_MARK_OF_RECOVERY: return AddSkillEffectProjectile( pCharacter, StrToWzID("J510") ); case eSKILL_MARK_OF_CHANCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("H550") ); case eSKILL_DEVINE_FORCE: return AddSkillEffectProjectile( pCharacter, StrToWzID("H540") ); case eSKILL_BERSERK_MODE: return AddSkillEffectProjectile( pCharacter, StrToWzID("I510") ); case eSKILL_DAMAGE_RECOVERY: return AddSkillEffectProjectile( pCharacter, StrToWzID("I470") ); // case eSKILL_WILD_SPIRITS: return AddSkillEffectProjectile( pCharacter, StrToWzID("I390") ); case eSKILL_VITAL_AMPLYFY: return AddSkillEffectProjectile( pCharacter, StrToWzID("I480") ); case eSKILL_SPECTUAL_GUARD: return AddSkillEffectProjectile( pCharacter, StrToWzID("I350") ); } return 0; } DWORD CreateDirtyReceiverSkillEffect(DWORD dwSkillClassCode, Character *pTarget ) { //ÆÐŶÀ» ¹Þ¾Æ ¹ß»çü¸¦ »ý¼ºÇÏ´Â °Íµé switch(dwSkillClassCode) { case eSKILL_TAUNT: return AddSkillEffectProjectile( pTarget, StrToWzID("I461") ); case eSKILL_WILD_SPIRITS: return AddSkillEffectProjectile( pTarget, StrToWzID("I391") ); case eSKILL_THORNS_SKIN: return AddSkillEffectProjectile( pTarget, StrToWzID("I441") ); case eSKILL_BERSERK_MODE: return AddSkillEffectProjectile( pTarget, StrToWzID("I511") ); case eSKILL_DEVINE_FORCE: return AddSkillEffectProjectile( pTarget, StrToWzID("H541") ); case eSKILL_MARK_OF_CHANCE: return AddSkillEffectProjectile( pTarget, StrToWzID("H551") ); case eSKILL_FEAR: return AddSkillEffectProjectile( pTarget, StrToWzID("H571") ); case eSKILL_MARK_OF_RECOVERY : return AddSkillEffectProjectile( pTarget, StrToWzID("H581") ); case eSKILL_MARK_OF_SPIRIT_POWER: return AddSkillEffectProjectile( pTarget, StrToWzID("H431") ); case eSKILL_UNLIMIT_FORCE: return AddSkillEffectProjectile( pTarget, StrToWzID("J511") ); case eSKILL_MARK_OF_FACTION: return AddSkillEffectProjectile( pTarget, StrToWzID("J521") ); case eSKILL_MARK_OF_SYMPHONY: return AddSkillEffectProjectile( pTarget, StrToWzID("J531") ); case eSKILL_PATIENCE: return AddSkillEffectProjectile( pTarget, StrToWzID("J541") ); //case eSKILL_BATTLE_BARRIOR: return AddSkillEffectProjectile( pTarget, StrToWzID("J551") ); case eSKILL_RESSURECTION: return AddSkillEffectProjectile( pTarget, StrToWzID("J561") ); case eSKILL_MIGHTY_SPIRIT: return AddSkillEffectProjectile( pTarget, StrToWzID("k481") ); case eSKILL_MIGHT_POWER: return AddSkillEffectProjectile( pTarget, StrToWzID("k491") ); case eSKILL_BLAZE_FORCE: return AddSkillEffectProjectile( pTarget, StrToWzID("k521") ); case eSKILL_FOCUS: return AddSkillEffectProjectile( pTarget, StrToWzID("k531") ); case eSKILL_ICE_FORCE: return AddSkillEffectProjectile( pTarget, StrToWzID("k541") ); case eSKILL_NATURAL_ATTACK: return AddSkillEffectProjectile( pTarget, StrToWzID("k551") ); case eSKILL_ACCRUCY_SPIRIT: return AddSkillEffectProjectile( pTarget, StrToWzID("k561") ); case eSKILL_MAGIC_FORCE: return AddSkillEffectProjectile( pTarget, StrToWzID("k571") ); case eSKILL_MANA_RECOVERY: return AddSkillEffectProjectile( pTarget, StrToWzID("k581") ); case eSKILL_INCRESE_SPEED: return AddSkillEffectProjectile( pTarget, StrToWzID("k591") ); } return 0; } //------------------------------------------------------------------------------ /** ½ºÅ³ »ç¿ë °á°ú ÀÌÆåÆ®¸¦ Ãâ·Â ÇÑ´Ù.ÁÖ·Î ¹öÇÁ °è¿­ */ void CreateReceiverSkillEffect(DWORD dwSkillCode, int TargetIndex, Character* pTarget, Character* pCharacter) { if( pTarget && pCharacter ) { if ( SkillScriptInfo *pInfo = SkillInfoParser::Instance()->GetSkillInfo((SLOTCODE)dwSkillCode) ) { // ¹èƲ¹è¸®¾îÀΰæ¿ì¿¡´Â ÆÄƼ¸¸ if( pInfo->m_SkillClassCode == eSKILL_BATTLE_BARRIOR ) { if( pTarget->IsPartyMember() == TRUE ) { SkillEffectFunc::CreateSkillEventEffect( pInfo->m_SkillClassCode, pTarget, cSkillEventEffectInfoData::EVENT_TYPE_BUFF ); } } else { SkillEffectFunc::CreateSkillEventEffect( pInfo->m_SkillClassCode, pTarget, cSkillEventEffectInfoData::EVENT_TYPE_BUFF ); } if( pInfo->m_SkillClassCode == eSKILL_MYSTIC_916 ) // ¹Ì½ºÆ½´í½º { DWORD ActiveDealy = 150 * TargetIndex; if( TargetIndex >= 5 ) { ActiveDealy = 150 * (rand()%5); } WzVector TargetPosition = pTarget->GetVisiblePos(); WzVector Direction = TargetPosition - pCharacter->GetVisiblePos(); VectorNormalize(&Direction, &Direction ); static DWORD s_life_time = 1300; static DWORD s_delay_time = 200; static float s_length = 1.2f; static size_t s_max_clone = 1; static DWORD s_color = 0xEEEEEEEE; // argb static ENUM_ALPHABLEND s_blend = AB_LIGHTING; std::vector animation_array_array; animation_array_array.push_back( StrToWzID("S419") ); animation_array_array.push_back( StrToWzID("S420") ); animation_array_array.push_back( StrToWzID("S421") ); animation_array_array.push_back( StrToWzID("S422") ); animation_array_array.push_back( StrToWzID("S423") ); std::random_shuffle( animation_array_array.begin(), animation_array_array.end() ); for( size_t i=0;i!=animation_array_array.size();++i) { WzVector NewDirection = Direction; Math_ZRotateVector( &Direction, NewDirection, rand() % 360 ); WzVector NewPosition = TargetPosition - NewDirection * s_length; { cProjectileClone* pProjectile = new cProjectileClone(); //pProjectile->SetTargetObjectKey( pCharacter->GetObjectKey(), TRUE ); pProjectile->SetCloneColor( s_color ); pProjectile->SetCloneBlendType( s_blend ); pProjectile->SetClonePosition( NewPosition ); pProjectile->SetCloneDirection( NewDirection ); pProjectile->SetActiveDelayTime( i*s_delay_time + ActiveDealy ); pProjectile->CreateClone( pCharacter->GetObjectKey(), animation_array_array.at(i) ); pProjectile->SetLifeTime( s_life_time ); //pProjectile->SetCloneFadeOut(TRUE); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } { static DWORD s_ActiveDelay = 100; cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetLifeTime( 1000 ); pProjectile->SetTargetPosition( pTarget->GetArrowTargetPos() ); pProjectile->CreateEffect( StrToWzID("KB21"), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); pProjectile->SetActiveDelayTime( s_ActiveDelay + ActiveDealy ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } { static DWORD s_ActiveDelay = 1200; cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetLifeTime( 1000 ); pProjectile->SetTargetPosition( NewPosition ); pProjectile->CreateEffect( StrToWzID("KB20"), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); pProjectile->SetActiveDelayTime( s_ActiveDelay + ActiveDealy ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } if( i +1 >= s_max_clone ) break; } } //// ½ºÅ©¸³Æ®¸¦ ÅëÇÑ ÀÌÆåÆ® //if ( SkillEffectInfo *pEffectInfo = SkillEffectInfoParser::Instance()->GetSkillEffectInfo(pInfo->m_SkillClassCode) ) //{ // AddSkillEffectProjectile( pTarget, &pEffectInfo->m_EffectInfo[eEffect_Type_Buff], TRUE ); //} // ÀÌÆåÆ® CreateDirtyReceiverSkillEffect( pInfo->m_SkillClassCode, pTarget ); // ±×¿Ü switch(pInfo->m_SkillClassCode)//½ºÅ©¸³Æ®·Î ¾ÈµÇ´Â ¿¬Ãâ ÀûÀÎ °Íµé { case eSKILL_SACRED_FIRE: for(int i=0;i<8;i++) { WzVector vDirection; vDirection.x = (float)sin(WZ_PI/4.0f*(float)i); vDirection.y = (float)-cos(WZ_PI/4.0f*(float)i); vDirection.z=0.0f; WzVector StartPosition; WzVector TargetPosition; StartPosition = pTarget->GetVisiblePos(); StartPosition.z += 10.0f; StartPosition += vDirection * 1.5f; TargetPosition = pTarget->GetVisiblePos(); TargetPosition += vDirection * 1.5f; { cProjectileUnit* pProjectile = new cProjectileUnit(); pProjectile->SetArrowStartPosition( StartPosition ); pProjectile->SetArrowTargetPosition( TargetPosition ); pProjectile->SetLifeTime( 500 ); pProjectile->SetRemainTime( 100 ); pProjectile->CreateEffect( StrToWzID("k601"), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); pProjectile->SetHitData( pCharacter->GetObjectKey(), pCharacter->GetCurrentAttackSerial(), 0, FALSE, 0, FALSE ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } { TargetPosition = pTarget->GetVisiblePos(); TargetPosition += vDirection * 1.5f; TargetPosition.z += 0.5f; cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( TargetPosition ); pProjectile->SetLifeTime(2000); pProjectile->SetActiveDelayTime( 600 ); pProjectile->CreateEffect( StrToWzID("k602"), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } } break; case eSKILL_BATTLE_BARRIOR: { if (pTarget) { EffectInfo effectInfo; if (pTarget->GetObjectType() == PLAYER_OBJECT) { effectInfo.m_wzidEffectCode.id = StrToWzID("J551"); effectInfo.m_bChase = 1; effectInfo.m_dwLifeTime = 1000; effectInfo.m_dwPositionType = eSKILLEFFECT_POS_HEAD; effectInfo.m_wBoneIndex = 0; effectInfo.m_bRot = 0; } else if (pTarget == pCharacter) { //¼úÀÚÀڽŠeffectInfo.m_wzidEffectCode.id = StrToWzID("J550"); effectInfo.m_bChase = 1; effectInfo.m_dwLifeTime = 1000; effectInfo.m_dwPositionType = eSKILLEFFECT_POS_FOOT; effectInfo.m_wBoneIndex = 0; effectInfo.m_bRot = 0; } AddSkillEffectProjectile(pTarget, &effectInfo, TRUE); } } break; case eSKILL_SONY_VINE: { BASE_ABILITYINFO * pAbility =pInfo->GetAbilityInfo( eABILITY_STUN_STATUS ); assert(pAbility); if(pAbility) { WzVector Rotate = c_ZeroVector; Rotate.z = (float)(rand() % 628) / 100.f; cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( pTarget->GetVisiblePos() ); pProjectile->SetUnitCode( eProjectile_SRC_THORN2 ); pProjectile->SetUnitRotate( Rotate ); pProjectile->SetUnitAnimation( StrToWzID("N001"), FALSE ); pProjectile->SetUnitFadeOut( TRUE ); pProjectile->SetLifeTime( pAbility->m_iParam[2] ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); float inc=rand()%50+50.0f; if(rand()%2==1) { inc*=-1.0f; } inc/=100.0f; if(rand()%5>=2)//º¸¿©Áö´Â °Í srandÇØ¾ß ÇÒ±î? { WzVector Rotate = c_ZeroVector; Rotate.z = (float)(rand() % 628) / 100.f; WzVector TargetPosition = pTarget->GetVisiblePos(); TargetPosition.x += inc; TargetPosition.y += inc; cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( TargetPosition ); pProjectile->SetUnitCode( eProjectile_SRC_THORN ); pProjectile->SetUnitRotate( Rotate ); pProjectile->SetUnitAnimation( StrToWzID("N001"), FALSE ); pProjectile->SetUnitFadeOut( TRUE ); pProjectile->SetLifeTime( pAbility->m_iParam[2] ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } } } break; case eSKILL_BEAST_MASTER_DEADLY_STRIKE: { //Ç÷¹À̾°Ô º¼À» ½ð´Ù. º¸¿©Áö´Â°Í À̿ܿ¡ È¿°ú ¾øÀ½ WzVector StartPosition =pCharacter->GetVisiblePos(); StartPosition += pCharacter->GetDirection(); StartPosition.z += 4.0f; cProjectileUnit* pProjectile = new cProjectileUnit(); pProjectile->SetArrowStartPosition( StartPosition ); pProjectile->SetArrowTargetObjectKey( pTarget->GetObjectKey(), TRUE ); pProjectile->SetLifeTime( 1000 ); pProjectile->SetActiveDelayTime( 3200 ); pProjectile->CreateEffect( StrToWzID("E020"), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } break; #ifdef _NA_007113_20140324_SHADOW_HPSUCTION_RENEWAL case eSKILL_HP_SUCTION: { // ¸ÂÀº ´ë»ó¿¡¼­ ¿À³Ê Ç÷¹À̾°Ô·Î »¡¾ÆµéÀÌ´Â ÀÌÆåÆ® if ((pCharacter->GetCurState() == STATE::SKILL) && (pCharacter->GetCurSkillState()->GetSkillClassCode() == eSKILL_HP_SUCTION)) { SkillStateHpSuction* skill_state = (SkillStateHpSuction*)pCharacter->GetCurSkillState(); skill_state->AddHpSuctionProjectile(pCharacter, pTarget); } } break; #endif //_NA_007113_20140324_SHADOW_HPSUCTION_RENEWAL } } } } BOOL IsEnableWeapon( Character* pCharacter, SkillEffectInfo* pSkillEffectInfo ) { // ÀÌÆåÆ® ½ºÅ©¸³Æ®¿¡ ÁöÁ¤µÈ ¹«±â¿Í ´Ù¸¥ °æ¿ì¿¡ ÆÐ½º if( pCharacter->IsKindOfObject(PLAYER_OBJECT) ) { Player* pPlayer = (Player*)pCharacter; if( pSkillEffectInfo->m_byWeaponType != 0 && pPlayer->GetWeaponKind() != pSkillEffectInfo->m_byWeaponType ) { return FALSE; } } return TRUE; } DWORD CreateStartSkillEffect(DWORD dwSkillClassCode, Character* pCharacter ) { SkillEffectFunc::CreateSkillEventEffect( dwSkillClassCode, pCharacter, cSkillEventEffectInfoData::EVENT_TYPE_START ); return CreateDirtyStartSkillEffect( dwSkillClassCode, pCharacter ); //// ÀÌÆåÆ®°¡ ½ºÅ©¸³Æ®¿¡ ÀÖ´Â °æ¿ì //if( SkillEffectInfo* pSkillEffectInfo = SkillEffectInfoParser::Instance()->GetSkillEffectInfo( (SLOTCODE)dwSkillClassCode ) ) //{ // if( IsEnableWeapon( pCharacter, pSkillEffectInfo ) == FALSE ) // return 0; // return AddSkillEffectProjectile( pCharacter, &pSkillEffectInfo->m_EffectInfo[eEffect_Type_Start], TRUE ); //} //else //ÀÌÆåÆ® ½ºÅ©¸³Æ®°¡ ¾øÀ»¶© Çϵå ÄÚµù µÈ ÀÌÆåÆ® ½ÇÇà //{ // return CreateDirtyStartSkillEffect( dwSkillClassCode, pCharacter ); //} //return 0; } HANDLE CreateCastingSkillEffect(DWORD dwSkillClassCode, Character* pCharacter ) { WzID EffectID = INVALID_WZID; switch(dwSkillClassCode) { case eSKILL_FIRE_FILA: EffectID=StrToWzID("C011"); break; case eSKILL_FIRE_SPEAR: EffectID=StrToWzID("C021"); break; case eSKILL_PRESSING_WALL: EffectID=StrToWzID("C010"); break; case eSKILL_LIGHTING_WAVE: EffectID=StrToWzID("C013"); break; case eSKILL_SONY_VINE: EffectID=StrToWzID("C024"); break; case eSKILL_POISON_RAIN: EffectID=StrToWzID("C014"); break; case eSKILL_MAGIC_SHIELD: EffectID=StrToWzID("C024"); break; case eSKILL_REVIVAL: EffectID=StrToWzID("C024"); break; case eSKILL_REVERSE: EffectID=StrToWzID("C024"); break; } if( EffectID == INVALID_WZID ) return INVALID_HANDLE_VALUE; WzVector pos = pCharacter->GetVisiblePos(); pos.z += 0.25f; return GlobalFunc::CreateEffectBeUpToOption( EffectID, pos, pCharacter->GetScale(), pCharacter->GetObjectKey() ); } HANDLE CreateCastingSkillBottomEffect( DWORD dwSkillClassCode, Character* pCharacter ) { WzID EffectID = INVALID_WZID; switch(dwSkillClassCode) { case eSKILL_FIRE_ARROW: EffectID=StrToWzID("D008"); break; case eSKILL_FIRE_BALL: EffectID=StrToWzID("D008"); break; case eSKILL_FIRE_FILA: EffectID=StrToWzID("D008"); break; case eSKILL_FIRE_SPEAR: EffectID=StrToWzID("D008"); break; case eSKILL_ICE_DAGGER: EffectID=StrToWzID("D007"); break; case eSKILL_ICE_DAGGER2: EffectID=StrToWzID("D007"); break; case eSKILL_ICE_BLAST: EffectID=StrToWzID("D007"); break; case eSKILL_ICE_BOLT: EffectID=StrToWzID("D007"); break; case eSKILL_PRESSING_WALL: EffectID=StrToWzID("D007"); break; case eSKILL_FROZON_SHIELD: EffectID=StrToWzID("D007"); break; case eSKILL_WIND_BOLT: EffectID=StrToWzID("D010"); break; case eSKILL_LIGHTING: EffectID=StrToWzID("D010"); break; case eSKILL_ELECTRIC_FIELD: EffectID=StrToWzID("D010"); break; case eSKILL_WIND_SHIELD: EffectID=StrToWzID("D010"); break; case eSKILL_LIGHTING_WAVE: EffectID=StrToWzID("D010"); break; case eSKILL_POISON_THORN: EffectID=StrToWzID("D011"); break; case eSKILL_SONY_VINE: EffectID=StrToWzID("D011"); break; case eSKILL_POISON_RAIN: EffectID=StrToWzID("D011"); break; case eSKILL_POWER_WAVE: EffectID=StrToWzID("D011"); break; case eSKILL_MAGIC_SHIELD: EffectID=StrToWzID("D011"); break; } if( EffectID == INVALID_WZID ) return INVALID_HANDLE_VALUE; return GlobalFunc::CreateEffectBeUpToOption( EffectID, pCharacter->GetPosition(), pCharacter->GetScale(), pCharacter->GetObjectKey() ); } void CreateHandEffect( Object* pOwner, DWORD dwId, WzID effectID, const WzVector& vPos ) { WzVector vTarget = pOwner->GetVisiblePos() + pOwner->GetDirection()*2.0f; vTarget.z = vPos.z; //¼Õ¾Õ¿¡ ÅÍÁö±â HANDLE handle; Character* pCharacter = (Character*)pOwner; handle = GlobalFunc::CreateEffectBeUpToOption(effectID,vPos,pCharacter->GetScale(),dwId); WzVector vDest,vTemp; float fArrowAngleZ,fArrowAngleX; vDest = vTarget - vPos; vTemp = vDest; vTemp.z = 0.0f; float fLength; if (vTemp.x == 0.0f && vTemp.y == 0.0f) { fLength = 0.0f; } else { fLength = VectorLength(&vTemp); } fArrowAngleX = -atan2(vDest.z,fLength); fArrowAngleZ = Math_GetAngleFromVector(&vDest); CEffectBody *pBody = g_pEffectManager->GetEffectPtrHandle(handle); if(pBody) { WzVector vRot; vRot.x = fArrowAngleX; vRot.y = 0.0f; vRot.z = fArrowAngleZ; WzVector vScale; vScale.x = 1.0f; vScale.y = 1.0f; vScale.z = 1.0f; pBody->SetResultMatrix(vPos,vRot,vScale); } } void _CalcDirectionRotate( const WzVector& StartPosition, const WzVector& TargetPosition, OUT WzVector& Rotate ) { WzVector vDest = TargetPosition - StartPosition; float fLength; if ( vDest.x == 0.0f && vDest.y == 0.0f ) { fLength = 0.0f; } else { WzVector vTemp = vDest; vTemp.z = 0.0f; fLength = VectorLength(&vTemp); } float fArrowAngleX = -atan2(vDest.z,fLength); float fArrowAngleZ = Math_GetAngleFromVector(&vDest); Rotate.x = fArrowAngleX; Rotate.y = 0.0f; Rotate.z = fArrowAngleZ; } void CreateCameraViberation( const cSkillEventEffectInfoData* data, const WzVector& Position ) { cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( Position ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->SetHitData( 0, 0, 0, TRUE, 1, FALSE ); pProjectile->SetCameraShakeType( data->GetCameraViberationType(), data->GetCameraViberationTime(), data->GetCameraViberationPower() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } void CreateFieldEffect( const cSkillEventEffectInfoData* data, const WzVector& Position ) { cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( Position ); //pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), 0, 0 ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } void CreateTargetEffect( const cSkillEventEffectInfoData* data, Character* pCharacter ) { Character* pTarget = (Character*)pCharacter->GetTargetObject(); WzVector EffectScale = c_UnitVector; if( data->GetPositionType() == cSkillEventEffectInfoData::SCALE_TYPE_USER ) EffectScale = pCharacter->GetScale(); else if( data->GetPositionType() == cSkillEventEffectInfoData::SCALE_TYPE_TARGET ) EffectScale = pTarget != NULL ? pTarget->GetScale() : c_UnitVector; if( data->GetPositionType() == cSkillEventEffectInfoData::POSITION_TYPE_TARGET_ARROW ) { if( pTarget != NULL ) { if( data->IsChaseTarget() == TRUE ) { cTargetPosition Position; Position.SetTargetArrowPosition( pTarget->GetObjectKey(), TRUE ); Position.SetSyncTargetAngle( data->IsStaticRotate() == FALSE ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetPositionData( Position ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } else { WzVector HitPosition = pTarget->GetArrowTargetPos(); WzVector HitRotate; _CalcDirectionRotate( pCharacter->GetArrowTargetPos(), HitPosition, HitRotate ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( HitPosition ); pProjectile->SetEffectRotate( HitRotate ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } } } else if( data->GetPositionType() == cSkillEventEffectInfoData::POSITION_TYPE_TARGET_POSITION ) { if( pTarget != NULL ) { if( data->IsChaseTarget() == TRUE ) { cTargetPosition Position; Position.SetTargetVisiblePosition( pTarget->GetObjectKey(), TRUE ); Position.SetSyncTargetAngle( data->IsStaticRotate() == FALSE ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetPositionData( Position ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } else { WzVector HitPosition = pTarget->GetVisiblePos(); WzVector HitRotate; _CalcDirectionRotate( pCharacter->GetVisiblePos(), HitPosition, HitRotate ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetTargetPosition( HitPosition ); pProjectile->SetEffectRotate( HitRotate ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget->GetObjectKey() ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } } } else if( data->GetPositionType() == cSkillEventEffectInfoData::POSITION_TYPE_USER_POSITION ) { cTargetPosition Position; Position.SetTargetVisiblePosition( pCharacter->GetObjectKey(), data->IsChaseTarget() ); Position.SetSyncTargetAngle( data->IsStaticRotate() == FALSE ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetPositionData( Position ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget != NULL ? pTarget->GetObjectKey() : 0 ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } else if( data->GetPositionType() == cSkillEventEffectInfoData::POSITION_TYPE_USER_ARROW_POSITION ) { cTargetPosition Position; Position.SetTargetArrowPosition( pCharacter->GetObjectKey(), data->IsChaseTarget() ); Position.SetSyncTargetAngle( data->IsStaticRotate() == FALSE ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetPositionData( Position ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), pTarget != NULL ? pTarget->GetObjectKey() : 0 ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } else if( data->GetPositionType() == cSkillEventEffectInfoData::POSITION_TYPE_CUSTOM ) { cTargetPosition Position; Position.SetTargetBonePosition( pCharacter->GetObjectKey(), data->GetPositionData().GetPositionType(), data->GetPositionData().GetBoneIndex(), data->IsChaseTarget() ); Position.SetSyncTargetAngle( data->IsStaticRotate() == FALSE ); cProjectileChaseTarget* pProjectile = new cProjectileChaseTarget(); pProjectile->SetPositionData( Position ); pProjectile->SetEffectScale( EffectScale ); pProjectile->SetLifeTime( data->GetLifeTime() ); pProjectile->SetActiveDelayTime( data->GetDelayTime() ); pProjectile->CreateEffect( data->GetEventCode(), pCharacter->GetObjectKey(), 0 ); g_ProjectileManagerEx.InsertProjectile( pProjectile ); } } void CreateSkillEventEffectByFieldSkill( DWORD dwSkillClassCode, const WzVector& Position ) { if( dwSkillClassCode == INVALID_SKILL_CLASS_CODE ) return; if( cSkillEventEffectInfo* pInfo = cSkillEventEffectInfoParser::Instance()->GetInfo( dwSkillClassCode ) ) { for( size_t i=0;i!=pInfo->GetEventDataCount();++i) { const cSkillEventEffectInfoData* data = pInfo->GetEventData(i); if( data->GetEventType() == cSkillEventEffectInfoData::EVENT_TYPE_FIELD ) { if( data->HasCameraViberation() ) { CreateCameraViberation( data, Position ); } else { CreateFieldEffect( data, Position ); } } } } } void ProcessSkillProjectile( Character* pCharacter, DWORD dwSkillClassCode, SkillScriptInfo* pSkillInfo, int HitCount ) { if( pCharacter == NULL ) return; if( dwSkillClassCode == INVALID_SKILL_CLASS_CODE ) return; #ifdef _NA_000000_20130812_NEW_CHARACTER_HELLROID if( dwSkillClassCode == eSKILL_HELLROID_1017 ) // ¿¡Å׸£Â÷¡ { if( HitCount == 1 ) { if( cProjectileUnit* pProjectile = g_ProjectileManagerEx.CreateSkillFlyingObject( pCharacter, (Character*)pCharacter->GetTargetObject(), pSkillInfo ) ) { pProjectile->SetAddNextAttackSerial(TRUE); } } } #endif //_NA_000000_20130812_NEW_CHARACTER_HELLROID if( dwSkillClassCode == eSKILL_MYSTIC_919 || dwSkillClassCode == eSKILL_MYSTIC_920 ) { if( HitCount == 1 ) { if( cProjectileUnit* pProjectile = g_ProjectileManagerEx.CreateSkillFlyingObject( pCharacter, (Character*)pCharacter->GetTargetObject(), pSkillInfo ) ) { pProjectile->SetAddNextAttackSerial(TRUE); } } } #ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE if( dwSkillClassCode == eSKILL_WITCHBLADE_1100 || dwSkillClassCode == eSKILL_WITCHBLADE_1119 || dwSkillClassCode == eSKILL_WITCHBLADE_1125 ) // È£¶óÀÌÁðÀè, ´ÙÀ̺êÇïÆÎ, ÇÁ·Î½ºÆ®ºê·¹½º { if( HitCount == 1 ) { if( cProjectileUnit* pProjectile = g_ProjectileManagerEx.CreateSkillFlyingObject( pCharacter, (Character*)pCharacter->GetTargetObject(), pSkillInfo ) ) { pProjectile->SetAddNextAttackSerial(TRUE); } } } #endif // _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE } void CreateSkillEventEffectByAnimationEvent( DWORD dwSkillClassCode, Character* pCharacter, int HitCount ) { if( pCharacter == NULL ) return; if( dwSkillClassCode == INVALID_SKILL_CLASS_CODE ) return; #ifdef _NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL if (pCharacter && pCharacter->GetHideSkill() == HIDE_SKILL_INFO::ALL_HIDE) { // ÇÏÀÌµå »óÅÂ¸é ¾È¶ç¿ò return; } #endif //_NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL if( cSkillEventEffectInfo* pInfo = cSkillEventEffectInfoParser::Instance()->GetInfo( dwSkillClassCode ) ) { for( size_t i=0;i!=pInfo->GetEventDataCount();++i) { const cSkillEventEffectInfoData* data = pInfo->GetEventData(i); if( data->GetEventType() != cSkillEventEffectInfoData::EVENT_TYPE_ANIMATION_EVENT ) continue; if( HitCount == 0 ) continue; if( data->GetHitEventNumber() != HitCount ) continue; if( data->HasCameraViberation() == TRUE ) { CreateCameraViberation( data, pCharacter->GetVisiblePos() ); } else { CreateTargetEffect( data, pCharacter ); } } } } void CreateSkillEventEffect( DWORD dwSkillClassCode, Character* pCharacter, cSkillEventEffectInfoData::eEventType EventType ) { if( pCharacter == NULL ) return; if( dwSkillClassCode == INVALID_SKILL_CLASS_CODE ) return; #ifdef _NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL if (pCharacter && pCharacter->GetHideSkill() == HIDE_SKILL_INFO::ALL_HIDE) { // ÇÏÀÌµå »óÅÂ¸é ¾È¶ç¿ò return; } #endif //_NA_007113_20140324_SHADOW_SKILL_BALLANCE_RENEWAL if( cSkillEventEffectInfo* pInfo = cSkillEventEffectInfoParser::Instance()->GetInfo( dwSkillClassCode ) ) { for( size_t i=0;i!=pInfo->GetEventDataCount();++i) { const cSkillEventEffectInfoData* data = pInfo->GetEventData(i); if( data->GetEventType() == EventType ) { if( data->HasCameraViberation() == TRUE ) { CreateCameraViberation( data, pCharacter->GetVisiblePos() ); } else { CreateTargetEffect( data, pCharacter ); } } } } } void ProcessSkillHitEffect( Character* pCharacter, DWORD dwSkillClassCode, int HitCount ) { CreateSkillEventEffectByAnimationEvent( dwSkillClassCode, pCharacter, HitCount); } BOOL ProcessSkillEffect( Character* pCharacter, DWORD dwSkillClassCode, int HitCount ) { switch ( dwSkillClassCode ) { case eSKILL_UPPER_BLOW: if(HitCount == 1 ) { WzVector wvEffectPos = pCharacter->GetVisiblePos() + pCharacter->GetDirection()*2; GlobalFunc::CreateEffectBeUpToOption( StrToWzID("A012"), wvEffectPos, pCharacter->GetScale(), pCharacter->GetObjectKey() ); return TRUE; } break; case eSKILL_SONIC_EXPLOSION: AddCameraVibration( pCharacter, 50.f ); return TRUE; case eSKILL_HEAL_MAGIC_ARRAY: if(HitCount == 1 ) { GlobalFunc::CreateEffectBeUpToOption( StrToWzID("k421"), pCharacter->GetVisiblePos(), pCharacter->GetScale(), pCharacter->GetObjectKey());//!loop ÀÌÆåÆ® ¾²Áö ¸»°Í return TRUE; } break; case eSKILL_FIST_OF_FIRE: if( HitCount == 1 ) { if( Object* pTargetObject = pCharacter->GetTargetObject() ) { GlobalFunc::CreateEffectBeUpToOption( StrToWzID("H646"), pTargetObject->GetVisiblePos(), pCharacter->GetScale(), pCharacter->GetObjectKey());//!loop ÀÌÆåÆ® ¾²Áö ¸»°Í return TRUE; } } break; case eSKILL_GROUND_SHOCK: AddCameraVibration( pCharacter, 60.f, Camera::VIBE_TYPE_VERTICAL, 0.1f ); return TRUE; case eSKILL_KNIGHT_OF_HUNGRY_SLAYER_THUNDER_CLAP: if( HitCount == 1 ) { AddCameraVibration( pCharacter, 60.f, Camera::VIBE_TYPE_ALL, 0.1f ); return TRUE; } break; case eSKILL_EARTHQUAKE: AddCameraVibration( pCharacter, 500.f ); GlobalFunc::CreateEffectBeUpToOption(StrToWzID("K350"), pCharacter->GetCurrentAction()->SKILL.vTargePos, pCharacter->GetObjectKey()); return TRUE; } return FALSE; } void CreateFootEffect( DWORD dwObjectKey, const WzVector& vPosition, DWORD dwTerrainAttribute) { // ÁöÇü¼Ó¼º¿¡ µû¶ó ÀÌÆåÆ®¸¦ »Ñ·ÁÁØ´Ù switch(dwTerrainAttribute) { case eTERRAIN_ATTRIBUTE_WOOD: case eTERRAIN_ATTRIBUTE_MUD: case eTERRAIN_ATTRIBUTE_METAL: case eTERRAIN_ATTRIBUTE_STONE: case eTERRAIN_ATTRIBUTE_DIRT: { GlobalFunc::CreateEffectBeUpToOption(StrToWzID("A000"),vPosition,dwObjectKey); } break; case eTERRAIN_ATTRIBUTE_WATER: { GlobalFunc::CreateEffectBeUpToOption(StrToWzID("A002"),vPosition,dwObjectKey); } break; case eTERRAIN_ATTRIBUTE_SNOW: { GlobalFunc::CreateEffectBeUpToOption(StrToWzID("A003"),vPosition,dwObjectKey); } break; case eTERRAIN_ATTRIBUTE_DESERT: { GlobalFunc::CreateEffectBeUpToOption(StrToWzID("A001"),vPosition,dwObjectKey); } break; default: { GlobalFunc::CreateEffectBeUpToOption(StrToWzID("A000"),vPosition,dwObjectKey); } break; } } }