diff --git a/Editor/EditorItems.cpp b/Editor/EditorItems.cpp index a3d2d93d..775310ab 100644 --- a/Editor/EditorItems.cpp +++ b/Editor/EditorItems.cpp @@ -192,6 +192,7 @@ void EntryInitEditorItemsInfo() case IC_KIT: case IC_FACE: case IC_MONEY: + case IC_BELTCLIP: eInfo.sNumEquipment1++; break; case IC_MISC: @@ -452,6 +453,7 @@ void InitEditorItemsInfo(UINT32 uiItemType) case IC_KIT: case IC_FACE: case IC_MONEY: + case IC_BELTCLIP: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_EQUIPMENT1; break; case IC_MISC: @@ -1661,3 +1663,4 @@ void DisplayItemStatistics() + diff --git a/Editor/Item Statistics.cpp b/Editor/Item Statistics.cpp index 3643872c..a7d408f3 100644 --- a/Editor/Item Statistics.cpp +++ b/Editor/Item Statistics.cpp @@ -430,6 +430,7 @@ void SpecifyItemToEdit( OBJECTTYPE *pItem, INT32 iMapIndex ) case IC_LAUNCHER: case IC_THROWING_KNIFE: case IC_MONEY: + case IC_BELTCLIP: gbEditingMode = EDITING_EQUIPMENT; SetupEquipGUI(); break; diff --git a/GameInitOptionsScreen.cpp b/GameInitOptionsScreen.cpp index 55781d50..de53ff40 100644 --- a/GameInitOptionsScreen.cpp +++ b/GameInitOptionsScreen.cpp @@ -474,7 +474,7 @@ BOOLEAN EnterGIOScreen() } // CHRISL: New inventory options - if(iResolution != 0){ + if(iResolution != 0 && gCustomDataCat.GetRootDir() != ""){ usPosY = GIO_INV_SETTING_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y; for( cnt=0; cnt= iNumber && LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize] < capacity && pProfile->inv[uiPos] == 0) { - if((LBEPocketType[pIndex].pRestriction != 0 && LBEPocketType[pIndex].pRestriction == Item[usItem].usItemClass) || + if((LBEPocketType[pIndex].pRestriction != 0 && (LBEPocketType[pIndex].pRestriction & Item[usItem].usItemClass)) || LBEPocketType[pIndex].pRestriction == 0) { capacity = LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize]; pocket = uiPos; @@ -1479,3 +1479,4 @@ void GiveIMPItems( MERCPROFILESTRUCT *pProfile, INT8 abilityValue, UINT8 typeInd } + diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 4fed8271..9273a9ad 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -2886,7 +2886,7 @@ BOOLEAN LoadSavedGame( UINT8 ubSavedGameID ) gGameOptions.ubInventorySystem = SaveGameHeader.ubInventorySystem; if((UsingNewInventorySystem() == true)) { - if(iResolution == 0){ + if(iResolution == 0 || gCustomDataCat.GetRootDir() == ""){ // Only load NewInv in higher screen res FileClose( hFile ); return(FALSE); diff --git a/SaveLoadScreen.cpp b/SaveLoadScreen.cpp index da88c237..6298c195 100644 --- a/SaveLoadScreen.cpp +++ b/SaveLoadScreen.cpp @@ -2128,6 +2128,11 @@ void DoneFadeOutForSaveLoadScreen( void ) DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_INV_RES_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); NextLoopCheckForEnoughFreeHardDriveSpace(); } + else if(UsingNewInventorySystem() == true && gCustomDataCat.GetRootDir() == "") + { + DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_INV_CUSTUM_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); + NextLoopCheckForEnoughFreeHardDriveSpace(); + } else { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_LOAD_GAME_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index 78323832..9445d1d3 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -153,6 +153,8 @@ UINT32 guiMapInvenButton[ 3 ]; BOOLEAN gfCheckForCursorOverMapSectorInventoryItem = FALSE; +extern int PLAYER_INFO_Y; +extern int INV_REGION_Y; extern BOOLEAN fShowInventoryFlag; extern BOOLEAN fMapScreenBottomDirty; @@ -211,6 +213,7 @@ BOOLEAN CanPlayerUseSectorInventory( SOLDIERTYPE *pSelectedSoldier ); extern void MAPEndItemPointer( ); extern BOOLEAN GetCurrentBattleSectorXYZAndReturnTRUEIfThereIsABattle( INT16 *psSectorX, INT16 *psSectorY, INT16 *psSectorZ ); +extern BOOLEAN MAPInternalInitItemDescriptionBox( OBJECTTYPE *pObject, UINT8 ubStatusIndex, SOLDIERTYPE *pSoldier ); void DeleteAllItemsInInventoryPool(); void DeleteItemsOfType( UINT16 usItemType ); @@ -341,7 +344,7 @@ BOOLEAN RenderItemInPoolSlot( INT32 iCurrentSlot, INT32 iFirstSlotOnPage ) if( pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object.exists() == false ) { - return ( FALSE ); + //return ( FALSE ); } GetVideoObject( &hHandle, GetInterfaceGraphicForItem( &(Item[ pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object.usItem ] ) ) ); @@ -372,12 +375,23 @@ BOOLEAN RenderItemInPoolSlot( INT32 iCurrentSlot, INT32 iFirstSlotOnPage ) SetFontDestBuffer( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); - INVRenderItem( guiSAVEBUFFER, NULL, &(pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object), - (INT16)(sX + 7), sY, 60, 25, DIRTYLEVEL2, NULL, 0, fOutLine, sOutLine );//67 + if(UsingNewInventorySystem() == true && gpItemPointer != NULL) + { + int itemSlotLimit = ItemSlotLimit(gpItemPointer, STACK_SIZE_LIMIT); + RenderPocketItemCapacity( guiSAVEBUFFER, itemSlotLimit, STACK_SIZE_LIMIT, 0, &pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object, (sX + 7), sY ); + } + + INVRenderItem( guiSAVEBUFFER, NULL, &(pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object), + (INT16)(sX + 7), sY, 60, 25, DIRTYLEVEL2, NULL, 0, fOutLine, sOutLine );//67 SetFontDestBuffer( FRAME_BUFFER, 0,0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); + if( pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object.exists() == false ) + { + return ( FALSE ); + } + // now blit this object in the box //BltVideoObjectOutlineFromIndex( guiSAVEBUFFER, GetInterfaceGraphicForItem( &(Item[ pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object.usItem ]) ), // Item[ pInventoryPoolList[ iCurrentSlot + iFirstSlotOnPage ].object.usItem ].ubGraphicNum, @@ -810,9 +824,25 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason ) if( ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) ) { + //CHRISL: Make it possible to right click and pull up stack popup and/or item description boxes + WORLDITEM * twItem = &(pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ]); + if ( !InSectorStackPopup( ) && !InItemStackPopup( ) && !InItemDescriptionBox( ) && !InKeyRingPopup( ) && twItem->object.exists() == true) + { + if(ItemSlotLimit( &twItem->object, STACK_SIZE_LIMIT ) == 1) + { + fShowInventoryFlag = TRUE; + MAPInternalInitItemDescriptionBox( &twItem->object, 0, 0 ); + } + else if(gpItemPointer == NULL || gpItemPointer->usItem == twItem->object.usItem || ValidAttachment(gpItemPointer->usItem, twItem->object.usItem) == TRUE) + { + InitSectorStackPopup( twItem, iCounter, 0, INV_REGION_Y, 261, ( SCREEN_HEIGHT - PLAYER_INFO_Y ) ); + fTeamPanelDirty=TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; + } + } if ( gpItemPointer == NULL ) { - fShowMapInventoryPool = FALSE; + //fShowMapInventoryPool = FALSE; } // else do nothing } diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index d5ba1993..38793303 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -506,6 +506,8 @@ extern UINT16 usVehicleY; //void DeleteButtonsForScrolling(void); void BtnMessageUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason ); +void BeginSellAllCallBack( UINT8 bExitValue ); +void BeginDeleteAllCallBack( UINT8 bExitValue ); BOOLEAN fScrollButtonsInitialized = FALSE; BOOLEAN fFlashAssignDone = FALSE; @@ -1049,6 +1051,7 @@ void MapscreenMarkButtonsDirty(); extern BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSectorY, INT8 bClickedTownId ); extern INT32 GetNumberOfMercsInUpdateList( void ); +extern INT32 SellItem( OBJECTTYPE& object, BOOLEAN useModifier = TRUE ); void DeleteAllItemsInInventoryPool(); @@ -1058,6 +1061,70 @@ void DumpSectorDifficultyInfo( void ); void DumpItemsList( void ); #endif +void BeginSellAllCallBack( UINT8 bExitValue ) +{ + INT32 iPrice = 0; + bool anythingSold = false; + + if( bExitValue == MSG_BOX_RETURN_YES ) + { + fRestoreBackgroundForMessageBox = TRUE; + if ( gpItemPointer != NULL ) + { + return; + } + for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++) + { + if(0 == pInventoryPoolList[wItem].object.MoveThisObjectTo(gItemPointer,-1,0,NUM_INV_SLOTS,MAX_OBJECTS_PER_SLOT)) + { + if (pInventoryPoolList[wItem].object.exists() == false) { + pInventoryPoolList[wItem].object.initialize(); + } + // Dirty interface + fMapPanelDirty = TRUE; + gpItemPointer = &gItemPointer; + // Sell Item + iPrice += SellItem( gItemPointer ); + gpItemPointer = NULL; + fMapInventoryItem = FALSE; + if (iPrice == 0) { + iPrice = 1; + } + anythingSold = true; + HandleButtonStatesWhileMapInventoryActive(); + } + } + if(anythingSold == true) + AddTransactionToPlayersBook( SOLD_ITEMS, 0, GetWorldTotalMin(), iPrice ); + } +} + +void BeginDeleteAllCallBack( UINT8 bExitValue ) +{ + if( bExitValue == MSG_BOX_RETURN_YES ) + { + fRestoreBackgroundForMessageBox = TRUE; + if ( gpItemPointer != NULL ) + { + return; + } + for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++) + { + if(0 == pInventoryPoolList[wItem].object.MoveThisObjectTo(gItemPointer,-1,0,NUM_INV_SLOTS,MAX_OBJECTS_PER_SLOT)) + { + if (pInventoryPoolList[wItem].object.exists() == false) { + pInventoryPoolList[wItem].object.initialize(); + } + // Dirty interface + fMapPanelDirty = TRUE; + gpItemPointer = &gItemPointer; + // Delete Item + gpItemPointer = NULL; + fMapInventoryItem = FALSE; + } + } + } +} // CHRISL: New functions to handle initialization of inventory coordinates BOOLEAN InitializeInvPanelCoordsOld() @@ -4649,7 +4716,7 @@ UINT32 MapScreenHandle(void) // handle video overlays ExecuteVideoOverlays( ); - if ( InItemStackPopup( ) ) + if ( InItemStackPopup( ) || InSectorStackPopup( ) ) { RenderItemStackPopup( FALSE ); } @@ -6137,6 +6204,23 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent ) #endif break; + case 'D': + if( fCtrl ) + { + //CHRISL: Delete all items + if(!fShowMapInventoryPool) + { + fShowMapInventoryPool = TRUE; + CreateDestroyMapInventoryPoolButtons( TRUE ); + } + DoMessageBox( MSG_BOX_BASIC_STYLE, NewInvMessage[NIV_DELETE_ALL], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, BeginDeleteAllCallBack, NULL ); + if(fShowMapInventoryPool) + { + fShowMapInventoryPool = FALSE; + } + } + break; + case 'e': if( gfPreBattleInterfaceActive ) { //activate enter sector in prebattle interface. @@ -6462,6 +6546,25 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent ) RequestTriggerExitFromMapscreen( MAP_EXIT_TO_SAVE ); } break; + case 'S': + if( fCtrl ) + { + //CHRISL: Sell all items + if(gGameExternalOptions.fSellAll == TRUE) + { + if(!fShowMapInventoryPool) + { + fShowMapInventoryPool = TRUE; + CreateDestroyMapInventoryPoolButtons( TRUE ); + } + DoMessageBox( MSG_BOX_BASIC_STYLE, NewInvMessage[NIV_SELL_ALL], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, BeginSellAllCallBack, NULL ); + if(fShowMapInventoryPool) + { + fShowMapInventoryPool = FALSE; + } + } + } + break; case 't': // Teleport: CTRL-T if( ( fCtrl )&&( CHEATER_CHEAT_LEVEL( ) ) ) diff --git a/Tactical/Arms Dealer Init.cpp b/Tactical/Arms Dealer Init.cpp index dda7ebbb..0f533ca5 100644 --- a/Tactical/Arms Dealer Init.cpp +++ b/Tactical/Arms Dealer Init.cpp @@ -992,6 +992,7 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem ) // CHRISL: Itendify new class for inventory system case IC_LBEGEAR: + case IC_BELTCLIP: return( 0 ); break; default: diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 5df3e33d..5796c8f7 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -2116,7 +2116,7 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV { ITEM_POOL *pItemPool; ITEM_POOL *pItemPoolTemp; - INT32 iWorldItem; + INT32 iWorldItem = 0; STRUCTURE *pStructure, *pBase; INT16 sDesiredLevel; INT16 sNewGridNo = *psGridNo; diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp index db2d06b5..bb209182 100644 --- a/Tactical/Interface Control.cpp +++ b/Tactical/Interface Control.cpp @@ -601,7 +601,7 @@ void RenderTopmostTacticalInterface( ) return; } - if ( InItemStackPopup( ) ) + if ( InItemStackPopup( ) || InSectorStackPopup( ) ) { RenderItemStackPopup( ( BOOLEAN )( fInterfacePanelDirty == DIRTYLEVEL2 ) ); } @@ -1049,4 +1049,4 @@ BOOLEAN InterfaceOKForMeanwhilePopup() } return( TRUE ); -} \ No newline at end of file +} diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 0d3d4fbf..f260acd9 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -350,6 +350,7 @@ void DeletePool(ITEM_POOL *pItemPool); // ITEM STACK POPUP STUFF BOOLEAN gfInItemStackPopup = FALSE; +BOOLEAN gfInSectorStackPopup = FALSE; UINT32 guiItemPopupBoxes; OBJECTTYPE *gpItemPopupObject; INT16 gsItemPopupWidth; @@ -402,6 +403,7 @@ extern void StartSKIDescriptionBox( void ); void UpdateItemHatches(); +extern void BeginInventoryPoolPtr( OBJECTTYPE *pInventorySlot ); UINT8 ubRGBItemCyclePlacedItemColors[] = { @@ -607,7 +609,7 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi UINT32 uiStringLength = 0; STR16 zTemp; UINT16 usItem = pObject->usItem; - UINT8 ubWeight; + UINT16 ubWeight; zItemPros[0] = 0; @@ -733,7 +735,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi { UINT32 uiStringLength = 0; STR16 zTemp; - UINT8 ubWeight; + UINT16 ubWeight; UINT16 usItem = pObject->usItem; zItemCons[0] = 0; @@ -1527,7 +1529,7 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe if (!gfSMDisableForItems && (UsingNewInventorySystem() == true) && gpItemPointer != NULL) { int itemSlotLimit = ItemSlotLimit(gpItemPointer, sPocket, pSoldier); - RenderPocketItemCapacity( itemSlotLimit, sPocket, pSoldier); + RenderPocketItemCapacity( guiSAVEBUFFER, itemSlotLimit, sPocket, pSoldier, &pSoldier->inv[sPocket], sX, sY ); if(itemSlotLimit == 0 && !CanItemFitInPosition(pSoldier, gpItemPointer, (INT8)sPocket, FALSE)) { fHatchItOut = TRUE; } @@ -2353,15 +2355,14 @@ void InitItemInterface( ) } // CHRISL: Function to display pocket inventory quantity based on object in cursor -void RenderPocketItemCapacity( UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldier ) +void RenderPocketItemCapacity( UINT32 uiWhichBuffer, UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT16 sX, INT16 sY ) { - INT16 sX, sY; static CHAR16 pStr[ 100 ]; // Can pocket hold the item in the cursor? if(InItemDescriptionBox( )) return; - if(!CanItemFitInPosition( pSoldier, gpItemPointer, (INT8)bPos, FALSE )) + if(pSoldier != NULL && !CanItemFitInPosition( pSoldier, gpItemPointer, (INT8)bPos, FALSE )) { // Further check to see if the cursor item is valid ammo or a valid attachment if(!CompatibleAmmoForGun(gpItemPointer, &pSoldier->inv[bPos]) && !ValidAttachment(gpItemPointer->usItem, pSoldier->inv[bPos].usItem)) @@ -2374,18 +2375,13 @@ void RenderPocketItemCapacity( UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldie SetFont( ITEM_FONT ); SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( FONT_RED ); - if(CompatibleAmmoForGun(gpItemPointer, &pSoldier->inv[bPos]) || ValidLaunchable(gpItemPointer->usItem, pSoldier->inv[bPos].usItem)) - { - SetFontForeground( FONT_YELLOW ); - swprintf( pStr, L"L" ); - } - else if(pCapacity != 0 && CanItemFitInPosition(pSoldier, gpItemPointer, (INT8)bPos, FALSE)) + if(pSoldier == NULL || (pCapacity != 0 && CanItemFitInPosition(pSoldier, gpItemPointer, (INT8)bPos, FALSE))) { // Adjust capacity to account for current items - if(gpItemPointer->usItem == pSoldier->inv[bPos].usItem) + if(gpItemPointer->usItem == pObj->usItem) { SetFontForeground( FONT_GREEN ); - pCapacity = pCapacity - pSoldier->inv[bPos].ubNumberOfObjects; + pCapacity = pCapacity - pObj->ubNumberOfObjects; if(pCapacity > 0) swprintf( pStr, L"+%d", pCapacity ); else @@ -2394,14 +2390,17 @@ void RenderPocketItemCapacity( UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldie else swprintf( pStr, L"%d", pCapacity ); } + else if(CompatibleAmmoForGun(gpItemPointer, &pSoldier->inv[bPos]) || ValidLaunchable(gpItemPointer->usItem, pSoldier->inv[bPos].usItem)) + { + SetFontForeground( FONT_YELLOW ); + swprintf( pStr, L"L" ); + } else if(ValidAttachment(gpItemPointer->usItem, pSoldier->inv[bPos].usItem)) { SetFontForeground( FONT_YELLOW ); swprintf( pStr, L"A" ); } - sX = gSMInvData[ bPos ].sX + 1; - sY = gSMInvData[ bPos ].sY; - UINT32 uiWhichBuffer = ( guiCurrentItemDescriptionScreen == MAP_SCREEN ) ? guiSAVEBUFFER : guiRENDERBUFFER; + sX = sX + 1; // Display pocket capacity if ( uiWhichBuffer == guiSAVEBUFFER ) @@ -3370,6 +3369,7 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason) { static BOOLEAN fRightDown = FALSE; CHAR16 pStr[10]; + CHAR8 ubString[48]; UINT32 ubStatusIndex = MSYS_GetBtnUserData( btn, 1 ); /* region gets disabled in SKI for shopkeeper boxes. It now works normally for merc's inventory boxes! @@ -3394,23 +3394,77 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason) if( guiCurrentItemDescriptionScreen == MAP_SCREEN ) { - if ( gpItemPointer == NULL && EmptyWeaponMagazine( gpItemDescObject, &gItemPointer, ubStatusIndex ) ) + //if ( gpItemPointer == NULL && EmptyWeaponMagazine( gpItemDescObject, &gItemPointer, ubStatusIndex ) ) + EmptyWeaponMagazine( gpItemDescObject, &gTempObject, ubStatusIndex ); + if(gpItemPointer == NULL) { - // OK, END the description box - //fItemDescDelete = TRUE; - fInterfacePanelDirty = DIRTYLEVEL2; + //not holding anything + gTempObject.MoveThisObjectTo(gItemPointer); gpItemPointer = &gItemPointer; - gpItemPointerSoldier = gpItemDescSoldier; + } + else + { + //holding an item + if(Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubCalibre == Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubCalibre) + { + ReloadGun(gpItemDescSoldier, gpItemDescObject, gpItemPointer); + } + if(gpItemPointer->ubNumberOfObjects == 0) + { + // nothing left in cursor + gTempObject.MoveThisObjectTo(gItemPointer); + gpItemPointer = &gItemPointer; + if(gpItemPointer->ubNumberOfObjects == 0) + { + // delete object if nothing left + MAPEndItemPointer( ); + } + } + else + { + // still holding someting so drop the clip we just pulled from the weapon + // start by searching merc for a place to put the clip + if(AutoPlaceObject(gpItemDescSoldier, &gTempObject, TRUE) == FALSE) + { + // couldn't find a place on the merc, so drop into the sector + if(fShowMapInventoryPool) //sector inventory panel is open + { + AutoPlaceObjectInInventoryStash(&gTempObject, gpItemDescSoldier->sGridNo); + fMapPanelDirty = TRUE; + } + else //sector inventory panel is closed + { + AddItemToPool(gpItemDescSoldier->sGridNo, &gTempObject, 1, gpItemDescSoldier->pathing.bLevel, WORLD_ITEM_REACHABLE, 0); + } + } + } + } + // OK, END the description box + //fItemDescDelete = TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; + gpItemPointerSoldier = gpItemDescSoldier; - swprintf( pStr, L"0" ); - SpecifyButtonText( giItemDescAmmoButton, pStr ); + if ( GetMagSize(gpItemDescObject) <= 99 ) + swprintf( pStr, L"%d/%d", (*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunShotsLeft, GetMagSize(gpItemDescObject)); + else + swprintf( pStr, L"%d", (*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunShotsLeft ); - // Set mouse + FilenameForBPP("INTERFACE\\infobox.sti", ubString); + + UnloadButtonImage(giItemDescAmmoButtonImages); + giItemDescAmmoButtonImages = LoadButtonImage(ubString,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].grayed,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].offNormal,-1,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].onNormal,-1 ); + //swprintf( pStr, L"0" ); + SpecifyButtonText( giItemDescAmmoButton, pStr ); + + // Set mouse + if(gpItemPointer->exists() == true) + { guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) ); gusExternVoSubIndex = Item[ gpItemPointer->usItem ].ubGraphicNum; MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR ); MSYS_SetCurrentCursor( EXTERN_CURSOR ); + fMapInventoryItem=TRUE; fTeamPanelDirty=TRUE; } @@ -3418,27 +3472,67 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason) else { // Set pointer to item - if ( gpItemPointer == NULL && EmptyWeaponMagazine( gpItemDescObject, &gItemPointer, ubStatusIndex ) ) + EmptyWeaponMagazine( gpItemDescObject, &gTempObject, ubStatusIndex ); + if(gpItemPointer == NULL) { + //not holding anything + gTempObject.MoveThisObjectTo(gItemPointer); gpItemPointer = &gItemPointer; - gpItemPointerSoldier = gpItemDescSoldier; - - // if in SKI, load item into SKI's item pointer - if( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) - { - // pick up bullets from weapon into cursor (don't try to sell) - BeginSkiItemPointer( PLAYERS_INVENTORY, -1, FALSE ); - } - - // OK, END the description box - //fItemDescDelete = TRUE; - fInterfacePanelDirty = DIRTYLEVEL2; - - swprintf( pStr, L"0" ); - SpecifyButtonText( giItemDescAmmoButton, pStr ); - - fItemDescDelete = TRUE; } + else + { + //holding an item + if(Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubCalibre == Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubCalibre) + { + ReloadGun(gpItemDescSoldier, gpItemDescObject, gpItemPointer); + } + if(gpItemPointer->ubNumberOfObjects == 0) + { + // nothing left in cursor + gTempObject.MoveThisObjectTo(gItemPointer); + gpItemPointer = &gItemPointer; + if(gpItemPointer->ubNumberOfObjects == 0) + { + // delete object if nothing left + EndItemPointer( ); + } + } + else + { + // still holding someting so drop the clip we just pulled from the weapon + // start by searching merc for a place to put the clip + if(AutoPlaceObject(gpItemDescSoldier, &gTempObject, TRUE) == FALSE) + { + AddItemToPool(gpItemDescSoldier->sGridNo, &gTempObject, 1, gpItemDescSoldier->pathing.bLevel, WORLD_ITEM_REACHABLE, 0); + } + } + } + gpItemPointerSoldier = gpItemDescSoldier; + + // if in SKI, load item into SKI's item pointer + if( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) + { + // pick up bullets from weapon into cursor (don't try to sell) + BeginSkiItemPointer( PLAYERS_INVENTORY, -1, FALSE ); + } + + // OK, END the description box + //fItemDescDelete = TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; + + if ( GetMagSize(gpItemDescObject) <= 99 ) + swprintf( pStr, L"%d/%d", (*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunShotsLeft, GetMagSize(gpItemDescObject)); + else + swprintf( pStr, L"%d", (*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunShotsLeft ); + + FilenameForBPP("INTERFACE\\infobox.sti", ubString); + + UnloadButtonImage(giItemDescAmmoButtonImages); + giItemDescAmmoButtonImages = LoadButtonImage(ubString,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].grayed,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].offNormal,-1,AmmoTypes[(*gpItemDescObject)[ubStatusIndex]->data.gun.ubGunAmmoType].onNormal,-1 ); + //swprintf( pStr, L"0" ); + SpecifyButtonText( giItemDescAmmoButton, pStr ); + + fItemDescDelete = TRUE; } btn->uiFlags &= (~BUTTON_CLICKED_ON ); @@ -6040,18 +6134,127 @@ BOOLEAN ItemCursorInLobRange( INT16 sMapPos ) +BOOLEAN InSectorStackPopup( ) +{ + return( gfInSectorStackPopup ); +} BOOLEAN InItemStackPopup( ) { return( gfInItemStackPopup ); } - BOOLEAN InKeyRingPopup( ) { return( gfInKeyRingPopup ); } +BOOLEAN InitSectorStackPopup( WORLDITEM *pInventoryPoolList, INT32 ubPosition, INT16 sInvX, INT16 sInvY, INT16 sInvWidth, INT16 sInvHeight ) +{ + VOBJECT_DESC VObjectDesc; + SGPRect aRect; + ETRLEObject *pTrav; + HVOBJECT hVObject; + INT32 cnt; + UINT16 usPopupWidth, usPopupHeight; + INT16 sOffSetY = 0, sOffSetX = 0; + INT16 sItemWidth = 0; + static CHAR16 pStr[ 512 ]; + + sItemWidth = MAP_INV_ITEM_ROW_WIDTH - 1; + sOffSetY = 120; + + // Set some globals + guiCurrentItemDescriptionScreen = guiCurrentScreen; + gsItemPopupInvX = sInvX; + gsItemPopupInvY = sInvY; + gsItemPopupInvWidth = sInvWidth; + gsItemPopupInvHeight = sInvHeight; + // Determine # of items + gpItemPopupObject = &(pInventoryPoolList->object ); + gubNumItemPopups = ItemSlotLimit( gpItemPopupObject, STACK_SIZE_LIMIT ); + + // Return false if #objects not >1 + if ( gubNumItemPopups <1 ) + return( FALSE ); + + // Load graphics + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + strcpy( VObjectDesc.ImageFile, "INTERFACE\\extra_inventory.STI" ); + CHECKF( AddVideoObject( &VObjectDesc, &guiItemPopupBoxes) ); + + // Get size + GetVideoObject( &hVObject, guiItemPopupBoxes ); + pTrav = &(hVObject->pETRLEObject[ 0 ] ); + usPopupWidth = 75; + //usPopupWidth = pTrav->usWidth; + usPopupHeight = pTrav->usHeight; + + // Get Width, Height + gsItemPopupWidth = gubNumItemPopups * usPopupWidth; + gsItemPopupHeight = pTrav->usHeight; + gsItemPopupX = gsItemPopupInvX; + gsItemPopupY = gsItemPopupInvY; + + for ( cnt = 0; cnt < gubNumItemPopups; cnt++ ) + { + // Build a mouse region here that is over any others..... + MSYS_DefineRegion( &gItemPopupRegions[cnt], + (INT16)( gsItemPopupInvX + ( cnt % sItemWidth * usPopupWidth ) + sOffSetX ), // top left + (INT16)( sInvY + sOffSetY +( cnt / sItemWidth * usPopupHeight ) ), // top right + (INT16)( gsItemPopupInvX + ( ( cnt % sItemWidth ) + 1 ) * usPopupWidth + sOffSetX ), // bottom left + (INT16)( sInvY + ( (cnt / sItemWidth + 1) * usPopupHeight ) + sOffSetY ), // bottom right + MSYS_PRIORITY_HIGHEST, + MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemPopupRegionCallback ); + // Add region + MSYS_AddRegion( &gItemPopupRegions[cnt]); + MSYS_SetRegionUserData( &gItemPopupRegions[cnt], 0, cnt ); + //CHRISL: Include the pockets capacity as UserData 1 + MSYS_SetRegionUserData( &gItemPopupRegions[cnt], 1, gubNumItemPopups ); + // Flag this as a sectory item + MSYS_SetRegionUserData( &gItemPopupRegions[cnt], 2, -1); + //CHRISL: Include the pocket we're looking at so we can display the right graphic + MSYS_SetRegionUserData( &gItemPopupRegions[cnt], 3, ubPosition); + + //OK, for each item, set dirty text if applicable! + //CHRISL: + if(cnt < gpItemPopupObject->ubNumberOfObjects && gpItemPopupObject->exists() == true){ + GetHelpTextForItem( pStr, gpItemPopupObject, 0, cnt ); + SetRegionFastHelpText( &(gItemPopupRegions[ cnt ]), pStr ); + } + else{ + SetRegionFastHelpText( &(gItemPopupRegions[ cnt ]), ItemNames[ gpItemPopupObject->usItem ] ); + } + SetRegionHelpEndCallback( &(gItemPopupRegions[ cnt ]), HelpTextDoneCallback ); + gfItemPopupRegionCallbackEndFix = FALSE; + } + + + // Build a mouse region here that is over any others..... + MSYS_DefineRegion( &gItemPopupRegion, sInvX, sInvY ,(INT16)(sInvX + sInvWidth), (INT16)(sInvY + sInvHeight), MSYS_PRIORITY_HIGH, + MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemPopupFullRegionCallback ); + // Add region + MSYS_AddRegion( &gItemPopupRegion); + + //Disable all faces + SetAllAutoFacesInactive( ); + + fInterfacePanelDirty = DIRTYLEVEL2; + + gfInSectorStackPopup = TRUE; + fShowInventoryFlag = TRUE; + + //Reserict mouse cursor to panel + aRect.iLeft = sInvX + sOffSetX; + aRect.iTop = sInvY + sOffSetY; + aRect.iRight = aRect.iLeft + sItemWidth * usPopupWidth; + aRect.iBottom = aRect.iTop + (INT32)(ceil((float)cnt/(float)sItemWidth)+1) * usPopupHeight; + + RestrictMouseCursor( &aRect ); + + return( TRUE ); +} + BOOLEAN InitItemStackPopup( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT16 sInvX, INT16 sInvY, INT16 sInvWidth, INT16 sInvHeight ) { VOBJECT_DESC VObjectDesc; @@ -6211,10 +6414,14 @@ BOOLEAN InitItemStackPopup( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT16 sInvX gfInItemStackPopup = TRUE; //Reserict mouse cursor to panel - aRect.iTop = sInvY; - aRect.iLeft = sInvX; - aRect.iBottom = sInvY + sInvHeight; - aRect.iRight = sInvX + sInvWidth; + aRect.iLeft = sInvX + sOffSetX; + aRect.iTop = sInvY + sOffSetY; + aRect.iRight = aRect.iLeft + sItemWidth * usPopupWidth; + aRect.iBottom = aRect.iTop + (INT32)(ceil((float)cnt/(float)sItemWidth)+1) * usPopupHeight; + //aRect.iTop = sInvY; + //aRect.iLeft = sInvX; + //aRect.iBottom = sInvY + sInvHeight; + //aRect.iRight = sInvX + sInvWidth; RestrictMouseCursor( &aRect ); @@ -6237,7 +6444,8 @@ void RenderItemStackPopup( BOOLEAN fFullRender ) UINT32 cnt; INT16 sX, sY, sNewX, sNewY; INT16 sItemWidth = 0, sOffSetY = 0, sWidth = 29; - UINT8 ubPosition, image = 0, sID; + UINT8 ubPosition, image = 0; + int sID; // CHRISL: Setup witdh and offset to layer inventory boxes if necessary if( guiCurrentScreen == MAP_SCREEN ) @@ -6276,9 +6484,9 @@ void RenderItemStackPopup( BOOLEAN fFullRender ) usWidth = (UINT32)pTrav->usWidth; //CHRISL: resize usPopupWidth based on popup stack location - if(UsingNewInventorySystem() == true) + if(UsingNewInventorySystem() == true || sID == -1) { - if((ubPosition >=BIGPOCKSTART && ubPosition < BIGPOCKFINAL) || (gGameExternalOptions.fVehicleInventory && (MercPtrs[sID]->flags.uiStatusFlags & SOLDIER_VEHICLE))) + if(sID == -1 || (ubPosition >=BIGPOCKSTART && ubPosition < BIGPOCKFINAL) || (gGameExternalOptions.fVehicleInventory && (MercPtrs[sID]->flags.uiStatusFlags & SOLDIER_VEHICLE))) { if(guiCurrentScreen != MAP_SCREEN) sItemWidth -= 2; @@ -6345,6 +6553,7 @@ void DeleteItemStackPopup( ) gfInItemStackPopup = FALSE; + gfInSectorStackPopup = FALSE; for ( cnt = 0; cnt < gubNumItemPopups; cnt++ ) { @@ -6466,10 +6675,10 @@ BOOLEAN InitKeyRingPopup( SOLDIERTYPE *pSoldier, INT16 sInvX, INT16 sInvY, INT16 gfInKeyRingPopup = TRUE; //Reserict mouse cursor to panel - aRect.iTop = sInvY; - aRect.iLeft = sInvX; - aRect.iBottom = sInvY + sInvHeight; - aRect.iRight = sInvX + sInvWidth; + aRect.iLeft = gsKeyRingPopupInvX + sOffSetX; + aRect.iTop = sInvY + sOffSetY; + aRect.iRight = aRect.iLeft + sKeyRingItemWidth * usPopupWidth; + aRect.iBottom = aRect.iTop + (INT32)(ceil((float)cnt/(float)sKeyRingItemWidth)+1) * usPopupHeight; RestrictMouseCursor( &aRect ); @@ -6811,7 +7020,7 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) { UINT32 uiItemPos; UINT32 iItemCap; - UINT32 ubID; + INT32 ubID; uiItemPos = MSYS_GetRegionUserData( pRegion, 0 ); iItemCap = MSYS_GetRegionUserData( pRegion, 1 ); @@ -6884,15 +7093,26 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) { // Here, grab an item and put in cursor to swap //RemoveObjFrom( OBJECTTYPE * pObj, UINT8 ubRemoveIndex ) - gpItemPopupObject->RemoveObjectAtIndex( uiItemPos, &gItemPointer ); if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) { // pick it up - InternalMAPBeginItemPointer( gpItemPopupSoldier ); + if(ubID != -1) + { + gpItemPopupObject->RemoveObjectAtIndex( uiItemPos, &gItemPointer ); + InternalMAPBeginItemPointer( gpItemPopupSoldier ); + } + else + { + OBJECTTYPE tSectorItem; + gpItemPopupObject->RemoveObjectAtIndex( uiItemPos, &tSectorItem ); + BeginInventoryPoolPtr(&tSectorItem); + guiCurrentItemDescriptionScreen = MAP_SCREEN; + } } else { + gpItemPopupObject->RemoveObjectAtIndex( uiItemPos, &gItemPointer ); gpItemPointer = &gItemPointer; gpItemPointerSoldier = gpItemPopupSoldier; } @@ -6903,13 +7123,13 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) // pick up stacked item into cursor and try to sell it ( unless CTRL is held down ) BeginSkiItemPointer( PLAYERS_INVENTORY, -1, ( BOOLEAN )!gfKeyState[ CTRL ] ); - // if we've just removed the last one there - if ( gpItemPopupObject->exists() == false ) - { - // we must immediately get out of item stack popup, because the item has been deleted (memset to 0), and - // errors like a right bringing up an item description for item 0 could happen then. ARM. - DeleteItemStackPopup( ); - } + } + // if we've just removed the last one there + if ( gpItemPopupObject->exists() == false ) + { + // we must immediately get out of item stack popup, because the item has been deleted (memset to 0), and + // errors like a right bringing up an item description for item 0 could happen then. ARM. + DeleteItemStackPopup( ); } // re-evaluate repairs @@ -6933,7 +7153,9 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) DeleteItemStackPopup( ); - if ( !InItemDescriptionBox( ) ) + if ( gpItemPopupObject->ubNumberOfObjects <= uiItemPos ) + fTeamPanelDirty = TRUE; + else if ( !InItemDescriptionBox( ) ) { // RESTORE BACKGROUND RestoreExternBackgroundRect( gsItemPopupInvX, gsItemPopupInvY, gsItemPopupInvWidth, gsItemPopupInvHeight ); @@ -6972,7 +7194,7 @@ void ItemPopupFullRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) } else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { - if ( InItemStackPopup( ) ) + if ( InItemStackPopup( ) || InSectorStackPopup( ) ) { DeleteItemStackPopup( ); fTeamPanelDirty = TRUE; diff --git a/Tactical/Interface Items.h b/Tactical/Interface Items.h index 5fbab870..32e91759 100644 --- a/Tactical/Interface Items.h +++ b/Tactical/Interface Items.h @@ -115,7 +115,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObject // CHRISL: Add a new function that will be used to render a pocket silhouette void INVRenderSilhouette( UINT32 uiBugger, INT16 PocketIndex, INT16 SilIndex, INT16 sX, INT16 sY, INT16 sWideth, INT16 sHeight); // CHRISL: New function to handle display of inventory quantities based on item current in cursor -void RenderPocketItemCapacity( UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldier ); +void RenderPocketItemCapacity( UINT32 uiWhichBuffer, UINT8 pCapacity, INT16 bPos, SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT16 sX, INT16 sY ); // CHRISL: New function to display items stored in an LBENODE void RenderLBENODEItems( OBJECTTYPE *pObj, int subObject ); // CHRISL: New function to setup GSMInvData based on game options @@ -140,6 +140,8 @@ void DeleteItemDescriptionBox( ); BOOLEAN InItemStackPopup( ); BOOLEAN InitItemStackPopup( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT16 sInvX, INT16 sInvY, INT16 sInvWidth, INT16 sInvHeight ); +BOOLEAN InSectorStackPopup( ); +BOOLEAN InitSectorStackPopup( WORLDITEM *pInventoryPoolList, INT32 ubPosition, INT16 sInvX, INT16 sInvY, INT16 sInvWidth, INT16 sInvHeight ); void RenderItemStackPopup( BOOLEAN fFullRender ); void HandleItemStackPopup( ); void DeleteItemStackPopup( ); diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index 017c1089..fd885fc8 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -3476,7 +3476,7 @@ void SMInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason ) invWidth = 314; //InitItemStackPopup( gpSMCurrentMerc, (UINT8)uiHandPos, SM_ITEMDESC_START_X, SM_ITEMDESC_START_Y, SM_ITEMDESC_WIDTH, SM_ITEMDESC_HEIGHT ); - InitItemStackPopup( gpSMCurrentMerc, (UINT8)uiHandPos, 216, INV_INTERFACE_START_Y, invWidth, ( SCREEN_HEIGHT - INV_INTERFACE_START_Y ) ); + InitItemStackPopup( gpSMCurrentMerc, (UINT8)uiHandPos, 248, INV_INTERFACE_START_Y, invWidth, ( SCREEN_HEIGHT - INV_INTERFACE_START_Y ) ); } } @@ -6277,7 +6277,8 @@ UINT8 FindNextMercInTeamPanel( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKLife if ( pNewSoldier->bAssignment != iCurrentSquad ) { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( CurrentSquad( ) + 1 ) ); + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( CurrentSquad( ) + 1 ) ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( pNewSoldier->bAssignment + 1 ) ); return( pNewSoldier->ubID ); } @@ -6368,7 +6369,7 @@ void BeginKeyPanelFromKeyShortcut( ) if( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) return; - InitKeyRingPopup( pSoldier, 0, sStartYPosition, sWidth, sHeight ); + InitKeyRingPopup( pSoldier, 35, sStartYPosition, sWidth, sHeight ); } @@ -6431,7 +6432,7 @@ void KeyRingItemPanelButtonCallback( MOUSE_REGION * pRegion, INT32 iReason ) InvalidateRegion( 0, 107, 261, 359 ); } - InitKeyRingPopup( pSoldier, 0, sStartYPosition, sWidth, sHeight ); + InitKeyRingPopup( pSoldier, 35, sStartYPosition, sWidth, sHeight ); } } @@ -7013,3 +7014,4 @@ void GoToMapScreenFromTactical( void ) + diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 5c78f06f..768261b5 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -526,6 +526,7 @@ extern OBJECTTYPE gTempObject; #define IC_KEY 0x00010000 #define IC_LBEGEAR 0x00020000 // Added for LBE items as part of the new inventory system +#define IC_BELTCLIP 0x00040000 // Added for Belt Clip items #define IC_MISC 0x10000000 #define IC_MONEY 0x20000000 @@ -590,7 +591,7 @@ typedef struct INT8 bSoundType; UINT8 ubGraphicType; UINT16 ubGraphicNum; - UINT8 ubWeight; //2 units per kilogram; roughly 1 unit per pound + UINT16 ubWeight; //2 units per kilogram; roughly 1 unit per pound UINT8 ubPerPocket; UINT8 ItemSize; UINT16 usPrice; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 8a8e5db9..b9cddf27 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -1439,7 +1439,7 @@ UINT8 ItemSlotLimit( OBJECTTYPE * pObject, INT16 bSlot, SOLDIERTYPE *pSoldier, B //if ( iSize < 10 && ubSlotLimit > 1) // ubSlotLimit = 1; - if(LBEPocketType[pIndex].pRestriction != 0 && LBEPocketType[pIndex].pRestriction != Item[usItem].usItemClass) { + if(LBEPocketType[pIndex].pRestriction != 0 && !(LBEPocketType[pIndex].pRestriction & Item[usItem].usItemClass)) { return 0; } @@ -3678,6 +3678,12 @@ BOOLEAN OBJECTTYPE::AttachObject( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttachme // check for merges else if (EvaluateValidMerge( pAttachment->usItem, this->usItem, &usResult, &usResult2, &ubType, &ubAPCost )) { + //CHRISL: we don't want to try to merge IC_LBEGEAR items that are currently storing items. + if(Item[this->usItem].usItemClass == IC_LBEGEAR) + { + if(this->IsActiveLBE(subObject) == true) + return( FALSE ); + } //CHRISL: We don't want to do any merges if we're looking at a stack of items, with the exception of combines. if ( this->ubNumberOfObjects > 1 && ubType != COMBINE_POINTS ) { @@ -4180,7 +4186,7 @@ BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos lbePocket = (pSoldier->inv[icLBE[bPos]].exists() == false) ? LoadBearingEquipment[Item[icDefault[bPos]].ubClassIndex].lbePocketIndex[icPocket[bPos]] : LoadBearingEquipment[Item[pSoldier->inv[icLBE[bPos]].usItem].ubClassIndex].lbePocketIndex[icPocket[bPos]]; pRestrict = LBEPocketType[lbePocket].pRestriction; if(pRestrict != 0) - if(pRestrict != Item[pObj->usItem].usItemClass) + if(!(pRestrict & Item[pObj->usItem].usItemClass)) lbePocket = 0; } break; @@ -4267,7 +4273,7 @@ INT32 PickPocket(SOLDIERTYPE *pSoldier, UINT8 ppStart, UINT8 ppStop, UINT16 usIt if(LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize] >= iNumber && LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize] < capacity && pSoldier->inv[uiPos].exists() == false && uiPos != bExcludeSlot) { - if((LBEPocketType[pIndex].pRestriction != 0 && LBEPocketType[pIndex].pRestriction == Item[usItem].usItemClass) || + if((LBEPocketType[pIndex].pRestriction != 0 && (LBEPocketType[pIndex].pRestriction & Item[usItem].usItemClass)) || LBEPocketType[pIndex].pRestriction == 0) { capacity = LBEPocketType[pIndex].ItemCapacityPerSize[Item[usItem].ItemSize]; pocket = uiPos; diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 5f273d8c..231a6cc9 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -534,6 +534,10 @@ BOOLEAN EnoughPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, BOOLE { INT16 sNewAP = 0; + //CHRISL: if we don't have soldier information, assume we have enough points. + if(pSoldier == NULL) + return( TRUE ); + // If this guy is on a special move... don't care about APS, OR BPSs! if ( pSoldier->ubWaitActionToDo ) { diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 300b5d39..3ae8cef4 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -544,7 +544,14 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * // Copy the items over for the soldier, only if we have a valid profile id! if ( pCreateStruct->ubProfile != NO_PROFILE ) + { CopyProfileItems( &Soldier, pCreateStruct ); + //CHRISL: make sure nails gets his jacket no matter what + if(pCreateStruct->ubProfile == 34 && pCreateStruct->fCopyProfileItemsOver == FALSE) + { + CreateItem(188, 100, &Soldier.inv[VESTPOS]); + } + } // Given team, get an ID for this guy! diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 435f44f2..42db93dc 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -1866,7 +1866,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) { HandleLocateSelectMerc( pNewSoldier->ubID, LOCATEANDSELECT_MERC ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( CurrentSquad( ) + 1 ) ); + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( CurrentSquad( ) + 1 ) ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( pNewSoldier->bAssignment + 1 ) ); // Center to guy.... LocateSoldier( gusSelectedSoldier, SETLOCATOR ); @@ -2327,93 +2328,96 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) //CHRISL: Ammo Crate if ( fCtrl ) { - INT32 crateItem; - INT32 worldItem; - bool mergeSuccessful; - OBJECTTYPE newCrate; - //look through all sector items for ammo. - for(unsigned int wItem = 0; wItem < guiNumWorldItems; wItem++) + if(!(gTacticalStatus.fEnemyInSector)) { - crateItem = 0; - mergeSuccessful = false; - if(Item[gWorldItems[wItem].object.usItem].usItemClass == IC_AMMO && gWorldItems[wItem].bVisible == TRUE && gWorldItems[wItem].fExists && (gWorldItems[wItem].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[wItem].usFlags & WORLD_ITEM_ARMED_BOMB)) + INT32 crateItem; + INT32 worldItem; + bool mergeSuccessful; + OBJECTTYPE newCrate; + //look through all sector items for ammo. + for(unsigned int wItem = 0; wItem < guiNumWorldItems; wItem++) { - worldItem = gWorldItems[wItem].object.usItem; - //we don't want to do anything if the world item is already an ammo crate - if(Item[worldItem].ammocrate == TRUE) - continue; - //we have a valid, ammo item. Look through Items.xml and see if we have an ammo crate for - // this ammo type - for(int iLoop = 0; iLoop < MAXITEMS; iLoop++) + crateItem = 0; + mergeSuccessful = false; + if(Item[gWorldItems[wItem].object.usItem].usItemClass == IC_AMMO && gWorldItems[wItem].bVisible == TRUE && gWorldItems[wItem].fExists && (gWorldItems[wItem].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[wItem].usFlags & WORLD_ITEM_ARMED_BOMB)) { - //if ammocrate && calibers match && Ammo Types match - if(Item[iLoop].ammocrate == TRUE && Magazine[Item[iLoop].ubClassIndex].ubCalibre == Magazine[Item[worldItem].ubClassIndex].ubCalibre && Magazine[Item[iLoop].ubClassIndex].ubAmmoType == Magazine[Item[worldItem].ubClassIndex].ubAmmoType) + worldItem = gWorldItems[wItem].object.usItem; + //we don't want to do anything if the world item is already an ammo crate + if(Item[worldItem].ammocrate == TRUE) + continue; + //we have a valid, ammo item. Look through Items.xml and see if we have an ammo crate for + // this ammo type + for(int iLoop = 0; iLoop < MAXITEMS; iLoop++) { - crateItem = iLoop; - break; - } - } - //if we found a crateItem in the list, we first want to see if we already have an item created - if(crateItem != 0) - { - //look through world items first - for(unsigned int loop=0; loop < guiNumWorldItems; loop++) - { - if(gWorldItems[loop].object.usItem == crateItem) + //if ammocrate && calibers match && Ammo Types match + if(Item[iLoop].ammocrate == TRUE && Magazine[Item[iLoop].ubClassIndex].ubCalibre == Magazine[Item[worldItem].ubClassIndex].ubCalibre && Magazine[Item[iLoop].ubClassIndex].ubAmmoType == Magazine[Item[worldItem].ubClassIndex].ubAmmoType) { - DistributeStatus(&gWorldItems[wItem].object, &gWorldItems[loop].object, Magazine[Item[crateItem].ubClassIndex].ubMagSize); + crateItem = iLoop; + break; + } + } + //if we found a crateItem in the list, we first want to see if we already have an item created + if(crateItem != 0) + { + //look through world items first + for(unsigned int loop=0; loop < guiNumWorldItems; loop++) + { + if(gWorldItems[loop].object.usItem == crateItem) + { + DistributeStatus(&gWorldItems[wItem].object, &gWorldItems[loop].object, Magazine[Item[crateItem].ubClassIndex].ubMagSize); + if(gWorldItems[wItem].object.ubNumberOfObjects < 1) + { + mergeSuccessful = true; + RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel); + RemoveItemFromWorld(wItem); + break; + } + } + } + //no crates in sector inventory. search merc inventories + if(mergeSuccessful == false) + { + for(int loop=0; loop<18; loop++) + { + if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector) + { + for(unsigned int pocket=0; pocket < MercPtrs[loop]->inv.size(); pocket++) + { + if(MercPtrs[loop]->inv[pocket].usItem == crateItem) + { + DistributeStatus(&gWorldItems[wItem].object, &MercPtrs[loop]->inv[pocket], Magazine[Item[crateItem].ubClassIndex].ubMagSize); + if(gWorldItems[wItem].object.ubNumberOfObjects < 1) + { + mergeSuccessful = true; + RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel); + RemoveItemFromWorld(wItem); + break; + } + } + } + if(mergeSuccessful == true) + break; + } + } + } + //no crates in merc inventory. create a new sector item + if(mergeSuccessful == false) + { + CreateAmmo(crateItem, &newCrate, 0); + DistributeStatus(&gWorldItems[wItem].object, &newCrate, Magazine[Item[crateItem].ubClassIndex].ubMagSize); + AddItemToPool(gWorldItems[wItem].sGridNo, &newCrate, 1, gWorldItems[wItem].ubLevel, gWorldItems[wItem].usFlags, gWorldItems[wItem].bRenderZHeightAboveLevel); if(gWorldItems[wItem].object.ubNumberOfObjects < 1) { mergeSuccessful = true; RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel); RemoveItemFromWorld(wItem); - break; } } } - //no crates in sector inventory. search merc inventories - if(mergeSuccessful == false) - { - for(int loop=0; loop<18; loop++) - { - if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector) - { - for(unsigned int pocket=0; pocket < MercPtrs[loop]->inv.size(); pocket++) - { - if(MercPtrs[loop]->inv[pocket].usItem == crateItem) - { - DistributeStatus(&gWorldItems[wItem].object, &MercPtrs[loop]->inv[pocket], Magazine[Item[crateItem].ubClassIndex].ubMagSize); - if(gWorldItems[wItem].object.ubNumberOfObjects < 1) - { - mergeSuccessful = true; - RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel); - RemoveItemFromWorld(wItem); - break; - } - } - } - if(mergeSuccessful == true) - break; - } - } - } - //no crates in merc inventory. create a new sector item - if(mergeSuccessful == false) - { - CreateAmmo(crateItem, &newCrate, 0); - DistributeStatus(&gWorldItems[wItem].object, &newCrate, Magazine[Item[crateItem].ubClassIndex].ubMagSize); - AddItemToPool(gWorldItems[wItem].sGridNo, &newCrate, 1, gWorldItems[wItem].ubLevel, gWorldItems[wItem].usFlags, gWorldItems[wItem].bRenderZHeightAboveLevel); - if(gWorldItems[wItem].object.ubNumberOfObjects < 1) - { - mergeSuccessful = true; - RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel); - RemoveItemFromWorld(wItem); - } - } } } + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] ); } - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] ); } break; diff --git a/Utils/Text.h b/Utils/Text.h index 655882f3..354c6fed 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -1330,6 +1330,7 @@ enum SLG_BR_AWESOME_TEXT, SLG_INV_RES_ERROR, + SLG_INV_CUSTUM_ERROR, }; extern STR16 zSaveLoadText[]; @@ -1570,6 +1571,8 @@ enum NIV_NO_PACK, NIV_ZIPPER_COMBAT, NIV_ZIPPER_NO_MOVE, + NIV_SELL_ALL, + NIV_DELETE_ALL, }; #endif diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index ed4bd07f..40805de7 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -456,7 +456,7 @@ itemEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "ubWeight") == 0) { pData->curElement = ELEMENT; - pData->curItem.ubWeight = (UINT8) atol(pData->szCharData); + pData->curItem.ubWeight = (UINT16) atol(pData->szCharData); } else if(strcmp(name, "ubPerPocket") == 0) { diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 4f666444..f0323e05 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -3390,6 +3390,7 @@ STR16 zSaveLoadText[] = L"Awesome Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4271,6 +4272,8 @@ STR16 NewInvMessage[] = L"Gevonden niet rugzak", L"De ritssluiting werkt slechts in gevecht", L"Kan niet me bewegen terwijl actieve rugzakritssluiting", + L"Bent zeker u u wilt alle sectorpunten verkopen?", + L"Bent zeker u u wilt alle sectorpunten schr?", }; #endif //DUTCH diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 7626d995..5ff60d9d 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -3391,6 +3391,7 @@ STR16 zSaveLoadText[] = L"Awesome Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4266,6 +4267,8 @@ STR16 NewInvMessage[] = L"Backpack not found", L"Zipper only works in combat", L"Can not move while backpack zipper active", + L"Are you sure you want to sell all sector items?", + L"Are you sure you want to delete all sector items?", }; #endif //ENGLISH diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index f7c463ae..5e0c88de 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -3379,6 +3379,7 @@ STR16 zSaveLoadText[] = L"Superb Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4253,6 +4254,8 @@ STR16 NewInvMessage[] = L"Baluchon non trouvй", L"La tirette fonctionne seulement dans le combat", L"Ne peut pas se dйplacer alors que la tirette de baluchon active", + L"Кtes vous sыr vous voulez vendre tous les articles de secteur?", + L"Кtes vous sыr vous voulez supprimer tous les articles de secteur?", }; #endif //FRENCH diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 288eb852..c3c79bd6 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -656,11 +656,11 @@ STR16 pAttributeMenuStrings[] = STR16 pTrainingMenuStrings[] = { - L"Ьben", // train yourself - L"Miliz", // train the town - L"Trainer", // train your teammates - L"Rekrut", // be trained by an instructor - L"Abbrechen", // cancel this menu + L"Ьben", // train yourself + L"Miliz", // train the town + L"Trainer", // train your teammates + L"Rekrut", // be trained by an instructor + L"Abbrechen", // cancel this menu }; STR16 pSquadMenuStrings[] = @@ -3193,7 +3193,8 @@ STR16 zSaveLoadText[] = L"Ausgezeichnete Auswahl", L"Fantastische Auswahl", - L"Neuer Warenbestand arbeitet nicht im 640x480 Bildumfang. Bitte bestimmen Sie die GrцЯe neu und versuchen Sie wieder.", + L"Neues Inventar funktioniert nicht in 640x480 Auflцsung. Wдhlen Sie eine andere Auflцsung und versuchen Sie es erneut.", + L"Neues Inventar funktioniert nicht mit dem ausgewдhlten 'Data' Ordner.", }; //MapScreen @@ -4059,6 +4060,8 @@ STR16 NewInvMessage[] = L"Rucksack nicht gefunden", L"ReiЯverschluss funktioniert nur im Kampf", L"Bewegung nicht mцglich, wдhrend ReiЯverschluss des Rucksacks offen ist", + L"Sind Sie sicher, dass Sie alle Gegenstдnde im Sektor verkaufen wollen?", + L"Sind Sie sicher, dass Sie alle Gegenstдnde im Sektor lцschen wollen?", }; #endif //GERMAN diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index c23dfaf1..c7549e09 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -3371,6 +3371,7 @@ STR16 zSaveLoadText[] = L"Awesome Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4250,6 +4251,8 @@ STR16 NewInvMessage[] = L"Fagotto non trovato", L"La chiusura lampo funziona soltanto nel combattimento", L"Non puт muoversi mentre la chiusura lampo del fagotto attiva", + L"Siete sicuri voi desiderate vendere tutti gli articoli del settore?", + L"Siete sicuri voi desiderate cancellare tutti gli articoli del settore?", }; #endif //ITALIAN diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 43acaf37..3e3aed30 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -3371,6 +3371,7 @@ STR16 zSaveLoadText[] = L"Awesome Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4246,6 +4247,8 @@ STR16 NewInvMessage[] = L"Backpack not found", L"Zipper only works in combat", L"Can not move while backpack zipper active", + L"Are you sure you want to sell all sector items?", + L"Are you sure you want to delete all sector items?", }; #endif //POLISH diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index edf2cbf2..12036326 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -3385,6 +3385,7 @@ STR16 zSaveLoadText[] = L"Все, включая эксклюзив", L"Новый инвентарь, используемый в этом релизе, не работает при разрешении экрана 640х480. Измените разрешение и запустит игру заново.", + L"Новый инвентарь не работает, если выбрана по умолчанию игровая папка 'Data'.", }; @@ -4259,6 +4260,8 @@ STR16 NewInvMessage[] = L"Вы потеряли свой рюкзак...", L"Замок рюкзака работает лишь во время битвы.", L"Вы не можете передвигаться с открытым рюкзаком.", + L"Вы уверены что находитесь в здравом уме и отвечаете за свои действия? И вы в самом деле хотите продать весь хлам этого сектора голодающему населению Арулько?", + L"Вы уверены что находитесь в здравом уме и отвечаете за свои действия? И вы в самом деле хотите выбросить весь хлам, валяющийся в этом секторе?", }; #endif //RUSSIAN diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index b6233795..45b07a34 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -3391,6 +3391,7 @@ STR16 zSaveLoadText[] = L"Awesome Selection", L"New Inventory does not work in 640x480 screen size. Please resize and try again.", + L"New Inventory does not work from the default 'Data' folder.", }; @@ -4266,6 +4267,8 @@ STR16 NewInvMessage[] = L"Backpack not found", L"Zipper only works in combat", L"Can not move while backpack zipper active", + L"Are you sure you want to sell all sector items?", + L"Are you sure you want to delete all sector items?", }; #endif //TAIWANESE diff --git a/ja2_2005Express.vcproj b/ja2_2005Express.vcproj index 1ea2f354..596fa2ac 100644 --- a/ja2_2005Express.vcproj +++ b/ja2_2005Express.vcproj @@ -17,7 +17,7 @@