mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
*************************
* HAM 3.6 (by Headrock) * ************************* - Info: Needed GameDir files for HAM 3.6 are not committed yet to the SVN GameDir. Will do that in the next few days - For more infos on HAM 3.6 check out: http://www.ja-galaxy-forum.com/board/ubbthreads.php?ubb=showflat&Number=244808&page=0&fpart=1 git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@3323 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1256,7 +1256,8 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
|
||||
UINT32 uiWorldMin;
|
||||
Compression0Callback( ButtonList[ iViewerButton[ COMPRESSION0 ] ], MSYS_CALLBACK_REASON_LBUTTON_UP );
|
||||
if( ( gsSelSectorX == 0 ) || ( gsSelSectorY == 0 ) )
|
||||
gsSelSectorX = 9, gsSelSectorY = 1;
|
||||
// HEADROCK HAM 3.5: Not sure what this function does at all... But this is externalized now anyway.
|
||||
gsSelSectorX = gGameExternalOptions.ubDefaultArrivalSectorX, gsSelSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
|
||||
ubSector = SECTOR( gsSelSectorX, gsSelSectorY );
|
||||
uiWorldMin = GetWorldTotalMin();
|
||||
|
||||
+3553
-316
File diff suppressed because it is too large
Load Diff
+54
-5
@@ -26,7 +26,7 @@
|
||||
|
||||
#define VEHICLE_REPAIR_POINTS_DIVISOR 10
|
||||
|
||||
|
||||
// HEADROCK HAM 3.6: Added separate Mobile Militia training assignment.
|
||||
// Assignments Defines
|
||||
enum{
|
||||
SQUAD_1 =0,
|
||||
@@ -57,8 +57,11 @@ enum{
|
||||
REPAIR,
|
||||
TRAIN_SELF,
|
||||
TRAIN_TOWN,
|
||||
TRAIN_MOBILE, // HEADROCK HAM 3.6: Training mobile militia.
|
||||
TRAIN_TEAMMATE,
|
||||
TRAIN_BY_OTHER,
|
||||
FACILITY_STAFF, // HEADROCK HAM 3.6: Operating a facility for strategic gain.
|
||||
FACILITY_REST, // HEADROCK HAM 3.6: Facility equivalent of resting (no assignment)
|
||||
ASSIGNMENT_DEAD,
|
||||
ASSIGNMENT_UNCONCIOUS, // unused
|
||||
ASSIGNMENT_POW,
|
||||
@@ -83,6 +86,16 @@ enum{
|
||||
// NOTE: Wisdom isn't trainable!
|
||||
};
|
||||
|
||||
// HEADROCK HAM 3.2: Set bitwise flags for locating facilities in current sector (for training/otherwise)
|
||||
// facilities flags
|
||||
// HEADROCK HAM 3.4: Removed due to facility externalization.
|
||||
/*#define AT_HOSPITAL 0x00000001
|
||||
#define AT_INDUSTRY 0x00000002
|
||||
#define AT_PRISON 0x00000004
|
||||
#define AT_MILITARY 0x00000008
|
||||
#define AT_AIRPORT 0x00000010
|
||||
#define AT_GUN_RANGE 0x00000020*/
|
||||
|
||||
|
||||
typedef struct TOWN_TRAINER_TYPE
|
||||
{
|
||||
@@ -106,6 +119,7 @@ BOOLEAN CanCharacterPatient( SOLDIERTYPE *pCharacter );
|
||||
|
||||
// can character train militia?
|
||||
BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pCharacter );
|
||||
BOOLEAN CanCharacterTrainMobileMilitia( SOLDIERTYPE *pSoldier );
|
||||
|
||||
// can character train stat?..as train self or as trainer?
|
||||
BOOLEAN CanCharacterTrainStat( SOLDIERTYPE *pSoldier, INT8 bStat, BOOLEAN fTrainSelf, BOOLEAN fTrainTeammate );
|
||||
@@ -116,6 +130,9 @@ BOOLEAN CanCharacterPractise( SOLDIERTYPE *pCharacter );
|
||||
// can this character train others?
|
||||
BOOLEAN CanCharacterTrainTeammates( SOLDIERTYPE *pSoldier );
|
||||
|
||||
// HEADROCK HAM 3.6: Can character use a specific facility?
|
||||
BOOLEAN CanCharacterFacility( SOLDIERTYPE *pSoldier, UINT8 ubFacilityType, UINT8 ubAssignmentType );
|
||||
|
||||
// put character on duty?
|
||||
BOOLEAN CanCharacterOnDuty( SOLDIERTYPE *pCharacter );
|
||||
|
||||
@@ -183,16 +200,18 @@ UINT8 CalculateRepairPointsForRepairman(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts
|
||||
|
||||
|
||||
// get bonus tarining pts due to an instructor for this student
|
||||
INT16 GetBonusTrainingPtsDueToInstructor( SOLDIERTYPE *pInstructor, SOLDIERTYPE *pStudent, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
|
||||
// HEADROCK HAM 3.5: Three functions below have lost an argument which is no longer required ("uiAtGunRange", which was "uiAtFacility" in HAM 3.4)
|
||||
INT16 GetBonusTrainingPtsDueToInstructor( SOLDIERTYPE *pInstructor, SOLDIERTYPE *pStudent, INT8 bTrainStat, UINT16 *pusMaxPts );
|
||||
|
||||
// get training pts for this soldier
|
||||
INT16 GetSoldierTrainingPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
|
||||
INT16 GetSoldierTrainingPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, UINT16 *pusMaxPts );
|
||||
|
||||
// pts for being a student for this soldier
|
||||
INT16 GetSoldierStudentPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
|
||||
INT16 GetSoldierStudentPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, UINT16 *pusMaxPts );
|
||||
|
||||
// HEADROCK HAM 3.6: Completely unused.
|
||||
// reset these soldiers
|
||||
void ResetAssignmentsForAllSoldiersInSectorWhoAreTrainingTown( SOLDIERTYPE *pSoldier );
|
||||
//void ResetAssignmentsForAllSoldiersInSectorWhoAreTrainingTown( SOLDIERTYPE *pSoldier );
|
||||
|
||||
// Handle assignment done
|
||||
void AssignmentDone( SOLDIERTYPE *pSoldier, BOOLEAN fSayQuote, BOOLEAN fMeToo );
|
||||
@@ -207,6 +226,9 @@ extern INT32 ghAttributeBox;
|
||||
extern INT32 ghRemoveMercAssignBox;
|
||||
extern INT32 ghContractBox;
|
||||
extern INT32 ghMoveBox;
|
||||
// HEADROCK HAM 3.6: Facility Menu, Submenu
|
||||
extern INT32 ghFacilityBox;
|
||||
extern INT32 ghFacilityAssignmentBox;
|
||||
//extern INT32 ghUpdateBox;
|
||||
|
||||
|
||||
@@ -219,6 +241,9 @@ extern MOUSE_REGION gSquadMenuRegion[ ];
|
||||
extern MOUSE_REGION gContractMenuRegion[ ];
|
||||
extern MOUSE_REGION gRemoveMercAssignRegion[ ];
|
||||
extern MOUSE_REGION gVehicleMenuRegion[];
|
||||
// HEADROCK HAM 3.6: Facility Menu.
|
||||
extern MOUSE_REGION gFacilityMenuRegion[];
|
||||
extern MOUSE_REGION gFacilityMenuRegion[];
|
||||
|
||||
extern BOOLEAN fShownContractMenu;
|
||||
extern BOOLEAN fShownAssignmentMenu;
|
||||
@@ -260,6 +285,16 @@ void CreateDestroyMouseRegionForRepairMenu( void );
|
||||
void RepairMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason );
|
||||
void RepairMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
|
||||
|
||||
// HEADROCK HAM 3.6: Facility Menu
|
||||
void CreateDestroyMouseRegionForFacilityMenu( void );
|
||||
void FacilityMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason );
|
||||
void FacilityMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
|
||||
|
||||
// HEADROCK HAM 3.6: Facility sub-menu
|
||||
void CreateDestroyMouseRegionsForFacilityAssignmentMenu( void );
|
||||
void FacilityAssignmentMenuMvtCallBack( MOUSE_REGION * pRegion, INT32 iReason );
|
||||
void FacilityAssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
|
||||
|
||||
// contract menu
|
||||
void CreateDestroyMouseRegionsForContractMenu( void );
|
||||
void ContractMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
|
||||
@@ -334,6 +369,20 @@ void HandleTrainingWakeSynchronize( SOLDIERTYPE *pSoldier );
|
||||
BOOLEAN FindAnyAwakeTrainers( SOLDIERTYPE *pTrainee );
|
||||
BOOLEAN FindAnyAwakeTrainees( SOLDIERTYPE *pTrainer );
|
||||
|
||||
// HEADROCK HAM 3.6: Functions for testing and reporting reasons why character can't train here.
|
||||
BOOLEAN CanCharacterTrainMilitiaWithErrorReport( SOLDIERTYPE *pSoldier );
|
||||
BOOLEAN CanCharacterTrainMobileMilitiaWithErrorReport( SOLDIERTYPE *pSoldier );
|
||||
// HEADROCK HAM 3.6: Function for testing and reporting reasons why character can't staff a facility.
|
||||
BOOLEAN CanCharacterFacilityWithErrorReport( SOLDIERTYPE *pSoldier, UINT8 ubFacilityType, UINT8 ubAssignmentType );
|
||||
void HandleInterfaceMessageForCostOfOperatingFacility( SOLDIERTYPE *pSoldier, UINT8 ubAssignmentType );
|
||||
void PayFacilityCostsYesNoBoxCallback( UINT8 bExitValue );
|
||||
void FacilityStaffingRejected( void );
|
||||
void ResetAllExpensiveFacilityAssignments();
|
||||
BOOLEAN IsOutstandingFacilityDebtWithErrorReport();
|
||||
extern INT8 gubFacilityInSubmenu;
|
||||
extern UINT8 gubFacilityLineForSubmenu;
|
||||
extern SOLDIERTYPE *gpFacilityStaffer;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -339,7 +339,8 @@ void RenderSoldierCellHealth( SOLDIERCELL *pCell );
|
||||
void RenderSoldierCell( SOLDIERCELL *pCell );
|
||||
void RenderSoldierCellBars( SOLDIERCELL *pCell );
|
||||
|
||||
void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
|
||||
// HEADROCK HAM 3.4: New argument configuration to make use of revamped movement controls
|
||||
void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fForTraining, BOOLEAN fForBattle );
|
||||
|
||||
|
||||
//Dynamic globals -- to conserve memory, all global variables are allocated upon entry
|
||||
@@ -2146,8 +2147,8 @@ void CreateAutoResolveInterface()
|
||||
ARCreateMilitiaSquad( &cnt, ubEliteMilitia, ubRegMilitia, ubGreenMilitia, gpAR->ubSectorX, gpAR->ubSectorY);
|
||||
|
||||
// Add the militia in the surrounding sectors
|
||||
GenerateDirectionInfos( gpAR->ubSectorX, gpAR->ubSectorY, &uiDirNumber, pMoveDir,
|
||||
( GetTownIdForSector( gpAR->ubSectorX, gpAR->ubSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, FALSE );
|
||||
// HEADROCK HAM 3.4: Changed argument configuration.
|
||||
GenerateDirectionInfos( gpAR->ubSectorX, gpAR->ubSectorY, &uiDirNumber, pMoveDir, FALSE, TRUE );
|
||||
for( i=0; i<uiDirNumber; i++)
|
||||
{
|
||||
INT16 sX = SECTORX( pMoveDir[ i ][0] );
|
||||
|
||||
@@ -273,8 +273,28 @@ UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UI
|
||||
// setup which know facilities are in which cities
|
||||
void InitKnowFacilitiesFlags( )
|
||||
{
|
||||
SECTORINFO *pSector;
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.5: No longer required. Function disconnected.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
//SECTORINFO *pSector;
|
||||
|
||||
// HEADROCK HAM 3.4: Externalized. All "known" facilities are read from gFacilityLocations. The
|
||||
// ones that have (fHidden=0) will be added to the sector info now, and thus visible immediately.
|
||||
// The others are added only once the player visits those sectors.
|
||||
|
||||
/*for(UINT32 cnt=0; (gFacilityLocations[cnt].uiSectorID >= 0 && gFacilityLocations[cnt].uiSectorID <= 256); cnt++ )
|
||||
{
|
||||
// Is the current sector valid? Is the facility set to be revealed on game-start?
|
||||
if (gFacilityLocations[cnt].uiSectorID > 0 && gFacilityLocations[cnt].uiSectorID < 257 &&
|
||||
gFacilityLocations[cnt].fHidden == 0)
|
||||
{
|
||||
// Reveal the facility.
|
||||
pSector = &SectorInfo[gFacilityLocations[cnt].uiSectorID];
|
||||
pSector->uiFacilitiesFlags |= (1 << (gFacilityLocations[cnt].uiFacilityType-1));
|
||||
}
|
||||
}*/
|
||||
|
||||
/* HEADROCK HAM 3.4: Externalized.
|
||||
// Cambria hospital
|
||||
pSector = &SectorInfo[SEC_G8];
|
||||
pSector->uiFacilitiesFlags |= SFCF_HOSPITAL;
|
||||
@@ -304,6 +324,7 @@ void InitKnowFacilitiesFlags( )
|
||||
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
|
||||
pSector = &SectorInfo[SEC_O4];
|
||||
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -603,13 +624,16 @@ void InitNewCampaign()
|
||||
|
||||
InitWorld(); // Lesh: generate different world each time using alternative maps
|
||||
InitMiningLocations();
|
||||
InitKnowFacilitiesFlags( );
|
||||
|
||||
// HEADROCK HAM 3.5: This is no longer required.
|
||||
//InitKnowFacilitiesFlags( );
|
||||
|
||||
BuildUndergroundSectorInfoList();
|
||||
|
||||
if (!is_networked)
|
||||
// allow overhead view of omerta A9 on game onset
|
||||
SetSectorFlag( startingX, startingY, startingZ, SF_ALREADY_VISITED ); //hayden
|
||||
// HEADROCK HAM 3.5: Externalized.
|
||||
SetSectorFlag( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ, SF_ALREADY_VISITED ); //hayden
|
||||
|
||||
//Generates the initial forces in a new campaign. The idea is to randomize numbers and sectors
|
||||
//so that no two games are the same.
|
||||
|
||||
+210
-8
@@ -112,19 +112,214 @@ enum
|
||||
MAX_MILITIA_LEVELS
|
||||
};
|
||||
|
||||
// facilities flags
|
||||
// HEADROCK HAM 3.5: No longer needed. Facility types externalized.
|
||||
/*// facilities flags
|
||||
#define SFCF_HOSPITAL 0x00000001
|
||||
#define SFCF_INDUSTRY 0x00000002
|
||||
#define SFCF_PRISON 0x00000004
|
||||
#define SFCF_MILITARY 0x00000008
|
||||
#define SFCF_AIRPORT 0x00000010
|
||||
#define SFCF_GUN_RANGE 0x00000020
|
||||
#define SFCF_GUN_RANGE 0x00000020*/
|
||||
|
||||
// coordinates of shooting range sector
|
||||
// HEADROCK HAM 3.4: These are no longer needed anywhere in the code.
|
||||
/*// coordinates of shooting range sector
|
||||
#define GUN_RANGE_X 13
|
||||
#define GUN_RANGE_Y MAP_ROW_H
|
||||
#define GUN_RANGE_Z 0
|
||||
|
||||
// HEADROCK HAM 3.2: New values for the location of an Industrial sector in Grumm H2. This sector boosts repair rates.
|
||||
#define INDUSTRIAL_X 2
|
||||
#define INDUSTRIAL_Y MAP_ROW_H
|
||||
#define INDUSTRIAL_Z 0*/
|
||||
|
||||
// HEADROCK HAM 3.4: Facility Locations
|
||||
typedef struct FACILITYLOCATIONS
|
||||
{
|
||||
BOOLEAN fFacilityHere;
|
||||
UINT8 ubHidden;
|
||||
}FACILITYLOCATIONS;
|
||||
|
||||
enum
|
||||
{
|
||||
// Enumerate the different assignments that a facility can emulate.
|
||||
FAC_AMBIENT = 0,
|
||||
FAC_STAFF,
|
||||
FAC_REST,
|
||||
FAC_REPAIR_ITEMS,
|
||||
FAC_REPAIR_VEHICLE,
|
||||
FAC_REPAIR_ROBOT,
|
||||
FAC_DOCTOR,
|
||||
FAC_PATIENT,
|
||||
FAC_PRACTICE_STRENGTH,
|
||||
FAC_PRACTICE_DEXTERITY,
|
||||
FAC_PRACTICE_AGILITY,
|
||||
FAC_PRACTICE_HEALTH,
|
||||
FAC_PRACTICE_MARKSMANSHIP,
|
||||
FAC_PRACTICE_MEDICAL,
|
||||
FAC_PRACTICE_MECHANICAL,
|
||||
FAC_PRACTICE_LEADERSHIP,
|
||||
FAC_PRACTICE_EXPLOSIVES,
|
||||
FAC_STUDENT_STRENGTH,
|
||||
FAC_STUDENT_DEXTERITY,
|
||||
FAC_STUDENT_AGILITY,
|
||||
FAC_STUDENT_HEALTH,
|
||||
FAC_STUDENT_MARKSMANSHIP,
|
||||
FAC_STUDENT_MEDICAL,
|
||||
FAC_STUDENT_MECHANICAL,
|
||||
FAC_STUDENT_LEADERSHIP,
|
||||
FAC_STUDENT_EXPLOSIVES,
|
||||
FAC_TRAINER_STRENGTH,
|
||||
FAC_TRAINER_DEXTERITY,
|
||||
FAC_TRAINER_AGILITY,
|
||||
FAC_TRAINER_HEALTH,
|
||||
FAC_TRAINER_MARKSMANSHIP,
|
||||
FAC_TRAINER_MEDICAL,
|
||||
FAC_TRAINER_MECHANICAL,
|
||||
FAC_TRAINER_LEADERSHIP,
|
||||
FAC_TRAINER_EXPLOSIVES,
|
||||
NUM_FACILITY_ASSIGNMENTS,
|
||||
};
|
||||
|
||||
|
||||
// Enumerated list of risk types
|
||||
enum
|
||||
{
|
||||
RISK_STRENGTH = 0,
|
||||
RISK_HEALTH,
|
||||
RISK_AGILITY,
|
||||
RISK_DEXTERITY,
|
||||
RISK_WISDOM,
|
||||
RISK_MARKSMANSHIP,
|
||||
RISK_LEADERSHIP,
|
||||
RISK_EXPLOSIVES,
|
||||
RISK_MECHANICAL,
|
||||
RISK_MEDICAL,
|
||||
|
||||
RISK_INJURY,
|
||||
RISK_MORALE,
|
||||
RISK_FATIGUE,
|
||||
RISK_DRUNK,
|
||||
|
||||
RISK_LOYALTY_LOCAL,
|
||||
RISK_LOYALTY_GLOBAL,
|
||||
|
||||
NUM_RISKS,
|
||||
};
|
||||
|
||||
typedef struct FACILITYRISKTYPE
|
||||
{
|
||||
// The risks involved with perfoming an assignment at a specific facility.
|
||||
|
||||
UINT8 ubChance; // Chance out of X that this risk will trigger every hour. X is INI-defined and is normally 1000.
|
||||
INT8 bBaseEffect; // Base result. If negative, result will always be negative. If positive, result will always be positive.
|
||||
// If 0, result can be either negative or positive.
|
||||
UINT8 ubRange; // Range of deviation for the base effect.
|
||||
|
||||
} FACILITYRISKTYPE;
|
||||
|
||||
typedef struct FACILITYASSIGNMENTTYPE
|
||||
{
|
||||
// This contains data about performing a specific assignment at a specific facility.
|
||||
|
||||
UINT8 ubStaffLimit; // Maximum number of people who can perform this assignment simultaneously
|
||||
CHAR16 szTooltipText[300]; // Tooltip explaining the assignment in general terms.
|
||||
INT16 sCostPerHour; // Cost per hour. Can be negative to indicate FLAT PROFIT per hour.
|
||||
|
||||
UINT16 usPerformance; // Percentage effectiveness of this assignment compared to non-emulated assignment (100 = normal)
|
||||
UINT16 usFatigue; // Percentage speed of losing Max Breath (100 = normal)
|
||||
UINT16 usSleep; // Percentage effectiveness of sleeping on the job (100 = normal)
|
||||
UINT16 usKitDegrade; // Percentage speed of kit degrade (100 = normal)
|
||||
|
||||
UINT8 ubMaximumMorale; // Maximum morale achievable while performing this assignment
|
||||
UINT8 ubMaximumBreath; // Maximum breath achievable while performing this assignment
|
||||
|
||||
UINT8 ubDetectEnemiesImmediate; // Detection of enemies in adjacent sectors, value = range of detection.
|
||||
BOOLEAN fDetectEnemiesLongrange; // Detection of enemies in explored territory
|
||||
BOOLEAN fDetectEnemiesDynamic; // Detection of enemies in Mobile Militia areas
|
||||
BOOLEAN fDetectEnemiesAnywhere; // Detection of enemies all over the map
|
||||
BOOLEAN fCountEnemiesInWild; // Count number of enemies in wilderness sectors
|
||||
BOOLEAN fCountEnemiesInCities; // Count number of enemies in city sectors
|
||||
|
||||
INT16 sSkyriderCostModifier; // Flat modifier for Skyrider's Cost Per Tile
|
||||
UINT16 usMineIncomeModifier; // Percentage income adjustment
|
||||
BOOLEAN fOnlyLocalMineAffected; // Determines whether income modifier applies to local mine only, or all mines.
|
||||
|
||||
UINT8 ubMinimumStrength; // Minimum STR Requirement to begin this assignment
|
||||
UINT8 ubMinimumHealth; // Minimum HLT Requirement to begin this assignment
|
||||
UINT8 ubMinimumWisdom; // Minimum WIS Requirement to begin this assignment
|
||||
UINT8 ubMinimumAgility; // Minimum AGI Requirement to begin this assignment
|
||||
UINT8 ubMinimumDexterity; // Minimum DEX Requirement to begin this assignment
|
||||
UINT8 ubMinimumMarksmanship; // Minimum MRK Requirement to begin this assignment
|
||||
UINT8 ubMinimumLeadership; // Minimum LDR Requirement to begin this assignment
|
||||
UINT8 ubMinimumExplosives; // Minimum EXP Requirement to begin this assignment
|
||||
UINT8 ubMinimumMechanical; // Minimum MEC Requirement to begin this assignment
|
||||
UINT8 ubMinimumMedical; // Minimum MED Requirement to begin this assignment
|
||||
UINT8 ubMinimumLevel; // Minimum LVL Requirement to begin this assignment
|
||||
|
||||
UINT8 ubMinimumLoyaltyHere; // Minimum loyalty required in the town where the facility is placed (if any)
|
||||
UINT8 ubMinimumBreath; // Minimum Breath Requirement to begin this assignment
|
||||
UINT8 ubMinimumMorale; // Minimum Morale Requirement to begin this assignment
|
||||
|
||||
FACILITYRISKTYPE Risk[ NUM_RISKS ]; // Data about risks/chances possible when doing this assignment
|
||||
|
||||
} FACILITYASSIGNMENTTYPE;
|
||||
|
||||
// HEADROCK HAM 3.5: Facility Type
|
||||
typedef struct FACILITYTYPE
|
||||
{
|
||||
// Basic data about the facility
|
||||
|
||||
CHAR16 szFacilityName[30]; // Long facility name
|
||||
CHAR16 szFacilityShortName[15]; // Short facility name
|
||||
UINT8 ubTotalStaffLimit; // Total number of people who can work here simultaneously
|
||||
|
||||
UINT8 ubMilitiaTrainersAllowed; // Number of Militia trainers allowed simultaneously
|
||||
UINT8 ubMobileMilitiaTrainersAllowed; // Number of Mobile Militia trainers allowed simultaneously
|
||||
UINT16 usMilitiaTraining; // Percentage effectiveness of Militia training (100 = normal)
|
||||
UINT16 usMobileMilitiaTraining; // Percentage effectiveness of Mobile Militia training (100 = normal)
|
||||
|
||||
FACILITYASSIGNMENTTYPE AssignmentData[ NUM_FACILITY_ASSIGNMENTS ]; // Data about possible assignments that can be done here
|
||||
|
||||
} FACILITYTYPE;
|
||||
|
||||
|
||||
// HEADROCK HAM 3.5: Maximum number of different facility types
|
||||
#define MAX_NUM_FACILITY_TYPES 255
|
||||
// HEADROCK HAM 3.5: Number of facilities placed on the map
|
||||
extern UINT16 NUM_FACILITIES;
|
||||
// HEADROCK HAM 3.5: Number of facility types read from XML
|
||||
extern UINT16 NUM_FACILITY_TYPES;
|
||||
// HEADROCK HAM 3.4: Array to hold facilities in each sector
|
||||
extern FACILITYLOCATIONS gFacilityLocations[256][MAX_NUM_FACILITY_TYPES];
|
||||
// HEADROCK HAM 3.5: Array to hold all different facility types
|
||||
extern FACILITYTYPE gFacilityTypes[MAX_NUM_FACILITY_TYPES];
|
||||
|
||||
// HEADROCK HAM 3.6: Bloodcat Placement and Encounter data.
|
||||
typedef struct BLOODCATPLACEMENT
|
||||
{
|
||||
UINT8 PlacementType;
|
||||
UINT8 ubMinBloodcats;
|
||||
UINT8 ubMaxBloodcats;
|
||||
UINT8 ubAmbushChance;
|
||||
BOOLEAN ubFactionAffiliation;
|
||||
BOOLEAN fRespawn;
|
||||
}BLOODCATPLACEMENT;
|
||||
|
||||
// HEADROCK HAM 3.6: Array to hold bloodcat placements and user-set bloodcat encounter data. There are 256 of these
|
||||
// (one for each sector), with 4 sublevels (one for each difficulty)
|
||||
extern BLOODCATPLACEMENT gBloodcatPlacements[256][4];
|
||||
// Location of the Bloodcat Lair. There can be only one, as there's a quest that relies on its location. This is a
|
||||
// sectorID, 0-255.
|
||||
extern UINT8 gubBloodcatLairSectorId;
|
||||
|
||||
// HEADROCK HAM 3.6: Enumerated Bloodcat Placement types
|
||||
enum
|
||||
{
|
||||
BLOODCAT_PLACEMENT_AMBUSH = 0,
|
||||
BLOODCAT_PLACEMENT_STATIC,
|
||||
BLOODCAT_PLACEMENT_LAIR,
|
||||
NUM_BLOODCAT_PLACEMENT_TYPES
|
||||
};
|
||||
|
||||
//Vehicle types
|
||||
#define FOOT 0x01 //anywhere
|
||||
@@ -227,8 +422,8 @@ typedef struct SECTORINFO
|
||||
//throught the sector without entering it.
|
||||
INT8 bNameId;
|
||||
INT8 bUSUSED;
|
||||
INT8 bBloodCats;
|
||||
INT8 bBloodCatPlacements;
|
||||
INT8 bBloodCats; // Actual number of bloodcats existing on this map.
|
||||
INT8 bBloodCatPlacements; // "Maximum" potential bloodcats that can appear on this map.
|
||||
INT8 UNUSEDbSAMCondition;
|
||||
|
||||
UINT8 ubTravelRating; //Represents how travelled a sector is. Typically, the higher the travel rating,
|
||||
@@ -236,15 +431,22 @@ typedef struct SECTORINFO
|
||||
//around. This value is used for determining how often items would "vanish" from
|
||||
//a sector (nice theory, except it isn't being used that way. Stealing is only in towns. ARM)
|
||||
UINT8 ubNumberOfCivsAtLevel[ MAX_MILITIA_LEVELS ]; // town militia per experience class, 0/1/2 is GREEN/REGULAR/ELITE
|
||||
UINT16 usUNUSEDMilitiaLevels; // unused (ARM)
|
||||
UINT8 ubUNUSEDNumberOfJoeBlowCivilians; // unused (ARM)
|
||||
// HEADROCK HAM 3.6: Adding separate training percentage for MOBILES.
|
||||
UINT8 ubMobileMilitiaTrainingPercentDone;
|
||||
UINT8 ubMobileMilitiaTrainingHundredths;
|
||||
BOOLEAN fMobileMilitiaTrainingPaid;
|
||||
// Replacing these variables with the ones above. They really are unused.
|
||||
//UINT16 usUNUSEDMilitiaLevels; // unused (ARM)
|
||||
//UINT8 ubUNUSEDNumberOfJoeBlowCivilians; // unused (ARM)
|
||||
UINT32 uiTimeCurrentSectorWasLastLoaded; //Specifies the last time the player was in the sector
|
||||
UINT8 ubUNUSEDNumberOfEnemiesThoughtToBeHere; // using bLastKnownEnemies instead
|
||||
UINT32 uiTimeLastPlayerLiberated; //in game seconds (used to prevent the queen from attacking for awhile)
|
||||
|
||||
BOOLEAN fSurfaceWasEverPlayerControlled;
|
||||
|
||||
UINT8 bFiller1;
|
||||
// HEADROCK HAM 3.6: Flag to determine whether enemy units in this sector can be seen, and whether their numbers
|
||||
// should be displayed. One filler was replaced to make room.
|
||||
UINT8 ubDetectionLevel;
|
||||
UINT8 bFiller2;
|
||||
UINT8 bFiller3;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
||||
#ifndef _FACILITIES_H
|
||||
#define _FACILITIES_H
|
||||
|
||||
#include "campaign types.h"
|
||||
#include "Soldier Control.h"
|
||||
|
||||
// Get a specific modifier for a specific assignment at a specific facility. Includes Ambient (non-assignment based)
|
||||
// effects, if any.
|
||||
INT16 GetFacilityModifier( UINT8 ubModifierType, UINT8 ubFacilityType, UINT8 ubAssignmentType );
|
||||
// Get a specific modifier from all facilities in the soldier's sector. This utilizes the above function.
|
||||
INT16 GetSectorModifier( SOLDIERTYPE *pSoldier, UINT8 ubModifierType );
|
||||
|
||||
// Level of awareness to enemy movements, bestowed by facilities
|
||||
extern void UpdateStrategicDetectionLevel( );
|
||||
|
||||
// Adjustment to Skyrider's cost-per-tile, bestowed by facilities
|
||||
extern void UpdateSkyriderCostModifier( );
|
||||
extern INT16 gsSkyriderCostModifier; // This variable is SAVED/LOADED
|
||||
|
||||
// HEADROCK HAM 3.6: Strategic info variable, total of costs accumulated for the use of facilities today. Deducted
|
||||
// from account and reset at midnight, unless player can't pay (in which case, carries over to the next day).
|
||||
extern INT32 giTotalOwedForFacilityOperationsToday; // This variable is SAVED and LOADED.
|
||||
// Do we have outstanding debts for facility operation?
|
||||
extern BOOLEAN gfOutstandingFacilityDebt; // This variable is SAVED and LOADED.
|
||||
|
||||
// Place this here for facility staffing checks.
|
||||
extern UINT32 GetWorldTotalMin( );
|
||||
|
||||
// These are all the different modifiers we could be checking for.
|
||||
enum
|
||||
{
|
||||
FACILITY_PERFORMANCE_MOD = 0,
|
||||
FACILITY_SLEEP_MOD,
|
||||
FACILITY_FATIGUE_MOD,
|
||||
FACILITY_KIT_DEGRADE_MOD,
|
||||
|
||||
FACILITY_MAX_MORALE,
|
||||
FACILITY_MAX_BREATH,
|
||||
|
||||
FACILITY_DETECT_IMMEDIATE,
|
||||
FACILITY_DETECT_DYNAMIC,
|
||||
FACILITY_DETECT_LONGRANGE,
|
||||
FACILITY_DETECT_ANYWHERE,
|
||||
FACILITY_COUNT_INWILD,
|
||||
FACILITY_COUNT_INCITIES,
|
||||
|
||||
FACILITY_MINE_INCOME_MOD,
|
||||
FACILITY_SKYRIDER_COST_MOD,
|
||||
};
|
||||
|
||||
// HEADROCK HAM 3.6: Different enemy detection and counting levels
|
||||
enum
|
||||
{
|
||||
DETECT_ENEMIES_DYNAMIC = 0,
|
||||
DETECT_ENEMIES_LONGRANGE,
|
||||
DETECT_ENEMIES_ANYWHERE,
|
||||
|
||||
COUNT_ENEMIES_IN_WILD,
|
||||
COUNT_ENEMIES_IN_CITIES,
|
||||
};
|
||||
|
||||
void UpdateGlobalVariablesFromFacilities( void );
|
||||
void UpdateFacilityUsageCosts( void );
|
||||
|
||||
void HandleDailyPaymentFacilityDebt( void );
|
||||
void HandleManualPaymentFacilityDebt( void );
|
||||
void HandleHourlyRisks( void );
|
||||
|
||||
INT32 MineIncomeModifierFromFacility( UINT8 ubMine );
|
||||
INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier );
|
||||
void HandleRisksForSoldier( SOLDIERTYPE *pSoldier );
|
||||
void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFacilityType, UINT8 ubAssignmentType );
|
||||
INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacilityType, UINT8 ubAssignmentType );
|
||||
INT32 GetTotalFacilityHourlyCosts( BOOLEAN fPositive );
|
||||
|
||||
void InitFacilities();
|
||||
|
||||
#endif
|
||||
+78
-2
@@ -61,6 +61,8 @@
|
||||
#include "Interface.h"
|
||||
#include "cheats.h"
|
||||
#include "Interface Panels.h"
|
||||
// HEADROCK HAM 3.6: Include for adding facility debt reset
|
||||
#include "Facilities.h"
|
||||
#endif
|
||||
|
||||
#include "Vehicles.h"
|
||||
@@ -233,6 +235,64 @@ void InitNPCs( void )
|
||||
|
||||
void InitBloodCatSectors()
|
||||
{
|
||||
///////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.6: Bloodcat Placement Externalization
|
||||
//
|
||||
// It is now possible for the user/modder to set the maximum number of bloodcats that may appear in the sector.
|
||||
// We can now place bloodcats anywhere we'd like (aboveground), stretching the limits of maps without disturbing
|
||||
// the game. The placements defined here are still the absolute MAXIMUM, so if the map has more placements available
|
||||
// they will be ignored.
|
||||
// Please note that if the mapfile has LESS placements than indicated here, then the game will reduce the number of
|
||||
// placements automatically to fit the MAP, not the XML.
|
||||
|
||||
UINT16 x = 0;
|
||||
UINT8 PlacementType = 0;
|
||||
UINT8 ubMaxBloodcats = 0;
|
||||
UINT8 ubDifficulty = gGameOptions.ubDifficultyLevel-1; // This way, novice=0.
|
||||
INT16 ubLairSectorId = -1; // Location of ONE lair sector (the first one found)
|
||||
|
||||
// Clean all bloodcat data.
|
||||
for( x = 0; x < 256; x++ )
|
||||
{
|
||||
SectorInfo[ x ].bBloodCats = 0;
|
||||
SectorInfo[ x ].bBloodCatPlacements = 0;
|
||||
}
|
||||
|
||||
// Begin loop for every sector.
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
// Set "maximum placements" value to whatever is defined in the XML file for this difficulty level.
|
||||
SectorInfo[ x ].bBloodCatPlacements = gBloodcatPlacements[x][ubDifficulty].ubMaxBloodcats;
|
||||
|
||||
PlacementType = gBloodcatPlacements[x][0].PlacementType;
|
||||
|
||||
// Record the first sector you can find which is defined as a LAIR sector. Only one sector can serve
|
||||
// this purpose, because the quests rely on it.
|
||||
if (PlacementType == BLOODCAT_PLACEMENT_LAIR && ubLairSectorId == -1)
|
||||
{
|
||||
ubLairSectorId = x;
|
||||
}
|
||||
|
||||
if (PlacementType != 0)
|
||||
{
|
||||
// Sector is a lair or static bloodcat sector. Fill it up with actual bloodcats please.
|
||||
SectorInfo[ x ].bBloodCats = gBloodcatPlacements[x][ubDifficulty].ubMaxBloodcats;
|
||||
// "Ambush" sectors (PlacementType 0) do not have bloodcats in them until triggered.
|
||||
}
|
||||
}
|
||||
|
||||
if (ubLairSectorId >= 0)
|
||||
{
|
||||
gubBloodcatLairSectorId = (UINT8)ubLairSectorId;
|
||||
}
|
||||
else
|
||||
{
|
||||
THROWEXCEPTION(L"At least one Bloodcat Lair must be defined in BloodcatPlacements.XML!");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
INT32 i;
|
||||
//Hard coded table of bloodcat populations. We don't have
|
||||
//access to the real population (if different) until we physically
|
||||
@@ -296,7 +356,7 @@ void InitBloodCatSectors()
|
||||
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 18;
|
||||
SectorInfo[ SEC_N5 ].bBloodCats = 18;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@@ -334,6 +394,8 @@ void InitStrategicLayer( void )
|
||||
// make Orta, Tixa, SAM sites not found
|
||||
InitMapSecrets();
|
||||
|
||||
// HEADROCK HAM 3.6: Initialize facilities.
|
||||
InitFacilities();
|
||||
|
||||
// free up any leave list arrays that were left allocated
|
||||
ShutDownLeaveList( );
|
||||
@@ -344,7 +406,8 @@ void InitStrategicLayer( void )
|
||||
SetGameTimeCompressionLevel( TIME_COMPRESS_X0 );
|
||||
|
||||
// select A9 Omerta as the initial selected sector
|
||||
ChangeSelectedMapSector( startingX, startingY, startingZ );
|
||||
// HEADROCK HAM 3.5: Actually, this is where we set the starting sector based on external variables.
|
||||
ChangeSelectedMapSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
|
||||
|
||||
// Reset these flags or mapscreen could be disabled and cause major headache.
|
||||
fDisableDueToBattleRoster = FALSE;
|
||||
@@ -498,6 +561,10 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
|
||||
AddFutureDayStrategicEvent( EVENT_DAY3_ADD_EMAIL_FROM_SPECK, 60*7, 0, uiDaysTimeMercSiteAvailable );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.5: Reset LZ to default arrival
|
||||
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
|
||||
#ifdef CRIPPLED_VERSION
|
||||
{
|
||||
UINT32 cnt;
|
||||
@@ -864,6 +931,15 @@ void ReStartingGame()
|
||||
//Reload the Merc profiles
|
||||
LoadMercProfiles( );
|
||||
|
||||
if (gGameExternalOptions.fWriteProfileDataToXML)
|
||||
{
|
||||
// HEADROCK PROFEX: Create mercprofiles xml output
|
||||
WriteMercProfiles();
|
||||
|
||||
// HEADROCK PROFEX: Create mercopinions xml output
|
||||
WriteMercOpinions();
|
||||
}
|
||||
|
||||
// Reload quote files
|
||||
ReloadAllQuoteFiles();
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "SaveLoadGame.h"
|
||||
#include "GameSettings.h"
|
||||
#include "connect.h"
|
||||
// HEADROCK HAM 3.5: Add facility code for hourly update of detection levels
|
||||
#include "Facilities.h"
|
||||
|
||||
void HourlyQuestUpdate( void );
|
||||
void HourlyLarryUpdate( void );
|
||||
@@ -56,9 +58,17 @@ void HandleHourlyUpdate()
|
||||
// hourly update of team assignments
|
||||
UpdateAssignments();
|
||||
|
||||
// HEADROCK HAM 3.5: Tells the rest of the program whether we've got mercs working on detecting enemy units.
|
||||
UpdateStrategicDetectionLevel();
|
||||
|
||||
// HEADROCK HAM 3.5: Re-calculates a modifier to Skyrider's flight costs based on mercs working in specific facilities.
|
||||
UpdateSkyriderCostModifier();
|
||||
|
||||
// hourly update of hated/liked mercs
|
||||
UpdateBuddyAndHatedCounters();
|
||||
|
||||
HandleHourlyRisks();
|
||||
|
||||
// update morale!
|
||||
HourlyMoraleUpdate();
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "soundman.h"
|
||||
#include "Isometric Utils.h"
|
||||
#include "Scheduling.h"
|
||||
// HEADROCK HAM 3.5: Added facility-based skyrider costs modifier
|
||||
#include "Facilities.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -527,16 +529,23 @@ INT32 GetCostOfPassageForHelicopter( INT16 sX, INT16 sY )
|
||||
// check if sector is air controlled or not, if so, then normal cost, otherwise increase the cost
|
||||
INT32 iCost = 0;
|
||||
|
||||
// HEADROCK HAM 3.5: Costs externalized
|
||||
INT32 iBaseCostPerGreenTile = gGameExternalOptions.usHelicopterBaseCostPerGreenTile;
|
||||
INT32 iBaseCostPerRedTile = gGameExternalOptions.usHelicopterBaseCostPerRedTile;
|
||||
|
||||
// if they don't control it
|
||||
if( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sX, sY ) ].fEnemyAirControlled == FALSE )
|
||||
{
|
||||
iCost = COST_AIRSPACE_SAFE;
|
||||
iCost = iBaseCostPerGreenTile;
|
||||
}
|
||||
else
|
||||
{
|
||||
iCost = COST_AIRSPACE_UNSAFE;
|
||||
iCost = iBaseCostPerRedTile;
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.5: Apply facility-based modifiers from global integer recalculated hourly
|
||||
iCost = __max(0, iCost + gsSkyriderCostModifier);
|
||||
|
||||
return( iCost );
|
||||
}
|
||||
|
||||
|
||||
@@ -773,7 +773,9 @@ void ToggleShowMilitiaMode( void )
|
||||
// no - so put up a message explaining how it works
|
||||
|
||||
// if he's already training some
|
||||
if( IsAnyOneOnPlayersTeamOnThisAssignment( TRAIN_TOWN ) )
|
||||
// HEADROCK HAM 3.6: Also for Mobile trainers.
|
||||
if( IsAnyOneOnPlayersTeamOnThisAssignment( TRAIN_TOWN ) ||
|
||||
IsAnyOneOnPlayersTeamOnThisAssignment( TRAIN_MOBILE ) )
|
||||
{
|
||||
// say they'll show up when training is completed
|
||||
pwString = pMapErrorString[ 28 ];
|
||||
|
||||
@@ -68,8 +68,12 @@ want to have the new inventory panel not overlap the message text area. */
|
||||
#define MESSAGE_SCROLL_AREA_HEIGHT ( MESSAGE_SCROLL_AREA_END_Y - MESSAGE_SCROLL_AREA_START_Y + 1 )
|
||||
|
||||
// CHRISL: Use these if we want scroll bar based on left edge of screen
|
||||
#define MESSAGE_SCROLL_AREA_START_X 330
|
||||
#define MESSAGE_SCROLL_AREA_END_X 344
|
||||
// HEADROCK HAM 3.6: Now global variables to be changed when initializing map mode.
|
||||
// See InitMapScreenInterfaceBottomCoords()
|
||||
//#define MESSAGE_SCROLL_AREA_START_X 330
|
||||
//#define MESSAGE_SCROLL_AREA_END_X 344
|
||||
UINT16 MESSAGE_SCROLL_AREA_START_X;
|
||||
UINT16 MESSAGE_SCROLL_AREA_END_X;
|
||||
|
||||
#define SLIDER_HEIGHT 11
|
||||
#define SLIDER_WIDTH 11
|
||||
@@ -184,6 +188,7 @@ void DeleteMapScreenBottomMessageScrollRegion( void );
|
||||
void DisplayCurrentBalanceForMapBottom( void );
|
||||
void DisplayCurrentBalanceTitleForMapBottom( void );
|
||||
void DisplayProjectedDailyMineIncome( void );
|
||||
void DisplayProjectedDailyExpenses( void ); // HEADROCK HAM 3.6: New expenses window shows running costs today.
|
||||
void DrawNameOfLoadedSector( void );
|
||||
|
||||
void EnableDisableBottomButtonsAndRegions( void );
|
||||
@@ -296,7 +301,8 @@ void RenderMapScreenInterfaceBottom( BOOLEAN fForceMapscreenFullRender )
|
||||
// render whole panel
|
||||
// HEADROCK Changed this line to accept outside influence through the new boolean:
|
||||
//if ( fForceMapscreenFullRender == TRUE || fMapScreenBottomDirty == TRUE)
|
||||
if ( fMapScreenBottomDirty )
|
||||
// HEADROCK HAM 3.6: OK, let's always render this panel, as long as the team inventory screen isn't open.
|
||||
if ( fMapScreenBottomDirty || !fShowInventoryFlag )
|
||||
{
|
||||
// get and blt panel
|
||||
GetVideoObject(&hHandle, guiMAPBOTTOMPANEL );
|
||||
@@ -334,12 +340,20 @@ void RenderMapScreenInterfaceBottom( BOOLEAN fForceMapscreenFullRender )
|
||||
|
||||
// Headrock: Moved this next line from the above marker ^
|
||||
fMapScreenBottomDirty = FALSE;
|
||||
|
||||
// CHRISL: Don't display messagelist if inventory panel is open
|
||||
// CHRISL: Only run this condition if we're drawing the message list on the left
|
||||
// display messages that can be scrolled through
|
||||
// HEADROCK HAM 3.6: Hmmmm, why not draw them? LEt's just move this whole segment here, shall we?
|
||||
//if(!fShowInventoryFlag)
|
||||
DisplayStringsInMapScreenMessageList( );
|
||||
}
|
||||
|
||||
DisplayCompressMode( );
|
||||
|
||||
DisplayCurrentBalanceForMapBottom( );
|
||||
DisplayProjectedDailyMineIncome( );
|
||||
DisplayProjectedDailyExpenses( );
|
||||
|
||||
// draw the name of the loaded sector
|
||||
DrawNameOfLoadedSector( );
|
||||
@@ -347,12 +361,7 @@ void RenderMapScreenInterfaceBottom( BOOLEAN fForceMapscreenFullRender )
|
||||
// display slider on the scroll bar
|
||||
DisplayScrollBarSlider( );
|
||||
|
||||
// CHRISL: Don't display messagelist if inventory panel is open
|
||||
// CHRISL: Only run this condition if we're drawing the message list on the left
|
||||
// display messages that can be scrolled through
|
||||
if(!fShowInventoryFlag)
|
||||
DisplayStringsInMapScreenMessageList( );
|
||||
|
||||
|
||||
// handle auto scroll
|
||||
//CheckForAndHandleAutoMessageScroll( );
|
||||
|
||||
@@ -427,10 +436,12 @@ BOOLEAN CreateButtonsForMapScreenInterfaceBottom( void )
|
||||
// BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
||||
// (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMessageDownMapScreenCallback);
|
||||
// CHRISL: Use these if we want buttons based on left edge of screen
|
||||
guiMapMessageScrollButtons[ MAP_SCROLL_MESSAGE_UP ] = QuickCreateButton( guiMapMessageScrollButtonsImage[ MAP_SCROLL_MESSAGE_UP ], 331, (SCREEN_HEIGHT - 109),
|
||||
// HEADROCK HAM 3.6: Message window is now as wide as possible.
|
||||
|
||||
guiMapMessageScrollButtons[ MAP_SCROLL_MESSAGE_UP ] = QuickCreateButton( guiMapMessageScrollButtonsImage[ MAP_SCROLL_MESSAGE_UP ], (SCREEN_WIDTH - 306), (SCREEN_HEIGHT - 109),
|
||||
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
||||
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMessageUpMapScreenCallback);
|
||||
guiMapMessageScrollButtons[ MAP_SCROLL_MESSAGE_DOWN ] = QuickCreateButton( guiMapMessageScrollButtonsImage[ MAP_SCROLL_MESSAGE_DOWN ], 331, (SCREEN_HEIGHT - 28),
|
||||
guiMapMessageScrollButtons[ MAP_SCROLL_MESSAGE_DOWN ] = QuickCreateButton( guiMapMessageScrollButtonsImage[ MAP_SCROLL_MESSAGE_DOWN ], (SCREEN_WIDTH - 306), (SCREEN_HEIGHT - 28),
|
||||
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
||||
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMessageDownMapScreenCallback);
|
||||
|
||||
@@ -1334,7 +1345,8 @@ BOOLEAN AllowedToTimeCompress( void )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( fShowAssignmentMenu || fShowTrainingMenu || fShowAttributeMenu || fShowSquadMenu || fShowContractMenu || fShowRemoveMenu )
|
||||
// HEADROCK HAM 3.6: Added Facility Menus
|
||||
if( fShowAssignmentMenu || fShowTrainingMenu || fShowAttributeMenu || fShowSquadMenu || fShowContractMenu || fShowRemoveMenu || fShowFacilityAssignmentMenu || fShowFacilityMenu )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -1428,7 +1440,9 @@ void DisplayCurrentBalanceTitleForMapBottom( void )
|
||||
// CHRISL: Replaced X coordinate with dynamic coordinate set from right edge of screen
|
||||
//VarFindFontCenterCoordinates( (SCREEN_WIDTH - 637), (SCREEN_HEIGHT - 107), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// CHRISL: Use this if we want to display from the left edge
|
||||
VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 107), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
//VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 107), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// HEADROCK HAM 3.6: The balance/income box has been moved to the right side, near the laptop button.
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 111), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
@@ -1439,7 +1453,18 @@ void DisplayCurrentBalanceTitleForMapBottom( void )
|
||||
// CHRISL: Replaced X coordinate with dynamic coordinate set from right edge of screen
|
||||
//VarFindFontCenterCoordinates( (SCREEN_WIDTH - 637), (SCREEN_HEIGHT - 61), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// CHRISL: Use this if we want to display from the left edge
|
||||
VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 61), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
//VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 61), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// HEADROCK HAM 3.6: The balance/income box has been moved to the right side, near the laptop button.
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 74), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
|
||||
swprintf( sString, L"%s", New113HAMMessage[ 20 ] );
|
||||
|
||||
// HEADROCK HAM 3.6: Projected expenses for today, with facilities (and in the future, merc contracts) taken into
|
||||
// account.
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 37), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
@@ -1474,7 +1499,9 @@ void DisplayCurrentBalanceForMapBottom( void )
|
||||
// CHRISL: Replaced X coordinate with dynamic coordinate set from right edge of screen
|
||||
//VarFindFontCenterCoordinates( (SCREEN_WIDTH - 637), (SCREEN_HEIGHT - 91), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// CHRISL: Use this if we want to display from the left edge
|
||||
VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 91), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
//VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 91), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// HEADROCK HAM 3.6: The balance/income box has been moved to the right side, near the laptop button.
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 95), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
@@ -1588,7 +1615,9 @@ void DisplayProjectedDailyMineIncome( void )
|
||||
// CHRISL: Replaced X coordinate with dynamic coordinate set from right edge of screen
|
||||
//VarFindFontCenterCoordinates( (SCREEN_WIDTH - 637), (SCREEN_HEIGHT - 45), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// CHRISL: Use this if we want to display from the left edge
|
||||
VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 45), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
//VarFindFontCenterCoordinates( 359, (SCREEN_HEIGHT - 45), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
// HEADROCK HAM 3.6: The balance/income box has been moved to the right side, near the laptop button.
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 58), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
@@ -1596,6 +1625,58 @@ void DisplayProjectedDailyMineIncome( void )
|
||||
return;
|
||||
}
|
||||
|
||||
void DisplayProjectedDailyExpenses( void )
|
||||
{
|
||||
INT32 iRate = 0;
|
||||
static INT32 iOldExpensesRate = -1;
|
||||
CHAR16 sString[ 128 ];
|
||||
INT16 sFontX, sFontY;
|
||||
|
||||
// grab the rate from the financial system
|
||||
iRate = GetProjectedExpenses( );
|
||||
|
||||
if( iRate != iOldExpensesRate )
|
||||
{
|
||||
iOldExpensesRate = iRate;
|
||||
fMapScreenBottomDirty = TRUE;
|
||||
|
||||
// if screen was not dirtied, leave
|
||||
if( fMapBottomDirtied == FALSE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// set the font buffer
|
||||
SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
||||
|
||||
// set up the font
|
||||
SetFont( COMPFONT );
|
||||
if (iRate == 0)
|
||||
{
|
||||
SetFontForeground( 183 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFontForeground( FONT_MCOLOR_LTRED );
|
||||
}
|
||||
SetFontBackground( FONT_BLACK );
|
||||
|
||||
swprintf( sString, L"%d", iRate );
|
||||
|
||||
// insert extra characters
|
||||
InsertCommasForDollarFigure( sString );
|
||||
InsertDollarSignInToString( sString );
|
||||
|
||||
// center it
|
||||
VarFindFontCenterCoordinates( (SCREEN_WIDTH - 278), (SCREEN_HEIGHT - 21), 78, 10, COMPFONT, &sFontX, &sFontY, sString );
|
||||
|
||||
// print it
|
||||
mprintf( sFontX, sFontY, L"%s", sString );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN CommonTimeCompressionChecks( void )
|
||||
{
|
||||
@@ -1950,3 +2031,11 @@ void ChangeCurrentMapscreenMessageIndex( UINT8 ubNewMessageIndex )
|
||||
// refresh screen
|
||||
fMapScreenBottomDirty = TRUE;
|
||||
}
|
||||
|
||||
void InitMapScreenInterfaceBottomCoords( void )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Message window is now as wide as possible.
|
||||
MESSAGE_SCROLL_AREA_START_X = SCREEN_WIDTH - 307;
|
||||
MESSAGE_SCROLL_AREA_END_X = SCREEN_WIDTH - 293;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,4 +65,7 @@ void MapScreenMsgScrollUp( UINT8 ubLinesUp );
|
||||
void ChangeCurrentMapscreenMessageIndex( UINT8 ubNewMessageIndex );
|
||||
void MoveToEndOfMapScreenMessageList( void );
|
||||
|
||||
// HEADROCK HAM 3.6: Reset coordinates for slider bar and message window
|
||||
void InitMapScreenInterfaceBottomCoords( void );
|
||||
|
||||
#endif
|
||||
@@ -582,6 +582,8 @@ void CreateDestroyMapInventoryPoolButtons( BOOLEAN fExitFromMapScreen )
|
||||
fMapPanelDirty = TRUE;
|
||||
fTeamPanelDirty = TRUE;
|
||||
fCharacterInfoPanelDirty = TRUE;
|
||||
// HEADROCK HAM 3.6: Yet again, make sure to refresh the bottom panel on closing.
|
||||
fMapScreenBottomDirty = TRUE;
|
||||
|
||||
//CHRISL: close stack popup and item description windows
|
||||
DeleteItemStackPopup();
|
||||
@@ -1471,8 +1473,6 @@ void BeginInventoryPoolPtr( OBJECTTYPE *pInventorySlot )
|
||||
{
|
||||
for( UINT32 iNumber = 0 ; iNumber < pInventoryPoolList.size() ; ++iNumber)
|
||||
{
|
||||
// WANNE: Fix by Headrock
|
||||
//if ( pInventoryPoolList[ iNumber ].object.usItem == gItemPointer.usItem )
|
||||
if ( pInventoryPoolList[ iNumber ].object.usItem == gItemPointer.usItem && pInventoryPoolList[ iNumber ].usFlags & WORLD_ITEM_REACHABLE)
|
||||
{
|
||||
iPrice += SellItem( pInventoryPoolList[ iNumber ].object );
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
|
||||
#include "Quests.h"
|
||||
#include "connect.h"
|
||||
// HEADROCK HAM 3.5: included for detectionlevels
|
||||
#include "Facilities.h"
|
||||
#include "MilitiaSquads.h"
|
||||
|
||||
// zoom x and y coords for map scrolling
|
||||
INT32 iZoomX = 0;
|
||||
@@ -355,8 +358,9 @@ extern BOOLEAN fMapScreenBottomDirty;
|
||||
BOOLEAN fFoundTixa = FALSE;
|
||||
|
||||
// selected sector
|
||||
UINT16 sSelMapX = 9;
|
||||
UINT16 sSelMapY = 1;
|
||||
// HEADROCK HAM 3.5: Default selected sector doesn't have to be Omerta does it? :)
|
||||
UINT16 sSelMapX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
UINT16 sSelMapY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
|
||||
// highlighted sector
|
||||
INT16 gsHighlightSectorX=-1;
|
||||
@@ -522,6 +526,7 @@ void CreateMilitiaPanelBottomButton( void );
|
||||
void DeleteMilitiaPanelBottomButton( void );
|
||||
void MilitiaDoneButtonCallback(GUI_BUTTON *btn,INT32 reason);
|
||||
void MilitiaAutoButtonCallback(GUI_BUTTON *btn,INT32 reason);
|
||||
void MilitiaDisbandYesNoBoxCallback( UINT8 bExitValue ); // HEADROCK HAM 3.6: Disband militia callback
|
||||
void RenderShadingForUnControlledSectors( void );
|
||||
void DrawTownMilitiaForcesOnMap( void );
|
||||
void CheckAndUpdateStatesOfSelectedMilitiaSectorButtons( void );
|
||||
@@ -4381,7 +4386,10 @@ void DisplayDistancesForHelicopter( void )
|
||||
|
||||
|
||||
// calculate the cost of the trip based on the number of safe and unsafe sectors it will pass through
|
||||
uiTripCost = ( sNumSafeSectors * COST_AIRSPACE_SAFE ) + ( sNumUnSafeSectors * COST_AIRSPACE_UNSAFE );
|
||||
// HEADROCK HAM 3.5: Externalized Base Cost. Also includes hourly-calculated facility modifier.
|
||||
UINT32 uiCostGreen = __max(0,gGameExternalOptions.usHelicopterBaseCostPerGreenTile + gsSkyriderCostModifier);
|
||||
UINT32 uiCostRed = __max(0,gGameExternalOptions.usHelicopterBaseCostPerRedTile + gsSkyriderCostModifier);
|
||||
uiTripCost = ( sNumSafeSectors * uiCostGreen ) + ( sNumUnSafeSectors * uiCostRed );
|
||||
|
||||
swprintf( sString, L"%d", uiTripCost );
|
||||
InsertCommasForDollarFigure( sString );
|
||||
@@ -6092,13 +6100,22 @@ void MilitiaDoneButtonCallback(GUI_BUTTON *btn,INT32 reason)
|
||||
{
|
||||
btn->uiFlags &= ~( BUTTON_CLICKED_ON );
|
||||
|
||||
// reset fact we are in the box
|
||||
sSelectedMilitiaTown = 0;
|
||||
fMapPanelDirty = TRUE;
|
||||
// Go ahead and reset the militia in the selected sector (even if we didn't change it here)
|
||||
if (gfStrategicMilitiaChangesMade)
|
||||
// HEADROCK HAM 3.6: Clicking the done button while militia are on the cursor causes a pop-up
|
||||
// for authorizing DISBANDING those militia.
|
||||
if (sGreensOnCursor || sRegularsOnCursor || sElitesOnCursor)
|
||||
{
|
||||
ResetMilitia();
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMilitiaString[ 3 ], MAP_SCREEN, MSG_BOX_FLAG_YESNO, MilitiaDisbandYesNoBoxCallback );
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset fact we are in the box
|
||||
sSelectedMilitiaTown = 0;
|
||||
fMapPanelDirty = TRUE;
|
||||
// Go ahead and reset the militia in the selected sector (even if we didn't change it here)
|
||||
if (gfStrategicMilitiaChangesMade)
|
||||
{
|
||||
ResetMilitia();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6279,13 +6296,17 @@ void CheckAndUpdateStatesOfSelectedMilitiaSectorButtons( void )
|
||||
iNumberOfRegulars = SectorInfo[ sGlobalMapSector ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + sRegularsOnCursor;
|
||||
iNumberOfElites = SectorInfo[ sGlobalMapSector ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] + sElitesOnCursor;
|
||||
|
||||
// HEADROCK HAM 3.6: This button is no longer disabled when there are unassigned militia. In fact,
|
||||
// clicking the button when militia are unassigned will prompt the player to authorize disbanding them.
|
||||
if( ( sGreensOnCursor > 0 ) || ( sRegularsOnCursor > 0 ) || ( sElitesOnCursor > 0 ) )
|
||||
{
|
||||
DisableButton( giMapMilitiaButton[ 4 ] ); // DONE
|
||||
// DisableButton( giMapMilitiaButton[ 4 ] ); // DONE
|
||||
SpecifyButtonText( giMapMilitiaButton[ 4 ], pMilitiaButtonString[ 2 ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableButton( giMapMilitiaButton[ 4 ] ); // DONE
|
||||
// EnableButton( giMapMilitiaButton[ 4 ] ); // DONE
|
||||
SpecifyButtonText( giMapMilitiaButton[ 4 ], pMilitiaButtonString[ 1 ] );
|
||||
}
|
||||
|
||||
// greens button
|
||||
@@ -6445,34 +6466,59 @@ void ClearAnySectorsFlashingNumberOfEnemies()
|
||||
UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
UINT32 uiSectorFlags = SectorInfo[ SECTOR( sSectorX, sSectorY ) ].uiFlags;
|
||||
BOOLEAN fDetection = FALSE;
|
||||
BOOLEAN fCount = FALSE;
|
||||
|
||||
Assert(sSectorX > 0 && sSectorY > 0 && sSectorX < 17 && sSectorY < 17);
|
||||
|
||||
// if player has militia close enough to scout this sector out, if there are mercs who can scout here, OR
|
||||
//Special case flag used when players encounter enemies in a sector, then retreat. The number of enemies
|
||||
//will display on mapscreen until time is compressed. When time is compressed, the flag is cleared, and
|
||||
//a question mark is displayed to reflect that the player no longer knows.
|
||||
// HEADROCK HAM 3.5: There are now several ways to control the detection of enemy units. This function has been revamped
|
||||
// to consider all options. Depending on externalized settings, different conditions yield different results.
|
||||
//
|
||||
// Option #1: Vanilla Default.
|
||||
// It is possible to detect all enemies in explored territory, including cities.
|
||||
// Militia in an adjacent sector can count how many enemies are there, except standing garrisons.
|
||||
// Option #2: HAM 3.2. No Detection without Recon.
|
||||
// Mobile enemy groups are only detected if there are militia in any adjacent sector. Otherwise, they can
|
||||
// travel through explored sectors without being seen.
|
||||
//
|
||||
// Option #3: This is a new feature for HAM 3.5, which ties together with Facility Externalization.
|
||||
// In simple words, facilities can enhance detection abilities. Facilities that do so may be placed around the
|
||||
// map in any sector. When a merc with sufficient wisdom is resting here, he increases the detection "level",
|
||||
// making it easier to detect or even count enemies in distant sectors.
|
||||
// This option can be combined with either of the two above.
|
||||
|
||||
|
||||
// Detection through active recon.
|
||||
// Mercs provide recon in the same sector they're in.
|
||||
// Militia provide recon in any adjacent sector (diagonals included)
|
||||
// There's also a special case flag used when players encounter enemies in a sector, then retreat. You can only
|
||||
// see the size of their force while the clock is paused. When unpaused, the flag is reset.
|
||||
if ( CanMercsScoutThisSector( sSectorX, sSectorY, 0 ) ||
|
||||
CanNearbyMilitiaScoutThisSector( sSectorX, sSectorY ) ||
|
||||
( uiSectorFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE ) )
|
||||
{
|
||||
// if the enemies are stationary (i.e. mercs attacking a garrison)
|
||||
if ( NumStationaryEnemiesInSector( sSectorX, sSectorY ) > 0 )
|
||||
fDetection = TRUE;
|
||||
|
||||
// if all enemies are mobile (I.E. not garrison troops)
|
||||
if ( NumStationaryEnemiesInSector( sSectorX, sSectorY ) == 0 )
|
||||
{
|
||||
// inside a garrison - hide their # (show question mark) to match what the PBI is showing
|
||||
return KNOWS_THEYRE_THERE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// other situations - show exactly how many there are
|
||||
return KNOWS_HOW_MANY;
|
||||
// They're also counted by default.
|
||||
fCount = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// if the player has visited the sector during this game
|
||||
// Explored Sector Detection
|
||||
// Enemy can be detected in any previously-visited sector.
|
||||
// This is also enabled by some facilities, provided a merc is present and available to do it.
|
||||
if( GetSectorFlagStatus( sSectorX, sSectorY, 0, SF_ALREADY_VISITED ) == TRUE )
|
||||
{
|
||||
// then he always knows about any enemy presence for the remainder of the game, but not exact numbers
|
||||
return KNOWS_THEYRE_THERE;
|
||||
// HEADROCK HAM 3.2: When enabled, this INI setting disallows detection of enemy roamers beyond merc/militia
|
||||
// recon range.
|
||||
if (!gGameExternalOptions.fNoEnemyDetectionWithoutRecon)
|
||||
{
|
||||
// then he always knows about any enemy presence for the remainder of the game, but not exact numbers
|
||||
fDetection = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// if Skyrider noticed the enemis in the sector recently
|
||||
@@ -6482,7 +6528,7 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
|
||||
if( IsSkyriderIsFlyingInSector( sSectorX, sSectorY ) )
|
||||
{
|
||||
// player remains aware of them as long as Skyrider remains in the sector
|
||||
return KNOWS_THEYRE_THERE;
|
||||
fDetection = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6491,9 +6537,32 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
|
||||
}
|
||||
}
|
||||
|
||||
// Facilities can set a flag that allows detection in some sectors. We can read flags directly from the sector
|
||||
// data to know whether we should show the enemies there. This overrides ANYTHING else.
|
||||
if (SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubDetectionLevel & 1)
|
||||
{
|
||||
fDetection = TRUE;
|
||||
}
|
||||
if (SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubDetectionLevel & (1<<2) )
|
||||
{
|
||||
fCount = TRUE;
|
||||
}
|
||||
|
||||
// no information available
|
||||
return KNOWS_NOTHING;
|
||||
if (!fDetection)
|
||||
{
|
||||
// no information available
|
||||
return KNOWS_NOTHING;
|
||||
}
|
||||
else if (!fCount)
|
||||
{
|
||||
// No accurate information
|
||||
return KNOWS_THEYRE_THERE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Accurate information
|
||||
return KNOWS_HOW_MANY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7126,3 +7195,38 @@ BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSec
|
||||
// the fight is elsewhere - ok to redistribute
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// Callback for disbanding militia in the Militia Box
|
||||
void MilitiaDisbandYesNoBoxCallback( UINT8 bExitValue )
|
||||
{
|
||||
// yes
|
||||
if( bExitValue == MSG_BOX_RETURN_YES )
|
||||
{
|
||||
if( sSelectedMilitiaTown != BLANK_SECTOR )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Adjust loyalty based on how many militia were disbanded, compared to
|
||||
// how many can be trained in a single session (max).
|
||||
UINT32 uiMilitiaToDisband = sGreensOnCursor + (2*sRegularsOnCursor) + (3*sElitesOnCursor);
|
||||
UINT32 uiTownLoyaltyBonus = (LOYALTY_BONUS_FOR_TOWN_TRAINING * uiMilitiaToDisband) / gGameExternalOptions.iTrainingSquadSize;
|
||||
// loyalty in this town increases a bit because we obviously care about them...
|
||||
DecrementTownLoyalty( (UINT8)sSelectedMilitiaTown, uiTownLoyaltyBonus );
|
||||
}
|
||||
|
||||
// zero out numbers on the cursor
|
||||
sGreensOnCursor = 0;
|
||||
sRegularsOnCursor = 0;
|
||||
sElitesOnCursor = 0;
|
||||
|
||||
// reset fact we are in the box
|
||||
sSelectedMilitiaTown = 0;
|
||||
fMapPanelDirty = TRUE;
|
||||
// Go ahead and reset the militia in the selected sector
|
||||
ResetMilitia();
|
||||
}
|
||||
else if( bExitValue == MSG_BOX_RETURN_NO )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -340,11 +340,8 @@ void AddTextToTownBox( void )
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
|
||||
// main facilities
|
||||
swprintf( wString, L"%s:", pwTownInfoStrings[ 8 ] );
|
||||
AddMonoString( &hStringHandle, wString );
|
||||
wcscpy(wString, L"");
|
||||
GetSectorFacilitiesFlags( bCurrentTownMineSectorX, bCurrentTownMineSectorY, wString );
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
// HEADROCK HAM 3.6: This function now does all the work of assembling a facility entry.
|
||||
AddFacilitiesToBox( bCurrentTownMineSectorX, bCurrentTownMineSectorY, &hStringHandle, TRUE );
|
||||
|
||||
// the concept of control is only meaningful in sectors where militia can be trained
|
||||
if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) )
|
||||
@@ -551,6 +548,9 @@ void AddTextToBlankSectorBox( void )
|
||||
|
||||
// sector
|
||||
AddSectorToBox();
|
||||
|
||||
// HEADROCK HAM 3.6: Facilities
|
||||
AddFacilitiesToBox( bCurrentTownMineSectorX, bCurrentTownMineSectorY, &hStringHandle, FALSE );
|
||||
}
|
||||
|
||||
|
||||
@@ -639,12 +639,64 @@ void AddCommonInfoToBox(void)
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Only show these for sectors that have a training facility
|
||||
BOOLEAN fMilitiaTrainingAllowed = FALSE;
|
||||
BOOLEAN fMobileTrainingAllowed = FALSE;
|
||||
|
||||
// percentage of current militia squad training completed
|
||||
swprintf( wString, L"%s:", pwTownInfoStrings[ 10 ] );
|
||||
AddMonoString( &hStringHandle, wString );
|
||||
swprintf( wString, L"%d%%%%", SectorInfo[ SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].ubMilitiaTrainingPercentDone );
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
|
||||
// Sector contains Militia training facility?
|
||||
for (UINT8 ubCounter = 0; ubCounter < MAX_NUM_FACILITY_TYPES; ubCounter++)
|
||||
{
|
||||
if (gFacilityLocations[SECTOR(bCurrentTownMineSectorX, bCurrentTownMineSectorY)][ubCounter].fFacilityHere)
|
||||
{
|
||||
if (gFacilityTypes[ubCounter].ubMilitiaTrainersAllowed)
|
||||
{
|
||||
fMilitiaTrainingAllowed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fMilitiaTrainingAllowed)
|
||||
{
|
||||
// Show percent completed
|
||||
swprintf( wString, L"%d%%%%", SectorInfo[ SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].ubMilitiaTrainingPercentDone );
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show N/A
|
||||
AddSecondColumnMonoString( &hStringHandle, New113HAMMessage[19] );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: percentage of current Mobile Militia squad training completed
|
||||
swprintf( wString, L"%s:", pwTownInfoStrings[ 12 ] );
|
||||
AddMonoString( &hStringHandle, wString );
|
||||
|
||||
// Sector contains Mobile training facility?
|
||||
for (UINT8 ubCounter = 0; ubCounter < MAX_NUM_FACILITY_TYPES; ubCounter++)
|
||||
{
|
||||
if (gFacilityLocations[SECTOR(bCurrentTownMineSectorX, bCurrentTownMineSectorY)][ubCounter].fFacilityHere)
|
||||
{
|
||||
if (gFacilityTypes[ubCounter].ubMobileMilitiaTrainersAllowed)
|
||||
{
|
||||
fMobileTrainingAllowed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fMobileTrainingAllowed)
|
||||
{
|
||||
// Show percentage completed
|
||||
swprintf( wString, L"%d%%%%", SectorInfo[ SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].ubMobileMilitiaTrainingPercentDone );
|
||||
AddSecondColumnMonoString( &hStringHandle, wString );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show N/A
|
||||
AddSecondColumnMonoString( &hStringHandle, New113HAMMessage[19] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -313,6 +313,8 @@ BOOLEAN fShowContractMenu = FALSE;
|
||||
BOOLEAN fShowRemoveMenu = FALSE;
|
||||
BOOLEAN fShowMilitiaControlMenu = FALSE; //lal
|
||||
//BOOLEAN fShowTalkToAllMenu = FALSE;//lal
|
||||
BOOLEAN fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu
|
||||
BOOLEAN fShowFacilityAssignmentMenu = FALSE; // HEADROCK HAM 3.6: Facility Sub-menu
|
||||
|
||||
BOOLEAN fRebuildMoveBox = FALSE;
|
||||
|
||||
@@ -325,6 +327,12 @@ SGPRect TrainDimensions={0,0,100,95};
|
||||
SGPPoint TrainPosition={160,150};
|
||||
SGPRect VehicleDimensions={0,0,80,60};
|
||||
SGPPoint VehiclePosition={160,150};
|
||||
// HEADROCK HAM 3.6: Facility Menu Position/Size:
|
||||
SGPRect FacilityDimensions={0,0,80,60};
|
||||
SGPPoint FacilityPosition={160,150};
|
||||
// HEADROCK HAM 3.6: Facility Sub-menu Position/Size:
|
||||
SGPRect FacilityAssignmentDimensions={0,0,80,60};
|
||||
SGPPoint FacilityAssignmentPosition={220,150};
|
||||
|
||||
SGPPoint RepairPosition={160,150};
|
||||
SGPRect RepairDimensions={0,0,80,80};
|
||||
@@ -350,6 +358,8 @@ SGPPoint OrigAssignmentPosition = { 120, 150 };
|
||||
SGPPoint OrigTrainPosition={160,150};
|
||||
SGPPoint OrigVehiclePosition={160,150};
|
||||
SGPPoint OrigMilitiaControlPosition = { 120, 150 }; //lal
|
||||
SGPPoint OrigFacilityPosition = { 160, 150 }; // HEADROCK HAM 3.6
|
||||
SGPPoint OrigFacilityAssignmentPosition = { 220,150 }; // HEADROCK HAM 3.6
|
||||
//SGPPoint OrigTalkToAllPosition = { 160, 150 };
|
||||
|
||||
//extern BOOLEAN fMapExitDueToMessageBox;
|
||||
@@ -542,7 +552,7 @@ BOOLEAN MultipleCharacterListEntriesSelected( void )
|
||||
|
||||
|
||||
|
||||
void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( INT8 bAssignment )
|
||||
void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( UINT8 ubMilitiaType )
|
||||
{
|
||||
INT32 iCounter = 0;
|
||||
SOLDIERTYPE *pSoldier = NULL;
|
||||
@@ -563,18 +573,31 @@ void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( INT8 bAssignme
|
||||
continue;
|
||||
}
|
||||
|
||||
if( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
if (ubMilitiaType == TOWN_MILITIA)
|
||||
{
|
||||
if ( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ].fMilitiaTrainingPaid == FALSE )
|
||||
if( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
if ( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ].fMilitiaTrainingPaid == FALSE )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ubMilitiaType == MOBILE_MILITIA)
|
||||
{
|
||||
if( pSoldier->bAssignment == TRAIN_MOBILE )
|
||||
{
|
||||
if ( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ].fMobileMilitiaTrainingPaid == FALSE )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX, INT16 sSectorY )
|
||||
// HEADROCK HAM 3.6: Added argument for Militia Type
|
||||
void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubMilitiaType )
|
||||
{
|
||||
INT32 iCounter = 0;
|
||||
SOLDIERTYPE *pSoldier = NULL;
|
||||
@@ -595,11 +618,24 @@ void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX,
|
||||
continue;
|
||||
}
|
||||
|
||||
if( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
if( ubMilitiaType == TOWN_MILITIA )
|
||||
{
|
||||
if( ( pSoldier->sSectorX == sSectorX ) && ( pSoldier->sSectorY == sSectorY ) && ( pSoldier->bSectorZ == 0 ) )
|
||||
if( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
if( ( pSoldier->sSectorX == sSectorX ) && ( pSoldier->sSectorY == sSectorY ) && ( pSoldier->bSectorZ == 0 ) )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ubMilitiaType == MOBILE_MILITIA )
|
||||
{
|
||||
if( pSoldier->bAssignment == TRAIN_MOBILE )
|
||||
{
|
||||
if( ( pSoldier->sSectorX == sSectorX ) && ( pSoldier->sSectorY == sSectorY ) && ( pSoldier->bSectorZ == 0 ) )
|
||||
{
|
||||
ResumeOldAssignment( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -890,6 +926,7 @@ void RestoreBackgroundForAssignmentGlowRegionList( void )
|
||||
// restore background
|
||||
RestoreExternBackgroundRect( 66, Y_START - 1, 118 + 1 - 67, yHeight );
|
||||
|
||||
|
||||
// ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!!
|
||||
fTeamPanelDirty = TRUE;
|
||||
|
||||
@@ -2285,7 +2322,24 @@ void UpdateMapScreenAssignmentPositions( void )
|
||||
SetBoxPosition( ghRepairBox, pPoint );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Facility Menu
|
||||
if( fShowFacilityMenu )
|
||||
{
|
||||
GetBoxPosition( ghFacilityBox, &pPoint);
|
||||
pPoint.iY = giBoxY + ( GetFontHeight( MAP_SCREEN_FONT ) + 2 ) * ASSIGN_MENU_FACILITY;
|
||||
|
||||
SetBoxPosition( ghFacilityBox, pPoint );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Facility Sub-menu
|
||||
if( fShowFacilityAssignmentMenu )
|
||||
{
|
||||
GetBoxPosition( ghFacilityAssignmentBox, &pPoint);
|
||||
|
||||
pPoint.iY = giBoxY + ( GetFontHeight( MAP_SCREEN_FONT ) + 2 ) * ASSIGN_MENU_FACILITY;
|
||||
|
||||
SetBoxPosition( ghFacilityAssignmentBox, pPoint );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -5655,7 +5709,8 @@ BOOLEAN HandleTimeCompressWithTeamJackedInAndGearedToGo( void )
|
||||
|
||||
if (!is_networked)
|
||||
// select starting sector (A9 - Omerta)
|
||||
ChangeSelectedMapSector( startingX, startingY, startingZ );
|
||||
// HEADROCK HAM 3.5: Externalized.
|
||||
ChangeSelectedMapSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
|
||||
|
||||
if (is_networked)
|
||||
{
|
||||
@@ -5671,22 +5726,30 @@ BOOLEAN HandleTimeCompressWithTeamJackedInAndGearedToGo( void )
|
||||
else
|
||||
{
|
||||
// load starting sector
|
||||
if ( !SetCurrentWorldSector( startingX, startingY, startingZ ) )
|
||||
// Externalized
|
||||
if ( !SetCurrentWorldSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
gubPBSectorX = startingX;
|
||||
gubPBSectorY = startingY;
|
||||
gubPBSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
gubPBSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
}
|
||||
|
||||
gubPBSectorZ = 0;
|
||||
|
||||
//Setup variables in the PBI for this first battle. We need to support the
|
||||
//non-persistant PBI in case the user goes to mapscreen.
|
||||
gfBlitBattleSectorLocator = TRUE;
|
||||
|
||||
gubPBSectorZ = 0;
|
||||
gubEnemyEncounterCode = ENTERING_ENEMY_SECTOR_CODE;
|
||||
// HEADROCK HAM 3.5: Arrival sector externalized. Fix for entering non-hostile sector/
|
||||
if ( NumEnemiesInAnySector( gubPBSectorX, gubPBSectorY, 0 ) > 0 )
|
||||
{
|
||||
gfBlitBattleSectorLocator = TRUE;
|
||||
gubEnemyEncounterCode = ENTERING_ENEMY_SECTOR_CODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gfBlitBattleSectorLocator = FALSE;
|
||||
gubEnemyEncounterCode = NO_ENCOUNTER_CODE;
|
||||
}
|
||||
|
||||
InitHelicopterEntranceByMercs( );
|
||||
|
||||
|
||||
@@ -113,15 +113,17 @@ enum {
|
||||
ASSIGN_MENU_VEHICLE,
|
||||
ASSIGN_MENU_REPAIR,
|
||||
ASSIGN_MENU_TRAIN,
|
||||
ASSIGN_MENU_FACILITY, // HEAROCK HAM 3.6: Facility List menu
|
||||
ASSIGN_MENU_CANCEL,
|
||||
MAX_ASSIGN_STRING_COUNT,
|
||||
};
|
||||
|
||||
|
||||
// HEADROCK HAM 3.6: Added new option to train Mobile Militia separately.
|
||||
// training assignment menu defines
|
||||
enum {
|
||||
TRAIN_MENU_SELF,
|
||||
TRAIN_MENU_TOWN,
|
||||
TRAIN_MENU_MOBILE,
|
||||
TRAIN_MENU_TEAMMATES,
|
||||
TRAIN_MENU_TRAIN_BY_OTHER,
|
||||
TRAIN_MENU_CANCEL,
|
||||
@@ -202,6 +204,12 @@ enum{
|
||||
STOP_YELLOW_SECTOR_LOCATOR,
|
||||
};
|
||||
|
||||
// HEADROCK HAM 3.6: Enums for Militia Training Types
|
||||
enum{
|
||||
TOWN_MILITIA = 0,
|
||||
MOBILE_MILITIA,
|
||||
NUM_MILITIA_TRAINING_TYPES
|
||||
};
|
||||
|
||||
// dimensions and offset for merc update box
|
||||
#define UPDATE_MERC_FACE_X_WIDTH 50
|
||||
@@ -254,6 +262,8 @@ extern BOOLEAN fShowContractMenu ;
|
||||
extern BOOLEAN fShowRemoveMenu ;
|
||||
extern BOOLEAN fShowMilitiaControlMenu ; //lal
|
||||
//extern BOOLEAN fShowTalkToAllMenu ;
|
||||
extern BOOLEAN fShowFacilityMenu; // HEADROCK HAM 3.6
|
||||
extern BOOLEAN fShowFacilityAssignmentMenu; // HEADROCK HAM 3.6
|
||||
|
||||
extern BOOLEAN fFirstTimeInMapScreen;
|
||||
extern BOOLEAN fLockOutMapScreenInterface;
|
||||
@@ -299,6 +309,11 @@ extern SGPRect AssignmentDimensions ;
|
||||
extern SGPPoint AssignmentPosition ;
|
||||
extern SGPPoint SquadPosition ;
|
||||
extern SGPRect SquadDimensions ;
|
||||
// HEADROCK HAM 3.6: Facility Menu variables
|
||||
extern SGPPoint FacilityPosition;
|
||||
extern SGPRect FacilityDimensions;
|
||||
extern SGPPoint FacilityAssignmentPosition;
|
||||
extern SGPRect FacilityAssignmentDimensions;
|
||||
|
||||
extern SGPPoint RepairPosition;
|
||||
extern SGPRect RepairDimensions;
|
||||
@@ -316,6 +331,8 @@ extern SGPPoint OrigAssignmentPosition ;
|
||||
extern SGPPoint OrigTrainPosition;
|
||||
extern SGPPoint OrigVehiclePosition;
|
||||
extern SGPPoint OrigMilitiaControlPosition ; //lal
|
||||
extern SGPPoint OrigFacilityPosition; // HEADROCK HAM 3.6: Facility Menu
|
||||
extern SGPPoint OrigFacilityAssignmentPosition; // HEADROCK HAM 3.6
|
||||
//extern SGPPoint OrigTalkToAllPosition ;
|
||||
|
||||
// disble team info panel due to showing of battle roster
|
||||
@@ -374,7 +391,8 @@ BOOLEAN MultipleCharacterListEntriesSelected( void );
|
||||
void ToggleEntryInSelectedList( INT8 bEntry );
|
||||
|
||||
// reset assignments for mercs on selected list who have this assignment
|
||||
void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( INT8 bAssignment );
|
||||
// HEADROCK HAM 3.6: Argument was unused... adding my own.
|
||||
void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( UINT8 ubMilitiaType );
|
||||
|
||||
/*
|
||||
// plot path for selected character list
|
||||
@@ -553,7 +571,7 @@ BOOLEAN SetUpFastHelpListRegions( INT32 iXPosition[], INT32 iYPosition[], INT32
|
||||
void InitializeMovingLists( void );
|
||||
|
||||
// reset assignment for mercs trainign militia in this sector
|
||||
void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX, INT16 sSectorY );
|
||||
void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubMilitiaType );
|
||||
|
||||
|
||||
// the sector move box
|
||||
|
||||
+1250
-430
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "Types.h"
|
||||
#include "Soldier Control.h"
|
||||
#include "campaign types.h"
|
||||
|
||||
//#define MAXIMUM_MILITIA_SQUAD_SIZE 30
|
||||
|
||||
@@ -18,7 +19,8 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY );
|
||||
void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY );
|
||||
void MilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY );
|
||||
|
||||
void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
|
||||
// HEADROCK HAM 3.4: Now using different arguments for this function. All relevent instances have also been altered.
|
||||
void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fForTraining, BOOLEAN fForBattle );
|
||||
BOOLEAN MoveOneBestMilitiaMan(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY);
|
||||
void MilitiaFollowPlayer( INT16 sMapX, INT16 sMapY, INT16 sDMapX, INT16 sDMapY );
|
||||
|
||||
@@ -29,9 +31,29 @@ extern BOOLEAN gDynamicRestrictMilitia[ 256 ];
|
||||
// HEADROCK HAM B2.7: Wonder why this function wasn't declared here. It is now, to allow Town Militia.cpp to
|
||||
// access it.
|
||||
|
||||
BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 sMapX, INT16 sMapY, BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
|
||||
BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 sMapX, INT16 sMapY, BOOLEAN fForTraining, BOOLEAN fForBattle );
|
||||
|
||||
// HEADROCK HAM B2.7: Generates possible movement directions - this is used only in CreateMilitiaGroup(), and
|
||||
// makes sure that the target sector has room for more militia.
|
||||
void GenerateDirectionInfosWithCapacityCheck( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
|
||||
void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3] );
|
||||
|
||||
// HEADROCK HAM 3.4: Stores restriction data from XML, including required cities for each sector to be allowed.
|
||||
typedef struct DYNAMICRESTRICTIONS
|
||||
{
|
||||
INT8 bSectorID;
|
||||
UINT32 uiReqTownFlags;
|
||||
} DYNAMICRESTRICTIONS;
|
||||
|
||||
// HEADROCK HAM 3.4: New function for simple Roaming Restriction testing.
|
||||
BOOLEAN IsSectorRoamingAllowed( UINT32 uiSector );
|
||||
|
||||
// HEADROCK HAM 3.6: New upgrade check returns the amount of militia that can be upgraded at target sector, in
|
||||
// "upgrade points"
|
||||
UINT16 MilitiaUpgradeSlotsCheck( SECTORINFO * pSectorInfo );
|
||||
|
||||
// HEADROCK HAM 3.6: This needs to be accessible.
|
||||
void AddToBlockMoveList(INT16 sMapX, INT16 sMapY);
|
||||
// And this:
|
||||
UINT8 CountMilitia(SECTORINFO *pSectorInfo);
|
||||
|
||||
#endif
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "Tactical Save.h"
|
||||
#include "interface Dialogue.h"
|
||||
#include "Random.h"
|
||||
// HEADROCK HAM 3.6: Added for facility string printing...
|
||||
#include "PopUpBox.h"
|
||||
#endif
|
||||
|
||||
#include "postalservice.h"
|
||||
@@ -32,26 +34,70 @@
|
||||
extern BOOLEAN fMapScreenBottomDirty;
|
||||
extern CPostalService gPostalService;
|
||||
|
||||
void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString )
|
||||
|
||||
void AddFacilitiesToBox( INT16 sMapX, INT16 sMapY, UINT32 *uiHandle, BOOLEAN fCityInfoBox )
|
||||
{
|
||||
// will build a string stating current facilities present in sector
|
||||
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags == 0 )
|
||||
// HEADROCK HAM 3.5: Facilities are now read from XMLs, including their names.
|
||||
|
||||
UINT32 cnt = 0;
|
||||
UINT32 uiNumFacilities = 0;
|
||||
BOOLEAN fHeaderAdded = FALSE;
|
||||
|
||||
CHAR16 szFacilityString[30];
|
||||
|
||||
Assert(sMapX > 0 && sMapY > 0 && sMapX < 17 && sMapY < 17);
|
||||
|
||||
for ( cnt = 0; cnt < NUM_FACILITY_TYPES; cnt++ )
|
||||
{
|
||||
// none
|
||||
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 0 ] );
|
||||
if (fCityInfoBox && uiNumFacilities == 0 && !fHeaderAdded )
|
||||
{
|
||||
// For a city info box, always show this line on the left side.
|
||||
swprintf( szFacilityString, L"%s:", pwTownInfoStrings[ 8 ] );
|
||||
AddMonoString( uiHandle, szFacilityString );
|
||||
fHeaderAdded = TRUE;
|
||||
}
|
||||
// Facility type exists at this location?
|
||||
if (gFacilityLocations[SECTOR(sMapX,sMapY)][cnt].fFacilityHere)
|
||||
{
|
||||
if (gFacilityLocations[SECTOR(sMapX,sMapY)][cnt].ubHidden == 0 ||
|
||||
(gFacilityLocations[SECTOR(sMapX,sMapY)][cnt].ubHidden == 1 && SectorInfo[SECTOR(sMapX,sMapY)].fSurfaceWasEverPlayerControlled) )
|
||||
{
|
||||
if (!fCityInfoBox && uiNumFacilities == 0 && !fHeaderAdded )
|
||||
{
|
||||
// For a non-city info box, show this line on the left side only if there's at least one facility.
|
||||
swprintf( szFacilityString, L"%s:", pwTownInfoStrings[ 8 ] );
|
||||
AddMonoString( uiHandle, szFacilityString );
|
||||
}
|
||||
else if (uiNumFacilities > 0)
|
||||
{
|
||||
// Add empty line on the left size to make room for text on the right.
|
||||
AddMonoString( uiHandle, L"" );
|
||||
}
|
||||
|
||||
AddSecondColumnMonoString( uiHandle, gFacilityTypes[cnt].szFacilityName );
|
||||
uiNumFacilities++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( uiNumFacilities == 0 && fCityInfoBox )
|
||||
{
|
||||
// Add "NONE" on the right side. Only happens when the sector is a city.
|
||||
AddSecondColumnMonoString( uiHandle, sFacilitiesStrings[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* HEADROCK HAM 3.4: Hardcodes removed.
|
||||
// hospital
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_HOSPITAL )
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_HOSPITAL) )
|
||||
{
|
||||
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 1 ] );
|
||||
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ FACILITY_HOSPITAL ] );
|
||||
}
|
||||
|
||||
// industry
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_INDUSTRY )
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_INDUSTRY) )
|
||||
{
|
||||
if( wcslen( sFacilitiesString ) == 0 )
|
||||
{
|
||||
@@ -59,13 +105,13 @@ void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( sFacilitiesString, L",");
|
||||
wcscat( sFacilitiesString, L", ");
|
||||
wcscat( sFacilitiesString, sFacilitiesStrings[ 2 ]);
|
||||
}
|
||||
}
|
||||
|
||||
// prison
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_PRISON )
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_PRISON) )
|
||||
{
|
||||
if( wcslen( sFacilitiesString ) == 0 )
|
||||
{
|
||||
@@ -73,13 +119,27 @@ void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( sFacilitiesString, L",");
|
||||
wcscat( sFacilitiesString, L", ");
|
||||
wcscat( sFacilitiesString, sFacilitiesStrings[ 3 ]);
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.4: What about the military base!
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_MILITARY) )
|
||||
{
|
||||
if( wcslen( sFacilitiesString ) == 0 )
|
||||
{
|
||||
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 4 ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( sFacilitiesString, L", ");
|
||||
wcscat( sFacilitiesString, sFacilitiesStrings[ 4 ]);
|
||||
}
|
||||
}
|
||||
|
||||
// airport
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_AIRPORT )
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_AIRPORT) )
|
||||
{
|
||||
if( wcslen( sFacilitiesString ) == 0 )
|
||||
{
|
||||
@@ -87,13 +147,13 @@ void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( sFacilitiesString, L",");
|
||||
wcscat( sFacilitiesString, L", ");
|
||||
wcscat( sFacilitiesString, sFacilitiesStrings[ 5 ]);
|
||||
}
|
||||
}
|
||||
|
||||
// gun range
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_GUN_RANGE )
|
||||
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & (1 << FACILITY_GUNRANGE) )
|
||||
{
|
||||
if( wcslen( sFacilitiesString ) == 0 )
|
||||
{
|
||||
@@ -101,12 +161,11 @@ void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( sFacilitiesString, L",");
|
||||
wcscat( sFacilitiesString, L", ");
|
||||
wcscat( sFacilitiesString, sFacilitiesStrings[ 6 ]);
|
||||
}
|
||||
}
|
||||
|
||||
sFacilitiesString[ wcslen( sFacilitiesString ) ] = 0;
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
// build main facilities strings for sector
|
||||
void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString );
|
||||
void AddFacilitiesToBox( INT16 sMapX, INT16 sMapY, UINT32 *uiHandle, BOOLEAN fCityInfoBox );
|
||||
|
||||
// set sector as enemy controlled
|
||||
BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested );
|
||||
|
||||
+16
-12
@@ -210,15 +210,15 @@ UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
|
||||
GROUP *pGroup;
|
||||
UINT8 ubNumTroops;
|
||||
|
||||
// HEADROCK: This is a TEMPORARY fix to avoid the assertion error. Not sure this is the best solution,
|
||||
// probably isn't. But I need this bit to work.
|
||||
if (sSectorX < MINIMUM_VALID_X_COORDINATE ||
|
||||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
|
||||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
|
||||
sSectorY > MAXIMUM_VALID_Y_COORDINATE)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
// HEADROCK HAM 3.5: This is a TEMPORARY fix to avoid the assertion error. Not sure this is the best solution,
|
||||
// probably isn't. But I need this bit to work.
|
||||
if (sSectorX < MINIMUM_VALID_X_COORDINATE ||
|
||||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
|
||||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
|
||||
sSectorY > MAXIMUM_VALID_Y_COORDINATE)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
|
||||
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
|
||||
@@ -503,8 +503,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
// They arrived in multiple groups, so here they come
|
||||
pThisSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
|
||||
|
||||
GenerateDirectionInfos( gWorldSectorX, gWorldSectorY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( gWorldSectorX, gWorldSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( gWorldSectorX, gWorldSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( unsigned ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
{
|
||||
@@ -788,7 +787,6 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point we should not have added more soldiers than are in slots
|
||||
AssertGT( sNumSlots, 0 );
|
||||
|
||||
switch( pSoldier->ubSoldierClass )
|
||||
@@ -1394,6 +1392,7 @@ void AddPossiblePendingEnemiesToBattle()
|
||||
|
||||
if( ubStrategicInsertionCode == 255 )
|
||||
{
|
||||
// HEADROCK HAM 3.5: This runs into assertion errors along the map's edge! Should be fixed!
|
||||
if( NumEnemiesInSector( gWorldSectorX + 1, gWorldSectorY ) )
|
||||
ubStrategicInsertionCode = INSERTION_CODE_EAST;
|
||||
else if( NumEnemiesInSector( gWorldSectorX - 1, gWorldSectorY ) )
|
||||
@@ -1704,6 +1703,11 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
|
||||
}
|
||||
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
|
||||
}
|
||||
// HEADROCK HAM 3.2: enemy reinforcements arrive with 0 APs.
|
||||
if (gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 1 || gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 2)
|
||||
{
|
||||
pSoldier->bActionPoints = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1126,8 +1126,9 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID )
|
||||
gubFact[usFact] = gMercProfiles[ ARNIE ].bMercStatus != MERC_IS_DEAD;
|
||||
break;
|
||||
|
||||
case FACT_I16_BLOODCATS_KILLED:
|
||||
gubFact[usFact] = (SectorInfo[ SEC_I16 ].bBloodCats == 0);
|
||||
// HEADROCK HAM 3.6: No longer necessarily I16.
|
||||
case FACT_BLOODCAT_LAIR_CLEANED:
|
||||
gubFact[usFact] = (SectorInfo[ gubBloodcatLairSectorId ].bBloodCats == 0);
|
||||
break;
|
||||
|
||||
case FACT_NPC_BANDAGED_TODAY:
|
||||
|
||||
+2
-1
@@ -430,7 +430,8 @@ enum Facts
|
||||
FACT_KINGPIN_NOT_IN_OFFICE,// 256
|
||||
FACT_DONT_OWE_KINGPIN_MONEY,// 257
|
||||
FACT_PC_MARRYING_DARYL_IS_FLO,// 258
|
||||
FACT_I16_BLOODCATS_KILLED,// 259
|
||||
// HEADROCK HAM 3.6: Renamed this. It is no longer necessarily at I16.
|
||||
FACT_BLOODCAT_LAIR_CLEANED,// 259
|
||||
|
||||
FACT_NPC_COWERING = 261,
|
||||
|
||||
|
||||
+11
-20
@@ -52,8 +52,7 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
|
||||
if ( ( GetTownIdForSector( sSectorX, sSectorY ) == OMERTA )&&( gGameOptions.ubDifficultyLevel != DIF_LEVEL_INSANE ) ) //Madd: skip Omerta //Lal: but not on insane ;-)
|
||||
return;
|
||||
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sSectorX, sSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
{
|
||||
@@ -104,8 +103,7 @@ BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 s
|
||||
if( !gGameExternalOptions.gfAllowReinforcements )
|
||||
return FALSE;
|
||||
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sSectorX, sSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
if( pGroup->ubSectorX == SECTORX( pusMoveDir[ ubIndex ][ 0 ] ) && pGroup->ubSectorY == SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) )
|
||||
@@ -120,8 +118,7 @@ UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY )
|
||||
UINT8 ubDirNumber = 0, ubIndex;
|
||||
UINT8 ubCounter = 0;
|
||||
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sSectorX, sSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
pSectors[ ubCounter++ ] = (UINT8)pusMoveDir[ ubIndex ][ 0 ];
|
||||
@@ -140,8 +137,7 @@ UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY)
|
||||
if( !gGameExternalOptions.gfAllowReinforcements )
|
||||
return ubResult;
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
ubResult += CountAllMilitiaInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) );
|
||||
@@ -161,8 +157,7 @@ UINT8 MilitiaInFiveSectorsOfRank( INT16 sMapX, INT16 sMapY, UINT8 ubRank )
|
||||
if( !gGameExternalOptions.gfAllowReinforcements )
|
||||
return ubResult;
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
ubResult += MilitiaInSectorOfRank( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), ubRank );
|
||||
@@ -179,12 +174,11 @@ BOOLEAN ARMoveBestMilitiaManFromAdjacentSector(INT16 sMapX, INT16 sMapY)
|
||||
if( !gGameExternalOptions.gfAllowReinforcements )
|
||||
return FALSE;
|
||||
|
||||
if( CountAllMilitiaInSector( sMapX, sMapY ) >= gGameExternalOptions.guiMaxMilitiaSquadSize ||
|
||||
if( CountAllMilitiaInSector( sMapX, sMapY ) >= gGameExternalOptions.iMaxMilitiaPerSector ||
|
||||
CountAllMilitiaInFiveSectors( sMapX, sMapY ) - CountAllMilitiaInSector( sMapX, sMapY ) == 0 )
|
||||
return FALSE;
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
ubRandom = Random( ubDirNumber );
|
||||
|
||||
@@ -209,8 +203,7 @@ BOOLEAN ARRemoveMilitiaMan( INT16 sMapX, INT16 sMapY, UINT8 ubRank )
|
||||
if( !gGameExternalOptions.gfAllowReinforcements )
|
||||
return FALSE;
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
@@ -256,8 +249,7 @@ UINT8 DoReinforcementAsPendingEnemy( INT16 sMapX, INT16 sMapY )
|
||||
|
||||
pThisSector = &SectorInfo[ SECTOR( sMapX, sMapY ) ];
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
|
||||
{
|
||||
@@ -328,7 +320,7 @@ UINT8 NumFreeMilitiaSlots()
|
||||
if( !pSoldier->bActive )
|
||||
ubNumFreeSlots++;
|
||||
}
|
||||
return max( 0 , ubNumFreeSlots - ( gGameExternalOptions.ubGameMaximumNumberOfRebels - gGameExternalOptions.guiMaxMilitiaSquadSize ) );
|
||||
return max( 0 , ubNumFreeSlots - ( gGameExternalOptions.ubGameMaximumNumberOfRebels - gGameExternalOptions.iMaxMilitiaPerSector ) );
|
||||
}
|
||||
|
||||
UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank )
|
||||
@@ -342,8 +334,7 @@ UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank
|
||||
|
||||
// pThisSector = &SectorInfo[ SECTOR( sMapX, sMapY ) ];
|
||||
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir,
|
||||
( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
|
||||
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
|
||||
|
||||
if( CountAllMilitiaInFiveSectors( sMapX, sMapY ) - CountAllMilitiaInSector( sMapX, sMapY ) == 0 )
|
||||
{
|
||||
|
||||
@@ -3704,6 +3704,9 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
|
||||
}
|
||||
if( ubSAIVersion < 18 )
|
||||
{ //adjust down the number of bloodcats based on difficulty in the two special bloodcat levels
|
||||
// HEADROCK HAM 3.6: Run the Init function instead.
|
||||
InitBloodCatSectors();
|
||||
/*
|
||||
switch( gGameOptions.ubDifficultyLevel )
|
||||
{
|
||||
case DIF_LEVEL_EASY: //50%
|
||||
@@ -3729,7 +3732,7 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
|
||||
SectorInfo[ SEC_I16 ].bBloodCats = 39;
|
||||
SectorInfo[ SEC_N5 ].bBloodCats = 37;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
if( ubSAIVersion < 19 )
|
||||
{
|
||||
@@ -3753,6 +3756,8 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
|
||||
}
|
||||
if( ubSAIVersion < 22 )
|
||||
{ //adjust down the number of bloodcats based on difficulty in the two special bloodcat levels
|
||||
// HEADROCK HAM 3.6: Run the Init function instead.
|
||||
InitBloodCatSectors();
|
||||
switch( gGameOptions.ubDifficultyLevel )
|
||||
{
|
||||
case DIF_LEVEL_EASY: //50%
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
#include "Quests.h"
|
||||
// HEADROCK HAM B1: Additional Include for Dynamic Roaming Restrictions
|
||||
#include "MilitiaSquads.h"
|
||||
// HEADROCK HAM 3.6: Additional include for Facility Operating Deby
|
||||
#include "Facilities.h"
|
||||
// HEADROCK HAM 3.6: And another include, for militia upkeep costs.
|
||||
#include "Town Militia.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -513,10 +517,19 @@ void MercDailyUpdate()
|
||||
// rebuild list for mapscreen
|
||||
ReBuildCharactersList( );
|
||||
// HEADROCK HAM B1: Run a function to redefine Roaming Militia Restrictions.
|
||||
if (gGameExternalOptions.bDynamicRestrictRoaming)
|
||||
if (gGameExternalOptions.fDynamicRestrictRoaming)
|
||||
{
|
||||
AdjustRoamingRestrictions();
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Pay debt for operating Facilities today. If can't be paid, apply loyalty hit.
|
||||
if (giTotalOwedForFacilityOperationsToday)
|
||||
{
|
||||
HandleDailyPaymentFacilityDebt();
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Pay for militia upkeep
|
||||
HandleMilitiaUpkeepPayment();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Strategic AI.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "history.h"
|
||||
#include "Facilities.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -202,12 +203,27 @@ void InitializeMines( void )
|
||||
// Alma mine can't run out for quest-related reasons (see Ian)
|
||||
} while (gMineStatus[ubDepletedMineIndex].fEmpty || (ubDepletedMineIndex == MINE_ALMA));
|
||||
|
||||
// HEADROCK HAM 3.1: We can now select which mine runs out, or disable mine shutdown.
|
||||
if (gGameExternalOptions.fManuallySelectMineShutdown)
|
||||
{
|
||||
// Make sure selection isn't 0 (no mine runs out) or invalid (San Mona, Alma)
|
||||
if (gGameExternalOptions.ubWhichMineRunsOut > 0 &&
|
||||
gGameExternalOptions.ubWhichMineRunsOut < MAX_NUMBER_OF_MINES &&
|
||||
gGameExternalOptions.ubWhichMineRunsOut-1 != MINE_SAN_MONA &&
|
||||
gGameExternalOptions.ubWhichMineRunsOut-1 != MINE_ALMA )
|
||||
{
|
||||
// Set depleted mine index.
|
||||
ubDepletedMineIndex = (gGameExternalOptions.ubWhichMineRunsOut-1);
|
||||
}
|
||||
}
|
||||
|
||||
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
|
||||
{
|
||||
pMineStatus = &(gMineStatus[ ubMineIndex ]);
|
||||
|
||||
if (ubMineIndex == ubDepletedMineIndex)
|
||||
// HEADROCK HAM 3.1: We can disable mine shutdown, so make sure the settings aren't telling us to do so.
|
||||
if (!(gGameExternalOptions.fManuallySelectMineShutdown && gGameExternalOptions.ubWhichMineRunsOut == 0) &&
|
||||
(ubMineIndex == ubDepletedMineIndex))
|
||||
{
|
||||
if ( ubDepletedMineIndex == MINE_DRASSEN )
|
||||
{
|
||||
@@ -343,7 +359,7 @@ UINT32 GetMaxPeriodicRemovalFromMine( INT8 bMineIndex )
|
||||
}
|
||||
|
||||
// HEADROCK HAM B1: Affected by external INI option.
|
||||
return(( gMineStatus[ bMineIndex ].uiMaxRemovalRate * gGameExternalOptions.iMineIncomePercentage ) / 100);
|
||||
return(( gMineStatus[ bMineIndex ].uiMaxRemovalRate * gGameExternalOptions.usMineIncomePercentage ) / 100);
|
||||
}
|
||||
|
||||
|
||||
@@ -370,7 +386,7 @@ UINT32 GetMaxDailyRemovalFromMine( INT8 bMineIndex )
|
||||
uiAmtExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply;
|
||||
}
|
||||
// HEADROCK HAM B1: Affected by external INI option.
|
||||
uiAmtExtracted = (uiAmtExtracted * gGameExternalOptions.iMineIncomePercentage) / 100;
|
||||
uiAmtExtracted = (uiAmtExtracted * gGameExternalOptions.usMineIncomePercentage) / 100;
|
||||
|
||||
return(uiAmtExtracted);
|
||||
}
|
||||
@@ -660,15 +676,22 @@ void HandleIncomeFromMines( void )
|
||||
{
|
||||
INT32 iIncome = 0;
|
||||
INT8 bCounter = 0;
|
||||
// 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++ )
|
||||
{
|
||||
if (bCounter)
|
||||
{
|
||||
// HEADROCK HAM 3.6: Add facility modifier as a percentage
|
||||
iFacilityModifier = 100 + MineIncomeModifierFromFacility( bCounter );
|
||||
}
|
||||
// mine this mine
|
||||
iIncome += MineAMine( bCounter );
|
||||
iIncome += (MineAMine( bCounter ) * iFacilityModifier) / 100;
|
||||
}
|
||||
// HEADROCK HAM B1: Affected by external INI Option.
|
||||
iIncome = (iIncome * gGameExternalOptions.iMineIncomePercentage) / 100;
|
||||
iIncome = (iIncome * gGameExternalOptions.usMineIncomePercentage) / 100;
|
||||
if( iIncome )
|
||||
{
|
||||
AddTransactionToPlayersBook( DEPOSIT_FROM_SILVER_MINE, 0, GetWorldTotalMin( ), iIncome );
|
||||
@@ -681,6 +704,8 @@ UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
|
||||
// predict income from this mine, estimate assumes mining situation will not change during next 4 income periods
|
||||
// (miner loyalty, % town controlled, monster infestation level, and current max removal rate may all in fact change)
|
||||
UINT32 uiAmtExtracted = 0;
|
||||
// HEADROCK HAM 3.6: Facilities can now modify income
|
||||
INT32 iFacilityModifier = 0;
|
||||
|
||||
if(PlayerControlsMine(bMineIndex))
|
||||
{
|
||||
@@ -693,10 +718,16 @@ UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
|
||||
// yes reduce to value of mine
|
||||
uiAmtExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply;
|
||||
}
|
||||
if (bMineIndex)
|
||||
{
|
||||
// HEADROCK HAM 3.6: Facility modifier applied as a percentage
|
||||
iFacilityModifier = 100 + MineIncomeModifierFromFacility( bMineIndex );
|
||||
uiAmtExtracted = (uiAmtExtracted * iFacilityModifier) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM B1: Affected by external INI Option.
|
||||
return( ( uiAmtExtracted * gGameExternalOptions.iMineIncomePercentage ) / 100 ) ;
|
||||
return( ( uiAmtExtracted * gGameExternalOptions.usMineIncomePercentage ) / 100 ) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -727,7 +758,7 @@ INT32 CalcMaxPlayerIncomeFromMines( void )
|
||||
iTotal += (MINE_PRODUCTION_NUMBER_OF_PERIODS * gMineStatus[bCounter].uiMaxRemovalRate);
|
||||
}
|
||||
// HEADROCK HAM B1: Affected by external INI Option.
|
||||
iTotal = (iTotal * gGameExternalOptions.iMineIncomePercentage) / 100;
|
||||
iTotal = (iTotal * gGameExternalOptions.usMineIncomePercentage) / 100;
|
||||
|
||||
return( iTotal );
|
||||
}
|
||||
|
||||
@@ -1554,6 +1554,10 @@ void AwardExperienceForTravelling( GROUP * pGroup )
|
||||
|
||||
void AddCorpsesToBloodcatLair( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Note, lair location externalized, but may cause issues because the GridNos here are
|
||||
// hardcoded... Maybe there will be a better way to solve this in the future, with externalized GridNos.
|
||||
// At the moment, no changes.
|
||||
|
||||
ROTTING_CORPSE_DEFINITION Corpse;
|
||||
INT16 sXPos, sYPos;
|
||||
|
||||
@@ -1884,12 +1888,14 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
|
||||
if( pGroup->pPlayerList->pSoldier->bAssignment < ON_DUTY )
|
||||
{
|
||||
// squad
|
||||
ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pAssignmentStrings[ pGroup->pPlayerList->pSoldier->bAssignment ], pMapVertIndex[ pGroup->pPlayerList->pSoldier->sSectorY ], pMapHortIndex[ pGroup->pPlayerList->pSoldier->sSectorX ]);
|
||||
// HEADROCK HAM 3.6: Messages are no longer yellow by default.
|
||||
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pAssignmentStrings[ pGroup->pPlayerList->pSoldier->bAssignment ], pMapVertIndex[ pGroup->pPlayerList->pSoldier->sSectorY ], pMapHortIndex[ pGroup->pPlayerList->pSoldier->sSectorX ]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// a loner
|
||||
ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pGroup->pPlayerList->pSoldier->name, pMapVertIndex[ pGroup->pPlayerList->pSoldier->sSectorY ], pMapHortIndex[ pGroup->pPlayerList->pSoldier->sSectorX ] );
|
||||
// HEADROCK HAM 3.6: Messages are no longer yellow by default.
|
||||
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pGroup->pPlayerList->pSoldier->name, pMapVertIndex[ pGroup->pPlayerList->pSoldier->sSectorY ], pMapHortIndex[ pGroup->pPlayerList->pSoldier->sSectorX ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1978,7 +1984,8 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
|
||||
// don't print any messages when arriving underground, there's no delay involved
|
||||
if ( GroupAtFinalDestination( pGroup ) && ( pGroup->ubSectorZ == 0 ) && !fNeverLeft )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pVehicleStrings[ pVehicleList[ iVehId ].ubVehicleType ], pMapVertIndex[ pGroup->ubSectorY ], pMapHortIndex[ pGroup->ubSectorX ] );
|
||||
// HEADROCK HAM 3.6: Messages are no longer yellow by default.
|
||||
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, pMessageStrings[ MSG_ARRIVE ], pVehicleStrings[ pVehicleList[ iVehId ].ubVehicleType ], pMapVertIndex[ pGroup->ubSectorY ], pMapHortIndex[ pGroup->ubSectorX ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1997,7 +2004,8 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
|
||||
if ( !pGroup->fVehicle || !IsGroupTheHelicopterGroup( pGroup ) )
|
||||
{
|
||||
// ATE: Add a few corpse to the bloodcat lair...
|
||||
if ( SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ) == SEC_I16 && fFirstTimeInSector )
|
||||
// HEADROCK: No longer hardcoded to I16
|
||||
if ( SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ) == gubBloodcatLairSectorId && fFirstTimeInSector )
|
||||
{
|
||||
AddCorpsesToBloodcatLair( pGroup->ubSectorX, pGroup->ubSectorY );
|
||||
}
|
||||
@@ -4708,13 +4716,20 @@ void RandomizePatrolGroupLocation( GROUP *pGroup )
|
||||
//roll the dice to see if this will become an ambush random encounter.
|
||||
BOOLEAN TestForBloodcatAmbush( GROUP *pGroup )
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.6: Ambush locations, min/max strength and chance of ambush have all been externalized to XML.
|
||||
|
||||
SECTORINFO *pSector;
|
||||
INT32 iHoursElapsed;
|
||||
UINT8 ubSectorID;
|
||||
UINT8 ubChance;
|
||||
INT8 bDifficultyMaxCats;
|
||||
INT8 bProgressMaxCats;
|
||||
UINT8 ubDifficulty = gGameOptions.ubDifficultyLevel-1; // For use by Placements Array. Novice = 0 instead of 1.
|
||||
UINT8 ubRange;
|
||||
UINT8 ubRandomCats;
|
||||
INT8 bNumMercMaxCats;
|
||||
UINT8 PlacementType; // 0 = Ambush site. 1 = Static placement. 2 = Lair.
|
||||
UINT8 ubMinBloodcats; // XML minimum.
|
||||
UINT8 ubMaxBloodcats; // XML maximum.
|
||||
BOOLEAN fAlreadyAmbushed = FALSE;
|
||||
|
||||
if( pGroup->ubSectorZ )
|
||||
@@ -4725,17 +4740,24 @@ BOOLEAN TestForBloodcatAmbush( GROUP *pGroup )
|
||||
ubSectorID = (UINT8)SECTOR( pGroup->ubSectorX, pGroup->ubSectorY );
|
||||
pSector = &SectorInfo[ ubSectorID ];
|
||||
|
||||
ubChance = 5 * gGameOptions.ubDifficultyLevel;
|
||||
// Read chance from XML data, based on difficulty.
|
||||
ubChance = gBloodcatPlacements[ ubSectorID ][ ubDifficulty ].ubAmbushChance;
|
||||
iHoursElapsed = __max(0,(GetWorldTotalMin() - pSector->uiTimeCurrentSectorWasLastLoaded) / 60);
|
||||
// Decrease chance to 0% if sector has been visited this hour. Every hour after that, increase the chance by 1%
|
||||
// until it reaches the default value again.
|
||||
ubChance = (UINT8)__min((INT32)ubChance, iHoursElapsed);
|
||||
ubChance = __max(0,ubChance);
|
||||
|
||||
iHoursElapsed = (GetWorldTotalMin() - pSector->uiTimeCurrentSectorWasLastLoaded) / 60;
|
||||
if( ubSectorID == SEC_N5 || ubSectorID == SEC_I16 )
|
||||
{ //These are special maps -- we use all placements.
|
||||
if( pSector->bBloodCats == -1 )
|
||||
{
|
||||
pSector->bBloodCats = pSector->bBloodCatPlacements;
|
||||
}
|
||||
else if( pSector->bBloodCats > 0 && pSector->bBloodCats < pSector->bBloodCatPlacements )
|
||||
{ //Slowly have them recuperate if we haven't been here for a long time. The population will
|
||||
// Determine what type of placement this is.
|
||||
PlacementType = gBloodcatPlacements[ ubSectorID ][0].PlacementType;
|
||||
|
||||
// At lair?
|
||||
if( PlacementType == BLOODCAT_PLACEMENT_LAIR )
|
||||
{
|
||||
// Bloodcats still exist here, but aren't at the optimal number?
|
||||
if( pSector->bBloodCats > 0 && pSector->bBloodCats < pSector->bBloodCatPlacements )
|
||||
{
|
||||
//Slowly have them recuperate if we haven't been here for a long time. The population will
|
||||
//come back up to the maximum if left long enough.
|
||||
INT32 iBloodCatDiff;
|
||||
iBloodCatDiff = pSector->bBloodCatPlacements - pSector->bBloodCats;
|
||||
@@ -4743,55 +4765,80 @@ BOOLEAN TestForBloodcatAmbush( GROUP *pGroup )
|
||||
}
|
||||
//Once 0, the bloodcats will never recupe.
|
||||
}
|
||||
else if( pSector->bBloodCats == -1 )
|
||||
{ //If we haven't been ambushed by bloodcats yet...
|
||||
if( gfAutoAmbush || PreChance( ubChance ) )
|
||||
|
||||
// At ambush sector?
|
||||
else if( PlacementType == BLOODCAT_PLACEMENT_AMBUSH )
|
||||
{
|
||||
//If there's any chance of ambush in this sector, and we beat that chance...
|
||||
if( ubChance && (gfAutoAmbush || PreChance( ubChance )) )
|
||||
{
|
||||
//randomly choose from 5-8, 7-10, 9-12 bloodcats based on easy, normal, and hard, respectively
|
||||
bDifficultyMaxCats = (INT8)( Random( 4 ) + gGameOptions.ubDifficultyLevel*2 + 3 );
|
||||
|
||||
//bDifficultyMaxCats = (INT8)( Random( 4 ) + gGameOptions.ubDifficultyLevel*2 + 3 );
|
||||
//maximum of 3 bloodcats or 1 for every 6%, 5%, 4% progress based on easy, normal, and hard, respectively
|
||||
bProgressMaxCats = (INT8)max( CurrentPlayerProgressPercentage() / (7 - gGameOptions.ubDifficultyLevel), 3 );
|
||||
|
||||
//make sure bloodcats don't outnumber mercs by a factor greater than 2
|
||||
bNumMercMaxCats = (INT8)(PlayerMercsInSector( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ ) * 2);
|
||||
|
||||
//bProgressMaxCats = (INT8)max( CurrentPlayerProgressPercentage() / (7 - gGameOptions.ubDifficultyLevel), 3 );
|
||||
//choose the lowest number of cats calculated by difficulty and progress.
|
||||
pSector->bBloodCats = (INT8)min( bDifficultyMaxCats, bProgressMaxCats );
|
||||
//pSector->bBloodCats = (INT8)min( bDifficultyMaxCats, bProgressMaxCats );
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.6: Minimum and Maximum are now modder-defined, so pick a random number between them.
|
||||
|
||||
// Read Min/Max from XML
|
||||
ubMaxBloodcats = gBloodcatPlacements[ ubSectorID ][ ubDifficulty ].ubMaxBloodcats;
|
||||
ubMinBloodcats = gBloodcatPlacements[ ubSectorID ][ ubDifficulty ].ubMinBloodcats;
|
||||
// Find range between Min and Max
|
||||
ubRange = ubMaxBloodcats-ubMinBloodcats;
|
||||
// Adjust range based on current progress.
|
||||
ubRange = __max(0,( ubRange * CurrentPlayerProgressPercentage() ) / 100);
|
||||
// Randomize "extra" bloodcats
|
||||
ubRandomCats = PreRandom(ubRange+1);
|
||||
// Add "extra" bloodcats to minimum value
|
||||
ubRandomCats += ubMinBloodcats;
|
||||
|
||||
// SET NUMBER OF CATS THAT WILL APPEAR
|
||||
pSector->bBloodCats = ubRandomCats;
|
||||
|
||||
if( gGameOptions.ubDifficultyLevel < DIF_LEVEL_HARD )
|
||||
{ //if not hard difficulty, ensure cats never outnumber mercs by a factor of 2 (min 3 bloodcats)
|
||||
{
|
||||
//At NOVICE/EXPERIENCED difficulty, ensure cats never outnumber mercs by a factor of more than 2.
|
||||
bNumMercMaxCats = (INT8)(PlayerMercsInSector( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ ) * 2);
|
||||
pSector->bBloodCats = (INT8)min( pSector->bBloodCats, bNumMercMaxCats );
|
||||
pSector->bBloodCats = (INT8)max( pSector->bBloodCats, 3 );
|
||||
//pSector->bBloodCats = (INT8)max( pSector->bBloodCats, 3 );
|
||||
}
|
||||
|
||||
//ensure that there aren't more bloodcats than placements
|
||||
pSector->bBloodCats = (INT8)min( pSector->bBloodCats, pSector->bBloodCatPlacements );
|
||||
|
||||
// Once again, make absolutely sure we're still within XML-set limits
|
||||
pSector->bBloodCats = (INT8)min( pSector->bBloodCats, ubMaxBloodcats);
|
||||
pSector->bBloodCats = (INT8)max( pSector->bBloodCats, ubMinBloodcats);
|
||||
}
|
||||
}
|
||||
else if( ubSectorID != SEC_I16 )
|
||||
{
|
||||
if( !gfAutoAmbush && PreChance( 95 ) )
|
||||
{ //already ambushed here. But 5% chance of getting ambushed again!
|
||||
else
|
||||
{
|
||||
// Chance was 0.
|
||||
fAlreadyAmbushed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( !fAlreadyAmbushed && ubSectorID != SEC_N5 && pSector->bBloodCats > 0 &&
|
||||
// An ambush is occuring?
|
||||
if( !fAlreadyAmbushed && PlacementType != BLOODCAT_PLACEMENT_STATIC && pSector->bBloodCats > 0 &&
|
||||
!pGroup->fVehicle && !NumEnemiesInSector( pGroup->ubSectorX, pGroup->ubSectorY ) )
|
||||
{
|
||||
if( ubSectorID != SEC_I16 || !gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] )
|
||||
// Wilderness ambush, or the player has unwittingly entered the lair?
|
||||
if( PlacementType == BLOODCAT_PLACEMENT_AMBUSH || !gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] )
|
||||
{
|
||||
// Ambush occurs.
|
||||
gubEnemyEncounterCode = BLOODCAT_AMBUSH_CODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Player knowingly enters lair.
|
||||
gubEnemyEncounterCode = ENTERING_BLOODCAT_LAIR_CODE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No special bloodcat encounter. This ALWAYS happens in STATIC PLACEMENT sectors.
|
||||
gubEnemyEncounterCode = NO_ENCOUNTER_CODE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -4808,7 +4855,8 @@ void NotifyPlayerOfBloodcatBattle( UINT8 ubSectorX, UINT8 ubSectorY )
|
||||
}
|
||||
else if( gubEnemyEncounterCode == ENTERING_BLOODCAT_LAIR_CODE )
|
||||
{
|
||||
wcscpy( str, pMapErrorString[ 13 ] );
|
||||
GetSectorIDString( ubSectorX, ubSectorY, 0, zTempString, FALSE );
|
||||
swprintf( str, pMapErrorString[ 13 ], zTempString );
|
||||
}
|
||||
|
||||
if( guiCurrentScreen == MAP_SCREEN )
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "Strategic Status.h"
|
||||
// HEADROCK HAM B1: Added include for Dynamic Roaming Militia
|
||||
#include "MilitiaSquads.h"
|
||||
// HEADROCK HAM 3.6: Include for Facility Debt
|
||||
#include "Facilities.h"
|
||||
#endif
|
||||
|
||||
// the max loyalty rating for any given town
|
||||
@@ -1817,7 +1819,7 @@ void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSec
|
||||
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) );
|
||||
}
|
||||
// HEADROCK HAM B1: Run a function to redefine Roaming Militia Restrictions on city capture.
|
||||
if (gGameExternalOptions.bDynamicRestrictRoaming)
|
||||
if (gGameExternalOptions.fDynamicRestrictRoaming)
|
||||
{
|
||||
AdjustRoamingRestrictions();
|
||||
}
|
||||
@@ -1994,3 +1996,24 @@ void MaximizeLoyaltyForDeidrannaKilled(void)
|
||||
SetTownLoyalty(bTownId, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: A loyalty hit based on outstanding debt for facility use.
|
||||
void HandleFacilityDebtLoyaltyHit( void )
|
||||
{
|
||||
// Loyalty hit is 1% per $1000 dollars owed.
|
||||
INT32 iLoyaltyHit = giTotalOwedForFacilityOperationsToday;
|
||||
|
||||
if (giTotalOwedForFacilityOperationsToday > 500)
|
||||
{
|
||||
// But no less than 1%, if $500 are owed.
|
||||
iLoyaltyHit = __max(500,iLoyaltyHit);
|
||||
}
|
||||
|
||||
if (iLoyaltyHit > 1)
|
||||
{
|
||||
DecrementTownLoyaltyEverywhere( iLoyaltyHit );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,4 +204,7 @@ void HandleLoyaltyImplicationsOfMercRetreat( INT8 bRetreatCode, INT16 sSectorX,
|
||||
|
||||
void MaximizeLoyaltyForDeidrannaKilled( void );
|
||||
|
||||
// HEADROCK HAM 3.6: Loyalty hit for owing too much money on facility work
|
||||
void HandleFacilityDebtLoyaltyHit( void );
|
||||
|
||||
#endif
|
||||
@@ -296,6 +296,10 @@
|
||||
RelativePath=".\Creature Spreading.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Facilities.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Game Clock.h"
|
||||
>
|
||||
@@ -470,6 +474,10 @@
|
||||
RelativePath=".\Creature Spreading.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Facilities.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Game Clock.cpp"
|
||||
>
|
||||
@@ -626,14 +634,38 @@
|
||||
RelativePath=".\XML_Army.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Bloodcats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_DynamicRestrictions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_ExtraItems.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Facilities.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_FacilityTypes.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Roaming.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SectorNames.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_UniformColors.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
||||
@@ -295,6 +295,10 @@
|
||||
RelativePath="Creature Spreading.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Facilities.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Game Clock.h"
|
||||
>
|
||||
@@ -467,6 +471,10 @@
|
||||
RelativePath="Creature Spreading.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Facilities.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Game Clock.cpp"
|
||||
>
|
||||
@@ -623,15 +631,39 @@
|
||||
RelativePath="XML_Army.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Bloodcats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_DynamicRestrictions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_ExtraItems.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Facilities.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_FacilityTypes.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="XML_Roaming.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_SectorNames.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_UniformColors.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\XML_ExtraItems.cpp"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
||||
+854
-144
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,11 @@ UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank,
|
||||
|
||||
void BuildMilitiaPromotionsString( STR16 str );
|
||||
|
||||
// HEADROCK HAM 3.3: Function to determine best leadership for militia training in a given sector.
|
||||
// Is used for both town and mobile militia.
|
||||
// HEADROCK HAM 3.6: Argument for Mobile/Town Militia training
|
||||
UINT8 FindBestMilitiaTrainingLeadershipInSector ( INT16 sMapX, INT16 sMapY, INT8 usMapZ, UINT8 ubMilitiaType );
|
||||
|
||||
// call this if the player attacks his own militia
|
||||
void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY);
|
||||
|
||||
@@ -70,7 +75,8 @@ BOOLEAN IsSAMSiteFullOfMilitia( INT16 sSectorX, INT16 sSectorY, INT8 iMilitiaTyp
|
||||
void HandleContinueOfTownTraining( void );
|
||||
|
||||
// handle completion of assignment byt his soldier too and inform the player
|
||||
void HandleCompletionOfTownTrainingByGroupWithTrainer( SOLDIERTYPE *pTrainer );
|
||||
// HEADROCK HAM 3.6: Added argument for Mobile Militia training.
|
||||
void HandleCompletionOfTownTrainingByGroupWithTrainer( SOLDIERTYPE *pTrainer, UINT8 ubMilitiaType );
|
||||
|
||||
// clear the list of training completed sectors
|
||||
void ClearSectorListForCompletedTrainingOfMilitia( void );
|
||||
@@ -78,4 +84,29 @@ void ClearSectorListForCompletedTrainingOfMilitia( void );
|
||||
BOOLEAN MilitiaTrainingAllowedInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
|
||||
BOOLEAN MilitiaTrainingAllowedInTown( INT8 bTownId );
|
||||
|
||||
// HEADROCK HAM 3.6: Function to calculate Militia and Mobile Militia training squad size.
|
||||
UINT8 CalcNumMilitiaTrained(UINT8 ubBestLeadership, BOOLEAN fMobile);
|
||||
|
||||
// HEADROCK HAM 3.6: Total upkeep costs for YESTERDAY at midnight. Saved to savegames.
|
||||
extern UINT32 guiTotalUpkeepForMilitia;
|
||||
|
||||
// HEADROCK HAM 3.6: Daily check for upkeep of all militia
|
||||
void HandleMilitiaUpkeepPayment( void );
|
||||
|
||||
// Type to hold number of militia in each sector.
|
||||
typedef struct MILITIA_LIST_TYPE
|
||||
{
|
||||
UINT8 ubSectorId;
|
||||
UINT8 ubNumTownGreens;
|
||||
UINT8 ubNumTownRegulars;
|
||||
UINT8 ubNumTownElites;
|
||||
UINT8 ubNumMobileGreens;
|
||||
UINT8 ubNumMobileRegulars;
|
||||
UINT8 ubNumMobileElites;
|
||||
|
||||
} MILITIA_LIST_TYPE;
|
||||
|
||||
// HEADROCK HAM 3.6: Calculate upkeep costs for militia
|
||||
UINT32 CalcMilitiaUpkeep( void );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,343 @@
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Strategic All.h"
|
||||
#include "XML.h"
|
||||
#else
|
||||
#include "builddefines.h"
|
||||
#include <stdio.h>
|
||||
#include "XML.h"
|
||||
#include "expat.h"
|
||||
#include "string.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "FileMan.h"
|
||||
#include "MemMan.h"
|
||||
#include "Debug Control.h"
|
||||
#include "mapscreen.h"
|
||||
#endif
|
||||
|
||||
#define MAX_CHAR_DATA_LENGTH 500
|
||||
|
||||
// This array stores all XML-read placement data. There are four arrays for each sector, one array for each difficulty
|
||||
// level. Please note that the Placement Type is only stored in array 0 (gBloodcatPlacements[x][0].PlacementType). It
|
||||
// is not possible to have different placement types at different difficulty levels. Yet.
|
||||
BLOODCATPLACEMENT gBloodcatPlacements[256][4];
|
||||
// Location of the Bloodcat Lair. There can be only one, as there's a quest that relies on its location. This is a
|
||||
// sectorID, 0-255.
|
||||
UINT8 gubBloodcatLairSectorId;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BLOODCAT_ELEMENT_NONE = 0,
|
||||
BLOODCAT_ELEMENT_PLACEMENTS,
|
||||
BLOODCAT_ELEMENT_SECTOR,
|
||||
BLOODCAT_ELEMENT,
|
||||
BLOODCAT_ELEMENT_DIFFICULTY,
|
||||
BLOODCAT_ELEMENT_DIFFICULTY_DATA,
|
||||
} BLOODCAT_PARSE_STAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BLOODCAT_PARSE_STAGE curElement;
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
|
||||
UINT8 sCurSectorX;
|
||||
UINT8 sCurSectorY;
|
||||
BLOODCATPLACEMENT CurPlacement[4];
|
||||
UINT8 ubCurDifficulty;
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
} BloodcatsParseData;
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
BloodcatsStartElementHandle(void *userData, const XML_Char *name, const char **atts)
|
||||
{
|
||||
BloodcatsParseData * pData = (BloodcatsParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
|
||||
{
|
||||
|
||||
if(strcmp(name, "BLOODCAT_PLACEMENTS") == 0 && pData->curElement == BLOODCAT_ELEMENT_NONE)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_PLACEMENTS;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
// Initiate Array by setting first character to 0.
|
||||
for (UINT16 x = 0; x < 256; x++)
|
||||
{
|
||||
for (UINT16 y = 0; y < 4; y++)
|
||||
{
|
||||
gBloodcatPlacements[x][y].ubFactionAffiliation = 0;
|
||||
gBloodcatPlacements[x][y].fRespawn = 0;
|
||||
gBloodcatPlacements[x][y].PlacementType = 0;
|
||||
gBloodcatPlacements[x][y].ubAmbushChance = 0;
|
||||
gBloodcatPlacements[x][y].ubMaxBloodcats = 0;
|
||||
gBloodcatPlacements[x][y].ubMinBloodcats = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SECTOR") == 0 && pData->curElement == BLOODCAT_ELEMENT_PLACEMENTS)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_SECTOR &&
|
||||
(strcmp(name, "SectorGrid") == 0 ||
|
||||
strcmp(name, "ubPlacementType") == 0) )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_SECTOR &&
|
||||
strcmp(name, "NOVICE") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->ubCurDifficulty = 0;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_SECTOR &&
|
||||
strcmp(name, "EXPERIENCED") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->ubCurDifficulty = 1;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_SECTOR &&
|
||||
strcmp(name, "EXPERT") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->ubCurDifficulty = 2;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_SECTOR &&
|
||||
strcmp(name, "INSANE") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->ubCurDifficulty = 3;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == BLOODCAT_ELEMENT_DIFFICULTY &&
|
||||
(strcmp(name, "ubMinBloodcats") == 0 ||
|
||||
strcmp(name, "ubMaxBloodcats") == 0 ||
|
||||
strcmp(name, "ubAmbushChance") == 0 ||
|
||||
strcmp(name, "ubFactionAffiliation") == 0 ||
|
||||
strcmp(name, "fRespawn") == 0 ))
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY_DATA;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
BloodcatsCharacterDataHandle(void *userData, const XML_Char *str, int len)
|
||||
{
|
||||
BloodcatsParseData * pData = (BloodcatsParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
|
||||
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
BloodcatsEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
BloodcatsParseData * pData = (BloodcatsParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if(strcmp(name, "BLOODCAT_PLACEMENTS") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_NONE;
|
||||
}
|
||||
else if(strcmp(name, "SECTOR") == 0)
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_PLACEMENTS;
|
||||
|
||||
UINT8 ubSectorId = SECTOR(pData->sCurSectorX, pData->sCurSectorY);
|
||||
if (ubSectorId >= 0 && ubSectorId < 256)
|
||||
{
|
||||
// Set placement type for this sector. Only first array has this set, as it is not difficulty-dependent.
|
||||
gBloodcatPlacements[ ubSectorId ][0].PlacementType = pData->CurPlacement[0].PlacementType;
|
||||
for (UINT8 x = 0; x < 4; x++)
|
||||
{
|
||||
if (pData->CurPlacement[0].PlacementType == 0)
|
||||
{
|
||||
// Ambush placement. Bloodcats will appear in this sector randomly.
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = pData->CurPlacement[x].ubMinBloodcats;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = pData->CurPlacement[x].ubAmbushChance;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].fRespawn = 0;
|
||||
}
|
||||
|
||||
else if (pData->CurPlacement[0].PlacementType == 1)
|
||||
{
|
||||
// Static placement. Bloodcats always appear here, but never respawn, and may be unaggressive
|
||||
// to enemies.
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = pData->CurPlacement[x].ubFactionAffiliation;
|
||||
gBloodcatPlacements[ ubSectorId ][x].fRespawn = 0;
|
||||
}
|
||||
|
||||
else if (pData->CurPlacement[0].PlacementType == 2)
|
||||
{
|
||||
// Lair sector. There can be only one, and it is affected by the Quest. Bloodcats can regenerate
|
||||
// their numbers here over time.
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].ubFactionAffiliation = 0;
|
||||
gBloodcatPlacements[ ubSectorId ][x].fRespawn = pData->CurPlacement[x].fRespawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SectorGrid") == 0 )
|
||||
{
|
||||
UINT8 x, y;
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
|
||||
y = (UINT8)pData->szCharData[0] & 0x1F;
|
||||
x = (UINT8)atol(&pData->szCharData[1]);
|
||||
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
|
||||
{
|
||||
pData->sCurSectorX = x;
|
||||
pData->sCurSectorY = y;
|
||||
}
|
||||
THROWIFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in BloodcatPlacements.XML" );
|
||||
}
|
||||
else if(strcmp(name, "ubPlacementType") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
// Only set for first array (Difficulty Irrelevant)
|
||||
pData->CurPlacement[0].PlacementType = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "NOVICE") == 0 )
|
||||
{
|
||||
// Just return to sector data.
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
}
|
||||
|
||||
else if(strcmp(name, "EXPERIENCED") == 0 )
|
||||
{
|
||||
// Just return to sector data.
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
}
|
||||
|
||||
else if(strcmp(name, "EXPERT") == 0 )
|
||||
{
|
||||
// Just return to sector data.
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
}
|
||||
|
||||
else if(strcmp(name, "INSANE") == 0 )
|
||||
{
|
||||
// Just return to sector data.
|
||||
pData->curElement = BLOODCAT_ELEMENT_SECTOR;
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ubMinBloodcats") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->CurPlacement[pData->ubCurDifficulty].ubMinBloodcats = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ubMaxBloodcats") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->CurPlacement[pData->ubCurDifficulty].ubMaxBloodcats = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ubAmbushChance") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->CurPlacement[pData->ubCurDifficulty].ubAmbushChance = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ubFactionAffiliation") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->CurPlacement[pData->ubCurDifficulty].ubFactionAffiliation = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "fRespawn") == 0 )
|
||||
{
|
||||
pData->curElement = BLOODCAT_ELEMENT_DIFFICULTY;
|
||||
pData->CurPlacement[pData->ubCurDifficulty].fRespawn = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ReadInBloodcatPlacements(STR fileName)
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
BloodcatsParseData pData;
|
||||
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return( FALSE );
|
||||
|
||||
uiFSize = FileGetSize(hFile);
|
||||
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree(lpcBuffer);
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
|
||||
XML_SetElementHandler(parser, BloodcatsStartElementHandle, BloodcatsEndElementHandle);
|
||||
XML_SetCharacterDataHandler(parser, BloodcatsCharacterDataHandle);
|
||||
|
||||
|
||||
memset(&pData,0,sizeof(pData));
|
||||
XML_SetUserData(parser, &pData);
|
||||
|
||||
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
sprintf(errorBuf, "XML Parser Error in BloodcatPlacements.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
LiveMessage(errorBuf);
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.4: Dynamic Roaming Restrictions XMLization
|
||||
//
|
||||
// This is a new part of the Dynamic Roaming Restrictions system. It reads in
|
||||
// data about sectors to "un-restrict", and the towns that must be liberated
|
||||
// for them to be unrestricted. There can be several unrestriction conditions
|
||||
// for each sector, and only one of the conditions must be true for the sector
|
||||
// to become allowed.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Tactical All.h"
|
||||
#else
|
||||
#include "sgp.h"
|
||||
#include "Debug Control.h"
|
||||
#include "expat.h"
|
||||
#include "gamesettings.h"
|
||||
#include "XML.h"
|
||||
#include "FileMan.h"
|
||||
#include "campaign types.h"
|
||||
#include "militiasquads.h"
|
||||
#include "mapscreen.h"
|
||||
#endif
|
||||
|
||||
// HEADROCK HAM 3.4: Stores restriction data from XML, including required cities for each sector to be allowed.
|
||||
extern DYNAMICRESTRICTIONS gDynamicRestrictions[5001];
|
||||
|
||||
struct
|
||||
{
|
||||
PARSE_STAGE curElement;
|
||||
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
|
||||
|
||||
INT16 sCurSectorX;
|
||||
INT16 sCurSectorY;
|
||||
UINT32 uiReqTownFlags;
|
||||
UINT32 maxArraySize;
|
||||
UINT32 curIndex;
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
}
|
||||
typedef dynamicroamingParseData;
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
dynamicroamingStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
{
|
||||
dynamicroamingParseData * pData = (dynamicroamingParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
|
||||
{
|
||||
if(strcmp(name, "DYNAMICROAMING") == 0 && pData->curElement == ELEMENT_NONE)
|
||||
{
|
||||
// Set all sector IDs to -1 ("unused")
|
||||
for (UINT16 cnt=0; cnt<5001; cnt++)
|
||||
{
|
||||
gDynamicRestrictions[cnt].bSectorID = -1;
|
||||
}
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if(strcmp(name, "RESTRICTION") == 0 && pData->curElement == ELEMENT_LIST)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->uiReqTownFlags = 0;
|
||||
|
||||
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3,"MergeStartElementHandle: setting memory for curMerge");
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
|
||||
//pData->curIndex++;
|
||||
}
|
||||
else if(pData->curElement == ELEMENT &&
|
||||
(strcmp(name, "SectorGrid") == 0 ||
|
||||
strcmp(name, "ReqTown") == 0 ))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
static void XMLCALL
|
||||
dynamicroamingCharacterDataHandle(void *userData, const XML_Char *str, int len)
|
||||
{
|
||||
dynamicroamingParseData * pData = (dynamicroamingParseData *)userData;
|
||||
|
||||
if( (pData->currentDepth <= pData->maxReadDepth) &&
|
||||
(strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
|
||||
){
|
||||
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
dynamicroamingEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
dynamicroamingParseData * pData = (dynamicroamingParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if(strcmp(name, "DYNAMICROAMING") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT_NONE;
|
||||
}
|
||||
else if(strcmp(name, "RESTRICTION") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
if (SECTOR(pData->sCurSectorX, pData->sCurSectorY) >= 0 && SECTOR(pData->sCurSectorX, pData->sCurSectorY) < 256)
|
||||
{
|
||||
pData->curIndex++;
|
||||
gDynamicRestrictions[pData->curIndex].bSectorID = SECTOR(pData->sCurSectorX,pData->sCurSectorY);
|
||||
gDynamicRestrictions[pData->curIndex].uiReqTownFlags |= pData->uiReqTownFlags;
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SectorGrid") == 0 )
|
||||
{
|
||||
UINT8 x, y;
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
y = (UINT8)pData->szCharData[0] & 0x1F;
|
||||
x = (UINT8)atol(&pData->szCharData[1]);
|
||||
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
|
||||
{
|
||||
pData->sCurSectorX = x;
|
||||
pData->sCurSectorY = y;
|
||||
}
|
||||
}
|
||||
else if(strcmp(name, "ReqTown") == 0 )
|
||||
{
|
||||
if ((UINT8) atol(pData->szCharData) > 0 && (UINT8) atol(pData->szCharData) < NUM_TOWNS )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->uiReqTownFlags |= (1 << ((UINT8) atol(pData->szCharData) - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->uiReqTownFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOLEAN ReadInDynamicRoamingRestrictions(STR fileName)
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
dynamicroamingParseData pData;
|
||||
|
||||
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading DynamicRestrictions.xml" );
|
||||
|
||||
// Open merges file
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return( FALSE );
|
||||
|
||||
uiFSize = FileGetSize(hFile);
|
||||
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree(lpcBuffer);
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
|
||||
XML_SetElementHandler(parser, dynamicroamingStartElementHandle, dynamicroamingEndElementHandle);
|
||||
XML_SetCharacterDataHandler(parser, dynamicroamingCharacterDataHandle);
|
||||
|
||||
|
||||
memset(&pData,0,sizeof(pData));
|
||||
pData.maxArraySize = MAXITEMS;
|
||||
pData.curIndex = -1;
|
||||
|
||||
XML_SetUserData(parser, &pData);
|
||||
|
||||
|
||||
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
|
||||
sprintf(errorBuf, "XML Parser Error in DynamicRestrictions.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
LiveMessage(errorBuf);
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// HEADROCK HAM 3.5: Facility Location Externalization
|
||||
//
|
||||
// This file reads from an XML called "Facilities.XML". That file contains
|
||||
// the locations of all facilities such as the "Gun Range", "Industrial",
|
||||
// "Prison", etcetera. The data is written DIRECTLY into the global SectorInfo
|
||||
// array, replacing a hardcoded system.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Tactical All.h"
|
||||
#else
|
||||
#include "sgp.h"
|
||||
#include "Debug Control.h"
|
||||
#include "expat.h"
|
||||
#include "gamesettings.h"
|
||||
#include "XML.h"
|
||||
#include "FileMan.h"
|
||||
#include "Campaign Types.h"
|
||||
#endif
|
||||
|
||||
FACILITYLOCATIONS gFacilityLocations[256][MAX_NUM_FACILITY_TYPES];
|
||||
UINT16 NUM_FACILITIES;
|
||||
|
||||
struct
|
||||
{
|
||||
PARSE_STAGE curElement;
|
||||
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
|
||||
|
||||
INT16 sCurSectorX;
|
||||
INT16 sCurSectorY;
|
||||
UINT8 ubCurFacilityType;
|
||||
UINT8 ubHidden;
|
||||
UINT32 maxArraySize;
|
||||
UINT32 curIndex;
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
}
|
||||
typedef facilityParseData;
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
facilityStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
|
||||
{
|
||||
facilityParseData * pData = (facilityParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
|
||||
{
|
||||
if(strcmp(name, "SECTORFACILITIES") == 0 && pData->curElement == ELEMENT_NONE)
|
||||
{
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
else if(strcmp(name, "FACILITY") == 0 && pData->curElement == ELEMENT_LIST)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3,"MergeStartElementHandle: setting memory for curMerge");
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
|
||||
//pData->curIndex++;
|
||||
}
|
||||
else if(pData->curElement == ELEMENT &&
|
||||
(strcmp(name, "SectorGrid") == 0 ||
|
||||
strcmp(name, "FacilityType") == 0 ||
|
||||
strcmp(name, "ubHidden") == 0
|
||||
))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
static void XMLCALL
|
||||
facilityCharacterDataHandle(void *userData, const XML_Char *str, int len)
|
||||
{
|
||||
facilityParseData * pData = (facilityParseData *)userData;
|
||||
|
||||
if( (pData->currentDepth <= pData->maxReadDepth) &&
|
||||
(strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
|
||||
){
|
||||
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
facilityEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
facilityParseData * pData = (facilityParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if(strcmp(name, "SECTORFACILITIES") == 0)
|
||||
{
|
||||
pData->curElement = ELEMENT_NONE;
|
||||
NUM_FACILITIES = pData->curIndex;
|
||||
}
|
||||
else if(strcmp(name, "FACILITY") == 0)
|
||||
{
|
||||
pData->curIndex++;
|
||||
pData->curElement = ELEMENT_LIST;
|
||||
|
||||
if (pData->ubCurFacilityType != 0)
|
||||
{
|
||||
gFacilityLocations[SECTOR(pData->sCurSectorX,pData->sCurSectorY)][pData->ubCurFacilityType].fFacilityHere = TRUE;
|
||||
gFacilityLocations[SECTOR(pData->sCurSectorX,pData->sCurSectorY)][pData->ubCurFacilityType].ubHidden = pData->ubHidden;
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SectorGrid") == 0 )
|
||||
{
|
||||
UINT8 x, y;
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
y = (UINT8)pData->szCharData[0] & 0x1F;
|
||||
x = (UINT8)atol(&pData->szCharData[1]);
|
||||
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
|
||||
{
|
||||
pData->sCurSectorX = x;
|
||||
pData->sCurSectorY = y;
|
||||
}
|
||||
}
|
||||
else if(strcmp(name, "FacilityType") == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->ubCurFacilityType = (UINT8) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ubHidden") == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->ubHidden = (BOOLEAN) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOLEAN ReadInSectorFacilities(STR fileName)
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
facilityParseData pData;
|
||||
|
||||
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Facilities.xml" );
|
||||
|
||||
// Open merges file
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return( FALSE );
|
||||
|
||||
uiFSize = FileGetSize(hFile);
|
||||
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree(lpcBuffer);
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
|
||||
XML_SetElementHandler(parser, facilityStartElementHandle, facilityEndElementHandle);
|
||||
XML_SetCharacterDataHandler(parser, facilityCharacterDataHandle);
|
||||
|
||||
|
||||
memset(&pData,0,sizeof(pData));
|
||||
pData.maxArraySize = MAXITEMS;
|
||||
pData.curIndex = -1;
|
||||
|
||||
XML_SetUserData(parser, &pData);
|
||||
|
||||
|
||||
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
|
||||
sprintf(errorBuf, "XML Parser Error in Facilities.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
LiveMessage(errorBuf);
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@
|
||||
extern INT32 iRestrictedSectorArraySize;
|
||||
extern UINT32 gRestrictMilitia[256];
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ROAMING_ELEMENT_NONE = 0,
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Strategic All.h"
|
||||
#include "XML.h"
|
||||
#else
|
||||
#include "builddefines.h"
|
||||
#include <stdio.h>
|
||||
#include "XML.h"
|
||||
#include "expat.h"
|
||||
#include "string.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "FileMan.h"
|
||||
#include "MemMan.h"
|
||||
#include "Debug Control.h"
|
||||
#include "mapscreen.h"
|
||||
#endif
|
||||
|
||||
#define MAX_CHAR_DATA_LENGTH 500
|
||||
|
||||
// Four different sector names, used at different times.
|
||||
extern CHAR16 gzSectorNames[256][4][MAX_SECTOR_NAME_LENGTH];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SECTORNAME_ELEMENT_NONE = 0,
|
||||
SECTORNAME_ELEMENT_SECTOR_NAMES,
|
||||
SECTORNAME_ELEMENT_SECTOR,
|
||||
SECTORNAME_ELEMENT,
|
||||
} SECTORNAME_PARSE_STAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SECTORNAME_PARSE_STAGE curElement;
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
|
||||
UINT8 sCurSectorX;
|
||||
UINT8 sCurSectorY;
|
||||
CHAR16 szCurUnexploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 szCurDetailedUnexploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 szCurExploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 szCurDetailedExploredName[MAX_SECTOR_NAME_LENGTH];
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
} SectorNameParseData;
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **atts)
|
||||
{
|
||||
SectorNameParseData * pData = (SectorNameParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
|
||||
{
|
||||
|
||||
if(strcmp(name, "SECTOR_NAMES") == 0 && pData->curElement == SECTORNAME_ELEMENT_NONE)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR_NAMES;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
// Initiate Array by setting first character to 0.
|
||||
for (UINT16 x = 0; x < 256; x++)
|
||||
{
|
||||
gzSectorNames[x][0][0]=0;
|
||||
gzSectorNames[x][1][0]=0;
|
||||
gzSectorNames[x][2][0]=0;
|
||||
gzSectorNames[x][3][0]=0;
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SECTOR") == 0 && pData->curElement == SECTORNAME_ELEMENT_SECTOR_NAMES)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == SECTORNAME_ELEMENT_SECTOR &&
|
||||
(strcmp(name, "SectorGrid") == 0 ||
|
||||
strcmp(name, "szUnexploredName") == 0 ||
|
||||
strcmp(name, "szDetailedUnexploredName") == 0 ||
|
||||
strcmp(name, "szExploredName") == 0 ||
|
||||
strcmp(name, "szDetailedExploredName") == 0 ))
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
SectorNameCharacterDataHandle(void *userData, const XML_Char *str, int len)
|
||||
{
|
||||
SectorNameParseData * pData = (SectorNameParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
|
||||
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
SectorNameParseData * pData = (SectorNameParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if(strcmp(name, "SECTOR_NAMES") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_NONE;
|
||||
}
|
||||
else if(strcmp(name, "SECTOR") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR_NAMES;
|
||||
|
||||
UINT8 ubSectorId = SECTOR(pData->sCurSectorX, pData->sCurSectorY);
|
||||
if (ubSectorId >= 0 && ubSectorId < 256)
|
||||
{
|
||||
wcscpy(gzSectorNames[ubSectorId][0], pData->szCurUnexploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
|
||||
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "SectorGrid") == 0 )
|
||||
{
|
||||
UINT8 x, y;
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
|
||||
y = (UINT8)pData->szCharData[0] & 0x1F;
|
||||
x = (UINT8)atol(&pData->szCharData[1]);
|
||||
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
|
||||
{
|
||||
pData->sCurSectorX = x;
|
||||
pData->sCurSectorY = y;
|
||||
}
|
||||
}
|
||||
else if(strcmp(name, "szUnexploredName") == 0 )
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurUnexploredName, sizeof(pData->szCurUnexploredName)/sizeof(pData->szCurUnexploredName[0]) );
|
||||
pData->szCurUnexploredName[sizeof(pData->szCurUnexploredName)/sizeof(pData->szCurUnexploredName[0]) - 1] = '\0';
|
||||
}
|
||||
|
||||
else if(strcmp(name, "szDetailedUnexploredName") == 0 )
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurDetailedUnexploredName, sizeof(pData->szCurDetailedUnexploredName)/sizeof(pData->szCurDetailedUnexploredName[0]) );
|
||||
pData->szCurDetailedUnexploredName[sizeof(pData->szCurDetailedUnexploredName)/sizeof(pData->szCurDetailedUnexploredName[0]) - 1] = '\0';
|
||||
}
|
||||
|
||||
else if(strcmp(name, "szExploredName") == 0 )
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurExploredName, sizeof(pData->szCurExploredName)/sizeof(pData->szCurExploredName[0]) );
|
||||
pData->szCurExploredName[sizeof(pData->szCurExploredName)/sizeof(pData->szCurExploredName[0]) - 1] = '\0';
|
||||
}
|
||||
|
||||
else if(strcmp(name, "szDetailedExploredName") == 0 )
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
|
||||
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurDetailedExploredName, sizeof(pData->szCurDetailedExploredName)/sizeof(pData->szCurDetailedExploredName[0]) );
|
||||
pData->szCurDetailedExploredName[sizeof(pData->szCurDetailedExploredName)/sizeof(pData->szCurDetailedExploredName[0]) - 1] = '\0';
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ReadInSectorNames(STR fileName)
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
SectorNameParseData pData;
|
||||
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return( FALSE );
|
||||
|
||||
uiFSize = FileGetSize(hFile);
|
||||
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree(lpcBuffer);
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
|
||||
XML_SetElementHandler(parser, SectorNameStartElementHandle, SectorNameEndElementHandle);
|
||||
XML_SetCharacterDataHandler(parser, SectorNameCharacterDataHandle);
|
||||
|
||||
|
||||
memset(&pData,0,sizeof(pData));
|
||||
XML_SetUserData(parser, &pData);
|
||||
|
||||
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
sprintf(errorBuf, "XML Parser Error in SectorNames.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
LiveMessage(errorBuf);
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEADROCK HAM 3.6:
|
||||
//
|
||||
// This code reads an XML called "UniformColors.XML", which tells the program which colors to use for
|
||||
// "standard" uniforms, including randomly-generated enemies and militia (for now).
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "Strategic All.h"
|
||||
#include "XML.h"
|
||||
#else
|
||||
#include "builddefines.h"
|
||||
#include <stdio.h>
|
||||
#include "XML.h"
|
||||
#include "expat.h"
|
||||
#include "string.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "FileMan.h"
|
||||
#include "MemMan.h"
|
||||
#include "Debug Control.h"
|
||||
#include "mapscreen.h"
|
||||
#endif
|
||||
|
||||
#define MAX_CHAR_DATA_LENGTH 500
|
||||
|
||||
// Error strings for this XML reader
|
||||
STR16 szUniformErrorStrings[]=
|
||||
{
|
||||
L"ENEMY_ADMIN",
|
||||
L"ENEMY_TROOP",
|
||||
L"ENEMY_ELITE",
|
||||
L"MILITIA_ROOKIE",
|
||||
L"MILITIA_REGULAR",
|
||||
L"MILITIA_ELITE",
|
||||
};
|
||||
|
||||
// Array to hold uniform data
|
||||
UNIFORMCOLORS gUniformColors[NUM_UNIFORMS];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNIFORM_ELEMENT_NONE = 0,
|
||||
UNIFORM_ELEMENT_LIST,
|
||||
UNIFORM_ELEMENT,
|
||||
UNIFORM_ELEMENT_DATA,
|
||||
} UNIFORM_PARSE_STAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UNIFORM_PARSE_STAGE curElement;
|
||||
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
|
||||
UINT8 sCurUniform;
|
||||
PaletteRepID szCurVest;
|
||||
PaletteRepID szCurPants;
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
} UniformParseData;
|
||||
|
||||
// Array for flags making sure that we have ALL uniform data defined.
|
||||
BOOLEAN UniformDataFound[NUM_UNIFORMS];
|
||||
|
||||
static void XMLCALL
|
||||
UniformStartElementHandle(void *userData, const XML_Char *name, const char **atts)
|
||||
{
|
||||
UniformParseData * pData = (UniformParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
|
||||
{
|
||||
|
||||
if(strcmp(name, "UNIFORMS") == 0 && pData->curElement == UNIFORM_ELEMENT_NONE)
|
||||
{
|
||||
pData->curElement = UNIFORM_ELEMENT_LIST;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
for (UINT8 cnt = 0; cnt < NUM_UNIFORMS; cnt++)
|
||||
{
|
||||
// reset array
|
||||
UniformDataFound[cnt] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
else if(pData->curElement == UNIFORM_ELEMENT_LIST &&
|
||||
(strcmp(name, "ENEMY_ADMIN") == 0 ||
|
||||
strcmp(name, "ENEMY_TROOP") == 0 ||
|
||||
strcmp(name, "ENEMY_ELITE") == 0 ||
|
||||
strcmp(name, "MILITIA_ROOKIE") == 0 ||
|
||||
strcmp(name, "MILITIA_REGULAR") == 0 ||
|
||||
strcmp(name, "MILITIA_ELITE") == 0 ) )
|
||||
{
|
||||
if (strcmp(name, "ENEMY_ADMIN") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_ENEMY_ADMIN;
|
||||
}
|
||||
else if (strcmp(name, "ENEMY_TROOP") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_ENEMY_TROOP;
|
||||
}
|
||||
else if (strcmp(name, "ENEMY_ELITE") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_ENEMY_ELITE;
|
||||
}
|
||||
else if (strcmp(name, "MILITIA_ROOKIE") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_MILITIA_ROOKIE;
|
||||
}
|
||||
else if (strcmp(name, "MILITIA_REGULAR") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_MILITIA_REGULAR;
|
||||
}
|
||||
else if (strcmp(name, "MILITIA_ELITE") == 0)
|
||||
{
|
||||
pData->sCurUniform = UNIFORM_MILITIA_ELITE;
|
||||
}
|
||||
pData->curElement = UNIFORM_ELEMENT;
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
else if(pData->curElement == UNIFORM_ELEMENT &&
|
||||
(strcmp(name, "Vest") == 0 ||
|
||||
strcmp(name, "Pants") == 0 ))
|
||||
{
|
||||
pData->curElement = UNIFORM_ELEMENT_DATA;
|
||||
|
||||
pData->maxReadDepth++; //we are not skipping this element
|
||||
}
|
||||
|
||||
pData->szCharData[0] = '\0';
|
||||
}
|
||||
|
||||
pData->currentDepth++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
UniformCharacterDataHandle(void *userData, const XML_Char *str, int len)
|
||||
{
|
||||
UniformParseData * pData = (UniformParseData *) userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
|
||||
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
|
||||
}
|
||||
|
||||
|
||||
static void XMLCALL
|
||||
UniformEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
UniformParseData * pData = (UniformParseData *)userData;
|
||||
|
||||
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
|
||||
{
|
||||
if(strcmp(name, "UNIFORMS") == 0)
|
||||
{
|
||||
// All entries are mandatory. Exception thrown if an entry was not found
|
||||
for (UINT8 cnt = 0; cnt < NUM_UNIFORMS; cnt++)
|
||||
{
|
||||
if (!UniformDataFound[cnt])
|
||||
{
|
||||
CHAR16 sString[256];
|
||||
swprintf( sString, L"Error in UniformColors.XML: Uniform color for %s not found or not properly defined!", szUniformErrorStrings[ cnt ] );
|
||||
THROWEXCEPTION( sString );
|
||||
}
|
||||
}
|
||||
|
||||
pData->curElement = UNIFORM_ELEMENT_NONE;
|
||||
}
|
||||
|
||||
else if(strcmp(name, "ENEMY_ADMIN") == 0 ||
|
||||
strcmp(name, "ENEMY_TROOP") == 0 ||
|
||||
strcmp(name, "ENEMY_ELITE") == 0 ||
|
||||
strcmp(name, "MILITIA_ROOKIE") == 0 ||
|
||||
strcmp(name, "MILITIA_REGULAR") == 0 ||
|
||||
strcmp(name, "MILITIA_ELITE") == 0 )
|
||||
{
|
||||
pData->curElement = UNIFORM_ELEMENT_LIST;
|
||||
|
||||
if (pData->sCurUniform >= UNIFORM_ENEMY_ADMIN && pData->sCurUniform < NUM_UNIFORMS )
|
||||
{
|
||||
memcpy( &(gUniformColors[pData->sCurUniform].pants), &(pData->szCurPants), sizeof(PaletteRepID) );
|
||||
memcpy( &(gUniformColors[pData->sCurUniform].vest), &(pData->szCurVest), sizeof(PaletteRepID) );
|
||||
UniformDataFound[pData->sCurUniform] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
else if(strcmp(name, "Vest") == 0 )
|
||||
{
|
||||
pData->curElement = UNIFORM_ELEMENT;
|
||||
|
||||
strcpy(pData->szCurVest, pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "Pants") == 0 )
|
||||
{
|
||||
pData->curElement = UNIFORM_ELEMENT;
|
||||
|
||||
strcpy(pData->szCurPants, pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
pData->currentDepth--;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN ReadInUniforms(STR fileName)
|
||||
{
|
||||
HWFILE hFile;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFSize;
|
||||
CHAR8 * lpcBuffer;
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
UniformParseData pData;
|
||||
|
||||
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
|
||||
if ( !hFile )
|
||||
return( FALSE );
|
||||
|
||||
uiFSize = FileGetSize(hFile);
|
||||
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
|
||||
|
||||
//Read in block
|
||||
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
|
||||
{
|
||||
MemFree(lpcBuffer);
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
lpcBuffer[uiFSize] = 0; //add a null terminator
|
||||
|
||||
FileClose( hFile );
|
||||
|
||||
|
||||
XML_SetElementHandler(parser, UniformStartElementHandle, UniformEndElementHandle);
|
||||
XML_SetCharacterDataHandler(parser, UniformCharacterDataHandle);
|
||||
|
||||
|
||||
memset(&pData,0,sizeof(pData));
|
||||
XML_SetUserData(parser, &pData);
|
||||
|
||||
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
|
||||
{
|
||||
CHAR8 errorBuf[511];
|
||||
sprintf(errorBuf, "XML Parser Error in UniformColors.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
|
||||
LiveMessage(errorBuf);
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MemFree(lpcBuffer);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
+329
-11
@@ -111,6 +111,8 @@
|
||||
#include "Strategic Status.h"
|
||||
#include "Soldier Create.h"
|
||||
#include "Animation Control.h"
|
||||
// HEADROCK HAM 3.6: Include facilities for assignment display
|
||||
#include "Facilities.h"
|
||||
#endif
|
||||
|
||||
#include "connect.h" //hayden
|
||||
@@ -905,6 +907,9 @@ void CreateContractBox( SOLDIERTYPE *pCharacter );
|
||||
void CreateAssignmentsBox( void );
|
||||
void CreateTrainingBox( void );
|
||||
void CreateMercRemoveAssignBox( void );
|
||||
// HEADROCK HAM 3.6: Facility box, Sub-menu
|
||||
void CreateFacilityBox( void );
|
||||
void CreateFacilityAssignmentBox( void );
|
||||
|
||||
void DetermineWhichAssignmentMenusCanBeShown( void );
|
||||
void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lal
|
||||
@@ -2837,16 +2842,29 @@ void DrawCharacterInfo(INT16 sCharNumber)
|
||||
|
||||
// second assignment line
|
||||
|
||||
// HEADROCK HAM 3.6: Operating a facility?
|
||||
if (pSoldier->sFacilityTypeOperated != -1)
|
||||
{
|
||||
UINT8 ubFacilityType = (UINT8)pSoldier->sFacilityTypeOperated;
|
||||
// Print sector ID string
|
||||
GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, sString );
|
||||
wcscat( sString, L": " );
|
||||
wcscat( sString, gFacilityTypes[ubFacilityType].szFacilityShortName );
|
||||
//wcscpy(sString, gFacilityTypes[ pSoldier->sFacilityTypeOperated ].szFacilityName);
|
||||
}
|
||||
|
||||
// train self / teammate / by other ?
|
||||
if( ( pSoldier->bAssignment == TRAIN_SELF ) || ( pSoldier->bAssignment == TRAIN_TEAMMATE ) || ( pSoldier->bAssignment == TRAIN_BY_OTHER ) )
|
||||
else if( ( pSoldier->bAssignment == TRAIN_SELF ) || ( pSoldier->bAssignment == TRAIN_TEAMMATE ) || ( pSoldier->bAssignment == TRAIN_BY_OTHER ) )
|
||||
{
|
||||
wcscpy(sString, pAttributeMenuStrings[pSoldier->bTrainStat]);
|
||||
}
|
||||
// train town?
|
||||
else if( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
// HEADROCK HAM 3.6: Draw for Mobile Trainers as well.
|
||||
else if( pSoldier->bAssignment == TRAIN_TOWN || pSoldier->bAssignment == TRAIN_MOBILE )
|
||||
{
|
||||
wcscpy(sString,pTownNames[GetTownIdForSector( pSoldier->sSectorX, pSoldier->sSectorY ) ] );
|
||||
}
|
||||
|
||||
// repairing?
|
||||
else if( pSoldier->bAssignment == REPAIR )
|
||||
{
|
||||
@@ -3127,6 +3145,136 @@ void DisplayCharacterInfo( void )
|
||||
// set font buffer
|
||||
SetFontDestBuffer( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
|
||||
|
||||
// HEADROCK HAM 3.6: "progress" bars showing how near the character is to "leveling up" in any stat. The bar
|
||||
// is displayed behind the current stat value, as see on the character's info panel.
|
||||
// This section draws STRATEGIC info pages. Another section is in Interface Panels.cpp and draws TACTICAL info pages.
|
||||
// The feature is toggled by Options-Menu switch, and its color is determined in the INI files.
|
||||
if ( gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] )
|
||||
{
|
||||
SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[bSelectedInfoChar].usSolID ];
|
||||
|
||||
UINT8 *pDestBuf;
|
||||
UINT32 uiDestPitchBYTES = 0;
|
||||
SGPRect ClipRect;
|
||||
UINT8 ubBarWidth = 0;
|
||||
UINT16 usColor = Get16BPPColor( FROMRGB( gGameExternalOptions.ubStatProgressBarsRed, gGameExternalOptions.ubStatProgressBarsGreen, gGameExternalOptions.ubStatProgressBarsBlue ) );
|
||||
//pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
||||
pDestBuf = LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES );
|
||||
|
||||
// AGI
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sAgilityGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sAgilityGain+1)) / SubpointsPerPoint(AGILAMT,0);
|
||||
ClipRect.iTop = (AGL_Y-1);
|
||||
ClipRect.iBottom = (AGL_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = AGL_X;
|
||||
ClipRect.iRight = AGL_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// DEX
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sDexterityGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sDexterityGain+1)) / SubpointsPerPoint(DEXTAMT,0);
|
||||
ClipRect.iTop = (DEX_Y-1);
|
||||
ClipRect.iBottom = (DEX_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = DEX_X;
|
||||
ClipRect.iRight = DEX_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// STR
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sStrengthGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sStrengthGain+1)) / SubpointsPerPoint(STRAMT,0);
|
||||
ClipRect.iTop = (STR_Y-1);
|
||||
ClipRect.iBottom = (STR_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = STR_X;
|
||||
ClipRect.iRight = STR_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// WIS
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sWisdomGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sWisdomGain+1)) / SubpointsPerPoint(WISDOMAMT,0);
|
||||
ClipRect.iTop = (WIS_Y-1);
|
||||
ClipRect.iBottom = (WIS_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = WIS_X;
|
||||
ClipRect.iRight = WIS_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// MRK
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sMarksmanshipGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMarksmanshipGain+1)) / SubpointsPerPoint(MARKAMT,0);
|
||||
ClipRect.iTop = (MRK_Y-1);
|
||||
ClipRect.iBottom = (MRK_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = MRK_X;
|
||||
ClipRect.iRight = MRK_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// LDR
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sLeadershipGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sLeadershipGain+1)) / SubpointsPerPoint(LDRAMT,0);
|
||||
ClipRect.iTop = (LDR_Y-1);
|
||||
ClipRect.iBottom = (LDR_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = LDR_X;
|
||||
ClipRect.iRight = LDR_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// MECH
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sMechanicGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMechanicGain+1)) / SubpointsPerPoint(MECHANAMT,0);
|
||||
ClipRect.iTop = (MEC_Y-1);
|
||||
ClipRect.iBottom = (MEC_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = MEC_X;
|
||||
ClipRect.iRight = MEC_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// EXPLO
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sExplosivesGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sExplosivesGain+1)) / SubpointsPerPoint(EXPLODEAMT,0);
|
||||
ClipRect.iTop = (EXP_Y-1);
|
||||
ClipRect.iBottom = (EXP_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = EXP_X;
|
||||
ClipRect.iRight = EXP_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// MED
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sMedicalGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMedicalGain+1)) / SubpointsPerPoint(MEDICALAMT,0);
|
||||
ClipRect.iTop = (MED_Y-1);
|
||||
ClipRect.iBottom = (MED_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = MED_X;
|
||||
ClipRect.iRight = MED_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
// EXPLEVEL
|
||||
if (gMercProfiles[ pSoldier->ubProfile ].sExpLevelGain)
|
||||
{
|
||||
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sExpLevelGain+1)) / SubpointsPerPoint(EXPERAMT, pSoldier->stats.bExpLevel);
|
||||
ClipRect.iTop = (LVL_Y-1);
|
||||
ClipRect.iBottom = (LVL_Y-1) + STAT_HEI;
|
||||
ClipRect.iLeft = LVL_X;
|
||||
ClipRect.iRight = LVL_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
}
|
||||
|
||||
UnLockVideoSurface( guiSAVEBUFFER );
|
||||
}
|
||||
|
||||
|
||||
// draw character info and face
|
||||
DrawCharacterInfo( bSelectedInfoChar );
|
||||
|
||||
@@ -4428,12 +4576,16 @@ UINT32 MapScreenHandle(void)
|
||||
|
||||
InitPreviousPaths();
|
||||
|
||||
// HEADROCK HAM 3.6: Init coordinates for new variable-sized message window
|
||||
InitMapScreenInterfaceBottomCoords();
|
||||
|
||||
// if arrival sector is invalid, reset to A9
|
||||
if ( ( gsMercArriveSectorX < 1 ) || ( gsMercArriveSectorY < 1 ) ||
|
||||
( gsMercArriveSectorX > 16 ) || ( gsMercArriveSectorY > 16 ) )
|
||||
{
|
||||
gsMercArriveSectorX = 9;
|
||||
gsMercArriveSectorY = 1;
|
||||
// HEADROCK HAM 3.5: Externalized coordinates
|
||||
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
}
|
||||
|
||||
gfInConfirmMapMoveMode = FALSE;
|
||||
@@ -4702,7 +4854,8 @@ UINT32 MapScreenHandle(void)
|
||||
if( AnyMercsHired( ) == FALSE )
|
||||
{
|
||||
// select starting sector (A9 - Omerta)
|
||||
ChangeSelectedMapSector( startingX, startingY, startingZ );
|
||||
// HEADROCK HAM 3.5: Externalized!
|
||||
ChangeSelectedMapSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
|
||||
}
|
||||
else if( ( gWorldSectorX > 0 ) && ( gWorldSectorY > 0 ) && ( gbWorldSectorZ != -1 ) )
|
||||
{
|
||||
@@ -4714,7 +4867,8 @@ UINT32 MapScreenHandle(void)
|
||||
// only select A9 - Omerta IF there is no current selection, otherwise leave it as is
|
||||
if ( ( sSelMapX == 0 ) || ( sSelMapY == 0 ) || ( iCurrentMapSectorZ == -1 ) )
|
||||
{
|
||||
ChangeSelectedMapSector( startingX, startingY, startingZ );
|
||||
// HEADROCK HAM 3.5: Externalized!
|
||||
ChangeSelectedMapSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5261,7 +5415,8 @@ UINT32 MapScreenHandle(void)
|
||||
|
||||
|
||||
// handle display of inventory pop up
|
||||
HandleDisplayOfItemPopUpForSector( startingX, startingY, startingZ );
|
||||
// HEADROCK HAM 3.5: Externalize!
|
||||
HandleDisplayOfItemPopUpForSector( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
|
||||
|
||||
// Display Framerate
|
||||
DisplayFrameRate( );
|
||||
@@ -5311,7 +5466,9 @@ UINT32 MapScreenHandle(void)
|
||||
|
||||
|
||||
|
||||
|
||||
fCharacterInfoPanelDirty=TRUE;
|
||||
fMapPanelDirty = TRUE;
|
||||
fMapScreenBottomDirty = TRUE;
|
||||
fTeamPanelDirty = TRUE;
|
||||
fEndShowInventoryFlag = FALSE;
|
||||
}
|
||||
@@ -5702,6 +5859,8 @@ void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont)
|
||||
FindFontCenterCoordinates((short)ASSIGN_X + 1, (short)(usVehicleY+(sRowIndex*Y_SIZE)), (short)ASSIGN_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY);
|
||||
}
|
||||
|
||||
SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ sCharNumber ].usSolID ];
|
||||
|
||||
if( fFlashAssignDone == TRUE )
|
||||
{
|
||||
if( Menptr[gCharactersList[sCharNumber].usSolID].flags.fDoneAssignmentAndNothingToDoFlag )
|
||||
@@ -5710,6 +5869,97 @@ void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont)
|
||||
}
|
||||
}
|
||||
|
||||
if ( gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] &&
|
||||
(pSoldier->bAssignment >= TRAIN_SELF ||
|
||||
pSoldier->bAssignment <= TRAIN_BY_OTHER ) &&
|
||||
pSoldier->bAssignment != TRAIN_TEAMMATE )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Draw militia training progress bar
|
||||
UINT32 uiDestBuffer;
|
||||
UINT8 *pDestBuf;
|
||||
UINT32 uiDestPitchBYTES = 0;
|
||||
SGPRect ClipRect;
|
||||
UINT8 ubBarWidth;
|
||||
UINT16 usColor = Get16BPPColor( FROMRGB( gGameExternalOptions.ubStatProgressBarsRed, gGameExternalOptions.ubStatProgressBarsGreen, gGameExternalOptions.ubStatProgressBarsBlue ) );
|
||||
|
||||
if( ( fShowAssignmentMenu == TRUE ) && ( fTeamPanelDirty == FALSE ) )
|
||||
{
|
||||
uiDestBuffer = FRAME_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiDestBuffer = guiSAVEBUFFER;
|
||||
}
|
||||
pDestBuf = LockVideoSurface( uiDestBuffer, &uiDestPitchBYTES );
|
||||
|
||||
UINT8 ubProgress;
|
||||
UINT16 usMaxProgress;
|
||||
UINT8 sMapX = (UINT8)pSoldier->sSectorX;
|
||||
UINT8 sMapY = (UINT8)pSoldier->sSectorY;
|
||||
if ( pSoldier->bAssignment == TRAIN_TOWN )
|
||||
{
|
||||
ubProgress = SectorInfo[SECTOR(sMapX, sMapY)].ubMilitiaTrainingPercentDone;
|
||||
usMaxProgress = 100;
|
||||
}
|
||||
else if ( pSoldier->bAssignment == TRAIN_MOBILE )
|
||||
{
|
||||
ubProgress = SectorInfo[SECTOR(sMapX, sMapY)].ubMobileMilitiaTrainingPercentDone;
|
||||
usMaxProgress = 100;
|
||||
}
|
||||
else if ( pSoldier->bAssignment == TRAIN_SELF ||
|
||||
pSoldier->bAssignment == TRAIN_BY_OTHER )
|
||||
{
|
||||
switch (pSoldier->bTrainStat)
|
||||
{
|
||||
case STRENGTH:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sStrengthGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usStrengthSubpointsToImprove;
|
||||
break;
|
||||
case AGILITY:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sAgilityGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usAgilitySubpointsToImprove;
|
||||
break;
|
||||
case DEXTERITY:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sDexterityGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usDexteritySubpointsToImprove;
|
||||
break;
|
||||
case HEALTH:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sLifeGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usHealthSubpointsToImprove;
|
||||
break;
|
||||
case MARKSMANSHIP:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sMarksmanshipGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usMarksmanshipSubpointsToImprove;
|
||||
break;
|
||||
case LEADERSHIP:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sLeadershipGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usLeadershipSubpointsToImprove;
|
||||
break;
|
||||
case MECHANICAL:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sMechanicGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usMechanicalSubpointsToImprove;
|
||||
break;
|
||||
case MEDICAL:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sMedicalGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usMedicalSubpointsToImprove;
|
||||
break;
|
||||
case EXPLOSIVE_ASSIGN:
|
||||
ubProgress = gMercProfiles[ pSoldier->ubProfile ].sExplosivesGain+1;
|
||||
usMaxProgress = gGameExternalOptions.usExplosivesSubpointsToImprove;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ubBarWidth = (ASSIGN_WIDTH * ubProgress) / usMaxProgress;
|
||||
ClipRect.iTop = (usY+(Y_OFFSET*sRowIndex+1))-1;
|
||||
ClipRect.iBottom = ClipRect.iTop + Y_SIZE;
|
||||
ClipRect.iLeft = ASSIGN_X+2;
|
||||
ClipRect.iRight = ASSIGN_X + ubBarWidth;
|
||||
Blt16BPPBufferHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect, usColor );
|
||||
|
||||
UnLockVideoSurface( uiDestBuffer );
|
||||
}
|
||||
|
||||
//RestoreExternBackgroundRect(ASSIGN_X-2, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), ASSIGN_WIDTH+2, Y_SIZE);
|
||||
DrawString(sString, (UINT16)usX, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), iFont);
|
||||
}
|
||||
@@ -6438,6 +6688,12 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
|
||||
fShowAttributeMenu = FALSE;
|
||||
fMapPanelDirty = TRUE;
|
||||
}
|
||||
// stop showing current assignment box
|
||||
if( fShowFacilityAssignmentMenu == TRUE )
|
||||
{
|
||||
fShowFacilityAssignmentMenu = FALSE;
|
||||
fMapPanelDirty = TRUE;
|
||||
}
|
||||
else if( fShowTrainingMenu == TRUE )
|
||||
{
|
||||
fShowTrainingMenu = FALSE;
|
||||
@@ -6450,6 +6706,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
|
||||
{
|
||||
fShowRepairMenu = FALSE;
|
||||
}
|
||||
// HEADROCK HAM 3.6: Facility Menu
|
||||
else if( fShowFacilityMenu == TRUE )
|
||||
{
|
||||
fShowFacilityMenu = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fShowAssignmentMenu = FALSE;
|
||||
@@ -10695,6 +10956,12 @@ void RenderMapRegionBackground( void )
|
||||
ForceUpDateOfBox( ghAttributeBox );
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Force re-render due to Facility box
|
||||
if ( ghFacilityAssignmentBox != 1 )
|
||||
{
|
||||
ForceUpDateOfBox( ghFacilityAssignmentBox );
|
||||
}
|
||||
|
||||
if ( ghTownMineBox != - 1 )
|
||||
{
|
||||
// force update of town mine info boxes
|
||||
@@ -14970,13 +15237,18 @@ void HandlePostAutoresolveMessages()
|
||||
|
||||
void GetMapscreenMercAssignmentString( SOLDIERTYPE *pSoldier, CHAR16 sString[] )
|
||||
{
|
||||
if( pSoldier->bAssignment != VEHICLE )
|
||||
if ( pSoldier->bAssignment == VEHICLE )
|
||||
{
|
||||
wcscpy(sString, pAssignmentStrings[ pSoldier->bAssignment ] );
|
||||
wcscpy( sString, pShortVehicleStrings[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( sString, pShortVehicleStrings[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ] );
|
||||
wcscpy(sString, pAssignmentStrings[ pSoldier->bAssignment ] );
|
||||
}
|
||||
// If soldier is working at a facility, add an asterisk.
|
||||
if (pSoldier->sFacilityTypeOperated != -1)
|
||||
{
|
||||
wcscat(sString, L"*");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15433,6 +15705,7 @@ void RequestToggleMercInventoryPanel( void )
|
||||
else
|
||||
{
|
||||
// Headrock. New line forces InvBottom rerender when the inventory is opened and closed.
|
||||
fEndShowInventoryFlag = TRUE;
|
||||
RenderMapScreenInterfaceBottom ( TRUE );
|
||||
SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] );
|
||||
}
|
||||
@@ -15549,3 +15822,48 @@ void MapscreenMarkButtonsDirty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: Get a total of all merc salaries. Used for the new Daily Expenses display.
|
||||
INT32 GetTotalContractExpenses ( void )
|
||||
{
|
||||
if (gGameExternalOptions.ubIncludeContractsInExpenses == 0)
|
||||
{
|
||||
// Contract costs are excluded.
|
||||
return (0);
|
||||
}
|
||||
|
||||
UINT8 ubCounter = 0;
|
||||
SOLDIERTYPE *pSoldier;
|
||||
INT32 iTotalCost = 0;
|
||||
|
||||
while(gCharactersList[ubCounter].fValid)
|
||||
{
|
||||
pSoldier = MercPtrs[ gCharactersList[ ubCounter ].usSolID ];
|
||||
// salary
|
||||
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
|
||||
{
|
||||
if (gGameExternalOptions.ubIncludeContractsInExpenses == 2)
|
||||
{
|
||||
// daily rate
|
||||
if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_2_WEEK )
|
||||
{
|
||||
iTotalCost += ( gMercProfiles[ pSoldier->ubProfile ].uiBiWeeklySalary / 14 );
|
||||
}
|
||||
if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_1_WEEK )
|
||||
{
|
||||
iTotalCost += ( gMercProfiles[ pSoldier->ubProfile ].uiWeeklySalary / 7 );
|
||||
}
|
||||
else
|
||||
{
|
||||
iTotalCost += gMercProfiles[ pSoldier->ubProfile ].sSalary;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iTotalCost += gMercProfiles[ pSoldier->ubProfile ].sSalary;
|
||||
}
|
||||
ubCounter++;
|
||||
}
|
||||
return (iTotalCost);
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#define MAP_WORLD_Y 18
|
||||
|
||||
#define MAX_TOWN_NAME_LENGHT 32
|
||||
#define MAX_SECTOR_NAME_LENGTH 128
|
||||
|
||||
#define MAX_TOWNS 50 //13 //50
|
||||
#define MAX_TOWN_SECTORS 260 //40 //260
|
||||
@@ -93,4 +94,7 @@ BOOLEAN InitializeInvPanelCoordsOld( );
|
||||
BOOLEAN InitializeInvPanelCoordsNew( );
|
||||
BOOLEAN InitializeInvPanelCoordsVehicle( );
|
||||
|
||||
// HEADROCK HAM 3.6: Calculate daily cost for all mercs who have one.
|
||||
INT32 GetTotalContractExpenses ( void );
|
||||
|
||||
#endif
|
||||
+194
-91
@@ -296,6 +296,9 @@ STR8 pHortStrings[]={
|
||||
"17",
|
||||
};
|
||||
|
||||
// HEADROCK HAM 3.6: Array to hold user-defined sector names
|
||||
CHAR16 gzSectorNames[256][4][MAX_SECTOR_NAME_LENGTH];
|
||||
|
||||
BOOLEAN ReadInStrategicMapSectorTownNames(STR fileName, BOOLEAN localizedVersion);
|
||||
|
||||
void DoneFadeOutAdjacentSector( void );
|
||||
@@ -1616,8 +1619,9 @@ void InitializeSAMSites( void )
|
||||
{
|
||||
UINT32 cnt;
|
||||
// move the landing zone over to Omerta
|
||||
gsMercArriveSectorX = 9;
|
||||
gsMercArriveSectorY = 1;
|
||||
// HEADROCK HAM 3.5: Externalized coordinates
|
||||
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
|
||||
// all SAM sites start game in perfect working condition
|
||||
for ( cnt = 0; cnt < NUMBER_OF_SAMS; cnt++ )
|
||||
@@ -3009,109 +3013,179 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
bTownNameID = StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].bNameId;
|
||||
ubSectorID = (UINT8)SECTOR( sSectorX, sSectorY );
|
||||
AssertGE(ubSectorID, 0);
|
||||
AssertLT(ubSectorID,256);
|
||||
pSector = &SectorInfo[ ubSectorID ];
|
||||
ubLandType = pSector->ubTraversability[ 4 ];
|
||||
swprintf( zString, L"%c%d: ", 'A' + sSectorY - 1, sSectorX );
|
||||
|
||||
if ( bTownNameID == BLANK_SECTOR )
|
||||
////////////////////////////////////
|
||||
// Read and verify XML sector names
|
||||
BOOLEAN fSectorHasXMLNames = TRUE;
|
||||
CHAR16 zUnexplored[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 zDetailedUnexplored[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 zExplored[MAX_SECTOR_NAME_LENGTH];
|
||||
CHAR16 zDetailedExplored[MAX_SECTOR_NAME_LENGTH];
|
||||
|
||||
wcscpy( zUnexplored, gzSectorNames[ ubSectorID ][0] );
|
||||
wcscpy( zDetailedUnexplored, gzSectorNames[ ubSectorID ][1] );
|
||||
wcscpy( zExplored, gzSectorNames[ ubSectorID ][2] );
|
||||
wcscpy( zDetailedExplored, gzSectorNames[ ubSectorID ][3] );
|
||||
|
||||
if (zUnexplored[0] == 0 || zDetailedUnexplored[0] == 0 || zExplored[0] == 0 || zDetailedExplored[0] == 0)
|
||||
{
|
||||
// OK, build string id like J11
|
||||
// are we dealing with the unfound towns?
|
||||
switch( ubSectorID )
|
||||
fSectorHasXMLNames = FALSE;
|
||||
}
|
||||
|
||||
if (fSectorHasXMLNames)
|
||||
{
|
||||
// HEADROCK HAM 3.6: The program can now read custom names from XML for all above-ground sectors.
|
||||
// In the event that a specific name or set of names is missing, the program generates a default
|
||||
// name as it always has.
|
||||
// I've also updated the SAM Site sectors to rely on SamSite.XML data.
|
||||
|
||||
BOOLEAN fVisited = (SectorInfo[ ubSectorID ].uiFlags & SF_ALREADY_VISITED);
|
||||
BOOLEAN fSAMSiteKnown = FALSE;
|
||||
|
||||
// Test for known SAM Site at this location
|
||||
for (UINT16 x=0; x < MAX_NUMBER_OF_SAMS; x++)
|
||||
{
|
||||
case SEC_D2: //Chitzena SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_ONE ] )
|
||||
wcscat( zString, pLandTypeStrings[ TROPICS ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ TROPICS_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
break;
|
||||
case SEC_D15: //Drassen SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_TWO ] )
|
||||
wcscat( zString, pLandTypeStrings[ SPARSE ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ SPARSE_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
break;
|
||||
case SEC_I8: //Cambria SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_THREE ] )
|
||||
wcscat( zString, pLandTypeStrings[ SAND ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ SAND_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
break;
|
||||
default:
|
||||
wcscat( zString, pLandTypeStrings[ ubLandType ] );
|
||||
break;
|
||||
if ( pSamList[x] == ubSectorID )
|
||||
{
|
||||
if ( fSamSiteFound[ x ] )
|
||||
{
|
||||
fSAMSiteKnown = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fVisited || fSAMSiteKnown)
|
||||
{
|
||||
if (fDetailed)
|
||||
{
|
||||
wcscat( zString, zDetailedExplored );
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( zString, zExplored);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fDetailed)
|
||||
{
|
||||
wcscat( zString, zDetailedUnexplored);
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat( zString, zUnexplored );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ubSectorID )
|
||||
// Default JA2 Name selection
|
||||
if ( bTownNameID == BLANK_SECTOR )
|
||||
{
|
||||
case SEC_B13:
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ DRASSEN ] );
|
||||
break;
|
||||
case SEC_F8:
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ CAMBRIA ] );
|
||||
break;
|
||||
case SEC_J9: //Tixa
|
||||
if( !fFoundTixa )
|
||||
wcscat( zString, pLandTypeStrings[ SAND ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ TIXA ] );
|
||||
break;
|
||||
case SEC_K4: //Orta
|
||||
if( !fFoundOrta )
|
||||
wcscat( zString, pLandTypeStrings[ SWAMP ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ ORTA ] );
|
||||
break;
|
||||
case SEC_N3:
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ MEDUNA ] );
|
||||
break;
|
||||
default:
|
||||
if( ubSectorID == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] )
|
||||
{ //Meduna's SAM site
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ MEDUNA_SAM_SITE ] );
|
||||
// OK, build string id like J11
|
||||
// are we dealing with the unfound towns?
|
||||
switch( ubSectorID )
|
||||
{
|
||||
case SEC_D2: //Chitzena SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_ONE ] )
|
||||
wcscat( zString, pLandTypeStrings[ TROPICS ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ TROPICS_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
}
|
||||
else
|
||||
{ //All other towns that are known since beginning of the game.
|
||||
wcscat( zString, pTownNames[ bTownNameID ] );
|
||||
break;
|
||||
case SEC_D15: //Drassen SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_TWO ] )
|
||||
wcscat( zString, pLandTypeStrings[ SPARSE ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ SPARSE_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
break;
|
||||
case SEC_I8: //Cambria SAM
|
||||
if( !fSamSiteFound[ SAM_SITE_THREE ] )
|
||||
wcscat( zString, pLandTypeStrings[ SAND ] );
|
||||
else if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ SAND_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
break;
|
||||
default:
|
||||
wcscat( zString, pLandTypeStrings[ ubLandType ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ubSectorID )
|
||||
{
|
||||
case SEC_B13:
|
||||
if( fDetailed )
|
||||
{
|
||||
switch( ubSectorID )
|
||||
{ //Append the word, "mine" for town sectors containing a mine.
|
||||
case SEC_B2:
|
||||
case SEC_D4:
|
||||
case SEC_D13:
|
||||
case SEC_H3:
|
||||
case SEC_H8:
|
||||
case SEC_I14:
|
||||
wcscat( zString, L" " ); //space
|
||||
wcscat( zString, pwMineStrings[ 0 ] ); //then "Mine"
|
||||
break;
|
||||
wcscat( zString, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ DRASSEN ] );
|
||||
break;
|
||||
case SEC_F8:
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ CAMBRIA ] );
|
||||
break;
|
||||
case SEC_J9: //Tixa
|
||||
if( !fFoundTixa )
|
||||
wcscat( zString, pLandTypeStrings[ SAND ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ TIXA ] );
|
||||
break;
|
||||
case SEC_K4: //Orta
|
||||
if( !fFoundOrta )
|
||||
wcscat( zString, pLandTypeStrings[ SWAMP ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ ORTA ] );
|
||||
break;
|
||||
case SEC_N3:
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] );
|
||||
else
|
||||
wcscat( zString, pTownNames[ MEDUNA ] );
|
||||
break;
|
||||
default:
|
||||
if( ubSectorID == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] )
|
||||
{ //Meduna's SAM site
|
||||
if( fDetailed )
|
||||
wcscat( zString, pLandTypeStrings[ MEDUNA_SAM_SITE ] );
|
||||
else
|
||||
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
|
||||
}
|
||||
else
|
||||
{ //All other towns that are known since beginning of the game.
|
||||
wcscat( zString, pTownNames[ bTownNameID ] );
|
||||
if( fDetailed )
|
||||
{
|
||||
switch( ubSectorID )
|
||||
{ //Append the word, "mine" for town sectors containing a mine.
|
||||
case SEC_B2:
|
||||
case SEC_D4:
|
||||
case SEC_D13:
|
||||
case SEC_H3:
|
||||
case SEC_H8:
|
||||
case SEC_I14:
|
||||
wcscat( zString, L" " ); //space
|
||||
wcscat( zString, pwMineStrings[ 0 ] ); //then "Mine"
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4605,8 +4679,26 @@ void UpdateAirspaceControl( void )
|
||||
GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, sMsgSubString1, FALSE );
|
||||
|
||||
// move the landing zone over to Omerta
|
||||
gsMercArriveSectorX = 9;
|
||||
gsMercArriveSectorY = 1;
|
||||
// HEADROCK HAM 3.5: Externalized coordinates
|
||||
if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY ) ].fEnemyAirControlled == FALSE )
|
||||
{
|
||||
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
|
||||
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT8 ubSectorX = 1; ubSectorX <= 16; ubSectorX++)
|
||||
{
|
||||
for (UINT8 ubSectorY = 1; ubSectorY <=16; ubSectorY++)
|
||||
{
|
||||
if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( ubSectorX, ubSectorY ) ].fEnemyAirControlled == FALSE )
|
||||
{
|
||||
gsMercArriveSectorX = ubSectorX;
|
||||
gsMercArriveSectorY = ubSectorY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the name of the new sector
|
||||
GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, sMsgSubString2, FALSE );
|
||||
@@ -4615,7 +4707,11 @@ void UpdateAirspaceControl( void )
|
||||
swprintf( sMsgString, pBullseyeStrings[ 4 ], sMsgSubString1, sMsgSubString2 );
|
||||
|
||||
// confirm the change with overlay message
|
||||
DoScreenIndependantMessageBox( sMsgString, MSG_BOX_FLAG_OK, NULL );
|
||||
// HEADROCK HAM 3.5: If we do this during SaveLoad, the message box prevents loading the game at all!
|
||||
if (guiCurrentScreen != SAVE_LOAD_SCREEN)
|
||||
{
|
||||
DoScreenIndependantMessageBox( sMsgString, MSG_BOX_FLAG_OK, NULL );
|
||||
}
|
||||
|
||||
// update position of bullseye
|
||||
fMapPanelDirty = TRUE;
|
||||
@@ -4627,6 +4723,7 @@ void UpdateAirspaceControl( void )
|
||||
|
||||
// ARM: airspace control now affects refueling site availability, so update that too with every change!
|
||||
UpdateRefuelSiteAvailability( );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5524,6 +5621,12 @@ void HandleSlayDailyEvent( void )
|
||||
|
||||
BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY )
|
||||
{
|
||||
// HEADROCK HAM 3.5: Fix for assertion errors associated with rain checks.
|
||||
if (sSectorX <= 0 || sSectorY <=0 || sSectorX > 16 || sSectorY > 16)
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if ( SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == SAND )
|
||||
{
|
||||
// desert
|
||||
@@ -5669,7 +5772,7 @@ BOOLEAN CheckAndHandleUnloadingOfCurrentWorld()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( gTacticalStatus.fDidGameJustStart && gWorldSectorX == 9 && gWorldSectorY == 1 && !gbWorldSectorZ )
|
||||
if( gTacticalStatus.fDidGameJustStart && gWorldSectorX == gGameExternalOptions.ubDefaultArrivalSectorX && gWorldSectorY == gGameExternalOptions.ubDefaultArrivalSectorY && !gbWorldSectorZ )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user