void CItem::Spawn_GenerateChar( CResourceDef * pDef ) { if ( ! IsTopLevel()) return; // creatures can only be top level. if ( m_itSpawnChar.m_current >= GetAmount()) return; int iComplexity = GetTopSector()->GetCharComplexity(); if ( iComplexity > g_Cfg.m_iMaxCharComplexity ) { DEBUG_MSG(( "Spawn uid=0%lx too complex (%d>%d)\n", GetUID(), iComplexity, g_Cfg.m_iMaxCharComplexity )); return; } int iDistMax = m_itSpawnChar.m_DistMax; RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef * pSpawnGroup = STATIC_CAST <const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); int i = pSpawnGroup->GetRandMemberIndex(); if ( i >= 0 ) { rid = pSpawnGroup->GetMemberID(i); } } CREID_TYPE id; if ( rid.GetResType() == RES_CHARDEF || rid.GetResType() == RES_UNKNOWN ) { id = (CREID_TYPE) rid.GetResIndex(); } else { return; } CChar * pChar = CChar::CreateNPC( id ); if ( pChar == NULL ) return; ASSERT(pChar->m_pNPC); m_itSpawnChar.m_current ++; pChar->Memory_AddObjTypes( this, MEMORY_ISPAWNED ); // Move to spot "near" the spawn item. pChar->MoveNearObj( this, iDistMax ); if ( iDistMax ) { pChar->m_ptHome = GetTopPoint(); pChar->m_pNPC->m_Home_Dist_Wander = iDistMax; } pChar->Update(); }
void CItemSpawn::GenerateChar(CResourceDef *pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); RESOURCE_ID_BASE rid = pDef->GetResourceID(); if ( rid.GetResType() == RES_SPAWN ) { const CRandGroupDef *pSpawnGroup = static_cast<const CRandGroupDef *>(pDef); ASSERT(pSpawnGroup); size_t i = pSpawnGroup->GetRandMemberIndex(); if ( i != pSpawnGroup->BadMemberIndex() ) rid = pSpawnGroup->GetMemberID(i); } if ( (rid.GetResType() != RES_CHARDEF) && (rid.GetResType() != RES_UNKNOWN) ) return; CPointMap pt = GetTopPoint(); CRegionBase *pRegion = pt.GetRegion(REGION_TYPE_AREA); if ( !pRegion ) return; CChar *pChar = CChar::CreateBasic(static_cast<CREID_TYPE>(rid.GetResIndex())); if ( !pChar ) return; pChar->NPC_LoadScript(true); pChar->StatFlag_Set(STATF_Spawned); // Try placing the char near the spawn if ( !pChar->MoveNearObj(this, m_itSpawnChar.m_DistMax) || !pChar->CanSeeLOS(pt) ) { // If this fails, try placing the char over the spawn if ( !pChar->MoveTo(pt) ) { DEBUG_ERR(("Spawn UID:0%lx is unable to place a character inside the world.\n", static_cast<DWORD>(GetUID()))); pChar->Delete(); return; } } AddObj(pChar->GetUID()); pChar->NPC_CreateTrigger(); // removed from NPC_LoadScript() and triggered after char placement and attachment to the spawnitem pChar->Update(); size_t iCount = GetTopSector()->GetCharComplexity(); if ( iCount > g_Cfg.m_iMaxCharComplexity ) g_Log.Event(LOGL_WARN, "%" FMTSIZE_T " chars at %s. Sector too complex!\n", iCount, GetTopSector()->GetBasePoint().WriteUsed()); }