Files
Client/Server/RylServerProject/RylGameLibrary/Creature/Threat.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

1010 lines
28 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include <Utility/Math/Math.h>
#include <Utility/Setup/ServerSetup.h>
#include <Network/Dispatch/GameClient/GameClientDispatch.h>
#include <Network/Dispatch/GameClient/SendCharEtc.h>
#include <Network/Dispatch/GameClient/SendCharLevelUp.h>
#include <Network/Packet/PacketStruct/ServerInfo.h>
#include <Network/Packet/PacketCommand.h>
#include <Community/Party/Party.h>
#include <Skill/Spell/Spell.h>
#include <Creature/Character/CharacterClass.h>
#include <Creature/Character/Character.h>
#include <Creature/Character/ExpTable.h>
#include <Creature/Monster/Monster.h>
#include <Creature/Monster/PatternMonster.h>
#include <Creature/Monster/AwardTable.h>
#include <Creature/Monster/VirtualMonsterMgr.h>
#include "AggresiveCreature.h"
#include "CreatureManager.h"
#include "Threat.h"
#include <Map/FieldMap/VirtualArea/VirtualArea.h>
#include <Map/FieldMap/VirtualArea/VirtualAreaMgr.h>
#include <Creature/Siege/SiegeConstants.h>
#include <Creature/Siege/SiegeObject.h>
struct CompareAmount
{
int operator() (const CThreat::ThreatInfo& ThreatInfo1, const CThreat::ThreatInfo& ThreatInfo2)
{
return ThreatInfo1.m_lThreatAmount < ThreatInfo2.m_lThreatAmount;
}
};
struct CompareLevel
{
int operator() (const CThreat::ThreatInfo& ThreatInfo1, const CThreat::ThreatInfo& ThreatInfo2)
{
return ThreatInfo1.m_pCreature->GetStatus().m_nLevel < ThreatInfo2.m_pCreature->GetStatus().m_nLevel;
}
};
struct CompareFame
{
int operator() (const CThreat::ThreatInfo& ThreatInfo1, const CThreat::ThreatInfo& ThreatInfo2)
{
return ThreatInfo1.m_pCreature->GetFame() < ThreatInfo2.m_pCreature->GetFame();
}
};
CThreat::CThreat(void)
: m_pOwner(NULL)
{
ClearAll();
}
CThreat::~CThreat(void)
{
}
void CThreat::ClearAll(void)
{
m_cMaxLevel = 0;
m_eMaxLevelCreatureType = Creature::CT_NONE_TYPE;
ClearThreatList();
ClearThreatenedList();
}
void CThreat::ClearThreatList(void)
{
for (ThreatList::iterator ThreatIt = m_ThreatList.begin(), ThreatEnd = m_ThreatList.end();
ThreatIt != ThreatEnd; ++ThreatIt)
{
ThreatIt->m_pCreature->GetThreat().DeleteThreatened(m_pOwner);
}
m_ThreatList.clear();
}
void CThreat::ClearThreatenedList(void)
{
for (ThreatenedList::iterator ThreatenedIt = m_ThreatenedList.begin(), ThreatenedEnd = m_ThreatenedList.end();
ThreatenedIt != ThreatenedEnd; ++ThreatenedIt)
{
(*ThreatenedIt)->GetThreat().DeleteThreat(m_pOwner);
}
m_ThreatenedList.clear();
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::AddToThreatList
//
// Description : <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> ũ<><C5A9><EFBFBD><EFBFBD> <20>߰<EFBFBD>
//
// Inputs : pAttackCreature - <20>߰<EFBFBD><DFB0><EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// lThreatAmount - <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
void CThreat::AddToThreatList(CAggresiveCreature* pAttackCreature, long lThreatAmount)
{
if (NULL == pAttackCreature || 0 == lThreatAmount)
{
return;
}
if (EnemyCheck::EC_ENEMY != m_pOwner->IsEnemy(pAttackCreature))
{
return;
}
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ִ<EFBFBD> <20><EFBFBD><E0BCAE> ó<><C3B3>
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
if (pAttackCreature == it->m_pCreature)
{
it->m_lThreatAmount += lThreatAmount;
if (0 >= it->m_lThreatAmount)
{
pAttackCreature->GetThreat().DeleteThreatened(m_pOwner);
DeleteThreat(pAttackCreature);
}
m_ThreatList.sort(CompareAmount());
return;
}
}
// ó<><C3B3> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E0BCAE> ó<><C3B3>
if (0 > lThreatAmount)
{
return;
}
size_t nThreatListSize = m_ThreatList.size();
if (nThreatListSize > MAX_THREAT_TARGET)
{
ERRLOG2(g_Log, "CID:0x%08x <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><20>ִ<EFBFBD>ġ<EFBFBD><C4A1> <20>Ѿ<D1BE><EEBCB9><EFBFBD>ϴ<EFBFBD>. Size:%d",
m_pOwner->GetCID(), nThreatListSize);
return;
}
else if (nThreatListSize == MAX_THREAT_TARGET)
{
ThreatInfo& MinThreatInfo = m_ThreatList.front();
if (lThreatAmount < MinThreatInfo.m_lThreatAmount)
{
return;
}
MinThreatInfo.m_pCreature->GetThreat().DeleteThreatened(m_pOwner);
m_ThreatList.pop_front();
}
if (pAttackCreature->GetStatus().m_nLevel > m_cMaxLevel)
{
m_cMaxLevel = pAttackCreature->GetStatus().m_nLevel;
m_eMaxLevelCreatureType = Creature::GetCreatureType(pAttackCreature->GetCID());
}
pAttackCreature->GetThreat().AddToThreatenedList(m_pOwner);
m_ThreatList.push_front(ThreatInfo(pAttackCreature, lThreatAmount));
m_ThreatList.sort(CompareAmount());
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::AddToThreatenedList
//
// Description : <20><>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> ũ<><C5A9><EFBFBD><EFBFBD> <20>߰<EFBFBD>
//
// Inputs : pDefendCreature - <20>߰<EFBFBD><DFB0><EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
void CThreat::AddToThreatenedList(CAggresiveCreature* pDefendCreature)
{
ThreatenedList::iterator FindIt = std::find(m_ThreatenedList.begin(), m_ThreatenedList.end(), pDefendCreature);
if (FindIt == m_ThreatenedList.end())
{
// ThreatenedList<73><74> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
m_ThreatenedList.push_back(pDefendCreature);
}
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::HealThreat
//
// Description : 'Heal Threat'<27><> <20><><EFBFBD><EFBFBD>
//
// Inputs : pHealCreature - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ũ<><C5A9><EFBFBD><EFBFBD>
// lThreatAmount - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
class CAddToThreatList
{
public:
CAddToThreatList(CAggresiveCreature* lpAggresiveCreature, long lThreatAmount)
: m_lpAdd(lpAggresiveCreature), m_nAmount(lThreatAmount) { }
void operator () (CAggresiveCreature* lpAdded)
{ if (NULL != lpAdded) { lpAdded->GetThreat().AddToThreatList(m_lpAdd, m_nAmount); } }
private:
CAggresiveCreature* m_lpAdd;
int m_nAmount;
};
void CThreat::HealThreat(CAggresiveCreature* pHealCreature, long lThreatAmount)
{
const int MAX_HEAL_THREATEN_NUM = 30;
CAggresiveCreature* lpHealThreaten[MAX_HEAL_THREATEN_NUM];
CAggresiveCreature** lpDestination = lpHealThreaten;
unsigned long nCount = 0;
for (ThreatenedList::iterator first = m_ThreatenedList.begin(), last = m_ThreatenedList.end();
first != last && nCount < MAX_HEAL_THREATEN_NUM; ++lpDestination, ++nCount, ++first)
{
*lpDestination = *first;
}
std::for_each(lpHealThreaten, lpDestination, CAddToThreatList(pHealCreature, lThreatAmount));
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::AffectThreat
//
// Description : <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> Ÿ<><C5B8>Ʈ, <20><>Ÿ<EFBFBD><C5B8>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
//
// Inputs : pTauntCreature - Ÿ<><C5B8>Ʈ<EFBFBD><C6AE> ũ<><C5A9><EFBFBD><EFBFBD>
// lThreatAmount - Ÿ<><C5B8>Ʈ<EFBFBD><C6AE>
// eType - Ÿ<><C5B8>Ʈ/<2F><>Ÿ<EFBFBD><C5B8>Ʈ <20><><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
void CThreat::AffectThreat(CAggresiveCreature* pTauntCreature, long lDamage, AffectThreatType eType)
{
// <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
if (m_pOwner->GetStatus().m_nNowHP <= lDamage)
{
return;
}
const long lThreatAmount = lDamage * ((eType == TAUNT) ? 1 : (-1));
unsigned short wThreatNum = 0;
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
ThreatInfo& threatInfo = *it;
threatInfo.m_lThreatAmount = (threatInfo.m_lThreatAmount > lThreatAmount) ?
(threatInfo.m_lThreatAmount - lThreatAmount) : 0;
++wThreatNum;
}
if (wThreatNum > MAX_THREAT_TARGET || wThreatNum < 0)
{
ERRLOG1(g_Log, "Ÿ<EFBFBD><EFBFBD>Ʈ<EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>̻<EFBFBD><CCBB>մϴ<D5B4>. <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : %d", wThreatNum);
}
AddToThreatList(pTauntCreature, lThreatAmount * wThreatNum);
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::DeleteThreatened
//
// Description : <20><>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD>ĸ<EFBFBD> <20><><EFBFBD><EFBFBD>
//
// Inputs : pDefendCreature - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
bool CThreat::DeleteThreatened(CAggresiveCreature* pDefendCreature)
{
ThreatenedList::iterator FindIt = std::find(m_ThreatenedList.begin(), m_ThreatenedList.end(), pDefendCreature);
if (FindIt == m_ThreatenedList.end())
{
return false;
}
m_ThreatenedList.erase(FindIt);
return true;
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::DeleteThreat
//
// Description : <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD>ĸ<EFBFBD> <20><><EFBFBD><EFBFBD>
//
// Inputs : pAttackCreature - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
bool CThreat::DeleteThreat(CAggresiveCreature* pAttackCreature)
{
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
if (pAttackCreature == it->m_pCreature)
{
m_ThreatList.erase(it);
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::GetTarget
//
// Description : <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>˻<EFBFBD><CBBB><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
//
// Inputs : None.
//
// Outputs : None.
//
// Returns : CAggresiveCreature* - Ÿ<><C5B8> ũ<><C5A9><EFBFBD><EFBFBD>
///////////////////////////////////////////////////////////////////////////////////
CAggresiveCreature* CThreat::GetTarget(void)
{
if (true == m_ThreatList.empty())
{
return NULL;
}
Creature::CreatureType eCreatureType = Creature::GetCreatureType(m_pOwner->GetCID());
if (Creature::CT_MONSTER == eCreatureType ||
Creature::CT_SUMMON == eCreatureType ||
Creature::CT_STRUCT == eCreatureType)
{
CMonster* lpMonster = reinterpret_cast<CMonster *>(m_pOwner);
ThreatList TargetThreatList;
ThreatInfo TempTargetInfo;
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
TempTargetInfo = *it;
if (NULL == TempTargetInfo.m_pCreature)
{
continue;
}
if (true == TempTargetInfo.m_pCreature->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth))
{
continue;
}
if (EnemyCheck::EC_ENEMY != m_pOwner->IsEnemy(TempTargetInfo.m_pCreature))
{
continue;
}
const float fAttackRange = lpMonster->GetAttackRange() / 100.0f;
MotionInfo Motion;
lpMonster->GetMotion(MonsterInfo::Z3D_CA_WALK, Motion);
const float fMovingAttackRange = fAttackRange + Motion.m_fVelocity;
const float fDX = TempTargetInfo.m_pCreature->GetCurrentPos().m_fPointX - m_pOwner->GetCurrentPos().m_fPointX;
const float fDZ = TempTargetInfo.m_pCreature->GetCurrentPos().m_fPointZ - m_pOwner->GetCurrentPos().m_fPointZ;
const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ));
if (fDistance < fAttackRange)
{
TempTargetInfo.m_lThreatAmount *= ATTACK_TAUNT_RATE;
}
else if (fDistance < fMovingAttackRange)
{
TempTargetInfo.m_lThreatAmount *= MOVING_ATTACK_TAUNT_RATE;
}
TargetThreatList.push_back(TempTargetInfo);
}
if (true == TargetThreatList.empty())
{
return NULL;
}
TargetThreatList.sort(CompareAmount());
return TargetThreatList.back().m_pCreature;
}
else if (Creature::CT_SIEGE_OBJECT == eCreatureType)
{
CSiegeObject* lpSiegeObject = reinterpret_cast<CSiegeObject*>(m_pOwner);
if (!lpSiegeObject)
{
ERRLOG1(g_Log, "CID:0x%08x <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.", m_pOwner->GetCID());
return NULL;
}
if (!lpSiegeObject->IsGuard() && !lpSiegeObject->IsEmblem() && !lpSiegeObject->IsCamp())
{
ERRLOG2(g_Log, "CID:0x%08x wObjectType:%d <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>, <20><>¡<EFBFBD><C2A1>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴմϴ<D5B4>.",
m_pOwner->GetCID(), lpSiegeObject->GetObjectType());
return NULL;
}
ThreatList TargetThreatList;
ThreatInfo TempTargetInfo;
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
TempTargetInfo = *it;
if (NULL == TempTargetInfo.m_pCreature)
{
continue;
}
if (true == TempTargetInfo.m_pCreature->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth))
{
continue;
}
if (EnemyCheck::EC_ENEMY != m_pOwner->IsEnemy(TempTargetInfo.m_pCreature))
{
continue;
}
TargetThreatList.push_back(TempTargetInfo);
}
if (true == TargetThreatList.empty())
{
return NULL;
}
TargetThreatList.sort(CompareAmount());
return TargetThreatList.back().m_pCreature;
}
ERRLOG1(g_Log, "CID:0x%08x <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȥ<><C8A4> <20><><EFBFBD><EFBFBD>, <20><> <20><>¡<EFBFBD><C2A1>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴ<EFBFBD> <20><EFBFBD><E0BCAE> <20><><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> ã<><C3A3><EFBFBD>ϴ<EFBFBD>.", m_pOwner->GetCID());
return NULL;
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::GetAggravation
//
// Description : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>ġ <20>й<EFBFBD><D0B9><EFBFBD>)
//
// Inputs : pCreature - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD>
//
// Outputs : None.
//
// Returns : float - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
///////////////////////////////////////////////////////////////////////////////////
float CThreat::GetAggravation(CAggresiveCreature* pCreature)
{
static const float aryAggravation[CAggresiveCreature::AGGRAVATION_NUM] = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f,
1.0f,
1.05f, 1.1f, 1.15f, 1.2f, 1.25f, 1.3f, 1.35f, 1.4f, 1.45f, 1.5f,
1.55f, 1.6f, 1.65f, 1.7f, 1.75f, 1.8f, 1.85f, 1.9f, 1.95f, 2.0f,
};
const int nLevelDifference = m_pOwner->CalculateLevelGap(pCreature);
return aryAggravation[nLevelDifference + CAggresiveCreature::MAX_LEVEL_GAP];
}
unsigned char CThreat::GetAward(unsigned long* aryItemID, Item::CItem** aryItem, unsigned long* dwOwnerID)
{
if (true == m_ThreatList.empty()) { return 0; }
if (Creature::CT_MONSTER != Creature::GetCreatureType(m_pOwner->GetCID())) { return 0; }
if (Creature::CT_PC != m_eMaxLevelCreatureType && Creature::CT_SUMMON != m_eMaxLevelCreatureType)
{
// <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9><EFBFBD>İ<EFBFBD>
// '<27>÷<EFBFBD><C3B7>̾<EFBFBD>'<27><> '<27><>ȯ<EFBFBD><C8AF>'<27><> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
return 0;
}
int nRandPoint = 0;
int nGradeSpace = 0;
int nLevelDifferenceForArray = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ뷹<D6B4><EBB7B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
const int nLevelDifference = m_pOwner->CalculateLevelGap(m_pOwner->GetStatus().m_nLevel, m_cMaxLevel);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+20 <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
nLevelDifferenceForArray = nLevelDifference + CAggresiveCreature::MAX_LEVEL_GAP;
ThreatInfo HighestThreatInfo = m_ThreatList.back();
if (NULL == HighestThreatInfo.m_pCreature)
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> ž<><C5BE> ũ<><C5A9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return 0;
}
CMonster* lpMonster = reinterpret_cast<CMonster *>(m_pOwner);
CCharacter* lpCharacter = NULL;
float fPt = 1.0f;
switch (Creature::GetCreatureType(HighestThreatInfo.m_pCreature->GetCID()))
{
case Creature::CT_PC: lpCharacter = reinterpret_cast<CCharacter *>(HighestThreatInfo.m_pCreature); break;
case Creature::CT_SUMMON: lpCharacter = reinterpret_cast<CSummonMonster *>(HighestThreatInfo.m_pCreature)->GetMaster(); break;
default: return 0;
}
// <20>ۼ<EFBFBD>Ʈ<EFBFBD><C6AE> 0<≯<EFBFBD> <20>ƹ<EFBFBD><C6B9>͵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD>
fPt = lpCharacter->GetAwardPer();
if(fPt == 0.0f)
return 0;
bool bPremiumTime = lpCharacter->CheckPremiumTime();
*dwOwnerID = lpCharacter->GetCID();
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ƽ<EFBFBD><C6BC> <20>߿<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>߰<EFBFBD> '<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>'<27><> <20><><EFBFBD><EFBFBD><EFBFBD>ߴٸ<DFB4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD>.
bool bLuckyOrb = false;
if (NULL != lpCharacter->GetParty())
{
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
if (it->m_pCreature->GetParty() == lpCharacter->GetParty())
{
if (true == it->m_pCreature->GetEnchantInfo().GetFlag(Skill::SpellID::LuckyOrb))
{
bLuckyOrb = true;
break;
}
}
}
}
float fAddDropPt = 0.0f;
// '<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (true == bLuckyOrb)
{
fAddDropPt += 0.3f;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(bPremiumTime)
{
fAddDropPt += lpCharacter->GetPremiumPt();
}
// '<27><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if (true == lpCharacter->GetEnchantInfo().GetFlag(Skill::SpellID::WealthStatue))
{
unsigned short wLevel = lpCharacter->GetEnchantLevel(Skill::SpellID::WealthStatue);
fAddDropPt += (wLevel * 0.01f);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> Ȯ<><C8AE><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
unsigned char cItemKindIndex = 0;
int nTotalRate = 0;
for (cItemKindIndex = 0; cItemKindIndex < MonsterInfo::MAX_AWARD_KIND; ++cItemKindIndex)
{
// <20><>ũ<EFBFBD><C5A9>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ۺ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
nTotalRate += lpMonster->GetDropRate(cItemKindIndex);
}
// <20>ҷ<EFBFBD><D2B7><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><> <20>Դ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> (<28>Դ<EFBFBD><D4B4><EFBFBD> <20>ִ<EFBFBD> 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
int MonID = lpMonster->GetKID();
int MonDropMax = 1+Math::Random::ComplexRandom(2);
bool bAllInOne = false;
if(3006 <= MonID && MonID <= 3009)
bAllInOne = true;
else if(3101 <= MonID && MonID <= 3500)
bAllInOne = true; // <20>Դ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
int nDropItemIndex = 0, nDropItemNum = 0;
for (; nDropItemIndex < AwardTable::MAX_DROP_ITEM + EliteBonus::MAX_BONUS_DROP_ITEM;
++nDropItemIndex)
{
aryItemID[nDropItemNum] = 0;
unsigned short wDropRate = 0;
if (nDropItemIndex < AwardTable::MAX_DROP_ITEM)
{
wDropRate = AwardTable::aryItemDropRate[nLevelDifferenceForArray][nDropItemIndex];
}
else
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
char eliteBonus = lpCharacter->GetEliteBonus();
if (0 < eliteBonus)
{
wDropRate = EliteBonus::usBonusItemDropRate[eliteBonus - 1][nDropItemIndex - AwardTable::MAX_DROP_ITEM];
}
}
// <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD>.
if(fAddDropPt > 0.0f)
{
wDropRate += static_cast<unsigned short>(wDropRate * fAddDropPt);
}
wDropRate = (unsigned short)(wDropRate*(CServerSetup::GetInstance().GetDropDefault() / 100.0f)*fPt);
// fPt<50><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fPt <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޶<EFBFBD><DEB6><EFBFBD><EFBFBD><EFBFBD>.
// CServerSetup::GetInstance().GetDropDefault() = 100 <20><>.
//
if (!bAllInOne && Math::Random::ComplexRandom(1000) > wDropRate)
{
continue;
}
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> 10<31><30><EFBFBD≯<EFBFBD> 10<31><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ų<EFBFBD><C5B2>.
nRandPoint = Math::Random::ComplexRandom(nTotalRate);
for (cItemKindIndex = 0; cItemKindIndex < MonsterInfo::MAX_AWARD_KIND; ++cItemKindIndex)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int nDropRate = lpMonster->GetDropRate(cItemKindIndex);
if (0 == nDropRate) { continue; }
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
nGradeSpace += nDropRate;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
if (nGradeSpace > nRandPoint)
{
aryItemID[nDropItemNum] = AwardTable::CAward::GetInstance().GetAward(
cItemKindIndex, reinterpret_cast<CMonster *>(m_pOwner), lpCharacter, aryItem + nDropItemNum);
if (0 == aryItemID[nDropItemNum])
{
CMonster* pMon = reinterpret_cast<CMonster *>(m_pOwner);
if(pMon)
ERRLOG2(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>KID : %d, <20><><EFBFBD><EFBFBD> : %d", pMon->GetKID(), cItemKindIndex);
}
else
{
++nDropItemNum;
}
// <20>ʱ<EFBFBD>ȭ.
cItemKindIndex = MonsterInfo::MAX_AWARD_KIND;
nGradeSpace = 0;
}
// <20>ҷ<EFBFBD><D2B7><EFBFBD> <20>̺<EFBFBD>Ʈ. 3000~3005
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ. 3006~3010
if(3001 <= MonID && MonID <= 3010)
{
// 3006 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3009<30><39><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if(3006 <= MonID && MonID <= 3010 && nDropItemNum >= 1)
return nDropItemNum;
if(MonID == 3003 && nDropItemNum >= 1)
return nDropItemNum;
if(nDropItemNum >= MonDropMax)
return nDropItemNum;
}
// <20>Դ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
if(3101 <= MonID && MonID <= 3500)
{
if(nDropItemNum >= MonDropMax)
return nDropItemNum;
}
}
}
// <20>ҷ<EFBFBD><D2B7><EFBFBD> <20>̺<EFBFBD>Ʈ. 3000~3005
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ. 3006~3010
if(0 == nDropItemNum && 3001 <= MonID && MonID <= 3010)
{
// cItemKindIndex <20><> 0<><30><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> A<><41> <20><EFBFBD><E2BABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϱ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC>̴<EFBFBD>.
cItemKindIndex = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD>A<EFBFBD><41> <20><><EFBFBD><EFBFBD><EFBFBD>߸<EFBFBD><DFB8><EFBFBD> <20>ߴµ<DFB4> <20><> <20><><EFBFBD><EFBFBD>A<EFBFBD><41> 0 <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD>
// <20>̰<EFBFBD> <20>ƹ<EFBFBD><C6B9>͵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int nDropRate = lpMonster->GetDropRate(cItemKindIndex);
if (0 == nDropRate)
return 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD>ε<EFBFBD> <20>Ѱ<EFBFBD><D1B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>
aryItemID[nDropItemNum] = AwardTable::CAward::GetInstance().GetAward(
cItemKindIndex, reinterpret_cast<CMonster *>(m_pOwner), lpCharacter, aryItem + nDropItemNum);
if (0 == aryItemID[nDropItemNum])
{
CMonster* pMon = reinterpret_cast<CMonster *>(m_pOwner);
if(pMon)
ERRLOG2(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>KID : %d, <20><><EFBFBD><EFBFBD> : %d", pMon->GetKID(), cItemKindIndex);
return 0;
}
++nDropItemNum;
}
return nDropItemNum;
}
///////////////////////////////////////////////////////////////////////////////////
// Function : CThreat::DivisionExp
//
// Description : <20><><EFBFBD><EFBFBD>ġ <20>й<EFBFBD>
//
// Inputs : None.
//
// Outputs : None.
//
// Returns : None.
///////////////////////////////////////////////////////////////////////////////////
void CThreat::DivisionExp(void)
{
if (true == m_ThreatList.empty())
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20><> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD><EFBFBD><EFBFBD> Exp<78><70> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return;
}
if (NULL == m_pOwner)
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> NULL<4C>Դϴ<D4B4>.");
return;
}
unsigned long lSumOfThreatAmount = 0;
for (ThreatList::iterator it = m_ThreatList.begin(); it != m_ThreatList.end(); ++it)
{
lSumOfThreatAmount += it->m_lThreatAmount;
}
// <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ִ<EFBFBD> <20><EFBFBD><E0BCAE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ <20><><EFBFBD><EFBFBD>
AwardInfo aryIndividualAwardInfo[MAX_THREAT_TARGET];
CAggresiveCreature* pHighestThreatCreature = m_ThreatList.back().m_pCreature;
const unsigned char cHighestLevel = pHighestThreatCreature->GetStatus().m_nLevel;
int nNumber = 0;
for (ThreatList::iterator it = m_ThreatList.begin();
it != m_ThreatList.end() && nNumber < MAX_THREAT_TARGET; ++it, ++nNumber)
{
if (nNumber >= MAX_THREAT_TARGET)
{
ERRLOG1(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB>մϴ<D5B4>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> %d<>Դϴ<D4B4>.", nNumber);
break;
}
const ThreatInfo& tempThreatInfo = *it;
aryIndividualAwardInfo[nNumber].m_pCreature = tempThreatInfo.m_pCreature;
aryIndividualAwardInfo[nNumber].m_pParty = tempThreatInfo.m_pCreature->GetParty();
aryIndividualAwardInfo[nNumber].m_lAward =
static_cast<long>(m_pOwner->GetStatus().m_nExp * tempThreatInfo.m_lThreatAmount /
std::max(static_cast<float>(lSumOfThreatAmount), static_cast<float>(m_pOwner->GetStatus().m_StatusInfo.m_nMaxHP)));
const int nIndividualLevel = aryIndividualAwardInfo[nNumber].m_pCreature->GetStatus().m_nLevel;
if (::abs(cHighestLevel - nIndividualLevel) > EXP_CONSENT_GAP)
{
aryIndividualAwardInfo[nNumber].m_lAward = 1;
}
}
// <20><>ȯ<EFBFBD><C8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
for (int nSummoneeIndex = 0; nSummoneeIndex < nNumber; ++nSummoneeIndex)
{
unsigned long dwCID = aryIndividualAwardInfo[nSummoneeIndex].m_pCreature->GetCID();
CAggresiveCreature* lpMaster = NULL;
bool bSummonee = false;
if (0 != aryIndividualAwardInfo[nSummoneeIndex].m_pCreature->GetMapIndex())
{
VirtualArea::CVirtualArea* lpVirtualArea =
VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(
aryIndividualAwardInfo[nSummoneeIndex].m_pCreature->GetMapIndex());
if (NULL != lpVirtualArea)
{
CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager();
if (NULL != lpVirtualMonsterMgr && true == lpVirtualMonsterMgr->IsSummonee(dwCID))
{
lpMaster = reinterpret_cast<CSummonMonster *>(
aryIndividualAwardInfo[nSummoneeIndex].m_pCreature)->GetMaster();
bSummonee = true;
}
}
}
else
{
if (true == CCreatureManager::GetInstance().IsSummonee(dwCID))
{
lpMaster = reinterpret_cast<CSummonMonster *>(
aryIndividualAwardInfo[nSummoneeIndex].m_pCreature)->GetMaster();
bSummonee = true;
}
}
if (true == bSummonee)
{
if (NULL != lpMaster)
{
if (pHighestThreatCreature == aryIndividualAwardInfo[nSummoneeIndex].m_pCreature)
{
pHighestThreatCreature = lpMaster;
}
int nMasterIndex = 0;
for (; nMasterIndex < nNumber; ++nMasterIndex)
{
if (aryIndividualAwardInfo[nMasterIndex].m_pCreature == lpMaster)
{
aryIndividualAwardInfo[nMasterIndex].m_lAward += aryIndividualAwardInfo[nSummoneeIndex].m_lAward;
aryIndividualAwardInfo[nSummoneeIndex] = AwardInfo();
break;
}
}
if (nMasterIndex == nNumber)
{
aryIndividualAwardInfo[nSummoneeIndex].m_pCreature = lpMaster;
aryIndividualAwardInfo[nSummoneeIndex].m_pParty = lpMaster->GetParty();
}
}
else
{
aryIndividualAwardInfo[nSummoneeIndex] = AwardInfo();
}
}
}
// <20><>Ƽ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ <20>й<EFBFBD>
AwardInfo aryPartyAwardInfo[MAX_THREAT_TARGET];
nNumber = 0;
for (int nIndividualIndex = 0; nIndividualIndex < MAX_THREAT_TARGET; ++nIndividualIndex)
{
if (NULL == aryIndividualAwardInfo[nIndividualIndex].m_pCreature)
{
continue;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD>ġ <20>й迡<D0B9><E8BFA1> <20><><EFBFBD>ܵȴ<DCB5>.
Creature::CreatureType eCreatureType = Creature::GetCreatureType(aryIndividualAwardInfo[nIndividualIndex].m_pCreature->GetCID());
if (Creature::CT_MONSTER == eCreatureType || Creature::CT_STRUCT == eCreatureType)
{
continue;
}
bool newParty = true;
for (int nPartyIndex = 0; nPartyIndex < nNumber; ++nPartyIndex)
{
if (NULL != aryPartyAwardInfo[nPartyIndex].m_pParty)
{
if (aryPartyAwardInfo[nPartyIndex].m_pParty == aryIndividualAwardInfo[nIndividualIndex].m_pParty)
{
aryPartyAwardInfo[nPartyIndex].m_lAward += aryIndividualAwardInfo[nIndividualIndex].m_lAward;
newParty = false;
break;
}
}
}
if (true == newParty)
{
aryPartyAwardInfo[nNumber] = aryIndividualAwardInfo[nIndividualIndex];
if (++nNumber > MAX_THREAT_TARGET)
{
ERRLOG1(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB>մϴ<D5B4>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> %d<>Դϴ<D4B4>.", nNumber);
}
}
}
// <20><><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> MAX_THREAT_REWARD <20><>ŭ<EFBFBD><C5AD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
for (int nPartyIndex = 0; nPartyIndex < MAX_THREAT_REWARD; ++nPartyIndex)
{
for (int nCompareIndex = nPartyIndex + 1; nCompareIndex < nNumber; ++nCompareIndex)
{
if (aryPartyAwardInfo[nPartyIndex].m_lAward < aryPartyAwardInfo[nCompareIndex].m_lAward)
{
std::swap(aryPartyAwardInfo[nPartyIndex], aryPartyAwardInfo[nCompareIndex]);
}
}
if (NULL == aryPartyAwardInfo[nPartyIndex].m_pCreature)
{
break;
}
long lIndividualExp = aryPartyAwardInfo[nPartyIndex].m_lAward;
// <20><>Ƽ
if (NULL != aryPartyAwardInfo[nPartyIndex].m_pParty)
{
reinterpret_cast<CCharacterParty* >(aryPartyAwardInfo[nPartyIndex].m_pParty)->SendDivisionExp(
reinterpret_cast<CCharacter *>(aryPartyAwardInfo[nPartyIndex].m_pCreature), m_pOwner, lIndividualExp, cHighestLevel);
}
// <20><><EFBFBD><EFBFBD>
else
{
CCharacter *lpCharacter = reinterpret_cast<CCharacter *>(aryPartyAwardInfo[nPartyIndex].m_pCreature);
lIndividualExp = static_cast<long>(lIndividualExp * GetAggravation(lpCharacter));
// Threat List<73><74> 2<><32> <20><><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD> <20>޴´<DEB4>.
if (pHighestThreatCreature != lpCharacter)
{
lIndividualExp /= 2;
}
lpCharacter->GetHuntingExp(m_pOwner, lIndividualExp, 1);
}
}
}
bool CThreat::SaveEnemy(unsigned long dwCID)
{
int nOldestIndex = 0;
int nLoopIndex = 0;
const unsigned long dwLastTickCount = ::GetTickCount();
for (nLoopIndex = 0; nLoopIndex < SaveEnemyInfo::MAX_SAVING_ENEMY; ++nLoopIndex)
{
if (0 == m_LatestEnemy[nLoopIndex].m_dwCID)
{
continue;
}
// <20>̱<EFBFBD><CCB1><EFBFBD> <20><><EFBFBD>ʸ<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PvP<76><50><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>¡ <20><><EFBFBD><EFBFBD>å<EFBFBD><C3A5> <20><>ȭ<EFBFBD>ȴ<EFBFBD>.
const unsigned long dwSavingTicCount = SaveEnemyInfo::MAX_SAVING_TICKCOUNT;
if (dwLastTickCount - m_LatestEnemy[nLoopIndex].m_dwTickCount >= dwSavingTicCount)
{
m_LatestEnemy[nLoopIndex] = SaveEnemyInfo();
continue;
}
if (dwCID == m_LatestEnemy[nLoopIndex].m_dwCID)
{
m_LatestEnemy[nLoopIndex].m_dwTickCount = dwLastTickCount;
return true;
}
if (m_LatestEnemy[nLoopIndex].m_dwTickCount < m_LatestEnemy[nOldestIndex].m_dwTickCount)
{
nOldestIndex = nLoopIndex;
}
}
for (nLoopIndex = 0; nLoopIndex < SaveEnemyInfo::MAX_SAVING_ENEMY; ++nLoopIndex)
{
if (0 == m_LatestEnemy[nLoopIndex].m_dwCID)
{
m_LatestEnemy[nLoopIndex].m_dwCID = dwCID;
m_LatestEnemy[nLoopIndex].m_dwTickCount = dwLastTickCount;
return false;
}
}
m_LatestEnemy[nOldestIndex].m_dwCID = dwCID;
m_LatestEnemy[nOldestIndex].m_dwTickCount = dwLastTickCount;
return false;
}