Fix: Improved the fix for militia manning tanks in revision 7557. Tank slots are not made invalid anymore. Instead the placement body type will be converted to a normal militia body and moved to a free slot next to the tank. There is a new function "FindNearestPassableSpot" for finding an accessible tile next to a starting grid.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7588 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
silversurfer
2014-10-18 15:26:03 +00:00
parent e000abcc57
commit f05cdc3286
3 changed files with 56 additions and 8 deletions
+20 -8
View File
@@ -1476,13 +1476,6 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
if( curr->pBasicPlacement->bTeam == ENEMY_TEAM || curr->pBasicPlacement->bTeam == MILITIA_TEAM )
{
// silversurfer: Militia is not supposed to reuse tanks, especially enemy tanks that have been destroyed in combat.
// The player would get free tanks to drive around with. Not good...
// Set the SoldierClass to None so this spot is no longer considered. We do not want to put militia here because it could get stuck in the tank body.
if( curr->pDetailedPlacement )
if( curr->pDetailedPlacement->bBodyType == TANK_NE || curr->pDetailedPlacement->bBodyType == TANK_NW )
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_NONE;
//Matching team (kindof), now check the soldier class...
if( ubNumElites && curr->pBasicPlacement->ubSoldierClass == SOLDIER_CLASS_ELITE )
{
@@ -1507,6 +1500,16 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->bTeam = MILITIA_TEAM;
curr->pBasicPlacement->bOrders = STATIONARY;
curr->pBasicPlacement->bAttitude = (INT8) Random( MAXATTITUDES );
// silversurfer: Replace body type. Militia tanks are not allowed.
if( curr->pDetailedPlacement->bBodyType == TANK_NE || curr->pDetailedPlacement->bBodyType == TANK_NW
|| curr->pBasicPlacement->bBodyType == TANK_NE || curr->pBasicPlacement->bBodyType == TANK_NW )
{
curr->pBasicPlacement->bBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank
INT32 iNewSpot = FindNearestPassableSpot( curr->pBasicPlacement->usStartingGridNo );
if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot;
}
if( curr->pDetailedPlacement )
{ //delete the detailed placement information.
delete( curr->pDetailedPlacement );
@@ -1635,7 +1638,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr = gSoldierInitHead;
while( curr && ubFreeSlots && ubMaxNum )
{
if( !curr->pSoldier && (curr->pBasicPlacement->bTeam == ENEMY_TEAM || curr->pBasicPlacement->bTeam == MILITIA_TEAM) && curr->pBasicPlacement->ubSoldierClass != SOLDIER_CLASS_NONE )
if( !curr->pSoldier && (curr->pBasicPlacement->bTeam == ENEMY_TEAM || curr->pBasicPlacement->bTeam == MILITIA_TEAM) )
{
//Randomly determine if we will use this slot; the more available slots in proportion to
//the number of enemies, the lower the chance of accepting the slot.
@@ -1663,6 +1666,15 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->bTeam = MILITIA_TEAM;
curr->pBasicPlacement->bOrders = STATIONARY;
curr->pBasicPlacement->bAttitude = (INT8) Random( MAXATTITUDES );
// silversurfer: Replace body type. Militia tanks are not allowed.
if( curr->pBasicPlacement->bBodyType == TANK_NE || curr->pBasicPlacement->bBodyType == TANK_NW )
{
curr->pBasicPlacement->bBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank
INT32 iNewSpot = FindNearestPassableSpot( curr->pBasicPlacement->usStartingGridNo );
if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot;
}
if( curr->pDetailedPlacement )
{ //delete the detailed placement information.
delete( curr->pDetailedPlacement );
+35
View File
@@ -2907,5 +2907,40 @@ INT8 FindDirectionForClimbing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel
return DIRECTION_IRRELEVANT;
}
INT32 FindNearestPassableSpot( INT32 sGridNo, UINT8 usSearchRadius )
{
INT32 sNearestSpot = NOWHERE;
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
INT32 sTestGridNo;
INT32 iDist, iClosestDist = 10;
// determine maximum horizontal limits
sMaxLeft = min( usSearchRadius, (sGridNo % MAXCOL));
sMaxRight = min( usSearchRadius, MAXCOL - ((sGridNo % MAXCOL) + 1));
// determine maximum vertical limits
sMaxUp = min( usSearchRadius, (sGridNo / MAXROW));
sMaxDown = min( usSearchRadius, MAXROW - ((sGridNo / MAXROW) + 1));
// SET UP DOUBLE-LOOP TO STEP THROUGH POTENTIAL GRID #s
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
{
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
{
// calculate the next potential gridno
sTestGridNo = sGridNo + sXOffset + (MAXCOL * sYOffset);
// is this an empty tile (no structure on it) or is the structure passable?
if (gpWorldLevelData[sTestGridNo].pStructureHead == NULL || FindStructure( sTestGridNo, STRUCTURE_PASSABLE ) != NULL)
{
iDist = PythSpacesAway( sGridNo, sTestGridNo );
if (iDist < iClosestDist)
{
iClosestDist = iDist;
sNearestSpot = sTestGridNo;
}
}
}
}
return( sNearestSpot );
}
+1
View File
@@ -189,6 +189,7 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *pPercentBe
INT32 FindClosestDoor( SOLDIERTYPE * pSoldier );
INT32 FindNearbyPointOnEdgeOfMap( SOLDIERTYPE * pSoldier, INT8 * pbDirection );
INT32 FindNearestEdgePoint( INT32 sGridNo );
INT32 FindNearestPassableSpot( INT32 sGridNo, UINT8 usSearchRadius = 5 );
//Kris: Added these as I need specific searches on certain sides.
enum