Original Source for 1.13 Mod High Resolution version from 12/06/05

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@21 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
lalien
2006-04-19 11:32:51 +00:00
commit e54aeb96aa
790 changed files with 741287 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+334
View File
@@ -0,0 +1,334 @@
#ifndef _ASSIGNMENTS_H
#define _ASSIGNMENTS_H
// header for assignment manipulation/updating for characters
#include "Types.h"
#include "Soldier Control.h"
#include "mousesystem.h"
#include "Strategic Movement.h"
// this distinguishes whether we're only looking for patients healable THIS HOUR (those that have been on their assignment
// long enough), or those that will be healable EVER (regardless of whether they're getting healed during this hour)
#define HEALABLE_EVER 0
#define HEALABLE_THIS_HOUR 1
// merc collapses from fatigue if max breath drops to this. Can't go any lower!
#define BREATHMAX_ABSOLUTE_MINIMUM 10
#define BREATHMAX_GOTTA_STOP_MOVING 30
#define BREATHMAX_PRETTY_TIRED 50
#define BREATHMAX_CANCEL_COLLAPSE 60
#define BREATHMAX_CANCEL_TIRED 75
#define BREATHMAX_FULLY_RESTED 95
#define VEHICLE_REPAIR_POINTS_DIVISOR 10
// Assignments Defines
enum{
SQUAD_1 =0,
SQUAD_2,
SQUAD_3,
SQUAD_4,
SQUAD_5,
SQUAD_6,
SQUAD_7,
SQUAD_8,
SQUAD_9,
SQUAD_10,
SQUAD_11,
SQUAD_12,
SQUAD_13,
SQUAD_14,
SQUAD_15,
SQUAD_16,
SQUAD_17,
SQUAD_18,
SQUAD_19,
SQUAD_20,
ON_DUTY,
DOCTOR,
PATIENT,
VEHICLE,
IN_TRANSIT,
REPAIR,
TRAIN_SELF,
TRAIN_TOWN,
TRAIN_TEAMMATE,
TRAIN_BY_OTHER,
ASSIGNMENT_DEAD,
ASSIGNMENT_UNCONCIOUS, // unused
ASSIGNMENT_POW,
ASSIGNMENT_HOSPITAL,
ASSIGNMENT_EMPTY,
};
#define NO_ASSIGNMENT 127 //used when no pSoldier->ubDesiredSquad
// Train stats defines (must match ATTRIB_MENU_ defines, and pAttributeMenuStrings )
enum{
STRENGTH = 0,
DEXTERITY,
AGILITY,
HEALTH,
MARKSMANSHIP,
MEDICAL,
MECHANICAL,
LEADERSHIP,
EXPLOSIVE_ASSIGN,
NUM_TRAINABLE_STATS
// NOTE: Wisdom isn't trainable!
};
typedef struct TOWN_TRAINER_TYPE
{
SOLDIERTYPE *pSoldier;
INT16 sTrainingPts;
} TOWN_TRAINER_TYPE;
// can character do this assignment?
//BOOLEAN CanSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment );
// can this character be assigned as a doctor?
BOOLEAN CanCharacterDoctor( SOLDIERTYPE *pCharacter );
// can this character be assigned as a repairman?
BOOLEAN CanCharacterRepair( SOLDIERTYPE *pCharacter );
// can character be patient?
BOOLEAN CanCharacterPatient( SOLDIERTYPE *pCharacter );
// can character train militia?
BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pCharacter );
// can character train stat?..as train self or as trainer?
BOOLEAN CanCharacterTrainStat( SOLDIERTYPE *pSoldier, INT8 bStat, BOOLEAN fTrainSelf, BOOLEAN fTrainTeammate );
// is character capable of practising at all?
BOOLEAN CanCharacterPractise( SOLDIERTYPE *pCharacter );
// can this character train others?
BOOLEAN CanCharacterTrainTeammates( SOLDIERTYPE *pSoldier );
// put character on duty?
BOOLEAN CanCharacterOnDuty( SOLDIERTYPE *pCharacter );
// put character to sleep?
BOOLEAN CanCharacterSleep( SOLDIERTYPE *pCharacter, BOOLEAN fExplainWhyNot );
BOOLEAN CanCharacterBeAwakened( SOLDIERTYPE *pSoldier, BOOLEAN fExplainWhyNot );
// put character in vehicle?
BOOLEAN CanCharacterVehicle( SOLDIERTYPE *pCharacter );
#define CHARACTER_CANT_JOIN_SQUAD_ALREADY_IN_IT -6
#define CHARACTER_CANT_JOIN_SQUAD_SQUAD_MOVING -5
#define CHARACTER_CANT_JOIN_SQUAD_MOVING -4
#define CHARACTER_CANT_JOIN_SQUAD_VEHICLE -3
#define CHARACTER_CANT_JOIN_SQUAD_TOO_FAR -2
#define CHARACTER_CANT_JOIN_SQUAD_FULL -1
#define CHARACTER_CANT_JOIN_SQUAD 0
#define CHARACTER_CAN_JOIN_SQUAD 1
// can character be added to squad
INT8 CanCharacterSquad( SOLDIERTYPE *pCharacter, INT8 bSquadValue );
// if merc could train militia here, do they have sufficient loyalty?
BOOLEAN DoesSectorMercIsInHaveSufficientLoyaltyToTrainMilitia( SOLDIERTYPE *pSoldier );
BOOLEAN DoesTownHaveRatingToTrainMilitia( INT8 bTownId );
// is the character in transit?
BOOLEAN IsCharacterInTransit( SOLDIERTYPE *pCharacter );
// handler for assignments -- called once per hour via event
void UpdateAssignments();
// how many people in this secotr have this assignment?
UINT8 FindNumberInSectorWithAssignment( INT16 sX, INT16 sY, INT8 bAssignment );
void MakeSoldiersTacticalAnimationReflectAssignment( SOLDIERTYPE *pSoldier );
// build list of sectors with mercs
void BuildSectorsWithSoldiersList( void );
// init sectors with soldiers list
void InitSectorsWithSoldiersList( void );
// is there a soldier in this sector?..only use after BuildSectorsWithSoldiersList is called
BOOLEAN IsThereASoldierInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void CheckIfSoldierUnassigned( SOLDIERTYPE *pSoldier );
// figure out the assignment menu pop up box positions
void DetermineBoxPositions( void );
// set x,y position in tactical
void SetTacticalPopUpAssignmentBoxXY( void );
// get number of pts that are being used this strategic turn
INT16 GetTownTrainPtsForCharacter( SOLDIERTYPE *pTrainer, UINT16 *pusMaxPts );
// find number of healing pts
UINT16 CalculateHealingPointsForDoctor(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts, BOOLEAN fMakeSureKitIsInHand );
// find number of repair pts repairman has available
UINT8 CalculateRepairPointsForRepairman(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts, BOOLEAN fMakeSureKitIsInHand );
// get bonus tarining pts due to an instructor for this student
INT16 GetBonusTrainingPtsDueToInstructor( SOLDIERTYPE *pInstructor, SOLDIERTYPE *pStudent, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
// get training pts for this soldier
INT16 GetSoldierTrainingPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
// pts for being a student for this soldier
INT16 GetSoldierStudentPts( SOLDIERTYPE *pSoldier, INT8 bTrainStat, BOOLEAN fAtGunRange, UINT16 *pusMaxPts );
// reset these soldiers
void ResetAssignmentsForAllSoldiersInSectorWhoAreTrainingTown( SOLDIERTYPE *pSoldier );
// Handle assignment done
void AssignmentDone( SOLDIERTYPE *pSoldier, BOOLEAN fSayQuote, BOOLEAN fMeToo );
extern INT32 ghAssignmentBox;
extern INT32 ghEpcBox;
extern INT32 ghSquadBox;
extern INT32 ghVehicleBox;
extern INT32 ghRepairBox;
extern INT32 ghTrainingBox;
extern INT32 ghAttributeBox;
extern INT32 ghRemoveMercAssignBox;
extern INT32 ghContractBox;
extern INT32 ghMoveBox;
//extern INT32 ghUpdateBox;
extern MOUSE_REGION gAssignmentScreenMaskRegion;
extern MOUSE_REGION gAssignmentMenuRegion[ ];
extern MOUSE_REGION gTrainingMenuRegion[ ];
extern MOUSE_REGION gAttributeMenuRegion[ ];
extern MOUSE_REGION gSquadMenuRegion[ ];
extern MOUSE_REGION gContractMenuRegion[ ];
extern MOUSE_REGION gRemoveMercAssignRegion[ ];
extern MOUSE_REGION gVehicleMenuRegion[];
extern BOOLEAN fShownContractMenu;
extern BOOLEAN fShownAssignmentMenu;
extern BOOLEAN fShowRepairMenu;
extern BOOLEAN fFirstClickInAssignmentScreenMask;
extern void RestorePopUpBoxes( void );
extern BOOLEAN fGlowContractRegion;
extern BOOLEAN gfReEvaluateEveryonesNothingToDo;
// pop up menu mouse regions
void CreateDestroyMouseRegionsForAssignmentMenu( void );
void AssignmentMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
void CreateDestroyMouseRegionsForTrainingMenu( void );
void TrainingMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void TrainingMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
void CreateDestroyMouseRegionsForAttributeMenu( void );
void AttributeMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void AttributesMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
void CreateDestroyMouseRegionsForSquadMenu( BOOLEAN fPositionBox );
void SquadMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void SquadMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
// vehicle menu
void CreateDestroyMouseRegionForVehicleMenu( void );
void VehicleMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason );
void VehicleMenuBtnCallback(MOUSE_REGION * pRegion, INT32 iReason );
// repair menu
void CreateDestroyMouseRegionForRepairMenu( void );
void RepairMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason );
void RepairMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
// contract menu
void CreateDestroyMouseRegionsForContractMenu( void );
void ContractMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
void ContractMenuMvtCallback( MOUSE_REGION * pRegion, INT32 iReason );
void RebuildContractBoxForMerc( SOLDIERTYPE *pCharacter );
// remove merc from team menu callback
void RemoveMercMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason );
void RemoveMercMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void CreateDestroyMouseRegionsForRemoveMenu( void );
// misc assignment GUI functions
void HandleShadingOfLinesForAssignmentMenus( void );
BOOLEAN IsCharacterAliveAndConscious( SOLDIERTYPE *pCharacter );
void CreateDestroyScreenMaskForAssignmentAndContractMenus( void );
BOOLEAN CreateDestroyAssignmentPopUpBoxes( void );
void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam1, INT32 iParam2, INT32 iParam3 );
// set merc asleep and awake under the new sleep system implemented June 29, 1998
// if give warning is false, the function can be used as an internal function
BOOLEAN SetMercAwake( SOLDIERTYPE *pSoldier, BOOLEAN fGiveWarning, BOOLEAN fForceHim );
BOOLEAN SetMercAsleep( SOLDIERTYPE *pSoldier, BOOLEAN fGiveWarning );
BOOLEAN PutMercInAsleepState( SOLDIERTYPE *pSoldier );
BOOLEAN PutMercInAwakeState( SOLDIERTYPE *pSoldier );
BOOLEAN AssignMercToAMovementGroup( SOLDIERTYPE *pSoldier );
// set what time this merc undertook this assignment
void SetTimeOfAssignmentChangeForMerc( SOLDIERTYPE *pSoldier );
// enough time on assignment for it to count?
BOOLEAN EnoughTimeOnAssignment( SOLDIERTYPE *pSoldier );
// check if any merc in group is too tired to keep moving
BOOLEAN AnyMercInGroupCantContinueMoving( GROUP *pGroup );
// handle selected group of mercs being put to sleep
BOOLEAN HandleSelectedMercsBeingPutAsleep( BOOLEAN fWakeUp, BOOLEAN fDisplayWarning );
// is any one on the team on this assignment?
BOOLEAN IsAnyOneOnPlayersTeamOnThisAssignment( INT8 bAssignment );
// rebuild assignments box
void RebuildAssignmentsBox( void );
void BandageBleedingDyingPatientsBeingTreated( );
void ReEvaluateEveryonesNothingToDo();
// set assignment for list of characters
void SetAssignmentForList( INT8 bAssignment, INT8 bParam );
// is this area maxed out on militia?
BOOLEAN IsMilitiaTrainableFromSoldiersSectorMaxed( SOLDIERTYPE *pSoldier );
// function where we actually set someone's assignment so we can trap certain situations
void ChangeSoldiersAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment );
void UnEscortEPC( SOLDIERTYPE *pSoldier );
SOLDIERTYPE *AnyDoctorWhoCanHealThisPatient( SOLDIERTYPE *pPatient, BOOLEAN fThisHour );
#endif
File diff suppressed because it is too large Load Diff
+22
View File
@@ -0,0 +1,22 @@
#ifndef __AUTO_RESOLVE_H
#define __AUTO_RESOLVE_H
#include "types.h"
void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY );
// is the autoresolve active?
BOOLEAN IsAutoResolveActive( void );
void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY );
void ConvertTacticalBattleIntoStrategicAutoResolveBattle();
UINT8 GetAutoResolveSectorID();
extern BOOLEAN gfTransferTacticalOppositionToAutoResolve;
//Returns TRUE if autoresolve is active or a sector is loaded.
BOOLEAN GetCurrentBattleSectorXYZ( INT16 *psSectorX, INT16 *psSectorY, INT16 *psSectorZ );
#endif
+373
View File
@@ -0,0 +1,373 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "types.h"
#include "Campaign Init.h"
#include "Random.h"
#include "Campaign Types.h"
#include "Queen Command.h"
#include "overhead.h"
#include "Strategic Movement.h"
#include "Strategic Status.h"
#include "GameSettings.h"
#include "Creature Spreading.h"
#include "Strategic AI.h"
#endif
extern void InitStrategicMovementCosts();
void InitKnowFacilitiesFlags( );
UNDERGROUND_SECTORINFO* gpUndergroundSectorInfoTail = NULL;
UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ )
{
UNDERGROUND_SECTORINFO *curr;
curr = (UNDERGROUND_SECTORINFO*)MemAlloc( sizeof( UNDERGROUND_SECTORINFO ) );
AssertMsg( curr, "Failed to create an underground sector info node." );
memset( curr, 0, sizeof( UNDERGROUND_SECTORINFO ) );
curr->ubSectorX = ubSectorX;
curr->ubSectorY = ubSectorY;
curr->ubSectorZ = ubSectorZ;
if( gpUndergroundSectorInfoTail )
{
gpUndergroundSectorInfoTail->next = curr;
gpUndergroundSectorInfoTail = gpUndergroundSectorInfoTail->next;
}
else
{
gpUndergroundSectorInfoHead = curr;
gpUndergroundSectorInfoTail = gpUndergroundSectorInfoHead;
}
return curr;
}
// setup which know facilities are in which cities
void InitKnowFacilitiesFlags( )
{
SECTORINFO *pSector;
// Cambria hospital
pSector = &SectorInfo[SEC_G8];
pSector->uiFacilitiesFlags |= SFCF_HOSPITAL;
pSector = &SectorInfo[SEC_F8];
pSector->uiFacilitiesFlags |= SFCF_HOSPITAL;
pSector = &SectorInfo[SEC_G9];
pSector->uiFacilitiesFlags |= SFCF_HOSPITAL;
pSector = &SectorInfo[SEC_F9];
pSector->uiFacilitiesFlags |= SFCF_HOSPITAL;
// Drassen airport
pSector = &SectorInfo[SEC_B13];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_C13];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_D13];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
// Meduna airport & military complex
pSector = &SectorInfo[SEC_N3];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_N4];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_N5];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_O3];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
pSector = &SectorInfo[SEC_O4];
pSector->uiFacilitiesFlags |= SFCF_AIRPORT;
return;
}
void InitMiningLocations()
{
SECTORINFO *pSector;
//Set up mining sites
pSector = &SectorInfo[SEC_D4];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 33;
pSector = &SectorInfo[SEC_D13];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 41;
pSector = &SectorInfo[SEC_B2];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 20;
pSector = &SectorInfo[SEC_H8];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 64;
pSector = &SectorInfo[SEC_I14];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 80;
//Grumm
pSector = &SectorInfo[SEC_H3];
pSector->uiFlags |= SF_MINING_SITE;
// pSector->ubIncomeValue = 100;
}
//Mobile groups are handled separately from sectors, because they are on the move.
void GeneratePatrolGroups()
{
GROUP *pGroup;
UINT8 ubNumTroops;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0 );
pGroup->ubTransportationMask = CAR;
AddWaypointToPGroup( pGroup, 8, 3 ); //C8
AddWaypointToPGroup( pGroup, 7, 3 ); //C7
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0 );
AddWaypointToPGroup( pGroup, 9, 5 ); //E9
AddWaypointToPGroup( pGroup, 9, 4 ); //D9
pGroup->ubTransportationMask = TRUCK;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0 );
AddWaypointToPGroup( pGroup, 12, 2 ); //B12
AddWaypointToPGroup( pGroup, 9, 2 ); //B9
pGroup->ubTransportationMask = FOOT;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0 );
pGroup->ubMoveType = ENDTOEND_FORWARDS;
AddWaypointToPGroup( pGroup, 13, 1 ); //A13
AddWaypointToPGroup( pGroup, 15, 1 ); //A15
AddWaypointToPGroup( pGroup, 15, 5 ); //E15
AddWaypointToPGroup( pGroup, 13, 5 ); //E13
AddWaypointToPGroup( pGroup, 12, 5 ); //E12
AddWaypointToPGroup( pGroup, 12, 3 ); //C12
pGroup->ubTransportationMask = TRACKED;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0 );
AddWaypointToPGroup( pGroup, 9, 14 ); //N9
AddWaypointToPGroup( pGroup, 6, 14 ); //N6
pGroup->ubTransportationMask = CAR;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0 );
AddWaypointToPGroup( pGroup, 10, 11 ); //K10
AddWaypointToPGroup( pGroup, 10, 14 ); //N10
pGroup->ubTransportationMask = CAR;
}
void TrashUndergroundSectorInfo()
{
UNDERGROUND_SECTORINFO *curr;
while( gpUndergroundSectorInfoHead )
{
curr = gpUndergroundSectorInfoHead;
gpUndergroundSectorInfoHead = gpUndergroundSectorInfoHead->next;
MemFree( curr );
}
gpUndergroundSectorInfoHead = NULL;
gpUndergroundSectorInfoTail = NULL;
}
//Defines the sectors that can be occupied by enemies, creatures, etc. It also
//contains the network of cave connections critical for strategic creature spreading, as we can't
//know how the levels connect without loading the maps. This is completely hardcoded, and any
//changes to the maps, require changes accordingly.
void BuildUndergroundSectorInfoList()
{
UNDERGROUND_SECTORINFO *curr;
SECTORINFO *pSector = NULL;
TrashUndergroundSectorInfo();
//********************
//* BASEMENT LEVEL 1 *
//********************
//Miguel's basement. Nothing here.
curr = NewUndergroundNode( 10, 1, 1 );
//Chitzena mine. Nothing here.
curr = NewUndergroundNode( 2, 2, 1 );
//San mona mine. Nothing here.
curr = NewUndergroundNode( 4, 4, 1 );
curr = NewUndergroundNode( 5, 4, 1 );
//J9
curr = NewUndergroundNode( 9, 10, 1 );
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
curr->ubNumTroops = 8;
break;
case DIF_LEVEL_MEDIUM:
curr->ubNumTroops = 11;
break;
case DIF_LEVEL_HARD:
curr->ubNumTroops = 15;
break;
case DIF_LEVEL_INSANE:
curr->ubNumTroops = 20;
break;
}
//J9 feeding zone
curr = NewUndergroundNode( 9, 10, 2 );
curr->ubNumCreatures = (UINT8)(2 + gGameOptions.ubDifficultyLevel*2 + Random( 2 ));
//K4
curr = NewUndergroundNode( 4, 11, 1 );
curr->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + gGameOptions.ubDifficultyLevel + Random( 2 ));
//O3
curr = NewUndergroundNode( 3, 15, 1 );
curr->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + gGameOptions.ubDifficultyLevel + Random( 2 ));
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//P3
curr = NewUndergroundNode( 3, 16, 1 );
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
curr->ubNumElites = (UINT8)(8 + Random( 3 ));
break;
case DIF_LEVEL_MEDIUM:
curr->ubNumElites = (UINT8)(10 + Random( 5 ));
break;
case DIF_LEVEL_HARD:
curr->ubNumElites = (UINT8)(14 + Random( 6 ));
break;
case DIF_LEVEL_INSANE:
curr->ubNumElites = 20;
break;
}
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//Do all of the mandatory underground mine sectors
//Drassen's mine
//D13_B1
curr = NewUndergroundNode( 13, 4, 1 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//E13_B1
curr = NewUndergroundNode( 13, 5, 1 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//E13_B2
curr = NewUndergroundNode( 13, 5, 2 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//F13_B2
curr = NewUndergroundNode( 13, 6, 2 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR | SOUTH_ADJACENT_SECTOR;
//G13_B2
curr = NewUndergroundNode( 13, 7, 2 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//G13_B3
curr = NewUndergroundNode( 13, 7, 3 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//F13_B3
curr = NewUndergroundNode( 13, 6, 3 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//Cambria's mine
//H8_B1
curr = NewUndergroundNode( 8, 8, 1 );
curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR;
//H9_B1
curr = NewUndergroundNode( 9, 8, 1 );
curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR;
//H9_B2
curr = NewUndergroundNode( 9, 8, 2 );
curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR;
//H8_B2
curr = NewUndergroundNode( 8, 8, 2 );
curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR;
//H8_B3
curr = NewUndergroundNode( 8, 8, 3 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//I8_B3
curr = NewUndergroundNode( 8, 9, 3 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR | SOUTH_ADJACENT_SECTOR;
//J8_B3
curr = NewUndergroundNode( 8, 10, 3 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//Alma's mine
//I14_B1
curr = NewUndergroundNode( 14, 9, 1 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//J14_B1
curr = NewUndergroundNode( 14, 10, 1 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//J14_B2
curr = NewUndergroundNode( 14, 10, 2 );
curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR;
//J13_B2
curr = NewUndergroundNode( 13, 10, 2 );
curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR;
//J13_B3
curr = NewUndergroundNode( 13, 10, 3 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//K13_B3
curr = NewUndergroundNode( 13, 11, 3 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//Grumm's mine
//H3_B1
curr = NewUndergroundNode( 3, 8, 1 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
//I3_B1
curr = NewUndergroundNode( 3, 9, 1 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//I3_B2
curr = NewUndergroundNode( 3, 9, 2 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//H3_B2
curr = NewUndergroundNode( 3, 8, 2 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR | EAST_ADJACENT_SECTOR;
//H4_B2
curr = NewUndergroundNode( 4, 8, 2 );
curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR;
curr->uiFlags |= SF_PENDING_ALTERNATE_MAP;
//H4_B3
curr = NewUndergroundNode( 4, 8, 3 );
curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR;
//G4_B3
curr = NewUndergroundNode( 4, 7, 3 );
curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR;
}
//This is the function that is called only once, when the player begins a new game. This will calculate
//starting numbers of the queen's army in various parts of the map, which will vary from campaign to campaign.
//This is also highly effected by the game's difficulty setting.
void InitNewCampaign()
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewCampaign");
//First clear all the sector information of all enemy existance. Conveniently, the
//ubGroupType is also cleared, which is perceived to be an empty group.
memset( &SectorInfo, 0, sizeof( SECTORINFO ) * 256 );
InitStrategicMovementCosts();
RemoveAllGroups();
InitMiningLocations();
InitKnowFacilitiesFlags( );
BuildUndergroundSectorInfoList();
// allow overhead view of omerta A9 on game onset
SetSectorFlag( 9, 1, 0, SF_ALREADY_VISITED );
//Generates the initial forces in a new campaign. The idea is to randomize numbers and sectors
//so that no two games are the same.
InitStrategicAI();
InitStrategicStatus();
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewCampaign done");
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef __CAMPAIGN_INIT_H
#define __CAMPAIGN_INIT_H
extern void InitNewCampaign();
extern void BuildUndergroundSectorInfoList();
extern void TrashUndergroundSectorInfo();
#endif
+270
View File
@@ -0,0 +1,270 @@
#ifndef __CAMPAIGN_TYPES_H
#define __CAMPAIGN_TYPES_H
#include "types.h"
//Macro to convert sector coordinates (1-16,1-16) to 0-255
#define SECTOR(x,y) ((y-1)*16+x-1)
#define SECTORX(SectorID) ((SectorID % 16) + 1)
#define SECTORY(SectorID) ((SectorID / 16) + 1)
//Sector enumerations
//
//NOTE: These use the 0-255 SectorInfo[] numbering system, and CAN'T be used as indexes into the StrategicMap[] array
//Use SECTOR_INFO_TO_STRATEGIC_INDEX() macro to convert...
enum
{
SEC_A1, SEC_A2, SEC_A3, SEC_A4, SEC_A5, SEC_A6, SEC_A7, SEC_A8, SEC_A9, SEC_A10, SEC_A11, SEC_A12, SEC_A13, SEC_A14, SEC_A15, SEC_A16,
SEC_B1, SEC_B2, SEC_B3, SEC_B4, SEC_B5, SEC_B6, SEC_B7, SEC_B8, SEC_B9, SEC_B10, SEC_B11, SEC_B12, SEC_B13, SEC_B14, SEC_B15, SEC_B16,
SEC_C1, SEC_C2, SEC_C3, SEC_C4, SEC_C5, SEC_C6, SEC_C7, SEC_C8, SEC_C9, SEC_C10, SEC_C11, SEC_C12, SEC_C13, SEC_C14, SEC_C15, SEC_C16,
SEC_D1, SEC_D2, SEC_D3, SEC_D4, SEC_D5, SEC_D6, SEC_D7, SEC_D8, SEC_D9, SEC_D10, SEC_D11, SEC_D12, SEC_D13, SEC_D14, SEC_D15, SEC_D16,
SEC_E1, SEC_E2, SEC_E3, SEC_E4, SEC_E5, SEC_E6, SEC_E7, SEC_E8, SEC_E9, SEC_E10, SEC_E11, SEC_E12, SEC_E13, SEC_E14, SEC_E15, SEC_E16,
SEC_F1, SEC_F2, SEC_F3, SEC_F4, SEC_F5, SEC_F6, SEC_F7, SEC_F8, SEC_F9, SEC_F10, SEC_F11, SEC_F12, SEC_F13, SEC_F14, SEC_F15, SEC_F16,
SEC_G1, SEC_G2, SEC_G3, SEC_G4, SEC_G5, SEC_G6, SEC_G7, SEC_G8, SEC_G9, SEC_G10, SEC_G11, SEC_G12, SEC_G13, SEC_G14, SEC_G15, SEC_G16,
SEC_H1, SEC_H2, SEC_H3, SEC_H4, SEC_H5, SEC_H6, SEC_H7, SEC_H8, SEC_H9, SEC_H10, SEC_H11, SEC_H12, SEC_H13, SEC_H14, SEC_H15, SEC_H16,
SEC_I1, SEC_I2, SEC_I3, SEC_I4, SEC_I5, SEC_I6, SEC_I7, SEC_I8, SEC_I9, SEC_I10, SEC_I11, SEC_I12, SEC_I13, SEC_I14, SEC_I15, SEC_I16,
SEC_J1, SEC_J2, SEC_J3, SEC_J4, SEC_J5, SEC_J6, SEC_J7, SEC_J8, SEC_J9, SEC_J10, SEC_J11, SEC_J12, SEC_J13, SEC_J14, SEC_J15, SEC_J16,
SEC_K1, SEC_K2, SEC_K3, SEC_K4, SEC_K5, SEC_K6, SEC_K7, SEC_K8, SEC_K9, SEC_K10, SEC_K11, SEC_K12, SEC_K13, SEC_K14, SEC_K15, SEC_K16,
SEC_L1, SEC_L2, SEC_L3, SEC_L4, SEC_L5, SEC_L6, SEC_L7, SEC_L8, SEC_L9, SEC_L10, SEC_L11, SEC_L12, SEC_L13, SEC_L14, SEC_L15, SEC_L16,
SEC_M1, SEC_M2, SEC_M3, SEC_M4, SEC_M5, SEC_M6, SEC_M7, SEC_M8, SEC_M9, SEC_M10, SEC_M11, SEC_M12, SEC_M13, SEC_M14, SEC_M15, SEC_M16,
SEC_N1, SEC_N2, SEC_N3, SEC_N4, SEC_N5, SEC_N6, SEC_N7, SEC_N8, SEC_N9, SEC_N10, SEC_N11, SEC_N12, SEC_N13, SEC_N14, SEC_N15, SEC_N16,
SEC_O1, SEC_O2, SEC_O3, SEC_O4, SEC_O5, SEC_O6, SEC_O7, SEC_O8, SEC_O9, SEC_O10, SEC_O11, SEC_O12, SEC_O13, SEC_O14, SEC_O15, SEC_O16,
SEC_P1, SEC_P2, SEC_P3, SEC_P4, SEC_P5, SEC_P6, SEC_P7, SEC_P8, SEC_P9, SEC_P10, SEC_P11, SEC_P12, SEC_P13, SEC_P14, SEC_P15, SEC_P16
};
enum //group types
{
NOGROUP,
MOBILE,
DEFENCE
};
enum //strategic values for each sector
{
NO_VALUE,
LOW_VALUE,
FAIR_VALUE,
AVG_VALUE,
GOOD_VALUE,
HI_VALUE,
GREAT_VALUE
};
//Various flag definitions
#define SF_USE_MAP_SETTINGS 0x00000001
#define SF_ENEMY_AMBUSH_LOCATION 0x00000002
//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.
#define SF_PLAYER_KNOWS_ENEMIES_ARE_HERE 0x00000004
#define SF_SAM_SITE 0x00000008
#define SF_MINING_SITE 0x00000010
#define SF_ALREADY_VISITED 0x00000020
#define SF_USE_ALTERNATE_MAP 0x00000040
#define SF_PENDING_ALTERNATE_MAP 0x00000080
#define SF_ALREADY_LOADED 0x00000100
#define SF_HAS_ENTERED_TACTICAL 0x00000200
#define SF_SKYRIDER_NOTICED_ENEMIES_HERE 0x00000400
#define SF_HAVE_USED_GUIDE_QUOTE 0x00000800
#define SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS 0x00100000 //Temp File starts with sm_
#define SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS 0x00200000 //Temp File starts with l_
#define SF_REVEALED_STATUS_TEMP_FILE_EXISTS 0x01000000 //Temp File starts with v_
#define SF_DOOR_STATUS_TEMP_FILE_EXISTS 0x02000000 //Temp File starts with ds_
#define SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS 0x04000000 //Temp File starts with e_
#define SF_CIV_PRESERVED_TEMP_FILE_EXISTS 0x08000000 //Temp File starts with c_
#define SF_ITEM_TEMP_FILE_EXISTS 0x10000000 //Temp File starts with i_
#define SF_ROTTING_CORPSE_TEMP_FILE_EXISTS 0x20000000 //Temp File starts with r_
#define SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS 0x40000000 //Temp File starts with m_
#define SF_DOOR_TABLE_TEMP_FILES_EXISTS 0x80000000 //Temp File starts with d_
// town militia experience categories
enum
{
GREEN_MILITIA = 0,
REGULAR_MILITIA,
ELITE_MILITIA,
MAX_MILITIA_LEVELS
};
// 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
// coordinates of shooting range sector
#define GUN_RANGE_X 13
#define GUN_RANGE_Y MAP_ROW_H
#define GUN_RANGE_Z 0
//Vehicle types
#define FOOT 0x01 //anywhere
#define CAR 0x02 //roads
#define TRUCK 0x04 //roads, plains, sparse
#define TRACKED 0x08 //roads, plains, sand, sparse
#define AIR 0x10 //can traverse all terrains at 100%
//Traversability ratings
enum
{
TOWN, //instant
ROAD, //everything travels at 100%
PLAINS, //foot 90%, truck 75%, tracked 100%
SAND, //foot 70%, tracked 60%
SPARSE, //foot 70%, truck 50%, tracked 60%
DENSE, //foot 50%
SWAMP, //foot 20%
WATER, //foot 15%
HILLS, //foot 50%, truck 50%, tracked 50%
GROUNDBARRIER,//only air (super dense forest, ocean, etc.)
NS_RIVER, //river from north to south
EW_RIVER, //river from east to west
EDGEOFWORLD, //nobody can traverse.
//NEW (not used for border values -- traversal calculations)
TROPICS,
FARMLAND,
PLAINS_ROAD,
SPARSE_ROAD,
FARMLAND_ROAD,
TROPICS_ROAD,
DENSE_ROAD,
COASTAL,
HILLS_ROAD,
COASTAL_ROAD,
SAND_ROAD,
SWAMP_ROAD,
//only used for text purposes and not assigned to areas (SAM sites are hard coded throughout the code)
SPARSE_SAM_SITE, //D15 near Drassen
SAND_SAM_SITE, //I8 near Tixa
TROPICS_SAM_SITE, //D2 near Chitzena
MEDUNA_SAM_SITE, //N4 in Meduna
CAMBRIA_HOSPITAL_SITE,
DRASSEN_AIRPORT_SITE,
MEDUNA_AIRPORT_SITE,
SAM_SITE,
REBEL_HIDEOUT,
TIXA_DUNGEON,
CREATURE_LAIR,
ORTA_BASEMENT,
TUNNEL,
SHELTER,
ABANDONED_MINE,
NUM_TRAVTERRAIN_TYPES
};
extern UINT8 gszTerrain[NUM_TRAVTERRAIN_TYPES][15];
#define TRAVELRATING_NONE 0
#define TRAVELRATING_LOW 25
#define TRAVELRATING_NORMAL 50
#define TRAVELRATING_HIGH 75
#define TRAVELRATING_EXTREME 100
//Used by ubGarrisonID when a sector doesn't point to a garrison. Used by strategic AI only.
#define NO_GARRISON 255
typedef struct SECTORINFO
{
//information pertaining to this sector
UINT32 uiFlags; //various special conditions
UINT8 ubInvestigativeState; //When the sector is attacked by the player, the state increases by 1 permanently.
//This value determines how quickly it is investigated by the enemy.
UINT8 ubGarrisonID; //IF the sector has an ID for this (non 255), then the queen values this sector and it
//indexes the garrison group.
INT8 ubPendingReinforcements; //when the enemy owns this sector, this value will keep track of HIGH priority reinforcements -- not regular.
BOOLEAN fMilitiaTrainingPaid;
UINT8 ubMilitiaTrainingPercentDone;
UINT8 ubMilitiaTrainingHundredths;
//enemy military presence
BOOLEAN fPlayer[ 4 ]; //whether the player THINKS the sector is unde his control or not. array is for sublevels
//enemy only info
UINT8 ubNumTroops; //the actual number of troops here.
UINT8 ubNumElites; //the actual number of elites here.
UINT8 ubNumAdmins; //the actual number of admins here.
UINT8 ubNumCreatures; //only set when immediately before ground attack made!
UINT8 ubTroopsInBattle, ubElitesInBattle, ubAdminsInBattle, ubCreaturesInBattle;
INT8 bLastKnownEnemies; // -1 means never been there, no idea, otherwise it's what we'd observed most recently
// while this is being maintained (partially, surely buggy), nothing uses it anymore. ARM
UINT32 ubDayOfLastCreatureAttack;
UINT32 uiFacilitiesFlags; // the flags for various facilities
UINT8 ubTraversability[5];//determines the traversability ratings to adjacent sectors.
//The last index represents the traversability if travelling
//throught the sector without entering it.
INT8 bNameId;
INT8 bUSUSED;
INT8 bBloodCats;
INT8 bBloodCatPlacements;
INT8 UNUSEDbSAMCondition;
UINT8 ubTravelRating; //Represents how travelled a sector is. Typically, the higher the travel rating,
//the more people go near it. A travel rating of 0 means there are never people
//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)
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;
UINT8 bFiller2;
UINT8 bFiller3;
UINT32 uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer;
INT8 bPadding[ 41 ];
}SECTORINFO;
#define NO_ADJACENT_SECTOR 0x00
#define NORTH_ADJACENT_SECTOR 0x01
#define EAST_ADJACENT_SECTOR 0x02
#define SOUTH_ADJACENT_SECTOR 0x04
#define WEST_ADJACENT_SECTOR 0x08
typedef struct UNDERGROUND_SECTORINFO
{
UINT32 uiFlags;
UINT8 ubSectorX, ubSectorY, ubSectorZ;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumCreatures;
UINT8 fVisited;
INT8 ubTravelRating; //Represents how travelled a sector is. Typically, the higher the travel rating,
//the more people go near it. A travel rating of 0 means there are never people
//around. This value is used for determining how often items would "vanish" from
//a sector.
UINT32 uiTimeCurrentSectorWasLastLoaded; //Specifies the last time the player was in the sector
struct UNDERGROUND_SECTORINFO *next;
UINT8 ubAdjacentSectors; //mask containing which sectors are adjacent
UINT8 ubCreatureHabitat; //determines how creatures live in this sector (see creature spreading.c)
UINT8 ubElitesInBattle, ubTroopsInBattle, ubAdminsInBattle, ubCreaturesInBattle;
UINT32 uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer;
INT8 bPadding[36];
//no padding left!
}UNDERGROUND_SECTORINFO;
//The sector information required for the strategic AI. Contains the number of enemy troops,
//as well as intentions, etc.
extern SECTORINFO SectorInfo[256];
extern UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead;
#endif
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
#ifndef __CREATURE_SPREADING_H
#define __CREATURE_SPREADING_H
void InitCreatureQuest();
void SpreadCreatures();
void DecayCreatures();
void ChooseCreatureQuestStartDay();
void ClearCreatureQuest();
void DeleteCreatureDirectives();
BOOLEAN SaveCreatureDirectives( HWFILE hFile );
BOOLEAN LoadCreatureDirectives( HWFILE hFile, UINT32 uiSavedGameVersion );
UINT8 CreaturesInUndergroundSector( UINT8 ubSectorID, UINT8 ubSectorZ );
BOOLEAN PrepareCreaturesForBattle();
void CreatureNightPlanning();
void CreatureAttackTown( UINT8 ubSectorID, BOOLEAN fOverrideTest );
void CheckConditionsForTriggeringCreatureQuest( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void ForceCreaturesToAvoidMineTemporarily( UINT8 ubMineIndex );
extern BOOLEAN gfUseCreatureMusic;
BOOLEAN MineClearOfMonsters( UINT8 ubMineIndex );
//Returns TRUE if valid and creature quest over, FALSE if creature quest active or not yet started
BOOLEAN GetWarpOutOfMineCodes( INT16 *psSectorX, INT16 *psSectorY, INT8 *pbSectorZ, INT16 *psInsertionGridNo );
extern INT16 gsCreatureInsertionCode;
extern INT16 gsCreatureInsertionGridNo;
extern UINT8 gubNumCreaturesAttackingTown;
extern UINT8 gubYoungMalesAttackingTown;
extern UINT8 gubYoungFemalesAttackingTown;
extern UINT8 gubAdultMalesAttackingTown;
extern UINT8 gubAdultFemalesAttackingTown;
extern UINT8 gubSectorIDOfCreatureAttack;
enum{
CREATURE_BATTLE_CODE_NONE,
CREATURE_BATTLE_CODE_TACTICALLYADD,
CREATURE_BATTLE_CODE_TACTICALLYADD_WITHFOV,
CREATURE_BATTLE_CODE_PREBATTLEINTERFACE,
CREATURE_BATTLE_CODE_AUTORESOLVE,
};
extern UINT8 gubCreatureBattleCode;
void DetermineCreatureTownComposition( UINT8 ubNumCreatures,
UINT8 *pubNumYoungMales, UINT8 *pubNumYoungFemales,
UINT8 *pubNumAdultMales, UINT8 *pubNumAdultFemales );
void DetermineCreatureTownCompositionBasedOnTacticalInformation( UINT8 *pubNumCreatures,
UINT8 *pubNumYoungMales, UINT8 *pubNumYoungFemales,
UINT8 *pubNumAdultMales, UINT8 *pubNumAdultFemales );
BOOLEAN PlayerGroupIsInACreatureInfestedMine();
#endif
File diff suppressed because it is too large Load Diff
+204
View File
@@ -0,0 +1,204 @@
#ifndef __WORLD_CLOCK
#define __WORLD_CLOCK
#include "FileMan.h"
// where the time string itself is rendered
#define CLOCK_X 554
#define CLOCK_Y 459
// the mouse region around the clock (bigger)
#define CLOCK_REGION_START_X 552
#define CLOCK_REGION_START_Y 456
#define CLOCK_REGION_WIDTH ( 620 - CLOCK_REGION_START_X )
#define CLOCK_REGION_HEIGHT ( 468 - CLOCK_REGION_START_Y )
#define NUM_SEC_IN_DAY 86400
#define NUM_SEC_IN_HOUR 3600
#define NUM_SEC_IN_MIN 60
#define ROUNDTO_MIN 5
#define NUM_MIN_IN_DAY 1440
#define NUM_MIN_IN_HOUR 60
//Kris:
//This is the plan for game time...
//Game time should be restricted to outside code. Think of it as encapsulation. Anyway, using these
//simple functions, you will be able to change the amount of time that passes per frame. The gameloop will
//automatically update the clock once per cycle, regardless of the mode you are in.
//This does pose potential problems in modes such as the editor, or similar where time shouldn't pass, and
//isn't currently handled. The best thing to do in these cases is call the PauseGame() function when entering
//such a mode, and UnPauseGame() when finished. Everything will be restored just the way you left it. This
//is much simpler to handle in the overall scheme of things.
//PAUSE FEATURES
//Pauses and unpauses the game. It sets and clears a flag which preserves the time rate.
extern void PauseGame();
extern void UnPauseGame();
extern void TogglePause();
extern BOOLEAN GamePaused();
extern void LockPauseState( UINT32 uiUniqueReasonId );
extern void UnLockPauseState();
extern BOOLEAN PauseStateLocked();
//USING HIGH RESOLUTION TIME RATE MANIPULATION/ACCESS
//Allows external code to change the time rate.
void SetGameHoursPerSecond( UINT32 uiGameHoursPerSecond );
void SetGameMinutesPerSecond( UINT32 uiGameMinutesPerSecond );
void SetGameSecondsPerSecond( UINT32 uiGameSecondsPerSecond );
//Allows access to the current time rate.
UINT32 GetGameSecondsPerFrame();
void RenderPausedGameBox( void );
void StopTimeCompression( void );
void StartTimeCompression( void );
BOOLEAN IsTimeBeingCompressed( void ); // returns FALSE if time isn't currently being compressed for ANY reason (various pauses, etc.)
BOOLEAN IsTimeCompressionOn( void ); // returns TRUE if the player currently wants time to be compressing
//USING TIME COMPRESSION
//Allows the setting/changing/access of time rate via predefined compression values.
//These functions change the index in giTimeCompressSpeeds which aren't in any
//particular mathematical pattern. The higher the index, the faster the time is processed
//per frame. These functions have their limits, so game time will also be between
//TIME_COMPRESS_X1 to TIME_COMPRESS_X8 based in the laptop time compression.
void SetGameTimeCompressionLevel( UINT32 uiCompressionRate );
void DecreaseGameTimeCompressionRate();
void IncreaseGameTimeCompressionRate();
//USING CLOCK RESOLUTION
//Note, that changing the clock resolution doesn't effect the amount of game time that passes per
//real second, but how many times per second the clock is updated. This rate will break up the actual
//time slices per second into smaller chunks. This is useful for animating strategic movement under
//fast time compression, so objects don't warp around.
void SetClockResolutionToDefault(); //1 time per second
//Valid range is 1 - 60 times per second.
void SetClockResolutionPerSecond( UINT8 ubNumTimesPerSecond );
//Function for accessing the current rate
UINT8 ClockResolution();
//time compression defines
enum
{
NOT_USING_TIME_COMPRESSION = -1,
TIME_COMPRESS_X0,
TIME_COMPRESS_X1,
TIME_COMPRESS_5MINS,
TIME_COMPRESS_30MINS,
TIME_COMPRESS_60MINS,
TIME_SUPER_COMPRESS,
NUM_TIME_COMPRESS_SPEEDS
};
//dereferenced with the above enumerations to provide the actual time compression rate.
extern INT32 giTimeCompressSpeeds[ NUM_TIME_COMPRESS_SPEEDS ];
#define STARTING_TIME ( ( 1 * NUM_SEC_IN_HOUR ) + ( 0 * NUM_SEC_IN_MIN ) + NUM_SEC_IN_DAY ) // 1am
#define FIRST_ARRIVAL_DELAY ( ( 6 * NUM_SEC_IN_HOUR ) + ( 0 * NUM_SEC_IN_MIN ) ) // 7am ( 6hours later)
#define WORLDTIMESTR gswzWorldTimeStr
// compress mode now in use
extern INT32 giTimeCompressMode;
enum
{
WARPTIME_NO_PROCESSING_OF_EVENTS,
WARPTIME_PROCESS_EVENTS_NORMALLY,
WARPTIME_PROCESS_TARGET_TIME_FIRST,
};
void WarpGameTime( UINT32 uiAdjustment, UINT8 ubWarpCode );
void AdvanceToNextDay();
//This function is called once per cycle in the game loop. This determine how often the clock should be
//as well as how much to update the clock by.
void UpdateClock();
extern UINT16 gswzWorldTimeStr[ 20 ]; //Day 99, 23:55
extern UINT32 guiDay;
extern UINT32 guiHour;
extern UINT32 guiMin;
//Advanced function used by certain event callbacks. In the case where time is warped, certain event
//need to know how much time was warped since the last query to the event list.
//This function returns that value
extern UINT32 guiTimeOfLastEventQuery;
//This value represents the time that the sector was loaded. If you are in sector A9, and leave
//the game clock at that moment will get saved into the temp file associated with it. The next time you
//enter A9, this value will contain that time. Used for scheduling purposes.
extern UINT32 guiTimeCurrentSectorWasLastLoaded;
// is the current pause state due to the player?
extern BOOLEAN gfPauseDueToPlayerGamePause;
// we've just clued up a pause by the player, the tactical screen will need a full one shot refresh to remove a 2 frame update problem
extern BOOLEAN gfJustFinishedAPause;
extern BOOLEAN gfResetAllPlayerKnowsEnemiesFlags;
extern UINT32 guiLockPauseStateLastReasonId;
UINT32 GetWorldTotalMin( );
UINT32 GetWorldTotalSeconds( );
UINT32 GetWorldHour( );
UINT32 GetWorldDay( );
UINT32 GetWorldMinutesInDay( );
UINT32 GetWorldDayInSeconds( );
UINT32 GetWorldDayInMinutes( );
UINT32 GetFutureDayInMinutes( UINT32 uiDay );
UINT32 GetMidnightOfFutureDayInMinutes( UINT32 uiDay );
BOOLEAN DayTime();
BOOLEAN NightTime();
void InitNewGameClock( );
void GotoNextTimeOfDay( UINT32 uiTOD );
void RenderClock( INT16 sX, INT16 sY );
void ToggleSuperCompression();
//IMPORTANT FUNCTION: Used whenever an event or situation is deemed important enough to cancel the
//further processing of time in this current time slice! This can only be used inside of event callback
//functions -- otherwise, it'll be ignored and automatically reset. An example of this would be when arriving
//in a new sector and being prompted to attack or retreat.
void InterruptTime();
void PauseTimeForInterupt();
extern BOOLEAN gfTimeInterrupt;
BOOLEAN DidGameJustStart();
BOOLEAN SaveGameClock( HWFILE hFile, BOOLEAN fGamePaused, BOOLEAN fLockPauseState );
BOOLEAN LoadGameClock( HWFILE hFile );
// time compress flag stuff
BOOLEAN HasTimeCompressOccured( void );
void ResetTimeCompressHasOccured( void );
void SetFactTimeCompressHasOccured( void );
// create mouse region to pause game
void CreateMouseRegionForPauseOfClock( INT16 sX, INT16 sY );
// remove mouse region for pause game
void RemoveMouseRegionForPauseOfClock( void );
// handle pausing and unpausing of game
void HandlePlayerPauseUnPauseOfGame( void );
void ClearTacticalStuffDueToTimeCompression( void );
#endif
+472
View File
@@ -0,0 +1,472 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#include "InIReader.h"
#else
#include "types.h"
#include "Game Events.h"
#include "soundman.h"
#include "environment.h"
#include "Ambient Control.h"
#include "Quests.h"
#include "Sound Control.h"
#include "AimMembers.h"
#include "Strategic Event Handler.h"
#include "BobbyR.h"
#include "mercs.h"
#include "email.h"
#include "Game Clock.h"
#include "Merc Hiring.h"
#include "Insurance Contract.h"
#include "Strategic Merc Handler.h"
#include "Strategic Movement.h"
#include "Assignments.h"
#include "Strategic Mines.h"
#include "Strategic Town Loyalty.h"
#include "Message.h"
#include "Map Screen Interface.h"
#include "Map Screen Helicopter.h"
#include "Scheduling.h"
#include "BobbyRGuns.h"
#include "Arms Dealer Init.h"
#include "Strategic town reputation.h"
#include "air raid.h"
#include "meanwhile.h"
#include "overhead.h"
#include "random.h"
#include "Creature Spreading.h"
#include "Strategic AI.h"
#include "Merc Contract.h"
#include "Strategic Status.h"
#endif
#ifdef JA2BETAVERSION
extern BOOLEAN gfMercsNeverQuit;
#endif
extern void ValidateGameEvents();
extern void HandleHourlyUpdate();
extern void HandleQuarterHourUpdate();
extern void HandleMinuteUpdate();
extern BOOLEAN gfProcessingGameEvents;
extern UINT32 guiTimeStampOfCurrentlyExecutingEvent;
extern BOOLEAN gfPreventDeletionOfAnyEvent;
#ifdef CRIPPLED_VERSION
void CrippledVersionEndGameCheckCallBack( UINT8 bExitValue );
void CrippledVersionEndGameCheck();
#endif
BOOLEAN DelayEventIfBattleInProgress( STRATEGICEVENT *pEvent )
{
STRATEGICEVENT *pNewEvent;
if( gTacticalStatus.fEnemyInSector )
{
pNewEvent = AddAdvancedStrategicEvent( pEvent->ubEventType, pEvent->ubCallbackID, pEvent->uiTimeStamp + 180 + Random( 121 ), pEvent->uiParam );
Assert( pNewEvent );
pNewEvent->uiTimeOffset = pEvent->uiTimeOffset;
return TRUE;
}
return FALSE;
}
BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
{
BOOLEAN bMercDayOne = FALSE;
// Kaiden: Opening the INI File
CIniReader iniReader("..\\Ja2_Options.ini");
//Kaiden: Getting Value for MERC Available on Day one?
bMercDayOne = iniReader.ReadBoolean("Options","MERC_DAY_ONE",FALSE);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ExecuteStrategicEvent");
BOOLEAN fOrigPreventFlag;
fOrigPreventFlag = gfPreventDeletionOfAnyEvent;
gfPreventDeletionOfAnyEvent = TRUE;
//No events can be posted before this time when gfProcessingGameEvents is set, otherwise,
//we have a chance of running into an infinite loop.
guiTimeStampOfCurrentlyExecutingEvent = pEvent->uiTimeStamp;
if( pEvent->ubFlags & SEF_DELETION_PENDING)
{
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
return FALSE;
}
#ifdef JA2BETAVERSION
//If we are currently in the AIViewer, only process the events that we want to process.
//The rest of the events will be delayed until AFTER we leave the viewer.
if( guiCurrentScreen == AIVIEWER_SCREEN )
{
if( pEvent->ubCallbackID != EVENT_BEGIN_CREATURE_QUEST &&
pEvent->ubCallbackID != EVENT_CREATURE_SPREAD &&
pEvent->ubCallbackID != EVENT_DELAYED_HIRING_OF_MERC &&
pEvent->ubCallbackID != EVENT_GROUP_ARRIVAL &&
pEvent->ubCallbackID != EVENT_EVALUATE_QUEEN_SITUATION &&
pEvent->ubCallbackID != EVENT_CHECK_ENEMY_CONTROLLED_SECTOR )
{
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
return FALSE;
}
}
#endif
#ifdef JA2BETAVERSION
if( gfMercsNeverQuit )
{
if( pEvent->ubCallbackID == EVENT_MERC_ABOUT_TO_LEAVE_COMMENT ||
pEvent->ubCallbackID == EVENT_MERC_CONTRACT_OVER )
{
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
return FALSE;
}
}
#endif
// Look at the ID of event and do stuff according to that!
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("ExecuteStrategicEvent: event callback id = %d", pEvent->ubCallbackID));
switch( pEvent->ubCallbackID )
{
case EVENT_CHANGELIGHTVAL:
// Change light to value
gubEnvLightValue = (UINT8)pEvent->uiParam;
if( !gfBasement && !gfCaves )
gfDoLighting = TRUE;
break;
case EVENT_CHECKFORQUESTS:
CheckForQuests( GetWorldDay() );
break;
case EVENT_AMBIENT:
if( pEvent->ubEventType == ENDRANGED_EVENT )
{
if ( pEvent->uiParam != NO_SAMPLE )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ExecuteStrategicEvent: SoundRemoveSampleFlags");
SoundRemoveSampleFlags( pEvent->uiParam, SAMPLE_RANDOM );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ExecuteStrategicEvent: SoundRemoveSampleFlags done");
}
}
else
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ExecuteStrategicEvent: SetupNewAmbientSound");
pEvent->uiParam = SetupNewAmbientSound( pEvent->uiParam );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ExecuteStrategicEvent: SetupNewAmbientSound done");
}
break;
case EVENT_AIM_RESET_MERC_ANNOYANCE:
ResetMercAnnoyanceAtPlayer( (UINT8) pEvent->uiParam );
break;
//The players purchase from Bobby Ray has arrived
case EVENT_BOBBYRAY_PURCHASE:
BobbyRayPurchaseEventCallback( (UINT8) pEvent->uiParam);
break;
//Gets called once a day ( at BOBBYRAY_UPDATE_TIME). To simulate the items being bought and sold at bobby rays
case EVENT_DAILY_UPDATE_BOBBY_RAY_INVENTORY:
DailyUpdateOfBobbyRaysNewInventory();
DailyUpdateOfBobbyRaysUsedInventory();
DailyUpdateOfArmsDealersInventory();
break;
//Add items to BobbyR's new/used inventory
case EVENT_UPDATE_BOBBY_RAY_INVENTORY:
AddFreshBobbyRayInventory( (UINT16) pEvent->uiParam );
break;
//Called once a day to update the number of days that a hired merc from M.E.R.C. has been on contract.
// Also if the player hasn't paid for a while Specks will start sending e-mails to the player
case EVENT_DAILY_UPDATE_OF_MERC_SITE:
DailyUpdateOfMercSite( (UINT16)GetWorldDay() );
break;
case EVENT_DAY3_ADD_EMAIL_FROM_SPECK:
if(!bMercDayOne)
{
AddEmail(MERC_INTRO, MERC_INTRO_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin( ) );
}
break;
case EVENT_DAY2_ADD_EMAIL_FROM_IMP:
AddEmail(IMP_EMAIL_PROFILE_RESULTS, IMP_EMAIL_PROFILE_RESULTS_LENGTH, IMP_PROFILE_RESULTS, GetWorldTotalMin( ) );
break;
//If a merc gets hired and they dont show up immediately, the merc gets added to the queue and shows up
// uiTimeTillMercArrives minutes later
case EVENT_DELAYED_HIRING_OF_MERC:
MercArrivesCallback( (UINT8) pEvent->uiParam );
break;
//handles the life insurance contract for a merc from AIM.
case EVENT_HANDLE_INSURED_MERCS:
DailyUpdateOfInsuredMercs();
break;
//handles when a merc is killed an there is a life insurance payout
case EVENT_PAY_LIFE_INSURANCE_FOR_DEAD_MERC:
InsuranceContractPayLifeInsuranceForDeadMerc( (UINT8) pEvent->uiParam );
break;
//gets called every day at midnight.
case EVENT_MERC_DAILY_UPDATE:
MercDailyUpdate();
break;
//gets when a merc is about to leave.
case EVENT_MERC_ABOUT_TO_LEAVE_COMMENT:
break;
// show the update menu
case( EVENT_SHOW_UPDATE_MENU ):
AddDisplayBoxToWaitingQueue( );
break;
case EVENT_MERC_ABOUT_TO_LEAVE:
FindOutIfAnyMercAboutToLeaveIsGonnaRenew( );
break;
//When a merc is supposed to leave
case EVENT_MERC_CONTRACT_OVER:
MercsContractIsFinished( (UINT8) pEvent->uiParam );
break;
case EVENT_ADDSOLDIER_TO_UPDATE_BOX:
// if the grunt is currently active, add to update box
if( Menptr[ pEvent->uiParam ].bActive )
{
AddSoldierToWaitingListQueue( &( Menptr[ pEvent->uiParam ] ) );
}
break;
case EVENT_SET_MENU_REASON:
AddReasonToWaitingListQueue( (UINT8) pEvent->uiParam );
break;
//Whenever any group (player or enemy) arrives in a new sector during movement.
case EVENT_GROUP_ARRIVAL:
//ValidateGameEvents();
GroupArrivedAtSector( (UINT8)pEvent->uiParam, TRUE, FALSE );
//ValidateGameEvents();
break;
case EVENT_MERC_COMPLAIN_EQUIPMENT:
MercComplainAboutEquipment( (UINT8) pEvent->uiParam );
break;
case EVENT_HOURLY_UPDATE:
HandleHourlyUpdate();
break;
case EVENT_MINUTE_UPDATE:
HandleMinuteUpdate();
break;
case EVENT_HANDLE_MINE_INCOME:
HandleIncomeFromMines( );
//ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, L"Income From Mines at %d", GetWorldTotalMin( ) );
break;
case EVENT_SETUP_MINE_INCOME:
PostEventsForMineProduction();
break;
case EVENT_SETUP_TOWN_OPINION:
PostEventsForSpreadOfTownOpinion( );
break;
case EVENT_HANDLE_TOWN_OPINION:
HandleSpreadOfAllTownsOpinion( );
break;
case EVENT_SET_BY_NPC_SYSTEM:
HandleNPCSystemEvent( pEvent->uiParam );
break;
case EVENT_SECOND_AIRPORT_ATTENDANT_ARRIVED:
AddSecondAirportAttendant();
break;
case EVENT_HELICOPTER_HOVER_TOO_LONG:
HandleHeliHoverLong( );
break;
case EVENT_HELICOPTER_HOVER_WAY_TOO_LONG:
HandleHeliHoverTooLong( );
break;
case EVENT_MERC_LEAVE_EQUIP_IN_DRASSEN:
HandleEquipmentLeftInDrassen( pEvent->uiParam );
break;
case EVENT_MERC_LEAVE_EQUIP_IN_OMERTA:
HandleEquipmentLeftInOmerta( pEvent->uiParam );
break;
case EVENT_BANDAGE_BLEEDING_MERCS:
BandageBleedingDyingPatientsBeingTreated( );
break;
case EVENT_DAILY_EARLY_MORNING_EVENTS:
HandleEarlyMorningEvents();
break;
case EVENT_GROUP_ABOUT_TO_ARRIVE:
HandleGroupAboutToArrive();
break;
case EVENT_PROCESS_TACTICAL_SCHEDULE:
ProcessTacticalSchedule( (UINT8)pEvent->uiParam );
break;
case EVENT_BEGINRAINSTORM:
//EnvBeginRainStorm( (UINT8)pEvent->uiParam );
break;
case EVENT_ENDRAINSTORM:
//EnvEndRainStorm( );
break;
case EVENT_RAINSTORM:
// ATE: Disabled
//
//if( pEvent->ubEventType == ENDRANGED_EVENT )
//{
// EnvEndRainStorm( );
//}
//else
//{
// EnvBeginRainStorm( (UINT8)pEvent->uiParam );
//}
break;
case EVENT_MAKE_CIV_GROUP_HOSTILE_ON_NEXT_SECTOR_ENTRANCE:
MakeCivGroupHostileOnNextSectorEntrance( (UINT8)pEvent->uiParam );
break;
case EVENT_CHECK_FOR_AIR_RAID:
CheckForAndSetupAirRaid( );
break;
case EVENT_BEGIN_AIR_RAID:
BeginAirRaid( );
break;
case EVENT_MEANWHILE:
if( !DelayEventIfBattleInProgress( pEvent ) )
{
BeginMeanwhile( (UINT8)pEvent->uiParam );
InterruptTime();
}
break;
case EVENT_BEGIN_CREATURE_QUEST:
break;
case EVENT_CREATURE_SPREAD:
SpreadCreatures();
break;
case EVENT_DECAY_CREATURES:
DecayCreatures();
break;
case EVENT_CREATURE_NIGHT_PLANNING:
CreatureNightPlanning();
break;
case EVENT_CREATURE_ATTACK:
CreatureAttackTown( (UINT8)pEvent->uiParam, FALSE );
break;
case EVENT_EVALUATE_QUEEN_SITUATION:
EvaluateQueenSituation();
break;
case EVENT_CHECK_ENEMY_CONTROLLED_SECTOR:
CheckEnemyControlledSector( (UINT8)pEvent->uiParam );
break;
case EVENT_TURN_ON_NIGHT_LIGHTS:
TurnOnNightLights();
break;
case EVENT_TURN_OFF_NIGHT_LIGHTS:
TurnOffNightLights();
break;
case EVENT_TURN_ON_PRIME_LIGHTS:
TurnOnPrimeLights();
break;
case EVENT_TURN_OFF_PRIME_LIGHTS:
TurnOffPrimeLights();
break;
case EVENT_INTERRUPT_TIME:
InterruptTime( );
break;
case EVENT_ENRICO_MAIL:
HandleEnricoEmail();
break;
case EVENT_INSURANCE_INVESTIGATION_STARTED:
StartInsuranceInvestigation( (UINT8) pEvent->uiParam );
break;
case EVENT_INSURANCE_INVESTIGATION_OVER:
EndInsuranceInvestigation( (UINT8) pEvent->uiParam );
break;
case EVENT_TEMPERATURE_UPDATE:
UpdateTemperature( (UINT8) pEvent->uiParam );
break;
case EVENT_KEITH_GOING_OUT_OF_BUSINESS:
// make sure killbillies are still alive, if so, set fact 274 true
if( CheckFact( FACT_HILLBILLIES_KILLED, KEITH ) == FALSE )
{
//s et the fact true keith is out of business
SetFactTrue( FACT_KEITH_OUT_OF_BUSINESS );
}
break;
case EVENT_MERC_SITE_BACK_ONLINE:
GetMercSiteBackOnline();
break;
case EVENT_INVESTIGATE_SECTOR:
InvestigateSector( (UINT8)pEvent->uiParam );
break;
case EVENT_CHECK_IF_MINE_CLEARED:
// If so, the head miner will say so, and the mine's shutdown will be ended.
HourlyMinesUpdate(); // not-so hourly, in this case!
break;
case EVENT_REMOVE_ASSASSIN:
RemoveAssassin( (UINT8) pEvent->uiParam );
break;
case EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE:
BeginContractRenewalSequence( );
break;
case EVENT_RPC_WHINE_ABOUT_PAY:
RPCWhineAboutNoPay( (UINT8) pEvent->uiParam );
break;
case EVENT_HAVENT_MADE_IMP_CHARACTER_EMAIL:
HaventMadeImpMercEmailCallBack();
break;
case EVENT_QUARTER_HOUR_UPDATE:
HandleQuarterHourUpdate();
break;
case EVENT_MERC_MERC_WENT_UP_LEVEL_EMAIL_DELAY:
MERCMercWentUpALevelSendEmail( (UINT8) pEvent->uiParam );
break;
case EVENT_MERC_SITE_NEW_MERC_AVAILABLE:
NewMercsAvailableAtMercSiteCallBack( );
break;
#ifdef CRIPPLED_VERSION
case EVENT_CRIPPLED_VERSION_END_GAME_CHECK:
CrippledVersionEndGameCheck();
break;
#endif
}
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
return TRUE;
}
#ifdef CRIPPLED_VERSION
void CrippledVersionEndGameCheck()
{
CHAR16 zString[512];
//Dont want this to appear before we arrive
if( guiDay == 1 )
return;
if( guiDay >= 8 )
{
swprintf( zString, L"Game Over. We hope you have enjoyed playing the limited version of Jagged Alliance 2." );
}
else
{
swprintf( zString, L"You have %d game days left in this limited version of Jagged Alliance 2.", ( 8 - guiDay ) );
}
DoScreenIndependantMessageBox( zString, MSG_BOX_FLAG_OK, CrippledVersionEndGameCheckCallBack );
}
void CrippledVersionEndGameCheckCallBack( UINT8 bExitValue )
{
//if we should restart the game
if( guiDay >= 8 )
{
//clean up the code
ReStartingGame();
//go to the main menu
if( guiCurrentScreen == MAP_SCREEN )
{
SetPendingNewScreen(MAINMENU_SCREEN);
}
else
{
InternalLeaveTacticalScreen( MAINMENU_SCREEN );
}
}
}
#endif
+163
View File
@@ -0,0 +1,163 @@
#ifndef __GAME_EVENT_HOOK_H
#define __GAME_EVENT_HOOK_H
#include "types.h"
enum
{
EVENT_CHANGELIGHTVAL = 1,
EVENT_WEATHERSTART,
EVENT_WEATHEREND,
EVENT_CHECKFORQUESTS,
EVENT_AMBIENT,
EVENT_AIM_RESET_MERC_ANNOYANCE,
EVENT_BOBBYRAY_PURCHASE,
EVENT_DAILY_UPDATE_BOBBY_RAY_INVENTORY,
EVENT_UPDATE_BOBBY_RAY_INVENTORY,
EVENT_DAILY_UPDATE_OF_MERC_SITE,
EVENT_DAY3_ADD_EMAIL_FROM_SPECK,
EVENT_DELAYED_HIRING_OF_MERC,
EVENT_HANDLE_INSURED_MERCS,
EVENT_PAY_LIFE_INSURANCE_FOR_DEAD_MERC,
EVENT_MERC_DAILY_UPDATE,
EVENT_MERC_ABOUT_TO_LEAVE_COMMENT,
EVENT_MERC_CONTRACT_OVER,
EVENT_GROUP_ARRIVAL,
EVENT_DAY2_ADD_EMAIL_FROM_IMP,
EVENT_MERC_COMPLAIN_EQUIPMENT,
EVENT_HOURLY_UPDATE,
EVENT_HANDLE_MINE_INCOME,
EVENT_SETUP_MINE_INCOME,
EVENT_QUEUED_BATTLE,
EVENT_LEAVING_MERC_ARRIVE_IN_DRASSEN, // unused
EVENT_LEAVING_MERC_ARRIVE_IN_OMERTA, // unused
EVENT_SET_BY_NPC_SYSTEM,
EVENT_SECOND_AIRPORT_ATTENDANT_ARRIVED,
EVENT_HELICOPTER_HOVER_TOO_LONG,
EVENT_HELICOPTER_HOVER_WAY_TOO_LONG,
EVENT_HELICOPTER_DONE_REFUELING,
EVENT_MERC_LEAVE_EQUIP_IN_OMERTA,
EVENT_MERC_LEAVE_EQUIP_IN_DRASSEN,
EVENT_DAILY_EARLY_MORNING_EVENTS,
EVENT_GROUP_ABOUT_TO_ARRIVE,
EVENT_PROCESS_TACTICAL_SCHEDULE,
EVENT_BEGINRAINSTORM,
EVENT_ENDRAINSTORM,
EVENT_HANDLE_TOWN_OPINION,
EVENT_SETUP_TOWN_OPINION,
EVENT_MAKE_CIV_GROUP_HOSTILE_ON_NEXT_SECTOR_ENTRANCE,
EVENT_BEGIN_AIR_RAID,
EVENT_TOWN_LOYALTY_UPDATE, /* Delayed loyalty effects elimininated. Sep.12/98. ARM */
EVENT_MEANWHILE,
EVENT_BEGIN_CREATURE_QUEST,
EVENT_CREATURE_SPREAD,
EVENT_DECAY_CREATURES,
EVENT_CREATURE_NIGHT_PLANNING,
EVENT_CREATURE_ATTACK,
EVENT_EVALUATE_QUEEN_SITUATION,
EVENT_CHECK_ENEMY_CONTROLLED_SECTOR,
EVENT_TURN_ON_NIGHT_LIGHTS,
EVENT_TURN_OFF_NIGHT_LIGHTS,
EVENT_TURN_ON_PRIME_LIGHTS,
EVENT_TURN_OFF_PRIME_LIGHTS,
EVENT_MERC_ABOUT_TO_LEAVE,
EVENT_INTERRUPT_TIME,
EVENT_ENRICO_MAIL,
EVENT_INSURANCE_INVESTIGATION_STARTED,
EVENT_INSURANCE_INVESTIGATION_OVER,
EVENT_MINUTE_UPDATE,
EVENT_TEMPERATURE_UPDATE,
EVENT_KEITH_GOING_OUT_OF_BUSINESS,
EVENT_MERC_SITE_BACK_ONLINE,
EVENT_INVESTIGATE_SECTOR,
EVENT_CHECK_IF_MINE_CLEARED,
EVENT_REMOVE_ASSASSIN,
EVENT_BANDAGE_BLEEDING_MERCS,
EVENT_SHOW_UPDATE_MENU,
EVENT_SET_MENU_REASON,
EVENT_ADDSOLDIER_TO_UPDATE_BOX,
EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE,
EVENT_RPC_WHINE_ABOUT_PAY,
EVENT_HAVENT_MADE_IMP_CHARACTER_EMAIL,
EVENT_RAINSTORM,
EVENT_QUARTER_HOUR_UPDATE,
EVENT_MERC_MERC_WENT_UP_LEVEL_EMAIL_DELAY,
EVENT_MERC_SITE_NEW_MERC_AVAILABLE,
EVENT_CHECK_FOR_AIR_RAID,
#ifdef CRIPPLED_VERSION
EVENT_CRIPPLED_VERSION_END_GAME_CHECK,
#endif
/*
HEY, YOU GUYS AREN'T DOING THIS!!!!!! (see below)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! IMPORTANT NOTE !!
!! FOR ALL NEW EVENTS: For text debug support, make sure you add the text version of the !!
!! new event into the gEventName[] at the top of Game Events.c. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
NUMBER_OF_EVENT_TYPES_PLUS_ONE,
NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1
};
// This value is added to the param value for NPC-system-created events which are based on an
// action rather than a fact:
#define NPC_SYSTEM_EVENT_ACTION_PARAM_BONUS 10000
//One Time Events
//These events are scheduled to happen, and when their time is up, they are processed
//once, and deleted. The first prototype requires the actual world time in minutes
//included the current day, and the additional ones are wrappers which calculate the
//actual world time for you.
BOOLEAN AddStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam );
BOOLEAN AddSameDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam );
BOOLEAN AddFutureDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam, UINT32 uiNumDaysFromPresent );
//Same but uses seconds instead of minutes.
BOOLEAN AddStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam );
BOOLEAN AddSameDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam );
BOOLEAN AddFutureDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam, UINT32 uiNumDaysFromPresent );
//Ranged Events
//In certain cases, you may wish to create an event that has a start time and an end
//time. If this is used, then the execution of the event will happen once at the
//beginning of the event and once at the expiration time of the event. A flag,
//pEvent->fEndEvent is set for the second call. It is up to you process it
//separately. An example use of ranged events would be for ambient sounds. The
//start time would be called to define the sounds for use within the game. The end
//time would be used to remove the sound from the system.
BOOLEAN AddRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam );
BOOLEAN AddSameDayRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam);
BOOLEAN AddFutureDayRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam, UINT32 uiNumDaysFromPresent );
BOOLEAN AddRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam );
BOOLEAN AddSameDayRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam);
BOOLEAN AddFutureDayRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam, UINT32 uiNumDaysFromPresent );
//EveryDay Events
//A second special case event, this event will get processed automatically at the
//same time every day. Time of day lighting is a perfect example. Other events
//such as checking for quests, can also be automated using this system. NOTE:
//Only specify the time of day in minutes (don't add the actual day to this value)
BOOLEAN AddEveryDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiParam );
BOOLEAN AddEveryDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiParam );
//Periodic Events
//Event will get processed automatically once every X minutes. The period is added to the current time for
//the time stamp.
BOOLEAN AddPeriodStrategicEvent( UINT8 ubCallbackID, UINT32 uiOnceEveryXMinutes, UINT32 uiParam );
BOOLEAN AddPeriodStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiOnceEveryXSeconds, UINT32 uiParam );
//Hybrids that aren't based from the current time. They are offsetted from the current time first.
BOOLEAN AddPeriodStrategicEventWithOffset( UINT8 ubCallbackID, UINT32 uiOnceEveryXMinutes, UINT32 uiOffsetFromCurrent, UINT32 uiParam );
BOOLEAN AddPeriodStrategicEventUsingSecondsWithOffset( UINT8 ubCallbackID, UINT32 uiOnceEveryXSeconds, UINT32 uiOffsetFromCurrent, UINT32 uiParam );
//Searches for and removes the first event matching the supplied information. There may very well be a need
//for more specific event removal, so let me know (Kris), of any support needs. Function returns FALSE if
//no events were found.
BOOLEAN DeleteStrategicEvent( UINT8 ubCallbackID, UINT32 uiParam );
void DeleteAllStrategicEventsOfType( UINT8 ubCallbackID );
void DeleteAllStrategicEvents();
#endif
+785
View File
@@ -0,0 +1,785 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include <stdio.h>
#include "types.h"
#include "Game Events.h"
#include "Game Clock.h"
#include "MemMan.h"
#include "Debug.h"
#include "Font Control.h"
#include "message.h"
#include "Text.h"
#endif
#ifdef JA2TESTVERSION
UINT16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"Null",
L"ChangeLightValue",
L"WeatherStart",
L"WeatherEnd",
L"CheckForQuests",
L"Ambient",
L"AIMResetMercAnnoyance",
L"BobbyRayPurchase",
L"DailyUpdateBobbyRayInventory",
L"UpdateBobbyRayInventory",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"DailyUpdateOfMercSite",
L"Day3AddEMailFromSpeck",
L"DelayedHiringOfMerc",
L"HandleInsuredMercs",
L"PayLifeInsuranceForDeadMerc",
L"MercDailyUpdate",
L"MercAboutToLeaveComment",
L"MercContractOver",
L"GroupArrival",
L"Day2AddEMailFromIMP",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"MercComplainEquipment",
L"HourlyUpdate",
L"HandleMineIncome",
L"SetupMineIncome",
L"QueuedBattle",
L"LeavingMercArriveInDrassen",
L"LeavingMercArriveInOmerta",
L"SetByNPCSystem",
L"SecondAirportAttendantArrived",
L"HelicopterHoverTooLong",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"HelicopterHoverWayTooLong",
L"HelicopterDoneRefuelling",
L"MercLeaveEquipInOmerta",
L"MercLeaveEquipInDrassen",
L"DailyEarlyMorningEvents",
L"GroupAboutToArrive",
L"ProcessTacticalSchedule",
L"BeginRainStorm",
L"EndRainStorm",
L"HandleTownOpinion",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"SetupTownOpinion",
L"DelayedDeathHandling",
L"BeginAirRaid",
L"TownLoyaltyUpdate",
L"Meanwhile",
L"BeginCreatureQuest",
L"CreatureSpread",
L"DecayCreatures",
L"CreatureNightPlanning",
L"CreatureAttack",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"EvaluateQueenSituation",
L"CheckEnemyControlledSector",
L"TurnOnNightLights",
L"TurnOffNightLights",
L"TurnOnPrimeLights",
L"TurnOffPrimeLights",
L"MercAboutToLeaveComment",
L"ForceTimeInterupt",
L"EnricoEmailEvent",
L"InsuranceInvestigationStarted",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"InsuranceInvestigationOver",
L"HandleMinuteUpdate",
L"TemperatureUpdate",
L"Keith going out of business",
L"MERC site back online",
L"Investigate Sector",
L"CheckIfMineCleared",
L"RemoveAssassin",
L"BandageBleedingMercs",
L"ShowUpdateMenu",
//1234567890123456789012345678901234567890 (increase size of array if necessary)
L"SetMenuReason",
L"AddSoldierToUpdateBox",
L"BeginContractRenewalSequence",
L"RPC_WHINE_ABOUT_PAY",
L"HaventMadeImpCharacterEmail",
L"Rainstorm",
L"Quarter Hour Update",
L"MERC Merc went up level email delay",
L".",
#ifdef CRIPPLED_VERSION
L"Crippled version end game check",
#endif
};
#endif
void ValidateGameEvents();
STRATEGICEVENT *gpEventList = NULL;
extern UINT32 guiGameClock;
extern BOOLEAN gfTimeInterruptPause;
BOOLEAN gfPreventDeletionOfAnyEvent = FALSE;
BOOLEAN gfEventDeletionPending = FALSE;
BOOLEAN gfProcessingGameEvents = FALSE;
UINT32 guiTimeStampOfCurrentlyExecutingEvent = 0;
//Determines if there are any events that will be processed between the current global time,
//and the beginning of the next global time.
BOOLEAN GameEventsPending( UINT32 uiAdjustment )
{
#ifdef CRIPPLED_VERSION
if( guiDay >= 8 )
{
return FALSE;
}
#endif
if( !gpEventList )
return FALSE;
if( gpEventList->uiTimeStamp <= GetWorldTotalSeconds() + uiAdjustment )
return TRUE;
return FALSE;
}
//returns TRUE if any events were deleted
BOOLEAN DeleteEventsWithDeletionPending()
{
STRATEGICEVENT *curr, *prev, *temp;
BOOLEAN fEventDeleted = FALSE;
//ValidateGameEvents();
curr = gpEventList;
prev = NULL;
while( curr )
{
//ValidateGameEvents();
if( curr->ubFlags & SEF_DELETION_PENDING )
{
if( prev )
{ //deleting node in middle
prev->next = curr->next;
temp = curr;
curr = curr->next;
MemFree( temp );
fEventDeleted = TRUE;
//ValidateGameEvents();
continue;
}
else
{ //deleting head
gpEventList = gpEventList->next;
temp = curr;
prev = NULL;
curr = curr->next;
MemFree( temp );
fEventDeleted = TRUE;
//ValidateGameEvents();
continue;
}
}
prev = curr;
curr = curr->next;
}
gfEventDeletionPending = FALSE;
return fEventDeleted;
}
void AdjustClockToEventStamp( STRATEGICEVENT *pEvent, UINT32 *puiAdjustment )
{
UINT32 uiDiff;
uiDiff = pEvent->uiTimeStamp - guiGameClock;
guiGameClock += uiDiff;
*puiAdjustment -= uiDiff;
//Calculate the day, hour, and minutes.
guiDay = ( guiGameClock / NUM_SEC_IN_DAY );
guiHour = ( guiGameClock - ( guiDay * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR;
guiMin = ( guiGameClock - ( ( guiDay * NUM_SEC_IN_DAY ) + ( guiHour * NUM_SEC_IN_HOUR ) ) ) / NUM_SEC_IN_MIN;
#ifdef CRIPPLED_VERSION
if( guiDay >= 8 )
{
guiDay = 8;
guiHour = 0;
guiMin = 0;
return;
}
#endif
swprintf( WORLDTIMESTR, L"%s %d, %02d:%02d", gpGameClockString[ STR_GAMECLOCK_DAY_NAME ], guiDay, guiHour, guiMin );
}
//If there are any events pending, they are processed, until the time limit is reached, or
//a major event is processed (one that requires the player's attention).
void ProcessPendingGameEvents( UINT32 uiAdjustment, UINT8 ubWarpCode )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ProcessPendingGameEvents");
STRATEGICEVENT *curr, *pEvent, *prev, *temp;
BOOLEAN fDeleteEvent = FALSE, fDeleteQueuedEvent = FALSE;
#ifdef CRIPPLED_VERSION
if( guiDay >= 8 )
{
return;
}
#endif
gfTimeInterrupt = FALSE;
gfProcessingGameEvents = TRUE;
//While we have events inside the time range to be updated, process them...
curr = gpEventList;
prev = NULL; //prev only used when warping time to target time.
while( !gfTimeInterrupt && curr && curr->uiTimeStamp <= guiGameClock + uiAdjustment )
{
fDeleteEvent = FALSE;
//Update the time by the difference, but ONLY if the event comes after the current time.
//In the beginning of the game, series of events are created that are placed in the list
//BEFORE the start time. Those events will be processed without influencing the actual time.
if( curr->uiTimeStamp > guiGameClock && ubWarpCode != WARPTIME_PROCESS_TARGET_TIME_FIRST )
{
AdjustClockToEventStamp( curr, &uiAdjustment );
}
//Process the event
if( ubWarpCode != WARPTIME_PROCESS_TARGET_TIME_FIRST )
{
fDeleteEvent = ExecuteStrategicEvent( curr );
}
else if( curr->uiTimeStamp == guiGameClock + uiAdjustment )
{ //if we are warping to the target time to process that event first,
if( !curr->next || curr->next->uiTimeStamp > guiGameClock + uiAdjustment )
{ //make sure that we are processing the last event for that second
AdjustClockToEventStamp( curr, &uiAdjustment );
fDeleteEvent = ExecuteStrategicEvent( curr );
if( curr && prev && fDeleteQueuedEvent )
{ //The only case where we are deleting a node in the middle of the list
prev->next = curr->next;
}
}
else
{ //We are at the current target warp time however, there are still other events following in this time cycle.
//We will only target the final event in this time. NOTE: Events are posted using a FIFO method
prev = curr;
curr = curr->next;
continue;
}
}
else
{ //We are warping time to the target time. We haven't found the event yet,
//so continuing will keep processing the list until we find it. NOTE: Events are posted using a FIFO method
prev = curr;
curr = curr->next;
continue;
}
if( fDeleteEvent )
{
//Determine if event node is a special event requiring reposting
switch( curr->ubEventType )
{
case RANGED_EVENT:
AddAdvancedStrategicEvent( ENDRANGED_EVENT, curr->ubCallbackID, curr->uiTimeStamp+curr->uiTimeOffset, curr->uiParam );
break;
case PERIODIC_EVENT:
pEvent = AddAdvancedStrategicEvent( PERIODIC_EVENT, curr->ubCallbackID, curr->uiTimeStamp+curr->uiTimeOffset, curr->uiParam );
if( pEvent )
pEvent->uiTimeOffset = curr->uiTimeOffset;
break;
case EVERYDAY_EVENT:
AddAdvancedStrategicEvent( EVERYDAY_EVENT, curr->ubCallbackID, curr->uiTimeStamp+NUM_SEC_IN_DAY, curr->uiParam );
break;
}
if( curr == gpEventList )
{
gpEventList = gpEventList->next;
MemFree( curr );
curr = gpEventList;
prev = NULL;
//ValidateGameEvents();
}
else
{
temp = curr;
prev->next = curr->next;
curr = curr->next;
MemFree( temp );
//ValidateGameEvents();
}
}
else
{
prev = curr;
curr = curr->next;
}
}
gfProcessingGameEvents = FALSE;
if( gfEventDeletionPending )
{
DeleteEventsWithDeletionPending();
}
if( uiAdjustment && !gfTimeInterrupt )
guiGameClock += uiAdjustment;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ProcessPendingGameEvents done");
}
BOOLEAN AddSameDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam )
{
return( AddStrategicEvent( ubCallbackID, uiMinStamp + GetWorldDayInMinutes(), uiParam ) );
}
BOOLEAN AddSameDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam )
{
return( AddStrategicEventUsingSeconds( ubCallbackID, uiSecondStamp + GetWorldDayInSeconds(), uiParam ) );
}
BOOLEAN AddFutureDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam, UINT32 uiNumDaysFromPresent )
{
UINT32 uiDay;
uiDay = GetWorldDay();
return( AddStrategicEvent( ubCallbackID, uiMinStamp + GetFutureDayInMinutes( uiDay + uiNumDaysFromPresent ), uiParam ) );
}
BOOLEAN AddFutureDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam, UINT32 uiNumDaysFromPresent )
{
UINT32 uiDay;
uiDay = GetWorldDay();
return( AddStrategicEventUsingSeconds( ubCallbackID, uiSecondStamp + GetFutureDayInMinutes( uiDay + uiNumDaysFromPresent ) * 60, uiParam ) );
}
STRATEGICEVENT* AddAdvancedStrategicEvent( UINT8 ubEventType, UINT8 ubCallbackID, UINT32 uiTimeStamp, UINT32 uiParam )
{
STRATEGICEVENT *pNode, *pNewNode, *pPrevNode;
if( gfProcessingGameEvents && uiTimeStamp <= guiTimeStampOfCurrentlyExecutingEvent )
{ //Prevents infinite loops of posting events that are the same time or earlier than the event
//currently being processed.
#ifdef JA2TESTVERSION
//if( ubCallbackID == EVENT_PROCESS_TACTICAL_SCHEDULE )
{
ScreenMsg( FONT_RED, MSG_DEBUG, L"%s Event Rejected: Can't post events <= time while inside an event callback. This is a special case situation that isn't a bug.", gEventName[ ubCallbackID ] );
}
//else
//{
// AssertMsg( 0, String( "%S Event Rejected: Can't post events <= time while inside an event callback.", gEventName[ ubCallbackID ] ) );
//}
#endif
return NULL;
}
pNewNode = (STRATEGICEVENT *) MemAlloc( sizeof( STRATEGICEVENT ) );
Assert( pNewNode );
memset( pNewNode, 0, sizeof( STRATEGICEVENT ) );
pNewNode->ubCallbackID = ubCallbackID;
pNewNode->uiParam = uiParam;
pNewNode->ubEventType = ubEventType;
pNewNode->uiTimeStamp = uiTimeStamp;
pNewNode->uiTimeOffset = 0;
// Search list for a place to insert
pNode = gpEventList;
// If it's the first head, do this!
if( !pNode )
{
gpEventList = pNewNode;
pNewNode->next = NULL;
}
else
{
pPrevNode = NULL;
while( pNode )
{
if( uiTimeStamp < pNode->uiTimeStamp )
{
break;
}
pPrevNode = pNode;
pNode = pNode->next;
}
// If we are at the end, set at the end!
if ( !pNode )
{
pPrevNode->next = pNewNode;
pNewNode->next = NULL;
}
else
{
// We have a previous node here
// Insert IN FRONT!
if ( pPrevNode )
{
pNewNode->next = pPrevNode->next;
pPrevNode->next = pNewNode;
}
else
{ // It's the head
pNewNode->next = gpEventList;
gpEventList = pNewNode;
}
}
}
return pNewNode ;
}
BOOLEAN AddStrategicEvent( UINT8 ubCallbackID, UINT32 uiMinStamp, UINT32 uiParam )
{
if( AddAdvancedStrategicEvent( ONETIME_EVENT, ubCallbackID, uiMinStamp*60, uiParam ) )
return TRUE;
return FALSE;
}
BOOLEAN AddStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiSecondStamp, UINT32 uiParam )
{
if( AddAdvancedStrategicEvent( ONETIME_EVENT, ubCallbackID, uiSecondStamp, uiParam ) )
return TRUE;
return FALSE;
}
BOOLEAN AddRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( RANGED_EVENT, ubCallbackID, uiStartMin*60, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiLengthMin * 60;
return TRUE;
}
return FALSE;
}
BOOLEAN AddSameDayRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam)
{
return AddRangedStrategicEvent( ubCallbackID, uiStartMin + GetWorldDayInMinutes(), uiLengthMin, uiParam );
}
BOOLEAN AddFutureDayRangedStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiLengthMin, UINT32 uiParam, UINT32 uiNumDaysFromPresent )
{
return AddRangedStrategicEvent( ubCallbackID, uiStartMin + GetFutureDayInMinutes( GetWorldDay() + uiNumDaysFromPresent ), uiLengthMin, uiParam );
}
BOOLEAN AddRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( RANGED_EVENT, ubCallbackID, uiStartSeconds, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiLengthSeconds;
return TRUE;
}
return FALSE;
}
BOOLEAN AddSameDayRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam)
{
return AddRangedStrategicEventUsingSeconds( ubCallbackID, uiStartSeconds + GetWorldDayInSeconds(), uiLengthSeconds, uiParam );
}
BOOLEAN AddFutureDayRangedStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiLengthSeconds, UINT32 uiParam, UINT32 uiNumDaysFromPresent )
{
return AddRangedStrategicEventUsingSeconds( ubCallbackID, uiStartSeconds + GetFutureDayInMinutes( GetWorldDay() + uiNumDaysFromPresent ) * 60, uiLengthSeconds, uiParam );
}
BOOLEAN AddEveryDayStrategicEvent( UINT8 ubCallbackID, UINT32 uiStartMin, UINT32 uiParam )
{
if( AddAdvancedStrategicEvent( EVERYDAY_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiStartMin * 60, uiParam ) )
return TRUE;
return FALSE;
}
BOOLEAN AddEveryDayStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiStartSeconds, UINT32 uiParam )
{
if( AddAdvancedStrategicEvent( EVERYDAY_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiStartSeconds, uiParam ) )
return TRUE;
return FALSE;
}
//NEW: Period Events
//Event will get processed automatically once every X minutes.
BOOLEAN AddPeriodStrategicEvent( UINT8 ubCallbackID, UINT32 uiOnceEveryXMinutes, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( PERIODIC_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiOnceEveryXMinutes * 60, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiOnceEveryXMinutes * 60;
return TRUE;
}
return FALSE;
}
BOOLEAN AddPeriodStrategicEventUsingSeconds( UINT8 ubCallbackID, UINT32 uiOnceEveryXSeconds, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( PERIODIC_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiOnceEveryXSeconds, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiOnceEveryXSeconds;
return TRUE;
}
return FALSE;
}
BOOLEAN AddPeriodStrategicEventWithOffset( UINT8 ubCallbackID, UINT32 uiOnceEveryXMinutes, UINT32 uiOffsetFromCurrent, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( PERIODIC_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiOffsetFromCurrent * 60, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiOnceEveryXMinutes * 60;
return TRUE;
}
return FALSE;
}
BOOLEAN AddPeriodStrategicEventUsingSecondsWithOffset( UINT8 ubCallbackID, UINT32 uiOnceEveryXSeconds, UINT32 uiOffsetFromCurrent, UINT32 uiParam )
{
STRATEGICEVENT *pEvent;
pEvent = AddAdvancedStrategicEvent( PERIODIC_EVENT, ubCallbackID, GetWorldDayInSeconds() + uiOffsetFromCurrent, uiParam );
if( pEvent )
{
pEvent->uiTimeOffset = uiOnceEveryXSeconds;
return TRUE;
}
return FALSE;
}
void DeleteAllStrategicEventsOfType( UINT8 ubCallbackID )
{
STRATEGICEVENT *curr, *prev, *temp;
prev = NULL;
curr = gpEventList;
while( curr )
{
if( curr->ubCallbackID == ubCallbackID && !(curr->ubFlags & SEF_DELETION_PENDING) )
{
if( gfPreventDeletionOfAnyEvent )
{
curr->ubFlags |= SEF_DELETION_PENDING;
gfEventDeletionPending = TRUE;
prev = curr;
curr = curr->next;
continue;
}
//Detach the node
if( prev )
prev->next = curr->next;
else
gpEventList = curr->next;
//isolate and remove curr
temp = curr;
curr = curr->next;
MemFree( temp );
//ValidateGameEvents();
}
else
{ //Advance all the nodes
prev = curr;
curr = curr->next;
}
}
}
void DeleteAllStrategicEvents()
{
STRATEGICEVENT *temp;
while( gpEventList )
{
temp = gpEventList;
gpEventList = gpEventList->next;
MemFree( temp );
//ValidateGameEvents();
temp = NULL;
}
gpEventList = NULL;
}
//Searches for and removes the first event matching the supplied information. There may very well be a need
//for more specific event removal, so let me know (Kris), of any support needs. Function returns FALSE if
//no events were found or if the event wasn't deleted due to delete lock,
BOOLEAN DeleteStrategicEvent( UINT8 ubCallbackID, UINT32 uiParam )
{
STRATEGICEVENT *curr, *prev;
curr = gpEventList;
prev = NULL;
while( curr )
{ //deleting middle
if( curr->ubCallbackID == ubCallbackID && curr->uiParam == uiParam )
{
if( !(curr->ubFlags & SEF_DELETION_PENDING) )
{
if( gfPreventDeletionOfAnyEvent )
{
curr->ubFlags |= SEF_DELETION_PENDING;
gfEventDeletionPending = TRUE;
return FALSE;
}
if( prev )
{
prev->next = curr->next;
}
else
{
gpEventList = gpEventList->next;
}
MemFree( curr );
//ValidateGameEvents();
return TRUE;
}
}
prev = curr;
curr = curr->next;
}
return FALSE;
}
//part of the game.sav files (not map files)
BOOLEAN SaveStrategicEventsToSavedGame( HWFILE hFile )
{
UINT32 uiNumBytesWritten=0;
STRATEGICEVENT sGameEvent;
UINT32 uiNumGameEvents=0;
STRATEGICEVENT *pTempEvent = gpEventList;
//Go through the list and determine the number of events
while( pTempEvent )
{
pTempEvent = pTempEvent->next;
uiNumGameEvents++;
}
//write the number of strategic events
FileWrite( hFile, &uiNumGameEvents, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
{
return(FALSE);
}
//loop through all the events and save them.
pTempEvent = gpEventList;
while( pTempEvent )
{
//save the current structure
memcpy( &sGameEvent, pTempEvent, sizeof( STRATEGICEVENT ) );
//write the current strategic event
FileWrite( hFile, &sGameEvent, sizeof( STRATEGICEVENT ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( STRATEGICEVENT ) )
{
return(FALSE);
}
pTempEvent = pTempEvent->next;
}
return( TRUE );
}
BOOLEAN LoadStrategicEventsFromSavedGame( HWFILE hFile )
{
UINT32 uiNumGameEvents;
STRATEGICEVENT sGameEvent;
UINT32 cnt;
UINT32 uiNumBytesRead=0;
STRATEGICEVENT *pTemp = NULL;
//erase the old Game Event queue
DeleteAllStrategicEvents();
//Read the number of strategic events
FileRead( hFile, &uiNumGameEvents, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) )
{
return(FALSE);
}
pTemp = NULL;
//loop through all the events and save them.
for( cnt=0; cnt<uiNumGameEvents; cnt++ )
{
STRATEGICEVENT *pTempEvent = NULL;
// allocate memory for the event
pTempEvent = (STRATEGICEVENT *) MemAlloc( sizeof( STRATEGICEVENT ) );
if( pTempEvent == NULL )
return( FALSE );
//Read the current strategic event
FileRead( hFile, &sGameEvent, sizeof( STRATEGICEVENT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( STRATEGICEVENT ) )
{
return(FALSE);
}
memcpy( pTempEvent, &sGameEvent, sizeof( STRATEGICEVENT ) );
// Add the new node to the list
//if its the first node,
if( cnt == 0 )
{
// assign it as the head node
gpEventList = pTempEvent;
//assign the 'current node' to the head node
pTemp = gpEventList;
}
else
{
// add the new node to the next field of the current node
pTemp->next = pTempEvent;
//advance the current node to the next node
pTemp = pTemp->next;
}
// NULL out the next field ( cause there is no next field yet )
pTempEvent->next = NULL;
}
return( TRUE );
}
void LockStrategicEventFromDeletion( STRATEGICEVENT *pEvent )
{
pEvent->ubFlags |= SEF_PREVENT_DELETION;
}
void UnlockStrategicEventFromDeletion( STRATEGICEVENT *pEvent )
{
pEvent->ubFlags &= ~SEF_PREVENT_DELETION;
}
void ValidateGameEvents()
{
STRATEGICEVENT *curr;
curr = gpEventList;
while( curr )
{
curr = curr->next;
if( curr == (STRATEGICEVENT*)0xdddddddd )
{
return;
}
}
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef __GAME_EVENTS_H
#define __GAME_EVENTS_H
#include "Game Event Hook.h"
#include "FileMan.h"
#define SEF_PREVENT_DELETION 0x01
#define SEF_DELETION_PENDING 0x02
typedef struct STRATEGICEVENT
{
struct STRATEGICEVENT *next;
UINT32 uiTimeStamp;
UINT32 uiParam;
UINT32 uiTimeOffset;
UINT8 ubEventType;
UINT8 ubCallbackID;
UINT8 ubFlags;
INT8 bPadding[6];
} STRATEGICEVENT;
enum
{
ONETIME_EVENT,
RANGED_EVENT,
ENDRANGED_EVENT,
EVERYDAY_EVENT,
PERIODIC_EVENT,
QUEUED_EVENT
};
void LockStrategicEventFromDeletion( STRATEGICEVENT *pEvent );
void UnlockStrategicEventFromDeletion( STRATEGICEVENT *pEvent );
//part of the game.sav files (not map files)
BOOLEAN SaveStrategicEventsToSavedGame( HWFILE hFile );
BOOLEAN LoadStrategicEventsFromSavedGame( HWFILE hFile );
STRATEGICEVENT* AddAdvancedStrategicEvent( UINT8 ubEventType, UINT8 ubCallbackID, UINT32 uiTimeStamp, UINT32 uiParam );
BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent );
extern BOOLEAN gfEventDeletionPending;
BOOLEAN DeleteEventsWithDeletionPending();
extern STRATEGICEVENT *gpEventList;
#endif
+843
View File
@@ -0,0 +1,843 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#include "Language Defines.h"
#include "HelpScreen.h"
#include "GameSettings.h"
#else
#include "sgp.h"
#include "jascreens.h"
#include "laptop.h"
#include "worlddef.h"
#include "Soldier Control.h"
#include "overhead.h"
#include "fade screen.h"
#include "gamescreen.h"
#include "email.h"
#include "Game Clock.h"
#include "soldier profile.h"
#include "strategicmap.h"
#include "game init.h"
#include "animation data.h"
#include "finances.h"
#include "soldier create.h"
#include "Soldier Init List.h"
#include "music control.h"
#include "strategic.h"
#include "history.h"
#include "merc entering.h"
#include "Squads.h"
#include "Campaign Init.h"
#include "Strategic Town Loyalty.h"
#include "Strategic Mines.h"
#include "gameloop.h"
#include "Random.h"
#include "Map Screen Interface.h"
#include "Tactical Save.h"
#include "Campaign Types.h"
#include "Message.h"
#include "Game Event Hook.h"
#include "Strategic Movement.h"
#include "Creature Spreading.h"
#include "Quests.h"
#include "Strategic AI.h"
#include "sound control.h"
#include "Laptopsave.h"
#include "AimMembers.h"
#include "dialogue control.h"
#include "npc.h"
#include "Init.h"
#include "GameSettings.h"
#endif
// Temp function
void QuickSetupOfMercProfileItems( UINT32 uiCount, UINT8 ubProfileIndex );
BOOLEAN QuickGameMemberHireMerc( UINT8 ubCurrentSoldier );
extern UINT32 guiExitScreen;
extern UINT32 uiMeanWhileFlags;
extern BOOLEAN gfGamePaused;
extern UNDERGROUND_SECTORINFO* FindUnderGroundSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ );
extern void InitVehicles( );
UINT8 gubScreenCount=0;
void InitNPCs( void )
{
MERCPROFILESTRUCT * pProfile;
// add the pilot at a random location!
pProfile = &(gMercProfiles[ SKYRIDER ]);
switch( Random( 4 ) )
{
case 0:
pProfile->sSectorX = 15;
pProfile->sSectorY = MAP_ROW_B;
pProfile->bSectorZ = 0;
break;
case 1:
pProfile->sSectorX = 14;
pProfile->sSectorY = MAP_ROW_E;
pProfile->bSectorZ = 0;
break;
case 2:
pProfile->sSectorX = 12;
pProfile->sSectorY = MAP_ROW_D;
pProfile->bSectorZ = 0;
break;
case 3:
pProfile->sSectorX = 16;
pProfile->sSectorY = MAP_ROW_C;
pProfile->bSectorZ = 0;
break;
}
#ifdef JA2TESTVERSION
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"Skyrider in %c %d", 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
#endif
// use alternate map, with Skyrider's shack, in this sector
SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
// set up Madlab's secret lab (he'll be added when the meanwhile scene occurs)
switch( Random( 4 ) )
{
case 0:
// use alternate map in this sector
SectorInfo[ SECTOR( 7, MAP_ROW_H ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
break;
case 1:
SectorInfo[ SECTOR( 16, MAP_ROW_H ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
break;
case 2:
SectorInfo[ SECTOR( 11, MAP_ROW_I ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
break;
case 3:
SectorInfo[ SECTOR( 4, MAP_ROW_E ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
break;
}
// add Micky in random location
pProfile = &(gMercProfiles[MICKY]);
switch( Random( 5 ) )
{
case 0:
pProfile->sSectorX = 9;
pProfile->sSectorY = MAP_ROW_G;
pProfile->bSectorZ = 0;
break;
case 1:
pProfile->sSectorX = 13;
pProfile->sSectorY = MAP_ROW_D;
pProfile->bSectorZ = 0;
break;
case 2:
pProfile->sSectorX = 5;
pProfile->sSectorY = MAP_ROW_C;
pProfile->bSectorZ = 0;
break;
case 3:
pProfile->sSectorX = 2;
pProfile->sSectorY = MAP_ROW_H;
pProfile->bSectorZ = 0;
break;
case 4:
pProfile->sSectorX = 6;
pProfile->sSectorY = MAP_ROW_C;
pProfile->bSectorZ = 0;
break;
}
#ifdef JA2TESTVERSION
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s in %c %d", pProfile->zNickname, 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
#endif
// use alternate map in this sector
//SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
gfPlayerTeamSawJoey = FALSE;
if ( gGameOptions.ubGameStyle == STYLE_SCIFI )
{
// add Bob
pProfile = &(gMercProfiles[BOB]);
pProfile->sSectorX = 8;
pProfile->sSectorY = MAP_ROW_F;
pProfile->bSectorZ = 0;
// add Gabby in random location
pProfile = &(gMercProfiles[GABBY]);
switch( Random( 2 ) )
{
case 0:
pProfile->sSectorX = 11;
pProfile->sSectorY = MAP_ROW_H;
pProfile->bSectorZ = 0;
break;
case 1:
pProfile->sSectorX = 4;
pProfile->sSectorY = MAP_ROW_I;
pProfile->bSectorZ = 0;
break;
}
#ifdef JA2TESTVERSION
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s in %c %d", pProfile->zNickname, 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
#endif
// use alternate map in this sector
SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
}
else
{ //not scifi, so use alternate map in Tixa's b1 level that doesn't have the stairs going down to the caves.
UNDERGROUND_SECTORINFO *pSector;
pSector = FindUnderGroundSector( 9, 10, 1 ); //j9_b1
if( pSector )
{
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
}
}
// init hospital variables
giHospitalTempBalance = 0;
giHospitalRefund = 0;
gbHospitalPriceModifier = 0;
// set up Devin so he will be placed ASAP
gMercProfiles[ DEVIN ].bNPCData = 3;
}
void InitBloodCatSectors()
{
INT32 i;
//Hard coded table of bloodcat populations. We don't have
//access to the real population (if different) until we physically
//load the map. If the real population is different, then an error
//will be reported.
for( i = 0; i < 255; i++ )
{
SectorInfo[ i ].bBloodCats = -1;
}
SectorInfo[ SEC_A15 ].bBloodCatPlacements = 9;
SectorInfo[ SEC_B4 ].bBloodCatPlacements = 9;
SectorInfo[ SEC_B16 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_C3 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_C8 ].bBloodCatPlacements = 13;
SectorInfo[ SEC_C11 ].bBloodCatPlacements = 7;
SectorInfo[ SEC_D4 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_D9 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_E11 ].bBloodCatPlacements = 10;
SectorInfo[ SEC_E13 ].bBloodCatPlacements = 14;
SectorInfo[ SEC_F3 ].bBloodCatPlacements = 13;
SectorInfo[ SEC_F5 ].bBloodCatPlacements = 7;
SectorInfo[ SEC_F7 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_F12 ].bBloodCatPlacements = 9;
SectorInfo[ SEC_F14 ].bBloodCatPlacements = 14;
SectorInfo[ SEC_F15 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_G6 ].bBloodCatPlacements = 7;
SectorInfo[ SEC_G10 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_G12 ].bBloodCatPlacements = 11;
SectorInfo[ SEC_H5 ].bBloodCatPlacements = 9;
SectorInfo[ SEC_I4 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_I15 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_J6 ].bBloodCatPlacements = 11;
SectorInfo[ SEC_K3 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_K6 ].bBloodCatPlacements = 14;
SectorInfo[ SEC_K10 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_K14 ].bBloodCatPlacements = 14;
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY: //50%
SectorInfo[ SEC_I16 ].bBloodCatPlacements = 14;
SectorInfo[ SEC_I16 ].bBloodCats = 14;
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_N5 ].bBloodCats = 8;
break;
case DIF_LEVEL_MEDIUM: //75%
SectorInfo[ SEC_I16 ].bBloodCatPlacements = 19;
SectorInfo[ SEC_I16 ].bBloodCats = 19;
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 10;
SectorInfo[ SEC_N5 ].bBloodCats = 10;
break;
case DIF_LEVEL_HARD: //100%
SectorInfo[ SEC_I16 ].bBloodCatPlacements = 26;
SectorInfo[ SEC_I16 ].bBloodCats = 26;
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_N5 ].bBloodCats = 12;
break;
case DIF_LEVEL_INSANE: //150%
SectorInfo[ SEC_I16 ].bBloodCatPlacements = 39;
SectorInfo[ SEC_I16 ].bBloodCats = 39;
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 18;
SectorInfo[ SEC_N5 ].bBloodCats = 18;
break;
}
}
void InitStrategicLayer( void )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitStrategicLayer");
// Clear starategic layer!
SetupNewStrategicGame();
InitQuestEngine();
//Setup a new campaign via the enemy perspective.
InitNewCampaign();
// Init Squad Lists
InitSquads();
// Init vehicles
InitVehicles( );
// init town loyalty
InitTownLoyalty();
// init the mine management system
InitializeMines();
// initialize map screen flags
InitMapScreenFlags();
// initialize NPCs, select alternate maps, etc
InitNPCs();
// init Skyrider and his helicopter
InitializeHelicopter();
//Clear out the vehicle list
ClearOutVehicleList();
InitBloodCatSectors();
InitializeSAMSites();
// make Orta, Tixa, SAM sites not found
InitMapSecrets();
// free up any leave list arrays that were left allocated
ShutDownLeaveList( );
// re-set up leave list arrays for dismissed mercs
InitLeaveList( );
// reset time compression mode to X0 (this will also pause it)
SetGameTimeCompressionLevel( TIME_COMPRESS_X0 );
// select A9 Omerta as the initial selected sector
ChangeSelectedMapSector( 9, 1, 0 );
// Reset these flags or mapscreen could be disabled and cause major headache.
fDisableDueToBattleRoster = FALSE;
fDisableMapInterfaceDueToBattle = FALSE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitStrategicLayer done");
}
void ShutdownStrategicLayer()
{
DeleteAllStrategicEvents();
RemoveAllGroups();
TrashUndergroundSectorInfo();
DeleteCreatureDirectives();
KillStrategicAI();
}
BOOLEAN InitNewGame( BOOLEAN fReset )
{
INT32 iStartingCash;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame");
// static fScreenCount = 0;
if( fReset )
{
gubScreenCount = 0;
return( TRUE );
}
// reset meanwhile flags
uiMeanWhileFlags = 0;
// Reset the selected soldier
gusSelectedSoldier = NOBODY;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: loading merc profiles");
if( gubScreenCount == 0 )
{
if( !LoadMercProfiles() )
return(FALSE);
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: init arms dealers");
//Initialize the Arms Dealers and Bobby Rays inventory
if( gubScreenCount == 0 )
{
//Init all the arms dealers inventory
InitAllArmsDealers();
InitBobbyRayInventory();
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: clearing messages");
// clear tactical
ClearTacticalMessageQueue( );
// clear mapscreen messages
FreeGlobalMessageList();
// IF our first time, go into laptop!
if ( gubScreenCount == 0 )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: first time: init laptop");
//Init the laptop here
InitLaptopAndLaptopScreens();
InitStrategicLayer();
// Set new game flag
SetLaptopNewGameFlag( );
// this is for the "mercs climbing down from a rope" animation, NOT Skyrider!!
ResetHeliSeats( );
// Setup two new messages!
AddPreReadEmail(OLD_ENRICO_1,OLD_ENRICO_1_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddPreReadEmail(OLD_ENRICO_2,OLD_ENRICO_2_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddPreReadEmail(RIS_REPORT,RIS_REPORT_LENGTH,RIS_EMAIL, GetWorldTotalMin() );
AddPreReadEmail(OLD_ENRICO_3,OLD_ENRICO_3_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddEmail(IMP_EMAIL_INTRO,IMP_EMAIL_INTRO_LENGTH,CHAR_PROFILE_SITE, GetWorldTotalMin() );
//AddEmail(ENRICO_CONGRATS,ENRICO_CONGRATS_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
if(gGameExternalOptions.fMercDayOne)
{
AddEmail(MERC_INTRO, MERC_INTRO_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin( ) );
}
// ATE: Set starting cash....
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
iStartingCash = gGameExternalOptions.iStartingCashNovice;
//iStartingCash = 45000;
break;
case DIF_LEVEL_MEDIUM:
iStartingCash = gGameExternalOptions.iStartingCashExperienced;
//iStartingCash = 35000;
break;
case DIF_LEVEL_HARD:
iStartingCash = gGameExternalOptions.iStartingCashExpert;
//iStartingCash = 30000;
break;
case DIF_LEVEL_INSANE:
iStartingCash = gGameExternalOptions.iStartingCashInsane;
// iStartingCash = 15000;
break;
default:
Assert(0);
return( FALSE );
}
// Setup initial money
AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), iStartingCash );
{
UINT32 uiDaysTimeMercSiteAvailable = Random( 2 ) + 1;
// schedule email for message from spec at 7am 3 days in the future
AddFutureDayStrategicEvent( EVENT_DAY3_ADD_EMAIL_FROM_SPECK, 60*7, 0, uiDaysTimeMercSiteAvailable );
}
#ifdef CRIPPLED_VERSION
{
UINT32 cnt;
//loop through the first 20 AIM mercs and set them to be away
for( cnt = 0; cnt < 20; cnt++)
{
gMercProfiles[ cnt ].bMercStatus = MERC_WORKING_ELSEWHERE;
gMercProfiles[ cnt ].uiDayBecomesAvailable = 14; // 14 days should be ok considering crippled version only goes to day 7
}
}
//Add an event to check for the end of the crippled version
AddEveryDayStrategicEvent( EVENT_CRIPPLED_VERSION_END_GAME_CHECK, 0, 0 );
#endif
SetLaptopExitScreen( INIT_SCREEN );
SetPendingNewScreen(LAPTOP_SCREEN);
gubScreenCount = 1;
//Set the fact the game is in progress
gTacticalStatus.fHasAGameBeenStarted = TRUE;
return( TRUE );
}
/*
if( ( guiExitScreen == MAP_SCREEN ) && ( LaptopSaveInfo.gfNewGameLaptop ) )
{
SetLaptopExitScreen( GAME_SCREEN );
return( TRUE );
}
*/
if ( gubScreenCount == 1 )
{
// OK , FADE HERE
//BeginFade( INIT_SCREEN, 35, FADE_OUT_REALFADE, 5 );
//BeginFade( INIT_SCREEN, 35, FADE_OUT_VERSION_FASTER, 25 );
//BeginFade( INIT_SCREEN, 35, FADE_OUT_VERSION_SIDE, 0 );
gubScreenCount = 2;
return( TRUE );
}
/*
if ( gubScreenCount == 2 )
{
if ( !SetCurrentWorldSector( 9, 1, 0 ) )
{
}
SetLaptopExitScreen( MAP_SCREEN );
FadeInGameScreen( );
EnterTacticalScreen( );
if( gfAtLeastOneMercWasHired == TRUE )
{
gubScreenCount = 3;
}
else
{
}
return( TRUE );
}
*/
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame done");
return( TRUE );
}
BOOLEAN AnyMercsHired( )
{
INT32 cnt;
SOLDIERTYPE *pTeamSoldier;
INT16 bLastTeamID;
// Find first guy availible in team
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
// look for all mercs on the same team,
for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pTeamSoldier++)
{
if ( pTeamSoldier->bActive )
{
return( TRUE );
}
}
return( FALSE );
}
void QuickStartGame( )
{
INT32 cnt;
UINT16 usVal;
UINT8 ub1 = 0, ub2 = 0;
for ( cnt = 0; cnt < 3; cnt++ )
{
if ( cnt == 0 )
{
usVal = (UINT16)Random( 40 );
QuickSetupOfMercProfileItems( cnt, (UINT8)usVal );
QuickGameMemberHireMerc( (UINT8)usVal );
}
else if ( cnt == 1 )
{
do
{
usVal = (UINT16)Random( 40 );
}
while( usVal != ub1 );
QuickSetupOfMercProfileItems( cnt, (UINT8)usVal );
QuickGameMemberHireMerc( (UINT8)usVal );
}
else if ( cnt == 2 )
{
do
{
usVal = (UINT16)Random( 40 );
}
while( usVal != ub1 && usVal != ub2 );
QuickSetupOfMercProfileItems( cnt, (UINT8)usVal );
QuickGameMemberHireMerc( (UINT8)usVal );
}
}
}
// TEMP FUNCTION!
void QuickSetupOfMercProfileItems( UINT32 uiCount, UINT8 ubProfileIndex )
{
// Quickly give some guys we hire some items
if ( uiCount == 0 )
{
//CreateGun( GLOCK_17, &(pSoldier->inv[ HANDPOS ] ) );
//gMercProfiles[ ubProfileIndex ].inv[ HANDPOS ] = HAND_GRENADE;
//gMercProfiles[ ubProfileIndex ].bInvStatus[ HANDPOS ] = 100;
//gMercProfiles[ ubProfileIndex ].bInvNumber[ HANDPOS ] = 3;
gMercProfiles[ ubProfileIndex ].inv[ HANDPOS ] = C7;
gMercProfiles[ ubProfileIndex ].bInvStatus[ HANDPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ HANDPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ BIGPOCK1POS ] = CAWS;
gMercProfiles[ ubProfileIndex ].bInvStatus[ BIGPOCK1POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ BIGPOCK1POS ] = 1;
gMercProfiles[ ubProfileIndex ].bSkillTrait = MARTIALARTS;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK3POS ] = KEY_2;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK3POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK3POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK5POS ] = LOCKSMITHKIT;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK5POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK5POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ BIGPOCK3POS ] = MEDICKIT;
gMercProfiles[ ubProfileIndex ].bInvStatus[ BIGPOCK3POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ BIGPOCK3POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ BIGPOCK4POS ] = SHAPED_CHARGE;
gMercProfiles[ ubProfileIndex ].bInvStatus[ BIGPOCK4POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ BIGPOCK4POS ] = 1;
// TEMP!
// make carman's opinion of us high!
gMercProfiles[ 78 ].bMercOpinion[ ubProfileIndex ] = 25;
}
else if ( uiCount == 1 )
{
gMercProfiles[ ubProfileIndex ].inv[ HANDPOS ] = CAWS;
gMercProfiles[ ubProfileIndex ].bInvStatus[ HANDPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ HANDPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK3POS ] = KEY_1;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK3POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK3POS ] = 1;
}
else if ( uiCount == 2 )
{
gMercProfiles[ ubProfileIndex ].inv[ HANDPOS ] = GLOCK_17;
gMercProfiles[ ubProfileIndex ].bInvStatus[ HANDPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ HANDPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SECONDHANDPOS ] = 5;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SECONDHANDPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SECONDHANDPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK1POS ] = SILENCER;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK1POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK1POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK2POS ] = SNIPERSCOPE;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK2POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK2POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK3POS ] = LASERSCOPE;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK3POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK3POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK5POS ] = BIPOD;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK5POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK5POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK6POS ] = LOCKSMITHKIT;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK6POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK6POS ] = 1;
}
else
{
gMercProfiles[ ubProfileIndex ].inv[ HANDPOS ] = (UINT8)Random(30);
gMercProfiles[ ubProfileIndex ].bInvNumber[ HANDPOS ] = 1;
}
gMercProfiles[ ubProfileIndex ].inv[ HELMETPOS ] = KEVLAR_HELMET;
gMercProfiles[ ubProfileIndex ].bInvStatus[ HELMETPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ HELMETPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ VESTPOS ] = KEVLAR_VEST;
gMercProfiles[ ubProfileIndex ].bInvStatus[ VESTPOS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ VESTPOS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ BIGPOCK2POS ] = RDX;
gMercProfiles[ ubProfileIndex ].bInvStatus[ BIGPOCK2POS ] = 10;
gMercProfiles[ ubProfileIndex ].bInvNumber[ BIGPOCK2POS ] = 1;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK4POS ] = HAND_GRENADE;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK4POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ SMALLPOCK4POS ] = 4;
// Give special items to some NPCs
//gMercProfiles[ 78 ].inv[ SMALLPOCK4POS ] = TERRORIST_INFO;
//gMercProfiles[ 78 ].bInvStatus[ SMALLPOCK4POS ] = 100;
//gMercProfiles[ 78 ].bInvNumber[ SMALLPOCK4POS ] = 1;
}
BOOLEAN QuickGameMemberHireMerc( UINT8 ubCurrentSoldier )
{
MERC_HIRE_STRUCT HireMercStruct;
memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT));
HireMercStruct.ubProfileID = ubCurrentSoldier;
HireMercStruct.sSectorX = gsMercArriveSectorX;
HireMercStruct.sSectorY = gsMercArriveSectorY;
HireMercStruct.fUseLandingZoneForArrival = TRUE;
HireMercStruct.fCopyProfileItemsOver = TRUE;
HireMercStruct.ubInsertionCode = INSERTION_CODE_CHOPPER;
HireMercStruct.iTotalContractLength = 7;
//specify when the merc should arrive
HireMercStruct.uiTimeTillMercArrives = 0;
//if we succesfully hired the merc
if( !HireMerc( &HireMercStruct ) )
{
return(FALSE);
}
//add an entry in the finacial page for the hiring of the merc
AddTransactionToPlayersBook(HIRED_MERC, ubCurrentSoldier, GetWorldTotalMin(), -(INT32) gMercProfiles[ubCurrentSoldier].uiWeeklySalary );
if( gMercProfiles[ ubCurrentSoldier ].bMedicalDeposit )
{
//add an entry in the finacial page for the medical deposit
AddTransactionToPlayersBook(MEDICAL_DEPOSIT, ubCurrentSoldier, GetWorldTotalMin(), -(gMercProfiles[ubCurrentSoldier].sMedicalDepositAmount) );
}
//add an entry in the history page for the hiring of the merc
AddHistoryToPlayersLog( HISTORY_HIRED_MERC_FROM_AIM, ubCurrentSoldier, GetWorldTotalMin(), -1, -1 );
return(TRUE);
}
//This function is called when the game is REstarted. Things that need to be reinited are placed in here
void ReStartingGame()
{
UINT16 cnt;
//Pause the game
gfGamePaused = TRUE;
//Reset the sectors
gWorldSectorX = gWorldSectorY = 0;
gbWorldSectorZ = -1;
SoundStopAll( );
//we are going to restart a game so initialize the variable so we can initialize a new game
InitNewGame( TRUE );
//Deletes all the Temp files in the Maps\Temp directory
InitTacticalSave( TRUE );
//Loop through all the soldier and delete them all
for( cnt=0; cnt< TOTAL_SOLDIERS; cnt++)
{
TacticalRemoveSoldier( cnt );
}
// Re-init overhead...
InitOverhead( );
//Reset the email list
ShutDownEmailList();
//Reinit the laptopn screen variables
InitLaptopAndLaptopScreens();
LaptopScreenInit();
//Reload the Merc profiles
LoadMercProfiles( );
// Reload quote files
ReloadAllQuoteFiles();
//Initialize the ShopKeeper Interface ( arms dealer inventory, etc. )
ShopKeeperScreenInit();
//Delete the world info
TrashWorld();
//Init the help screen system
InitHelpScreenSystem();
EmptyDialogueQueue( );
if ( InAirRaid( ) )
{
EndAirRaid( );
}
#ifdef JA2TESTVERSION
//Reset so we can use the 'cheat key' to start with mercs
TempHiringOfMercs( 0, TRUE );
#endif
//Make sure the game starts in the TEAM panel ( it wasnt being reset )
gsCurInterfacePanel = TEAM_PANEL;
//Delete all the strategic events
DeleteAllStrategicEvents();
//This function gets called when ur in a game a click the quit to main menu button, therefore no game is in progress
gTacticalStatus.fHasAGameBeenStarted = FALSE;
// Reset timer callbacks
gpCustomizableTimerCallback = NULL;
gubCheatLevel = STARTING_CHEAT_LEVEL;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef __GAME_INIT_H
#define __GAME_INIT_H
BOOLEAN InitNewGame( BOOLEAN fReset );
BOOLEAN AnyMercsHired( );
void QuickStartGame( );
void InitStrategicLayer();
void ShutdownStrategicLayer();
void ReStartingGame();
void InitBloodCatSectors();
#endif
+329
View File
@@ -0,0 +1,329 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "Assignments.h"
#include "Strategic Town Loyalty.h"
#include "Strategic Merc Handler.h"
#include "Strategic Mines.h"
#include "Campaign.h"
#include "Morale.h"
#include "Quests.h"
#include "Game Clock.h"
#endif
void HourlyQuestUpdate( void );
void HourlyLarryUpdate( void );
extern INT32 GetCurrentBalance( void );
extern void PayOffSkyriderDebtIfAny( );
void HourlyCheckIfSlayAloneSoHeCanLeave();
void UpdateRegenCounters( void );
void HandleMinuteUpdate()
{
}
// This function gets called every hour, on the hour.
// It spawns the handling of all sorts of stuff:
// Morale changes, assignment progress, town loyalties, etc.
void HandleHourlyUpdate()
{
//if the game hasnt even started yet ( we havent arrived in the sector ) dont process this
if ( DidGameJustStart() )
return;
// hourly update of town loyalty
HandleTownLoyalty();
// hourly update of team assignments
UpdateAssignments();
// hourly update of hated/liked mercs
UpdateBuddyAndHatedCounters();
// update morale!
HourlyMoraleUpdate();
// degrade camouflage
HourlyCamouflageUpdate();
// check mines for monster infestation/extermination
HourlyMinesUpdate();
// check how well the player is doing right now
HourlyProgressUpdate();
// do any quest stuff necessary
HourlyQuestUpdate();
HourlyLarryUpdate();
HourlyCheckIfSlayAloneSoHeCanLeave();
PayOffSkyriderDebtIfAny();
if ( GetWorldHour() % 6 == 0 ) // 4 times a day
{
UpdateRegenCounters();
}
}
void UpdateRegenCounters( void )
{
UINT8 ubID;
for ( ubID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubID <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubID++ )
{
if ( MercPtrs[ ubID ]->bRegenBoostersUsedToday > 0 )
{
MercPtrs[ ubID ]->bRegenBoostersUsedToday--;
}
}
}
void HandleQuarterHourUpdate()
{
//if the game hasnt even started yet ( we havent arrived in the sector ) dont process this
if ( DidGameJustStart() )
return;
DecayTacticalMoraleModifiers( );
}
void HourlyQuestUpdate( void )
{
UINT32 uiHour = GetWorldHour();
// brothel
if ( uiHour == 4 )
{
SetFactFalse( FACT_BROTHEL_OPEN );
}
else if ( uiHour == 20 )
{
SetFactTrue( FACT_BROTHEL_OPEN );
}
// bar/nightclub
if ( uiHour == 15 )
{
UINT8 ubLoop;
SetFactTrue( FACT_CLUB_OPEN );
SetFactFalse( FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED );
// reset boxes fought
for ( ubLoop = 0; ubLoop < NUM_BOXERS; ubLoop++ )
{
gfBoxerFought[ ubLoop ] = FALSE;
}
// if # of boxing matches the player has won is a multiple of
// 3, and the boxers haven't rested, then make them rest
if ( gfBoxersResting )
{
// done resting now!
gfBoxersResting = FALSE;
gubBoxersRests++;
}
else if ( gubBoxingMatchesWon / 3 > gubBoxersRests )
{
// time for the boxers to rest!
gfBoxersResting = TRUE;
}
}
else if ( uiHour == 2 )
{
SetFactFalse( FACT_CLUB_OPEN );
}
// museum
if ( uiHour == 9 )
{
SetFactTrue( FACT_MUSEUM_OPEN );
}
else if ( uiHour == 18 )
{
SetFactFalse( FACT_MUSEUM_OPEN );
}
}
#define BAR_TEMPTATION 4
#define NUM_LARRY_ITEMS 6
UINT16 LarryItems[ NUM_LARRY_ITEMS ][ 3 ] =
{
// item, temptation, points to use
{ ADRENALINE_BOOSTER, 5, 100 },
{ ALCOHOL, BAR_TEMPTATION, 25 },
{ MEDICKIT, 4, 10 },
{ WINE, 3, 50 },
{ REGEN_BOOSTER, 3, 100 },
{ BEER, 2, 100 },
};
#define LARRY_FALLS_OFF_WAGON 8
void HourlyLarryUpdate( void )
{
SOLDIERTYPE * pSoldier;
INT8 bSlot, bBoozeSlot;
INT8 bLarryItemLoop;
UINT16 usTemptation = 0;
UINT16 usCashAmount;
BOOLEAN fBar = FALSE;
pSoldier = FindSoldierByProfileID( LARRY_NORMAL, TRUE );
if ( !pSoldier )
{
pSoldier = FindSoldierByProfileID( LARRY_DRUNK, TRUE );
}
if ( pSoldier )
{
if ( pSoldier->bAssignment >= ON_DUTY )
{
return;
}
if ( pSoldier->fBetweenSectors )
{
return;
}
if ( pSoldier->bActive && pSoldier->bInSector && (gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN ) )
{
return;
}
// look for items in Larry's inventory to maybe use
for ( bLarryItemLoop = 0; bLarryItemLoop < NUM_LARRY_ITEMS; bLarryItemLoop++ )
{
bSlot = FindObj( pSoldier, LarryItems[ bLarryItemLoop ][ 0 ] );
if ( bSlot != NO_SLOT )
{
usTemptation = LarryItems[ bLarryItemLoop ][ 1 ];
break;
}
}
// check to see if we're in a bar sector, if we are, we have access to alcohol
// which may be better than anything we've got...
if ( usTemptation < BAR_TEMPTATION && GetCurrentBalance() >= Item[ ALCOHOL ].usPrice )
{
if ( pSoldier->bSectorZ == 0 &&
( ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_B) ||
( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_C) ||
( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_C) ||
( pSoldier->sSectorX == 6 && pSoldier->sSectorY == MAP_ROW_C) ||
( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_D) ||
( pSoldier->sSectorX == 2 && pSoldier->sSectorY == MAP_ROW_H)
)
)
{
// in a bar!
fBar = TRUE;
usTemptation = BAR_TEMPTATION;
}
}
if ( usTemptation > 0 )
{
if ( pSoldier->ubProfile == LARRY_NORMAL )
{
gMercProfiles[ LARRY_NORMAL ].bNPCData += (INT8) Random( usTemptation );
if ( gMercProfiles[ LARRY_NORMAL ].bNPCData >= LARRY_FALLS_OFF_WAGON )
{
if ( fBar )
{
// take $ from player's account
usCashAmount = Item[ ALCOHOL ].usPrice;
AddTransactionToPlayersBook ( TRANSFER_FUNDS_TO_MERC, pSoldier->ubProfile, GetWorldTotalMin() , -( usCashAmount ) );
// give Larry some booze and set slot etc values appropriately
bBoozeSlot = FindEmptySlotWithin( pSoldier, HANDPOS, SMALLPOCK8POS );
if ( bBoozeSlot != NO_SLOT )
{
// give Larry booze here
CreateItem( ALCOHOL, 100, &(pSoldier->inv[bBoozeSlot]) );
}
bSlot = bBoozeSlot;
bLarryItemLoop = 1;
}
// ahhhh!!!
SwapLarrysProfiles( pSoldier );
if ( bSlot != NO_SLOT )
{
UseKitPoints( &(pSoldier->inv[ bSlot ]), LarryItems[ bLarryItemLoop ][ 2 ], pSoldier );
}
}
}
else
{
// NB store all drunkenness info in LARRY_NORMAL profile (to use same values)
// so long as he keeps consuming, keep number above level at which he cracked
gMercProfiles[ LARRY_NORMAL ].bNPCData = __max( gMercProfiles[ LARRY_NORMAL ].bNPCData, LARRY_FALLS_OFF_WAGON );
gMercProfiles[ LARRY_NORMAL ].bNPCData += (INT8) Random( usTemptation );
// allow value to keep going up to 24 (about 2 days since we subtract Random( 2 ) when he has no access )
gMercProfiles[ LARRY_NORMAL ].bNPCData = __min( gMercProfiles[ LARRY_NORMAL ].bNPCData, 24 );
if ( fBar )
{
// take $ from player's account
usCashAmount = Item[ ALCOHOL ].usPrice;
AddTransactionToPlayersBook ( TRANSFER_FUNDS_TO_MERC, pSoldier->ubProfile, GetWorldTotalMin() , -( usCashAmount ) );
// give Larry some booze and set slot etc values appropriately
bBoozeSlot = FindEmptySlotWithin( pSoldier, HANDPOS, SMALLPOCK8POS );
if ( bBoozeSlot != NO_SLOT )
{
// give Larry booze here
CreateItem( ALCOHOL, 100, &(pSoldier->inv[bBoozeSlot]) );
}
bSlot = bBoozeSlot;
bLarryItemLoop = 1;
}
if ( bSlot != NO_SLOT )
{
// ahhhh!!!
UseKitPoints( &(pSoldier->inv[ bSlot ]), LarryItems[ bLarryItemLoop ][ 2 ], pSoldier );
}
}
}
else if ( pSoldier->ubProfile == LARRY_DRUNK )
{
gMercProfiles[ LARRY_NORMAL ].bNPCData -= (INT8) Random( 2 );
if ( gMercProfiles[ LARRY_NORMAL ].bNPCData <= 0 )
{
// goes sober!
SwapLarrysProfiles( pSoldier );
}
}
}
}
void HourlyCheckIfSlayAloneSoHeCanLeave()
{
SOLDIERTYPE *pSoldier;
pSoldier = FindSoldierByProfileID( SLAY, TRUE );
if( !pSoldier )
{
return;
}
if( pSoldier->fBetweenSectors )
{
return;
}
if( !pSoldier->bActive || !pSoldier->bLife )
{
return;
}
if( PlayerMercsInSector( (UINT8)pSoldier->sSectorX, (UINT8)pSoldier->sSectorY, pSoldier->bSectorZ ) == 1 )
{
if( Chance( 15 ) )
{
pSoldier->ubLeaveHistoryCode = HISTORY_SLAY_MYSTERIOUSLY_LEFT;
TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP, 0, 0 );
}
}
}
File diff suppressed because it is too large Load Diff
+265
View File
@@ -0,0 +1,265 @@
#ifndef __MAP_SCREEN_HELICOPTER_H
#define __MAP_SCREEN_HELICOPTER_H
#include "Types.h"
#include "Soldier Control.h"
// costs of flying through sectors
#define COST_AIRSPACE_SAFE 100
#define COST_AIRSPACE_UNSAFE 1000 // VERY dangerous
#define MIN_PROGRESS_FOR_SKYRIDER_QUOTE_DOING_WELL 25 // scale of 0-100
#define MIN_REGRESS_FOR_SKYRIDER_QUOTE_DOING_BADLY 10 // scale of 0-100
// skyrider quotes
#define OWED_MONEY_TO_SKYRIDER 11
#define MENTION_DRASSEN_SAM_SITE 20
#define SECOND_HALF_OF_MENTION_DRASSEN_SAM_SITE 21
#define SAM_SITE_TAKEN 22
#define SKYRIDER_SAYS_HI 23
#define SPIEL_ABOUT_OTHER_SAM_SITES 24
#define SECOND_HALF_OF_SPIEL_ABOUT_OTHER_SAM_SITES 25
#define SPIEL_ABOUT_ESTONI_AIRSPACE 26
#define CONFIRM_DESTINATION 27
//#define DESTINATION_TOO_FAR 28 // unused
#define ALTERNATE_FUEL_SITE 26
#define ARRIVED_IN_HOSTILE_SECTOR 29
#define BELIEVED_ENEMY_SECTOR 30 // may become unused
#define ARRIVED_IN_NON_HOSTILE_SECTOR 31
#define HOVERING_A_WHILE 32
#define RETURN_TO_BASE 33
#define ENEMIES_SPOTTED_EN_ROUTE_IN_FRIENDLY_SECTOR_A 34
#define ENEMIES_SPOTTED_EN_ROUTE_IN_FRIENDLY_SECTOR_B 35
#define MENTION_HOSPITAL_IN_CAMBRIA 45
#define THINGS_ARE_GOING_BADLY 46
#define THINGS_ARE_GOING_WELL 47
#define CHOPPER_NOT_ACCESSIBLE 48
#define DOESNT_WANT_TO_FLY 49
#define HELI_TOOK_MINOR_DAMAGE 52
#define HELI_TOOK_MAJOR_DAMAGE 53
#define HELI_GOING_DOWN 54
// enums for skyrider monologue
enum{
SKYRIDER_MONOLOGUE_EVENT_DRASSEN_SAM_SITE = 0,
SKYRIDER_MONOLOGUE_EVENT_OTHER_SAM_SITES,
SKYRIDER_MONOLOGUE_EVENT_ESTONI_REFUEL,
SKYRIDER_MONOLOGUE_EVENT_CAMBRIA_HOSPITAL,
};
enum
{
DRASSEN_REFUELING_SITE = 0,
ESTONI_REFUELING_SITE,
NUMBER_OF_REFUEL_SITES,
};
// the sam site enums
enum{
SAM_SITE_ONE = 0, // near Chitzena
SAM_SITE_TWO, // near Drassen
SAM_SITE_THREE, // near Cambria
SAM_SITE_FOUR, // near Meduna
NUMBER_OF_SAM_SITES,
};
// list of refueling site's sector locations
extern UINT8 ubRefuelList[ NUMBER_OF_REFUEL_SITES ][ 2 ];
// is the helicopter available to player?
extern BOOLEAN fHelicopterAvailable;
// helicopter vehicle id value
extern INT32 iHelicopterVehicleId;
// heli is hovering
extern BOOLEAN fHoveringHelicopter;
// helicopter icon
extern UINT32 guiHelicopterIcon;
// helicopter destroyed
extern BOOLEAN fHelicopterDestroyed;
// is the pilot returning straight to base?
extern BOOLEAN fHeliReturnStraightToBase;
// is the heli in the air?
extern BOOLEAN fHelicopterIsAirBorne;
// total distance travelled
//extern INT32 iTotalHeliDistanceSinceRefuel;
// total owed to player
//extern INT32 iTotalAccumlatedCostByPlayer;
// whether or not skyrider is alive and well? and on our side yet?
extern BOOLEAN fSkyRiderAvailable;
// time started hovering
extern UINT32 uiStartHoverTime;
// what state is skyrider's dialogue in in?
extern UINT32 guiHelicopterSkyriderTalkState;
// plot for helicopter
extern BOOLEAN fPlotForHelicopter;
// the flags for skyrider events
extern BOOLEAN fShowEstoniRefuelHighLight;
extern BOOLEAN fShowOtherSAMHighLight;
extern BOOLEAN fShowDrassenSAMHighLight;
extern BOOLEAN fShowCambriaHospitalHighLight;
extern INT32 iTotalAccumulatedCostByPlayer;
extern UINT32 guiTimeOfLastSkyriderMonologue;
extern BOOLEAN fSkyRiderSetUp;
extern BOOLEAN fRefuelingSiteAvailable[ NUMBER_OF_REFUEL_SITES ];
extern UINT8 gubHelicopterHitsTaken;
extern BOOLEAN gfSkyriderSaidCongratsOnTakingSAM;
extern UINT8 gubPlayerProgressSkyriderLastCommentedOn;
// add and remove grunts from the helicopter
BOOLEAN AddSoldierToHelicopter( SOLDIERTYPE *pSoldier );
BOOLEAN RemoveSoldierFromHelicopter( SOLDIERTYPE *pSoldier );
#ifdef JA2TESTVERSION
extern BOOLEAN fSAMSitesDisabledFromAttackingPlayer;
#endif
/* ARM: Max. fuel range system removed
// add another sector to how far helictoper has travelled
void AddSectorToHelicopterDistanceTravelled( void );
// total distance travelled since last refuel
INT32 HowFarHelicopterhasTravelledSinceRefueling( void );
// get the total the heli can go
INT32 GetTotalDistanceHelicopterCanTravel( void );
// how far can helicopter can travel before refuel
INT32 HowFurtherCanHelicopterTravel( void );
// check if this sector is out of the way
BOOLEAN IsSectorOutOfTheWay( INT16 sX, INT16 sY );
*/
// how far to nearest refuel point from this sector?
INT32 DistanceToNearestRefuelPoint( INT16 sX, INT16 sY );
// location of closest
INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ );
// refuel helicopter
void ReFuelHelicopter( void );
// how much will it cost for helicopter to travel through this sector?
INT32 GetCostOfPassageForHelicopter( INT16 sX, INT16 sY );
// helicopter shot down, kill all on board
void SkyriderDestroyed( void );
// have pilot say different stuff
void HelicopterDialogue( UINT8 ubDialogueCondition );
// is the helicopter available for flight?
BOOLEAN CanHelicopterFly( void );
// is the pilot alive and on our side?
BOOLEAN IsHelicopterPilotAvailable( void );
// land the helicopter here
void LandHelicopter( void );
// have helicopter take off
void TakeOffHelicopter( void );
// test whether or not a sector contains a fuel site
BOOLEAN IsRefuelSiteInSector( INT16 sMapX, INT16 sMapY );
// update which refueling sites are controlled by player & therefore available
void UpdateRefuelSiteAvailability( void );
// setup helicopter for player
void SetUpHelicopterForPlayer( INT16 sX, INT16 sY );
// the intended path of the helicopter
INT32 DistanceOfIntendedHelicopterPath( void );
// handle a little wait for hover
void HandleHeliHoverLong( void );
// handle a LONG wait in hover mode
void HandleHeliHoverTooLong( void );
// start the heli hover time
void StartHoverTime( void );
// drop off everyone in helicopter
void DropOffEveryOneInHelicopter( void );
// handle heli entering this sector
BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY );
// check for arrival at refuel
BOOLEAN CheckForArrivalAtRefuelPoint( void );
// set up helic, if it doesn't have a mvt group
void SetUpHelicopterForMovement( void );
// number of passengers in helicopter
INT32 GetNumberOfPassengersInHelicopter( void );
// skyrider talking to player
void SkyRiderTalk( UINT16 usQuoteNum );
// sky rider monlogue events for mapscreen
void HandleSkyRiderMonologueEvent( UINT32 uiEventCode, UINT32 uiSpecialCode );
// handle animation of sectors for mapscreen
void HandleAnimationOfSectors( void );
// check and handle skyrider monologue
void CheckAndHandleSkyriderMonologues( void );
// last sector value in helicopter's path
INT16 LastSectorInHelicoptersPath( void );
// total cost of helicopter trip
//INT32 GetTotalCostOfHelicopterTrip( void );
void HandleHelicopterOnGroundGraphic( void );
void HandleHelicopterOnGroundSkyriderProfile( void );
BOOLEAN IsHelicopterOnGroundAtRefuelingSite( UINT8 ubRefuelingSite );
BOOLEAN HandleSAMSiteAttackOfHelicopterInSector( INT16 sSectorX, INT16 sSectorY );
// is the helicopter capable of taking off for the player?
BOOLEAN CanHelicopterTakeOff( void );
void InitializeHelicopter( void );
BOOLEAN IsSkyriderIsFlyingInSector( INT16 sSectorX, INT16 sSectorY );
BOOLEAN IsGroupTheHelicopterGroup( GROUP *pGroup );
INT16 GetNumSafeSectorsInPath( void );
INT16 GetNumUnSafeSectorsInPath( void );
BOOLEAN SoldierAboardAirborneHeli( SOLDIERTYPE *pSoldier );
UINT8 MoveAllInHelicopterToFootMovementGroup( void );
#endif
File diff suppressed because it is too large Load Diff
+112
View File
@@ -0,0 +1,112 @@
#ifndef __MAP_INTERFACE_BORDER_H
#define __MAP_INTERFACE_BORDER_H
#include "Types.h"
#define MAP_BORDER_START_X 261
#define MAP_BORDER_START_Y 0
// scroll directions
enum{
ZOOM_MAP_SCROLL_UP =0,
ZOOM_MAP_SCROLL_DWN,
ZOOM_MAP_SCROLL_RIGHT,
ZOOM_MAP_SCROLL_LEFT,
};
enum{
EAST_DIR = 0,
WEST_DIR,
NORTH_DIR,
SOUTH_DIR,
};
enum{
MAP_BORDER_TOWN_BTN =0,
MAP_BORDER_MINE_BTN,
MAP_BORDER_TEAMS_BTN,
MAP_BORDER_AIRSPACE_BTN,
MAP_BORDER_ITEM_BTN,
MAP_BORDER_MILITIA_BTN,
};
/*
enum{
MAP_BORDER_RAISE_LEVEL=0,
MAP_BORDER_LOWER_LEVEL,
};
*/
#define MAP_LEVEL_MARKER_X 565
#define MAP_LEVEL_MARKER_Y 323
#define MAP_LEVEL_MARKER_DELTA 8
#define MAP_LEVEL_MARKER_WIDTH ( 620 - MAP_LEVEL_MARKER_X )
extern BOOLEAN fShowTownFlag;
extern BOOLEAN fShowMineFlag;
extern BOOLEAN fShowTeamFlag;
extern BOOLEAN fShowMilitia;
extern BOOLEAN fShowAircraftFlag;
extern BOOLEAN fShowItemsFlag;
extern BOOLEAN fZoomFlag;
//extern BOOLEAN fShowVehicleFlag;
//extern BOOLEAN fMapScrollDueToPanelButton;
//extern BOOLEAN fCursorIsOnMapScrollButtons;
//extern BOOLEAN fDisabledMapBorder;
// scroll animation
extern INT32 giScrollButtonState;
BOOLEAN LoadMapBorderGraphics( void );
void DeleteMapBorderGraphics( void );
void RenderMapBorder( void );
//void RenderMapBorderCorner( void );
//void ShowDestinationOfPlottedPath( STR16 pLoc );
//void ResetAircraftButton( void );
//void HandleMapScrollButtonStates( void );
void ToggleShowTownsMode( void );
void ToggleShowMinesMode( void );
void ToggleShowMilitiaMode( void );
void ToggleShowTeamsMode( void );
void ToggleAirspaceMode( void );
void ToggleItemsFilter( void );
void TurnOnShowTeamsMode( void );
void TurnOnAirSpaceMode( void );
void TurnOnItemFilterMode( void );
/*
// enable disable map border
void DisableMapBorderRegion( void );
void EnableMapBorderRegion( void );
*/
// create/destroy buttons for map border region
void DeleteMapBorderButtons( void );
BOOLEAN CreateButtonsForMapBorder( void );
// render the pop up for eta in path plotting in map screen
void RenderMapBorderEtaPopUp( void );
BOOLEAN DoesPlayerHaveAnyMilitia( void );
//void UpdateLevelButtonStates( void );
// create mouse regions for level markers
void CreateMouseRegionsForLevelMarkers( void );
void DeleteMouseRegionsForLevelMarkers( void );
void InitMapScreenFlags( void );
void MapBorderButtonOff( UINT8 ubBorderButtonIndex );
void MapBorderButtonOn( UINT8 ubBorderButtonIndex );
#endif
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
#ifndef __MAP_INTERFACE_BOTTOM
#define __MAP_INTERFACE_BOTTOM
#include "types.h"
#include "Soldier Control.h"
#define MAX_MESSAGES_ON_MAP_BOTTOM 9
// exit to where defines
enum{
MAP_EXIT_TO_LAPTOP = 0,
MAP_EXIT_TO_TACTICAL,
MAP_EXIT_TO_OPTIONS,
MAP_EXIT_TO_LOAD,
MAP_EXIT_TO_SAVE,
};
// there's no button for entering SAVE/LOAD screen directly...
extern UINT32 guiMapBottomExitButtons[ 3 ];
extern BOOLEAN fLapTop;
extern BOOLEAN fLeavingMapScreen;
extern BOOLEAN gfDontStartTransitionFromLaptop;
extern BOOLEAN gfStartMapScreenToLaptopTransition;
// function prototypes
BOOLEAN LoadMapScreenInterfaceBottom( void );
void DeleteMapScreenInterfaceBottom( void );
void DestroyButtonsForMapScreenInterfaceBottom( void );
BOOLEAN CreateButtonsForMapScreenInterfaceBottom( void );
void RenderMapScreenInterfaceBottom( void );
// delete map bottom graphics
void DeleteMapBottomGraphics( void );
// load bottom graphics
void HandleLoadOfMapBottomGraphics( void );
// allowed to time compress?
BOOLEAN AllowedToTimeCompress( void );
void EnableDisAbleMapScreenOptionsButton( BOOLEAN fEnable );
// create and destroy masks to cover the time compression buttons as needed
void CreateDestroyMouseRegionMasksForTimeCompressionButtons( void );
BOOLEAN CommonTimeCompressionChecks( void );
BOOLEAN AnyUsableRealMercenariesOnTeam( void );
void RequestTriggerExitFromMapscreen( INT8 bExitToWhere );
BOOLEAN AllowedToExitFromMapscreenTo( INT8 bExitToWhere );
void HandleExitsFromMapScreen( void );
void MapScreenMsgScrollDown( UINT8 ubLinesDown );
void MapScreenMsgScrollUp( UINT8 ubLinesUp );
void ChangeCurrentMapscreenMessageIndex( UINT8 ubNewMessageIndex );
void MoveToEndOfMapScreenMessageList( void );
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,60 @@
#ifndef _MAP_INTERFACE_MAP_INVEN_H
#define _MAP_INTERFACE_MAP_INVEN_H
#include "types.h"
#include "World Items.h"
// this is how close one has to be in the loaded sector to pickup an item
#define MAX_DISTANCE_TO_PICKUP_ITEM 5
// number of inventory slots
#define MAP_INVENTORY_POOL_SLOT_COUNT 45
// whether we are showing the inventory pool graphic
extern BOOLEAN fShowMapInventoryPool;
// load inventory pool graphic
BOOLEAN LoadInventoryPoolGraphic( void );
// remove inventory pool graphic
void RemoveInventoryPoolGraphic( void );
// blit the inventory graphic
void BlitInventoryPoolGraphic( void );
// which buttons in map invneotyr panel?
void HandleButtonStatesWhileMapInventoryActive( void );
// handle creation and destruction of map inventory pool buttons
void CreateDestroyMapInventoryPoolButtons( BOOLEAN fExitFromMapScreen );
// bail out of sector inventory mode if it is on
void CancelSectorInventoryDisplayIfOn( BOOLEAN fExitFromMapScreen );
INT32 GetSizeOfStashInSector( INT16 sMapX, INT16 sMapY, INT16 sMapZ, BOOLEAN fCountStacksAsOne );
// get total number of items in sector
INT32 GetTotalNumberOfItems( void );
// handle flash of inventory items
void HandleFlashForHighLightedItem( void );
// the list for the inventory
extern WORLDITEM *pInventoryPoolList;
// autoplace down object
BOOLEAN AutoPlaceObjectInInventoryStash( OBJECTTYPE *pItemPtr );
// the current inventory item
extern INT32 iCurrentlyHighLightedItem;
extern BOOLEAN fFlashHighLightInventoryItemOnradarMap;
extern INT16 sObjectSourceGridNo;
extern WORLDITEM *pInventoryPoolList;
extern INT32 iCurrentInventoryPoolPage;
extern BOOLEAN fMapInventoryItemCompatable[ ];
BOOLEAN IsMapScreenWorldItemInvisibleInMapInventory( WORLDITEM *pWorldItem );
BOOLEAN IsMapScreenWorldItemVisibleInMapInventory( WORLDITEM *pWorldItem );
#endif
File diff suppressed because it is too large Load Diff
+274
View File
@@ -0,0 +1,274 @@
#ifndef _MAP_SCREEN_INTERFACE_MAP_H
#define _MAP_SCREEN_INTERFACE_MAP_H
#include "Vehicles.h"
// functions
void DrawMapIndexBigMap( BOOLEAN fSelectedCursorIsYellow );
//void DrawMapIndexSmallMap( BOOLEAN fSelectedCursorIsYellow );
UINT32 DrawMap( void );
void GetScreenXYFromMapXY( INT16 sMapX, INT16 sMapY, INT16 *psX, INT16 *psY );
void GetScreenXYFromMapXYStationary( INT16 sMapX, INT16 sMapY, INT16 *psX, INT16 *psY );
BOOLEAN InitializePalettesForMap( void );
void ShutDownPalettesForMap( void );
// plot path for helicopter
void PlotPathForHelicopter( INT16 sX, INT16 sY );
// the temp path, where the helicopter could go
void PlotATemporaryPathForHelicopter( INT16 sX, INT16 sY );
// trace a route for a passed path...doesn't require dest char - most more general
BOOLEAN TracePathRoute( BOOLEAN fCheckFlag, BOOLEAN fForceUpDate, PathStPtr pPath );
// show arrows for this char
void DisplayPathArrows(UINT16 usCharNum, HVOBJECT hMapHandle);
// restore backgrounds for arrows
void RestoreArrowBackgroundsForTrace(INT32 iArrow, INT32 iArrowX, INT32 iArrowY, BOOLEAN fZoom);
// build path for character
void PlotPathForCharacter( SOLDIERTYPE *pCharacter, INT16 sX, INT16 sY, BOOLEAN fTacticalTraversal );
// build temp path for character
void PlotATemporaryPathForCharacter( SOLDIERTYPE *pCharacter, INT16 sX, INT16 sY );
// display current/temp paths
void DisplaySoldierPath( SOLDIERTYPE *pCharacter );
void DisplaySoldierTempPath( SOLDIERTYPE *pCharacter );
void DisplayHelicopterPath( void );
void DisplayHelicopterTempPath( void );
// clear path after this sector
UINT32 ClearPathAfterThisSectorForCharacter( SOLDIERTYPE *pCharacter, INT16 sX, INT16 sY );
// cancel path : clear the path completely and gives player feedback message that the route was canceled
void CancelPathForCharacter( SOLDIERTYPE *pCharacter );
void CancelPathForVehicle( VEHICLETYPE *pVehicle, BOOLEAN fAlreadyReversed );
void CancelPathForGroup( GROUP *pGroup );
// check if we have waited long enought o update temp path
void DisplayThePotentialPathForHelicopter(INT16 sMapX, INT16 sMapY );
// clear out helicopter list after this sector
UINT32 ClearPathAfterThisSectorForHelicopter( INT16 sX, INT16 sY );
// check to see if sector is highlightable
BOOLEAN IsTheCursorAllowedToHighLightThisSector( INT16 sSectorX, INT16 sSectorY );
// set bad sectors list
void SetUpBadSectorsList( void );
// restore background for map grids
void RestoreBackgroundForMapGrid( INT16 sMapX, INT16 sMapY );
// clip blits to map view region
void ClipBlitsToMapViewRegion( void );
void ClipBlitsToMapViewRegionForRectangleAndABit( UINT32 uiDestPitchBYTES );
// clip blits to full screen....restore after use of ClipBlitsToMapViewRegion( )
void RestoreClipRegionToFullScreen( void );
void RestoreClipRegionToFullScreenForRectangle( UINT32 uiDestPitchBYTES );
// show the icons for people in motion
void ShowPeopleInMotion( INT16 sX, INT16 sY );
// last sector in helicopter's path
INT16 GetLastSectorOfHelicoptersPath( void );
// display info about helicopter path
void DisplayDistancesForHelicopter( void );
// display where hei is
void DisplayPositionOfHelicopter( void );
// check for click
BOOLEAN CheckForClickOverHelicopterIcon( INT16 sX, INT16 sY );
// show town markers
void BlitTownGridMarkers( void );
// load and delete the graphics for the map screen map militia
BOOLEAN LoadMilitiaPopUpBox( void );
void RemoveMilitiaPopUpBox( void );
// check if anyone left behind, if not, move selected cursor along with movement group
//void CheckIfAnyoneLeftInSector( INT16 sX, INT16 sY, INT16 sNewX, INT16 sNewY, INT8 bZ );
// grab the total number of militia in sector
INT32 GetNumberOfMilitiaInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// create destroy
void CreateDestroyMilitiaPopUPRegions( void );
// draw the militia box
BOOLEAN DrawMilitiaPopUpBox( void );
//Returns true if the player knows how many enemies are in the sector if that number is greater than 0.
//Returns false for all other cases.
UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
//There is a 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. This is the function that clears that
//flag.
void ClearAnySectorsFlashingNumberOfEnemies();
void CopyPathToCharactersSquadIfInOne( SOLDIERTYPE *pCharacter );
void InitMapSecrets( void );
enum {
ABORT_PLOTTING = 0,
PATH_CLEARED,
PATH_SHORTENED,
};
// what the player knows about the enemies in a given sector
enum {
KNOWS_NOTHING = 0,
KNOWS_THEYRE_THERE,
KNOWS_HOW_MANY,
};
// size of squares on the map
#define MAP_GRID_X 21
#define MAP_GRID_Y 18
// scroll bounds
#define EAST_ZOOM_BOUND 378
#define WEST_ZOOM_BOUND 42
#define SOUTH_ZOOM_BOUND 324
#define NORTH_ZOOM_BOUND 36
// map view region
#define MAP_VIEW_START_X 270
#define MAP_VIEW_START_Y 10
#define MAP_VIEW_WIDTH 336
#define MAP_VIEW_HEIGHT 298
// zoomed in grid sizes
#define MAP_GRID_ZOOM_X MAP_GRID_X*2
#define MAP_GRID_ZOOM_Y MAP_GRID_Y*2
// number of units wide
#define WORLD_MAP_X 18
// dirty regions for the map
#define DMAP_GRID_X ( MAP_GRID_X + 1 )
#define DMAP_GRID_Y ( MAP_GRID_Y + 1 )
#define DMAP_GRID_ZOOM_X ( MAP_GRID_ZOOM_X+1)
#define DMAP_GRID_ZOOM_Y ( MAP_GRID_ZOOM_Y+1)
// Orta position on the map
#define ORTA_SECTOR_X 4
#define ORTA_SECTOR_Y 11
#define TIXA_SECTOR_X 9
#define TIXA_SECTOR_Y 10
// what are we showing?..teams/vehicles
// Show values
#define SHOW_TEAMMATES 1
#define SHOW_VEHICLES 2
// wait time until temp path is drawn, from placing cursor on a map grid
#define MIN_WAIT_TIME_FOR_TEMP_PATH 200
// zoom UL coords
extern INT32 iZoomX;
extern INT32 iZoomY;
// the number of militia on the cursor
extern INT16 sGreensOnCursor;
extern INT16 sRegularsOnCursor;
extern INT16 sElitesOnCursor;
// highlighted sectors
extern INT16 gsHighlightSectorX;
extern INT16 gsHighlightSectorY;
// the big map
extern UINT32 guiBIGMAP;
// the orta icon
extern UINT32 guiORTAICON;
extern UINT32 guiTIXAICON;
// the character icons
extern UINT32 guiCHARICONS;
// the merc arrival sector landing zone icon
extern UINT32 guiBULLSEYE;
// character between sector icons
extern UINT32 guiCHARBETWEENSECTORICONS;
extern UINT32 guiCHARBETWEENSECTORICONSCLOSE;
// the viewable map bound region
extern SGPRect MapScreenRect;
// draw temp path
extern BOOLEAN fDrawTempHeliPath;
// selected destination char
extern INT8 bSelectedDestChar;
// current assignment character
extern INT8 bSelectedAssignChar;
// the info character
extern INT8 bSelectedInfoChar;
// the contract char
extern INT8 bSelectedContractChar;
// map arrows graphical index value
extern UINT32 guiMAPCURSORS;
// has temp path for character path or helicopter been already drawn
extern BOOLEAN fTempPathAlreadyDrawn;
// map view region clipping rect
extern SGPRect MapScreenRect;
// the map border eta pop up
extern UINT32 guiMapBorderEtaPopUp;
// heli pop up
extern UINT32 guiMapBorderHeliSectors;
// the currently selected town militia
extern INT16 sSelectedMilitiaTown;
// the selected sectors
extern UINT16 sSelMapX;
extern UINT16 sSelMapY;
extern BOOLEAN fFoundTixa;
extern UINT32 guiSubLevel1, guiSubLevel2, guiSubLevel3;
extern INT16 sBaseSectorList[12];
extern POINT pTownPoints[13];
#endif
@@ -0,0 +1,922 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#include "HelpScreen.h"
#else
#include "Map Screen Interface TownMine Info.h"
#include "strategicmap.h"
#include "popupbox.h"
#include "Map Screen Interface.h"
#include "Queen Command.h"
#include "Player Command.h"
#include "Font Control.h"
#include "Font.h"
#include "Text.h"
#include "Map Screen Interface Map.h"
#include "Map Screen Interface Border.h"
#include "Handle UI.h"
#include "NPC.h"
#include "Strategic Town Loyalty.h"
#include "Strategic Mines.h"
#include "finances.h"
#include "Map Screen Interface Map Inventory.h"
#include "Strategic.h"
#include "Utilities.h"
#include "video.h"
#include "Town Militia.h"
#include "HelpScreen.h"
#endif
#define BOX_BUTTON_WIDTH 100
#define BOX_BUTTON_HEIGHT 20
// flag to say if we are showing town/mine box at all
BOOLEAN fShowTownInfo = FALSE;
INT32 ghTownMineBox = -1;
SGPPoint TownMinePosition ={ 300, 150 };
SGPRect TownMineDimensions ={ 0, 0, 240, 60 };
INT8 bCurrentTownMineSectorX = 0;
INT8 bCurrentTownMineSectorY = 0;
INT8 bCurrentTownMineSectorZ = 0;
// inventory button
UINT32 guiMapButtonInventoryImage[2];
UINT32 guiMapButtonInventory[2];
UINT16 sTotalButtonWidth = 0;
extern MINE_LOCATION_TYPE gMineLocation[];
extern MINE_STATUS_TYPE gMineStatus[];
extern BOOLEAN fMapScreenBottomDirty;
//extern UINT8 gubMonsterMineInfestation[];
// create the town/mine info box
void CreateTownInfoBox( void );
// add town text to town info box
void AddTextToTownBox( void );
// add text to mine info box
void AddTextToMineBox( void );
// add text to non-town/non-mine the other boxes
void AddTextToBlankSectorBox( void );
// add "sector" line text to any popup box
void AddSectorToBox(void);
void AddCommonInfoToBox(void);
void AddItemsInSectorToBox(void);
// position town/mine info box on the screen
void PositionTownMineInfoBox( void );
// add the pop up button for the map inventory pop up activation
void AddInventoryButtonForMapPopUpBox( void );
// now remove the above button
void RemoveInventoryButtonForMapPopUpBox( void );
// callback to turn on sector invneotry list
void MapTownMineInventoryButtonCallBack( GUI_BUTTON *btn, INT32 reason );
void MapTownMineExitButtonCallBack( GUI_BUTTON *btn, INT32 reason );
void MinWidthOfTownMineInfoBox( void );
void DisplayTownInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
// will display town info for a particular town
// set current sector
if( ( bCurrentTownMineSectorX != sMapX ) || ( bCurrentTownMineSectorY != sMapY ) || ( bCurrentTownMineSectorZ != bMapZ ) )
{
bCurrentTownMineSectorX = ( INT8 )sMapX;
bCurrentTownMineSectorY = ( INT8 )sMapY;
bCurrentTownMineSectorZ = bMapZ;
}
//create destroy the box
CreateDestroyTownInfoBox( );
}
void CreateDestroyTownInfoBox( void )
{
// create destroy pop up box for town/mine info
static BOOLEAN fCreated = FALSE;
SGPRect pDimensions;
SGPPoint pPosition;
INT16 sButtonX = 0, sButtonY = 0;
INT8 bTownId = 0;
if( ( fCreated == FALSE ) && ( fShowTownInfo == TRUE ) )
{
// create pop up box
CreateTownInfoBox( );
// decide what kind of text to add to display
if ( bCurrentTownMineSectorZ == 0 )
{
// only show the mine info when mines button is selected, otherwise we need to see the sector's regular town info
if ( ( IsThereAMineInThisSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) == TRUE) && fShowMineFlag )
{
AddTextToMineBox( );
}
else
{
bTownId = GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
// do we add text for the town box?
if( bTownId != BLANK_SECTOR )
{
// add text for town box
AddTextToTownBox( );
}
else
{
// just a blank sector (handles SAM sites if visible)
AddTextToBlankSectorBox( );
}
}
// add "militia", "militia training", "control" "enemy forces", etc. lines text to any popup box
AddCommonInfoToBox();
}
else // underground
{
// sector
AddSectorToBox();
}
AddItemsInSectorToBox();
// set font type
SetBoxFont(ghTownMineBox, BLOCKFONT2);
// set highlight color
SetBoxHighLight(ghTownMineBox, FONT_WHITE);
SetBoxSecondColumnForeground( ghTownMineBox, FONT_WHITE );
SetBoxSecondColumnBackground( ghTownMineBox, FONT_BLACK );
SetBoxSecondColumnHighLight( ghTownMineBox, FONT_WHITE );
SetBoxSecondColumnShade( ghTownMineBox, FONT_BLACK );
SetBoxSecondColumnFont( ghTownMineBox, BLOCKFONT2 );
SetBoxSecondColumnMinimumOffset( ghTownMineBox, 20 );
// unhighlighted color
SetBoxForeground(ghTownMineBox, FONT_YELLOW);
// background color
SetBoxBackground(ghTownMineBox, FONT_BLACK);
// shaded color..for darkened text
SetBoxShade( ghTownMineBox, FONT_BLACK );
// give title line (0) different color from the rest
SetBoxLineForeground( ghTownMineBox, 0, FONT_LTGREEN );
// ressize box to text
ResizeBoxToText( ghTownMineBox );
// make box bigger to this size
GetBoxSize( ghTownMineBox , &pDimensions );
if( pDimensions.iRight < BOX_BUTTON_WIDTH )
{
// resize box to fit button
pDimensions.iRight += BOX_BUTTON_WIDTH;
}
pDimensions.iBottom += BOX_BUTTON_HEIGHT;
SetBoxSize( ghTownMineBox, pDimensions );
ShowBox( ghTownMineBox );
// now position box
MinWidthOfTownMineInfoBox( );
PositionTownMineInfoBox( );
// now add the button
AddInventoryButtonForMapPopUpBox( );
// now position box
PositionTownMineInfoBox( );
fCreated = TRUE;
}
else if( ( fCreated == TRUE ) && ( fShowTownInfo == FALSE ) )
{
// get box size
GetBoxSize( ghTownMineBox, &pDimensions );
// get position
GetBoxPosition( ghTownMineBox, &pPosition);
// destroy pop up box
RemoveBox( ghTownMineBox );
ghTownMineBox = -1;
// remove inventory button
RemoveInventoryButtonForMapPopUpBox( );
// restore background
RestoreExternBackgroundRect( ( INT16 )pPosition.iX, ( INT16 )pPosition.iY, ( INT16 ) ( pDimensions.iRight - pDimensions.iLeft ), ( INT16 ) ( pDimensions.iBottom - pDimensions.iTop + 3 ) );
fCreated = FALSE;
}
return;
}
void CreateTownInfoBox( void )
{
// create basic box
CreatePopUpBox(&ghTownMineBox, TownMineDimensions, TownMinePosition, (POPUP_BOX_FLAG_CLIP_TEXT ));
// which buffer will box render to
SetBoxBuffer(ghTownMineBox, FRAME_BUFFER);
// border type?
SetBorderType(ghTownMineBox, guiPOPUPBORDERS);
// background texture
SetBackGroundSurface(ghTownMineBox, guiPOPUPTEX);
// margin sizes
SetMargins(ghTownMineBox, 6,6,8,6);
// space between lines
SetLineSpace(ghTownMineBox, 2);
// set current box to this one
SetCurrentBox( ghTownMineBox );
return;
}
// adds text to town info box
void AddTextToTownBox( void )
{
UINT32 hStringHandle = 0;
CHAR16 wString[ 64 ];
UINT8 ubTownId = 0;
UINT16 usTownSectorIndex;
INT16 sMineSector = 0;
// remember town id
ubTownId = GetTownIdForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
Assert((ubTownId >= FIRST_TOWN) && (ubTownId < NUM_TOWNS));
usTownSectorIndex = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
switch( usTownSectorIndex )
{
case SEC_B13:
AddMonoString( &hStringHandle, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] );
break;
case SEC_F8:
AddMonoString( &hStringHandle, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] );
break;
case SEC_J9: //Tixa
if( !fFoundTixa )
AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] );
else
AddMonoString( &hStringHandle, pTownNames[ TIXA ] );
break;
case SEC_K4: //Orta
if( !fFoundOrta )
AddMonoString( &hStringHandle, pLandTypeStrings[ SWAMP ] );
else
AddMonoString( &hStringHandle, pTownNames[ ORTA ] );
break;
case SEC_N3:
AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] );
break;
default:
if( usTownSectorIndex == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] )
{ //Meduna's SAM site
AddMonoString( &hStringHandle, pLandTypeStrings[ MEDUNA_SAM_SITE ] );
}
else
{ // town name
swprintf( wString, L"%s", pTownNames[ ubTownId ] );
AddMonoString( &hStringHandle, wString );
}
break;
}
// blank line
AddMonoString( &hStringHandle, L"" );
// sector
AddSectorToBox();
// town size
swprintf( wString, L"%s:", pwTownInfoStrings[ 0 ] );
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d", GetTownSectorSize( ubTownId ) );
AddSecondColumnMonoString( &hStringHandle, wString );
// main facilities
swprintf( wString, L"%s:", pwTownInfoStrings[ 8 ] );
AddMonoString( &hStringHandle, wString );
wcscpy(wString, L"");
GetSectorFacilitiesFlags( bCurrentTownMineSectorX, bCurrentTownMineSectorY, wString );
AddSecondColumnMonoString( &hStringHandle, wString );
// the concept of control is only meaningful in sectors where militia can be trained
if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) )
{
// town control
swprintf( wString, L"%s:", pwTownInfoStrings[ 2 ] );
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( ubTownId ) * 100) / GetTownSectorSize( ubTownId ));
AddSecondColumnMonoString( &hStringHandle, wString );
}
// the concept of town loyalty is only meaningful in towns where loyalty is tracked
if( gTownLoyalty[ ubTownId ].fStarted && gfTownUsesLoyalty[ ubTownId ])
{
// town loyalty
swprintf( wString, L"%s:", pwTownInfoStrings[ 5 ] );
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", gTownLoyalty[ ubTownId ].ubRating );
AddSecondColumnMonoString( &hStringHandle, wString );
}
// if the town has a mine
sMineSector = GetMineSectorForTown( ubTownId );
if( sMineSector != -1 )
{
// Associated Mine: Sector
swprintf( wString, L"%s:", pwTownInfoStrings[ 4 ] );
AddMonoString( &hStringHandle, wString );
GetShortSectorString( ( INT16 )( sMineSector % MAP_WORLD_X ), ( INT16 )( sMineSector / MAP_WORLD_X ), wString );
AddSecondColumnMonoString( &hStringHandle, wString );
}
}
// adds text to mine info box
void AddTextToMineBox( void )
{
UINT8 ubMineIndex;
UINT8 ubTown;
UINT32 hStringHandle;
CHAR16 wString[ 64 ];
ubMineIndex = GetMineIndexForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
// name of town followed by "mine"
swprintf( wString, L"%s %s", pTownNames[ GetTownAssociatedWithMine( ubMineIndex ) ], pwMineStrings[ 0 ] );
AddMonoString( &hStringHandle, wString );
// blank line
AddMonoString( &hStringHandle, L"" );
// sector
AddSectorToBox();
// mine status
swprintf( wString, L"%s:", pwMineStrings[ 9 ]);
AddMonoString( &hStringHandle, wString );
// check if mine is empty (abandoned) or running out
if (gMineStatus[ ubMineIndex ].fEmpty)
{
// abandonded
wcscpy( wString, pwMineStrings[ 5 ] );
}
else
if (gMineStatus[ ubMineIndex ].fShutDown)
{
// shut down
wcscpy( wString, pwMineStrings[ 6 ] );
}
else
if (gMineStatus[ ubMineIndex ].fRunningOut)
{
// running out
wcscpy( wString, pwMineStrings[ 7 ] );
}
else
{
// producing
wcscpy( wString, pwMineStrings[ 8 ] );
}
AddSecondColumnMonoString( &hStringHandle, wString );
// if still producing
if (!gMineStatus[ ubMineIndex ].fEmpty)
{
// current production
swprintf( wString, L"%s:", pwMineStrings[ 3 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d", PredictDailyIncomeFromAMine( ubMineIndex ) );
InsertCommasForDollarFigure( wString );
InsertDollarSignInToString( wString );
AddSecondColumnMonoString( &hStringHandle, wString );
// potential production
swprintf( wString, L"%s:", pwMineStrings[ 4 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d", GetMaxDailyRemovalFromMine( ubMineIndex ) );
InsertCommasForDollarFigure( wString );
InsertDollarSignInToString( wString );
AddSecondColumnMonoString( &hStringHandle, wString );
// if potential is not nil
if (GetMaxPeriodicRemovalFromMine(ubMineIndex) > 0)
{
// production rate (current production as a percentage of potential production)
swprintf( wString, L"%s:", pwMineStrings[ 10 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", (PredictDailyIncomeFromAMine(ubMineIndex) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
AddSecondColumnMonoString( &hStringHandle, wString );
}
// town control percentage
swprintf( wString, L"%s:", pwMineStrings[ 12 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( gMineLocation[ ubMineIndex ].bAssociatedTown ) * 100) / GetTownSectorSize( gMineLocation[ ubMineIndex ].bAssociatedTown ));
AddSecondColumnMonoString( &hStringHandle, wString );
ubTown = gMineLocation[ ubMineIndex ].bAssociatedTown;
if( gTownLoyalty[ ubTown ].fStarted && gfTownUsesLoyalty[ ubTown ])
{
// town loyalty percentage
swprintf( wString, L"%s:", pwMineStrings[ 13 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", gTownLoyalty[ gMineLocation[ ubMineIndex ].bAssociatedTown ].ubRating);
AddSecondColumnMonoString( &hStringHandle, wString );
}
/* gradual monster infestation concept was ditched, now simply IN PRODUCTION or SHUT DOWN
// percentage of miners working
swprintf( wString, L"%s:", pwMineStrings[ 14 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", gubMonsterMineInfestation[ gMineStatus[ ubMineIndex ].bMonsters ]);
AddSecondColumnMonoString( &hStringHandle, wString );
*/
// ore type (silver/gold
swprintf( wString, L"%s:", pwMineStrings[ 11 ]);
AddMonoString( &hStringHandle, wString );
AddSecondColumnMonoString( &hStringHandle, (gMineStatus[ubMineIndex].ubMineType == SILVER_MINE) ? pwMineStrings[ 1 ] : pwMineStrings[ 2 ] );
}
#ifdef _DEBUG
// dollar amount remaining in mine
wcscpy( wString, L"Remaining (DEBUG):");
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d", GetTotalLeftInMine( ubMineIndex ) );
InsertCommasForDollarFigure( wString );
InsertDollarSignInToString( wString );
AddSecondColumnMonoString( &hStringHandle, wString );
#endif
}
void AddTextToBlankSectorBox( void )
{
UINT32 hStringHandle;
UINT16 usSectorValue = 0;
// get the sector value
usSectorValue = SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
switch( usSectorValue )
{
case SEC_D2: //Chitzena SAM
if( !fSamSiteFound[ SAM_SITE_ONE ] )
AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS ] );
else
AddMonoString( &hStringHandle, pLandTypeStrings[ TROPICS_SAM_SITE ] );
break;
case SEC_D15: //Drassen SAM
if( !fSamSiteFound[ SAM_SITE_TWO ] )
AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE ] );
else
AddMonoString( &hStringHandle, pLandTypeStrings[ SPARSE_SAM_SITE ] );
break;
case SEC_I8: //Cambria SAM
if( !fSamSiteFound[ SAM_SITE_THREE ] )
AddMonoString( &hStringHandle, pLandTypeStrings[ SAND ] );
else
AddMonoString( &hStringHandle, pLandTypeStrings[ SAND_SAM_SITE ] );
break;
// SAM Site 4 in Meduna is within town limits, so it's handled in AddTextToTownBox()
default:
AddMonoString( &hStringHandle, pLandTypeStrings[ ( SectorInfo[ usSectorValue ].ubTraversability[ 4 ] ) ] );
break;
}
// blank line
AddMonoString( &hStringHandle, L"" );
// sector
AddSectorToBox();
}
void AddSectorToBox(void)
{
CHAR16 wString[ 64 ];
CHAR16 wString2[ 10 ];
UINT32 hStringHandle = 0;
// sector
swprintf( wString, L"%s:", pwMiscSectorStrings[ 1 ]);
AddMonoString( &hStringHandle, wString );
GetShortSectorString( bCurrentTownMineSectorX, bCurrentTownMineSectorY, wString );
if (bCurrentTownMineSectorZ != 0 )
{
swprintf( wString2, L"-%d", bCurrentTownMineSectorZ );
wcscat( wString, wString2 );
}
AddSecondColumnMonoString( &hStringHandle, wString );
}
void AddCommonInfoToBox(void)
{
CHAR16 wString[ 64 ];
UINT32 hStringHandle = 0;
BOOLEAN fUnknownSAMSite = FALSE;
UINT8 ubMilitiaTotal = 0;
UINT8 ubNumEnemies;
switch( SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
{
case SEC_D2: //Chitzena SAM
if( !fSamSiteFound[ SAM_SITE_ONE ] )
fUnknownSAMSite = TRUE;
break;
case SEC_D15: //Drassen SAM
if( !fSamSiteFound[ SAM_SITE_TWO ] )
fUnknownSAMSite = TRUE;
break;
case SEC_I8: //Cambria SAM
if( !fSamSiteFound[ SAM_SITE_THREE ] )
fUnknownSAMSite = TRUE;
break;
// SAM Site 4 in Meduna is within town limits, so it's always controllable
default:
break;
}
// in sector where militia can be trained,
// control of the sector matters, display who controls this sector. Map brightness no longer gives this!
if ( MilitiaTrainingAllowedInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, 0 ) && !fUnknownSAMSite )
{
// controlled:
swprintf( wString, L"%s:", pwMiscSectorStrings[ 4 ] );
AddMonoString( &hStringHandle, wString );
// No/Yes
swprintf( wString, L"%s", pwMiscSectorStrings[ ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ].fEnemyControlled ) ? 6 : 5 ] );
AddSecondColumnMonoString( &hStringHandle, wString );
// militia - is there any?
swprintf( wString, L"%s:", pwTownInfoStrings[ 11 ] );
AddMonoString( &hStringHandle, wString );
ubMilitiaTotal = CountAllMilitiaInSector(bCurrentTownMineSectorX, bCurrentTownMineSectorY);
if (ubMilitiaTotal > 0)
{
// some militia, show total & their breakdown by level
swprintf( wString, L"%d (%d/%d/%d)", ubMilitiaTotal,
MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, GREEN_MILITIA),
MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, REGULAR_MILITIA),
MilitiaInSectorOfRank(bCurrentTownMineSectorX, bCurrentTownMineSectorY, ELITE_MILITIA));
AddSecondColumnMonoString( &hStringHandle, wString );
}
else
{
// no militia: don't bother displaying level breakdown
wcscpy( wString, L"0");
AddSecondColumnMonoString( &hStringHandle, wString );
}
// 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 );
}
// enemy forces
swprintf( wString, L"%s:", pwMiscSectorStrings[ 0 ] );
AddMonoString( &hStringHandle, wString );
// how many are there, really?
ubNumEnemies = NumEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
switch ( WhatPlayerKnowsAboutEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
{
case KNOWS_NOTHING:
// show "Unknown"
wcscpy(wString, pwMiscSectorStrings[ 3 ] );
break;
case KNOWS_THEYRE_THERE:
// if there are any there
if ( ubNumEnemies > 0 )
{
// show "?", but not exactly how many
wcscpy(wString, L"?" );
}
else
{
// we know there aren't any (or we'd be seing them on map, too)
wcscpy(wString, L"0" );
}
break;
case KNOWS_HOW_MANY:
// show exactly how many
swprintf( wString, L"%d", ubNumEnemies );
break;
}
AddSecondColumnMonoString( &hStringHandle, wString );
}
void AddItemsInSectorToBox(void)
{
CHAR16 wString[ 64 ];
UINT32 hStringHandle = 0;
// items in sector (this works even for underground)
swprintf( wString, L"%s:", pwMiscSectorStrings[ 2 ] );
AddMonoString( &hStringHandle, wString );
// swprintf( wString, L"%d", GetSizeOfStashInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, bCurrentTownMineSectorZ, FALSE ));
swprintf( wString, L"%d", GetNumberOfVisibleWorldItemsFromSectorStructureForSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY, bCurrentTownMineSectorZ ));
AddSecondColumnMonoString( &hStringHandle, wString );
}
void PositionTownMineInfoBox( void )
{
// position town mine info box
SGPRect pDimensions;
SGPPoint pPosition;
INT16 sX =0, sY = 0;
INT16 sNewMargin = 0;
// position the box based on x and y of the selected sector
GetScreenXYFromMapXY( bCurrentTownMineSectorX, bCurrentTownMineSectorY, &sX, &sY);
// set box position
pPosition.iX = sX;
pPosition.iY = sY;
// set new position
SetBoxPosition( ghTownMineBox, pPosition );
// get box size
GetBoxSize( ghTownMineBox, &pDimensions );
// get position
GetBoxPosition( ghTownMineBox, &pPosition);
if( pDimensions.iRight < ( sTotalButtonWidth + 30 ) )
{
SpecifyBoxMinWidth( ghTownMineBox, ( sTotalButtonWidth + 30 ) );
pDimensions.iRight = sTotalButtonWidth + 30;
}
// now position box - the x axis
if( pPosition.iX < MapScreenRect.iLeft )
{
pPosition.iX = MapScreenRect.iLeft + 5;
}
if( pPosition.iX + pDimensions.iRight > MapScreenRect.iRight )
{
pPosition.iX = MapScreenRect.iRight - pDimensions.iRight - 5;
}
// position - the y axis
if( pPosition.iY < MapScreenRect.iTop )
{
pPosition.iY = MapScreenRect.iTop + 5;
}
if( pPosition.iY + pDimensions.iBottom > MapScreenRect.iBottom )
{
pPosition.iY = MapScreenRect.iBottom - pDimensions.iBottom - 8;
}
// reset position
SetBoxPosition( ghTownMineBox, pPosition );
return;
}
void AddInventoryButtonForMapPopUpBox( void )
{
INT16 sX, sY;
SGPRect pDimensions;
SGPPoint pPosition;
VOBJECT_DESC VObjectDesc;
UINT32 uiObject;
ETRLEObject *pTrav;
INT16 sWidthA = 0, sWidthB = 0, sTotalBoxWidth = 0;
HVOBJECT hHandle;
// load the button
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\mapinvbtns.sti", VObjectDesc.ImageFile);
AddVideoObject( &VObjectDesc, &uiObject );
// Calculate smily face positions...
GetVideoObject( &hHandle, uiObject );
pTrav = &(hHandle->pETRLEObject[ 0 ] );
sWidthA = pTrav->usWidth;
pTrav = &(hHandle->pETRLEObject[ 1 ] );
sWidthB = pTrav->usWidth;
sTotalBoxWidth = sTotalButtonWidth;
GetBoxSize( ghTownMineBox , &pDimensions );
GetBoxPosition( ghTownMineBox, &pPosition );
sX = pPosition.iX + ( pDimensions.iRight - sTotalBoxWidth ) / 3;
sY = pPosition.iY + pDimensions.iBottom - ( ( BOX_BUTTON_HEIGHT + 5 ) );
guiMapButtonInventoryImage[0] = LoadButtonImage( "INTERFACE\\mapinvbtns.sti" ,-1,0,-1,2,-1 );
guiMapButtonInventory[0] = CreateIconAndTextButton( guiMapButtonInventoryImage[0], pMapPopUpInventoryText[ 0 ], BLOCKFONT2,
FONT_WHITE, FONT_BLACK,
FONT_WHITE, FONT_BLACK,
TEXT_CJUSTIFIED,
(INT16)(sX ), (INT16)( sY ), BUTTON_TOGGLE , MSYS_PRIORITY_HIGHEST - 1,
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)MapTownMineInventoryButtonCallBack );
sX = sX + sWidthA + ( pDimensions.iRight - sTotalBoxWidth ) / 3;
sY = pPosition.iY + pDimensions.iBottom - ( ( BOX_BUTTON_HEIGHT + 5) );
guiMapButtonInventoryImage[1] = LoadButtonImage( "INTERFACE\\mapinvbtns.sti" ,-1,1,-1,3,-1 );
guiMapButtonInventory[1] = CreateIconAndTextButton( guiMapButtonInventoryImage[1], pMapPopUpInventoryText[ 1 ], BLOCKFONT2,
FONT_WHITE, FONT_BLACK,
FONT_WHITE, FONT_BLACK,
TEXT_CJUSTIFIED,
(INT16)(sX ), (INT16)( sY ), BUTTON_TOGGLE , MSYS_PRIORITY_HIGHEST - 1,
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)MapTownMineExitButtonCallBack );
// delete video object
DeleteVideoObjectFromIndex( uiObject );
/*
// if below ground disable
if( iCurrentMapSectorZ )
{
DisableButton( guiMapButtonInventory[ 0 ] );
}
*/
return;
}
void RemoveInventoryButtonForMapPopUpBox( void )
{
// get rid of button
RemoveButton( guiMapButtonInventory[0] );
UnloadButtonImage( guiMapButtonInventoryImage[0] );
RemoveButton( guiMapButtonInventory[1] );
UnloadButtonImage( guiMapButtonInventoryImage[1] );
return;
}
void MapTownMineInventoryButtonCallBack( GUI_BUTTON *btn, INT32 reason )
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags|=(BUTTON_CLICKED_ON);
}
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if (btn->uiFlags & BUTTON_CLICKED_ON)
{
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// done
fShowMapInventoryPool = TRUE;
fMapPanelDirty = TRUE;
fMapScreenBottomDirty = TRUE;
fShowTownInfo = FALSE;
//since we are bring up the sector inventory, check to see if the help screen should come up
if( ShouldTheHelpScreenComeUp( HELP_SCREEN_MAPSCREEN_SECTOR_INVENTORY, FALSE ) )
{
//normally this is handled in the screen handler, we have to set up a little different this time around
ShouldTheHelpScreenComeUp( HELP_SCREEN_MAPSCREEN_SECTOR_INVENTORY, TRUE );
}
}
}
}
void MapTownMineExitButtonCallBack( GUI_BUTTON *btn, INT32 reason )
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags|=(BUTTON_CLICKED_ON);
}
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if (btn->uiFlags & BUTTON_CLICKED_ON)
{
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// done
fMapPanelDirty = TRUE;
fMapScreenBottomDirty = TRUE;
fShowTownInfo = FALSE;
}
}
}
// get the min width of the town mine info pop up box
void MinWidthOfTownMineInfoBox( void )
{
HVOBJECT hHandle;
VOBJECT_DESC VObjectDesc;
INT16 sWidthA = 0, sWidthB = 0, sTotalBoxWidth = 0;
UINT32 uiObject;
ETRLEObject *pTrav;
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\mapinvbtns.sti", VObjectDesc.ImageFile);
AddVideoObject( &VObjectDesc, &uiObject );
// Calculate smily face positions...
GetVideoObject( &hHandle, uiObject );
pTrav = &(hHandle->pETRLEObject[ 0 ] );
sWidthA = pTrav->usWidth;
pTrav = &(hHandle->pETRLEObject[ 1 ] );
sWidthB = pTrav->usWidth;
sTotalBoxWidth = sWidthA + sWidthB;
sTotalButtonWidth = sTotalBoxWidth;
// delete video object
DeleteVideoObjectFromIndex( uiObject );
return;
}
@@ -0,0 +1,15 @@
#ifndef __MS_I_TOWNMINE_INFO_H
#define __MS_I_TOWNMINE_INFO_H
#include "Types.h"
extern BOOLEAN fShowTownInfo;
// display the box
void DisplayTownInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
// create or destroy the town info box..should only be directly called the exit code for mapscreen
void CreateDestroyTownInfoBox( void );
#endif
File diff suppressed because it is too large Load Diff
+606
View File
@@ -0,0 +1,606 @@
#ifndef MAP_SCREEN_INTERFACE_H
#define MAP_SCREEN_INTERFACE_H
#include "Types.h"
#include "Soldier Control.h"
#include "MessageBoxScreen.h"
typedef struct FASTHELPREGION {
// the string
CHAR16 FastHelpText[ 256 ];
// the x and y position values
INT32 iX;
INT32 iY;
INT32 iW;
} FASTHELPREGION;
// String Lengths Defines
#define MAX_NAME_LENGTH 10
#define MAX_LOCATION_SIZE 8
#define MAX_DESTETA_SIZE 8
#define MAX_ASSIGN_SIZE 10
#define MAX_TIME_REMAINING_SIZE 8
// char breath and life position
#define BAR_INFO_X 66
#define BAR_INFO_Y 61
// merc icon position
#define CHAR_ICON_CONTRACT_Y 64
#define CHAR_ICON_X 187
#define CHAR_ICON_WIDTH 10
#define CHAR_ICON_HEIGHT 10
#define CHAR_ICON_SPACING 13
// max number of characters and vehicles
//Character List Length
#define MAX_CHARACTER_COUNT 20
#define MAX_VEHICLE_COUNT 20
// map screen font
#define MAP_SCREEN_FONT BLOCKFONT2
// characterlist regions
#define Y_START 146
#define MAP_START_KEYRING_Y 107
#define Y_SIZE GetFontHeight(MAP_SCREEN_FONT)
// attribute menu defines (must match NUM_TRAINABLE_STATS defines, and pAttributeMenuStrings )
enum {
ATTRIB_MENU_STR=0,
ATTRIB_MENU_DEX,
ATTRIB_MENU_AGI,
ATTRIB_MENU_HEA,
ATTRIB_MENU_MARK,
ATTRIB_MENU_MED,
ATTRIB_MENU_MECH,
ATTRIB_MENU_LEAD,
ATTRIB_MENU_EXPLOS,
ATTRIB_MENU_CANCEL,
MAX_ATTRIBUTE_STRING_COUNT,
};
// the epc assignment menu
enum{
EPC_MENU_ON_DUTY = 0,
EPC_MENU_PATIENT,
EPC_MENU_VEHICLE,
EPC_MENU_REMOVE,
EPC_MENU_CANCEL,
MAX_EPC_MENU_STRING_COUNT,
};
// assignment menu defines
enum {
ASSIGN_MENU_ON_DUTY=0,
ASSIGN_MENU_DOCTOR,
ASSIGN_MENU_PATIENT,
ASSIGN_MENU_VEHICLE,
ASSIGN_MENU_REPAIR,
ASSIGN_MENU_TRAIN,
ASSIGN_MENU_CANCEL,
MAX_ASSIGN_STRING_COUNT,
};
// training assignment menu defines
enum {
TRAIN_MENU_SELF,
TRAIN_MENU_TOWN,
TRAIN_MENU_TEAMMATES,
TRAIN_MENU_TRAIN_BY_OTHER,
TRAIN_MENU_CANCEL,
MAX_TRAIN_STRING_COUNT,
};
// the remove merc from team pop up box strings
enum{
REMOVE_MERC = 0,
REMOVE_MERC_CANCEL,
MAX_REMOVE_MERC_COUNT,
};
// squad menu defines
enum{
SQUAD_MENU_1,
SQUAD_MENU_2,
SQUAD_MENU_3,
SQUAD_MENU_4,
SQUAD_MENU_5,
SQUAD_MENU_6,
SQUAD_MENU_7,
SQUAD_MENU_8,
SQUAD_MENU_9,
SQUAD_MENU_10,
SQUAD_MENU_11,
SQUAD_MENU_12,
SQUAD_MENU_13,
SQUAD_MENU_14,
SQUAD_MENU_15,
SQUAD_MENU_16,
SQUAD_MENU_17,
SQUAD_MENU_18,
SQUAD_MENU_19,
SQUAD_MENU_20,
SQUAD_MENU_CANCEL,
MAX_SQUAD_MENU_STRING_COUNT,
};
// contract menu defines
enum{
CONTRACT_MENU_CURRENT_FUNDS = 0,
CONTRACT_MENU_SPACE,
CONTRACT_MENU_DAY,
CONTRACT_MENU_WEEK,
CONTRACT_MENU_TWO_WEEKS,
CONTRACT_MENU_TERMINATE,
CONTRACT_MENU_CANCEL,
MAX_CONTRACT_MENU_STRING_COUNT,
};
// enums for pre battle interface pop ups
enum
{
ASSIGNMENT_POPUP,
DESTINATION_POPUP,
CONTRACT_POPUP
};
enum{
NO_REASON_FOR_UPDATE = 0,
CONTRACT_FINISHED_FOR_UPDATE,
ASSIGNMENT_FINISHED_FOR_UPDATE,
ASSIGNMENT_RETURNING_FOR_UPDATE,
ASLEEP_GOING_AUTO_FOR_UPDATE,
CONTRACT_EXPIRE_WARNING_REASON,
};
enum{
START_RED_SECTOR_LOCATOR = 0,
STOP_RED_SECTOR_LOCATOR,
START_YELLOW_SECTOR_LOCATOR,
STOP_YELLOW_SECTOR_LOCATOR,
};
// dimensions and offset for merc update box
#define UPDATE_MERC_FACE_X_WIDTH 50
#define UPDATE_MERC_FACE_X_HEIGHT 50
#define UPDATE_MERC_FACE_X_OFFSET 2
#define UPDATE_MERC_FACE_Y_OFFSET 2
#define WIDTH_OF_UPDATE_PANEL_BLOCKS 50
#define HEIGHT_OF_UPDATE_PANEL_BLOCKS 50
#define UPDATE_MERC_Y_OFFSET 4
#define UPDATE_MERC_X_OFFSET 4
// dimensions and offset for merc update box
#define TACT_UPDATE_MERC_FACE_X_WIDTH 70
#define TACT_UPDATE_MERC_FACE_X_HEIGHT 49
#define TACT_UPDATE_MERC_FACE_X_OFFSET 8
#define TACT_UPDATE_MERC_FACE_Y_OFFSET 6
#define TACT_WIDTH_OF_UPDATE_PANEL_BLOCKS 70
#define TACT_HEIGHT_OF_UPDATE_PANEL_BLOCKS 49
#define TACT_UPDATE_MERC_Y_OFFSET 4
#define TACT_UPDATE_MERC_X_OFFSET 4
// the first vehicle slot int he list
#define FIRST_VEHICLE 18
typedef struct MERC_LEAVE_ITEM{
OBJECTTYPE o;
struct MERC_LEAVE_ITEM *pNext;
}MERC_LEAVE_ITEM;
extern BOOLEAN fShowAssignmentMenu;
extern BOOLEAN fShowTrainingMenu ;
extern BOOLEAN fShowAttributeMenu;
extern BOOLEAN fShowSquadMenu ;
extern BOOLEAN fShowContractMenu ;
extern BOOLEAN fShowRemoveMenu ;
extern BOOLEAN fFirstTimeInMapScreen;
extern BOOLEAN fLockOutMapScreenInterface;
// The character data structure
typedef struct {
UINT16 usSolID;// soldier ID in MenPtrs
BOOLEAN fValid;// is the current soldier a valid soldier
} MapScreenCharacterSt;
// map screen character structure list, contrains soldier ids into menptr
extern MapScreenCharacterSt gCharactersList[ ];
extern BOOLEAN fShowMapScreenHelpText;
// map inventory pool inited
extern BOOLEAN fMapInventoryPoolInited;
// highlighted lines
extern INT32 giHighLine;
extern INT32 giAssignHighLine;
extern INT32 giDestHighLine;
extern INT32 giContractHighLine;
extern INT32 giSleepHighLine;
extern UINT32 guiUpdatePanel;
extern UINT32 guiUpdatePanelTactical;
extern BOOLEAN fShowUpdateBox;
extern SGPRect ContractDimensions;
extern SGPPoint ContractPosition;
extern SGPRect AttributeDimensions;
extern SGPPoint AttributePosition;
extern SGPRect TrainDimensions;
extern SGPPoint TrainPosition;
extern SGPRect VehicleDimensions;
extern SGPPoint VehiclePosition;
extern SGPRect AssignmentDimensions ;
extern SGPPoint AssignmentPosition ;
extern SGPPoint SquadPosition ;
extern SGPRect SquadDimensions ;
extern SGPPoint RepairPosition;
extern SGPRect RepairDimensions;
extern SGPPoint OrigContractPosition;
extern SGPPoint OrigAttributePosition;
extern SGPPoint OrigSquadPosition ;
extern SGPPoint OrigAssignmentPosition ;
extern SGPPoint OrigTrainPosition;
extern SGPPoint OrigVehiclePosition;
// disble team info panel due to showing of battle roster
extern BOOLEAN fDisableDueToBattleRoster;
extern BOOLEAN gfAtLeastOneMercWasHired;
// curtrent map sector z that is being displayed in the mapscreen
extern INT32 iCurrentMapSectorZ;
// y position of the pop up box
extern INT32 giBoxY;
// pop up box textures
extern UINT32 guiPOPUPTEX;
extern UINT32 guiPOPUPBORDERS;
// the level-changing markers on the map border
extern UINT32 guiLEVELMARKER;
// the currently selected character arrow
extern UINT32 guiSelectedCharArrow;
// sam and mine icons
extern UINT32 guiSAMICON;
extern BOOLEAN fShowMapScreenMovementList;
// do we need to rebuild the mapscreen characterlist?
extern BOOLEAN fReBuildCharacterList;
// restore glow rotation in contract region glow boxes
extern BOOLEAN fResetContractGlow;
// init vehicle and characters list
void InitalizeVehicleAndCharacterList( void );
// set this entry to as selected
void SetEntryInSelectedCharacterList( INT8 bEntry );
// set this entry to as unselected
void ResetEntryForSelectedList( INT8 bEntry );
// reset selected list
void ResetSelectedListForMapScreen( );
// build a selected list from a to b, inclusive
void BuildSelectedListFromAToB( INT8 bA, INT8 bB );
// isa this entry int he selected character list set?
BOOLEAN IsEntryInSelectedListSet( INT8 bEntry );
// is there more than one person selected?
BOOLEAN MultipleCharacterListEntriesSelected( void );
// toggle this entry on or off
void ToggleEntryInSelectedList( INT8 bEntry );
// reset assignments for mercs on selected list who have this assignment
void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( INT8 bAssignment );
/*
// plot path for selected character list
void PlotPathForSelectedCharacterList( INT16 sX, INT16 sY );
*/
void RestoreBackgroundForAssignmentGlowRegionList( void );
void RestoreBackgroundForDestinationGlowRegionList( void );
void RestoreBackgroundForContractGlowRegionList( void );
void RestoreBackgroundForSleepGlowRegionList( void );
// play click when we are entering a glow region
void PlayGlowRegionSound( void );
// is this character in the action of plotting a path?
INT16 CharacterIsGettingPathPlotted( INT16 sCharNumber );
// disable team info panels
void DisableTeamInfoPanels( void );
// enable team info panels
void EnableTeamInfoPanels( void );
// activate pop up for soldiers in the pre battle interface
void ActivateSoldierPopup( SOLDIERTYPE *pSoldier, UINT8 ubPopupType, INT16 xp, INT16 yp );
// do mapscreen message box
INT32 DoMapMessageBox( UINT8 ubStyle, INT16 * zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback );
// hop up one leve,l int he map screen level interface
void GoUpOneLevelInMap( void );
// go down one level in the mapscreen map interface
void GoDownOneLevelInMap( void );
// jump to this level on the map
void JumpToLevel( INT32 iLevel );
// check to see if we need to update the screen
void CheckAndUpdateBasedOnContractTimes( void );
// check if are just about to display this pop up or stopping display
void HandleDisplayOfItemPopUpForSector( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
// display red arrow by name of selected merc
void HandleDisplayOfSelectedMercArrows( void );
// check which guys can move with this guy
void DeselectSelectedListMercsWhoCantMoveWithThisGuy( SOLDIERTYPE *pSoldier );
// get morale string for this grunt given this morale level
void GetMoraleString( SOLDIERTYPE *pSoldier, STR16 sString );
// handle leaving of equipment in sector
void HandleLeavingOfEquipmentInCurrentSector( UINT32 uiMercId );
// set up a linked list of items being dropped and post an event to later drop them
void HandleMercLeavingEquipmentInDrassen( UINT32 uiMercId );
void HandleMercLeavingEquipmentInOmerta( UINT32 uiMercId );
// actually drop the stored list of items
void HandleEquipmentLeftInOmerta( UINT32 uiSlotIndex );
void HandleEquipmentLeftInDrassen( UINT32 uiSlotIndex );
// init/shutdown leave item lists
void InitLeaveList( void );
void ShutDownLeaveList( void );
// add item to leave equip index
BOOLEAN AddItemToLeaveIndex( OBJECTTYPE *o, UINT32 uiIndex );
// release memory for all items in this slot's leave item list
void FreeLeaveListSlot( UINT32 uiSlotIndex );
// first free slot in equip leave list
INT32 FindFreeSlotInLeaveList( void );
// set up drop list
INT32 SetUpDropItemListForMerc( UINT32 uiMercId );
// store owner's profile id for the items added to this leave slot index
void SetUpMercAboutToLeaveEquipment( UINT32 ubProfileId, UINT32 uiSlotIndex );
// remove item from leave index
//BOOLEAN RemoveItemFromLeaveIndex( MERC_LEAVE_ITEM *pItem, UINT32 uiIndex );
// handle a group about to arrive in a sector
void HandleGroupAboutToArrive( void );
// up arrow
void HandleMapScreenUpArrow( void );
void HandleMapScreenDownArrow( void );
// create and destroy the status bars mouse region
void CreateMapStatusBarsRegion( void );
void RemoveMapStatusBarsRegion( void );
void UpdateCharRegionHelpText( void );
// find this soldier in mapscreen character list and set as contract
void FindAndSetThisContractSoldier( SOLDIERTYPE *pSoldier );
// lose the cursor, re-render
void HandleMAPUILoseCursorFromOtherScreen( void );
void RenderMapRegionBackground( void );
// update mapscreen assignment positions
void UpdateMapScreenAssignmentPositions( void );
// get the umber of valid mercs in the mapscreen character list
INT32 GetNumberOfPeopleInCharacterList( void );
// the next and previous people in the mapscreen
void GoToPrevCharacterInList( void );
void GoToNextCharacterInList( void );
// this does the whole miner giving player info speil
void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen );
// set up the event of animating a mine sector
void SetUpAnimationOfMineSectors( INT32 iEvent );
// display map screen
void DisplayMapScreenFastHelpList( void );
// handle display of fast help
void HandleDisplayOfExitToTacticalMessageForFirstEntryToMapScreen( void );
// is the text up?
BOOLEAN IsMapScreenHelpTextUp( void );
// stop the help text in mapscreen
void StopMapScreenHelpText( void );
// set up the help text
void SetUpMapScreenFastHelpText( void );
void TurnOnSectorLocator( UINT8 ubProfileID );
void TurnOffSectorLocator();
extern INT16 gsSectorLocatorX;
extern INT16 gsSectorLocatorY;
extern UINT8 gubBlitSectorLocatorCode;
enum
{
LOCATOR_COLOR_NONE,
LOCATOR_COLOR_RED,
LOCATOR_COLOR_YELLOW
};
extern UINT32 guiSectorLocatorGraphicID;
void HandleBlitOfSectorLocatorIcon( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubLocatorID );
// the tactical version
// handle the actual showingof the list
void HandleShowingOfTacticalInterfaceFastHelpText( void );
// start showing the list
void StartShowingInterfaceFastHelpText( void );
// stop showing the list
void StopShowingInterfaceFastHelpText( void );
// is the list active?
BOOLEAN IsTheInterfaceFastHelpTextActive( void );
//set up the tactical lists
BOOLEAN SetUpFastHelpListRegions( INT32 iXPosition[], INT32 iYPosition[], INT32 iWidth[], STR16 sString[], INT32 iSize );
// the alternate mapscreen movement system
void InitializeMovingLists( void );
// reset assignment for mercs trainign militia in this sector
void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX, INT16 sSectorY );
// the sector move box
void DeselectSquadForMovement( INT32 iSquadNumber );
void SelectedSquadForMovement( INT32 iSquadNumber );
void DeselectSoldierForMovement( SOLDIERTYPE *pSoldier );
void SelectSoldierForMovement( SOLDIERTYPE *pSoldier );
void SelectVehicleForMovement( INT32 iVehicleId, BOOLEAN fAndAllOnBoard );
void DeselectVehicleForMovement( INT32 iVehicleId );
void AddVehicleToMovingLists( INT32 iVehicleId );
void AddSquadToMovingLists( INT32 iSquadNumber );
void AddSoldierToMovingLists( SOLDIERTYPE *pSoldier );
void CreateDestroyMovementBox( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
void SetUpMovingListsForSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
void ReBuildMoveBox( void );
BOOLEAN IsCharacterSelectedForAssignment( INT16 sCharNumber );
BOOLEAN IsCharacterSelectedForSleep( INT16 sCharNumber );
// the update box
void CreateDestroyTheUpdateBox( void );
void SetSoldierUpdateBoxReason( INT32 iReason );
void AddSoldierToUpdateBox( SOLDIERTYPE *pSoldier );
void ResetSoldierUpdateBox( void );
void DisplaySoldierUpdateBox( );
BOOLEAN IsThePopUpBoxEmpty( void );
// unmarking buttons dirty for dialogue
void UpdateButtonsDuringCharacterDialogue( void );
void UpdateButtonsDuringCharacterDialogueSubTitles( void );
void SetUpdateBoxFlag( BOOLEAN fFlag );
/// set the town of Tixa as found by the player
void SetTixaAsFound( void );
// set the town of Orta as found by the player
void SetOrtaAsFound( void );
// set this SAM site as being found by the player
void SetSAMSiteAsFound( UINT8 uiSamIndex );
// init time menus
void InitTimersForMoveMenuMouseRegions( void );
// the screen mask
void CreateScreenMaskForMoveBox( void );
void RemoveScreenMaskForMoveBox( void );
// help text to show user merc has insurance
void UpdateHelpTextForMapScreenMercIcons( void );
void CreateDestroyInsuranceMouseRegionForMercs( BOOLEAN fCreate );
// stuff to deal with player just starting the game
BOOLEAN HandleTimeCompressWithTeamJackedInAndGearedToGo( void );
//void HandlePlayerEnteringMapScreenBeforeGoingToTactical( void );
// handle sector being taken over uncontested
BOOLEAN NotifyPlayerWhenEnemyTakesControlOfImportantSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fContested );
// handle notifying player of invasion by enemy
void NotifyPlayerOfInvasionByEnemyForces( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, MSGBOX_CALLBACK ReturnCallback );
void ShutDownUserDefineHelpTextRegions( void );
// shwo the update box
void ShowUpdateBox( void );
// add special events
void AddSoldierToWaitingListQueue( SOLDIERTYPE *pSoldier );
void AddReasonToWaitingListQueue( INT32 iReason );
void AddDisplayBoxToWaitingQueue( void );
// can this group move it out
BOOLEAN CanEntireMovementGroupMercIsInMove( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber );
void ReportMapScreenMovementError( INT8 bErrorNumber );
void HandleRebuildingOfMapScreenCharacterList( void );
void RequestToggleTimeCompression( void );
void RequestIncreaseInTimeCompression( void );
void RequestDecreaseInTimeCompression( void );
void SelectUnselectedMercsWhoMustMoveWithThisGuy( void );
BOOLEAN AnyMercInSameSquadOrVehicleIsSelected( SOLDIERTYPE *pSoldier );
BOOLEAN LoadLeaveItemList( HWFILE hFile );
BOOLEAN SaveLeaveItemList( HWFILE hFile );
BOOLEAN CheckIfSalaryIncreasedAndSayQuote( SOLDIERTYPE *pSoldier, BOOLEAN fTriggerContractMenu );
void EndUpdateBox( BOOLEAN fContinueTimeCompression );
extern BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber );
extern BOOLEAN MapscreenCanPassItemToCharNum( INT32 iNewCharSlot );
#endif
File diff suppressed because it is too large Load Diff
+106
View File
@@ -0,0 +1,106 @@
#ifndef MEANWHILE_H
#define MEANWHILE_H
enum
{
END_OF_PLAYERS_FIRST_BATTLE,
DRASSEN_LIBERATED,
CAMBRIA_LIBERATED,
ALMA_LIBERATED,
GRUMM_LIBERATED,
CHITZENA_LIBERATED,
NW_SAM,
NE_SAM,
CENTRAL_SAM,
FLOWERS,
LOST_TOWN,
INTERROGATION,
CREATURES,
KILL_CHOPPER,
AWOL_SCIENTIST,
OUTSKIRTS_MEDUNA,
BALIME_LIBERATED,
NUM_MEANWHILES
};
typedef struct
{
INT16 sSectorX;
INT16 sSectorY;
UINT16 usTriggerEvent;
UINT8 ubMeanwhileID;
UINT8 ubNPCNumber;
} MEANWHILE_DEFINITION;
void ScheduleMeanwhileEvent( MEANWHILE_DEFINITION *pMeanwhileDef, UINT32 uiTime );
void HandleFirstBattleVictory( void );
BOOLEAN BeginMeanwhile( UINT8 ubMeanwhileID );
void CheckForMeanwhileOKStart( );
void EndMeanwhile( );
BOOLEAN AreInMeanwhile( );
UINT8 GetMeanwhileID( );
BOOLEAN AreReloadingFromMeanwhile( );
void LocateToMeanwhileCharacter( );
// post meanwhile event for town liberation
void HandleMeanWhileEventPostingForTownLiberation( UINT8 bTownId );
// post meanwhile event for SAM liberation
void HandleMeanWhileEventPostingForSAMLiberation( INT8 bSAMId );
// trash world has been called, should we do the first meanwhile?
void HandleFirstMeanWhileSetUpWithTrashWorld( void );
// battle ended, check if we should set up a meanwhile?
void HandleFirstBattleEndingWhileInTown( INT16 sSectorX, INT16 sSectorY, INT16 bSectorZ, BOOLEAN fFromAutoResolve );
// lost an entire town to the enemy!
void HandleMeanWhileEventPostingForTownLoss( UINT8 bTownId );
// handle short cutting past a meanwhilescene while it is being handled
void HandleShortCuttingOfMeanwhileSceneByPlayer( UINT8 ubMeanwhileID, INT32 iLastProfileId, INT32 iLastProfileAction );
// handle release of creatures meanwhile
void HandleCreatureRelease( void );
// handle sending flowers to the queen
void HandleFlowersMeanwhileScene( INT8 bTimeCode );
// player reaches the outskirts of Meduna
void HandleOutskirtsOfMedunaMeanwhileScene( void );
// let player know about Madlab after certain status % reached
void HandleScientistAWOLMeanwhileScene( void );
// handle chopper used meanwhile
void HandleKillChopperMeanwhileScene( void );
// handle interrogation meanwhile
void HandleInterrogationMeanwhileScene( void );
extern MEANWHILE_DEFINITION gCurrentMeanwhileDef;
extern MEANWHILE_DEFINITION gMeanwhileDef[NUM_MEANWHILES];
extern BOOLEAN gfMeanwhileScheduled;
extern BOOLEAN gfMeanwhileTryingToStart;
extern BOOLEAN gfInMeanwhile;
extern UINT32 uiMeanWhileFlags;
#endif
File diff suppressed because it is too large Load Diff
+88
View File
@@ -0,0 +1,88 @@
#ifndef _MERC_CONTRACT_H_
#define _MERC_CONTRACT_H_
#include "Soldier Control.h"
//enums used for extending contract, etc.
enum
{
CONTRACT_EXTEND_1_DAY,
CONTRACT_EXTEND_1_WEEK,
CONTRACT_EXTEND_2_WEEK,
};
typedef struct
{
UINT8 ubProfileID;
UINT8 ubFiller[ 3 ];
} CONTRACT_NEWAL_LIST_NODE;
extern CONTRACT_NEWAL_LIST_NODE ContractRenewalList[ 20 ];
extern UINT8 ubNumContractRenewals;
extern BOOLEAN gfContractRenewalSquenceOn;
extern UINT8 ubCurrentContractRenewal;
extern BOOLEAN gfInContractMenuFromRenewSequence;
/*
//list of quotes used in renewing a mercs contract
enum
{
LAME_REFUSAL_DOING_SOMETHING_ELSE = 73,
DEPARTING_COMMENT_AFTER_48_HOURS = 75,
CONTRACTS_OVER_U_EXTENDING = 79,
ACCEPT_CONTRACT_RENEWAL = 80,
REFUSAL_TO_RENEW_POOP_MORALE = 85,
DEPARTING_COMMENT_BEFORE_48_HOURS=88,
DEATH_RATE_REFUSAL=89,
HATE_MERC_1_ON_TEAM,
HATE_MERC_2_ON_TEAM,
LEARNED_TO_HATE_MERC_ON_TEAM,
JOING_CAUSE_BUDDY_1_ON_TEAM,
JOING_CAUSE_BUDDY_2_ON_TEAM,
JOING_CAUSE_LEARNED_TO_LIKE_BUDDY_ON_TEAM,
PRECEDENT_TO_REPEATING_ONESELF,
REFUSAL_DUE_TO_LACK_OF_FUNDS,
};
*/
BOOLEAN MercContractHandling( SOLDIERTYPE *pSoldier, UINT8 ubDesiredAction );
BOOLEAN StrategicRemoveMerc( SOLDIERTYPE *pSoldier );
BOOLEAN BeginStrategicRemoveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fAddRehireButton );
BOOLEAN WillMercRenew( SOLDIERTYPE *pSoldier, BOOLEAN fSayQuote );
void CheckIfMercGetsAnotherContract( SOLDIERTYPE *pSoldier );
void FindOutIfAnyMercAboutToLeaveIsGonnaRenew( void );
void BeginContractRenewalSequence( );
void HandleContractRenewalSequence( );
void EndCurrentContractRenewal( );
void HandleMercIsWillingToRenew( UINT8 ubID );
void HandleMercIsNotWillingToRenew( UINT8 ubID );
BOOLEAN ContractIsExpiring( SOLDIERTYPE *pSoldier );
UINT32 GetHourWhenContractDone( SOLDIERTYPE *pSoldier );
BOOLEAN ContractIsGoingToExpireSoon( SOLDIERTYPE *pSoldier );
BOOLEAN LoadContractRenewalDataFromSaveGameFile( HWFILE hFile );
BOOLEAN SaveContractRenewalDataToSaveGameFile( HWFILE hFile );
// rehiring of mercs from leave equipment pop up
extern BOOLEAN fEnterMapDueToContract;
extern SOLDIERTYPE *pContractReHireSoldier;
extern SOLDIERTYPE *pLeaveSoldier;
extern UINT8 ubQuitType;
extern BOOLEAN gfFirstMercSayQuote;
#endif
+467
View File
@@ -0,0 +1,467 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "Player Command.h"
#include "Queen Command.h"
#include "Campaign Types.h"
#include "Strategic.h"
#include "Strategic Town Loyalty.h"
#include "Strategic Mines.h"
#include "text.h"
#include "laptopsave.h"
#include "quests.h"
#include "Morale.h"
#include "Overhead.h"
#include "strategicmap.h"
#include "Map Screen Helicopter.h"
#include "Game Clock.h"
#endif
extern BOOLEAN fMapScreenBottomDirty;
void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString )
{
// will build a string stating current facilities present in sector
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags == 0 )
{
// none
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 0 ] );
return;
}
// hospital
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_HOSPITAL )
{
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 1 ] );
}
// industry
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_INDUSTRY )
{
if( wcslen( sFacilitiesString ) == 0 )
{
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 2 ] );
}
else
{
wcscat( sFacilitiesString, L",");
wcscat( sFacilitiesString, sFacilitiesStrings[ 2 ]);
}
}
// prison
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_PRISON )
{
if( wcslen( sFacilitiesString ) == 0 )
{
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 3 ] );
}
else
{
wcscat( sFacilitiesString, L",");
wcscat( sFacilitiesString, sFacilitiesStrings[ 3 ]);
}
}
// airport
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_AIRPORT )
{
if( wcslen( sFacilitiesString ) == 0 )
{
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 5 ] );
}
else
{
wcscat( sFacilitiesString, L",");
wcscat( sFacilitiesString, sFacilitiesStrings[ 5 ]);
}
}
// gun range
if( SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFacilitiesFlags & SFCF_GUN_RANGE )
{
if( wcslen( sFacilitiesString ) == 0 )
{
swprintf( sFacilitiesString, L"%s", sFacilitiesStrings[ 6 ] );
}
else
{
wcscat( sFacilitiesString, L",");
wcscat( sFacilitiesString, sFacilitiesStrings[ 6 ]);
}
}
sFacilitiesString[ wcslen( sFacilitiesString ) ] = 0;
return;
}
// ALL changes of control to player must be funneled through here!
BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested )
{
// NOTE: MapSector must be 16-bit, cause MAX_WORLD_X is actually 18, so the sector numbers exceed 256 although we use only 16x16
UINT16 usMapSector = 0;
BOOLEAN fWasEnemyControlled = FALSE;
INT8 bTownId = 0;
UINT8 ubSectorID;
if( AreInMeanwhile( ) )
{
return FALSE;
}
if( bMapZ == 0 )
{
usMapSector = sMapX + ( sMapY * MAP_WORLD_X );
/*
// if enemies formerly controlled this sector
if (StrategicMap[ usMapSector ].fEnemyControlled)
{
// remember that the enemies have lost it
StrategicMap[ usMapSector ].fLostControlAtSomeTime = TRUE;
}
*/
if( NumHostilesInSector( sMapX, sMapY, bMapZ ) )
{ //too premature: enemies still in sector.
return FALSE;
}
// check if we ever grabbed drassen airport, if so, set fact we can go to BR's
if( ( sMapX == BOBBYR_SHIPPING_DEST_SECTOR_X ) && ( sMapY == BOBBYR_SHIPPING_DEST_SECTOR_Y ) )
{
LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE;
//If the player has been to Bobbyr when it was down, and we havent already sent email, send him an email
if( LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction == BOBBYR_BEEN_TO_SITE_ONCE && LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction != BOBBYR_ALREADY_SENT_EMAIL )
{
AddEmail( BOBBYR_NOW_OPEN, BOBBYR_NOW_OPEN_LENGTH, BOBBY_R, GetWorldTotalMin());
LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction = BOBBYR_ALREADY_SENT_EMAIL;
}
}
fWasEnemyControlled = StrategicMap[ usMapSector ].fEnemyControlled;
StrategicMap[ usMapSector ].fEnemyControlled = FALSE;
SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE;
bTownId = StrategicMap[ usMapSector ].bNameId;
// check if there's a town in the sector
if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS))
{
// yes, start tracking (& displaying) this town's loyalty if not already doing so
StartTownLoyaltyIfFirstTime( bTownId );
}
// if player took control away from enemy
if( fWasEnemyControlled && fContested )
{
// and it's a town
if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS))
{
// don't do these for takeovers of Omerta sectors at the beginning of the game
if ((bTownId != OMERTA) || (GetWorldDay() != 1))
{
ubSectorID = (UINT8)SECTOR( sMapX, sMapY );
if( !bMapZ && ubSectorID != SEC_J9 && ubSectorID != SEC_K4 )
{
HandleMoraleEvent( NULL, MORALE_TOWN_LIBERATED, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_TOWN_SECTOR, sMapX, sMapY, bMapZ );
// liberation by definition requires that the place was enemy controlled in the first place
CheckIfEntireTownHasBeenLiberated( bTownId, sMapX, sMapY );
}
}
}
// if it's a mine that's still worth something
if ( IsThereAMineInThisSector( sMapX, sMapY ) )
{
if ( GetTotalLeftInMine( GetMineIndexForSector( sMapX, sMapY ) ) > 0)
{
HandleMoraleEvent( NULL, MORALE_MINE_LIBERATED, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_MINE, sMapX, sMapY, bMapZ );
}
}
// if it's a SAM site sector
if( IsThisSectorASAMSector( sMapX, sMapY, bMapZ ) )
{
if ( 1 /*!GetSectorFlagStatus( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE ) */)
{
// SAM site liberated for first time, schedule meanwhile
HandleMeanWhileEventPostingForSAMLiberation( GetSAMIdFromSector( sMapX, sMapY, bMapZ ) );
}
HandleMoraleEvent( NULL, MORALE_SAM_SITE_LIBERATED, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_SAM, sMapX, sMapY, bMapZ );
// if Skyrider has been delivered to chopper, and already mentioned Drassen SAM site, but not used this quote yet
if ( IsHelicopterPilotAvailable() && ( guiHelicopterSkyriderTalkState >= 1 ) && ( !gfSkyriderSaidCongratsOnTakingSAM ) )
{
SkyRiderTalk( SAM_SITE_TAKEN );
gfSkyriderSaidCongratsOnTakingSAM = TRUE;
}
if ( !SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled )
{
// grant grace period
if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) );
}
else
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 1 ) );
}
}
}
// if it's a helicopter refueling site sector
if( IsRefuelSiteInSector( sMapX, sMapY) )
{
UpdateRefuelSiteAvailability( );
}
// SetSectorFlag( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE );
if ( bMapZ == 0 && ( ( sMapY == MAP_ROW_M && (sMapX >= 2 && sMapX <= 6) ) || sMapY == MAP_ROW_N && sMapX == 6) )
{
HandleOutskirtsOfMedunaMeanwhileScene();
}
}
if( fContested )
{
StrategicHandleQueenLosingControlOfSector( (UINT8)sMapX, (UINT8)sMapY, (UINT8)bMapZ );
}
}
else
{
if( sMapX == 3 && sMapY == 16 && bMapZ == 1 )
{ //Basement sector (P3_b1)
gfUseAlternateQueenPosition = TRUE;
}
}
// also set fact the player knows they own it
SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE;
if ( bMapZ == 0 )
{
SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled = TRUE;
}
//KM : Aug 11, 1999 -- Patch fix: Relocated this check so it gets called everytime a sector changes hands,
// even if the sector isn't a SAM site. There is a bug _somewhere_ that fails to update the airspace,
// even though the player controls it.
UpdateAirspaceControl( );
// redraw map/income if in mapscreen
fMapPanelDirty = TRUE;
fMapScreenBottomDirty = TRUE;
return fWasEnemyControlled;
}
// ALL changes of control to enemy must be funneled through here!
BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested )
{
UINT16 usMapSector = 0;
BOOLEAN fWasPlayerControlled = FALSE;
INT8 bTownId = 0;
UINT8 ubTheftChance;
UINT8 ubSectorID;
//KM : August 6, 1999 Patch fix
// This check was added because this function gets called when player mercs retreat from an unresolved
// battle between militia and enemies. It will get called again AFTER autoresolve is finished.
if( gfAutomaticallyStartAutoResolve )
{
return( FALSE );
}
if( bMapZ == 0 )
{
usMapSector = sMapX + ( sMapY * MAP_WORLD_X );
fWasPlayerControlled = !StrategicMap[ usMapSector ].fEnemyControlled;
StrategicMap[ usMapSector ].fEnemyControlled = TRUE;
// if player lost control to the enemy
if ( fWasPlayerControlled )
{
if( PlayerMercsInSector( (UINT8)sMapX, (UINT8)sMapY, (UINT8)bMapZ ) )
{ //too premature: Player mercs still in sector.
return FALSE;
}
// check if there's a town in the sector
bTownId = StrategicMap[ usMapSector ].bNameId;
SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = FALSE;
// and it's a town
if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS))
{
ubSectorID = (UINT8)SECTOR( sMapX, sMapY );
if( !bMapZ && ubSectorID != SEC_J9 && ubSectorID != SEC_K4 )
{
HandleMoraleEvent( NULL, MORALE_TOWN_LOST, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_TOWN_SECTOR, sMapX, sMapY, bMapZ );
CheckIfEntireTownHasBeenLost( bTownId, sMapX, sMapY );
}
}
// if the sector has a mine which is still worth something
if ( IsThereAMineInThisSector( sMapX, sMapY ) )
{
// if it isn't empty
if ( GetTotalLeftInMine( GetMineIndexForSector( sMapX, sMapY ) ) > 0)
{
QueenHasRegainedMineSector(GetMineIndexForSector (sMapX, sMapY));
HandleMoraleEvent( NULL, MORALE_MINE_LOST, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_MINE, sMapX, sMapY, bMapZ );
}
}
// if it's a SAM site sector
if( IsThisSectorASAMSector( sMapX, sMapY, bMapZ ) )
{
HandleMoraleEvent( NULL, MORALE_SAM_SITE_LOST, sMapX, sMapY, bMapZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_LOSE_SAM, sMapX, sMapY, bMapZ );
}
// if it's a helicopter refueling site sector
if( IsRefuelSiteInSector( sMapX, sMapY) )
{
UpdateRefuelSiteAvailability( );
}
// ARM: this must be AFTER all resulting loyalty effects are resolved, or reduced mine income shown won't be accurate
NotifyPlayerWhenEnemyTakesControlOfImportantSector( sMapX, sMapY, 0, fContested );
}
// NOTE: Stealing is intentionally OUTSIDE the fWasPlayerControlled branch. This function gets called if new
// enemy reinforcements arrive, and they deserve another crack at stealing what the first group missed! :-)
// stealing should fail anyway 'cause there shouldn't be a temp file for unvisited sectors, but let's check anyway
if ( GetSectorFlagStatus( sMapX, sMapY, ( UINT8 ) bMapZ, SF_ALREADY_VISITED ) == TRUE )
{
// enemies can steal items left lying about (random chance). The more there are, the more they take!
ubTheftChance = 5 * NumEnemiesInAnySector( sMapX, sMapY, bMapZ );
// max 90%, some stuff may just simply not get found
if (ubTheftChance > 90 )
{
ubTheftChance = 90;
}
RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, ubTheftChance );
}
// don't touch fPlayer flag for a surface sector lost to the enemies!
// just because player has lost the sector doesn't mean he realizes it - that's up to our caller to decide!
}
else
{
// underground sector control is always up to date, because we don't track control down there
SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = FALSE;
}
//KM : Aug 11, 1999 -- Patch fix: Relocated this check so it gets called everytime a sector changes hands,
// even if the sector isn't a SAM site. There is a bug _somewhere_ that fails to update the airspace,
// even though the player controls it.
UpdateAirspaceControl( );
// redraw map/income if in mapscreen
fMapPanelDirty = TRUE;
fMapScreenBottomDirty = TRUE;
return fWasPlayerControlled;
}
#ifdef JA2TESTVERSION
void ClearMapControlledFlags( void )
{
INT32 iCounterA = 0, iCounterB = 0;
UINT16 usMapSector = 0;
for( iCounterA = 1; iCounterA < MAP_WORLD_X - 1; iCounterA++ )
{
for( iCounterB = 1; iCounterB < MAP_WORLD_Y - 1; iCounterB++ )
{
usMapSector = iCounterA + ( iCounterB * MAP_WORLD_X );
StrategicMap[ usMapSector ].fEnemyControlled = FALSE;
SectorInfo[ SECTOR( iCounterA, iCounterB ) ].fPlayer[ 0 ] = TRUE;
}
}
}
#endif
/*
BOOLEAN IsTheSectorPerceivedToBeUnderEnemyControl( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
// are we in battle in this sector?
if( ( sMapX == gWorldSectorX ) && ( sMapY == gWorldSectorY ) && ( bMapZ == gbWorldSectorZ ) && ( gTacticalStatus.uiFlags & INCOMBAT ) )
{
return( TRUE );
}
// does the player believe this sector is under enemy control?
return( !( SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] ) );
}
void MakePlayerPerceptionOfSectorControlCorrect( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
if (bMapZ == 0)
{
SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = !( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sMapX, sMapY ) ].fEnemyControlled );
}
// else nothing, underground sector control is always up to date, because we don't track control down there
fMapPanelDirty = TRUE;
}
*/
void ReplaceSoldierProfileInPlayerGroup( UINT8 ubGroupID, UINT8 ubOldProfile, UINT8 ubNewProfile )
{
GROUP *pGroup;
PLAYERGROUP *curr;
pGroup = GetGroup( ubGroupID );
if ( !pGroup )
{
return;
}
curr = pGroup->pPlayerList;
while( curr )
{
if( curr->ubProfileID == ubOldProfile )
{
// replace and return!
curr->ubProfileID = ubNewProfile;
return;
}
curr = curr->next;
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef _PLAYER_COMMAND_H
#define _PLAYER_COMMAND_H
// header file to track the information a player 'knows' about a sector, which may in fact not be true
#include "Strategic Movement.h"
// build main facilities strings for sector
void GetSectorFacilitiesFlags( INT16 sMapX, INT16 sMapY, STR16 sFacilitiesString );
// set sector as enemy controlled
BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested );
// set sector as player controlled
BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested );
#ifdef JA2TESTVERSION
void ClearMapControlledFlags( void );
#endif
/*
// is this sector under player control
BOOLEAN IsTheSectorPerceivedToBeUnderEnemyControl( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
// make player's perceived control over the sector reflect reality
void MakePlayerPerceptionOfSectorControlCorrect( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
*/
void ReplaceSoldierProfileInPlayerGroup( UINT8 ubGroupID, UINT8 ubOldProfile, UINT8 ubNewProfile );
#endif
File diff suppressed because it is too large Load Diff
+101
View File
@@ -0,0 +1,101 @@
#ifndef __PREBATTLE_INTERFACE_H
#define __PREBATTLE_INTERFACE_H
#include "types.h"
#include "Strategic Movement.h"
void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI );
void KillPreBattleInterface();
void RenderPreBattleInterface();
extern BOOLEAN gfPreBattleInterfaceActive;
extern BOOLEAN gfDisplayPotentialRetreatPaths;
extern BOOLEAN gfAutomaticallyStartAutoResolve;
extern BOOLEAN fDisableMapInterfaceDueToBattle;
extern GROUP *gpBattleGroup;
extern BOOLEAN gfTacticalTraversal;
extern GROUP *gpTacticalTraversalGroup;
extern SOLDIERTYPE *gpTacticalTraversalChosenSoldier;
extern BOOLEAN gfGotoSectorTransition;
extern BOOLEAN gfEnteringMapScreenToEnterPreBattleInterface;
enum
{
//General encounter codes (gubEnemyEncounterCode)
NO_ENCOUNTER_CODE, //when there is no encounter
ENEMY_INVASION_CODE,
ENEMY_ENCOUNTER_CODE,
ENEMY_AMBUSH_CODE,
ENTERING_ENEMY_SECTOR_CODE,
CREATURE_ATTACK_CODE,
BLOODCAT_AMBUSH_CODE,
ENTERING_BLOODCAT_LAIR_CODE,
//Explicit encounter codes only (gubExplicitEnemyEncounterCode -- a superset of gubEnemyEncounterCode)
FIGHTING_CREATURES_CODE,
HOSTILE_CIVILIANS_CODE,
HOSTILE_BLOODCATS_CODE,
};
extern BOOLEAN gfAutoAmbush;
extern BOOLEAN gfHighPotentialForAmbush;
extern void ActivatePreBattleAutoresolveAction();
extern void ActivatePreBattleEnterSectorAction();
extern void ActivatePreBattleRetreatAction();
extern void ActivateAutomaticAutoResolveStart();
void CalculateNonPersistantPBIInfo();
void ClearNonPersistantPBIInfo();
//SAVE START
//Using the ESC key in the PBI will get rid of the PBI and go back to mapscreen, but
//only if the PBI isn't persistant (!gfPersistantPBI).
extern BOOLEAN gfPersistantPBI;
//Contains general information about the type of encounter the player is faced with. This
//determines whether or not you can autoresolve the battle or even retreat. This code
//dictates the header that is used at the top of the PBI.
extern UINT8 gubEnemyEncounterCode;
//The autoresolve during tactical battle option needs more detailed information than the
//gubEnemyEncounterCode can provide. The explicit version contains possibly unique codes
//for reasons not normally used in the PBI. For example, if we were fighting the enemy
//in a normal situation, then shot at a civilian, the civilians associated with the victim
//would turn hostile, which would disable the ability to autoresolve the battle.
extern BOOLEAN gubExplicitEnemyEncounterCode;
//Location of the current battle (determines where the animated icon is blitted) and if the
//icon is to be blitted.
extern BOOLEAN gfBlitBattleSectorLocator;
extern UINT8 gubPBSectorX;
extern UINT8 gubPBSectorY;
extern UINT8 gubPBSectorZ;
extern BOOLEAN gfCantRetreatInPBI;
//SAVE END
void WakeUpAllMercsInSectorUnderAttack( void );
void ClearMovementForAllInvolvedPlayerGroups( void );
void RetreatAllInvolvedPlayerGroups( void );
BOOLEAN PlayerGroupInvolvedInThisCombat( GROUP *pGroup );
BOOLEAN PlayerMercInvolvedInThisCombat( SOLDIERTYPE *pSoldier );
BOOLEAN CurrentBattleSectorIs( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
enum
{
LOG_DEFEAT,
LOG_VICTORY,
};
void LogBattleResults( UINT8 ubVictoryCode);
#endif
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
#ifndef __QUEEN_COMMAND_H
#define __QUEEN_COMMAND_H
#include "types.h"
#include "Campaign Types.h"
#include "Soldier Control.h"
#include "FileMan.h"
#include "Strategic Movement.h"
extern BOOLEAN gfPendingEnemies;
UINT8 NumFreeEnemySlots();
//Counts enemies and crepitus, but not bloodcats.
UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
//Called when entering a sector so the campaign AI can automatically insert the
//correct number of troops of each type based on the current number in the sector
//in global focus (gWorldSectorX/Y)
BOOLEAN PrepareEnemyForSectorBattle();
BOOLEAN PrepareEnemyForUndergroundBattle();
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, BOOLEAN fMagicallyAppeared );
void AddPossiblePendingEnemiesToBattle();
void EndTacticalBattleForEnemy();
void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier );
void HandleEnemyStatusInCurrentMapBeforeLoadingNewMap();
BOOLEAN SaveUnderGroundSectorInfoToSaveGame( HWFILE hFile );
BOOLEAN LoadUnderGroundSectorInfoFromSavedGame( HWFILE hFile );
//Finds and returns the specified underground structure ( DONT MODIFY IT ). Else returns NULL
UNDERGROUND_SECTORINFO* FindUnderGroundSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ );
void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier );
void BeginCaptureSquence( );
void EndCaptureSequence( );
BOOLEAN PlayerSectorDefended( UINT8 ubSectorID );
BOOLEAN OnlyHostileCivsInSector();
extern INT16 gsInterrogationGridNo[3];
#endif
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
#ifndef _QUEST_DEBUG_SYSTEM_H_
#define _QUEST_DEBUG_SYSTEM_H_
#include "Soldier Control.h"
#include "NPC.h"
extern BOOLEAN gfNpcLogButton;
extern INT16 gsQdsEnteringGridNo;
void NpcRecordLoggingInit( UINT8 ubNpcID, UINT8 ubMercID, UINT8 ubQuoteNum, UINT8 ubApproach );
void NpcRecordLogging( UINT8 ubApproach, STR pStringA, ...);
#endif
+609
View File
@@ -0,0 +1,609 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "Types.h"
#include "Quests.h"
#endif
STR16 QuestDescText[] =
{
L"Deliver Letter",
L"Food Route",
L"Terrorists",
L"Kingpin Chalice",
L"Kingpin Money",
L"Runaway Joey",
L"Rescue Maria",
L"Chitzena Chalice",
L"Held in Alma",
L"Interogation",
L"Hillbilly Problem", //10
L"Find Scientist",
L"Deliver Video Camera",
L"Blood Cats",
L"Find Hermit",
L"Creatures",
L"Find Chopper Pilot",
L"Escort SkyRider",
L"Free Dynamo",
L"Escort Tourists",
L"Doreen", //20
L"Leather Shop Dream",
L"Escort Shank",
L"No 23 Yet",
L"No 24 Yet",
L"Kill Deidranna",
L"No 26 Yet",
L"No 27 Yet",
L"No 28 Yet",
L"No 29 Yet",
};
STR16 FactDescText[] =
{
L"Omerta Liberated",
L"Drassen Liberated",
L"Sanmona Liberated",
L"Cambria Liberated",
L"Alma Liberated",
L"Grumm Liberated",
L"Tixa Liberated",
L"Chitzena Liberated",
L"Estoni Liberated",
L"Balime Liberated",
L"Orta Liberated", //10
L"Meduna Liberated",
L"Pacos approched",
L"Fatima Read note",
L"Fatima Walked away from player",
L"Dimitri (#60) is dead",
L"Fatima responded to Dimitri's supprise",
L"Carlo's exclaimed 'no one moves'",
L"Fatima described note",
L"Fatima arrives at final dest",
L"Dimitri said Fatima has proof", //20
L"Miguel overheard conversation",
L"Miguel asked for letter",
L"Miguel read note",
L"Ira comment on Miguel reading note",
L"Rebels are enemies",
L"Fatima spoken to before given note",
L"Start Drassen quest",
L"Miguel offered Ira",
L"Pacos hurt/Killed",
L"Pacos is in A10", //30
L"Current Sector is safe",
L"Bobby R Shpmnt in transit",
L"Bobby R Shpmnt in Drassen",
L"33 is TRUE and it arrived within 2 hours",
L"33 is TRUE 34 is false more then 2 hours",
L"Player has realized part of shipment is missing",
L"36 is TRUE and Pablo was injured by player",
L"Pablo admitted theft",
L"Pablo returned goods, set 37 false",
L"Miguel will join team", //40
L"Gave some cash to Pablo",
L"Skyrider is currently under escort",
L"Skyrider is close to his chopper in Drassen",
L"Skyrider explained deal",
L"Player has clicked on Heli in Mapscreen at least once",
L"NPC is owed money",
L"Npc is wounded",
L"Npc was wounded by Player",
L"Father J.Walker was told of food shortage",
L"Ira is not in sector", //50
L"Ira is doing the talking",
L"Food quest over",
L"Pablo stole something from last shpmnt",
L"Last shipment crashed",
L"Last shipment went to wrong airport",
L"24 hours elapsed since notified that shpment went to wrong airport",
L"Lost package arrived with damaged goods. 56 to False",
L"Lost package is lost permanently. Turn 56 False",
L"Next package can (random) be lost",
L"Next package can(random) be delayed", //60
L"Package is medium sized",
L"Package is largesized",
L"Doreen has conscience",
L"Player Spoke to Gordon",
L"Ira is still npc and in A10-2(hasnt joined)",
L"Dynamo asked for first aid",
L"Dynamo can be recruited",
L"Npc is bleeding",
L"Shank wnts to join",
L"NPC is bleeding", //70
L"Player Team has head & Carmen in San Mona",
L"Player Team has head & Carmen in Cambria",
L"Player Team has head & Carmen in Drassen",
L"Father is drunk",
L"Player has wounded mercs within 8 tiles of NPC",
L"1 & only 1 merc wounded within 8 tiles of NPC",
L"More then 1 wounded merc within 8 tiles of NPC",
L"Brenda is in the store ",
L"Brenda is Dead",
L"Brenda is at home", //80
L"NPC is an enemy",
L"Speaker Strength >= 84 and < 3 males present",
L"Speaker Strength >= 84 and at least 3 males present",
L"Hans lets ou see Tony",
L"Hans is standing on 13523",
L"Tony isnt available Today",
L"Female is speaking to NPC",
L"Player has enjoyed the Brothel",
L"Carla is available",
L"Cindy is available", //90
L"Bambi is available",
L"No girls is available",
L"Player waited for girls",
L"Player paid right amount of money",
L"Mercs walked by goon",
L"More thean 1 merc present within 3 tiles of NPC",
L"At least 1 merc present withing 3 tiles of NPC",
L"Kingping expectingh visit from player",
L"Darren expecting money from player",
L"Player within 5 tiles and NPC is visible", // 100
L"Carmen is in San Mona",
L"Player Spoke to Carmen",
L"KingPin knows about stolen money",
L"Player gave money back to KingPin",
L"Frank was given the money ( not to buy booze )",
L"Player was told about KingPin watching fights",
L"Past club closing time and Darren warned Player. (reset every day)",
L"Joey is EPC",
L"Joey is in C5",
L"Joey is within 5 tiles of Martha(109) in sector G8", //110
L"Joey is Dead!",
L"At least one player merc within 5 tiles of Martha",
L"Spike is occuping tile 9817",
L"Angel offered vest",
L"Angel sold vest",
L"Maria is EPC",
L"Maria is EPC and inside leather Shop",
L"Player wants to buy vest",
L"Maria rescue was noticed by KingPin goons and Kingpin now enemy",
L"Angel left deed on counter", //120
L"Maria quest over",
L"Player bandaged NPC today",
L"Doreen revealed allegiance to Queen",
L"Pablo should not steal from player",
L"Player shipment arrived but loyalty to low, so it left",
L"Helicopter is in working condition",
L"Player is giving amount of money >= $1000",
L"Player is giving amount less than $1000",
L"Waldo agreed to fix helicopter( heli is damaged )",
L"Helicopter was destroyed", //130
L"Waldo told us about heli pilot",
L"Father told us about Deidranna killing sick people",
L"Father told us about Chivaldori family",
L"Father told us about creatures",
L"Loyalty is OK",
L"Loyalty is Low",
L"Loyalty is High",
L"Player doing poorly",
L"Player gave valid head to Carmen",
L"Current sector is G9(Cambria)", //140
L"Current sector is C5(SanMona)",
L"Current sector is C13(Drassen",
L"Carmen has at least $10,000 on him",
L"Player has Slay on team for over 48 hours",
L"Carmen is suspicous about slay",
L"Slay is in current sector",
L"Carmen gave us final warning",
L"Vince has explained that he has to charge",
L"Vince is expecting cash (reset everyday)",
L"Player stole some medical supplies once", //150
L"Player stole some medical supplies again",
L"Vince can be recruited",
L"Vince is currently doctoring",
L"Vince was recruited",
L"Slay offered deal",
L"All terrorists killed",
L"",
L"Maria left in wrong sector",
L"Skyrider left in wrong sector",
L"Joey left in wrong sector", //160
L"John left in wrong sector",
L"Mary left in wrong sector",
L"Walter was bribed",
L"Shank(67) is part of squad but not speaker",
L"Maddog spoken to",
L"Jake told us about shank",
L"Shank(67) is not in secotr",
L"Bloodcat quest on for more than 2 days",
L"Effective threat made to Armand",
L"Queen is DEAD!", //170
L"Speaker is with Aim or Aim person on squad within 10 tiles",
L"Current mine is empty",
L"Current mine is running out",
L"Loyalty low in affiliated town (low mine production)",
L"Creatures invaded current mine",
L"Player LOST current mine",
L"Current mine is at FULL production",
L"Dynamo(66) is Speaker or within 10 tiles of speaker",
L"Fred told us about creatures",
L"Matt told us about creatures", //180
L"Oswald told us about creatures",
L"Calvin told us about creatures",
L"Carl told us about creatures",
L"Chalice stolen from museam",
L"John(118) is EPC",
L"Mary(119) and John (118) are EPC's",
L"Mary(119) is alive",
L"Mary(119)is EPC",
L"Mary(119) is bleeding",
L"John(118) is alive", //190
L"John(118) is bleeding",
L"John or Mary close to airport in Drassen(B13)",
L"Mary is Dead",
L"Miners placed",
L"Krott planning to shoot player",
L"Madlab explained his situation",
L"Madlab expecting a firearm",
L"Madlab expecting a video camera.",
L"Item condition is < 70 ",
L"Madlab complained about bad firearm.", //200
L"Madlab complained about bad video camera.",
L"Robot is ready to go!",
L"First robot destroyed.",
L"Madlab given a good camera.",
L"Robot is ready to go a second time!",
L"Second robot destroyed.",
L"Mines explained to player.",
L"Dynamo (#66) is in sector J9.",
L"Dynamo (#66) is alive.",
L"One PC hasn't fought, but is able, and less than 3 fights have occured", //210
L"Player receiving mine income from Drassen, Cambria, Alma & Chitzena",
L"Player has been to K4_b1",
L"Brewster got to talk while Warden was alive",
L"Warden (#103) is dead.",
L"Ernest gave us the guns",
L"This is the first bartender",
L"This is the second bartender",
L"This is the third bartender",
L"This is the fourth bartender",
L"Manny is a bartender.", //220
L"Nothing is repaired yet (some stuff being worked on, nothing to give player right now)",
L"Player made purchase from Howard (#125)",
L"Dave sold vehicle",
L"Dave's vehicle ready",
L"Dave expecting cash for car",
L"Dave has gas. (randomized daily)",
L"Vehicle is present",
L"First battle won by player",
L"Robot recruited and moved",
L"No club fighting allowed", //230
L"Player already fought 3 fights today",
L"Hans mentioned Joey",
L"Player is doing better than 50% (Alex's function)",
L"Player is doing very well (better than 80%)",
L"Father is drunk and sci-fi option is on",
L"Micky (#96) is drunk",
L"Player has attempted to force their way into brothel",
L"Rat effectively threatened 3 times",
L"Player paid for two people to enter brothel",
L"", //240
L"",
L"Player owns 2 towns including omerta",
L"Player owns 3 towns including omerta",// 243
L"Player owns 4 towns including omerta",// 244
L"",
L"",
L"",
L"Fact male speaking female present",
L"Fact hicks married player merc",// 249
L"Fact museum open",// 250
L"Fact brothel open",// 251
L"Fact club open",// 252
L"Fact first battle fought",// 253
L"Fact first battle being fought",// 254
L"Fact kingpin introduced self",// 255
L"Fact kingpin not in office",// 256
L"Fact dont owe kingpin money",// 257
L"Fact pc marrying daryl is flo",// 258
L"",
L"", //260
L"Fact npc cowering", // 261,
L"",
L"",
L"Fact top and bottom levels cleared",
L"Fact top level cleared",// 265
L"Fact bottom level cleared",// 266
L"Fact need to speak nicely",// 267
L"Fact attached item before",// 268
L"Fact skyrider ever escorted",// 269
L"Fact npc not under fire",// 270
L"Fact willis heard about joey rescue",// 271
L"Fact willis gives discount",// 272
L"Fact hillbillies killed",// 273
L"Fact keith out of business", // 274
L"Fact mike available to army",// 275
L"Fact kingpin can send assassins",// 276
L"Fact estoni refuelling possible",// 277
L"Fact museum alarm went off",// 278
L"",
L"Fact maddog is speaker", //280,
L"",
L"Fact angel mentioned deed", // 282,
L"Fact iggy available to army",// 283
L"Fact pc has conrads recruit opinion",// 284
L"",
L"",
L"",
L"",
L"Fact npc hostile or pissed off", //289,
L"", //290
L"Fact tony in building", //291,
L"Fact shank speaking", // 292,
L"Fact doreen alive",// 293
L"Fact waldo alive",// 294
L"Fact perko alive",// 295
L"Fact tony alive",// 296
L"",
L"Fact vince alive",// 298,
L"Fact jenny alive",// 299
L"", //300
L"",
L"Fact arnold alive",// 302,
L"",
L"Fact rocket rifle exists",// 304,
L"",
L"",
L"",
L"",
L"",
L"", //310
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //320
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //330
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //340
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //350
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //360
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //370
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //380
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //390
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //400
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //410
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //420
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //430
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //440
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //450
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //460
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //470
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //480
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //490
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"",
L"", //500
};
+15
View File
@@ -0,0 +1,15 @@
#ifndef _QUEST_TEXT_H_
#define _QUEST_TEXT_H_
STR16 QuestDescText[];
STR16 FactDescText[];
#endif
+1390
View File
File diff suppressed because it is too large Load Diff
+571
View File
@@ -0,0 +1,571 @@
#ifndef __QUESTS_H
#define __QUESTS_H
#include "FileMan.h"
// Quest.ubStatus values
#define QUESTNOTSTARTED 0
#define QUESTINPROGRESS 1
#define QUESTDONE 2
#define MAX_QUESTS 30
#define MAX_FACTS 65536
#define NUM_FACTS 500 //If you increase this number, add entries to the fact text list in QuestText.c
#define MAP_ROW_A 1
#define MAP_ROW_B 2
#define MAP_ROW_C 3
#define MAP_ROW_D 4
#define MAP_ROW_E 5
#define MAP_ROW_F 6
#define MAP_ROW_G 7
#define MAP_ROW_H 8
#define MAP_ROW_I 9
#define MAP_ROW_J 10
#define MAP_ROW_K 11
#define MAP_ROW_L 12
#define MAP_ROW_M 13
#define MAP_ROW_N 14
#define MAP_ROW_O 15
#define MAP_ROW_P 16
// --------------------------------------------------------------------------------------
// Q U E S T D E F I N E S
// --------------------------------------------------------------------------------------
enum Quests
{
QUEST_DELIVER_LETTER = 0,
QUEST_FOOD_ROUTE,
QUEST_KILL_TERRORISTS,
QUEST_KINGPIN_IDOL,
QUEST_KINGPIN_MONEY,
QUEST_RUNAWAY_JOEY,
QUEST_RESCUE_MARIA,
QUEST_CHITZENA_IDOL,
QUEST_HELD_IN_ALMA,
QUEST_INTERROGATION,
QUEST_ARMY_FARM, // 10
QUEST_FIND_SCIENTIST,
QUEST_DELIVER_VIDEO_CAMERA,
QUEST_BLOODCATS,
QUEST_FIND_HERMIT,
QUEST_CREATURES,
QUEST_CHOPPER_PILOT,
QUEST_ESCORT_SKYRIDER,
QUEST_FREE_DYNAMO,
QUEST_ESCORT_TOURISTS,
QUEST_FREE_CHILDREN, // 20
QUEST_LEATHER_SHOP_DREAM,
QUEST_KILL_DEIDRANNA = 25
} ;
/*
// The first quest is mandatory. Player must find Miguel and deliver letter to him. The tough
// part is finding him. Miguel is UNDERGROUND in EAST OMERTA. Only by talking to Miguel's right
// hand man will the player be delivered to this hideout. This hideout will also serve as the
// player's HQ and inventory stash.
#define QUEST_DELIVER_LETTER 0
// This quest is triggered by Miguel. Player can liberate route from either SAN MONA or
// Drassen. Result allows player to hire on 2 of Miguel's guys.
#define QUEST_FOOD_ROUTE 1
// terrorist quests: 3 out of possible 6 per game - randomized which 3 and where. The
// Bounty Hunter will either appear in CAMBRIA or ALMA. He'll give a diskette with files
// on three of these terrorists. (we won't give files for all six since it may confuse
// player if ony 3 of them exist). The files will contain photographs. The terrorists will go
// by aliases and the photographs will be hard to tell if the NPC is really a terrorist.
// Bounty Hunter will give reward ($$$ CASH $$$) for proof of each death.
#define QUEST_KILL_TERRORISTS 2
#define QUEST_KILL_IMPOSTER 3
#define QUEST_KILL_TERRORIST3 4
#define QUEST_KILL_TERRORIST4 5
#define QUEST_KILL_TERRORIST5 6
#define QUEST_KILL_TERRORIST6 7
// While there'll always be one arms dealer in SAN MONA, there'll be a second one
// randomized in the outskirts of either: GRUMM, BARLINETTA or ESTONI. Only way player
// will know where to look will be to talk to certain town residents.
#define QUEST_FIND_ARMSDEALER 8
// CAMBRIA has 4 medical doctors, supplies and facilities
#define QUEST_MEDICAL_FACILITY 9 // Cambria
// A hermit will exist in each game, but in a different location. The player can try to
// talk to him, but he won't admit much. If the player threatens him, he gets his pet blood
// cats to attack the player. However, if the player talks to the hermit's brother, the brother
// will give valuable info (a code phrase) to the player that will allow the hermit to talk
// to the player, telling him about using creature blood when in the mines and giving him a
// vile - good enough for 3 mercs.
#define QUEST_FIND_HERMIT 10
// SAN MONA is a tough town. Player will find it tough to get any info out of any residents
// because they won't trust the player's mercs. SAN MONA doesn't have it as tough as any of
// the other towns - the local authorities (Queen's police) is as corrupt as the residents
// and to protect themselves they don't deal with outsiders. All residents will more or less
// let the player know that unless the word comes down from the top dude, no one will speak
// or deal with them. So, the player must seek out the top dude who'll want the player to
// fight his strongest bodyguard (hand to hand or knife).
#define QUEST_SAN_MONA_FIGHT 11
// Need a way to bring a kid giving us something into the picture.
// Micky returns in JA2 but with a new occupation.
#define QUEST_FIND_MICKY 12
#define QUEST_FREE_PRISONERS 13 // Tixa
#define QUEST_FIND_SCIENTIST 14
#define QUEST_KILL_BUGS 15 // Queen bug - randomized location?
//
#define QUEST_ESCAPE_MEDUNA 16
// Arulco farmer in F11 (Juan Erizia) is suspected of harboring a weapons cache in support
// of the Queen's forces. Player finds out about him in Cambria via conversation with a non
// family member (many of Cambria's residents are related/Erizias). So, player can go
// investigate. F11 must be liberated and Juan Erizia must still be alive. We randomize
// between QUEST_WEAPON_FARM and QUEST_SICK_WIFE. Player goes to talk to Juan. If he arrives
// during nighttime, there won't be too many cousins hanging around, but player has to be
// careful
//any attempt to
// investigate will awaken everyone, a battle will ensue.
// Player finds out through conversation in Cambria that Juan suspected of harboring weapons
// cache.
// Juan is very protective of his farm.
// Juan has 3 sons, 4 nephews and a sick wife.
// Juan refuses attempts to inspect his farm unless his brother has arranged it.
// Brother Emile is in Cambria.
// Player can investigate at night as long as he doesn't wake anyone.
// If player has talked to Emile, Juan will give him permission to investigate everywhere
// except his bedroom (citing a sick wife).
#define QUEST_WEAPON_FARM 17
#define QUEST_SICK_WIFE 18
// Queen has removed a national & historic treasure from the ruins of Chitzena. It is
// believed a wealthy supporter of the Queen purchased the item and that it is located in
// his home in Balime. Returning the treasure to Chitzena boosts loyalty points.
#define QUEST_RUIN_ARTIFACT 19
// In Cambria, there is a serial killer on the loose, attacking miners. This will only
// start to happen once player has control over the city & mine. It affects the number
// of residents willing to work in the mines (loyalty basically).
#define QUEST_MURDERER 20
// Find the chopper pilot near Drassen(?) and get him to work for you.
#define QUEST_CHOPPER_PILOT 21
#define QUEST_KILL_DEIDRANNA 29 // Meduna
// --------------------------------------------------------------------------------------
*/
// FACTS
enum Facts
{
// city liberations
FACT_OMERTA_LIBERATED = 0,
FACT_DRASSEN_LIBERATED, // 1
FACT_SANMONA_LIBERATED, // 2
FACT_CAMBRIA_LIBERATED, // 3
FACT_ALMA_LIBERATED, // 4
FACT_GRUMM_LIBERATED, // 5
FACT_TIXA_LIBERATED, // 6
FACT_CHITZENA_LIBERATED,// 7
FACT_ESTONI_LIBERATED, // 8
FACT_BALIME_LIBERATED, // 9
FACT_ORTA_LIBERATED, // 10
FACT_MEDUNA_LIBERATED, // 11
// quest stuff
FACT_MIGUEL_FOUND, // 12
FACT_LETTER_DELIVERED, // 13
FACT_FOOD_ROUTE_EXISTS, // 14
FACT_DIMITRI_DEAD, // 15
FACT_MIGUEL_READ_LETTER = 23,
// rebels do not trust player
FACT_REBELS_HATE_PLAYER = 25,
FACT_PACOS_KILLED = 29,
FACT_CURRENT_SECTOR_IS_SAFE = 31,
FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT, // 32
FACT_NEW_BOBBYRAY_SHIPMENT_WAITING, // 33
FACT_REALLY_NEW_BOBBYRAY_SHIPMENT_WAITING,// 34
FACT_LARGE_SIZED_OLD_SHIPMENT_WAITING,// 35
FACT_PLAYER_FOUND_ITEMS_MISSING,// 36
FACT_PABLO_PUNISHED_BY_PLAYER,// 37
FACT_PABLO_RETURNED_GOODS = 39,
FACT_PABLOS_BRIBED = 41,
FACT_ESCORTING_SKYRIDER,// 42
FACT_SKYRIDER_CLOSE_TO_CHOPPER,// 43
FACT_SKYRIDER_USED_IN_MAPSCREEN = 45,
FACT_NPC_OWED_MONEY,// 46
FACT_NPC_WOUNDED,// 47
FACT_NPC_WOUNDED_BY_PLAYER,// 48
FACT_IRA_NOT_PRESENT = 50,
FACT_IRA_TALKING,// 51
FACT_FOOD_QUEST_OVER,// 52
FACT_PABLOS_STOLE_FROM_LATEST_SHIPMENT,// 53
FACT_LAST_SHIPMENT_CRASHED,// 54
FACT_LAST_SHIPMENT_WENT_TO_WRONG_AIRPORT,// 55
FACT_SHIPMENT_DELAYED_24_HOURS,// 56
FACT_PACKAGE_DAMAGED,// 57
FACT_PACKAGE_LOST_PERMANENTLY,// 58
FACT_NEXT_PACKAGE_CAN_BE_LOST,// 59
FACT_NEXT_PACKAGE_CAN_BE_DELAYED,// 60
FACT_MEDIUM_SIZED_SHIPMENT_WAITING,// 61
FACT_LARGE_SIZED_SHIPMENT_WAITING,// 62
FACT_DOREEN_HAD_CHANGE_OF_HEART,// 63
FACT_IRA_UNHIRED_AND_ALIVE = 65,
FACT_NPC_BLEEDING = 68,
FACT_NPC_BLEEDING_BUT_OKAY = 70,
FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_SAN_MONA,// 71
FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_CAMBRIA,// 72
FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_DRASSEN,// 73
FACT_FATHER_DRUNK,// 74
FACT_WOUNDED_MERCS_NEARBY,// 75
FACT_ONE_WOUNDED_MERC_NEARBY,// 76
FACT_MULTIPLE_WOUNDED_MERCS_NEARBY,// 77
FACT_BRENDA_IN_STORE_AND_ALIVE,// 78
FACT_BRENDA_DEAD,// 79
FACT_NPC_IS_ENEMY = 81,
FACT_PC_STRONG_AND_LESS_THAN_3_MALES_PRESENT,// 82
FACT_PC_STRONG_AND_3_PLUS_MALES_PRESENT,// 83
FACT_HANS_AT_SPOT = 85,
FACT_TONY_NOT_AVAILABLE,// 86
FACT_FEMALE_SPEAKING_TO_NPC,// 87
FACT_PLAYER_USED_BROTHEL,// 88
FACT_CARLA_AVAILABLE,// 89
FACT_CINDY_AVAILABLE,// 90
FACT_BAMBI_AVAILABLE,// 91
FACT_NO_GIRLS_AVAILABLE,// 92
FACT_PLAYER_WAITED_FOR_GIRL,// 93
FACT_PLAYER_PAID_RIGHT_AMOUNT,// 94
FACT_PLAYER_PASSED_GOON,// 95
FACT_MULTIPLE_MERCS_CLOSE ,// 96,
FACT_SOME_MERCS_CLOSE,// 97
FACT_DARREN_EXPECTING_MONEY = 99,
FACT_PC_NEAR,// 100
FACT_CARMEN_IN_C5,// 101
FACT_CARMEN_EXPLAINED_DEAL,// 102
FACT_KINGPIN_KNOWS_MONEY_GONE,// 103
FACT_PLAYER_REPAID_KINGPIN,// 104
FACT_FRANK_HAS_BEEN_BRIBED,// 105
FACT_PAST_CLUB_CLOSING_AND_PLAYER_WARNED = 107,
FACT_JOEY_ESCORTED,// 108
FACT_JOEY_IN_C5,// 109
FACT_JOEY_NEAR_MARTHA,// 110
FACT_JOEY_DEAD,// 111
FACT_MERC_NEAR_MARTHA,// 112
FACT_SPIKE_AT_DOOR,// 113
FACT_ANGEL_SOLD_VEST = 115,
FACT_MARIA_ESCORTED,// 116
FACT_MARIA_ESCORTED_AT_LEATHER_SHOP,// 117
FACT_PLAYER_WANTS_TO_BUY_LEATHER_VEST,// 118
FACT_MARIA_ESCAPE_NOTICED,// 119
FACT_ANGEL_LEFT_DEED,// 120
FACT_NPC_BANDAGED_TODAY = 122,
FACT_PABLO_WONT_STEAL = 124,
FACT_AGENTS_PREVENTED_SHIPMENT,// 125
FACT_LARGE_AMOUNT_OF_MONEY = 127,
FACT_SMALL_AMOUNT_OF_MONEY,// 128
FACT_LOYALTY_OKAY = 135,
FACT_LOYALTY_LOW,// 136
FACT_LOYALTY_HIGH,// 137
FACT_PLAYER_DOING_POORLY,// 138
FACT_CURRENT_SECTOR_G9 = 140,
FACT_CURRENT_SECTOR_C5,// 141
FACT_CURRENT_SECTOR_C13,// 142
FACT_CARMEN_HAS_TEN_THOUSAND,// 143
FACT_SLAY_HIRED_AND_WORKED_FOR_48_HOURS,// 144
FACT_SLAY_IN_SECTOR = 146,
FACT_VINCE_EXPLAINED_HAS_TO_CHARGE = 148,
FACT_VINCE_EXPECTING_MONEY,// 149
FACT_PLAYER_STOLE_MEDICAL_SUPPLIES,// 150
FACT_PLAYER_STOLE_MEDICAL_SUPPLIES_AGAIN,// 151
FACT_VINCE_RECRUITABLE,// 152
FACT_ALL_TERRORISTS_KILLED = 156,
FACT_ELGIN_ALIVE,// 157
FACT_SHANK_IN_SQUAD_BUT_NOT_SPEAKING = 164,
FACT_SHANK_NOT_IN_SECTOR = 167,
FACT_BLOODCAT_QUEST_STARTED_TWO_DAYS_AGO,// 168
FACT_QUEEN_DEAD = 170,
FACT_SPEAKER_AIM_OR_AIM_NEARBY = 171,
FACT_MINE_EMPTY,// 172
FACT_MINE_RUNNING_OUT,// 173
FACT_MINE_PRODUCING_BUT_LOYALTY_LOW,// 174
FACT_CREATURES_IN_MINE,// 175
FACT_PLAYER_LOST_MINE,// 176
FACT_MINE_AT_FULL_PRODUCTION,// 177
FACT_DYNAMO_SPEAKING_OR_NEARBY,// 178
FACT_CHALICE_STOLEN = 184,
FACT_JOHN_EPC,// 185
FACT_JOHN_AND_MARY_EPCS,// 186
FACT_MARY_ALIVE,// 187
FACT_MARY_EPC,// 188
FACT_MARY_BLEEDING,// 189
FACT_JOHN_ALIVE,// 190
FACT_JOHN_BLEEDING,// 191
FACT_MARY_OR_JOHN_ARRIVED,// 192
FACT_MARY_DEAD,// 193
FACT_MINERS_PLACED,// 194
FACT_KROTT_GOT_ANSWER_NO,// 195
FACT_MADLAB_EXPECTING_FIREARM = 197,
FACT_MADLAB_EXPECTING_VIDEO_CAMERA,// 198
FACT_ITEM_POOR_CONDITION,// 199
FACT_ROBOT_READY = 202,
FACT_FIRST_ROBOT_DESTROYED,// 203
FACT_MADLAB_HAS_GOOD_CAMERA,// 204
FACT_ROBOT_READY_SECOND_TIME,// 205
FACT_SECOND_ROBOT_DESTROYED,// 206
FACT_DYNAMO_IN_J9 = 208,
FACT_DYNAMO_ALIVE,// 209
FACT_ANOTHER_FIGHT_POSSIBLE,// 210
FACT_RECEIVING_INCOME_FROM_DCAC,// 211
FACT_PLAYER_BEEN_TO_K4,// 212
FACT_WARDEN_DEAD = 214,
FACT_FIRST_BARTENDER = 216,
FACT_SECOND_BARTENDER,// 217
FACT_THIRD_BARTENDER,// 218
FACT_FOURTH_BARTENDER,// 219
FACT_MANNY_IS_BARTENDER,// 220
FACT_NOTHING_REPAIRED_YET,// 221,
FACT_OK_USE_HUMMER = 224,
FACT_DAVE_HAS_GAS = 226,
FACT_VEHICLE_PRESENT,// 227
FACT_FIRST_BATTLE_WON,// 228
FACT_ROBOT_RECRUITED_AND_MOVED,// 229
FACT_NO_CLUB_FIGHTING_ALLOWED,// 230
FACT_PLAYER_FOUGHT_THREE_TIMES_TODAY,// 231
FACT_PLAYER_SPOKE_TO_DRASSEN_MINER,// 232
FACT_PLAYER_DOING_WELL,// 233
FACT_PLAYER_DOING_VERY_WELL,// 234
FACT_FATHER_DRUNK_AND_SCIFI_OPTION_ON,// 235
FACT_MICKY_DRUNK,// 236
FACT_PLAYER_FORCED_WAY_INTO_BROTHEL,// 237
FACT_PLAYER_PAID_FOR_TWO_IN_BROTHEL = 239,
FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA = 242,
FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA,// 243
FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA,// 244
FACT_MALE_SPEAKING_FEMALE_PRESENT = 248,
FACT_HICKS_MARRIED_PLAYER_MERC,// 249
FACT_MUSEUM_OPEN,// 250
FACT_BROTHEL_OPEN,// 251
FACT_CLUB_OPEN,// 252
FACT_FIRST_BATTLE_FOUGHT,// 253
FACT_FIRST_BATTLE_BEING_FOUGHT,// 254
FACT_KINGPIN_INTRODUCED_SELF,// 255
FACT_KINGPIN_NOT_IN_OFFICE,// 256
FACT_DONT_OWE_KINGPIN_MONEY,// 257
FACT_PC_MARRYING_DARYL_IS_FLO,// 258
FACT_I16_BLOODCATS_KILLED,// 259
FACT_NPC_COWERING = 261,
FACT_TOP_AND_BOTTOM_LEVELS_CLEARED = 264,
FACT_TOP_LEVEL_CLEARED,// 265
FACT_BOTTOM_LEVEL_CLEARED,// 266
FACT_NEED_TO_SAY_SOMETHING,// 267
FACT_ATTACHED_ITEM_BEFORE,// 268
FACT_SKYRIDER_EVER_ESCORTED,// 269
FACT_NPC_NOT_UNDER_FIRE,// 270
FACT_WILLIS_HEARD_ABOUT_JOEY_RESCUE,// 271
FACT_WILLIS_GIVES_DISCOUNT,// 272
FACT_HILLBILLIES_KILLED,// 273
FACT_KEITH_OUT_OF_BUSINESS, // 274
FACT_MIKE_AVAILABLE_TO_ARMY,// 275
FACT_KINGPIN_CAN_SEND_ASSASSINS,// 276
FACT_ESTONI_REFUELLING_POSSIBLE,// 277
FACT_MUSEUM_ALARM_WENT_OFF,// 278
FACT_MADDOG_IS_SPEAKER = 280,
FACT_ANGEL_MENTIONED_DEED = 282,
FACT_IGGY_AVAILABLE_TO_ARMY,// 283
FACT_PC_HAS_CONRADS_RECRUIT_OPINION,// 284
FACT_NPC_HOSTILE_OR_PISSED_OFF = 289,
FACT_TONY_IN_BUILDING = 291,
FACT_SHANK_SPEAKING = 292,
FACT_PABLO_ALIVE,// 293
FACT_DOREEN_ALIVE,// 294
FACT_WALDO_ALIVE,// 295
FACT_PERKO_ALIVE,// 296
FACT_TONY_ALIVE,// 297
FACT_VINCE_ALIVE = 299,
FACT_JENNY_ALIVE,// 300
FACT_ARNOLD_ALIVE = 303,
FACT_ROCKET_RIFLE_EXISTS,// 304,
FACT_24_HOURS_SINCE_JOEY_RESCUED,// 305
FACT_24_HOURS_SINCE_DOCTOR_TALKED_TO, // 306
FACT_OK_USE_ICECREAM, // 307
FACT_KINGPIN_DEAD,// 308
FACT_KIDS_ARE_FREE = 318,
FACT_PLAYER_IN_SAME_ROOM,// 319
FACT_PLAYER_IN_CONTROLLED_DRASSEN_MINE = 324,
FACT_PLAYER_SPOKE_TO_CAMBRIA_MINER,// 325
FACT_PLAYER_IN_CONTROLLED_CAMBRIA_MINE,// 326
FACT_PLAYER_SPOKE_TO_CHITZENA_MINER,// 327
FACT_PLAYER_IN_CONTROLLED_CHITZENA_MINE,// 328
FACT_PLAYER_SPOKE_TO_ALMA_MINER,// 329
FACT_PLAYER_IN_CONTROLLED_ALMA_MINE,// 330
FACT_PLAYER_SPOKE_TO_GRUMM_MINER,// 331
FACT_PLAYER_IN_CONTROLLED_GRUMM_MINE,// 332
FACT_LARRY_CHANGED = 334,
FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR,// 335
FACT_HOSPITAL_FREEBIE_DECISION_MADE,// 336
FACT_ENOUGH_LOYALTY_TO_TRAIN_MILITIA,// 337
FACT_WALKER_AT_BAR,// 338
FACT_JOEY_ALIVE = 340,
FACT_UNPROPOSITIONED_FEMALE_SPEAKING_TO_NPC,// 341
FACT_84_AND_85_TRUE,// 342
FACT_KINGPIN_WILL_LEARN_OF_MONEY_GONE = 350,
FACT_SKYRIDER_IN_B15 = 354,
FACT_SKYRIDER_IN_C16,// 355
FACT_SKYRIDER_IN_E14,// 356
FACT_SKYRIDER_IN_D12,// 357
FACT_SKYRIDER_HINT_GIVEN,// 358
FACT_KINGPIN_IS_ENEMY,// 359
FACT_BRENDA_PATIENCE_TIMER_EXPIRED,// 360
FACT_DYNAMO_NOT_SPEAKER = 362,
FACT_PABLO_BRIBED = 365,
FACT_CONRAD_SHOULD_GO = 367,
FACT_PLAYER_KILLED_BOXERS = 368,
} ;
//** END FACTS *************************
#define BOBBYR_SHIPPING_DEST_SECTOR_X 13
#define BOBBYR_SHIPPING_DEST_SECTOR_Y 2
#define BOBBYR_SHIPPING_DEST_SECTOR_Z 0
#define BOBBYR_SHIPPING_DEST_GRIDNO 10112
#define PABLOS_STOLEN_DEST_GRIDNO 1
#define LOST_SHIPMENT_GRIDNO 2
// omerta positions
#define OMERTA_LEAVE_EQUIP_SECTOR_X 9
#define OMERTA_LEAVE_EQUIP_SECTOR_Y 1
#define OMERTA_LEAVE_EQUIP_SECTOR_Z 0
#define OMERTA_LEAVE_EQUIP_GRIDNO 4868
// NB brothel rooms 88-90 removed because they are the antechamber
#define IN_BROTHEL( room ) (gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_C && (room) >= 91 && (room) <= 119)
#define IN_BROTHEL_GUARD_ROOM( room ) ( room == 110 )
#define IN_KINGPIN_HOUSE( room ) ( gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_D && (room) >= 30 && (room) <= 39 )
#define LOYALTY_LOW_THRESHOLD 30
#define LOYALTY_OK_THRESHOLD 50
#define LOYALTY_HIGH_THRESHOLD 80
extern UINT8 gubQuest[MAX_QUESTS];
extern UINT8 gubFact[NUM_FACTS];
extern void SetFactTrue( UINT16 usFact );
extern void SetFactFalse( UINT16 usFact );
extern BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID );
extern void StartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY );
extern void EndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY );
extern void InternalStartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fUpdateHistory );
extern void InternalEndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fUpdateHistory );
extern void CheckForQuests( UINT32 uiDay );
void InitQuestEngine();
BOOLEAN LoadQuestInfoFromSavedGameFile( HWFILE hFile );
BOOLEAN SaveQuestInfoToSavedGameFile( HWFILE hFile );
#endif
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
#ifndef __SCHEDULING_H
#define __SCHEDULING_H
#include "BuildDefines.h"
#include "Soldier Init List.h"
//Merc scheduling actions
//NOTE: Any modifications to this enumeration also require updating the text in EditorMercs.c used
// in the editor for merc schedule purposes.
enum
{
SCHEDULE_ACTION_NONE,
SCHEDULE_ACTION_LOCKDOOR,
SCHEDULE_ACTION_UNLOCKDOOR,
SCHEDULE_ACTION_OPENDOOR,
SCHEDULE_ACTION_CLOSEDOOR,
SCHEDULE_ACTION_GRIDNO,
SCHEDULE_ACTION_LEAVESECTOR,
SCHEDULE_ACTION_ENTERSECTOR,
SCHEDULE_ACTION_STAYINSECTOR,
SCHEDULE_ACTION_SLEEP,
SCHEDULE_ACTION_WAKE,
NUM_SCHEDULE_ACTIONS
};
#define SCHEDULE_FLAGS_VARIANCE1 0x0001
#define SCHEDULE_FLAGS_VARIANCE2 0x0002
#define SCHEDULE_FLAGS_VARIANCE3 0x0004
#define SCHEDULE_FLAGS_VARIANCE4 0x0008
#define SCHEDULE_FLAGS_ACTIVE1 0x0010
#define SCHEDULE_FLAGS_ACTIVE2 0x0020
#define SCHEDULE_FLAGS_ACTIVE3 0x0040
#define SCHEDULE_FLAGS_ACTIVE4 0x0080
#define SCHEDULE_FLAGS_TEMPORARY 0x0100 //for default schedules -- not saved.
#define SCHEDULE_FLAGS_SLEEP_CONVERTED 0x0200 //converted (needs to be uncoverted before saving)
#define SCHEDULE_FLAGS_NPC_SLEEPING 0x0400 //if processing a sleep command, this flag will be set.
// combo flag for turning active flags off
#define SCHEDULE_FLAGS_ACTIVE_ALL 0x00F0
#define MAX_SCHEDULE_ACTIONS 4
typedef struct SCHEDULENODE
{
struct SCHEDULENODE *next;
UINT16 usTime[MAX_SCHEDULE_ACTIONS]; //converted to minutes 12:30PM would be 12*60 + 30 = 750
UINT16 usData1[MAX_SCHEDULE_ACTIONS]; //typically the gridno, but depends on the action
UINT16 usData2[MAX_SCHEDULE_ACTIONS]; //secondary information, not used by most actions
UINT8 ubAction[MAX_SCHEDULE_ACTIONS];
UINT8 ubScheduleID;
UINT8 ubSoldierID;
UINT16 usFlags;
}SCHEDULENODE;
extern UINT8 gubScheduleID;
extern SCHEDULENODE *gpScheduleList;
//Access functions
SCHEDULENODE* GetSchedule( UINT8 ubScheduleID );
//Removes all schedules from the event list, and cleans out the list.
void DestroyAllSchedules();
void DestroyAllSchedulesWithoutDestroyingEvents();
//This is the callback whenever a schedule is processed
void ProcessTacticalSchedule( UINT8 ubScheduleID );
void DeleteSchedule( UINT8 ubScheduleID );
void LoadSchedules( INT8 **hBuffer );
BOOLEAN LoadSchedulesFromSave( HWFILE hFile );
BOOLEAN SaveSchedules( HWFILE hFile );
void PostSchedule( SOLDIERTYPE *pSoldier );
void PostDefaultSchedule( SOLDIERTYPE *pSoldier );
void PostNextSchedule( SOLDIERTYPE *pSoldier );
//After the world is loaded and the temp modifications have been applied,
//we then need to post the events and process schedules for the time that we have been gone.
void PostSchedules();
//Sorts the schedule in chronological order. Returns TRUE if any sorting took place.
BOOLEAN SortSchedule( SCHEDULENODE *pSchedule );
//Adds a schedule to the list. COPIES THE DATA OVER (ALLOCATES NEW NODE!)
void CopyScheduleToList( SCHEDULENODE *pSchedule, SOLDIERINITNODE *pNode );
//Entering the editor automatically removes all events posted.
void PrepareSchedulesForEditorEntry();
//Leaving the editor and entering the game posts the events.
void PrepareSchedulesForEditorExit();
//Packs all of the scheduleIDs, and updates the links. This is done whenever necessary and
//before saving the map, as this forces the IDs to align with the SOLDIERINITNODE->ubScheduleID's.
void OptimizeSchedules();
void PerformActionOnDoorAdjacentToGridNo( UINT8 ubScheduleAction, UINT16 usMapIndex );
BOOLEAN ExtractScheduleEntryAndExitInfo( SOLDIERTYPE * pSoldier, UINT32 * puiEntryTime, UINT32 * puiExitTime );
BOOLEAN ExtractScheduleDoorLockAndUnlockInfo( SOLDIERTYPE * pSoldier, UINT32 * puiOpeningTime, UINT32 * puiClosingTime );
void ReconnectSchedules( void );
void SecureSleepSpot( SOLDIERTYPE * pSoldier, UINT16 usSleepSpot );
BOOLEAN BumpAnyExistingMerc( INT16 sGridNo );
#endif
File diff suppressed because it is too large Load Diff
+142
View File
@@ -0,0 +1,142 @@
#ifndef __STRATEGIC_AI_H
#define __STRATEGIC_AI_H
#include "FileMan.h"
#include "Strategic Movement.h"
void InitStrategicAI();
void KillStrategicAI();
BOOLEAN SaveStrategicAI( HWFILE hFile );
BOOLEAN LoadStrategicAI( HWFILE hFile );
//NPC ACTION TRIGGERS SPECIAL CASE AI
enum
{
STRATEGIC_AI_ACTION_WAKE_QUEEN = 1,
STRATEGIC_AI_ACTION_KINGPIN_DEAD,
STRATEGIC_AI_ACTION_QUEEN_DEAD,
};
void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSectorY );
void CheckEnemyControlledSector( UINT8 ubSectorID );
void EvaluateQueenSituation();
extern BOOLEAN gfUseAlternateQueenPosition;
//returns TRUE if the group was deleted.
BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup );
void RemoveGroupFromStrategicAILists( UINT8 ubGroupID );
void RecalculateSectorWeight( UINT8 ubSectorID );
void RecalculateGroupWeight( GROUP *pGroup );
BOOLEAN OkayForEnemyToMoveThroughSector( UINT8 ubSectorID );
BOOLEAN EnemyPermittedToAttackSector( GROUP **pGroup, UINT8 ubSectorID );
void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
void InvestigateSector( UINT8 ubSectorID );
void WakeUpQueen();
void StrategicHandleMineThatRanOut( UINT8 ubSectorID );
INT16 FindPatrolGroupIndexForGroupID( UINT8 ubGroupID );
INT16 FindPatrolGroupIndexForGroupIDPending( UINT8 ubGroupID );
INT16 FindGarrisonIndexForGroupIDPending( UINT8 ubGroupID );
GROUP* FindPendingGroupInSector( UINT8 ubSectorID );
void RepollSAIGroup( GROUP *pGroup );
//When an enemy AI group is eliminated by the player, apply a grace period in which the
//group isn't allowed to be filled for several days.
void TagSAIGroupWithGracePeriod( GROUP *pGroup );
BOOLEAN PermittedToFillPatrolGroup( INT32 iPatrolID );
extern BOOLEAN gfDisplayStrategicAILogs;
extern BOOLEAN gfFirstBattleMeanwhileScenePending;
extern UINT8 gubSAIVersion;
//These enumerations define all of the various types of stationary garrison
//groups, and index their compositions for forces, etc.
enum
{
QUEEN_DEFENCE, //The most important sector, the queen's palace.
MEDUNA_DEFENCE, //The town surrounding the queen's palace.
MEDUNA_SAMSITE, //A sam site within Meduna (higher priority)
LEVEL1_DEFENCE, //The sectors immediately adjacent to Meduna (defence and spawning area)
LEVEL2_DEFENCE, //Two sectors away from Meduna (defence and spawning area)
LEVEL3_DEFENCE, //Three sectors away from Meduna (defence and spawning area)
ORTA_DEFENCE, //The top secret military base containing lots of elites
EAST_GRUMM_DEFENCE, //The most-industrial town in Arulco (more mine income)
WEST_GRUMM_DEFENCE, //The most-industrial town in Arulco (more mine income)
GRUMM_MINE,
OMERTA_WELCOME_WAGON,//Small force that greets the player upon arrival in game.
BALIME_DEFENCE, //Rich town, paved roads, close to Meduna (in queen's favor)
TIXA_PRISON, //Prison, well defended, but no point in retaking
TIXA_SAMSITE, //The central-most sam site (important for queen to keep)
ALMA_DEFENCE, //The military town of Meduna. Also very important for queen.
ALMA_MINE, //Mine income AND administrators
CAMBRIA_DEFENCE, //Medical town, large, central.
CAMBRIA_MINE,
CHITZENA_DEFENCE, //Small town, small mine, far away.
CHITZENA_MINE,
CHITZENA_SAMSITE, //Sam site near Chitzena.
DRASSEN_AIRPORT, //Very far away, a supply depot of little importance.
DRASSEN_DEFENCE, //Medium town, normal.
DRASSEN_MINE,
DRASSEN_SAMSITE, //Sam site near Drassen (least importance to queen of all samsites)
ROADBLOCK, //General outside city roadblocks -- enhance chance of ambush?
SANMONA_SMALL,
NUM_ARMY_COMPOSITIONS
};
typedef struct ARMY_COMPOSITION
{
INT32 iReadability; //contains the enumeration which is useless, but helps readability.
INT8 bPriority;
INT8 bElitePercentage;
INT8 bTroopPercentage;
INT8 bAdminPercentage;
INT8 bDesiredPopulation;
INT8 bStartPopulation;
INT8 bPadding[10];
}ARMY_COMPOSITION;
//Defines the patrol groups -- movement groups.
typedef struct PATROL_GROUP
{
INT8 bSize;
INT8 bPriority;
UINT8 ubSectorID[4];
INT8 bFillPermittedAfterDayMod100;
UINT8 ubGroupID;
INT8 bWeight;
UINT8 ubPendingGroupID;
INT8 bPadding[10];
}PATROL_GROUP;
//Defines all stationary defence forces.
typedef struct GARRISON_GROUP
{
UINT8 ubSectorID;
UINT8 ubComposition;
INT8 bWeight;
UINT8 ubPendingGroupID;
INT8 bPadding[10];
}GARRISON_GROUP;
#endif
+229
View File
@@ -0,0 +1,229 @@
#ifndef __STRATEGIC_ALL_H
#define __STRATEGIC_ALL_H
#pragma message("GENERATED PCH FOR STRATEGIC PROJECT.")
#include <stdio.h>
#include "types.h"
#include "english.h"
#include "Timer Control.h"
#include "vsurface.h"
#include "Button System.h"
#include "Font Control.h"
#include "Simple Render Utils.h"
#include "Editor Taskbar Utils.h"
#include "line.h"
#include "input.h"
#include "vobject_blitters.h"
#include "Text Input.h"
#include "mousesystem.h"
#include "strategicmap.h"
#include "Fileman.h"
#include "Map Information.h"
#include "render dirty.h"
#include "Game Clock.h"
#include "Campaign Types.h"
#include "Campaign Init.h"
#include "cheats.h"
#include "Queen Command.h"
#include "overhead.h"
#include "Strategic Movement.h"
#include "GameSettings.h"
#include "Game Event Hook.h"
#include "Creature Spreading.h"
#include "message.h"
#include "Game Init.h"
#include "Assignments.h"
#include "Soldier Control.h"
#include "Item Types.h"
#include "Strategic.h"
#include "Items.h"
#include <stdlib.h>
#include "Map Screen Interface.h"
#include "Soldier Profile Type.h"
#include "Soldier Profile.h"
#include "Campaign.h"
#include "Text.h"
#include "dialogue control.h"
#include "NPC.h"
#include "Strategic Town Loyalty.h"
#include "animation control.h"
#include "mapscreen.h"
#include "Squads.h"
#include "Map Screen Helicopter.h"
#include "PopUpBox.h"
#include "Vehicles.h"
#include "Strategic Merc Handler.h"
#include "Merc Contract.h"
#include "Map Screen Interface Map.h"
#include "laptop.h"
#include "Finances.h"
#include "LaptopSave.h"
#include "renderworld.h"
#include "Interface Control.h"
#include "Interface.h"
#include "Soldier Find.h"
#include "ai.h"
#include "utilities.h"
#include "random.h"
#include "Soldier Add.h"
#include "Isometric Utils.h"
#include "Soldier Macros.h"
#include "Explosion Control.h"
#include "SkillCheck.h"
#include "Quests.h"
#include "Town Militia.h"
#include "Map Screen Interface Border.h"
#include "math.h"
#include "Strategic Pathing.h"
#include "Auto Resolve.h"
#include "Music Control.h"
#include "PreBattle Interface.h"
#include "Player Command.h"
#include "gameloop.h"
#include "screenids.h"
#include "vObject.h"
#include "video.h"
#include "gamescreen.h"
#include "sysutil.h"
#include "Soldier Create.h"
#include "Weapons.h"
#include "Sound Control.h"
#include "Tactical Save.h"
#include "Strategic Status.h"
#include "WordWrap.h"
#include "Animation Data.h"
#include "Strategic AI.h"
#include "rt time defines.h"
#include "morale.h"
#include "himage.h"
#include "Soldier Init List.h"
#include "lighting.h"
#include "Strategic Mines.h"
#include "jascreens.h"
#include "Map Edgepoints.h"
#include "opplist.h"
#include "sgp.h"
#include "environment.h"
#include "Game Events.h"
#include "MercTextBox.h"
#include "Event Pump.h"
#include "soundman.h"
#include "Ambient Control.h"
#include "AimMembers.h"
#include "Strategic Event Handler.h"
#include "BobbyR.h"
#include "mercs.h"
#include "email.h"
#include "Merc Hiring.h"
#include "Insurance Contract.h"
#include "Scheduling.h"
#include "BobbyRGuns.h"
#include "Arms Dealer Init.h"
#include "Strategic town reputation.h"
#include "air raid.h"
#include "meanwhile.h"
#include "MemMan.h"
#include "Debug.h"
#include "worlddef.h"
#include "fade screen.h"
#include "history.h"
#include "merc entering.h"
#include <String.h>
#include "worldman.h"
#include "tiledat.h"
#include "WCheck.h"
#include "Map Screen Interface Map Inventory.h"
#include "Map Screen Interface Bottom.h"
#include "Radar Screen.h"
#include "cursors.h"
#include "Options Screen.h"
#include "Cursor Control.h"
#include "Interface Items.h"
#include "Interface Utils.h"
#include "World Items.h"
#include "Multi Language Graphic Utils.h"
#include "Font.h"
#include "Militia Control.h"
#include "Map Screen Interface TownMine Info.h"
#include "Handle UI.h"
#include "Handle Items.h"
#include <stdarg.h>
#include <time.h>
#include "screens.h"
#include <wchar.h>
#include <tchar.h>
#include "Interface Cursors.h"
#include "Interface Panels.h"
#include "sys globals.h"
#include "faces.h"
#include "strategic turns.h"
#include "Personnel.h"
#include "Animated ProgressBar.h"
#include "GameVersion.h"
#include "SaveLoadScreen.h"
#include "messageboxscreen.h"
#include "rotting corpses.h"
#include "Tactical Placement GUI.h"
#include "Overhead Types.h"
#include "Soldier Ani.h"
#include "Types.h"
#include "Quest Debug System.h"
#include "WCheck.h"
#include "Font Control.h"
#include "Video.h"
#include "Game Clock.h"
#include "Render Dirty.h"
#include "WordWrap.h"
#include "Interface.h"
#include "Cursors.h"
#include "Quests.h"
#include "stdio.h"
#include "QuestText.h"
#include "Soldier Profile.h"
#include "Utilities.h"
#include "Text.h"
#include "Text Input.h"
#include "Soldier Create.h"
#include "strategicmap.h"
#include "soldier add.h"
#include "Opplist.h"
#include "Handle Items.h"
#include "Game Clock.h"
#include "environment.h"
#include "dialogue control.h"
#include "Soldier Control.h"
#include "overhead.h"
#include "AimMembers.h"
#include "MessageBoxScreen.h"
#include "Stdio.h"
#include "english.h"
#include "line.h"
#include "Keys.h"
#include "Interface Dialogue.h"
#include "SysUtil.h"
#include "Message.h"
#include "Interface Dialogue.h"
#include "Render Fun.h"
#include "Boxing.h"
#include <memory.h>
#include "Keys.h"
#include "Structure Wrap.h"
#include "SaveLoadMap.h"
#include "aim.h"
#include <windows.h>
#include "Inventory Choosing.h"
#include "LOS.h"
#include "Tactical Turns.h"
#include <math.h>
#include "worlddat.h"
#include "Exit Grids.h"
#include "pathai.h"
#include "Shade Table Util.h"
#include "points.h"
#include "Bullets.h"
#include "physics.h"
#include "_JA25EnglishText.h"
#include "Debug Control.h"
#include "expat.h"
#endif
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
#ifndef _STRATEGIC_EVENT_HANDLER_H_
#define _STRATEGIC_EVENT_HANDLER_H_
#include "Types.h"
#define KINGPIN_MONEY_SECTOR_X 5
#define KINGPIN_MONEY_SECTOR_Y MAP_ROW_D
#define KINGPIN_MONEY_SECTOR_Z 1
#define HOSPITAL_SECTOR_X 8
#define HOSPITAL_SECTOR_Y MAP_ROW_F
#define HOSPITAL_SECTOR_Z 0
extern UINT8 gubCambriaMedicalObjects;
void CheckForKingpinsMoneyMissing( BOOLEAN fFirstCheck );
void CheckForMissingHospitalSupplies( void );
void BobbyRayPurchaseEventCallback( UINT8 ubOrderID );
void HandleStolenItemsReturned( void );
void AddSecondAirportAttendant( void );
void SetPabloToUnbribed( void );
void HandleNPCSystemEvent( UINT32 uiEvent );
void HandleEarlyMorningEvents( void );
void MakeCivGroupHostileOnNextSectorEntrance( UINT8 ubCivGroup );
void RemoveAssassin( UINT8 ubProfile );
#endif
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
#ifndef _STRATEGIC_MERC_HANDLER_H_
#define _STRATEGIC_MERC_HANDLER_H_
void StrategicHandlePlayerTeamMercDeath( SOLDIERTYPE *pSoldier );
void MercDailyUpdate();
void MercsContractIsFinished( UINT8 ubID );
void RPCWhineAboutNoPay( UINT8 ubID );
void MercComplainAboutEquipment( UINT8 ubProfileID );
BOOLEAN SoldierHasWorseEquipmentThanUsedTo( SOLDIERTYPE *pSoldier );
void UpdateBuddyAndHatedCounters( void );
void HourlyCamouflageUpdate( void );
#endif
File diff suppressed because it is too large Load Diff
+204
View File
@@ -0,0 +1,204 @@
#ifndef __STRATEGIC_MINES_H
#define __STRATEGIC_MINES_H
// the .h to the mine management system
#include "Types.h"
// the mines
enum{
MINE_SAN_MONA = 0,
MINE_DRASSEN,
MINE_ALMA,
MINE_CAMBRIA,
MINE_CHITZENA,
MINE_GRUMM,
MAX_NUMBER_OF_MINES,
};
enum{
MINER_FRED = 0,
MINER_MATT,
MINER_OSWALD,
MINER_CALVIN,
MINER_CARL,
NUM_HEAD_MINERS,
};
// different types of mines
enum{
SILVER_MINE=0,
GOLD_MINE,
NUM_MINE_TYPES,
};
// monster infestatation level, as percieved by the villagers
enum{
MINES_NO_MONSTERS = 0, // nothing there at all
MINES_TRACE_MONSTERS, // monsters leave traces behind, but no one has seen them yet
MINES_SOME_MONSTERS, // there have been sightings but no one believes the witnesses
MINES_MODERATE_MONSTERS, // scattered reports of monsters in lower levels, leaves workers uneasy
MINES_HIGH_MONSTERS, // workers know they are there and all but a few refuse to work
MINES_RAMPANT_MONSTERS, // the few that go down don't seem to return, no one wants to work period
MINES_MONSTERS_SURFACE, // monsters are coming out of the mines into the town looking for any edibles
};
// head miner quote types
enum{
HEAD_MINER_STRATEGIC_QUOTE_RUNNING_OUT = 0,
HEAD_MINER_STRATEGIC_QUOTE_CREATURES_ATTACK,
HEAD_MINER_STRATEGIC_QUOTE_CREATURES_GONE,
HEAD_MINER_STRATEGIC_QUOTE_CREATURES_AGAIN,
NUM_HEAD_MINER_STRATEGIC_QUOTES
};
// the strategic mine structures
typedef struct MINE_LOCATION_TYPE
{
INT16 sSectorX; // x value of sector mine is in
INT16 sSectorY; // y value of sector mine is in
INT8 bAssociatedTown; // associated town of this mine
} MINE_LOCATION_TYPE;
typedef struct MINE_STATUS_TYPE
{
UINT8 ubMineType; // type of mine (silver or gold)
BYTE filler1[3];
UINT32 uiMaxRemovalRate; // fastest rate we can move ore from this mine in period
UINT32 uiRemainingOreSupply; // the total value left to this mine (-1 means unlimited)
UINT32 uiOreRunningOutPoint; // when supply drop below this, workers tell player the mine is running out of ore
BOOLEAN fEmpty; // whether no longer minable
BOOLEAN fRunningOut; // whether mine is beginning to run out
BOOLEAN fWarnedOfRunningOut; // whether mine foreman has already told player the mine's running out
BOOLEAN fShutDownIsPermanent; // means will never produce again in the game (head miner was attacked & died/quit)
BOOLEAN fShutDown; // TRUE means mine production has been shut off
BOOLEAN fPrevInvadedByMonsters; // whether or not mine has been previously invaded by monsters
BOOLEAN fSpokeToHeadMiner; // player doesn't receive income from mine without speaking to the head miner first
BOOLEAN fMineHasProducedForPlayer; // player has earned income from this mine at least once
BOOLEAN fQueenRetookProducingMine; // whether or not queen ever retook a mine after a player had produced from it
BOOLEAN fAttackedHeadMiner; // player has attacked the head miner, shutting down mine & decreasing loyalty
UINT16 usValidDayCreaturesCanInfest; //Creatures will be permitted to spread if the game day is greater than this value.
UINT32 uiTimePlayerProductionStarted; // time in minutes when 'fMineHasProducedForPlayer' was first set
BYTE filler[11]; // reserved for expansion
} MINE_STATUS_TYPE;
typedef struct HEAD_MINER_TYPE
{
UINT16 usProfileId;
INT8 bQuoteNum[NUM_HEAD_MINER_STRATEGIC_QUOTES];
UINT8 ubExternalFace;
} HEAD_MINER_TYPE;
// init mines
void InitializeMines( void );
void HourlyMinesUpdate(void);
// get total left in this mine
INT32 GetTotalLeftInMine( INT8 bMineIndex );
// get max rates for this mine (per period, per day)
UINT32 GetMaxPeriodicRemovalFromMine( INT8 bMineIndex );
UINT32 GetMaxDailyRemovalFromMine( INT8 bMineIndex );
// which town does this mine belong to?
INT8 GetTownAssociatedWithMine( INT8 bMineIndex );
// which mine belongs tot his town
INT8 GetMineAssociatedWithThisTown( INT8 bTownValue );
// posts the actual mine production events daily
void PostEventsForMineProduction(void);
// the periodic checking for income from mines
void HandleIncomeFromMines( void );
// predict income from mines
INT32 PredictIncomeFromPlayerMines( void );
// predict income from a mine
UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex );
// calculate maximum possible daily income from all mines
INT32 CalcMaxPlayerIncomeFromMines( void );
// get index value of this mine in the mine list
INT8 GetMineIndexForSector( INT16 sX, INT16 sY );
// get the index of the mine associated with this town
INT8 GetMineIndexForTown( INT8 bTownId );
// get the sector value for the mine associated with this town
INT16 GetMineSectorForTown( INT8 bTownId );
// is there a mine here?
BOOLEAN IsThereAMineInThisSector( INT16 sX, INT16 sY );
//Save the mine status to the save game file
BOOLEAN SaveMineStatusToSaveGameFile( HWFILE hFile );
//Load the mine status from the saved game file
BOOLEAN LoadMineStatusFromSavedGameFile( HWFILE hFile );
// if the player controls a given mine
BOOLEAN PlayerControlsMine(INT8 bMineIndex);
void ShutOffMineProduction( INT8 bMineIndex );
void RestartMineProduction( INT8 bMineIndex );
void MineShutdownIsPermanent( INT8 bMineIndex );
BOOLEAN IsMineShutDown( INT8 bMineIndex );
UINT8 GetHeadMinerIndexForMine( INT8 bMineIndex );
UINT16 GetHeadMinerProfileIdForMine( INT8 bMineIndex );
// Find the sector location of a mine
void GetMineSector( UINT8 ubMineIndex, INT16 * psX, INT16 * psY );
void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType );
UINT8 GetHeadMinersMineIndex(UINT8 ubMinerProfileId);
void PlayerSpokeToHeadMiner(UINT8 ubMinerProfile );
BOOLEAN IsHisMineRunningOut(UINT8 ubMinerProfileId );
BOOLEAN IsHisMineEmpty(UINT8 ubMinerProfileId );
BOOLEAN IsHisMineDisloyal(UINT8 ubMinerProfileId );
BOOLEAN IsHisMineInfested(UINT8 ubMinerProfileId );
BOOLEAN IsHisMineLostAndRegained(UINT8 ubMinerProfileId );
BOOLEAN IsHisMineAtMaxProduction(UINT8 ubMinerProfileId );
void ResetQueenRetookMine( UINT8 ubMinerProfileId );
void QueenHasRegainedMineSector(INT8 bMineIndex);
BOOLEAN HasAnyMineBeenAttackedByMonsters(void);
void PlayerAttackedHeadMiner( UINT8 ubMinerProfileId );
BOOLEAN HasHisMineBeenProducingForPlayerForSomeTime( UINT8 ubMinerProfileId );
// given sector value, get mine id value
INT8 GetIdOfMineForSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// use this for miner (civilian) quotes when *underground* in a mine
BOOLEAN PlayerForgotToTakeOverMine( UINT8 ubMineIndex );
// use this to determine whether or not to place miners into a underground mine level
BOOLEAN AreThereMinersInsideThisMine( UINT8 ubMineIndex );
// use this to determine whether or not the player has spoken to a head miner
BOOLEAN SpokenToHeadMiner( UINT8 ubMineIndex );
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+306
View File
@@ -0,0 +1,306 @@
#ifndef __STRATEGIC_MOVEMENT_H
#define __STRATEGIC_MOVEMENT_H
#include "types.h"
#include "Soldier Control.h"
#include "FileMan.h"
enum //enemy intentions,
{
NO_INTENTIONS, //enemy intentions are undefined.
PURSUIT, //enemy group has spotted a player group and is pursuing them. If they lose the player group, they
//will get reassigned.
STAGING, //enemy is prepare to assault a town sector, but doesn't have enough troops.
PATROL, //enemy is moving around determining safe areas.
REINFORCEMENTS, //enemy group has intentions to fortify position at final destination.
ASSAULT, //enemy is ready to fight anything they encounter.
NUM_ENEMY_INTENTIONS
};
enum //move types
{
ONE_WAY, //from first waypoint to last, deleting each waypoint as they are reached.
CIRCULAR, //from first to last, recycling forever.
ENDTOEND_FORWARDS, //from first to last -- when reaching last, change to backwards.
ENDTOEND_BACKWARDS //from last to first -- when reaching first, change to forwards.
};
enum
{
NORTH_STRATEGIC_MOVE,
EAST_STRATEGIC_MOVE,
SOUTH_STRATEGIC_MOVE,
WEST_STRATEGIC_MOVE,
THROUGH_STRATEGIC_MOVE
};
//This structure contains all of the information about a group moving in the strategic
//layer. This includes all troops, equipment, and waypoints, and location.
//NOTE: This is used for groups that are initiating a movement to another sector.
typedef struct WAYPOINT
{
UINT8 x; //sector x position of waypoint
UINT8 y; //sector y position of waypoint
struct WAYPOINT *next; //next waypoint in list
}WAYPOINT;
#define PG_INDIVIDUAL_MERGED 0x01
typedef struct PLAYERGROUP
{
UINT8 ubProfileID; //SAVE THIS VALUE ONLY. The others are temp (for quick access)
UINT8 ubID; //index in the Menptr array
SOLDIERTYPE *pSoldier; //direct access to the soldier pointer
UINT8 bFlags; //flags referring to individual player soldiers
struct PLAYERGROUP *next; //next player in list
}PLAYERGROUP;
typedef struct ENEMYGROUP
{
UINT8 ubNumTroops; //number of regular troops in the group
UINT8 ubNumElites; //number of elite troops in the group
UINT8 ubNumAdmins; //number of administrators in the group
UINT8 ubLeaderProfileID; //could be Mike, maybe the warden... someone new, but likely nobody.
UINT8 ubPendingReinforcements;//This group is waiting for reinforcements before attacking or attempting to fortify newly aquired sector.
UINT8 ubAdminsInBattle; //number of administrators in currently in battle.
UINT8 ubIntention; //the type of group this is: patrol, assault, spies, etc.
UINT8 ubTroopsInBattle; //number of soldiers currently in battle.
UINT8 ubElitesInBattle; //number of elite soldiers currently in battle.
INT8 bPadding[20];
}ENEMYGROUP;
//NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE
// DELETED!!!
#define GROUPFLAG_SIMULTANEOUSARRIVAL_APPROVED 0x00000001
#define GROUPFLAG_SIMULTANEOUSARRIVAL_CHECKED 0x00000002
//I use this flag when traversing through a list to determine which groups meet whatever conditions,
//then add this marker flag. The second time I traverse the list, I simply check for this flag,
//apply my modifications to the group, and remove the flag. If you decide to use it, make sure the
//flag is cleared.
#define GROUPFLAG_MARKER 0x00000004
//Set whenever a group retreats from battle. If the group arrives in the next sector and enemies are there
//retreat will not be an option.
#define GROUPFLAG_JUST_RETREATED_FROM_BATTLE 0x00000008
#define GROUPFLAG_HIGH_POTENTIAL_FOR_AMBUSH 0x00000010
#define GROUPFLAG_GROUP_ARRIVED_SIMULTANEOUSLY 0x00000020
typedef struct GROUP
{
BOOLEAN fDebugGroup; //for testing purposes -- handled differently in certain cases.
BOOLEAN fPlayer; //set if this is a player controlled group.
BOOLEAN fVehicle; //vehicle controlled group?
BOOLEAN fPersistant; //This flag when set prevents the group from being automatically deleted when it becomes empty.
UINT8 ubGroupID; //the unique ID of the group (used for hooking into events and SOLDIERTYPE)
UINT8 ubGroupSize; //total number of individuals in the group.
UINT8 ubSectorX, ubSectorY; //last/curr sector occupied
UINT8 ubSectorZ;
UINT8 ubNextX, ubNextY; //next sector destination
UINT8 ubPrevX, ubPrevY; //prev sector occupied (could be same as ubSectorX/Y)
UINT8 ubOriginalSector; //sector where group was created.
BOOLEAN fBetweenSectors; //set only if a group is between sector.
UINT8 ubMoveType; //determines the type of movement (ONE_WAY, CIRCULAR, ENDTOEND, etc.)
UINT8 ubNextWaypointID; //the ID of the next waypoint
UINT8 ubFatigueLevel; //the fatigue level of the weakest member in group
UINT8 ubRestAtFatigueLevel; //when the group's fatigue level <= this level, they will rest upon arrival at next sector.
UINT8 ubRestToFatigueLevel; //when resting, the group will rest until the fatigue level reaches this level.
UINT32 uiArrivalTime; //the arrival time in world minutes that the group will arrive at the next sector.
UINT32 uiTraverseTime; //the total traversal time from the previous sector to the next sector.
BOOLEAN fRestAtNight; //set when the group is permitted to rest between 2200 and 0600 when moving
BOOLEAN fWaypointsCancelled; //set when groups waypoints have been removed.
WAYPOINT *pWaypoints; //a list of all of the waypoints in the groups movement.
UINT8 ubTransportationMask; //the mask combining all of the groups transportation methods.
UINT32 uiFlags; //various conditions that apply to the group
UINT8 ubCreatedSectorID; //used for debugging strategic AI for keeping track of the sector ID a group was created in.
UINT8 ubSectorIDOfLastReassignment; //used for debuggin strategic AI. Records location of any reassignments.
INT8 bPadding[29]; //***********************************************//
union
{
PLAYERGROUP *pPlayerList; //list of players in the group
ENEMYGROUP *pEnemyGroup; //a structure containing general enemy info
};
struct GROUP *next; //next group
}GROUP;
extern GROUP *gpGroupList;
//General utility functions
void RemoveAllGroups();
GROUP* GetGroup( UINT8 ubGroupID );
//Remove a group from the list. This removes all of the waypoints as well as the members of the group.
//Calling this function doesn't position them in a sector. It is up to you to do that. The event system
//will automatically handle their updating as they arrive in sectors.
void RemoveGroup( UINT8 ubGroupID );//takes a groupID
void RemovePGroup( GROUP *pGroup ); //same function, but takes a GROUP*
void RemoveGroupIdFromList( UINT8 ubId );
//Clears a groups waypoints. This is necessary when sending new orders such as different routes.
void RemoveGroupWaypoints( UINT8 ubGroupID );
void RemovePGroupWaypoints( GROUP *pGroup ); //same function, but takes a GROUP*
//Player grouping functions
//.........................
//Creates a new player group, returning the unique ID of that group. This is the first
//step before adding waypoints and members to the player group.
UINT8 CreateNewPlayerGroupDepartingFromSector( UINT8 ubSectorX, UINT8 ubSectorY );
//Allows you to add or remove players from the group.
BOOLEAN AddPlayerToGroup( UINT8 ubGroupID, SOLDIERTYPE *pSoldier);
BOOLEAN RemovePlayerFromGroup( UINT8 ubGroupID, SOLDIERTYPE *pSoldier );
BOOLEAN RemovePlayerFromPGroup( GROUP *pGroup, SOLDIERTYPE *pSoldier );
BOOLEAN RemoveAllPlayersFromGroup( UINT8 ubGroupId );
BOOLEAN RemoveAllPlayersFromPGroup( GROUP *pGroup );
// create a vehicle group, it is by itself,
UINT8 CreateNewVehicleGroupDepartingFromSector( UINT8 ubSectorX, UINT8 ubSectorY , UINT32 uiVehicleId );
//Appends a waypoint to the end of the list. Waypoint MUST be on the
//same horizontal xor vertical level as the last waypoint added.
BOOLEAN AddWaypointToGroup( UINT8 ubGroupID, UINT8 ubSectorX, UINT8 ubSectorY );
BOOLEAN AddWaypointToPGroup( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY );
//Same, but uses a plain sectorID (0-255)
BOOLEAN AddWaypointIDToGroup( UINT8 ubGroupID, UINT8 ubSectorID );
BOOLEAN AddWaypointIDToPGroup( GROUP *pGroup, UINT8 ubSectorID );
//Same, but uses a strategic sectorID
BOOLEAN AddWaypointStrategicIDToGroup( UINT8 ubGroupID, UINT32 uiSectorID );
BOOLEAN AddWaypointStrategicIDToPGroup( GROUP *pGroup, UINT32 uiSectorID );
//Allows you to change any group's orders based on movement type, and when to rest
BOOLEAN SetGroupPatrolParameters( UINT8 ubGroupID, UINT8 ubRestAtFL, UINT8 ubRestToFL, BOOLEAN fRestAtNight );
//Enemy grouping functions -- private use by the strategic AI.
//............................................................
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
//ARRIVALCALLBACK -- None of these functions should be called directly.
//...............
//This is called whenever any group arrives in the next sector (player or enemy)
//This function will first check to see if a battle should start, or if they
//aren't at the final destination, they will move to the next sector.
void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNeverLeft );
//Calculates and posts an event to move the group to the next sector.
void InitiateGroupMovementToNextSector( GROUP *pGroup );
void CalculateNextMoveIntention( GROUP *pGroup );
// set current sector of the group..used for player controlled mercs
void SetGroupSectorValue( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubGroupID );
void SetEnemyGroupSector( GROUP *pGroup, UINT8 ubSectorID );
// set groups next sector x,y value..used ONLY for teleporting groups
void SetGroupNextSectorValue( INT16 sSectorX, INT16 sSectorY, UINT8 ubGroupID );
// calculate the eta time in world total mins of this group
INT32 CalculateTravelTimeOfGroup( GROUP *pGroup );
INT32 CalculateTravelTimeOfGroupId( UINT8 ubId );
INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup );
UINT8 PlayerMercsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ );
UINT8 PlayerGroupsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ );
// is the player greoup with this id in motion
BOOLEAN PlayerIDGroupInMotion( UINT8 ubID );
// is this player group in motion?
BOOLEAN PlayerGroupInMotion( GROUP *pGroup );
// find if a path exists?
INT32 GetTravelTimeForFootTeam( UINT8 ubSector, UINT8 ubDirection );
// get travel time for this group?
INT32 GetTravelTimeForGroup( UINT8 ubSector, UINT8 ubDirection, UINT8 ubGroup );
// get number of mercs between sectors
BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnter, INT32 *iCountExit, BOOLEAN *fAboutToArriveEnter );
// set this groups waypoints as cancelled
void SetWayPointsAsCanceled( UINT8 ubGroupID );
void SetGroupPrevSectors( UINT8 ubGroupID, UINT8 ubX, UINT8 ubY );
void MoveAllGroupsInCurrentSectorToSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ );
// this is for groups that are between sectors, nothing else
// get group position
void GetGroupPosition( UINT8 *ubNextX, UINT8 *ubNextY, UINT8 *ubPrevX, UINT8 *ubPrevY, UINT32 *uiTraverseTime, UINT32 *uiArriveTime, UINT8 ubGroupId );
// set groups postion
void SetGroupPosition( UINT8 ubNextX, UINT8 ubNextY, UINT8 ubPrevX, UINT8 ubPrevY, UINT32 uiTraverseTime, UINT32 uiArriveTime, UINT8 ubGroupId );
//Save the strategic movemnet Group paths to the saved game file
BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile );
//Load the strategic movement Group paths from the saved game file
BOOLEAN LoadStrategicMovementGroupsFromSavedGameFile( HWFILE hFile );
// check members of mvt group, if any are bleeding, complain before moving
void CheckMembersOfMvtGroupAndComplainAboutBleeding( SOLDIERTYPE *pSoldier );
void HandleArrivalOfReinforcements( GROUP *pGroup );
void PlanSimultaneousGroupArrivalCallback( UINT8 bMessageValue );
//When groups meet up, then it is possible that they may join up. This only happens if
//the groups were separated because of singular tactical/exitgrid traversal, and the timing
//expires.
BOOLEAN AttemptToMergeSeparatedGroups( GROUP *pGroup, BOOLEAN fDecrementTraversals );
//Called when all checks have been made for the group (if possible to retreat, etc.) This function
//blindly determines where to move the group.
void RetreatGroupToPreviousSector( GROUP *pGroup );
GROUP* FindMovementGroupInSector( UINT8 ubSectorX, UINT8 ubSectorY, BOOLEAN fPlayer );
BOOLEAN GroupAtFinalDestination( GROUP *pGroup );
// find the travel time between waypts for this group
INT32 FindTravelTimeBetweenWaypoints( WAYPOINT * pSource, WAYPOINT * pDest, GROUP *pGroup );
BOOLEAN GroupReversingDirectionsBetweenSectors( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY, BOOLEAN fBuildingWaypoints );
BOOLEAN GroupBetweenSectorsAndSectorXYIsInDifferentDirection( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY );
void RemoveGroupFromList( GROUP *pGroup );
WAYPOINT *GetFinalWaypoint( GROUP *pGroup );
void ResetMovementForEnemyGroupsInLocation( UINT8 ubSectorX, UINT8 ubSectorY );
void ResetMovementForEnemyGroup( GROUP *pGroup );
//Determines if any particular group WILL be moving through a given sector given it's current
//position in the route and TREATS the pGroup->ubMoveType as ONE_WAY EVEN IF IT ISN'T. If the
//group is currently IN the sector, or just left the sector, it will return FALSE.
BOOLEAN GroupWillMoveThroughSector( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY );
//Vehicle fuel support functions
INT16 CalculateFuelCostBetweenSectors( UINT8 ubSectorID1, UINT8 ubSectorID2 );
BOOLEAN VehicleHasFuel( SOLDIERTYPE *pSoldier );
INT16 VehicleFuelRemaining( SOLDIERTYPE *pSoldier );
BOOLEAN SpendVehicleFuel( SOLDIERTYPE* pSoldier, INT16 sFuelSpent );
void ReportVehicleOutOfGas( INT32 iVehicleID, UINT8 ubSectorX, UINT8 ubSectorY );
void RandomizePatrolGroupLocation( GROUP *pGroup );
void InitStrategicMovementCosts();
void PlaceGroupInSector( UINT8 ubGroupID, INT16 sPrevX, INT16 sPrevY, INT16 sNextX, INT16 sNextY, INT8 bZ, BOOLEAN fCheckForBattle );
void SetGroupArrivalTime( GROUP *pGroup, UINT32 uiArrivalTime );
void PlayerGroupArrivedSafelyInSector( GROUP *pGroup, BOOLEAN fCheckForNPCs );
BOOLEAN DoesPlayerExistInPGroup( UINT8 ubGroupID, SOLDIERTYPE *pSoldier );
BOOLEAN GroupHasInTransitDeadOrPOWMercs( GROUP *pGroup );
#endif
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
#ifndef __STRATPATH_H
#define __STRATPATH_H
#include "Map Screen Interface Map.h"
// directions of movement for badsector determination ( blocking off of a sector exit from foot or vehicle travel)
// Shortest Path Defines
#define NORTH_MOVE -18
#define EAST_MOVE 1
#define WEST_MOVE -1
#define SOUTH_MOVE 18
// Movement speed defines
#define NORMAL_MVT 1
#define SLOW_MVT 0
// movment modes
enum{
MVT_MODE_AIR,
MVT_MODE_VEHICLE,
MVT_MODE_FOOT,
};
INT32 FindStratPath(INT16 sStart, INT16 sDestination, INT16 sMvtGroupNumber, BOOLEAN fTacticalTraversal );
/*
BOOLEAN SectorIsBlockedFromVehicleExit( UINT16 sSectorDest, INT8 bToDirection );
BOOLEAN SectorIsBlockedFromFootExit( UINT16 sSector, INT8 bToDirection );
BOOLEAN TravelBetweenSectorsIsBlockedFromVehicle( UINT16 sSourceSector, UINT16 sDestSector );
BOOLEAN TravelBetweenSectorsIsBlockedFromFoot( UINT16 sSourceSector, UINT16 sDestSector );
BOOLEAN CanThisMercMoveToThisSector( SOLDIERTYPE *pSoldier ,INT16 sX, INT16 sY );
void SetThisMercsSectorXYToTheseValues( SOLDIERTYPE *pSoldier ,INT16 sX, INT16 sY, UINT8 ubFromDirection);
*/
BOOLEAN AddSectorToPathList( PathStPtr pPath ,UINT16 uiSectorNum );
// build a stategic path
PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEndSectorNum, INT16 sMvtGroupNumber, BOOLEAN fTacticalTraversal /*, BOOLEAN fTempPath */ );
// append onto path list
PathStPtr AppendStrategicPath( PathStPtr pNewSection, PathStPtr pHeadOfPathList );
// clear out strategic path list
PathStPtr ClearStrategicPathList( PathStPtr pHeadOfPath, INT16 sMvtGroup );
// move to beginning of list
PathStPtr MoveToBeginningOfPathList( PathStPtr pList );
// move to end of path list
PathStPtr MoveToEndOfPathList( PathStPtr pList );
// remove tail of list
PathStPtr RemoveTailFromStrategicPath( PathStPtr pHeadOfList );
// remove head of list
PathStPtr RemoveHeadFromStrategicPath( PathStPtr pList );
// remove node with this value.. starting at end and working it's way back
PathStPtr RemoveSectorFromStrategicPathList( PathStPtr pList , INT16 sX, INT16 sY );
// clear out path list after/including this sector sX, sY..will start at end of path and work it's way back till sector is found...removes most recent sectors first
PathStPtr ClearStrategicPathListAfterThisSector( PathStPtr pHeadOfPath, INT16 sX, INT16 sY, INT16 sMvtGroup );
// get id of last sector in mercs path list
INT16 GetLastSectorIdInCharactersPath( SOLDIERTYPE *pCharacter );
// get id of last sector in mercs path list
INT16 GetLastSectorIdInVehiclePath( INT32 iId );
// copy paths
PathStPtr CopyPaths( PathStPtr pSourcePath, PathStPtr pDestPath );
// build eta's for characters path - no longer used
//void CalculateEtaForCharacterPath( SOLDIERTYPE *pCharacter );
/*
// move character along path
void MoveCharacterOnPath( SOLDIERTYPE *pCharacter );
// move the whole team
void MoveTeamOnFoot( void );
// get the final eta of this path to the last sector in it's list
UINT32 GetEtaGivenRoute( PathStPtr pPath );
*/
// rebuild way points for strategic mapscreen path changes
void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup );
// clear strategic movement (mercpaths and waypoints) for this soldier, and his group (including its vehicles)
void ClearMvtForThisSoldierAndGang( SOLDIERTYPE *pSoldier );
// start movement of this group to this sector...not to be used by the player merc groups.
BOOLEAN MoveGroupFromSectorToSector( UINT8 ubGroupID, INT16 sStartX, INT16 sStartY, INT16 sDestX, INT16 sDestY );
BOOLEAN MoveGroupFromSectorToSectorButAvoidPlayerInfluencedSectors( UINT8 ubGroupID, INT16 sStartX, INT16 sStartY, INT16 sDestX, INT16 sDestY );
BOOLEAN MoveGroupFromSectorToSectorButAvoidPlayerInfluencedSectorsAndStopOneSectorBeforeEnd( UINT8 ubGroupID, INT16 sStartX, INT16 sStartY, INT16 sDestX, INT16 sDestY );
/*
BOOLEAN MoveGroupToOriginalSector( UINT8 ubGroupID );
*/
// get length of path
INT32 GetLengthOfPath( PathStPtr pHeadPath );
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier );
// is the path empty?
BOOLEAN CheckIfPathIsEmpty( PathStPtr pHeadPath );
PathStPtr GetSoldierMercPathPtr( SOLDIERTYPE *pSoldier );
PathStPtr GetGroupMercPathPtr( GROUP *pGroup );
UINT8 GetSoldierGroupId( SOLDIERTYPE *pSoldier );
// clears this groups strategic movement (mercpaths and waypoints), include those in the vehicle structs(!)
void ClearMercPathsAndWaypointsForAllInGroup( GROUP *pGroup );
void ClearPathForSoldier( SOLDIERTYPE *pSoldier );
void AddSectorToFrontOfMercPathForAllSoldiersInGroup( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY );
#endif
+405
View File
@@ -0,0 +1,405 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include <memory.h>
#include "Strategic Status.h"
#include "Inventory Choosing.h"
#include "FileMan.h"
#include "Soldier Profile.h"
#include "Campaign.h"
#include "Strategic Mines.h"
#include "email.h"
#include "Game Clock.h"
#endif
STRATEGIC_STATUS gStrategicStatus;
void InitStrategicStatus(void)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitStrategicStatus: InitArmyGunTypes");
memset( &gStrategicStatus, 0, sizeof( STRATEGIC_STATUS ) );
//Add special non-zero start conditions here...
InitArmyGunTypes();
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitStrategicStatus: InitArmyGunTypes Done");
}
BOOLEAN SaveStrategicStatusToSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesWritten;
//Save the Strategic Status structure to the saved game file
FileWrite( hFile, &gStrategicStatus, sizeof( STRATEGIC_STATUS ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( STRATEGIC_STATUS ) )
{
return( FALSE );
}
return( TRUE );
}
BOOLEAN LoadStrategicStatusFromSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
//Load the Strategic Status structure from the saved game file
FileRead( hFile, &gStrategicStatus, sizeof( STRATEGIC_STATUS ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( STRATEGIC_STATUS ) )
{
return( FALSE );
}
return( TRUE );
}
#define DEATH_RATE_SEVERITY 1.0f // increase to make death rates higher for same # of deaths/time
UINT8 CalcDeathRate(void)
{
UINT32 uiDeathRate = 0;
// give the player a grace period of 1 day
if (gStrategicStatus.uiManDaysPlayed > 0)
{
// calculates the player's current death rate
uiDeathRate = (UINT32) ((gStrategicStatus.ubMercDeaths * DEATH_RATE_SEVERITY * 100) / gStrategicStatus.uiManDaysPlayed);
}
return((UINT8) uiDeathRate);
}
void ModifyPlayerReputation(INT8 bRepChange)
{
INT32 iNewBadRep;
// subtract, so that a negative reputation change results in an increase in bad reputation
iNewBadRep = (INT32) gStrategicStatus.ubBadReputation - bRepChange;
// keep within a 0-100 range (0 = Saint, 100 = Satan)
iNewBadRep = __max( 0, iNewBadRep );
iNewBadRep = __min( 100, iNewBadRep );
gStrategicStatus.ubBadReputation = (UINT8) iNewBadRep;
}
BOOLEAN MercThinksDeathRateTooHigh( UINT8 ubProfileID )
{
INT8 bDeathRateTolerance;
bDeathRateTolerance = gMercProfiles[ ubProfileID ].bDeathRate;
// if he couldn't care less what it is
if (bDeathRateTolerance == 101)
{
// then obviously it CAN'T be too high...
return(FALSE);
}
if (CalcDeathRate() > bDeathRateTolerance)
{
// too high - sorry
return(TRUE);
}
else
{
// within tolerance
return(FALSE);
}
}
BOOLEAN MercThinksBadReputationTooHigh( UINT8 ubProfileID )
{
INT8 bRepTolerance;
bRepTolerance = gMercProfiles[ ubProfileID ].bReputationTolerance;
// if he couldn't care less what it is
if (bRepTolerance == 101)
{
// then obviously it CAN'T be too high...
return(FALSE);
}
if (gStrategicStatus.ubBadReputation > bRepTolerance)
{
// too high - sorry
return(TRUE);
}
else
{
// within tolerance
return(FALSE);
}
}
// only meaningful for already hired mercs
BOOLEAN MercThinksHisMoraleIsTooLow( SOLDIERTYPE *pSoldier )
{
INT8 bRepTolerance;
INT8 bMoraleTolerance;
bRepTolerance = gMercProfiles[ pSoldier->ubProfile ].bReputationTolerance;
// if he couldn't care less what it is
if (bRepTolerance == 101)
{
// that obviously it CAN'T be too low...
return(FALSE);
}
// morale tolerance is based directly upon reputation tolerance
// above 50, morale is GOOD, never below tolerance then
bMoraleTolerance = (100 - bRepTolerance) / 2;
if (pSoldier->bMorale < bMoraleTolerance)
{
// too low - sorry
return(TRUE);
}
else
{
// within tolerance
return(FALSE);
}
}
void UpdateLastDayOfPlayerActivity( UINT16 usDay )
{
if ( usDay > gStrategicStatus.usLastDayOfPlayerActivity )
{
gStrategicStatus.usLastDayOfPlayerActivity = usDay;
gStrategicStatus.ubNumberOfDaysOfInactivity = 0;
}
}
UINT8 LackOfProgressTolerance( void )
{
if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
{
// give an EXTRA day over normal
return( 7 - DIF_LEVEL_MEDIUM + gStrategicStatus.ubHighestProgress / 42 );
}
else
{
return( 6 - gGameOptions.ubDifficultyLevel + gStrategicStatus.ubHighestProgress / 42 );
}
}
// called once per day in the morning, decides whether Enrico should send any new E-mails to the player
void HandleEnricoEmail(void)
{
UINT8 ubCurrentProgress = CurrentPlayerProgressPercentage();
UINT8 ubHighestProgress = HighestPlayerProgressPercentage();
// if creatures have attacked a mine (doesn't care if they're still there or not at the moment)
if (HasAnyMineBeenAttackedByMonsters() && !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_CREATURES))
{
AddEmail(ENRICO_CREATURES, ENRICO_CREATURES_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_CREATURES;
return; // avoid any other E-mail at the same time
}
if ((ubCurrentProgress >= SOME_PROGRESS_THRESHOLD) && !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_SOME_PROGRESS))
{
AddEmail(ENRICO_PROG_20, ENRICO_PROG_20_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_SOME_PROGRESS;
return; // avoid any setback E-mail at the same time
}
if ((ubCurrentProgress >= ABOUT_HALFWAY_THRESHOLD) && !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_ABOUT_HALFWAY))
{
AddEmail(ENRICO_PROG_55, ENRICO_PROG_55_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_ABOUT_HALFWAY;
return; // avoid any setback E-mail at the same time
}
if ((ubCurrentProgress >= NEARLY_DONE_THRESHOLD) && !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_NEARLY_DONE))
{
AddEmail(ENRICO_PROG_80, ENRICO_PROG_80_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_NEARLY_DONE;
return; // avoid any setback E-mail at the same time
}
// test for a major setback OR a second minor setback
if ((((ubHighestProgress - ubCurrentProgress) >= MAJOR_SETBACK_THRESHOLD) ||
(((ubHighestProgress - ubCurrentProgress) >= MINOR_SETBACK_THRESHOLD) && (gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_FLAG_SETBACK_OVER))) &&
!(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_MAJOR_SETBACK))
{
AddEmail(ENRICO_SETBACK, ENRICO_SETBACK_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_MAJOR_SETBACK;
}
else
// test for a first minor setback
if (((ubHighestProgress - ubCurrentProgress) >= MINOR_SETBACK_THRESHOLD) &&
!(gStrategicStatus.usEnricoEmailFlags & (ENRICO_EMAIL_SENT_MINOR_SETBACK | ENRICO_EMAIL_SENT_MAJOR_SETBACK)))
{
AddEmail(ENRICO_SETBACK_2, ENRICO_SETBACK_2_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_MINOR_SETBACK;
}
else
// if player is back at his maximum progress after having suffered a minor setback
if ((ubHighestProgress == ubCurrentProgress) && (gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_MINOR_SETBACK))
{
// remember that the original setback has been overcome, so another one can generate another E-mail
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_FLAG_SETBACK_OVER;
}
else if ( GetWorldDay() > (UINT32) (gStrategicStatus.usLastDayOfPlayerActivity) )
{
INT8 bComplaint = 0;
UINT8 ubTolerance;
gStrategicStatus.ubNumberOfDaysOfInactivity++;
ubTolerance = LackOfProgressTolerance();
if ( gStrategicStatus.ubNumberOfDaysOfInactivity >= ubTolerance )
{
if ( gStrategicStatus.ubNumberOfDaysOfInactivity == ubTolerance )
{
// send email
if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS1 ) )
{
bComplaint = 1;
}
else if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS2 ) )
{
bComplaint = 2;
}
else if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS3 ) )
{
bComplaint = 3;
}
}
else if ( gStrategicStatus.ubNumberOfDaysOfInactivity == (UINT32) ubTolerance * 2 )
{
// six days? send 2nd or 3rd message possibly
if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS2 ) )
{
bComplaint = 2;
}
else if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS3 ) )
{
bComplaint = 3;
}
}
else if ( gStrategicStatus.ubNumberOfDaysOfInactivity == ubTolerance * 3 )
{
// nine days??? send 3rd message possibly
if ( !(gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS3 ) )
{
bComplaint = 3;
}
}
if ( bComplaint != 0 )
{
switch( bComplaint )
{
case 3:
AddEmail(LACK_PLAYER_PROGRESS_3, LACK_PLAYER_PROGRESS_3_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_LACK_PROGRESS3;
break;
case 2:
AddEmail(LACK_PLAYER_PROGRESS_2, LACK_PLAYER_PROGRESS_2_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_LACK_PROGRESS2;
break;
default:
AddEmail(LACK_PLAYER_PROGRESS_1, LACK_PLAYER_PROGRESS_1_LENGTH, MAIL_ENRICO, GetWorldTotalMin());
gStrategicStatus.usEnricoEmailFlags |= ENRICO_EMAIL_SENT_LACK_PROGRESS1;
break;
}
AddHistoryToPlayersLog( HISTORY_ENRICO_COMPLAINED, 0, GetWorldTotalMin(), -1, -1 );
}
// penalize loyalty!
if ( gStrategicStatus.usEnricoEmailFlags & ENRICO_EMAIL_SENT_LACK_PROGRESS2 )
{
DecrementTownLoyaltyEverywhere( LOYALTY_PENALTY_INACTIVE * (gStrategicStatus.ubNumberOfDaysOfInactivity - LackOfProgressTolerance() + 1) );
}
else
{
// on first complaint, give a day's grace...
DecrementTownLoyaltyEverywhere( LOYALTY_PENALTY_INACTIVE * (gStrategicStatus.ubNumberOfDaysOfInactivity - LackOfProgressTolerance() ) );
}
}
}
// reset # of new sectors visited 'today'
// grant some leeway for the next day, could have started moving
// at night...
gStrategicStatus.ubNumNewSectorsVisitedToday = __min( gStrategicStatus.ubNumNewSectorsVisitedToday, NEW_SECTORS_EQUAL_TO_ACTIVITY ) / 3;
}
void TrackEnemiesKilled( UINT8 ubKilledHow, UINT8 ubSoldierClass )
{
INT8 bRankIndex;
bRankIndex = SoldierClassToRankIndex( ubSoldierClass );
// if it's not a standard enemy-class soldier
if ( bRankIndex == -1 )
{
// don't count him as an enemy
return;
}
gStrategicStatus.usEnemiesKilled[ ubKilledHow ][ bRankIndex ]++;
if ( ubKilledHow != ENEMY_KILLED_TOTAL )
{
gStrategicStatus.usEnemiesKilled[ ENEMY_KILLED_TOTAL ][ bRankIndex ]++;
}
}
INT8 SoldierClassToRankIndex( UINT8 ubSoldierClass )
{
INT8 bRankIndex = -1;
// the soldier class defines are not in natural ascending order, elite comes before army!
switch ( ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: bRankIndex = 0; break;
case SOLDIER_CLASS_ELITE: bRankIndex = 2; break;
case SOLDIER_CLASS_ARMY: bRankIndex = 1; break;
default:
// this happens when an NPC joins the enemy team (e.g. Conrad, Iggy, Mike)
break;
}
return( bRankIndex );
}
UINT8 RankIndexToSoldierClass( UINT8 ubRankIndex )
{
UINT8 ubSoldierClass = 0;
Assert( ubRankIndex < NUM_ENEMY_RANKS );
switch ( ubRankIndex )
{
case 0: ubSoldierClass = SOLDIER_CLASS_ADMINISTRATOR; break;
case 1: ubSoldierClass = SOLDIER_CLASS_ARMY; break;
case 2: ubSoldierClass = SOLDIER_CLASS_ELITE; break;
}
return( ubSoldierClass );
}
+133
View File
@@ -0,0 +1,133 @@
#ifndef __STRATEGIC_STATUS_H
#define __STRATEGIC_STATUS_H
#include "types.h"
#include "Item Types.h"
#include "Soldier Control.h"
//Enemy is allowed to capture the player after certain day
#define STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE 4
#define STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE 0x00000001
#define STRATEGIC_PLAYER_CAPTURED_FOR_ESCAPE 0x00000002
#define ARMY_GUN_LEVELS 11
// player reputation modifiers
#define REPUTATION_LOW_DEATHRATE +5
#define REPUTATION_HIGH_DEATHRATE -5
#define REPUTATION_GREAT_MORALE +3
#define REPUTATION_POOR_MORALE -3
#define REPUTATION_BATTLE_WON +2
#define REPUTATION_BATTLE_LOST -2
#define REPUTATION_TOWN_WON +5
#define REPUTATION_TOWN_LOST -5
#define REPUTATION_SOLDIER_DIED -2 // per exp. level
#define REPUTATION_SOLDIER_CAPTURED -1
#define REPUTATION_KILLED_CIVILIAN -5
#define REPUTATION_EARLY_FIRING -3
#define REPUTATION_KILLED_MONSTER_QUEEN +15
#define REPUTATION_KILLED_DEIDRANNA +25
// flags to remember whether a certain E-mail has already been sent out
#define ENRICO_EMAIL_SENT_SOME_PROGRESS 0x0001
#define ENRICO_EMAIL_SENT_ABOUT_HALFWAY 0x0002
#define ENRICO_EMAIL_SENT_NEARLY_DONE 0x0004
#define ENRICO_EMAIL_SENT_MINOR_SETBACK 0x0008
#define ENRICO_EMAIL_SENT_MAJOR_SETBACK 0x0010
#define ENRICO_EMAIL_SENT_CREATURES 0x0020
#define ENRICO_EMAIL_FLAG_SETBACK_OVER 0x0040
#define ENRICO_EMAIL_SENT_LACK_PROGRESS1 0x0080
#define ENRICO_EMAIL_SENT_LACK_PROGRESS2 0x0100
#define ENRICO_EMAIL_SENT_LACK_PROGRESS3 0x0200
// progress threshold that control Enrico E-mail timing
#define SOME_PROGRESS_THRESHOLD 20
#define ABOUT_HALFWAY_THRESHOLD 55
#define NEARLY_DONE_THRESHOLD 80
#define MINOR_SETBACK_THRESHOLD 5
#define MAJOR_SETBACK_THRESHOLD 15
#define NEW_SECTORS_EQUAL_TO_ACTIVITY 4
// enemy ranks
enum
{
ENEMY_RANK_ADMIN,
ENEMY_RANK_TROOP,
ENEMY_RANK_ELITE,
NUM_ENEMY_RANKS
};
// ways enemies can be killed
enum
{
ENEMY_KILLED_IN_TACTICAL,
ENEMY_KILLED_IN_AUTO_RESOLVE,
ENEMY_KILLED_TOTAL,
NUM_WAYS_ENEMIES_KILLED
};
typedef struct STRATEGIC_STATUS
{
UINT32 uiFlags;
UINT8 ubNumCapturedForRescue;
UINT8 ubHighestProgress; // the highest level of progress player has attained thus far in the game (0-100)
UINT8 ubStandardArmyGunIndex[ARMY_GUN_LEVELS]; // type of gun in each group that Queen's army is using this game
BOOLEAN fWeaponDroppedAlready[MAXITEMS]; // flag that tracks whether this weapon type has been dropped before
UINT8 ubMercDeaths; // how many soldiers have bit it while in the player's employ (0-100)
UINT32 uiManDaysPlayed; // once per day, # living mercs on player's team is added to this running total
UINT8 ubBadReputation; // how bad a reputation player has earned through his actions, performance, etc. (0-100)
UINT16 usEnricoEmailFlags; // bit flags that control progress-related E-mails from Enrico
UINT8 ubInsuranceInvestigationsCnt; // how many times merc has been investigated for possible insurance fraud
UINT8 ubUnhiredMercDeaths; // how many mercs have died while NOT working for the player
UINT16 usPlayerKills; // kills achieved by all mercs controlled by player together. *Excludes* militia kills!
UINT16 usEnemiesKilled[NUM_WAYS_ENEMIES_KILLED][NUM_ENEMY_RANKS]; // admin/troop/elite. Includes kills by militia, too
UINT16 usLastDayOfPlayerActivity;
UINT8 ubNumNewSectorsVisitedToday;
UINT8 ubNumberOfDaysOfInactivity;
INT8 bPadding[70];
} STRATEGIC_STATUS;
void InitStrategicStatus();
extern STRATEGIC_STATUS gStrategicStatus;
BOOLEAN SaveStrategicStatusToSaveGameFile( HWFILE hFile );
BOOLEAN LoadStrategicStatusFromSaveGameFile( HWFILE hFile );
UINT8 CalcDeathRate(void);
void ModifyPlayerReputation(INT8 bRepChange);
BOOLEAN MercThinksDeathRateTooHigh( UINT8 ubProfileID );
BOOLEAN MercThinksBadReputationTooHigh( UINT8 ubProfileID );
BOOLEAN MercThinksHisMoraleIsTooLow( SOLDIERTYPE *pSoldier );
void HandleEnricoEmail(void);
void TrackEnemiesKilled( UINT8 ubKilledHow, UINT8 ubSoldierClass );
INT8 SoldierClassToRankIndex( UINT8 ubSoldierClass );
UINT8 RankIndexToSoldierClass( UINT8 ubRankIndex );
void UpdateLastDayOfPlayerActivity( UINT16 usDay );
#endif
File diff suppressed because it is too large Load Diff
+207
View File
@@ -0,0 +1,207 @@
#ifndef __STRATEGIC_TOWN_LOYALTY_H
#define __STRATEGIC_TOWN_LOYALTY_H
#include "Types.h"
#include "mapscreen.h"
#include "Soldier Control.h"
// gain pts per real loyalty pt
#define GAIN_PTS_PER_LOYALTY_PT 500
// --- LOYALTY BONUSES ---
// Omerta
#define LOYALTY_BONUS_MIGUEL_READS_LETTER (10 * GAIN_PTS_PER_LOYALTY_PT) // multiplied by 4.5 due to Omerta's high seniment, so it's 45%
// Drassen
#define LOYALTY_BONUS_CHILDREN_FREED_DOREEN_KILLED (10 * GAIN_PTS_PER_LOYALTY_PT) // +50% bonus for Drassen
#define LOYALTY_BONUS_CHILDREN_FREED_DOREEN_SPARED (20 * GAIN_PTS_PER_LOYALTY_PT) // +50% bonus for Drassen
// Cambria
#define LOYALTY_BONUS_MARTHA_WHEN_JOEY_RESCUED (15 * GAIN_PTS_PER_LOYALTY_PT) // -25% for low Cambria sentiment
#define LOYALTY_BONUS_KEITH_WHEN_HILLBILLY_SOLVED (15 * GAIN_PTS_PER_LOYALTY_PT) // -25% for low Cambria sentiment
// Chitzena
#define LOYALTY_BONUS_YANNI_WHEN_CHALICE_RETURNED_LOCAL (20 * GAIN_PTS_PER_LOYALTY_PT) // +75% higher in Chitzena
#define LOYALTY_BONUS_YANNI_WHEN_CHALICE_RETURNED_GLOBAL (10 * GAIN_PTS_PER_LOYALTY_PT) // for ALL towns!
// Alma
#define LOYALTY_BONUS_AUNTIE_WHEN_BLOODCATS_KILLED (20 * GAIN_PTS_PER_LOYALTY_PT) // Alma's increases reduced by half due to low rebel sentiment
#define LOYALTY_BONUS_MATT_WHEN_DYNAMO_FREED (20 * GAIN_PTS_PER_LOYALTY_PT) // Alma's increases reduced by half due to low rebel sentiment
#define LOYALTY_BONUS_FOR_SERGEANT_KROTT (20 * GAIN_PTS_PER_LOYALTY_PT) // Alma's increases reduced by half due to low rebel sentiment
// Everywhere
#define LOYALTY_BONUS_TERRORISTS_DEALT_WITH ( 5 * GAIN_PTS_PER_LOYALTY_PT)
#define LOYALTY_BONUS_KILL_QUEEN_MONSTER (10 * GAIN_PTS_PER_LOYALTY_PT)
// Anywhere
// loyalty bonus for completing town training
#define LOYALTY_BONUS_FOR_TOWN_TRAINING ( 2 * GAIN_PTS_PER_LOYALTY_PT ) // 2%
// --- LOYALTY PENALTIES ---
// Cambria
#define LOYALTY_PENALTY_MARTHA_HEART_ATTACK (20 * GAIN_PTS_PER_LOYALTY_PT)
#define LOYALTY_PENALTY_JOEY_KILLED (10 * GAIN_PTS_PER_LOYALTY_PT)
// Balime
#define LOYALTY_PENALTY_ELDIN_KILLED (20 * GAIN_PTS_PER_LOYALTY_PT) // effect is double that!
// Any mine
#define LOYALTY_PENALTY_HEAD_MINER_ATTACKED (20 * GAIN_PTS_PER_LOYALTY_PT) // exact impact depends on rebel sentiment in that town
// Loyalty penalty for being inactive, per day after the third
//Madd:
#define LOYALTY_PENALTY_INACTIVE 0 // (10 * GAIN_PTS_PER_LOYALTY_PT)
typedef enum
{
// There are only for distance-adjusted global loyalty effects. Others go into list above instead!
GLOBAL_LOYALTY_BATTLE_WON,
GLOBAL_LOYALTY_BATTLE_LOST,
GLOBAL_LOYALTY_ENEMY_KILLED,
GLOBAL_LOYALTY_NATIVE_KILLED,
GLOBAL_LOYALTY_GAIN_TOWN_SECTOR,
GLOBAL_LOYALTY_LOSE_TOWN_SECTOR,
GLOBAL_LOYALTY_LIBERATE_WHOLE_TOWN, // awarded only the first time it happens
GLOBAL_LOYALTY_ABANDON_MILITIA,
GLOBAL_LOYALTY_GAIN_MINE,
GLOBAL_LOYALTY_LOSE_MINE,
GLOBAL_LOYALTY_GAIN_SAM,
GLOBAL_LOYALTY_LOSE_SAM,
GLOBAL_LOYALTY_QUEEN_BATTLE_WON,
} GlobalLoyaltyEventTypes;
typedef struct TOWN_LOYALTY
{
UINT8 ubRating;
INT16 sChange;
BOOLEAN fStarted; // starting loyalty of each town is initialized only when player first enters that town
UINT8 UNUSEDubRebelSentiment; // current rebel sentiment. Events could change the starting value...
BOOLEAN fLiberatedAlready;
BYTE filler[19]; // reserved for expansion
} TOWN_LOYALTY;
// the loyalty variables for each town
extern TOWN_LOYALTY gTownLoyalty[ NUM_TOWNS ];
// town names list
extern INT32 pTownNamesList[];
// town locations list
extern INT32 pTownLocationsList[];
// whether town maintains/displays loyalty or not
extern BOOLEAN gfTownUsesLoyalty[ NUM_TOWNS ];
// initialize a specific town's loyalty if it hasn't already been
void StartTownLoyaltyIfFirstTime( INT8 bTownId );
// set a speciafied town's loyalty rating
void SetTownLoyalty( INT8 bTownId, UINT8 ubLoyaltyValue );
// increment the town loyalty rating (hundredths!)
void IncrementTownLoyalty( INT8 bTownId, UINT32 uiLoyaltyIncrease );
// decrement the town loyalty rating (hundredths!)
void DecrementTownLoyalty( INT8 bTownId, UINT32 uiLoyaltyDecrease );
// update the loyalty based on current % control of the town
void UpdateLoyaltyBasedOnControl( INT8 bTownId );
// strategic handler, goes through and handles all strategic events for town loyalty updates...player controlled, monsters
void HandleTownLoyalty( void );
// init town loyalty lists
void InitTownLoyalty( void );
// handle the death of a civ
void HandleMurderOfCivilian( SOLDIERTYPE *pSoldier, BOOLEAN fIntentional );
// handle town loyalty adjustment for recruitment
void HandleTownLoyaltyForNPCRecruitment( SOLDIERTYPE *pSoldier );
// handle loyalty adjustment for theft
BOOLEAN HandleLoyaltyAdjustmentForRobbery( SOLDIERTYPE *pSoldier );
// handle loyalty adjustments for dmg/destruction of buildings
void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsDmg );
// remove random item from this sector
void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubChance );
// get the shortest distance between these two towns via roads
INT32 GetTownDistances( UINT8 ubTown, UINT8 ubTownA );
// build list of town sectors
void BuildListOfTownSectors( void );
//#ifdef JA2TESTVERSION
// calculate shortest distances between towns
void CalcDistancesBetweenTowns( void );
// write out distances between towns to a data file
void WriteOutDistancesBetweenTowns( void );
// dumps the calc'ed distances into a text file table for easy verification
void DumpDistancesBetweenTowns(void);
//#endif // JA2TESTVERSION
// read in distances between towns
void ReadInDistancesBetweenTowns( void );
/* Delayed loyalty effects elimininated. Sep.12/98. ARM
// delayed town loyalty event
void HandleDelayedTownLoyaltyEvent( UINT32 uiValue );
// build loyalty event value
UINT32 BuildLoyaltyEventValue( INT8 bTownValue, UINT32 uiValue, BOOLEAN fIncrement );
*/
BOOLEAN LoadStrategicTownLoyaltyFromSavedGameFile( HWFILE hFile );
BOOLEAN SaveStrategicTownLoyaltyToSaveGameFile( HWFILE hFile );
void ReduceLoyaltyForRebelsBetrayed(void);
// how many towns under player control?
INT32 GetNumberOfWholeTownsUnderControl( void );
// is all the sectors of this town under control by the player
INT32 IsTownUnderCompleteControlByPlayer( INT8 bTownId );
// used when monsters attack a town sector without going through tactical and they win
void AdjustLoyaltyForCivsEatenByMonsters( INT16 sSectorX, INT16 sSectorY, UINT8 ubHowMany);
// these are used to handle global loyalty events (ones that effect EVERY town on the map)
void IncrementTownLoyaltyEverywhere( UINT32 uiLoyaltyIncrease );
void DecrementTownLoyaltyEverywhere( UINT32 uiLoyaltyDecrease );
void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ);
void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ);
// handle a town being liberated for the first time
void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
void CheckIfEntireTownHasBeenLost( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
void HandleLoyaltyChangeForNPCAction( UINT8 ubNPCProfileId );
BOOLEAN DidFirstBattleTakePlaceInThisTown( INT8 bTownId );
void SetTheFirstBattleSector( INT16 sSectorValue );
// gte number of whole towns but exclude this one
INT32 GetNumberOfWholeTownsUnderControlButExcludeCity( INT8 bCityToExclude );
//Function assumes that mercs have retreated already. Handles two cases, one for general merc retreat
//which slightly demoralizes the mercs, the other handles abandonment of militia forces which poses
//as a serious loyalty penalty.
#define RETREAT_TACTICAL_TRAVERSAL 0
#define RETREAT_PBI 1
#define RETREAT_AUTORESOLVE 2
void HandleLoyaltyImplicationsOfMercRetreat( INT8 bRetreatCode, INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
void MaximizeLoyaltyForDeidrannaKilled( void );
#endif
+110
View File
@@ -0,0 +1,110 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "sgp.h"
#include "Game Clock.h"
#include "Font Control.h"
#include "render dirty.h"
#include "Timer Control.h"
#include "overhead.h"
#include "environment.h"
#include "Game Clock.h"
#include "message.h"
#include "worlddef.h"
#include "rotting corpses.h"
#include "soldier create.h"
#include "soldier add.h"
#include "strategic turns.h"
#include "isometric utils.h"
#include "animation data.h"
#include "animation control.h"
#include "Tactical Turns.h"
#include "strategic turns.h"
#include "rt time defines.h"
#include "assignments.h"
#endif
#define NUM_SEC_PER_STRATEGIC_TURN ( NUM_SEC_IN_MIN * 15 ) // Every fifteen minutes
UINT32 guiLastStrategicTime = 0;
UINT32 guiLastTacticalRealTime = 0;
void StrategicTurnsNewGame( )
{
// Sync game start time
SyncStrategicTurnTimes( );
}
void SyncStrategicTurnTimes( )
{
guiLastStrategicTime = GetWorldTotalSeconds( );
guiLastTacticalRealTime = GetJA2Clock( );
}
void HandleStrategicTurn( )
{
UINT32 uiTime;
UINT32 uiCheckTime;
// OK, DO THIS CHECK EVERY ONCE AND A WHILE...
if ( COUNTERDONE( STRATEGIC_OVERHEAD ) )
{
RESETCOUNTER( STRATEGIC_OVERHEAD );
// if the game is paused, or we're in mapscreen and time is not being compressed
if( ( GamePaused() == TRUE ) ||
( ( guiCurrentScreen == MAP_SCREEN ) && !IsTimeBeingCompressed() ) )
{
// don't do any of this
return;
}
//Kris -- What to do?
if( giTimeCompressMode == NOT_USING_TIME_COMPRESSION )
{
SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );
}
uiTime = GetJA2Clock( );
// Do not handle turns update if in turnbased combat
if ( ( gTacticalStatus.uiFlags & TURNBASED ) && ( gTacticalStatus.uiFlags & INCOMBAT ) )
{
guiLastTacticalRealTime = uiTime;
}
else
{
if ( giTimeCompressMode == TIME_COMPRESS_X1 || giTimeCompressMode == 0 )
{
uiCheckTime = NUM_REAL_SEC_PER_TACTICAL_TURN;
}
else
{
// OK, if we have compressed time...., adjust our check value to be faster....
if( giTimeCompressSpeeds[ giTimeCompressMode ] > 0 )
{
uiCheckTime = NUM_REAL_SEC_PER_TACTICAL_TURN / ( giTimeCompressSpeeds[ giTimeCompressMode ] * RT_COMPRESSION_TACTICAL_TURN_MODIFIER );
}
}
if ( ( uiTime - guiLastTacticalRealTime ) > uiCheckTime )
{
HandleTacticalEndTurn( );
guiLastTacticalRealTime = uiTime;
}
}
}
}
void HandleStrategicTurnImplicationsOfExitingCombatMode( void )
{
SyncStrategicTurnTimes();
HandleTacticalEndTurn( /*GetWorldTotalSeconds()*/ ); // doesn't take parameters
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef _STRATEGIC_TURNS_H
#define _STRATEGIC_TURNS_H
void StrategicTurnsNewGame( );
void HandleStrategicTurn( );
void SyncStrategicTurnTimes( );
void HandleStrategicTurnImplicationsOfExitingCombatMode( void );
#endif
File diff suppressed because it is too large Load Diff
+550
View File
@@ -0,0 +1,550 @@
# Microsoft Developer Studio Project File - Name="Strategic" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Strategic - Win32 Demo Bounds Checker
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Strategic.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Strategic.mak" CFG="Strategic - Win32 Demo Bounds Checker"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Strategic - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Debug Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Release Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Demo Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "Strategic - Win32 Demo Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Jagged Alliance 2/Development/Programming/Jagged Alliance 2/Build", AVAAAAAA"
# PROP Scc_LocalPath "..\..\..\ja2\build"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Strategic - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\Standard Gaming Platform" /I "..\TileEngine" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\Laptop" /I ".\\" /D "PRECOMPILEDHEADERS" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\Standard Gaming Platform" /I "..\TileEngine" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\Laptop" /I ".\\" /D "PRECOMPILEDHEADERS" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Strategi"
# PROP BASE Intermediate_Dir "Strategi"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release with Debug"
# PROP Intermediate_Dir "Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\Editor" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\TileEngine" /I "..\Utils" /I "..\TacticalAI" /I "..\Tactical" /I "..\Laptop" /I "..\Editor" /I ".\\" /D "NDEBUG" /D "RELEASE_WITH_DEBUG_INFO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Strateg1"
# PROP BASE Intermediate_Dir "Strateg1"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Bounds Checker"
# PROP Intermediate_Dir "Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Debug Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Strateg0"
# PROP BASE Intermediate_Dir "Strateg0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug Demo"
# PROP Intermediate_Dir "Debug Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Release Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Strateg2"
# PROP BASE Intermediate_Dir "Strateg2"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release Demo"
# PROP Intermediate_Dir "Release Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\Editor" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "RELEASE_WITH_DEBUG_INFO" /FR /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\Editor" /D "RELEASE_WITH_DEBUG_INFO" /D "NDEBUG" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Demo Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Strateg3"
# PROP BASE Intermediate_Dir "Strateg3"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Demo Release with Debug"
# PROP Intermediate_Dir "Demo Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\Editor" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "RELEASE_WITH_DEBUG_INFO" /FR /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\TileEngine" /I "..\Utils" /I "..\TacticalAI" /I "..\Tactical" /I "..\Laptop" /I "..\Editor" /I ".\\" /D "RELEASE_WITH_DEBUG_INFO" /D "NDEBUG" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Strategic - Win32 Demo Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Strateg4"
# PROP BASE Intermediate_Dir "Strateg4"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Demo Bounds Checker"
# PROP Intermediate_Dir "Demo Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "BOUNDS_CHECKER" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\Laptop" /I "\ja2\build\editor" /I "\ja2\build\tactical" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Strategic All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Strategic - Win32 Release"
# Name "Strategic - Win32 Debug"
# Name "Strategic - Win32 Release with Debug Info"
# Name "Strategic - Win32 Bounds Checker"
# Name "Strategic - Win32 Debug Demo"
# Name "Strategic - Win32 Release Demo"
# Name "Strategic - Win32 Demo Release with Debug Info"
# Name "Strategic - Win32 Demo Bounds Checker"
# Begin Group "Source Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=".\AI Viewer.cpp"
# End Source File
# Begin Source File
SOURCE=.\Assignments.cpp
# End Source File
# Begin Source File
SOURCE=".\Auto Resolve.cpp"
# End Source File
# Begin Source File
SOURCE=".\Campaign Init.cpp"
# End Source File
# Begin Source File
SOURCE=".\Creature Spreading.cpp"
# End Source File
# Begin Source File
SOURCE=".\Game Clock.cpp"
# End Source File
# Begin Source File
SOURCE=".\Game Event Hook.cpp"
# End Source File
# Begin Source File
SOURCE=".\Game Events.cpp"
# End Source File
# Begin Source File
SOURCE=".\Game Init.cpp"
# End Source File
# Begin Source File
SOURCE=".\Hourly Update.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Helicopter.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Border.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Bottom.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Map Inventory.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Map.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface TownMine Info.cpp"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface.cpp"
# End Source File
# Begin Source File
SOURCE=.\mapscreen.cpp
# End Source File
# Begin Source File
SOURCE=.\Meanwhile.cpp
# End Source File
# Begin Source File
SOURCE=".\Merc Contract.cpp"
# End Source File
# Begin Source File
SOURCE=".\Player Command.cpp"
# End Source File
# Begin Source File
SOURCE=".\PreBattle Interface.cpp"
# End Source File
# Begin Source File
SOURCE=".\Queen Command.cpp"
# End Source File
# Begin Source File
SOURCE=".\Quest Debug System.cpp"
# End Source File
# Begin Source File
SOURCE=.\Quests.cpp
# End Source File
# Begin Source File
SOURCE=.\QuestText.cpp
# End Source File
# Begin Source File
SOURCE=.\Scheduling.cpp
# End Source File
# Begin Source File
SOURCE=".\Strategic AI.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Event Handler.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Merc Handler.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Mines.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Movement Costs.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Movement.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Pathing.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Status.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Town Loyalty.cpp"
# End Source File
# Begin Source File
SOURCE=".\strategic town reputation.cpp"
# End Source File
# Begin Source File
SOURCE=".\Strategic Turns.cpp"
# End Source File
# Begin Source File
SOURCE=.\strategic.cpp
# End Source File
# Begin Source File
SOURCE=.\strategicmap.cpp
# End Source File
# Begin Source File
SOURCE=".\Town Militia.cpp"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Assignments.h
# End Source File
# Begin Source File
SOURCE=".\Auto Resolve.h"
# End Source File
# Begin Source File
SOURCE=".\Campaign Init.h"
# End Source File
# Begin Source File
SOURCE=".\Campaign Types.h"
# End Source File
# Begin Source File
SOURCE=".\Creature Spreading.h"
# End Source File
# Begin Source File
SOURCE=".\Game Clock.h"
# End Source File
# Begin Source File
SOURCE=".\Game Event Hook.h"
# End Source File
# Begin Source File
SOURCE=".\Game Events.h"
# End Source File
# Begin Source File
SOURCE=".\Game Init.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Helicopter.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Border.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Bottom.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Map Inventory.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface Map.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface TownMine Info.h"
# End Source File
# Begin Source File
SOURCE=".\Map Screen Interface.h"
# End Source File
# Begin Source File
SOURCE=.\mapscreen.h
# End Source File
# Begin Source File
SOURCE=".\Merc Contract.h"
# End Source File
# Begin Source File
SOURCE=".\Player Command.h"
# End Source File
# Begin Source File
SOURCE=".\PreBattle Interface.h"
# End Source File
# Begin Source File
SOURCE=".\Queen Command.h"
# End Source File
# Begin Source File
SOURCE=.\Quests.h
# End Source File
# Begin Source File
SOURCE=.\Scheduling.h
# End Source File
# Begin Source File
SOURCE=".\Strategic AI.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic All.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Event Handler.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Merc Handler.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Mines.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Movement.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Pathing.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Status.h"
# End Source File
# Begin Source File
SOURCE=".\Strategic Town Loyalty.h"
# End Source File
# Begin Source File
SOURCE=".\strategic town reputation.h"
# End Source File
# Begin Source File
SOURCE=.\strategic.h
# End Source File
# Begin Source File
SOURCE=.\strategicmap.h
# End Source File
# Begin Source File
SOURCE=".\Town Militia.h"
# End Source File
# End Group
# End Target
# End Project
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+81
View File
@@ -0,0 +1,81 @@
#ifndef _TOWN_MILITIA_H
#define _TOWN_MILITIA_H
// header for town militia strategic control module
#include "Types.h"
#include "Soldier Control.h"
// how many militia of all ranks can be in any one sector at once
//#define MAX_ALLOWABLE_MILITIA_PER_SECTOR 20
// how many new green militia civilians are trained at a time
//#define MILITIA_TRAINING_SQUAD_SIZE 10 // was 6
// cost of starting a new militia training assignment
//#define MILITIA_TRAINING_COST 750
// minimum loyalty rating before training is allowed in a town
//#define MIN_RATING_TO_TRAIN_TOWN 20
// this handles what happens when a new militia unit is finishes getting trained
void TownMilitiaTrainingCompleted( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMapY );
// feed this a SOLDIER_CLASS_, it will return you a _MITILIA rank, or -1 if the guy's not militia
INT8 SoldierClassToMilitiaRank(UINT8 ubSoldierClass);
// feed this a _MITILIA rank, it will return you a SOLDIER_CLASS_, or -1 if the guy's not militia
INT8 MilitiaRankToSoldierClass(UINT8 ubRank);
// these add, promote, and remove militias of a certain rank
void StrategicAddMilitiaToSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany);
void StrategicPromoteMilitiaInSector(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubHowMany);
void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany);
// this will check for promotions and handle them for you
UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubRecentKillPts);
void BuildMilitiaPromotionsString( UINT16 *str );
// call this if the player attacks his own militia
void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY);
UINT8 CountAllMilitiaInSector(INT16 sMapX, INT16 sMapY);
UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank);
// Returns TRUE if sector is under player control, has no enemies in it, and isn't currently in combat mode
BOOLEAN SectorOursAndPeaceful( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
// tell player how much it will cost
void HandleInterfaceMessageForCostOfTrainingMilitia( SOLDIERTYPE *pSoldier );
// continue training?
void HandleInterfaceMessageForContinuingTrainingMilitia( SOLDIERTYPE *pSoldier );
// call this when the sector changes...
void HandleMilitiaStatusInCurrentMapBeforeLoadingNewMap( void );
// is there a town with militia here or nearby?
BOOLEAN CanNearbyMilitiaScoutThisSector( INT16 sSectorX, INT16 sSectorY );
// is the town militia full?
BOOLEAN IsTownFullMilitia( INT8 bTownId );
// is the SAM site full of militia?
BOOLEAN IsSAMSiteFullOfMilitia( INT16 sSectorX, INT16 sSectorY );
// now that town training is complete, handle the continue boxes
void HandleContinueOfTownTraining( void );
// handle completion of assignment byt his soldier too and inform the player
void HandleCompletionOfTownTrainingByGroupWithTrainer( SOLDIERTYPE *pTrainer );
// clear the list of training completed sectors
void ClearSectorListForCompletedTrainingOfMilitia( void );
BOOLEAN MilitiaTrainingAllowedInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
BOOLEAN MilitiaTrainingAllowedInTown( INT8 bTownId );
#endif
File diff suppressed because it is too large Load Diff
+81
View File
@@ -0,0 +1,81 @@
#ifndef __MAPSCREEN_H
#define __MAPSCREEN_H
#include "Types.h"
#include "Soldier Control.h"
#define MAP_WORLD_X 18
#define MAP_WORLD_Y 18
// Sector name identifiers
enum Towns
{
BLANK_SECTOR=0,
OMERTA,
DRASSEN,
ALMA,
GRUMM,
TIXA,
CAMBRIA,
SAN_MONA,
ESTONI,
ORTA,
BALIME,
MEDUNA,
CHITZENA,
NUM_TOWNS
} ;
#define FIRST_TOWN OMERTA
//#define PALACE NUM_TOWNS
extern BOOLEAN fCharacterInfoPanelDirty;
extern BOOLEAN fTeamPanelDirty;
extern BOOLEAN fMapPanelDirty;
extern BOOLEAN fMapInventoryItem;
extern BOOLEAN gfInConfirmMapMoveMode;
extern BOOLEAN gfInChangeArrivalSectorMode;
extern BOOLEAN gfSkyriderEmptyHelpGiven;
BOOLEAN SetInfoChar(UINT8 ubSolId);
void EndMapScreen( BOOLEAN fDuringFade );
void ReBuildCharactersList( void );
BOOLEAN HandlePreloadOfMapGraphics( void );
void HandleRemovalOfPreLoadedMapGraphics( void );
void ChangeSelectedMapSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN CanToggleSelectedCharInventory( void );
BOOLEAN CanExtendContractForCharSlot( INT8 bCharNumber );
void TellPlayerWhyHeCantCompressTime( void );
void ChangeSelectedInfoChar( INT8 bCharNumber, BOOLEAN fResetSelectedList );
void MAPEndItemPointer();
void CopyPathToAllSelectedCharacters( PathStPtr pPath );
void CancelPathsOfAllSelectedCharacters();
INT32 GetPathTravelTimeDuringPlotting( PathStPtr pPath );
void AbortMovementPlottingMode( void );
void ExplainWhySkyriderCantFly( void );
BOOLEAN CanChangeSleepStatusForCharSlot( INT8 bCharNumber );
BOOLEAN CanChangeSleepStatusForSoldier( SOLDIERTYPE *pSoldier );
BOOLEAN MapCharacterHasAccessibleInventory( INT8 bCharNumber );
#endif
+205
View File
@@ -0,0 +1,205 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "types.h"
#include "strategic town reputation.h"
#include "soldier profile type.h"
#include "game event hook.h"
#include "Soldier Profile.h"
#include "Overhead.h"
#include "Game Clock.h"
#include "strategic town loyalty.h"
#include "Debug.h"
#include "message.h"
#endif
// init for town reputation at game start
#define INITIAL_TOWN_REPUTATION 0
// the max and min town opinion of an individual merc can be
#define MAX_TOWN_OPINION 50
#define MIN_TOWN_OPINION -50
// town reputation is currently updated 4x per day: at 9am, noon, 3pm, and 6pm
// the number of events per day
#define TOWN_OPINION_NUMBER_OF_PERIODS 4
// the start time after midnight that first town reputation event takes place .. in minutes
#define TOWN_OPINION_START_TIME (9 * 60)
// how often the town opinion events occur...right now every 3 hours
#define TOWN_OPINION_PERIOD (3 * 60)
void InitializeProfilesForTownReputation( void )
{
UINT32 uiProfileId = 0;
// initialize the town opinion values in each recruitable merc's profile structure
for( uiProfileId = 0; uiProfileId < FIRST_NPC; uiProfileId++ )
{
memset( &( gMercProfiles[ uiProfileId ].bMercTownReputation ), INITIAL_TOWN_REPUTATION, sizeof( gMercProfiles[ uiProfileId ].bMercTownReputation ) );
}
}
void PostEventsForSpreadOfTownOpinion( void )
{
/* ARM - Do nothing, this system has been scrapped because it is so marginal and it's too late to bother with it now
INT32 iCounter = 0;
// called every day at 3am to set up daily events to handle spreading of town opinion about mercs
for( iCounter = 0; iCounter < TOWN_OPINION_NUMBER_OF_PERIODS; iCounter++ )
{
AddStrategicEvent( EVENT_HANDLE_TOWN_OPINION, GetWorldDayInMinutes() + TOWN_OPINION_START_TIME + iCounter * TOWN_OPINION_PERIOD, 0 );
}
*/
}
UINT8 GetTownOpinionOfMerc( UINT8 ubProfileId, UINT8 ubTownId )
{
Assert(ubProfileId < FIRST_NPC);
Assert(ubTownId < NUM_TOWNS);
// return amount
return( gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] );
}
UINT8 GetTownOpinionOfMercForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubTownId )
{
// error check
if( pSoldier == NULL )
{
return( 0 );
}
Assert(ubTownId < NUM_TOWNS);
// pass on to
return( GetTownOpinionOfMerc( pSoldier->ubProfile, ubTownId ) );
}
void UpdateTownOpinionOfThisMerc( UINT8 ubProfileId, UINT8 ubTownId, INT8 bAmount )
{
Assert(ubProfileId < FIRST_NPC);
Assert(ubTownId < NUM_TOWNS);
// check if opinion would be affected too greatly
if( gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] + bAmount > MAX_TOWN_OPINION )
{
// maximize
gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] = MAX_TOWN_OPINION;
}
else if( gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] + bAmount < MIN_TOWN_OPINION )
{
// minimize
gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] = MIN_TOWN_OPINION;
}
else
{
// update amount
gMercProfiles[ ubProfileId ].bMercTownReputation[ ubTownId ] += bAmount;
}
}
void UpdateTownOpinionOfThisMercForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubTownId, INT8 bAmount )
{
// error check
if( pSoldier == NULL )
{
return;
}
Assert(ubTownId < NUM_TOWNS);
// pass this on to the profile based function
UpdateTownOpinionOfThisMerc( pSoldier->ubProfile, ubTownId, bAmount );
}
void HandleSpreadOfAllTownsOpinion( void )
{
UINT8 ubProfileId;
// debug message
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s - Spreading town opinions about mercs", WORLDTIMESTR );
// run though all player-recruitable profiles and update towns opinion of mercs
for( ubProfileId = 0; ubProfileId < FIRST_NPC; ubProfileId++ )
{
HandleSpreadOfTownOpinionForMerc( ubProfileId );
}
}
void HandleSpreadOfTownOpinionForMerc( UINT8 ubProfileId )
{
// handle opinion spread for this grunt
INT32 iDistanceBetweenTowns;
INT8 iCounterA, iCounterB;
INT8 bOpinionOfTownA, bOpinionOfTownB;
Assert(ubProfileId < FIRST_NPC);
for( iCounterA = FIRST_TOWN; iCounterA < NUM_TOWNS; iCounterA++ )
{
for( iCounterB = iCounterA; iCounterB < NUM_TOWNS; iCounterB++ )
{
if( iCounterA != iCounterB )
{
bOpinionOfTownA = GetTownOpinionOfMerc( ubProfileId, iCounterA );
bOpinionOfTownB = GetTownOpinionOfMerc( ubProfileId, iCounterB );
iDistanceBetweenTowns = GetTownDistances( iCounterA, iCounterB );
// spread opinion between towns
HandleOpinionOfTownsAboutSoldier( bOpinionOfTownA, bOpinionOfTownB, iDistanceBetweenTowns, ubProfileId );
}
}
}
}
void HandleOpinionOfTownsAboutSoldier( INT8 bTownA, INT8 bTownB, INT32 iDistanceBetweenThem, UINT8 ubProfile )
{
// ARM: System has been scrapped
}
/*
void HandleSpreadOfTownOpinionForMercForSoldier( SOLDIERTYPE *pSoldier )
{
// error check
if( pSoldier == NULL )
{
return;
}
// let the profile based one do the handling
HandleSpreadOfTownOpinionForMerc( pSoldier->ubProfile );
}
void HandleSpreadOfTownsOpinionForCurrentMercs( void )
{
INT32 iCounter = 0, iNumberOnPlayersTeam = 0;
// get the number on players team
iNumberOnPlayersTeam = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
// run through all mercs on players current team
for(iCounter = 0; iCounter < iNumberOnPlayersTeam; iCounter++ )
{
HandleSpreadOfTownOpinionForMercForSoldier( MercPtrs[ iCounter ] );
}
return;
}
*/
+36
View File
@@ -0,0 +1,36 @@
#ifndef _STRATEGIC_TOWN_REPUTATION_H
#define _STRATEGIC_TOWN_REPUTATION_H
#include "types.h"
#include "Soldier Control.h"
// header to contain functions to handle strategic town reputation
// initialize profiles for the town reputation system
void InitializeProfilesForTownReputation( void );
// post events to handle spread of town loyalty
void PostEventsForSpreadOfTownOpinion( void );
// get the towns opinion of this merc...indexed by profile type
UINT8 GetTownOpinionOfMerc( UINT8 ubProfileId, UINT8 ubTownId );
UINT8 GetTownOpinionOfMercForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubTownId );
// update merc reputation for this town by this amount
void UpdateTownOpinionOfThisMerc( UINT8 ubProfileId, UINT8 ubTownId, INT8 bAmount );
void UpdateTownOpinionOfThisMercForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubTownId, INT8 bAmount );
// global handling of spread
void HandleSpreadOfAllTownsOpinion( void );
// handles the spread of town opinion for one merc
void HandleSpreadOfTownOpinionForMerc( UINT8 ubProfileId );
// handles the opinion spread between these two towns about this merc at the distance between them
void HandleOpinionOfTownsAboutSoldier( INT8 bTownA, INT8 bTownB, INT32 iDistanceBetweenThem, UINT8 ubProfile );
/*
// handle only for mercs on players team
void HandleSpreadOfTownsOpinionForCurrentMercs( void );
void HandleSpreadOfTownOpinionForMercForSoldier( SOLDIERTYPE *pSoldier );
*/
#endif
+129
View File
@@ -0,0 +1,129 @@
#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "Strategic.h"
#include "Types.h"
#include "Squads.h"
#include "jascreens.h"
#include "Assignments.h"
#include "Interface Control.h"
#include "Overhead.h"
#include "Music Control.h"
#include "Soldier Profile.h"
#include "Dialogue Control.h"
#include "personnel.h"
#include "Tactical Save.h"
#include "Isometric Utils.h"
#endif
StrategicMapElement StrategicMap[MAP_WORLD_X*MAP_WORLD_Y];
extern BOOLEAN fReDrawFace;
BOOLEAN HandleStrategicDeath( SOLDIERTYPE *pSoldier )
{
// add the guy to the dead list
//AddCharacterToDeadList( pSoldier );
// If in a vehicle, remove them!
if( ( pSoldier->bAssignment == VEHICLE ) && ( pSoldier->iVehicleId != -1 ) )
{
// remove from vehicle
TakeSoldierOutOfVehicle( pSoldier );
}
// if not in mapscreen
if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
{
// ATE; At least make them dead!
if( ( pSoldier->bAssignment != ASSIGNMENT_DEAD ) )
{
SetTimeOfAssignmentChangeForMerc( pSoldier );
}
ChangeSoldiersAssignment( pSoldier, ASSIGNMENT_DEAD );
}
else if( ( pSoldier -> bLife == 0 )&&( pSoldier->bAssignment != ASSIGNMENT_DEAD ) )
{
// died in mapscreen
fReDrawFace = TRUE;
// dead
if( ( pSoldier->bAssignment != ASSIGNMENT_DEAD ) )
{
SetTimeOfAssignmentChangeForMerc( pSoldier );
}
ChangeSoldiersAssignment( pSoldier, ASSIGNMENT_DEAD );
//s et breath and breath max to 0
pSoldier -> bBreath = pSoldier->bBreathMax = 0;
// rebuild list
ReBuildCharactersList( );
// ste merc as dead
// pSoldier->fUIdeadMerc = TRUE;
// attempt o remove character from squad
RemoveCharacterFromSquads( pSoldier );
// handle any passign comments by grunts
HandleSoldierDeadComments( pSoldier );
// put the dead guys down
AddDeadSoldierToUnLoadedSector( ( UINT8 ) ( pSoldier->sSectorX ), ( UINT8 )( pSoldier->sSectorY ), pSoldier->bSectorZ, pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT );
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
StopTimeCompression();
}
return( TRUE );
}
void HandleSoldierDeadComments( SOLDIERTYPE *pSoldier )
{
INT32 cnt = 0;
SOLDIERTYPE *pTeamSoldier;
INT8 bBuddyIndex;
// IF IT'S THE SELECTED GUY, MAKE ANOTHER SELECTED!
cnt = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID;
// see if this was the friend of a living merc
for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++)
{
if ( pTeamSoldier->bLife >= OKLIFE && pTeamSoldier->bActive )
{
bBuddyIndex = WhichBuddy( pTeamSoldier->ubProfile, pSoldier->ubProfile );
switch( bBuddyIndex )
{
case 0:
// buddy #1 died!
TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_ONE_KILLED );
break;
case 1:
// buddy #2 died!
TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_TWO_KILLED );
break;
case 2:
// learn to like buddy died!
TacticalCharacterDialogue( pTeamSoldier, QUOTE_LEARNED_TO_LIKE_MERC_KILLED );
break;
default:
break;
}
}
}
return;
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef __STRATEGIC_H
#define __STRATEGIC_H
// header for strategic structure
#include "Types.h"
#include "mapscreen.h"
#include "soldier control.h"
struct strategicmapelement{
UINT8 UNUSEDuiFootEta[4]; // eta/mvt costs for feet
UINT8 UNUSEDuiVehicleEta[4]; // eta/mvt costs for vehicles
UINT8 uiBadFootSector[4]; // blocking mvt for foot
UINT8 uiBadVehicleSector[4]; // blocking mvt from vehicles
INT8 bNameId;
BOOLEAN fEnemyControlled; // enemy controlled or not
BOOLEAN fEnemyAirControlled;
BOOLEAN UNUSEDfLostControlAtSomeTime;
INT8 bSAMCondition; // SAM Condition .. 0 - 100, just like an item's status
INT8 bPadding[ 20 ];
} ;
enum
{
INSERTION_CODE_NORTH,
INSERTION_CODE_SOUTH,
INSERTION_CODE_EAST,
INSERTION_CODE_WEST,
INSERTION_CODE_GRIDNO,
INSERTION_CODE_ARRIVING_GAME,
INSERTION_CODE_CHOPPER,
INSERTION_CODE_PRIMARY_EDGEINDEX,
INSERTION_CODE_SECONDARY_EDGEINDEX,
INSERTION_CODE_CENTER,
};
//PLEASE USE CALCULATE_STRATEGIC_INDEX() macro instead (they're identical).
//#define GETWORLDMAPNO( x, y ) ( x+(MAP_WORLD_X*y) )
typedef struct strategicmapelement StrategicMapElement;
extern StrategicMapElement StrategicMap[MAP_WORLD_X*MAP_WORLD_Y];
BOOLEAN InitStrategicEngine( );
void HandleSoldierDeadComments( SOLDIERTYPE *pSoldier );
BOOLEAN HandleStrategicDeath( SOLDIERTYPE *pSoldier );
#endif
File diff suppressed because it is too large Load Diff
+183
View File
@@ -0,0 +1,183 @@
#ifndef __STRATMAP_H
#define __STRATMAP_H
// this file is for manipulation of the strategic map structure
#include "types.h"
#include "soldier control.h"
#include "FileMan.h"
//The maximum size for any team strategically speaking. For example, we can't have more than 20 enemies, militia, or creatures at a time.
//#define MAX_STRATEGIC_TEAM_SIZE 20
// Codes for jumoing into adjacent sectors..
enum
{
JUMP_ALL_LOAD_NEW,
JUMP_ALL_NO_LOAD,
JUMP_SINGLE_LOAD_NEW,
JUMP_SINGLE_NO_LOAD
};
enum{
CONTROLLED=0,
UNCONTROLLED,
};
// For speed, etc lets make these globals, forget the functions if you want
extern INT16 gWorldSectorX;
extern INT16 gWorldSectorY;
extern INT8 gbWorldSectorZ;
#define NUMBER_OF_SAMS 4
extern INT16 pSamList[ NUMBER_OF_SAMS ];
extern INT16 pSamGridNoAList[ NUMBER_OF_SAMS ];
extern INT16 pSamGridNoBList[ NUMBER_OF_SAMS ];
extern BOOLEAN fFoundOrta;
extern BOOLEAN fSamSiteFound[ NUMBER_OF_SAMS ];
extern BOOLEAN gfUseAlternateMap;
// SAM sites
#define SAM_1_X 2
#define SAM_2_X 15
#define SAM_3_X 8
#define SAM_4_X 4
#define SAM_1_Y 4
#define SAM_2_Y 4
#define SAM_3_Y 9
#define SAM_4_Y 14
// min condition for sam site to be functional
#define MIN_CONDITION_FOR_SAM_SITE_TO_WORK 80
// FUNCTIONS FOR DERTERMINING GOOD SECTOR EXIT DATA
#define CHECK_DIR_X_DELTA ( WORLD_TILE_X * 4 )
#define CHECK_DIR_Y_DELTA ( WORLD_TILE_Y * 10 )
// get index into aray
#define CALCULATE_STRATEGIC_INDEX( x, y ) ( x + ( y * MAP_WORLD_X ) )
#define GET_X_FROM_STRATEGIC_INDEX( i ) ( i % MAP_WORLD_X )
#define GET_Y_FROM_STRATEGIC_INDEX( i ) ( i / MAP_WORLD_X )
// macros to convert between the 2 different sector numbering systems
#define SECTOR_INFO_TO_STRATEGIC_INDEX( i ) ( CALCULATE_STRATEGIC_INDEX ( SECTORX( i ), SECTORY( i ) ) )
#define STRATEGIC_INDEX_TO_SECTOR_INFO( i ) ( SECTOR( GET_X_FROM_STRATEGIC_INDEX( i ), GET_Y_FROM_STRATEGIC_INDEX( i ) ) )
// grab the town id value
UINT8 GetTownIdForSector( INT16 sMapX, INT16 sMapY );
void GetCurrentWorldSector( INT16 *psMapX, INT16 *psMapY );
BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void UpdateMercInSector( SOLDIERTYPE *pSoldier, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
BOOLEAN ReadInMapStructure(STR fileName);
// get short sector name without town name
void GetShortSectorString( INT16 sMapX,INT16 sMapY, STR16 sString );
//NEW!
//Calculates the name of the sector based on the loaded sector values.
//Examples: A9
// A10_B1
// J9_B2_A ( >= BETAVERSION ) else J9_B2 (release equivalent)
void GetLoadedSectorString( UINT16 *pString );
// This will get an ID string like A9- OMERTA...
void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , CHAR16 * zString, BOOLEAN fDetailed );
void GetMapFileName(INT16 sMapX,INT16 sMapY, INT8 bSectorZ, STR8 bString, BOOLEAN fUsePlaceholder, BOOLEAN fAddAlternateMapLetter );
// Called from within tactical.....
void JumpIntoAdjacentSector( UINT8 ubDirection, UINT8 ubJumpCode, INT16 sAdditionalData );
BOOLEAN CanGoToTacticalInSector( INT16 sX, INT16 sY, UINT8 ubZ );
void UpdateAirspaceControl( void );
BOOLEAN IsThisSectorASAMSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// init sam sites
void InitializeSAMSites( void );
// get town sector size
UINT8 GetTownSectorSize( INT8 bTownId );
// get town sector size, that is under play control
UINT8 GetTownSectorsUnderControl( INT8 bTownId );
// is this sector part of this town
BOOLEAN SectorIsPartOfTown( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
//BOOLEAN IsThereAnyOneInThisTown( UINT8 ubTownId );
BOOLEAN SoldierOKForSectorExit( SOLDIERTYPE * pSoldier, INT8 bExitDirection, UINT16 usAdditionalData );
BOOLEAN OKForSectorExit( INT8 bExitDirection, UINT16 usAdditionalData, UINT32 *puiTraverseTimeInMinutes );
void SetupNewStrategicGame( );
BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile );
BOOLEAN SaveStrategicInfoToSavedFile( HWFILE hFile );
void AllMercsHaveWalkedOffSector( );
void AdjustSoldierPathToGoOffEdge( SOLDIERTYPE *pSoldier, INT16 sEndGridNo, UINT8 ubTacticalDirection );
void AllMercsWalkedToExitGrid();
UINT8 GetMilitiaCountAtLevelAnywhereInTown( UINT8 ubTownValue, UINT8 ubLevelValue );
void PrepareLoadedSector();
// handle for slay...no better place to really put this stuff
void HandleSlayDailyEvent( void );
void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bNewSectorZ );
// handle a soldier leaving thier squad behind, this sets them up for mvt and potential rejoining of group
void HandleSoldierLeavingSectorByThemSelf( SOLDIERTYPE *pSoldier );
BOOLEAN CheckAndHandleUnloadingOfCurrentWorld();
// number of SAM sites under player control
INT32 GetNumberOfSAMSitesUnderPlayerControl( void );
// is there a FUNCTIONAL SAM site in this sector?
BOOLEAN IsThereAFunctionalSAMSiteInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY );
// sam site under players control?
INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY );
INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void SetupProfileInsertionDataForSoldier( SOLDIERTYPE *pSoldier );
BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle( );
//Used for determining the type of error message that comes up when you can't traverse to
//an adjacent sector. THESE VALUES DO NOT NEED TO BE SAVED!
extern BOOLEAN gfInvalidTraversal;
extern BOOLEAN gfLoneEPCAttemptingTraversal;
extern BOOLEAN gfRobotWithoutControllerAttemptingTraversal;
extern UINT8 gubLoneMercAttemptingToAbandonEPCs;
extern INT8 gbPotentiallyAbandonedEPCSlotID;
extern INT8 gbGreenToElitePromotions;
extern INT8 gbGreenToRegPromotions;
extern INT8 gbRegToElitePromotions;
extern INT8 gbMilitiaPromotions;
#endif