Пример #1
0
bool CItemMulti::Ship_SetMoveDir( DIR_TYPE dir )
{
	// Set the direction we will move next time we get a tick.
	int iSpeed = 1;
	if ( m_itShip.m_DirMove == dir && m_itShip.m_fSail )
	{
		if ( m_itShip.m_DirFace == m_itShip.m_DirMove &&
			m_itShip.m_fSail == 1 )
		{
			iSpeed = 2;
		}
		else return( false );
	}

	if ( ! IsAttr(ATTR_MAGIC ))	// make sound.
	{
		if ( ! Calc_GetRandVal(10))
		{
			Sound( Calc_GetRandVal(2)?0x12:0x13 );
		}
	}

	m_itShip.m_DirMove = dir;
	m_itShip.m_fSail = iSpeed;
	GetTopSector()->SetSectorWakeStatus();	// may get here b4 my client does.
	SetTimeout(( m_itShip.m_fSail == 1 ) ? 1*TICK_PER_SEC : (TICK_PER_SEC/5));
	return( true );
}
Пример #2
0
void CItemCommCrystal::OnMoveFrom()
{
	ADDTOCALLSTACK("CItemCommCrystal::OnMoveFrom");
	// Being removed from the top level.
	CSector *pSector = GetTopSector();
	if ( pSector )
		pSector->RemoveListenItem();
}
Пример #3
0
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());
}
Пример #4
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();
}
Пример #5
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());
}
Пример #6
0
bool CItemMulti::Ship_Move( DIR_TYPE dir )
{
	if ( dir >= DIR_QTY )
		return( false );

	if ( m_pRegion == NULL )
	{
		DEBUG_ERR(( "Ship bad region\n" ));
		return false;
	}

	CPointMap ptDelta;
	ptDelta.ZeroPoint();
	ptDelta.Move( dir );

	CPointMap ptForePrv = m_pRegion->GetRegionCorner(dir);
	CPointMap ptFore = ptForePrv;
	ptFore.Move( dir );
	ptFore.m_z = GetTopZ();

	if ( ! ptFore.IsValidPoint() ||
		( ptForePrv.m_x < UO_SIZE_X_REAL && ptFore.m_x >= UO_SIZE_X_REAL && ( ptFore.m_map <= 1 )))
	{
		// Circle the globe
		// Fall off edge of world ?
		CItem * pTiller = Multi_GetSign();
		ASSERT(pTiller);
		pTiller->Speak( "Turbulent waters Cap'n", 0, TALKMODE_SAY, FONT_NORMAL );

		// Compute the new safe place to go. (where we will not overlap)
		int iMaxDist = Multi_GetMaxDist();

/*		if ( ptFore.m_x <= 0 )
		{
			
		}
		else if ( ptFore.m_x >= UO_SIZE_X_REAL )
		{
			
		}
		else if ( ptFore.m_y <= 0 )
		{
			
		}
		else if ( ptFore.m_y >= UO_SIZE_Y )
		{
			
		}

*/		return false;
	}

	// We should check all relevant corners.
	if ( ! Ship_CanMoveTo( ptFore ))
	{
cantmove:
		CItem * pTiller = Multi_GetSign();
		ASSERT(pTiller);
		pTiller->Speak( "We've stopped Cap'n", 0, TALKMODE_SAY, FONT_NORMAL );
		return false;
	}

	// left side
	CPointMap ptTmp = m_pRegion->GetRegionCorner(GetDirTurn(dir,-1));
	ptTmp.Move( dir );
	ptTmp.m_z = GetTopZ();
	if ( ! Ship_CanMoveTo( ptTmp ))
		goto cantmove;

	// right side.
	ptTmp = m_pRegion->GetRegionCorner(GetDirTurn(dir,+1));
	ptTmp.Move( dir );
	ptTmp.m_z = GetTopZ();
	if ( ! Ship_CanMoveTo( ptTmp ))
		goto cantmove;

	Ship_MoveDelta( ptDelta );

	// Move again
	GetTopSector()->SetSectorWakeStatus();	// may get here b4 my client does.
	return true;
}
Пример #7
0
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();

}