New feature: radio operator trait allows calling in artillery, requesting reinforcements, scanning for enemies and a few other skills.

Also includes mechansim for easy implementation of new skills.

For more info see http://www.bears-pit.com/board/ubbthreads.php/topics/327348.html#Post327348

Requires GameDir >= r1848.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6547 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2013-10-30 23:05:37 +00:00
parent bef4e7b52b
commit f17829fac9
80 changed files with 4722 additions and 243 deletions
+50
View File
@@ -374,6 +374,9 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32
// HEADROCK HAM 5: Deactivated until the release of HAM 5.1.
FireFragments( MercPtrs[ubOwner], sX, sY, sZ, usItem, ubDirection );
}
// Flugente: Items can have secondary explosions
HandleBuddyExplosions(ubOwner, sX, sY, sZ, sGridNo, usItem, fLocate, bLevel, ubDirection );
}
@@ -2225,6 +2228,13 @@ BOOLEAN ExpAffect( INT32 sBombGridNo, INT32 sGridNo, UINT32 uiDist, UINT16 usIte
bSmokeEffectType = CREATURE_SMOKE_EFFECT;
fBlastEffect = FALSE;
break;
case EXPLOSV_SIGNAL_SMOKE:
fSmokeEffect = TRUE;
bSmokeEffectType = SIGNAL_SMOKE_EFFECT;
fBlastEffect = FALSE;
break;
}
}
@@ -2872,6 +2882,7 @@ void SpreadEffect( INT32 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner,
case EXPLOSV_TEARGAS:
case EXPLOSV_SMOKE:
case EXPLOSV_CREATUREGAS:
case EXPLOSV_SIGNAL_SMOKE:
fSmokeEffect = TRUE;
break;
@@ -3993,6 +4004,25 @@ void HandleExplosionQueue( void )
// now add a tripwire item to the floor, simulating that activating tripwire deactivates it
AddItemToPool( sGridNo, &newtripwireObject, 1, ubLevel, 0, -1 );
}
else if ( (*pObj)[0]->data.ubWireNetworkFlag & ANY_ARTILLERY_FLAG )
{
UINT8 cnt = 0;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_1 ) cnt += 1;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_2 ) cnt += 2;
if ( (*pObj)[0]->data.ubWireNetworkFlag & ARTILLERY_STRIKE_COUNT_4 ) cnt += 4;
// determine gridno to attack - smoke signal required. Otherwise, it is assumed the radio operator ordered the bombing of his OWN position
// if we cannot even find a radio operator, all bets are off - target a random gridno
INT32 sTargetGridNo = -1;
if ( GetRandomSignalSmokeGridNo(&sTargetGridNo) || GetRadioOperatorSignal((*pObj)[0]->data.misc.ubBombOwner, &sTargetGridNo) || (sTargetGridNo = RandomGridNo()) )
{
for ( UINT8 i = 0; i < cnt; ++i)
ArtilleryStrike(pObj->usItem, sGridNo, sTargetGridNo);
}
// not needed anymore
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
}
else
{
gfExplosionQueueMayHaveChangedSight = TRUE;
@@ -5376,3 +5406,23 @@ void HandleSeeingPowerGenFan( UINT32 sGridNo )
}
}
#endif
void HandleBuddyExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection )
{
// Flugente: Items can have secondary explosions
if ( Item[usItem].usBuddyItem )
{
if ( Item[Item[usItem].usBuddyItem].flare )
{
if( !sZ || !FindBuilding(sGridNo) )
{
// Add a light effect...
NewLightEffect( sGridNo, (UINT8)Explosive[Item[Item[usItem].usBuddyItem].ubClassIndex].ubDuration , (UINT8)Explosive[Item[Item[usItem].usBuddyItem].ubClassIndex].ubStartRadius );
}
}
else if ( Item[Item[usItem].usBuddyItem ].usItemClass & (IC_GRENADE|IC_BOMB) )
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, Item[usItem].usBuddyItem, bLevel, ubDirection );
}
}
}
+4
View File
@@ -159,4 +159,8 @@ extern void HandleSwitchToOpenFortifiedDoor( UINT32 sGridNo );
extern void HandleSeeingPowerGenFan( UINT32 sGridNo );
extern void HandleSeeingFortifiedDoor( UINT32 sGridNo );//Ja25 UB
#endif
// 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 );
#endif
+156 -91
View File
@@ -126,6 +126,10 @@ INT8 FromWorldFlagsToSmokeType( UINT16 ubWorldFlags )
{
return( BURNABLEGAS_SMOKE_EFFECT );
}
else if ( ubWorldFlags & MAPELEMENT_EXT_SIGNAL_SMOKE )
{
return( SIGNAL_SMOKE_EFFECT );
}
else
{
return( NO_SMOKE_EFFECT );
@@ -157,10 +161,15 @@ UINT16 FromSmokeTypeToWorldFlags( INT8 bType )
return( MAPELEMENT_EXT_BURNABLEGAS );
break;
case CREATURE_SMOKE_EFFECT:
case CREATURE_SMOKE_EFFECT:
return( MAPELEMENT_EXT_CREATUREGAS );
break;
return( MAPELEMENT_EXT_CREATUREGAS );
break;
case SIGNAL_SMOKE_EFFECT:
return( MAPELEMENT_EXT_SIGNAL_SMOKE );
break;
default:
@@ -250,7 +259,8 @@ INT32 NewSmokeEffect( INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner,
//ubStartRadius = 1;
//break;
case EXPLOSV_CREATUREGAS:
case EXPLOSV_CREATUREGAS:
bSmokeEffectType = CREATURE_SMOKE_EFFECT;
break;
@@ -259,11 +269,14 @@ INT32 NewSmokeEffect( INT32 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner,
//bSmokeEffectType = CREATURE_SMOKE_EFFECT;
//ubDuration = 2;
//ubStartRadius = 0;
break;
//break;
case EXPLOSV_SIGNAL_SMOKE:
bSmokeEffectType = SIGNAL_SMOKE_EFFECT;
break;
}
pSmoke->ubDuration = (UINT8)Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
pSmoke->ubRadius = (UINT8)Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
pSmoke->bAge = 0;
@@ -372,99 +385,117 @@ void AddSmokeEffectToTile( INT32 iSmokeEffectID, INT8 bType, INT32 sGridNo, INT8
{
case NORMAL_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" );
}
}
break;
case TEARGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" );
}
}
break;
case MUSTARDGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" );
}
}
break;
case BURNABLEGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMCHZE.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalflam.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMETH2.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMCHZE.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalflam.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\FLAMETH2.STI" );
}
}
break;
case CREATURE_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
}
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
}
break;
case SIGNAL_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\signal_gas.STI" );
}
}
break;
}
// Create tile...
@@ -944,18 +975,52 @@ void UpdateSmokeEffectGraphics( )
//if the smoke is active
if( gSmokeEffectData[ uiCnt ].fAllocated )
{
if ( gSmokeEffectData[uiCnt].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
if ( gSmokeEffectData[uiCnt].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, ERASE_SPREAD_EFFECT, bLevel, uiCnt );
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, TRUE, bLevel, uiCnt );
}
}
}
}
BOOL GetRandomSignalSmokeGridNo(INT32* psGridNo)
{
UINT32 uiCnt;
//SMOKEEFFECT *pSmoke;
//INT8 bLevel;
INT32 smokearray[50];
for (UINT8 i = 0; i < 50; ++i)
smokearray[i] = -1;
UINT8 cnt = 0;
//loop through and save the number of smoke effects
for( uiCnt=0; uiCnt < guiNumSmokeEffects; uiCnt++)
{
if ( gSmokeEffectData[ uiCnt ].fAllocated && gSmokeEffectData[ uiCnt ].bType == SIGNAL_SMOKE_EFFECT )
{
smokearray[cnt++] = uiCnt;
if ( cnt >= 50 )
break;
}
}
if ( !cnt )
return FALSE;
UINT8 target = Random(cnt);
(*psGridNo) = gSmokeEffectData[ smokearray[target] ].sGridNo;
return TRUE;
}
+3
View File
@@ -11,6 +11,7 @@ enum
MUSTARDGAS_SMOKE_EFFECT,
CREATURE_SMOKE_EFFECT,
BURNABLEGAS_SMOKE_EFFECT,
SIGNAL_SMOKE_EFFECT, // added by Flugente for artillery
};
#define SMOKE_EFFECT_INDOORS 0x01
@@ -68,5 +69,7 @@ void ResetSmokeEffects();
void UpdateSmokeEffectGraphics( );
// Flugente: get the gridno and blevel of a random smoke signal, if one exists
BOOL GetRandomSignalSmokeGridNo(INT32* psGridNo);
#endif
+1 -1
View File
@@ -573,7 +573,7 @@ void UpdateAniTiles( )
// if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
// ubExpType == EXPLOSV_SMOKE )
if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
ubExpType == EXPLOSV_SMOKE || ubExpType == EXPLOSV_BURNABLEGAS )
ubExpType == EXPLOSV_SMOKE || ubExpType == EXPLOSV_BURNABLEGAS || ubExpType == EXPLOSV_SIGNAL_SMOKE )
{
// Do sound....
// PlayJA2Sample( AIR_ESCAPING_1, RATE_11025, SoundVolume( HIGHVOLUME, pNode->sGridNo ), 1, SoundDir( pNode->sGridNo ) );
+30 -15
View File
@@ -1307,13 +1307,24 @@ void RenderOverheadOverlays()
{ //loop through all soldiers.
end = MAX_NUM_SOLDIERS;
}
if(is_networked)end = MAX_NUM_SOLDIERS;
if(is_networked)
end = MAX_NUM_SOLDIERS;
SGPRect HostileArea = {0,0,0,0};
// Flugente: is one of the player's mercs scanning for jam signals while someone is actually jamming signals?
BOOLEAN showjammers = FALSE;
if ( PlayerTeamIsScanning() && SectorJammed() )
showjammers = TRUE;
UINT16 jamcolour = Get16BPPColor( FROMRGB( 36, 219, 151 ) );
BOOLEAN marklastenemy = FALSE;
if ( gGameSettings.fOptions[TOPTION_SHOW_LAST_ENEMY] && gGameExternalOptions.ubMarkerMode && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector <= gGameExternalOptions.ubSoldiersLeft )
marklastenemy = TRUE;
for( i = 0; i < end; i++ )
for( i = 0; i < end; ++i )
{
//First, check to see if the soldier exists and is in the sector.
pSoldier = MercPtrs[ i ];
@@ -1325,14 +1336,16 @@ void RenderOverheadOverlays()
continue;
//DBrot: mark his general area as hostile
if(!gfEditMode && gGameSettings.fOptions[TOPTION_SHOW_LAST_ENEMY] /*&& gfUseBiggerOverview */&& gGameExternalOptions.ubMarkerMode && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector <= gGameExternalOptions.ubSoldiersLeft){
if(pSoldier->bTeam == ENEMY_TEAM){
// Flugente: also do that if the we scanned a jamming person
if(!gfEditMode && (showjammers || marklastenemy ) )
{
if ( ( marklastenemy && pSoldier->bTeam == ENEMY_TEAM ) || ( showjammers && pSoldier->IsJamming() ) )
{
UINT8 ubGridSquareX, ubGridSquareY;
ubGridSquareX = sX / (gusGridFrameX / gubGridDivisor); //( pSoldier->sGridNo / WORLD_COLS ) / ( WORLD_COLS / ubResolutionTable[gGameExternalOptions.ubGridResolution]);
ubGridSquareY = sY / (gusGridFrameY / gubGridDivisor); //( pSoldier->sGridNo - ( ( pSoldier->sGridNo / WORLD_COLS ) * WORLD_COLS ) ) / ( WORLD_COLS / ubResolutionTable[gGameExternalOptions.ubGridResolution]);
HostileArea.iLeft = iOffsetHorizontal + (((gusGridFrameX / gubGridDivisor) * ubGridSquareX));
HostileArea.iTop = iOffsetVertical + (((gusGridFrameY / gubGridDivisor) * ubGridSquareY));
HostileArea.iRight = iOffsetHorizontal + (((gusGridFrameX / gubGridDivisor) * (ubGridSquareX + 1)));
@@ -1340,9 +1353,14 @@ void RenderOverheadOverlays()
if(gGameExternalOptions.ubMarkerMode == SHARPBORDER)
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, 255, pDestBuf);
if(gGameExternalOptions.ubMarkerMode == HATCHED){
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, 0xF000, pDestBuf);
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &HostileArea, 0xF000 );
if(gGameExternalOptions.ubMarkerMode == HATCHED)
{
UINT16 colour = 0xF000;
if ( showjammers && pSoldier->IsJamming() )
colour = jamcolour;
RectangleDraw(TRUE, HostileArea.iLeft, HostileArea.iTop, HostileArea.iRight, HostileArea.iBottom, colour, pDestBuf);
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &HostileArea, colour );
}
}
}
@@ -1352,10 +1370,7 @@ void RenderOverheadOverlays()
sX += 2;
sY -= 5;
//sScreenY -= 7; //height of doll
if( !gfTacticalPlacementGUIActive && pSoldier->bLastRenderVisibleValue == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
{
+35
View File
@@ -2867,3 +2867,38 @@ INT32 RandomGridFromRadius( INT32 sSweetGridNo, INT8 ubMinRadius, INT8 ubMaxRadi
return( sGridNo );
}
UINT32 GetArtilleryTargetGridNo( UINT32 sTargetGridNo, INT8 bRadius )
{
return RandomGridFromRadius( sTargetGridNo, 1, bRadius );
}
BOOLEAN GetArtilleryLaunchParams( UINT32 sStartingGridNo, UINT32 sTargetGridNo, INT16 sStartZ, INT16 sEndZ, UINT16 usLauncher, OBJECTTYPE* pObj, FLOAT* pdForce, FLOAT* pdDegrees)
{
FLOAT dMagForce, dMaxForce, dMinForce;
FLOAT dDegrees = OUTDOORS_START_ANGLE;
INT16 sMinRange = MIN_MORTAR_RANGE;
sStartZ = 256;
// Find force for basic
INT32 sFinalGridNo = 0;
FindBestForceForTrajectory( sStartingGridNo, sTargetGridNo, sStartZ, sEndZ, dDegrees, pObj, &sFinalGridNo, &dMagForce );
INT32 uiMaxRange = GetModifiedGunRange(usLauncher) / CELL_X_SIZE;
dMaxForce = CalculateForceFromRange( NULL, (INT16) uiMaxRange, (FLOAT)( PI/4 ) );
if ( dMagForce > dMaxForce )
dMagForce = dMaxForce;
dMinForce = CalculateForceFromRange( NULL, (INT16)( sMinRange / 10 ), (FLOAT)( PI / 4 ) );
if ( dMagForce < dMinForce )
dMagForce = dMinForce;
(*pdForce) = dMagForce;
(*pdDegrees) = dDegrees;
return TRUE;
}
+5
View File
@@ -181,5 +181,10 @@ BOOLEAN SavePhysicsTableToSaveGameFile( HWFILE hFile );
BOOLEAN LoadPhysicsTableFromSavedGameFile( HWFILE hFile );
// Flugente: artillery functions
INT32 RandomGridFromRadius( INT32 sSweetGridNo, INT8 ubMinRadius, INT8 ubMaxRadius );
UINT32 GetArtilleryTargetGridNo( UINT32 sTargetGridNo, INT8 bRadius );
BOOLEAN GetArtilleryLaunchParams( UINT32 sStartingGridNo, UINT32 sTargetGridNo, INT16 sStartZ, INT16 sEndZ, UINT16 usLauncher, OBJECTTYPE* pObj, FLOAT* pdForce, FLOAT* pdDegrees);
#endif
+2 -1
View File
@@ -134,12 +134,13 @@ class SOLDIERTYPE;
#define MAPELEMENT_EXT_CREATUREGAS 0x0080 //0x80
#define MAPELEMENT_EXT_BURNABLEGAS 0x0100 //0x100
#define MAPELEMENT_EXT_CLIMBPOINT 0x0200 //0x200
#define MAPELEMENT_EXT_SIGNAL_SMOKE 0x0400 //0x400 // added by Flugente
#define FIRST_LEVEL 0
#define SECOND_LEVEL 1
//#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS )
#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS )
#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS | MAPELEMENT_EXT_SIGNAL_SMOKE )
// WDS - Clean up inventory handling