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:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "CharacterStructure.h"
CharacterStatus::CharacterStatus()
: m_nSTR(0), m_nDEX(0), m_nCON(0), m_nINT(0), m_nWIS(0)
{
}
CharacterStatus::CharacterStatus(CHAR_INFOST& characterDBData)
: m_nSTR(characterDBData.STR), m_nDEX(characterDBData.DEX), m_nCON(characterDBData.CON),
m_nINT(characterDBData.INT), m_nWIS(characterDBData.WIS)
{
}
void CharacterStatus::Init(CHAR_INFOST& characterDBData)
{
m_nSTR = characterDBData.STR;
m_nDEX = characterDBData.DEX;
m_nCON = characterDBData.CON;
m_nINT = characterDBData.INT;
m_nWIS = characterDBData.WIS;
}
CharacterFightInfo::CharacterFightInfo()
: m_pDuelOpponent(NULL), m_cResult(0)
{
}

View File

@@ -0,0 +1,89 @@
#ifndef _CHARACTER_STRUCTURE_H_
#define _CHARACTER_STRUCTURE_H_
#include "../CreatureStructure.h"
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CCharacter;
// ij<><C4B3><EFBFBD>Ϳ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD>
struct CharacterStatus
{
short m_nSTR; // ij<><C4B3><EFBFBD><EFBFBD> STR
short m_nDEX; // ij<><C4B3><EFBFBD><EFBFBD> DEX
short m_nCON; // ij<><C4B3><EFBFBD><EFBFBD> CON
short m_nINT; // ij<><C4B3><EFBFBD><EFBFBD> INT
short m_nWIS; // ij<><C4B3><EFBFBD><EFBFBD> WIS
CharacterStatus();
CharacterStatus(CHAR_INFOST& characterDBData);
void Init(CHAR_INFOST& characterDBData);
};
typedef CharacterStatus* LPCharacterStatus;
// -----------------------------------------------------------------------
// DB <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>о<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>. <20>߰<EFBFBD><DFB0>߰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> DB<44><42> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <20>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>߿<EFBFBD><DFBF><EFBFBD> <20>ǵ帮<C7B5><E5B8AE> <20>ʴ´<CAB4>. ( <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> ... )
struct CharacterDBData
{
CHAR_INFOST m_Info; // <20>ܸ<EFBFBD>, <20≯<EFBFBD>, <20>ɷ<EFBFBD>ġ, hp,mp <20><> <20><20><><EFBFBD><EFBFBD>
CHAR_POS m_Pos; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD> ( Respawn <20><><EFBFBD><EFBFBD> )
SKILL m_Skill;
QUICK m_Quick;
bool m_Admin;
};
typedef CharacterDBData* LPCharacterDBData;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP<49><50> <20><><EFBFBD><EFBFBD>.
struct ConnectInfo
{
SOCKADDR_IN m_siAgentHost; // agent UDP address of host
SOCKADDR_IN m_siPrivateHost; // private UDP address of host
SOCKADDR_IN m_siPublicHost; // public UDP address of host
};
typedef ConnectInfo* LPConnectInfo;
// ij<><C4B3><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>)
struct CharacterFightInfo
{
enum _VictoryOrDefeat { DRAW = 0, WIN = 1, LOSE = 2, DEAD_TO_CHARACTER = 3 };
CCharacter* m_pDuelOpponent;
char m_cResult;
CharacterFightInfo();
};
typedef CharacterFightInfo* LPCharacterFightInfo;
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD>
struct CharacterMasteryInfo
{
union {
struct {
unsigned short m_SwordMastery : 2;
unsigned short m_AxeMastery : 2;
unsigned short m_BluntMastery : 2;
unsigned short m_DaggerMastery : 2;
unsigned short m_CrushWeapon : 2;
unsigned short m_Blade : 2;
unsigned short m_ClawMastery : 2;
unsigned short m_Remainder : 2;
} MasteryKind;
unsigned short m_wMasteryInfo;
};
CharacterMasteryInfo() : m_wMasteryInfo(0) { }
CharacterMasteryInfo(unsigned short wMasteryInfo) : m_wMasteryInfo(wMasteryInfo) { }
};
typedef CharacterMasteryInfo* LPCharacterMasteryInfo;
#endif

View File

@@ -0,0 +1,339 @@
#include "stdafx.h"
#include <algorithm>
#ifndef _RYL_GAME_CLIENT_
#include "./Character/CharacterClass.h"
#endif
#include "CreatureStructure.h"
#include "./Character/CharacterStructure.h"
#include "../Item/Item.h"
MotionInfo::MotionInfo()
: m_fDirection(0.0f), m_fVelocity(0.0f), m_wAction(0), m_dwFrame(0) { }
StatusInfo::StatusInfo()
: m_nCriticalType(0), m_nCriticalPercentage(0),
m_nMinDamage(0), m_nMaxDamage(0), m_fDRC(0.0f), m_nOffenceRevision(0),
m_nDefence(0), m_nDefenceRevision(0),
m_nMagicResistance(0), m_nBlockingPercentage(0),
m_nAttackSpeed(0), m_nMoveSpeed(0), m_nAttackRange(0), m_nRangeAttackDistance(0),
m_nMaxHP(0), m_nMaxMP(0), m_nHPRegenAmount(0), m_nMPRegenAmount(0)
{
int nMaxAttributeNum = MAX_ATTRIBUTE_NUM;
std::fill_n(m_nWeaponAttributeLevel, nMaxAttributeNum, 0);
std::fill_n(m_nAttributeResistance, nMaxAttributeNum, 0);
}
#ifndef _RYL_GAME_CLIENT_
bool StatusInfo::CalculateStatus(const CharacterStatus& characterStatus,
const unsigned short nLevel, const unsigned short nClass, unsigned char cUsingWeaponType)
{
switch (nClass)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::Fighter:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20>α<EFBFBD>
case CClass::Rouge:
{
m_nOffenceRevision = characterStatus.m_nDEX / 4;
m_nDefenceRevision = characterStatus.m_nDEX / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::Mage:
{
m_nOffenceRevision = characterStatus.m_nINT / 4;
m_nDefenceRevision = characterStatus.m_nINT / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD>Ʈ
case CClass::Acolyte:
{
m_nOffenceRevision = characterStatus.m_nWIS / 2;
m_nDefenceRevision = characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::Defender:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 800;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::Warrior:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 550;
} break;
// <20><><EFBFBD>ؽ<EFBFBD>
case CClass::Assasin:
{
m_nOffenceRevision = characterStatus.m_nDEX / 4;
m_nDefenceRevision = characterStatus.m_nDEX / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 800;
} break;
// <20><>ó
case CClass::Archer:
{
m_nOffenceRevision = characterStatus.m_nDEX / 4;
m_nDefenceRevision = characterStatus.m_nDEX / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 550;
} break;
// <20>Ҽ<EFBFBD><D2BC><EFBFBD>
case CClass::Sorcerer:
{
m_nOffenceRevision = characterStatus.m_nINT / 4;
m_nDefenceRevision = characterStatus.m_nINT / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 800;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::Enchanter:
{
m_nOffenceRevision = characterStatus.m_nINT / 4;
m_nDefenceRevision = characterStatus.m_nINT / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 550;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
case CClass::Priest:
{
m_nOffenceRevision = characterStatus.m_nWIS / 2;
m_nDefenceRevision = characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 800;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 300;
} break;
// Ŭ<><C5AC><EFBFBD><EFBFBD>
case CClass::Cleric:
{
m_nOffenceRevision = characterStatus.m_nWIS / 2;
m_nDefenceRevision = characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 550;
} break;
// <20>Ĺ<EFBFBD><C4B9><EFBFBD>Ʈ
case CClass::Combatant:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD><EFBFBD>
case CClass::Officetor:
{
m_nOffenceRevision = characterStatus.m_nDEX / 4;
m_nDefenceRevision = characterStatus.m_nDEX / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD>÷<EFBFBD>
case CClass::Templar:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 800;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 300;
} break;
// <20><><EFBFBD><EFBFBD>Ŀ
case CClass::Attacker:
{
m_nOffenceRevision = characterStatus.m_nSTR / 4;
m_nDefenceRevision = characterStatus.m_nSTR / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 550;
} break;
// <20>ų<EFBFBD>
case CClass::Gunner:
{
m_nOffenceRevision = characterStatus.m_nDEX / 2;
m_nDefenceRevision = characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 800;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::RuneOff:
{
m_nOffenceRevision = characterStatus.m_nINT / 4;
m_nDefenceRevision = characterStatus.m_nINT / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 300;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel, (characterStatus.m_nWIS - 20) * nLevel / 2) + nLevel * 40 + 800;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::LifeOff:
{
m_nOffenceRevision = characterStatus.m_nWIS / 2;
m_nDefenceRevision = characterStatus.m_nWIS / 2 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 550;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 550;
} break;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
case CClass::ShadowOff:
{
m_nOffenceRevision = characterStatus.m_nDEX / 4;
m_nDefenceRevision = characterStatus.m_nDEX / 4 + characterStatus.m_nDEX / 5;
m_nMaxHP = (characterStatus.m_nCON - 20) * nLevel / 2 + nLevel * 40 + 800;
m_nMaxMP = max((characterStatus.m_nINT - 20) * nLevel / 2, (characterStatus.m_nWIS - 20) * nLevel) + nLevel * 40 + 300;
} break;
default:
{
#ifdef ERRLOG0
ERRLOG0(g_Log, "Ŭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> None<6E><65> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.");
#endif
return false;
} break;
}
// Ȱ, <20><><EFBFBD><EFBFBD>
if (cUsingWeaponType == Item::CItemType::BOW || cUsingWeaponType == Item::CItemType::CROSSBOW)
{
m_nMinDamage = characterStatus.m_nDEX / 2;
m_nMaxDamage = characterStatus.m_nDEX / 2;
}
// <20>׿<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
else
{
m_nMinDamage = characterStatus.m_nSTR / 3;
m_nMaxDamage = characterStatus.m_nSTR / 3;
// <20>α<EFBFBD>, <20><><EFBFBD>ؽ<EFBFBD>, <20><>ó, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> DEX<45><58> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
if (CClass::Rouge == CClass::GetPreviousJob(static_cast<unsigned char>(nClass)) ||
CClass::ShadowOff == nClass)
{
m_nMinDamage += characterStatus.m_nDEX / 6;
m_nMaxDamage += characterStatus.m_nDEX / 6;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>
m_nDefence = 0;
m_nBlockingPercentage = 0;
m_fDRC = 0;
m_nCriticalPercentage = characterStatus.m_nDEX / 5;
m_nCriticalType = 0;
m_nMagicResistance = characterStatus.m_nWIS / 3;
m_nAttackSpeed = 0;
m_nMoveSpeed = 0;
m_nAttackRange = 0;
m_nRangeAttackDistance = 0;
m_nHPRegenAmount = ((characterStatus.m_nCON - 20) * nLevel + nLevel * 40 + 300) / 50;
m_nMPRegenAmount = ((characterStatus.m_nINT + characterStatus.m_nWIS - 40) * nLevel + nLevel * 40 + 300) / 50;
for (int nAttribute = 0; nAttribute < MAX_ATTRIBUTE_NUM; ++nAttribute)
{
m_nWeaponAttributeLevel[nAttribute] = 0;
m_nAttributeResistance[nAttribute] = 0;
}
return true;
}
#endif
CreatureStatus::CreatureStatus()
: m_nLevel(0), m_nExp(0), m_nNowHP(0), m_nNowMP(0)
{
}
CreatureStatus::CreatureStatus(CHAR_INFOST& characterDBData)
: m_nLevel(characterDBData.Level), m_nExp(characterDBData.Exp),
m_nNowHP(characterDBData.HP), m_nNowMP(characterDBData.MP)
{
}
void CreatureStatus::Init(CHAR_INFOST& characterDBData)
{
m_nLevel = characterDBData.Level;
m_nExp = characterDBData.Exp;
m_nNowHP = characterDBData.HP;
m_nNowMP = characterDBData.MP;
}

View File

@@ -0,0 +1,138 @@
#ifndef _CREATURE_STRUCTURE_H_
#define _CREATURE_STRUCTURE_H_
#include <winsock2.h>
#include <windows.h>
#include <cmath>
#include <DB/DBDefine.h>
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
struct CreatureStatus;
struct CharacterStatus;
// <20><> <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD>
struct Position
{
float m_fPointX; // Point X <20><>ǥ
float m_fPointY; // Point Y <20><>ǥ
float m_fPointZ; // Point Z <20><>ǥ
inline Position();
inline Position(const POS& Pos);
inline Position(const Position& Pos);
inline Position(float fPointX, float fPointY, float fPointZ);
inline unsigned int GetDistance(const Position& rhs) const
{
return (unsigned int)sqrt((m_fPointX - rhs.m_fPointX) * (m_fPointX - rhs.m_fPointX) +
(m_fPointY - rhs.m_fPointY) * (m_fPointY - rhs.m_fPointY) +
(m_fPointZ - rhs.m_fPointZ) * (m_fPointZ - rhs.m_fPointZ));
}
};
typedef Position* LPPosition;
inline Position::Position()
: m_fPointX(0.0f), m_fPointY(0.0f), m_fPointZ(0.0f) { }
inline Position::Position(const POS& Pos)
: m_fPointX(Pos.fPointX), m_fPointY(Pos.fPointY), m_fPointZ(Pos.fPointZ) { }
inline Position::Position(const Position& Pos)
: m_fPointX(Pos.m_fPointX), m_fPointY(Pos.m_fPointY), m_fPointZ(Pos.m_fPointZ) { }
inline Position::Position(float fPointX, float fPointY, float fPointZ)
: m_fPointX(fPointX), m_fPointY(fPointY), m_fPointZ(fPointZ) { }
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
struct MotionInfo
{
float m_fDirection; // <20>ٶ󺸴<D9B6> <20><><EFBFBD><EFBFBD>
float m_fVelocity; // <20>ӵ<EFBFBD>
unsigned short m_wAction; // <20><><EFBFBD>ϴ<EFBFBD> <20>ൿ
unsigned long m_dwFrame; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ( <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, NPC<50><43> <20><><EFBFBD><EFBFBD> )
MotionInfo();
};
typedef MotionInfo* LPMotionInfo;
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͽ<EFBFBD> <20><><EFBFBD><EFBFBD>.
struct StatusInfo
{
enum {
ATTRIBUTE_FIRE = 0,
ATTRIBUTE_LIGHTNING = 1,
ATTRIBUTE_COLD = 2,
ATTRIBUTE_DRAIN = 3,
ATTRIBUTE_POISON = 4,
MAX_ATTRIBUTE_NUM = 5
};
short m_nCriticalType; // ũ<><C5A9>Ƽ<EFBFBD><C6BC> Ÿ<><C5B8> ( <20>߰<EFBFBD> ȿ<><C8BF> Ÿ<><C5B8> ex> <20><> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20>б<EFBFBD> - <20><><EFBFBD><EFBFBD> ... )
short m_nCriticalPercentage; // ũ<><C5A9>Ƽ<EFBFBD><C6BC> Ȯ<><C8AE>
short m_nMinDamage; // <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
short m_nMaxDamage; // <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float m_fDRC; // DRC
short m_nOffenceRevision; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
short m_nDefence; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
short m_nDefenceRevision; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
short m_nMagicResistance; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>׷<EFBFBD>
short m_nBlockingPercentage; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
short m_nAttackSpeed; // <20><><EFBFBD><EFBFBD> <20>ӵ<EFBFBD>.
short m_nMoveSpeed; // <20>̵<EFBFBD> <20>ӵ<EFBFBD>.
short m_nAttackRange; // <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD>. // <20><><EFBFBD><EFBFBD> = cm
short m_nRangeAttackDistance; // <20><><EFBFBD>Ÿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD>. // <20><><EFBFBD><EFBFBD> = m
unsigned short m_nMaxHP; // <20>ִ<EFBFBD> HP<48><50>
unsigned short m_nMaxMP; // <20>ִ<EFBFBD> MP<4D><50>
short m_nHPRegenAmount; // <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> HP<48><50> Regen <20><>
short m_nMPRegenAmount; // <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> MP<4D><50> Regen <20><>
short m_nWeaponAttributeLevel[MAX_ATTRIBUTE_NUM]; // <20><><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
short m_nAttributeResistance[MAX_ATTRIBUTE_NUM]; // <20>Ӽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
StatusInfo(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
#ifndef _RYL_GAME_CLIENT_
bool CalculateStatus(const CharacterStatus& characterStatus,
const unsigned short nLevel, const unsigned short nClass, unsigned char cUsingWeaponType);
#endif
};
typedef StatusInfo* LPStatusInfo;
#pragma pack(8)
//------------------------------------------------------------------------------------
// TODO : memory alignment <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
// : 4byte<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD> alignment <20><> <20>ǵ<EFBFBD><C7B5><EFBFBD> <20><> <20><>.
// : <20>޸<EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD> ũ<><20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> short<72><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>.
struct CreatureStatus
{
// <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ɷ<EFBFBD>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> ( <20><><EFBFBD>ӻ󿡼<D3BB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD> <20><> )
__int64 m_nExp; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
int m_nLevel; // <20><><EFBFBD><EFBFBD>
unsigned short m_nNowHP; // <20><><EFBFBD><EFBFBD> HP
unsigned short m_nNowMP; // <20><><EFBFBD><EFBFBD> MP, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ밪<D6B4><EBB0AA><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ.
StatusInfo m_StatusInfo; // <20><><EFBFBD>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̰<EFBFBD><CCB0><EFBFBD> <20><><EFBFBD><EFBFBD>.
CreatureStatus();
CreatureStatus(CHAR_INFOST& characterDBData);
void Init(CHAR_INFOST& characterDBData);
};
typedef CreatureStatus* LPCreatureStatus;
#pragma pack()
#endif

View 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;
}

View 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

View 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;
}

View 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

View File

@@ -0,0 +1,672 @@
// NPCList.cpp: implementation of the CNPCList class.
//
//////////////////////////////////////////////////////////////////////
#include "NPCList.h"
#include <ScriptEngine/ScriptEngine.h>
CNPCList g_NPCList;
static SCRIPT m_scQuestScript;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static void ScriptErrorMessage(const char *msg)
{
MessageBox(NULL, msg, "Script Error", MB_OK);
}
//static void SetNpc(int nUID, int nJob, const char *strNpcSkin, const char *strNpcName)
static void SetNpc(int nZone, int nUID, int nJob, const char *strNpcSkin, const char *strNpcName)
{
if(nZone != g_NPCList.GetZone()) return;
//
if(!g_NPCList.IsExistNpc(nUID))
{
LPNPCNode lpNPCNode = new NPCNode;
lpNPCNode->m_dwUID = (unsigned long)nUID;
lpNPCNode->m_dwJob = (unsigned long)nJob;
lpNPCNode->m_strNpcSkin = new char[strlen(strNpcSkin) + 1];
strcpy(lpNPCNode->m_strNpcSkin, strNpcSkin);
lpNPCNode->m_fDirection = 0.0f;
lpNPCNode->m_fPosX = 0.0f;
lpNPCNode->m_fPosY = 0.0f;
lpNPCNode->m_fPosZ = 0.0f;
lpNPCNode->m_strNpcName = new char[strlen(strNpcName) + 1];
strcpy(lpNPCNode->m_strNpcName, strNpcName);
g_NPCList.AddNpc(lpNPCNode);
}
}
static void SetPosition(int nUID, float fDirection, float fPosX, float fPosY, float fPosZ)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
lpNode->m_fDirection = fDirection + (3.1415926535f);
lpNode->m_fPosX = fPosX;
lpNode->m_fPosY = fPosY;
lpNode->m_fPosZ = fPosZ;
}
}
static void AddWords(int nUID, const char *strNpcScript)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
char *strScript = new char[strlen(strNpcScript) + 1];
strcpy(strScript, strNpcScript);
LPDialogNode lpWord = new DialogNode;
lpWord->m_wKindWord = 0;
lpWord->m_wDialogFlag = 0;
lpWord->m_strWord = strScript;
lpNode->m_lstScript.push_back(lpWord);
}
}
static void AddDialog(int nUID, int nPage, int nFlag, const char *strNpcScript)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
char *strScript = new char[strlen(strNpcScript) + 1];
strcpy(strScript, strNpcScript);
LPDialogNode lpWord = new DialogNode;
lpWord->m_wKindWord = (unsigned short)nPage;
lpWord->m_wDialogFlag = (unsigned short)nFlag;
lpWord->m_strWord = strScript;
lpNode->m_lstScript.push_back(lpWord);
}
}
static void AddItem(int nUID, int nKindItem, int nTabPage, int nIndexPosition)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
LPITEMNode lpItem = lpNode->GetITEMNode(nKindItem);
if(!lpItem)
{
lpItem = new ITEMNode;
lpItem->m_wKindItem = (unsigned short)nKindItem;
lpItem->m_wSkill = 0;
lpItem->m_wSkillLevel = 0;
lpItem->m_wTabPage = (unsigned short)nTabPage;
lpItem->m_dwIndexPosition = (unsigned long)nIndexPosition;
lpNode->m_lstItem.push_back(lpItem);
}
}
}
static void AddSkillBook(int nUID, int nKindItem, int nSkill, int nSkillLevel, int nTabPage, int nIndexPosition)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
LPITEMNode lpItem;
lpItem = new ITEMNode;
lpItem->m_wKindItem = (unsigned short)nKindItem;
lpItem->m_wSkill = (unsigned short)nSkill;
lpItem->m_wSkillLevel = (unsigned short)nSkillLevel;
lpItem->m_wTabPage = (unsigned short)nTabPage;
lpItem->m_dwIndexPosition = (unsigned long)nIndexPosition;
lpNode->m_lstItem.push_back(lpItem);
}
}
static void AddZoneMove(int nUID, int nZoneNumber, float fPosX, float fPosY, float fPosZ)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
LPWarpNode lpZone = new WarpNode;
lpZone->m_wNumber = (unsigned short)lpNode->m_lstWarpZone.size();
lpZone->m_wZoneNumber = (unsigned short)nZoneNumber;
lpZone->m_fPosX = fPosX;
lpZone->m_fPosY = fPosY;
lpZone->m_fPosZ = fPosZ;
lpNode->m_lstWarpZone.push_back(lpZone);
}
}
static void AddQuest(int nUID, int nQuestID, int nMinLevel, int nMaxLevel, int nClass, int nCompleteClass, const char *strQuestFunc)
{
LPNPCNode lpNode = g_NPCList.GetNPCNode(nUID);
if(lpNode)
{
g_NPCList.m_lpQuestNode = new QuestNode;
g_NPCList.m_lpQuestNode->m_wQuestID = (unsigned short)nQuestID;
g_NPCList.m_lpQuestNode->m_wMinLevel = (unsigned short)nMinLevel;
g_NPCList.m_lpQuestNode->m_wMaxLevel = (unsigned short)nMaxLevel;
g_NPCList.m_lpQuestNode->m_dwClass = nClass;
g_NPCList.m_lpQuestNode->m_dwCompletedQuest = nCompleteClass;
g_NPCList.m_lpQuestNode->m_strQuestTitle = NULL;
SE_FUNC Func_Quest = _SE_GetScriptFunction(m_scQuestScript, T_VOID, strQuestFunc, 0 );
_SE_CallScriptFunction(m_scQuestScript, Func_Quest);
lpNode->m_lstQuest.push_back(g_NPCList.m_lpQuestNode);
g_NPCList.m_lpQuestNode = NULL;
g_NPCList.m_lpPhaseNode = NULL;
g_NPCList.m_lpTriggerNode = NULL;
}
}
static void QuestTitle(const char *strQuestTitle)
{
if(g_NPCList.m_lpQuestNode)
{
char *strScript = new char[strlen(strQuestTitle) + 1];
strcpy(strScript, strQuestTitle);
g_NPCList.m_lpQuestNode->m_strQuestTitle = strScript;
}
}
static void AddPhase(int nPhaseNumber, const char *strQuestDesc)
{
if(g_NPCList.m_lpQuestNode)
{
g_NPCList.m_lpPhaseNode = new PhaseNode;
g_NPCList.m_lpPhaseNode->m_dwPhaseNumber = nPhaseNumber;
char *strScript = new char[strlen(strQuestDesc) + 1];
strcpy(strScript, strQuestDesc);
g_NPCList.m_lpPhaseNode->m_strPhaseDesc = strScript;
g_NPCList.m_lpQuestNode->m_lstPhase.push_back(g_NPCList.m_lpPhaseNode);
g_NPCList.m_lpTriggerNode = NULL;
}
}
static void Trigger_Start(void)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_START;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = 0;
g_NPCList.m_lpTriggerNode->m_dwZoneID = 0;
g_NPCList.m_lpTriggerNode->m_fDistance = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosX = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosY = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosZ = 0.0f;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Trigger_Puton(int nItemID, int nZoneID, float fPosX, float fPosY, float fPosZ, float fDistance)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_PUTON;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = nItemID;
g_NPCList.m_lpTriggerNode->m_dwZoneID = nZoneID;
g_NPCList.m_lpTriggerNode->m_fDistance = fDistance;
g_NPCList.m_lpTriggerNode->m_fPosX = fPosX;
g_NPCList.m_lpTriggerNode->m_fPosY = fPosY;
g_NPCList.m_lpTriggerNode->m_fPosZ = fPosZ;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Trigger_Geton(int nItemID, int nZoneID, float fPosX, float fPosY, float fPosZ, float fDistance)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_GETON;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = nItemID;
g_NPCList.m_lpTriggerNode->m_dwZoneID = nZoneID;
g_NPCList.m_lpTriggerNode->m_fDistance = fDistance;
g_NPCList.m_lpTriggerNode->m_fPosX = fPosX;
g_NPCList.m_lpTriggerNode->m_fPosY = fPosY;
g_NPCList.m_lpTriggerNode->m_fPosZ = fPosZ;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Trigger_Talk(int nNpcID)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_TALK;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = nNpcID;
g_NPCList.m_lpTriggerNode->m_dwZoneID = 0;
g_NPCList.m_lpTriggerNode->m_fDistance = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosX = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosY = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosZ = 0.0f;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Trigger_Kill(int nMonsterID)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_KILL;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = nMonsterID;
g_NPCList.m_lpTriggerNode->m_dwZoneID = 0;
g_NPCList.m_lpTriggerNode->m_fDistance = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosX = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosY = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosZ = 0.0f;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Trigger_Pick(int nItemID)
{
if(g_NPCList.m_lpPhaseNode)
{
g_NPCList.m_lpTriggerNode = new TriggerNode;
g_NPCList.m_lpTriggerNode->m_dwTriggerKind = TRIGGER_PICK;
g_NPCList.m_lpTriggerNode->m_dwTriggerID = nItemID;
g_NPCList.m_lpTriggerNode->m_dwZoneID = 0;
g_NPCList.m_lpTriggerNode->m_fDistance = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosX = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosY = 0.0f;
g_NPCList.m_lpTriggerNode->m_fPosZ = 0.0f;
g_NPCList.m_lpPhaseNode->m_lstTrigger.push_back(g_NPCList.m_lpTriggerNode);
}
}
static void Event_Disappear(int nItemID, int nAmount)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_DISAPPEAR;
lpEventNode->m_dwEventNumber = nItemID;
lpEventNode->m_dwEventAmount = nAmount;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_Get(int nItemID, int nAmount)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_GET;
lpEventNode->m_dwEventNumber = nItemID;
lpEventNode->m_dwEventAmount = nAmount;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_Spawn(int nMonsterID, float fPosX, float fPosY, float fPosZ)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_SPAWN;
lpEventNode->m_dwEventNumber = nMonsterID;
lpEventNode->m_dwEventAmount = 0;
lpEventNode->m_fPosX = fPosX;
lpEventNode->m_fPosY = fPosY;
lpEventNode->m_fPosZ = fPosZ;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_MonsterDrop(int nItemID, int nAmount)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_MONSTERDROP;
lpEventNode->m_dwEventNumber = nItemID;
lpEventNode->m_dwEventAmount = nAmount;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_Drop(int nItemID, int nAmount, float fPosX, float fPosY, float fPosZ)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_DROP;
lpEventNode->m_dwEventNumber = nItemID;
lpEventNode->m_dwEventAmount = nAmount;
lpEventNode->m_fPosX = fPosX;
lpEventNode->m_fPosY = fPosY;
lpEventNode->m_fPosZ = fPosZ;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_Award(int nExp, int nGold)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_AWARD;
lpEventNode->m_dwEventNumber = nExp;
lpEventNode->m_dwEventAmount = nGold;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_MsgBox(const char *strMessage)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_MSGBOX;
lpEventNode->m_dwEventNumber = 0;
lpEventNode->m_dwEventAmount = 0;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
char *strScript = new char[strlen(strMessage) + 1];
strcpy(strScript, strMessage);
lpEventNode->m_strWord = strScript;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
static void Event_Phase(int nPhaseNumber)
{
if(g_NPCList.m_lpTriggerNode)
{
LPEventNode lpEventNode = new EventNode;
lpEventNode->m_dwEventKind = EVENT_PHASE;
lpEventNode->m_dwEventNumber = nPhaseNumber;
lpEventNode->m_dwEventAmount = 0;
lpEventNode->m_fPosX = 0.0f;
lpEventNode->m_fPosY = 0.0f;
lpEventNode->m_fPosZ = 0.0f;
lpEventNode->m_strWord = NULL;
g_NPCList.m_lpTriggerNode->m_lstEvent.push_back(lpEventNode);
}
}
CNPCList::CNPCList()
{
m_lpQuestNode = NULL;
m_lpPhaseNode = NULL;
m_lpTriggerNode = NULL;
}
CNPCList::~CNPCList()
{
DestroyNPCList();
}
void CNPCList::Create()
{
}
BOOL CNPCList::Load(const char *strScriptFile, const char *strQuestFile, unsigned long dwZone)
{
DestroyNPCList();
m_dwZone = dwZone;
m_scQuestScript = _SE_Create(strQuestFile);
if(!m_scQuestScript) return FALSE;
_SE_RegisterFunction(m_scQuestScript, QuestTitle, T_VOID, "QuestTitle", T_STRING, 0);
_SE_RegisterFunction(m_scQuestScript, AddPhase, T_VOID, "AddPhase", T_INT, T_STRING, 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Start, T_VOID, "Trigger_Start", 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Puton, T_VOID, "Trigger_Puton", T_INT, T_INT, T_FLOAT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Geton, T_VOID, "Trigger_Geton", T_INT, T_INT, T_FLOAT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Talk, T_VOID, "Trigger_Talk", T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Kill, T_VOID, "Trigger_Kill", T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Trigger_Pick, T_VOID, "Trigger_Pick", T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Disappear, T_VOID, "Event_Disappear", T_INT, T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Get, T_VOID, "Event_Get", T_INT, T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Spawn, T_VOID, "Event_Spawn", T_INT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_MonsterDrop, T_VOID, "Event_MonsterDrop", T_INT, T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Drop, T_VOID, "Event_Drop", T_INT, T_INT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Award, T_VOID, "Event_Award", T_INT, T_INT, 0);
_SE_RegisterFunction(m_scQuestScript, Event_MsgBox, T_VOID, "Event_MsgBox", T_STRING, 0);
_SE_RegisterFunction(m_scQuestScript, Event_Phase, T_VOID, "Event_Phase", T_INT, 0);
_SE_SetMessageFunction(ScriptErrorMessage);
SCRIPT Script = _SE_Create(strScriptFile);
if(!Script) return FALSE;
// _SE_RegisterFunction(Script, SetNpc, T_VOID, "SetNPC", T_INT, T_INT, T_STRING, T_STRING, 0);
_SE_RegisterFunction(Script, SetNpc, T_VOID, "SetNPC", T_INT, T_INT, T_INT, T_STRING, T_STRING, 0);
_SE_RegisterFunction(Script, SetPosition, T_VOID, "SetPosition", T_INT, T_FLOAT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(Script, AddWords, T_VOID, "AddWords", T_INT, T_STRING, 0);
_SE_RegisterFunction(Script, AddDialog, T_VOID, "AddDialog", T_INT, T_INT, T_INT, T_STRING, 0);
_SE_RegisterFunction(Script, AddItem, T_VOID, "AddItem", T_INT, T_INT, T_INT, T_INT, 0);
_SE_RegisterFunction(Script, AddSkillBook, T_VOID, "AddSkillBook", T_INT, T_INT, T_INT, T_INT, T_INT, T_INT, 0);
_SE_RegisterFunction(Script, AddZoneMove, T_VOID, "AddZoneMove", T_INT, T_INT, T_FLOAT, T_FLOAT, T_FLOAT, 0);
_SE_RegisterFunction(Script, AddQuest, T_VOID, "AddQuest", T_INT, T_INT, T_INT, T_INT, T_INT, T_INT, T_STRING, 0);
_SE_Execute(Script);
_SE_Destroy(Script);
return TRUE;
}
BOOL CNPCList::IsExistNpc(unsigned long dwUID)
{
vector<LPNPCNode>::iterator it;
for(it = m_lstNpcNode.begin(); it != m_lstNpcNode.end(); it++)
{
if((*it)->m_dwUID == dwUID) return TRUE;
}
return FALSE;
}
void CNPCList::AddNpc(LPNPCNode lpNewNode)
{
m_lstNpcNode.push_back(lpNewNode);
}
LPNPCNode CNPCList::GetNPCNode(unsigned long dwUID)
{
vector<LPNPCNode>::iterator it;
for(it = m_lstNpcNode.begin(); it != m_lstNpcNode.end(); it++)
{
if((*it)->m_dwUID == dwUID) return (*it);
}
return NULL;
}
void CNPCList::DestroyNPCList()
{
vector<LPNPCNode>::iterator it;
vector<LPDialogNode>::iterator itchar;
vector<LPITEMNode>::iterator itItem;
vector<LPWarpNode>::iterator itWarp;
vector<LPQuestNode>::iterator itQuest;
vector<LPPhaseNode>::iterator itPhase;
vector<LPTriggerNode>::iterator itTrigger;
vector<LPEventNode>::iterator itEvent;
LPNPCNode lpNPC;
LPDialogNode lpWord;
LPITEMNode lpItem;
LPWarpNode lpWarp;
LPQuestNode lpQuest;
LPPhaseNode lpPhase;
LPTriggerNode lpTrigger;
LPEventNode lpEvent;
for(it = m_lstNpcNode.begin(); it != m_lstNpcNode.end();)
{
lpNPC = (*it);
it = m_lstNpcNode.erase(it);
for(itchar = lpNPC->m_lstScript.begin(); itchar != lpNPC->m_lstScript.end();)
{
lpWord = (*itchar);
itchar = lpNPC->m_lstScript.erase(itchar);
delete[] lpWord->m_strWord;
delete lpWord;
}
lpNPC->m_lstScript.clear();
for(itItem = lpNPC->m_lstItem.begin(); itItem != lpNPC->m_lstItem.end();)
{
lpItem = (*itItem);
itItem = lpNPC->m_lstItem.erase(itItem);
delete lpItem;
}
lpNPC->m_lstItem.clear();
for(itWarp = lpNPC->m_lstWarpZone.begin(); itWarp != lpNPC->m_lstWarpZone.end();)
{
lpWarp = (*itWarp);
itWarp = lpNPC->m_lstWarpZone.erase(itWarp);
delete lpWarp;
}
lpNPC->m_lstWarpZone.clear();
for(itQuest = lpNPC->m_lstQuest.begin(); itQuest != lpNPC->m_lstQuest.end();)
{
lpQuest = (*itQuest);
itQuest = lpNPC->m_lstQuest.erase(itQuest);
for(itPhase = lpQuest->m_lstPhase.begin(); itPhase != lpQuest->m_lstPhase.end();)
{
lpPhase = (*itPhase);
itPhase = lpQuest->m_lstPhase.erase(itPhase);
for(itTrigger = lpPhase->m_lstTrigger.begin(); itTrigger != lpPhase->m_lstTrigger.end();)
{
lpTrigger = (*itTrigger);
itTrigger = lpPhase->m_lstTrigger.erase(itTrigger);
for(itEvent = lpTrigger->m_lstEvent.begin(); itEvent != lpTrigger->m_lstEvent.end();)
{
lpEvent = (*itEvent);
itEvent = lpTrigger->m_lstEvent.erase(itEvent);
if(lpEvent->m_strWord) delete[] lpEvent->m_strWord;
delete lpEvent;
}
lpTrigger->m_lstEvent.clear();
delete lpTrigger;
}
lpPhase->m_lstTrigger.clear();
delete[] lpPhase->m_strPhaseDesc;
delete lpPhase;
}
lpQuest->m_lstPhase.clear();
if(lpQuest->m_strQuestTitle) delete[] lpQuest->m_strQuestTitle;
delete lpQuest;
}
lpNPC->m_lstQuest.clear();
delete[] lpNPC->m_strNpcSkin;
delete[] lpNPC->m_strNpcName;
delete lpNPC;
}
m_lstNpcNode.clear();
_SE_Destroy(m_scQuestScript);
}
const char *CNPCList::GetGreeting(unsigned long dwUID)
{
vector<LPNPCNode>::iterator it;
for(it = m_lstNpcNode.begin(); it != m_lstNpcNode.end(); it++)
{
if((*it)->m_dwUID == dwUID)
{
return (*it)->GetGreeting();
}
}
return NULL;
}
void NPCNode::SearchQuestList(unsigned long m_dwLevel, unsigned long m_dwClass, unsigned short *m_lstCompleted, unsigned short m_wNumCompleted, unsigned short *m_lstQuestList)
{
vector<LPQuestNode>::iterator it;
unsigned long count = 0;
unsigned long i = 0;
for(it = m_lstQuest.begin(); it != m_lstQuest.end(); it++, i++)
{
BOOL bPass = FALSE;
// <20>̹<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20>˻<EFBFBD><CBBB><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ߴ<EFBFBD><DFB4><EFBFBD> <20>˻<EFBFBD>
for(unsigned long t = 0; t < m_wNumCompleted; t++)
{
if(m_lstCompleted[t] == (*it)->m_wQuestID)
{
bPass = TRUE;
}
}
if(bPass) continue;
if((*it)->m_dwCompletedQuest)
{
for(unsigned long t = 0; t < m_wNumCompleted; t++)
{
if(m_lstCompleted[t] == (*it)->m_dwCompletedQuest)
{
bPass = TRUE;
}
}
if(!bPass) continue;
}
if((*it)->m_wMinLevel <= m_dwLevel && m_dwLevel <= (*it)->m_wMaxLevel)
{
m_lstQuestList[count] = i;
count++;
}
}
m_lstQuestList[count] = 0xFFFF;
}

View File

@@ -0,0 +1,213 @@
// NPCList.h: interface for the CNPCList class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_NPCLIST_H__E20011A2_96E4_44B4_AB08_826651FF4122__INCLUDED_)
#define AFX_NPCLIST_H__E20011A2_96E4_44B4_AB08_826651FF4122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <windows.h>
#include <vector>
#define TRIGGER_START 0
#define TRIGGER_PUTON 1
#define TRIGGER_GETON 2
#define TRIGGER_TALK 3
#define TRIGGER_KILL 4
#define TRIGGER_PICK 5
#define EVENT_DISAPPEAR 0
#define EVENT_GET 1
#define EVENT_SPAWN 2
#define EVENT_MONSTERDROP 3
#define EVENT_DROP 4
#define EVENT_AWARD 5
#define EVENT_MSGBOX 6
#define EVENT_PHASE 7
using namespace std;
typedef struct ITEMNode
{
unsigned short m_wKindItem;
unsigned short m_wSkill;
unsigned short m_wSkillLevel;
unsigned short m_wTabPage;
unsigned long m_dwIndexPosition;
} ITEMNode, *LPITEMNode;
typedef struct DialogNode
{
unsigned short m_wKindWord;
unsigned short m_wDialogFlag;
unsigned long m_dwFlag;
char *m_strWord;
} DialogNode, *LPDialogNode;
typedef struct WarpNode
{
unsigned short m_wNumber;
unsigned short m_wZoneNumber;
float m_fPosX;
float m_fPosY;
float m_fPosZ;
} WarpNode, *LPWarpNode;
typedef struct EventNode
{
unsigned long m_dwEventKind;
unsigned long m_dwEventNumber;
unsigned long m_dwEventAmount;
float m_fPosX;
float m_fPosY;
float m_fPosZ;
char *m_strWord;
} EventNode, *LPEventNode;
typedef struct TriggerNode
{
unsigned long m_dwTriggerKind;
unsigned long m_dwTriggerID;
unsigned long m_dwZoneID;
float m_fPosX;
float m_fPosY;
float m_fPosZ;
float m_fDistance;
vector<LPEventNode> m_lstEvent;
} TriggerNode, *LPTriggerNode;
typedef struct PhaseNode
{
unsigned long m_dwPhaseNumber;
char *m_strPhaseDesc;
vector<LPTriggerNode> m_lstTrigger;
} PhaseNode, *LPPhaseNode;
typedef struct QuestNode
{
unsigned short m_wQuestID;
unsigned short m_wMaxPhase;
unsigned short m_wMinLevel;
unsigned short m_wMaxLevel;
unsigned long m_dwClass;
unsigned long m_dwCompletedQuest;
char *m_strQuestTitle;
vector<LPPhaseNode> m_lstPhase;
} QuestNode, *LPQuestNode;
typedef struct NPCNode
{
unsigned long m_dwUID;
unsigned long m_dwJob;
float m_fDirection;
float m_fPosX, m_fPosY, m_fPosZ;
char *m_strNpcSkin;
char *m_strNpcName;
vector<LPITEMNode> m_lstItem;
vector<LPDialogNode> m_lstScript;
vector<LPWarpNode> m_lstWarpZone;
vector<LPQuestNode> m_lstQuest;
LPITEMNode GetITEMNode(unsigned short wKindItem)
{
vector<LPITEMNode>::iterator it;
for(it = m_lstItem.begin(); it != m_lstItem.end(); it++)
{
if((*it)->m_wKindItem == wKindItem) return (*it);
}
return NULL;
}
LPDialogNode GetScript(unsigned short wPage)
{
vector<LPDialogNode>::iterator it;
for(it = m_lstScript.begin(); it != m_lstScript.end(); it++)
{
if((*it)->m_wKindWord == wPage) return (*it);
}
return NULL;
}
LPWarpNode GetWarpNode(unsigned short wNumber)
{
vector<LPWarpNode>::iterator it;
for(it = m_lstWarpZone.begin(); it != m_lstWarpZone.end(); it++)
{
if((*it)->m_wNumber == wNumber) return (*it);
}
return NULL;
}
LPQuestNode GetQuestforID(unsigned short wQuestID)
{
vector<LPQuestNode>::iterator it;
for(it = m_lstQuest.begin(); it != m_lstQuest.end(); it++)
{
if((*it)->m_wQuestID == wQuestID) return (*it);
}
return NULL;
}
LPQuestNode GetQuestforNumber(unsigned short wNumber)
{
if(m_lstQuest.size() > wNumber)
{
return m_lstQuest[wNumber];
}
return NULL;
}
const char *GetGreeting(void)
{
vector<LPDialogNode>::iterator it;
for(it = m_lstScript.begin(); it != m_lstScript.end(); it++)
{
if((*it)->m_wKindWord == 0) return (*it)->m_strWord;
}
return NULL;
}
void SearchQuestList(unsigned long m_dwLevel, unsigned long m_dwClass, unsigned short *m_lstCompleted, unsigned short m_wNumCompleted, unsigned short *m_lstQuestList);
} NPCNode, *LPNPCNode;
class CNPCList
{
protected:
vector<LPNPCNode> m_lstNpcNode;
unsigned long m_dwZone;
public:
LPQuestNode m_lpQuestNode;
LPPhaseNode m_lpPhaseNode;
LPTriggerNode m_lpTriggerNode;
const char *GetGreeting(unsigned long dwUID);
void DestroyNPCList(void);
LPITEMNode GetITEMNode(unsigned short wKindItem);
LPNPCNode GetNPCNode(unsigned long dwUID);
LPNPCNode GetNPCNodeByOrder(unsigned long dwOrder) { return m_lstNpcNode[dwOrder]; }
void AddNpc(LPNPCNode lpNewNode);
BOOL IsExistNpc(unsigned long dwUID);
CNPCList();
~CNPCList();
BOOL Load(const char *strScriptFile, const char *strQuestFile, unsigned long dwZone = 1);
void Create(void);
unsigned long GetNpcNum(void) { return m_lstNpcNode.size(); }
unsigned long GetZone(void) { return m_dwZone; }
};
extern CNPCList g_NPCList;
#endif // !defined(AFX_NPCLIST_H__E20011A2_96E4_44B4_AB08_826651FF4122__INCLUDED_)