From 7baeb2017538f25204052659e2a4b4657ec7f7dc Mon Sep 17 00:00:00 2001 From: Shadooow Date: Tue, 22 Mar 2022 22:12:07 +0000 Subject: [PATCH] INI option SOLDIERS_ALWAYS_WEAR_ANY_ARMOR works improperly at 100% game progress, so that a soldier lacks 1, 2 or all 3 armor items ('naked' guy). (by sun_alf) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9341 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Inventory Choosing.cpp | 96 ++++++++++++++------------------- 1 file changed, 40 insertions(+), 56 deletions(-) diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index 475fd139..f552825e 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -98,8 +98,8 @@ void ChooseBombsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bBombClas void ChooseLBEsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bLBEClass ); UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass); -UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness); -UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, BOOLEAN getMatchingCoolness); +UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 wantedCoolness); +UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 wantedCoolness, BOOLEAN getMatchingCoolness); UINT16 PickARandomAttachment(UINT8 typeIndex, INT8 bSoldierClass, UINT16 usBaseItem, UINT8 maxCoolness, BOOLEAN getMatchingCoolness); void InitArmyGunTypes(void) @@ -833,8 +833,7 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8 //selection for that particular type of item, and 1-11 means to choose an item if possible. 1 is //the worst class of item, while 11 is the best. -void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponClass, - INT8 bAmmoClips, INT8 bAttachClass, BOOLEAN fAttachment ) +void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponClass, INT8 bAmmoClips, INT8 bAttachClass, BOOLEAN fAttachment ) { //INVTYPE *pItem; UINT16 i; @@ -1460,47 +1459,31 @@ void ChooseArmourForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bHelmetC UINT16 usItem = 0, usHelmetItem = 0, usVestItem = 0, usLeggingsItem = 0; //UINT16 usNumMatches; //INT8 bOrigVestClass = bVestClass; - INT8 i; - //tais: always get any armor... smeagol doesnt like naked people.. - if(gGameExternalOptions.fSoldiersWearAnyArmour) + // This option wants us to dress soldier up surely. But unfortunately it cannot be guaranteed due to: + // * item choises XML can be empty + // * a picking is random after all + // So we are going to try to pick something other than nothing but not guarantee it. + if (gGameExternalOptions.fSoldiersWearAnyArmour) { - if(bHelmetClass < 1) bHelmetClass = 1; - //search for a non-empty class with items we need - for(i=bHelmetClass;i<=10;i++) - { - usHelmetItem = PickARandomItem(HELMET, pp->ubSoldierClass, i ); - //if we find a non-empty class change to that and break - if(usHelmetItem > 0) - { - bHelmetClass = i; - break; - } - } - if(bVestClass < 1) bVestClass = 1; - //search for a non-empty class with items we need - for(i=bVestClass;i<=10;i++) - { - usVestItem = PickARandomItem(VEST, pp->ubSoldierClass, i ); - //if we find a non-empty class change to that and break - if(usVestItem > 0) - { - bVestClass = i; - break; - } - } - if(bLeggingsClass < 1) bLeggingsClass = 1; - //search for a non-empty class with items we need - for(i=bLeggingsClass;i<=10;i++) - { - usLeggingsItem = PickARandomItem(LEGS, pp->ubSoldierClass, i ); - //if we find a non-empty class change to that and break - if(usLeggingsItem > 0) - { - bLeggingsClass = i; - break; - } - } + if (bHelmetClass < MIN_EQUIPMENT_CLASS) bHelmetClass = MIN_EQUIPMENT_CLASS; + if (bVestClass < MIN_EQUIPMENT_CLASS) bVestClass = MIN_EQUIPMENT_CLASS; + if (bLeggingsClass < MIN_EQUIPMENT_CLASS) bLeggingsClass = MIN_EQUIPMENT_CLASS; + + // Make the first attempt for each item type + usHelmetItem = PickARandomItem(HELMET, pp->ubSoldierClass, bHelmetClass, TRUE); + usVestItem = PickARandomItem(VEST, pp->ubSoldierClass, bVestClass, TRUE); + usLeggingsItem = PickARandomItem(LEGS, pp->ubSoldierClass, bLeggingsClass, TRUE); + + // PickARandomItem(getMatchingCoolness = TRUE) must have a strong reason to return 0 disregarding wantedCoolness + // we pass, e.g. itemChoices is empty or filled with improper items. So let's make another attempt to ensure we did + // all what we can. Unlikely it will help, though. + if (usHelmetItem == 0) + usHelmetItem = PickARandomItem(HELMET, pp->ubSoldierClass, bHelmetClass, TRUE); + if (usVestItem == 0) + usVestItem = PickARandomItem(VEST, pp->ubSoldierClass, bVestClass, TRUE); + if (usLeggingsItem == 0) + usLeggingsItem = PickARandomItem(LEGS, pp->ubSoldierClass, bLeggingsClass, TRUE); } //Madd: added minimum protection of 10 for armours to be used by enemies @@ -3313,11 +3296,11 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass) { return PickARandomItem(typeIndex, bSoldierClass, 100,FALSE); } -UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness) +UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 wantedCoolness) { - return PickARandomItem(typeIndex, bSoldierClass, maxCoolness,TRUE); + return PickARandomItem(typeIndex, bSoldierClass, wantedCoolness,TRUE); } -UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, BOOLEAN getMatchingCoolness) +UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 wantedCoolness, BOOLEAN getMatchingCoolness) { //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("PickARandomItem: typeIndex = %d, maxCoolness = %d, getMatchingCoolness = %d",typeIndex,maxCoolness,getMatchingCoolness)); @@ -3342,8 +3325,10 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, B if ( i > gArmyItemChoices[bSoldierClass][ typeIndex ].ubChoices ) break; - // a chance for nothing! - uiChoice = Random(gArmyItemChoices[bSoldierClass][ typeIndex ].ubChoices + (int) ( gArmyItemChoices[bSoldierClass][ typeIndex ].ubChoices / 3 )); + if (getMatchingCoolness == TRUE) + uiChoice = Random(gArmyItemChoices[bSoldierClass][typeIndex].ubChoices); + else // otherwise there is a chance to pick nothing! + uiChoice = Random(gArmyItemChoices[bSoldierClass][typeIndex].ubChoices + (int)(gArmyItemChoices[bSoldierClass][typeIndex].ubChoices / 3)); if ( uiChoice >= gArmyItemChoices[bSoldierClass][ typeIndex ].ubChoices ) { @@ -3365,7 +3350,7 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, B pickItem = FALSE; - if (usItem >= 0 && Item[usItem].ubCoolness <= maxCoolness && ItemIsLegal(usItem)) + if (usItem > 0 && Item[usItem].randomitem == 0 && ItemIsLegal(usItem)) { // On day if (DayTime() == TRUE) @@ -3387,10 +3372,6 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, B pickItem = TRUE; } } - - // Flugente: if item is still random, don't pick it - if ( Item[usItem].randomitem > 0 ) - pickItem = FALSE; } @@ -3399,12 +3380,15 @@ UINT16 PickARandomItem(UINT8 typeIndex, INT8 bSoldierClass, UINT8 maxCoolness, B if (pickItem == TRUE) { - // pick a default item in case we don't find anything with a matching coolness, but pick the coolest item we can find - if ( defaultItem == 0 || Item[usItem].ubCoolness > Item[defaultItem].ubCoolness ) + // pick a default item in case we don't find anything with a matching coolness, but pick the most matching (by coolness) item + if ( defaultItem == 0 || + abs((int)wantedCoolness - (int)Item[usItem].ubCoolness) < abs((int)wantedCoolness - (int)Item[defaultItem].ubCoolness)) + { defaultItem = usItem; + } // found something with the right coolness - if ( Item[usItem].ubCoolness == maxCoolness || !getMatchingCoolness ) + if ( Item[usItem].ubCoolness == wantedCoolness || !getMatchingCoolness ) return usItem; } }