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; }
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; }