From 91eef3098cc8b6443ad41fe4aa2f28f319d0d7e7 Mon Sep 17 00:00:00 2001 From: Wanne Date: Thu, 15 Oct 2015 10:40:58 +0000 Subject: [PATCH] - Equip Milita Improvements: I've written code, which adds attachments to free positions on the gun militia chose to pick up (by navaroe) - Bugfix: Reinforcements: Parts of roadblocks were resurrected after reinforcements death (by navaroe) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7995 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Auto Resolve.cpp | 42 +++++++----- Strategic/Queen Command.cpp | 2 +- Strategic/Reinforcement.cpp | 6 +- Tactical/Inventory Choosing.cpp | 118 +++++++++++++++++++++++++++----- Tactical/Items.cpp | 12 ++-- Tactical/Soldier Control.h | 2 +- 6 files changed, 135 insertions(+), 47 deletions(-) diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index 27a71d7d..38263e34 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -764,7 +764,7 @@ void AssociateEnemiesWithStrategicGroups() { SECTORINFO *pSector; GROUP *pGroup; - UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; + UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; //how many soldiers of the type do we still have to assign to a group? UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks; UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup; INT32 i; @@ -784,10 +784,10 @@ void AssociateEnemiesWithStrategicGroups() ubNumTanks = pSector->ubNumTanks; //Now go through our enemies in the autoresolve array, and assign the ubGroupID to the soldier - //Stationary groups have a group ID of 0 + //Stationary groups have a group ID of 0 - first assign enemies from those stationary groups for( i = 0; i < gpAR->ubEnemies; ++i ) { - if ( gpEnemies[i].uiFlags & CELL_TANK && ubNumTanks ) + if ( gpEnemies[i].uiFlags & CELL_TANK && ubNumTanks ) //is this soldier a tank? and we still have some tanks to add? (since there might not be a static tank in sector) { gpEnemies[i].pSoldier->ubGroupID = 0; gpEnemies[i].uiFlags |= CELL_ASSIGNED; @@ -835,36 +835,36 @@ void AssociateEnemiesWithStrategicGroups() ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks; for( i = 0; i < gpAR->ubEnemies; i++ ) { - if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) + if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) //has this soldier already been assigned to a cell and therefore a group (while processing the static enemies above) ? { - if( ubNumTanks && ubNumTanksInGroup ) + if (ubNumTanks && ubNumTanksInGroup && gpEnemies[i].uiFlags & CELL_TANK ) //is there still a tank to assign and is this a cell for tank? { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumTanks--; ubNumTanksInGroup--; } - else if( ubNumElites && ubNumElitesInGroup ) + else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE) { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumElites--; ubNumElitesInGroup--; } - else if( ubNumTroops && ubNumTroopsInGroup ) + else if (ubNumTroops && ubNumTroopsInGroup && gpEnemies[i].uiFlags & CELL_TROOP) { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumTroops--; ubNumTroopsInGroup--; } - else if( ubNumAdmins && ubNumAdminsInGroup ) + else if (ubNumAdmins && ubNumAdminsInGroup && gpEnemies[i].uiFlags & CELL_ADMIN) { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumAdmins--; ubNumAdminsInGroup--; - } + } } } } @@ -876,7 +876,7 @@ void AssociateEnemiesWithStrategicGroups() pGroup = gpGroupList; while( pGroup ) { - // Don't process road block. It'll be processed as static + // Don't process road block. It'll be processed as static (because their ubGroupID is 0 so the first term eval to false) if ( pGroup->ubGroupID && pGroup->usGroupTeam == ENEMY_TEAM && IsGroupInARightSectorToReinforce( pGroup, gpAR->ubSectorX, gpAR->ubSectorY ) ) { ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites; @@ -887,28 +887,28 @@ void AssociateEnemiesWithStrategicGroups() { if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) { - if ( ubNumTanks && ubNumTanksInGroup ) + if (ubNumTanks && ubNumTanksInGroup && gpEnemies[i].uiFlags & CELL_TANK) { gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[i].uiFlags |= CELL_ASSIGNED; ubNumTanks--; ubNumTanksInGroup--; } - else if ( ubNumElites && ubNumElitesInGroup ) + else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE) { - gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; + gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumElites--; ubNumElitesInGroup--; } - else if( ubNumTroops && ubNumTroopsInGroup ) + else if (ubNumTroops && ubNumTroopsInGroup && gpEnemies[i].uiFlags & CELL_TROOP) { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; ubNumTroops--; ubNumTroopsInGroup--; } - else if( ubNumAdmins && ubNumAdminsInGroup ) + else if (ubNumAdmins && ubNumAdminsInGroup && gpEnemies[i].uiFlags & CELL_ADMIN) { gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; @@ -921,7 +921,7 @@ void AssociateEnemiesWithStrategicGroups() pGroup = pGroup->next; } - // Set GroupID = 0 for the rest + // Set GroupID = 0 for the rest (that includes reinforcements) ubDirAmount = GetAdjacentSectors( pSectors, gpAR->ubSectorX, gpAR->ubSectorY ); for( ubCurrSI = 0; ubCurrSI < ubDirAmount; ++ubCurrSI ) @@ -935,7 +935,7 @@ void AssociateEnemiesWithStrategicGroups() for( i = 0; i < gpAR->ubEnemies; ++i ) { - if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break; + if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break; //if group would be left understaffed, it wont reinforce - go chceck another sector (what if are there more groups here?) if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) { @@ -978,6 +978,10 @@ void AssociateEnemiesWithStrategicGroups() } } } + /*at this point, all enemies should have been assigned to their cell and group. If not, there is a bug around + Because number and type of cells should be computed for the same composition of enemies as the one we see in this function, it should not happen though*/ + AssertMsg(!(ubISNumAdmins & ubISNumTroops & ubISNumElites & ubISNumTanks), "Mapping between actual enemies and autoresolve cells is wrong."); + } @@ -2531,9 +2535,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2"); { if( gpEnemies[ i ].pSoldier ) { - if( fDeleteForGood && gpEnemies[ i ].pSoldier->stats.bLife < OKLIFE ) + if( fDeleteForGood && gpEnemies[ i ].pSoldier->stats.bLife < OKLIFE ) //if we are finished with battle and soldier is either dead or dying { - TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass ); + TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass ); //add casualty to some statistic if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); ProcessQueenCmdImplicationsOfDeath( gpEnemies[ i ].pSoldier ); AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpEnemies[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT ); diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index d87f6ca0..8e077c56 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -655,7 +655,7 @@ BOOLEAN PrepareEnemyForSectorBattle() if (mapMaximumNumberOfEnemies > gGameExternalOptions.ubGameMaximumNumberOfEnemies) mapMaximumNumberOfEnemies = gGameExternalOptions.ubGameMaximumNumberOfEnemies; - + //is there more enemies in the sector then we can actually place on map? //are there more enemies in the sector then we can actually place on map? gfPendingNonPlayerTeam[ENEMY_TEAM] = (NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, ENEMY_TEAM ) > mapMaximumNumberOfEnemies); diff --git a/Strategic/Reinforcement.cpp b/Strategic/Reinforcement.cpp index 9c71e1b2..5e72377e 100644 --- a/Strategic/Reinforcement.cpp +++ b/Strategic/Reinforcement.cpp @@ -36,7 +36,7 @@ UINT32 guiMilitiaReinforceTurn = 0, guiMilitiaArrived = 0;//dnl ch68 090913 void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ) { UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; - UINT16 pusMoveDir[4][3]; + UINT16 pusMoveDir[4][3]; //first column in this matrix is number of sector, except for 4th row UINT8 ubDirNumber, ubIndex; GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks ); @@ -57,10 +57,10 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE ); for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ ) - { + { //take number of the involved sector, find its X and Y coordintes and then ask for number of troops there GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); - while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize) + while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize) //count how many of static group will reinforce the battle, but leave minimal group size to guard { if( ubNumElites ) { diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index 45cbc441..99741639 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -86,6 +86,7 @@ ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[SOLDIER_GUN_CHOICE_SELECTIONS][ARMY // { /* 10- rocket rifle */ 5, ROCKET_RIFLE, AUTO_ROCKET_RIFLE , RPK74, HK21E, MINIMI , -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, //}; + // Flugente: created separate gun choices for different soldier classes ARMY_GUN_CHOICE_TYPE gArmyItemChoices[SOLDIER_GUN_CHOICE_SELECTIONS][MAX_ITEM_TYPES]; @@ -103,7 +104,6 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness); UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, BOOLEAN getMatchingCoolness); UINT16 PickARandomAttachment(UINT8 typeIndex, INT8 bSoldierClass, UINT16 usBaseItem, UINT8 maxCoolness, BOOLEAN getMatchingCoolness); - void InitArmyGunTypes(void) { ARMY_GUN_CHOICE_TYPE *pGunChoiceTable; @@ -3701,7 +3701,7 @@ enum { SI_LEGS, SI_SIGHT, // for sunglasses and NVGs SI_FACE2, - SI_FACE_SPARESIGHT, // for sunglasses at night an NVGs during the day - militia take those at well, otherwise mobiles are ill equipped when the night begins/ends + SI_FACE_SPARESIGHT, // for sunglasses at night an NVGs during the day - militia take those as well, otherwise mobiles are ill equipped when the night begins/ends SI_GASMASK, SI_MELEE, SI_GRENADE, @@ -3722,6 +3722,8 @@ struct ItemSearchStruct { UINT32 val; // the fitness value of this object }; +void addAttachementsToMilitiaWeapon(std::vector& pWorldItem, UINT16 usTabooFlag, SOLDIERCREATE_STRUCT *pp); + // evaluate an object an remember it if it is the best so far void EvaluateObjForItem( std::vector& pWorldItem, OBJECTTYPE* pObj, UINT32 uiCount, ItemSearchStruct* pSi )//dnl ch75 271013 { @@ -3764,40 +3766,73 @@ void EvaluateObjForItem_WithAmmo( std::vector& pWorldItem, OBJECTTYPE } } +/** +Makes sure that stack of items on stacksIndexInWorldItem is removed, if it does not contain any items now. + +Use after removing stuff from pWorldItem like by attaching it to something or by putting it into inventory. +*/ +void RemoveStackIfEmpty(std::vector& pWorldItem, UINT32 stacksIndexInWorldItem) { + if (pWorldItem[stacksIndexInWorldItem].object.ubNumberOfObjects < 1) + { + // account for items with invalid gridnos... + if (pWorldItem[stacksIndexInWorldItem].sGridNo != NOWHERE) + { + RemoveItemFromPool(pWorldItem[stacksIndexInWorldItem].sGridNo, stacksIndexInWorldItem, pWorldItem[stacksIndexInWorldItem].ubLevel); + } + + // setting this to false can lead to cases where we 'forget' items without a valid gridno - though I am unsure why. + //pWorldItem[ pSi->pos ].fExists = FALSE; + } +} + // forward declaration for default parameter // if pSi has an entry, move gun from pWorldItem into pp void SearchItemRetrieval( std::vector& pWorldItem, ItemSearchStruct* pSi, SOLDIERCREATE_STRUCT *pp, UINT8 usTake = 1 );//dnl ch75 271013 + +/** Used after taking item from world and putting it into militias inventory. +Makes sure TAKEN_BY_MILITIA flags are set in manner reflecting the flags on items stack of origin. +*/ +void SetTakenByMilitiaFlagsWhenForRetrievedItem(std::vector& pWorldItem, UINT32 itemsPositionInWorld, SOLDIERCREATE_STRUCT *pp, UINT32 slotInInventory, UINT8 numberOfItemsToMark) { + for (UINT8 i = 0; i < numberOfItemsToMark; ++i) + { + (pp->Inv[slotInInventory])[i]->data.sObjectFlag |= TAKEN_BY_MILITIA; + } + + if (pWorldItem[itemsPositionInWorld].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN) + (pp->Inv[slotInInventory])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN; //remember the taboo we set on item while it was on ground + if (pWorldItem[itemsPositionInWorld].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE) + (pp->Inv[slotInInventory])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE; +} + // if pSi has an entry, move gun from pWorldItem into pp void SearchItemRetrieval( std::vector& pWorldItem, ItemSearchStruct* pSi, SOLDIERCREATE_STRUCT *pp, UINT8 usTake )//dnl ch75 271013 { if ( pSi->found && !pSi->done ) { - UINT8 usRealTake = min(usTake, pWorldItem[ pSi->pos ].object.ubNumberOfObjects); - pWorldItem[ pSi->pos ].object.MoveThisObjectTo(pp->Inv[ pSi->soldierslot ], usRealTake ); + //never take more than there actually is on the given stack (atm. we try to take 2 grenades, but there might be only 1) + UINT8 usRealTake = min(usTake, pWorldItem[ pSi->pos ].object.ubNumberOfObjects); + //move objects (like weapon) to soldiers slot, position of object in the world and target slot are determined by values in pSi + pWorldItem[ pSi->pos ].object.MoveThisObjectTo(pp->Inv[ pSi->soldierslot ], usRealTake ); - for ( UINT8 i = 0; i < usRealTake; ++i ) + SetTakenByMilitiaFlagsWhenForRetrievedItem(pWorldItem, pSi->pos, pp, pSi->soldierslot, usRealTake); +/* for ( UINT8 i = 0; i < usRealTake; ++i ) (pp->Inv[ pSi->soldierslot ])[i]->data.sObjectFlag |= TAKEN_BY_MILITIA; - if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN ) - (pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN; + if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN ) + (pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_GREEN; if ( pWorldItem[ pSi->pos ].usFlags & WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE ) - (pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE; - - if ( pWorldItem[ pSi->pos ].object.ubNumberOfObjects < 1 ) - { - // account for items with invalid gridnos... - if ( pWorldItem[ pSi->pos ].sGridNo != NOWHERE ) - RemoveItemFromPool(pWorldItem[ pSi->pos ].sGridNo, (pSi->pos), pWorldItem[ pSi->pos ].ubLevel); + (pp->Inv[ pSi->soldierslot ])[0]->data.sObjectFlag |= TAKEN_BY_MILITIA_TABOO_BLUE;*/ - // setting this to false can lead to cases where we 'forget' items without a valid gridno - though I am unsure why. - //pWorldItem[ pSi->pos ].fExists = FALSE; - } + // account for items with invalid gridnos - when we take last item from the stack, the whole stack object should be gone + RemoveStackIfEmpty(pWorldItem, pSi->pos); + } pSi->done = TRUE; } + typedef std::map AmmoType_BulletCountMap; // used to count how many bullets of an ammotype we have typedef std::map Calibre_BulletCountMap; // this map stores a map containing all the different ammotypes and how many bulltes we have for them @@ -4510,6 +4545,8 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI // take this gun SearchItemRetrieval( pWorldItem, &si[SI_GUN], pp ); + //soldier has his gun now, look for attachments for it + addAttachementsToMilitiaWeapon(pWorldItem, usTabooFlag, pp); // empty the gun, create a mag if ( !fSearchForAmmo ) @@ -4535,6 +4572,8 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI // take this gun SearchItemRetrieval( pWorldItem, &si[SI_GUN], pp ); + //soldier has his gun now, look for attachments for it + addAttachementsToMilitiaWeapon(pWorldItem, usTabooFlag, pp); // empty the gun, create a mag if ( !fSearchForAmmo ) @@ -4808,4 +4847,49 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI ///////////////////////////////// Exit ///////////////////////////////////////////////////////// } + + +/** Goes through items in pWorldItem and looks for scopes, foregrips, lasers, etc. and tries to attach them to thing in soldiers (pp) hand. Hopefuly, +it is a weapon. If thing is successfuly attached, it is removed from world. Attachement has to be reachable and not a taboo for militia. + +Does not attempt to improve current attachments, first item to fit in a position will remain there. +*/ +void addAttachementsToMilitiaWeapon(std::vector& pWorldItem, UINT16 usTabooFlag, SOLDIERCREATE_STRUCT *pp) { + for (UINT32 uiCount = 0; uiCount < pWorldItem.size(); ++uiCount) // ... for all items in the world ... + { + if ((pWorldItem)[uiCount].fExists) // ... if item exists ... + { + OBJECTTYPE* pObj = &((pWorldItem)[uiCount].object); // ... get pointer for this item ... + + if (pObj != NULL && pObj->exists()) // ... if pointer is not obviously useless ... + { + // this would be the place where we check wether the militia is allowed to pick up an item depending on its soldierclass + // test wether item is reachable and its not taboo + if (((pWorldItem)[uiCount].usFlags & WORLD_ITEM_REACHABLE) && !((pWorldItem)[uiCount].usFlags & usTabooFlag)) + { + + UINT32 usItemClass = Item[(pWorldItem)[uiCount].object.usItem].usItemClass; + UINT64 nasAttachmentClass = Item[(pWorldItem)[uiCount].object.usItem].nasAttachmentClass; //eg. 16 for scope + UINT32 attachmentClass = Item[(pWorldItem)[uiCount].object.usItem].attachmentclass; + + //check if this item is something we might want to attach, bipods are excluded atm because militia mainly runs around and doesn't camp enough + //also under barrel launchers are not dealt with (at least for now) + if (usItemClass & IC_MISC && attachmentClass & (AC_SCOPE | AC_FOREGRIP | AC_STOCK | AC_SIGHT | AC_LASER | AC_MUZZLE | AC_SLING)) { + //we got something, lets get the weapon and try to attach it. + OBJECTTYPE* gun = &pp->Inv[HANDPOS]; //we are looking to attach to thing in hand, should be gun + OBJECTTYPE* attachment = &(pWorldItem)[uiCount].object; + BOOLEAN isAttachedNow = gun->AttachObject(NULL, attachment, FALSE); //do the actual attaching + + if (isAttachedNow) { //might be false, if attachement was not valid for the gun (like small scope to M-960A) + RemoveStackIfEmpty(pWorldItem, uiCount); //chceck uiCount stack, might be empty now and should be removed + //SetTakenByMilitiaFlagsWhenForRetrievedItem(pWorldItem,... //Nav:I realized, this is not required for attachement, hopefuly correctly (because weapon got proper flags already) + } + } + } + } + } + } + +} + ////////////////// Flugente: militia equipment feature /////////////////////////////////// diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 9e05a06d..338cb166 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -2329,7 +2329,7 @@ BOOLEAN ValidItemAttachmentSlot( OBJECTTYPE * pObj, UINT16 usAttachment, BOOLEAN OBJECTTYPE * tmpObj = FindAttachmentByClass(pObj,IC_GUN,subObject); usSimilarItem = tmpObj->usItem; } - if ( !fSameItem ) + if ( !fSameItem ) //Nav: why is this check here? fSameItem can only be false here, doesn't hurt I guess... { for(int i = 0;i usAttachmentSlotIndexVector ) { @@ -4950,7 +4950,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1); } else - pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1); + pAttachment->MoveThisObjectTo(attachmentObject,1,pSoldier,NUM_INV_SLOTS,1); } //WarmSteel - Because we want every attachment to stay in place in NAS, we must first delete the "null" attachment, then insert the new one. diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index ab75747b..a88acf61 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1327,7 +1327,7 @@ public: UINT32 uiLastAssignmentChangeMin; // timestamp of last assignment change in minutes INT32 iTotalLengthOfInsuranceContract; - UINT8 ubSoldierClass; //admin, elite, troop (creature types?) + UINT8 ubSoldierClass; //admin, elite, troop (creature types?) Nav: 2 seems to mean elite, 3 troop so admin is 1 UINT8 ubAPsLostToSuppression; UINT8 ubSuppressorID;