Exemplo n.º 1
0
CPointMap CWorld::FindItemTypeNearby(const CPointMap & pt, IT_TYPE iType, int iDistance, bool bCheckMulti, bool bLimitZ)
{
	ADDTOCALLSTACK("CWorld::FindItemTypeNearby");
	// Find the closest item of this type.
	// This does not mean that i can touch it.
	// ARGS:
	//   iDistance = 2d distance to search.

	CPointMap ptFound;
	int iTestDistance;

		
	// Check dynamics first since they are the easiest.
	CWorldSearch Area( pt, iDistance );
	for (;;)
	{
		CItem * pItem = Area.GetItem();
		if ( pItem == NULL )
			break;

		if ( ! pItem->IsType( iType ) && ! pItem->Item_GetDef()->IsType(iType) )
			continue;
		if ( bLimitZ && ( pItem->GetTopPoint().m_z != pt.m_z ))
			continue;

		iTestDistance = pt.GetDist(pItem->GetTopPoint());
		if ( iTestDistance > iDistance )
			continue;

		ptFound = pItem->GetTopPoint();
		iDistance = iTestDistance;	// tighten up the search.
		if ( ! iDistance )
			return( ptFound );
	}

	// Check for appropriate terrain type
	CRectMap rect;
	rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
		pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
		pt.m_map);

	const CUOMapMeter * pMeter = NULL;
	for (int x = rect.m_left; x < rect.m_right; x++, pMeter = NULL )
	{
		for ( int y = rect.m_top; y < rect.m_bottom; y++, pMeter = NULL )
		{
			CPointMap ptTest(static_cast<WORD>(x), static_cast<WORD>(y), pt.m_z, pt.m_map);
			pMeter = GetMapMeter(ptTest);

			if ( !pMeter )
				continue;
			if ( bLimitZ && ( pMeter->m_z != pt.m_z ) )
				continue;

			ptTest.m_z = pMeter->m_z;

			if ( iType != g_World.GetTerrainItemType( pMeter->m_wTerrainIndex ) )
				continue;

			iTestDistance = pt.GetDist(ptTest);
			if ( iTestDistance > iDistance )
				break;

			ptFound = ptTest;
			iDistance = iTestDistance;	// tighten up the search.
			if ( ! iDistance )
				return( ptFound );

			rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
				pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
				pt.m_map);
		}
	}


	// Check for statics
	rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
		pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
		pt.m_map);

	const CGrayMapBlock * pMapBlock = NULL;
	const CUOStaticItemRec * pStatic = NULL;
	const CItemBase * pItemDef = NULL;

	for (int x = rect.m_left; x < rect.m_right; x += UO_BLOCK_SIZE, pMapBlock = NULL )
	{
		for ( int y = rect.m_top; y < rect.m_bottom; y += UO_BLOCK_SIZE, pMapBlock = NULL )
		{
			CPointMap ptTest(static_cast<WORD>(x), static_cast<WORD>(y), pt.m_z, pt.m_map);
			pMapBlock = GetMapBlock( ptTest );

			if ( !pMapBlock )
				continue;
			
			size_t iQty = pMapBlock->m_Statics.GetStaticQty();
			if ( iQty <= 0 )
				continue;

			pStatic = NULL; 
			pItemDef = NULL;

			for ( size_t i = 0; i < iQty; i++, pStatic = NULL, pItemDef = NULL )
			{
				pStatic = pMapBlock->m_Statics.GetStatic( i );
				if ( bLimitZ && ( pStatic->m_z != ptTest.m_z ) )
					continue;

				// inside the range we want ?
				CPointMap ptStatic( pStatic->m_x+pMapBlock->m_x, pStatic->m_y+pMapBlock->m_y, pStatic->m_z, ptTest.m_map);
				iTestDistance = pt.GetDist(ptStatic);
				if ( iTestDistance > iDistance )
					continue;

				ITEMID_TYPE idTile = pStatic->GetDispID();

				// Check the script def for the item.
				pItemDef = CItemBase::FindItemBase( idTile );
				if ( pItemDef == NULL )
					continue;
				if ( ! pItemDef->IsType( iType ))
					continue;

				ptFound = ptStatic;
				iDistance = iTestDistance;
				if ( ! iDistance )
					return( ptFound );

				rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
					pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
					pt.m_map);
			}
		}
	}

	// Check for multi components
	if (bCheckMulti == true)
	{
		rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
			pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
			pt.m_map);

		for (int x = rect.m_left; x < rect.m_right; x++)
		{
			for (int y = rect.m_top; y < rect.m_bottom; y++)
			{
				CPointMap ptTest(static_cast<WORD>(x), static_cast<WORD>(y), pt.m_z, pt.m_map);

				CRegionLinks rlinks;
				size_t iRegionQty = ptTest.GetRegions(REGION_TYPE_MULTI, rlinks);
				if ( iRegionQty > 0 )
				{
					for (size_t iRegion = 0; iRegion < iRegionQty; iRegion++)
					{
						CRegionBase* pRegion = rlinks.GetAt(iRegion);
						CItem* pItem = pRegion->GetResourceID().ItemFind();
						if (pItem == NULL)
							continue;

						const CGrayMulti * pMulti = g_Cfg.GetMultiItemDefs(pItem);
						if (pMulti == NULL)
							continue;

						int x2 = ptTest.m_x - pItem->GetTopPoint().m_x;
						int y2 = ptTest.m_y - pItem->GetTopPoint().m_y;

						size_t iItemQty = pMulti->GetItemCount();
						for (size_t iItem = 0; iItem < iItemQty; iItem++)
						{
							const CUOMultiItemRec2* pMultiItem = pMulti->GetItem(iItem);
							ASSERT(pMultiItem);

							if ( !pMultiItem->m_visible )
								continue;
							if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 )
								continue;
							if ( bLimitZ && (pMultiItem->m_dz != ptTest.m_z))
								continue;

							iTestDistance = pt.GetDist(ptTest);
							if (iTestDistance > iDistance)
								continue;

							ITEMID_TYPE idTile = pMultiItem->GetDispID();

							// Check the script def for the item.
							pItemDef = CItemBase::FindItemBase(idTile);
							if (pItemDef == NULL || !pItemDef->IsType(iType))
								continue;

							ptFound = ptTest;
							iDistance = iTestDistance;
							if ( !iDistance )
								return( ptFound );

							rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
										  pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
										  pt.m_map);
						}
					}
				}
			}
		}
	}

	return ptFound;
}
Exemplo n.º 2
0
void WINAPI duXmlStatic::OnMouseMove(POINT pt)
{
	duRect rectStatic;
	Plugin_GetRect(this, &rectStatic);
	
	POINT ptStatic(pt);
	ptStatic.x -= rectStatic.left;
	ptStatic.y -= rectStatic.top;
	rectStatic.OffsetRect(-rectStatic.left, -rectStatic.top);
	duRect rcLine;
	duRect rcSegMent;
	int nSegMentLeft = 0;

	int nLineCount = (int)m_vtLine.size();
	int i;
	int nCurTop = 0;
	int nCurTextIndex = 0;
	for (i = 0;i < nLineCount; i++)
	{
		XMLSTATICLINE *pLine = m_vtLine[i];
		rcLine.SetRectEmpty();
		rcLine.right = rectStatic.Width();
		rcLine.top = nCurTop;
		rcLine.bottom = nCurTop + pLine->nHeight;
		
		int j;
		nSegMentLeft = 0;
		for (j = 0;j < (int)pLine->vtLineSegment.size(); j++)
		{
			XMLSTATICLINESEGMENT *pSegment = pLine->vtLineSegment[j];
			rcSegMent.SetRectEmpty();
			
			rcSegMent.left = nSegMentLeft;
			rcSegMent.right = nSegMentLeft + pSegment->nWidth; 
			rcSegMent.bottom = rcLine.bottom;
			rcSegMent.top = rcSegMent.bottom - pSegment->nHeight;
			
			if (rcSegMent.PtInRect(ptStatic))
			{
				if (m_pHotSegMent != pSegment)
				{
					BOOL fNeedRedraw = FALSE;
					if (IsHrefSegment(m_pHotSegMent) || IsHrefSegment(pSegment))
						fNeedRedraw = TRUE;
					
					m_pHotSegMent = pSegment;
					if (fNeedRedraw)
						Plugin_Redraw(this, TRUE);
				}
				return;
			}
			
			nSegMentLeft = rcSegMent.right;
		}
		
		nCurTop += (pLine->nHeight + m_nParagraphSpace);
	}
	
	if (IsHrefSegment(m_pHotSegMent))
	{
		m_pHotSegMent = NULL;
		Plugin_Redraw(this, TRUE);
	}
	else
		m_pHotSegMent = NULL;
}