New Feature: strategic militia command allows ordering militia around in the map if someoen performs the STRATEGIC_MILITIA_MOVEMENT facility assignment.

requires GameDir >= r1946

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6943 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2014-02-18 21:26:46 +00:00
parent e04bff6f61
commit cee17f5651
29 changed files with 643 additions and 57 deletions
+88 -3
View File
@@ -455,6 +455,9 @@ void ClearSectorScanResults();
void HandleSpreadingPropagandaInSector( INT16 sMapX, INT16 sMapY, INT8 bZ );
// Flugente: handle militia command
void HandleMilitiaCommand();
// is the character between secotrs in mvt
BOOLEAN CharacterIsBetweenSectors( SOLDIERTYPE *pSoldier );
@@ -2425,7 +2428,7 @@ void UpdateAssignments()
// handle any training
HandleTrainingInSector( sX, sY, bZ );
// handle training of character in sector
HandleRadioScanInSector( sX, sY, bZ );
@@ -2445,6 +2448,9 @@ void UpdateAssignments()
}
}
// Flugente: handle militia command
HandleMilitiaCommand();
// check to see if anyone is done healing?
UpdatePatientsWhoAreDoneHealing( );
@@ -5617,6 +5623,24 @@ void ClearSectorScanResults()
}
}
// Flugente: handle militia command
void HandleMilitiaCommand()
{
SOLDIERTYPE *pSoldier = NULL;
UINT32 uiCnt = 0;
UINT32 firstid = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
{
if( pSoldier && pSoldier->bAssignment == FACILITY_STRATEGIC_MILITIA_MOVEMENT && pSoldier->flags.fMercAsleep == FALSE )
{
// every commander gets a bit of leadership and wisdom
StatChange( pSoldier, LDRAMT, 2, TRUE );
StatChange( pSoldier, WISDOMAMT, 1, TRUE );
}
}
}
// handle snitch spreading propaganda assignment
// totally not a copy of HandleRadioScanInSector
void HandleSpreadingPropagandaInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
@@ -14575,6 +14599,28 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam
AssignMercToAMovementGroup( pSoldier );
}
break;
case FACILITY_STRATEGIC_MILITIA_MOVEMENT:
{
pSoldier->bOldAssignment = pSoldier->bAssignment;
// remove from squad
RemoveCharacterFromSquads( pSoldier );
// remove from any vehicle
if( pSoldier->bOldAssignment == VEHICLE )
{
TakeSoldierOutOfVehicle( pSoldier );
}
if ( pSoldier->bAssignment != bAssignment )
{
SetTimeOfAssignmentChangeForMerc( pSoldier );
}
ChangeSoldiersAssignment( pSoldier, bAssignment );
AssignMercToAMovementGroup( pSoldier );
}
break;
case( VEHICLE ):
if( CanCharacterVehicle( pSoldier ) && IsThisVehicleAccessibleToSoldier( pSoldier, iParam1 ) )
{
@@ -15820,6 +15866,10 @@ void ReEvaluateEveryonesNothingToDo()
fNothingToDo = FALSE;
break;
case FACILITY_STRATEGIC_MILITIA_MOVEMENT:
fNothingToDo = FALSE;
break;
case VEHICLE:
default: // squads
fNothingToDo = FALSE;
@@ -16101,6 +16151,14 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam )
fItWorked = TRUE;
}
break;
case FACILITY_STRATEGIC_MILITIA_MOVEMENT:
if( CanCharacterFacility( pSoldier, bParam, FAC_STRATEGIC_MILITIA_MOVEMENT ) )
{
pSoldier->bOldAssignment = pSoldier->bAssignment;
SetSoldierAssignment( pSoldier, FACILITY_STRATEGIC_MILITIA_MOVEMENT, bParam, 0,0 );
fItWorked = TRUE;
}
break;
case( SQUAD_1 ):
case( SQUAD_2 ):
case( SQUAD_3 ):
@@ -18605,9 +18663,16 @@ BOOLEAN CanCharacterFacility( SOLDIERTYPE *pSoldier, UINT8 ubFacilityType, UINT8
}
}
/*if ( ubAssignmentType == FAC_STRATEGIC_MILITIA_MOVEMENT )
{
if( !CanCharacterGatherInformation(pSoldier) )
{
return( FALSE );
}
}*/
// If we've reached this, then all is well.
return( TRUE );
}
INT8 CountFreeFacilitySlots( UINT8 sMapX, UINT8 sMapY, UINT8 ubFacilityType )
@@ -19632,6 +19697,9 @@ void FacilityAssignmentMenuBtnCallback ( MOUSE_REGION * pRegion, INT32 iReason )
case FAC_GATHER_RUMOURS:
ChangeSoldiersAssignment( pSoldier, FACILITY_GATHER_RUMOURS );
break;
case FAC_STRATEGIC_MILITIA_MOVEMENT:
ChangeSoldiersAssignment( pSoldier, FACILITY_STRATEGIC_MILITIA_MOVEMENT );
break;
}
// Flugente: I guess this piece of code is here to get a group Id for the soldier, which must not be there for movement specifically. Just my understanding, in case anybody else coming here wonders
@@ -20408,4 +20476,21 @@ void MoveItemMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason )
// unhighlight all strings in box
UnHighLightBox( ghMoveItemBox );
}
}
}
BOOLEAN MercStaffsMilitaryHQ()
{
SOLDIERTYPE *pSoldier = NULL;
UINT32 uiCnt = 0;
UINT32 firstid = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
{
if( pSoldier && pSoldier->bAssignment == FACILITY_STRATEGIC_MILITIA_MOVEMENT && pSoldier->flags.fMercAsleep == FALSE )
{
return TRUE;
}
}
return FALSE;
}
+3
View File
@@ -78,6 +78,7 @@ enum
FACILITY_GATHER_RUMOURS,
SNITCH_SPREAD_PROPAGANDA,
SNITCH_GATHER_RUMOURS,
FACILITY_STRATEGIC_MILITIA_MOVEMENT, // Flugente: merc staffs a military HQ, we can now control militia movement on the map
NUM_ASSIGNMENTS,
};
@@ -451,6 +452,8 @@ UINT32 HandlePropagandaBlockingBadNewsInTown( INT8 bTownId, UINT32 uiLoyaltyDecr
void HandleGatheringInformationBySoldier( SOLDIERTYPE* pSoldier );
BOOLEAN MercStaffsMilitaryHQ();
#endif
+1
View File
@@ -191,6 +191,7 @@ enum
FAC_SPREAD_PROPAGANDA,
FAC_SPREAD_PROPAGANDA_GLOBAL,
FAC_GATHER_RUMOURS,
FAC_STRATEGIC_MILITIA_MOVEMENT,
NUM_FACILITY_ASSIGNMENTS,
};
+4 -1
View File
@@ -769,7 +769,7 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
bAssignment == IN_TRANSIT ||
bAssignment == TRAIN_TOWN ||
bAssignment == TRAIN_MOBILE ||
( bAssignment > FACILITY_REST && ( bAssignment < FACILITY_PRISON_SNITCH || bAssignment > FACILITY_GATHER_RUMOURS ) ))
( bAssignment > FACILITY_REST && bAssignment != FACILITY_STRATEGIC_MILITIA_MOVEMENT && ( bAssignment < FACILITY_PRISON_SNITCH || bAssignment > FACILITY_GATHER_RUMOURS ) ))
{
// Soldier is performing a distinctly NON-FACILITY assignment.
return (-1);
@@ -933,6 +933,9 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
case FACILITY_GATHER_RUMOURS:
bAssignmentIndex = FAC_GATHER_RUMOURS;
break;
case FACILITY_STRATEGIC_MILITIA_MOVEMENT:
bAssignmentIndex = FAC_STRATEGIC_MILITIA_MOVEMENT;
break;
default:
bAssignmentIndex = -1;
break;
+4
View File
@@ -44,6 +44,7 @@
#include "laptop.h"
#include "Campaign.h"
#include "PostalService.h"
#include "MilitiaSquads.h"
#endif
#include "connect.h"
@@ -505,6 +506,9 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
CrippledVersionEndGameCheck();
break;
#endif
case EVENT_MILITIA_MOVEMENT_ORDER:
MilitiaMovementOrder( (UINT8) pEvent->uiParam );
break;
}
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
return TRUE;
+2
View File
@@ -112,6 +112,8 @@ enum
EVENT_HELICOPTER_HOVER_FOR_A_MINUTE,
EVENT_HELICOPTER_REFUEL_FOR_A_MINUTE,
EVENT_MILITIA_MOVEMENT_ORDER, // Flugente: timed event: militia was ordered to move, at this time they should arrive
NUMBER_OF_EVENT_TYPES_PLUS_ONE,
NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1
};
+104
View File
@@ -3741,7 +3741,108 @@ void ShowEnemyGroupsInMotion( INT16 sX, INT16 sY )
}
curr = curr->next;
}
}
// Flugente: show militia movement
void ShowMilitiaInMotion( INT16 sX, INT16 sY )
{
INT32 sExiting = 0;
INT32 sEntering = 0;
INT16 sDest = 0;
INT16 sSource = 0;
INT16 sOffsetX = 0, sOffsetY = 0;
INT16 sXPosition = 0, sYPosition = 0;
INT32 iCounter = 0;
HVOBJECT hIconHandle;
INT16 sTextXOffset = 0;
INT16 sTextYOffset = 0;
INT32 iWidth = 0, iHeight = 0;
INT32 iDeltaXForError = 0, iDeltaYForError = 0;
if( iCurrentMapSectorZ )
return;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sX, sY ) ] );
if ( !CountMilitia(pSectorInfo) )
return;
if ( ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_ALLDIRS ) == 0 )
return;
// show the icons for people in motion from this sector to the next guy over
INT16 iX = sX, iY = sY;
UINT8 ubDirection = 0;
GetVideoObject(&hIconHandle, guiENEMYBETWEENSECTORICONS );
INT16 iconOffsetX = 0;
INT16 iconOffsetY = 0;
if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_NORTH )
{
ubDirection = 4;
sOffsetX = (MAP_GRID_X / 2);
sOffsetY = 0;
iconOffsetX = -(hIconHandle->pETRLEObject[ubDirection].usWidth / 2);
iconOffsetY = -(hIconHandle->pETRLEObject[ubDirection].usHeight);
}
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_EAST )
{
ubDirection = 5;
sOffsetX = MAP_GRID_X;
sOffsetY = (MAP_GRID_Y / 2);
iconOffsetY = -(hIconHandle->pETRLEObject[ubDirection].usHeight / 2);
}
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_SOUTH )
{
ubDirection = 6;
sOffsetX = (MAP_GRID_X / 2);
sOffsetY = MAP_GRID_Y;
iconOffsetX = -(hIconHandle->pETRLEObject[ubDirection].usWidth / 2);
}
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_WEST )
{
ubDirection = 7;
sOffsetX = 0;
sOffsetY = (MAP_GRID_Y / 2);
iconOffsetX = -(hIconHandle->pETRLEObject[ubDirection].usWidth);
iconOffsetY = -(hIconHandle->pETRLEObject[ubDirection].usHeight / 2);
}
if (iResolution >= _1024x768 )
{
iconOffsetY -= 1;
}
iX = MAP_VIEW_START_X+( sX * MAP_GRID_X ) + sOffsetX + iconOffsetX;
iY = MAP_VIEW_START_Y + ( sY * MAP_GRID_Y ) + sOffsetY + iconOffsetY;
BltVideoObject(guiSAVEBUFFER, hIconHandle, ubDirection , ( INT16 ) iX, ( INT16 ) iY , VO_BLT_SRCTRANSPARENCY, NULL );
iWidth = 12;
iHeight = 7;
// error correction for scrolling with people on the move
if( iX < 0 )
{
iDeltaXForError = 0 - iX;
iWidth -= iDeltaXForError;
iX = 0;
}
if( iY < 0 )
{
iDeltaYForError = 0 - iY;
iHeight -= iDeltaYForError;
iY = 0;
}
if( ( iWidth > 0 )&&( iHeight > 0 ) )
{
RestoreExternBackgroundRect( iX, iY, ( INT16 )iWidth, ( INT16 )iHeight );
}
}
void DisplayDistancesForHelicopter( void )
@@ -6389,6 +6490,9 @@ void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bS
return;
}
// Flugente: show militia in motion
ShowMilitiaInMotion( sSectorX, sSectorY );
// get total number of badguys here
sNumberOfEnemies = NumEnemiesInSector( sSectorX, sSectorY );
+2 -1
View File
@@ -110,6 +110,7 @@ void RestoreClipRegionToFullScreenForRectangle( UINT32 uiDestPitchBYTES );
// show the icons for people in motion
void ShowPeopleInMotion( INT16 sX, INT16 sY );
void ShowEnemyGroupsInMotion( INT16 sX, INT16 sY);
void ShowMilitiaInMotion( INT16 sX, INT16 sY); // added by Flugente
// last sector in helicopter's path
INT16 GetLastSectorOfHelicoptersPath( void );
@@ -298,7 +299,7 @@ extern SGPRect MapScreenRect;
extern BOOLEAN fDrawTempHeliPath;
// selected destination char
extern INT8 bSelectedDestChar;
extern INT8 bSelectedDestChar;
// current assignment character
extern INT8 bSelectedAssignChar;
+106 -36
View File
@@ -464,7 +464,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
}
// Creates militia at destination sector and removes it from starting sector
void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOLEAN fAlternativeMax )
void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOLEAN fAlternativeMax, BOOLEAN fSkipSpreading )
{
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
SECTORINFO *pTSectorInfo = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
@@ -476,13 +476,13 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
UINT8 bTotalGreensPercent = 0, bTotalRegularsPercent = 0, bTotalElitesPercent = 0;
INT8 bNewSourceGroupSize = 0, bNewDestGroupSize = 0, bGroupSizeRatio = 0;
UINT8 ubChanceToSpreadOut;
//////////////////////////////////////////////////////////
// We begin by determining the group's chance to "spread out" into the next sector rather
// than moving in en-masse. This is mainly affected by the presence of enemies.
// Is the target a city or SAM site?
if (IsThisSectorASAMSector( sTMapX, sTMapY, 0 ) ||
if (fSkipSpreading || IsThisSectorASAMSector( sTMapX, sTMapY, 0 ) ||
( GetTownIdForSector( sTMapX, sTMapY ) != BLANK_SECTOR &&
gfMilitiaAllowedInTown[GetTownIdForSector( sTMapX, sTMapY )] ))
{
@@ -1421,13 +1421,78 @@ void ClearBlockMoveList()
BOOLEAN CheckInBlockMoveList(INT16 sMapX, INT16 sMapY)
{
UINT16 i;
for( i = 0; i < uiBlockMoveListPointer ; ++i)
if( sMapX == SECTORX(pBlockMoveList[i]) && sMapY == SECTORY(pBlockMoveList[i]) )return TRUE;
for( UINT16 i = 0; i < uiBlockMoveListPointer ; ++i)
{
if( sMapX == SECTORX(pBlockMoveList[i]) && sMapY == SECTORY(pBlockMoveList[i]) )
return TRUE;
}
return FALSE;
}
void MilitiaMovementOrder(UINT8 sector)
{
INT16 sX = SECTORX(sector);
INT16 sY = SECTORY(sector);
// if we are in gamescreen and a battle is going on, and this is the sector that militia moves from, don't move them. Suddenly disappearing would be... awkward
if ( guiCurrentScreen == GAME_SCREEN && gTacticalStatus.uiFlags & INCOMBAT && gWorldSectorX == sX && gWorldSectorY == sY && !gbWorldSectorZ )
{
// remove all movement flags
StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags &= ~MILITIA_MOVE_ALLDIRS;
return;
}
// to stop the player from just setting someone in HQ to give orders and then reassigning them, we simply demand that there'll also be someone when the militia peform the travelling
if ( !MercStaffsMilitaryHQ() )
{
// remove all movement flags
StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags &= ~MILITIA_MOVE_ALLDIRS;
return;
}
INT16 targetX = sX;
INT16 targetY = sY;
if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_NORTH )
--targetY;
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_WEST )
--targetX;
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_EAST )
++targetX;
else if ( StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags & MILITIA_MOVE_SOUTH )
++targetY;
// remove all movement flags
StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags &= ~MILITIA_MOVE_ALLDIRS;
UINT8 targetsector = SECTOR(targetX, targetY);
if ( gGameExternalOptions.gflimitedRoaming && !IsSectorRoamingAllowed(targetsector) )
return;
// if militia moves from the currently loaded sector, it has to drop all gear first
if ( gGameExternalOptions.fMilitiaUseSectorInventory && gWorldSectorX == sX && gWorldSectorY == sY && !gbWorldSectorZ )
{
TeamDropAll( MILITIA_TEAM );
}
MoveMilitiaSquad( sX, sY, targetX, targetY, FALSE, TRUE );
if ( gfStrategicMilitiaChangesMade)
ResetMilitia();
if( NumEnemiesInSector( targetX, targetY ) )
{
//Moa: handle deserters before moving in hostile territory
MobileMilitiaDeserters( targetX, targetY, TRUE, TRUE );
gfMSBattle = TRUE;
EnterAutoResolveMode( targetX, targetY );
}
}
void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
{
UINT16 pMoveDir[4][3];
@@ -1456,11 +1521,13 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
gfMSBattle = FALSE;
}
if( CheckInBlockMoveList( sMapX, sMapY ) )return;
if( CheckInBlockMoveList( sMapX, sMapY ) )
return;
uiMilitiaCount = CountMilitia(pSectorInfo);
if( !uiMilitiaCount )return;
if( !uiMilitiaCount )
return;
// Kaiden: Moved Create Militia code into CreateMilitiaSquads
// Removed the code from here and added the procedure call
@@ -1469,19 +1536,21 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
if( (!gGameExternalOptions.gfmusttrainroaming) && ( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ) )
{
if (GetWorldDay( ) < gGameExternalOptions.guiAllowMilitiaGroupsDelay)
return;
if( GetWorldHour() % gGameExternalOptions.guiCreateEachNHours )
return;
CreateMilitiaSquads( sMapX, sMapY );
if (gfStrategicMilitiaChangesMade)
// Flugente: only enter this if the time is correct (but do not return if it isn't, we still might do the movement part)
if (GetWorldDay( ) < gGameExternalOptions.guiAllowMilitiaGroupsDelay && GetWorldHour() % gGameExternalOptions.guiCreateEachNHours )
{
ResetMilitia();
CreateMilitiaSquads( sMapX, sMapY );
if (gfStrategicMilitiaChangesMade)
{
ResetMilitia();
}
}
}
// Flugente: if we can order militia directly, don't have them wander around at random
if ( !MercStaffsMilitaryHQ() )
return;
// HEADROCK HAM B2.7: If INI flag is set, allow militia to move out of Minor City sectors (Orta, Tixa, San Mona, etc).
if (gGameExternalOptions.fAllowMilitiaMoveThroughMinorCities)
fSourceCityAllowsRoaming = ( !gfMilitiaAllowedInTown[GetTownIdForSector( sMapX, sMapY )] );
@@ -1493,14 +1562,16 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
{
if( !gGameExternalOptions.gfAllowMilitiaFollowPlayer || !PlayerMercsInSector_MSE( (UINT8)sMapX, (UINT8)sMapY, FALSE ) ) // and there's no player's mercs in the sector, or they are not forced to follow
{
if( GetWorldHour() % 2 )return;
if( GetWorldHour() % 2 )
return;
memset(pMoveDir, 0, sizeof(pMoveDir));
GenerateDirectionInfos( sMapX, sMapY, &uiDirNumber, pMoveDir, FALSE, FALSE );
if( uiDirNumber )
{
for( x = 1; x < uiDirNumber ; ++x )pMoveDir[x][1] += pMoveDir[x-1][1];
for( x = 1; x < uiDirNumber ; ++x )
pMoveDir[x][1] += pMoveDir[x-1][1];
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld", x, pMoveDir[x][1]);
// HEADROCK HAM 3.6: Too many INI settings. Removed a couple, including MIN/MAX SQUAD SIZE.
@@ -1508,12 +1579,12 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
// ( uiMilitiaCount >= gGameExternalOptions.guiMinMilitiaSquadSize ? CHANCE_TO_MOVE_A_SQUAD : CHANCE_TO_MOVE_AN_UNFULL_SQUAD ) );
iRandom = Random( pMoveDir[ uiDirNumber - 1 ][1] );
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Roll %ld", iRandomRes);
iRandomRes = 256;
for( x = 0; x < uiDirNumber; ++x)
{
if( iRandom < pMoveDir[x][1] )
{
iRandomRes = x;
@@ -1544,11 +1615,11 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
}
// WDS bug fix for moving militia
int targetX = SECTORX( pMoveDir[ iRandomRes ][0] );
int targetY = SECTORY( pMoveDir[ iRandomRes ][0] );
INT16 targetX = SECTORX( pMoveDir[ iRandomRes ][0] );
INT16 targetY = SECTORY( pMoveDir[ iRandomRes ][0] );
Assert(targetX >= 0 && targetX < MAP_WORLD_X);
Assert(targetY >= 0 && targetY < MAP_WORLD_Y);
MoveMilitiaSquad( sMapX, sMapY, targetX, targetY, FALSE );
MoveMilitiaSquad( sMapX, sMapY, targetX, targetY, FALSE, FALSE );
if ( gfStrategicMilitiaChangesMade)
{
@@ -1575,23 +1646,23 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
//Moa: handle deserters before moving in hostile territory
MobileMilitiaDeserters( targetX, targetY, TRUE, TRUE );
gfMSBattle = TRUE;
gfMSBattle = TRUE;
// GroupArrivedAtSector( pEnemyGroup->ubGroupID , TRUE, FALSE );
EnterAutoResolveMode( targetX, targetY );
// GroupArrivedAtSector( pEnemyGroup->ubGroupID , TRUE, FALSE );
EnterAutoResolveMode( targetX, targetY );
// }
}
}
}
else return;
}
}
}
// Kaiden: Roaming Militia Training:
// If we're training roaming militia,
// we'll get our squad from here:
// Don't need to check for delay, as this function won't be
// called if there is a delay set.
// Kaiden: Roaming Militia Training:
// If we're training roaming militia,
// we'll get our squad from here:
// Don't need to check for delay, as this function won't be
// called if there is a delay set.
void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
{
// Variables for Direction Rating checks
@@ -1690,7 +1761,7 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
}
}
}
iCounter++;
++iCounter;
}
}
@@ -1718,7 +1789,7 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
// Check for enemies in target sector
if( NumEnemiesInSector( sTMapX, sTMapY ) )
{
{
// Initiave battle
gfMSBattle = TRUE;
EnterAutoResolveMode( sTMapX, sTMapY );
@@ -1742,7 +1813,6 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
}
}
}
return;
}
@@ -1976,7 +2046,7 @@ void MilitiaFollowPlayer( INT16 sMapX, INT16 sMapY, INT16 sDMapX, INT16 sDMapY )
IsThisSectorASAMSector( sDMapX, sDMapY, 0 ) )return;
MoveMilitiaSquad( sMapX, sMapY, sDMapX, sDMapY, FALSE );
MoveMilitiaSquad( sMapX, sMapY, sDMapX, sDMapY, FALSE, FALSE );
}
+4
View File
@@ -14,6 +14,10 @@ extern UINT8 guiDirNumber;
// Updates movement orders for militia squads
void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY );
// Flugente: militia in this sector is ordered to move according to flags that were applied to it prior
void MilitiaMovementOrder(UINT8 sector);
// Kaiden: creates militia squad in an adjacent sector
// to the coordinates you pass to it.
void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY );
+1 -1
View File
@@ -3059,7 +3059,7 @@ INT32 FindTravelTimeBetweenWaypoints( WAYPOINT * pSource, WAYPOINT * pDest, GROU
#define FOOT_TRAVEL_TIME 89
//#define FOOT_TRAVEL_TIME 89 // Flugente: moved to header
#define CAR_TRAVEL_TIME 30
#define TRUCK_TRAVEL_TIME 32
#define TRACKED_TRAVEL_TIME 46
+2
View File
@@ -35,6 +35,8 @@ enum
THROUGH_STRATEGIC_MOVE
};
#define FOOT_TRAVEL_TIME 89
//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.
+4
View File
@@ -852,6 +852,10 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
{
//pData->curAssignmentType = (INT16) atol(pData->szCharData);
pData->curAssignmentType = FAC_GATHER_RUMOURS;
}
else if (strcmp(pData->szCharData, "STRATEGIC_MILITIA_MOVEMENT") == 0)
{
pData->curAssignmentType = FAC_STRATEGIC_MILITIA_MOVEMENT;
}
else
{
+20
View File
@@ -7438,6 +7438,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
//activate autoresolve in prebattle interface.
ActivatePreBattleAutoresolveAction();
}
// Flugente: militia orders
else if ( SetMilitiaMovementOrder(sSelMapX, sSelMapY, iCurrentMapSectorZ, MILITIA_MOVE_WEST) )
{
;
}
else
{
// only handle border button keyboard equivalents if the button is visible!
@@ -7491,6 +7496,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
TestDumpStatChanges();
}
#endif
// Flugente: militia orders
if ( SetMilitiaMovementOrder(sSelMapX, sSelMapY, iCurrentMapSectorZ, MILITIA_MOVE_EAST) )
{
;
}
break;
case 'D':
@@ -7950,6 +7960,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
gfSaveGame = TRUE;
RequestTriggerExitFromMapscreen( MAP_EXIT_TO_SAVE );
}
// Flugente: militia orders
else if ( SetMilitiaMovementOrder(sSelMapX, sSelMapY, iCurrentMapSectorZ, MILITIA_MOVE_SOUTH) )
{
;
}
else if(gGameExternalOptions.fEnableInventoryPoolQ && fShowMapInventoryPool == TRUE)//dnl ch51 081009
{
SortInventoryPoolQ();
@@ -8192,6 +8207,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
else if( fCtrl )
{
}
// Flugente: militia orders
else if ( SetMilitiaMovementOrder(sSelMapX, sSelMapY, iCurrentMapSectorZ, MILITIA_MOVE_NORTH) )
{
;
}
else
{
// only handle border button keyboard equivalents if the button is visible!
+98 -3
View File
@@ -16,6 +16,10 @@
#include "Vehicles.h"
#include "Game Clock.h"
#include "CampaignStats.h" // added by Flugente
#include "militiasquads.h" // added by Flugente
#include "Game Event Hook.h" // added by Flugente
#include "message.h" // added by Flugente
#include "Text.h" // added by Flugente
#endif
#ifdef JA2UB
@@ -160,7 +164,98 @@ void HandleSoldierDeadComments( SOLDIERTYPE *pSoldier )
#endif
}
return;
}
BOOLEAN SetMilitiaMovementOrder(INT16 sX, INT16 sY, INT8 sZ, UINT32 dir)
{
// militia can only move on the surface
if ( sZ )
return FALSE;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sX, sY ) ] );
// militia needs to be here...
if ( !CountMilitia(pSectorInfo) )
return FALSE;
// in order to give movement orders, we need a merc to staff a military headquarter
if ( !MercStaffsMilitaryHQ() )
return FALSE;
INT16 newX = sX;
INT16 newY = sY;
UINT8 movetype = THROUGH_STRATEGIC_MOVE;
switch (dir)
{
case MILITIA_MOVE_NORTH:
--newY;
movetype = NORTH_STRATEGIC_MOVE;
break;
case MILITIA_MOVE_WEST:
--newX;
movetype = WEST_STRATEGIC_MOVE;
break;
case MILITIA_MOVE_EAST:
++newX;
movetype = EAST_STRATEGIC_MOVE;
break;
case MILITIA_MOVE_SOUTH:
++newY;
movetype = SOUTH_STRATEGIC_MOVE;
break;
default:
return FALSE;
break;
}
if ( gGameExternalOptions.gflimitedRoaming && !IsSectorRoamingAllowed( SECTOR(newX, newY) ) )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gpStrategicString[STR_MILITIAMOVEMENT_NO_LIMITEDROAMING] );
return FALSE;
}
UINT8 ubTraverseType = SectorInfo[ SECTOR(sX, sY) ].ubTraversability[ movetype ];
if( ubTraverseType == GROUNDBARRIER || ubTraverseType == EDGEOFWORLD )
return FALSE;
UINT32 ubTraverseMod = 0;
switch( ubTraverseType )
{
case TOWN: ubTraverseMod = 1780;break;
case ROAD: ubTraverseMod = 100;break;
case PLAINS: ubTraverseMod = 85; break;
case SAND: ubTraverseMod = 50; break;
case SPARSE: ubTraverseMod = 70; break;
case DENSE: ubTraverseMod = 60; break;
case SWAMP: ubTraverseMod = 35; break;
case WATER: ubTraverseMod = 25; break;
case HILLS: ubTraverseMod = 50; break;
case NS_RIVER: ubTraverseMod = 25; break;
case EW_RIVER: ubTraverseMod = 25; break;
}
if( ubTraverseMod )
{
UINT32 timeneeded = FOOT_TRAVEL_TIME * 100 / ubTraverseMod;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sX, sY ) ] );
StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags &= ~MILITIA_MOVE_ALLDIRS;
StrategicMap[ sX + ( sY * MAP_WORLD_X ) ].usFlags |= dir;
AddStrategicEvent( EVENT_MILITIA_MOVEMENT_ORDER, GetWorldTotalMin() + timeneeded, SECTOR( sX, sY ) );
fMapPanelDirty = TRUE;
return TRUE;
}
return FALSE;
}
+19 -5
View File
@@ -9,15 +9,18 @@
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
UINT8 uiBadFootSector[4]; // blocking mvt for foot
UINT8 uiBadVehicleSector[4]; // blocking mvt from vehicles
INT8 bNameId;
BOOLEAN fEnemyControlled; // enemy controlled or not
BOOLEAN fEnemyControlled; // enemy controlled or not
BOOLEAN fEnemyAirControlled;
BOOLEAN UNUSEDfLostControlAtSomeTime;
INT8 bSAMCondition; // SAM Condition .. 0 - 100, just like an item's status
INT8 bSAMCondition; // SAM Condition .. 0 - 100, just like an item's status
INT8 bFillupforPadding[ 3 ]; // necessary for padding
UINT32 usFlags; // Flugente: various flags
INT8 bPadding[ 20 ];
} ;
};
enum
{
@@ -33,6 +36,15 @@ enum
INSERTION_CODE_CENTER,
};
// -------- added by Flugente: various item flags --------
// flags used for various properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
#define MILITIA_MOVE_NORTH 0x00000001 //1 // movement directions for ordering militia on the strategic map
#define MILITIA_MOVE_WEST 0x00000002 //2
#define MILITIA_MOVE_EAST 0x00000004 //4
#define MILITIA_MOVE_SOUTH 0x00000008 //8
#define MILITIA_MOVE_ALLDIRS 0x0000000F // 15
// -------------------------------------------------------
//PLEASE USE CALCULATE_STRATEGIC_INDEX() macro instead (they're identical).
//#define GETWORLDMAPNO( x, y ) ( x+(MAP_WORLD_X*y) )
@@ -46,4 +58,6 @@ void HandleSoldierDeadComments( SOLDIERTYPE *pSoldier );
BOOLEAN HandleStrategicDeath( SOLDIERTYPE *pSoldier );
BOOLEAN SetMilitiaMovementOrder(INT16 sX, INT16 sY, INT8 sZ, UINT32 dir);
#endif
+28 -6
View File
@@ -103,6 +103,7 @@
#include "Explosion Control.h"
#include "Auto Resolve.h"
#include "cursors.h"
#include "GameVersion.h"
#endif
#include "LuaInitNPCs.h"
@@ -5306,16 +5307,38 @@ BOOLEAN SaveStrategicInfoToSavedFile( HWFILE hFile )
BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
{
UINT32 uiNumBytesRead=0;
UINT32 uiSize = sizeof( StrategicMapElement ) * ( MAP_WORLD_X * MAP_WORLD_Y );
UINT32 uiSize = sizeof( StrategicMapElement );
// Load the strategic map information
FileRead( hFile, StrategicMap, uiSize, &uiNumBytesRead );
if( uiNumBytesRead != uiSize)
if ( guiCurrentSaveGameVersion >= MILITIA_MOVEMENT )
{
return(FALSE);
for(UINT16 i = 0; i < MAP_WORLD_X * MAP_WORLD_Y; ++i)
{
// Load the strategic map information
FileRead( hFile, &StrategicMap[i], uiSize, &uiNumBytesRead );
if( uiNumBytesRead != uiSize)
{
return(FALSE);
}
}
}
else
{
uiSize = 41;
for(UINT16 i = 0; i < MAP_WORLD_X * MAP_WORLD_Y; ++i)
{
// Load the strategic map information
FileRead( hFile, &StrategicMap[i], uiSize, &uiNumBytesRead );
if( uiNumBytesRead != uiSize)
{
return(FALSE);
}
StrategicMap[i].usFlags = 0;
}
}
// Load the Sector Info
for (int sectorID = 0; sectorID <= 255; ++ sectorID) {
FileRead( hFile, &SectorInfo[sectorID], sizeof( SECTORINFO ), &uiNumBytesRead );
@@ -5348,7 +5371,6 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
return(FALSE);
}
return( TRUE );
}