From 7124df235402523eccff2b6aaff0d2fbf8d1f2ea Mon Sep 17 00:00:00 2001 From: Flugente Date: Sat, 9 Apr 2016 16:11:43 +0000 Subject: [PATCH] - Fix: Get Item assignement: if no valid gridno is found, let the game find one upon loading the sector instead of risking a wrong gridno assignment - Fix: When dropping an item in strategic inventory, height values are not set - Fix: When looking for a valid gridno to drop items t via strategic inventory, WORLD_ITEM_REACHABLE is not reliable, as updated map topology trumps this. Instead rely upon finding a valid gridno once the sector is entered. - Fix: when searching for a new item dropoff gridno, search for new height too - Fix: if items are spawned mid-air, the player cannot retrieve them git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8136 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Assignments.cpp | 21 +++--- .../Map Screen Interface Map Inventory.cpp | 73 +++++++++--------- Tactical/Handle Items.cpp | 3 +- Tactical/Interface Control.cpp | 74 +++++++++---------- Tactical/Tactical Save.cpp | 3 + Tactical/Turn Based Input.cpp | 4 +- TileEngine/overhead map.cpp | 4 +- 7 files changed, 94 insertions(+), 88 deletions(-) diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index dec0bd61..dfc3f855 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -7197,14 +7197,7 @@ void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ ) CHAR16 wSectorName[ 64 ]; GetShortSectorString( sMapX, sMapY, wSectorName ); - - // if we don't have a valid spot to drop gear at, don't do so - better than having tons of items unreachable - if ( TileIsOutOfBounds( sDropOffGridNo ) ) - { - ScreenMsg( FONT_MCOLOR_RED, MSG_INTERFACE, pMapErrorString[50], wSectorName ); - return; - } - + std::vector pWorldItem_Target;//dnl ch75 271013 // now loop over all sectors from which we take stuff, and move the equipment @@ -7333,14 +7326,22 @@ void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ ) // move if( ( gWorldSectorX == sMapX )&&( gWorldSectorY == sMapY ) && (gbWorldSectorZ == bZ ) ) { + UINT16 flags = (WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO | WORLD_ITEM_REACHABLE); + if ( TileIsOutOfBounds( sDropOffGridNo ) ) + flags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT; + for (UINT16 i = 0; i < moveobjectcounter; ++i ) { - AddItemToPool( sDropOffGridNo, &(pObjectToMove[i]), 1 , 0, (WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO|WORLD_ITEM_REACHABLE), -1 ); + AddItemToPool( sDropOffGridNo, &(pObjectToMove[i]), 1, 0, flags, -1 ); } } else { - AddItemsToUnLoadedSector( sMapX, sMapY, bZ, sDropOffGridNo, moveobjectcounter, pObjectToMove, 0, WORLD_ITEM_REACHABLE, 0, 1, FALSE ); + UINT16 flags = WORLD_ITEM_REACHABLE; + if ( TileIsOutOfBounds( sDropOffGridNo ) ) + flags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT; + + AddItemsToUnLoadedSector( sMapX, sMapY, bZ, sDropOffGridNo, moveobjectcounter, pObjectToMove, 0, flags, 0, 1, FALSE ); } if ( pObjectToMove ) diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index a75954bd..e0db1723 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -1599,6 +1599,12 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason ) if ( PlaceObjectInInventoryStash( &( pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].object ), gpItemPointer, ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter, iCurrentlyPickedUpItem ) ) { + INT8 bRenderZHeightAboveLevel = 0; + + //CHRISL: Make sure we put the item at the same level as the merc + if ( gpItemPointerSoldier->exists( ) ) + pInventoryPoolList[(iCurrentInventoryPoolPage*MAP_INVENTORY_POOL_SLOT_COUNT) + iCounter].ubLevel = gpItemPointerSoldier->pathing.bLevel; + // HEADROCK HAM 5: A LOT of functions rely on these flags being set. So set them!! pInventoryPoolList[(iCurrentInventoryPoolPage*MAP_INVENTORY_POOL_SLOT_COUNT)+iCounter].bVisible = TRUE; pInventoryPoolList[(iCurrentInventoryPoolPage*MAP_INVENTORY_POOL_SLOT_COUNT)+iCounter].fExists = TRUE; @@ -1612,47 +1618,48 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason ) // set a grid no for item from mercs with invalid grid no in sector inventory, e.g. merc arriving in sector with a different tactical map loaded if(!GridNoOnVisibleWorldTile(sObjectSourceGridNo)) { - // use the grid no of the first visible, reachable item - for(UINT32 i = 0; i < pInventoryPoolList.size(); i++ ) + pInventoryPoolList[(iCurrentInventoryPoolPage*MAP_INVENTORY_POOL_SLOT_COUNT) + iCounter].ubLevel = 0; + + // if this is the current sector, use the center gridno, otherwise look for other items to get a good position + if ( (sSelMapX == gWorldSectorX) && (gWorldSectorY == sSelMapY) && (gbWorldSectorZ == iCurrentMapSectorZ) ) + sObjectSourceGridNo = gMapInformation.sCenterGridNo; + + // Flugente 2016-04-09: (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE) does not guarantee that an item is reachable. + // For example, a previously reachable item might now be inside a locked house. This would result in all items to be dropped inside that house! + // It is better so simply leave sObjectSourceGridNo at NOWHERE. This will cause WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT to be set, which in turn causes + // a reassignment to the (by then correct) gMapInformation.sCenterGridNo in LoadAndAddWorldItemsFromTempFile(...) + /*if ( !GridNoOnVisibleWorldTile( sObjectSourceGridNo ) ) { - if( pInventoryPoolList[i].bVisible == 1 && pInventoryPoolList[i].fExists == TRUE && pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE ) + // use the grid no of the first visible, reachable item + for(UINT32 i = 0; i < pInventoryPoolList.size(); ++i ) { - sObjectSourceGridNo = pInventoryPoolList[i].sGridNo; - break; + if( pInventoryPoolList[i].bVisible == 1 && pInventoryPoolList[i].fExists == TRUE && pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE ) + { + sObjectSourceGridNo = pInventoryPoolList[i].sGridNo; + bRenderZHeightAboveLevel = pInventoryPoolList[i].bRenderZHeightAboveLevel; + break; + } } - - // empty sector to use the center grid no of the loaded tactical sector, hope that it's accessible - if(!GridNoOnVisibleWorldTile(sObjectSourceGridNo)) - sObjectSourceGridNo = gMapInformation.sCenterGridNo; - } - } - - //CHRISL: Make sure we put the item at the same level as the merc - if(gpItemPointerSoldier->exists() == true) - pInventoryPoolList[(iCurrentInventoryPoolPage*MAP_INVENTORY_POOL_SLOT_COUNT)+iCounter].ubLevel = gpItemPointerSoldier->pathing.bLevel; - + }*/ + } + // set as reachable and set gridno pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].usFlags |= WORLD_ITEM_REACHABLE; + + // nothing here before, then place here + if( iOldNumberOfObjects == 0 ) + { + pInventoryPoolList[(iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT) + iCounter].sGridNo = sObjectSourceGridNo; + pInventoryPoolList[(iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT) + iCounter].bRenderZHeightAboveLevel = bRenderZHeightAboveLevel; - // if loaded sector, grab grid no of dropping soldier - //if( ( sSelMapX == gWorldSectorX )&&( gWorldSectorY == sSelMapY ) &&(gbWorldSectorZ == iCurrentMapSectorZ ) ) - //{ - // nothing here before, then place here - if( iOldNumberOfObjects == 0 ) + if(TileIsOutOfBounds(sObjectSourceGridNo)) { - if(TileIsOutOfBounds(sObjectSourceGridNo)) - { - pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].usFlags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT; - pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].sGridNo = sObjectSourceGridNo; - } - else - { - pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].sGridNo = sObjectSourceGridNo; - } - //if( sObjectSourseSoldierID != -1 ) - // pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].soldierID = sObjectSourseSoldierID; + pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].usFlags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT; } - //} + + //if( sObjectSourseSoldierID != -1 ) + // pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].soldierID = sObjectSourseSoldierID; + } // Check if it's the same now! if ( gpItemPointer->exists() == false ) diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 845a4897..043f2560 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -3230,7 +3230,8 @@ BOOLEAN LookForHiddenItems( INT32 sGridNo, INT8 ubLevel, BOOLEAN fSetLocator, IN return( fFound ); } - +// Flugente 2016-04-09: this function seems dubious. The only difference from GetLargestZLevelOfItemPool is that this guarantees 0 if there is a structure. +// That doesn't make any sense, so I'm replacing all calls of this INT8 GetZLevelOfItemPoolGivenStructure( INT32 sGridNo, UINT8 ubLevel, STRUCTURE *pStructure ) { ITEM_POOL *pItemPool; diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp index 3d3bd9c6..4f2e8627 100644 --- a/Tactical/Interface Control.cpp +++ b/Tactical/Interface Control.cpp @@ -790,7 +790,7 @@ void RenderTopmostTacticalInterface( ) sActionGridNo = sIntTileGridNo; } - bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, pSoldier->pathing.bLevel, pStructure ); + bZLevel = GetLargestZLevelOfItemPool( pItemPool ); if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) ) { @@ -798,49 +798,47 @@ void RenderTopmostTacticalInterface( ) // ATE: If over items, remove locator.... RemoveFlashItemSlot( pItemPool ); - } } - else - { - INT8 bCheckLevel; - - // ATE: Allow to see list if a different level.... - if ( pSoldier->pathing.bLevel == 0 ) - { - bCheckLevel = 1; - } - else - { - bCheckLevel = 0; - } - - // Check if we are over an item pool - if ( GetItemPool( gfUIOverItemPoolGridNo, &pItemPool, bCheckLevel ) ) + else { - STRUCTURE *pStructure = NULL; - INT32 sIntTileGridNo; - INT8 bZLevel = 0; - INT32 sActionGridNo = usMapPos; + INT8 bCheckLevel; - // Get interactive tile... - if ( ConditionalGetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo , &pStructure, FALSE ) ) + // ATE: Allow to see list if a different level.... + if ( pSoldier->pathing.bLevel == 0 ) { - sActionGridNo = sIntTileGridNo; + bCheckLevel = 1; + } + else + { + bCheckLevel = 0; } - bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, bCheckLevel, pStructure ); - - if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) ) + // Check if we are over an item pool + if ( GetItemPool( gfUIOverItemPoolGridNo, &pItemPool, bCheckLevel ) ) { - DrawItemPoolList( pItemPool, gfUIOverItemPoolGridNo , ITEMLIST_DISPLAY, bZLevel, gusMouseXPos, gusMouseYPos ); + STRUCTURE *pStructure = NULL; + INT32 sIntTileGridNo; + INT8 bZLevel = 0; + INT32 sActionGridNo = usMapPos; - // ATE: If over items, remove locator.... - RemoveFlashItemSlot( pItemPool ); + // Get interactive tile... + if ( ConditionalGetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo , &pStructure, FALSE ) ) + { + sActionGridNo = sIntTileGridNo; + } + + bZLevel = GetLargestZLevelOfItemPool( pItemPool ); + if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) ) + { + DrawItemPoolList( pItemPool, gfUIOverItemPoolGridNo , ITEMLIST_DISPLAY, bZLevel, gusMouseXPos, gusMouseYPos ); + + // ATE: If over items, remove locator.... + RemoveFlashItemSlot( pItemPool ); + } } } - } } } } @@ -854,9 +852,9 @@ void RenderTopmostTacticalInterface( ) } // Check if we should render item selection window - if ( gCurrentUIMode == OPENDOOR_MENU_MODE ) + if ( gCurrentUIMode == OPENDOOR_MENU_MODE ) { - RenderOpenDoorMenu( ); + RenderOpenDoorMenu( ); } if ( gfInTalkPanel ) @@ -887,8 +885,7 @@ void RenderTopmostTacticalInterface( ) { RemoveMouseRegionForPauseOfClock( ); } - - + if ( !(guiTacticalInterfaceFlags & INTERFACE_NORENDERBUTTONS ) ) { // If we want to rederaw whole screen, dirty all buttons! @@ -896,13 +893,12 @@ void RenderTopmostTacticalInterface( ) { MarkButtonsDirty( ); } - - + RenderButtons( ); RenderPausedGameBox( ); } - // mark all pop ups as dirty + // mark all pop ups as dirty MarkAllBoxesAsAltered( ); HandleShowingOfTacticalInterfaceFastHelpText( ); diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index d2c18ebb..42637c0e 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -1563,6 +1563,9 @@ BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) if( pWorldItems[cnt].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT ) { pWorldItems[cnt].sGridNo = gMapInformation.sCenterGridNo; + + // if we move the item, recalculate the height + pWorldItems[cnt].bRenderZHeightAboveLevel = -1; } //add the item to the world diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 4af07d42..97f6d071 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -5549,9 +5549,7 @@ void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent ) } else if ( UIOkForItemPickup( pSoldier, sActionGridNo ) ) { - INT8 bZLevel; - - bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, pSoldier->pathing.bLevel, pStructure ); + INT8 bZLevel = GetLargestZLevelOfItemPool( pItemPool ); SoldierPickupItem( pSoldier, pItemPool->iItemIndex, sActionGridNo, bZLevel ); diff --git a/TileEngine/overhead map.cpp b/TileEngine/overhead map.cpp index 015669ab..c0162a23 100644 --- a/TileEngine/overhead map.cpp +++ b/TileEngine/overhead map.cpp @@ -528,8 +528,8 @@ void HandleOverheadMap( ) { sActionGridNo = sIntTileGridNo; } - - bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, 0, pStructure ); + + bZLevel = GetLargestZLevelOfItemPool( pItemPool ); if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) ) {