mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added missing #includes Added LUA scripting and console Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain Fixed signedness of many grid variables used in GetMouseMapPos calls Fixed enemy weapon choosing: Sometimes a mortar is chosen but later rejected, but the grenade class was not reset. Caused assertion failure Added checks so enemies don't try to chuck RPG grenades with their hands Now possible to shoot a someone in the head if he's in water Fixed InitSightArrays to also clear soldier interrupt duel points. This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called. Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have Removed early setting of muzzle flash. This would allow enemies to get an interrupt before you even fired. Fixed item dropping by AI. If AI tried to drop something while standing it would cause deadlock Change to greatly speed up closing the sector inventory window in an unloaded sector Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting Check builddefines.h for the conditional flags. Of greatest interest might be LUA_CONSOLE. This will cause the game to bring up a command console when run. However this console is severely lacking in many areas. If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated. The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus. LUA scripting is very limited, basically just proof of concept. There is one global variable, the Soldiers array. An array index gives you the soldier in that slot in the currently loaded sector. The soldier has a few things that can be accessed: name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1079 lines
29 KiB
C++
1079 lines
29 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "AI All.h"
|
|
#include "DisplayCover.h"
|
|
#include "Interface.h"
|
|
#include "opplist.h"
|
|
#include "_Ja25Englishtext.h"
|
|
//#include "Ja25 Strategic Ai.h"
|
|
#else
|
|
#include "builddefines.h"
|
|
#include "Types.h"
|
|
#include "Isometric Utils.h"
|
|
#include "Soldier Control.h"
|
|
#include "Overhead.h"
|
|
#include "displaycover.h"
|
|
#include "Font Control.h"
|
|
#include "_Ja25EnglishText.h"
|
|
#include "message.h"
|
|
#include "GameSettings.h"
|
|
#include "renderworld.h"
|
|
#include "Interface.h"
|
|
#include "Debug.h"
|
|
#include "PATHAI.H"
|
|
#include "worldman.h"
|
|
#include "opplist.h"
|
|
#include "los.h"
|
|
#include "weapons.h"
|
|
#include "Game Clock.h"
|
|
#include "Animation Control.h"
|
|
#include "lighting.h"
|
|
#include "Text.h"
|
|
#include "strategicmap.h"
|
|
#include "Render Fun.h"
|
|
#endif
|
|
|
|
//******* Local Defines **************************************************
|
|
|
|
|
|
#define DC_MAX_COVER_RANGE 42 //31
|
|
#define DC__SOLDIER_VISIBLE_RANGE 42 //31
|
|
|
|
#define DC__MIN_SIZE 4
|
|
#define DC__MAX_SIZE 21 //11
|
|
|
|
typedef struct
|
|
{
|
|
INT16 sGridNo;
|
|
INT8 bCover; //% chance that the gridno is fully covered. ie 100 if safe, 0 is has no cover
|
|
// BOOLEAN fRoof;
|
|
} BEST_COVER_STRUCT;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
INT16 sGridNo;
|
|
INT8 bVisibleToSoldier;
|
|
BOOLEAN fRoof;
|
|
} VISIBLE_TO_SOLDIER_STRUCT;
|
|
|
|
|
|
/*
|
|
#define DC__PRONE (INT8)( 0x01 )
|
|
#define DC__CROUCH (INT8)( 0x02 )
|
|
#define DC__STAND (INT8)( 0x04 )
|
|
*/
|
|
enum
|
|
{
|
|
DC__SEE_NO_STANCES,
|
|
DC__SEE_1_STANCE,
|
|
DC__SEE_2_STANCE,
|
|
DC__SEE_3_STANCE,
|
|
};
|
|
|
|
//****** Global Variables *****************************************
|
|
|
|
|
|
BEST_COVER_STRUCT gCoverRadius[ DC_MAX_COVER_RANGE ][ DC_MAX_COVER_RANGE ];
|
|
INT16 gsLastCoverGridNo=NOWHERE;
|
|
INT16 gsLastSoldierGridNo=NOWHERE;
|
|
INT8 gbLastStance=-1;
|
|
|
|
|
|
VISIBLE_TO_SOLDIER_STRUCT gVisibleToSoldierStruct[ DC__SOLDIER_VISIBLE_RANGE ][ DC__SOLDIER_VISIBLE_RANGE ];
|
|
INT16 gsLastVisibleToSoldierGridNo=NOWHERE;
|
|
|
|
//******* Function Prototypes ***************************************
|
|
|
|
INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTargetGridno, INT8 bStance );
|
|
void CalculateCoverInRadiusAroundGridno( INT16 sTargetGridNo, INT8 bSearchRange );
|
|
void AddCoverTileToEachGridNo();
|
|
void AddCoverObjectToWorld( INT16 sGridNo, UINT16 usGraphic, BOOLEAN fRoof );
|
|
void RemoveCoverObjectFromWorld( INT16 sGridNo, UINT16 usGraphic, BOOLEAN fRoof );
|
|
INT8 GetCurrentMercForDisplayCoverStance();
|
|
SOLDIERTYPE *GetCurrentMercForDisplayCover();
|
|
|
|
void CalculateVisibleToSoldierAroundGridno( INT16 sGridNo, INT8 bSearchRange );
|
|
void AddVisibleToSoldierToEachGridNo();
|
|
INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOLEAN fRoof );
|
|
BOOLEAN IsTheRoofVisible( INT16 sGridNo );
|
|
|
|
//ppp
|
|
|
|
//******* Functions **************************************************
|
|
|
|
|
|
void DisplayCoverOfSelectedGridNo( )
|
|
{
|
|
UINT16 usGridNo;
|
|
INT8 bStance;
|
|
|
|
GetMouseMapPos( &usGridNo );
|
|
|
|
//Only allowed in if there is someone selected
|
|
if( gusSelectedSoldier == NOBODY )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//if the cursor is in a the tactical map
|
|
if( usGridNo != NOWHERE && usGridNo != 0 )
|
|
{
|
|
bStance = GetCurrentMercForDisplayCoverStance();
|
|
|
|
//if the gridno is different then the last one that was displayed
|
|
if( usGridNo != gsLastCoverGridNo ||
|
|
gbLastStance != bStance ||
|
|
MercPtrs[ gusSelectedSoldier ]->sGridNo != gsLastSoldierGridNo )
|
|
{
|
|
//if the cover is currently being displayed
|
|
if( gsLastCoverGridNo != NOWHERE || gbLastStance != -1 || gsLastSoldierGridNo != NOWHERE )
|
|
{
|
|
//remove the gridnos
|
|
RemoveCoverOfSelectedGridNo();
|
|
}
|
|
else
|
|
{
|
|
//if it is the first time in here
|
|
|
|
//pop up a message to say we are in the display cover routine
|
|
#ifdef JA2TESTVERSION
|
|
{
|
|
CHAR16 zString[512];
|
|
swprintf( zString, L"%s, (%d)", zNewTacticalMessages[ TCTL_MSG__DISPLAY_COVER ], gGameSettings.ubSizeOfDisplayCover );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zString );
|
|
}
|
|
#else
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zNewTacticalMessages[ TCTL_MSG__DISPLAY_COVER ] );
|
|
#endif
|
|
|
|
//increment the display cover counter ( just seeing how many times people use it )
|
|
//gJa25SaveStruct.uiDisplayCoverCounter++;
|
|
}
|
|
|
|
gbLastStance = bStance;
|
|
gsLastCoverGridNo = usGridNo;
|
|
gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo;
|
|
|
|
//Fill the array of gridno and cover values
|
|
CalculateCoverInRadiusAroundGridno( usGridNo, gGameSettings.ubSizeOfDisplayCover );
|
|
|
|
//Add the graphics to each gridno
|
|
AddCoverTileToEachGridNo();
|
|
|
|
// Re-render the scene!
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddCoverTileToEachGridNo()
|
|
{
|
|
UINT32 uiCntX, uiCntY;
|
|
BOOLEAN fRoof = ( gsInterfaceLevel != I_GROUND_LEVEL );
|
|
|
|
|
|
//loop through all the gridnos
|
|
for(uiCntY=0; uiCntY<DC_MAX_COVER_RANGE ;uiCntY++)
|
|
{
|
|
for(uiCntX=0; uiCntX<DC_MAX_COVER_RANGE ;uiCntX++)
|
|
{
|
|
//if there is a valid cover at this gridno
|
|
if( gCoverRadius[ uiCntX ][ uiCntY ].bCover != -1 )
|
|
{
|
|
//if the tile provides 80-100% cover
|
|
if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 100 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 80 )
|
|
{
|
|
AddCoverObjectToWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_5, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 60-80% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 80 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 60 )
|
|
{
|
|
AddCoverObjectToWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_4, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 40-60% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 60 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 40 )
|
|
{
|
|
AddCoverObjectToWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_3, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 20-40% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 40 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 20 )
|
|
{
|
|
AddCoverObjectToWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_2, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 0-20% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 20 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover >= 0 )
|
|
{
|
|
AddCoverObjectToWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_1, fRoof );
|
|
}
|
|
|
|
//should never get in here
|
|
else
|
|
{
|
|
Assert( 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void RemoveCoverOfSelectedGridNo()
|
|
{
|
|
UINT32 uiCntX, uiCntY;
|
|
BOOLEAN fRoof = ( gsInterfaceLevel != I_GROUND_LEVEL );
|
|
|
|
|
|
if( gsLastCoverGridNo == NOWHERE )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//loop through all the gridnos
|
|
for(uiCntY=0; uiCntY<DC_MAX_COVER_RANGE ;uiCntY++)
|
|
{
|
|
for(uiCntX=0; uiCntX<DC_MAX_COVER_RANGE ;uiCntX++)
|
|
{
|
|
//if there is a valid cover at this gridno
|
|
if( gCoverRadius[ uiCntX ][ uiCntY ].bCover != -1 )
|
|
{
|
|
// fRoof = gCoverRadius[ uiCntX ][ uiCntY ].fRoof;
|
|
|
|
//if the tile provides 80-100% cover
|
|
if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 100 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 80 )
|
|
{
|
|
RemoveCoverObjectFromWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_5, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 60-80% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 80 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 60 )
|
|
{
|
|
RemoveCoverObjectFromWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_4, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 40-60% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 60 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 40 )
|
|
{
|
|
RemoveCoverObjectFromWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_3, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 20-40% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 40 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover > 20 )
|
|
{
|
|
RemoveCoverObjectFromWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_2, fRoof );
|
|
}
|
|
|
|
//else if the tile provides 0-20% cover
|
|
else if( gCoverRadius[ uiCntX ][ uiCntY ].bCover <= 20 &&
|
|
gCoverRadius[ uiCntX ][ uiCntY ].bCover >= 0 )
|
|
{
|
|
RemoveCoverObjectFromWorld( gCoverRadius[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_1, fRoof );
|
|
}
|
|
|
|
//should never get in here
|
|
else
|
|
{
|
|
Assert( 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Re-render the scene!
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
|
|
gsLastCoverGridNo = NOWHERE;
|
|
gbLastStance = -1;
|
|
gsLastSoldierGridNo = NOWHERE;
|
|
}
|
|
|
|
|
|
void CalculateCoverInRadiusAroundGridno( INT16 sTargetGridNo, INT8 bSearchRange )
|
|
{
|
|
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
|
|
SOLDIERTYPE *pSoldier=NULL;
|
|
INT16 sGridNo;
|
|
INT16 sCounterX, sCounterY;
|
|
UINT8 ubID;
|
|
INT8 bStance;
|
|
// BOOLEAN fRoof;
|
|
|
|
//clear out the array first
|
|
// memset( gCoverRadius, -1, DC_MAX_COVER_RANGE * DC_MAX_COVER_RANGE );
|
|
//loop through all the gridnos that we are interested in
|
|
for (sCounterY = 0; sCounterY < DC_MAX_COVER_RANGE; sCounterY++)
|
|
{
|
|
for (sCounterX = 0; sCounterX < DC_MAX_COVER_RANGE; sCounterX++)
|
|
{
|
|
gCoverRadius[ sCounterX ][ sCounterY ].sGridNo = -1;
|
|
gCoverRadius[ sCounterX ][ sCounterY ].bCover = -1;
|
|
}
|
|
}
|
|
|
|
if( bSearchRange > ( DC_MAX_COVER_RANGE / 2 ) )
|
|
bSearchRange = ( DC_MAX_COVER_RANGE / 2 );
|
|
|
|
// determine maximum horizontal limits
|
|
sMaxLeft = min( bSearchRange,( sTargetGridNo % MAXCOL ));
|
|
sMaxRight = min( bSearchRange,MAXCOL - (( sTargetGridNo % MAXCOL ) + 1));
|
|
|
|
// determine maximum vertical limits
|
|
sMaxUp = min( bSearchRange,( sTargetGridNo / MAXROW ));
|
|
sMaxDown = min( bSearchRange,MAXROW - (( sTargetGridNo / MAXROW ) + 1));
|
|
|
|
|
|
//Find out which tiles around the location are reachable
|
|
LocalReachableTest( sTargetGridNo, bSearchRange );
|
|
|
|
pSoldier = GetCurrentMercForDisplayCover();
|
|
|
|
sCounterX = sCounterY = 0;
|
|
|
|
//Determine the stance to use
|
|
bStance = GetCurrentMercForDisplayCoverStance();
|
|
|
|
//loop through all the gridnos that we are interested in
|
|
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
|
|
{
|
|
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
|
|
{
|
|
sGridNo = sTargetGridNo + sXOffset + (MAXCOL * sYOffset);
|
|
|
|
//record the gridno
|
|
gCoverRadius[ sCounterX ][ sCounterY ].sGridNo = sGridNo;
|
|
|
|
/*
|
|
fRoof = FALSE;
|
|
|
|
//is there a roof above this gridno
|
|
if( FlatRoofAboveGridNo( sGridNo ) )
|
|
{
|
|
if( IsTheRoofVisible( sGridNo ) )
|
|
{
|
|
fRoof = TRUE;
|
|
}
|
|
}
|
|
*/
|
|
//if the gridno is NOT on screen
|
|
if( !GridNoOnScreen( sGridNo ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//if we are to display cover for the roofs, and there is a roof above us
|
|
if( gsInterfaceLevel == I_ROOF_LEVEL && !FlatRoofAboveGridNo( sGridNo ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//if the gridno cant be reached
|
|
if ( !(gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_REACHABLE) )
|
|
{
|
|
//skip to the next gridno
|
|
sCounterX++;
|
|
continue;
|
|
}
|
|
|
|
// if someone (visible) is there, skip
|
|
//Check both bottom level, and top level
|
|
ubID = WhoIsThere2( sGridNo, 0 );
|
|
if( ubID == NOBODY )
|
|
{
|
|
ubID = WhoIsThere2( sGridNo, 1 );
|
|
}
|
|
//if someone is here, and they are an enemy, skip over them
|
|
if ( ubID != NOBODY && Menptr[ ubID ].bVisible == TRUE && Menptr[ ubID ].bTeam != pSoldier->bTeam )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//Calculate the cover for this gridno
|
|
gCoverRadius[ sCounterX ][ sCounterY ].bCover = CalcCoverForGridNoBasedOnTeamKnownEnemies( pSoldier, sGridNo, bStance );
|
|
// gCoverRadius[ sCounterX ][ sCounterY ].fRoof = fRoof;
|
|
|
|
|
|
sCounterX++;
|
|
}
|
|
sCounterY++;
|
|
sCounterX = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, INT8 bStance )
|
|
{
|
|
INT32 iTotalCoverPoints=0;
|
|
INT8 bNumEnemies=0;
|
|
INT8 bPercentCoverForGridno=0;
|
|
UINT32 uiLoop;
|
|
SOLDIERTYPE *pOpponent;
|
|
INT8 *pbPersOL;
|
|
INT8 *pbPublOL;
|
|
INT32 iGetThrough=0;
|
|
INT32 iBulletGetThrough=0;
|
|
INT32 iHighestValue=0;
|
|
INT32 iCover=0;
|
|
UINT16 usMaxRange;
|
|
UINT16 usRange;
|
|
UINT16 usSightLimit;
|
|
|
|
//loop through all the enemies and determine the cover
|
|
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
|
{
|
|
pOpponent = MercSlots[ uiLoop ];
|
|
|
|
// if this merc is inactive, at base, on assignment, dead, unconscious
|
|
if (!pOpponent || pOpponent->bLife < OKLIFE)
|
|
{
|
|
continue; // next merc
|
|
}
|
|
|
|
// if this man is neutral / on the same side, he's not an opponent
|
|
if( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide))
|
|
{
|
|
continue; // next merc
|
|
}
|
|
|
|
pbPersOL = pSoldier->bOppList + pOpponent->ubID;
|
|
pbPublOL = gbPublicOpplist[ OUR_TEAM ] + pOpponent->ubID;
|
|
|
|
// if this opponent is unknown personally and publicly
|
|
if( *pbPersOL != SEEN_CURRENTLY &&
|
|
*pbPersOL != SEEN_THIS_TURN &&
|
|
*pbPublOL != SEEN_CURRENTLY &&
|
|
*pbPublOL != SEEN_THIS_TURN )
|
|
{
|
|
continue; // next merc
|
|
}
|
|
|
|
usRange = (UINT16)GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, sTargetGridNo );
|
|
// Lesh: changed 2-nd parameter in DistanceVisible function call
|
|
usSightLimit = DistanceVisible( pOpponent, (SoldierHasLimitedVision(pOpponent) ? pOpponent->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sTargetGridNo, pSoldier->bLevel, pSoldier );
|
|
|
|
|
|
if( usRange > ( usSightLimit * CELL_X_SIZE ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// if actual LOS check fails, then chance to hit is 0, ignore this guy
|
|
if( SoldierToVirtualSoldierLineOfSightTest( pOpponent, sTargetGridNo, pSoldier->bLevel, bStance, (UINT8)usSightLimit, TRUE ) == 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
iGetThrough = SoldierToLocationChanceToGetThrough( pOpponent, sTargetGridNo, pSoldier->bLevel, bStance, NOBODY );
|
|
// iBulletGetThrough = CalcChanceToHitGun( pOpponent, sTargetGridNo, AP_MAX_AIM_ATTACK, AIM_SHOT_TORSO );
|
|
|
|
if( WeaponInHand( pOpponent ) )
|
|
{
|
|
usMaxRange = GunRange( &pOpponent->inv[ HANDPOS ] );
|
|
}
|
|
else
|
|
{
|
|
usMaxRange = Weapon[ GLOCK_18 ].usRange;
|
|
}
|
|
|
|
iBulletGetThrough = __min( __max( (INT32)( ( ( ( ( usMaxRange - usRange ) / (FLOAT)( usMaxRange ) ) + .3 ) * 100 ) ), 0 ), 100 );
|
|
|
|
if( iBulletGetThrough > 5 && iGetThrough > 0 )
|
|
{
|
|
iCover = (iGetThrough * iBulletGetThrough / 100);
|
|
|
|
if( iCover > iHighestValue )
|
|
iHighestValue = iCover;
|
|
|
|
iTotalCoverPoints += iCover;
|
|
bNumEnemies++;
|
|
}
|
|
}
|
|
|
|
if( bNumEnemies == 0 )
|
|
{
|
|
bPercentCoverForGridno = 100;
|
|
}
|
|
else
|
|
{
|
|
INT32 iTemp;
|
|
|
|
bPercentCoverForGridno = ( iTotalCoverPoints / bNumEnemies );
|
|
|
|
iTemp = bPercentCoverForGridno - ( iHighestValue / bNumEnemies );
|
|
|
|
iTemp = iTemp + iHighestValue;
|
|
|
|
bPercentCoverForGridno = 100 - ( __min( iTemp, 100 ) );
|
|
}
|
|
|
|
|
|
return( bPercentCoverForGridno );
|
|
}
|
|
|
|
|
|
void AddCoverObjectToWorld( INT16 sGridNo, UINT16 usGraphic, BOOLEAN fRoof )
|
|
{
|
|
LEVELNODE *pNode;
|
|
|
|
if( fRoof )
|
|
{
|
|
AddOnRoofToHead( sGridNo, usGraphic );
|
|
pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
|
|
}
|
|
else
|
|
{
|
|
AddObjectToHead( sGridNo, usGraphic );
|
|
pNode = gpWorldLevelData[ sGridNo ].pObjectHead;
|
|
}
|
|
|
|
|
|
pNode->uiFlags |= LEVELNODE_REVEAL;
|
|
|
|
if( NightTime() )
|
|
{
|
|
pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
}
|
|
|
|
void RemoveCoverObjectFromWorld( INT16 sGridNo, UINT16 usGraphic, BOOLEAN fRoof )
|
|
{
|
|
if( fRoof )
|
|
{
|
|
RemoveOnRoof( sGridNo, usGraphic );
|
|
}
|
|
else
|
|
{
|
|
RemoveObject( sGridNo, usGraphic );
|
|
}
|
|
}
|
|
|
|
SOLDIERTYPE *GetCurrentMercForDisplayCover()
|
|
{
|
|
SOLDIERTYPE *pSoldier=NULL;
|
|
//Get a soldier that is on the player team
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
}
|
|
else
|
|
{
|
|
Assert( 0 );
|
|
}
|
|
return( pSoldier );
|
|
}
|
|
|
|
INT8 GetCurrentMercForDisplayCoverStance()
|
|
{
|
|
INT8 bStance;
|
|
SOLDIERTYPE *pSoldier = NULL;
|
|
|
|
pSoldier = GetCurrentMercForDisplayCover();
|
|
|
|
switch( pSoldier->usUIMovementMode )
|
|
{
|
|
case PRONE:
|
|
case CRAWLING:
|
|
bStance = ANIM_PRONE;
|
|
break;
|
|
|
|
case KNEEL_DOWN:
|
|
case SWATTING:
|
|
case CROUCHING:
|
|
bStance = ANIM_CROUCH;
|
|
break;
|
|
|
|
case WALKING:
|
|
case RUNNING:
|
|
case STANDING:
|
|
bStance = ANIM_STAND;
|
|
break;
|
|
|
|
default:
|
|
bStance = ANIM_CROUCH;
|
|
break;
|
|
}
|
|
|
|
return( bStance );
|
|
}
|
|
|
|
|
|
void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo )
|
|
{
|
|
UINT16 usRange=0;
|
|
CHAR16 zOutputString[512];
|
|
|
|
if( sTargetGridNo == NOWHERE || sTargetGridNo == 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Get the range to the target location
|
|
usRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sTargetGridNo );
|
|
|
|
usRange = usRange / 10;
|
|
|
|
// Snap: get target brightness:
|
|
UINT8 bLightLevel = LightTrueLevel(sTargetGridNo, gsInterfaceLevel);
|
|
|
|
//display a string with the range to target and target brightness (Snap)
|
|
swprintf( zOutputString, zNewTacticalMessages[ TCTL_MSG__RANGE_TO_TARGET ], usRange, SHADE_MIN - bLightLevel, SHADE_MIN );
|
|
|
|
//Display the msg
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
|
|
|
|
//if the soldier has a weapon in hand, display gun range and chance to hit
|
|
if( WeaponInHand( pSoldier ) )
|
|
{
|
|
UINT32 uiHitChance;
|
|
//AXP 30.03.2007: Fix CtH calculation for first shot after changing aim level (roof/ground)
|
|
INT8 bTempTargetLevel = pSoldier->bTargetLevel;
|
|
pSoldier->bTargetLevel = (INT8)gsInterfaceLevel;
|
|
uiHitChance = CalcChanceToHitGun( pSoldier, sTargetGridNo, (INT8)(pSoldier->bShownAimTime ), pSoldier->bAimShotLocation );
|
|
pSoldier->bTargetLevel = bTempTargetLevel;
|
|
|
|
swprintf( zOutputString, zNewTacticalMessages[ TCTL_MSG__GUN_RANGE_AND_CTH ], Weapon[ pSoldier->inv[HANDPOS].usItem ].usRange / 10, uiHitChance );
|
|
|
|
//Display the msg
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
|
|
}
|
|
|
|
|
|
//if the target is out of the mercs gun range or knife
|
|
if( !InRange( pSoldier, sTargetGridNo ) &&
|
|
( Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN || Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_THROWING_KNIFE ) )
|
|
{
|
|
// Display a warning saying so
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ OUT_OF_RANGE_STRING ] );
|
|
}
|
|
|
|
//increment the display gun range counter ( just seeing how many times people use it )
|
|
//gJa25SaveStruct.uiDisplayGunRangeCounter++;
|
|
}
|
|
|
|
|
|
|
|
void DisplayGridNoVisibleToSoldierGrid( )
|
|
{
|
|
UINT16 usGridNo;
|
|
// INT8 bStance;
|
|
|
|
GetMouseMapPos( &usGridNo );
|
|
|
|
//Only allowed in if there is someone selected
|
|
if( gusSelectedSoldier == NOBODY )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//if the cursor is in a the tactical map
|
|
if( usGridNo != NOWHERE && usGridNo != 0 )
|
|
{
|
|
//if the gridno is different then the last one that was displayed
|
|
if( usGridNo != gsLastVisibleToSoldierGridNo || MercPtrs[ gusSelectedSoldier ]->sGridNo != gsLastSoldierGridNo )
|
|
{
|
|
//if the cover is currently being displayed
|
|
if( gsLastVisibleToSoldierGridNo != NOWHERE || gsLastSoldierGridNo != NOWHERE )
|
|
{
|
|
//remove the gridnos
|
|
RemoveVisibleGridNoAtSelectedGridNo();
|
|
}
|
|
else
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
{
|
|
CHAR16 zString[512];
|
|
swprintf( zString, L"%s, (%d)", zNewTacticalMessages[ TCTL_MSG__LOS ], gGameSettings.ubSizeOfLOS );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zString );
|
|
}
|
|
#else
|
|
//pop up a message to say we are in the display cover routine
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zNewTacticalMessages[ TCTL_MSG__LOS ] );
|
|
#endif
|
|
//increment the display LOS counter ( just seeing how many times people use it )
|
|
//gJa25SaveStruct.uiDisplayLosCounter++;
|
|
}
|
|
|
|
gsLastVisibleToSoldierGridNo = usGridNo;
|
|
gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo;
|
|
|
|
|
|
//Fill the array of gridno and cover values
|
|
CalculateVisibleToSoldierAroundGridno( usGridNo, gGameSettings.ubSizeOfLOS );
|
|
|
|
//Add the graphics to each gridno
|
|
AddVisibleToSoldierToEachGridNo();
|
|
|
|
// Re-render the scene!
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CalculateVisibleToSoldierAroundGridno( INT16 sTargetGridNo, INT8 bSearchRange )
|
|
{
|
|
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
|
|
SOLDIERTYPE *pSoldier=NULL;
|
|
INT16 sGridNo;
|
|
INT16 sCounterX, sCounterY;
|
|
BOOLEAN fRoof=FALSE;
|
|
|
|
//clear out the struct
|
|
memset( gVisibleToSoldierStruct, 0, sizeof( VISIBLE_TO_SOLDIER_STRUCT ) * DC__SOLDIER_VISIBLE_RANGE * DC__SOLDIER_VISIBLE_RANGE );
|
|
|
|
if( bSearchRange > ( DC_MAX_COVER_RANGE / 2 ) )
|
|
bSearchRange = ( DC_MAX_COVER_RANGE / 2 );
|
|
|
|
|
|
// determine maximum horizontal limits
|
|
sMaxLeft = min( bSearchRange,( sTargetGridNo % MAXCOL ));
|
|
sMaxRight = min( bSearchRange,MAXCOL - (( sTargetGridNo % MAXCOL ) + 1));
|
|
|
|
// determine maximum vertical limits
|
|
sMaxUp = min( bSearchRange,( sTargetGridNo / MAXROW ));
|
|
sMaxDown = min( bSearchRange,MAXROW - (( sTargetGridNo / MAXROW ) + 1));
|
|
|
|
pSoldier = GetCurrentMercForDisplayCover();
|
|
|
|
sCounterX=0;
|
|
sCounterY=0;
|
|
|
|
//loop through all the gridnos that we are interested in
|
|
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
|
|
{
|
|
sCounterX = 0;
|
|
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
|
|
{
|
|
sGridNo = sTargetGridNo + sXOffset + (MAXCOL * sYOffset);
|
|
fRoof = FALSE;
|
|
|
|
//record the gridno
|
|
gVisibleToSoldierStruct[ sCounterX ][ sCounterY ].sGridNo = sGridNo;
|
|
|
|
//if the gridno is NOT on screen
|
|
if( !GridNoOnScreen( sGridNo ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//is there a roof above this gridno
|
|
if( FlatRoofAboveGridNo( sGridNo ) )
|
|
{
|
|
if( IsTheRoofVisible( sGridNo ) && gbWorldSectorZ == 0 )
|
|
{
|
|
fRoof = TRUE;
|
|
}
|
|
|
|
//if wer havent explored the area yet and we are underground, dont show cover
|
|
else if( !( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && gbWorldSectorZ != 0 )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/*
|
|
//if we are to display cover for the roofs, and there is a roof above us
|
|
if( gsInterfaceLevel == I_ROOF_LEVEL && !FlatRoofAboveGridNo( sGridNo ) )
|
|
{
|
|
continue;
|
|
}
|
|
*/
|
|
/*
|
|
// if someone (visible) is there, skip
|
|
//Check both bottom level, and top level
|
|
ubID = WhoIsThere2( sGridNo, 0 );
|
|
if( ubID == NOBODY )
|
|
{
|
|
ubID = WhoIsThere2( sGridNo, 1 );
|
|
}
|
|
//if someone is here, and they are an enemy, skip over them
|
|
if ( ubID != NOBODY && Menptr[ ubID ].bVisible == TRUE && Menptr[ ubID ].bTeam != pSoldier->bTeam )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//Calculate the cover for this gridno
|
|
gCoverRadius[ sCounterX ][ sCounterY ].bCover = CalcCoverForGridNoBasedOnTeamKnownEnemies( pSoldier, sGridNo, bStance );
|
|
*/
|
|
|
|
gVisibleToSoldierStruct[ sCounterX ][ sCounterY ].bVisibleToSoldier = CalcIfSoldierCanSeeGridNo( pSoldier, sGridNo, fRoof );
|
|
gVisibleToSoldierStruct[ sCounterX ][ sCounterY ].fRoof = fRoof;
|
|
sCounterX++;
|
|
}
|
|
|
|
sCounterY++;
|
|
}
|
|
}
|
|
|
|
|
|
void AddVisibleToSoldierToEachGridNo()
|
|
{
|
|
UINT32 uiCntX, uiCntY;
|
|
INT8 bVisibleToSoldier=0;
|
|
BOOLEAN fRoof;
|
|
INT16 sGridNo;
|
|
|
|
//loop through all the gridnos
|
|
for(uiCntY=0; uiCntY<DC_MAX_COVER_RANGE ;uiCntY++)
|
|
{
|
|
for(uiCntX=0; uiCntX<DC_MAX_COVER_RANGE ;uiCntX++)
|
|
{
|
|
bVisibleToSoldier = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].bVisibleToSoldier;
|
|
if( bVisibleToSoldier == -1 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
fRoof = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].fRoof;
|
|
sGridNo = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo;
|
|
|
|
//if the soldier can easily see this gridno. Can see all 3 positions
|
|
if( bVisibleToSoldier == DC__SEE_3_STANCE )
|
|
{
|
|
AddCoverObjectToWorld( sGridNo, SPECIALTILE_COVER_5, fRoof );
|
|
}
|
|
|
|
//cant see a thing
|
|
else if( bVisibleToSoldier == DC__SEE_NO_STANCES )
|
|
{
|
|
AddCoverObjectToWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_1, fRoof );
|
|
}
|
|
|
|
//can only see prone
|
|
else if( bVisibleToSoldier == DC__SEE_1_STANCE )
|
|
{
|
|
AddCoverObjectToWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_2, fRoof );
|
|
}
|
|
|
|
//can see crouch or prone
|
|
else if( bVisibleToSoldier == DC__SEE_2_STANCE )
|
|
{
|
|
AddCoverObjectToWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_3, fRoof );
|
|
}
|
|
|
|
else
|
|
{
|
|
Assert( 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void RemoveVisibleGridNoAtSelectedGridNo()
|
|
{
|
|
UINT32 uiCntX, uiCntY;
|
|
INT8 bVisibleToSoldier;
|
|
INT16 sGridNo;
|
|
BOOLEAN fRoof;
|
|
|
|
//make sure to only remove it when its right
|
|
if( gsLastVisibleToSoldierGridNo == NOWHERE )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//loop through all the gridnos
|
|
for(uiCntY=0; uiCntY<DC_MAX_COVER_RANGE ;uiCntY++)
|
|
{
|
|
for(uiCntX=0; uiCntX<DC_MAX_COVER_RANGE ;uiCntX++)
|
|
{
|
|
bVisibleToSoldier = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].bVisibleToSoldier;
|
|
fRoof = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].fRoof;
|
|
sGridNo = gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo;
|
|
|
|
//if there is a valid cover at this gridno
|
|
if( bVisibleToSoldier == DC__SEE_3_STANCE )
|
|
{
|
|
RemoveCoverObjectFromWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_5, fRoof );
|
|
}
|
|
|
|
//cant see a thing
|
|
else if( bVisibleToSoldier == DC__SEE_NO_STANCES )
|
|
{
|
|
RemoveCoverObjectFromWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_1, fRoof );
|
|
}
|
|
|
|
//can only see prone
|
|
else if( bVisibleToSoldier == DC__SEE_1_STANCE )
|
|
{
|
|
RemoveCoverObjectFromWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_2, fRoof );
|
|
}
|
|
|
|
//can see crouch or prone
|
|
else if( bVisibleToSoldier == DC__SEE_2_STANCE )
|
|
{
|
|
RemoveCoverObjectFromWorld( gVisibleToSoldierStruct[ uiCntX ][ uiCntY ].sGridNo, SPECIALTILE_COVER_3, fRoof );
|
|
}
|
|
|
|
else
|
|
{
|
|
Assert( 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Re-render the scene!
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
|
|
gsLastVisibleToSoldierGridNo = NOWHERE;
|
|
gsLastSoldierGridNo = NOWHERE;
|
|
}
|
|
|
|
|
|
INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOLEAN fRoof )
|
|
{
|
|
INT8 bRetVal=0;
|
|
INT32 iLosForGridNo=0;
|
|
UINT16 usSightLimit=0;
|
|
INT8 *pPersOL,*pbPublOL;
|
|
UINT8 ubID;
|
|
BOOLEAN bAware=FALSE;
|
|
|
|
if( fRoof )
|
|
{
|
|
ubID = WhoIsThere2( sTargetGridNo, 1 );
|
|
}
|
|
else
|
|
{
|
|
ubID = WhoIsThere2( sTargetGridNo, 0 );
|
|
}
|
|
|
|
if( ubID != NOBODY )
|
|
{
|
|
pPersOL = &(pSoldier->bOppList[ubID]);
|
|
pbPublOL = &(gbPublicOpplist[pSoldier->bTeam][ubID]);
|
|
|
|
// if soldier is known about (SEEN or HEARD within last few turns)
|
|
if (*pPersOL || *pbPublOL)
|
|
{
|
|
bAware = TRUE;
|
|
}
|
|
}
|
|
|
|
// Lesh: changed 2-nd parameter in DistanceVisible function call
|
|
usSightLimit = DistanceVisible( pSoldier, (SoldierHasLimitedVision(pSoldier) ? pSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sTargetGridNo, fRoof, pSoldier );
|
|
|
|
|
|
//
|
|
// Prone
|
|
//
|
|
iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_PRONE, (UINT8)usSightLimit, bAware );
|
|
if( iLosForGridNo != 0 )
|
|
{
|
|
bRetVal++;
|
|
}
|
|
|
|
//
|
|
// Crouch
|
|
//
|
|
iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_CROUCH, (UINT8)usSightLimit, bAware );
|
|
if( iLosForGridNo != 0 )
|
|
{
|
|
bRetVal++;
|
|
}
|
|
|
|
//
|
|
// Standing
|
|
//
|
|
iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_STAND, (UINT8)usSightLimit, bAware );
|
|
if( iLosForGridNo != 0 )
|
|
{
|
|
bRetVal++;
|
|
}
|
|
|
|
return( bRetVal );
|
|
}
|
|
|
|
BOOLEAN IsTheRoofVisible( INT16 sGridNo )
|
|
{
|
|
UINT8 ubRoom;
|
|
|
|
if( InARoom( sGridNo, &ubRoom ) )
|
|
{
|
|
if( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED )
|
|
{
|
|
if( gTacticalStatus.uiFlags & SHOW_ALL_ROOFS )
|
|
return( TRUE );
|
|
else
|
|
return( FALSE );
|
|
}
|
|
else
|
|
{
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef JA2TESTVERSION
|
|
/*
|
|
void DisplayLosAndDisplayCoverUsageScreenMsg()
|
|
{
|
|
CHAR16 zString[512];
|
|
|
|
swprintf( zString, L"Display Cover: %d", gJa25SaveStruct.uiDisplayCoverCounter );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zString );
|
|
|
|
swprintf( zString, L"LOS: %d", gJa25SaveStruct.uiDisplayLosCounter );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zString );
|
|
|
|
swprintf( zString, L"Gun Range: %d", gJa25SaveStruct.uiDisplayGunRangeCounter );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zString );
|
|
}
|
|
*/
|
|
#endif
|
|
|
|
void ChangeSizeOfDisplayCover( INT32 iNewSize )
|
|
{
|
|
//if the new size is smaller or greater, scale it
|
|
if( iNewSize < DC__MIN_SIZE )
|
|
{
|
|
iNewSize = DC__MIN_SIZE;
|
|
}
|
|
else if( iNewSize > DC__MAX_SIZE )
|
|
{
|
|
iNewSize = DC__MAX_SIZE;
|
|
}
|
|
|
|
//Set new size
|
|
gGameSettings.ubSizeOfDisplayCover = (UINT8)iNewSize;
|
|
|
|
//redisplay the cover
|
|
RemoveCoverOfSelectedGridNo();
|
|
DisplayCoverOfSelectedGridNo( );
|
|
}
|
|
|
|
void ChangeSizeOfLOS( INT32 iNewSize )
|
|
{
|
|
//if the new size is smaller or greater, scale it
|
|
if( iNewSize < DC__MIN_SIZE )
|
|
{
|
|
iNewSize = DC__MIN_SIZE;
|
|
}
|
|
else if( iNewSize > DC__MAX_SIZE )
|
|
{
|
|
iNewSize = DC__MAX_SIZE;
|
|
}
|
|
|
|
//Set new size
|
|
gGameSettings.ubSizeOfLOS = (UINT8)iNewSize;
|
|
|
|
//ReDisplay the los
|
|
RemoveVisibleGridNoAtSelectedGridNo();
|
|
DisplayGridNoVisibleToSoldierGrid( );
|
|
}
|