void CItemSpawn::GenerateChar(CResourceDef *pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); if ( !IsTopLevel() ) return; 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; CChar *pChar = CChar::CreateBasic(static_cast<CREID_TYPE>(rid.GetResIndex())); if ( !pChar ) return; CPointMap pt = GetTopPoint(); pChar->NPC_LoadScript(true); pChar->StatFlag_Set(STATF_Spawned); pChar->MoveTo(pt); // Check if the NPC can spawn in this region CRegionBase *pRegion = GetTopPoint().GetRegion(REGION_TYPE_AREA); if ( !pRegion || (pRegion->IsGuarded() && pChar->Noto_IsEvil()) ) { 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, "%d chars at %s. Sector too complex!\n", iCount, GetTopSector()->GetBasePoint().WriteUsed()); }
void CItemSpawn::GenerateChar(CResourceDef * pDef) { ADDTOCALLSTACK("CitemSpawn:GenerateChar"); if ( !IsTopLevel() || ( m_itSpawnChar.m_current >= GetAmount() ) || ( GetTopSector()->GetCharComplexity() > 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); size_t i = pSpawnGroup->GetRandMemberIndex(); if ( i != pSpawnGroup->BadMemberIndex() ) { rid = pSpawnGroup->GetMemberID(i); } } if (( rid.GetResType() != RES_CHARDEF ) && ( rid.GetResType() != RES_UNKNOWN )) return; CREID_TYPE id = static_cast<CREID_TYPE>(rid.GetResIndex()); bool isBadPlaceToSpawn = false; CChar * pChar = CChar::CreateBasic(id); if( pChar == NULL ) { return; } pChar->NPC_LoadScript(true); AddObj(pChar->GetUID()); pChar->m_uidSpawnItem = GetUID(); // SpawnItem for this char pChar->StatFlag_Set( STATF_Spawned ); pChar->MoveTo(GetTopPoint()); pChar->NPC_CreateTrigger(); //Removed from NPC_LoadScript() and triggered after char placement if( pChar->GetRegion() == NULL ) { isBadPlaceToSpawn = true; } else if( pChar->GetRegion()->IsGuarded() && pChar->Noto_IsEvil() ) { isBadPlaceToSpawn = true; } // Deny definitely known a bad place to spawn (like red NPCs in guarded areas) // Usually caused by wide range near the edge of the towns if( isBadPlaceToSpawn ) { pChar->Delete(); //m_itSpawnChar.m_current--; return; } ASSERT(pChar->m_pNPC); if ( iDistMax ) { pChar->m_ptHome = GetTopPoint(); pChar->m_pNPC->m_Home_Dist_Wander = static_cast<WORD>(iDistMax); } pChar->Update(); }