Files
2022-10-26 12:25:11 +08:00

174 lines
5.6 KiB
C++

#pragma once
#ifndef PROGRAMCOMMON_NPCINFOPARSER_H
#define PROGRAMCOMMON_NPCINFOPARSER_H
//==================================================================================================
// @history
// ~10.06.05
// 10.06.06|waverix|fit in a coding style and changes a data structure related to the BASE_NPCINFO
// that unidimentional array has an O(1) time complexity about fixed size base key.
//
//==================================================================================================
#include <ScriptCode.IParser.h>
#include <SolarHashTable.h>
//#include <Singleton.h>
//#include <SolarFileReader.h>
//#include <vector>
struct BASE_NPCINFO;
struct EXTRA_NPCINFO;
//typedef util::SolarHashTable<BASE_NPCINFO *>::iterator NPCINFO_ITERATOR;
//==================================================================================================
struct EXTRA_NPCINFO_SET
{
typedef std::vector<EXTRA_NPCINFO*> Container;
//
EXTRA_NPCINFO_SET() { }
~EXTRA_NPCINFO_SET() { }
Container::iterator GetBegin() {
return extra_info_set_.begin();
}
Container::iterator GetEnd() {
return extra_info_set_.end();
}
void Insert(EXTRA_NPCINFO* extra_info) {
extra_info_set_.push_back(extra_info);
}
void Clear() {
extra_info_set_.resize(0);
}
int GetSize() {
static_cast<int>(extra_info_set_.size());
}
Container extra_info_set_; // Hash 에서 관리 되는것이라 지울 필요없음.
};
//==================================================================================================
class NPCInfoParser : public IParser
{
public:
// interfaces for util::Singleton<>
static NPCInfoParser* Instance();
static void DestroyInstance();
void Init(DWORD unused_arg1, DWORD unused_arg2 = 50);
void Init(DWORD unused_arg1, char* pack_file_name, DWORD unused_arg2 = 50);
// IParser interface implementation = { Init, Release, LoadScript }
virtual void Release();
virtual BOOL LoadScript(eSCRIPT_CODE script_code, BOOL reloaded);
// (CHANGES) (f100606.2L) remove an unused section
//void Reload();
//void ReloadExtra();
BASE_NPCINFO* GetNPCInfo(CODETYPE npc_code);
const BASE_NPCINFO* GetNPCInfo(CODETYPE npc_code) const;
EXTRA_NPCINFO_SET* GetExtraInfoSetFromFieldID(MAPCODE map_code,FIELDID field_id);
EXTRA_NPCINFO* GetExtraInfo(CODETYPE npc_code);
// (f100606.2L) changed interfaces to support begin and end interface
void SetFirst() const ;
const BASE_NPCINFO* GetNext() const;
//NPCINFO_ITERATOR Begin() { return npc_table_.begin(); }
//NPCINFO_ITERATOR End() { return npc_table_.end(); }
private:
// (f100606.2L) add the item access facility which is supported an O(1) time complexity
struct NpcTable {
int number_of_total_npcs_;
// iterator
mutable const uint16_t* seq_total_it_;
const uint16_t* seq_total_indexes_;
const BASE_NPCINFO* seq_total_array_;
BASE_NPCINFO* array_[USHRT_MAX];
};
//
NPCInfoParser();
~NPCInfoParser();
static NPCInfoParser* CreateInstance();
BOOL _Load(BOOL reloaded);
BOOL _LoadExtra(BOOL reloaded);
bool _BuildReference(int added_number_of_nodes, bool is_extra_loading);
bool _AddNpcInfo(CODETYPE npc_code, BASE_NPCINFO* npc_info);
BOOL CheckValidity(BASE_NPCINFO* const npc_info);
void Unload();
void UnLoadExtra();
private:
//----------------------------------------------------------------------------------------------
// data fields...
bool loaded_;
util::SolarHashTable<EXTRA_NPCINFO*>* extra_npc_table_;
// sequential stream array to support an extra npc information
EXTRA_NPCINFO* extra_npc_info_array_;
EXTRA_NPCINFO_SET extra_npc_info_set_;
//util::SolarHashTable<BASE_NPCINFO*> npc_table_;
NpcTable npc_table_;
//
static NPCInfoParser* npc_info_parser_static_;
};
// interfaces for util::Singleton<>
inline NPCInfoParser* NPCInfoParser::Instance()
{
if (npc_info_parser_static_) {
return npc_info_parser_static_;
}
return CreateInstance();
}
inline BASE_NPCINFO* NPCInfoParser::GetNPCInfo(CODETYPE npc_code)
{
// (CHANGES) (f100606.2L) changes a search algorithm
if (npc_code == 0 || npc_code > USHRT_MAX) {
return NULL;
}
--npc_code;
BASE_NPCINFO* npc_info = npc_table_.array_[npc_code];
return npc_info;
}
inline const BASE_NPCINFO* NPCInfoParser::GetNPCInfo(CODETYPE npc_code) const
{
// (CHANGES) (f100606.2L) changes a search algorithm
if (npc_code == 0 || npc_code > USHRT_MAX) {
return NULL;
}
--npc_code;
const BASE_NPCINFO* npc_info = npc_table_.array_[npc_code];
return npc_info;
}
//NPCINFO_ITERATOR NPCInfoParser::Begin() { return npc_table_.begin(); }
//NPCINFO_ITERATOR NPCInfoParser::End() { return npc_table_.end(); }
// changed interfaces to support begin and end interface
inline void NPCInfoParser::SetFirst() const
{
npc_table_.seq_total_it_ = npc_table_.seq_total_indexes_;
}
// changed interfaces to support begin and end interface
inline const BASE_NPCINFO* NPCInfoParser::GetNext() const
{
const uint16_t* end = npc_table_.seq_total_indexes_ + npc_table_.number_of_total_npcs_;
if (npc_table_.seq_total_it_ >= end ||
npc_table_.seq_total_it_ < npc_table_.seq_total_indexes_)
{
return NULL;
}
uint16_t index = *npc_table_.seq_total_it_++; // change iterator
assert(npc_table_.array_[index]);
return npc_table_.array_[index];
}
inline EXTRA_NPCINFO* NPCInfoParser::GetExtraInfo(CODETYPE npc_code)
{
return extra_npc_table_->GetData(npc_code);
}
#endif //PROGRAMCOMMON_NPCINFOPARSER_H