- main flashbang code added

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@462 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Lesh
2006-08-23 15:28:55 +00:00
parent eef9f7309d
commit 944df34a9e
7 changed files with 283 additions and 52 deletions
+3
View File
@@ -172,6 +172,9 @@ enum
#define FIRE_WEAPON_SLEEP_DART_SPECIAL 6 #define FIRE_WEAPON_SLEEP_DART_SPECIAL 6
#define FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL 7 #define FIRE_WEAPON_BLINDED_BY_SPIT_SPECIAL 7
#define FIRE_WEAPON_TOSSED_OBJECT_SPECIAL 8 #define FIRE_WEAPON_TOSSED_OBJECT_SPECIAL 8
#define FIRE_WEAPON_BLINDED 9
#define FIRE_WEAPON_DEAFENED 10
#define FIRE_WEAPON_BLINDED_AND_DEAFENED 11
#define NO_INTERRUPTS 0 #define NO_INTERRUPTS 0
+131 -2
View File
@@ -3549,11 +3549,48 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa
ubReason = TAKE_DAMAGE_HANDTOHAND; ubReason = TAKE_DAMAGE_HANDTOHAND;
} }
// marke added one 'or' for explosive ammo. variation of: AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].explosionSize > 1 // marke added one 'or' for explosive ammo. variation of: AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].explosionSize > 1
// marke need another attacker id assignment
// MercPtrs[ubAttackerID]->bLastAttackHit = TRUE;
// extracting attacker´s ammo type // extracting attacker´s ammo type
else if ( Item[ usWeaponIndex ].usItemClass & IC_EXPLOSV || AmmoTypes[MercPtrs[ubAttackerID]->inv[MercPtrs[ubAttackerID]->ubAttackingHand ].ubGunAmmoType].explosionSize > 1) else if ( Item[ usWeaponIndex ].usItemClass & IC_EXPLOSV || AmmoTypes[MercPtrs[ubAttackerID]->inv[MercPtrs[ubAttackerID]->ubAttackingHand ].ubGunAmmoType].explosionSize > 1)
{ {
INT8 bDeafValue;
bDeafValue = Explosive[ Item[ usWeaponIndex ].ubClassIndex ].ubVolume / 10;
if ( bDeafValue == 0 )
bDeafValue = 1;
// Lesh: flashbang does damage
switch ( ubSpecial )
{
case FIRE_WEAPON_BLINDED_AND_DEAFENED:
pSoldier->bDeafenedCounter = bDeafValue;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Soldier is blinded and deafened" );
// if soldier in building OR underground
if ( InBuilding(sLocationGrid) || (gbWorldSectorZ) )
{
// deal max special damage
pSoldier->bBlindedCounter = (INT8)Explosive[ Item[ usWeaponIndex ].ubClassIndex ].ubDuration;
}
else if ( NightTime() ) // if soldier outside at night
{
// halve effect
pSoldier->bBlindedCounter = (INT8)Explosive[ Item[ usWeaponIndex ].ubClassIndex ].ubDuration / 2;
if ( pSoldier->bBlindedCounter == 0 )
pSoldier->bBlindedCounter = 1;
pSoldier->bDeafenedCounter /= 2;
}
DecayIndividualOpplist( pSoldier );
break;
case FIRE_WEAPON_BLINDED:
break;
case FIRE_WEAPON_DEAFENED:
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Soldier is deafened" );
pSoldier->bDeafenedCounter = bDeafValue;
break;
};
if ( usWeaponIndex == STRUCTURE_EXPLOSION ) if ( usWeaponIndex == STRUCTURE_EXPLOSION )
{ {
ubReason = TAKE_DAMAGE_STRUCTURE_EXPLOSION; ubReason = TAKE_DAMAGE_STRUCTURE_EXPLOSION;
@@ -4110,12 +4147,98 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16
return; return;
} }
// Lesh: possible soldier behavior when affected by flashbang
// Soldier can:
// 1. stand as if there was no explosion at all
// 2. crouch. represent that soldier didn't expect such blow and instinctively
// made defensive movement to protect his body
// 3. fall forward. again, he didn't expect that something will explode behind
// him and deafens him
// 4. fall backward. unexpected blast, fear, clumsy moves and soldier flies backward.
// Based on stance, select generic hit animation // Based on stance, select generic hit animation
switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
{ {
case ANIM_STAND: case ANIM_STAND:
if ( ubSpecial == FIRE_WEAPON_DEAFENED )
{
switch( Random(10) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
// 6 of 10 - crouch
ChangeSoldierStance( pSoldier, ANIM_CROUCH );
break;
case 6:
case 7:
case 8:
// 3 of 10 - fall forward
BeginTyingToFall( pSoldier );
EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE );
break;
case 9:
// 1 of 10 - still standing
DoGenericHit( pSoldier, 0, bDirection );
break;
};
break;
}
else if ( ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED )
{
switch( Random(10) )
{
case 0:
case 1:
case 2:
case 3:
case 4:
// 5 of 10 - crouch
ChangeSoldierStance( pSoldier, ANIM_CROUCH );
break;
case 5:
case 6:
case 7:
case 8:
// 4 of 10 - fall backward (if possible) either forward
// Check behind us!
sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( gOppositeDirection[ bDirection ] ) );
if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, gOppositeDirection[ bDirection ], FLYBACK_HIT ) )
{
EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection );
EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection );
ChangeToFallbackAnimation( pSoldier, (INT8)bDirection );
}
else
{
BeginTyingToFall( pSoldier );
EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE );
}
break;
case 9:
// 1 of 10 - still standing
DoGenericHit( pSoldier, 0, bDirection );
break;
};
break;
}
else if ( ubSpecial == FIRE_WEAPON_BLINDED )
{
}
case ANIM_CROUCH: case ANIM_CROUCH:
if ( ubSpecial == FIRE_WEAPON_BLINDED ||
ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED ||
ubSpecial == FIRE_WEAPON_DEAFENED )
{
DoGenericHit( pSoldier, 0, bDirection );
break;
}
EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection );
EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection );
@@ -4920,6 +5043,12 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR
} }
} }
if ( pSoldier->bDeafenedCounter > 0 )
{
pSoldier->bDeafenedCounter--;
}
// ATE: To get around a problem... // ATE: To get around a problem...
// If an AI guy, and we have 0 life, and are still at higher hieght, // If an AI guy, and we have 0 life, and are still at higher hieght,
// Kill them..... // Kill them.....
+1 -1
View File
@@ -927,7 +927,7 @@ typedef struct
BOOLEAN fRTInNonintAnim; BOOLEAN fRTInNonintAnim;
BOOLEAN fDoingExternalDeath; BOOLEAN fDoingExternalDeath;
INT8 bCorpseQuoteTolerance; INT8 bCorpseQuoteTolerance;
INT8 bYetAnotherPaddingSpace; INT8 bDeafenedCounter;
INT32 iPositionSndID; INT32 iPositionSndID;
INT32 iTuringSoundID; INT32 iTuringSoundID;
UINT8 ubLastDamageReason; UINT8 ubLastDamageReason;
+1
View File
@@ -181,6 +181,7 @@ enum
EXPLOSV_SMOKE, EXPLOSV_SMOKE,
EXPLOSV_CREATUREGAS, EXPLOSV_CREATUREGAS,
EXPLOSV_BURNABLEGAS, EXPLOSV_BURNABLEGAS,
EXPLOSV_FLASHBANG,
}; };
#define AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( x ) (x / 4) #define AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( x ) (x / 4)
+6
View File
@@ -5459,6 +5459,12 @@ UINT8 CalcEffVolume(SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bLevel, UINT8 ubN
{ {
INT32 iEffVolume, iDistance; INT32 iEffVolume, iDistance;
// Lesh: deafness
if ( pSoldier->bDeafenedCounter > 0 )
{
return( 0 );
}
if ( FindWalkman(pSoldier) != ITEM_NOT_FOUND ) if ( FindWalkman(pSoldier) != ITEM_NOT_FOUND )
{ {
return( 0 ); return( 0 );
+134 -44
View File
@@ -65,6 +65,9 @@
// Spreads the effects of explosions... // Spreads the effects of explosions...
BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usItem, UINT8 ubOwner, INT16 sSubsequent, BOOLEAN *pfMercHit, INT8 bLevel, INT32 iSmokeEffectID ); BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usItem, UINT8 ubOwner, INT16 sSubsequent, BOOLEAN *pfMercHit, INT8 bLevel, INT32 iSmokeEffectID );
// Flashbang effect on soldier
UINT8 DetermineFlashbangEffect( SOLDIERTYPE *pSoldier, INT8 ubExplosionDir, BOOLEAN fInBuilding);
extern INT8 gbSAMGraphicList[ NUMBER_OF_SAMS ]; extern INT8 gbSAMGraphicList[ NUMBER_OF_SAMS ];
extern void AddToShouldBecomeHostileOrSayQuoteList( UINT8 ubID ); extern void AddToShouldBecomeHostileOrSayQuoteList( UINT8 ubID );
extern void RecompileLocalMovementCostsForWall( INT16 sGridNo, UINT8 ubOrientation ); extern void RecompileLocalMovementCostsForWall( INT16 sGridNo, UINT8 ubOrientation );
@@ -386,17 +389,17 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion )
// Setup explosion! // Setup explosion!
memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) ); memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );
AniParams.sGridNo = sGridNo; AniParams.sGridNo = sGridNo;
AniParams.ubLevelID = ANI_TOPMOST_LEVEL; AniParams.ubLevelID = ANI_TOPMOST_LEVEL;
AniParams.sDelay = gExpAniData[ ubTypeID ].sBlastSpeed; // Lesh: edit this line AniParams.sDelay = gExpAniData[ ubTypeID ].sBlastSpeed; // Lesh: edit this line
AniParams.sStartFrame = pExplosion->sCurrentFrame; AniParams.sStartFrame = pExplosion->sCurrentFrame;
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_EXPLOSION; AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_EXPLOSION;
if ( ubTerrainType == LOW_WATER || ubTerrainType == MED_WATER || ubTerrainType == DEEP_WATER ) if ( ubTerrainType == LOW_WATER || ubTerrainType == MED_WATER || ubTerrainType == DEEP_WATER )
{ {
// Change type to water explosion... // Change type to water explosion...
ubTypeID = WATER_BLAST; ubTypeID = WATER_BLAST;
AniParams.uiFlags |= ANITILE_ALWAYS_TRANSLUCENT; AniParams.uiFlags |= ANITILE_ALWAYS_TRANSLUCENT;
} }
@@ -415,35 +418,40 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion )
} }
AniParams.ubKeyFrame1 = gExpAniData[ ubTypeID ].ubTransKeyFrame; // Lesh: edit this line AniParams.ubKeyFrame1 = gExpAniData[ ubTypeID ].ubTransKeyFrame; // Lesh: edit this line
AniParams.uiKeyFrame1Code = ANI_KEYFRAME_BEGIN_TRANSLUCENCY; AniParams.uiKeyFrame1Code = ANI_KEYFRAME_BEGIN_TRANSLUCENCY;
if ( !( uiFlags & EXPLOSION_FLAG_DISPLAYONLY ) ) if ( !( uiFlags & EXPLOSION_FLAG_DISPLAYONLY ) )
{ {
AniParams.ubKeyFrame2 = gExpAniData[ ubTypeID ].ubDamageKeyFrame; // Lesh: edit this line AniParams.ubKeyFrame2 = gExpAniData[ ubTypeID ].ubDamageKeyFrame; // Lesh: edit this line
AniParams.uiKeyFrame2Code = ANI_KEYFRAME_BEGIN_DAMAGE; AniParams.uiKeyFrame2Code = ANI_KEYFRAME_BEGIN_DAMAGE;
} }
AniParams.uiUserData = usItem; AniParams.uiUserData = usItem;
AniParams.ubUserData2 = ubOwner; AniParams.ubUserData2 = ubOwner;
AniParams.uiUserData3 = pExplosion->iID; AniParams.uiUserData3 = pExplosion->iID;
strcpy( AniParams.zCachedFile, gExpAniData[ ubTypeID ].zBlastFilename ); // Lesh: edit this line strcpy( AniParams.zCachedFile, gExpAniData[ ubTypeID ].zBlastFilename ); // Lesh: edit this line
CreateAnimationTile( &AniParams ); CreateAnimationTile( &AniParams );
// set light source.... // set light source for flashbangs.... or...
if ( pExplosion->iLightID == -1 ) if ( pExplosion->Params.ubTypeID == FLASHBANG_EXP )
{ {
pExplosion->iLightID = LightSpriteCreate("FLSHBANG.LHT", 0 );
}
else
// generic light
// DO ONLY IF WE'RE AT A GOOD LEVEL // DO ONLY IF WE'RE AT A GOOD LEVEL
if ( ubAmbientLightLevel >= MIN_AMB_LEVEL_FOR_MERC_LIGHTS ) if ( ubAmbientLightLevel >= MIN_AMB_LEVEL_FOR_MERC_LIGHTS )
{ {
if( ( pExplosion->iLightID = LightSpriteCreate("L-R04.LHT", 0 ) ) != (-1) ) pExplosion->iLightID = LightSpriteCreate("L-R04.LHT", 0 );
{
LightSpritePower( pExplosion->iLightID, TRUE );
LightSpritePosition( pExplosion->iLightID, (INT16)(sX/CELL_X_SIZE), (INT16)(sY/CELL_Y_SIZE) );
}
} }
if( pExplosion->iLightID != -1 )
{
LightSpritePower ( pExplosion->iLightID, TRUE );
LightSpriteRoofStatus( pExplosion->iLightID, pExplosion->Params.bLevel );
LightSpritePosition ( pExplosion->iLightID, (INT16)(sX/CELL_X_SIZE), (INT16)(sY/CELL_Y_SIZE) );
} }
// Lesh: sound randomization // Lesh: sound randomization
@@ -468,6 +476,18 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion )
void UpdateExplosionFrame( INT32 iIndex, INT16 sCurrentFrame ) void UpdateExplosionFrame( INT32 iIndex, INT16 sCurrentFrame )
{ {
gExplosionData[ iIndex ].sCurrentFrame = sCurrentFrame; gExplosionData[ iIndex ].sCurrentFrame = sCurrentFrame;
// Lesh: make sparkling effect
if ( gExplosionData[iIndex].Params.ubTypeID == FLASHBANG_EXP )
{
if ( gExplosionData[iIndex].iLightID != -1 )
{
INT16 iX, iY;
iX = gExplosionData[iIndex].Params.sX/CELL_X_SIZE + Random(3) - 1;
iY = gExplosionData[iIndex].Params.sY/CELL_Y_SIZE + Random(3) - 1;
LightSpritePosition( gExplosionData[iIndex].iLightID, iX, iY);
}
}
} }
void RemoveExplosionData( INT32 iIndex ) void RemoveExplosionData( INT32 iIndex )
@@ -1172,39 +1192,63 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe
STRUCTURE *gStruct; STRUCTURE *gStruct;
// Lesh: somewhere here once I got CTD when militia stepped on mine in cambria sam
void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLEAN *pfRecompileMovementCosts, BOOLEAN fOnlyWalls, INT8 bMultiStructSpecialFlag, BOOLEAN fSubSequentMultiTilesTransitionDamage, UINT8 ubOwner, INT8 bLevel ) void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLEAN *pfRecompileMovementCosts, BOOLEAN fOnlyWalls, INT8 bMultiStructSpecialFlag, BOOLEAN fSubSequentMultiTilesTransitionDamage, UINT8 ubOwner, INT8 bLevel )
{ {
STRUCTURE * pCurrent, *pNextCurrent, *pStructure; STRUCTURE * pCurrent, *pNextCurrent, *pStructure;
STRUCTURE * pBaseStructure; STRUCTURE * pBaseStructure;
INT16 sDesiredLevel; INT16 sDesiredLevel;
DB_STRUCTURE_TILE **ppTile; DB_STRUCTURE_TILE **ppTile;
UINT8 ubLoop, ubLoop2; UINT8 ubLoop, ubLoop2;
INT16 sNewGridNo, sNewGridNo2, sBaseGridNo; INT16 sNewGridNo, sNewGridNo2, sBaseGridNo;
BOOLEAN fToBreak = FALSE; BOOLEAN fToBreak = FALSE;
BOOLEAN fMultiStructure = FALSE; BOOLEAN fMultiStructure = FALSE;
UINT8 ubNumberOfTiles; UINT8 ubNumberOfTiles;
BOOLEAN fMultiStructSpecialFlag = FALSE; BOOLEAN fMultiStructSpecialFlag = FALSE;
BOOLEAN fExplodeDamageReturn = FALSE; BOOLEAN fExplodeDamageReturn = FALSE;
FILE *pDebug;
pDebug = fopen("explosion.log", "wt");
fprintf(pDebug, "ExplosiveDamageGridNo start\n");
fclose(pDebug);
// Based on distance away, damage any struct at this gridno // Based on distance away, damage any struct at this gridno
// OK, loop through structures and damage! // OK, loop through structures and damage!
pCurrent = gpWorldLevelData[ sGridNo ].pStructureHead; pCurrent = gpWorldLevelData[ sGridNo ].pStructureHead;
sDesiredLevel = STRUCTURE_ON_GROUND; sDesiredLevel = STRUCTURE_ON_GROUND;
pDebug = fopen("explosion.log", "a+t");
fprintf(pDebug, "sGridNo = %d\n", sGridNo);
fprintf(pDebug, "pCurrent = %08X\n", pCurrent);
fclose(pDebug);
// This code gets a little hairy because // This code gets a little hairy because
// (1) we might need to destroy the currently-examined structure // (1) we might need to destroy the currently-examined structure
while (pCurrent != NULL) while (pCurrent != NULL)
{ {
// ATE: These are for the chacks below for multi-structs.... // ATE: These are for the chacks below for multi-structs....
pBaseStructure = FindBaseStructure( pCurrent ); pBaseStructure = FindBaseStructure( pCurrent );
pDebug = fopen("explosion.log", "a+t");
fprintf(pDebug, "pBaseStructure = %08X\n", pBaseStructure);
fclose(pDebug);
if ( pBaseStructure ) if ( pBaseStructure )
{ {
sBaseGridNo = pBaseStructure->sGridNo; sBaseGridNo = pBaseStructure->sGridNo;
ubNumberOfTiles = pBaseStructure->pDBStructureRef->pDBStructure->ubNumberOfTiles; ubNumberOfTiles = pBaseStructure->pDBStructureRef->pDBStructure->ubNumberOfTiles;
fMultiStructure = ( ( pBaseStructure->fFlags & STRUCTURE_MULTI ) != 0 ); fMultiStructure = ( ( pBaseStructure->fFlags & STRUCTURE_MULTI ) != 0 );
ppTile = (DB_STRUCTURE_TILE **) MemAlloc( sizeof( DB_STRUCTURE_TILE ) * ubNumberOfTiles ); ppTile = (DB_STRUCTURE_TILE **) MemAlloc( sizeof( DB_STRUCTURE_TILE ) * ubNumberOfTiles );
memcpy( ppTile, pBaseStructure->pDBStructureRef->ppTile, sizeof( DB_STRUCTURE_TILE ) * ubNumberOfTiles );
pDebug = fopen("explosion.log", "a+t");
fprintf(pDebug, "sBaseGridNo = %d\n", sBaseGridNo);
fprintf(pDebug, "ubNumberOfTiles = %d\n", ubNumberOfTiles);
fprintf(pDebug, "fMultiStructure = %d\n", fMultiStructure);
fprintf(pDebug, "ppTile = %08X\n", ppTile);
fprintf(pDebug, "pBaseStructure->pDBStructureRef->ppTile = %08X\n", pBaseStructure->pDBStructureRef->ppTile);
fclose(pDebug);
// Lesh: CTD was in next line once
memcpy( ppTile, pBaseStructure->pDBStructureRef->ppTile, sizeof( DB_STRUCTURE_TILE ) * ubNumberOfTiles );
if ( bMultiStructSpecialFlag == -1 ) if ( bMultiStructSpecialFlag == -1 )
{ {
@@ -1257,10 +1301,10 @@ void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLE
// ATE: Don't after first attack... // ATE: Don't after first attack...
if ( uiDist > 1 ) if ( uiDist > 1 )
{ {
if ( pBaseStructure ) if ( pBaseStructure )
{ {
MemFree( ppTile ); MemFree( ppTile );
} }
return; return;
} }
@@ -1312,12 +1356,16 @@ void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLE
if ( pBaseStructure ) if ( pBaseStructure )
{ {
MemFree( ppTile ); MemFree( ppTile );
} }
pCurrent = pNextCurrent; pCurrent = pNextCurrent;
} }
pDebug = fopen("explosion.log", "a+t");
fprintf(pDebug, "ExplosiveDamageGridNo finish\n");
fclose(pDebug);
} }
@@ -1325,7 +1373,11 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT16 sBombGridNo
{ {
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
INT16 sNewWoundAmt = 0; INT16 sNewWoundAmt = 0;
UINT8 ubDirection; UINT8 ubDirection;
UINT8 ubSpecial = 0;
BOOLEAN fInBuilding = InBuilding(sBombGridNo);
BOOLEAN fFlashbang = Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLASHBANG;
UINT16 usHalfExplosionRadius;
pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt
@@ -1338,6 +1390,15 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT16 sBombGridNo
return( FALSE ); return( FALSE );
} }
// Lesh: if flashbang
// check if soldier is outdoor and situated farther that half explosion radius and not underground
usHalfExplosionRadius = Explosive[Item[usItem].ubClassIndex].ubRadius / 2;
if ( fFlashbang && !gbWorldSectorZ && !fInBuilding && (UINT16)uiDist > usHalfExplosionRadius )
{
// then no effect
return( FALSE );
}
// Direction to center of explosion // Direction to center of explosion
ubDirection = (UINT8)GetDirectionFromGridNo( sBombGridNo, pSoldier ); ubDirection = (UINT8)GetDirectionFromGridNo( sBombGridNo, pSoldier );
@@ -1350,7 +1411,14 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT16 sBombGridNo
{ {
sNewWoundAmt = 0; sNewWoundAmt = 0;
} }
EVENT_SoldierGotHit( pSoldier, usItem, sNewWoundAmt, sBreathAmt, ubDirection, (INT16)uiDist, ubOwner, 0, ANIM_CROUCH, sSubsequent, sBombGridNo );
// Lesh: flashbang does affect on soldier or not - check it
if ( (Item[usItem].usItemClass & IC_EXPLOSV) && fFlashbang )
{
ubSpecial = DetermineFlashbangEffect( pSoldier, ubDirection, fInBuilding);
}
EVENT_SoldierGotHit( pSoldier, usItem, sNewWoundAmt, sBreathAmt, ubDirection, (INT16)uiDist, ubOwner, ubSpecial, ANIM_CROUCH, sSubsequent, sBombGridNo );
pSoldier->ubMiscSoldierFlags |= SOLDIER_MISC_HURT_BY_EXPLOSION; pSoldier->ubMiscSoldierFlags |= SOLDIER_MISC_HURT_BY_EXPLOSION;
@@ -1531,12 +1599,12 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte
EXPLOSIVETYPE *pExplosive; EXPLOSIVETYPE *pExplosive;
INT16 sX, sY; INT16 sX, sY;
BOOLEAN fRecompileMovementCosts = FALSE; BOOLEAN fRecompileMovementCosts = FALSE;
BOOLEAN fSmokeEffect=FALSE; BOOLEAN fSmokeEffect = FALSE;
BOOLEAN fStunEffect = FALSE; BOOLEAN fStunEffect = FALSE;
INT8 bSmokeEffectType = 0;
BOOLEAN fBlastEffect = TRUE; BOOLEAN fBlastEffect = TRUE;
INT16 sNewGridNo;
BOOLEAN fBloodEffect = FALSE; BOOLEAN fBloodEffect = FALSE;
INT8 bSmokeEffectType = 0;
INT16 sNewGridNo;
ITEM_POOL * pItemPool, * pItemPoolNext; ITEM_POOL * pItemPool, * pItemPoolNext;
UINT32 uiRoll; UINT32 uiRoll;
@@ -3604,3 +3672,25 @@ void RemoveAllActiveTimedBombs( void )
} while( iItemIndex != -1 ); } while( iItemIndex != -1 );
} }
UINT8 DetermineFlashbangEffect( SOLDIERTYPE *pSoldier, INT8 ubExplosionDir, BOOLEAN fInBuilding)
{
INT8 bNumTurns;
UINT16 usHeadItem1, usHeadItem2;
bNumTurns = FindNumTurnsBetweenDirs(pSoldier->bDirection, ubExplosionDir);
usHeadItem1 = pSoldier->inv[ HEAD1POS ].usItem;
usHeadItem2 = pSoldier->inv[ HEAD2POS ].usItem;
// if soldier got in explosion area check if he is affected by flash
// if soldier wears sun goggles OR grenade behind him OR
// (he is not underground AND it is day AND he is outdoor)
if ( (usHeadItem1 == SUNGOGGLES || usHeadItem2 == SUNGOGGLES) || (bNumTurns > 1) ||
(!gbWorldSectorZ && !NightTime() && !fInBuilding) )
{
// soldier didn't see flash or wears protective sungogles or outdoor at day, so he is only deafened
return ( FIRE_WEAPON_DEAFENED );
}
return ( FIRE_WEAPON_BLINDED_AND_DEAFENED );
}
+7 -5
View File
@@ -16,7 +16,7 @@ typedef struct
UINT32 uiFlags; UINT32 uiFlags;
UINT8 ubOwner; UINT8 ubOwner;
UINT8 ubTypeID; INT8 ubTypeID;
UINT16 usItem; UINT16 usItem;
@@ -52,10 +52,12 @@ enum EXPLOSION_TYPES
BLAST_3, BLAST_3,
STUN_BLAST, STUN_BLAST,
WATER_BLAST, WATER_BLAST,
TARGAS_EXP, TARGAS_EXP,
SMOKE_EXP, SMOKE_EXP,
MUSTARD_EXP, MUSTARD_EXP,
BURN_EXP, BURN_EXP,
THERMOBARIC_EXP,
FLASHBANG_EXP, // Lesh: enum added
NUM_EXP_TYPES=50 NUM_EXP_TYPES=50
} ; } ;
@@ -91,8 +93,8 @@ typedef struct
#define NUM_EXPLOSION_SLOTS 100 #define NUM_EXPLOSION_SLOTS 100
extern EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ];
extern EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ];
extern UINT8 gubElementsOnExplosionQueue; extern UINT8 gubElementsOnExplosionQueue;
extern BOOLEAN gfExplosionQueueActive; extern BOOLEAN gfExplosionQueueActive;