bool CMenuItem::ParseLine( TCHAR * pszArgs, CScriptObj * pObjBase, CTextConsole * pSrc ) { ADDTOCALLSTACK("CMenuItem::ParseLine"); if ( *pszArgs == '@' ) { // This allows for triggers in menus return false; } TCHAR * pszArgStart = pszArgs; while ( _ISCSYM( *pszArgs )) pszArgs++; if ( *pszArgs ) { *pszArgs = '\0'; pszArgs++; GETNONWHITESPACE( pszArgs ); } // The item id (if we want to have an item type menu) or 0 if ( strcmp( pszArgStart, "0" ) != 0 ) { CItemBase * pItemBase = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(g_Cfg.ResourceGetIndexType( RES_ITEMDEF, pszArgStart ))); if ( pItemBase != NULL ) { m_id = static_cast<WORD>(pItemBase->GetDispID()); pObjBase = pItemBase; } else { DEBUG_ERR(( "Bad MENU item id '%s'\n", pszArgStart )); return( false ); // skip this. } } else { m_id = 0; } if ( pObjBase != NULL ) { pObjBase->ParseText( pszArgs, pSrc ); } else { g_Serv.ParseText( pszArgs, pSrc ); } // Parsing @color if ( *pszArgs == '@' ) { pszArgs++; HUE_TYPE wHue = static_cast<HUE_TYPE>(Exp_GetVal( pszArgs )); if ( wHue != 0 ) wHue = (wHue == 1? 0x7FF: wHue-1); m_color = wHue; SKIP_ARGSEP( pszArgs ); } else m_color = 0; m_sText = pszArgs; if ( m_sText.IsEmpty()) { if ( pObjBase ) // use the objects name by default. { m_sText = pObjBase->GetName(); if ( ! m_sText.IsEmpty()) return( true ); } DEBUG_ERR(( "Bad MENU item text '%s'\n", pszArgStart )); } return( !m_sText.IsEmpty() ); }
void CWorld::GetFixPoint( const CPointMap & pt, CGrayMapBlockState & block) { //Will get the highest CAN_I_PLATFORM|CAN_I_CLIMB and places it into block.Bottom ADDTOCALLSTACK("CWorld::GetFixPoint"); CItemBase * pItemDef = NULL; CItemBaseDupe * pDupeDef = NULL; CItem * pItem = NULL; DWORD wBlockThis = 0; signed char z = 0; int x2 = 0, y2 = 0; // Height of statics at/above given coordinates // do gravity here for the z. const CGrayMapBlock * pMapBlock = GetMapBlock( pt ); if (pMapBlock == NULL) return; size_t iQty = pMapBlock->m_Statics.GetStaticQty(); if ( iQty > 0 ) // no static items here. { x2 = pMapBlock->GetOffsetX(pt.m_x); y2 = pMapBlock->GetOffsetY(pt.m_y); const CUOStaticItemRec * pStatic = NULL; for ( size_t i = 0; i < iQty; ++i, z = 0, pStatic = NULL, pDupeDef = NULL ) { if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 )) continue; pStatic = pMapBlock->m_Statics.GetStatic( i ); if ( pStatic == NULL ) continue; z = pStatic->m_z; pItemDef = CItemBase::FindItemBase( pStatic->GetDispID() ); if ( pItemDef ) { if (pItemDef->GetID() == pStatic->GetDispID()) //parent item { wBlockThis = (pItemDef->m_Can & CAN_I_MOVEMASK); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pStatic->GetDispID())); if ( ! pDupeDef ) { g_Log.EventDebug("Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pStatic->GetDispID(),pStatic->m_x+pMapBlock->m_x,pStatic->m_y+pMapBlock->m_y,pStatic->m_z); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else { wBlockThis = (pDupeDef->m_Can & CAN_I_MOVEMASK); z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight()); } } } else if ( pStatic->GetDispID() ) CItemBase::GetItemTiledataFlags(wBlockThis,pStatic->GetDispID()); if (block.m_Bottom.m_z < z) { if ((z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER))) { block.m_Bottom.m_dwBlockFlags = wBlockThis; block.m_Bottom.m_dwTile = pStatic->GetDispID() + TERRAIN_QTY; block.m_Bottom.m_z = z; } else if (block.m_Top.m_z > z) { block.m_Top.m_dwBlockFlags = wBlockThis; block.m_Top.m_dwTile = pStatic->GetDispID() + TERRAIN_QTY; block.m_Top.m_z = z; } } } } pItemDef = NULL; pDupeDef = NULL; pItem = NULL; wBlockThis = 0; z = 0; x2 = y2 = 0; iQty = 0; // Any multi items here ? // Check all of them CRegionLinks rlinks; size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks ); if ( iRegionQty > 0 ) { // ------------ For variables -------------------- CRegionBase * pRegion = NULL; const CGrayMulti * pMulti = NULL; const CUOMultiItemRec2 * pMultiItem = NULL; x2 = 0; y2 = 0; // ------------ For variables -------------------- for ( size_t iRegion = 0; iRegion < iRegionQty; ++iRegion, pRegion = NULL, pItem = NULL, pMulti = NULL, x2 = 0, y2 = 0 ) { pRegion = rlinks.GetAt(iRegion); if ( pRegion != NULL ) pItem = pRegion->GetResourceID().ItemFind(); if ( pItem != NULL ) { pMulti = g_Cfg.GetMultiItemDefs(pItem); if ( pMulti ) { x2 = pt.m_x - pItem->GetTopPoint().m_x; y2 = pt.m_y - pItem->GetTopPoint().m_y; iQty = pMulti->GetItemCount(); for ( size_t ii = 0; ii < iQty; ++ii, pMultiItem = NULL, z = 0 ) { pMultiItem = pMulti->GetItem(ii); if ( !pMultiItem ) break; if ( ! pMultiItem->m_visible ) continue; if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 ) continue; z = static_cast<signed char>(pItem->GetTopZ() + pMultiItem->m_dz); pItemDef = CItemBase::FindItemBase( pMultiItem->GetDispID() ); if ( pItemDef != NULL ) { if ( pItemDef->GetID() == pMultiItem->GetDispID() ) //parent item { wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pMultiItem->GetDispID())); if ( pDupeDef == NULL ) { g_Log.EventDebug("Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pMultiItem->GetDispID(),pMultiItem->m_dx+pItem->GetTopPoint().m_x,pMultiItem->m_dy+pItem->GetTopPoint().m_y,pMultiItem->m_dz+pItem->GetTopPoint().m_z); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else { wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight()); } } } else if ( pMultiItem->GetDispID() ) CItemBase::GetItemTiledataFlags(wBlockThis,pMultiItem->GetDispID()); if (block.m_Bottom.m_z < z) { if ((z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER))) { block.m_Bottom.m_dwBlockFlags = wBlockThis; block.m_Bottom.m_dwTile = pMultiItem->GetDispID() + TERRAIN_QTY; block.m_Bottom.m_z = z; } else if (block.m_Top.m_z > z) { block.m_Top.m_dwBlockFlags = wBlockThis; block.m_Top.m_dwTile = pMultiItem->GetDispID() + TERRAIN_QTY; block.m_Top.m_z = z; } } } } } } } pItemDef = NULL; pDupeDef = NULL; pItem = NULL; wBlockThis = 0; x2 = y2 = iQty = 0; z = 0; // Any dynamic items here ? // NOTE: This could just be an item that an NPC could just move ? CWorldSearch Area( pt ); for (;;) { pItem = Area.GetItem(); if ( !pItem ) break; z = pItem->GetTopZ(); // Invis items should not block ??? pItemDef = CItemBase::FindItemBase( pItem->GetDispID() ); if ( pItemDef ) { if ( pItemDef->GetDispID() == pItem->GetDispID() )//parent item { wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pItem->GetDispID())); if ( ! pDupeDef ) { g_Log.EventDebug("Failed to get non-parent reference (dynamic) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pItem->GetDispID(),pItem->GetTopPoint().m_x,pItem->GetTopPoint().m_y,pItem->GetTopPoint().m_z); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight()); } else { wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight()); } } if ( block.m_Bottom.m_z < z ) { if ( (z < pt.m_z + PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER)) ) { block.m_Bottom.m_dwBlockFlags = wBlockThis; block.m_Bottom.m_dwTile = pItemDef->GetDispID() + TERRAIN_QTY; block.m_Bottom.m_z = z; } else if ( block.m_Top.m_z > z ) { block.m_Top.m_dwBlockFlags = wBlockThis; block.m_Top.m_dwTile = pItemDef->GetDispID() + TERRAIN_QTY; block.m_Top.m_z = z; } } } else if (pItem->GetDispID()) CItemBase::GetItemTiledataFlags(wBlockThis,pItem->GetDispID()); } wBlockThis = 0; // Terrain height is screwed. Since it is related to all the terrain around it. const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y)); if ( ! pMeter ) return; if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE ) { wBlockThis = 0; } else if ( CUOMapMeter::IsTerrainNull( pMeter->m_wTerrainIndex ) ) // inter dungeon type. { wBlockThis = CAN_I_BLOCK; } else { CGrayTerrainInfo land( pMeter->m_wTerrainIndex ); //DEBUG_ERR(("Terrain flags - land.m_flags 0%x wBlockThis (0%x)\n",land.m_flags,wBlockThis)); if ( land.m_flags & UFLAG1_WATER ) wBlockThis |= CAN_I_WATER; if ( land.m_flags & UFLAG1_DAMAGE ) wBlockThis |= CAN_I_FIRE; if ( land.m_flags & UFLAG1_BLOCK ) wBlockThis |= CAN_I_BLOCK; if (( ! wBlockThis ) || ( land.m_flags & UFLAG2_PLATFORM )) // Platform items should take precendence over non-platforms. wBlockThis = CAN_I_PLATFORM; } if (block.m_Bottom.m_z < pMeter->m_z) { if (((pMeter->m_z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER))) || (block.m_Bottom.m_z == UO_SIZE_MIN_Z)) { block.m_Bottom.m_dwBlockFlags = wBlockThis; block.m_Bottom.m_dwTile = pMeter->m_wTerrainIndex; block.m_Bottom.m_z = pMeter->m_z; } else if (block.m_Top.m_z > pMeter->m_z) { block.m_Top.m_dwBlockFlags = wBlockThis; block.m_Top.m_dwTile = pMeter->m_wTerrainIndex; block.m_Top.m_z = pMeter->m_z; } } if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z ) { //Fail safe... Reset to 0z with no top block; block.m_Bottom.m_dwBlockFlags = 0; block.m_Bottom.m_dwTile = 0; block.m_Bottom.m_z = 0; block.m_Top.m_dwBlockFlags = 0; block.m_Top.m_dwTile = 0; block.m_Top.m_z = UO_SIZE_Z; } }
void CWorld::GetHeightPoint( const CPointMap & pt, CGrayMapBlockState & block, bool fHouseCheck ) { ADDTOCALLSTACK("CWorld::GetHeightPoint"); CItemBase * pItemDef = NULL; CItemBaseDupe * pDupeDef = NULL; CItem * pItem = NULL; DWORD wBlockThis = 0; signed char z = 0; height_t zHeight = 0; int x2 = 0, y2 = 0; // Height of statics at/above given coordinates // do gravity here for the z. const CGrayMapBlock * pMapBlock = GetMapBlock( pt ); if (pMapBlock == NULL) return; size_t iQty = pMapBlock->m_Statics.GetStaticQty(); if ( iQty > 0 ) // no static items here. { x2 = pMapBlock->GetOffsetX(pt.m_x); y2 = pMapBlock->GetOffsetY(pt.m_y); const CUOStaticItemRec * pStatic = NULL; for ( size_t i = 0; i < iQty; ++i, z = 0, zHeight = 0, pStatic = NULL, pDupeDef = NULL ) { if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 )) continue; pStatic = pMapBlock->m_Statics.GetStatic( i ); if ( pStatic == NULL ) continue; z = pStatic->m_z; //DEBUG_ERR(("z (%d) block.m_zHeight (%d) block.m_Bottom.m_z (%d)\n",z,block.m_zHeight,block.m_Bottom.m_z)); if ( ! block.IsUsableZ( z, block.m_zHeight )) continue; // This static is at the coordinates in question. // enough room for me to stand here ? pItemDef = CItemBase::FindItemBase( pStatic->GetDispID() ); if ( pItemDef ) { //DEBUG_ERR(("pItemDef->GetID(0%x) pItemDef->GetDispID(0%x) pStatic->GetDispID(0%x)\n",pItemDef->GetID(),pItemDef->GetDispID(),pStatic->GetDispID())); if ( pItemDef->GetID() == pStatic->GetDispID() ) //parent item { zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pStatic->GetDispID())); if ( ! pDupeDef ) { g_Log.EventDebug("Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pStatic->GetDispID(),pStatic->m_x+pMapBlock->m_x,pStatic->m_y+pMapBlock->m_y,pStatic->m_z); zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); } else { zHeight = pDupeDef->GetHeight(); wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack... } } } else if ( pStatic->GetDispID() ) CItemBase::GetItemTiledataFlags(wBlockThis,pStatic->GetDispID()); block.CheckTile_Item( wBlockThis, z, zHeight, pStatic->GetDispID() + TERRAIN_QTY ); } } pItemDef = NULL; pDupeDef = NULL; pItem = NULL; wBlockThis = 0; z = 0; zHeight = 0; x2 = y2 = 0; iQty = 0; // Any multi items here ? // Check all of them if ( fHouseCheck ) { CRegionLinks rlinks; size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks ); if ( iRegionQty > 0 ) { // ------------ For variables -------------------- CRegionBase * pRegion = NULL; const CGrayMulti * pMulti = NULL; const CUOMultiItemRec2 * pMultiItem = NULL; x2 = 0; y2 = 0; // ------------ For variables -------------------- for ( size_t iRegion = 0; iRegion < iRegionQty; ++iRegion, pRegion = NULL, pItem = NULL, pMulti = NULL, x2 = 0, y2 = 0 ) { pRegion = rlinks.GetAt(iRegion); if ( pRegion != NULL ) pItem = pRegion->GetResourceID().ItemFind(); if ( pItem != NULL ) { pMulti = g_Cfg.GetMultiItemDefs(pItem); if ( pMulti ) { x2 = pt.m_x - pItem->GetTopPoint().m_x; y2 = pt.m_y - pItem->GetTopPoint().m_y; iQty = pMulti->GetItemCount(); for ( size_t ii = 0; ii < iQty; ++ii, pMultiItem = NULL, z = 0, zHeight = 0 ) { pMultiItem = pMulti->GetItem(ii); if ( !pMultiItem ) break; if ( ! pMultiItem->m_visible ) continue; if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 ) continue; z = static_cast<signed char>( pItem->GetTopZ() + pMultiItem->m_dz ); if ( ! block.IsUsableZ(z,block.m_zHeight)) continue; pItemDef = CItemBase::FindItemBase( pMultiItem->GetDispID() ); if ( pItemDef != NULL ) { if ( pItemDef->GetID() == pMultiItem->GetDispID() ) //parent item { zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pMultiItem->GetDispID())); if ( pDupeDef == NULL ) { g_Log.EventDebug("Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pMultiItem->GetDispID(),pMultiItem->m_dx+pItem->GetTopPoint().m_x,pMultiItem->m_dy+pItem->GetTopPoint().m_y,pMultiItem->m_dz+pItem->GetTopPoint().m_z); zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); } else { zHeight = pDupeDef->GetHeight(); wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack... } } } else if ( pMultiItem->GetDispID() ) CItemBase::GetItemTiledataFlags(wBlockThis,pMultiItem->GetDispID()); block.CheckTile_Item( wBlockThis, z, zHeight, pMultiItem->GetDispID() + TERRAIN_QTY ); } } } } } } pItemDef = NULL; pDupeDef = NULL; pItem = NULL; wBlockThis = 0; x2 = y2 = iQty = 0; zHeight = 0; z = 0; // Any dynamic items here ? // NOTE: This could just be an item that an NPC could just move ? CWorldSearch Area( pt ); for (;;) { pItem = Area.GetItem(); if ( !pItem ) break; z = pItem->GetTopZ(); if ( !block.IsUsableZ( z, block.m_zHeight ) ) continue; // Invis items should not block ??? pItemDef = CItemBase::FindItemBase( pItem->GetDispID() ); if ( pItemDef ) { if ( pItemDef->GetDispID() == pItem->GetDispID() )//parent item { zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove } else //non-parent item { pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pItem->GetDispID())); if ( ! pDupeDef ) { g_Log.EventDebug("Failed to get non-parent reference (dynamic) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pItem->GetDispID(),pItem->GetTopPoint().m_x,pItem->GetTopPoint().m_y,pItem->GetTopPoint().m_z); zHeight = pItemDef->GetHeight(); wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); } else { zHeight = pDupeDef->GetHeight(); wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack... } } } else if (pItem->GetDispID()) CItemBase::GetItemTiledataFlags(wBlockThis,pItem->GetDispID()); block.CheckTile_Item(wBlockThis, z, zHeight, pItem->GetDispID() + TERRAIN_QTY); } wBlockThis = 0; // Terrain height is screwed. Since it is related to all the terrain around it. const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y)); if ( ! pMeter ) return; if ( block.IsUsableZ( pMeter->m_z,block.m_zHeight ) ) { //DEBUG_ERR(("pMeter->m_wTerrainIndex 0%x wBlockThis (0%x)\n",pMeter->m_wTerrainIndex,wBlockThis)); if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE ) { wBlockThis = 0; } else if ( CUOMapMeter::IsTerrainNull( pMeter->m_wTerrainIndex ) ) // inter dungeon type. { wBlockThis = CAN_I_BLOCK; } else { CGrayTerrainInfo land( pMeter->m_wTerrainIndex ); //DEBUG_ERR(("Terrain flags - land.m_flags 0%x wBlockThis (0%x)\n",land.m_flags,wBlockThis)); if ( land.m_flags & UFLAG1_WATER ) wBlockThis |= CAN_I_WATER; if ( land.m_flags & UFLAG1_DAMAGE ) wBlockThis |= CAN_I_FIRE; if ( land.m_flags & UFLAG1_BLOCK ) wBlockThis |= CAN_I_BLOCK; if (( ! wBlockThis ) || ( land.m_flags & UFLAG2_PLATFORM )) // Platform items should take precendence over non-platforms. wBlockThis = CAN_I_PLATFORM; } //DEBUG_ERR(("TERRAIN wBlockThis (0%x)\n",wBlockThis)); block.CheckTile_Terrain( wBlockThis, pMeter->m_z, pMeter->m_wTerrainIndex ); } if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z ) { block.m_Bottom = block.m_Lowest; if ( block.m_Top.m_z == block.m_Bottom.m_z ) { block.m_Top.m_dwBlockFlags = 0; block.m_Top.m_dwTile = 0; block.m_Top.m_z = UO_SIZE_Z; } } }
void CWorld::GetHeightPoint2( const CPointMap & pt, CGrayMapBlockState & block, bool fHouseCheck ) { ADDTOCALLSTACK("CWorld::GetHeightPoint2"); // Height of statics at/above given coordinates // do gravity here for the z. DWORD wBlockThis = 0; const CGrayMapBlock * pMapBlock = GetMapBlock( pt ); if ( !pMapBlock ) { g_Log.EventWarn("GetMapBlock failed at %s.\n", pt.WriteUsed()); return; } { size_t iStaticQty = pMapBlock->m_Statics.GetStaticQty(); if ( iStaticQty > 0 ) // no static items here. { int x2 = pMapBlock->GetOffsetX(pt.m_x); int y2 = pMapBlock->GetOffsetY(pt.m_y); for ( size_t i = 0; i < iStaticQty; i++ ) { if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 )) continue; const CUOStaticItemRec * pStatic = pMapBlock->m_Statics.GetStatic( i ); signed char z = pStatic->m_z; if ( ! block.IsUsableZ(z,PLAYER_HEIGHT)) continue; // This static is at the coordinates in question. // enough room for me to stand here ? wBlockThis = 0; height_t zHeight = CItemBase::GetItemHeight( pStatic->GetDispID(), wBlockThis ); block.CheckTile( wBlockThis, z, zHeight, pStatic->GetDispID() + TERRAIN_QTY ); } } } // Any multi items here ? if ( fHouseCheck ) { CRegionLinks rlinks; size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks ); if ( iRegionQty > 0 ) { for ( size_t i = 0; i < iRegionQty; i++) { CRegionBase * pRegion = rlinks.GetAt(i); CItem * pItem = pRegion->GetResourceID().ItemFind(); if ( pItem != NULL ) { const CGrayMulti * pMulti = g_Cfg.GetMultiItemDefs(pItem); if ( pMulti ) { int x2 = pt.m_x - pItem->GetTopPoint().m_x; int y2 = pt.m_y - pItem->GetTopPoint().m_y; size_t iMultiQty = pMulti->GetItemCount(); for ( size_t j = 0; j < iMultiQty; j++ ) { const CUOMultiItemRec2 * pMultiItem = pMulti->GetItem(j); ASSERT(pMultiItem); if ( ! pMultiItem->m_visible ) continue; if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 ) continue; signed char zitem = static_cast<signed char>( pItem->GetTopZ() + pMultiItem->m_dz ); if ( ! block.IsUsableZ(zitem,PLAYER_HEIGHT)) continue; wBlockThis = 0; height_t zHeight = CItemBase::GetItemHeight( pMultiItem->GetDispID(), wBlockThis ); block.CheckTile( wBlockThis, zitem, zHeight, pMultiItem->GetDispID() + TERRAIN_QTY ); } } } } } } { // Any dynamic items here ? // NOTE: This could just be an item that an NPC could just move ? CWorldSearch Area( pt ); for (;;) { CItem * pItem = Area.GetItem(); if ( pItem == NULL ) break; signed char zitem = pItem->GetTopZ(); if ( ! block.IsUsableZ(zitem,PLAYER_HEIGHT)) continue; // Invis items should not block ??? CItemBase * pItemDef = pItem->Item_GetDef(); ASSERT(pItemDef); // Get Attributes from ItemDef. If they are not set, get them from the static object (DISPID) wBlockThis = pItemDef->m_Can & (CAN_I_DOOR | CAN_I_WATER | CAN_I_CLIMB | CAN_I_BLOCK | CAN_I_PLATFORM); height_t zHeight = pItemDef->GetHeight(); DWORD wStaticBlockThis = 0; height_t zStaticHeight = CItemBase::GetItemHeight(pItem->GetDispID(), wStaticBlockThis); if (wBlockThis == 0) wBlockThis = wStaticBlockThis; if (zHeight == 0) zHeight = zStaticHeight; if ( !block.CheckTile( wBlockThis, zitem, zHeight, pItemDef->GetDispID() + TERRAIN_QTY ) ) { } } } // Check Terrain here. // Terrain height is screwed. Since it is related to all the terrain around it. { const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y)); ASSERT(pMeter); if ( block.IsUsableZ(pMeter->m_z,0)) { if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE ) wBlockThis = 0; else if ( pMeter->m_wTerrainIndex == TERRAIN_NULL ) // inter dungeon type. wBlockThis = CAN_I_BLOCK; else { CGrayTerrainInfo land( pMeter->m_wTerrainIndex ); if ( land.m_flags & UFLAG2_PLATFORM ) // Platform items should take precendence over non-platforms. wBlockThis = CAN_I_PLATFORM; else if ( land.m_flags & UFLAG1_WATER ) wBlockThis = CAN_I_WATER; else if ( land.m_flags & UFLAG1_DAMAGE ) wBlockThis = CAN_I_FIRE; else if ( land.m_flags & UFLAG1_BLOCK ) wBlockThis = CAN_I_BLOCK; else wBlockThis = CAN_I_PLATFORM; } block.CheckTile( wBlockThis, pMeter->m_z, 0, pMeter->m_wTerrainIndex ); } } if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z ) { block.m_Bottom = block.m_Lowest; } }