int CItemMulti::Ship_ListObjs( CObjBase ** ppObjList ) { // List all the objects in the structure. // Move the ship and everything on the deck // If too much stuff. then some will fall overboard. hehe. if ( ! IsTopLevel()) return 0; int iMaxDist = Multi_GetMaxDist(); // always list myself first. All other items must see my new region ! int iCount = 0; ppObjList[iCount++] = this; CWorldSearch AreaChar( GetTopPoint(), iMaxDist ); while ( iCount < MAX_MULTI_LIST_OBJS ) { CChar * pChar = AreaChar.GetChar(); if ( pChar == NULL ) break; if ( pChar->IsClient()) { pChar->GetClient()->addPause(); // get rid of flicker. for anyone even seeing this. } if ( ! m_pRegion->IsInside2d( pChar->GetTopPoint())) continue; int zdiff = pChar->GetTopZ() - GetTopZ(); if ( abs( zdiff ) > 3 ) continue; ppObjList[iCount++] = pChar; } CWorldSearch AreaItem( GetTopPoint(), iMaxDist ); while ( iCount < MAX_MULTI_LIST_OBJS ) { CItem * pItem = AreaItem.GetItem(); if ( pItem == NULL ) break; if ( pItem == this ) // already listed. continue; if ( ! Multi_IsPartOf( pItem )) { if ( ! m_pRegion->IsInside2d( pItem->GetTopPoint())) continue; if ( ! pItem->IsMovable()) continue; int zdiff = pItem->GetTopZ() - GetTopZ(); if ( abs( zdiff ) > 3 ) continue; } ppObjList[iCount++] = pItem; } return( iCount ); }
bool CChar::NPC_CheckWalkHere( const CPointBase & pt, const CRegionBase * pArea, WORD wBlockFlags ) const { ADDTOCALLSTACK("CChar::NPC_CheckWalkHere"); UNREFERENCED_PARAMETER(wBlockFlags); // Does the NPC want to walk here ? step on this item ? if ( !m_pNPC ) return false; if ( !pt.IsValidXY() ) return true; if ( m_pArea != NULL ) { if ( m_pNPC->m_Brain == NPCBRAIN_GUARD && !IsStatFlag(STATF_War) ) // guards will want to stay in guard range { if ( m_pArea->IsGuarded() && !pArea->IsGuarded() ) return false; } if ( Noto_IsCriminal() ) { if ( !m_pArea->IsGuarded() && pArea->IsGuarded() ) return false; } } // Is there a nasty object here that will hurt us ? CWorldSearch AreaItems(pt); for (;;) { CItem * pItem = AreaItems.GetItem(); if ( pItem == NULL ) break; if ( abs(pItem->GetTopZ() - pt.m_z) > 5 ) continue; switch ( pItem->GetType() ) { case IT_WEB: return (GetDispID() == CREID_GIANT_SPIDER) ? true : false; case IT_FIRE: return Can(CAN_C_FIRE_IMMUNE); case IT_TRAP: case IT_TRAP_ACTIVE: case IT_MOONGATE: case IT_TELEPAD: return false; default: break; } } return true; }
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::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::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; } }
void CImportFile::ImportFix() { ADDTOCALLSTACK("CImportFile::ImportFix"); // adjust all the containered items and eliminate duplicates. CheckLast(); int iRemoved = 0; CImportSer * pSerNext; m_pCurSer = static_cast <CImportSer*> ( m_ListSer.GetHead()); for ( ; m_pCurSer != NULL; m_pCurSer = pSerNext ) { pSerNext = static_cast <CImportSer*> ( m_pCurSer->GetNext()); if ( m_pCurSer->m_pObj == NULL ) // NEver created correctly { delete m_pCurSer; continue; } // Make sure this item is not a dupe ? CItem * pItemTest; if ( m_pCurSer->IsTopLevel()) // top level only { if ( m_pCurSer->m_pObj->IsItem()) { CItem * pItemCheck = dynamic_cast <CItem*>( m_pCurSer->m_pObj ); ASSERT(pItemCheck); pItemCheck->SetAttr(ATTR_MOVE_NEVER); CWorldSearch AreaItems( m_pCurSer->m_pObj->GetTopPoint()); for (;;) { CItem * pItem = AreaItems.GetItem(); if ( pItem == NULL ) break; if ( ! pItem->IsSameType( m_pCurSer->m_pObj )) continue; pItem->SetName( m_pCurSer->m_pObj->GetName()); if ( ! ( m_pCurSer->m_pObj->GetTopZ() == pItem->GetTopZ())) continue; goto item_delete; } } else { // dupe char ? } // Make sure the top level object is placed correctly. m_pCurSer->m_pObj->MoveTo( m_pCurSer->m_pObj->GetTopPoint()); m_pCurSer->m_pObj->Update(); if ( ! m_pCurSer->m_pObj->IsContainer()) delete m_pCurSer; continue; } pItemTest = dynamic_cast <CItem*> (m_pCurSer->m_pObj); if ( pItemTest == NULL ) { item_delete: delete m_pCurSer->m_pObj; delete m_pCurSer; iRemoved ++; continue; } // Find it's container. CImportSer* pSerCont = static_cast <CImportSer*> ( m_ListSer.GetHead()); CObjBase * pObjCont = NULL; for ( ; pSerCont != NULL; pSerCont = static_cast <CImportSer*> ( pSerCont->GetNext())) { if ( pSerCont->m_pObj == NULL ) continue; if ( pSerCont->m_dwSer == m_pCurSer->m_dwContSer ) { pObjCont = pSerCont->m_pObj; if ( ! pItemTest->LoadSetContainer( pObjCont->GetUID(), m_pCurSer->m_layer )) { goto item_delete; // not in a cont ? } m_pCurSer->m_dwContSer = UID_UNUSED; // found it. break; } } if ( ! m_pCurSer->IsTopLevel() || pObjCont == NULL) { goto item_delete; } // Is it a dupe in the container or equipped ? for ( CItem *pItem = dynamic_cast<CContainer*>(pObjCont)->GetContentHead(); pItem != NULL; pItem = pItem->GetNext() ) { if ( pItemTest == pItem ) continue; if ( pItemTest->IsItemEquipped()) { if ( pItemTest->GetEquipLayer() != pItem->GetEquipLayer()) continue; } else { if ( ! pItemTest->GetContainedPoint().IsSame2D( pItem->GetContainedPoint())) continue; } if ( ! pItemTest->IsSameType( pItem )) continue; goto item_delete; } // done with it if not a container. if ( ! pItemTest->IsContainer()) delete m_pCurSer; } if ( iRemoved ) { DEBUG_ERR(( "Import: removed %d bad items\n", iRemoved )); } m_ListSer.DeleteAll(); // done with the list now. }
bool CPointBase::r_WriteVal( LPCTSTR pszKey, CGString & sVal ) const { ADDTOCALLSTACK("CPointBase::r_WriteVal"); if ( !strnicmp( pszKey, "STATICS", 7 ) ) { pszKey += 7; const CGrayMapBlock * pBlock = g_World.GetMapBlock( *(this) ); if ( !pBlock ) return false; if ( *pszKey == '\0' ) { int iStaticQty = 0; for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); i++ ) { const CUOStaticItemRec * pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map ); if ( this->GetDist( ptTest ) > 0 ) continue; iStaticQty++; } sVal.FormatVal( iStaticQty ); return true; } SKIP_SEPARATORS( pszKey ); const CUOStaticItemRec * pStatic = NULL; int iStatic = 0; int type = 0; if ( !strnicmp( pszKey, "FINDID", 6 ) ) { pszKey += 6; SKIP_SEPARATORS( pszKey ); iStatic = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iStatic ); if ( type == 0 ) type = RES_ITEMDEF; SKIP_SEPARATORS( pszKey ); } else { iStatic = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iStatic ); } if ( type == RES_ITEMDEF ) { const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iStatic))); if ( !pItemDef ) { sVal.FormatVal( 0 ); return false; } for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ ) { pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map); if ( this->GetDist( ptTest ) > 0 ) continue; if ( pStatic->GetDispID() == pItemDef->GetDispID() ) break; } } else { for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ ) { pStatic = pBlock->m_Statics.GetStatic( i ); CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map); if ( this->GetDist( ptTest ) > 0 ) continue; if ( iStatic == 0 ) break; iStatic--; } } if ( !pStatic ) { sVal.FormatHex(0); return true; } SKIP_SEPARATORS( pszKey ); if ( !*pszKey ) pszKey = "ID"; ITEMID_TYPE idTile = pStatic->GetDispID(); if ( !strnicmp( pszKey, "COLOR", 5 ) ) { sVal.FormatHex( pStatic->m_wHue ); return true; } else if ( !strnicmp( pszKey, "ID", 2 ) ) { sVal.FormatHex( idTile ); return true; } else if ( !strnicmp( pszKey, "Z", 1 ) ) { sVal.FormatVal( pStatic->m_z ); return true; } // Check the script def for the item. CItemBase * pItemDef = CItemBase::FindItemBase( idTile ); if ( pItemDef == NULL ) { DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile )); return false; } return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv ); } else if ( !strnicmp( pszKey, "COMPONENTS", 10) ) { pszKey += 10; CRegionLinks rlinks; const CRegionBase* pRegion = NULL; CItem* pItem = NULL; const CGrayMulti* pMulti = NULL; const CUOMultiItemRec2* pMultiItem = NULL; size_t iMultiQty = GetRegions(REGION_TYPE_MULTI, rlinks); if ( *pszKey == '\0' ) { int iComponentQty = 0; for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; iComponentQty++; } } sVal.FormatVal( iComponentQty ); return true; } SKIP_SEPARATORS( pszKey ); int iComponent = 0; int type = 0; if ( strnicmp( pszKey, "FINDID", 6 ) == 0 ) { pszKey += 6; SKIP_SEPARATORS( pszKey ); iComponent = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iComponent ); if ( type == 0 ) type = RES_ITEMDEF; SKIP_SEPARATORS( pszKey ); } else { iComponent = Exp_GetVal( pszKey ); type = RES_GET_TYPE( iComponent ); } if ( type == RES_ITEMDEF ) { const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iComponent))); if ( pItemDef == NULL ) { sVal.FormatVal( 0 ); return false; } for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; const CItemBase* pMultiItemDef = CItemBase::FindItemBase(pMultiItem->GetDispID()); if (pMultiItemDef != NULL && pMultiItemDef->GetDispID() == pItemDef->GetDispID()) break; } if (pMultiItem != NULL) break; } } else { for (size_t i = 0; i < iMultiQty; i++) { pRegion = rlinks.GetAt(i); if (pRegion == NULL) continue; pItem = pRegion->GetResourceID().ItemFind(); if (pItem == NULL) continue; const CPointMap ptMulti = pItem->GetTopPoint(); pMulti = g_Cfg.GetMultiItemDefs(pItem); if (pMulti == NULL) continue; size_t iQty = pMulti->GetItemCount(); for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++) { pMultiItem = pMulti->GetItem(ii); if (pMultiItem == NULL) break; if (pMultiItem->m_visible == 0) continue; CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map); if (GetDist(ptTest) > 0) continue; if (iComponent == 0) break; iComponent--; } if (pMultiItem != NULL) break; } } if ( pMultiItem == NULL ) { sVal.FormatHex(0); return true; } SKIP_SEPARATORS( pszKey ); if ( !*pszKey ) pszKey = "ID"; ITEMID_TYPE idTile = pMultiItem->GetDispID(); if ( strnicmp( pszKey, "ID", 2 ) == 0 ) { sVal.FormatHex( idTile ); return true; } else if ( strnicmp( pszKey, "MULTI", 5 ) == 0 ) { pszKey += 5; if (*pszKey != '\0') { SKIP_SEPARATORS(pszKey); return pItem->r_WriteVal( pszKey, sVal, &g_Serv ); } sVal.FormatHex( pItem->GetUID() ); return true; } else if ( strnicmp( pszKey, "Z", 1 ) == 0 ) { sVal.FormatVal( pItem->GetTopZ() + pMultiItem->m_dz ); return true; } // Check the script def for the item. CItemBase * pItemDef = CItemBase::FindItemBase( idTile ); if ( pItemDef == NULL ) { DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile )); return false; } return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv ); } int index = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 ); if ( index < 0 ) return false; switch ( index ) { case PT_M: case PT_MAP: sVal.FormatVal(m_map); break; case PT_X: sVal.FormatVal(m_x); break; case PT_Y: sVal.FormatVal(m_y); break; case PT_Z: sVal.FormatVal(m_z); break; case PT_ISNEARTYPE: { pszKey += 10; SKIP_SEPARATORS( pszKey ); SKIP_ARGSEP( pszKey ); int iType = g_Cfg.ResourceGetIndexType( RES_TYPEDEF, pszKey ); int iDistance = 0; bool bCheckMulti = false; SKIP_IDENTIFIERSTRING( pszKey ); SKIP_SEPARATORS( pszKey ); SKIP_ARGSEP( pszKey ); if ( *pszKey ) iDistance = Exp_GetVal(pszKey); if ( *pszKey ) bCheckMulti = Exp_GetVal(pszKey) != 0; sVal.FormatVal( g_World.IsItemTypeNear(*this, static_cast<IT_TYPE>(iType), iDistance, bCheckMulti)); break; } case PT_REGION: { // Check that the syntax is correct. if ( pszKey[6] && pszKey[6] != '.' ) return false; CRegionWorld * pRegionTemp = dynamic_cast <CRegionWorld*>(this->GetRegion(REGION_TYPE_AREA | REGION_TYPE_MULTI)); if ( !pszKey[6] ) { // We're just checking if the reference is valid. sVal.FormatVal( pRegionTemp? 1:0 ); return true; } // We're trying to retrieve a property from the region. pszKey += 7; if ( pRegionTemp ) return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv ); return false; } case PT_ROOM: { if ( pszKey[4] && pszKey[4] != '.' ) return false; CRegionBase * pRegionTemp = this->GetRegion( REGION_TYPE_ROOM ); if ( !pszKey[4] ) { sVal.FormatVal( pRegionTemp? 1:0 ); return true; } pszKey += 5; if ( pRegionTemp ) return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv ); return false; } case PT_SECTOR: { if ( pszKey[6] == '.' ) { pszKey += 7; CSector * pSectorTemp = this->GetSector(); if (pSectorTemp) return pSectorTemp->r_WriteVal(pszKey, sVal, &g_Serv); } return false; } default: { const CUOMapMeter * pMeter = g_World.GetMapMeter(*this); if ( pMeter ) { switch( index ) { case PT_TYPE: { CItemTypeDef * pTypeDef = g_World.GetTerrainItemTypeDef( pMeter->m_wTerrainIndex ); if ( pTypeDef != NULL ) sVal = pTypeDef->GetResourceName(); else sVal = ""; } return true; case PT_TERRAIN: { pszKey += strlen(sm_szLoadKeys[index]); if ( *pszKey == '.' ) // do we have an argument? { SKIP_SEPARATORS( pszKey ); if ( !strnicmp( pszKey, "Z", 1 )) { sVal.FormatVal( pMeter->m_z ); return( true ); } return( false ); } else { sVal.FormatHex( pMeter->m_wTerrainIndex ); } } return true; } } return false; } } return true; }
void CImportFile::MergeDupes() { ADDTOCALLSTACK("CImportFile::MergeDupes"); // place all items and eliminate duplicates. CheckLast(); int iRemoved = 0; CImportSer *pSerNext; m_pCurSer = static_cast<CImportSer *>(m_ListSer.GetHead()); for ( ; m_pCurSer != NULL; m_pCurSer = pSerNext ) { pSerNext = static_cast<CImportSer *>(m_pCurSer->GetNext()); if ( m_pCurSer->m_pObj == NULL ) // never created correctly { delete m_pCurSer; continue; } // Make sure this item is not a dupe ? CItem *pItemTest; if ( m_pCurSer->IsTopLevel() ) // top level only { if ( m_pCurSer->m_pObj->IsItem() ) { CItem *pItemCheck = dynamic_cast<CItem *>(m_pCurSer->m_pObj); ASSERT(pItemCheck); pItemCheck->SetAttr(ATTR_MOVE_NEVER); CWorldSearch AreaItems(m_pCurSer->m_pObj->GetTopPoint()); for (;;) { CItem *pItem = AreaItems.GetItem(); if ( pItem == NULL ) break; if ( !pItem->IsIdentical(m_pCurSer->m_pObj )) continue; pItem->SetName(m_pCurSer->m_pObj->GetName()); if ( !(m_pCurSer->m_pObj->GetTopZ() == pItem->GetTopZ()) ) continue; goto item_delete; } } // Make sure the top level object is placed correctly. m_pCurSer->m_pObj->MoveTo(m_pCurSer->m_pObj->GetTopPoint()); m_pCurSer->m_pObj->Update(); if ( !m_pCurSer->m_pObj->IsContainer() ) delete m_pCurSer; continue; } pItemTest = dynamic_cast <CItem*> (m_pCurSer->m_pObj); if ( pItemTest == NULL ) { item_delete: delete m_pCurSer->m_pObj; delete m_pCurSer; iRemoved ++; continue; } delete m_pCurSer; } if ( iRemoved ) { DEBUG_ERR(( "Import: removed %d bad items\n", iRemoved )); } m_ListSer.DeleteAll(); // done with the list now. }