diff --git a/GameSettings.cpp b/GameSettings.cpp index 6815b30b..92931564 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1340,6 +1340,18 @@ void LoadGameExternalOptions() // Civils don't make too much actions (for faster civils turn) gGameExternalOptions.bLazyCivilians = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_LAZY_CIVILIANS",FALSE); + // Neutral civilians can detect and avoid player's mines + gGameExternalOptions.bNeutralCiviliansAvoidPlayerMines = iniReader.ReadBoolean("Tactical Interface Settings","CIVILIANS_AVOID_PLAYER_MINES",FALSE); + + // Add smoke after regular explosions + gGameExternalOptions.bAddSmokeAfterExplosion = iniReader.ReadBoolean("Tactical Interface Settings","ADD_SMOKE_AFTER_EXPLOSION",FALSE); + + // Attachments now can explode + gGameExternalOptions.bAllowExplosiveAttachments = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_EXPLOSIVE_ATTACHMENTS",FALSE); + + // , and add special bonuses to explosion + gGameExternalOptions.bAllowSpecialExplosiveAttachments = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_SPECIAL_EXPLOSIVE_ATTACHMENTS",FALSE); + // Chance to Say Annoying Phrase (you can just turn of it by button in game) gGameExternalOptions.iChanceSayAnnoyingPhrase = iniReader.ReadInteger("Tactical Interface Settings","CHANCE_SAY_ANNOYING_PHRASE",100); @@ -1372,6 +1384,7 @@ void LoadGameExternalOptions() // SANDRO - Improved camo applying and camo can be removed gGameExternalOptions.fCamoRemoving = iniReader.ReadBoolean("Tactical Gameplay Settings", "CAMO_REMOVING", TRUE); + gGameExternalOptions.bCamoKitArea = iniReader.ReadInteger("Tactical Gameplay Settings", "CAMO_KIT_USABLE_AREA", 5, 0, 100); // SANDRO - Enhanced close combat system gGameExternalOptions.fEnhancedCloseCombatSystem = iniReader.ReadBoolean("Tactical Gameplay Settings", "ENHANCED_CLOSE_COMBAT_SYSTEM", TRUE); @@ -2748,7 +2761,8 @@ void LoadItemSettings() gItemSettings.fHandlingModifierLauncher = iniReader.ReadFloat ("Weapon Settings","HANDLING_LAUNCHER_MODIFIER", 1.0f, 0.1f, 5.0f); // -------------- ARMOR MODIFIERS ---------------- - gItemSettings.fCamoLBEoverArmorModifier = iniReader.ReadFloat ("Armor Settings","CAMO_LBE_OVER_ARMOR_MODIFIER", 0.2f, 0.0f, 1.0f); + gItemSettings.fCamoLBEoverVestModifier = iniReader.ReadFloat ("Armor Settings","CAMO_LBE_OVER_VEST_MODIFIER", 0.2f, 0.0f, 1.0f); + gItemSettings.fCamoLBEoverPantsModifier = iniReader.ReadFloat ("Armor Settings","CAMO_LBE_OVER_PANTS_MODIFIER", 0.2f, 0.0f, 1.0f); // ------------ EXPLOSIVE MODIFIERS -------------- gItemSettings.fDamageHealthModifierExplosive = iniReader.ReadFloat ("Explosives Settings","DAMAGE_HEALTH_EXPLOSIVE_MODIFIER", 1.0f, 0.1f, 5.0f); diff --git a/GameSettings.h b/GameSettings.h index f2f2883b..fbbe4ec9 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -342,6 +342,7 @@ typedef struct INT8 bAssignedTraitsRarity; BOOLEAN fCamoRemoving; + INT8 bCamoKitArea; // silversurfer added this. It defines how much of the body can be painted with camo kits (usually face and hands). BOOLEAN fEnhancedCloseCombatSystem; //BOOLEAN fImprovedInterruptSystem; @@ -791,6 +792,10 @@ typedef struct BOOLEAN bWeSeeWhatMilitiaSeesAndViceVersa; BOOLEAN bAllowWearSuppressor; BOOLEAN bLazyCivilians; + BOOLEAN bNeutralCiviliansAvoidPlayerMines; //sevenfm: Neutral civilians can detect mines with MAPELEMENT_PLAYER_MINE_PRESENT flag set + BOOLEAN bAddSmokeAfterExplosion; + BOOLEAN bAllowExplosiveAttachments; + BOOLEAN bAllowSpecialExplosiveAttachments; INT16 iChanceSayAnnoyingPhrase; BOOLEAN bNewTacticalAIBehavior; FLOAT uShotHeadPenalty; @@ -1197,7 +1202,7 @@ typedef struct BOOLEAN fShowSkillsInHirePage; UINT8 ubMercRandomStats; - + BOOLEAN fMercRandomBellDistribution; UINT8 ubMercRandomStatsRange; @@ -1989,7 +1994,8 @@ typedef struct FLOAT fHandlingModifierLauncher; // -------------- ARMOR MODIFIERS ---------------- - FLOAT fCamoLBEoverArmorModifier; + FLOAT fCamoLBEoverVestModifier; + FLOAT fCamoLBEoverPantsModifier; // ------------ EXPLOSIVE MODIFIERS -------------- // Grenade Damage Modifiers diff --git a/Strategic/Strategic Merc Handler.cpp b/Strategic/Strategic Merc Handler.cpp index 7c288e59..1655739e 100644 --- a/Strategic/Strategic Merc Handler.cpp +++ b/Strategic/Strategic Merc Handler.cpp @@ -1254,13 +1254,16 @@ void HourlyCamouflageUpdate( void ) { if( pSoldier->bCamo > 0 ) { + // first limit camo to valid values + pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo ); + if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT )) { pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + // pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } else - pSoldier->bCamo -= 2; + pSoldier->bCamo -= 1; // 2 if (pSoldier->bCamo <= 0) { @@ -1278,13 +1281,16 @@ void HourlyCamouflageUpdate( void ) } if( pSoldier->urbanCamo > 0 ) { + // first limit camo to valid values + pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo ); + if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT )) { pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + // pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } else - pSoldier->urbanCamo -= 2; + pSoldier->urbanCamo -= 1; // 2 if (pSoldier->urbanCamo <= 0) { @@ -1302,13 +1308,16 @@ void HourlyCamouflageUpdate( void ) } if( pSoldier->desertCamo > 0 ) { + // first limit camo to valid values + pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo ); + if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT )) { pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + // pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } else - pSoldier->desertCamo -= 2; + pSoldier->desertCamo -= 1; // 2 if (pSoldier->desertCamo <= 0) { @@ -1326,13 +1335,16 @@ void HourlyCamouflageUpdate( void ) } if( pSoldier->snowCamo > 0 ) { + // first limit camo to valid values + pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo ); + if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT )) { pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + // pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } else - pSoldier->snowCamo -= 2; + pSoldier->snowCamo -= 1; // 2 if (pSoldier->snowCamo <= 0) { @@ -1355,7 +1367,7 @@ void HourlyCamouflageUpdate( void ) // SANDRO - different types of Camouflaged trait have been merged together if( ( pSoldier->bCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) ) { - pSoldier->bCamo -= 2; + pSoldier->bCamo -= 1; // 2 if (pSoldier->bCamo <= 0) { pSoldier->bCamo = 0; @@ -1372,7 +1384,7 @@ void HourlyCamouflageUpdate( void ) } if( ( pSoldier->urbanCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) ) { - pSoldier->urbanCamo -= 2; + pSoldier->urbanCamo -= 1; // 2 if (pSoldier->urbanCamo <= 0) { pSoldier->urbanCamo = 0; @@ -1389,7 +1401,7 @@ void HourlyCamouflageUpdate( void ) } if( ( pSoldier->desertCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) ) { - pSoldier->desertCamo -= 2; + pSoldier->desertCamo -= 1; // 2 if (pSoldier->desertCamo <= 0) { pSoldier->desertCamo = 0; @@ -1406,7 +1418,7 @@ void HourlyCamouflageUpdate( void ) } if( ( pSoldier->snowCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) ) { - pSoldier->snowCamo -= 2; + pSoldier->snowCamo -= 1; // 2 if (pSoldier->snowCamo <= 0) { pSoldier->snowCamo = 0; diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp index d4bf20ff..2e501bc2 100644 --- a/Tactical/Faces.cpp +++ b/Tactical/Faces.cpp @@ -919,9 +919,10 @@ void SetAutoFaceInActive(INT32 iFaceIndex ) BOOLEAN SetCamoFace(SOLDIERTYPE * pSoldier) { - INT8 worn = -1; + // silversurfer: Worn camo is not relevant for the face anymore. Only camo kits can paint our face. +// INT8 worn = -1; INT8 applied = -1; - INT16 wornCamo[4]; +// INT16 wornCamo[4]; INT16 appliedCamo[4]; //reset gCamoFace @@ -934,27 +935,27 @@ BOOLEAN SetCamoFace(SOLDIERTYPE * pSoldier) appliedCamo[1] = pSoldier->urbanCamo; appliedCamo[2] = pSoldier->desertCamo; appliedCamo[3] = pSoldier->snowCamo; - wornCamo[0] = pSoldier->wornCamo; +/* wornCamo[0] = pSoldier->wornCamo; wornCamo[1] = pSoldier->wornUrbanCamo; wornCamo[2] = pSoldier->wornDesertCamo; - wornCamo[3] = pSoldier->wornSnowCamo; + wornCamo[3] = pSoldier->wornSnowCamo;*/ for(INT8 loop = 0; loop < 4; loop ++) { - if(wornCamo[loop] > 50) - worn = loop; - if(appliedCamo[loop] > 50) +// if(wornCamo[loop] > 50) +// worn = loop; + if(appliedCamo[loop] > 0 ) //50) applied = loop; } BOOLEAN isCamoFace = FALSE; - if(applied != -1 && worn != -1) + if(applied != -1) // && worn != -1) { isCamoFace = TRUE; - if(appliedCamo[applied] >= wornCamo[worn]) +// if(appliedCamo[applied] >= wornCamo[worn]) { if(applied == 0) gCamoFace[pSoldier->ubProfile].gCamoface = TRUE; @@ -967,7 +968,7 @@ BOOLEAN SetCamoFace(SOLDIERTYPE * pSoldier) return TRUE; } - else +/* else { isCamoFace = TRUE; @@ -992,7 +993,7 @@ BOOLEAN SetCamoFace(SOLDIERTYPE * pSoldier) if(applied == 2 || worn == 2) gCamoFace[pSoldier->ubProfile].gDesertCamoface = TRUE; if(applied == 3 || worn == 3) - gCamoFace[pSoldier->ubProfile].gSnowCamoface = TRUE; + gCamoFace[pSoldier->ubProfile].gSnowCamoface = TRUE;*/ } return isCamoFace; diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index c2f00af4..3111ebdd 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -1835,7 +1835,7 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo ) if ( iResult < -20 && Item[ pSoldier->inv[ HANDPOS ].usItem ].tripwire != 1 ) { // OOPS! ... BOOM! - IgniteExplosion( NOBODY, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pSoldier->inv[ HANDPOS ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection ); + IgniteExplosion( NOBODY, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pSoldier->inv[ HANDPOS ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, &pSoldier->inv[ HANDPOS ] ); pSoldier->inv[ HANDPOS ].MoveThisObjectTo(gTempObject, 1); } } @@ -5019,7 +5019,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue ) if ( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].tripwire != 1 ) { // OOPS! ... BOOM! - IgniteExplosion( NOBODY, gpTempSoldier->sX, gpTempSoldier->sY, (INT16) (gpWorldLevelData[gpTempSoldier->sGridNo].sHeight), gpTempSoldier->sGridNo, gpTempSoldier->inv[ HANDPOS ].usItem, gpTempSoldier->pathing.bLevel, gpTempSoldier->ubDirection ); + IgniteExplosion( NOBODY, gpTempSoldier->sX, gpTempSoldier->sY, (INT16) (gpWorldLevelData[gpTempSoldier->sGridNo].sHeight), gpTempSoldier->sGridNo, gpTempSoldier->inv[ HANDPOS ].usItem, gpTempSoldier->pathing.bLevel, gpTempSoldier->ubDirection, &gpTempSoldier->inv[ HANDPOS ] ); } return; @@ -5774,7 +5774,9 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f */ } - if (pSoldier->bSide == 0) + // sevenfm + // pSoldier->aiData.bNeutral is needed to prevent neutral civs stepping on player's mines + if (pSoldier->bSide == 0 || (pSoldier->aiData.bNeutral && gGameExternalOptions.bNeutralCiviliansAvoidPlayerMines)) { fCheckFlag = MAPELEMENT_PLAYER_MINE_PRESENT; } @@ -5815,7 +5817,15 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f if (pMapElement->uiFlags & fCheckFlag) { // already know there's a mine there - continue; +// sevenfm +// if we try to step on known (planted by player) mine we should consider it wrong + if(!fCheckAroundGridNo) + { + *psProblemGridNo = sNextGridNo; + return( TRUE ); + }else{ + continue; + } } // check for boobytraps diff --git a/Tactical/Interface Dialogue.cpp b/Tactical/Interface Dialogue.cpp index 8156c6ce..d6d6c6b0 100644 --- a/Tactical/Interface Dialogue.cpp +++ b/Tactical/Interface Dialogue.cpp @@ -5683,7 +5683,7 @@ void HandleTexBecomingCamoed() if( pSoldier != NULL ) { //make him camoed - pSoldier->bCamo = 100; + pSoldier->bCamo = gGameExternalOptions.bCamoKitArea; // 100 pSoldier->CreateSoldierPalettes( ); } diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 3ff1e0da..109abe75 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -6213,7 +6213,7 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason ) if ( guiCurrentScreen == GAME_SCREEN ) { // ignite explosions manually - this item is not in the WorldBombs-structure, so we can't add it to the queue - IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemPointerSoldier->sX, gpItemPointerSoldier->sY, (INT16) (gpWorldLevelData[gpItemPointerSoldier->sGridNo].sHeight), gpItemPointerSoldier->sGridNo, gpItemDescObject->usItem, gpItemPointerSoldier->pathing.bLevel, gpItemPointerSoldier->ubDirection ); + IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemPointerSoldier->sX, gpItemPointerSoldier->sY, (INT16) (gpWorldLevelData[gpItemPointerSoldier->sGridNo].sHeight), gpItemPointerSoldier->sGridNo, gpItemDescObject->usItem, gpItemPointerSoldier->pathing.bLevel, gpItemPointerSoldier->ubDirection, gpItemDescObject ); } else if ( (guiCurrentScreen == MAP_SCREEN) || (guiCurrentScreen == MSG_BOX_SCREEN) ) { @@ -13272,7 +13272,7 @@ void TransformationMenuPopup_Arm( OBJECTTYPE* pObj ) if ( screen == GAME_SCREEN ) { // ignite explosions manually - this item is not in the WorldBombs-structure, so we can't add it to the queue - IgniteExplosion( gpItemDescSoldier->ubID, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, pObj->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection ); + IgniteExplosion( gpItemDescSoldier->ubID, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, pObj->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection, pObj ); } else { @@ -13411,7 +13411,7 @@ void BombInventoryMessageBoxCallBack( UINT8 ubExitValue ) if ( screen == GAME_SCREEN ) { // ignite explosions manually - this item is not in the WorldBombs-structure, so we can't add it to the queue - IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, gpItemDescObject->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection ); + IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, gpItemDescObject->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection, gpItemDescObject ); } else if ( (screen == MAP_SCREEN) || (screen == MSG_BOX_SCREEN) ) { @@ -13581,7 +13581,7 @@ void BombInventoryDisArmMessageBoxCallBack( UINT8 ubExitValue ) if ( screen == GAME_SCREEN ) { // ignite explosions manually - this item is not in the WorldBombs-structure, so we can't add it to the queue - IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, gpItemDescObject->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection ); + IgniteExplosion( (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2, gpItemDescSoldier->sX, gpItemDescSoldier->sY, (INT16) (gpWorldLevelData[gpItemDescSoldier->sGridNo].sHeight), gpItemDescSoldier->sGridNo, gpItemDescObject->usItem, gpItemDescSoldier->pathing.bLevel, gpItemDescSoldier->ubDirection, gpItemDescObject ); } else if ( (screen == MAP_SCREEN) || (screen == MSG_BOX_SCREEN) ) { diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 9cda2e6f..0ef7398e 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -1438,6 +1438,10 @@ typedef enum SMALL_CREATURE_GAS, LARGE_CREATURE_GAS, VERY_SMALL_CREATURE_GAS=270, // Renumbered because the original 160 was lost + SMALL_SMOKE=1702, // sevenfm - item for small smoke effect after explosion + MOLOTOV_EXPLOSION=979, // molotov - small fire explosion + GAS_EXPLOSION=1703, // molotov - small fire explosion + FRAG_EXPLOSION=1704, // molotov - small fire explosion // armor FLAK_JACKET=161, //= FIRST_ARMOUR, ( We're out of space! ) diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 70d3adcf..b1712c16 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -8652,11 +8652,11 @@ void CheckEquipmentForDamage( SOLDIERTYPE *pSoldier, INT32 iDamage ) // blow it up! if ( gTacticalStatus.ubAttackBusyCount ) { - IgniteExplosion( pSoldier->ubAttackerID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[ bSlot ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection ); + IgniteExplosion( pSoldier->ubAttackerID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[ bSlot ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, &pSoldier->inv[ bSlot ] ); } else { - IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[ bSlot ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection ); + IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[ bSlot ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, &pSoldier->inv[ bSlot ] ); } //ADB when something in a stack blows up the whole stack goes, so no need to worry about number of items @@ -8721,7 +8721,7 @@ BOOLEAN DamageItemOnGround( OBJECTTYPE * pObject, INT32 sGridNo, INT8 bLevel, IN if ( fBlowsUp ) { // OK, Ignite this explosion! - IgniteExplosion( ubOwner, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, pObject->usItem, bLevel, DIRECTION_IRRELEVANT ); + IgniteExplosion( ubOwner, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, pObject->usItem, bLevel, DIRECTION_IRRELEVANT, pObject ); // SANDRO - merc records if ( (pObject->fFlags & OBJECT_ARMED_BOMB) && ((*pObject)[0]->data.misc.ubBombOwner > 1) ) @@ -8873,8 +8873,9 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) // I've messed this part a little to be more clean, the different camouflaged traits have been merged into one if ( gGameOptions.fNewTraitSystem) { - // reduce camouflage by 2% per tile of deep water - // and 1% for medium water + // silversurfer: We only allow painting the face and hands now so in medium water camo shouldn't wear off anymore. + // reduce camouflage by 1% //2% per tile of deep water + // and 0% //1% for medium water if ( pSoldier->bCamo > 0 ) { if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) ) @@ -8882,19 +8883,19 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->MercInDeepWater( ) ) { pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + //pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } - else +/* else { pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - } + }*/ } else { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->bCamo = __max( 0, pSoldier->bCamo - 2 ); - else - pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); + pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); // 2 + //else + // pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); } if ( pSoldier->bCamo <= 0 ) @@ -8910,19 +8911,19 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->MercInDeepWater( ) ) { pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + //pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } - else +/* else { pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - } + }*/ } else { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 2); - else - pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); + pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); // 2 + //else + // pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); } if ( pSoldier->urbanCamo <= 0 ) @@ -8938,19 +8939,19 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->MercInDeepWater( ) ) { pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + //pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } - else +/* else { pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - } + }*/ } else { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 2); - else - pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); + pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); // 2 + //else + // pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); } if ( pSoldier->desertCamo <= 0 ) @@ -8966,19 +8967,19 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->MercInDeepWater( ) ) { pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); + //pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); } - else +/* else { pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 ); - } + }*/ } else { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 2); - else - pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); + pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); // 2 + //else + // pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); } if ( pSoldier->snowCamo <= 0 ) @@ -8995,9 +8996,9 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->bCamo > 0 ) { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->bCamo = __max( 0, pSoldier->bCamo - 2 ); - else - pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); + pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); // 2 + //else + // pSoldier->bCamo = __max( 0, pSoldier->bCamo - 1 ); if ( (pSoldier->bCamo)== 0) camoWoreOff = TRUE; @@ -9005,9 +9006,9 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->urbanCamo > 0 ) { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 2); - else - pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); + pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); // 2 + //else + // pSoldier->urbanCamo = __max( 0, pSoldier->urbanCamo - 1); if ( (pSoldier->urbanCamo)== 0) camoWoreOff = TRUE; @@ -9015,9 +9016,9 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->desertCamo > 0 ) { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 2); - else - pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); + pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); // 2 + //else + // pSoldier->desertCamo = __max( 0, pSoldier->desertCamo - 1); if ( (pSoldier->desertCamo)== 0) camoWoreOff = TRUE; @@ -9025,9 +9026,9 @@ void WaterDamage( SOLDIERTYPE *pSoldier ) if ( pSoldier->snowCamo > 0 ) { if ( pSoldier->MercInDeepWater( ) ) - pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 2); - else - pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); + pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); // 2 + //else + // pSoldier->snowCamo = __max( 0, pSoldier->snowCamo - 1); if ( (pSoldier->snowCamo)== 0) camoWoreOff = TRUE; @@ -9149,33 +9150,32 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP if (gGameExternalOptions.fCamoRemoving) { - int iJungleCamoTotal = pSoldier->bCamo + pSoldier->wornCamo; - int iUrbanCamoTotal = pSoldier->urbanCamo + pSoldier->wornUrbanCamo; - int iDesertCamoTotal = pSoldier->desertCamo + pSoldier->wornDesertCamo; - int iSnowCamoTotal = pSoldier->snowCamo + pSoldier->wornSnowCamo; - int totalCamo = iJungleCamoTotal + iUrbanCamoTotal + iDesertCamoTotal + iSnowCamoTotal; + int totalCamo = pSoldier->bCamo + pSoldier->urbanCamo + pSoldier->desertCamo + pSoldier->snowCamo; // First, check if we have an item with major JUNGLE camobonus if ( (Item[pObj->usItem].camobonus > Item[pObj->usItem].urbanCamobonus) && (Item[pObj->usItem].camobonus > Item[pObj->usItem].desertCamobonus) && (Item[pObj->usItem].camobonus > Item[pObj->usItem].snowCamobonus) ) { - if (iJungleCamoTotal >= 100) + if ( pSoldier->bCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].camobonus == 0 ) return( FALSE ); // determine how much we can add - bPointsToUse = (100 - (iJungleCamoTotal) + 1 ) / 2; + bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->bCamo ) ); + // check how much of the kit we need for that + bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].camobonus / 100.0 ) ); + // limit to what we have in the kit bPointsToUse = __min( bPointsToUse, usTotalKitPoints ); // determine how much we will add - int iJungleCamoAdded = (int)(Item[pObj->usItem].camobonus * bPointsToUse * 2 / 100 ); + int iJungleCamoAdded = (int)(Item[pObj->usItem].camobonus * bPointsToUse / 100 ); // if we have already too much different camo on ourselves, reduce some or all - if ( (totalCamo + iJungleCamoAdded) > 100 ) + if ( (totalCamo + iJungleCamoAdded) > gGameExternalOptions.bCamoKitArea ) { // first, determine how much we actually want to remove - int iCamoToRemove = (totalCamo + iJungleCamoAdded) - 100; + int iCamoToRemove = (totalCamo + iJungleCamoAdded) - gGameExternalOptions.bCamoKitArea; // reduce camo.. IMPORTANT - third value is type of camo to skip (0=skip-none, 1=jungle, 2=urban, 3=desert,4=snow) iRemainingCamoAfterRemoving = ReduceCamoFromSoldier( pSoldier, iCamoToRemove, 1 ); // "1" - we want to keep the JUNGLE camo @@ -9188,36 +9188,39 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP return( FALSE ); else // otherwise apply the camo { - pSoldier->bCamo = __min( 100, pSoldier->bCamo + iJungleCamoAdded ); + pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo + iJungleCamoAdded ); } } else // everything's fine, apply!! { - pSoldier->bCamo = __min( 100, pSoldier->bCamo + iJungleCamoAdded ); + pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo + iJungleCamoAdded ); } // update with amount that we really used - bPointsToUse = __min( bPointsToUse, (iJungleCamoAdded + 1) / 2 ); + bPointsToUse = ( (FLOAT)iJungleCamoAdded / ( (FLOAT)Item[pObj->usItem].camobonus / 100.0 ) ); } // Second, check if we have an item with major URBAN camobonus else if ( (Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].camobonus) && (Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].desertCamobonus) && (Item[pObj->usItem].urbanCamobonus > Item[pObj->usItem].snowCamobonus) ) { - if (iUrbanCamoTotal >= 100) + if ( pSoldier->urbanCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].urbanCamobonus == 0 ) return( FALSE ); // determine how much we can add - bPointsToUse = (100 - (iUrbanCamoTotal) + 1 ) / 2; + bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->urbanCamo ) ); + // check how much of the kit we need for that + bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].urbanCamobonus / 100.0 ) ); + // limit to what we have in the kit bPointsToUse = __min( bPointsToUse, usTotalKitPoints ); // determine how much we will add - int iUrbanCamoAdded = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse * 2 / 100 ); + int iUrbanCamoAdded = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse / 100 ); // if we have already too much different camo on ourselves, reduce some or all - if ( (totalCamo + iUrbanCamoAdded) > 100 ) + if ( (totalCamo + iUrbanCamoAdded) > gGameExternalOptions.bCamoKitArea ) { // first, determine how much we actually want to remove - int iCamoToRemove = (totalCamo + iUrbanCamoAdded) - 100; + int iCamoToRemove = (totalCamo + iUrbanCamoAdded) - gGameExternalOptions.bCamoKitArea; // reduce camo.. IMPORTANT - third value is type of camo to skip (0=skip-none, 1=jungle, 2=urban, 3=desert,4=snow) iRemainingCamoAfterRemoving = ReduceCamoFromSoldier( pSoldier, iCamoToRemove, 2 ); // "2" - we want to keep the URBAN camo @@ -9230,36 +9233,39 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP return( FALSE ); else // otherwise apply the camo { - pSoldier->urbanCamo = __min( 100, pSoldier->urbanCamo + iUrbanCamoAdded ); + pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo + iUrbanCamoAdded ); } } else // everything's fine, apply!! { - pSoldier->urbanCamo = __min( 100, pSoldier->urbanCamo + iUrbanCamoAdded ); + pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo + iUrbanCamoAdded ); } // update with amount that we really used - bPointsToUse = __min( bPointsToUse, (iUrbanCamoAdded + 1) / 2 ); + bPointsToUse = ( (FLOAT)iUrbanCamoAdded / ( (FLOAT)Item[pObj->usItem].urbanCamobonus / 100.0 ) ); } // Third, check if we have an item with major DESERT camobonus else if ( (Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].camobonus) && (Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].urbanCamobonus) && (Item[pObj->usItem].desertCamobonus > Item[pObj->usItem].snowCamobonus) ) { - if (iDesertCamoTotal >= 100) + if ( pSoldier->desertCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].desertCamobonus == 0 ) return( FALSE ); // determine how much we can add - bPointsToUse = (100 - (iDesertCamoTotal) + 1 ) / 2; + bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->desertCamo ) ); + // check how much of the kit we need for that + bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].desertCamobonus / 100.0 ) ); + // limit to what we have in the kit bPointsToUse = __min( bPointsToUse, usTotalKitPoints ); // determine how much we will add - int iDesertCamoAdded = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse * 2 / 100 ); + int iDesertCamoAdded = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse / 100 ); // if we have already too much different camo on ourselves, reduce some or all - if ( (totalCamo + iDesertCamoAdded) > 100 ) + if ( (totalCamo + iDesertCamoAdded) > gGameExternalOptions.bCamoKitArea ) { // first, determine how much we actually want to remove - int iCamoToRemove = (totalCamo + iDesertCamoAdded) - 100; + int iCamoToRemove = (totalCamo + iDesertCamoAdded) - gGameExternalOptions.bCamoKitArea; // reduce camo.. IMPORTANT - third value is type of camo to skip (0=skip-none, 1=jungle, 2=urban, 3=desert,4=snow) iRemainingCamoAfterRemoving = ReduceCamoFromSoldier( pSoldier, iCamoToRemove, 3 ); // "3" - we want to keep the DESERT camo @@ -9272,36 +9278,39 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP return( FALSE ); else // otherwise apply the camo { - pSoldier->desertCamo = __min( 100, pSoldier->desertCamo + iDesertCamoAdded ); + pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo + iDesertCamoAdded ); } } else // everything's fine, apply!! { - pSoldier->desertCamo = __min( 100, pSoldier->desertCamo + iDesertCamoAdded ); + pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo + iDesertCamoAdded ); } // update with amount that we really used - bPointsToUse = __min( bPointsToUse, (iDesertCamoAdded + 1) / 2 ); + bPointsToUse = ( (FLOAT)iDesertCamoAdded / ( (FLOAT)Item[pObj->usItem].desertCamobonus / 100.0 ) ); } // Fourth, check if we have an item with major SNOW camobonus else if ( (Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].camobonus) && (Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].urbanCamobonus) && (Item[pObj->usItem].snowCamobonus > Item[pObj->usItem].desertCamobonus) ) { - if (iSnowCamoTotal >= 100) + if ( pSoldier->snowCamo >= gGameExternalOptions.bCamoKitArea || Item[pObj->usItem].snowCamobonus == 0 ) return( FALSE ); // determine how much we can add - bPointsToUse = (100 - (iSnowCamoTotal) + 1 ) / 2; + bPointsToUse = __max( 0, ( gGameExternalOptions.bCamoKitArea - pSoldier->snowCamo ) ); + // check how much of the kit we need for that + bPointsToUse = ( (FLOAT)bPointsToUse / ( (FLOAT)Item[pObj->usItem].snowCamobonus / 100.0 ) ); + // limit to what we have in the kit bPointsToUse = __min( bPointsToUse, usTotalKitPoints ); // determine how much we will add - int iSnowCamoAdded = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse * 2 / 100 ); + int iSnowCamoAdded = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse / 100 ); // if we have already too much different camo on ourselves, reduce some or all - if ( (totalCamo + iSnowCamoAdded) > 100 ) + if ( (totalCamo + iSnowCamoAdded) > gGameExternalOptions.bCamoKitArea ) { // first, determine how much we actually want to remove - int iCamoToRemove = (totalCamo + iSnowCamoAdded) - 100; + int iCamoToRemove = (totalCamo + iSnowCamoAdded) - gGameExternalOptions.bCamoKitArea; // reduce camo.. IMPORTANT - third value is type of camo to skip (0=skip-none, 1=jungle, 2=urban, 3=desert,4=snow) iRemainingCamoAfterRemoving = ReduceCamoFromSoldier( pSoldier, iCamoToRemove, 4 ); // "4" - we want to keep the SNOW camo @@ -9314,15 +9323,15 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP return( FALSE ); else // otherwise apply the camo { - pSoldier->snowCamo = __min( 100, pSoldier->snowCamo + iSnowCamoAdded ); + pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo + iSnowCamoAdded ); } } else // everything's fine, apply!! { - pSoldier->snowCamo = __min( 100, pSoldier->snowCamo + iSnowCamoAdded ); + pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo + iSnowCamoAdded ); } // update with amount that we really used - bPointsToUse = __min( bPointsToUse, (iSnowCamoAdded + 1) / 2 ); + bPointsToUse = ( (FLOAT)iSnowCamoAdded / ( (FLOAT)Item[pObj->usItem].snowCamobonus / 100.0 ) ); } else // the item has no major camo, return return( FALSE ); @@ -9334,28 +9343,26 @@ BOOLEAN ApplyCammo( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN *pfGoodAP //get total camo bonus for kit -- note that camo kits now require the camobonus tag to be set //int itemCamo = Item[pObj->usItem].camobonus + Item[pObj->usItem].urbanCamobonus + Item[pObj->usItem].desertCamobonus + Item[pObj->usItem].snowCamobonus; - int totalCamo = pSoldier->bCamo + pSoldier->wornCamo + pSoldier->urbanCamo+pSoldier->wornUrbanCamo+pSoldier->desertCamo+pSoldier->wornDesertCamo+pSoldier->snowCamo+pSoldier->wornSnowCamo; - if ((totalCamo) >= 100) + int iKitCamo = pSoldier->bCamo + pSoldier->urbanCamo + pSoldier->desertCamo + pSoldier->snowCamo; + if ( iKitCamo >= gGameExternalOptions.bCamoKitArea ) { // nothing more to add return( FALSE ); } - // points are used up at a rate of 50% kit = 100% cammo on guy - // add 1 to round off - bPointsToUse = (100 - (totalCamo) + 1 ) / 2; + bPointsToUse = (gGameExternalOptions.bCamoKitArea - iKitCamo); bPointsToUse = __min( bPointsToUse, usTotalKitPoints ); //figure out proportions of each to be applied, one item can theoretically have more than one camouflage type this way - int urban = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse * 2 / 100 ); - int jungle = (int)(Item[pObj->usItem].camobonus * bPointsToUse * 2 / 100 ); - int desert = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse * 2 / 100 ); - int snow = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse * 2 / 100 ); + int urban = (int)(Item[pObj->usItem].urbanCamobonus * bPointsToUse / 100 ); + int jungle = (int)(Item[pObj->usItem].camobonus * bPointsToUse / 100 ); + int desert = (int)(Item[pObj->usItem].desertCamobonus * bPointsToUse / 100 ); + int snow = (int)(Item[pObj->usItem].snowCamobonus * bPointsToUse / 100 ); - pSoldier->bCamo = __min( 100, pSoldier->bCamo + jungle ); - pSoldier->urbanCamo = __min( 100, pSoldier->urbanCamo + urban ); - pSoldier->desertCamo = __min( 100, pSoldier->desertCamo + desert ); - pSoldier->snowCamo = __min( 100, pSoldier->snowCamo + snow ); + pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo + jungle ); + pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo + urban ); + pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo + desert ); + pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo + snow ); } UseKitPoints( pObj, bPointsToUse, pSoldier ); @@ -9400,7 +9407,8 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs // if not a clothes item, nothing to see here if ( clothestype == 0 || clothestype > CLOTHES_MAX ) { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_UNIFORM_FOUND] ); + // silversurfer: This produces an annoying message whenever any invalid item is used on the char so I removed it. + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_NO_UNIFORM_FOUND] ); return( FALSE); } @@ -12372,8 +12380,18 @@ INT16 GetWornCamo( SOLDIERTYPE * pSoldier ) if ( UsingNewInventorySystem() ) if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() ) { - // silversurver: Using LBE vest. Only apply partial bonus from armor vest. - ttl -= ( ( 1.0 - gItemSettings.fCamoLBEoverArmorModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus ); + // silversurfer: Using LBE vest. Only apply partial bonus from armor vest. + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus ); + } + else if ( bLoop == LEGPOS ) + { + FLOAT fLegPenalty = 0; + // depending on how many leg LBE we use the camo effect of the armor pants is higher or lower + fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists(); + fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists(); + // Using thigh rigs. Only apply partial bonus from armor pants. + if ( fLegPenalty > 0 ) + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus * fLegPenalty / 2 ); } } } @@ -12396,7 +12414,7 @@ INT16 GetWornCamo( SOLDIERTYPE * pSoldier ) ttl += GetCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]); } - return __min( ttl, 100 ); + return __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ); } INT16 GetWornUrbanCamo( SOLDIERTYPE * pSoldier ) { @@ -12411,8 +12429,18 @@ INT16 GetWornUrbanCamo( SOLDIERTYPE * pSoldier ) if ( UsingNewInventorySystem() ) if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() ) { - // silversurver: Using LBE vest. Only apply partial bonus from armor vest. - ttl -= ( ( 1.0 - gItemSettings.fCamoLBEoverArmorModifier ) * Item[ pSoldier->inv[bLoop].usItem ].urbanCamobonus ); + // silversurfer: Using LBE vest. Only apply partial bonus from armor vest. + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].urbanCamobonus ); + } + else if ( bLoop == LEGPOS ) + { + FLOAT fLegPenalty = 0; + // depending on how many leg LBE we use the camo effect of the armor pants is higher or lower + fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists(); + fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists(); + // Using thigh rigs. Only apply partial bonus from armor pants. + if ( fLegPenalty > 0 ) + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].urbanCamobonus * fLegPenalty / 2 ); } } } @@ -12435,7 +12463,7 @@ INT16 GetWornUrbanCamo( SOLDIERTYPE * pSoldier ) ttl += GetUrbanCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]); } - return __min( ttl, 100 ); + return __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ); } INT16 GetWornDesertCamo( SOLDIERTYPE * pSoldier ) { @@ -12450,8 +12478,18 @@ INT16 GetWornDesertCamo( SOLDIERTYPE * pSoldier ) if ( UsingNewInventorySystem() ) if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() ) { - // silversurver: Using LBE vest. Only apply partial bonus from armor vest. - ttl -= ( ( 1.0 - gItemSettings.fCamoLBEoverArmorModifier ) * Item[ pSoldier->inv[bLoop].usItem ].desertCamobonus ); + // silversurfer: Using LBE vest. Only apply partial bonus from armor vest. + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].desertCamobonus ); + } + else if ( bLoop == LEGPOS ) + { + FLOAT fLegPenalty = 0; + // depending on how many leg LBE we use the camo effect of the armor pants is higher or lower + fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists(); + fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists(); + // Using thigh rigs. Only apply partial bonus from armor pants. + if ( fLegPenalty > 0 ) + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].desertCamobonus * fLegPenalty / 2 ); } } } @@ -12473,7 +12511,7 @@ INT16 GetWornDesertCamo( SOLDIERTYPE * pSoldier ) if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON) ttl += GetDesertCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]); } - return __min( ttl, 100 ); + return __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ); } INT16 GetWornSnowCamo( SOLDIERTYPE * pSoldier ) { @@ -12488,8 +12526,18 @@ INT16 GetWornSnowCamo( SOLDIERTYPE * pSoldier ) if ( UsingNewInventorySystem() ) if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() ) { - // silversurver: Using LBE vest. Only apply partial bonus from armor vest. - ttl -= ( ( 1.0 - gItemSettings.fCamoLBEoverArmorModifier ) * Item[ pSoldier->inv[bLoop].usItem ].snowCamobonus ); + // silversurfer: Using LBE vest. Only apply partial bonus from armor vest. + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].snowCamobonus ); + } + else if ( bLoop == LEGPOS ) + { + FLOAT fLegPenalty = 0; + // depending on how many leg LBE we use the camo effect of the armor pants is higher or lower + fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists(); + fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists(); + // Using thigh rigs. Only apply partial bonus from armor pants. + if ( fLegPenalty > 0 ) + ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].snowCamobonus * fLegPenalty / 2 ); } } } @@ -12511,7 +12559,7 @@ INT16 GetWornSnowCamo( SOLDIERTYPE * pSoldier ) if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON) ttl += GetSnowCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]); } - return __min( ttl, 100 ); + return __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ); } void ApplyEquipmentBonuses(SOLDIERTYPE * pSoldier) diff --git a/Tactical/Rotting Corpses.cpp b/Tactical/Rotting Corpses.cpp index d155a6fc..5ff3e7e6 100644 --- a/Tactical/Rotting Corpses.cpp +++ b/Tactical/Rotting Corpses.cpp @@ -2869,23 +2869,23 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo ) } else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_CAMO_PALETTE ) { - pNewSoldier->bCamo = 60; - pNewSoldier->wornCamo = 60; + pNewSoldier->bCamo = gGameExternalOptions.bCamoKitArea; + pNewSoldier->wornCamo = __max(0, ( 65 - gGameExternalOptions.bCamoKitArea ) ); } else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE ) { - pNewSoldier->urbanCamo = 60; - pNewSoldier->wornUrbanCamo = 60; + pNewSoldier->urbanCamo = gGameExternalOptions.bCamoKitArea; + pNewSoldier->wornUrbanCamo = __max(0, ( 65 - gGameExternalOptions.bCamoKitArea ) ); } else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE ) { - pNewSoldier->desertCamo = 60; - pNewSoldier->wornDesertCamo = 60; + pNewSoldier->desertCamo = gGameExternalOptions.bCamoKitArea; + pNewSoldier->wornDesertCamo = __max(0, ( 65 - gGameExternalOptions.bCamoKitArea ) ); } else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE ) { - pNewSoldier->snowCamo = 60; - pNewSoldier->wornSnowCamo = 60; + pNewSoldier->snowCamo = gGameExternalOptions.bCamoKitArea; + pNewSoldier->wornSnowCamo = __max(0, ( 65 - gGameExternalOptions.bCamoKitArea ) ); } // Reload palettes.... diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index de49c391..fd3de9b7 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -900,7 +900,6 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src) this->bAIScheduleProgress = src.bAIScheduleProgress; this->sOffWorldGridNo = src.sOffWorldGridNo; this->pAniTile = src.pAniTile; - this->bCamo = src.bCamo; this->sAbsoluteFinalDestination = src.sAbsoluteFinalDestination; this->ubHiResDirection = src.ubHiResDirection; this->ubHiResDesiredDirection = src.ubHiResDesiredDirection; @@ -997,16 +996,18 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src) this->lastFlankSpot = src.lastFlankSpot; this->sniper = src.sniper; this->origDir = src.origDir; - this->wornCamo = src.wornCamo; - this->urbanCamo = src.urbanCamo; // Madd: new camo types - this->wornUrbanCamo = src.wornUrbanCamo; + this->bCamo = __min( gGameExternalOptions.bCamoKitArea, src.bCamo); + this->wornCamo = __min( ( 100 - gGameExternalOptions.bCamoKitArea ), src.wornCamo ); - this->desertCamo = src.desertCamo; - this->wornDesertCamo = src.wornDesertCamo; + this->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, src.urbanCamo); // Madd: new camo types + this->wornUrbanCamo = __min( ( 100 - gGameExternalOptions.bCamoKitArea ), src.wornUrbanCamo ); - this->snowCamo = src.snowCamo; - this->wornSnowCamo = src.wornSnowCamo; + this->desertCamo = __min( gGameExternalOptions.bCamoKitArea, src.desertCamo); + this->wornDesertCamo = __min( ( 100 - gGameExternalOptions.bCamoKitArea ), src.wornDesertCamo ); + + this->snowCamo = __min( gGameExternalOptions.bCamoKitArea, src.snowCamo); + this->wornSnowCamo = __min( ( 100 - gGameExternalOptions.bCamoKitArea ), src.wornSnowCamo ); this->bScopeMode = USE_BEST_SCOPE; diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index a603dc74..a46bb4d8 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -936,10 +936,22 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * if ( i != NO_SLOT && Random( 5 ) < SoldierDifficultyLevel( &Soldier )) { // start camouflaged - Soldier.bCamo = (INT8)Item[Soldier.inv[ i ].usItem].camobonus; - Soldier.urbanCamo = (INT8)Item[Soldier.inv[ i ].usItem].urbanCamobonus; - Soldier.desertCamo = (INT8)Item[Soldier.inv[ i ].usItem].desertCamobonus; - Soldier.snowCamo = (INT8)Item[Soldier.inv[ i ].usItem].snowCamobonus; + Soldier.bCamo = (INT8)__min( gGameExternalOptions.bCamoKitArea, Item[Soldier.inv[ i ].usItem].camobonus ); + Soldier.urbanCamo = (INT8)__min( gGameExternalOptions.bCamoKitArea, Item[Soldier.inv[ i ].usItem].urbanCamobonus ); + Soldier.desertCamo = (INT8)__min( gGameExternalOptions.bCamoKitArea, Item[Soldier.inv[ i ].usItem].desertCamobonus ); + Soldier.snowCamo = (INT8)__min( gGameExternalOptions.bCamoKitArea, Item[Soldier.inv[ i ].usItem].snowCamobonus ); + + // silversurfer: With the new balance setting for kit camo we would probably not see camouflaged soldiers anymore + // (the default for gGameExternalOptions.bCamoKitArea is 5 which is less than the required 50 to be shown as camouflaged). + // So let's give him some bonus to worn camo if kit camo is too low. + if ( Soldier.bCamo > 0 ) + Soldier.wornCamo = __max(0, ( 50 - Soldier.bCamo ) ); + if ( Soldier.urbanCamo > 0 ) + Soldier.wornUrbanCamo = __max(0, ( 50 - Soldier.urbanCamo ) ); + if ( Soldier.desertCamo > 0 ) + Soldier.wornDesertCamo = __max(0, ( 50 - Soldier.desertCamo ) ); + if ( Soldier.snowCamo > 0 ) + Soldier.wornSnowCamo = __max(0, ( 50 - Soldier.snowCamo ) ); } } } @@ -1224,7 +1236,8 @@ BOOLEAN TacticalCopySoldierFromProfile( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STR if ( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT ) ) { // set camouflaged to 100 automatically - pSoldier->bCamo = 100; + // silversurfer: No, set it to the new limit for camo kits. + pSoldier->bCamo = gGameExternalOptions.bCamoKitArea; // 100 } //if ( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED ) ) //{ diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index b9551bf8..32d7c4bd 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -955,6 +955,9 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) //Save the Blood, smell and the revealed status for map elements SaveBloodSmellAndRevealedStatesFromMapToTempFile(); + // sevenfm + SaveMineFlagFromMapToTempFile(); + // handle all reachable before save HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index f1097a60..b5c764ce 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -273,7 +273,7 @@ void RecountExplosions( void ) extern void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsDmg ); // GENERATE EXPLOSION -void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection ) +void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj ) { #ifdef JA2BETAVERSION if (is_networked) { @@ -377,13 +377,25 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 // Flugente: Items can have secondary explosions HandleBuddyExplosions(ubOwner, sX, sY, sZ, sGridNo, usItem, fLocate, bLevel, ubDirection ); + + // sevenfm: handle explosive items from attachments + if( gGameExternalOptions.bAllowExplosiveAttachments ) + HandleAttachedExplosions(ubOwner, sX, sY, sZ, sGridNo, usItem, fLocate, bLevel, ubDirection, pObj ); + + // sevenfm: add smoke effect if not in room and not underground, only for normal explosions + if(!InARoom( sGridNo, &tmp ) && !gbWorldSectorZ && gGameExternalOptions.bAddSmokeAfterExplosion) + { + if( Explosive[ Item[ usItem ].ubClassIndex ].ubType == 0 ) + { + NewSmokeEffect( sGridNo, SMALL_SMOKE, 0, NOBODY ); + } + } } - -void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubDirection ) +void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj ) { - InternalIgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, usItem, TRUE, bLevel, ubDirection ); + InternalIgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, usItem, TRUE, bLevel, ubDirection, pObj ); } void GenerateExplosion( EXPLOSION_PARAMS *pExpParams ) @@ -4043,7 +4055,7 @@ void HandleExplosionQueue( void ) // bomb objects only store the SIDE who placed the bomb! :-( if ( (*pObj)[0]->data.misc.ubBombOwner > 1 ) { - IgniteExplosion( (UINT8) ((*pObj)[0]->data.misc.ubBombOwner - 2), CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, (*pObj)[0]->data.misc.usBombItem, ubLevel, (*pObj)[0]->data.ubDirection ); + IgniteExplosion( (UINT8) ((*pObj)[0]->data.misc.ubBombOwner - 2), CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, (*pObj)[0]->data.misc.usBombItem, ubLevel, (*pObj)[0]->data.ubDirection, pObj); } else { @@ -4204,7 +4216,7 @@ void DecayBombTimers( void ) } // ignite explosions manually - this item is not in the WorldBombs-structure, so we can't add it to the queue - IgniteExplosion( gubPersonToSetOffExplosions, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pObj->usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection ); + IgniteExplosion( gubPersonToSetOffExplosions, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pObj->usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, pObj ); DeleteObj( pObj ); } @@ -4365,7 +4377,7 @@ void SetOffBombsByFrequency( UINT8 ubID, INT8 bFrequency ) gubPersonToSetOffExplosions = ubID; // ignite explosions manually - this item is not in the WorldBobms-structure, so we can't add it to the queue - IgniteExplosion( ubID, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pObj->usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection ); + IgniteExplosion( ubID, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pObj->usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, pObj ); DeleteObj( pObj ); } @@ -5426,3 +5438,55 @@ void HandleBuddyExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sG } } } + +// sevenfm: handle explosive items from attachments +void HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj) +{ + BOOLEAN binderFound = FALSE; + attachmentList::iterator iterend; + attachmentList::iterator iter; + UINT8 direction; + + if(pObj==NULL) + return; + + // check all attachments, search for ELASTIC or DUCT_TAPE; + iterend = (*pObj)[0]->attachments.end(); + for (iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter) + { + if ( iter->exists() && Item[iter->usItem].usItemClass == IC_MISC ) + { + if(Item[iter->usItem].uiIndex == ELASTIC || Item[iter->usItem].uiIndex == DUCT_TAPE ) + { + binderFound = TRUE; + break; + } + } + } + + if( !binderFound ) + return; + + // search for attached explosives + for (iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter) + { + if ( iter->exists() && Item[iter->usItem].usItemClass & (IC_GRENADE|IC_BOMB) ) + { + if(Item[iter->usItem].directional && ubDirection == DIRECTION_IRRELEVANT) + direction=Random(8); + else + direction=ubDirection; + if( Explosive[Item[iter->usItem].ubClassIndex].ubVolatility > 0 ) + IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, Item[iter->usItem].uiIndex, bLevel, direction , NULL ); + } + if ( gGameExternalOptions.bAllowSpecialExplosiveAttachments && iter->exists() && Item[iter->usItem].usItemClass & IC_MISC ) + { + if(Item[iter->usItem].gascan) + IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, GAS_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL ); + if(Item[iter->usItem].alcohol) + IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, MOLOTOV_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL ); + if(Item[iter->usItem].marbles) + IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, FRAG_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL ); + } + } +} diff --git a/TileEngine/Explosion Control.h b/TileEngine/Explosion Control.h index 9e37dc9b..d5fddec3 100644 --- a/TileEngine/Explosion Control.h +++ b/TileEngine/Explosion Control.h @@ -98,8 +98,8 @@ extern EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ]; extern UINT8 gubElementsOnExplosionQueue; extern BOOLEAN gfExplosionQueueActive; -void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubDirection = DIRECTION_IRRELEVANT ); -void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection = DIRECTION_IRRELEVANT ); +void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubDirection = DIRECTION_IRRELEVANT, OBJECTTYPE * pObj =NULL ); +void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection = DIRECTION_IRRELEVANT, OBJECTTYPE * pObj =NULL ); void GenerateExplosion( EXPLOSION_PARAMS *pExpParams ); @@ -163,4 +163,6 @@ extern void HandleSeeingFortifiedDoor( UINT32 sGridNo );//Ja25 UB // Flugente: handle secondary explosive effects void HandleBuddyExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection ); +// sevenfm: handle explosive items from attachments +void HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj ); #endif diff --git a/TileEngine/SaveLoadMap.cpp b/TileEngine/SaveLoadMap.cpp index ea8ded45..473fd553 100644 --- a/TileEngine/SaveLoadMap.cpp +++ b/TileEngine/SaveLoadMap.cpp @@ -40,6 +40,8 @@ void AddRemoveExitGridToUnloadedMapTempFile( UINT32 usGridNo, INT16 sSectorX, IN void RemoveSavedStructFromMap( INT32 uiMapIndex, UINT16 usIndex ); void AddObjectFromMapTempFileToMap( INT32 uiMapIndex, UINT16 usIndex ); void AddBloodOrSmellFromMapTempFileToMap( MODIFY_MAP *pMap ); +// sevenfm +void AddMineFlagFromMapTempFileToMap( MODIFY_MAP *pMap ); void SetSectorsRevealedBit( UINT32 usMapIndex ); void SetMapRevealedStatus(); void DamageStructsFromMapTempFile( MODIFY_MAP * pMap ); @@ -450,7 +452,10 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( ) case SLM_BLOOD_SMELL: AddBloodOrSmellFromMapTempFileToMap( pMap ); break; - +// sevenfm + case SLM_MINE_PRESENT: + AddMineFlagFromMapTempFileToMap( pMap ); + break; case SLM_DAMAGED_STRUCT: DamageStructsFromMapTempFile( pMap ); break; @@ -665,8 +670,23 @@ void RemoveSavedStructFromMap( INT32 uiMapIndex, UINT16 usIndex ) } +// sevenfm +void SaveMineFlagFromMapToTempFile() +{ + MODIFY_MAP Map; + INT32 cnt; - + for ( cnt = 0; cnt < WORLD_MAX; cnt++ ) + { + if( gpWorldLevelData[cnt].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT ) + { + memset( &Map, 0, sizeof( MODIFY_MAP ) ); + Map.usGridNo = cnt; + Map.ubType = SLM_MINE_PRESENT; + SaveModifiedMapStructToMapTempFile( &Map, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + } + } +} void SaveBloodSmellAndRevealedStatesFromMapToTempFile() { MODIFY_MAP Map; @@ -786,6 +806,11 @@ void AddBloodOrSmellFromMapTempFileToMap( MODIFY_MAP *pMap ) gpWorldLevelData[ pMap->usGridNo ].ubSmellInfo = (UINT8)pMap->usSubImageIndex; } +//sevenfm +void AddMineFlagFromMapTempFileToMap( MODIFY_MAP *pMap ) +{ + gpWorldLevelData[ pMap->usGridNo ].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT; +} BOOLEAN SaveRevealedStatusArrayToRevealedTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) diff --git a/TileEngine/SaveLoadMap.h b/TileEngine/SaveLoadMap.h index c8062b7e..05efca65 100644 --- a/TileEngine/SaveLoadMap.h +++ b/TileEngine/SaveLoadMap.h @@ -46,6 +46,8 @@ enum #ifdef JA2UB SLM_REMOVE_EXIT_GRID, #endif + // sevenfm + SLM_MINE_PRESENT, }; typedef struct @@ -88,6 +90,8 @@ void AddRemoveObjectToMapTempFile( INT32 uiMapIndex, UINT16 usIndex ); void SaveBloodSmellAndRevealedStatesFromMapToTempFile(); +// sevenfm +void SaveMineFlagFromMapToTempFile(); BOOLEAN SaveRevealedStatusArrayToRevealedTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp index 4f76a57e..532026da 100644 --- a/TileEngine/physics.cpp +++ b/TileEngine/physics.cpp @@ -2708,7 +2708,7 @@ void HandleArmedObjectImpact( REAL_OBJECT *pObject ) } */ - IgniteExplosion( pObject->ubOwner, (INT16)pObject->Position.x, (INT16)pObject->Position.y, sZ, pObject->sGridNo, pObject->Obj.usItem, GET_OBJECT_LEVEL( pObject->Position.z - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ pObject->sGridNo ].sHeight ) ) ); + IgniteExplosion( pObject->ubOwner, (INT16)pObject->Position.x, (INT16)pObject->Position.y, sZ, pObject->sGridNo, pObject->Obj.usItem, GET_OBJECT_LEVEL( pObject->Position.z - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ pObject->sGridNo ].sHeight ) ), DIRECTION_IRRELEVANT, &pObject->Obj ); } else if ( Item[ pObject->Obj.usItem ].usItemClass == IC_BOMB ) //if ( pObject->Obj.usItem == MORTAR_SHELL ) {