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>
This commit is contained in:
384
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterMgr.cpp
Normal file
384
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterMgr.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Math/Math.h>
|
||||
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
|
||||
#include <Utility/Resource/EnsureCleanup.h>
|
||||
#include <Network/XORCrypt/XORCrypt.h>
|
||||
|
||||
#define ENCODEHEADER(Start_In, Length_In, PageNum_In, PageVer_In) CXORCrypt::GetInstance().EncodeHeader((Start_In), (Length_In), (PageNum_In), (PageVer_In))
|
||||
#define DECODEHEADER(Start_In, Length_In, PageNum_In, PageVer_In) CXORCrypt::GetInstance().DecodeHeader((Start_In), (Length_In), (PageNum_In), (PageVer_In))
|
||||
#define COMPRESS(In, In_len, Out, Out_len) CMiniLZOCompress::Compress((In), (In_len), (Out), (Out_len))
|
||||
#define DECOMPRESS(In, In_len, Out, Out_len) CMiniLZOCompress::Decompress((In), (In_len), (Out), (Out_len))
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "MonsterMgr.h"
|
||||
|
||||
CMonsterMgr CMonsterMgr::ms_this;
|
||||
|
||||
#ifdef _TEST_SERVER_
|
||||
const char* CMonsterMgr::m_szMonsterScriptFileName = "TestMonsterProtoType.txt";
|
||||
#else
|
||||
const char* CMonsterMgr::m_szMonsterScriptFileName = "MonsterProtoType.txt";
|
||||
#endif
|
||||
|
||||
|
||||
CMonsterMgr::CMonsterMgr(void)
|
||||
: m_nMonsterNum(0), m_ProtoTypeArray(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CMonsterMgr::~CMonsterMgr(void)
|
||||
{
|
||||
ClearProtoType();
|
||||
}
|
||||
|
||||
void CMonsterMgr::ClearProtoType()
|
||||
{
|
||||
if(NULL != m_ProtoTypeArray)
|
||||
{
|
||||
delete [] m_ProtoTypeArray;
|
||||
}
|
||||
}
|
||||
|
||||
bool CMonsterMgr::LoadMonstersFromFile(const char* szFileName)
|
||||
{
|
||||
int nIndex = 0;
|
||||
int nLineCount = 0;
|
||||
char strTemp[MAX_PATH];
|
||||
|
||||
CDelimitedFile DelimitedFile; // <20><>ü <20>Ҹ<EFBFBD><D2B8><EFBFBD>, <20>ڵ<EFBFBD> Close.
|
||||
std::vector<MonsterProtoType> monsterProtoTypeVector;
|
||||
|
||||
monsterProtoTypeVector.reserve(1000);
|
||||
MonsterProtoType tempProtoType;
|
||||
|
||||
// <20><>ũ<EFBFBD>ο<EFBFBD> <20>α<EFBFBD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><>.
|
||||
// <20><>ũ<EFBFBD>ο<EFBFBD><CEBF><EFBFBD> \<5C>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
|
||||
// ( '<27>̽<EFBFBD><CCBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߸<EFBFBD><DFB8>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>' <20><><EFBFBD><EFBFBD> <20><EFBFBD> )
|
||||
#define READ_DATA(ColumnName, Argument) \
|
||||
if (!DelimitedFile.ReadData(Argument)) { \
|
||||
ERRLOG2(g_Log, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9>Ʈ <20>б<EFBFBD> <20><><EFBFBD><EFBFBD> : %d<><64> %s<>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>!", nLineCount, #ColumnName); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define READ_STRING(ColumnName, Buffer, BufferSize) \
|
||||
if (!DelimitedFile.ReadString(Buffer, BufferSize)) { \
|
||||
ERRLOG2(g_Log, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9>Ʈ <20>б<EFBFBD> <20><><EFBFBD><EFBFBD> : %d<><64> %s<>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>!", nLineCount, #ColumnName); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define READ_DATA_ARRAY(ColumnName, Argument, ArgumentNum) \
|
||||
for (nIndex=0; nIndex < ArgumentNum; ++nIndex) { \
|
||||
READ_DATA(ColumnName, Argument[nIndex]); \
|
||||
}
|
||||
|
||||
#define READ_DATA_BOOL(ColumnName, Argument) \
|
||||
if (!DelimitedFile.ReadString(strTemp, MAX_PATH)) { \
|
||||
ERRLOG2(g_Log, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9>Ʈ <20>б<EFBFBD> <20><><EFBFBD><EFBFBD> : %d<><64> %s<>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>!", nLineCount, #ColumnName); \
|
||||
return false; \
|
||||
} \
|
||||
Argument = (!strcmp(strTemp, "O")) ? true : false;
|
||||
|
||||
|
||||
if (!DelimitedFile.Open(szFileName ? szFileName : m_szMonsterScriptFileName))
|
||||
{
|
||||
ERRLOG1(g_Log, "%s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.", szFileName ? szFileName : m_szMonsterScriptFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (DelimitedFile.ReadLine())
|
||||
{
|
||||
++nLineCount;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD><D9B2><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴٴϱ<D9B4>~!!! (<28><><EFBFBD><EFBFBD>!)
|
||||
READ_DATA("KID", tempProtoType.m_MonsterInfo.m_dwKID);
|
||||
|
||||
READ_STRING("<EFBFBD≯<EFBFBD>", tempProtoType.m_MonsterInfo.m_strName, MonsterInfo::MAX_NAME_LENGTH);
|
||||
READ_STRING("<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>", tempProtoType.m_MonsterInfo.m_strModelingFlag, MonsterInfo::MAX_MODELING_FLAG_LENGTH);
|
||||
|
||||
READ_STRING("<EFBFBD><EFBFBD>ų<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", strTemp, MAX_PATH);
|
||||
tempProtoType.m_MonsterInfo.m_nSkillPattern = MonsterInfo::GetMonsterPattern(strTemp);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[0].m_wAction = MonsterInfo::Z3D_CA_WALK;
|
||||
READ_DATA("<EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[0].m_dwFrame);
|
||||
|
||||
READ_DATA("<EFBFBD>ȱ<EFBFBD><EFBFBD>Ÿ<EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[0].m_fVelocity);
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[0].m_fVelocity /= 100.0f;
|
||||
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[1].m_wAction = MonsterInfo::Z3D_CA_RUN;
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[1].m_dwFrame);
|
||||
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[1].m_fVelocity);
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[1].m_fVelocity /= 100.0f;
|
||||
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[2].m_wAction = MonsterInfo::Z3D_CA_ATTACK;
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[2].m_dwFrame);
|
||||
|
||||
tempProtoType.m_MonsterInfo.m_MonsterMotions[3].m_wAction = MonsterInfo::Z3D_CA_CASTING;
|
||||
READ_DATA("<EFBFBD><EFBFBD>ų<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_MonsterMotions[3].m_dwFrame);
|
||||
|
||||
READ_DATA_ARRAY("Ÿ<EFBFBD>ݹڽ<EFBFBD>", tempProtoType.m_MonsterInfo.m_fHitBox, MonsterInfo::MAX_HITBOX_NUM);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD>ݰŸ<EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nAttackRange);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_fAttackAngle);
|
||||
|
||||
// <20>⺻ <20><><EFBFBD><EFBFBD>
|
||||
READ_DATA("<EFBFBD>⺻ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_nExp);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_nLevel);
|
||||
READ_DATA("<EFBFBD>ּҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMinDamage);
|
||||
READ_DATA("<EFBFBD>ִ뵥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMaxDamage);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nOffenceRevision);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nDefence);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nDefenceRevision);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nBlockingPercentage);
|
||||
READ_DATA("DRC", tempProtoType.m_CreatureStatus.m_StatusInfo.m_fDRC);
|
||||
READ_DATA("ũ<EFBFBD><EFBFBD>Ƽ<EFBFBD><EFBFBD>Ȯ<EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nCriticalPercentage);
|
||||
READ_DATA("ũ<EFBFBD><EFBFBD>Ƽ<EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nCriticalType);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMagicResistance);
|
||||
READ_DATA_ARRAY("<EFBFBD><EFBFBD><EFBFBD>ݼӼ<EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nWeaponAttributeLevel, StatusInfo::MAX_ATTRIBUTE_NUM);
|
||||
READ_DATA_ARRAY("<EFBFBD>Ӽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nAttributeResistance, StatusInfo::MAX_ATTRIBUTE_NUM);
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD>ݼӵ<EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nAttackSpeed);
|
||||
READ_DATA("<EFBFBD>̵<EFBFBD><EFBFBD>ӵ<EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMoveSpeed);
|
||||
READ_DATA("HP Max", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMaxHP);
|
||||
READ_DATA("MP Max", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMaxMP);
|
||||
READ_DATA("HP ȸ<><C8B8><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nHPRegenAmount);
|
||||
READ_DATA("MP ȸ<><C8B8><EFBFBD><EFBFBD>", tempProtoType.m_CreatureStatus.m_StatusInfo.m_nMPRegenAmount);
|
||||
|
||||
// <20><>Ÿ
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_fSize);
|
||||
READ_DATA("<EFBFBD><EFBFBD>ų<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_nSkillLevel);
|
||||
|
||||
READ_DATA_BOOL("<EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD>Ÿ<EFBFBD>Կ<EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_bStealth);
|
||||
READ_DATA_BOOL("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_bFirstAttack);
|
||||
READ_DATA_BOOL("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_bEscape);
|
||||
READ_DATA_BOOL("<EFBFBD><EFBFBD>ȯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_bReturnPosition);
|
||||
|
||||
READ_DATA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_dwRespawnTime);
|
||||
READ_DATA_ARRAY("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_AwardItem, MonsterInfo::MAX_ORIGINAL_ITEM_NUM);
|
||||
READ_DATA_ARRAY("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", tempProtoType.m_MonsterInfo.m_nDropRate, MonsterInfo::MAX_AWARD_KIND);
|
||||
|
||||
monsterProtoTypeVector.push_back(tempProtoType);
|
||||
}
|
||||
|
||||
std::sort(monsterProtoTypeVector.begin(), monsterProtoTypeVector.end());
|
||||
|
||||
for(std::vector<MonsterProtoType>::iterator itr = monsterProtoTypeVector.begin();
|
||||
itr != monsterProtoTypeVector.end() - 1; ++itr)
|
||||
{
|
||||
if(itr->m_MonsterInfo.m_dwKID == (itr+1)->m_MonsterInfo.m_dwKID)
|
||||
{
|
||||
ERRLOG1(g_Log, "<EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ID<49><44> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20><><EFBFBD><EFBFBD>ID:%d", itr->m_MonsterInfo.m_dwKID);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
m_nMonsterNum = monsterProtoTypeVector.size();
|
||||
m_ProtoTypeArray = new MonsterProtoType[m_nMonsterNum];
|
||||
if(NULL == m_ProtoTypeArray)
|
||||
{
|
||||
ERRLOG0(g_Log, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9>Ʈ <20>ʱ<EFBFBD>ȭ <20><><EFBFBD><EFBFBD> : <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD>");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::copy(monsterProtoTypeVector.begin(), monsterProtoTypeVector.end(), m_ProtoTypeArray);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const CMonsterMgr::MonsterProtoType* CMonsterMgr::GetMonsterProtoType(DWORD dwKID)
|
||||
{
|
||||
MonsterProtoType* lpFirst = m_ProtoTypeArray;
|
||||
MonsterProtoType* lpLast = m_ProtoTypeArray + m_nMonsterNum;
|
||||
MonsterProtoType* lpMid = NULL;
|
||||
|
||||
size_t nCount = m_nMonsterNum;
|
||||
size_t nCount2 = 0;
|
||||
|
||||
for (; 0 < nCount; )
|
||||
{
|
||||
nCount2 = nCount / 2;
|
||||
lpMid = lpFirst + nCount2;
|
||||
|
||||
if(lpMid->m_MonsterInfo.m_dwKID < dwKID)
|
||||
{
|
||||
lpFirst = ++lpMid, nCount -= nCount2 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nCount = nCount2;
|
||||
}
|
||||
}
|
||||
|
||||
return (lpFirst != lpLast && !(dwKID < lpFirst->m_MonsterInfo.m_dwKID)) ? lpFirst : NULL;
|
||||
}
|
||||
|
||||
|
||||
const CMonsterMgr::MonsterProtoType* CMonsterMgr::GetMonsterProtoType(char* szName)
|
||||
{
|
||||
for (size_t nIndex = 0; nIndex < m_nMonsterNum; nIndex++)
|
||||
{
|
||||
if (0 == strncmp(szName, m_ProtoTypeArray[nIndex].m_MonsterInfo.m_strName, MonsterInfo::MAX_NAME_LENGTH))
|
||||
{
|
||||
return m_ProtoTypeArray + nIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool CMonsterMgr::LoadMonstersFromBinary(const char* szFileNameBinary)
|
||||
{
|
||||
HANDLE hFile = CreateFile((0 == szFileNameBinary) ? m_szMonsterScriptFileName : szFileNameBinary,
|
||||
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) { return false; }
|
||||
|
||||
CEnsureCloseHandle readFile(hFile);
|
||||
|
||||
DWORD dwRead = 0;
|
||||
DWORD dwFileHighSize = 0;
|
||||
DWORD dwFileSize = GetFileSize(hFile, &dwFileHighSize);
|
||||
|
||||
char* lpAllocated = new char[dwFileSize];
|
||||
if(NULL == lpAllocated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CEnsureDeleteArray<char> allocated(lpAllocated);
|
||||
|
||||
if(!ReadFile(hFile, lpAllocated, dwFileSize, &dwRead, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MonsterProtoType* lpProtoType = 0;
|
||||
MonsterInfo* lpMonsterInfo = 0;
|
||||
CreatureStatus* lpCreatureStatus = 0;
|
||||
|
||||
DWORD dwStructSize = 0;
|
||||
DWORD dwHeaderSize = sizeof(DWORD) + *reinterpret_cast<DWORD*>(lpAllocated) + sizeof(DWORD);
|
||||
DWORD dwBufferSize = *reinterpret_cast<DWORD*>(lpAllocated + dwHeaderSize - sizeof(DWORD));
|
||||
|
||||
char* lpBuffer = new char[dwBufferSize];
|
||||
if(NULL == lpBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CEnsureDeleteArray<char> buffer(lpBuffer);
|
||||
|
||||
char* lpBufferStartPointer = lpBuffer;
|
||||
|
||||
DECOMPRESS(lpAllocated + dwHeaderSize, dwFileSize - dwHeaderSize, lpBuffer, &dwBufferSize);
|
||||
DECODEHEADER(lpBuffer, dwBufferSize, 0, 3);
|
||||
|
||||
m_nMonsterNum = dwBufferSize / sizeof(MonsterProtoType);
|
||||
m_ProtoTypeArray = new MonsterProtoType[m_nMonsterNum];
|
||||
if(NULL == m_ProtoTypeArray)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(size_t nIndex = 0; nIndex < m_nMonsterNum; ++nIndex)
|
||||
{
|
||||
lpMonsterInfo = reinterpret_cast<MonsterInfo*>(lpBuffer);
|
||||
lpCreatureStatus = reinterpret_cast<CreatureStatus*>(lpBuffer + sizeof(MonsterInfo));
|
||||
|
||||
m_ProtoTypeArray[nIndex].m_MonsterInfo = MonsterInfo(*lpMonsterInfo);
|
||||
dwBufferSize -= sizeof(MonsterInfo);
|
||||
lpBuffer += sizeof(MonsterInfo);
|
||||
|
||||
m_ProtoTypeArray[nIndex].m_CreatureStatus = CreatureStatus(*lpCreatureStatus);
|
||||
dwBufferSize -= sizeof(CreatureStatus);
|
||||
lpBuffer += sizeof(CreatureStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CMonsterMgr::SaveMonstersToBinary(const char* szFileNameBinary, const char* szTrashFile)
|
||||
{
|
||||
if(0 == m_ProtoTypeArray)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE hFile = CreateFile((0 == szFileNameBinary) ? m_szMonsterScriptFileName : szFileNameBinary,
|
||||
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) { return false; }
|
||||
|
||||
CEnsureCloseHandle writeFile(hFile);
|
||||
|
||||
const size_t MAX_SCRIPT_FILE_SIZE = m_nMonsterNum * sizeof(MonsterProtoType);
|
||||
|
||||
char *pInputBuffer = new char[MAX_SCRIPT_FILE_SIZE];
|
||||
char *pOutputBuffer = new char[MAX_SCRIPT_FILE_SIZE];
|
||||
|
||||
CEnsureDeleteArray<char> input(pInputBuffer);
|
||||
CEnsureDeleteArray<char> output(pOutputBuffer);
|
||||
|
||||
if (0 == pInputBuffer || 0 == pOutputBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char *InputStartPointer = pInputBuffer;
|
||||
char *OutputStartPointer = pOutputBuffer;
|
||||
|
||||
DWORD dwInputBufferSize = 0;
|
||||
DWORD dwOutputBufferSize = 0;
|
||||
|
||||
for(size_t nCount = 0; nCount < m_nMonsterNum; ++nCount)
|
||||
{
|
||||
memcpy(pInputBuffer, &m_ProtoTypeArray[nCount].m_MonsterInfo, sizeof(MonsterInfo));
|
||||
dwInputBufferSize += sizeof(MonsterInfo);
|
||||
pInputBuffer += sizeof(MonsterInfo);
|
||||
|
||||
memcpy(pInputBuffer, &m_ProtoTypeArray[nCount].m_CreatureStatus, sizeof(CreatureStatus));
|
||||
dwInputBufferSize += sizeof(CreatureStatus);
|
||||
pInputBuffer += sizeof(CreatureStatus);
|
||||
}
|
||||
|
||||
ENCODEHEADER(InputStartPointer, dwInputBufferSize, 0, 3);
|
||||
COMPRESS(InputStartPointer, dwInputBufferSize, pOutputBuffer, &dwOutputBufferSize);
|
||||
|
||||
DWORD dwWritten = 0;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>) <20>ڷ<EFBFBD>
|
||||
HANDLE hTrashFile = CreateFile(szTrashFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hTrashFile == INVALID_HANDLE_VALUE) { return false; }
|
||||
|
||||
CEnsureCloseHandle trashFile(hTrashFile);
|
||||
|
||||
DWORD dwRead = 0;
|
||||
DWORD dwFileHighSize = 0;
|
||||
DWORD dwFileSize = GetFileSize(hTrashFile, &dwFileHighSize);
|
||||
|
||||
char* lpAllocated = new char[dwFileSize];
|
||||
if(NULL == lpAllocated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CEnsureDeleteArray<char> allocated(lpAllocated);
|
||||
|
||||
if (!ReadFile(hTrashFile, lpAllocated, dwFileSize, &dwRead, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>) <20>ڷ<EFBFBD>
|
||||
WriteFile(hFile, &dwFileSize, sizeof(DWORD), &dwWritten, 0);
|
||||
WriteFile(hFile, lpAllocated, dwFileSize, &dwWritten, 0);
|
||||
|
||||
// <20>ùٸ<C3B9> <20>ڷ<EFBFBD>
|
||||
WriteFile(hFile, &dwInputBufferSize, sizeof(DWORD), &dwWritten, 0);
|
||||
WriteFile(hFile, pOutputBuffer, dwOutputBufferSize, &dwWritten, 0);
|
||||
return true;
|
||||
}
|
||||
50
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterMgr.h
Normal file
50
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterMgr.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef _MONSTER_MGR_H_
|
||||
#define _MONSTER_MGR_H_
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#define g_MonsterMgr CMonsterMgr::GetInstance()
|
||||
|
||||
#include <Pattern/Singleton.h>
|
||||
#include "MonsterStructure.h"
|
||||
#include "../Character/CharacterStructure.h"
|
||||
#include "../../Utility/DelimitedFile.h"
|
||||
|
||||
class CMonsterMgr : public CSingleton<CMonsterMgr>
|
||||
{
|
||||
public:
|
||||
|
||||
struct MonsterProtoType
|
||||
{
|
||||
MonsterInfo m_MonsterInfo;
|
||||
CreatureStatus m_CreatureStatus;
|
||||
|
||||
inline bool operator < (MonsterProtoType& rhs)
|
||||
{ return m_MonsterInfo.m_dwKID < rhs.m_MonsterInfo.m_dwKID; }
|
||||
};
|
||||
|
||||
~CMonsterMgr();
|
||||
|
||||
bool LoadMonstersFromFile(const char* szFileName = 0);
|
||||
bool LoadMonstersFromBinary(const char* szFileNameBinary = 0);
|
||||
bool SaveMonstersToBinary(const char* szFileNameBinary = 0, const char* szTrashFile = 0);
|
||||
|
||||
void ClearProtoType();
|
||||
|
||||
const MonsterProtoType* GetMonsterProtoType(DWORD dwKID);
|
||||
const MonsterProtoType* GetMonsterProtoType(char* szName);
|
||||
|
||||
private:
|
||||
|
||||
CMonsterMgr();
|
||||
|
||||
static const char* m_szMonsterScriptFileName;
|
||||
static CMonsterMgr ms_this;
|
||||
|
||||
MonsterProtoType* m_ProtoTypeArray;
|
||||
size_t m_nMonsterNum;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
50
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterStructure.cpp
Normal file
50
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterStructure.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "stdafx.h"
|
||||
#include <algorithm>
|
||||
#include "MonsterStructure.h"
|
||||
|
||||
MonsterInfo::MonsterInfo()
|
||||
: m_dwKID(0), m_dwRespawnTime(0), m_fSize(0), m_fAttackAngle(0), m_nSkillPattern(0), m_nSkillLevel(0),
|
||||
m_bStealth(false), m_bFirstAttack(false), m_bReturnPosition(false), m_bEscape(false)
|
||||
{
|
||||
int nFill = MAX_ORIGINAL_ITEM_NUM; std::fill_n(m_AwardItem, nFill, 0);
|
||||
nFill = MAX_AWARD_KIND; std::fill_n(m_nDropRate, nFill, 0);
|
||||
nFill = MAX_NAME_LENGTH; std::fill_n(m_strName, nFill, 0);
|
||||
nFill = MAX_MODELING_FLAG_LENGTH; std::fill_n(m_strModelingFlag, nFill, 0);
|
||||
float fFill = MAX_HITBOX_NUM; std::fill_n(m_fHitBox, fFill, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
MonsterInfo::MonsterPattern MonsterInfo::GetMonsterPattern(const char* szMonsterType)
|
||||
{
|
||||
struct TypeAndName
|
||||
{
|
||||
const char* m_szName;
|
||||
const MonsterPattern m_MonsterPattern;
|
||||
|
||||
TypeAndName(const char* szName, const MonsterPattern ePattern)
|
||||
: m_szName(szName), m_MonsterPattern(ePattern) { }
|
||||
};
|
||||
|
||||
const int MAX_TYPE_NUM = 6;
|
||||
static TypeAndName monsterTypeName[MAX_TYPE_NUM] =
|
||||
{
|
||||
TypeAndName("Warrior", PATTERN_WARRIOR),
|
||||
TypeAndName("Defender", PATTERN_DEFENDER),
|
||||
TypeAndName("Mage", PATTERN_MAGE),
|
||||
TypeAndName("Acolyte", PATTERN_ACOLYTE),
|
||||
TypeAndName("Boss", PATTERN_BOSS),
|
||||
TypeAndName("BG", PATTERN_BG)
|
||||
};
|
||||
|
||||
TypeAndName* lpTypeNamePastEnd = monsterTypeName + MAX_TYPE_NUM;
|
||||
for(TypeAndName* lpTypeName = monsterTypeName; lpTypeName != lpTypeNamePastEnd; ++lpTypeName)
|
||||
{
|
||||
if(0 == strcmp(szMonsterType, lpTypeName->m_szName))
|
||||
{
|
||||
return lpTypeName->m_MonsterPattern;
|
||||
}
|
||||
}
|
||||
|
||||
return PATTERN_COMMON;
|
||||
}
|
||||
|
||||
75
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterStructure.h
Normal file
75
GameTools/GLOBALSCRIPT/Creature/Monster/MonsterStructure.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef _MONSTER_STRUCTURE_H_
|
||||
#define _MONSTER_STRUCTURE_H_
|
||||
|
||||
#include "../CreatureStructure.h"
|
||||
|
||||
#pragma pack(8)
|
||||
|
||||
struct MonsterInfo
|
||||
{
|
||||
enum MaxNumber
|
||||
{
|
||||
MAX_MOTION_NUM = 4, // <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
MAX_ORIGINAL_ITEM_NUM = 2,
|
||||
MAX_AWARD_KIND = 9,
|
||||
|
||||
MAX_NAME_LENGTH = 32,
|
||||
MAX_MODELING_FLAG_LENGTH = 32
|
||||
};
|
||||
|
||||
enum MonsterPattern
|
||||
{
|
||||
PATTERN_COMMON = 0,
|
||||
PATTERN_WARRIOR, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
PATTERN_DEFENDER, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
PATTERN_MAGE, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
PATTERN_ACOLYTE, // <20><><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD>Ʈ
|
||||
PATTERN_BOSS, // <20><><EFBFBD><EFBFBD>
|
||||
PATTERN_BG // <20><><EFBFBD><EFBFBD>(?)
|
||||
};
|
||||
|
||||
enum HitBox
|
||||
{
|
||||
XPlus = 0, XMinus, YPlus, YMinus,
|
||||
MAX_HITBOX_NUM = 4
|
||||
};
|
||||
|
||||
enum Z3D_CHR_ACTION
|
||||
{
|
||||
Z3D_CA_WALK = 8, // <20>ȱ<EFBFBD>
|
||||
Z3D_CA_RUN = 1, // <20><EFBFBD><DEB8><EFBFBD>
|
||||
Z3D_CA_CASTING = 50, // ij<><C4B3><EFBFBD><EFBFBD>
|
||||
Z3D_CA_ATTACK = 51 // <20><><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
|
||||
MotionInfo m_MonsterMotions[MAX_MOTION_NUM]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ൿ <20><><EFBFBD><EFBFBD> (<28>ȱ<EFBFBD>, <20><EFBFBD><DEB8><EFBFBD>, <20><><EFBFBD><EFBFBD>, ij<><C4B3><EFBFBD><EFBFBD>)
|
||||
char m_strName[MAX_NAME_LENGTH]; // <20≯<EFBFBD>
|
||||
char m_strModelingFlag[MAX_MODELING_FLAG_LENGTH]; // <20><EFBFBD> <20><><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
|
||||
float m_fHitBox[MAX_HITBOX_NUM]; // Ÿ<>ݹڽ<DDB9>
|
||||
|
||||
unsigned long m_AwardItem[MAX_ORIGINAL_ITEM_NUM]; // <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD>
|
||||
int m_nDropRate[MAX_AWARD_KIND]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
DWORD m_dwKID; // <20><><EFBFBD><EFBFBD> ID
|
||||
float m_fSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
DWORD m_dwRespawnTime; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8>
|
||||
float m_fAttackAngle; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
int m_nSkillPattern; // <20><>ų <20><><EFBFBD><EFBFBD>
|
||||
int m_nSkillLevel; // <20><>ų <20><><EFBFBD><EFBFBD>
|
||||
|
||||
bool m_bStealth; // <20><><EFBFBD>ڽ<EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
bool m_bFirstAttack; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
bool m_bReturnPosition; // Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD>ư<EFBFBD><C6B0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
bool m_bEscape; // <20>ڽ<EFBFBD><DABD><EFBFBD> HP<48><50> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD>ħ <20><><EFBFBD><EFBFBD>
|
||||
|
||||
MonsterInfo();
|
||||
static MonsterPattern GetMonsterPattern(const char* szMonsterType);
|
||||
};
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user