- 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:
Flugente
2016-01-09 19:45:30 +00:00
parent 70b832d0b4
commit 7664342746
67 changed files with 3187 additions and 165 deletions
+44
View File
@@ -1972,6 +1972,50 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("Strategic Enemy AI Settings","ENEMY_INVESTIGATE_SECTOR",FALSE);
gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("Strategic Enemy AI Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE);
// Flugente: Arulco special division
//################# Strategic Additional Enemy AI Settings ##################
gGameExternalOptions.fASDActive = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ACTIVE", FALSE );
gGameExternalOptions.usASDSupplyArrivalSector = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_SUPPLY_ARRIVAL_SECTOR", 210, 0, 255 );
gGameExternalOptions.gASDResource_Cost[ASD_MONEY] = 1;
gGameExternalOptions.gASDResource_Cost[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_FUEL", 10, 1, 100 );
gGameExternalOptions.gASDResource_Cost[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_HELI", 100000, 10000, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_JEEP] = 50000;
gGameExternalOptions.gASDResource_Cost[ASD_TANK] = 200000;
gGameExternalOptions.gASDResource_BuyTime[ASD_MONEY] = 0;
gGameExternalOptions.gASDResource_BuyTime[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_FUEL", 60 * 8, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_HELI", 60 * 20, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_JEEP] = 60 * 12;
gGameExternalOptions.gASDResource_BuyTime[ASD_TANK] = 60 * 24;
// Flugente: enemy heli
//################# Enemy Helicopter Settings ##################
gGameExternalOptions.fEnemyHeliActive = iniReader.ReadBoolean( "Enemy Helicopter Settings", "ENEMYHELI_ACTIVE", TRUE );
gGameExternalOptions.gEnemyHeliMaxHP = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_HP", 100, 1, 500 );
gGameExternalOptions.gEnemyHeliTimePerHPRepair = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_HP_REPAIRTIME", 6, 1, 20 );
gGameExternalOptions.gEnemyHeliCostPerRepair1HP = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_HP_COST", 200, 10, 1000 );
gGameExternalOptions.gEnemyHeliMaxFuel = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_FUEL", 50, 25, 200 );
gGameExternalOptions.gEnemyHeliTimePerFuelRefuel = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_FUEL_REFUELTIME", 3, 1, 10 );
gGameExternalOptions.gEnemyHeliAllowedSAMContacts = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_TOLERATED_HOSTILE_SAMSECTORS", 4, 0, 10 );
gGameExternalOptions.gEnemyHeliSAMDamage_Base = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_SAM_DAMAGE_BASE", 25, 10, 100 );
gGameExternalOptions.gEnemyHeliSAMDamage_Var = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_SAM_DAMAGE_VAR", 30, 10, 100 );
gGameExternalOptions.gEnemyHeliMANPADSDamage_Base = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_MANPADS_DAMAGE_BASE", 40, 10, 100 );
gGameExternalOptions.gEnemyHeliMANPADSDamage_Var = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_MANPADS_DAMAGE_VAR", 80, 10, 100 );
gGameExternalOptions.usEnemyHeliBaseSector = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_BASE", 210, 0, 255 );
gGameExternalOptions.sEnemyHeliBaseParkGridno[0] = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_BASE_PARKPOSITION_1", 18475, -1, 2147483647 );
gGameExternalOptions.sEnemyHeliBaseParkGridno[1] = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_BASE_PARKPOSITION_2", 18469, -1, 2147483647 );
gGameExternalOptions.sEnemyHeliBaseParkTileIndex = iniReader.ReadInteger( "Enemy Helicopter Settings", "ENEMYHELI_BASE_PARK_TILEINDEX", 1689, -1, 50000 );
//################# Militia Training Settings ##################
gGameExternalOptions.iMaxMilitiaPerSector = iniReader.ReadInteger("Militia Training Settings","MAX_MILITIA_PER_SECTOR",20, 1, CODE_MAXIMUM_NUMBER_OF_REBELS);
+39
View File
@@ -212,6 +212,18 @@ enum
PRISONER_INTERROGATION_MAX
};
// Flugente: ASD resource types
enum
{
ASD_MONEY,
ASD_FUEL,
ASD_HELI,
ASD_JEEP,
ASD_TANK,
ASD_RESOURCE_MAX
};
typedef struct
{
BOOLEAN fGunNut;
@@ -600,6 +612,33 @@ typedef struct
BOOLEAN gfInvestigateSector;
BOOLEAN gfReassignPendingReinforcements;
// Flugente: ASD
BOOLEAN fASDActive;
UINT8 usASDSupplyArrivalSector;
INT32 gASDResource_Cost[ASD_RESOURCE_MAX];
INT32 gASDResource_BuyTime[ASD_RESOURCE_MAX];
// Flugente: enemy heli
BOOLEAN fEnemyHeliActive;
UINT16 gEnemyHeliMaxHP;
UINT16 gEnemyHeliTimePerHPRepair;
INT32 gEnemyHeliCostPerRepair1HP;
UINT16 gEnemyHeliMaxFuel;
UINT16 gEnemyHeliTimePerFuelRefuel;
UINT8 gEnemyHeliAllowedSAMContacts;
UINT16 gEnemyHeliSAMDamage_Base;
UINT16 gEnemyHeliSAMDamage_Var;
UINT16 gEnemyHeliMANPADSDamage_Base;
UINT16 gEnemyHeliMANPADSDamage_Var;
UINT8 usEnemyHeliBaseSector;
INT32 sEnemyHeliBaseParkGridno[2];
INT32 sEnemyHeliBaseParkTileIndex;
INT32 ubEnemiesItemDrop;
BOOLEAN gfUseExternalLoadscreens;
+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 ENEMY_HELICOPTERS 164 // Flugente: enemy helicopters
#define DRUG_SYSTEM_REDONE 163 // Flugente: reworked the drug system
#define MILITIA_PATH_PLOTTING 162 // Flugente: the player can plot militia paths in strategic, similar to player or helicopter travel
#define STRATEGIC_TEAM_GROUPS 161 // Flugente: a change to the GROUP-structure allows any team to have strategic movement groups
@@ -82,7 +83,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 DRUG_SYSTEM_REDONE
#define SAVE_GAME_VERSION ENEMY_HELICOPTERS
//#define RUSSIANGOLD
#ifdef __cplusplus
+4 -19
View File
@@ -1576,28 +1576,13 @@ void ProcessTransactionString(STR16 pString, FinanceUnitPtr pFinance)
break;
// HEADROCK HAM 3.6: Paid for Facility Use
case( FACILITY_OPERATIONS ):
swprintf(pString, L"%s", pTransactionText[ FACILITY_OPERATIONS ]);
break;
// HEADROCK HAM 3.6: Paid for militia upkeep
case( MILITIA_UPKEEP ):
swprintf(pString, L"%s", pTransactionText[ MILITIA_UPKEEP ]);
break;
// Flugente: ransom from released prisoners
case FACILITY_OPERATIONS:
case MILITIA_UPKEEP:
case PRISONER_RANSOM:
swprintf(pString, L"%s", pTransactionText[ PRISONER_RANSOM ]);
break;
// Flugente: disease: subscription to WHO data
case WHO_SUBSCRIPTION:
swprintf( pString, L"%s", pTransactionText[WHO_SUBSCRIPTION] );
break;
// Flugente: a contract with a PMC
case PMC_CONTRACT:
swprintf( pString, L"%s", pTransactionText[PMC_CONTRACT] );
case SAM_REPAIR:
swprintf( pString, L"%s", pTransactionText[pFinance->ubCode] );
break;
}
}
+1
View File
@@ -56,6 +56,7 @@ enum
PRISONER_RANSOM, // Flugente: ransom for released prisoners
WHO_SUBSCRIPTION, // Flugente: subscription do WHO data
PMC_CONTRACT, // Flugente: hired militia from a PMC
SAM_REPAIR, // Flugente: repair SAM site
TEXT_NUM_FINCANCES
};
+28
View File
@@ -116,6 +116,7 @@
#include "CampaignStats.h" // added by Flugente
#include "DynamicDialogue.h" // added by Flugente
#include "PMC.h" // added by Flugente
#include "ASD.h" // added by Flugente
#endif
#include "BobbyR.h"
@@ -4398,6 +4399,13 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
goto FAILED_TO_SAVE;
}
// Flugente: enemy helicopters
if ( !SaveASDData( hFile ) )
{
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing Arulco special division data" );
goto FAILED_TO_SAVE;
}
//Close the saved game file
FileClose( hFile );
@@ -6097,6 +6105,26 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
return(FALSE);
}
if ( guiCurrentSaveGameVersion >= ENEMY_HELICOPTERS )
{
uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Load Arulco special division data..." );
RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc;
if ( !LoadASDData( hFile ) )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Arulco special division data Load failed" ) );
FileClose( hFile );
return(FALSE);
}
}
else
{
// if loading an old savegame that did not have this feature, initialise
InitASD();
}
//
//Close the saved game file
//
+1425
View File
File diff suppressed because it is too large Load Diff
+120
View File
@@ -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
+38
View File
@@ -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)
{
+3
View File
@@ -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
+1
View File
@@ -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
{
+1 -1
View File
@@ -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;
+43 -1
View File
@@ -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;
+12
View File
@@ -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
};
+9
View File
@@ -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
+8 -4
View File
@@ -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 );
+65 -7
View File
@@ -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 );
}
}
}
}
+3
View File
@@ -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 );
+72
View File
@@ -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 )
{
+2 -1
View File
@@ -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 );
+150 -28
View File
@@ -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 )
+7
View File
@@ -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 )
+1
View File
@@ -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 );
+14 -2
View File
@@ -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()
+2
View File
@@ -81,6 +81,8 @@ extern UINT8 gubPBSectorY;
extern UINT8 gubPBSectorZ;
extern BOOLEAN gfCantRetreatInPBI;
extern BOOLEAN gubSpecialEncounterCodeForEnemyHeli;
//SAVE END
void WakeUpAllMercsInSectorUnderAttack( void );
+8 -1
View File
@@ -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
View File
@@ -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++;
+33 -19
View File
@@ -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 );
}
}
+193
View File
@@ -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 );
}
}
}
+2
View File
@@ -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
+8
View File
@@ -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"
>
+8
View File
@@ -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"
>
+2
View File
@@ -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>
+2
View File
@@ -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>
+5 -9
View File
@@ -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;
+16
View File
@@ -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 );
+2 -1
View File
@@ -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
// -------------------------------------------------------
+40 -5
View File
@@ -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 )
{
+2
View File
@@ -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 );
+6 -6
View File
@@ -3322,9 +3322,9 @@ void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum )
void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT16 usQuoteNum )
{
// WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc;
std::vector<UINT16> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT16 ubNumMercs = 0;
UINT16 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier;
INT32 cnt;
@@ -3342,16 +3342,17 @@ void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSect
if( pTeamSoldier->sSectorX == sSectorX && pTeamSoldier->sSectorY == sSectorY && pTeamSoldier->bSectorZ == bSectorZ && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->flags.uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->flags.fMercAsleep )
{
ubMercsInSector[ ubNumMercs ] = (UINT8)cnt;
ubNumMercs++;
++ubNumMercs;
}
}
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SayQuoteFromAnyBodyInThisSector: num mercs = %d",ubNumMercs));
// If we are > 0
if ( ubNumMercs > 0 )
{
ubChosenMerc = (UINT8)Random( ubNumMercs );
ubChosenMerc = (UINT16)Random( ubNumMercs );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SayQuoteFromAnyBodyInThisSector: chosen merc = %d",ubChosenMerc));
//// If we are air raid, AND red exists somewhere...
@@ -3367,7 +3368,6 @@ void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSect
// }
//}
TacticalCharacterDialogue( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ], usQuoteNum );
}
}
+1
View File
@@ -175,6 +175,7 @@ enum {
BG_PERC_HEARING_NIGHT,
BG_PERC_HEARING_DAY,
BG_PERC_DISARM,
BG_PERC_SAM_CTH,
// approaches
BG_PERC_APPROACH_FRIENDLY,
+1 -1
View File
@@ -731,7 +731,7 @@ extern OBJECTTYPE gTempObject;
// flags used for various item properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
// note that these should not be used to determine what kind of an attachment an item is, that is determined by attachmentclass and the AC_xxx flags above
//#define EMPTY_SANDBAG 0x00000001 //1
//#define FULL_SANDBAG 0x00000002 //2
#define MANPAD 0x00000002 //2 // this item is a MAn-Portable Air-Defense System
//#define SHOVEL 0x00000004 //4 // a shovel is used for filling sandbags and other building-related tasks
//#define CONCERTINA 0x00000008 //8
+429 -1
View File
@@ -40,6 +40,7 @@
#include "Tactical Save.h"
// HEADROCK HAM 3.5: Need this to see if enemies present at starting sector
#include "Overhead.h"
#include "Map Information.h" // added by Flugente
#endif
#ifdef JA2UB
@@ -386,6 +387,7 @@ BOOLEAN gfIngagedInDrop = FALSE;
ANITILE *gpHeli;
BOOLEAN gfFirstHeliRun;
extern BOOLEAN gfTacticalDoHeliRun;
void HandleFirstHeliDropOfGame( );
@@ -479,13 +481,16 @@ void StartHelicopterRun()
}
void HandleHeliDrop( )
void HandleHeliDrop( BOOLEAN fPlayer )
{
UINT8 ubScriptCode;
UINT32 uiClock;
INT32 iVol;
INT32 cnt;
ANITILE_PARAMS AniParams;
if ( !fPlayer )
return HandleEnemyAirdrop();
if ( gfHandleHeli )
{
@@ -1021,3 +1026,426 @@ void HandleFirstHeliDropOfGame( )
// Send message to turn on ai again....
CharacterDialogueWithSpecialEvent( 0, 0, 0, DIALOGUE_TACTICAL_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_ENABLE_AI ,0, 0 );
}
UINT16 SpawnAirDropElite( INT32 sGridNo )
{
SOLDIERTYPE *pSoldier;
// not underground!
if ( gbWorldSectorZ )
return NOBODY;
// hmm...
if ( !IsLocationSittable( sGridNo, 0 ) )
return NOBODY;
// Flugente hack
pSoldier = TacticalCreateEliteEnemy( );
//Add soldier strategic info, so it doesn't break the counters!
if ( pSoldier )
{
if ( !gbWorldSectorZ )
{
SECTORINFO *pSector = &SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )];
switch ( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CHOPPER;
pSoldier->usStrategicInsertionData = sGridNo; // required, otherwise soldiers will spawn in map before jumping out of the heli
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
//AllTeamsLookForAll( NO_INTERRUPTS );
}
return pSoldier->ubID;
}
void InitiateEnemyAirDropSoldiers( INT32 sGridNo )
{
gfTacticalDoHeliRun = TRUE;
ResetHeliSeats( );
//SetHelicopterDroppoint( gMapInformation.sCenterGridNo );
SetHelicopterDroppoint( sGridNo );
SetHelicopterDropDirection( WEST );
for ( int i = 0; i < 6; ++i )
{
UINT8 id = SpawnAirDropElite( gMapInformation.sSouthGridNo + i );
if ( id == NOBODY )
return;
AddMercToHeli( id );
}
}
void HandleEnemyAirdrop( )
{
UINT8 ubScriptCode;
UINT32 uiClock;
INT32 iVol;
ANITILE_PARAMS AniParams;
if ( gfHandleHeli )
{
if ( gCurrentUIMode != LOCKUI_MODE )
{
guiPendingOverrideEvent = LU_BEGINUILOCK;
}
gfIgnoreScrolling = TRUE;
uiClock = GetJA2Clock( );
if ( (uiClock - guiHeliLastUpdate) > ME_SCRIPT_DELAY )
{
guiHeliLastUpdate = uiClock;
if ( fFadingHeliIn )
{
if ( uiSoundSample != NO_SAMPLE )
{
iVol = SoundGetVolume( uiSoundSample );
iVol = __min( HIGHVOLUME, iVol + 5 );
SoundSetVolume( uiSoundSample, iVol );
if ( iVol == HIGHVOLUME )
fFadingHeliIn = FALSE;
}
else
{
fFadingHeliIn = FALSE;
}
}
else if ( fFadingHeliOut )
{
if ( uiSoundSample != NO_SAMPLE )
{
iVol = SoundGetVolume( uiSoundSample );
iVol = __max( 0, iVol - 5 );
SoundSetVolume( uiSoundSample, iVol );
if ( iVol == 0 )
{
// Stop sound
SoundStop( uiSoundSample );
fFadingHeliOut = FALSE;
gfHandleHeli = FALSE;
gfIgnoreScrolling = FALSE;
gbNumHeliSeatsOccupied = 0;
guiPendingOverrideEvent = LU_ENDUILOCK;
UnLockPauseState( );
UnPauseGame( );
RebuildCurrentSquad( );
HandleFirstHeliDropOfGame( );
}
}
else
{
fFadingHeliOut = FALSE;
gfHandleHeli = FALSE;
gfIgnoreScrolling = FALSE;
gbNumHeliSeatsOccupied = 0;
guiPendingOverrideEvent = LU_ENDUILOCK;
UnLockPauseState( );
UnPauseGame( );
RebuildCurrentSquad( );
HandleFirstHeliDropOfGame( );
}
}
if ( gsHeliScript == MAX_HELI_SCRIPT )
{
return;
}
ubScriptCode = ubHeliScripts[gubHeliState][gsHeliScript];
// Switch on mode...
if ( gubHeliState == HELI_DROP )
{
if ( !gfIngagedInDrop )
{
INT8 bEndVal = (gbHeliRound * NUM_PER_HELI_RUN);
if ( bEndVal > gbNumHeliSeatsOccupied )
{
bEndVal = gbNumHeliSeatsOccupied;
}
// Flugente: watching mercs rope down one by one gets boring fast. So we allow up to 3 mercs to rope down at the same time
for ( int i = 0; i < 3; ++i )
{
// OK, Check if we have anybody left to send!
if ( gbCurDrop < bEndVal )
{
// Flugente: it is now possible to use airdrops with soldiers after they have arrived in Arulco. In that case, they might have an animation that breaks EVENT_InitNewSoldierAnim prematurely.
// In the worst case, this can cause the game to be unable to finish the airdrop. For that reason, we set all those soldiers to the STANDING aniamtion.
//MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->usAnimState = STANDING;
MercPtrs[gusHeliSeats[gbCurDrop]]->EVENT_InitNewSoldierAnim( HELIDROP, 0, FALSE );
// Change insertion code
MercPtrs[gusHeliSeats[gbCurDrop]]->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
MercPtrs[gusHeliSeats[gbCurDrop]]->usStrategicInsertionData = gsGridNoSweetSpot;
// HEADROCK HAM 3.5: Externalized!
UpdateMercInSector( MercPtrs[gusHeliSeats[gbCurDrop]], gWorldSectorX, gWorldSectorY, startingZ );
// IF the first guy down, set squad!
if ( gfFirstGuyDown )
{
gfFirstGuyDown = FALSE;
//SetCurrentSquad( MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->bAssignment, TRUE );
}
ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, TacticalStr[MERC_HAS_ARRIVED_STR], MercPtrs[gusHeliSeats[gbCurDrop]]->GetName( ) );
++gbCurDrop;
gfIngagedInDrop = TRUE;
}
else
{
if ( gbExitCount == 0 )
{
gbExitCount = 2;
}
else
{
--gbExitCount;
if ( gbExitCount == 1 )
{
// Goto leave
gsHeliScript = -1;
gubHeliState = HELI_ENDDROP;
}
}
break;
}
}
}
}
switch ( ubScriptCode )
{
case HELI_REST:
break;
case HELI_MOVE_DOWN:
gdHeliZPos -= 1;
gpHeli->pLevelNode->sRelativeZ = (INT16)gdHeliZPos;
break;
case HELI_MOVE_UP:
gdHeliZPos += 1;
gpHeli->pLevelNode->sRelativeZ = (INT16)gdHeliZPos;
break;
case HELI_MOVESMALL_DOWN:
gdHeliZPos -= 0.25;
gpHeli->pLevelNode->sRelativeZ = (INT16)gdHeliZPos;
break;
case HELI_MOVESMALL_UP:
gdHeliZPos += 0.25;
gpHeli->pLevelNode->sRelativeZ = (INT16)gdHeliZPos;
break;
case HELI_MOVEY:
if ( gHeliEnterDirection == SOUTH )
{
gpHeli->sRelativeY -= 4;
}
else if ( gHeliEnterDirection == EAST )
{
gpHeli->sRelativeX -= 4;
gpHeli->sRelativeY -= 1;
}
else if ( gHeliEnterDirection == WEST )
{
gpHeli->sRelativeX += 4;
gpHeli->sRelativeY += 1;
}
else
{
gpHeli->sRelativeY += 4;
}
break;
case HELI_MOVELARGERY:
if ( gHeliEnterDirection == SOUTH )
{
gpHeli->sRelativeY -= 6;
}
else if ( gHeliEnterDirection == EAST )
{
gpHeli->sRelativeX -= 6;
gpHeli->sRelativeY -= 1;
}
else if ( gHeliEnterDirection == WEST )
{
gpHeli->sRelativeX += 6;
gpHeli->sRelativeY += 1;
}
else
{
gpHeli->sRelativeY += 6;
}
break;
case HELI_GOTO_BEGINDROP:
gsHeliScript = -1;
gubHeliState = HELI_BEGINDROP;
break;
case HELI_SHOW_HELI:
// Start animation
memset( &AniParams, 0, sizeof(ANITILE_PARAMS) );
AniParams.sGridNo = gsGridNoSweetSpot;
AniParams.ubLevelID = ANI_SHADOW_LEVEL;
AniParams.sDelay = 90;
AniParams.sStartFrame = 0;
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_LOOPING;
AniParams.sX = gsHeliXPos;
AniParams.sY = gsHeliYPos;
AniParams.sZ = (INT16)gdHeliZPos;
if ( gHeliEnterDirection == SOUTH )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\HELI_SH_SOUTH.STI" );
}
else if ( gHeliEnterDirection == EAST )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\HELI_SH_EAST.STI" );
}
else if ( gHeliEnterDirection == WEST )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\HELI_SH_WEST.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\HELI_SH.STI" );
}
gpHeli = CreateAnimationTile( &AniParams );
break;
case HELI_GOTO_DROP:
// Goto drop animation
gdHeliZPos -= 0.25;
gpHeli->pLevelNode->sRelativeZ = (INT16)gdHeliZPos;
gsHeliScript = -1;
gubHeliState = HELI_DROP;
break;
case HELI_GOTO_MOVETO:
// Goto drop animation
gsHeliScript = -1;
gubHeliState = HELI_MOVETO;
break;
case HELI_GOTO_MOVEAWAY:
// Goto drop animation
gsHeliScript = -1;
gubHeliState = HELI_MOVEAWAY;
break;
case HELI_GOTO_EXIT:
if ( gbCurDrop < gbNumHeliSeatsOccupied )
{
// Start another run......
INT16 sX, sY;
ConvertGridNoToCenterCellXY( gsGridNoSweetSpot, &sX, &sY );
if ( gHeliEnterDirection == SOUTH )
{
gsHeliXPos = sX - (2 * CELL_X_SIZE);
gsHeliYPos = sY + (10 * CELL_Y_SIZE);
}
else if ( gHeliEnterDirection == EAST )
{
gsHeliXPos = sX + (10 * CELL_X_SIZE);
gsHeliYPos = sY + (2 * CELL_Y_SIZE);
}
else if ( gHeliEnterDirection == WEST )
{
gsHeliXPos = sX - (10 * CELL_X_SIZE);
gsHeliYPos = sY - (2 * CELL_Y_SIZE);
}
else
{
gsHeliXPos = sX - (2 * CELL_X_SIZE);
gsHeliYPos = sY - (10 * CELL_Y_SIZE);
}
gdHeliZPos = 0;
gsHeliScript = 0;
gbExitCount = 0;
gubHeliState = HELI_APPROACH;
++gbHeliRound;
// Ahh, but still delete the heli!
DeleteAniTile( gpHeli );
gpHeli = NULL;
}
else
{
// Goto drop animation
gsHeliScript = -1;
gubHeliState = HELI_EXIT;
// Delete helicopter image!
DeleteAniTile( gpHeli );
gpHeli = NULL;
gfIgnoreScrolling = FALSE;
// Select our first guy
SelectSoldier( gusHeliSeats[0], FALSE, TRUE );
}
break;
case HELI_DONE:
// End
fFadingHeliOut = TRUE;
// HEADROCK HAM 3.5: Update now, in case the LZ is still in a "RED" airspace sector. This is only
// required if the sector is free of enemies... but still required. Will run immediately after the
// helicopter is gone.
UpdateAirspaceControl( );
break;
}
++gsHeliScript;
}
}
}
+1 -1
View File
@@ -365,7 +365,7 @@ enum
UNNAMED_CIV_GROUP_23,
VOLUNTEER_CIV_GROUP, // Flugente: civilians that the player recruited
BOUNTYHUNTER_CIV_GROUP, // Flugente: hostile bounty hunters
UNNAMED_CIV_GROUP_26,
DOWNEDPILOT_CIV_GROUP, // Flugente: downed pilots
UNNAMED_CIV_GROUP_27,
UNNAMED_CIV_GROUP_28,
UNNAMED_CIV_GROUP_29,
+2 -1
View File
@@ -6829,7 +6829,8 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
// officers and generals are 'special' prisoners...
if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_VIP )
++sNumPrisoner[PRISONER_GENERAL];
else if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_ENEMY_OFFICER )
// downed pilots count as officers too, even though they are civilians. This makes capturing them more rewarding
else if ( (pTeamSoldier->usSoldierFlagMask & SOLDIER_ENEMY_OFFICER) || pTeamSoldier->ubCivilianGroup == DOWNEDPILOT_CIV_GROUP )
++sNumPrisoner[PRISONER_OFFICER];
else if ( pTeamSoldier->bTeam == ENEMY_TEAM )
{
+10 -12
View File
@@ -2826,28 +2826,27 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
}
void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos )
{
OBJECTTYPE * pObj;
return DeductAmmo( pSoldier, &(pSoldier->inv[bInvPos]) );
}
// tanks never run out of MG ammo!
// unlimited cannon ammo is handled in AI
if ( TANK( pSoldier ) && !Item[pSoldier->inv[bInvPos].usItem].cannon )
void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj )
{
if ( pSoldier && pObj->exists( ) )
{
return;
}
// tanks never run out of MG ammo!
// unlimited cannon ammo is handled in AI
if ( TANK( pSoldier ) && !Item[pObj->usItem].cannon )
return;
pObj = &(pSoldier->inv[ bInvPos ]);
if ( pObj->exists() == true )
{
if ( Item[pObj->usItem].cannon )
{
}
else if ( Item[ pObj->usItem ].usItemClass == IC_GUN && !Item[pObj->usItem].cannon && pSoldier->bWeaponMode != WM_ATTACHED_GL && pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bWeaponMode != WM_ATTACHED_GL_AUTO )
{
// Flugente: check for underbarrel weapons and use that object if necessary
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &(pSoldier->inv[bInvPos]) );
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( pObj );
// Flugente: external feeding allows us to take ammo from somewhere other than our magazine, like a belt in our inventory our even another mercs
if ( gGameExternalOptions.ubExternalFeeding > 0 )
@@ -2921,7 +2920,6 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos )
// Dirty Bars
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL1 );
}
}
+1 -1
View File
@@ -300,7 +300,7 @@ UINT16 CalculateRaiseGunCost(SOLDIERTYPE *pSoldier, BOOLEAN fAddingRaiseGunCost,
INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime, UINT8 ubAddTurningCost, UINT8 ubForceRaiseGunCost = 0 );
BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos );
void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos );
void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj );
UINT16 GetAPsToPickupItem( SOLDIERTYPE *pSoldier, INT32 usMapPos );
INT16 MinAPsToPunch(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurningCost );
+1 -1
View File
@@ -391,7 +391,7 @@ enum
#define SOLDIER_ENEMY_OBSERVEDTHISTURN 0x08000000 //134217728 // enemy soldier was seen by the player this turn
#define SOLDIER_VIP 0x10000000 //268435456 // soldier is a VIP - the player will likely try to assassinate him
#define SOLDIER_BODYGUARD 0x20000000 //536870912 // soldier is a bodyguard for a VIP/*
#define SOLDIER_BODYGUARD 0x20000000 //536870912 // soldier is a bodyguard for a VIP
#define SOLDIER_COVERT_TEMPORARY_OVERT 0x40000000 //1073741824 // we are covert, but just performed a obviously suspicious task. For a short time, we can be uncovered more easily
#define SOLDIER_MOVEITEM_RESTRICTED 0x80000000 //2147483648 // when moving item, this soldier will not pick up equipment the militia might use
// ----------------------------------------------------------------
+75
View File
@@ -3609,6 +3609,81 @@ void CreatePrisonerOfWar()
}
}
// create a downed pilot in a random location in the current sector
void CreateDownedPilot( )
{
UINT8 tries = 0;
INT32 sGridNo = NOWHERE;
do
{
if ( ++tries > 20 )
return;
sGridNo = RandomGridNo( );
}
// a valid starting gridno must be valid, not in a structure, not in water, and not too near to our mercs
while ( TileIsOutOfBounds( sGridNo ) || FindStructure( sGridNo, STRUCTURE_BLOCKSMOVES ) || TERRAIN_IS_WATER( gpWorldLevelData[sGridNo].ubTerrainID ) || GridNoNearPlayerMercs( sGridNo, 25 ) );
SOLDIERCREATE_STRUCT MercCreateStruct;
UINT8 ubID;
MercCreateStruct.initialize( );
MercCreateStruct.bTeam = CIV_TEAM;
MercCreateStruct.ubProfile = NO_PROFILE;
MercCreateStruct.sSectorX = gWorldSectorX;
MercCreateStruct.sSectorY = gWorldSectorY;
MercCreateStruct.bSectorZ = gbWorldSectorZ;
MercCreateStruct.sInsertionGridNo = sGridNo;
MercCreateStruct.ubDirection = Random( NUM_WORLD_DIRECTIONS );
MercCreateStruct.ubBodyType = Random( ADULTFEMALEMONSTER );
RandomizeNewSoldierStats( &MercCreateStruct );
SOLDIERTYPE* pSoldier = TacticalCreateSoldier( &MercCreateStruct, &ubID );
if ( pSoldier )
{
// a downed pilot might be wounded
pSoldier->stats.bLife = min( pSoldier->stats.bLifeMax, max( OKLIFE + 20, pSoldier->stats.bLife - 20 ) );
pSoldier->bBleeding = pSoldier->stats.bLifeMax - pSoldier->stats.bLife;
AddSoldierToSector( pSoldier->ubID );
// set correct civ group
pSoldier->ubCivilianGroup = DOWNEDPILOT_CIV_GROUP;
// make him wear administrator uniform
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
{
SET_PALETTEREP_ID( pSoldier->VestPal, gUniformColors[UNIFORM_ENEMY_ADMIN].vest );
SET_PALETTEREP_ID( pSoldier->PantsPal, gUniformColors[UNIFORM_ENEMY_ADMIN].pants );
// Use palette from HVOBJECT, then use substitution for pants, etc
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof(pSoldier->p8BPPPalette) * 256 );
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
pSoldier->CreateSoldierPalettes( );
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
}
// So we can see them!
AllTeamsLookForAll( NO_INTERRUPTS );
// downed pilots are hostile, even though they stand no chance against us
gTacticalStatus.fCivGroupHostile[POW_PRISON_CIV_GROUP] = CIV_GROUP_HOSTILE;
pSoldier->aiData.bNeutral = FALSE;
}
}
void RandomizeRelativeLevel( INT8 *pbRelLevel, UINT8 ubSoldierClass )
{
UINT8 ubLocationModifier = 0;
+3
View File
@@ -457,6 +457,9 @@ void CreateAssassin(UINT8 disguisetype);
// create a prisoner (in a prison cell) in the current sector
void CreatePrisonerOfWar();
// create a downed pilot in a random location in the current sector
void CreateDownedPilot();
// randomly generates a relative level rating (attributes or equipment)
void RandomizeRelativeLevel( INT8 *pbRelLevel, UINT8 ubSoldierClass );
+29
View File
@@ -954,6 +954,8 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
{
SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
SectorAddDownedPilot( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
}
@@ -1009,6 +1011,8 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
{
SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
SectorAddDownedPilot( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
}
@@ -3049,3 +3053,28 @@ void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
break;
}
}
// Flugente: decide wether to add a downed pilot if a helicopter was shot down here
void SectorAddDownedPilot( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
{
// not in underground sectors
if ( sMapZ > 0 )
return;
// get sector
SECTORINFO *pSector = &SectorInfo[SECTOR( sMapX, sMapY )];
if ( !pSector )
return;
if ( pSector->usSectorInfoFlag & SECTORINFO_ENEMYHELI_SHOTDOWN )
{
// it is likely that a pilot has survived, but not guaranteed
if ( Chance( 75 ) )
{
CreateDownedPilot();
}
// remove the flag. We can only find the pilot the first time we visit this sector after the heli was shut down
pSector->usSectorInfoFlag &= ~SECTORINFO_ENEMYHELI_SHOTDOWN;
}
}
+2 -2
View File
@@ -65,7 +65,7 @@ void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
// Flugente: decide wether to create prisoners of war in a sector. Not to be confused with player POWs
void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
// Flugente: add script-defined civilians if Lua functions say so
void SectorAddLuaCivilians( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
// Flugente: decide wether to add a downed pilot if a helicopter was shot down here
void SectorAddDownedPilot( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
#endif
+6
View File
@@ -117,6 +117,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
strcmp(name, "hearing_night") == 0 ||
strcmp(name, "hearing_day") == 0 ||
strcmp(name, "disarm_trap") == 0 ||
strcmp(name, "SAM_cth" ) == 0 ||
strcmp(name, "approach_friendly") == 0 ||
strcmp(name, "approach_direct") == 0 ||
strcmp(name, "approach_threaten") == 0 ||
@@ -486,6 +487,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curBackground.value[BG_PERC_DISARM] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) );
}
else if ( strcmp( name, "SAM_cth" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curBackground.value[BG_PERC_SAM_CTH] = min( 100, max( -50, (INT16)atol( pData->szCharData ) ) );
}
else if(strcmp(name, "approach_friendly") == 0)
{
pData->curElement = ELEMENT;
+6 -2
View File
@@ -1,6 +1,7 @@
#ifndef _MERC_ENTRING_H
#define _MERC_ENTRING_H
extern BOOLEAN gfIngagedInDrop;
void ResetHeliSeats( );
void AddMercToHeli( UINT8 ubID );
@@ -11,9 +12,12 @@ void SetHelicopterDropDirection( UINT8 usDirection );
void StartHelicopterRun();
void HandleHeliDrop( );
void HandleHeliDrop( BOOLEAN fPlayer = TRUE );
extern BOOLEAN gfIngagedInDrop;
UINT16 SpawnAirDropElite( INT32 sGridNo );
void InitiateEnemyAirDropSoldiers( INT32 sGridNo );
void HandleEnemyAirdrop( );
#endif
+5
View File
@@ -48,6 +48,7 @@
#include "Soldier Functions.h"
#include "Animation Control.h"
#include "Soldier Ani.h"
#include "ASD.h" // added by Flugente
#endif
#ifdef COUNT_PATHS
@@ -1930,11 +1931,15 @@ BOOLEAN DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason,
CHECKF( pBase );
if (pBase->ubHitPoints <= ubDamage)
{
UpdateAndDamageEnemyHeliIfFound( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo, ubDamage, TRUE );
// boom! structure destroyed!
return( TRUE );
}
else
{
UpdateAndDamageEnemyHeliIfFound( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo, ubDamage, FALSE );
pBase->ubHitPoints -= ubDamage;
//Since the structure is being damaged, set the map element that a structure is damaged
+3
View File
@@ -2925,6 +2925,9 @@ extern STR16 szIMPGearDropDownNoneText[];
// Flugente: militia movement
extern STR16 szMilitiaStrategicMovementText[];
// Flugente: enemy heli/SAM
extern STR16 szEnemyHeliText[];
#define TACTICAL_INVENTORY_DIALOG_NUM 16
#define TACTICAL_COVER_DIALOG_NUM 16
+18
View File
@@ -4155,6 +4155,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"存货",
L"离开",
L"Repair", // TODO.Translate
};
// town strings
@@ -4523,6 +4524,7 @@ STR16 pTransactionText[] =
L"释放俘虏所需的赎金", //L"Ransom for released prisoners",
L"记录捐款费", //L"WHO data subscription", // Flugente: disease
L"Kerberus安保公司的费用", //L"Payment to Kerberus",  // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8898,6 +8900,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d夜晚听力范围\n", //L" %s%d hearing range during the night\n",
L" %s%d白天听力范围\n", //L" %s%d hearing range during the day\n",
L" %s%d解除陷阱效率\n",
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%%友好对话效果\n", //L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%%直接对话效果\n", //L" %s%d%% effectiveness to direct approach\n",
@@ -10846,6 +10849,21 @@ STR16 szMilitiaStrategicMovementText[] =
L"民兵的志愿者: %d (+%5.3f)", //L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
// WANNE: Some Chinese specific strings that needs to be in unicode!
STR16 ChineseSpecString1 = L"%"; //defined in _ChineseText.cpp as this file is already unicode
STR16 ChineseSpecString2 = L"*%3d%%%"; //defined in _ChineseText.cpp as this file is already unicode
+18
View File
@@ -4154,6 +4154,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inventaris",
L"OK",
L"Repair", // TODO.Translate
};
// town strings
@@ -4524,6 +4525,7 @@ STR16 pTransactionText[] =
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
L"WHO data subscription", // Flugente: disease TODO.Translate
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8912,6 +8914,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d hearing range during the night\n",
L" %s%d hearing range during the day\n",
L" %s%d effectivity at disarming traps\n", // TODO.Translate
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%% effectiveness to direct approach\n",
@@ -10860,4 +10863,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //DUTCH
+18
View File
@@ -4152,6 +4152,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inventory",
L"Exit",
L"Repair",
};
// town strings
@@ -4520,6 +4521,7 @@ STR16 pTransactionText[] =
L"Ransom for released prisoners", // Flugente: prisoner system
L"WHO data subscription", // Flugente: disease
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair
};
STR16 pTransactionAlternateText[] =
@@ -8896,6 +8898,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d hearing range during the night\n",
L" %s%d hearing range during the day\n",
L" %s%d effectivity at disarming traps\n",
L" %s%d%% CTH with SAMs\n",
L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%% effectiveness to direct approach\n",
@@ -10898,4 +10901,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] =
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //ENGLISH
+18
View File
@@ -4158,6 +4158,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inventaire",
L"Quitter",
L"Repair", // TODO.Translate
};
// town strings
@@ -4528,6 +4529,7 @@ STR16 pTransactionText[] =
L"Argent des prisonniers libérés", // Flugente: prisoner system
L"WHO data subscription", // Flugente: disease TODO.Translate
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8897,6 +8899,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d en audition pendant la nuit\n",
L" %s%d en audition pendant la journée\n",
L" %s%d d'efficacité à désamorcer les pièges\n",
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% d'efficacité dans une approche amicale\n",
L" %s%d%% d'efficacité dans une approche directe\n",
@@ -10845,4 +10848,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //FRENCH
+18
View File
@@ -4153,6 +4153,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inventar",
L"Exit",
L"Repair", // TODO.Translate
};
// town strings
@@ -4500,6 +4501,7 @@ STR16 pTransactionText[] =
L"Lösegeld erpresst", // Flugente: prisoner system
L"WHO data subscription", // Flugente: disease TODO.Translate
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8728,6 +8730,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d hearing range during the night\n",
L" %s%d hearing range during the day\n",
L" %s%d effectivity at disarming traps\n", // TODO.Translate
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%% effectiveness to direct approach\n",
@@ -10676,4 +10679,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //GERMAN
+18
View File
@@ -4148,6 +4148,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inventario",
L"Uscita",
L"Repair", // TODO.Translate
};
// town strings
@@ -4518,6 +4519,7 @@ STR16 pTransactionText[] =
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
L"WHO data subscription", // Flugente: disease TODO.Translate
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8906,6 +8908,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d hearing range during the night\n",
L" %s%d hearing range during the day\n",
L" %s%d effectivity at disarming traps\n", // TODO.Translate
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%% effectiveness to direct approach\n",
@@ -10854,4 +10857,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //ITALIAN
+18
View File
@@ -4159,6 +4159,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Inwentarz",
L"Zamknij",
L"Repair", // TODO.Translate
};
// town strings
@@ -4529,6 +4530,7 @@ STR16 pTransactionText[] =
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
L"WHO data subscription", // Flugente: disease TODO.Translate
L"Payment to Kerberus", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8919,6 +8921,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d hearing range during the night\n",
L" %s%d hearing range during the day\n",
L" %s%d effectivity at disarming traps\n", // TODO.Translate
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% effectiveness to friendly approach\n",
L" %s%d%% effectiveness to direct approach\n",
@@ -10867,4 +10870,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //POLISH
+18
View File
@@ -4154,6 +4154,7 @@ STR16 pMapPopUpInventoryText[] =
{
L"Инвентарь",
L"Выйти",
L"Repair", // TODO.Translate
};
// town strings
@@ -4522,6 +4523,7 @@ STR16 pTransactionText[] =
L"Выкуп за освобожденных заключенных", // Flugente: prisoner system
L"ВОЗ, подписка", // Flugente: disease
L"Оплата услуг Цербер", // Flugente: PMC
L"SAM site repair", // Flugente: SAM repair // TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -8896,6 +8898,7 @@ STR16 szBackgroundText_Value[]=
L" %s%d дальность слуха ночью\n",
L" %s%d дальность слуха днем\n",
L" %s%d эффективность при разминировании ловушек\n",
L" %s%d%% CTH with SAMs\n", // TODO.Translate
L" %s%d%% эффективность дружеского обращения\n",
L" %s%d%% эффективность прямого обращении\n",
@@ -10898,4 +10901,19 @@ STR16 szMilitiaStrategicMovementText[] =
L"Militia Volunteers: %d (+%5.3f)",
};
STR16 szEnemyHeliText[] = // TODO.Translate
{
L"Enemy helicopter shot down in %s!",
L"We... uhm... currently don't control that site, commander...",
L"The SAM does not need maintenance at the moment.",
L"We've already ordered the repair, this will take time.",
L"We do not have enough resources to do that.",
L"Repair SAM site? This will cost %d$ and take %d hours.",
L"Enemy helicopter hit in %s.",
L"%s fires %s at enemy helicopter in %s.",
L"SAM in %s fires at enemy helicopter in %s.",
};
#endif //RUSSIAN
+1 -1
View File
@@ -640,7 +640,7 @@ UINT32 MainGameScreenHandle(void)
// Start heli Run...
StartHelicopterRun();
// Update clock by one so that our DidGameJustStatrt() returns now false for things like LAPTOP, etc...
SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );