示例#1
0
//=========================================================
// load the SkillData struct with the proper values based on the skill level.
//=========================================================
void CGameRules::RefreshSkillData ( bool forceUpdate )
{
#ifndef CLIENT_DLL
	if ( !forceUpdate )
	{
		if ( GlobalEntity_IsInTable( "skill.cfg" ) )
			return;
	}
	GlobalEntity_Add( "skill.cfg", STRING(gpGlobals->mapname), GLOBAL_ON );
	char	szExec[256];

	ConVarRef skill( "skill" );

	SetSkillLevel( skill.IsValid() ? skill.GetInt() : 1 );

#ifdef HL2_DLL
	// HL2 current only uses one skill config file that represents MEDIUM skill level and
	// synthesizes EASY and HARD. (sjb)
	Q_snprintf( szExec,sizeof(szExec), "exec skill_manifest.cfg\n" );

	engine->ServerCommand( szExec );
	engine->ServerExecute();
#else
	Q_snprintf( szExec,sizeof(szExec), "exec skill%d.cfg\n", GetSkillLevel() );

	engine->ServerCommand( szExec );
	engine->ServerExecute();
#endif // HL2_DLL
#endif // CLIENT_DLL
}
示例#2
0
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);
	}
}
示例#3
0
void KSkillList::OnPlayerLevelUp()
{
    BOOL                bRetCode        = false;
    DWORD               dwSkillID       = 0;
    DWORD               dwSkillLevel    = 0;
    KSkill*             pSkill          = NULL;
    std::vector<DWORD>  LevelUpSkillIDVector;

    LevelUpSkillIDVector.reserve(8);

    for (
        PLAYER_SKILL_LIST::iterator it = m_PlayerSkillList.begin(), itEnd = m_PlayerSkillList.end(); 
        it != itEnd; 
        ++it
    )
    {
        dwSkillID = it->first;

        dwSkillLevel = GetSkillLevel(dwSkillID);
        KGLOG_PROCESS_ERROR(dwSkillLevel > 0);

        pSkill = g_pSO3World->m_SkillManager.GetSkill_RAW(dwSkillID, dwSkillLevel);
        KGLOG_PROCESS_ERROR(pSkill);

        if (pSkill->m_pBaseInfo->dwBelongKungfu == INVALID_SKILL_ID)
        {
            continue;
        }

        if (!pSkill->m_pBaseInfo->bIsExpSkill)
        {
            continue;
        }

        bRetCode = CanRealizeSkill(dwSkillID);

        if (bRetCode)
        {
            LevelUpSkillIDVector.push_back(dwSkillID);
        }
    }

    for (
        std::vector<DWORD>::iterator it = LevelUpSkillIDVector.begin(), itEnd = LevelUpSkillIDVector.end(); 
        it != itEnd;
        ++it
    )
    {
        if (CanRealizeSkill(*it))
        {
            LearnSkill(*it, true);
        }
    }

Exit0:
    return;
}
示例#4
0
文件: XSkillUser.cpp 项目: xahgo/tama
/**
 @brief 첫번째 보유스킬을 사용한다
 그냥 편의 함수.
*/
XSkillUser::xUseSkill XSkillUser::UseSkill( XSkillReceiver *pTarget, const XE::VEC2& vPos )
{
	xUseSkill info;
	if( XBREAK( m_listUseSkill.empty() ) ) {
		info.errCode = xCANCEL;
		return info;
	}
	XSkillDat *pUseSkill = m_listUseSkill.GetFirst();
	int level = GetSkillLevel( pUseSkill );
	return UseSkill( pUseSkill, level, pTarget, vPos );
}
示例#5
0
BOOL KSkillList::IsSkillExist(DWORD dwID, DWORD dwLevel)
{
    BOOL    bResult         = false;
    DWORD   dwLearnLevel    = GetSkillLevel(dwID);

    KG_PROCESS_ERROR(dwLevel > 0);
    KG_PROCESS_ERROR(dwLearnLevel > 0);
    KG_PROCESS_ERROR(dwLevel == dwLearnLevel);

    bResult = true;
Exit0:
    return bResult;
}
void FireProjectile::HandlePlayerCollision(Player* pPlayer, BaseArena* pArena, ItemLoaderXML* pItemLoader)
{
	// Add a "impulse" to the player.
	XMFLOAT3 dir = GetDirection();
	dir.y = 0.0f;
	pPlayer->SetVelocity(dir * GetImpactImpulse() * (1-pPlayer->GetKnockBackResistance()));
	pPlayer->ClearTargetQueue();

	// Get item data.
	Item* item = pItemLoader->GetItem(ItemKey(GetSkillType(), GetSkillLevel()));

	Player* caster = (Player*)GetWorld()->GetObjectById(GetOwner());

	// Damage the player.
	pPlayer->TakeDamage(item->GetAttributes().damage + caster->GetBonusDamage());
	pPlayer->SetLastHitter((Player*)GetWorld()->GetObjectById(GetOwner()));
}
示例#7
0
bool CPythonPlayer::__CanUseSkill()
{
	CInstanceBase* pkInstMain=NEW_GetMainActorPtr();
	if (!pkInstMain)
		return false;

	if (IsObserverMode())
		return false;

	// Fix me
	// 뉴마운트. 승마스킬레벨 20 미만인 경우, 고급 마운트를 타고 승마 관련 스킬 못 쓰도록 못하도록 하드 코딩... 
	// 나중에 시간 나면 can use skill 체크를 서버에서 해주자...
	if (pkInstMain->IsMountingHorse() && (GetSkillGrade(109) < 1 && GetSkillLevel(109) < 20))
	{
		return false;
	}

	return pkInstMain->CanUseSkill();
}
示例#8
0
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;
}
	void CSingleplayRules::NPCKilled(CBaseEntity *pVictim, const CTakeDamageInfo &info)
	{
		CBasePlayer *pEntity = UTIL_GetLocalPlayer();
		if (pVictim->m_isRareEntity)
		{
			switch (GetSkillLevel())
			{
			case SKILL_EASY:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier1.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier1.GetInt());
				}
				break;

			case SKILL_MEDIUM:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier2.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier2.GetInt());
				}
				break;

			case SKILL_HARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier3.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier3.GetInt());
				}
				break;

			case SKILL_VERYHARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier4.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier4.GetInt());
				}
				break;

			case SKILL_NIGHTMARE:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(3 * sk_money_multiplier5.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(5 * sk_exp_multiplier5.GetInt());
				}
				break;
			}
		}
		else
		{
			switch (GetSkillLevel())
			{
			case SKILL_EASY:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier1.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier1.GetInt());
				}
				break;

			case SKILL_MEDIUM:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier2.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier2.GetInt());
				}
				break;

			case SKILL_HARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier3.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier3.GetInt());
				}
				break;

			case SKILL_VERYHARD:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier4.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier4.GetInt());
				}
				break;

			case SKILL_NIGHTMARE:
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2 * sk_money_multiplier5.GetInt());
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3 * sk_exp_multiplier5.GetInt());
				}
				break;
			}
		}
		pEntity->IncrementFragCount(1);

#define KILLING_SPREE_AMOUNT	5
#define KILLING_FRENZY_AMOUNT	10
#define OVERKILL_AMOUNT	15
#define RAMPAGE_AMOUNT	20
#define UNSTOPPABLE_AMOUNT	25
#define INCONCEIVABLE_AMOUNT	30
#define INVINCIBLE_AMOUNT	35
#define GODLIKE_AMOUNT	40

		if (info.GetInflictor() == pEntity)
		{
			if (sv_player_voice.GetBool())
			{
				if (sv_player_voice_kill.GetBool())
				{
					int killvoicerandom = random->RandomInt(0, sv_player_voice_kill_freq.GetInt());
					if (killvoicerandom == 0)
					{
						pEntity->EmitSound("Player.VoiceKill");
					}
				}
			}
		}

		if (sv_killingspree.GetBool())
		{
			int m_iKillsInSpree = pEntity->FragCount();

			if (m_iKillsInSpree == KILLING_SPREE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_KILLINGSPREE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(2);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(3);
				}
			}
			if (m_iKillsInSpree == KILLING_FRENZY_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_KILLINGFRENZY");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(4);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(6);
				}
			}
			if (m_iKillsInSpree == OVERKILL_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_OVERKILL");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(6);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(9);
				}
			}
			if (m_iKillsInSpree == RAMPAGE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_RAMPAGE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(8);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(12);
				}
			}
			if (m_iKillsInSpree == UNSTOPPABLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_UNSTOPPABLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(10);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(15);
				}
			}
			if (m_iKillsInSpree == INCONCEIVABLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_INCONCEIVABLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(12);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(18);
				}
			}
			if (m_iKillsInSpree == INVINCIBLE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_INVINCIBLE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(14);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(21);
				}
			}
			if (m_iKillsInSpree == GODLIKE_AMOUNT)
			{
				CFmtStr hint;
				hint.sprintf("#Valve_Hud_GODLIKE");
				pEntity->ShowLevelMessage(hint.Access());
				if (g_fr_economy.GetBool())
				{
					pEntity->AddMoney(16);
				}
				if (!g_fr_classic.GetBool())
				{
					pEntity->AddXP(24);
				}
			}
		}

		if (pVictim->m_isRareEntity)
		{
			if (g_fr_classic.GetBool())
			{
				pEntity->LevelUpClassic();
			}
		}
	}
示例#10
0
BOOL cActiveSkillObject::Consume(CObject& object) const
{
	if(FALSE == mSkillInfo->IsExcutableSkillState(
		object,
		mSkillObjectInfo.usedItem))
	{
		return FALSE;
	}
	else if(eObjectKind_Player == object.GetObjectKind())
	{
		CPlayer& player = (CPlayer&)object;

		if(0 < GetInfo().Money)
		{
			player.SetMoney(
				GetInfo().Money,
				MONEY_SUBTRACTION,
				MF_LOST);
			LogItemMoney(
				player.GetID(),
				player.GetObjectName(),
				GetInfo().Index,
				"*skill",
				eLog_SkillMoneyUse,
				player.GetMoney() + GetInfo().Money,
				player.GetMoney(),
				GetInfo().Money,
				0,
				0,
				0,
				0,
				0,
				0);
		}

		const eItemUse_Err itemUseError = ITEMMGR->UseItem(
			&player,
			mSkillObjectInfo.usedItem.Position,
			mSkillObjectInfo.usedItem.wIconIdx);

		if(eItemUseSuccess == itemUseError)
		{
			MSG_ITEM_USE_ACK message;
			ZeroMemory(
				&message,
				sizeof(message));
			message.Category = MP_ITEM;
			message.Protocol = MP_ITEM_USE_ACK;
			message.TargetPos = mSkillObjectInfo.usedItem.Position;
			message.dwItemIdx = mSkillObjectInfo.usedItem.wIconIdx;
			message.eResult = itemUseError;

			player.SendMsg(
				&message,
				sizeof(message));
		}

		switch(GetInfo().mConsumePoint.mType)
		{
		case ACTIVE_SKILL_INFO::ConsumePoint::TypeExperience:
			{
				player.ReduceExpPoint(
					GetInfo().mConsumePoint.mValue,
					eExpLog_LoseBySkillUse);
				break;
			}
		case ACTIVE_SKILL_INFO::ConsumePoint::TypePlayerKill:
			{
				const DWORD badFame = player.GetBadFame() - GetInfo().mConsumePoint.mValue;
				player.SetBadFame(
					badFame);
				BadFameCharacterUpdate(
					player.GetID(),
					badFame);

				MSG_FAME message;
				message.Category = MP_CHAR;
				message.Protocol = MP_CHAR_BADFAME_NOTIFY;
				message.dwObjectID = player.GetID();
				message.Fame = badFame;

				PACKEDDATA_OBJ->QuickSend(
					&player,
					&message,
					sizeof(message));
				break;
			}
		}

		// LUJ, 전역 스킬이 실행될 경우 패킷을 전송한다
		if(TARGET_KIND_WORLD == GetInfo().Area)
		{
			MSG_ITEM_SKILL_START_TO_MAP message;
			ZeroMemory(
				&message,
				sizeof(message));
			message.Category = MP_SKILL;
			message.Protocol = MP_SKILL_START_TO_MAP;
			message.mGuildIndex = player.GetGuildIdx();
			message.mFamilyIndex = player.GetFamilyIdx();

			switch(GetInfo().AreaTarget)
			{
			case eSkillAreaTargetGuild:
				{
					message.dwObjectID = player.GetGuildIdx();
					break;
				}
			case eSkillAreaTargetFamily:
				{
					message.dwObjectID = player.GetFamilyIdx();
					break;
				}
			case eSkillAreaTargetParty:
				{
					message.dwObjectID = player.GetPartyIdx();
					break;
				}
			}

			message.mSkill.wSkillIdx = GetSkillIdx();
			message.mSkill.Level = GetSkillLevel();

			SKILLMGR->NetworkMsgParse(
				message.Protocol,
				&message);
			g_Network.Broadcast2AgentServer(
				(char*)&message,
				sizeof(message));
		}
	}

	const float manaBonus = 1.0f + object.GetRateBuffStatus()->DecreaseManaRate / 100.0f;
	const float usedMana = float(object.GetMana()) * GetInfo().mMana.mPercent + GetInfo().mMana.mPlus;
	const float usedLife = float(object.GetLife()) * GetInfo().mLife.mPercent + GetInfo().mLife.mPlus;

	object.ReduceMana(
		DWORD(manaBonus * usedMana));
	object.ReduceLife(
		DWORD(usedLife));

	return TRUE;
}
示例#11
0
BOOL KSkillList::CanLearnSkill(DWORD dwSkillID, DWORD dwMasterID)
{
    BOOL                        bResult             = false;
    BOOL                        bRetCode            = false;
    DWORD                       dwSkillLevel        = 0;
    DWORD                       dwSkillExp          = 0;
    KSKILL_LEARNING_INFO*       pSkillLearningInfo  = NULL;
	PLAYER_SKILL_LIST::iterator it;

    KGLOG_PROCESS_ERROR(dwSkillID != INVALID_SKILL_ID);

    it = m_PlayerSkillList.find(dwSkillID);
    if (it == m_PlayerSkillList.end())
    {
        int     nSkillCount = 0;
        KSkill* pSkill      = NULL;

        nSkillCount = (int)m_PlayerSkillList.size();
        KGLOG_PROCESS_ERROR(nSkillCount < MAX_PLAYER_SKILL_COUNT);

        pSkill = g_pSO3World->m_SkillManager.GetSkill_RAW(dwSkillID, 1);
        KGLOG_PROCESS_ERROR(pSkill);

        if (pSkill->m_pBaseInfo->dwBelongKungfu != INVALID_SKILL_ID)
        {
            DWORD dwKungfuLevel = GetSkillLevel(pSkill->m_pBaseInfo->dwBelongKungfu);
            KG_PROCESS_ERROR(dwKungfuLevel);
        }

        dwSkillLevel = 1;
    }
    else
    {
        KPlayerSkill* pPlayerSkill = NULL;
        pPlayerSkill = &it->second;

        dwSkillLevel = pPlayerSkill->dwLevel + 1;
        dwSkillExp = pPlayerSkill->dwExp;
    }

    pSkillLearningInfo = g_pSO3World->m_SkillManager.GetSkillLearningInfo(dwMasterID, dwSkillID, dwSkillLevel);
    KG_PROCESS_ERROR(pSkillLearningInfo);

    KG_PROCESS_ERROR(dwSkillLevel == 1 || dwSkillExp >= pSkillLearningInfo->dwRequireExp);

    KG_PROCESS_ERROR(m_pPlayer->m_nLevel >= pSkillLearningInfo->nRequirePlayerLevel);

    if (pSkillLearningInfo->dwReputationID)
    {
        int nReputationLevel = m_pPlayer->m_ReputeList.GetReputeLevel(pSkillLearningInfo->dwReputationID);
        KG_PROCESS_ERROR(nReputationLevel >= pSkillLearningInfo->nReputationLevel);
    }

    if (pSkillLearningInfo->nPrice)
    {
        int nMoney = m_pPlayer->m_ItemList.GetMoney();
        KG_PROCESS_ERROR(nMoney >= pSkillLearningInfo->nPrice);
    }

    if (pSkillLearningInfo->nCostTrain)
    {
        KG_PROCESS_ERROR(m_pPlayer->m_nCurrentTrainValue >= pSkillLearningInfo->nCostTrain);
    }

    bResult = true;
Exit0:
    return bResult;
}
示例#12
0
BOOL KSkillList::LearnSkill(DWORD dwSkillID, BOOL bNotifyPlayer, DWORD dwMasterID /* = 0 */)
{
    BOOL                                bResult         = false;
    BOOL                                bRetCode        = false;
    DWORD                               dwNewLevel      = 0;
    const KPlayerSkill*                 cpPlayerSkill   = NULL;
    KSkill*                             pOldSkill       = NULL;
    KSkill*                             pNewSkill       = NULL;
    int                                 nSkillCount     = 0;
    PLAYER_SKILL_LIST::const_iterator   cit;

    KGLOG_PROCESS_ERROR(dwSkillID != INVALID_SKILL_ID);

    cit = m_PlayerSkillList.find(dwSkillID);
	if (cit == m_PlayerSkillList.end())
	{
        nSkillCount = (int)m_PlayerSkillList.size();
        KGLOG_PROCESS_ERROR(nSkillCount < MAX_PLAYER_SKILL_COUNT);

        pNewSkill = g_pSO3World->m_SkillManager.GetSkill_RAW(dwSkillID, 1);
        KGLOG_PROCESS_ERROR(pNewSkill);

        if (pNewSkill->m_pBaseInfo->dwBelongKungfu != INVALID_SKILL_ID)
        {
            DWORD dwKungfuLevel = GetSkillLevel(pNewSkill->m_pBaseInfo->dwBelongKungfu);
            KGLOG_PROCESS_ERROR(dwKungfuLevel);
        }

		dwNewLevel = 1;
	}
    else
    {
        cpPlayerSkill = &cit->second;

        pOldSkill = g_pSO3World->m_SkillManager.GetSkill_RAW(dwSkillID, cpPlayerSkill->dwLevel);
        KGLOG_PROCESS_ERROR(pOldSkill);

        KG_PROCESS_ERROR(cpPlayerSkill->dwLevel < pOldSkill->m_pBaseInfo->dwMaxLevel);

        pNewSkill = g_pSO3World->m_SkillManager.GetSkill_RAW(dwSkillID, cpPlayerSkill->dwLevel + 1);
        KGLOG_PROCESS_ERROR(pNewSkill);

        dwNewLevel = cpPlayerSkill->dwLevel + 1;
    }

    bRetCode = UpdateSkill(dwSkillID, dwNewLevel, 0, bNotifyPlayer);
    KGLOG_PROCESS_ERROR(bRetCode);

    bRetCode = pNewSkill->CallLevelUpScript(m_pPlayer);
    KGLOG_CHECK_ERROR(bRetCode);

    if (dwSkillID == m_dwMountKungfuID) // 如果升级的技能是目前装备的内功,则更换内功
    {
        m_pPlayer->UmountKungfu();
        m_pPlayer->MountKungfu(dwSkillID, dwNewLevel);
    }

    if (dwMasterID)
    {
        KSKILL_LEARNING_INFO*   pSkillLearningInfo  = NULL;
        int                     nPlayerMoney        = 0;
        int                     nCostTrain          = 0;

        pSkillLearningInfo = g_pSO3World->m_SkillManager.GetSkillLearningInfo(
            dwMasterID, dwSkillID, dwNewLevel
        );
        KGLOG_PROCESS_ERROR(pSkillLearningInfo);

        nPlayerMoney = m_pPlayer->m_ItemList.GetMoney();
        nPlayerMoney -= pSkillLearningInfo->nPrice;
        nPlayerMoney = max(nPlayerMoney, 0);

        nCostTrain = min(m_pPlayer->m_nCurrentTrainValue, pSkillLearningInfo->nCostTrain);
        if (nCostTrain)
        {
            m_pPlayer->AddTrain(-nCostTrain);
        }

        bRetCode = m_pPlayer->m_ItemList.SetMoney(nPlayerMoney);
        KGLOG_CHECK_ERROR(bRetCode);

        g_LogClient.LogPlayerMoneyChange(-pSkillLearningInfo->nPrice, m_pPlayer, "learn skill");
    }

    bResult = true;
Exit0:
	return bResult;
}
示例#13
0
//
// 외부에서 UseSkill을 명령할땐 이것으로 호출하자.
// sutType : 스킬을 사용할때 스킬큐에서 연타로 사용한건가 일반적인 사용을 한건가.c
//
int	CMover::CMD_SetUseSkill( OBJID idTarget, int nSkillIdx, SKILLUSETYPE sutType )
{
	m_oaCmd = OBJACT_NONE;
	TRACE( "CMD_SetUseSkill( " );
	if( m_pActMover->IsFly() )	return 0;				// 비행중엔 스킬사용 금지.
	if( m_pActMover->IsActAttack() )	return 0;
	if( m_pActMover->IsActJump() )	return 0;			// 점프중엔 사용금지.
	if( m_pActMover->GetState() & OBJSTA_DMG_FLY_ALL )		return 0;	// 데미지 플라이중엔 스킬사용금지.
	if( IsDie() )	return 0;		// 죽었을때 사용금지.

	LPSKILL pSkill	= GetSkill( 0, nSkillIdx );		// this가 가진 스킬중 nIdx에 해당하는 스킬을 꺼낸다.
	if( pSkill == NULL )
	{
		Error( "CMD_SetUseSkill : %s skill(%d) not found", m_szName, nSkillIdx );
		return 0;	// 
	}

	ItemProp* pSkillProp = pSkill->GetProp();
	if( pSkillProp == NULL )		// JobSkill 리스트에서 꺼낸 스킬의 프로퍼티를 꺼냄.
	{
		Error( "CMD_SetUseSkill : %s. skill(%d) property not found", m_szName, pSkill->dwSkill );
		return 0;	// 
	}
	
	if( IsPlayer() && IsStateMode( STATE_BASEMOTION_MODE ) )	// 시전중(준비시간)일땐 사용금지.
	{
	#ifdef __CLIENT
		g_DPlay.SendStateModeCancel( STATE_BASEMOTION_MODE, STATEMODE_BASEMOTION_CANCEL );
	#endif 
		return 0;		
	}

	// 도달범위 - 얼마나 가까이 근접해야하는가. 미터단위
	float	fArrivalRange = 0.0f;		
	fArrivalRange = GetAttackRange( pSkillProp->dwAttackRange );
	
	switch( pSkillProp->dwUseChance )
	{
	case WUI_NOW:	// 타겟팅과 상관없이 자기자신에게 쓰는 방식.
		idTarget = GetId();
		break;
	case WUI_TARGETINGOBJ:	// 셀렉트 되어 있는 타겟에게 사용.
		{
#ifdef __CLIENT
		CObj *pFocusObj = GetWorld()->GetObjFocus();
		if( pFocusObj && pFocusObj->GetType() == OT_MOVER )
			idTarget = ((CMover*)pFocusObj)->GetId();
#else
		if( IsPlayer() )
			idTarget = ((CUser *)this)->m_idSetTarget;
#endif // __CLIENT
		}

		break;
#ifdef __CLIENT
	case WUI_TARGETCURSORPTZ:
		{
			idTarget = GetId();
			
			CRect rect;
			D3DXVECTOR3 vPos;
			CWndWorld* pWndWorld;
			
			pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD );

			rect = pWndWorld->GetClientRect();

			if( GetWorld()->ClientPointToVector( NULL, rect, pWndWorld->GetMousePoint(), &GetWorld()->m_matProj, &GetWorld()->GetCamera()->m_matView, &vPos, TRUE ) )
			{
#ifdef __SKILL0517
				AddSkillProp* pAddSkillProp = prj.GetAddSkillProp( pSkillProp->dwSubDefine, GetSkillLevel( pSkill ) );		// UseSkill에서 사용한 스킬의 프로퍼티 꺼냄
#else	// __SKILL0517
				AddSkillProp* pAddSkillProp = prj.GetAddSkillProp( pSkillProp->dwSubDefine, pSkill->dwLevel );		// UseSkill에서 사용한 스킬의 프로퍼티 꺼냄
#endif	// __SKILL0517
				if( pAddSkillProp == NULL )
				{
					Error( "CMover::OnMagicSkill : %s. add스킬(%d)의 프로퍼티가 없다.", m_szName, nSkillIdx );
					return 0;	// property not found
				}
				
				FLOAT	fDist;
				FLOAT	fMaxDistSq;
				D3DXVECTOR3	vDist;
				fMaxDistSq  = (float)pAddSkillProp->dwSkillRange;
				fMaxDistSq *= fMaxDistSq;
				vDist = vPos - GetPos();
				fDist = D3DXVec3LengthSq( &vDist );	

				SetAngle( GetDegree(vPos, GetPos()) );		// 목표쪽으로 몸을 돌림.
				
				// 텔레포트 할 위치가 멀경우 현제 스킬에 해당하는 거리로 바꿔준다
				if( fDist > fMaxDistSq )
				{
					FLOAT fLength;
					D3DXVECTOR3 vDirNor;
					D3DXVec3Normalize( &vDirNor, &vDist );
					fLength = (float)pAddSkillProp->dwSkillRange;
					float y = vPos.y;
					vPos = GetPos() + (vDirNor * fLength);
					vPos.y	= y;

					// 스킬에 해당하는 거리로 바꾼곳이 못가는 지역이라면 갈수 있는 지역을 검사한다.
					int nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

					if( nAttr != HATTR_NONE ) 
					{
						while( nAttr != HATTR_NONE )
						{
							if( nAttr == HATTR_NOFLY )
								break;
							
							fLength -= 1.0f; // 1미터씩 줄여가며 계산한다.
							vPos  = GetPos() + (vDirNor * fLength);
							nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

							// 캐릭터의 앞 뒤로 이동불가 일 경우 뒷쪽이 이동불가 해제 될때 까지 계속 계산하여 이동시킴
							// 그러므로 텔레포트 스킬 범위를 넘어설 경우 원래 자리로 텔레포트 하도록 처리
							D3DXVECTOR3 vTemp = vPos - GetPos();
							float fTemp = D3DXVec3LengthSq( &vTemp );
							if(fTemp > fMaxDistSq)
							{
								vPos = GetPos();
								break;
							}
						}
						
						// 한번더 줄여줌
						fLength -= 1.0f; 
						vPos = GetPos() + (vDirNor * fLength);

						// 줄인 곳이 이동불가 지역일 수 있다.
						nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );
						if( nAttr != HATTR_NONE )
						{
							vPos = GetPos();
						}
					}
				}
				else // 텔레포트 할 위치가 해당스킬 거리보다 작을경우
				{
					int nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

					FLOAT fLength;
					D3DXVECTOR3 vDirNor;
					D3DXVec3Normalize( &vDirNor, &vDist );
					fLength = 0.0f;

					while( nAttr != HATTR_NONE )
					{
						if( nAttr == HATTR_NOFLY )
							break;

						fLength -= 1.0f;
						vPos = GetPos() + (vDirNor * fLength);
						
						nAttr = GetWorld()->GetHeightAttribute( vPos.x, vPos.z );

						// 캐릭터의 앞 뒤로 이동불가 일 경우 뒷쪽이 이동불가 해제 될때 까지 계속 계산하여 이동시킴
						// 그러므로 텔레포트 스킬 범위를 넘어설 경우 원래 자리로 텔레포트 하도록 처리
						D3DXVECTOR3 vTemp = vPos - GetPos();
						float fTemp = D3DXVec3LengthSq( &vTemp );
						if(fTemp > fMaxDistSq)
						{
							vPos = GetPos();
							break;
						}
					}
				}

				if( IsActiveMover() && g_eLocal.GetState( EVE_SCHOOL ) )	// 학교이벤섭이면.
				{
					D3DXVECTOR3 v1, v2;
					v1 = GetPos();	v1.y += 0.1f;
					v2 = vPos;		v2.y += 0.1f;
					if( GetWorld()->IntersectObjLine( NULL, v1, v2, FALSE, FALSE ) )	// 텔레포트는 라인체크함.
					{
						g_WndMng.PutString( prj.GetText(TID_GAME_NOMOVING), NULL, prj.GetTextColor(TID_GAME_NOMOVING) );
						g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
						return 0;
					}
				}

				pWndWorld->m_vTelePos = vPos;
			}
			else
			{
				g_WndMng.m_pWndWorld->SetNextSkill( NEXTSKILL_NONE );
				g_WndMng.PutString( prj.GetText(TID_GAME_NOMOVING), NULL, prj.GetTextColor(TID_GAME_NOMOVING) );
				return 0;
			}
		}
		break;
#endif // __CLIENT
	}

	// 타인에게 쓰는경우에만 검사...
	if( idTarget != GetId() )		
	{
		CMover *pTarget = prj.GetMover( idTarget );
		if( IsValidObj(pTarget) )
		{
			if( pSkillProp->nEvildoing < 0 )	// 나쁜 스킬은 
				if( IsAttackAble(pTarget) == FALSE )	// 공격허용이 되지 않으면 사용할 수 없음.
					return 0;
				
			if( pSkill->dwSkill == SI_ASS_HEAL_RESURRECTION )	// 부활을 사용했을때
			{
				if( pTarget->IsNPC() || pTarget->IsDie() == FALSE )		// 상대가 NPC거나 상대가 죽어있지 않다면 취소
					return 0;
			} else
			{
				if( pTarget->IsDie() )		// 부활이 아닌 스킬을 사용했을때 상대가 죽어있으면 사용안됨.
					return 0;
			}
		}
	}

	// 타겟 근접 방식.
	switch( pSkillProp->dwExeTarget )
	{
	case EXT_SELFCHGPARAMET:	// 시전자 자신에게 사용하는 종류
		idTarget = GetId();		// 타겟을 자기자신으로 설정.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정. << 이게 왜 필요하지? ㅡ.ㅡ?
		break;
	case EXT_MAGICATKSHOT:
	case EXT_MAGICATK:			// 원거리에서 마법으로 타겟을 공격
	case EXT_MAGICSHOT:
		if( idTarget == NULL_ID )	return 0;			// 타겟이 없거나 유효하지 않으면 실패.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정. 다가가는 범위는 fArrivalRange값으로..
		break;
	case EXT_ANOTHERWITH:		// 나 혹은 다른사람에게 시전
		if( idTarget == NULL_ID )	// 타겟이 잡혀있지 않으면
			idTarget = GetId();		// 자신을 타겟으로 잡음
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	case EXT_AROUNDATK:			// 내 주위적들을 대상.
		idTarget = GetId();		// 타겟을 자기자신으로 설정.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	case EXT_OBJCHGPARAMET:		// 타인에게 사용
	default:	// 그외는 모두 근접하자.
		if( idTarget == NULL_ID )	return 0;			// 타겟이 없거나 유효하지 않으면 실패.
		SetDestObj( idTarget, fArrivalRange, TRUE );		// 이동할 목표물을 idTarget으로 설정.
		break;
	}
	
	ClearActParam();
	SetCmd( OBJACT_USESKILL, nSkillIdx, idTarget, sutType );		// 사정거리가 되었을때 실행할 명령 셋팅.
	TRACE( "\n)CMD_SetUseSkill\n" );

	return 1;
}