diff --git a/GameSettings.cpp b/GameSettings.cpp index 7338c0fc..182e6c6a 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1451,6 +1451,8 @@ void LoadGameExternalOptions() // enable all weapon caches gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE); + //Madd: override map item appearance chance + gGameExternalOptions.ubMapItemChanceOverride = iniReader.ReadInteger("Strategic Gameplay Settings","MAP_ITEM_CHANCE_OVERRIDE", 0, 0, 100); //################# Laptop Settings ################## diff --git a/GameSettings.h b/GameSettings.h index 27f0673d..41155fa8 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1092,6 +1092,7 @@ typedef struct BOOLEAN gBriefingRoom; BOOLEAN gEncyclopedia; + UINT8 ubMapItemChanceOverride; //Madd: special map override, mostly for debugging } GAME_EXTERNAL_OPTIONS; typedef struct diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index a033ce8d..1e4ea1da 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -1530,12 +1530,15 @@ typedef enum DESTRUCTION, COMBINE_POINTS, TREAT_ARMOUR, - EXPLOSIVE, + EXPLOSIVE_MERGE_HARD, //Madd: renamed to hard EASY_MERGE, ELECTRONIC_MERGE, USE_ITEM, USE_ITEM_HARD, - TEMPERATURE + TEMPERATURE, + EXPLOSIVE_MERGE_EASY, //Madd: new merge types + MECHANICAL_MERGE_EASY, + MECHANICAL_MERGE_HARD } MergeType; extern UINT16 Merge[MAXITEMS+1][6]; @@ -1543,7 +1546,7 @@ extern UINT16 Merge[MAXITEMS+1][6]; typedef struct { UINT16 usItem; - UINT16 usAttachment[2]; + UINT16 usAttachment[MAX_DEFAULT_ATTACHMENTS]; //Madd: extended from 2 to 20, being lazy with constant reuse :p UINT16 usResult; UINT32 uiIndex; } ComboMergeInfoStruct; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 1184f7ae..3be0526c 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -3857,7 +3857,7 @@ INT8 GetAttachmentComboMerge( OBJECTTYPE * pObj, UINT8 subObject ) { // search for all the appropriate attachments /* every ComboMerge must have at least one attachments Field */ - for ( bAttachLoop = 0; bAttachLoop < 2; bAttachLoop++ ) + for ( bAttachLoop = 0; bAttachLoop < MAX_DEFAULT_ATTACHMENTS; bAttachLoop++ ) { /* if the none of both Fields contains anything, do not merge */ if ( AttachmentComboMerge[ bIndex ].usAttachment[ bAttachLoop ] == NOTHING ) @@ -3908,7 +3908,7 @@ void PerformAttachmentComboMerge( OBJECTTYPE * pObj, INT8 bAttachmentComboMerge // - status of new object should be average of items including attachments // - change object - for ( bAttachLoop = 0; bAttachLoop < 2; bAttachLoop++ ) + for ( bAttachLoop = 0; bAttachLoop < MAX_DEFAULT_ATTACHMENTS; bAttachLoop++ ) { if ( AttachmentComboMerge[ bAttachmentComboMerge ].usAttachment[ bAttachLoop ] == NOTHING ) { @@ -4327,7 +4327,7 @@ BOOLEAN OBJECTTYPE::AttachObjectOAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac return( FALSE ); } // grant experience! ... SANDRO - so what?! Grant them already! - StatChange( pSoldier, MECHANAMT, 30, FALSE ); + StatChange( pSoldier, MECHANAMT, 40, FALSE ); //Madd: upped this to 40, since standard is now 25 StatChange( pSoldier, WISDOMAMT, 10, FALSE ); // SANDRO - merc records - merging items @@ -4335,8 +4335,8 @@ BOOLEAN OBJECTTYPE::AttachObjectOAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; } // fall through - case EXPLOSIVE: - if ( ubType == EXPLOSIVE ) /// coulda fallen through + case EXPLOSIVE_MERGE_HARD: //Madd: new merge types + if ( ubType == EXPLOSIVE_MERGE_HARD ) /// coulda fallen through { if (pSoldier) { @@ -4360,6 +4360,81 @@ BOOLEAN OBJECTTYPE::AttachObjectOAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac } } // fall through + case EXPLOSIVE_MERGE_EASY: + if ( ubType == EXPLOSIVE_MERGE_EASY ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_DETONATOR_CHECK, 0 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, EXPLODEAMT, 10, FALSE ); + StatChange( pSoldier, WISDOMAMT, 2, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through + case MECHANICAL_MERGE_HARD: + if ( ubType == MECHANICAL_MERGE_HARD ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_SPECIAL_ITEM_CHECK, -30 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, MECHANAMT, 25, FALSE ); + StatChange( pSoldier, WISDOMAMT, 10, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through + case MECHANICAL_MERGE_EASY: + if ( ubType == MECHANICAL_MERGE_EASY ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_SPECIAL_ITEM_CHECK, 0 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, MECHANAMT, 10, FALSE ); + StatChange( pSoldier, WISDOMAMT, 2, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through default: // the merge will combine the two items //Madd: usResult2 only works for standard merges->item1 + item2 = item3 + item4 @@ -4944,11 +5019,17 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); return( FALSE ); } - // grant experience! + // grant experience! ... SANDRO - so what?! Grant them already! -- Madd: this was missing from AttachObjectNAS for some reason + StatChange( pSoldier, MECHANAMT, 40, FALSE ); + StatChange( pSoldier, WISDOMAMT, 10, FALSE ); + + // SANDRO - merc records - merging items -- Madd: this was missing from AttachObjectNAS for some reason + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; } // fall through - case EXPLOSIVE: - if ( ubType == EXPLOSIVE ) /// coulda fallen through + case EXPLOSIVE_MERGE_HARD: + if ( ubType == EXPLOSIVE_MERGE_HARD ) /// coulda fallen through { if (pSoldier) { @@ -4965,6 +5046,85 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac } StatChange( pSoldier, EXPLODEAMT, 25, FALSE ); StatChange( pSoldier, WISDOMAMT, 5, FALSE ); + + // SANDRO - merc records - merging items -- Madd: this was missing from AttachObjectNAS for some reason + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through + case EXPLOSIVE_MERGE_EASY://Madd: new merge types + if ( ubType == EXPLOSIVE_MERGE_EASY ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_DETONATOR_CHECK, 0 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, EXPLODEAMT, 10, FALSE ); + StatChange( pSoldier, WISDOMAMT, 2, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through + case MECHANICAL_MERGE_HARD: + if ( ubType == MECHANICAL_MERGE_HARD ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_SPECIAL_ITEM_CHECK, -30 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, MECHANAMT, 25, FALSE ); + StatChange( pSoldier, WISDOMAMT, 10, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; + } + } + // fall through + case MECHANICAL_MERGE_EASY: + if ( ubType == MECHANICAL_MERGE_EASY ) /// coulda fallen through + { + if (pSoldier) + { + // requires a skill check, and gives experience + iCheckResult = SkillCheck( pSoldier, ATTACHING_SPECIAL_ITEM_CHECK, 0 ); + if (iCheckResult < 0) + { + // could have a chance of detonation + // for now, damage both objects + DamageObj( this, (INT8) -iCheckResult ); + DamageObj( pAttachment, (INT8) -iCheckResult ); + pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 ); + return( FALSE ); + } + StatChange( pSoldier, MECHANAMT, 10, FALSE ); + StatChange( pSoldier, WISDOMAMT, 2, FALSE ); + + // SANDRO - merc records - merging items + if ( pSoldier->ubProfile != NO_PROFILE ) + gMercProfiles[ pSoldier->ubProfile ].records.usItemsCombined++; } } // fall through diff --git a/Tactical/World Items.cpp b/Tactical/World Items.cpp index a91c8bee..e411f6b0 100644 --- a/Tactical/World Items.cpp +++ b/Tactical/World Items.cpp @@ -594,7 +594,8 @@ void LoadWorldItemsFromMap( INT8 **hBuffer, float dMajorMapVersion, int ubMinorM { dummyItem.ubNonExistChance = 0; } - if( gfEditMode || dummyItem.ubNonExistChance <= PreRandom( 100 ) ) + if( gfEditMode || dummyItem.ubNonExistChance <= PreRandom( 100 ) || + (gGameExternalOptions.ubMapItemChanceOverride > 0 && (gGameExternalOptions.ubMapItemChanceOverride >= PreRandom(100)) ) ) //Madd: map item chance override, note this calc is done in reverse { if( !gfEditMode ) { diff --git a/Tactical/XML_ComboMergeInfo.cpp b/Tactical/XML_ComboMergeInfo.cpp index 12847d1c..e6d4d7ad 100644 --- a/Tactical/XML_ComboMergeInfo.cpp +++ b/Tactical/XML_ComboMergeInfo.cpp @@ -18,6 +18,7 @@ struct ComboMergeInfoStruct * curArray; UINT32 maxArraySize; + UINT32 curAttIndex; UINT32 currentDepth; UINT32 maxReadDepth; } @@ -43,14 +44,13 @@ attachmentcombomergeStartElementHandle(void *userData, const XML_Char *name, con pData->curElement = ELEMENT; memset(&pData->curAttachmentComboMerge,0,sizeof(ComboMergeInfoStruct)); - + pData->curAttIndex = 0; pData->maxReadDepth++; //we are not skipping this element } else if(pData->curElement == ELEMENT && (strcmp(name, "uiIndex") == 0 || strcmp(name, "usItem") == 0 || - strcmp(name, "usAttachment1") == 0 || - strcmp(name, "usAttachment2") == 0 || + strstr(name, "usAttachment") > 0 || strcmp(name, "usResult") == 0 )) { pData->curElement = ELEMENT_PROPERTY; @@ -108,15 +108,11 @@ attachmentcombomergeEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curAttachmentComboMerge.usItem = (UINT16) atol(pData->szCharData); } - else if(strcmp(name, "usAttachment1") == 0) + else if(strstr(name, "usAttachment") > 0) { pData->curElement = ELEMENT; - pData->curAttachmentComboMerge.usAttachment[0] = (UINT16) atol(pData->szCharData); - } - else if(strcmp(name, "usAttachment2") == 0) - { - pData->curElement = ELEMENT; - pData->curAttachmentComboMerge.usAttachment[1] = (UINT16) atol(pData->szCharData); + pData->curAttachmentComboMerge.usAttachment[pData->curAttIndex] = (UINT16) atol(pData->szCharData); + pData->curAttIndex++; } else if(strcmp(name, "usResult") == 0) {