PythonNetworkStreamPhaseGame.cpp
add:
#ifdef ENABLE_ENTITY_PRELOADING
extern bool IsInvisibleRace(WORD raceNum);
#endif
change:
#ifdef ENABLE_ENTITY_PRELOADING
bool CPythonNetworkStream::RecvPreloadEntitiesPacket()
{
TPacketGCPreloadEntities pack{};
if (!Recv(sizeof(pack), &pack))
return false;
assert(int32_t(pack.size) - sizeof(pack) == pack.count * sizeof(uint32_t) && "HEADER_GC_PRELOAD_ENTITIES");
uint32_t dwEntityRace = 0;
CInstanceBase::SCreateData d{};
static uint32_t s_dwPreloadVID = 0xC0000000;
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
for (uint16_t i = 0; i < pack.count; i++)
{
if (!Recv(sizeof(uint32_t), &dwEntityRace))
return false;
#ifdef _DEBUG
TraceError("Preloading %d", dwEntityRace);
#endif
if (IsInvisibleRace(static_cast<WORD>(dwEntityRace)))
continue;
d.m_dwRace = dwEntityRace;
const uint32_t dwPreloadVID = s_dwPreloadVID++;
if (s_dwPreloadVID < 0xC0000000)
s_dwPreloadVID = 0xC0000000;
d.m_dwVID = dwPreloadVID;
if (rkChrMgr.CreateInstance(d))
{
rkChrMgr.DeleteInstance(dwPreloadVID);
}
else
{
TraceError("Failed to preload race %u", dwEntityRace);
}
}
return true;
}
#endif
sectree_manager.cpp
change:
namespace
{
bool IsPreloadableRace(uint32_t raceVnum)
{
if (!raceVnum)
return false;
const CMob* pkMob = CMobManager::instance().Get(raceVnum);
if (!pkMob)
return false;
return pkMob->m_table.szFolder[0] != '\0';
}
bool ShouldCollectForPreload(LPENTITY ent)
{
if (!ent || !ent->IsType(ENTITY_CHARACTER))
return false;
LPCHARACTER pkChr = static_cast<LPCHARACTER>(ent);
if (pkChr->IsPC() || pkChr->IsPet())
return false;
#ifdef ENABLE_MOUNT_COSTUME_SYSTEM
if (pkChr->IsMount())
return false;
#endif
if (pkChr->IsWarp() || pkChr->IsGoto())
return false;
return IsPreloadableRace(pkChr->GetRaceNum());
}
}
void SECTREE_MANAGER::GeneratePreloadedEntitiesMap(int32_t mapIndex, LPSECTREE_MAP lpMapSectree)
{
if (m_preloadedEntities.find(mapIndex) == m_preloadedEntities.end())
{
m_preloadedEntities.insert({ mapIndex, {} });
auto lmbd = [&mapIndex, this](LPENTITY ent)
{
if (!ShouldCollectForPreload(ent))
return;
auto* pkChr = static_cast<LPCHARACTER>(ent);
this->m_preloadedEntities.at(mapIndex).emplace(pkChr->GetRaceNum());
};
lpMapSectree->for_each(lmbd);
for (int32_t i : m_preloadedEntities.at(mapIndex))
sys_log(0, "ENTITY_PRELOADING: [map: %d], [entity race: %d]", mapIndex, i);
}
}
void SECTREE_MANAGER::ExtendPreloadedEntitiesMap(int32_t mapIndex, uint32_t mob_race)
{
auto it = m_preloadedEntities.find(mapIndex);
if (it == m_preloadedEntities.end())
return;
if (!IsPreloadableRace(mob_race))
return;
if ((it->second.emplace(mob_race)).second)
sys_log(0, "ENTITY_PRELOADING: extended [map: %d], with [entity race: %d]", mapIndex, mob_race);
}