diff --git a/Laptop/BobbyRGuns.cpp b/Laptop/BobbyRGuns.cpp index f55d4556..2364d95b 100644 --- a/Laptop/BobbyRGuns.cpp +++ b/Laptop/BobbyRGuns.cpp @@ -2521,16 +2521,19 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum // HEADROCK HAM 3: Generate list of possible attachments to a gun (Guns only!) if (gGameExternalOptions.fBobbyRayTooltipsShowAttachments) { - // Check entire attachment list UINT16 iLoop = 0; + // Check entire attachment list while( 1 ) { - // Is the weapon we're checking the same as the one we're tooltipping? - if (Attachment[iLoop][1] == Item[pItemNumbers[ i ]].uiIndex) - { - usAttachment = Attachment[iLoop][0]; + //Madd: Common Attachment Framework + //TODO: Note that the items in this list will be duplicated if they are present in both the CAF and the old attachment method + //need to refactor this to work more like the NAS attachment slots method + usAttachment = 0; + if ( IsAttachmentPointAvailable(Item[pItemNumbers[ i ]].uiIndex, iLoop) ) + { + usAttachment = iLoop; // If the attachment is not hidden - if (!Item[ usAttachment ].hiddenaddon && !Item[ usAttachment ].hiddenattachment) + if (usAttachment > 0 && !Item[ usAttachment ].hiddenaddon && !Item[ usAttachment ].hiddenattachment) { if (wcslen( attachStr3 ) + wcslen(Item[usAttachment].szItemName) > 3800) { @@ -2546,8 +2549,34 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum } } } + + // Is the weapon we're checking the same as the one we're tooltipping? + usAttachment = 0; + if (Attachment[iLoop][1] == Item[pItemNumbers[ i ]].uiIndex) + { + usAttachment = Attachment[iLoop][0]; + } + + // If the attachment is not hidden + if (usAttachment > 0 && !Item[ usAttachment ].hiddenaddon && !Item[ usAttachment ].hiddenattachment) + { + if (wcslen( attachStr3 ) + wcslen(Item[usAttachment].szItemName) > 3800) + { + // End list early to avoid stack overflow + wcscat( attachStr3, L"\n..." ); + break; + } + else + {// Add the attachment's name to the list. + fAttachmentsFound = TRUE; + swprintf( attachStr2, L"\n%s", Item[ usAttachment ].szItemName ); + wcscat( attachStr3, attachStr2); + } + } + + iLoop++; - if (Attachment[iLoop][0] == 0) + if (Attachment[iLoop][0] == 0 && Item[iLoop].usItemClass == 0) { // Reached end of list break; diff --git a/Standard Gaming Platform/Types.h b/Standard Gaming Platform/Types.h index 46d11e0e..1386ce8e 100644 --- a/Standard Gaming Platform/Types.h +++ b/Standard Gaming Platform/Types.h @@ -36,7 +36,7 @@ typedef unsigned int UINT32; typedef signed __int64 INT64; // WANNE - BMP: Used for Big Maps typedef signed int INT32; typedef unsigned __int64 UINT64; -typedef unsigned long long UINT128; +//typedef unsigned long long UINT128; //Madd: Doing away with this redundant type #else typedef unsigned int UINT32; typedef int INT32; diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index 5516c1b6..013590f5 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -287,7 +287,7 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier ) // The drug rate is 0 now too pSoldier->drugs.bDrugEffectRate[ cnt ] = 0; - // morla downer only if side effect exists and this effect is allowed for a drug + // morale downer only if side effect exists and this effect is allowed for a drug if ( Drug[cnt].ubDrugSideEffect > 0 && Drug[cnt].ubMoralBacklash > 0 ) { // Once for each 'level' of crash.... diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index f6743bc3..a3db4145 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -5147,6 +5147,7 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex) UINT16 usAttachment; std::vector attachList, parseList; std::vector usAttachmentSlotIndexVector = GetItemSlots(pObject); + UINT64 point = GetAvailableAttachmentPoint(pObject, 0); //Madd: Common Attachment Framework //start by deleting the currently defined regions if they exist //BOB : also, clean up the popup boxes (in case they're still around) @@ -5205,10 +5206,32 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex) UINT16 usLoopSlotID = usAttachmentSlotIndexVector[slotCount]; attachList.clear(); - + //Print all attachments that fit on this item. for(UINT16 usLoop = 0; usLoop < MAXATTACHMENTS; usLoop++) { //We no longer find valid attachments from AttachmentSlots.xml so we need to work a bit harder to get our list + usAttachment = 0; + + //Madd: Common Attachment Framework + if (Item[usLoop].nasAttachmentClass & AttachmentSlots[usLoopSlotID].nasAttachmentClass && IsAttachmentPointAvailable(point, usLoop, TRUE)) + { + usAttachment = usLoop; + if( !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment)) + { + bool exists = false; + for (UINT32 i = 0; i < attachList.size(); i++) + { + if ( attachList[i] == usAttachment ) + { + exists = true; + break; + } + } + if (!exists) + attachList.push_back(usAttachment); + } + } + usAttachment = 0; if(Attachment[usLoop][1] == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[usLoop][0]].nasAttachmentClass) { //search primary item attachments.xml @@ -5232,11 +5255,24 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex) } } } - if(Attachment[usLoop][0] == 0 && Launchable[usLoop][0] == 0) + if(Attachment[usLoop][0] == 0 && Launchable[usLoop][0] == 0 && Item[usLoop].usItemClass == 0) break; - if( usAttachment > 0 && !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment)) - attachList.push_back(usAttachment); + if( usAttachment > 0 && !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment)) + { + bool exists = false; + for (UINT32 i = 0; i < attachList.size(); i++) + { + if ( attachList[i] == usAttachment ) + { + exists = true; + break; + } + } + + if (!exists) + attachList.push_back(usAttachment); + } } if(attachList.size()>0){ diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index a8044ee6..57a52c20 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -767,8 +767,12 @@ extern OBJECTTYPE gTempObject; typedef struct { UINT32 usItemClass; - UINT32 nasAttachmentClass; //CHRISL: Identify the class of attachment - UINT32 nasLayoutClass; + UINT64 nasAttachmentClass; //CHRISL: Identify the class of attachment + UINT64 nasLayoutClass; +//Madd: Common Attachment Framework: attach items based on matching connection points rather than using the old long attachmentinfo method + UINT64 ulAvailableAttachmentPoint; + UINT64 ulAttachmentPoint; + UINT8 ubAttachToPointAPCost; // cost to attach to any matching point UINT16 ubClassIndex; UINT8 ubCursor; INT8 bSoundType; @@ -1469,8 +1473,8 @@ typedef struct { UINT16 uiSlotIndex; CHAR16 szSlotName[200]; - UINT32 nasAttachmentClass; - UINT128 nasLayoutClass; + UINT64 nasAttachmentClass; + UINT64 nasLayoutClass; UINT16 usDescPanelPosX; UINT16 usDescPanelPosY; BOOLEAN fMultiShot; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 6e6e4e9a..25bddc18 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -2086,6 +2086,13 @@ BOOLEAN ValidAttachment( UINT16 usAttachment, UINT16 usItem, UINT8 * pubAPCost ) *pubAPCost = (UINT8)APBPConstants[AP_RELOAD_GUN]; //default value } + //Madd: Common Attachment Framework + if ( IsAttachmentPointAvailable(usItem, usAttachment)) + { + if (pubAPCost) + *pubAPCost = Item[usAttachment].ubAttachToPointAPCost; + return TRUE; + } // look for the section of the array pertaining to this attachment... while( 1 ) { @@ -2122,7 +2129,7 @@ BOOLEAN ValidAttachment( UINT16 usAttachment, UINT16 usItem, UINT8 * pubAPCost ) return( TRUE ); } -BOOLEAN ValidAttachment( UINT16 usAttachment, OBJECTTYPE * pObj, UINT8 * pubAPCost, UINT8 subObject, std::vector usAttachmentSlotIndexVector ) +BOOLEAN ValidAttachment( UINT16 usAttachment, OBJECTTYPE * pObj, UINT8 * pubAPCost, UINT8 subObject, std::vector usAttachmentSlotIndexVector) { if (pObj->exists() == false) { return FALSE; @@ -2142,16 +2149,22 @@ BOOLEAN ValidAttachment( UINT16 usAttachment, OBJECTTYPE * pObj, UINT8 * pubAPCo if(usAttachmentSlotIndexVector.empty()) return FALSE; - //Check if the attachment is valid with the main item - foundValidAttachment = (ValidAttachment(usAttachment, pObj->usItem, pubAPCost) || ValidLaunchable(usAttachment, pObj->usItem)); - - //Loop through all attachment points on the main item - for(attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end() && !foundValidAttachment; ++iter) + //Madd: Common Attachment Framework + foundValidAttachment = IsAttachmentPointAvailable(pObj, subObject, usAttachment); + if (foundValidAttachment && pubAPCost ) + *pubAPCost = Item[usAttachment].ubAttachToPointAPCost; + else { - if(iter->exists()) - foundValidAttachment = (ValidAttachment(usAttachment, iter->usItem, pubAPCost) || ValidLaunchable(usAttachment, iter->usItem)); - } + //Check if the attachment is valid with the main item + foundValidAttachment = (ValidAttachment(usAttachment, pObj->usItem, pubAPCost) || ValidLaunchable(usAttachment, pObj->usItem)); + //Loop through all attachment points on the main item + for(attachmentList::iterator iter = (*pObj)[subObject]->attachments.begin(); iter != (*pObj)[subObject]->attachments.end() && !foundValidAttachment; ++iter) + { + if(iter->exists()) + foundValidAttachment = (ValidAttachment(usAttachment, iter->usItem, pubAPCost) || ValidLaunchable(usAttachment, iter->usItem)); + } + } return ( foundValidAttachment ); } else @@ -2327,7 +2340,7 @@ BOOLEAN ValidItemAttachmentSlot( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN //Determine if this item can receive this attachment. This is different, in that it may //be possible to have this attachment on this item, but may already have an attachment on //it which doesn't work simultaneously with the new attachment (like a silencer and duckbill). -BOOLEAN ValidItemAttachment( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN fAttemptingAttachment, BOOLEAN fDisplayMessage, UINT8 subObject, std::vector usAttachmentSlotIndexVector ) +BOOLEAN ValidItemAttachment( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN fAttemptingAttachment, BOOLEAN fDisplayMessage, UINT8 subObject, std::vector usAttachmentSlotIndexVector) { BOOLEAN fSameItem = FALSE, fSimilarItems = FALSE; UINT16 usSimilarItem = NOTHING; @@ -2571,6 +2584,10 @@ BOOLEAN TwoHandedItem( UINT16 usItem ) BOOLEAN ValidLaunchable( UINT16 usLaunchable, UINT16 usItem ) { INT32 iLoop = 0; + //Madd: Common Attachment Framework + if ( IsAttachmentPointAvailable(usItem, usLaunchable) ) + return TRUE; + //DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("ValidLaunchable: launchable=%d, item=%d",usLaunchable,usItem)); // look for the section of the array pertaining to this launchable item... while( 1 ) @@ -2611,7 +2628,8 @@ BOOLEAN ValidItemLaunchable( OBJECTTYPE * pObj, UINT16 usAttachment ) if (pObj->exists() == false) { return FALSE; } - if ( !ValidLaunchable( usAttachment, pObj->usItem ) ) + //Madd: Common Attachment Framework + if ( !ValidLaunchable( usAttachment, pObj->usItem ) && !IsAttachmentPointAvailable(pObj, 0, usAttachment) ) { return( FALSE ); } @@ -4709,7 +4727,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac if ( pSoldier != NULL ) ApplyEquipmentBonuses(pSoldier); - + return( TRUE ); } // check for merges @@ -4993,33 +5011,51 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac } if ( pSoldier != NULL ) ApplyEquipmentBonuses(pSoldier); + return( TRUE ); } return( FALSE ); } //CHRISL: Use this function to sort through Attachments.xml and Launchables.xml -UINT32 SetAttachmentSlotsFlag(OBJECTTYPE* pObj){ - UINT32 uiSlotFlag = 0; +UINT64 SetAttachmentSlotsFlag(OBJECTTYPE* pObj){ + UINT64 uiSlotFlag = 0; UINT32 uiLoop = 0; UINT32 fItem; if(pObj->exists()==false) return 0; + + //Madd: Common Attachment Framework + UINT64 point = GetAvailableAttachmentPoint(pObj, 0); + while(1) { fItem = 0; + //Madd: Common Attachment Framework + if (IsAttachmentPointAvailable(point, uiLoop, TRUE)) + { + fItem = uiLoop; + if(fItem && ItemIsLegal(fItem, TRUE)) // We've found a valid attachment. Set the nasAttachmentSlots flag appropriately + uiSlotFlag |= Item[fItem].nasAttachmentClass; + } + if (Attachment[uiLoop][1] == pObj->usItem){ fItem = Attachment[uiLoop][0]; + + if(fItem && ItemIsLegal(fItem, TRUE)) + uiSlotFlag |= Item[fItem].nasAttachmentClass; } + if (Launchable[uiLoop][1] == pObj->usItem ){ fItem = Launchable[uiLoop][0]; + + if(fItem && ItemIsLegal(fItem, TRUE)) + uiSlotFlag |= Item[fItem].nasAttachmentClass; } - if(fItem && ItemIsLegal(fItem, TRUE)){ // We've found a valid attachment. Set the nasAttachmentSlots flag appropriately - uiSlotFlag |= Item[fItem].nasAttachmentClass; - } + uiLoop++; - if (Attachment[uiLoop][0] == 0 && Launchable[uiLoop][0] == 0){ + if (Attachment[uiLoop][0] == 0 && Launchable[uiLoop][0] == 0 && Item[uiLoop].usItemClass == 0 ){ // No more attachments to search break; } @@ -5035,8 +5071,8 @@ std::vector GetItemSlots(OBJECTTYPE* pObj, UINT8 subObject, BOOLEAN fAtt std::vector tempSlots; UINT8 numSlots = 0; UINT16 magSize = 0; - UINT32 fItemSlots = 0; - UINT128 fItemLayout = 0; + UINT64 fItemSlots = 0; //MM: Bumped the NAS UINT32s to UINT64s + UINT64 fItemLayout = 0; if(UsingNewAttachmentSystem()==false || !pObj->exists()) return tempItemSlots; @@ -5050,8 +5086,8 @@ std::vector GetItemSlots(OBJECTTYPE* pObj, UINT8 subObject, BOOLEAN fAtt //Next, let's figure out which slots the item gives us access to if(fItemSlots){ //We don't need to do anything if the item gets no slots - for(UINT8 sClass = 0; sClass < 32; sClass++){ //go through each attachment class and find the slots the item should have - UINT32 uiClass = (UINT32)pow((double)2, (int)sClass); + for(UINT8 sClass = 0; sClass < 64; sClass++){ //go through each attachment class and find the slots the item should have + UINT64 uiClass = (UINT64)pow((double)2, (int)sClass); UINT32 slotSize = tempItemSlots.size(); if(fItemSlots & uiClass){ //don't bother with this slot if it's not a valid class for(UINT32 sCount = 1; sCount < MAXITEMS+1; sCount++){ @@ -13458,4 +13494,49 @@ BOOLEAN OBJECTTYPE::TransformObject( SOLDIERTYPE * pSoldier, UINT8 ubStatusIndex // Signal a successful transformation. return TRUE; -} \ No newline at end of file +} + +//Madd: Common Attachment Framework - check if a given point is acceptable +bool IsAttachmentPointAvailable( OBJECTTYPE * pObject, UINT8 subObject, UINT32 attachmentID ) +{ + if (Item[pObject->usItem].ulAvailableAttachmentPoint > 0 && (Item[attachmentID].attachment || Item[attachmentID].usItemClass & IC_GRENADE || Item[attachmentID].usItemClass & IC_BOMB)&& Item[attachmentID].ulAttachmentPoint & GetAvailableAttachmentPoint(pObject, subObject)) + return true; + else + return false; +} + +//Madd: Common Attachment Framework - if we already know the point +bool IsAttachmentPointAvailable( UINT64 point, UINT32 attachmentID, BOOLEAN onlyCheckAttachments ) +{ + if (point > 0 && (!onlyCheckAttachments || (Item[attachmentID].attachment || Item[attachmentID].usItemClass & IC_GRENADE || Item[attachmentID].usItemClass & IC_BOMB)) && Item[attachmentID].ulAttachmentPoint & point) + return true; + else + return false; +} + +//Madd: Common Attachment Framework, doesn't look at attachments +bool IsAttachmentPointAvailable( UINT32 itemID, UINT32 attachmentID ) +{ + if (Item[itemID].ulAvailableAttachmentPoint > 0 && (Item[attachmentID].attachment || Item[attachmentID].usItemClass & IC_GRENADE || Item[attachmentID].usItemClass & IC_BOMB) && Item[attachmentID].ulAttachmentPoint & Item[itemID].ulAvailableAttachmentPoint) + return true; + else + return false; +} + +//Madd: Common Attachment Framework, get point value from object + attachments +UINT64 GetAvailableAttachmentPoint (OBJECTTYPE * pObject, UINT8 subObject) +{ + UINT64 point = 0; + if (pObject) + { + point = Item[pObject->usItem].ulAvailableAttachmentPoint; + for (attachmentList::iterator iter = (*pObject)[subObject]->attachments.begin(); iter != (*pObject)[subObject]->attachments.end(); ++iter) + { + if(iter->exists() && Item[iter->usItem].ulAvailableAttachmentPoint > 0 ) + point |= Item[iter->usItem].ulAvailableAttachmentPoint; + } + } + + return point; +} + diff --git a/Tactical/Items.h b/Tactical/Items.h index e568d941..a2689f28 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -154,7 +154,7 @@ BOOLEAN ValidItemAttachment( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN fAt //Return true if usAttachment would fit on an item with usItem, without considering possible other attachments on this gun. This may be inaccurate for NAS, because slots can change. BOOLEAN ValidAttachment( UINT16 usAttachment, UINT16 usItem, UINT8* ubAPCost = NULL ); //This function does the same as the above, but is more accurate. -BOOLEAN ValidAttachment( UINT16 usAttachment, OBJECTTYPE * pObj, UINT8* ubAPCost = NULL, UINT8 subObject = 0, std::vector usAttachmentSlotIndexVector = std::vector() ); +BOOLEAN ValidAttachment( UINT16 usAttachment, OBJECTTYPE * pObj, UINT8* ubAPCost = NULL, UINT8 subObject = 0, std::vector usAttachmentSlotIndexVector = std::vector()); BOOLEAN ValidItemAttachmentSlot( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN fAttemptingAttachment, BOOLEAN fDisplayMessage = TRUE, UINT8 subObject = 0, INT16 slotCount = -1, BOOLEAN fIgnoreAttachmentInSlot = FALSE, OBJECTTYPE ** ppAttachInSlot = NULL, std::vector usAttachmentSlotIndexVector = std::vector()); // Determines if it is possible to merge an item with any item whose class @@ -452,6 +452,12 @@ void GetScopeLists( OBJECTTYPE * pObj, std::map& arScopeMap BOOLEAN IsAttachmentClass( UINT16 usItem, UINT32 aFlag ); BOOLEAN HasAttachmentOfClass( OBJECTTYPE * pObj, UINT32 aFlag ); +//Madd: Common Attachment Framework +bool IsAttachmentPointAvailable( OBJECTTYPE * pObject, UINT8 subObject, UINT32 attachmentID ); +bool IsAttachmentPointAvailable( UINT32 itemID, UINT32 attachmentID ); +bool IsAttachmentPointAvailable( UINT64 point, UINT32 attachmentID, BOOLEAN onlyCheckAttachments ); +UINT64 GetAvailableAttachmentPoint ( OBJECTTYPE * pObject, UINT8 subObject ); + #endif diff --git a/Tactical/XML_AttachmentSlots.cpp b/Tactical/XML_AttachmentSlots.cpp index 63ed4db9..897aeea3 100644 --- a/Tactical/XML_AttachmentSlots.cpp +++ b/Tactical/XML_AttachmentSlots.cpp @@ -122,12 +122,12 @@ attachmentslotEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "nasAttachmentClass") == 0) { pData->curElement = ELEMENT; - pData->curAttachmentSlot.nasAttachmentClass = (UINT32) atol(pData->szCharData); + pData->curAttachmentSlot.nasAttachmentClass = (UINT64) atof(pData->szCharData); } else if(strcmp(name, "nasLayoutClass") == 0) { pData->curElement = ELEMENT; - pData->curAttachmentSlot.nasLayoutClass = (UINT128) atol(pData->szCharData); + pData->curAttachmentSlot.nasLayoutClass = (UINT64) atof(pData->szCharData); } else if(strcmp(name, "usDescPanelPosX") == 0) { diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp index 3fd215e4..2914a7db 100644 --- a/TileEngine/physics.cpp +++ b/TileEngine/physics.cpp @@ -1903,7 +1903,25 @@ void CalculateLaunchItemBasicParams( SOLDIERTYPE *pSoldier, OBJECTTYPE *pItem, I // Are we armed, and are we throwing a LAUNCHABLE? - usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + //MM: Again, this only works if the launchers are all the same + //usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + //MM: Replacement: + OBJECTTYPE *pObj = NULL; + usLauncher = 0; + pObj = pSoldier->GetUsedWeapon( &pSoldier->inv[pSoldier->ubAttackingHand] ); + if ( pObj != NULL ) + { + if (Item[pObj->usItem].usItemClass == IC_LAUNCHER) + usLauncher = pObj->usItem; + else if (Item[pObj->usItem].usItemClass == IC_GUN) + { + usLauncher = GetAttachedGrenadeLauncher(pObj); + } + } + if ( usLauncher == 0) // fail back to the original + usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1741")); if ( fArmed && ( Item[usLauncher].mortar || Item[pItem->usItem].mortar ) ) { @@ -2304,7 +2322,26 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT32 sGridNo, UI sStartZ = GET_SOLDIER_THROW_HEIGHT( pSoldier->pathing.bLevel ); - usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + + //MM: Again, this only works if the launchers are all the same + //usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + //MM: Replacement: + OBJECTTYPE *pObj = NULL; + usLauncher = 0; + pObj = pSoldier->GetUsedWeapon( &pSoldier->inv[pSoldier->ubAttackingHand] ); + if ( pObj != NULL ) + { + if (Item[pObj->usItem].usItemClass == IC_LAUNCHER) + usLauncher = pObj->usItem; + else if (Item[pObj->usItem].usItemClass == IC_GUN) + { + usLauncher = GetAttachedGrenadeLauncher(pObj); + } + } + if ( usLauncher == 0) // fail back to the original + usLauncher = GetLauncherFromLaunchable( pItem->usItem ); + + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2103")); if ( fArmed && Item[usLauncher].mortar ) diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index c6a47931..0b7f8799 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -124,6 +124,9 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "usItemClass") == 0 || strcmp(name, "nasAttachmentClass") == 0 || strcmp(name, "nasLayoutClass") == 0 || + strcmp(name, "AvailableAttachmentPoint") == 0 || + strcmp(name, "AttachmentPoint") == 0 || + strcmp(name, "AttachToPointAPCost") == 0 || strcmp(name, "ubClassIndex") == 0 || strcmp(name, "ubCursor") == 0 || strcmp(name, "bSoundType") == 0 || @@ -528,12 +531,27 @@ itemEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "nasAttachmentClass") == 0) { pData->curElement = ELEMENT; - pData->curItem.nasAttachmentClass = (UINT32) atol(pData->szCharData); + pData->curItem.nasAttachmentClass = (UINT64) atof(pData->szCharData); } else if(strcmp(name, "nasLayoutClass") == 0) { pData->curElement = ELEMENT; - pData->curItem.nasLayoutClass = (UINT32) atol(pData->szCharData); + pData->curItem.nasLayoutClass = (UINT64) atof(pData->szCharData); + } + else if(strcmp(name, "AvailableAttachmentPoint") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.ulAvailableAttachmentPoint = (UINT64) atof(pData->szCharData); + } + else if(strcmp(name, "AttachmentPoint") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.ulAttachmentPoint = (UINT64) atof(pData->szCharData); + } + else if(strcmp(name, "AttachToPointAPCost") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.ubAttachToPointAPCost = (UINT8) atol(pData->szCharData); } else if(strcmp(name, "ubClassIndex") == 0) {