mirror of
https://github.com/1dot13/source.git
synced 2026-09-09 14:46:05 +02:00
- New Feature: Arulco special division controls other features to fight the player. For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=tree&goto=343706&#msg_343706
- New Feature: Enemy helicopters allow the AI to rapidly deploy troops aross the map. For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=tree&goto=343707&#msg_343707. GameDir <= r2279 is required. - Fix: income of mine 0 was not correctly calculated git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8015 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+1425
File diff suppressed because it is too large
Load Diff
+120
@@ -0,0 +1,120 @@
|
||||
#ifndef __ASD_H
|
||||
#define __ASD_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Flugente (bears-pit.com)
|
||||
*/
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/** Flugente: Arulco special division decision code
|
||||
*
|
||||
* As I do not want to alter the current strategic AI (fragile and obscure as it is),
|
||||
* I am leaving the control over a number of new toys to a second 'AI' - the 'Arulco Special Division'.
|
||||
* This should control if, how and when new features are used by the AI.
|
||||
*
|
||||
* It has its own 'budget', which allows it to purchase new actions. This serves to limit the amount of the AIs actions.
|
||||
* It also gives the player a way to compete with the AI - lower the AI budget, and the AI can do less harm.
|
||||
* For example, part of the AI budget might come from mine income, which the player can take away.
|
||||
*
|
||||
* If possible, the AI should have to buy and maintain its assets.
|
||||
* This way the player could harm the AI by specifically targetting those assets if he chooses so.
|
||||
* Ideally this gives the player another immersive way to do sth. in the game.
|
||||
* For example, enemy helicopters have to be bought, fuelled and repaired.
|
||||
* In order to stop enemy heli raids, the player could
|
||||
* - shoot them down
|
||||
* - steal enemy fuel deliveries
|
||||
* - sabotage enemy helis in their airfield
|
||||
*
|
||||
* There is a cyclic update of this AI. Each time the AI decides whether it wants (and can afford) new assets.
|
||||
* These assets then have to be ordered and can only be used once arrived.
|
||||
* The AI also decides how to use these assets.
|
||||
*/
|
||||
|
||||
void InitASD( );
|
||||
BOOLEAN SaveASDData( HWFILE hwFile );
|
||||
BOOLEAN LoadASDData( HWFILE hwFile );
|
||||
|
||||
// when called, evaluate the current situation, and perform actions to harm the player if necessary
|
||||
void UpdateASD( );
|
||||
|
||||
// decide whether to purchase something
|
||||
void ASDDecideOnPurchases();
|
||||
|
||||
// decide in what to do with helicopters
|
||||
void ASDDecideHeliOperations();
|
||||
|
||||
// various flags for the AI to remember
|
||||
#define ASDFACT_HELI_UNLOCKED 0x00000001 // AI is allowed to purchase helicopters
|
||||
#define ASDFACT_JEEP_UNLOCKED 0x00000002 // AI is allowed to purchase jeeps
|
||||
#define ASDFACT_TANK_UNLOCKED 0x00000004 // AI is allowed to purchase tanks
|
||||
|
||||
void SetASDFlag( UINT32 aFlag );
|
||||
|
||||
UINT32 ASDResourceDeliveryTime( UINT8 aType );
|
||||
UINT32 ASDResourceCostMoney( UINT8 aType );
|
||||
|
||||
// add resources to the AIs resource pool
|
||||
void AddStrategicAIResources( UINT8 aType, INT32 aAmount );
|
||||
void ASDReceiveOrderedStrategicAIResources( UINT8 aType, INT32 aAmount );
|
||||
|
||||
// enemy helis
|
||||
class ENEMY_HELI
|
||||
{
|
||||
public:
|
||||
// determine best heli flight path (minimising contact to hostile SAM sectors) and return number of possible SAM contacts
|
||||
UINT8 SetHeliFlightPath( UINT8 aDest );
|
||||
|
||||
void Destroy( );
|
||||
|
||||
public:
|
||||
UINT32 flagmask; // flags: destroyed, refueling...
|
||||
UINT8 sector_current; // we are here
|
||||
UINT8 sector_destination; // we want to fly here
|
||||
UINT8 sector_waypoint; // a sector we travel to between our starting point and our destiantion. Choosing this gives us a way to plot a path minimising SAM-exposure
|
||||
UINT8 sector_home; // this is where our base is
|
||||
UINT8 troopcount; // number of troops we carry
|
||||
UINT8 hp;
|
||||
UINT8 fuel;
|
||||
};
|
||||
|
||||
extern std::vector<ENEMY_HELI> gEnemyHeliVector;
|
||||
|
||||
void EnemyHeliInit( );
|
||||
|
||||
void AddNewHeli( );
|
||||
|
||||
// all enemy helis carrying troops in this sector drop these into combat, and get the order to head home
|
||||
void EnemyHeliTroopDrop( UINT8 aSector );
|
||||
|
||||
std::set<UINT8> GetEnemyHeliSectors( BOOLEAN afKnownToPlayer );
|
||||
|
||||
void UpdateEnemyHeliRepair( INT16 id );
|
||||
void UpdateEnemyHeliRefuel( INT16 id );
|
||||
void UpdateEnemyHeli( INT16 id );
|
||||
void EnemyHeliSAMCheck( INT16 id );
|
||||
void EnemyHeliMANPADSCheck( INT16 id );
|
||||
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.
|
||||
UINT8 GetNextEnemyHeliSector( UINT8 aStart, UINT8 aDest );
|
||||
|
||||
void HandleEnemyHelicopterOnGroundGraphic( );
|
||||
|
||||
void UpdateAndDamageEnemyHeliIfFound( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT32 sGridNo, UINT8 ubDamage, BOOLEAN aDestroyed = FALSE );
|
||||
|
||||
|
||||
// enemy tanks (how and when they are used)
|
||||
UINT32 ASDResourceCostFuel( UINT8 aType );
|
||||
|
||||
// if ASD is used, any tanks the queen uses in mobile attacks come from its pool, and we have to account for that
|
||||
BOOLEAN ASDSoldierUpgradeToTank( );
|
||||
|
||||
#endif //__ASD_H
|
||||
@@ -3209,6 +3209,44 @@ UINT32 CalculateSnitchPrisonGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts
|
||||
return( usValue );
|
||||
}
|
||||
|
||||
// Flugente: Determine the best cth with SAMs in a sector, and which merc has that cth if present
|
||||
FLOAT GetBestSAMOperatorCTH_Player( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT16 *pubID )
|
||||
{
|
||||
// if nobody is here, nobody can fire
|
||||
FLOAT bestsamcth = 0.0f;
|
||||
*pubID = NOBODY;
|
||||
|
||||
// militia can at least operate the thing, but don't count on them hitting anything...
|
||||
if ( NumNonPlayerTeamMembersInSector( sSectorX, sSectorY, MILITIA_TEAM ) )
|
||||
bestsamcth = 40.0f;
|
||||
|
||||
// loop over all mercs present. Best cth wins
|
||||
UINT16 uiCnt = 0;
|
||||
SOLDIERTYPE* pSoldier = NULL;
|
||||
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier && pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE && (pSoldier->sSectorX == sSectorX) && (pSoldier->sSectorY == sSectorY) && (pSoldier->bSectorZ == sSectorZ) )
|
||||
{
|
||||
INT16 personal_bestsamcth = 70.0f +
|
||||
15 * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) +
|
||||
10 * NUM_SKILL_TRAITS( pSoldier, TECHNICIAN_NT ) +
|
||||
2 * NUM_SKILL_TRAITS( pSoldier, DEMOLITIONS_NT ) +
|
||||
5 * NUM_SKILL_TRAITS( pSoldier, RADIO_OPERATOR_NT );
|
||||
|
||||
personal_bestsamcth = (personal_bestsamcth * (100.0f + pSoldier->GetBackgroundValue( BG_PERC_SAM_CTH ))) / 100.0f;
|
||||
|
||||
if ( personal_bestsamcth > bestsamcth )
|
||||
{
|
||||
bestsamcth = personal_bestsamcth;
|
||||
*pubID = uiCnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestsamcth;
|
||||
}
|
||||
|
||||
// anv: handle prisoners exposing snitch as a snitch
|
||||
BOOL HandleSnitchExposition(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
|
||||
@@ -260,6 +260,9 @@ UINT32 CalculatePrisonGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts );
|
||||
|
||||
UINT32 CalculateSnitchInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts );
|
||||
|
||||
// Flugente: Determine the best cth with SAMs in a sector, and which merc has that cth if present
|
||||
FLOAT GetBestSAMOperatorCTH_Player( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT16 *pubID );
|
||||
|
||||
// Flugente: determine max items we can move, and the sector distance
|
||||
|
||||
// get bonus tarining pts due to an instructor for this student
|
||||
|
||||
@@ -441,6 +441,7 @@ typedef enum
|
||||
// -------- added by Flugente: sector info flags --------
|
||||
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
#define SECTORINFO_VOLUNTEERS_RECENTLY_RECRUITED 0x01 //1 // we recruited volunteers here. Until this flag is removed, newly created civilians wont be potential volunteers anymore
|
||||
#define SECTORINFO_ENEMYHELI_SHOTDOWN 0x02 //2 // an enemy helicopter was shot down here. The first time after that we enter this sector, there is a chance to find a downed pilot here
|
||||
|
||||
typedef struct SECTORINFO
|
||||
{
|
||||
|
||||
@@ -717,7 +717,7 @@ void HandleManualPaymentFacilityDebt( void )
|
||||
// HEADROCK HAM 3.6: Apply income bonuses from Facility Work to a specific mine.
|
||||
INT32 MineIncomeModifierFromFacility( UINT8 ubMine )
|
||||
{
|
||||
Assert (ubMine > 0 && ubMine < MAX_NUMBER_OF_MINES);
|
||||
Assert (ubMine >= 0 && ubMine < MAX_NUMBER_OF_MINES);
|
||||
|
||||
SOLDIERTYPE *pSoldier;
|
||||
INT32 iModifier = 0;
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "MilitiaSquads.h"
|
||||
#include "PMC.h" // added by Flugente
|
||||
#include "finances.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#include "Player Command.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "connect.h"
|
||||
@@ -573,7 +575,47 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
|
||||
EndQuest( QUEST_KINGPIN_ANGEL_MARIA, gWorldSectorX, gWorldSectorY );
|
||||
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
case EVENT_ASD_UPDATE:
|
||||
UpdateASD();
|
||||
break;
|
||||
|
||||
case EVENT_ASD_PURCHASE_FUEL:
|
||||
if ( IsSectorEnemyControlled( SECTORX( gGameExternalOptions.usASDSupplyArrivalSector ), SECTORY( gGameExternalOptions.usASDSupplyArrivalSector ), 0 ) )
|
||||
ASDReceiveOrderedStrategicAIResources( ASD_FUEL, pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ASD_PURCHASE_JEEP:
|
||||
if ( IsSectorEnemyControlled( SECTORX( gGameExternalOptions.usASDSupplyArrivalSector ), SECTORY( gGameExternalOptions.usASDSupplyArrivalSector ), 0 ) )
|
||||
ASDReceiveOrderedStrategicAIResources( ASD_JEEP, pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ASD_PURCHASE_TANK:
|
||||
if ( IsSectorEnemyControlled( SECTORX( gGameExternalOptions.usASDSupplyArrivalSector ), SECTORY( gGameExternalOptions.usASDSupplyArrivalSector ), 0 ) )
|
||||
ASDReceiveOrderedStrategicAIResources( ASD_TANK, pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ASD_PURCHASE_HELI:
|
||||
if ( IsSectorEnemyControlled( SECTORX( gGameExternalOptions.usEnemyHeliBaseSector ), SECTORY( gGameExternalOptions.usEnemyHeliBaseSector ), 0 ) )
|
||||
ASDReceiveOrderedStrategicAIResources( ASD_HELI, pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ENEMY_HELI_UPDATE:
|
||||
UpdateEnemyHeli( pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ENEMY_HELI_REPAIR:
|
||||
UpdateEnemyHeliRepair( pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_ENEMY_HELI_REFUEL:
|
||||
UpdateEnemyHeliRefuel( pEvent->uiParam );
|
||||
break;
|
||||
|
||||
case EVENT_SAMSITE_REPAIRED:
|
||||
RepairSamSite( pEvent->uiParam );
|
||||
break;
|
||||
}
|
||||
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
|
||||
return TRUE;
|
||||
|
||||
@@ -120,6 +120,18 @@ enum
|
||||
EVENT_KINGPIN_BOUNTY_END_KILLEDTHEM,
|
||||
EVENT_KINGPIN_BOUNTY_END_TIME_PASSED,
|
||||
|
||||
EVENT_ASD_UPDATE, // Flugente: the queen's special division decides it's next action
|
||||
EVENT_ASD_PURCHASE_FUEL,
|
||||
EVENT_ASD_PURCHASE_JEEP,
|
||||
EVENT_ASD_PURCHASE_TANK,
|
||||
EVENT_ASD_PURCHASE_HELI,
|
||||
|
||||
EVENT_ENEMY_HELI_UPDATE, // Flugente: move enemy helicopter to another sector
|
||||
EVENT_ENEMY_HELI_REPAIR,
|
||||
EVENT_ENEMY_HELI_REFUEL,
|
||||
|
||||
EVENT_SAMSITE_REPAIRED, // Flugente: have a SAM site be fully repaired
|
||||
|
||||
NUMBER_OF_EVENT_TYPES_PLUS_ONE,
|
||||
NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1
|
||||
};
|
||||
|
||||
@@ -115,6 +115,15 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={
|
||||
L"KingpinBounty1",
|
||||
L"KingpinBounty2",
|
||||
L"KingpinBounty3",
|
||||
L"ASDUpdate",
|
||||
L"ASDPurchaseFuel",
|
||||
L"ASDPurchaseJeep",
|
||||
L"ASDPurchaseTank",
|
||||
L"ASDPurchaseHeli",
|
||||
L"EnemyHeliUpdate",
|
||||
L"EnemyHeliRepair",
|
||||
L"EnemyHeliRefuel",
|
||||
L"SAMsiteRepaired",
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "Map Screen Interface Map Inventory.h"//dnl ch51 081009
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "PMC.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Vehicles.h"
|
||||
@@ -499,13 +500,16 @@ void InitStrategicLayer( void )
|
||||
// re-set up leave list arrays for dismissed mercs
|
||||
InitLeaveList( );
|
||||
|
||||
// Flugente: se up VIP locations
|
||||
void InitVIPSectors( );
|
||||
// Flugente: set up VIP locations
|
||||
InitVIPSectors();
|
||||
|
||||
// Flugente: init special AI
|
||||
InitASD();
|
||||
|
||||
#ifdef JA2UB
|
||||
#ifdef JA2UB
|
||||
LuaInitStrategicLayer(0); //JA25 UB InitStrategicLayer.lua
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// reset time compression mode to X0 (this will also pause it)
|
||||
SetGameTimeCompressionLevel( TIME_COMPRESS_X0 );
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "Debug Control.h"
|
||||
#include "expat.h"
|
||||
#include "merc entering.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Vehicles.h"
|
||||
@@ -106,6 +107,7 @@ INT32 iHelicopterVehicleId = -1;
|
||||
|
||||
// helicopter icon
|
||||
UINT32 guiHelicopterIcon;
|
||||
UINT32 guiEnemyHelicopterIcon;
|
||||
|
||||
// total distance travelled
|
||||
INT32 iTotalHeliDistanceSinceRefuel = 0;
|
||||
@@ -1292,6 +1294,9 @@ void LandHelicopter( void )
|
||||
HandleKillChopperMeanwhileScene();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Flugente: once the AI 'learns' of the player using helis, it wants some for itself
|
||||
SetASDFlag( ASDFACT_HELI_UNLOCKED );
|
||||
}
|
||||
|
||||
|
||||
@@ -2670,19 +2675,19 @@ void AddHelicopterToMaps( BOOLEAN fAdd, UINT8 ubSite )
|
||||
InvalidateWorldRedundency();
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
// ATE: If any mercs here, bump them off!
|
||||
// ATE: If any mercs here, bump them off!
|
||||
ConvertGridNoToXY( iGridNo, &sCentreGridX, &sCentreGridY );
|
||||
|
||||
for( sGridY = sCentreGridY - 5; sGridY < sCentreGridY + 5; sGridY++ )
|
||||
{
|
||||
for( sGridX = sCentreGridX - 5; sGridX < sCentreGridX + 5; sGridX++ )
|
||||
for( sGridY = sCentreGridY - 5; sGridY < sCentreGridY + 5; sGridY++ )
|
||||
{
|
||||
iGridNo = MAPROWCOLTOPOS( sGridY, sGridX );
|
||||
for( sGridX = sCentreGridX - 5; sGridX < sCentreGridX + 5; sGridX++ )
|
||||
{
|
||||
iGridNo = MAPROWCOLTOPOS( sGridY, sGridX );
|
||||
|
||||
BumpAnyExistingMerc( iGridNo );
|
||||
BumpAnyExistingMerc( iGridNo );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove from the world
|
||||
@@ -2695,9 +2700,62 @@ void AddHelicopterToMaps( BOOLEAN fAdd, UINT8 ubSite )
|
||||
|
||||
InvalidateWorldRedundency();
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
}
|
||||
|
||||
void AddEnemyHelicopterToMaps( BOOLEAN fAdd, BOOLEAN fDestroyed, INT32 aGridno, INT32 aTileIndex )
|
||||
{
|
||||
// for safety, remove the old one first
|
||||
{
|
||||
// remove from the world
|
||||
RemoveStruct( aGridno, (UINT16)aTileIndex );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 1) );
|
||||
RemoveStruct( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + 2) );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 3) );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 4) );
|
||||
RemoveStruct( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + 5) );
|
||||
|
||||
// for safety reasons, both versions are to be removed
|
||||
RemoveStruct( aGridno, (UINT16)aTileIndex + 6 );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 6 + 1) );
|
||||
RemoveStruct( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + 6 + 2) );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 6 + 3) );
|
||||
RemoveStruct( aGridno, (UINT16)(aTileIndex + 6 + 4) );
|
||||
RemoveStruct( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + 6 + 5) );
|
||||
|
||||
InvalidateWorldRedundency( );
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
|
||||
if ( fAdd )
|
||||
{
|
||||
INT16 sCentreGridX, sCentreGridY;
|
||||
|
||||
INT16 offset = fDestroyed ? 6 : 0;
|
||||
|
||||
AddHeliPiece( aGridno, (UINT16)aTileIndex + offset );
|
||||
AddHeliPiece( aGridno, (UINT16)(aTileIndex + offset + 1) );
|
||||
AddHeliPiece( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + offset + 2) );
|
||||
AddHeliPiece( aGridno, (UINT16)(aTileIndex + offset + 3) );
|
||||
AddHeliPiece( aGridno, (UINT16)(aTileIndex + offset + 4) );
|
||||
AddHeliPiece( (aGridno - WORLD_COLS * 5), (UINT16)(aTileIndex + offset + 5) );
|
||||
|
||||
InvalidateWorldRedundency( );
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
// ATE: If any mercs here, bump them off!
|
||||
ConvertGridNoToXY( aGridno, &sCentreGridX, &sCentreGridY );
|
||||
|
||||
for ( INT16 sGridY = sCentreGridY - 5; sGridY < sCentreGridY + 5; sGridY++ )
|
||||
{
|
||||
for ( INT16 sGridX = sCentreGridX - 5; sGridX < sCentreGridX + 5; sGridX++ )
|
||||
{
|
||||
aGridno = MAPROWCOLTOPOS( sGridY, sGridX );
|
||||
|
||||
BumpAnyExistingMerc( aGridno );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ extern BOOLEAN fHoveringHelicopter;
|
||||
|
||||
// helicopter icon
|
||||
extern UINT32 guiHelicopterIcon;
|
||||
extern UINT32 guiEnemyHelicopterIcon;
|
||||
|
||||
// helicopter destroyed
|
||||
extern BOOLEAN fHelicopterDestroyed;
|
||||
@@ -293,6 +294,8 @@ BOOLEAN CanHelicopterTakeOff( void );
|
||||
|
||||
void InitializeHelicopter( void );
|
||||
|
||||
void AddEnemyHelicopterToMaps( BOOLEAN fAdd, BOOLEAN fDestroyed, INT32 aGridno, INT32 aTileIndex );
|
||||
|
||||
BOOLEAN IsSkyriderIsFlyingInSector( INT16 sSectorX, INT16 sSectorY );
|
||||
|
||||
BOOLEAN IsGroupTheHelicopterGroup( GROUP *pGroup );
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "Map Information.h"
|
||||
#include "Air Raid.h"
|
||||
#include "Auto Resolve.h"
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Quests.h"
|
||||
@@ -4248,6 +4249,77 @@ void DisplayPositionOfHelicopter( void )
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayPositionOfEnemyHelicopter()
|
||||
{
|
||||
static INT16 sOldMapX = 0, sOldMapY = 0;
|
||||
// INT16 sX =0, sY = 0;
|
||||
FLOAT flRatio = 0.0;
|
||||
UINT32 x, y;
|
||||
UINT16 minX, minY, maxX, maxY;
|
||||
HVOBJECT hHandle;
|
||||
INT32 iNumberOfPeopleInHelicopter = 0;
|
||||
CHAR16 sString[4];
|
||||
|
||||
INT32 MAP_MVT_ICON_FONT = TINYFONT1;
|
||||
|
||||
AssertMsg( (sOldMapX >= 0) && (sOldMapX < SCREEN_WIDTH), String( "DisplayPositionOfHelicopter: Invalid sOldMapX = %d", sOldMapX ) );
|
||||
AssertMsg( (sOldMapY >= 0) && (sOldMapY < SCREEN_HEIGHT), String( "DisplayPositionOfHelicopter: Invalid sOldMapY = %d", sOldMapY ) );
|
||||
|
||||
// TODO: different icon
|
||||
|
||||
// HEADROCK HAM 5: Now has to be done here to get the size of the helicopter icon.
|
||||
GetVideoObject( &hHandle, guiEnemyHelicopterIcon );
|
||||
|
||||
UINT16 usIconWidth = hHandle->pETRLEObject[0].usWidth;
|
||||
UINT16 usIconHeight = hHandle->pETRLEObject[0].usHeight;
|
||||
UINT16 usIconOffsetX = hHandle->pETRLEObject[0].sOffsetX;
|
||||
UINT16 usIconOffsetY = hHandle->pETRLEObject[0].sOffsetY;
|
||||
|
||||
// restore background on map where it is
|
||||
if ( sOldMapX != 0 )
|
||||
{
|
||||
RestoreExternBackgroundRect( sOldMapX + usIconOffsetX, sOldMapY + usIconOffsetY, usIconWidth, usIconHeight );
|
||||
sOldMapX = 0;
|
||||
}
|
||||
|
||||
std::set<UINT8> helisectorset = GetEnemyHeliSectors( TRUE ); // if set to FALSE, display helicopters regardless of player knowledge
|
||||
|
||||
for ( std::set<UINT8>::iterator it = helisectorset.begin( ); it != helisectorset.end( ); ++it)
|
||||
{
|
||||
UINT8 sector = (*it);
|
||||
UINT8 sector_x = SECTORX( sector );
|
||||
UINT8 sector_y = SECTORY( sector );
|
||||
|
||||
// grab min and max locations to interpolate sub sector position
|
||||
minX = MAP_VIEW_START_X + MAP_GRID_X * (sector_x);
|
||||
maxX = MAP_VIEW_START_X + MAP_GRID_X * (sector_x);
|
||||
minY = MAP_VIEW_START_Y + MAP_GRID_Y * (sector_y);
|
||||
maxY = MAP_VIEW_START_Y + MAP_GRID_Y * (sector_y);
|
||||
|
||||
AssertMsg( (minX >= 0) && (minX < SCREEN_WIDTH), String( "DisplayPositionOfHelicopter: Invalid minX = %d", minX ) );
|
||||
AssertMsg( (maxX >= 0) && (maxX < SCREEN_WIDTH), String( "DisplayPositionOfHelicopter: Invalid maxX = %d", maxX ) );
|
||||
AssertMsg( (minY >= 0) && (minY < SCREEN_WIDTH), String( "DisplayPositionOfHelicopter: Invalid minY = %d", minY ) );
|
||||
AssertMsg( (maxY >= 0) && (maxY < SCREEN_WIDTH), String( "DisplayPositionOfHelicopter: Invalid maxY = %d", maxY ) );
|
||||
|
||||
// IMPORTANT: Since min can easily be larger than max, we gotta cast to as signed value
|
||||
x = (UINT32)(minX + flRatio * ((INT16)maxX - (INT16)minX));
|
||||
y = (UINT32)(minY + flRatio * ((INT16)maxY - (INT16)minY));
|
||||
|
||||
// clip blits to mapscreen region
|
||||
ClipBlitsToMapViewRegion( );
|
||||
|
||||
BltVideoObject( FRAME_BUFFER, hHandle, HELI_ICON, x, y, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
|
||||
InvalidateRegion( x, y, x + usIconWidth, y + usIconHeight );
|
||||
|
||||
RestoreClipRegionToFullScreen( );
|
||||
|
||||
// now store the old stuff
|
||||
sOldMapX = (INT16)x;
|
||||
sOldMapY = (INT16)y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DisplayDestinationOfHelicopter( void )
|
||||
{
|
||||
|
||||
@@ -169,8 +169,9 @@ INT16 GetLastSectorOfMilitiaPath( void );
|
||||
// display info about helicopter path
|
||||
void DisplayDistancesForHelicopter( void );
|
||||
|
||||
// display where hei is
|
||||
// display where heli is
|
||||
void DisplayPositionOfHelicopter( void );
|
||||
void DisplayPositionOfEnemyHelicopter();
|
||||
|
||||
// check for click
|
||||
BOOLEAN CheckForClickOverHelicopterIcon( INT16 sX, INT16 sY );
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "GameSettings.h"
|
||||
#include "debug.h"
|
||||
#include "Overhead.h" // added by Flugente
|
||||
#include "Game Clock.h" // added by Flugente
|
||||
#include "Game Event Hook.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Strategic Mines.h"
|
||||
@@ -49,8 +51,10 @@ INT8 bCurrentTownMineSectorY = 0;
|
||||
INT8 bCurrentTownMineSectorZ = 0;
|
||||
|
||||
// inventory button
|
||||
UINT32 guiMapButtonInventoryImage[2];
|
||||
UINT32 guiMapButtonInventory[2];
|
||||
UINT32 guiMapButtonInventoryImage[3];
|
||||
UINT32 guiMapButtonInventory[3];
|
||||
|
||||
BOOLEAN guiSAMButtonDefined = FALSE;
|
||||
|
||||
UINT16 sTotalButtonWidth = 0;
|
||||
|
||||
@@ -91,12 +95,13 @@ void AddInventoryButtonForMapPopUpBox( void );
|
||||
// now remove the above button
|
||||
void RemoveInventoryButtonForMapPopUpBox( void );
|
||||
|
||||
// callback to turn on sector invneotry list
|
||||
// callback to turn on sector inventory list
|
||||
void MapTownMineInventoryButtonCallBack( GUI_BUTTON *btn, INT32 reason );
|
||||
void MapTownMineExitButtonCallBack( GUI_BUTTON *btn, INT32 reason );
|
||||
void MapTownSAMRepairButtonCallBack( GUI_BUTTON *btn, INT32 reason );
|
||||
void MinWidthOfTownMineInfoBox( void );
|
||||
|
||||
|
||||
extern INT32 GetCurrentBalance( void );
|
||||
|
||||
void DisplayTownInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
{
|
||||
@@ -207,9 +212,19 @@ void CreateDestroyTownInfoBox( void )
|
||||
// resize box to fit button
|
||||
pDimensions.iRight += BOX_BUTTON_WIDTH;
|
||||
}
|
||||
|
||||
|
||||
pDimensions.iBottom += BOX_BUTTON_HEIGHT;
|
||||
|
||||
for ( UINT16 x = 0; x < MAX_NUMBER_OF_SAMS; ++x )
|
||||
{
|
||||
if ( pSamList[x] == SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
|
||||
{
|
||||
pDimensions.iBottom += BOX_BUTTON_HEIGHT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetBoxSize( ghTownMineBox, pDimensions );
|
||||
|
||||
ShowBox( ghTownMineBox );
|
||||
@@ -1004,13 +1019,9 @@ void PositionTownMineInfoBox( void )
|
||||
{
|
||||
pPosition.iY = MapScreenRect.iBottom - pDimensions.iBottom - 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// reset position
|
||||
SetBoxPosition( ghTownMineBox, pPosition );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1024,8 +1035,7 @@ void AddInventoryButtonForMapPopUpBox( void )
|
||||
ETRLEObject *pTrav;
|
||||
INT16 sWidthA = 0, sWidthB = 0, sTotalBoxWidth = 0;
|
||||
HVOBJECT hHandle;
|
||||
|
||||
|
||||
|
||||
// load the button
|
||||
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
||||
FilenameForBPP("INTERFACE\\mapinvbtns.sti", VObjectDesc.ImageFile);
|
||||
@@ -1070,23 +1080,39 @@ void AddInventoryButtonForMapPopUpBox( void )
|
||||
(INT16)(sX ), (INT16)( sY ), BUTTON_TOGGLE , MSYS_PRIORITY_HIGHEST - 1,
|
||||
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)MapTownMineExitButtonCallBack );
|
||||
|
||||
// Flugente: if this is SAM site we control, we have the option to repair it if it is damagged
|
||||
guiSAMButtonDefined = FALSE;
|
||||
|
||||
for ( UINT16 x = 0; x < MAX_NUMBER_OF_SAMS; ++x )
|
||||
{
|
||||
if ( pSamList[x] == SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
|
||||
{
|
||||
StrategicMapElement *pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX(pSamList[x])]);
|
||||
|
||||
sX = pPosition.iX + (pDimensions.iRight - sTotalBoxWidth) / 3;
|
||||
sY = pPosition.iY + pDimensions.iBottom - ((BOX_BUTTON_HEIGHT + 5)) - BOX_BUTTON_HEIGHT;
|
||||
|
||||
guiMapButtonInventoryImage[2] = LoadButtonImage( "INTERFACE\\mapinvbtns.sti", -1, 1, -1, 3, -1 );
|
||||
|
||||
guiMapButtonInventory[2] = CreateIconAndTextButton( guiMapButtonInventoryImage[2], pMapPopUpInventoryText[2], BLOCKFONT2,
|
||||
FONT_WHITE, FONT_BLACK,
|
||||
FONT_WHITE, FONT_BLACK,
|
||||
TEXT_CJUSTIFIED,
|
||||
(INT16)(sX), (INT16)(sY), BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
||||
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)MapTownSAMRepairButtonCallBack );
|
||||
|
||||
guiSAMButtonDefined = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// delete video object
|
||||
DeleteVideoObjectFromIndex( uiObject );
|
||||
|
||||
/*
|
||||
// if below ground disable
|
||||
if( iCurrentMapSectorZ )
|
||||
{
|
||||
DisableButton( guiMapButtonInventory[ 0 ] );
|
||||
}
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void RemoveInventoryButtonForMapPopUpBox( void )
|
||||
{
|
||||
|
||||
// get rid of button
|
||||
RemoveButton( guiMapButtonInventory[0] );
|
||||
UnloadButtonImage( guiMapButtonInventoryImage[0] );
|
||||
@@ -1094,7 +1120,11 @@ void RemoveInventoryButtonForMapPopUpBox( void )
|
||||
RemoveButton( guiMapButtonInventory[1] );
|
||||
UnloadButtonImage( guiMapButtonInventoryImage[1] );
|
||||
|
||||
return;
|
||||
if ( guiSAMButtonDefined )
|
||||
{
|
||||
RemoveButton( guiMapButtonInventory[2] );
|
||||
UnloadButtonImage( guiMapButtonInventoryImage[2] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1102,13 +1132,13 @@ void MapTownMineInventoryButtonCallBack( GUI_BUTTON *btn, INT32 reason )
|
||||
{
|
||||
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
||||
{
|
||||
btn->uiFlags|=(BUTTON_CLICKED_ON);
|
||||
btn->uiFlags|=(BUTTON_CLICKED_ON);
|
||||
}
|
||||
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
|
||||
{
|
||||
if (btn->uiFlags & BUTTON_CLICKED_ON)
|
||||
if (btn->uiFlags & BUTTON_CLICKED_ON)
|
||||
{
|
||||
btn->uiFlags&=~(BUTTON_CLICKED_ON);
|
||||
btn->uiFlags&=~(BUTTON_CLICKED_ON);
|
||||
|
||||
// done
|
||||
fShowMapInventoryPool = TRUE;
|
||||
@@ -1126,7 +1156,6 @@ void MapTownMineInventoryButtonCallBack( GUI_BUTTON *btn, INT32 reason )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapTownMineExitButtonCallBack( GUI_BUTTON *btn, INT32 reason )
|
||||
{
|
||||
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
||||
@@ -1148,6 +1177,99 @@ void MapTownMineExitButtonCallBack( GUI_BUTTON *btn, INT32 reason )
|
||||
}
|
||||
}
|
||||
|
||||
void SAMRepairCallBack( UINT8 bExitValue )
|
||||
{
|
||||
if ( bExitValue == MSG_BOX_RETURN_YES )
|
||||
{
|
||||
for ( UINT16 x = 0; x < MAX_NUMBER_OF_SAMS; ++x )
|
||||
{
|
||||
if ( pSamList[x] == SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
|
||||
{
|
||||
StrategicMapElement *pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[x] )]);
|
||||
|
||||
if ( !pSAMStrategicMap->fEnemyControlled && pSAMStrategicMap->bSAMCondition < 100 )
|
||||
{
|
||||
UINT32 cost = (100 - pSAMStrategicMap->bSAMCondition) * 100;
|
||||
|
||||
AddTransactionToPlayersBook( SAM_REPAIR, 0, GetWorldTotalMin( ), -cost );
|
||||
|
||||
// remember this, so we don't accidentally pay for repair again
|
||||
pSAMStrategicMap->usFlags |= SAMSITE_REPAIR_ORDERED;
|
||||
|
||||
UINT32 time = (100 - pSAMStrategicMap->bSAMCondition) / 4 + 1;
|
||||
|
||||
AddStrategicEvent( EVENT_SAMSITE_REPAIRED, GetWorldTotalMin( ) + 60 * time, pSamList[x] );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapTownSAMRepairButtonCallBack( GUI_BUTTON *btn, INT32 reason )
|
||||
{
|
||||
if ( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
||||
{
|
||||
btn->uiFlags |= (BUTTON_CLICKED_ON);
|
||||
}
|
||||
else if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
|
||||
{
|
||||
if ( btn->uiFlags & BUTTON_CLICKED_ON )
|
||||
{
|
||||
btn->uiFlags &= ~(BUTTON_CLICKED_ON);
|
||||
|
||||
// done
|
||||
fMapPanelDirty = TRUE;
|
||||
fMapScreenBottomDirty = TRUE;
|
||||
fShowTownInfo = FALSE;
|
||||
|
||||
for ( UINT16 x = 0; x < MAX_NUMBER_OF_SAMS; ++x )
|
||||
{
|
||||
if ( pSamList[x] == SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
|
||||
{
|
||||
StrategicMapElement *pSAMStrategicMap = &(StrategicMap[SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[x] )]);
|
||||
|
||||
if ( pSAMStrategicMap->fEnemyControlled )
|
||||
{
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, szEnemyHeliText[1], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pSAMStrategicMap->bSAMCondition >= 100 )
|
||||
{
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, szEnemyHeliText[2], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pSAMStrategicMap->usFlags & SAMSITE_REPAIR_ORDERED )
|
||||
{
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, szEnemyHeliText[3], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
UINT32 cost = (100 - pSAMStrategicMap->bSAMCondition) * 100;
|
||||
|
||||
if ( cost > GetCurrentBalance( ) )
|
||||
{
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, szEnemyHeliText[4], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
UINT32 time = (100 - pSAMStrategicMap->bSAMCondition) / 4 + 1;
|
||||
|
||||
CHAR16 sSamSiteRepairPromptText[320];
|
||||
swprintf( sSamSiteRepairPromptText, szEnemyHeliText[5], cost, time );
|
||||
|
||||
// ask the player whether he really wants to do this
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, sSamSiteRepairPromptText, MAP_SCREEN, MSG_BOX_FLAG_YESNO, SAMRepairCallBack );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the min width of the town mine info pop up box
|
||||
void MinWidthOfTownMineInfoBox( void )
|
||||
|
||||
@@ -542,6 +542,13 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO
|
||||
return fWasPlayerControlled;
|
||||
}
|
||||
|
||||
BOOLEAN IsSectorEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
{
|
||||
if ( !bMapZ )
|
||||
return StrategicMap[SECTOR( sMapX, sMapY )].fEnemyControlled;
|
||||
|
||||
return !SectorInfo[SECTOR( sMapX, sMapY )].fPlayer[bMapZ];
|
||||
}
|
||||
|
||||
#ifdef JA2TESTVERSION
|
||||
void ClearMapControlledFlags( void )
|
||||
|
||||
@@ -14,6 +14,7 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO
|
||||
// set sector as player controlled
|
||||
BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested );
|
||||
|
||||
BOOLEAN IsSectorEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
|
||||
|
||||
#ifdef JA2TESTVERSION
|
||||
void ClearMapControlledFlags( void );
|
||||
|
||||
@@ -181,6 +181,8 @@ UINT8 gubEnemyEncounterCode = NO_ENCOUNTER_CODE;
|
||||
//would turn hostile, which would disable the ability to autoresolve the battle.
|
||||
BOOLEAN gubExplicitEnemyEncounterCode = NO_ENCOUNTER_CODE;
|
||||
|
||||
BOOLEAN gubSpecialEncounterCodeForEnemyHeli = FALSE;
|
||||
|
||||
//Location of the current battle (determines where the animated icon is blitted) and if the
|
||||
//icon is to be blitted.
|
||||
BOOLEAN gfBlitBattleSectorLocator = FALSE;
|
||||
@@ -607,8 +609,15 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
{
|
||||
if( !pBattleGroup )
|
||||
{
|
||||
//creature's attacking!
|
||||
gubEnemyEncounterCode = CREATURE_ATTACK_CODE;
|
||||
if ( gubSpecialEncounterCodeForEnemyHeli )
|
||||
{
|
||||
gubEnemyEncounterCode = ENEMY_INVASION_CODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//creature's attacking!
|
||||
gubEnemyEncounterCode = CREATURE_ATTACK_CODE;
|
||||
}
|
||||
}
|
||||
else if ( gpBattleGroup->usGroupTeam == OUR_TEAM )
|
||||
{
|
||||
@@ -929,6 +938,9 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
DisableButton( iPBButton[0] );
|
||||
#endif
|
||||
DoTransitionFromMapscreenToPreBattleInterface();
|
||||
|
||||
// clean up
|
||||
gubSpecialEncounterCodeForEnemyHeli = FALSE;
|
||||
}
|
||||
|
||||
void DoTransitionFromMapscreenToPreBattleInterface()
|
||||
|
||||
@@ -81,6 +81,8 @@ extern UINT8 gubPBSectorY;
|
||||
extern UINT8 gubPBSectorZ;
|
||||
|
||||
extern BOOLEAN gfCantRetreatInPBI;
|
||||
|
||||
extern BOOLEAN gubSpecialEncounterCodeForEnemyHeli;
|
||||
//SAVE END
|
||||
|
||||
void WakeUpAllMercsInSectorUnderAttack( void );
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "Soldier macros.h"
|
||||
#include "Morale.h"
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#ifdef JA2BETAVERSION
|
||||
@@ -1559,11 +1560,17 @@ void AddPossiblePendingEnemiesToBattle()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( (!PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) && !NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, MILITIA_TEAM ))
|
||||
|| !NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, ENEMY_TEAM ) )
|
||||
return;
|
||||
|
||||
// Flugente: if there is an enemy helicopter here, it can add reinforcements
|
||||
if ( gTacticalStatus.Team[ENEMY_TEAM].bAwareOfOpposition )
|
||||
{
|
||||
EnemyHeliTroopDrop( SECTOR( gWorldSectorX, gWorldSectorY ) );
|
||||
}
|
||||
|
||||
ubSlots = NumFreeSlots( ENEMY_TEAM );
|
||||
if(gGameExternalOptions.sMinDelayEnemyReinforcements)//dnl ch68 080913
|
||||
{
|
||||
|
||||
+34
-37
@@ -35,6 +35,7 @@
|
||||
#include "Scheduling.h"
|
||||
#include "Map Information.h"
|
||||
#include "interface dialogue.h"
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "GameInitOptionsScreen.h"
|
||||
@@ -1489,33 +1490,30 @@ void InitStrategicAI()
|
||||
//Some of the patrol groups aren't there at the beginning of the game. This is
|
||||
//based on the difficulty settings in the above patrol table.
|
||||
//if( gPatrolGroup[ i ].ubUNUSEDStartIfDifficulty <= gGameOptions.ubDifficultyLevel )
|
||||
{ //Add this patrol group now.
|
||||
{
|
||||
//Add this patrol group now.
|
||||
ubNumTroops = (UINT8)(gPatrolGroup[ i ].bSize + Random( 3 ) - 1);
|
||||
ubNumTroops = (UINT8)max( gubMinEnemyGroupSize, min( iMaxEnemyGroupSize, ubNumTroops ) );
|
||||
ubNumTanks = 0;
|
||||
|
||||
if( ubNumTroops && gGameExternalOptions.fArmyUsesTanksInPatrols && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
if ( ubNumTroops && gGameExternalOptions.fArmyUsesTanksInPatrols && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
UINT32 val2;
|
||||
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
|
||||
val2 = 1;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
|
||||
val2 = 2;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
|
||||
val2 = 3;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
val2 = 4;
|
||||
else
|
||||
{
|
||||
val2 = Random( 4 );
|
||||
if (val2 == 0) val2 = 1;
|
||||
}
|
||||
|
||||
UINT32 val2;
|
||||
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
|
||||
val2 = 1;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
|
||||
val2 = 2;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
|
||||
val2 = 3;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
val2 = 4;
|
||||
else
|
||||
{
|
||||
val2 = Random( 4 );
|
||||
if (val2 == 0) val2 = 1;
|
||||
}
|
||||
|
||||
if( Random( 10 ) < val2 && i != 3 && i != 4)
|
||||
|
||||
//if( Random( 10 ) < gGameOptions.ubDifficultyLevel && i != 3 && i != 4)
|
||||
|
||||
if ( Random( 10 ) < val2 && i != 3 && i != 4 )
|
||||
{
|
||||
ubNumTroops--;
|
||||
ubNumTanks++;
|
||||
@@ -2229,14 +2227,17 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
|
||||
pSector->ubNumElites = (UINT8)(pSector->ubNumElites + pGroup->pEnemyGroup->ubNumElites);
|
||||
pSector->ubNumTanks = (UINT8)(pSector->ubNumTanks + pGroup->pEnemyGroup->ubNumTanks);
|
||||
|
||||
#ifdef JA2BETAVERSION
|
||||
LogStrategicEvent( "%d reinforcements have arrived to garrison sector %c%d",
|
||||
pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops +
|
||||
pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumTanks, pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
|
||||
#endif
|
||||
#ifdef JA2BETAVERSION
|
||||
LogStrategicEvent( "%d reinforcements have arrived to garrison sector %c%d",
|
||||
pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops +
|
||||
pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumTanks, pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
|
||||
#endif
|
||||
|
||||
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 ].usFlags &= ~SAMSITE_REPAIR_ORDERED;
|
||||
|
||||
UpdateSAMDoneRepair( pGroup->ubSectorX, pGroup->ubSectorY, 0 );
|
||||
}
|
||||
}
|
||||
@@ -4551,8 +4552,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
grouptanks[ubCounter] = 0;
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
if( Random(10) < val )
|
||||
//if( Random(10) < gGameOptions.ubDifficultyLevel )
|
||||
if ( Random( 10 ) < val && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
grouptroops[ubCounter]--;
|
||||
grouptanks[ubCounter]++;
|
||||
@@ -4636,7 +4636,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
grouptanks[ubCounter] = 0;
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
if( Random(10) < value )
|
||||
if ( Random( 10 ) < value && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
grouptroops[ubCounter]--;
|
||||
grouptanks[ubCounter]++;
|
||||
@@ -4848,7 +4848,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value2 * 3);
|
||||
//ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
|
||||
// anv: replace one of soldiers with tank
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
if ( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usTankMinimumProgress && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
ubNumSoldiers--;
|
||||
ubNumTanks++;
|
||||
@@ -5114,8 +5114,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
// anv: replace one of soldiers with tank
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
if( Random( 10 ) < value4 )
|
||||
//if( Random( 10 ) < gGameOptions.ubDifficultyLevel )
|
||||
if ( Random( 10 ) < value4 && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
ubNumSoldiers--;
|
||||
ubNumTanks++;
|
||||
@@ -5242,8 +5241,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
|
||||
if( Random( 10 * 100 ) < value5 * direness )
|
||||
//if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * direness )
|
||||
if ( Random( 10 * 100 ) < value5 * direness && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
elitesThisSquad--;
|
||||
tanksThisSquad++;
|
||||
@@ -5398,8 +5396,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
// anv: replace one of soldiers with tank
|
||||
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks && HighestPlayerProgressPercentage() >= gGameExternalOptions.usTankMinimumProgress )
|
||||
{
|
||||
if( Random( 10 * 100 ) < value7 * HighestPlayerProgressPercentage() )
|
||||
//if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * HighestPlayerProgressPercentage() )
|
||||
if ( Random( 10 * 100 ) < value7 * HighestPlayerProgressPercentage( ) && ASDSoldierUpgradeToTank( ) )
|
||||
{
|
||||
ubNumSoldiers--;
|
||||
ubNumTanks++;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Campaign Types.h"
|
||||
#include "history.h"
|
||||
#include "Facilities.h"
|
||||
#include "ASD.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "GameInitOptionsScreen.h"
|
||||
@@ -549,17 +550,14 @@ INT32 GetAvailableWorkForceForMineForEnemy( INT8 bMineIndex )
|
||||
|
||||
// if mine is shut down
|
||||
if ( gMineStatus[ bMineIndex ].fShutDown)
|
||||
{
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
//bTownId = gMineLocation[ bMineIndex ].bAssociatedTown;
|
||||
bTownId = gMineStatus[ bMineIndex ].bAssociatedTown;
|
||||
|
||||
if( GetTownSectorSize( bTownId ) == 0 )
|
||||
{
|
||||
UINT8 townsize = GetTownSectorSize( bTownId );
|
||||
|
||||
if ( !townsize )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get workforce size (is 0-100 based on REVERSE of local town's loyalty)
|
||||
iWorkForceSize = 100 - gTownLoyalty[ bTownId ].ubRating;
|
||||
@@ -571,10 +569,10 @@ INT32 GetAvailableWorkForceForMineForEnemy( INT8 bMineIndex )
|
||||
*/
|
||||
|
||||
// now adjust for town size.. the number of sectors you control
|
||||
iWorkForceSize *= ( GetTownSectorSize( bTownId ) - GetTownSectorsUnderControl( bTownId ) );
|
||||
iWorkForceSize /= GetTownSectorSize( bTownId );
|
||||
iWorkForceSize *= (townsize - GetTownSectorsUnderControl( bTownId ));
|
||||
iWorkForceSize /= townsize;
|
||||
|
||||
return ( iWorkForceSize );
|
||||
return iWorkForceSize;
|
||||
}
|
||||
|
||||
INT32 GetCurrentWorkRateOfMineForPlayer( INT8 bMineIndex )
|
||||
@@ -604,8 +602,7 @@ INT32 MineAMine( INT8 bMineIndex )
|
||||
// will extract ore based on available workforce, and increment players income based on amount
|
||||
INT8 bMineType = 0;
|
||||
INT32 iAmtExtracted = 0;
|
||||
|
||||
|
||||
|
||||
Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) );
|
||||
|
||||
// is mine is empty
|
||||
@@ -620,7 +617,6 @@ INT32 MineAMine( INT8 bMineIndex )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// who controls the PRODUCTION in the mine ? (Queen receives production unless player has spoken to the head miner)
|
||||
if( PlayerControlsMine(bMineIndex) )
|
||||
{
|
||||
@@ -651,13 +647,16 @@ INT32 MineAMine( INT8 bMineIndex )
|
||||
// we didn't want mines to run out without player ever even going to them, so now the queen doesn't reduce the
|
||||
// amount remaining until the mine has produced for the player first (so she'd have to capture it).
|
||||
|
||||
// WANNE: We do not want to give money to the player, when the queen has captured the mine!
|
||||
/*// WANNE: We do not want to give money to the player, when the queen has captured the mine!
|
||||
if ( gMineStatus[ bMineIndex ].fMineHasProducedForPlayer )
|
||||
{
|
||||
// don't actually give her money, just take production away
|
||||
//iAmtExtracted = ExtractOreFromMine( bMineIndex , GetCurrentWorkRateOfMineForEnemy( bMineIndex ) );
|
||||
iAmtExtracted = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Flugente: if the enemy controls a mine, simply don't lower the amount of ore in the mine, so it can still run out when the player controls it
|
||||
iAmtExtracted = GetCurrentWorkRateOfMineForEnemy( bMineIndex );
|
||||
}
|
||||
|
||||
|
||||
@@ -679,27 +678,42 @@ void PostEventsForMineProduction(void)
|
||||
void HandleIncomeFromMines( void )
|
||||
{
|
||||
INT32 iIncome = 0;
|
||||
INT8 bCounter = 0;
|
||||
INT32 iIncome_Enemy = 0; // Flugente: new AI gets money from mines
|
||||
|
||||
// HEADROCK HAM 3.6: Modifier from Facilities
|
||||
INT32 iFacilityModifier = 0;
|
||||
|
||||
// mine each mine, check if we own it and such
|
||||
for( bCounter = 0; bCounter < MAX_NUMBER_OF_MINES; bCounter++ )
|
||||
for ( INT8 bCounter = 0; bCounter < MAX_NUMBER_OF_MINES; ++bCounter )
|
||||
{
|
||||
if (bCounter)
|
||||
if ( PlayerControlsMine( bCounter ) )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Add facility modifier as a percentage
|
||||
iFacilityModifier = 100 + MineIncomeModifierFromFacility( bCounter );
|
||||
|
||||
// mine this mine
|
||||
iIncome += (MineAMine( bCounter ) * iFacilityModifier) / 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mine this mine
|
||||
iIncome_Enemy += MineAMine( bCounter );
|
||||
}
|
||||
// mine this mine
|
||||
iIncome += (MineAMine( bCounter ) * iFacilityModifier) / 100;
|
||||
}
|
||||
|
||||
// HEADROCK HAM B1: Affected by external INI Option.
|
||||
iIncome = (iIncome * gGameExternalOptions.usMineIncomePercentage) / 100;
|
||||
iIncome_Enemy = (iIncome_Enemy * gGameExternalOptions.usMineIncomePercentage) / 100;
|
||||
|
||||
if( iIncome )
|
||||
{
|
||||
AddTransactionToPlayersBook( DEPOSIT_FROM_SILVER_MINE, 0, GetWorldTotalMin( ), iIncome );
|
||||
}
|
||||
|
||||
if ( iIncome_Enemy )
|
||||
{
|
||||
AddStrategicAIResources( ASD_MONEY, iIncome_Enemy );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "Interface.h" // added by Flugente for zBackground
|
||||
#include "Reinforcement.h" // added by Flugente for AddPossiblePendingMilitiaToBattle()
|
||||
#include "Militia Control.h" // added by Flugente for ResetMilitia()
|
||||
#include "Creature Spreading.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "MilitiaSquads.h"
|
||||
@@ -5940,3 +5941,195 @@ GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
void CheckCombatInSectorDueToUnusualEnemyArrival( UINT8 aTeam, INT16 sX, INT16 sY, INT8 sZ )
|
||||
{
|
||||
GROUP *curr;
|
||||
GROUP *pPlayerDialogGroup = NULL;
|
||||
PLAYERGROUP *pPlayer;
|
||||
SOLDIERTYPE *pSoldier;
|
||||
BOOLEAN fBattlePending = FALSE;
|
||||
BOOLEAN fAliveMerc = FALSE;
|
||||
BOOLEAN fMilitiaPresent = FALSE;
|
||||
BOOLEAN fCombatAbleMerc = FALSE;
|
||||
BOOLEAN fBloodCatAmbush = FALSE;
|
||||
|
||||
gubEnemyEncounterCode = ENEMY_INVASION_CODE;
|
||||
|
||||
gubSectorIDOfCreatureAttack = SECTOR(sX, sY);
|
||||
|
||||
gubSpecialEncounterCodeForEnemyHeli = TRUE;
|
||||
|
||||
HandleOtherGroupsArrivingSimultaneously( sX, sY, sZ );
|
||||
|
||||
curr = gpGroupList;
|
||||
while ( curr )
|
||||
{
|
||||
if ( curr->usGroupTeam == OUR_TEAM && curr->ubGroupSize )
|
||||
{
|
||||
if ( !curr->fBetweenSectors )
|
||||
{
|
||||
if ( curr->ubSectorX == sX && curr->ubSectorY == sY && !sZ )
|
||||
{
|
||||
if ( !GroupHasInTransitDeadOrPOWMercs( curr ) &&
|
||||
(!IsGroupTheHelicopterGroup( curr ) || !fHelicopterIsAirBorne) &&
|
||||
(!curr->fVehicle || NumberMercsInVehicleGroup( curr )) )
|
||||
{
|
||||
//Now, a player group is in this sector. Determine if the group contains any mercs that can fight.
|
||||
//Vehicles, EPCs and the robot doesn't count. Mercs below OKLIFE do.
|
||||
pPlayer = curr->pPlayerList;
|
||||
while ( pPlayer )
|
||||
{
|
||||
pSoldier = pPlayer->pSoldier;
|
||||
if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) )
|
||||
{
|
||||
if ( !AM_A_ROBOT( pSoldier ) &&
|
||||
!AM_AN_EPC( pSoldier ) &&
|
||||
pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
fCombatAbleMerc = TRUE;
|
||||
}
|
||||
if ( pSoldier->stats.bLife > 0 )
|
||||
{
|
||||
fAliveMerc = TRUE;
|
||||
}
|
||||
}
|
||||
pPlayer = pPlayer->next;
|
||||
}
|
||||
|
||||
if ( !pPlayerDialogGroup && fCombatAbleMerc )
|
||||
{
|
||||
pPlayerDialogGroup = curr;
|
||||
}
|
||||
|
||||
if ( fCombatAbleMerc )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if ( aTeam == ENEMY_TEAM )
|
||||
{
|
||||
if ( NumNonPlayerTeamMembersInSector( sX, sY, MILITIA_TEAM ) )
|
||||
{
|
||||
fMilitiaPresent = TRUE;
|
||||
fBattlePending = TRUE;
|
||||
}
|
||||
|
||||
if ( fAliveMerc )
|
||||
{
|
||||
fBattlePending = TRUE;
|
||||
}
|
||||
|
||||
// huh?
|
||||
if ( !NumNonPlayerTeamMembersInSector( sX, sY, ENEMY_TEAM ) )
|
||||
{
|
||||
fBattlePending = FALSE;
|
||||
}
|
||||
}
|
||||
else if ( aTeam == MILITIA_TEAM )
|
||||
{
|
||||
if ( NumNonPlayerTeamMembersInSector( sX, sY, ENEMY_TEAM ) )
|
||||
{
|
||||
fMilitiaPresent = TRUE;
|
||||
fBattlePending = TRUE;
|
||||
}
|
||||
|
||||
/*if ( fBattlePending )
|
||||
{
|
||||
if ( PossibleToCoordinateSimultaneousGroupArrivals( pGroup ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if ( !fAliveMerc && !fMilitiaPresent )
|
||||
{
|
||||
// empty vehicle, everyone dead, don't care. Enemies don't care.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fBattlePending )
|
||||
{
|
||||
//A battle is pending, but the players could be all unconcious or dead.
|
||||
//Go through every group until we find at least one concious merc. The looping will determine
|
||||
//if there are any live mercs and/or concious ones. If there are no concious mercs, but alive ones,
|
||||
//then we will go straight to autoresolve, where the enemy will likely annihilate them or capture them.
|
||||
//If there are no alive mercs, then there is nothing anybody can do. The enemy will completely ignore
|
||||
//this, and continue on.
|
||||
|
||||
StopTimeCompression( );
|
||||
|
||||
if ( gubNumGroupsArrivedSimultaneously )
|
||||
{
|
||||
//Because this is a battle case, clear all the group flags
|
||||
curr = gpGroupList;
|
||||
while ( curr && gubNumGroupsArrivedSimultaneously )
|
||||
{
|
||||
if ( curr->uiFlags & GROUPFLAG_GROUP_ARRIVED_SIMULTANEOUSLY )
|
||||
{
|
||||
curr->uiFlags &= ~GROUPFLAG_GROUP_ARRIVED_SIMULTANEOUSLY;
|
||||
gubNumGroupsArrivedSimultaneously--;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
//gpInitPrebattleGroup = pGroup;
|
||||
|
||||
if ( gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE || gubEnemyEncounterCode == ENTERING_BLOODCAT_LAIR_CODE )
|
||||
{
|
||||
NotifyPlayerOfBloodcatBattle( sX, sY );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !fCombatAbleMerc )
|
||||
{
|
||||
//Prepare for instant autoresolve.
|
||||
gfDelayAutoResolveStart = TRUE;
|
||||
gfUsePersistantPBI = TRUE;
|
||||
if ( fMilitiaPresent )
|
||||
{
|
||||
NotifyPlayerOfInvasionByEnemyForces( sX, sY, 0, TriggerPrebattleInterface );
|
||||
|
||||
// trigger autoresolve if not in city, or this is a militia group
|
||||
if ( aTeam == MILITIA_TEAM || GetTownIdForSector( sX, sY ) == BLANK_SECTOR )
|
||||
{
|
||||
// CHAR16 str[ 256 ];
|
||||
// UINT16 uiSectorC = L'A' + pGroup->ubSectorY - 1;
|
||||
// swprintf( str, gpStrategicString[ STR_DIALOG_ENEMIES_ATTACK_MILITIA ], uiSectorC, pGroup->ubSectorX );
|
||||
// DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, TriggerPrebattleInterface );
|
||||
TriggerPrebattleInterface( 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHAR16 str[256];
|
||||
CHAR16 pSectorStr[128];
|
||||
GetSectorIDString( sX, sY, sZ, pSectorStr, TRUE );
|
||||
swprintf( str, gpStrategicString[STR_DIALOG_ENEMIES_ATTACK_UNCONCIOUSMERCS], pSectorStr );
|
||||
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, TriggerPrebattleInterface );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JA2BETAVERSION
|
||||
if ( guiCurrentScreen == AIVIEWER_SCREEN )
|
||||
gfExitViewer = TRUE;
|
||||
#endif
|
||||
|
||||
if ( pPlayerDialogGroup )
|
||||
{
|
||||
if ( !sZ )
|
||||
MilitiaHelpFromAdjacentSectors( sX, sY );
|
||||
|
||||
PrepareForPreBattleInterface( pPlayerDialogGroup, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,4 +316,6 @@ BOOLEAN GroupHasInTransitDeadOrPOWMercs( GROUP *pGroup );
|
||||
|
||||
BOOLEAN ScoutIsPresentInSquad( INT16 ubSectorNumX, INT16 ubSectorNumY ); // added by SANDRO
|
||||
|
||||
void CheckCombatInSectorDueToUnusualEnemyArrival( UINT8 aTeam, INT16 sX, INT16 sY, INT8 sZ );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -338,6 +338,10 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\ASD.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Assignments.h"
|
||||
>
|
||||
@@ -544,6 +548,10 @@
|
||||
RelativePath=".\AI Viewer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ASD.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Assignments.cpp"
|
||||
>
|
||||
|
||||
@@ -338,6 +338,10 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath="ASD.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Assignments.h"
|
||||
>
|
||||
@@ -542,6 +546,10 @@
|
||||
RelativePath="AI Viewer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ASD.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Assignments.cpp"
|
||||
>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ASD.h" />
|
||||
<ClInclude Include="Assignments.h" />
|
||||
<ClInclude Include="Auto Resolve.h" />
|
||||
<ClInclude Include="Campaign Init.h" />
|
||||
@@ -75,6 +76,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AI Viewer.cpp" />
|
||||
<ClCompile Include="ASD.cpp" />
|
||||
<ClCompile Include="Assignments.cpp" />
|
||||
<ClCompile Include="Auto Resolve.cpp" />
|
||||
<ClCompile Include="Campaign Init.cpp" />
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ASD.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Assignments.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -161,6 +164,9 @@
|
||||
<ClCompile Include="AI Viewer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ASD.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Assignments.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ASD.h" />
|
||||
<ClInclude Include="Assignments.h" />
|
||||
<ClInclude Include="Auto Resolve.h" />
|
||||
<ClInclude Include="Campaign Init.h" />
|
||||
@@ -75,6 +76,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AI Viewer.cpp" />
|
||||
<ClCompile Include="ASD.cpp" />
|
||||
<ClCompile Include="Assignments.cpp" />
|
||||
<ClCompile Include="Auto Resolve.cpp" />
|
||||
<ClCompile Include="Campaign Init.cpp" />
|
||||
|
||||
@@ -156,6 +156,9 @@
|
||||
<ClInclude Include="MapScreen Quotes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ASD.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AI Viewer.cpp">
|
||||
@@ -344,5 +347,8 @@
|
||||
<ClCompile Include="XML_Creatures.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ASD.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1325,6 +1325,7 @@ BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// SANDRO - STOMP traits - Scouting check
|
||||
if (fScoutTraitCheck && gGameOptions.fNewTraitSystem && ScoutIsPresentInSquad( sCounterA, sCounterB ))
|
||||
{
|
||||
@@ -1339,13 +1340,13 @@ BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN
|
||||
}
|
||||
else
|
||||
{
|
||||
bScout = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( bScout );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN IsTownFullMilitia( INT8 bTownId, INT8 iMilitiaType )
|
||||
@@ -2477,13 +2478,8 @@ FLOAT CalcHourlyVolunteerGain()
|
||||
|
||||
UINT8 sector = SECTOR( sX, sY );
|
||||
|
||||
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
|
||||
|
||||
if ( !pSectorInfo )
|
||||
continue;
|
||||
|
||||
// TODO: modifier increase for every farm we control
|
||||
if ( pSectorInfo->ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND || pSectorInfo->ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND_ROAD )
|
||||
// modifier increase for every farm we control
|
||||
if ( IsSectorFarm( sX, sY ) )
|
||||
populationmodifier += gGameExternalOptions.dMilitiaVolunteerMultiplierFarm;
|
||||
|
||||
UINT8 ubTownID = StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].bNameId;
|
||||
|
||||
@@ -5012,6 +5012,15 @@ UINT32 MapScreenHandle(void)
|
||||
|
||||
CHECKF(AddVideoObject(&VObjectDesc, &guiHelicopterIcon));
|
||||
|
||||
if ( iResolution >= _640x480 && iResolution < _800x600 )
|
||||
FilenameForBPP( "INTERFACE\\Helicopter_Map_Icon_Enemy_640.sti", VObjectDesc.ImageFile );
|
||||
else if ( iResolution < _1024x768 )
|
||||
FilenameForBPP( "INTERFACE\\Helicopter_Map_Icon_Enemy_800.sti", VObjectDesc.ImageFile );
|
||||
else
|
||||
FilenameForBPP( "INTERFACE\\Helicopter_Map_Icon_Enemy_1024.sti", VObjectDesc.ImageFile );
|
||||
|
||||
CHECKF( AddVideoObject( &VObjectDesc, &guiEnemyHelicopterIcon ) );
|
||||
|
||||
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
||||
FilenameForBPP("INTERFACE\\eta_pop_up.sti", VObjectDesc.ImageFile);
|
||||
CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderEtaPopUp));
|
||||
@@ -5638,6 +5647,11 @@ UINT32 MapScreenHandle(void)
|
||||
DisplayPositionOfHelicopter( );
|
||||
}
|
||||
|
||||
// Flugente: enemy helicopter
|
||||
if ( fShowAircraftFlag && (iCurrentMapSectorZ == 0) && !fShowMapInventoryPool )
|
||||
{
|
||||
DisplayPositionOfEnemyHelicopter();
|
||||
}
|
||||
|
||||
// display town info
|
||||
DisplayTownInfo( sSelMapX, sSelMapY, ( INT8 ) iCurrentMapSectorZ );
|
||||
@@ -8686,6 +8700,7 @@ INT32 iCounter2 = 0;
|
||||
DeleteVideoObjectFromIndex( guiMapBorderHeliSectors );
|
||||
DeleteVideoObjectFromIndex( guiMapBorderHeliSectorsAlternate );
|
||||
DeleteVideoObjectFromIndex( guiHelicopterIcon );
|
||||
DeleteVideoObjectFromIndex( guiEnemyHelicopterIcon );
|
||||
DeleteVideoObjectFromIndex( guiMINEICON );
|
||||
DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID );
|
||||
|
||||
@@ -13552,6 +13567,7 @@ void HandleRemovalOfPreLoadedMapGraphics( void )
|
||||
DeleteVideoObjectFromIndex( guiMapBorderHeliSectors );
|
||||
DeleteVideoObjectFromIndex( guiMapBorderHeliSectorsAlternate );
|
||||
DeleteVideoObjectFromIndex( guiHelicopterIcon );
|
||||
DeleteVideoObjectFromIndex( guiEnemyHelicopterIcon );
|
||||
DeleteVideoObjectFromIndex( guiMINEICON );
|
||||
DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID );
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ enum
|
||||
#define MILITIA_MOVE_SOUTH 0x00000008 //8
|
||||
|
||||
#define ENEMY_VIP_PRESENT 0x00000010 //16 // an enemy VIP is present in this sector
|
||||
#define ENEMY_VIP_PRESENT_KNOWN 0x00000020 //16 // player thinks a VIP is here
|
||||
#define ENEMY_VIP_PRESENT_KNOWN 0x00000020 //32 // player thinks a VIP is here
|
||||
#define SAMSITE_REPAIR_ORDERED 0x00000040 //64 // a repair for this SAM site has already been ordered (so we do not need to do that again)
|
||||
|
||||
#define MILITIA_MOVE_ALLDIRS 0x0000000F // 15
|
||||
// -------------------------------------------------------
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
#include "sgp_logger.h"
|
||||
|
||||
#include "Map Screen Interface Map Inventory.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
@@ -2153,6 +2154,8 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
// Check for helicopter being on the ground in this sector...
|
||||
HandleHelicopterOnGroundGraphic( );
|
||||
|
||||
HandleEnemyHelicopterOnGroundGraphic();
|
||||
|
||||
// 0verhaul: Okay, it is apparent that the enemies are not reset correctly. So I will now try to add symmetry
|
||||
// between enemy placement and militia placement. The enemies do have one advantage here, though: If a sector
|
||||
// is in enemy hands, then their sector is not actually loaded. At least not normally. Perhaps it would be useful
|
||||
@@ -2304,6 +2307,8 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
|
||||
// Check for helicopter being on the ground in this sector...
|
||||
HandleHelicopterOnGroundGraphic( );
|
||||
|
||||
HandleEnemyHelicopterOnGroundGraphic();
|
||||
}
|
||||
else
|
||||
return( FALSE );
|
||||
@@ -4994,7 +4999,7 @@ void SetupNewStrategicGame( )
|
||||
AddEveryDayStrategicEvent( EVENT_DAILY_UPDATE_BOBBY_RAY_INVENTORY, BOBBYRAY_UPDATE_TIME, 0 );
|
||||
//Daily Update of the M.E.R.C. site.
|
||||
AddEveryDayStrategicEvent( EVENT_DAILY_UPDATE_OF_MERC_SITE, 0, 0 );
|
||||
|
||||
|
||||
#ifdef JA2UB
|
||||
//Ja25: No insurance for mercs
|
||||
//JA25: There is no mines
|
||||
@@ -5021,6 +5026,9 @@ void SetupNewStrategicGame( )
|
||||
// Hourly update of all sorts of things
|
||||
AddPeriodStrategicEvent( EVENT_HOURLY_UPDATE, 60, 0 );
|
||||
AddPeriodStrategicEvent( EVENT_QUARTER_HOUR_UPDATE, 15, 0 );
|
||||
|
||||
// Flugente: ASD
|
||||
AddPeriodStrategicEvent( EVENT_ASD_UPDATE, 90, 0 );
|
||||
|
||||
//Clear any possible battle locator
|
||||
gfBlitBattleSectorLocator = FALSE;
|
||||
@@ -6179,6 +6187,7 @@ BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY )
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
// SANDRO - added function
|
||||
BOOLEAN IsSectorTropical( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
@@ -6188,12 +6197,38 @@ BOOLEAN IsSectorTropical( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
return ( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( FALSE );
|
||||
}
|
||||
|
||||
return ( FALSE );
|
||||
}
|
||||
|
||||
BOOLEAN IsSectorFarm( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
if ( SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND_ROAD )
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN IsSectorRoad( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
if ( SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == PLAINS_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == SPARSE_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == TROPICS_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == DENSE_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == HILLS_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == COASTAL_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == SAND_ROAD ||
|
||||
SectorInfo[SECTOR( sSectorX, sSectorY )].ubTraversability[THROUGH_STRATEGIC_MOVE] == SWAMP_ROAD )
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode )
|
||||
{
|
||||
|
||||
@@ -176,6 +176,8 @@ BOOLEAN IsThereAFunctionalSAMSiteInSector( INT16 sSectorX, INT16 sSectorY, INT8
|
||||
|
||||
BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY );
|
||||
BOOLEAN IsSectorTropical( INT16 sSectorX, INT16 sSectorY ); // added by SANDRO
|
||||
BOOLEAN IsSectorFarm( INT16 sSectorX, INT16 sSectorY ); // added by Flugente
|
||||
BOOLEAN IsSectorRoad( INT16 sSectorX, INT16 sSectorY ); // added by Flugente
|
||||
|
||||
// sam site under players control?
|
||||
INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY );
|
||||
|
||||
Reference in New Issue
Block a user