Explosive improvements and fixes (by Sevenfm)

- New mine disarm dialogue (only for realtime): Disarm, Inspect, Remove Blue Flag, Blow up.
- You can now attach tripwire-activated explosives to tripwire.
- attached explosives volatility is now used in chain explosion calculation: added new function CalcTotalVolatility.
- new function CheckForBuriedBombsAndRemoveFlags removes MAPELEMENT_XXX_MINE_PRESENT flags if there is no buried bomb at checked tile. This should fix problems with flag not removed correctly after chain explosions and such.
- trip klaxon no longer calls enemies if it's activated as attached explosive (instead it makes some noise).
- added check to MineSpottedDialogueCallBack. It should fix problem with game crash with tiles that have MAPELEMENT_PLAYER_MINE_PRESENT flag set but no buried mine
- disarmed item will keep it's attachments if ALLOW_ATTACHED_EXPLOSIVES is TRUE.
- IMPROVED_BOMB_PLANTING feature can be used to auto-take tripwire items from inventory.
- see: http://www.ja-galaxy-forum.com/board/ubbthreads.php/topics/172712/15/Code_Snippets.html


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6663 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2013-11-29 07:38:41 +00:00
parent 18af587c75
commit 2cba26ab07
17 changed files with 518 additions and 123 deletions
+159 -51
View File
@@ -110,6 +110,10 @@ void BoobyTrapDialogueCallBack( void );
void MineSpottedDialogueCallBack( void );
void MineSpottedLocatorCallback( void );
void RemoveBlueFlagDialogueCallBack( UINT8 ubExitValue );
INT32 CheckBombDisarmChance(void);
void ExtendedDisarmMessageBox(void);
void ExtendedBoobyTrapMessageBoxCallBack( UINT8 ubExitValue );
void HandleTakeNewBombFromIventory(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj);
void MineSpottedMessageBoxCallBack( UINT8 ubExitValue );
void CheckForPickedOwnership( void );
void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue );
@@ -1829,14 +1833,9 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
if (pSoldier->inv[ HANDPOS ].MoveThisObjectTo(gTempObject, 1) == 0) {
AddItemToPool( sGridNo, &gTempObject, BURIED, pSoldier->pathing.bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
// sevenfm: take another item with same id from inventory, only REALTIME
if(gGameExternalOptions.bImprovedBombPlanting &&
!( (gTacticalStatus.uiFlags & TURNBASED ) && (gTacticalStatus.uiFlags & INCOMBAT) ) &&
!pSoldier->inv[HANDPOS].exists() && _KeyDown( SHIFT ))
{
pSoldier->TakeNewBombFromIventory(gTempObject.usItem);
HandleTakeNewBombFromIventory(pSoldier, &gTempObject);
}
}
}
else
{
// EXPLOSIVES GAIN (10): Failed to place a bomb, or bury and arm a mine
@@ -2546,7 +2545,12 @@ void HandleSoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
ptr = wcscat(buffer, L"");
}
// DoMessageBox( MSG_BOX_BASIC_STYLE, ptr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack, NULL );
// sevenfm: added extended messagebox (inspect, remove blueflag, blow up). only for realtime
if( (gTacticalStatus.uiFlags & TURNBASED ) && (gTacticalStatus.uiFlags & INCOMBAT) )
DoMessageBox( MSG_BOX_BASIC_STYLE, ptr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack, NULL );
else
ExtendedDisarmMessageBox();
}
else
{
@@ -4775,6 +4779,13 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo )
//DBrot: More Rooms
UINT16 usRoom;
// sevenfm: cannot arm already armed bomb (for example, in inventory)
if( pSoldier->inv[HANDPOS].fFlags & OBJECT_ARMED_BOMB )
{
DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ ARM_MESSAGE_ALREADY_ARMED ] , GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
return;
}
gpTempSoldier = pSoldier;
gsTempGridNo = sGridNo;
if (Item[ pSoldier->inv[HANDPOS].usItem].remotetrigger )
@@ -4857,7 +4868,7 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo )
{
// sevenfm: do not allow arming bombs with only REMOTE_DET attached
// DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CHOOSE_REMOTE_DEFUSE_FREQUENCY_STR ], GAME_SCREEN, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, BombMessageBoxCallBack, NULL );
DoMessageBox( MSG_BOX_BASIC_STYLE, L"No detonator or remote detonator found!", GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ ARM_MESSAGE_NO_DETONATOR ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
}
}
else if ( HasAttachmentOfClass( &(pSoldier->inv[ HANDPOS ] ), (AC_DETONATOR ) ) )
@@ -5098,6 +5109,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
AddItemToPool( gsTempGridNo, &gTempObject, BURIED, gpTempSoldier->pathing.bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
// sevenfm: set flag only if planting tripwire
gpWorldLevelData[ gsTempGridNo ].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT;
HandleTakeNewBombFromIventory(gpTempSoldier, &gTempObject);
}
else
AddItemToPool( gsTempGridNo, &gTempObject, VISIBLE, gpTempSoldier->pathing.bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
@@ -5423,7 +5435,6 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
if (ubExitValue == MSG_BOX_RETURN_YES)
{
INT32 iCheckResult;
// get the item
gTempObject = gWorldItems[ gpBoobyTrapItemPool->iItemIndex ].object;
@@ -5440,41 +5451,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
return;
}
// NB owner grossness... bombs 'owned' by the enemy are stored with side value 1 in
// the map. So if we want to detect a bomb placed by the player, owner is > 1, and
// owner - 2 gives the ID of the character who planted it
if ( gTempObject[0]->data.misc.ubBombOwner > 1 && ( (INT32)gTempObject[0]->data.misc.ubBombOwner - 2 >= gTacticalStatus.Team[ OUR_TEAM ].bFirstID && gTempObject[0]->data.misc.ubBombOwner - 2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID ) )
{
// Flugente: get a tripwire-related bonus if we have a wire cutter in our hands
INT8 wirecutterbonus = 0;
if ( ( (&gpBoobyTrapSoldier->inv[HANDPOS])->exists() && Item[ gpBoobyTrapSoldier->inv[HANDPOS].usItem ].wirecutters == 1 ) || ( (&gpBoobyTrapSoldier->inv[SECONDHANDPOS])->exists() && Item[ gpBoobyTrapSoldier->inv[SECONDHANDPOS].usItem ].wirecutters == 1 ) )
{
// + 10 if item gets activated by tripwire
if ( Item[gTempObject.usItem].tripwireactivation == 1 )
wirecutterbonus += 10;
// + 10 if item is tripwire
if ( Item[gTempObject.usItem].tripwire == 1 )
wirecutterbonus += 10;
}
if ( gTempObject[0]->data.misc.ubBombOwner - 2 == gpBoobyTrapSoldier->ubID )
{
// my own boobytrap!
iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 40 + wirecutterbonus );
}
else
{
// our team's boobytrap!
iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 20 + wirecutterbonus );
}
}
else
{
iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 0 );
}
if (iCheckResult >= 0)
if ( CheckBombDisarmChance() >= 0)
{
if ( gTempObject[0]->data.misc.ubBombOwner > 1 && ( (INT32)gTempObject[0]->data.misc.ubBombOwner - 2 >= gTacticalStatus.Team[ OUR_TEAM ].bFirstID && gTempObject[0]->data.misc.ubBombOwner - 2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID ) )
@@ -5520,8 +5497,18 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
else
{
// switch action item to the real item type
// sevenfm: added check to only switch action items and not regular explosives
// this allows to keep all attachments
if( gTempObject.usItem == ACTION_ITEM || !gGameExternalOptions.bAllowExplosiveAttachments )
{
CreateItem( gTempObject[0]->data.misc.usBombItem, gTempObject[0]->data.misc.bBombStatus, &gTempObject );
}
else
{
gTempObject.fFlags &= ~(OBJECT_ARMED_BOMB);
gTempObject[0]->data.misc.bDetonatorType = 0;
}
if (is_networked && is_client)
{
OBJECTTYPE TempAttachment;
@@ -5842,8 +5829,8 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f
if (pMapElement->uiFlags & fCheckFlag)
{
// already know there's a mine there
// sevenfm
// if we try to step on known (planted by player) mine we should consider it wrong
// sevenfm
// if we try to step on known (planted by player) mine we should consider it wrong
if(!fCheckAroundGridNo)
{
*psProblemGridNo = sNextGridNo;
@@ -5859,7 +5846,9 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f
if (gWorldBombs[uiWorldBombIndex].fExists && gWorldItems[ gWorldBombs[uiWorldBombIndex].iItemIndex ].sGridNo == sNextGridNo)
{
pObj = &( gWorldItems[ gWorldBombs[uiWorldBombIndex].iItemIndex ].object );
if ( (*pObj)[0]->data.misc.bDetonatorType == BOMB_PRESSURE && !((*pObj).fFlags & OBJECT_KNOWN_TO_BE_TRAPPED) && (!((*pObj).fFlags & OBJECT_DISABLED_BOMB)) )
// sevenfm: removed OBJECT_KNOWN_TO_BE_TRAPPED check as we don't want to step on bomb even if it's known bomb
// if ( (*pObj)[0]->data.misc.bDetonatorType == BOMB_PRESSURE && !((*pObj).fFlags & OBJECT_KNOWN_TO_BE_TRAPPED) && (!((*pObj).fFlags & OBJECT_DISABLED_BOMB)) )
if ( (*pObj)[0]->data.misc.bDetonatorType == BOMB_PRESSURE && (!((*pObj).fFlags & OBJECT_DISABLED_BOMB)) )
{
// Flugente: some bombs cannot be found via metal detector
if ( fMining && (*pObj)[0]->data.bTrap <= 20 && !( HasItemFlag(pObj->usItem, NO_METAL_DETECTION) || HasItemFlag((*pObj)[0]->data.misc.usBombItem, NO_METAL_DETECTION) ) )
@@ -5877,6 +5866,10 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f
StatChange( pSoldier, EXPLODEAMT, (UINT16) ((*pObj)[0]->data.bTrap), FALSE );
StatChange( pSoldier, WISDOMAMT, (UINT16) ((*pObj)[0]->data.bTrap), FALSE );
// sevenfm: we should stop only if trying to step on bomb or if we found new bomb
if(fCheckAroundGridNo && ( (*pObj).fFlags & OBJECT_KNOWN_TO_BE_TRAPPED ) )
continue;
// set item as known
(*pObj).fFlags |= OBJECT_KNOWN_TO_BE_TRAPPED;
}
@@ -5944,17 +5937,28 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT32 sGridNo, BOOLEAN f
void MineSpottedDialogueCallBack( void )
{
ITEM_POOL * pItemPool;
BOOLEAN playerMine = FALSE;
// ATE: REALLY IMPORTANT - ALL CALLBACK ITEMS SHOULD UNLOCK
gTacticalStatus.fLockItemLocators = FALSE;
GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel );
// sevenfm: added check - if there is MAPELEMENT_PLAYER_MINE_PRESENT flag but there is no mine at tile
// this should prevent crash in rare situations
if( !GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel ) || pItemPool == NULL || FindWorldItemForBuriedBombInGridNo( gsBoobyTrapGridNo, gbBoobyTrapLevel ) == -1 )
{
// remove blue flag and MINE_PRESENT flags
RemoveBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
return;
}
if(gpWorldLevelData[ pItemPool->sGridNo ].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT)
playerMine = TRUE;
// WDS - Automatically flag mines
if (gGameExternalOptions.automaticallyFlagMines) {
// play a locator at the location of the mine
// sevenfm: only if it's not our mine
if (! gpWorldLevelData[ pItemPool->sGridNo ].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
if ( !playerMine )
SetItemPoolLocator( pItemPool );
AddBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
@@ -5962,8 +5966,8 @@ void MineSpottedDialogueCallBack( void )
guiPendingOverrideEvent = LU_BEGINUILOCK;
// play a locator at the location of the mine
// sevenfm: only if it's not our mine
if (gpWorldLevelData[ pItemPool->sGridNo ].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
// sevenfm: only if it's not our mine or we found new mine
if( playerMine || pItemPool->usFlags & OBJECT_KNOWN_TO_BE_TRAPPED )
MineSpottedLocatorCallback();
else
SetItemPoolLocatorWithCallback( pItemPool, MineSpottedLocatorCallback );
@@ -6838,3 +6842,107 @@ BOOLEAN RemoveFortification( INT32 sGridNo )
return FALSE;
}
INT32 CheckBombDisarmChance(void)
{
// NB owner grossness... bombs 'owned' by the enemy are stored with side value 1 in
// the map. So if we want to detect a bomb placed by the player, owner is > 1, and
// owner - 2 gives the ID of the character who planted it
if ( gTempObject[0]->data.misc.ubBombOwner > 1 && ( (INT32)gTempObject[0]->data.misc.ubBombOwner - 2 >= gTacticalStatus.Team[ OUR_TEAM ].bFirstID && gTempObject[0]->data.misc.ubBombOwner - 2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID ) )
{
// Flugente: get a tripwire-related bonus if we have a wire cutter in our hands
INT8 wirecutterbonus = 0;
if ( ( (&gpBoobyTrapSoldier->inv[HANDPOS])->exists() && Item[ gpBoobyTrapSoldier->inv[HANDPOS].usItem ].wirecutters == 1 ) || ( (&gpBoobyTrapSoldier->inv[SECONDHANDPOS])->exists() && Item[ gpBoobyTrapSoldier->inv[SECONDHANDPOS].usItem ].wirecutters == 1 ) )
{
// + 10 if item gets activated by tripwire
if ( Item[gTempObject.usItem].tripwireactivation == 1 )
wirecutterbonus += 10;
// + 10 if item is tripwire
if ( Item[gTempObject.usItem].tripwire == 1 )
wirecutterbonus += 10;
}
if ( gTempObject[0]->data.misc.ubBombOwner - 2 == gpBoobyTrapSoldier->ubID )
{
// my own boobytrap!
return SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 40 + wirecutterbonus );
}
else
{
// our team's boobytrap!
return SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 20 + wirecutterbonus );
}
}
else
{
return SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 0 );
}
}
void ExtendedDisarmMessageBox(void)
{
wcscpy( gzUserDefinedButton[0], TacticalStr[ DISARM_DIALOG_DISARM ] );
wcscpy( gzUserDefinedButton[1], TacticalStr[ DISARM_DIALOG_INSPECT ] );
wcscpy( gzUserDefinedButton[2], TacticalStr[ DISARM_DIALOG_REMOVE_BLUEFLAG ] );
wcscpy( gzUserDefinedButton[3], TacticalStr[ DISARM_DIALOG_BLOWUP ] );
DoMessageBox( MSG_BOX_BASIC_MEDIUM_BUTTONS, TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], guiCurrentScreen, MSG_BOX_FLAG_GENERIC_FOUR_BUTTONS, ExtendedBoobyTrapMessageBoxCallBack, NULL );
}
void ExtendedBoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
{
INT32 iCheckResult;
BOOLEAN playerMine = FALSE;
if(gpWorldLevelData[gsBoobyTrapGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT)
playerMine=TRUE;
if (ubExitValue == 1)
{
BoobyTrapMessageBoxCallBack(MSG_BOX_RETURN_YES);
}
else if (ubExitValue == 2)
{
iCheckResult=CheckBombDisarmChance();
if(iCheckResult>60)
ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, TacticalStr[ INSPECT_RESULT_SAFE ] );
else if(iCheckResult>20)
ScreenMsg( FONT_MCOLOR_LTGRAY, MSG_INTERFACE, TacticalStr[ INSPECT_RESULT_MOSTLY_SAFE ] );
else if(iCheckResult>-20)
ScreenMsg( FONT_MCOLOR_LTRED, MSG_INTERFACE, TacticalStr[ INSPECT_RESULT_RISKY ] );
else if(iCheckResult>-40)
ScreenMsg( FONT_MCOLOR_RED, MSG_INTERFACE, TacticalStr[ INSPECT_RESULT_DANGEROUS ] );
else
ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, TacticalStr[ INSPECT_RESULT_HIGH_DANGER ] );
}
else if (ubExitValue == 3)
{
RemoveBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
if(playerMine)
gpWorldLevelData[gsBoobyTrapGridNo].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT;
}
else if (ubExitValue == 4)
{
/* if(_KeyDown( SHIFT ) && gGameExternalOptions.bDontRevealTripwire )
gRevealTripwire = TRUE;
else
gRevealTripwire = FALSE; */
if (gfDisarmingBuriedBomb)
{
SetOffBombsInGridNo( gpBoobyTrapSoldier->ubID, gsBoobyTrapGridNo, TRUE, gbBoobyTrapLevel );
}
else
{
SetOffBoobyTrap( gpBoobyTrapItemPool );
}
}
}
void HandleTakeNewBombFromIventory(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj)
{
if(gGameExternalOptions.bImprovedBombPlanting &&
!( (gTacticalStatus.uiFlags & TURNBASED ) && (gTacticalStatus.uiFlags & INCOMBAT) ) &&
!pSoldier->inv[HANDPOS].exists() && _KeyDown( SHIFT ))
{
pSoldier->TakeNewBombFromIventory(pObj->usItem);
}
}
+13 -2
View File
@@ -8507,10 +8507,21 @@ INT8 CheckItemForDamage( UINT16 usItem, INT32 iMaxDamage )
return( bDamage );
}
BOOLEAN CheckForChainReaction( UINT16 usItem, INT16 bStatus, INT16 bDamage, BOOLEAN fOnGround )
//BOOLEAN CheckForChainReaction( UINT16 usItem, INT16 bStatus, INT16 bDamage, BOOLEAN fOnGround )
BOOLEAN CheckForChainReaction( OBJECTTYPE * pObj , INT16 bStatus, INT16 bDamage, BOOLEAN fOnGround )
{
INT32 iChance;
UINT16 usItem;
if(pObj == NULL)
return FALSE;
usItem = pObj->usItem;
// sevenfm: if ALLOW_EXPLOSIVE_ATTACHMENTS = TRUE calculate total average volatility of (item + explosive attachments)
if(gGameExternalOptions.bAllowExplosiveAttachments && pObj)
iChance = CalcTotalVolatility( pObj );
else
iChance = Explosive[Item[usItem].ubClassIndex].ubVolatility;
if (iChance > 0)
{
@@ -8591,7 +8602,7 @@ BOOLEAN DamageItem( OBJECTTYPE * pObject, INT32 iDamage, BOOLEAN fOnGround )
// FUN STUFF! Check for explosives going off as a result!
if (Item[pObject->usItem].usItemClass & IC_EXPLOSV)
{
if (CheckForChainReaction( pObject->usItem, (*pObject)[bLoop]->data.objectStatus, bDamage, fOnGround ))
if (CheckForChainReaction( pObject, (*pObject)[bLoop]->data.objectStatus, bDamage, fOnGround ))
{
return( TRUE );
}
-3
View File
@@ -16221,9 +16221,6 @@ void SOLDIERTYPE::TakeNewBombFromIventory(UINT16 item)
if(this->inv[HANDPOS].exists())
return;
if(Item[item].tripwire)
return;
// search for item with same id
for ( i = 0; i < invsize; i++)
+21
View File
@@ -284,6 +284,27 @@ INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel )
return( -1 );
}
INT32 FindWorldItemForBuriedBombInGridNo( INT32 sGridNo, INT8 bLevel )
{
UINT32 uiBombIndex;
OBJECTTYPE* pObj = NULL;
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
{
if (gWorldBombs[ uiBombIndex ].fExists &&
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].sGridNo == sGridNo &&
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].ubLevel == bLevel )
{
pObj=&gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].object;
if( pObj && pObj->exists() )
//if ( ( (*pObj)[0]->data.misc.bDetonatorType != BOMB_TIMED ) && ( (*pObj)[0]->data.misc.bDetonatorType != BOMB_REMOTE ) )
if( !HasAttachmentOfClass( pObj, AC_REMOTEDET | AC_DETONATOR ) )
return( gWorldBombs[ uiBombIndex ].iItemIndex );
}
}
return( -1 );
}
// Flugente: is there a planted tripwire at this gridno? fKnown = TRUE: only return true if we know of that one already
INT32 FindWorldItemForTripwireInGridNo( INT32 sGridNo, INT8 bLevel, BOOLEAN fKnown )
{
+1
View File
@@ -129,6 +129,7 @@ extern UINT32 guiNumWorldBombs;
extern INT32 AddBombToWorld( INT32 iItemIndex );
extern void FindPanicBombsAndTriggers( void );
extern INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel);
extern INT32 FindWorldItemForBuriedBombInGridNo( INT32 sGridNo, INT8 bLevel);
// Flugente: is there a planted tripwire at this gridno? fKnown = TRUE: only return true if we know of that one already
extern INT32 FindWorldItemForTripwireInGridNo( INT32 sGridNo, INT8 bLevel, BOOLEAN fKnown = TRUE );
+150 -65
View File
@@ -2371,6 +2371,8 @@ BOOLEAN ExpAffect( INT32 sBombGridNo, INT32 sGridNo, UINT32 uiDist, UINT16 usIte
{
// item was destroyed
RemoveItemFromPool( sGridNo, pItemPool->iItemIndex, bLevel );
// sevenfm: if no other bomb exists here
CheckForBuriedBombsAndRemoveFlags( sGridNo, bLevel );
}
pItemPool = pItemPoolNext;
}
@@ -3897,6 +3899,7 @@ void HandleExplosionQueue( void )
INT32 sGridNo;
OBJECTTYPE * pObj;
UINT8 ubLevel;
BOOLEAN fAttFound = FALSE;
if ( !gfExplosionQueueActive )
{
@@ -3929,8 +3932,11 @@ void HandleExplosionQueue( void )
//RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, 0 );
}
else if ( (*pObj)[0]->data.misc.usBombItem == TRIP_FLARE )
{
NewLightEffect( sGridNo, (UINT8)Explosive[pObj->usItem].ubDuration, (UINT8)Explosive[pObj->usItem].ubStartRadius );
{
// sevenfm: changed pObj->usItem to Item[pObj->usItem].ubClassIndex as it should be correct explosives index
// NewLightEffect( sGridNo, (UINT8)Explosive[pObj->usItem].ubDuration, (UINT8)Explosive[pObj->usItem].ubStartRadius );
NewLightEffect( sGridNo, (UINT8)Explosive[ Item[pObj->usItem].ubClassIndex ].ubDuration, (UINT8)Explosive[ Item[pObj->usItem].ubClassIndex ].ubStartRadius );
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
}
// Flugente: handle tripwire gun traps here...
@@ -3966,21 +3972,21 @@ void HandleExplosionQueue( void )
// fire with this gun, if possible. Afterwards place it on the floor
OBJECTTYPE object(*pAttGun);
CheckAndFireTripwireGun( &object, sGridNo, ubLevel, (*pObj)[0]->data.misc.ubBombOwner, (*pObj)[0]->data.ubDirection );
} else {
// sevenfm: blow attached items with tripwireactivation = TRUE
// no preplaced (owner=NOBODY) tripwire with explosive attachments allowed
if ( gGameExternalOptions.bAllowExplosiveAttachments && (*pObj)[0]->data.misc.ubBombOwner > 1 )
{
fAttFound=HandleAttachedExplosions( (UINT8) ((*pObj)[0]->data.misc.ubBombOwner - 2), CenterX( sGridNo ), CenterY( sGridNo ), 0,
sGridNo, (*pObj)[0]->data.misc.usBombItem, FALSE, ubLevel, (*pObj)[0]->data.ubDirection, pObj);
}
}
// this is important: delete the tripwire, otherwise we get into an infinite loop if there are two piecs of tripwire....
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
// if no other bomb exists here
if ( FindWorldItemForBombInGridNo(sGridNo, ubLevel) == -1 )
{
// make sure no one thinks there is a bomb here any more!
if ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
{
RemoveBlueFlag( sGridNo, ubLevel );
}
gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_ENEMY_MINE_PRESENT);
}
CheckForBuriedBombsAndRemoveFlags( sGridNo, ubLevel );
// delete the flag, otherwise wire will only work once
(newtripwireObject)[0]->data.sObjectFlag &= ~TRIPWIRE_ACTIVATED;
@@ -4000,15 +4006,7 @@ void HandleExplosionQueue( void )
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
// if no other bomb exists here
if ( FindWorldItemForBombInGridNo(sGridNo, ubLevel) == -1 )
{
// make sure no one thinks there is a bomb here any more!
if ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
{
RemoveBlueFlag( sGridNo, ubLevel );
}
gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_ENEMY_MINE_PRESENT);
}
CheckForBuriedBombsAndRemoveFlags( sGridNo, ubLevel );
// delete the flag, otherwise wire will only work once
(newtripwireObject)[0]->data.sObjectFlag &= ~TRIPWIRE_ACTIVATED;
@@ -4044,12 +4042,7 @@ void HandleExplosionQueue( void )
RemoveItemFromPool( sGridNo, gWorldBombs[ uiWorldBombIndex ].iItemIndex, ubLevel );
// make sure no one thinks there is a bomb here any more!
if ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
{
RemoveBlueFlag( sGridNo, ubLevel );
}
gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_ENEMY_MINE_PRESENT);
CheckForBuriedBombsAndRemoveFlags( sGridNo, ubLevel);
// BOOM!
// bomb objects only store the SIDE who placed the bomb! :-(
@@ -4063,6 +4056,11 @@ void HandleExplosionQueue( void )
IgniteExplosion( NOBODY, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, (*pObj)[0]->data.misc.usBombItem, ubLevel, (*pObj)[0]->data.ubDirection );
}
}
/* if ( FindWorldItemForBuriedBombInGridNo(sGridNo, ubLevel) != -1 )
{
gpWorldLevelData[sGridNo].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT;
gpWorldLevelData[sGridNo].uiFlags |= MAPELEMENT_ENEMY_MINE_PRESENT;
}*/
// Bye bye bomb
gExplosionQueue[ uiIndex ].fExists = FALSE;
@@ -5440,15 +5438,131 @@ 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 HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj)
{
BOOLEAN binderFound = FALSE;
BOOLEAN binderFound = FALSE;
BOOLEAN detonator = FALSE;
BOOLEAN fAttFound = FALSE;
attachmentList::iterator iterend;
attachmentList::iterator iter;
UINT8 direction;
if(pObj==NULL)
return;
return FALSE;
binderFound = FindBinderAttachment ( pObj );
detonator = CheckExplosiveTypeAsDetonator( Explosive[ Item[ usItem ].ubClassIndex ].ubType );
// search for attached explosives
iterend = (*pObj)[0]->attachments.end();
for (iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( iter->exists() && Item[iter->usItem].usItemClass & (IC_GRENADE|IC_BOMB) )
{
// no need for binder if both item and attachment are tripwire-activated
if( ( Item[pObj->usItem].tripwireactivation && Item[iter->usItem].tripwireactivation ) ||
( binderFound && detonator && Explosive[Item[iter->usItem].ubClassIndex].ubVolatility > 0 ) )
{
if(Item[iter->usItem].directional && ubDirection == DIRECTION_IRRELEVANT)
direction=Random(8);
else
direction=ubDirection;
if( Item[iter->usItem].uiIndex == TRIP_KLAXON )
{
PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) );
// CallAvailableEnemiesTo( sGridNo );
MakeNoise( NOBODY, sGridNo, bLevel, gpWorldLevelData[ sGridNo ].ubTerrainID, (UINT8)Explosive[ Item[iter->usItem].ubClassIndex ].ubVolume, NOISE_EXPLOSION );
} else if( Item[iter->usItem].uiIndex == TRIP_FLARE )
{
NewLightEffect( sGridNo, (UINT8)Explosive[ Item[iter->usItem].ubClassIndex ].ubDuration, (UINT8)Explosive[iter->usItem].ubStartRadius );
} else
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, Item[iter->usItem].uiIndex, bLevel, direction , NULL );
}
fAttFound = TRUE;
}
}
if ( binderFound && detonator && 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 );
fAttFound = TRUE;
}
if(Item[iter->usItem].alcohol)
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, MOLOTOV_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL );
fAttFound = TRUE;
}
if(Item[iter->usItem].marbles)
{
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, FRAG_EXPLOSION, bLevel, DIRECTION_IRRELEVANT , NULL );
fAttFound = TRUE;
}
}
}
return fAttFound;
}
void CheckForBuriedBombsAndRemoveFlags( INT32 sGridNo, INT8 bLevel )
{
if ( FindWorldItemForBuriedBombInGridNo(sGridNo, bLevel) == -1 )
{
// make sure no one thinks there is a bomb here any more!
if ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT )
{
RemoveBlueFlag( sGridNo, bLevel );
}
gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_ENEMY_MINE_PRESENT);
}
}
// sevenfm: calculate total average volatility of item+attachments
UINT16 CalcTotalVolatility(OBJECTTYPE * pObj)
{
BOOLEAN binderFound = FALSE;
BOOLEAN detonator = FALSE;
attachmentList::iterator iterend;
attachmentList::iterator iter;
UINT16 totalVolatility;
UINT8 num;
UINT16 usItem;
UINT16 classIndex;
if(pObj==NULL)
return 0;
usItem = pObj->usItem;
classIndex = Item[ usItem ].ubClassIndex;
totalVolatility = Explosive[ classIndex ].ubVolatility;
num = 1;
binderFound = FindBinderAttachment ( pObj );
detonator = CheckExplosiveTypeAsDetonator( Explosive[ classIndex ].ubType );
// search for attached explosives
iterend = (*pObj)[0]->attachments.end();
for (iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( iter->exists() && Item[iter->usItem].usItemClass & (IC_GRENADE|IC_BOMB) )
{
// no need for binder if both item and attachment are tripwire-activated
if( ( Item[usItem].tripwireactivation && Item[iter->usItem].tripwireactivation ) ||
( binderFound && detonator && Explosive[Item[iter->usItem].ubClassIndex].ubVolatility > 0 ) )
{
totalVolatility += Explosive[Item[iter->usItem].ubClassIndex].ubVolatility;
num++;
}
}
}
return totalVolatility / num;
}
BOOLEAN FindBinderAttachment (OBJECTTYPE * pObj)
{
attachmentList::iterator iterend;
attachmentList::iterator iter;
// check all attachments, search for ELASTIC or DUCT_TAPE;
iterend = (*pObj)[0]->attachments.end();
@@ -5458,44 +5572,15 @@ void HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32
{
if(Item[iter->usItem].uiIndex == ELASTIC || Item[iter->usItem].uiIndex == DUCT_TAPE )
{
binderFound = TRUE;
break;
return TRUE;
}
}
}
return FALSE;
}
// search for attached explosives
for (iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( iter->exists() && Item[iter->usItem].usItemClass & (IC_GRENADE|IC_BOMB) )
{
// no need for binder if both item and attachment are tripwire-activated
if( ( Item[pObj->usItem].tripwireactivation && Item[iter->usItem].tripwireactivation ) ||
( binderFound && Explosive[Item[iter->usItem].ubClassIndex].ubVolatility > 0 ) )
{
if(Item[iter->usItem].directional && ubDirection == DIRECTION_IRRELEVANT)
direction=Random(8);
else
direction=ubDirection;
if( Item[iter->usItem].uiIndex == TRIP_KLAXON )
{
PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) );
CallAvailableEnemiesTo( sGridNo );
} else if( Item[iter->usItem].uiIndex == TRIP_FLARE )
{
NewLightEffect( sGridNo, (UINT8)Explosive[iter->usItem].ubDuration, (UINT8)Explosive[iter->usItem].ubStartRadius );
} else
IgniteExplosion( ubOwner, sX, sY, sZ, sGridNo, Item[iter->usItem].uiIndex, bLevel, direction , NULL );
}
}
if ( binderFound && 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 );
}
}
BOOLEAN CheckExplosiveTypeAsDetonator(UINT16 ubType)
{
// attached explosives are allowed only for EXPLOSV_NORMAL, EXPLOSV_STUN and EXPLOSV_FLASHBANG types
return ( ubType == EXPLOSV_NORMAL || ubType == EXPLOSV_STUN || ubType == EXPLOSV_FLASHBANG );
}
+5 -1
View File
@@ -164,5 +164,9 @@ extern void HandleSeeingFortifiedDoor( UINT32 sGridNo );//Ja25 UB
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 );
BOOLEAN HandleAttachedExplosions(UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel, UINT8 ubDirection, OBJECTTYPE * pObj );
void CheckForBuriedBombsAndRemoveFlags( INT32 sGridNo, INT8 bLevel );
UINT16 CalcTotalVolatility(OBJECTTYPE * pObj);
BOOLEAN FindBinderAttachment (OBJECTTYPE * pObj);
BOOLEAN CheckExplosiveTypeAsDetonator(UINT16 ubType);
#endif
+17 -1
View File
@@ -1012,8 +1012,24 @@ enum
PRISONER_DEMAND_SURRENDER_STR,
PRISONER_OFFER_SURRENDER_STR,
PRISONER_TALK_STR,
// sevenfm: new disarm trap dialog, new messages for wrong mines when arming
DISARM_DIALOG_DISARM,
DISARM_DIALOG_INSPECT,
DISARM_DIALOG_REMOVE_BLUEFLAG,
DISARM_DIALOG_BLOWUP,
DISARM_DIALOG_ACTIVATE_TRIPWIRE,
DISARM_DIALOG_DEACTIVATE_TRIPWIRE,
DISARM_DIALOG_REVEAL_TRIPWIRE,
ARM_MESSAGE_NO_DETONATOR,
ARM_MESSAGE_ALREADY_ARMED,
INSPECT_RESULT_SAFE,
INSPECT_RESULT_MOSTLY_SAFE,
INSPECT_RESULT_RISKY,
INSPECT_RESULT_DANGEROUS,
INSPECT_RESULT_HIGH_DANGER,
TEXT_NUM_TACTICAL_STR
TEXT_NUM_TACTICAL_STR,
};
enum{
+17
View File
@@ -3191,6 +3191,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"劝说敌人投降",
L"劝降", //L"Offer surrender",
L"交谈",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3188,6 +3188,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Demand surrender",
L"Offer surrender",
L"Talk",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+16
View File
@@ -3191,6 +3191,22 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Demand surrender",
L"Offer surrender",
L"Talk",
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3195,6 +3195,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Parler",
L"Inspection milice",//TODO.Translate
L"Rien",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3191,6 +3191,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Kapitulation fordern",
L"Kapitulation anbieten",
L"Sprechen",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3182,6 +3182,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Demand surrender",
L"Offer surrender",
L"Talk",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3198,6 +3198,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Demand surrender",
L"Offer surrender",
L"Talk",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3189,6 +3189,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Требовать сдаться",
L"Предлоить сдаться",
L"Переговоры",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
+17
View File
@@ -3193,6 +3193,23 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
L"Demand surrender",
L"Offer surrender",
L"Talk",
// TODO.Translate
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
L"Disarm trap",
L"Inspect trap",
L"Remove blue flag",
L"Blow up!",
L"Activate tripwire",
L"Deactivate tripwire",
L"Reveal tripwire",
L"No detonator or remote detonator found!",
L"This bomb is already armed!",
L"Safe",
L"Mostly safe",
L"Risky",
L"Dangerous",
L"High danger!",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.