Exemplo n.º 1
0
void cSectorMaps::add( cUObject* object )
{
	// Very powerful statement. It completely
	// annihilates the need to check for
	// nullpointers in our object-map
	if ( !object )
		return;

	if ( isItemSerial( object->serial() ) )
	{
		P_ITEM pItem = dynamic_cast<P_ITEM>( object );
		if ( pItem )
		{
			Coord_cl pos = pItem->pos();

			std::map<unsigned char, cSectorMap*>::const_iterator it = itemmaps.find( pos.map );

			if ( it == itemmaps.end() )
				throw QString( "Couldn't find a map with the id %1." ).arg( pos.map );

			it->second->addItem( ( cUObject * ) pItem );

			Timing::instance()->addDecayItem( pItem );
		}
	}
	else if ( isCharSerial( object->serial() ) )
	{
		// This is a safety check to make sure that
		// stabled pets don't appear on our sectormap
		P_NPC npc = dynamic_cast<P_NPC>( object );

		if ( npc && npc->stablemasterSerial() != INVALID_SERIAL )
		{
			return;
		}

		// The same check for players
		P_PLAYER player = dynamic_cast<P_PLAYER>( object );

		if ( player && !player->socket() && !player->logoutTime() )
		{
			return;
		}

		P_CHAR pChar = dynamic_cast<P_CHAR>( object );
		if ( pChar )
		{
			Coord_cl pos = pChar->pos();

			std::map<unsigned char, cSectorMap*>::const_iterator it = charmaps.find( pos.map );

			if ( it == charmaps.end() )
				throw QString( "Couldn't find a map with the id %1." ).arg( pos.map );

			it->second->addItem( ( cUObject * ) pChar );
		}
	}
}
Exemplo n.º 2
0
cSectorIterator* cSectorMaps::findObjects( MapType type, cSectorMap* sector, uint x1, uint y1, uint x2, uint y2 )
{
	// First step: count how many items we are going to hold
	unsigned int count = 0;
	unsigned int xBlock, yBlock;

	if ( x1 > x2 )
	{
		std::swap( x1, x2 );
		std::swap( y1, y2 );
	}

	for ( xBlock = x1 / SECTOR_SIZE; xBlock <= x2 / SECTOR_SIZE; xBlock++ )
		for ( yBlock = y1 / SECTOR_SIZE; yBlock <= y2 / SECTOR_SIZE; yBlock++ )
			count += sector->countItems( ( xBlock * sector->gridHeight() ) + yBlock );

	// Second step: actually "compile" our list of items
	cUObject** items = ( cUObject** ) malloc( count * sizeof( cUObject* ) );
	unsigned int offset = 0;

	for ( xBlock = x1 / SECTOR_SIZE; xBlock <= x2 / SECTOR_SIZE; xBlock++ )
		for ( yBlock = y1 / SECTOR_SIZE; yBlock <= y2 / SECTOR_SIZE; yBlock++ )
		{
			// We *do* know that we allocated more memory than we need, but the effect is minimal!
			unsigned int block = ( xBlock * sector->gridHeight() ) + yBlock;

			if ( block >= sector->gridWidth() * sector->gridHeight() )
				continue;

			if ( sector->grid[block] )
			{
				for ( unsigned int i = 0; i < sector->grid[block]->count; ++i )
				{
					cUObject* object = sector->grid[block]->data[i];

					if ( object->pos().x >= x1 && object->pos().y >= y1 && object->pos().x <= x2 && object->pos().y <= y2 ) {
						// This sucks but we don't have much choice
						if (type == MT_CHARS) {
							P_PLAYER player = dynamic_cast<P_PLAYER>(object);

							// Exclude logged out players.
							if (!player || player->socket() || player->logoutTime()) {
								items[offset++] = object;
							}
						} else if (type == MT_MULTIS) {
							P_ITEM item = dynamic_cast<P_ITEM>(object);
							if (item && item->isMulti()) {
								items[offset++] = object;
							}
						} else {
							items[offset++] = object;
						}
					}
				}
			}
		}

	/*
		NOTE:
		Offset is our new count here. The count we measured previously
		was just there to measure the amount of memory we had to allocate
		for the list.
	*/

	switch ( type )
	{
	case MT_ITEMS:
	case MT_MULTIS:
		return new cItemSectorIterator( offset, items );

	case MT_CHARS:
	case MT_CHARSANDOFFLINE:
		return new cCharSectorIterator( offset, items );

	default:
		return new cSectorIterator( offset, items );
	};
}