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