mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
New Feature: Improved ambushes have mercs face the enemy and be somewhat scattered, while the enemy encircles the player but is not at point-blank range.
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7846 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+7
-1
@@ -1149,7 +1149,13 @@ void LoadGameExternalOptions()
|
||||
// SANDRO - changed this so on any difficulty there is a chance to beambushed. Hoever this chance is calculated differently to not lead to instant load game like before
|
||||
gGameExternalOptions.fEnableChanceOfEnemyAmbushes = iniReader.ReadBoolean("Tactical Difficulty Settings", "ENABLE_CHANCE_OF_ENEMY_AMBUSHES", TRUE);
|
||||
gGameExternalOptions.bChanceModifierEnemyAmbushes = iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AMBUSHES_CHANCE_MODIFIER ", 0, -100, 100);
|
||||
|
||||
|
||||
gGameExternalOptions.fAmbushSpreadMercs = iniReader.ReadBoolean( "Tactical Difficulty Settings", "AMBUSH_MERCS_SPREAD", TRUE );
|
||||
gGameExternalOptions.usAmbushSpreadRadiusMercs = iniReader.ReadInteger( "Tactical Difficulty Settings", "AMBUSH_MERCS_SPREAD_RADIUS", 10, 1, 20 );
|
||||
gGameExternalOptions.uAmbushEnemyEncircle = iniReader.ReadInteger( "Tactical Difficulty Settings", "AMBUSH_ENEMY_ENCIRCLEMENT", 2, 0, 2 );
|
||||
gGameExternalOptions.usAmbushEnemyEncircleRadius1 = iniReader.ReadInteger( "Tactical Difficulty Settings", "AMBUSH_ENEMY_ENCIRCLEMENT_RADIUS1", 15, gGameExternalOptions.usAmbushSpreadRadiusMercs, 50 );
|
||||
gGameExternalOptions.usAmbushEnemyEncircleRadius2 = iniReader.ReadInteger( "Tactical Difficulty Settings", "AMBUSH_ENEMY_ENCIRCLEMENT_RADIUS2", 30, gGameExternalOptions.usAmbushEnemyEncircleRadius1, 100 );
|
||||
|
||||
// SANDRO - Special NPCs strength increased by percent
|
||||
gGameExternalOptions.usSpecialNPCStronger = iniReader.ReadInteger("Tactical Difficulty Settings", "SPECIAL_NPCS_STRONGER",0, 0, 200);
|
||||
|
||||
|
||||
@@ -349,8 +349,16 @@ typedef struct
|
||||
// changed/added these - SANDRO
|
||||
UINT8 sMercsAutoresolveOffenseBonus;
|
||||
UINT8 sMercsAutoresolveDeffenseBonus;
|
||||
|
||||
// Flugente: more ambush options
|
||||
BOOLEAN fEnableChanceOfEnemyAmbushes;
|
||||
INT8 bChanceModifierEnemyAmbushes;
|
||||
BOOLEAN fAmbushSpreadMercs;
|
||||
UINT16 usAmbushSpreadRadiusMercs;
|
||||
UINT8 uAmbushEnemyEncircle;
|
||||
UINT16 usAmbushEnemyEncircleRadius1;
|
||||
UINT16 usAmbushEnemyEncircleRadius2;
|
||||
|
||||
UINT8 usSpecialNPCStronger;
|
||||
|
||||
// Flugente: should kingpin's hitmen be disguised? This will make them have random clothes among other stuff
|
||||
|
||||
@@ -2625,7 +2625,7 @@ void PrepareLoadedSector()
|
||||
|
||||
if( gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE )
|
||||
{
|
||||
if( gMapInformation.sCenterGridNo != -1 )
|
||||
if( gMapInformation.sCenterGridNo != NOWHERE )
|
||||
{
|
||||
CallAvailableEnemiesTo( gMapInformation.sCenterGridNo );
|
||||
}
|
||||
@@ -3118,11 +3118,25 @@ void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
|
||||
{
|
||||
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
|
||||
{
|
||||
if( gMapInformation.sCenterGridNo != -1 && gfBlitBattleSectorLocator &&
|
||||
if( gMapInformation.sCenterGridNo != NOWHERE && gfBlitBattleSectorLocator &&
|
||||
(gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE) && pSoldier->bTeam != CIV_TEAM )
|
||||
{
|
||||
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
|
||||
pSoldier->usStrategicInsertionData = gMapInformation.sCenterGridNo;
|
||||
// Flugente: improved ambush
|
||||
if ( gGameExternalOptions.fAmbushSpreadMercs )
|
||||
{
|
||||
UINT8 ubDirection;
|
||||
|
||||
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
|
||||
pSoldier->usStrategicInsertionData = FindRandomGridNoFromSweetSpotExcludingSweetSpot( pSoldier, gMapInformation.sCenterGridNo, gGameExternalOptions.usAmbushSpreadRadiusMercs, &ubDirection );
|
||||
|
||||
// have the merc look outward. We add + 100 because later on we use this to signify that we want really enforce this direction
|
||||
pSoldier->ubInsertionDirection = (UINT8)GetDirectionToGridNoFromGridNo( gMapInformation.sCenterGridNo, pSoldier->usStrategicInsertionData ) + 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
|
||||
pSoldier->usStrategicInsertionData = gMapInformation.sCenterGridNo;
|
||||
}
|
||||
}
|
||||
else if( gfOverrideInsertionWithExitGrid )
|
||||
{
|
||||
|
||||
+65
-21
@@ -1044,30 +1044,26 @@ INT32 FindRandomGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo,
|
||||
|
||||
}
|
||||
|
||||
// Flugente: I've altered this function in two ways:
|
||||
// 1. The gridno is now drawn from the entirety of the circle - not just for sX and sY being positive
|
||||
// 2. The direction now points to sSweetGridNo, center of the circle, instead of the map center
|
||||
INT32 FindRandomGridNoFromSweetSpotExcludingSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection )
|
||||
{
|
||||
INT16 sX, sY;
|
||||
INT16 sX, sY;
|
||||
INT32 sGridNo = NOWHERE;
|
||||
INT32 leftmost;
|
||||
BOOLEAN fFound = FALSE;
|
||||
UINT32 cnt = 0;
|
||||
UINT32 cnt = 0;
|
||||
|
||||
do
|
||||
{
|
||||
sX = (UINT16)Random( ubRadius );
|
||||
sY = (UINT16)Random( ubRadius );
|
||||
|
||||
leftmost = ( ( sSweetGridNo + ( WORLD_COLS * sY ) )/ WORLD_COLS ) * WORLD_COLS;
|
||||
|
||||
sGridNo = sSweetGridNo + ( WORLD_COLS * sY ) + sX;
|
||||
|
||||
if ( sGridNo == sSweetGridNo )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sGridNo >=0 && sGridNo < WORLD_MAX &&
|
||||
sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) )
|
||||
sX = (UINT16)Random( 2 * ubRadius ) - ubRadius;
|
||||
sY = (UINT16)Random( 2 * ubRadius ) - ubRadius;
|
||||
|
||||
sGridNo = sSweetGridNo + (WORLD_COLS * sY ) + sX;
|
||||
|
||||
if ( sGridNo == sSweetGridNo || TileIsOutOfBounds( sGridNo ) || PythSpacesAway( sGridNo, sSweetGridNo ) >= ubRadius || !IsLocationSittable( sGridNo, 0 ) )
|
||||
sGridNo = NOWHERE;
|
||||
else
|
||||
{
|
||||
// Go on sweet stop
|
||||
if ( NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->pathing.bLevel ) )
|
||||
@@ -1076,20 +1072,68 @@ INT32 FindRandomGridNoFromSweetSpotExcludingSweetSpot( SOLDIERTYPE *pSoldier, IN
|
||||
}
|
||||
}
|
||||
|
||||
cnt++;
|
||||
++cnt;
|
||||
|
||||
if ( cnt > 2000 )
|
||||
{
|
||||
return( NOWHERE );
|
||||
}
|
||||
|
||||
} while( !fFound );
|
||||
|
||||
// Set direction to center of map!
|
||||
*pubDirection = (UINT8)GetDirectionToGridNoFromGridNo( sGridNo, ( ( ( WORLD_ROWS / 2 ) * WORLD_COLS ) + ( WORLD_COLS / 2 ) ) );
|
||||
*pubDirection = (UINT8)GetDirectionToGridNoFromGridNo( sGridNo, sSweetGridNo );
|
||||
|
||||
return( sGridNo );
|
||||
}
|
||||
|
||||
// Flugente: returns random gridno in a circle around sCenterGridNo with radius uOuterRadius that is not inside the circle with radius uInnerRadius
|
||||
INT32 FindRandomGridNoBetweenCircles( INT32 sCenterGridNo, UINT8 uInnerRadius, UINT8 uOuterRadius, UINT8& urDirection )
|
||||
{
|
||||
INT16 sX, sY;
|
||||
INT32 sGridNo = NOWHERE;
|
||||
BOOLEAN fFound = FALSE;
|
||||
UINT32 cnt = 0;
|
||||
|
||||
if ( uInnerRadius >= uOuterRadius )
|
||||
return NOWHERE;
|
||||
|
||||
do
|
||||
{
|
||||
/*sX = (UINT16)Random( 2 * (uOuterRadius - uInnerRadius) ) - (uOuterRadius - uInnerRadius);
|
||||
sY = (UINT16)Random( 2 * (uOuterRadius - uInnerRadius) ) - (uOuterRadius - uInnerRadius);
|
||||
|
||||
if ( sX > 0 )
|
||||
sX += uInnerRadius;
|
||||
else
|
||||
sX -= uInnerRadius;
|
||||
|
||||
if ( sY > 0 )
|
||||
sY += uInnerRadius;
|
||||
else
|
||||
sY -= uInnerRadius;*/
|
||||
|
||||
sX = (UINT16)Random( 2 * uOuterRadius ) - uOuterRadius;
|
||||
sY = (UINT16)Random( 2 * uOuterRadius ) - uOuterRadius;
|
||||
|
||||
sGridNo = sCenterGridNo + (WORLD_COLS * sY) + sX;
|
||||
|
||||
if ( TileIsOutOfBounds( sGridNo ) || !IsLocationSittable( sGridNo, 0 ) || PythSpacesAway( sGridNo, sCenterGridNo ) <= uInnerRadius || PythSpacesAway( sGridNo, sCenterGridNo ) > uOuterRadius )
|
||||
sGridNo = NOWHERE;
|
||||
else
|
||||
fFound = TRUE;
|
||||
|
||||
++cnt;
|
||||
|
||||
if ( cnt > 2000 )
|
||||
{
|
||||
return(NOWHERE);
|
||||
}
|
||||
} while ( !fFound );
|
||||
|
||||
// Set direction to center of map!
|
||||
urDirection = (UINT8)GetDirectionToGridNoFromGridNo( sGridNo, sCenterGridNo );
|
||||
|
||||
return(sGridNo);
|
||||
}
|
||||
|
||||
|
||||
@@ -1238,7 +1282,7 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO
|
||||
pSoldier->usSoldierFlagMask |= SOLDIER_ASSAULT_BONUS;
|
||||
|
||||
// Override calculated direction if we were told to....
|
||||
if ( pSoldier->ubInsertionDirection > 100 )
|
||||
if ( pSoldier->ubInsertionDirection >= 100 )
|
||||
{
|
||||
pSoldier->ubInsertionDirection = pSoldier->ubInsertionDirection - 100;
|
||||
fCalculateDirection = FALSE;
|
||||
|
||||
@@ -20,8 +20,13 @@ INT32 FindGridNoFromSweetSpotExcludingSweetSpotInQuardent( SOLDIERTYPE *pSoldier
|
||||
INT32 FindRandomGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection );
|
||||
|
||||
// Finds a sweetspot but excluding this one!
|
||||
// Flugente: I've altered this function in two ways:
|
||||
// 1. The gridno is now drawn from the entirety of the circle - not just for sX and sY being positive
|
||||
// 2. The direction now points to sSweetGridNo, center of the circle, instead of the map center
|
||||
INT32 FindRandomGridNoFromSweetSpotExcludingSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection );
|
||||
|
||||
// Flugente: returns random gridno in a circle around sCenterGridNo with radius uOuterRadius that is not inside the circle with radius uInnerRadius
|
||||
INT32 FindRandomGridNoBetweenCircles( INT32 sCenterGridNo, UINT8 uInnerRadius, UINT8 uOuterRadius, UINT8& urDirection );
|
||||
|
||||
// Adds a soldier ( already created in mercptrs[] array )!
|
||||
// Finds a good placement based on data in the loaded sector and if they are enemy's or not, etc...
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "Campaign.h" // added by Flugente for HighestPlayerProgressPercentage()
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "Town Militia.h" // added by Flugente
|
||||
#include "PreBattle Interface.h" // added by Flugente
|
||||
|
||||
BOOLEAN gfOriginalList = TRUE;
|
||||
|
||||
@@ -769,6 +770,33 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: set npcs to enemies"));
|
||||
OkayToUpgradeEliteToSpecialProfiledEnemy( &tempDetailedPlacement );
|
||||
}
|
||||
|
||||
// Flugente: if this is an enemy, and we are using ambush code, place us somewhat away from the map center, where the player will be
|
||||
if ( (tempDetailedPlacement.bTeam == ENEMY_TEAM && gubEnemyEncounterCode == ENEMY_AMBUSH_CODE) ||
|
||||
(tempDetailedPlacement.bTeam == CREATURE_TEAM && gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE) )
|
||||
{
|
||||
if ( ( gGameExternalOptions.uAmbushEnemyEncircle == 1 && PythSpacesAway( tempDetailedPlacement.sInsertionGridNo, gMapInformation.sCenterGridNo ) <= gGameExternalOptions.usAmbushEnemyEncircleRadius1 ) ||
|
||||
( gGameExternalOptions.uAmbushEnemyEncircle == 2) )
|
||||
{
|
||||
// we simply look for a entry point inside a bigger circle, but not inside the merc deployment zone.
|
||||
INT32 bettergridno = NOWHERE;
|
||||
UINT16 counter = 0;
|
||||
UINT8 ubDirection = DIRECTION_IRRELEVANT;
|
||||
|
||||
while ( counter < 100 && (bettergridno == NOWHERE || PythSpacesAway( bettergridno, gMapInformation.sCenterGridNo ) <= gGameExternalOptions.usAmbushEnemyEncircleRadius1) )
|
||||
{
|
||||
bettergridno = FindRandomGridNoBetweenCircles( gMapInformation.sCenterGridNo, gGameExternalOptions.usAmbushEnemyEncircleRadius1, gGameExternalOptions.usAmbushEnemyEncircleRadius2, ubDirection );
|
||||
}
|
||||
|
||||
if ( bettergridno != NOWHERE )
|
||||
{
|
||||
tempDetailedPlacement.sInsertionGridNo = bettergridno;
|
||||
|
||||
// have the soldier look inward. We add + 100 because later on we use this to signify that we want really enforce this direction
|
||||
tempDetailedPlacement.ubDirection = (UINT8)GetDirectionToGridNoFromGridNo( tempDetailedPlacement.sInsertionGridNo, gMapInformation.sCenterGridNo ) + 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: create soldier"));
|
||||
|
||||
Reference in New Issue
Block a user