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 Go to next message
mgl is currently offline 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

Master Sergeant
Re: Patch: Garrison militia in wilderness[message #202673] Fri, 28 November 2008 00:23 Go to previous messageGo to next message
Headrock

 
Messages:1757
Registered:March 2006
Location: Jerusalem
... That's what 1.13 is for. Razz

Report message to a moderator

Sergeant Major

Re: Patch: Garrison militia in wilderness[message #202675] Fri, 28 November 2008 00:57 Go to previous messageGo to next message
mgl is currently offline mgl

 
Messages:255
Registered:December 2007
Location: France
I'll try something else then, next time.

Report message to a moderator

Master Sergeant
Re: Patch: Garrison militia in wilderness[message #202678] Fri, 28 November 2008 02:20 Go to previous messageGo to next message
InHuMan is currently offline InHuMan

 
Messages:43
Registered:November 2006
Location: Czech Republic
Headrock
... That's what 1.13 is for. Razz


Does 1.13 works everywhere, where GCC and SDL does? Wink

Report message to a moderator

Corporal
Re: Patch: Garrison militia in wilderness[message #202683] Fri, 28 November 2008 03:34 Go to previous messageGo to next message
Headrock

 
Messages:1757
Registered:March 2006
Location: Jerusalem
Good point.

Report message to a moderator

Sergeant Major

Re: Patch: Garrison militia in wilderness[message #202688] Fri, 28 November 2008 06:27 Go to previous messageGo to next message
Khor1255 is currently offline Khor1255

 
Messages:1815
Registered:August 2003
Location: Pleasantville, NJ
Not just that. Does 1.13 preserve anything useful? Like modding abilities?

Please, don't shit on this too.

Report message to a moderator

Sergeant Major
Re: Patch: Garrison militia in wilderness[message #202882] Mon, 01 December 2008 08:58 Go to previous message
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
Previous Topic: Bug: crash with helicopter in Estoni (r4823)
Next Topic: Patch: New IMP quiz
Goto Forum:
  


Current Time: Sat Jul 19 11:21:24 GMT+3 2025

Total time taken to generate the page: 0.00590 seconds