2022-03-05 12:44:06 +02:00
|
|
|
|
#ifndef __INC_SECTREE_H__
|
|
|
|
|
#define __INC_SECTREE_H__
|
|
|
|
|
|
|
|
|
|
#include "entity.h"
|
|
|
|
|
|
|
|
|
|
enum ESectree
|
|
|
|
|
{
|
|
|
|
|
SECTREE_SIZE = 6400,
|
|
|
|
|
SECTREE_HALF_SIZE = 3200,
|
|
|
|
|
CELL_SIZE = 50
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct sectree_coord
|
|
|
|
|
{
|
|
|
|
|
unsigned x : 16;
|
|
|
|
|
unsigned y : 16;
|
|
|
|
|
} SECTREE_COORD;
|
|
|
|
|
|
|
|
|
|
typedef union sectreeid
|
|
|
|
|
{
|
|
|
|
|
DWORD package;
|
|
|
|
|
SECTREE_COORD coord;
|
|
|
|
|
} SECTREEID;
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
ATTR_BLOCK = (1 << 0),
|
|
|
|
|
ATTR_WATER = (1 << 1),
|
|
|
|
|
ATTR_BANPK = (1 << 2),
|
|
|
|
|
ATTR_OBJECT = (1 << 7),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct FCollectEntity {
|
|
|
|
|
void operator()(LPENTITY entity) {
|
|
|
|
|
// Consider removing sanity check after debug pass
|
|
|
|
|
/*
|
|
|
|
|
if (entity->IsType(ENTITY_CHARACTER)) {
|
|
|
|
|
LPCHARACTER character = (LPCHARACTER)entity;
|
|
|
|
|
DWORD vid = character->GetVID();
|
|
|
|
|
LPCHARACTER found = CHARACTER_MANGAER::instance().Find(vid);
|
|
|
|
|
if (found == NULL || vid != found->GetVID()) {
|
|
|
|
|
sys_err("<Factor> Invalid character %p", get_pointer(character));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else if (entity->IsType(ENTITY_ITEM)) {
|
|
|
|
|
LPITEM item = (LPITEM)entity;
|
|
|
|
|
DWORD vid = item->GetVID();
|
|
|
|
|
LPITEM found = ITEM_MANGAER::instance().FindByVID(vid);
|
|
|
|
|
if (found == NULL || vid != found->GetVID()) {
|
|
|
|
|
sys_err("<Factor> Invalid item %p", get_pointer(item));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else if (entity->IsType(ENTITY_OBJECT)) {
|
|
|
|
|
LPOBJECT object = (LPOBJECT)entity;
|
|
|
|
|
DWORD vid = object->GetVID();
|
|
|
|
|
LPOBJECT found = CManager::instance().FindObjectByVID(vid);
|
|
|
|
|
if (found == NULL || vid != found->GetVID()) {
|
|
|
|
|
sys_err("<Factor> Invalid object %p", get_pointer(object));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
sys_err("<Factor> Invalid entity type %p", get_pointer(entity));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
result.push_back(entity);
|
|
|
|
|
}
|
|
|
|
|
template<typename F>
|
|
|
|
|
void ForEach(F& f) {
|
|
|
|
|
std::vector<LPENTITY>::iterator it = result.begin();
|
|
|
|
|
for ( ; it != result.end(); ++it) {
|
|
|
|
|
LPENTITY entity = *it;
|
|
|
|
|
f(entity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
typedef std::vector<LPENTITY> ListType;
|
|
|
|
|
ListType result; // list collected
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CAttribute;
|
|
|
|
|
|
|
|
|
|
class SECTREE
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
friend class SECTREE_MANAGER;
|
|
|
|
|
friend class SECTREE_MAP;
|
|
|
|
|
|
|
|
|
|
template <class _Func> LPENTITY find_if (_Func & func) const
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_LIST::iterator it_tree = m_neighbor_list.begin();
|
|
|
|
|
|
|
|
|
|
while (it_tree != m_neighbor_list.end())
|
|
|
|
|
{
|
|
|
|
|
ENTITY_SET::iterator it_entity = (*it_tree)->m_set_entity.begin();
|
|
|
|
|
|
|
|
|
|
while (it_entity != (*it_tree)->m_set_entity.end())
|
|
|
|
|
{
|
|
|
|
|
if (func(*it_entity))
|
|
|
|
|
return (*it_entity);
|
|
|
|
|
|
|
|
|
|
++it_entity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++it_tree;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class _Func> void ForEachAround(_Func & func)
|
|
|
|
|
{
|
|
|
|
|
// <Factor> Using snapshot copy to avoid side-effects
|
|
|
|
|
FCollectEntity collector;
|
|
|
|
|
LPSECTREE_LIST::iterator it = m_neighbor_list.begin();
|
|
|
|
|
for ( ; it != m_neighbor_list.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE sectree = *it;
|
|
|
|
|
sectree->for_each_entity(collector);
|
|
|
|
|
}
|
|
|
|
|
collector.ForEach(func);
|
|
|
|
|
/*
|
|
|
|
|
LPSECTREE_LIST::iterator it_tree = m_neighbor_list.begin();
|
|
|
|
|
for ( ; it_tree != m_neighbor_list.end(); ++it_tree) {
|
|
|
|
|
(*it_tree)->for_each_entity(func);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class _Func> void for_each_for_find_victim(_Func & func)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_LIST::iterator it_tree = m_neighbor_list.begin();
|
|
|
|
|
|
|
|
|
|
while (it_tree != m_neighbor_list.end())
|
|
|
|
|
{
|
|
|
|
|
//ù<><C3B9>°<EFBFBD><C2B0> ã<><C3A3><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if ( (*(it_tree++))->for_each_entity_for_find_victim(func) )
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
template <class _Func> bool for_each_entity_for_find_victim(_Func & func)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_set_entity) it = m_set_entity.begin();
|
|
|
|
|
|
|
|
|
|
while (it != m_set_entity.end())
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if ( func(*it++) )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
SECTREE();
|
|
|
|
|
~SECTREE();
|
|
|
|
|
|
|
|
|
|
void Initialize();
|
|
|
|
|
void Destroy();
|
|
|
|
|
|
|
|
|
|
SECTREEID GetID();
|
|
|
|
|
|
|
|
|
|
bool InsertEntity(LPENTITY ent);
|
|
|
|
|
void RemoveEntity(LPENTITY ent);
|
|
|
|
|
|
|
|
|
|
void SetRegenEvent(LPEVENT event);
|
|
|
|
|
bool Regen();
|
|
|
|
|
|
|
|
|
|
void IncreasePC();
|
|
|
|
|
void DecreasePC();
|
|
|
|
|
|
|
|
|
|
void BindAttribute(CAttribute * pkAttribute);
|
|
|
|
|
|
|
|
|
|
CAttribute * GetAttributePtr() { return m_pkAttribute; }
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
DWORD GetAttribute(int x, int y);
|
|
|
|
|
bool IsAttr(int x, int y, DWORD dwFlag);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
void CloneAttribute(LPSECTREE tree); // private map ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int GetEventAttribute(int x, int y); // 20050313 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
void SetAttribute(DWORD x, DWORD y, DWORD dwAttr);
|
|
|
|
|
void RemoveAttribute(DWORD x, DWORD y, DWORD dwAttr);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
template <class _Func> void for_each_entity(_Func & func)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_set_entity) it = m_set_entity.begin();
|
|
|
|
|
for ( ; it != m_set_entity.end(); ++it) {
|
|
|
|
|
LPENTITY entity = *it;
|
|
|
|
|
// <Factor> Sanity check
|
|
|
|
|
if (entity->GetSectree() != this) {
|
|
|
|
|
sys_err("<Factor> SECTREE-ENTITY relationship mismatch");
|
|
|
|
|
m_set_entity.erase(it);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
func(entity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SECTREEID m_id;
|
|
|
|
|
ENTITY_SET m_set_entity;
|
|
|
|
|
LPSECTREE_LIST m_neighbor_list;
|
|
|
|
|
int m_iPCCount;
|
|
|
|
|
bool isClone;
|
|
|
|
|
|
|
|
|
|
CAttribute * m_pkAttribute;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|