void EditorView::restoreState ( )
{
	QString guiKeyPrefix ( "user/sw/kdbe/gui/" );
	
	char buf[300];
	
	kdbGetValueByParent ( guiKeyPrefix, "width", buf, 300 );
	int vwidth = atoi ( buf );
	
	kdbGetValueByParent ( guiKeyPrefix, "height", buf, 300 );
	int vheight = atoi ( buf );
	
	
        kdbGetValueByParent ( guiKeyPrefix, "x", buf, 300 );
	int vx = atoi ( buf );
	
        kdbGetValueByParent ( guiKeyPrefix, "y", buf, 300 );
	int vy = atoi ( buf );
	
	QValueList<int> splittersizes;
	
	kdbGetValueByParent ( guiKeyPrefix + "splitter/", "left", buf, 300 );
	int left = atoi ( buf );
	
	
	kdbGetValueByParent ( guiKeyPrefix + "splitter/", "right", buf, 300 );
	int right = atoi ( buf );
	
	if ( left != 0 && right != 0 )
	{
		splittersizes.push_back ( left );
		splittersizes.push_back ( right );
		
		splitter->setSizes ( splittersizes );
	}
	
	if ( vx != 0 && vy != 0 )
		move ( vx, vy );
		
	if ( vwidth != 0 && vheight != 0 )
		resize ( vwidth, vheight );
	
	openedKeys.clear ( );
	
	KeySet *opened = ksNew ( );
	kdbGetChildKeys ( guiKeyPrefix + "openedKeys", opened, KDB_O_RECURSIVE );
	
	for ( size_t i = 0; i < ksGetSize ( opened ); i++)
	{
		kdbGetValueByParent ( guiKeyPrefix + "openedKeys", QString ( ).setNum ( i ), buf, 300 );
		//cout << "pushing back " << buf << endl;
		openedKeys.push_back ( buf );
	}
	ksDel ( opened );
}
//BEGIN internal SLOTS 
void ThumbnailList::slotRequestVisiblePixmaps( int /*newContentsX*/, int newContentsY )
{
    // if an update is already scheduled or the widget is hidden, don't proceed
    if ( (m_delayTimer && m_delayTimer->isActive()) || !isShown() )
        return;

    int vHeight = visibleHeight(),
        vOffset = newContentsY == -1 ? contentsY() : newContentsY;

    // scroll from the top to the last visible thumbnail
    m_visibleThumbnails.clear();
    QValueList< PixmapRequest * > requestedPixmaps;
    QValueVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end();
    for ( ; tIt != tEnd; ++tIt )
    {
        ThumbnailWidget * t = *tIt;
        int top = childY( t ) - vOffset;
        if ( top > vHeight )
            break;
        if ( top + t->height() < 0 )
            continue;
        // add ThumbnailWidget to visible list
        m_visibleThumbnails.push_back( t );
        // if pixmap not present add it to requests
        if ( !t->page()->hasPixmap( THUMBNAILS_ID, t->pixmapWidth(), t->pixmapHeight() ) )
        {
            PixmapRequest * p = new PixmapRequest(
                    THUMBNAILS_ID, t->pageNumber(), t->pixmapWidth(), t->pixmapHeight(), THUMBNAILS_PRIO, true );
            requestedPixmaps.push_back( p );
        }
    }

    // actually request pixmaps
    if ( !requestedPixmaps.isEmpty() )
        m_document->requestPixmaps( requestedPixmaps );
}
bool Coord_cl::lineOfSight( const Coord_cl &target, UI16 targetheight, bool touch )
{
	//Console::instance()->send( QString( "LOScheck: Source:%1,Target:%2,Targetheight:%3\n" ).arg( z ).arg( target.z ).arg( targetheight ) );
	if( target.map != map )
		return false;

	if( (x == target.x) && (y == target.y) && (z == target.z) )
		return true;		// if source and target are on the same position

	SI32 n = ( target.x - x ), m = ( target.y - y ), i = 0;
	SI08 sgn_x = ( x <= target.x ) ? 1 : (-1); // signum for x
	SI08 sgn_y = ( y <= target.y ) ? 1 : (-1); // signum for y
	SI08 sgn_z = ( z <= target.z ) ? 1 : (-1); // signum for z
	if( x == target.x )
		sgn_x = 0;
	if( y == target.y )
		sgn_y = 0;
	if( z == target.z )
		sgn_z = 0;

	QValueList< Coord_cl > collisions;

	//first we get our x-y-coordinates
	if( sgn_x == 0 && sgn_y == 0 && !sgn_z == 0 ) // should fix shooting through floor issues
		{
			collisions.push_back( Coord_cl( x, y, 0, map ) );
		}
	else if( sgn_x == 0 ) // if we are on the same x-level, just push every x/y coordinate in y-direction from src to trg into the array
		for( i = 0; i <= (sgn_y * m); ++i )
		{
			collisions.push_back( Coord_cl( x, y + (sgn_y * i), 0, map ) );
		}
	else if ( sgn_y == 0 ) // if we are on the same y-level, just push every x/y coordinate in x-direction from src to trg into the array
		for( i = 0; i <= (sgn_x * n); ++i )
		{
			collisions.push_back( Coord_cl( x + (sgn_x * i), y, 0, map ) );
		}
	else
	{
		SI32 oldpos = y;
		bool exaktpos = false;
		for( i = 0; (sgn_x * n >= sgn_y * m) && (i <= (sgn_x * n)); i++ )
		{
			//Console::instance()->send( QString( "x:%1\n" ).arg( i ) );
			SI32 gridx = x + (sgn_x * i);
			if( ( ( n == 0 ) && ( gridx == 0 ) ) ||
				( ( n + ( gridx * m ) == 0 ) ) )
				continue;
			else
			{
				if( exaktpos )
				{
					collisions.push_back( Coord_cl( gridx, oldpos-sgn_y, 0, map ) );
					//Console::instance()->send( QString( "add exaktpos coordinate %1,%2\n" ).arg( gridx ).arg( oldpos-sgn_y ) );
					exaktpos = false;
				}
					
				// linear evaluation of extended 2x2 matrix, abbreviated
				double t = (double)sgn_x * ((double)i+0.5) * (double)m / (double)n + (double)y;
				//Console::instance()->send( QString( "t:%1\n" ).arg( t ) );

				if( ((sgn_y>0) && (specialFloor(t)==oldpos+0.5)) || ((sgn_y<0) && (specialFloor(t)==oldpos-0.5)) )
				{
					exaktpos = true;
				}
				
				if( ((sgn_y>0) && (t<oldpos+0.5)) || ((sgn_y<0) && (t>oldpos-0.5)) || (oldpos==target.y) )
				{
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
				}
				// but if not, we have to take BOTH coordinates, which the calculated collision is between!
				else
				{ 
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
					oldpos += sgn_y;
					collisions.push_back( Coord_cl( gridx, oldpos, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( gridx ).arg( oldpos ) );
				}
			}
		}
		
		oldpos = x;
		exaktpos = false;
		for( i = 0; (sgn_y * m >= sgn_x * n) && (i <= (sgn_y * m)); ++i )
		{
			//Console::instance()->send( QString( "y:%1\n" ).arg( i ) );
			SI32 gridy = y + (sgn_y * i);
			if( ( ( m == 0 ) && ( gridy == 0 ) ) ||
				( ( m + ( gridy * n ) == 0 ) ) )
				continue;
			else
			{
				if( exaktpos )
				{
					collisions.push_back( Coord_cl( oldpos-sgn_x, gridy, 0, map ) );
					//Console::instance()->send( QString( "add exaktpos coordinate %1,%2\n" ).arg( oldpos-sgn_x ).arg( gridy ) );
					exaktpos = false;
				}

				double t = (double)x + (double)n / (double)m * (double)sgn_y * ((double)i+0.5);
				//Console::instance()->send( QString( "t:%1\n" ).arg( t ) );

				if( ((sgn_x>0) && (specialFloor(t)==oldpos+0.5)) || ((sgn_x<0) && (specialFloor(t)==oldpos-0.5)) )
				{
					exaktpos = true;
				}

				if( ((sgn_x>0) && (t<oldpos+0.5)) || ((sgn_x<0) && (t>oldpos-0.5)) || (oldpos==target.x) )
				{
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );

				}
				// but if not, we have to take BOTH coordinates, which the calculated collision is between!
				else
				{ 
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );
					oldpos += sgn_x;;
					collisions.push_back( Coord_cl( oldpos, gridy, 0, map ) );
					//Console::instance()->send( QString( "add coordinate %1,%2\n" ).arg( oldpos ).arg( gridy ) );
				}
			}
		}
	}

	// the next will search for multis
	QPtrList< cItem > multis;
	RegionIterator4Items ri( *this );
	for( ri.Begin(); !ri.atEnd(); ri++ )
	{
		P_ITEM pi = ri.GetData();
		if( pi && pi->id() >= 0x4000 )
		{
			multis.append( pi );
		}
	}

	//touch wird von notouch getrennt, da der notouch algorithmus wesentlich aufwändiger
	//ist (touch benötigt die erste for-schleife nicht), macht den code zwar bisserl
	//unübersichtlicher, aber ist wesentlich effizienter

	//touch is separated from notouch, because the notouch calculation is much more to do
	//( one additional for-loop )

	if( targetheight > 0 )
	{
		--targetheight;
	}

	if( !touch )
	{
		for( i = target.z+targetheight; i >= target.z; --i )
		{
			bool blocked = false;
			//Console::instance()->send( QString( "i:%1\n" ).arg( i ) );
			double dz;
			double gradient;
			double offset;
			if( (sgn_x == 0) && (sgn_y == 0) )
			{
				dz = (double)i - (double)z;
				gradient = 1; //only to avoid problems, isnt used
				offset = 1;
			}
			else
			{
				dz = ( (double)i -(double)z ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
				gradient = (double)m / (double)n;
				offset = 0.5*( (double)y + (double)target.y - gradient*( x + target.x ) );
			}
	
			map_st map1, map2;
			SI32 j;
	
			bool posHigherThanMap;
			map1 = Map->seekMap( (*this) );
			if( map1.z > z )
			{
				posHigherThanMap = false;
			}
			else
			{
				posHigherThanMap = true;
			}
			
			//Console::instance()->send( QString( "after first things\n" ) );
			QValueList< Coord_cl >::iterator pit = collisions.begin();
			while( pit != collisions.end() )
			{
				//Console::instance()->send( QString( "coordinate:%1,%2 dz:%3\n" ).arg( (*pit).x ).arg( (*pit).y ).arg( dz ) );
				//lets see what z-coordinates we have to test
				//we do our calculations exakt, because its the only way to solve all problems
				//of floor
				//"minimum" ist am anfang der platte, "maximum" am ende
				//our line is y = gradient * x + offset
				//or x = ( y - offset ) / gradient
				//we now have to test, where the line cuts one position
				//start and endposition has to be done alone
				
				double z1 = -300;
				double z2 = -300;
				SI08 zmin, zmax;

				if( (sgn_x == 0) && (sgn_y == 0) )
				{
					if( dz > 0 )
					{
						zmin = z+1;
						zmax = i;
					}
					else
					{
						zmin = i+1;
						zmax = z;
					}
				}
				else if( sgn_x == 0 )
				{
					//gradient only in y-direction
					z1 = (double)i - dz*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 ); 
					z2 = (double)i - dz*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );
					//Console::instance()->send( QString( "i:%1,ty:%2,cy:%3\n" ).arg( i ).arg( target.y ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );

					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}

					/*another try, but i think its needed for all positions, not only start and end...
					//target 
					if( (*pit).y == target.y )
					{
						if( dz > 0 )
						{
							zmax = QMIN( zmax, i );
							//Console::instance()->send( QString( "TargetY, zmax:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
						else
						{
							zmin = QMAX( zmin, i+1 );
							//Console::instance()->send( QString( "TargetY, zmin:%1, i:%2\n" ).arg( zmin ).arg( i ) );
						}
					}

					//source
					if( (*pit).y == y )
					{
						if( dz > 0 )
						{
							zmin = QMAX( zmin, z );
							//Console::instance()->send( QString( "SourceY, zmin:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
						else
						{
							zmax = QMIN( zmax, z );
							//Console::instance()->send( QString( "SourceY, zmax:%1, i:%2\n" ).arg( zmax ).arg( i ) );
						}
					}*/
					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}

				}
				else if( sgn_y == 0 )
				{
					//gradient only in y-direction
					z1 = (double)i - dz*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 ); 
					z2 = (double)i - dz*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );
					//Console::instance()->send( QString( "i:%1,tx:%2,cx:%3\n" ).arg( i ).arg( target.x ).arg( (*pit).x ) );
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );

					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}
					
					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}

				}
				else
				{
					//4 lines to test
					double gradx = ( (double)target.y*(double)z - (double)y*(double)i ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
					double grady = ( (double)target.x*(double)z - (double)x*(double)i ) / ( (double)y*(double)target.x - (double)target.y*(double)x );

					//Console::instance()->send( QString( "gradx:%1,grady:%2\n" ).arg( gradx ).arg( grady ) );
					//Console::instance()->send( QString( "Gradient:%1,Offset:%2\n" ).arg( gradient ).arg( offset ) );
					double temp;
					temp = specialFloor( gradient*( (double)((*pit).x) - 0.5 ) + offset );
					//Console::instance()->send( QString( "temp1:%1\n" ).arg( temp ) );
					if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * ( (double)((*pit).x)-0.5 ) + grady * temp;
						}
						else
						{	
							z1 = gradx * ( (double)((*pit).x)-0.5 ) + grady * temp;
						}
						//Console::instance()->send( QString( "1:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( gradient*( (double)((*pit).x) + 0.5 ) + offset );
					//Console::instance()->send( QString( "temp2:%1\n" ).arg( temp ) );
					if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * ( (double)((*pit).x)+0.5 ) + grady * temp;
						}
						else
						{	
							z1 = gradx * ( (double)((*pit).x)+0.5 ) + grady * temp;
						}
						//Console::instance()->send( QString( "2:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( (double)((*pit).y) - 0.5 - offset ) / gradient;
					//Console::instance()->send( QString( "temp3:%1\n" ).arg( temp ) );
					if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * temp + grady * ((double)((*pit).y)-0.5);
						}
						else
						{
							z1 = gradx * temp + grady * ((double)((*pit).y)-0.5);
						}
						//Console::instance()->send( QString( "3:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					temp = specialFloor( (double)((*pit).y) + 0.5 - offset ) / gradient;
					//Console::instance()->send( QString( "temp4:%1\n" ).arg( temp ) );
					if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
					{
						if( z1 > -300 )
						{
							z2 = gradx * temp + grady * ((double)((*pit).y)+0.5);
						}
						else
						{
							z1 = gradx * temp + grady * ((double)((*pit).y)+0.5);
						}
						//Console::instance()->send( QString( "4:i:%1,tx:%2,ty:%3,cy:%4,cy:%5\n" ).arg( i ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
						//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					}
					
					//Console::instance()->send( QString( "z1:%1,z2:%2\n" ).arg( z1 ).arg( z2 ) );
					if( z1 > z2 )
					{
						zmin = (SI08)floor( z2 );
						zmax = (SI08)ceilf( z1 );
					}
					else
					{
						zmin = (SI08)floor( z1 );
						zmax = (SI08)ceilf( z2 );
					}

					if( z2 == -300 )
					{
						zmin = (SI08)floor( z1 );
					}

					if( dz > 0 )
					{
						zmax = QMIN( zmax, i );
						zmin = QMAX( zmin, z );
					}
					else
					{
						zmin = QMAX( zmin, i+1 );
						zmax = QMIN( zmax, z );
					}
					//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );
				}

				/*SI08 zmin = (SI08)floor( i - dz*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
				SI08 zmax;
				//Console::instance()->send( QString( "zmin:%1,dz:%2\n" ).arg( zmin ).arg( dz ) );
				if( dz > 0 )
				{
					zmin = QMAX( (SI08)floor( zmin - dz/2 ), z+1 );
					zmax = QMIN( zmin + dz + 1, target.z+targetheight+1 );	//to prevent floor-mistakes
				}
				else
				{
					zmin = QMIN( (SI08)floor( zmin + dz/2 ), target.z+1 );
					zmax = QMAX( zmin - dz + 1, z );	//to prevent floor-mistakes
				}*/
	
				// Texture mapping  
				map1 = Map->seekMap( *pit );
				map2 = Map->seekMap( Coord_cl( (*pit).x + sgn_x, (*pit).y + sgn_y, (*pit).z, map ) );
			
				//Console::instance()->send( QString( "maphoehe:%1\n" ).arg( map1.z ) );
				StaticsIterator msi = Map->staticsIterator( *pit );
				if( (map1.id != 2) && (map2.id != 2) ) 
				{
					if( ( map1.z >= zmin ) && ( map1.z <= zmax ) )
					{
						//its just in our way
						//Console::instance()->send( QString( "Map gescheitert\n" ) );
						blocked = true;
						break;
					}
	
					//now we have to test, if this tile is under our line and the next above or
					//vice verse
					//in this case, both dont cut our line, but the mapconnection between them
					//should do
					if( ( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz ) ) ||						// 1) lineofsight collides with a map "wall"
						( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmax-dz ) ) ||
						( ( ( map1.id >= 431  && map1.id <= 432  ) ||	// 3) lineofsight cuts a mountain
						( map1.id >= 467  && map1.id <= 475  ) ||
						( map1.id >= 543  && map1.id <= 560  ) ||
						( map1.id >= 1754 && map1.id <= 1757 ) ||
						( map1.id >= 1787 && map1.id <= 1789 ) ||
						( map1.id >= 1821 && map1.id <= 1824 ) ||
						( map1.id >= 1851 && map1.id <= 1854 ) ||
						( map1.id >= 1881 && map1.id <= 1884 ) ) &&
						( posHigherThanMap ) && ( msi.atEnd() ) ) ) // mountains cut only if we are not beneath them
					{
						//Console::instance()->send( QString( "map1:%1,map2:%2\n" ).arg( map1.z ).arg( map2.z ) );
						blocked = true;
						break;
					}
				}	 
				
				//Console::instance()->send( QString( "after map\n" ) );
	
				// Statics
				tile_st tile;
				while( !msi.atEnd() )
				{
					tile = TileCache::instance()->getTile( msi->itemid );
					//if it is in our way
					//Console::instance()->send( QString( "tilepos:%1,zmax:%2" ).arg( msi->zoff ).arg( zmax ) );
					//Console::instance()->send( QString( "zmin:%3\n" ).arg( zmin ) );
					if( ( zmax >= msi->zoff ) && ( zmin <= ( msi->zoff + tile.height ) ) )
					{
						//Console::instance()->send( QString( "statictile, id: %1\n" ).arg( msi->itemid ) );
						if( tile.isNoShoot() )
						{
							blocked = true;
							break;
						}
					}
		
					++msi;
				}
				if( blocked )
				{
					break;
				}
				
				//Console::instance()->send( QString( "after statics\n" ) );
				// Items
				RegionIterator4Items rj( (*pit), 0 );
				for( rj.Begin(); !rj.atEnd(); rj++ )
				{
					P_ITEM pi = rj.GetData();
					if( pi && pi->id() < 0x4000 )
					{
						tile = TileCache::instance()->getTile( pi->id() );
						if(	( zmax >= pi->pos().z ) && ( zmin <= ( pi->pos().z + tile.height ) ) && ( pi->visible() == 0 ) )
						{
							//Console::instance()->send( QString( "item, id: %1" ).arg( pi->id() ) );
							if( tile.isNoShoot() )
							{
								blocked = true;
								break;
							}
						}	
					}
				}
				if( blocked )
				{
					break;
				}
	
				//Console::instance()->send( QString( "after items\n" ) );
				// Multis
				QPtrListIterator< cItem > mit( multis );
				P_ITEM pi;
				while( ( pi = mit.current() ) )
				{
					MultiDefinition* def = MultiCache::instance()->getMulti( pi->id() - 0x4000 );
					if ( !def )
						continue;
					QValueVector<multiItem_st> multi = def->getEntries();
					for( j = 0; j < multi.size(); ++j )
					{
						if( ( multi[j].visible ) && ( pi->pos().x + multi[j].x == (*pit).x ) &&
							( pi->pos().y + multi[j].y == (*pit).y ) )			
						{
							tile = TileCache::instance()->getTile( multi[j].tile );
							if( ( zmax >= pi->pos().z + multi[j].z ) &&
								( zmin <= pi->pos().z + multi[j].z + tile.height ) )
							{
								if( tile.isNoShoot() )
								{
									blocked = true;
									break;
								}
							}	
						}
					}
					++mit;
				}
				//Console::instance()->send( QString( "after multis\n" ) );
				++pit;
			}
	
			if( !blocked )
				return true;
		}
		//there was no line to see through
		return false;
	}
	//now touch=true
	else
	{
		//Console::instance()->send( "touch\n" );
		double dz_up, dz_down;
		double gradient;
		double offset;
		if( (sgn_x == 0) && (sgn_y == 0) )
		{
			dz_up = ( (double)targetheight + (double)target.z ) - (double)z;
			dz_down = (double)target.z - ( (double)z - (double)15 );
			gradient = 1; //only to prevent problems, isnt used
			offset = 1;
		}
		else
		{
			//Console::instance()->send( QString( "xdiff:%1,ydiff:%2\n" ).arg( (double)target.x - (double)x ).arg( (double)target.y - (double)y ) );
			dz_up = ( ( (double)targetheight + (double)target.z ) - (double)z ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
			dz_down = ( (double)target.z - ( (double)z - (double)15 ) ) / sqrt( ((double)target.x - (double)x)*((double)target.x - (double)x) + ((double)target.y - (double)y)*((double)target.y - (double)y) );
			gradient = (double)m / (double)n;
			offset = 0.5*( (double)y + (double)target.y - gradient*( x + target.x ) );
		}
	
		map_st map1, map2;
		SI32 j;
	
		bool posHigherThanMap;
		map1 = Map->seekMap( (*this) );
		if( map1.z > z )
		{
			posHigherThanMap = false;
		}
		else
		{
			posHigherThanMap = true;
		}
		
		//Console::instance()->send( QString( "after first things\n" ) );
		QValueList< Coord_cl >::iterator pit = collisions.begin();
		while( pit != collisions.end() )
		{
			//Console::instance()->send( QString( "coordinate:%1,%2\n" ).arg( (*pit).x ).arg( (*pit).y ) );				
			//lets see what z-coordinates we have to test
			//anmerkung: touch kommt nur für chars vor, grösse von chars ist 15
			//SI08 zmin = (SI08)floor(  (double)z - (double)sourceheight + dz_down*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
			//SI08 zmax = (SI08)floor(  (double)z + dz_up*sqrt( ((double)target.x - (double)(*pit).x)*((double)target.x - (double)(*pit).x) + ((double)target.y - (double)(*pit).y)*((double)target.y - (double)(*pit).y) ) );
			SI08 zmin, zmax;
			double z1_up = -300;
			double z2_up = -300;
			double z1_down = -300;
			double z2_down = -300;
			bool targetpos = false;
			//Console::instance()->send( QString( "dz_down:%3,dz_up:%4\n" ).arg( dz_down ).arg( dz_up ) );

			if( (sgn_x == 0) && (sgn_y == 0) )
			{
				if( dz_up > 0 )
				{
					zmin = z+1;
					zmax = target.z;
				}
				else
				{
					zmin = target.z+1;
					zmax = z;
				}
				targetpos = true;
				if( (dz_up >= 0) && (dz_down >= 0) )
				{
					if( zmin < target.z )
					{
						zmax = target.z -1;
					}
					else
					{
						//we ignore this coordinate
						++pit;
						continue;
					}
				}
				else if( (dz_up <= 0) && (dz_down <= 0) )
				{
					if( zmax > target.z + targetheight+1 )
					{
						zmin = target.z + targetheight + 2;
					}
					else
					{
						++pit;
						continue;
					}
				}
				else 
				{
					//we may have to split the test into two if we would do it exactly
					//but i think we can throw away the test from down in this case
					if( zmax > target.z + targetheight+1 )
					{
						zmin = target.z + targetheight + 2;
					}
					else if( zmin < target.z )
					{
						zmax = target.z -1;
					}
					else
					{
						++pit;
						continue;
					}
				}
			}
			else if( sgn_x == 0 )
			{
				z1_up = target.z + targetheight - dz_up*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 ); 
				z2_up = target.z + targetheight - dz_up*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );
			
				z1_down = target.z - dz_down*( fabs( (double)target.y - (double)((*pit).y) ) -0.5 );
				z2_down = target.z - dz_down*( fabs( (double)target.y - (double)((*pit).y) ) +0.5 );

				//Console::instance()->send( QString( "ty:%2,cy:%3\n" ).arg( target.y ).arg( (*pit).y ) );
				//Console::instance()->send( QString( "z1_up:%1,z2_up:%2,z1_down:%3,z2_down:%4\n" ).arg( z1_up ).arg( z2_up ).arg( z1_down ).arg( z2_down ) );

				zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				zmin = QMIN( floor( z1_down ), floor( z2_down ) );

				//Console::instance()->send( QString( "y:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				//Console::instance()->send( QString( "y2:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				//Console::instance()->send( QString( "y3:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( (*pit).y == target.y )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
					//Console::instance()->send( QString( "y4:zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );
				}
			}
			else if( sgn_y == 0 )
			{
				z1_up = target.z + targetheight - dz_up*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 ); 
				z2_up = target.z + targetheight - dz_up*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );
			
				z1_down = target.z - dz_down*( fabs( (double)target.x - (double)((*pit).x) ) -0.5 );
				z2_down = target.z - dz_down*( fabs( (double)target.x - (double)((*pit).x) ) +0.5 );

				//Console::instance()->send( QString( "tx:%2,cx:%3\n" ).arg( target.x ).arg( (*pit).x ) );
				//Console::instance()->send( QString( "z1_up:%1,z2_up:%2,z1_down:%3,z2_down:%4\n" ).arg( z1_up ).arg( z2_up ).arg( z1_down ).arg( z2_down ) );

				zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				zmin = QMIN( floor( z1_down ), floor( z2_down ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				if( (*pit).x == target.x )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
				}
			}
			else
			{
				double gradx_up = ( (double)target.y*(double)z - (double)y*(double)(target.z + targetheight) ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
				double grady_up = ( (double)target.x*(double)z - (double)x*(double)(target.z + targetheight) ) / ( (double)y*(double)target.x - (double)target.y*(double)x );
				double gradx_down = ( (double)target.y*(double)(z-15) - (double)y*(double)(target.z) ) / ( (double)target.y*(double)x - (double)y*(double)target.x );
				double grady_down = ( (double)target.x*(double)(z-15) - (double)x*(double)(target.z) ) / ( (double)y*(double)target.x - (double)target.y*(double)x );

				//Console::instance()->send( QString( "gradx_up:%1,grady_up:%2,gradx_down:%3,grady_down:%4\n" ).arg( gradx_up ).arg( grady_up ).arg( gradx_down ).arg( grady_down ) );
				//Console::instance()->send( QString( "Gradient:%1,Offset:%2\n" ).arg( gradient ).arg( offset ) );

				double temp = specialFloor( gradient*( (double)((*pit).x) - 0.5 ) + offset );
				//Console::instance()->send( QString( "temp1:%1\n" ).arg( temp ) );
				if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * ( (double)((*pit).x)-0.5 ) + grady_up * temp;
						z2_down = gradx_down * ( (double)((*pit).x)-0.5 ) + grady_down * temp;
					}
					else
					{
						z1_up = gradx_up * ( (double)((*pit).x)-0.5 ) + grady_up * temp;
						z1_down = gradx_down * ( (double)((*pit).x)-0.5 ) + grady_down * temp;
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( gradient*( (double)((*pit).x) + 0.5 ) + offset );
				//Console::instance()->send( QString( "temp2:%1\n" ).arg( temp ) );
				if( ( temp >= ((double)((*pit).y)-0.5) ) && ( temp <= ((double)((*pit).y)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * ( (double)((*pit).x)+0.5 ) + grady_up * temp;
						z2_down = gradx_down * ( (double)((*pit).x)+0.5 ) + grady_down * temp;
					}
					else
					{	
						z1_up = gradx_up * ( (double)((*pit).x)+0.5 ) + grady_up * temp;
						z1_down = gradx_down * ( (double)((*pit).x)+0.5 ) + grady_down * temp;
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( (double)((*pit).y) - 0.5 - offset ) / gradient;
				//Console::instance()->send( QString( "temp3:%1\n" ).arg( temp ) );
				if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * temp + grady_up * ((double)((*pit).y)-0.5);
						z2_down = gradx_down * temp + grady_down * ((double)((*pit).y)-0.5);
					}
					else
					{
						z1_up = gradx_up * temp + grady_up * ((double)((*pit).y)-0.5);
						z1_down = gradx_down * temp + grady_down * ((double)((*pit).y)-0.5);
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}
				temp = specialFloor( (double)((*pit).y) + 0.5 - offset ) / gradient;
				//Console::instance()->send( QString( "temp4:%1\n" ).arg( temp ) );
				if( ( temp > ((double)((*pit).x)-0.5) ) && ( temp < ((double)((*pit).x)+0.5) ) )
				{
					if( z1_up > -300 )
					{
						z2_up = gradx_up * temp + grady_up * ((double)((*pit).y)+0.5);
						z2_down = gradx_down * temp + grady_down * ((double)((*pit).y)+0.5);
					}
					else
					{
						z1_up = gradx_up * temp + grady_up * ((double)((*pit).y)+0.5);
						z1_down = gradx_down * temp + grady_down * ((double)((*pit).y)+0.5);
					}
					//Console::instance()->send( QString( "tx:%1,ty:%2,cy:%3,cy:%4\n" ).arg( target.x ).arg( target.y ).arg( (*pit).x ).arg( (*pit).y ) );
					//Console::instance()->send( QString( "z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );
				}

				//Console::instance()->send( QString( "ergebnis: z1_up:%1,z1_down:%2,z2_up:%3,z2_down:%4\n" ).arg( z1_up ).arg( z1_down ).arg( z2_up ).arg( z2_down ) );

				if( z2_up == -300 )
				{
					zmin = floor( z1_down );
					zmax = ceil( z1_up );
				}
				else
				{
					zmin = QMIN( floor( z1_down ), floor( z2_down ) );
					zmax = QMAX( ceil( z1_up ), ceil( z2_up ) );
				}

				//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( dz_up > 0 )
				{
					zmax = QMIN( zmax, target.z+targetheight );
				}
				else
				{
					zmax = QMIN( zmax, z );
				}

				if( dz_down > 0 )
				{
					zmin = QMAX( zmin, z-14 );
				}
				else
				{
					zmin = QMAX( zmin, target.z+1 );
				}

				//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

				if( ((*pit).x == target.x) && ((*pit).y == target.y) )
				{
					targetpos = true;
					if( (dz_up >= 0) && (dz_down >= 0) )
					{
						if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							//we ignore this coordinate
							++pit;
							continue;
						}
					}
					else if( (dz_up <= 0) && (dz_down <= 0) )
					{
						if( zmax > target.z + targetheight+1)
						{
							zmin = target.z + targetheight + 2;
						}
						else
						{
							++pit;
							continue;
						}
					}
					else 
					{
						//we may have to split the test into two if we would do it exactly
						//but i think we can throw away the test from down in this case
						if( zmax > target.z + targetheight+1 )
						{
							zmin = target.z + targetheight + 2;
						}
						else if( zmin < target.z )
						{
							zmax = target.z -1;
						}
						else
						{
							++pit;
							continue;
						}
					}
				}				
			}
			//Console::instance()->send( QString( "zmin:%1,zmax:%2\n" ).arg( zmin ).arg( zmax ) );

			// Texture mapping  
			map1 = Map->seekMap( *pit );
			map2 = Map->seekMap( Coord_cl( (*pit).x + sgn_x, (*pit).y + sgn_y, (*pit).z, map ) );
			
			//Console::instance()->send( QString( "try2" ) );
			StaticsIterator msi = Map->staticsIterator( *pit );
			RegionIterator4Items rj( (*pit), 0 );
			if( (map1.id != 2) && (map2.id != 2) ) 
			{
				if( ( map1.z > zmin ) && ( map1.z < zmax ) )
				{
					//its just in our way
					//Console::instance()->send( QString( "map cut 1\n" ) );
					return false;
				}
				
				//now we have to test, if this tile is under our line and the next above or
				//vice verse
				//in this case, both dont cut our line, but the mapconnection between them
				//should do
				land_st tile = TileCache::instance()->getLand( map1.id );
				if( ( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz_down ) && !targetpos ) ||						// 1) lineofsight collides with a map "wall"
					( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmin+dz_down ) && !targetpos ) ||
					( tile.isBlocking() && posHigherThanMap && msi.atEnd() && rj.atEnd() ) )
				{
					//Console::instance()->send( QString( "map1:%1,map2:%2,map1id:%3\n" ).arg( map1.z ).arg( map2.z ).arg( map1.id ) );
					if( ( map1.z < map2.z ) && ( map1.z < zmin ) && ( map2.z > zmax+dz_down ) )
					{
						//Console::instance()->send( QString( "mapcut1\n" ) ); 
					}
					else if( ( map1.z > map2.z ) && ( map1.z > zmin ) && ( map2.z < zmin+dz_down ) )
					{
						//Console::instance()->send( QString( "mapcut2\n" ) );
					}
					else if( tile.isBlocking() && posHigherThanMap && msi.atEnd() && rj.atEnd() )
					{
						//Console::instance()->send( QString( "mapcut3\n" ) );
					}
					else
					{
						//Console::instance()->send( QString( "mapcut: this isnt possible\n" ) );
					}
					return false;
				}
			}	 
			
			//Console::instance()->send( QString( "after map\n" ) );
		
			// Statics
			tile_st tile;
			while( !msi.atEnd() )
			{
				tile = TileCache::instance()->getTile( msi->itemid );
				//Console::instance()->send( QString( "statictilepos:%1,zmax:%2,zmin:%3\n" ).arg( msi->zoff ).arg( zmax ).arg( zmin ) );
				//if it is in our way
				if(	( zmax >= msi->zoff ) && ( zmin <= ( msi->zoff + tile.height ) ) )
				{
					if( tile.isBlocking() || tile.isRoofOrFloorTile() )
					{
						return false;
					}
				}
			
				++msi;
			}
			
			//Console::instance()->send( QString( "after statics\n" ) );
			// Items
			//Console::instance()->send( QString( "Items at: %1,%2,%3,%4\n" ).arg( (*pit).x ).arg( (*pit).y ).arg( (*pit).z ).arg( (*pit).map ) );
			for( rj.Begin(); !rj.atEnd(); rj++ )
			{
				//Console::instance()->send( QString( "foritem\n" ) );
				P_ITEM pi = rj.GetData();
				if( pi && pi->id() < 0x4000 )
				{
					tile = TileCache::instance()->getTile( pi->id() );
					//Console::instance()->send( QString( "itemtilepos:%1,zmax:%2,zmin:%3\n" ).arg( pi->pos().z ).arg( zmax ).arg( zmin ) );
					if(	( zmax >= pi->pos().z ) && ( zmin <= ( pi->pos().z + tile.height ) ) && ( pi->visible() == 0 ) )
					{
						if( tile.isBlocking() || tile.isRoofOrFloorTile() )
						{
							//Console::instance()->send( QString( "Item:%1,Z:%2,Height:%3\n" ).arg( pi->id() ).arg( pi->pos().z ).arg( tile.height ) );
							return false;
						}
					}	
				}
			}
			
			//Console::instance()->send( QString( "after items\n" ) );
			// Multis
			QPtrListIterator< cItem > mit( multis );
			P_ITEM pi;
			while( ( pi = mit.current() ) )
			{
				MultiDefinition* def = MultiCache::instance()->getMulti( pi->id() - 0x4000 );
				if ( !def )
				{
					++mit;
					continue;
				}
				QValueVector<multiItem_st> multi = def->getEntries();
				for( j = 0; j < multi.size(); ++j )
				{
					if( ( multi[j].visible ) && ( pi->pos().x + multi[j].x == (*pit).x ) &&
						( pi->pos().y + multi[j].y == (*pit).y ) )			
					{
						tile = TileCache::instance()->getTile( multi[j].tile );
						if( ( zmax >= pi->pos().z + multi[j].z ) &&
							( zmin <= pi->pos().z + multi[j].z + tile.height ) )
						{
							if( tile.isBlocking() || tile.isRoofOrFloorTile() )
							{
								return false;							
							}
						}	
					}
				}
				++mit;
			}
			//Console::instance()->send( QString( "after multis\n" ) );
			++pit;
		}
		return true;
	}
}
bool cMulti::canPlace( const Coord& pos, unsigned short multiid, QPtrList<cUObject>& moveOut, unsigned short yard )
{
	MultiDefinition *multi = MultiCache::instance()->getMulti( multiid );

	if ( !multi )
	{
		return false;
	}

	moveOut.setAutoDelete( false );

	// Get the boundaries and build a list sorted by x,y
	int left = multi->getLeft();
	int right = multi->getRight();
	int bottom = multi->getBottom();
	int top = multi->getTop();
	int height = multi->getHeight();
	int width = multi->getWidth();

	Q_UNUSED( bottom );

	QValueList<Coord> borderList; // a list of points around the foundation that need to be clear of impassables
	QValueList<Coord> yardList; // a list of points in the yard (front/back of the house that needs to be clear)

	for ( int x = 0; x < width; ++x )
	{
		for ( int y = 0; y < height; ++y )
		{
			Coord point = pos + Coord( x + left, y + top );
			bool hasBase = false; // Has this multi tile a base below the floor?

			// See if there are any tiles at that position
			const QValueVector<multiItem_st> &multiItems = multi->itemsAt( x + left, y + top );

			if ( multiItems.size() == 0 )
			{
				continue; // Skip this tile since there are no items here
			}

			cTerritory *region = Territories::instance()->region( point );
			if ( region && region->isNoHousing() )
			{
				return false; // No housing is allowed in this region
			}

			// Collect data for the intersect checks
			StaticsIterator statics = Maps::instance()->staticsIterator( point );
			MapItemsIterator items = MapObjects::instance()->listItemsAtCoord( point );
			int top, bottom;
			unsigned short landId;
			Maps::instance()->mapTileSpan( point, landId, bottom, top );

			// Check every tile of the multi at the current position
			// The following algorithm is more or less a ripoff of RunUOs idea.
			for ( unsigned int i = 0; i < multiItems.size(); ++i )
			{
				multiItem_st multiItem = multiItems[i];
				tile_st tile = TileCache::instance()->getTile( multiItem.tile );

				// Calculcate the spawn of the tile
				int itemBottom = point.z + multiItem.z;
				// if the tile is a surface, someone has to be able to stand on it.
				int itemTop = itemBottom + tile.height + ( ( ( tile.flag2 & 0x02 ) != 0 ) ? 16 : 0 );

				// There is special handling for floor tiles
				bool baseTile = multiItem.z == 0 && ( tile.flag1 & 0x10 ) != 0;
				bool isHovering = true; // This tile has not yet something to "stand" on

				Q_UNUSED( isHovering );
				if ( baseTile )
					hasBase = true;

				// Does the multi item intersect a land-tile?
				if ( ( itemTop < top && itemTop >= bottom ) || ( itemBottom < top && itemBottom >= bottom ) )
				{
					return false;
				}

				// Since houses can only be built on land and not on items, it's enough to check for
				// a solid foundation here
				if ( pos.z != bottom || pos.z != top )
				{
					return false;
				}

				// Check if the multi item is interfering with a static tile at the same position
				statics.reset();
				while ( !statics.atEnd() )
				{
					const staticrecord &staticTile = ( statics++ ).data();
					tile_st staticInfo = TileCache::instance()->getTile( staticTile.itemid );

					int staticBottom = staticTile.zoff;
					int staticTop = staticBottom + staticInfo.height;

					// The tile intersects a static tile
					if ( ( itemTop < staticTop && itemTop >= staticBottom ) || ( itemBottom < staticTop && itemBottom >= staticBottom ) )
					{
						bool impassable = ( staticInfo.flag1 & 0x40 ) != 0;
						bool background = ( staticInfo.flag1 & 0x01 ) != 0;
						bool surface = ( staticInfo.flag2 & 0x02 ) != 0;

						// A normally blocking tile is intersecting our multi
						if ( impassable || ( !background && surface ) )
						{
							return false;
						}
					}
				}

				// Do the same check (as above) with movable items, but make sure that movable items
				// are moved out of the house
				for ( P_ITEM pItem = items.first(); pItem; pItem = items.next() )
				{
					tile_st itemInfo = TileCache::instance()->getTile( pItem->id() );

					int dynamicBottom = pItem->pos().z;
					int dynamicTop = dynamicBottom + itemInfo.height;

					// Only handle the tile if it is intersecting the multi
					if ( ( itemTop < dynamicTop && itemTop >= dynamicBottom ) || ( itemBottom < dynamicTop && itemBottom >= dynamicBottom ) )
					{
						// Move the item out of the multi space if possible
						if ( ( pItem->movable() == 0 && itemInfo.weight != 255 ) || pItem->movable() == 1 )
						{
							moveOut.append( pItem );
						}
						else
						{
							bool impassable = ( itemInfo.flag1 & 0x40 ) != 0;
							bool background = ( itemInfo.flag1 & 0x01 ) != 0;
							bool surface = ( itemInfo.flag2 & 0x02 ) != 0;

							// A normally blocking tile is intersecting our multi
							if ( impassable || ( !background && surface ) )
							{
								return false;
							}
						}
					}
				}

				// Moves mobiles inside the multi out to the ban location
				MapCharsIterator chars = MapObjects::instance()->listCharsAtCoord( point );
				for ( P_CHAR pChar = chars.first(); pChar; pChar = chars.next() )
				{
					// Move them ALWAYS out, they could be trapped by the castle
					// otherwise (or other strange multi forms)
					moveOut.append( pChar );
				}

				// To keep roads house free, here's a specialized check for roads
				if ( ( landId >= 0x71 && landId <= 0x8c ) || ( landId >= 0x14c && landId <= 0x14f ) || ( landId >= 0x161 && landId <= 0x174 ) || ( landId >= 0x1f0 && landId <= 0x1f3 ) || ( landId >= 0x26e && landId <= 0x279 ) || ( landId >= 0x27e && landId <= 0x281 ) || ( landId >= 0x324 && landId <= 0x3ac ) || ( landId >= 0x597 && landId <= 0x5a6 ) || ( landId >= 0x637 && landId <= 0x63a ) || ( landId >= 0x67d && landId <= 0x6a0 ) || ( landId >= 0x7ae && landId <= 0x7b1 ) || ( landId >= 0x442 && landId <= 0x479 ) || ( landId >= 0x501 && landId <= 0x510 ) || ( landId >= 0x009 && landId <= 0x015 ) || ( landId >= 0x150 && landId <= 0x15c ) )
				{
					return false; // Road Blocked
				}

				// For houses (they have a base you know...)
				// we collect another list of points around the house that need to be checked
				if ( hasBase )
				{
					int xOffset, yOffset;

					// We have to do two loops since the yard size does play a role here
					// but not for the border
					for ( xOffset = -1; xOffset <= 1; ++xOffset )
					{
						for ( yOffset = -yard; yOffset <= yard; ++yOffset )
						{
							Coord pos = point + Coord( xOffset, yOffset );

							if ( !yardList.contains( pos ) )
							{
								yardList.push_back( pos ); // Put this point into the yard checklist if it's not there
							}
						}
					}

					for ( xOffset = -1; xOffset <= 1; ++xOffset )
					{
						for ( yOffset = -1; yOffset <= 1; ++yOffset )
						{
							Coord pos = point + Coord( xOffset, yOffset );

							// Only do the following if the current tiles position differs from the
							// check position.
							if ( xOffset != 0 || yOffset != 0 )
							{
								// The border list should not contain tiles that are actually below the multis
								// floor and hence not visible and covered by a walkable multi tile.
								// So what we do here is check if within 8 z units of the multis floor there is a
								// walkable tile above the border tile
								int multiX = x + xOffset; // Offset to the upper left corner of the multi
								int multiY = y + yOffset; // Offset to the upper left corner of the multi
								bool found = false; // Assume there is no such tile

								// Only do this check if the to-be-checked tile is really within the multi
								// boundaries
								if ( multiX >= 0 && multiY >= 0 && multiX < width && multiY < height )
								{
									// Get the multi tiles at the to-check position
									const QValueVector<multiItem_st> &tiles = multi->itemsAt( multiX + left, multiY + right );
									QValueVector<multiItem_st>::const_iterator it;
									for ( it = tiles.begin(); it != tiles.end(); ++it )
									{
										if ( it->z > 8 )
										{
											continue; // Skip the tile if its above the base (2nd floor etc.)
										}

										// Get the tiledata info for this tile if it's below z8
										tile_st tileInfo = TileCache::instance()->getTile( it->tile );
										bool surface = ( tileInfo.flag2 & 0x02 ) != 0;

										if ( tileInfo.height == 0 && surface )
										{
											found = true;
											break;
										}
									}

									// We found a tile that we could stand on. So it's not neccesary to check
									// that the house stands on something walkable here.
									if ( found )
									{
										continue;
									}
								}

								// Add the tile to the list of border tiles.
								if ( !borderList.contains( pos ) )
								{
									borderList.append( pos );
								}
							}
						}
					}
				}
			}
		}
	}

	QValueList<Coord>::const_iterator it;

	// Now check all the accumulated border tiles
	for ( it = borderList.begin(); it != borderList.end(); ++it )
	{
		map_st mapTile = Maps::instance()->seekMap( *it );
		land_st mapTileInfo = TileCache::instance()->getLand( mapTile.id );

		// Impassable map tiles are not allowed nearby
		bool impassable = ( mapTileInfo.flag1 & 0x40 ) != 0;
		if ( impassable )
		{
			return false;
		}

		// Get Static Tiles
		StaticsIterator statics = Maps::instance()->staticsIterator( *it );
		while ( !statics.atEnd() )
		{
			const staticrecord &staticItem = statics.data();
			tile_st staticInfo = TileCache::instance()->getTile( staticItem.itemid );

			bool impassable = ( staticInfo.flag1 & 0x40 ) != 0;
			bool background = ( staticInfo.flag1 & 0x01 ) != 0;
			bool surface = ( staticInfo.flag2 & 0x02 ) != 0;

			// The tile is only of importance if it's not below the multi
			if ( ( staticItem.zoff > ( ( *it ).z + 2 ) ) && ( impassable || ( !background && surface ) ) )
			{
				return false; // A normally blocking tile is intersecting our multi border
			}

			statics++;
		}

		// Do the same check (as above) with dynamic items
		MapItemsIterator items = MapObjects::instance()->listItemsAtCoord( *it );
		for ( P_ITEM pItem = items.first(); pItem; pItem = items.next() )
		{
			tile_st itemInfo = TileCache::instance()->getTile( pItem->id() );

			// Move the item out of the multi space if possible
			if ( ( pItem->movable() == 0 && itemInfo.weight != 255 ) || pItem->movable() == 1 )
				continue;

			if ( pItem->pos().z <= ( ( *it ).z + 2 ) )
				continue; // Does not interfere with the border

			bool impassable = ( itemInfo.flag1 & 0x40 ) != 0;
			bool background = ( itemInfo.flag1 & 0x01 ) != 0;
			bool surface = ( itemInfo.flag2 & 0x02 ) != 0;

			// A normally blocking tile is intersecting our multi
			if ( impassable || ( !background && surface ) )
				return false;
		}
	}

	// The yard has to be free of any multis at that position
	for ( it = yardList.begin(); it != yardList.end(); ++it )
	{
		// Search for multis in the region
		MapMultisIterator multis = MapObjects::instance()->listMultisInCircle( *it, 18 );
		for ( cMulti*multi = multis.first(); multi; multi = multis.next() )
		{
			if ( multi->inMulti( *it ) )
			{
				// This is a simplified check but it should be sufficient.
				return false;
			}
		}
	}

	return true;
}