Esempio n. 1
0
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();
}
Esempio n. 2
0
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());
}