New feature: SAM site cover can now overlap, and SAM sites can be hacked to lower their radius. For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=23211&goto=347188&#msg_347188

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8309 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2016-10-05 22:22:50 +00:00
parent 8523a1dead
commit 258e9c24a0
27 changed files with 554 additions and 319 deletions
+2 -1
View File
@@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16];
// Keeps track of the saved game version. Increment the saved game version whenever
// you will invalidate the saved game file
#define HACKABLE_SAMS 172 // Flugente: SAM sites now have a status for hacking
#define LUA_MODDERDATA 171 // Flugente: modders can set and use data in an exclusive array
#define WORKERS 170 // Flugente: train workers for facilities
#define WEATHER_CHANGE 169 // Flugente: sector-specific weather & more weather types
@@ -90,7 +91,7 @@ extern CHAR16 zTrackingNumber[16];
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
#define SAVE_GAME_VERSION LUA_MODDERDATA
#define SAVE_GAME_VERSION HACKABLE_SAMS
//#define RUSSIANGOLD
#ifdef __cplusplus
+70 -65
View File
@@ -59,8 +59,6 @@ extern INT32 giReinforcementPool;
extern BOOLEAN gfTacticalDoHeliRun;
extern UINT8 ubSAMControlledSectors[MAP_WORLD_Y][MAP_WORLD_X];
// Arulco special division decision code
// ASD savegame variables
@@ -1007,69 +1005,75 @@ void EnemyHeliSAMCheck( INT16 id )
INT8 heli_y = SECTORY( heli.sector_current );
// is the airspace in our current sector player-controlled and operational?
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( heli_x, heli_y )].usAirType == AIRSPACE_PLAYER_ACTIVE )
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( heli_x, heli_y )].usAirType & AIRSPACE_PLAYER_ACTIVE )
{
UINT8 ubControllingSAM = ubSAMControlledSectors[heli_y][heli_x];
StrategicMapElement *pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ubControllingSAM - 1] )]);
if ( pSAMStrategicMap )
for ( int i = 0; i < NUMBER_OF_SAMS; ++i )
{
UINT16 ubBestSAMOperatorID = NOBODY;
FLOAT samcth = GetBestSAMOperatorCTH_Player( gpSamSectorX[ubControllingSAM - 1], gpSamSectorY[ubControllingSAM - 1], 0, &ubBestSAMOperatorID );
// cth is reduced if SAM is damaged, even if it can still operate
samcth = (samcth * pSAMStrategicMap->bSAMCondition) / 100.0f;
// determine distance from SAM to heli
FLOAT distance = sqrt(FLOAT(abs( heli_x - gpSamSectorX[ubControllingSAM - 1] ) * abs( heli_x - gpSamSectorX[ubControllingSAM - 1] ) + abs( heli_y - gpSamSectorY[ubControllingSAM - 1] ) * abs( heli_y - gpSamSectorY[ubControllingSAM - 1] ) ));
// distance penalty
samcth = (samcth * (100.0f - 8 * distance)) / 100.0f;
// if cth is too low, we don't fire
if ( samcth > 0.01 )
BOOLEAN samworking = FALSE;
if ( DoesSamCoverSector( i, heli.sector_current, &samworking ) && samworking )
{
CHAR16 pStrSectorName[128];
GetSectorIDString( heli_x, heli_y, 0, pStrSectorName, FALSE );
StrategicMapElement *pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[i] )]);
CHAR16 pStrSectorName_SAM[128];
GetSectorIDString( gpSamSectorX[ubControllingSAM - 1], gpSamSectorY[ubControllingSAM - 1], 0, pStrSectorName_SAM, FALSE );
MapScreenMessage( FONT_MCOLOR_LTRED, MSG_INTERFACE, szEnemyHeliText[8], pStrSectorName_SAM, pStrSectorName );
// if we hit, damage the heli
BOOLEAN fHit = FALSE;
BOOLEAN fDestroyed = FALSE;
if ( Chance( (UINT32)(samcth) ) )
// also check whether this sector is not enemy-controlled - we can't have the AI shooting at its own helis
if ( pSAMStrategicMap && !pSAMStrategicMap->fEnemyControlled )
{
fHit = TRUE;
UINT16 ubBestSAMOperatorID = NOBODY;
FLOAT samcth = GetBestSAMOperatorCTH_Player( gpSamSectorX[i], gpSamSectorY[i], 0, &ubBestSAMOperatorID );
UINT8 damage = gGameExternalOptions.gEnemyHeliSAMDamage_Base + Random( gGameExternalOptions.gEnemyHeliSAMDamage_Var );
// cth is reduced if SAM is damaged, even if it can still operate
samcth = (samcth * pSAMStrategicMap->bSAMCondition) / 100.0f;
MapScreenMessage( FONT_MCOLOR_LTRED, MSG_INTERFACE, szEnemyHeliText[6], pStrSectorName );
// determine distance from SAM to heli
FLOAT distance = sqrt( FLOAT( abs( heli_x - gpSamSectorX[i] ) * abs( heli_x - gpSamSectorX[i] ) + abs( heli_y - gpSamSectorY[i] ) * abs( heli_y - gpSamSectorY[i] ) ) );
heli.hp = max( 0, heli.hp - damage );
// distance penalty
samcth = (samcth * (100.0f - 8 * distance)) / 100.0f;
if ( !heli.hp )
// if cth is too low, we don't fire
if ( samcth > 0.01 )
{
fDestroyed = TRUE;
CHAR16 pStrSectorName[128];
GetSectorIDString( heli_x, heli_y, 0, pStrSectorName, FALSE );
heli.flagmask |= ENEMYHELI_SHOTDOWN;
CHAR16 pStrSectorName_SAM[128];
GetSectorIDString( gpSamSectorX[i], gpSamSectorY[i], 0, pStrSectorName_SAM, FALSE );
heli.Destroy( );
MapScreenMessage( FONT_MCOLOR_LTRED, MSG_INTERFACE, szEnemyHeliText[8], pStrSectorName_SAM, pStrSectorName );
// if we hit, damage the heli
BOOLEAN fHit = FALSE;
BOOLEAN fDestroyed = FALSE;
if ( Chance( (UINT32)(samcth) ) )
{
fHit = TRUE;
UINT8 damage = gGameExternalOptions.gEnemyHeliSAMDamage_Base + Random( gGameExternalOptions.gEnemyHeliSAMDamage_Var );
MapScreenMessage( FONT_MCOLOR_LTRED, MSG_INTERFACE, szEnemyHeliText[6], pStrSectorName );
heli.hp = max( 0, heli.hp - damage );
if ( !heli.hp )
{
fDestroyed = TRUE;
heli.flagmask |= ENEMYHELI_SHOTDOWN;
heli.Destroy( );
}
}
// depending on our result, award experience to the operator
if ( ubBestSAMOperatorID != NOBODY )
{
if ( fHit )
StatChange( MercPtrs[ubBestSAMOperatorID], EXPERAMT, fDestroyed ? 30 : 10, TRUE );
StatChange( MercPtrs[ubBestSAMOperatorID], MECHANAMT, 5, TRUE );
}
}
}
// depending on our result, award experience to the operator
if ( ubBestSAMOperatorID != NOBODY )
{
if ( fHit )
StatChange( MercPtrs[ubBestSAMOperatorID], EXPERAMT, fDestroyed ? 30 : 10, TRUE );
StatChange( MercPtrs[ubBestSAMOperatorID], MECHANAMT, 5, TRUE );
}
}
}
}
@@ -1230,17 +1234,23 @@ void EnemyHeliCheckPlayerKnowledge( INT16 id )
}
// is the airspace in our current sector player-controlled and operational?
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( current_x, current_y )].usAirType == AIRSPACE_PLAYER_ACTIVE )
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( current_x, current_y )].usAirType & AIRSPACE_PLAYER_ACTIVE )
{
UINT8 ubControllingSAM = ubSAMControlledSectors[current_y][current_x];
// if mercs man the SAM, they will let us know of the new SAM
if ( PlayerMercsInSector( gpSamSectorX[ubControllingSAM - 1], gpSamSectorY[ubControllingSAM - 1], 0 ) )
for ( int i = 0; i < NUMBER_OF_SAMS; ++i )
{
// if we previously did not know of the heli, our mercs will alert us
if ( !(heli.flagmask & ENEMYHELI_KNOWNTOPLAYER) )
if ( DoesSamCoverSector( i, heli.sector_current ) )
{
SayQuoteFromAnyBodyInThisSector( gpSamSectorX[ubControllingSAM - 1], gpSamSectorY[ubControllingSAM - 1], 0, QUOTE_AIR_RAID );
// if mercs man the SAM, they will let us know of the new SAM
if ( PlayerMercsInSector( gpSamSectorX[i], gpSamSectorY[i], 0 ) )
{
// if we previously did not know of the heli, our mercs will alert us
if ( !(heli.flagmask & ENEMYHELI_KNOWNTOPLAYER) )
{
SayQuoteFromAnyBodyInThisSector( gpSamSectorX[i], gpSamSectorY[i], 0, QUOTE_AIR_RAID );
break;
}
}
}
}
@@ -1265,11 +1275,6 @@ void RepairSamSite( UINT8 aSector )
}
}
BOOLEAN IsSectorAirSpacePlayerControlled( UINT8 aSector )
{
return (StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( aSector )].usAirType == AIRSPACE_PLAYER_ACTIVE);
}
UINT8 NumPlayerAirSpaceOnHeliPath( UINT8 aStart, UINT8 aEnd )
{
UINT8 samcontacts = 0;
@@ -1280,7 +1285,7 @@ UINT8 NumPlayerAirSpaceOnHeliPath( UINT8 aStart, UINT8 aEnd )
{
tmpsect = GetNextEnemyHeliSector( tmpsect, aEnd );
if ( IsSectorAirSpacePlayerControlled( tmpsect ) )
if ( StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( tmpsect )].usAirType & AIRSPACE_PLAYER_ACTIVE )
++samcontacts;
}
-2
View File
@@ -101,8 +101,6 @@ void EnemyHeliCheckPlayerKnowledge( INT16 id );
void RepairSamSite( UINT8 aSector );
BOOLEAN IsSectorAirSpacePlayerControlled( UINT8 aSector );
UINT8 NumPlayerAirSpaceOnHeliPath( UINT8 aStart, UINT8 aEnd );
// get the next sector in an enemy heli flight path.
+52 -1
View File
@@ -860,6 +860,10 @@ static int l_GetUsedLanguage( lua_State *L );
static int l_DoInteractiveActionDefaultResult( lua_State *L );
static int l_GiveExp( lua_State *L );
static int l_NumNonPlayerTeamInSector( lua_State *L );
static int l_SetSamSiteHackStatus( lua_State *L );
static int l_GetSamSiteHackStatus( lua_State *L );
using namespace std;
UINT16 idProfil;
@@ -1728,6 +1732,10 @@ void IniFunction(lua_State *L, BOOLEAN bQuests )
lua_register( L, "DoInteractiveActionDefaultResult", l_DoInteractiveActionDefaultResult );
lua_register( L, "GiveExp", l_GiveExp );
lua_register( L, "NumNonPlayerTeamInSector", l_NumNonPlayerTeamInSector );
lua_register( L, "SetSamSiteHackStatus", l_SetSamSiteHackStatus );
lua_register( L, "GetSamSiteHackStatus", l_GetSamSiteHackStatus );
}
#ifdef NEWMUSIC
BOOLEAN LetLuaMusicControl(UINT8 Init)
@@ -7252,7 +7260,7 @@ static int l_ACTION_ITEM_LOCAL_ALARM (lua_State *L)
{
if ( lua_gettop(L) >= 1 )
{
UINT32 sGridNo = lua_tointeger(L, 1);
INT32 sGridNo = lua_tointeger(L, 1);
// Flugente: check for valid sGridNo
if ( TileIsOutOfBounds(sGridNo) )
@@ -13296,3 +13304,46 @@ static int l_GiveExp( lua_State *L )
return 0;
}
static int l_NumNonPlayerTeamInSector( lua_State *L )
{
if ( lua_gettop( L ) >= 3 )
{
INT16 sSectorX = lua_tointeger( L, 1 );
INT16 sSectorY = lua_tointeger( L, 2 );
UINT8 ubTeam = lua_tointeger( L, 3 );
UINT16 numteam = NumNonPlayerTeamMembersInSector( sSectorX, sSectorY, ubTeam );
lua_pushinteger( L, numteam );
}
return 1;
}
static int l_SetSamSiteHackStatus( lua_State *L )
{
if ( lua_gettop( L ) >= 3 )
{
INT16 sSectorX = lua_tointeger( L, 1 );
INT16 sSectorY = lua_tointeger( L, 2 );
INT8 sStatus = lua_tointeger( L, 3 );
SetSamHackStatus( sSectorX, sSectorY, sStatus );
}
return 0;
}
static int l_GetSamSiteHackStatus( lua_State *L )
{
if ( lua_gettop( L ) >= 2 )
{
INT16 sSectorX = lua_tointeger( L, 1 );
INT16 sSectorY = lua_tointeger( L, 2 );
lua_pushinteger( L, StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].sSamHackStatus );
}
return 1;
}
+107 -141
View File
@@ -81,8 +81,6 @@ extern UINT8 gubCurrentTalkingID;
// current temp path for dest char
extern PathStPtr pTempHelicopterPath;
extern UINT8 ubSAMControlledSectors[ MAP_WORLD_Y ][ MAP_WORLD_X ];
// the seating capacities
//extern INT32 iSeatingCapacities[];
@@ -1131,17 +1129,14 @@ INT32 GetCostOfPassageForHelicopter( INT16 sX, INT16 sY )
INT32 iCost = 0;
// HEADROCK HAM 3.5: Costs externalized
INT32 iBaseCostPerGreenTile = gGameExternalOptions.usHelicopterBaseCostPerGreenTile;
INT32 iBaseCostPerRedTile = gGameExternalOptions.usHelicopterBaseCostPerRedTile;
// if they don't control it
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
iCost = iBaseCostPerGreenTile;
iCost = gGameExternalOptions.usHelicopterBaseCostPerGreenTile;
}
else
{
iCost = iBaseCostPerRedTile;
iCost = gGameExternalOptions.usHelicopterBaseCostPerRedTile;
}
// HEADROCK HAM 3.5: Apply facility-based modifiers from global integer recalculated hourly
@@ -1349,7 +1344,7 @@ void HandleHeliHoverForAMinute( void )
gubHelicopterHoverTime = 0;
iTotalHeliDistanceSinceRefuel++;
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
iTotalAccumulatedCostByPlayer += gGameExternalOptions.usHelicopterHoverCostOnGreenTile;
}
@@ -2412,65 +2407,46 @@ BOOLEAN IsHelicopterOnGroundAtRefuelingSite( UINT8 ubRefuelingSite )
BOOLEAN WillAirRaidBeStopped( INT16 sSectorX, INT16 sSectorY )
{
UINT8 ubSamNumber = 0;
INT8 bSAMCondition;
UINT8 ubChance;
if ( !StrategicMap[(AIRPORT_X + (MAP_WORLD_X * AIRPORT_Y))].fEnemyControlled && !StrategicMap[(AIRPORT2_X + (MAP_WORLD_X * AIRPORT2_Y))].fEnemyControlled )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "WillAirRaidBeStopped: enemy has no more airports" ) );
return(TRUE);
}
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "WillAirRaidBeStopped: enemy air controlled = %d", StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].usAirType ) );
// if enemy controls this SAM site, then it can't stop an air raid
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].usAirType != AIRSPACE_PLAYER_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].usAirType & AIRSPACE_PLAYER_ACTIVE) )
{
return( FALSE );
}
if( !StrategicMap[ ( AIRPORT_X + ( MAP_WORLD_X * AIRPORT_Y ) ) ].fEnemyControlled && !StrategicMap[ ( AIRPORT2_X + ( MAP_WORLD_X * AIRPORT2_Y ) ) ].fEnemyControlled )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("WillAirRaidBeStopped: enemy has no more airports"));
return( TRUE );
}
// which SAM controls this sector?
ubSamNumber = ubSAMControlledSectors[ sSectorY ][ sSectorX ];
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("WillAirRaidBeStopped: SAM number = %d",ubSamNumber));
// if none of them
if (ubSamNumber == 0)
{
return( FALSE);
}
// get the condition of that SAM site (NOTE: SAM #s are 1-4, but indexes are 0-3!!!)
Assert( ubSamNumber <= NUMBER_OF_SAMS );
bSAMCondition = StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ ubSamNumber - 1 ] ) ].bSAMCondition;
// if it's too busted to work, then it can't stop an air raid
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("WillAirRaidBeStopped: SAM condition = %d",bSAMCondition));
if( bSAMCondition < MIN_CONDITION_FOR_SAM_SITE_TO_WORK )
{
// no problem, SAM site not working
return( FALSE );
}
// Friendly airspace controlled by a working SAM site, so SAM site fires a SAM at air raid bomber
// calc chance that chopper will be shot down
ubChance = bSAMCondition;
// there's a fair chance of a miss even if the SAM site is in perfect working order
if (ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3) // Madd - since this is only used for enemy air raids, we'll say that good guy SAMs can have a max of 99% to hit instead of 33%
for ( int i = 0; i < NUMBER_OF_SAMS; ++i )
{
ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3;
}
BOOLEAN samworking = FALSE;
if ( DoesSamCoverSector( i, SECTOR( sSectorX, sSectorY ), &samworking ) && samworking )
{
// calc chance that chopper will be shot down
ubChance = StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[i] )].bSAMCondition;
if( PreRandom( 100 ) < ubChance)
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("WillAirRaidBeStopped: return true"));
return( TRUE );
}
// there's a fair chance of a miss even if the SAM site is in perfect working order
if ( ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3 ) // Madd - since this is only used for enemy air raids, we'll say that good guy SAMs can have a max of 99% to hit instead of 33%
{
ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3;
}
if ( PreRandom( 100 ) < ubChance )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "WillAirRaidBeStopped: return true" ) );
return(TRUE);
}
}
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("WillAirRaidBeStopped: return false"));
return( FALSE );
}
@@ -2483,104 +2459,94 @@ void HeliCrashSoundStopCallback( void *pData )
BOOLEAN HandleSAMSiteAttackOfHelicopterInSector( INT16 sSectorX, INT16 sSectorY )
{
UINT8 ubSamNumber = 0;
UINT32 ubSamNumber = 0;
INT8 bSAMCondition;
UINT8 ubChance;
#ifdef JA2TESTVERSION
if ( fSAMSitesDisabledFromAttackingPlayer == TRUE )
{
return(FALSE);
}
#endif
// if this sector is in friendly airspace, we're safe
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
// no problem, friendly airspace
return( FALSE );
}
// which SAM controls this sector?
ubSamNumber = ubSAMControlledSectors[ sSectorY ][ sSectorX ];
// if none of them
if (ubSamNumber == 0)
{
return( FALSE);
}
// get the condition of that SAM site (NOTE: SAM #s are 1-4, but indexes are 0-3!!!)
Assert( ubSamNumber <= NUMBER_OF_SAMS );
bSAMCondition = StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ ubSamNumber - 1 ] ) ].bSAMCondition;
// if the SAM site is too damaged to be a threat
if( bSAMCondition < MIN_CONDITION_FOR_SAM_SITE_TO_WORK )
{
// no problem, SAM site not working
return( FALSE );
}
#ifdef JA2TESTVERSION
if( fSAMSitesDisabledFromAttackingPlayer == TRUE )
{
return( FALSE );
}
#endif
// Hostile airspace controlled by a working SAM site, so SAM site fires a SAM at Skyrider!!!
// calc chance that chopper will be shot down
ubChance = bSAMCondition;
// there's a fair chance of a miss even if the SAM site is in perfect working order
if (ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy)
for ( int i = 0; i < NUMBER_OF_SAMS; ++i )
{
ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy;
}
if( PreRandom( 100 ) < ubChance)
{
// another hit!
gubHelicopterHitsTaken++;
// Took a hit! Pause time so player can reconsider
StopTimeCompression();
// first hit?
if ( gubHelicopterHitsTaken == 1 )
BOOLEAN samworking = FALSE;
if ( DoesSamCoverSector( i, SECTOR( sSectorX, sSectorY ), &samworking ) && samworking )
{
HeliCharacterDialogue( pSkyRider, HELI_TOOK_MINOR_DAMAGE );
if( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE )
HurtPassengersInHelicopter( iHelicopterVehicleId );
}
// second hit?
else if ( gubHelicopterHitsTaken == 2 )
{
// going back to base (no choice, dialogue says so)
HeliCharacterDialogue( pSkyRider, HELI_TOOK_MAJOR_DAMAGE );
MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_DAMAGE );
if( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE )
HurtPassengersInHelicopter( iHelicopterVehicleId );
}
// third hit!
else
{
// Important: Skyrider must still be alive when he talks, so must do this before heli is destroyed!
HeliCharacterDialogue( pSkyRider, HELI_GOING_DOWN );
bSAMCondition = StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[i] )].bSAMCondition;
// everyone die die die
// play sound
// if ( PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback ) == SOUND_ERROR )
//{
//// Destroy here if we cannot play streamed sound sample....
// SkyriderDestroyed( );
//}
//else
//{
//// otherwise it's handled in the callback
//// remove any arrival events for the helicopter's group
//DeleteStrategicEvent( EVENT_GROUP_ARRIVAL, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup );
//}
// anv - calling SkyriderDestroyed() in callback from playing sound causes sound system to crash, as SkyriderDestroyed causes new sounds (hit battlesnds) to play while blah2 is not removed yet
// + if there's a pause while falling heli sound is played, it's possible to cheat by changing passengers assignments
PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback );
SkyriderDestroyed( );
// calc chance that chopper will be shot down
ubChance = bSAMCondition;
// special return code indicating heli was destroyed
return( TRUE );
// there's a fair chance of a miss even if the SAM site is in perfect working order
if ( ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy )
{
ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy;
}
if ( PreRandom( 100 ) < ubChance )
{
// another hit!
++gubHelicopterHitsTaken;
// Took a hit! Pause time so player can reconsider
StopTimeCompression( );
// first hit?
if ( gubHelicopterHitsTaken == 1 )
{
HeliCharacterDialogue( pSkyRider, HELI_TOOK_MINOR_DAMAGE );
if ( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE )
HurtPassengersInHelicopter( iHelicopterVehicleId );
}
// second hit?
else if ( gubHelicopterHitsTaken == 2 )
{
// going back to base (no choice, dialogue says so)
HeliCharacterDialogue( pSkyRider, HELI_TOOK_MAJOR_DAMAGE );
MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_DAMAGE );
if ( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE )
HurtPassengersInHelicopter( iHelicopterVehicleId );
}
// third hit!
else
{
// Important: Skyrider must still be alive when he talks, so must do this before heli is destroyed!
HeliCharacterDialogue( pSkyRider, HELI_GOING_DOWN );
// everyone die die die
// play sound
// if ( PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback ) == SOUND_ERROR )
//{
//// Destroy here if we cannot play streamed sound sample....
// SkyriderDestroyed( );
//}
//else
//{
//// otherwise it's handled in the callback
//// remove any arrival events for the helicopter's group
//DeleteStrategicEvent( EVENT_GROUP_ARRIVAL, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup );
//}
// anv - calling SkyriderDestroyed() in callback from playing sound causes sound system to crash, as SkyriderDestroyed causes new sounds (hit battlesnds) to play while blah2 is not removed yet
// + if there's a pause while falling heli sound is played, it's possible to cheat by changing passengers assignments
PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback );
SkyriderDestroyed( );
// special return code indicating heli was destroyed
return(TRUE);
}
}
}
}
@@ -2833,7 +2799,7 @@ INT16 GetNumSafeSectorsInPath( void )
{
uiLocation = pNode->uiSectorId;
if ( StrategicMap[uiLocation].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[uiLocation].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
++uiCount;
}
@@ -2861,7 +2827,7 @@ INT16 GetNumSafeSectorsInPath( void )
{
uiLocation = pNode->uiSectorId;
if ( StrategicMap[uiLocation].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[uiLocation].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
++uiCount;
}
@@ -2915,7 +2881,7 @@ INT16 GetNumUnSafeSectorsInPath( void )
{
uiLocation = pNode->uiSectorId;
if ( StrategicMap[uiLocation].usAirType == AIRSPACE_ENEMY_ACTIVE )
if ( StrategicMap[uiLocation].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
++uiCount;
}
@@ -2942,7 +2908,7 @@ INT16 GetNumUnSafeSectorsInPath( void )
{
uiLocation = pNode->uiSectorId;
if ( StrategicMap[uiLocation].usAirType == AIRSPACE_ENEMY_ACTIVE )
if ( StrategicMap[uiLocation].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
++uiCount;
}
+10 -6
View File
@@ -775,7 +775,7 @@ void ToggleShowTeamsMode( void )
void ToggleAirspaceMode( void )
{
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// turn airspace OFF
gusMapDisplayColourMode = MAP_DISPLAY_NORMAL;
@@ -1006,23 +1006,26 @@ void TurnOnAirSpaceMode( void )
{
// if mode already on, leave, else set and redraw
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE )
{
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
gusMapDisplayColourMode = MAP_DISPLAY_AIRSPACE;
else if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
gusMapDisplayColourMode = MAP_DISPLAY_AIRSPACE_COLOURED_SAMS;
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
MapBorderButtonOn( MAP_BORDER_AIRSPACE_BTN );
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
MapBorderButtonOff( MAP_BORDER_DISEASE_BTN );
MapBorderButtonOff( MAP_BORDER_WEATHER_BTN );
// Turn off towns & mines (mostly because town/mine names overlap SAM site names)
if( fShowTownFlag == TRUE )
if( fShowTownFlag )
{
fShowTownFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_TOWN_BTN );
}
if( fShowMineFlag == TRUE )
if( fShowMineFlag )
{
fShowMineFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MINE_BTN );
@@ -1044,7 +1047,7 @@ void TurnOnAirSpaceMode( void )
*/
// Turn off items
if( fShowItemsFlag == TRUE )
if( fShowItemsFlag )
{
fShowItemsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_ITEM_BTN );
@@ -1390,6 +1393,7 @@ void InitializeMapBorderButtonStates( void )
switch ( gusMapDisplayColourMode )
{
case MAP_DISPLAY_AIRSPACE:
case MAP_DISPLAY_AIRSPACE_COLOURED_SAMS:
MapBorderButtonOn( MAP_BORDER_AIRSPACE_BTN );
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
MapBorderButtonOff( MAP_BORDER_DISEASE_BTN );
+1
View File
@@ -56,6 +56,7 @@ enum
{
MAP_DISPLAY_NORMAL,
MAP_DISPLAY_AIRSPACE,
MAP_DISPLAY_AIRSPACE_COLOURED_SAMS,
MAP_DISPLAY_MOBILEMILITIARESTRICTIONS,
MAP_DISPLAY_DISEASE,
MAP_DISPLAY_WEATHER,
+115 -32
View File
@@ -693,7 +693,6 @@ void HandleShowingOfEnemiesWithMilitiaOn( void )
}
}
UINT32 DrawMap( void )
{
HVSURFACE hSrcVSurface;
@@ -731,6 +730,11 @@ UINT32 DrawMap( void )
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
// draw SAM sites
//ShowSAMSitesOnStrategicMap( );
//UpdateAirspaceControl();
if ( !iCurrentMapSectorZ )
{
// shade map sectors (must be done after Tixa/Orta/Mine icons have been blitted, but before icons!)
@@ -744,42 +748,99 @@ UINT32 DrawMap( void )
switch ( gusMapDisplayColourMode )
{
case MAP_DISPLAY_AIRSPACE:
if ( GetSectorFlagStatus( cnt, cnt2, (UINT8)iCurrentMapSectorZ, SF_ALREADY_VISITED ) == FALSE )
{
if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType == AIRSPACE_PLAYER_ACTIVE )
BOOLEAN fAlreadyVisited = GetSectorFlagStatus( cnt, cnt2, (UINT8)iCurrentMapSectorZ, SF_ALREADY_VISITED );
if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType & AIRSPACE_PLAYER_ACTIVE )
{
// sector not visited but air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN );
if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
// sector not visited and not air controlled
ShadeMapElem( cnt, cnt2, fAlreadyVisited ? MAP_SHADE_LT_YELLOW : MAP_SHADE_DK_YELLOW );
}
else
{
// sector not visited but air controlled
ShadeMapElem( cnt, cnt2, fAlreadyVisited ? MAP_SHADE_LT_GREEN : MAP_SHADE_DK_GREEN );
}
}
else if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType == AIRSPACE_ENEMY_ACTIVE )
else if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
// sector not visited and not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED );
ShadeMapElem( cnt, cnt2, fAlreadyVisited ? MAP_SHADE_LT_RED : MAP_SHADE_DK_RED );
}
else
{
// sector not visited, currently nobody controls the airspace
ShadeMapElem( cnt, cnt2, MAP_SHADE_MD_BLUE );
//ShadeMapElem( cnt, cnt2, fAlreadyVisited ? MAP_SHADE_LT_BLUE : MAP_SHADE_MD_BLUE );
}
}
else
break;
case MAP_DISPLAY_AIRSPACE_COLOURED_SAMS:
{
if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType == AIRSPACE_PLAYER_ACTIVE )
CHAR16 sString[20];
swprintf( sString, L"%d", ubSAMControlledSectors[cnt2][cnt] );
BOOLEAN a = FALSE;
BOOLEAN b = FALSE;
BOOLEAN c = FALSE;
BOOLEAN d = FALSE;
{
// sector visited and air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN );
for ( int i = 0; i < NUMBER_OF_SAMS; ++i )
{
BOOLEAN samworking = FALSE;
if ( DoesSamCoverSector( i, SECTOR( cnt, cnt2 ), &samworking ) && samworking )
{
if ( i == 0 ) a = TRUE;
if ( i == 1 ) b = TRUE;
if ( i == 2 ) c = TRUE;
if ( i == 3 ) d = TRUE;
}
}
}
else if ( StrategicMap[cnt + cnt2 * WORLD_MAP_X].usAirType == AIRSPACE_ENEMY_ACTIVE )
{
// sector visited but not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED );
}
else
{
// sector visited, currently nobody controls the airspace
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_BLUE );
}
}
if ( a && !b && !c && !d)
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED );
else if ( !a && b && !c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_GREEN );
else if ( !a && !b && c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_BLUE );
else if ( !a && !b && !c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_YELLOW );
else if ( a && b && !c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_GREEN );
else if ( a && !b && c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_BLUE );
else if ( a && !b && !c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_YELLOW );
else if ( !a && b && c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_GREEN_BLUE );
else if ( !a && b && !c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_GREEN_YELLOW );
else if ( !a && !b && c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_BLUE_YELLOW );
else if ( a && b && c && !d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_GREEN_BLUE );
else if ( a && b && !c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_GREEN_YELLOW );
else if ( a && !b && c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_BLUE_YELLOW );
else if ( !a && b && c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_GREEN_BLUE_YELLOW );
else if ( a && b && c && d )
ShadeMapElem( cnt, cnt2, MAP_SHADE_MIX_RED_GREEN_BLUE_YELLOW );
INT16 sXCorner = (INT16)(MAP_VIEW_START_X + (cnt * MAP_GRID_X));
INT16 sYCorner = (INT16)(MAP_VIEW_START_Y + (cnt2 * MAP_GRID_Y));
INT16 usXPos, usYPos;
FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, FONT14ARIAL, &usXPos, &usYPos );
gprintfdirty( usXPos, usYPos, sString );
mprintf( usXPos, usYPos, sString );
}
break;
case MAP_DISPLAY_MOBILEMILITIARESTRICTIONS:
@@ -905,7 +966,7 @@ UINT32 DrawMap( void )
DrawTownMilitiaForcesOnMap( );
}
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE && !gfInChangeArrivalSectorMode )
if ( ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS ) && !gfInChangeArrivalSectorMode )
{
DrawBullseye();
}
@@ -1172,7 +1233,7 @@ INT32 ShowAssignedTeam(INT16 sMapX, INT16 sMapY, INT32 iCount)
( !PlayerIDGroupInMotion( pSoldier->ubGroupID ) ) )
{
// skip mercs inside the helicopter if we're showing airspace level - they show up inside chopper icon instead
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE || (pSoldier->bAssignment != VEHICLE) || (pSoldier->iVehicleId != iHelicopterVehicleId) )
if ( (gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) || (pSoldier->bAssignment != VEHICLE) || (pSoldier->iVehicleId != iHelicopterVehicleId) )
{
++sNumberOfAssigned;
}
@@ -1577,7 +1638,29 @@ BOOLEAN InitializePalettesForMap( void )
pMapPalette[MAP_SHADE_LT_PINK] = Create16BPPPaletteShaded( pPalette, 200, 40, 175, TRUE );
pMapPalette[MAP_SHADE_ORANGE] = Create16BPPPaletteShaded( pPalette, 255, 127, 40, TRUE );
pMapPalette[MAP_SHADE_MIX_RED] = Create16BPPPaletteShaded( pPalette, 400, 0, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_GREEN] = Create16BPPPaletteShaded( pPalette, 0, 400, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_BLUE] = Create16BPPPaletteShaded( pPalette, 0, 0, 400, TRUE );
pMapPalette[MAP_SHADE_MIX_YELLOW] = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_GREEN] = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_BLUE] = Create16BPPPaletteShaded( pPalette, 200, 0, 200, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_YELLOW] = Create16BPPPaletteShaded( pPalette, 300, 100, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_GREEN_BLUE] = Create16BPPPaletteShaded( pPalette, 0, 200, 200, TRUE );
pMapPalette[MAP_SHADE_MIX_GREEN_YELLOW] = Create16BPPPaletteShaded( pPalette, 100, 300, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_BLUE_YELLOW] = Create16BPPPaletteShaded( pPalette, 100, 100, 200, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_GREEN_BLUE] = Create16BPPPaletteShaded( pPalette, 133, 133, 133, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_GREEN_YELLOW] = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_BLUE_YELLOW] = Create16BPPPaletteShaded( pPalette, 200, 66, 133, TRUE );
pMapPalette[MAP_SHADE_MIX_GREEN_BLUE_YELLOW] = Create16BPPPaletteShaded( pPalette, 66, 200, 133, TRUE );
pMapPalette[MAP_SHADE_MIX_RED_GREEN_BLUE_YELLOW] = Create16BPPPaletteShaded( pPalette, 150, 150, 100, TRUE );
// delete image
DeleteVideoSurfaceFromIndex(uiTempMap);
@@ -2007,7 +2090,7 @@ void PlotPathForHelicopter( INT16 sX, INT16 sY )
// will plot the path for the helicopter
// no heli...go back
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE || !fHelicopterAvailable )
if ( (gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) || !fHelicopterAvailable )
{
return;
}
@@ -2943,9 +3026,9 @@ void DisplayThePotentialPathForHelicopter(INT16 sMapX, INT16 sMapY )
static INT16 sOldMapX, sOldMapY;
INT32 iDifference = 0;
if ( fOldShowAirCraft != (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE) )
if ( fOldShowAirCraft != (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) )
{
fOldShowAirCraft = (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE);
fOldShowAirCraft = (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS);
giPotHeliPathBaseTime = GetJA2Clock( );
sOldMapX = sMapX;
@@ -4396,7 +4479,7 @@ BOOLEAN CheckForClickOverHelicopterIcon( INT16 sClickedSectorX, INT16 sClickedSe
fIgnoreClick = TRUE;
}
if ( !fHelicopterAvailable || gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE )
if ( !fHelicopterAvailable || (gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) )
{
return( FALSE );
}
@@ -6813,7 +6896,7 @@ void ShowSAMSitesOnStrategicMap( void )
INT8 ubVidObjIndex = 0;
CHAR16 wString[ 40 ];
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
BlitSAMGridMarkers( );
}
@@ -6843,7 +6926,7 @@ void ShowSAMSitesOnStrategicMap( void )
GetVideoObject( &hHandle, guiSAMICON);
BltVideoObject( guiSAVEBUFFER, hHandle, ubVidObjIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// write "SAM Site" centered underneath
@@ -6911,7 +6994,7 @@ void ShowSAMSitesOnStrategicMap( void )
sX += 5;
sY += 3;
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// write "Refuel Site" centered underneath
+23
View File
@@ -61,6 +61,29 @@ enum{
MAP_SHADE_ORANGE,
// Flugente: more colours
MAP_SHADE_MIX_RED,
MAP_SHADE_MIX_GREEN,
MAP_SHADE_MIX_BLUE,
MAP_SHADE_MIX_YELLOW,
MAP_SHADE_MIX_RED_GREEN,
MAP_SHADE_MIX_RED_BLUE,
MAP_SHADE_MIX_RED_YELLOW,
MAP_SHADE_MIX_GREEN_BLUE,
MAP_SHADE_MIX_GREEN_YELLOW,
MAP_SHADE_MIX_BLUE_YELLOW,
MAP_SHADE_MIX_RED_GREEN_BLUE,
MAP_SHADE_MIX_RED_GREEN_YELLOW,
MAP_SHADE_MIX_RED_BLUE_YELLOW,
MAP_SHADE_MIX_GREEN_BLUE_YELLOW,
MAP_SHADE_MIX_RED_GREEN_BLUE_YELLOW,
MAP_SHADE_MAX,
};
@@ -949,6 +949,21 @@ void AddCommonInfoToBox(void)
}
AddSecondColumnMonoString( &hStringHandle, wString );
// Flugente: if this is a SAM site we know about, display (hack-)status
for ( UINT16 x = 0; x < MAX_NUMBER_OF_SAMS; ++x )
{
if ( pSamList[x] == usSectorValue && fSamSiteFound[x] )
{
swprintf( wString, pwMiscSectorStrings[7] );
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d / %d", StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( usSectorValue )].bSAMCondition, StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( usSectorValue )].sSamHackStatus );
AddSecondColumnMonoString( &hStringHandle, wString );
break;
}
}
}
+1 -1
View File
@@ -6659,7 +6659,7 @@ void TurnOnSectorLocator( UINT8 ubProfileID )
{
// if helicopter position is being shown, don't do this, too, cause the helicopter icon is on top and it looks
// like crap. I tried moving the heli icon blit to before, but that screws up it's blitting.
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// can't use his profile, he's where his chopper is
Assert( iHelicopterVehicleId != -1 );
+1
View File
@@ -2251,6 +2251,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
if( IsThisSectorASAMSector( pGroup->ubSectorX, pGroup->ubSectorY, 0 ) )
{
StrategicMap[ pGroup->ubSectorX + pGroup->ubSectorY * MAP_WORLD_X ].bSAMCondition = 100;
StrategicMap[ pGroup->ubSectorX + pGroup->ubSectorY * MAP_WORLD_X ].sSamHackStatus = 100;
StrategicMap[ pGroup->ubSectorX + pGroup->ubSectorY * MAP_WORLD_X ].usFlags &= ~SAMSITE_REPAIR_ORDERED;
UpdateSAMDoneRepair( pGroup->ubSectorX, pGroup->ubSectorY, 0 );
+1 -1
View File
@@ -3806,7 +3806,7 @@ BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnt
// if this group is aboard the helicopter and we're showing the airspace layer, don't count any mercs aboard the
// chopper, because the chopper icon itself serves the function of showing the location/size of this group
if ( !fHelicopterGroup || gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE )
if ( !fHelicopterGroup || !(gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) )
{
// if only showing retreat paths, ignore groups not in the battle sector
// if NOT showing retreat paths, ignore groups not between sectors
+1 -1
View File
@@ -335,7 +335,7 @@ INT32 FindStratPath(INT16 sStart, INT16 sDestination, INT16 sMvtGroupNumber, BOO
{
// is a heli, its pathing is determined not by time (it's always the same) but by total cost
// Skyrider will avoid uncontrolled airspace as much as possible...
if ( StrategicMap[curLoc].usAirType == AIRSPACE_ENEMY_ACTIVE )
if ( StrategicMap[curLoc].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
nextCost = COST_AIRSPACE_UNSAFE;
}
+13 -19
View File
@@ -5641,14 +5641,14 @@ UINT32 MapScreenHandle(void)
// if heli is around, show it
if ( fHelicopterAvailable && (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || fShowTeamFlag) && (iCurrentMapSectorZ == 0) && !fShowMapInventoryPool )
if ( fHelicopterAvailable && ( (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) || fShowTeamFlag) && (iCurrentMapSectorZ == 0) && !fShowMapInventoryPool )
{
// this is done on EVERY frame, I guess it beats setting entire map dirty all the time while he's moving...
DisplayPositionOfHelicopter( );
}
// Flugente: enemy helicopter
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE && (iCurrentMapSectorZ == 0) && !fShowMapInventoryPool )
if ( (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) && (iCurrentMapSectorZ == 0) && !fShowMapInventoryPool )
{
DisplayPositionOfEnemyHelicopter();
}
@@ -6625,7 +6625,7 @@ UINT32 HandleMapUI( )
if( SectorInfo[ ( SECTOR( sMapX, sMapY ) ) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != GROUNDBARRIER )
{
// if it's not enemy air controlled
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sMapX, sMapY )].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( sMapX, sMapY )].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
CHAR16 sMsgString[ 128 ], sMsgSubString[ 64 ];
@@ -6730,7 +6730,7 @@ UINT32 HandleMapUI( )
// if we're in airspace mode
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// if not moving soldiers, and not yet plotting the helicopter
if ( (bSelectedDestChar == -1) && !fPlotForHelicopter && !fPlotForMilitia )
@@ -11700,7 +11700,7 @@ void PlotTemporaryPaths( void )
{
if ( fPlotForHelicopter )
{
Assert( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE );
Assert( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS );
// plot temp path
PlotATemporaryPathForHelicopter( sMapX, sMapY);
@@ -11979,7 +11979,7 @@ void CheckIfPlottingForCharacterWhileAirCraft( void )
// if the plotting modes are inconsistent, stop plotting
BOOLEAN fAbort = FALSE;
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
if ( (bSelectedDestChar != -1 || fPlotForMilitia) && !fPlotForHelicopter )
fAbort = TRUE;
@@ -12762,7 +12762,7 @@ void UpdateCursorIfInLastSector( void )
{
GetMouseMapXY(&sMapX, &sMapY);
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// check for helicopter
if ( fPlotForHelicopter )
@@ -14592,7 +14592,6 @@ void CheckForInventoryModeCancellation()
}
}
void ChangeSelectedMapSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
// ignore while map inventory pool is showing, or else items can be replicated, since sector inventory always applies
@@ -14609,14 +14608,13 @@ void ChangeSelectedMapSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
// disallow going underground while plotting (surface) movement
if ( ( bMapZ != 0 ) && ( ( bSelectedDestChar != -1 ) || fPlotForHelicopter ) )
return;
sSelMapX = sMapX;
sSelMapY = sMapY;
iCurrentMapSectorZ = bMapZ;
// if going underground while in airspace mode
if ( (bMapZ > 0) && (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE) )
if ( (bMapZ > 0) && (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) )
{
// turn off airspace mode
ToggleAirspaceMode( );
@@ -14629,8 +14627,6 @@ void ChangeSelectedMapSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
fTeamPanelDirty = TRUE;
}
BOOLEAN CanChangeDestinationForCharSlot( INT8 bCharNumber, BOOLEAN fShowErrorMessage )
{
SOLDIERTYPE *pSoldier = NULL;
@@ -14786,7 +14782,7 @@ void CancelOrShortenPlottedPath( void )
GetMouseMapXY(&sMapX, &sMapY);
// check if we are in aircraft mode
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// check for helicopter path being plotted
if( !fPlotForHelicopter )
@@ -14830,7 +14826,6 @@ void CancelOrShortenPlottedPath( void )
uiReturnValue = ClearPathAfterThisSectorForCharacter( &Menptr[gCharactersList[bSelectedDestChar].usSolID], sMapX, sMapY );
}
switch ( uiReturnValue )
{
case ABORT_PLOTTING:
@@ -15312,7 +15307,6 @@ void MakeMapModesSuitableForDestPlotting( INT8 bCharNumber )
{
SOLDIERTYPE *pSoldier = NULL;
if( gCharactersList[ bCharNumber ].fValid == TRUE )
{
pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ];
@@ -15323,7 +15317,7 @@ void MakeMapModesSuitableForDestPlotting( INT8 bCharNumber )
if ( ( pSoldier->bAssignment == VEHICLE ) && ( pSoldier->iVehicleId == iHelicopterVehicleId ) )
{
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE && gusMapDisplayColourMode != MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// turn on airspace mode automatically
ToggleAirspaceMode();
@@ -15331,7 +15325,7 @@ void MakeMapModesSuitableForDestPlotting( INT8 bCharNumber )
}
else
{
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE )
if ( gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS )
{
// turn off airspace mode automatically
ToggleAirspaceMode();
@@ -15791,7 +15785,7 @@ void StartChangeSectorArrivalMode( void )
BOOLEAN CanMoveBullseyeAndClickedOnIt( INT16 sMapX, INT16 sMapY )
{
// if in airspace mode, and not plotting paths
if ( (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE) && (bSelectedDestChar == -1) && (fPlotForHelicopter == FALSE) )
if ( (gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE || gusMapDisplayColourMode == MAP_DISPLAY_AIRSPACE_COLOURED_SAMS) && (bSelectedDestChar == -1) && (fPlotForHelicopter == FALSE) )
{
if (is_networked)
{
+6 -11
View File
@@ -5,14 +5,9 @@
#include "mapscreen.h"
#include "soldier control.h"
// different states for airspace control
enum
{
AIRSPACE_PLAYER_ACTIVE, // controlled by player and active
AIRSPACE_ENEMY_ACTIVE, // controlled by enemy and active
AIRSPACE_PLAYER_INACTIVE, // controlled by player but not active
AIRSPACE_ENEMY_INACTIVE, // controlled by enemy but not active
};
// Flugente: airspace flags
#define AIRSPACE_ENEMY_ACTIVE 0x01 //1 // controlled by enemy and active
#define AIRSPACE_PLAYER_ACTIVE 0x02 //2 // controlled by enemy and active
struct strategicmapelement{
UINT8 UNUSEDuiFootEta[4]; // eta/mvt costs for feet
@@ -21,11 +16,11 @@ struct strategicmapelement{
UINT8 uiBadVehicleSector[4]; // blocking mvt from vehicles
INT8 bNameId;
BOOLEAN fEnemyControlled; // enemy controlled or not
UINT8 usAirType;
UINT8 usAirType; // Flugente: This will now be used as a flagmask
BOOLEAN UNUSEDfLostControlAtSomeTime;
INT8 bSAMCondition; // SAM Condition .. 0 - 100, just like an item's status
INT8 bFillupforPadding[ 3 ]; // necessary for padding
INT8 sSamHackStatus; // this status influences a SAM's max radius
INT8 bFillupforPadding[ 2 ]; // necessary for padding
UINT32 usFlags; // Flugente: various flags
INT8 bPadding[ 20 ];
};
+114 -37
View File
@@ -238,7 +238,7 @@ INT8 gbMercIsNewInThisSector[MAX_NUM_SOLDIERS];
BOOLEAN localizedMapTextOnly;
UINT8 ubSAMControlledSectors[MAP_WORLD_Y][MAP_WORLD_X];// = {
UINT32 ubSAMControlledSectors[MAP_WORLD_Y][MAP_WORLD_X];// = {
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//
@@ -1973,7 +1973,8 @@ void InitializeSAMSites( void )
for ( UINT32 cnt = 0; cnt < NUMBER_OF_SAMS; ++cnt )
{
StrategicMap[gpSamSectorX[cnt] + (MAP_WORLD_X * gpSamSectorY[cnt])].bSAMCondition = 100;
};
StrategicMap[gpSamSectorX[cnt] + (MAP_WORLD_X * gpSamSectorY[cnt])].sSamHackStatus = 100;
}
// Flugente, bizarrely enough, this structure is not NULLED when starting a new campaign. For now, we NULL the flagmask to clear at least that
for ( INT32 cnt = 0; cnt < MAP_WORLD_X*MAP_WORLD_Y; ++cnt )
@@ -5147,6 +5148,15 @@ INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
return(-1);
}
void SetSamHackStatus( INT16 sSectorX, INT16 sSectorY, INT8 sStatus )
{
if ( IsThisSectorASAMSector( sSectorX, sSectorY, 0 ) )
{
StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].sSamHackStatus = sStatus;
UpdateAirspaceControl();
}
}
BOOLEAN CanGoToTacticalInSector( INT16 sX, INT16 sY, UINT8 ubZ )
{
@@ -5222,47 +5232,40 @@ INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY )
void UpdateAirspaceControl( void )
{
UINT8 ubControllingSAM;
StrategicMapElement *pSAMStrategicMap = NULL;
for ( INT32 iCounterA = 1; iCounterA < (INT32)(MAP_WORLD_X - 1); ++iCounterA )
{
for ( INT32 iCounterB = 1; iCounterB < (INT32)(MAP_WORLD_Y - 1); ++iCounterB )
{
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = 0;
// if networked, disable SAM airspace restrictions...
if ( is_networked )
{
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_ENEMY_INACTIVE;
continue;
}
// IMPORTANT: B and A are reverse here, since the table is stored transposed
ubControllingSAM = ubSAMControlledSectors[iCounterB][iCounterA];
if ( ubControllingSAM >= 1 && ubControllingSAM <= NUMBER_OF_SAMS )
for ( int samcnt = 0; samcnt < NUMBER_OF_SAMS; ++samcnt )
{
pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ubControllingSAM - 1] )]);
BOOLEAN samworking = FALSE;
if ( DoesSamCoverSector( samcnt, SECTOR( iCounterA, iCounterB ), &samworking ) )
{
if ( samworking )
{
pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[samcnt] )]);
// different status depending on who controls the SAM sector, and whether the SAM is operational
if ( pSAMStrategicMap->fEnemyControlled )
{
if ( pSAMStrategicMap->bSAMCondition >= MIN_CONDITION_FOR_SAM_SITE_TO_WORK )
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_ENEMY_ACTIVE;
else
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_ENEMY_INACTIVE;
// different status depending on who controls the SAM sector, and whether the SAM is operational
if ( pSAMStrategicMap->fEnemyControlled )
{
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType |= AIRSPACE_ENEMY_ACTIVE;
}
else
{
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType |= AIRSPACE_PLAYER_ACTIVE;
}
}
}
else
{
if ( pSAMStrategicMap->bSAMCondition >= MIN_CONDITION_FOR_SAM_SITE_TO_WORK )
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_PLAYER_ACTIVE;
else
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_PLAYER_INACTIVE;
}
}
else
{
// no controlling SAM site
StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].usAirType = AIRSPACE_ENEMY_INACTIVE;
}
}
}
@@ -5270,7 +5273,7 @@ void UpdateAirspaceControl( void )
// check if currently selected arrival sector still has secure airspace
// if it's not enemy air controlled
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( gsMercArriveSectorX, gsMercArriveSectorY )].usAirType == AIRSPACE_ENEMY_ACTIVE )
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( gsMercArriveSectorX, gsMercArriveSectorY )].usAirType & AIRSPACE_ENEMY_ACTIVE )
{
// NOPE!
CHAR16 sMsgString[256], sMsgSubString1[64], sMsgSubString2[64];
@@ -5280,7 +5283,7 @@ void UpdateAirspaceControl( void )
// move the landing zone over to Omerta
// HEADROCK HAM 3.5: Externalized coordinates
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY )].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY )].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
@@ -5291,7 +5294,7 @@ void UpdateAirspaceControl( void )
{
for ( UINT8 ubSectorY = 1; ubSectorY <= 16; ++ubSectorY )
{
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( ubSectorX, ubSectorY )].usAirType != AIRSPACE_ENEMY_ACTIVE && !sBadSectorsList[ubSectorX][ubSectorY] )
if ( !(StrategicMap[CALCULATE_STRATEGIC_INDEX( ubSectorX, ubSectorY )].usAirType & AIRSPACE_ENEMY_ACTIVE) && !sBadSectorsList[ubSectorX][ubSectorY] )
{
gsMercArriveSectorX = ubSectorX;
gsMercArriveSectorY = ubSectorY;
@@ -5324,6 +5327,72 @@ void UpdateAirspaceControl( void )
UpdateRefuelSiteAvailability( );
}
// get the maximum distance from a SAM to its covered sectors (in principle, not taking into account status)
FLOAT GetSAMMaxDistanceToCoveredSector( UINT8 usSam )
{
FLOAT maxdist = 0.0f;
if ( usSam < NUMBER_OF_SAMS )
{
UINT8 samsector = pSamList[usSam];
UINT8 sam_x = SECTORX( samsector );
UINT8 sam_y = SECTORY( samsector );
for ( int x = 1; x < MAP_WORLD_X - 1; ++x )
{
for ( int y = 1; y < MAP_WORLD_Y - 1; ++y )
{
if ( ubSAMControlledSectors[y][x] & (1 << usSam) )
{
FLOAT dist = std::sqrt( (sam_x - x)*(sam_x - x) + (sam_y - y)*(sam_y - y) );
if ( maxdist < dist )
maxdist = dist;
}
}
}
}
return maxdist;
}
BOOLEAN DoesSamCoverSector( UINT8 usSam, UINT8 usSector, BOOLEAN* apSamIsWorking )
{
if ( apSamIsWorking )
*apSamIsWorking = FALSE;
if ( usSam < NUMBER_OF_SAMS )
{
// can this sam control this sector in principle?
if ( ubSAMControlledSectors[SECTORY( usSector )][SECTORX( usSector )] & (1 << usSam) )
{
UINT8 samsector = pSamList[usSam];
if ( StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( samsector )].bSAMCondition >= MIN_CONDITION_FOR_SAM_SITE_TO_WORK && StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( samsector )].sSamHackStatus > 0 )
{
if ( apSamIsWorking )
*apSamIsWorking = TRUE;
}
FLOAT dist = std::sqrt( (SECTORX( samsector ) - SECTORX( usSector ))*(SECTORX( samsector ) - SECTORX( usSector )) + (SECTORY( samsector ) - SECTORY( usSector ))*(SECTORY( samsector ) - SECTORY( usSector )) );
// determine max distance SAM has to cover
FLOAT sammaxdistance = GetSAMMaxDistanceToCoveredSector( usSam );
// allowed range ratio according to status and hacking
FLOAT samrangeratio = StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( samsector )].bSAMCondition * StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( samsector )].sSamHackStatus / 10000.0f;
// can this SAM currently cover this sector?
if ( dist <= sammaxdistance * samrangeratio )
{
return TRUE;
}
}
}
return FALSE;
}
BOOLEAN IsThereAFunctionalSAMSiteInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
@@ -5333,24 +5402,23 @@ BOOLEAN IsThereAFunctionalSAMSiteInSector( INT16 sSectorX, INT16 sSectorY, INT8
}
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].bSAMCondition < MIN_CONDITION_FOR_SAM_SITE_TO_WORK )
{
return(FALSE);
}
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY )].sSamHackStatus <= 0 )
return(FALSE);
return(TRUE);
}
BOOLEAN IsThisSectorASAMSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
INT32 cnt;
// is the sector above ground?
if ( bSectorZ != 0 )
{
return(FALSE);
}
for ( cnt = 0; cnt < NUMBER_OF_SAMS; cnt++ )
for ( INT32 cnt = 0; cnt < NUMBER_OF_SAMS; ++cnt )
{
if ( (sSectorX == gpSamSectorX[cnt]) && (sSectorY == gpSamSectorY[cnt]) )
return(TRUE);
@@ -5446,6 +5514,15 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
if ( guiCurrentSaveGameVersion < MILITIA_MOVEMENT )
StrategicMap[i].usFlags = 0;
}
if ( guiCurrentSaveGameVersion < HACKABLE_SAMS )
{
// all SAM sites start game in perfect working condition
for ( UINT32 cnt = 0; cnt < NUMBER_OF_SAMS; ++cnt )
{
StrategicMap[gpSamSectorX[cnt] + (MAP_WORLD_X * gpSamSectorY[cnt])].sSamHackStatus = 100;
}
}
// Load the Sector Info
uiSize = sizeof(SECTORINFO);
+5
View File
@@ -119,8 +119,12 @@ void JumpIntoAdjacentSector( UINT8 ubDirection, UINT8 ubJumpCode, INT32 sAdditio
BOOLEAN CanGoToTacticalInSector( INT16 sX, INT16 sY, UINT8 ubZ );
extern UINT32 ubSAMControlledSectors[MAP_WORLD_Y][MAP_WORLD_X];
void UpdateAirspaceControl( void );
BOOLEAN DoesSamCoverSector( UINT8 usSam, UINT8 usSector, BOOLEAN* apSamIsWorking = NULL );
BOOLEAN IsThisSectorASAMSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// init sam sites
@@ -186,6 +190,7 @@ BOOLEAN IsSectorRoad( INT16 sSectorX, INT16 sSectorY ); // added by Flugente
INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY );
INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void SetSamHackStatus( INT16 sSectorX, INT16 sSectorY, INT8 sStatus );
void SetupProfileInsertionDataForSoldier( SOLDIERTYPE *pSoldier );
+1 -1
View File
@@ -872,7 +872,7 @@ void CheckForValidArrivalSector( )
if( sSectorGridNo2 >=1 && sSectorGridNo2 < ( ( MAP_WORLD_X - 1 ) * ( MAP_WORLD_X - 1 ) ) && sSectorGridNo2 >= leftmost && sSectorGridNo2 < ( leftmost + MAP_WORLD_X ) )
{
if ( !StrategicMap[ sSectorGridNo2 ].fEnemyControlled && !StrategicMap[ sSectorGridNo2 ].usAirType != AIRSPACE_ENEMY_ACTIVE )
if ( !StrategicMap[ sSectorGridNo2 ].fEnemyControlled && (StrategicMap[ sSectorGridNo2 ].usAirType & AIRSPACE_ENEMY_ACTIVE) )
{
uiRange = StrategicPythSpacesAway( sSectorGridNo2, sSectorGridNo );
+2
View File
@@ -4227,9 +4227,11 @@ STR16 pwMiscSectorStrings[] =
L"分区",
L"物品数量",
L"未知",
L"已占领",
L"",
L"",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory
+2
View File
@@ -4229,9 +4229,11 @@ STR16 pwMiscSectorStrings[] =
L"Sector",
L"# Items",
L"Onbekend",
L"Gecontrolleerd",
L"Ja",
L"Nee",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory
+2
View File
@@ -4227,9 +4227,11 @@ STR16 pwMiscSectorStrings[] =
L"Sector",
L"# of Items",
L"Unknown",
L"Controlled",
L"Yes",
L"No",
L"Status/Software status:",
};
// error strings for inventory
+2
View File
@@ -4233,9 +4233,11 @@ STR16 pwMiscSectorStrings[] =
L"Secteur ",
L"Nombre d'objets ",
L"Inconnu",
L"Contrôlé ",
L"Oui",
L"Non",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory
+2
View File
@@ -4225,9 +4225,11 @@ STR16 pwMiscSectorStrings[] =
L"Sektor",
L"# der Gegenstände",
L"Unbekannt",
L"Kontrolliert",
L"Ja",
L"Nein",
L"Status/Software Status:",
};
// error strings for inventory
+2
View File
@@ -4223,9 +4223,11 @@ STR16 pwMiscSectorStrings[] =
L"Settore",
L"# di oggetti",
L"Sconosciuto",
L"Controllato",
L"",
L"No",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory
+2
View File
@@ -4234,9 +4234,11 @@ STR16 pwMiscSectorStrings[] =
L"Sektor",
L"Przedmiotów",
L"Nieznane",
L"Pod kontrolą",
L"Tak",
L"Nie",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory
+2
View File
@@ -4227,9 +4227,11 @@ STR16 pwMiscSectorStrings[] =
L"Сектор",
L"Количество предметов",
L"Неизвестно",
L"Под контролем",
L"Да",
L"Нет",
L"Status/Software status:", // TODO.Translate
};
// error strings for inventory