bool CNPC::InitByPacket(PACKER_NZ_NEWNPC* p)
{
if (GetCharacterInfo()->isValid)
{
Trace("attempt to twice Init.");
return false;
}
auto x = p->xPos;
auto y = p->yPos;
m_npcType = p->npcType;
GetCharacterInfo()->job = p->spriteType;
GetCharacterInfo()->sex = SEX_FEMALE; // default
GetCharacterInfo()->xSize = p->xSize;
GetCharacterInfo()->ySize = p->ySize;
GetCharacterInfo()->head = HEADTYPE_SAMEASJOB; // default
GetCharacterInfo()->weapon = WEAPONTYPE_NONE;
GetCharacterInfo()->accessory = ACCESSORY_NONE;
GetCharacterInfo()->RegenMinTime = p->RegenMinTime;
GetCharacterInfo()->RegenMaxTime = p->RegenMaxTime;
GetCharacterInfo()->revivalYPos = y;
GetCharacterInfo()->RegenType = p->RegenType;
GetCharacterInfo()->revivalXPos = x;
GetCharacterInfo()->revivalXRange = p->xSize;
GetCharacterInfo()->revivalYRange = p->ySize;
std::strcpy(GetCharacterInfo()->mapName, p->mapName);
std::strcpy(GetCharacterInfo()->accountName, p->NPCName);
GetCharacterInfo()->originalJob = GetCharacterInfo()->job;
m_npcStateUpdater.SetFSM(g_fsmMgr.GetFSM(GetNPCType()));
if (!m_npcStateUpdater.GetFSM())
{
char errMsg[256];
std::memset(errMsg, '\0', sizeof(errMsg));
std::sprintf(errMsg, "spriteType:%d, npcType:%d FSM is NULL\n", p->spriteType, GetNPCType());
Trace(errMsg);
MessageBox(nullptr, errMsg, nullptr, MB_OK);
return false;
}
m_mapRes = g_mapResMgr.GetMapRes(GetCharacterInfo()->mapName);
if (!GetMapRes())
{
Trace("m_mapRes is NULL, map[%s] spriteType[%d] npcType[%d].\n", GetCharacterInfo()->mapName, p->spriteType, GetNPCType());
return false;
}
GetCharacterInfo()->mapID = GetMapRes()->GetID();
bool agitRegister = false;
bool isVisible = true;
if (GetMapRes()->IsAgit())
{
auto jt = GetCharacterInfo()->job;
auto regtype = 0;
if (jt >= JT_ARCHER_GUARDIAN && jt <= JT_SOLDIER_GUARDIAN)
regtype = 0;
else if (jt == JT_1_M_JOBTESTER)
regtype = 1;
else if (jt == JT_EMPELIUM)
regtype = 2;
else if (jt == JT_4_F_KAFRA01)
regtype = 3;
else if ((jt >= JT_TREASURE_BOX1 && jt <= JT_TREASURE_BOX40) || (jt >= JT_TREASURE_BOX41 && jt <= JT_TREASURE_BOX49))
regtype = 4;
if (!GetMapRes()->RegisterNPC(regtype, this, &isVisible))
return false;
}
if (isVisible)
{
if (x && y)
{
if (GetType() == NPC_MOB_TYPE)
{
if (p->force)
{
if (p->xSize && p->ySize)
GetMapRes()->GetRandomPosByRange(&x, &y, p->xSize, p->ySize, GetAccountID());
}
else
{
if (!GetMapRes()->GetRandomPosByRange(&x, &y, p->xSize, p->ySize, GetAccountID()) && !GetMapRes()->GetRandomPos(&x, &y))
return false;
}
}
}
else if (!GetMapRes()->GetRandomPos(&x, &y))
return false;
if (!m_npcUpdater.InitPosition(x, y, p->direction)) // can only return true
return false;
GetCharacterInfo()->isValid = true;
if (GetParentAID())
g_characterMgr.SendMsg(this, GetParentAID(), CM_ADD_MYMOB, GetAccountID());
SpawnMyMob(p->spriteType);
}
else
{
GetCharacterInfo()->RegenType = REGEN_TYPE_CREATEONLY;
SetCurrentFSMState(DEAD_ST);
}
InitSkill();
if (GetCharacterInfo()->isValid)
m_npcUpdater.CheckMove();
Trace("NPC[%d] create type:%d, %s, (%d, %d)\n", GetAccountID(), GetNPCType(), p->mapName, x, y);
if (GetCharacterInfo()->job == JT_WARPNPC)
g_characterMgr.AddWarpNpcList(GetMapRes(), this);
return true;
}