Home » PLAYER'S HQ 1.13 » JA2 Complete Mods & Sequels » Stracciatella Project (Platform Independent JA2) » Patch: Garrison militia in wilderness
Patch: Garrison militia in wilderness[message #202670]
|
Fri, 28 November 2008 00:05
|
|
mgl |
  |
Messages:255
Registered:December 2007 Location: France |
|
|
This is a patch against svn r4833 of Stracciatella,
but it will work with official release 0.10 too.
The idea was to be able to garrison militia in the sectors where Deidranna garrisons troops herself, but you can train militia in any sector in wilderness.
I kept the existing rules for towns (loyalty + no training in San Mona and Estoni) but you can now garrison Tixa and Orta and maybe Omerta, I don't remember.
It was written on x86 Linux.
The updated files are:
'Build/Strategic/Map_Screen_Interface.cc'
'Build/Strategic/Assignments.cc'
'Build/Strategic/Town_Militia.cc'
'Build/Strategic/Map_Screen_Interface_Map.cc'
The strange thing I have seen:
* A militian spawned under a destroyed tank (or he was himself the destroyed tank) in a level 1 defense sector around Meduna.
* Right click on Estoni on the strategic screen with "show militia" on shows a town of the size of Balime or Omerta northwest of there.
Here is the diff file, maybe I should host it elsewhere:
--- Build/Strategic/Map_Screen_Interface.cc (revision 4833)
+++ Build/Strategic/Map_Screen_Interface.cc (working copy)
@@ -63,6 +63,7 @@
#include "VSurface.h"
#include "EMail.h"
#include "Items.h"
+#include "Town_Militia.h" /* mgl: CountAllMilitiaInSector() */
// number of LINKED LISTS for sets of leave items (each slot holds an unlimited # of items)
@@ -4219,7 +4220,30 @@
GetShortSectorString( sSectorX, sSectorY, sStringA, lengthof(sStringA));
swprintf( sString, lengthof(sString), pMapErrorString[ 24 ], sStringA );
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, sString );
+
+ /* mgl: auto-resolve for militia garrisoned in wilderness
+ * We have mercs in the sector -> we shouldn't be called
+ * We have militia in the sector -> auto resolve screen
+ * We have nobody -> notification message
+ *
+ * Note:
+ * The only caller of _this_ function is from
+ * 'Build/Strategic/Strategic_Movement.c'
+ * It calls us when there are militia in the sector,
+ * but we'll check anyway.
+ * We should not be called if there are combat able mercs
+ * in the sector, but don't check.
+ */
+ if (CountAllMilitiaInSector(sSectorX, sSectorY))
+ {
+ /* Auto resolve screen */
+ DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, ReturnCallback );
+ }
+ else
+ { /* Notification */
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, sString );
+ }
+
}
}
--- Build/Strategic/Assignments.cc (revision 4833)
+++ Build/Strategic/Assignments.cc (working copy)
@@ -590,11 +590,13 @@
}
+/* mgl: Garrison militia in wilderness
+ * Any sector on surface can contain militia now,
+ * not only SAM sites and towns.
+ */
static BOOLEAN CanSectorContainMilita(const INT16 x, const INT16 y, const INT16 z)
{
- return
- (z == 0 && StrategicMap[CALCULATE_STRATEGIC_INDEX(x, y)].bNameId != BLANK_SECTOR) || // is there a town?
- IsThisSectorASAMSector(x, y, z);
+ return z == 0; /* i.e surface sector */
}
@@ -630,20 +632,31 @@
}
+/* mgl: Garrison militia in wilderness
+ * Perform a loyalty check for "town" sectors (except Tixa and Orta
+ * because they don't have an associated loyalty)
+ * and blindly return true for sectors in wilderness
+ *
+ * Note: this function is never called for the towns of Estoni,
+ * San mona and Omerta because the test fails earlier.
+ */
BOOLEAN DoesSectorMercIsInHaveSufficientLoyaltyToTrainMilitia(const SOLDIERTYPE* const s)
{
// underground training is not allowed (code doesn't support and it's a reasonable enough limitation)
if (s->bSectorZ != 0) return FALSE;
const INT8 bTownId = GetTownIdForSector(s->sSectorX, s->sSectorY);
- if (bTownId != BLANK_SECTOR)
+ if ((bTownId != BLANK_SECTOR)
+ && (bTownId != ORTA)
+ && (bTownId != TIXA)
+ )
{
// Does this town have sufficient loyalty to train militia?
return gTownLoyalty[bTownId].ubRating >= MIN_RATING_TO_TRAIN_TOWN;
}
else
{
- return IsThisSectorASAMSector(s->sSectorX, s->sSectorY, s->bSectorZ);
+ return TRUE;
}
}
--- Build/Strategic/Town_Militia.cc (revision 4833)
+++ Build/Strategic/Town_Militia.cc (working copy)
@@ -730,6 +730,11 @@
}
+/* mgl: Garrison militia in wilderness
+ * The logic was split between towns (with all their sectors taken
+ * into account) and SAM sites (single sector).
+ * We use the logic of the SAM sites for sectors in wilderness.
+ */
BOOLEAN IsAreaFullOfMilitia(const INT16 sector_x, const INT16 sector_y, const INT8 sector_z)
{
if (sector_z != 0) return TRUE;
@@ -754,7 +759,7 @@
}
}
}
- else if (IsThisSectorASAMSector(sector_x, sector_y, 0))
+ else
{
// don't count GREEN militia, they can be trained into regulars first
count_milita += MilitiaInSectorOfRank(sector_x, sector_y, REGULAR_MILITIA);
@@ -1027,34 +1032,27 @@
}
+/* mgl: garrison militia in wilderness
+ * This function was a filter that checked if the sector was
+ * on surface and either a SAM site or a town.
+ * It returned TRUE for a SAM site
+ * and "MilitiaTrainingAllowedInTown()" for a town sector.
+ *
+ * Now it's only a surface filter.
+ * If militia garrisons were to be restricted to the sectors that the queen
+ * garrisons herself (the "pGarrisonGroup" lookup table in
+ * 'Build/Strategic/Strategic_AI.cc'), it may be the place to check it.
+ */
BOOLEAN MilitiaTrainingAllowedInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
- INT8 bTownId;
- BOOLEAN fSamSitePresent = FALSE;
-
-
- if( bSectorZ != 0 )
- {
- return( FALSE );
- }
-
- fSamSitePresent = IsThisSectorASAMSector( sSectorX, sSectorY, bSectorZ );
-
- if( fSamSitePresent )
- {
- // all SAM sites may have militia trained at them
- return(TRUE);
- }
-
-
- bTownId = GetTownIdForSector( sSectorX, sSectorY );
-
-
- return( MilitiaTrainingAllowedInTown( bTownId ) );
+ return bSectorZ == 0;
}
-
+/* mgl: Garrison militia in wilderness
+ * We want to allow militia in the "towns" of Tixa and Orta
+ * because the queen will try to garrison them too.
+ */
BOOLEAN MilitiaTrainingAllowedInTown( INT8 bTownId )
{
switch ( bTownId )
@@ -1066,13 +1064,13 @@
case BALIME:
case MEDUNA:
case CHITZENA:
+ case TIXA:
+ case ORTA:
return(TRUE);
case OMERTA:
case ESTONI:
case SAN_MONA:
- case TIXA:
- case ORTA:
// can't keep militia in these towns
return(FALSE);
--- Build/Strategic/Map_Screen_Interface_Map.cc (revision 4833)
+++ Build/Strategic/Map_Screen_Interface_Map.cc (working copy)
@@ -481,6 +481,9 @@
INT32 giPotHeliPathBaseTime = 0;
+static void DrawMapBoxIcon(HVOBJECT hIconHandle, UINT16 usVOIndex, INT16 sMapX, INT16 sMapY, UINT8 ubIconPosition);
+
+
void DrawMapIndexBigMap( BOOLEAN fSelectedCursorIsYellow )
{
// this procedure will draw the coord indexes on the zoomed out map
@@ -580,18 +583,79 @@
static void HandleShowingOfEnemyForcesInSector(INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubIconPosition);
+/* mgl: Garrison militia in wilderness
+ * Blit the militia dots on each sector.
+ * Returns the number of militia forces (= dots). The caller will use it
+ * to start to add the enemy dots at the right place.
+ */
+static UINT8 ShowMilitiaInSector(INT16 sX, INT16 sY, INT sZ)
+{
+ /* Check if we are on surface */
+ if (sZ != 0) { return 0; }
+
+ /* Check if sector is in enemy hands */
+ if(StrategicMap[sX + sY * MAP_WORLD_X].fEnemyControlled)
+ {
+ return 0;
+ }
+
+ /* Count Militia */
+ UINT8 uGreen = MilitiaInSectorOfRank(sX, sY, GREEN_MILITIA);
+ UINT8 uReg = MilitiaInSectorOfRank(sX, sY, REGULAR_MILITIA);
+ UINT8 uElite = MilitiaInSectorOfRank(sX, sY, ELITE_MILITIA);
+ UINT8 uStagingCount = uGreen + uReg; /* Need later */
+ UINT8 uMilitiaCount = uStagingCount + uElite;
+
+ /* Draw militia small boxes */
+ INT32 i;
+ INT32 iIconValue;
+
+ if(fZoomFlag)
+ {
+ // LARGE icon offset in the .sti
+ iIconValue = 11;
+ }
+ else
+ {
+ // SMALL icon offset in the .sti
+ iIconValue = 5;
+ }
+
+ for (i = 0; i < uMilitiaCount; i++)
+ {
+ // Change offset for regulars and elites
+ (i == uGreen) && (++iIconValue); /* Reg militia offset */
+ (i == uStagingCount) && (++iIconValue); /* Elite offset */
+
+ DrawMapBoxIcon(guiMilitia, iIconValue, sX, sY, i);
+ }
+
+ return uMilitiaCount;
+}
+
+
static void HandleShowingOfEnemiesWithMilitiaOn(void)
{
+ UINT8 uMilitiaCount;
for (INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX)
{
for (INT16 sY = 1; sY < MAP_WORLD_Y - 1; ++sY)
{
- HandleShowingOfEnemyForcesInSector(sX, sY, iCurrentMapSectorZ, CountAllMilitiaInSector(sX, sY));
+ /* Draw militia small boxes, if any (and count them */
+ uMilitiaCount = ShowMilitiaInSector(sX,
+ sY,
+ iCurrentMapSectorZ
+ );
+
+ /* Draw enemies small boxes nest to the militia ones*/
+ HandleShowingOfEnemyForcesInSector(sX, sY, iCurrentMapSectorZ, uMilitiaCount);
}
}
}
+
+
static void BlitMineGridMarkers(void);
static void BlitMineIcon(INT16 sMapX, INT16 sMapY);
static void BlitMineText(INT16 sMapX, INT16 sMapY);
@@ -600,7 +664,6 @@
static void DrawBullseye(void);
static void DrawOrta(void);
static void DrawTixa(void);
-static void DrawTownMilitiaForcesOnMap(void);
static void HandleLowerLevelMapBlit(void);
static void ShadeMapElem(INT16 sMapX, INT16 sMapY, INT32 iColor);
static void ShowItemsOnMap(void);
@@ -716,8 +779,6 @@
ShowTownText();
}
- if (fShowMilitia) DrawTownMilitiaForcesOnMap();
-
if (fShowAircraftFlag && !gfInChangeArrivalSectorMode) DrawBullseye();
}
else
@@ -840,9 +901,7 @@
}
-static void DrawMapBoxIcon(HVOBJECT hIconHandle, UINT16 usVOIndex, INT16 sMapX, INT16 sMapY, UINT8 ubIconPosition);
-
// "on duty" includes mercs inside vehicles
static INT32 ShowOnDutyTeam(INT16 sMapX, INT16 sMapY)
{
@@ -4879,117 +4938,8 @@
}
-static void DrawTownMilitiaForcesOnMap(void)
-{
- INT32 iCounter = 0, iCounterB = 0, iTotalNumberOfTroops = 0, iIconValue = 0;
- INT32 iNumberOfGreens = 0, iNumberOfRegulars = 0, iNumberOfElites = 0;
- INT16 sSectorX = 0, sSectorY = 0;
- // clip blits to mapscreen region
- ClipBlitsToMapViewRegion( );
- while( pTownNamesList[ iCounter ] != 0 )
- {
- // run through each town sector and plot the icons for the militia forces in the town
- if( !StrategicMap[ pTownLocationsList[ iCounter ] ].fEnemyControlled )
- {
- sSectorX = GET_X_FROM_STRATEGIC_INDEX( pTownLocationsList[ iCounter ] );
- sSectorY = GET_Y_FROM_STRATEGIC_INDEX( pTownLocationsList[ iCounter ] );
-
- // get number of each
- iNumberOfGreens = SectorInfo[ STRATEGIC_INDEX_TO_SECTOR_INFO( pTownLocationsList[ iCounter ] ) ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
- iNumberOfRegulars = SectorInfo[ STRATEGIC_INDEX_TO_SECTOR_INFO( pTownLocationsList[ iCounter ] ) ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
- iNumberOfElites = SectorInfo[ STRATEGIC_INDEX_TO_SECTOR_INFO( pTownLocationsList[ iCounter ] ) ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
-
- // set the total for loop upper bound
- iTotalNumberOfTroops = iNumberOfGreens + iNumberOfRegulars + iNumberOfElites;
-
- for( iCounterB = 0; iCounterB < iTotalNumberOfTroops; iCounterB++ )
- {
- if( fZoomFlag )
- {
- // LARGE icon offset in the .sti
- iIconValue = 11;
- }
- else
- {
- // SMALL icon offset in the .sti
- iIconValue = 5;
- }
-
- // get the offset further into the .sti
- if( iCounterB < iNumberOfGreens )
- {
- iIconValue += 0;
- }
- else if( iCounterB < iNumberOfGreens + iNumberOfRegulars )
- {
- iIconValue += 1;
- }
- else
- {
- iIconValue += 2;
- }
-
- DrawMapBoxIcon(guiMilitia, iIconValue, sSectorX, sSectorY, iCounterB);
- }
- }
-
- iCounter++;
- }
-
- // now handle militia for sam sectors
- for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ )
- {
- sSectorX = SECTORX( pSamList[ iCounter ] );
- sSectorY = SECTORY( pSamList[ iCounter ] );
-
- if( !StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].fEnemyControlled )
- {
- // get number of each
- iNumberOfGreens = SectorInfo[ pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
- iNumberOfRegulars = SectorInfo[ pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
- iNumberOfElites = SectorInfo[pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
-
- // ste the total for loop upper bound
- iTotalNumberOfTroops = iNumberOfGreens + iNumberOfRegulars + iNumberOfElites;
-
- for( iCounterB = 0; iCounterB < iTotalNumberOfTroops; iCounterB++ )
- {
- if( fZoomFlag )
- {
- // LARGE icon offset in the .sti
- iIconValue = 11;
- }
- else
- {
- // SMALL icon offset in the .sti
- iIconValue = 5;
- }
-
- // get the offset further into the .sti
- if( iCounterB < iNumberOfGreens )
- {
- iIconValue += 0;
- }
- else if( iCounterB < iNumberOfGreens + iNumberOfRegulars )
- {
- iIconValue += 1;
- }
- else
- {
- iIconValue += 2;
- }
-
- DrawMapBoxIcon(guiMilitia, iIconValue, sSectorX, sSectorY, iCounterB);
- }
- }
- }
- // restore clip blits
- RestoreClipRegionToFullScreen( );
-}
-
-
static void CheckAndUpdateStatesOfSelectedMilitiaSectorButtons(void)
{
// now set the militia map button text Save it as 'wild_militia.diff' at the top directory of stracciatella and run from there:
$ patch -p0 < wild_militia.diff
$ make
Report message to a moderator
|
|
|
|
|
|
|
|
|
Re: Patch: Garrison militia in wilderness[message #202882]
|
Mon, 01 December 2008 08:58
|
|
Tron |
  |
Messages:225
Registered:August 2007 Location: Germany |
|
|
Thanks for your effort to create this patch. Though, I have one major concern: It substantially changes the gameplay. In my opinion, this change is too extensive to include it unconditionally.
Further, there seems to be at least one other bug: If I load an existing savegame with the patch applied, there are sectors outside of towns, which contain militia. This should not be the case.
mgl* Right click on Estoni on the strategic screen with "show militia" on shows a town of the size of Balime or Omerta northwest of there.
There are two bugs there. First, the militia count indicator is displayed in the wrong sector. It should be one sector to the north. So there is not a town above Estoni, it is Estoni. This can be resolved easily:
Index: Build/Strategic/Map_Screen_Interface_Map.cc
===================================================================
--- Build/Strategic/Map_Screen_Interface_Map.cc (Revision 4836)
+++ Build/Strategic/Map_Screen_Interface_Map.cc (Arbeitskopie)
@@ -388,7 +388,7 @@
SECTOR( 8, 9 ), // Tixa
SECTOR( 8, 6 ), // Cambria
SECTOR( 4, 2 ), // San Mona
- SECTOR( 5, 8 ), // Estoni
+ SECTOR( 5, 9 ), // Estoni
SECTOR( 3,10 ), // Orta
SECTOR( 11,11 ), // Balime
SECTOR( 3,14 ), // Meduna
Second, there seemingly is a second sector (I5) belonging to Estoni. This is because the graphic is stale. Probably Estoni was supposed to be larger. You can see this in the demo version, too.
Report message to a moderator
|
Sergeant 1st Class
|
|
|
Goto Forum:
Current Time: Sat Jul 19 11:21:24 GMT+3 2025
Total time taken to generate the page: 0.00590 seconds
|