Files
Client/Server/RylServerProject/RylGameLibrary/Creature/Monster/VirtualMonsterMgr.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

352 lines
8.0 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 "VirtualMonsterMgr.h"
#include <Creature/Creature.h>
#include <Creature/Monster/Monster.h>
#include <Creature/Monster/PatternMonster.h>
#include <Network/Dispatch/GameClient/SendCharAttack.h>
CVirtualMonsterMgr::CVirtualMonsterMgr()
: m_usSummonCount(0)
{
}
CVirtualMonsterMgr::~CVirtualMonsterMgr()
{
DestroyMonsterList();
}
struct FnDeleteSecond
{
template<typename PairType>
bool operator() (PairType& pair) { if(NULL != pair.second) { delete pair.second; } return true; }
};
struct FnLeaveParty
{
template<typename PairType>
bool operator() (PairType& pair)
{
if(NULL != pair.second)
{
CParty* lpParty = (pair.second)->GetParty();
if (lpParty)
{
lpParty->Leave((pair.second)->GetCID(), 0, (pair.second)->GetMapIndex());
}
}
return true;
}
};
void CVirtualMonsterMgr::DestroyMonsterList()
{
std::for_each(m_MonsterMap.begin(), m_MonsterMap.end(), FnLeaveParty());
std::for_each(m_MonsterMap.begin(), m_MonsterMap.end(), FnDeleteSecond());
m_MonsterMap.clear();
m_AdminMonsterUIDMap.clear();
}
bool CVirtualMonsterMgr::AddMonster(CMonster* lpMonster)
{
if (NULL == lpMonster) return false;
unsigned long dwCID = lpMonster->GetCID();
bool bResult = false;
Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID);
if (Creature::CT_MONSTER == eCreatureType ||
Creature::CT_SUMMON == eCreatureType ||
Creature::CT_STRUCT == eCreatureType)
{
bResult = m_MonsterMap.insert(std::make_pair(dwCID, reinterpret_cast<CMonster *>(lpMonster))).second;
unsigned short wKindID = static_cast<unsigned short>( (dwCID & Creature::MONSTER_KIND_BIT) );
if ( bResult && m_AdminMonsterUIDMap.end() == m_AdminMonsterUIDMap.find(wKindID) )
{
m_AdminMonsterUIDMap.insert(std::make_pair(wKindID, INIT_UID)).second;
}
}
return bResult;
}
CCreature* CVirtualMonsterMgr::GetCreature(unsigned long dwCID)
{
Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID);
if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType)
return (CCreature *)GetMonster(dwCID);
return (CCreature *)NULL;
}
CAggresiveCreature* CVirtualMonsterMgr::GetAggresiveCreature(unsigned long dwCID)
{
Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID);
if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType)
return (CAggresiveCreature *)GetMonster(dwCID);
return (CAggresiveCreature *)NULL;
}
CMonster* CVirtualMonsterMgr::GetMonster(unsigned long dwCID)
{
MonsterMap::iterator pos = m_MonsterMap.find(dwCID);
return (pos != m_MonsterMap.end()) ? pos->second : NULL;
}
void CVirtualMonsterMgr::ProcessAllMonster()
{
MonsterMap::iterator pos = m_MonsterMap.begin();
MonsterMap::iterator end = m_MonsterMap.end();
for (; pos != end; )
{
CMonster* lpMonster = pos->second;
if (lpMonster)
{
lpMonster->Process();
}
++pos;
}
}
void CVirtualMonsterMgr::ProcessMonsterRegenHPAndMP()
{
MonsterMap::iterator pos = m_MonsterMap.begin();
MonsterMap::iterator end = m_MonsterMap.end();
for (; pos != end; )
{
CMonster* lpMonster = pos->second;
if (lpMonster)
{
lpMonster->RegenHPAndMP(0, 0, true);
}
++pos;
}
}
void CVirtualMonsterMgr::ProcessSummonMonsterDead(void)
{
MonsterMap::iterator pos = m_MonsterMap.begin();
MonsterMap::iterator end = m_MonsterMap.end();
for (; pos != end; )
{
CMonster* lpMonster = pos->second;
if (lpMonster && true == lpMonster->IsDeadSummonMonster())
{
pos = m_MonsterMap.erase(pos);
delete lpMonster;
}
++pos;
}
}
bool CVirtualMonsterMgr::IsSummonee(unsigned long dwCID)
{
return Creature::IsSummonMonster(dwCID);
}
bool CVirtualMonsterMgr::SummonMonster(int nKID, Position Pos, CCharacter* lpMaster)
{
CMonster::MonsterCreateInfo tempInfo;
tempInfo.m_dwCID = Creature::SUMMON_MONSTER_BIT + (m_usSummonCount << 16) + nKID;
if (0 != GetMonster(tempInfo.m_dwCID))
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
tempInfo.m_nKID = nKID;
tempInfo.m_Pos = Pos;
CMonster* lpSummonMonster = 0;
if (0 != lpMaster)
{
CAggresiveCreature* lpSummonee = lpMaster->GetSummonee();
if (0 != lpSummonee)
{
lpSummonee->Dead(0);
}
}
lpSummonMonster = new CSummonMonster(tempInfo, lpMaster);
if (0 == lpSummonMonster)
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
lpSummonMonster->SetMapIndex(lpMaster->GetMapIndex());
if (false == lpSummonMonster->InitMonster(tempInfo.m_Pos))
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD>ȯ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
AddMonster(lpSummonMonster);
m_usSummonCount++;
if (CMonster::MAX_MONSTER_UID == m_usSummonCount) { m_usSummonCount = 0; }
if (0 != lpMaster)
{
lpMaster->SetSummonee(lpSummonMonster);
GameClientSendPacket::SendCharSummon(lpMaster->GetCID(), lpSummonMonster);
}
else
{
lpSummonMonster->SendMove(CMonster::RUN_ANI_LIMIT_MIN);
}
return true;
}
bool CVirtualMonsterMgr::AdminSummonMonster(int nKID, Position Pos, unsigned short wMapIndex)
{
CMonster::MonsterCreateInfo tempInfo;
CMonster* lpNewMonster = 0;
// nKID <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ
const CMonsterMgr::MonsterProtoType* lpProtoType = CMonsterMgr::GetInstance().GetMonsterProtoType(nKID);
if (0 == lpProtoType)
{
ERRLOG1(g_Log, "KID : %d <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><>ȯ<EFBFBD>ϴµ<CFB4> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.", nKID);
return false;
}
// <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD><CAB0>ϴ<EFBFBD><CFB4><EFBFBD> üũ
if (GetMonsterNum() >= CMonster::MAX_MONSTER_UID)
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4>Դϴ<D4B4>. <20><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD> <20>Ѱ<EFBFBD><D1B0>ش<EFBFBD>. (CID <20><> <20><><EFBFBD><EFBFBD>ũ<EFBFBD>ϰ<EFBFBD> <20>ϱ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD>)
unsigned long dwUID = GetAvailableMonsterUID(static_cast<unsigned short>(nKID));
if (dwUID == NO_BLANK_UID)
{
ERRLOG1(g_Log, "KindID:%d <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4>Դϴ<D4B4>. <20><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.", nKID);
return false;
}
tempInfo.m_dwCID = (dwUID << 16) + nKID;
tempInfo.m_nKID = nKID;
tempInfo.m_dwPID = 0;
tempInfo.m_Pos = Pos;
tempInfo.m_bScout = false;
tempInfo.m_nMovingPattern = 0;
tempInfo.m_wRespawnArea = CCell::CELL_DISTANCE;
// MON_TODO : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<>Կ<EFBFBD> <20>°<EFBFBD> <20><><EFBFBD><EFBFBD>
switch (lpProtoType->m_MonsterInfo.m_cSkillPattern)
{
case MonsterInfo::PATTERN_DEFENDER:
lpNewMonster = new CDefenderMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_WARRIOR:
lpNewMonster = new CWarriorMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_ACOLYTE:
lpNewMonster = new CAcolyteMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_MAGE:
lpNewMonster = new CMageMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_BOSS:
lpNewMonster = new CBossMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_NAMED:
lpNewMonster = new CNamedMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_CHIEF:
lpNewMonster = new CChiefMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_OBJECT:
lpNewMonster = new CObjectMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_GUARD:
lpNewMonster = new CGuardMonster(tempInfo, true);
break;
case MonsterInfo::PATTERN_GATHER:
lpNewMonster = new CGatherMonster(tempInfo, true);
break;
default:
lpNewMonster = new CMonster(tempInfo, true);
break;
};
if (0 == lpNewMonster)
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
lpNewMonster->SetMapIndex(wMapIndex);
if (false == lpNewMonster->InitMonster(tempInfo.m_Pos))
{
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
return AddMonster(lpNewMonster);
}
unsigned short CVirtualMonsterMgr::GetAvailableMonsterUID(unsigned short wKindID)
{
if (m_AdminMonsterUIDMap.end() == m_AdminMonsterUIDMap.find(wKindID))
{
m_AdminMonsterUIDMap.insert(std::make_pair(wKindID, INIT_UID)).second;
}
unsigned long nUID = ((m_AdminMonsterUIDMap[wKindID] << 16) | wKindID);
if (NULL != GetMonster(nUID))
{
if (m_AdminMonsterUIDMap[wKindID] == INIT_UID)
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>...
return NO_BLANK_UID;
}
m_AdminMonsterUIDMap[wKindID] = INIT_UID - 1;
return INIT_UID;
}
return m_AdminMonsterUIDMap[wKindID]--;
}