diff --git a/GameSettings.cpp b/GameSettings.cpp index 092ec97d..943f22aa 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -133,8 +133,8 @@ BOOLEAN LoadGameSettings() gGameSettings.ubSpeechVolume = iniReader.ReadInteger("JA2 Game Settings","ubSpeechVolume" , MIDVOLUME , 0 , HIGHVOLUME ); gGameSettings.uiMeanwhileScenesSeenFlags = iniReader.ReadUINT32 ("JA2 Game Settings","uiMeanwhileScenesSeenFlags" , 0 , 0 , UINT_MAX ); gGameSettings.fHideHelpInAllScreens = iniReader.ReadBoolean("JA2 Game Settings","fHideHelpInAllScreens" , FALSE ); - gGameSettings.ubSizeOfDisplayCover = iniReader.ReadInteger("JA2 Game Settings","ubSizeOfDisplayCover" , DC__MIN_SIZE , DC__MIN_SIZE , DC__MAX_SIZE ); - gGameSettings.ubSizeOfLOS = iniReader.ReadInteger("JA2 Game Settings","ubSizeOfLOS" , DC__MIN_SIZE , DC__MIN_SIZE , DC__MAX_SIZE ); + //gGameSettings.ubSizeOfDisplayCover = iniReader.ReadInteger("JA2 Game Settings","ubSizeOfDisplayCover" , DC__MIN_SIZE , DC__MIN_SIZE , DC__MAX_SIZE ); + //gGameSettings.ubSizeOfLOS = iniReader.ReadInteger("JA2 Game Settings","ubSizeOfLOS" , DC__MIN_SIZE , DC__MIN_SIZE , DC__MAX_SIZE ); gGameSettings.fOptions[TOPTION_SPEECH] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SPEECH" , TRUE ); gGameSettings.fOptions[TOPTION_MUTE_CONFIRMATIONS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_MUTE_CONFIRMATIONS" , FALSE ); gGameSettings.fOptions[TOPTION_SUBTITLES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SUBTITLES" , TRUE ); @@ -289,8 +289,8 @@ BOOLEAN SaveGameSettings() settings << "; UINT8 fOptions[ NUM_ALL_GAME_OPTIONS ]; // Toggle Options (Speech, Subtitles, Show Tree Tops, etc.. )" << endl; settings << "; UINT32 uiMeanwhileScenesSeenFlags; // Bit Vector describing seen 'mean whiles..'" << endl; settings << "; BOOLEAN fHideHelpInAllScreens; // Controls Help \"do not show help again\" checkbox" << endl; - settings << "; UINT8 ubSizeOfDisplayCover; // The number of grids the player designates thru [Delete + ( = or - )]" << endl; - settings << "; UINT8 ubSizeOfLOS; // The number of grids the player designates thru [End + ( = or - )]" << endl; + //settings << "; UINT8 ubSizeOfDisplayCover; // The number of grids the player designates thru [Delete + ( = or - )]" << endl; + //settings << "; UINT8 ubSizeOfLOS; // The number of grids the player designates thru [End + ( = or - )]" << endl; settings << "; } GAME_SETTINGS" << endl; settings << ";" << endl; settings << ";******************************************************************************************************************************" << endl; @@ -303,8 +303,8 @@ BOOLEAN SaveGameSettings() settings << "ubSpeechVolume = " << (int)gGameSettings.ubSpeechVolume << endl; settings << "uiMeanwhileScenesSeenFlags = " << gGameSettings.uiMeanwhileScenesSeenFlags << endl; settings << "fHideHelpInAllScreens = " << (gGameSettings.fHideHelpInAllScreens ? "TRUE" : "FALSE" ) << endl; - settings << "ubSizeOfDisplayCover = " << (int)gGameSettings.ubSizeOfDisplayCover << endl; - settings << "ubSizeOfLOS = " << (int)gGameSettings.ubSizeOfLOS << endl; + //settings << "ubSizeOfDisplayCover = " << (int)gGameSettings.ubSizeOfDisplayCover << endl; + //settings << "ubSizeOfLOS = " << (int)gGameSettings.ubSizeOfLOS << endl; settings << "TOPTION_SPEECH = " << (gGameSettings.fOptions[TOPTION_SPEECH] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_MUTE_CONFIRMATIONS = " << (gGameSettings.fOptions[TOPTION_MUTE_CONFIRMATIONS] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_SUBTITLES = " << (gGameSettings.fOptions[TOPTION_SUBTITLES] ? "TRUE" : "FALSE" ) << endl; @@ -461,6 +461,9 @@ void InitGameSettings() // enum control options (not real options but included here for the sake of complete control of values) + //gGameSettings.ubSizeOfDisplayCover = 16; + //gGameSettings.ubSizeOfLOS = 16; + // ary-05/05/2009 : TOPTION_LAST_OPTION is THE LAST options screen toggle option that exists. (its still an option, and its < NUM_GAME_OPTIONS) // : intended for debugging options screen final page. test to avoid last page over or under extension. // : might be useful in future of toggle option content developement. @@ -475,9 +478,6 @@ void InitGameSettings() gGameSettings.fOptions[ NUM_ALL_GAME_OPTIONS ] = FALSE; // Absolute final end of enum - gGameSettings.ubSizeOfDisplayCover = 4; - gGameSettings.ubSizeOfLOS = 4; - //Since we just set the settings, save them SaveGameSettings(); @@ -1005,6 +1005,17 @@ void LoadGameExternalOptions() // HEADROCK HAM B2.4 gGameExternalOptions.iMineIncomePercentage = iniReader.ReadInteger("JA2 HAM Settings","MINE_INCOME_PERCENTAGE", 100, 1, 1000); + + // CPT: Cover System Settings + gGameExternalOptions.ubStealthTraitCoverValue = iniReader.ReadInteger("JA2 Gameplay Settings","STEALTH_TRAIT_COVER_VALUE", 15, 0, 100); + gGameExternalOptions.ubStealthEffectiveness = iniReader.ReadInteger("JA2 Gameplay Settings", "STEALTH_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubTreeCoverEffectiveness = iniReader.ReadInteger("JA2 Gameplay Settings","TREE_COVER_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubCamouflageEffectiveness = iniReader.ReadInteger("JA2 Gameplay Settings", "CAMOUFLAGE_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubCoverDisplayUpdateWait = iniReader.ReadInteger("JA2 Gameplay Settings", "COVER_DISPLAY_UPDATE_WAIT", 500, -1, 10000); + + gGameExternalOptions.fMovementSightAdjustment = iniReader.ReadBoolean("JA2 Gameplay Settings", "MOVEMENT_SIGHT_ADJUSTMENT", TRUE); + gGameExternalOptions.fStanceSightAdjustment = iniReader.ReadBoolean("JA2 Gameplay Settings", "STANCE_SIGHT_ADJUSTMENT", TRUE); + gGameExternalOptions.fLBESightAdjustment = iniReader.ReadBoolean("JA2 Gameplay Settings", "LBE_SIGHT_ADJUSTMENT", TRUE); // HEADROCK HAM B1: Set minimum and maximum CTH gGameExternalOptions.iMaximumCTH = iniReader.ReadInteger("JA2 HAM Settings","MAXIMUM_POSSIBLE_CTH",99); diff --git a/GameSettings.h b/GameSettings.h index 123604c6..b8b4353d 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -80,6 +80,7 @@ enum TOPTION_HIDE_BULLETS, TOPTION_TRACKING_MODE, + NUM_ALL_GAME_OPTIONS, }; @@ -506,6 +507,17 @@ BOOLEAN gbBulletTracer; // WANNE: Always use "prof.dat". BOOLEAN fAlwaysUseProfDat; + // CPT: Cover System Settings + UINT8 ubStealthTraitCoverValue; + UINT8 ubStealthEffectiveness; + UINT8 ubTreeCoverEffectiveness; + UINT8 ubCamouflageEffectiveness; + UINT8 ubCoverDisplayUpdateWait; + + BOOLEAN fMovementSightAdjustment; + BOOLEAN fStanceSightAdjustment; + BOOLEAN fLBESightAdjustment; + // HEADROCK HAM B1: Global modifier for mine income (0 is automatically turned to 1 to avoid divide-by-zero.) INT16 iMineIncomePercentage; diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp index a847043a..db20ba08 100644 --- a/Tactical/DisplayCover.cpp +++ b/Tactical/DisplayCover.cpp @@ -34,403 +34,401 @@ #include "UI Cursors.h" #endif - //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; //******* Local Defines ************************************************** -// moved no longer local -typedef struct +struct CoverCell { 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; + INT8 bCover; + BOOLEAN fInverseColor; + CoverCell() : sGridNo(NOWHERE), bCover(-1), fInverseColor(FALSE) {} +}; -typedef struct +enum COVER_VALUES { - INT16 sGridNo; - INT8 bVisibleToSoldier; - BOOLEAN fRoof; -} VISIBLE_TO_SOLDIER_STRUCT; + NO_COVER=0, + MIN_COVER=1, + MED_COVER=2, + MAX_COVER=3 +}; +enum COVER_DRAW_MODE { + COVER_DRAW_OFF, + COVER_DRAW_MERC_VIEW, + COVER_DRAW_ENEMY_VIEW +}; -/* -#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, +COVER_DRAW_MODE gubDrawMode = COVER_DRAW_OFF; + +const UINT8 animArr[3] = { + ANIM_PRONE, + ANIM_CROUCH, + ANIM_STAND }; //****** Global Variables ***************************************** +// yea way too big... but some bytes more memory is cheap, as well as some extra loops +// PS: brainscells arn't cheap ;) +#define COVER_X_CELLS WORLD_COLS +#define COVER_Y_CELLS WORLD_ROWS +#define COVER_Z_CELLS 2 // roof or no roof -BEST_COVER_STRUCT gCoverRadius[ DC_MAX_COVER_RANGE ][ DC_MAX_COVER_RANGE ]; -INT16 gsLastCoverGridNo=NOWHERE; -INT16 gsLastSoldierGridNo=NOWHERE; -INT8 gbLastStance=-1; +CoverCell gCoverViewArea[ COVER_X_CELLS ][ COVER_Y_CELLS ][ COVER_Z_CELLS ]; - -VISIBLE_TO_SOLDIER_STRUCT gVisibleToSoldierStruct[ DC__SOLDIER_VISIBLE_RANGE ][ DC__SOLDIER_VISIBLE_RANGE ]; -INT16 gsLastVisibleToSoldierGridNo=NOWHERE; +DWORD guiCoverNextUpdateTime = 0; //******* 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 SwitchCoverDrawMode(); -void CalculateVisibleToSoldierAroundGridno( INT16 sGridNo, INT8 bSearchRange ); -void AddVisibleToSoldierToEachGridNo(); -INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOLEAN fRoof ); -BOOLEAN IsTheRoofVisible( INT16 sGridNo ); +CHAR16* GetTerrainName( const UINT8& ubTerrainType ); -//ppp +TileDefines GetTileCoverIndex( const INT8& bCover ); + +void AddCoverObjectToWorld( const INT16& sGridNo, const UINT16& usGraphic, const BOOLEAN& fRoof ); +void RemoveCoverObjectFromWorld( const INT16 sGridNo, const UINT16& usGraphic, const BOOLEAN& fRoof ); + +void AddCoverObjectsToViewArea(); +void RemoveCoverObjectsFromViewArea(); + +void CalculateCover(); +void CalculateCoverForSoldier( SOLDIERTYPE* pForSoldier, const INT16& sTargetGridNo, const BOOLEAN& fRoof, INT8& bCover ); +void CalculateCoverFromSoldier( SOLDIERTYPE* pFromSoldier, const INT16& sTargetGridNo, const BOOLEAN& fRoof, const INT32& iSightAdjustment, INT8& bCover ); + +void GetGridNoForViewPort( const UINT8& ubX, const UINT8& ubY, INT16& sGridNo ); + +BOOLEAN GridNoOnScreenAndAround( const INT16& sGridNo, const UINT8& ubRadius=2 ); + +BOOLEAN IsTheRoofVisible( const INT16& sGridNo ); +BOOLEAN HasAdjTile( const UINT8& ubX, const UINT8& ubY ); //******* Functions ************************************************** - -void DisplayCoverOfSelectedGridNo( ) +// TODO: internationalize +void SwitchCoverDrawMode() { - INT16 sGridNo; - INT8 bStance; + CHAR16 zDebugString[512]; - GetMouseMapPos( &sGridNo ); - - //Only allowed in if there is someone selected - if( gusSelectedSoldier == NOBODY ) + switch(gubDrawMode) { - return; + case COVER_DRAW_OFF: + swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_MERC_VIEW] ); + gubDrawMode = COVER_DRAW_MERC_VIEW; + break; + case COVER_DRAW_MERC_VIEW: + swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_ENEMY_VIEW] ); + gubDrawMode = COVER_DRAW_ENEMY_VIEW; + break; + default: + swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_OFF] ); + gubDrawMode = COVER_DRAW_OFF; + break; } + + DisplayCover(TRUE); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zDebugString ); +} - //if the cursor is in a the tactical map - if( sGridNo != NOWHERE && sGridNo != 0 ) - { - bStance = GetCurrentMercForDisplayCoverStance(); +void GetGridNoForViewPort( const UINT8& ubX, const UINT8& ubY, INT16& sGridNo ) +{ + sGridNo = MAPROWCOLTOPOS( ubY, ubX ); +} - //if the gridno is different then the last one that was displayed - if( sGridNo != 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 = sGridNo; - gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo; - - //Fill the array of gridno and cover values - CalculateCoverInRadiusAroundGridno( sGridNo, gGameSettings.ubSizeOfDisplayCover ); - - //Add the graphics to each gridno - AddCoverTileToEachGridNo(); - - // Re-render the scene! - SetRenderFlags( RENDER_FLAG_FULL ); - } +CHAR16* GetTerrainName( const UINT8& ubTerrainType ) +{ + switch(ubTerrainType) { + case LOW_GRASS: + case HIGH_GRASS: + return gzDisplayCoverText[DC_TTI__WOOD]; + case FLAT_FLOOR: + case PAVED_ROAD: + return gzDisplayCoverText[DC_TTI__URBAN]; + case DIRT_ROAD: + case TRAIN_TRACKS: + return gzDisplayCoverText[DC_TTI__DESERT]; + case FLAT_GROUND: + return gzDisplayCoverText[DC_TTI__WOOD_AND_DESERT]; + default: + return gzDisplayCoverText[DC_TTI__UNKNOWN]; } } -void AddCoverTileToEachGridNo() +TileDefines GetTileCoverIndex( const INT8& bCover ) { - UINT32 uiCntX, uiCntY; - BOOLEAN fRoof = ( gsInterfaceLevel != I_GROUND_LEVEL ); - - - //loop through all the gridnos - for(uiCntY=0; uiCntY 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 ); - } - } - } + switch(bCover) { + case NO_COVER: + return SPECIALTILE_COVER_1; // red + case MIN_COVER: + return SPECIALTILE_COVER_2; // orange + case MED_COVER: + return SPECIALTILE_COVER_3; // yellow + case MAX_COVER: + return SPECIALTILE_COVER_5; // green + default: + return SPECIALTILE_COVER_4; // light green, can be used to denote that you just don't know. } } -void RemoveCoverOfSelectedGridNo() +void AddCoverObjectToWorld( const INT16& sGridNo, const UINT16& usGraphic, const BOOLEAN& fRoof ) { - UINT32 uiCntX, uiCntY; - BOOLEAN fRoof = ( gsInterfaceLevel != I_GROUND_LEVEL ); + LEVELNODE *pNode; - - if( gsLastCoverGridNo == NOWHERE ) + if( fRoof ) { - return; + AddOnRoofToHead( sGridNo, usGraphic ); + pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead; + } + else + { + AddObjectToHead( sGridNo, usGraphic ); + pNode = gpWorldLevelData[ sGridNo ].pObjectHead; } - //loop through all the gridnos - for(uiCntY=0; uiCntYuiFlags |= LEVELNODE_REVEAL; + + if( NightTime() ) { - for(uiCntX=0; uiCntXubShadeLevel=DEFAULT_SHADE_LEVEL; + pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; + } +} + +void RemoveCoverObjectFromWorld( const INT16 sGridNo, const UINT16& usGraphic, const BOOLEAN& fRoof ) +{ + if( fRoof ) + { + RemoveOnRoof( sGridNo, usGraphic ); + } + else + { + RemoveObject( sGridNo, usGraphic ); + } +} + +BOOLEAN HasAdjTile( const UINT8& ubX, const UINT8& ubY, const UINT8& ubZ ) +{ + UINT8 ubTX, ubTY; + + for ( ubTX = ubX-1; ubTX <= ubX+1; ++ubTX ) + { + if ( ubTX < 0 || ubTX > WORLD_COLS ) { - //if there is a valid cover at this gridno - if( gCoverRadius[ uiCntX ][ uiCntY ].bCover != -1 ) + continue; + } + + for ( ubTY = ubY-1; ubTY <= ubY+1; ++ubTY ) + { + if ( ubTY < 0 || ubTY > WORLD_ROWS ) { -// fRoof = gCoverRadius[ uiCntX ][ uiCntY ].fRoof; + continue; + } - //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 ); - } + INT8& bCover = gCoverViewArea[ ubTX ][ ubTY ][ ubZ ].bCover; - //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 ); - } + if ( bCover > -1 && bCover < MAX_COVER ) + { + return TRUE; + } + } + } - //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 ); - } + return FALSE; +} - //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 ); - } +void AddCoverObjectsToViewArea() +{ + UINT8 ubX, ubY, ubZ; + BOOLEAN fChanged = FALSE; - //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 ); - } + for ( ubX=0; ubX ( 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 (sCounterY = 0, sCounterX = 0, sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++, sCounterY++, sCounterX = 0) - { - for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++, sCounterX++) - { - 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 ) ) + for ( ubZ=0; ubZbTeam ) - { - continue; - } - - //Calculate the cover for this gridno - gCoverRadius[ sCounterX ][ sCounterY ].bCover = CalcCoverForGridNoBasedOnTeamKnownEnemies( pSoldier, sGridNo, bStance ); -// gCoverRadius[ sCounterX ][ sCounterY ].fRoof = fRoof; - - -// sCounterX++; } -// sCounterY++; -// sCounterX = 0; + } + + // Re-render the scene! + if ( fChanged ) + { + SetRenderFlags( RENDER_FLAG_FULL ); } } - - -INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, INT8 bStance ) +// ubRadius in times of y or x cell sizes +BOOLEAN GridNoOnScreenAndAround( const INT16& sGridNo, const UINT8& ubRadius ) { - INT32 iTotalCoverPoints=0; - INT8 bNumEnemies=0; - INT8 bPercentCoverForGridno=0; - UINT32 uiLoop; + INT16 sNewCenterWorldX, sNewCenterWorldY; + INT16 sWorldX; + INT16 sWorldY; + + UINT16 usXDiff = ubRadius*CELL_X_SIZE; + UINT16 usYDiff = ubRadius*CELL_Y_SIZE; + + ConvertGridNoToXY( sGridNo, &sNewCenterWorldX, &sNewCenterWorldY ); + + // Get screen coordinates for current position of soldier + GetWorldXYAbsoluteScreenXY( (INT16)(sNewCenterWorldX), (INT16)(sNewCenterWorldY), &sWorldX, &sWorldY); + + if ( sWorldX >= ( gsTopLeftWorldX - usXDiff ) + && sWorldX <= ( gsBottomRightWorldX + usXDiff ) + && sWorldY >= ( gsTopLeftWorldY - usYDiff + gsVIEWPORT_WINDOW_START_Y ) + && sWorldY <= ( gsBottomRightWorldY + usYDiff ) ) + { + return( TRUE ); + } + return( FALSE ); +} + +void DisplayCover( const BOOLEAN& forceUpdate ) +{ + if ( gGameExternalOptions.ubCoverDisplayUpdateWait == -1 ) + { + return; + } + + if ( forceUpdate || ( !gfScrollPending && !gfScrollInertia && GetTickCount() > guiCoverNextUpdateTime ) ) + { + CalculateCover(); + guiCoverNextUpdateTime = GetTickCount() + gGameExternalOptions.ubCoverDisplayUpdateWait; + } +} + +void CalculateCover() +{ + UINT8 ubX, ubY, ubZ; + SOLDIERTYPE* pSoldier; + + RemoveCoverObjectsFromViewArea(); + + if( gubDrawMode == COVER_DRAW_OFF ) + { + return; + } + + if( gusSelectedSoldier == NOBODY ) + { + return; + } + + GetSoldier( &pSoldier, gusSelectedSoldier ); + + const INT16& sSelectedSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo; + + for ( ubX=0; ubXpathing.bLevel, bStance, TRUE, CALC_FROM_WANTED_DIR ) == 0 ) + INT16 iTileSightLimit = pOpponent->GetMaxDistanceVisible( sTargetGridNo, pSoldier->pathing.bLevel, CALC_FROM_WANTED_DIR ); + INT16 iSightAdjustment = GetSightAdjustment( pSoldier, sTargetGridNo, ANIM_PRONE ) - GetSightAdjustmentThroughStance( ANIM_PRONE ); + + CalculateCoverFromSoldier( pOpponent, sTargetGridNo, fRoof, iSightAdjustment, bCover ); + + // if we got no cover, just return, can't get any worse than that. Helldorados lets you count + if (bCover == NO_COVER) { - continue; - } - - iGetThrough = SoldierToLocationChanceToGetThrough( pOpponent, sTargetGridNo, pSoldier->pathing.bLevel, bStance, NOBODY ); -// iBulletGetThrough = CalcChanceToHitGun( pOpponent, sTargetGridNo, APBPConstants[AP_MAX_AIM_ATTACK], AIM_SHOT_TORSO ); - - if( WeaponInHand( pOpponent ) ) - { - usMaxRange = GunRange( &pOpponent->inv[ HANDPOS ] ); - } - else - { - usMaxRange = Weapon[ GLOCK_18 ].usRange; - } - - usRange = (UINT16)GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, sTargetGridNo ); - 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++; + return; } } - - 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 ) +void CalculateCoverFromSoldier( SOLDIERTYPE* pFromSoldier, const INT16& sTargetGridNo, const BOOLEAN& fRoof, const INT32& iSightAdjustment, INT8& bCover ) { - LEVELNODE *pNode; + UINT16 usSightLimit = pFromSoldier->GetMaxDistanceVisible(sTargetGridNo, (INT8)fRoof, CALC_FROM_WANTED_DIR); - if( fRoof ) + bCover = MAX_COVER; + for ( int i = 0; iuiFlags |= LEVELNODE_REVEAL; - - if( NightTime() ) - { - pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL; - pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; + if ( SoldierToVirtualSoldierLineOfSightTest( pFromSoldier, sTargetGridNo, (INT8) fRoof, ubStance, FALSE, usAdjustedSight ) != 0 ) + { + bCover = i; + break; // we go from prone to stand, if soldier can see someone crouching, he can also see someone standing + } } } -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; @@ -610,20 +498,24 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) return; } + { + UINT8 ubLightLevel = LightTrueLevel(sTargetGridNo, gsInterfaceLevel); + UINT8 ubBrightness = 100 * (SHADE_MIN - ubLightLevel)/SHADE_MIN; // percentage + + INT8 ubTerrainType = GetTerrainTypeForGrid(sTargetGridNo); + + INT8 ubCover = - GetSightAdjustment(pSoldier, sTargetGridNo); + + //display a string with cover value of current selected merc and brightness + swprintf( zOutputString, gzDisplayCoverText[DC_MSG__COVER_INFORMATION], ubCover, GetTerrainName(ubTerrainType), ubBrightness ); + + //Display the msg + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString ); + } + //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 ) ) { @@ -639,365 +531,25 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) } pSoldier->bTargetLevel = bTempTargetLevel; - swprintf( zOutputString, zNewTacticalMessages[ TCTL_MSG__GUN_RANGE_AND_CTH ], Weapon[ pSoldier->inv[HANDPOS].usItem ].usRange / 10, uiHitChance ); - + swprintf( zOutputString, gzDisplayCoverText[DC_MSG__GUN_RANGE_INFORMATION], usRange / 10, 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 ) ) + else { - // Display a warning saying so - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ OUT_OF_RANGE_STRING ] ); + swprintf( zOutputString, gzDisplayCoverText[DC_MSG__GUN_RANGE_INFORMATION], usRange / 10, 0, 0 ); + + //Display the msg + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString ); } //increment the display gun range counter ( just seeing how many times people use it ) //gJa25SaveStruct.uiDisplayGunRangeCounter++; } - - -void DisplayGridNoVisibleToSoldierGrid( ) +BOOLEAN IsTheRoofVisible( const INT16& sGridNo ) { - INT16 sGridNo; -// INT8 bStance; - - GetMouseMapPos( &sGridNo ); - - //Only allowed in if there is someone selected - if( gusSelectedSoldier == NOBODY ) - { - return; - } - - //if the cursor is in a the tactical map - if( sGridNo != NOWHERE && sGridNo != 0 ) - { - //if the gridno is different then the last one that was displayed - if( sGridNo != 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 = sGridNo; - gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo; - - - //Fill the array of gridno and cover values - CalculateVisibleToSoldierAroundGridno( sGridNo, 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; uiCntYaiData.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 = pSoldier->GetMaxDistanceVisible(sTargetGridNo, fRoof, CALC_FROM_WANTED_DIR); - - - // - // Prone - // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_PRONE, bAware, usSightLimit ); - if( iLosForGridNo != 0 ) - { - bRetVal++; - } - - // - // Crouch - // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_CROUCH, bAware, usSightLimit ); - if( iLosForGridNo != 0 ) - { - bRetVal++; - } - - // - // Standing - // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_STAND, bAware, usSightLimit ); - if( iLosForGridNo != 0 ) - { - bRetVal++; - } - - return( bRetVal ); -} - -BOOLEAN IsTheRoofVisible( INT16 sGridNo ) -{ - UINT8 ubRoom; - - if( InARoom( sGridNo, &ubRoom ) ) + if( FlatRoofAboveGridNo( sGridNo ) ) { if( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) { @@ -1014,61 +566,3 @@ BOOLEAN IsTheRoofVisible( INT16 sGridNo ) 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( ); -} diff --git a/Tactical/DisplayCover.h b/Tactical/DisplayCover.h index 8cba89d6..a6d02ba5 100644 --- a/Tactical/DisplayCover.h +++ b/Tactical/DisplayCover.h @@ -1,28 +1,8 @@ #ifndef _DISPLAY_COVER__H_ #define _DISPLAY_COVER__H_ -void DisplayCoverOfSelectedGridNo( ); -void RemoveCoverOfSelectedGridNo(); - void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ); - - -void RemoveVisibleGridNoAtSelectedGridNo(); -void DisplayGridNoVisibleToSoldierGrid( ); - - -#define DC_MAX_COVER_RANGE 43 //31 -#define DC__SOLDIER_VISIBLE_RANGE 43 //31 -#define DC__MIN_SIZE 4 -#define DC__MAX_SIZE 21 //11 - -#ifdef JA2TESTVERSION - void DisplayLosAndDisplayCoverUsageScreenMsg(); -#endif - -void ChangeSizeOfDisplayCover( INT32 iNewSize ); - -void ChangeSizeOfLOS( INT32 iNewSize ); +void DisplayCover(const BOOLEAN& forceUpdate = FALSE); +void SwitchCoverDrawMode(); #endif - diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp index ccad78ab..90a46706 100644 --- a/Tactical/Handle UI.cpp +++ b/Tactical/Handle UI.cpp @@ -87,6 +87,7 @@ #include "environment.h" #include "Map Information.h" #include "Soldier Control.h" +#include "DisplayCover.h" #endif #include "teamturns.h" @@ -605,6 +606,8 @@ UINT32 HandleTacticalUI( void ) guiPendingOverrideEvent = I_DO_NOTHING; } + DisplayCover(); + if ( HandleItemPickupMenu( ) ) { uiNewEvent = A_CHANGE_TO_MOVE; diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 52b35a7f..efea4c74 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -21,6 +21,8 @@ #include "opplist.h" #include "bullets.h" +#include "lighting.h" + #include "phys math.h" #include "items.h" #include "Soldier Profile.h" @@ -44,6 +46,8 @@ #endif #include "fresh_header.h" #include "test_space.h" +#include "WorldDat.h" + //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; @@ -373,6 +377,325 @@ enum } LocationCode; +// TODO: Relocate functions in appropriate class (soldiertype obviously) +/** +* Calculates the height and gives it back as one of the ANIM_* defines +* +* @comment I don't want to repetitivly use code that should be part of the pSoldier class, so I made a oo-c-based-method +* +* @param pSoldier +* @return ANIM_STAND or ANIM_CROUCH or ANIM_PRONE +*/ +inline UINT8 GetCurrentHeightOfSoldier( SOLDIERTYPE* pSoldier ) +{ + return gAnimControl[ pSoldier->usAnimState ].ubHeight; +} + +// why not functions? because these are typeless +#define MINMAX(iMin, iMax, iVal) min(iMax, max(iMin, iVal)) +#define MINMAX100(iVal) MINMAX(0, 100, iVal) +#define MINMAX100N(iVal) MINMAX(-100, 100, iVal) + +/* +* Calculates the total camouflage for the corresponding type. +* +* @comment I don't want to repetitivly use code that should be part of the pSoldier class, so I made a oo-c-based-method +* @comment we don't need the snow camo as we don't have a terrain type -> camouflage association for snow +* (meaning we would need externalisation for specifing camo effectivness based on terrain textures and not terrain types) +* (unfortunatly that's not only programming but alot of content-heavy work, which doesn't seem probable to happen) +* @precondition camo on soldiertypes are correctly set +* +* @param pSoldier +* @return a value generally between 0 and 100 (but who knows if someone wants to use negative values, the basic types allow for that) +*/ +inline INT8 GetJungleCamouflage( SOLDIERTYPE* pSoldier ) +{ + if (HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED )) { + return 100; + } + + return MINMAX100N(pSoldier->bCamo + pSoldier->wornCamo); +} +inline INT8 GetDesertCamouflage( SOLDIERTYPE* pSoldier ) +{ + if (HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_DESERT )) { + return 100; + } + + return MINMAX100N(pSoldier->desertCamo + pSoldier->wornDesertCamo); +} +inline INT8 GetUrbanCamouflage( SOLDIERTYPE* pSoldier ) +{ + if (HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_URBAN )) { + return 100; + } + + return MINMAX100N(pSoldier->urbanCamo + pSoldier->wornUrbanCamo); +} + +/** +* Calculates the total stealth value of a player. +* +* @comment I don't want to repetitivly use code that should be part of the pSoldier class, so I made a oo-c-based-method +* +* @param pSoldier +* @return ANIM_STAND or ANIM_CROUCH or ANIM_PRONE +*/ +inline INT8 GetStealth( SOLDIERTYPE* pSoldier ) +{ + INT16 stealth = GetWornStealth( pSoldier ); + if (HAS_SKILL_TRAIT( pSoldier, STEALTHY )) + { + stealth += gGameExternalOptions.ubStealthTraitCoverValue * NUM_SKILL_TRAITS( pSoldier, STEALTHY ); + } + + return MINMAX100N(stealth); +} + +/** +* Gives back a valid terrainId for a specified GridNo +* +* @comment I don't want to repetitivly use code that should be part of the pSoldier class, so I made a oo-c-based-method +* @comment the current method GetTerrainType doesn't check for more info, but for camouflage we need that extra info +* +* @param pSoldier +* @return ANIM_STAND or ANIM_CROUCH or ANIM_PRONE +*/ +INT8 GetTerrainTypeForGrid( const UINT16& sGridNo ) +{ + if (gpWorldLevelData[sGridNo].ubTerrainID != NO_TERRAIN) + { + return gpWorldLevelData[sGridNo].ubTerrainID; + } + + // Check if we have anything in object layer which has a terrain modifier + LEVELNODE* pNode = gpWorldLevelData[ sGridNo ].pObjectHead; + if ( pNode != NULL ) + { + if ( gTileDatabase[ pNode->usIndex ].ubTerrainID != NO_TERRAIN ) + { + return gTileDatabase[ pNode->usIndex ].ubTerrainID ; + } + } + + // Now try terrain! + pNode = gpWorldLevelData[ sGridNo ].pLandHead; + + return gTileDatabase[ pNode->usIndex ].ubTerrainID; +} + +// the following functions should return percentage values which can be easily added/substracted from +// the sight reduction variable inside the Soldier-sight-test. +// This means we specify here how much each test counts towards the total. +// e.g. camouflage of 100 at stance prone on perfect terrain will give back "-50" as value, indicating a 50% sight reduction + +/** +* Calculates a percentage value to be added (or substracted) from sight. it's based on the camouflage and stance of the soldier, as well as the type of terrain. +* - usually it should return something smaller than 0 but we might give a bonus in a later version if the target wears a red-glowing hat +* +* @param pSoldier the target needed to get the correct camouflage info +* @param ubTerrainType terrain type defined by TerrainTypeDefines +* @return a negative value will indicate a reduction of sight, a positive one an addition to sight +*/ +INT8 GetSightAdjustmentCamouflageOnTerrain( SOLDIERTYPE* pSoldier, const UINT8& ubStance, const UINT8& ubTerrainType ) +{ + if (gGameExternalOptions.ubCamouflageEffectiveness == 0) { + return 0; + } + + // current implementation will assume the return will be below 0 and then scale it depending on your stance + INT8 scaler = -(ANIM_STAND - ubStance) * 5; // stand = 0%, crouch = 6-3 = 30%, prone = 6-1 = 50; + + // last term corresponds to the maximum of scaler before + scaler *= gGameExternalOptions.ubCamouflageEffectiveness / 50; + + switch(ubTerrainType) { + case LOW_GRASS: + case HIGH_GRASS: + return GetJungleCamouflage(pSoldier) * scaler/100; + case FLAT_FLOOR: + case PAVED_ROAD: + return GetUrbanCamouflage(pSoldier) * scaler/100; + case DIRT_ROAD: + case TRAIN_TRACKS: + return GetDesertCamouflage(pSoldier) * scaler/100; + case FLAT_GROUND: + // here it would be best if we could have a terrain texture -> camo association instead of terrain type -> camo + // but we need to allow modders to specify that information in an xml file + // this is because flat ground is used by both (it's irritating to see wood camo work perfectly on brown ground, at least ingame) + return max( GetDesertCamouflage(pSoldier), GetJungleCamouflage(pSoldier) ) * scaler/100; + default: + return 0; + } +} + +/** +* Calculates a percentage value to be added (or substracted) from sight. it's based on the movement of a soldier and the brightness level. +* - this will be used to calculate the penalty (sight addition) which occurs on the soldier who is been spot-tested +* - it also will be used to reduce the ability to find others if the spotter moves +* +* @param pSoldier the target +* @return a negative value will indicate a reduction of sight, a positive one an addition to sight +*/ +INT8 GetSightAdjustmentThroughMovement( SOLDIERTYPE* pSoldier, const INT8& bTilesMoved, const UINT8& ubLightlevel ) +{ + if (!gGameExternalOptions.fMovementSightAdjustment) { + return 0; + } + + INT8 stealth = GetStealth(pSoldier); + + INT8 bMovementAdjustment = bTilesMoved * ( 100 - stealth ) / 100; + + UINT8 ubBrightness = SHADE_MIN - ubLightlevel; // 3: starlight, 5: evening dark, 15: day + UINT8 ubScalerInPercent = 6 * ubBrightness; //0:0, 15:90 + + return bMovementAdjustment * ubScalerInPercent / 100; +} + +INT8 GetSightAdjustmentThroughStance( const UINT8& ubStance ) +{ + if (!gGameExternalOptions.fStanceSightAdjustment) { + return 0; + } + + // well why do we have a positive number here? + // just because I wanted to have logic which goes both directions + INT8 bStanceAdjustment = (ubStance - 3) * 2; // stand = 15%, crouch = 0%, prone = -10% + + return bStanceAdjustment; +} + +/** +* TODO: Figure out how to find out your equipment cost. Big equipment will make you more visible! we could go after the load itself (kg) +* TODO: but we still want a backpack to count more than your vest +* +* Calculates a percentage value to be added (or substracted) from sight. it's based on the amount of LBE. +* +* @param pSoldier the target +* @return a negative value will indicate a reduction of sight, a positive one an addition to sight +*/ +INT8 GetSightAdjustmentBasedOnLBE( SOLDIERTYPE* pSoldier ) +{ + if (!gGameExternalOptions.fLBESightAdjustment) { + return 0; + } + + // .... + //if(UsingNewInventorySystem() == true && pSoldier->inv[BPACKPOCKPOS].exists() == true) { + //pSoldier->inv[BPACKPOCKPOS] + //CalculateObjectWeight + //} + return 0; +} + +/** +* Calculates a percentage value to be added (or substracted) from sight. it's based on the stealth value and the brightness. +* - usually it should return something smaller than 0 but we might give a bonus if the target uses a lamp for better viewing (LAM-Lamp) which the spotter can see +* +* @param pSoldier the target +* @param ubLightLevel light level given back by the LightTrueLevel function +* @return a negative value will indicate a reduction of sight, a positive one an addition to sight +*/ +INT8 GetSightAdjustmentStealthAtLightLevel( SOLDIERTYPE* pSoldier, const UINT8& ubLightlevel ) +{ + if (gGameExternalOptions.ubStealthEffectiveness == 0) { + return 0; + } + + INT8 ibStealthInPercent = GetStealth( pSoldier ); + + // set scaler to scale with light level + UINT8 ubBrightness = SHADE_MIN - ubLightlevel; // 3: starlight, 5: evening dark, 15: day + UINT8 ubScaler = -4 * ubBrightness + 60; //0:60, 15:0 + + // last term corresponds to the maximum of ubScaler before + ubScaler *= gGameExternalOptions.ubStealthEffectiveness / 60; + + return (INT8) MINMAX100N( - ibStealthInPercent * ubScaler / 100); +} + +/** +* Calculates a percentage value used for trees that hide you. Will be used inside line of sight function. +* - It's based on the tree "height", fill and density. +* - As well as range and you point of intersection +* - can go up to 100% hiding +* +* @param iRange one tile = 10 range +* @param pTreeStructure a structure containing the tree you want to check +* @param ubHeightLevel between 1 and 4 of the current merc +* @return >=0 the percentage a tree will give a bonus to hiding / view range degradation +*/ +INT8 GetSightAdjustmentBehindStructure( const INT16& iRange, STRUCTURE* pStructure, const UINT8& ubHeightLevel ) +{ + if (gGameExternalOptions.ubTreeCoverEffectiveness == 0) { + return 0; + } + + // Assertions here because we might need this function in other line of sight tests + Assert( ubHeightLevel >= 1 ); + Assert( ubHeightLevel <= 4 ); + Assert( pStructure != NULL ); + Assert( iRange >= 0 ); // ==0 for you being inside a passable tree + + // pStructure->fFlags & STRUCTURE_TREE + UINT8 ubLevels[4]; + if (StructureDensity( pStructure, &ubLevels[0], &ubLevels[1], &ubLevels[2], &ubLevels[3] ) != TRUE) + { + return 0; // this structure has no density therefore no additional sight adjustment possible + } + + //const UINT8& ubDensityInPercent = pStructure->pDBStructureRef->pDBStructure->ubDensity; + UINT16 ubFillInPercent = ubLevels[ubHeightLevel-1]; + + Assert( ubFillInPercent >= 0 ); + Assert( ubFillInPercent <= 100 ); + + // these scalers are for backwards compatibility to mods + UINT8 ubCloseRangeScaler = iRange > CLOSE_TO_FIRER; // zero or 1 + INT16 ubLongRangeScaler = iRange > 100 ? iRange / 100 : 1; + + //* ubDensityInPercent / 100 we assume densitiy is used for bullets + // we make the fill less effective + INT8 ubSolidityInPercent = ubFillInPercent * gGameExternalOptions.ubTreeCoverEffectiveness / 100; + + INT8 ubResult = MINMAX100N(- ubSolidityInPercent * ubCloseRangeScaler * ubLongRangeScaler); + + return ubResult; +} + +/* +* Easy way to get all sight adjustments into one that affect a soldier +*/ +INT16 GetSightAdjustment( SOLDIERTYPE* pSoldier, INT16 sGridNo, INT8 bStance ) +{ + if (sGridNo == -1) { + sGridNo = pSoldier->sGridNo; + } + + if (bStance == -1) { + bStance = GetCurrentHeightOfSoldier( pSoldier ); + } + + UINT8 ubTerrainType = GetTerrainTypeForGrid( sGridNo ); + UINT8 ubLightLevel = LightTrueLevel( sGridNo, gsInterfaceLevel ); + + INT16 iSightAdjustment = 0; + + // general stuff (independant of soldier) + iSightAdjustment += GetSightAdjustmentThroughStance( bStance ); + + // context sensitive (needs soldier) + iSightAdjustment += GetSightAdjustmentBasedOnLBE( pSoldier ); + + // context sensitive stuff with 2nd parameter (needs soldier for attributes but can be given a second parameter) + iSightAdjustment += GetSightAdjustmentThroughMovement( pSoldier, pSoldier->bTilesMoved, ubLightLevel ); + iSightAdjustment += GetSightAdjustmentStealthAtLightLevel( pSoldier, ubLightLevel ); + iSightAdjustment += GetSightAdjustmentCamouflageOnTerrain( pSoldier, bStance, ubTerrainType ); + + return MINMAX100N(iSightAdjustment); +} + BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX, INT8 bLOSIndexY, DOUBLE ddHorizAngle ) { BOOLEAN fNorthSouth, fEastWest; @@ -724,7 +1047,7 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX * - stops at other obstacles * */ -INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, int iTileSightLimit, UINT8 ubTreeSightReduction, INT8 bAware, INT32 bCamouflage, BOOLEAN fSmell, INT16 * psWindowGridNo, bool adjustForSight = true ) +INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, int iTileSightLimit, INT8 bAware, BOOLEAN fSmell, INT16 * psWindowGridNo, bool adjustForSight = true ) { // Parameters... // the X,Y,Z triplets should be obvious @@ -819,13 +1142,6 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("LineOfSightTest: Thermal Optics = %d",fSmell)); - - if (!bAware && !fSmell) - { - // trees are x3 as good at reducing sight if looker is unaware - // and increase that up to double for camouflage! - ubTreeSightReduction = (ubTreeSightReduction * 3) * (100 + bCamouflage) / 100; - } // verify start and end to make sure we'll always be inside the map // hack end location to the centre of the tile, because there was a problem @@ -1258,19 +1574,9 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, { if (pStructure->fFlags & STRUCTURE_TREE) { - // don't count trees close to the person - if (iLoop > CLOSE_TO_FIRER) - { - if (iLoop > 100) - { - // at longer range increase the value of tree cover - iAdjSightLimit -= (ubTreeSightReduction * iLoop) / 100; - } - else - { - // use standard value - iAdjSightLimit -= ubTreeSightReduction; - } + INT8 adjustment = GetSightAdjustmentBehindStructure( iLoop, pStructure, iCurrCubesAboveLevelZ+1 ); + iAdjSightLimit = iAdjSightLimit + iAdjSightLimit * adjustment/100; + #ifdef LOS_DEBUG gLOSTestResults.ubTreeSpotsHit++; gLOSTestResults.iMaxDistance = iSightLimit; @@ -1285,7 +1591,6 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, return( 0 ); } } - } else if ( (pStructure->fFlags & STRUCTURE_WALLNWINDOW) && !(pStructure->fFlags & STRUCTURE_SPECIAL) && qCurrZ >= (gqStandardWindowBottomHeight + qLandHeight) && qCurrZ <= (gqStandardWindowTopHeight + qLandHeight)) { // do nothing; windows are transparent (except ones marked as special) @@ -1670,17 +1975,15 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p return( TRUE ); } +// this is the only function which actually uses the SightAdjustment directly, as it knows that you want to point to a soldier and therefore it can +// calculate all stealthy stuff of that soldier so the "start soldier" cant see him that good INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, INT8 bAware, int iTileSightLimit, UINT8 ubAimLocation, bool adjustForSight ) { FLOAT dStartZPos, dEndZPos; BOOLEAN fOk; BOOLEAN fSmell; - INT16 bEffectiveCamo; - INT16 bEffectiveStealth; - UINT8 ubTreeReduction; UINT8 ubPosType; - // TO ADD: if target is camouflaged and in cover, reduce sight distance by 30% // TO ADD: if in tear gas, reduce sight limit to 2 tiles CHECKF( pStartSoldier ); CHECKF( pEndSoldier ); @@ -1759,98 +2062,27 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE } } - //get the total camouflage - int jungle = max(1,min(100,pEndSoldier->bCamo + pEndSoldier->wornCamo)); - int urban = max(1,min(100,pEndSoldier->urbanCamo + pEndSoldier->wornUrbanCamo)); - int desert = max(1,min(100,pEndSoldier->desertCamo + pEndSoldier->wornDesertCamo)); - int snow = max(1,min(100,pEndSoldier->snowCamo + pEndSoldier->wornSnowCamo)); - int totalCamo = max(1,min(100,jungle + urban + desert + snow)); - - if ( ( totalCamo ) > 0 && !bAware ) - { - - // reduce effects of camo of 5% per tile moved last turn - if ( pEndSoldier->ubBodyType == BLOODCAT ) - { - bEffectiveCamo = 100 - pEndSoldier->bTilesMoved * 5; - } - else - { - bEffectiveCamo = max(0,min(100,(totalCamo))) * (100 - pEndSoldier->bTilesMoved * 5) / 100; - } - bEffectiveCamo = __max( bEffectiveCamo, 0 ); - - if ( gAnimControl[ pEndSoldier->usAnimState ].ubEndHeight < ANIM_STAND ) - { - // reduce visibility by up to a third for camouflage! - switch( pEndSoldier->bOverTerrainType ) - { - case LOW_GRASS: - case HIGH_GRASS: // jungle camo bonus - iTileSightLimit -= iTileSightLimit * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; - break; - case FLAT_FLOOR: // flat floor = indoors - case PAVED_ROAD: // urban camo bonus - iTileSightLimit -= iTileSightLimit * (urban * bEffectiveCamo / 3 / totalCamo) / 100; - break; - case DIRT_ROAD: // desert camo bonus - case TRAIN_TRACKS: - iTileSightLimit -= iTileSightLimit * (desert * bEffectiveCamo / 3 / totalCamo) / 100; - break; - //case ??? : // snow camo bonus - // iTileSightLimit -= iTileSightLimit * (snow * bEffectiveCamo / 3 / totalCamo) / 100; - // break; - case FLAT_GROUND: - //in this case both desert and jungle can work: - iTileSightLimit -= iTileSightLimit * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; - iTileSightLimit -= iTileSightLimit * (desert * bEffectiveCamo / 3 / totalCamo) / 100; - break; - default: - break; - } - } - } - else - { - bEffectiveCamo = 0; - } - - //Madd: added - note stealth is capped at 100 just like camo - if ( ( GetWornStealth(pEndSoldier) ) > 0 && !bAware ) - { - - // reduce effects of stealth by 5% per tile moved last turn - bEffectiveStealth = max(0,min(100,(GetWornStealth(pEndSoldier)))) * (100 - pEndSoldier->bTilesMoved * 5) / 100; - - bEffectiveStealth = __max( bEffectiveStealth, 0 ); - - // reduce visibility by up to a third for Stealth! - // stance and terrain don't matter - iTileSightLimit -= iTileSightLimit * (bEffectiveStealth / 3) / 100; - } - else - { - bEffectiveStealth = 0; - } - - if ( TANK( pEndSoldier ) ) - { - ubTreeReduction = 0; - } - else - { - ubTreeReduction = gubTreeSightReduction[ gAnimControl[pEndSoldier->usAnimState].ubEndHeight ]; - } - + // needed for sight limit calculation if (iTileSightLimit == CALC_FROM_ALL_DIRS || iTileSightLimit == CALC_FROM_WANTED_DIR) { iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( pEndSoldier->sGridNo, pEndSoldier->pathing.bLevel, iTileSightLimit ); - } - else if (iTileSightLimit == NO_DISTANCE_LIMIT) { - iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( pEndSoldier->sGridNo, pEndSoldier->pathing.bLevel, CALC_FROM_ALL_DIRS ); + iTileSightLimit += iTileSightLimit * GetSightAdjustment(pEndSoldier) / 100; } - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, ubTreeReduction, bAware, bEffectiveCamo + bEffectiveStealth, fSmell, NULL, adjustForSight ) ); -} + // needed for gun hit calculation (can you even hit him) + else if (iTileSightLimit == NO_DISTANCE_LIMIT) { + iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( pEndSoldier->sGridNo, pEndSoldier->pathing.bLevel, CALC_FROM_ALL_DIRS ); + iTileSightLimit += iTileSightLimit * GetSightAdjustment(pEndSoldier) / 100; + iTileSightLimit += 255; // this shifts the limit for something special (we don't know yet) + } + + // we assume that if we are given a limit it doesn't include stealth or similar stuff + // for other function we assume the opposite but not this one, as we here are given the needed target soldier information to calculate sight adjustment + else { + iTileSightLimit += iTileSightLimit * GetSightAdjustment(pEndSoldier) / 100; + } + + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight ) ); + } INT16 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT16 sEndGridNo ) { @@ -1875,7 +2107,7 @@ INT16 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT16 sEndGridNo //ADB changed from 255 to 511 to handle new LOS test // We don't want to consider distance limits here so pass in tile sight limit of 255( + 256) // and consider trees as little as possible - iRet = LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, 511, 0, TRUE, 0, FALSE, &sWindowGridNo ); + iRet = LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, 511, TRUE, FALSE, &sWindowGridNo ); return( sWindowGridNo ); } @@ -1923,7 +2155,7 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGr iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, CALC_FROM_ALL_DIRS ); } - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL, adjustForSight ) ); + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, bAware, HasThermalOptics( pStartSoldier), NULL, adjustForSight ) ); } INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bStance, INT8 bAware, int iTileSightLimit ) @@ -1958,7 +2190,6 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 dEndZPos += WALL_HEIGHT_UNITS; } - ConvertGridNoToXY( sGridNo, &sXPos, &sYPos ); sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2); sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2); @@ -1970,7 +2201,7 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, CALC_FROM_ALL_DIRS ); } - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, bAware, HasThermalOptics( pStartSoldier), NULL, false ) ); } INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, INT16 sEndGridNo, INT8 bEndLevel, INT8 bAware, int iTileSightLimit ) @@ -2008,7 +2239,7 @@ INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, I else if (iTileSightLimit == NO_DISTANCE_LIMIT) { iTileSightLimit = 255 + MaxNormalDistanceVisible(); } - return( LineOfSightTest( (FLOAT)sStartXPos, (FLOAT)sStartYPos, dStartZPos, (FLOAT) sEndXPos, (FLOAT) sEndYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, FALSE, NULL ) ); + return( LineOfSightTest( (FLOAT)sStartXPos, (FLOAT)sStartYPos, dStartZPos, (FLOAT) sEndXPos, (FLOAT) sEndYPos, dEndZPos, iTileSightLimit, bAware, FALSE, NULL ) ); } /* diff --git a/Tactical/LOS.h b/Tactical/LOS.h index 870b71d2..8d1a53f2 100644 --- a/Tactical/LOS.h +++ b/Tactical/LOS.h @@ -2,7 +2,7 @@ #define LOS_H //#define LOS_DEBUG - +#include "WorldDat.h" // needed for MAX_TILESETS // fixed-point arithmetic definitions start here @@ -165,6 +165,17 @@ extern LOSResults gLOSTestResults; void MoveBullet( INT32 iBullet ); //BOOLEAN FireBullet2( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, INT16 sHitBy ); +// TODO: public but at the wrong place, the original function deletes the important parts, not sure what it could brake +// to be used in conjunction with the camo thing and the "F" key +INT8 GetTerrainTypeForGrid( const UINT16& uGridNo ); + +// check the flat distance adjustment based on your stance +// use this to test your view on your surroundings based on your stance +INT8 GetSightAdjustmentThroughStance( const UINT8& ubStance ); + +// quick way to get all. should be used for all sight line tests with target soldier known +INT16 GetSightAdjustment( SOLDIERTYPE* pSoldier, INT16 sGridNo = -1, INT8 bStance = -1 ); + //zilpin: pellet spread patterns externalized in XML #define SPREADPATTERN_NAME_SIZE 32 enum SpreadPatternMethod_enum diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index f55dd615..0aa5b286 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -1259,11 +1259,9 @@ void GetTBMousePositionInput( UINT32 *puiNewEvent ) } usOldMapPos = sMapPos; - } } - void GetPolledKeyboardInput( UINT32 *puiNewEvent ) { static BOOLEAN fShifted = FALSE; @@ -1382,32 +1380,32 @@ void GetPolledKeyboardInput( UINT32 *puiNewEvent ) if( _KeyDown( DEL ) ) { - DisplayCoverOfSelectedGridNo( ); + DisplayCover(TRUE); fDeleteDown = TRUE; } if( !_KeyDown( DEL ) && fDeleteDown ) { - RemoveCoverOfSelectedGridNo(); + //EMPTY fDeleteDown = FALSE; } if( _KeyDown( END ) ) { - DisplayGridNoVisibleToSoldierGrid( ); + //EMPTY fEndDown = TRUE; } if( !_KeyDown( END ) && fEndDown ) { - RemoveVisibleGridNoAtSelectedGridNo(); + //EMPTY + SwitchCoverDrawMode(); fEndDown = FALSE; } - } @@ -3774,11 +3772,11 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) //if the display cover or line of sight is being displayed if( _KeyDown( END ) || _KeyDown( DEL ) ) { - if( _KeyDown( DEL ) ) - ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover + 1 ); + //f( _KeyDown( DEL ) ) + //ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover + 1 ); - if( _KeyDown( END ) ) - ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS + 1 ); + //if( _KeyDown( END ) ) + //ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS + 1 ); } else { @@ -4020,11 +4018,11 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) //if the display cover or line of sight is being displayed if( _KeyDown( END ) || _KeyDown( DEL ) ) { - if( _KeyDown( DEL ) ) - ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover - 1 ); + //if( _KeyDown( DEL ) ) + //ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover - 1 ); - if( _KeyDown( END ) ) - ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS - 1 ); + //if( _KeyDown( END ) ) + //ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS - 1 ); } else { diff --git a/Utils/_Ja25ChineseText.cpp b/Utils/_Ja25ChineseText.cpp index 4a104139..fec085ef 100644 --- a/Utils/_Ja25ChineseText.cpp +++ b/Utils/_Ja25ChineseText.cpp @@ -25,7 +25,7 @@ STR16 zNewTacticalMessages[]= L"For a limited time, the above fee covers the cost of the entire mission and includes the equipment listed below.", L"Hire %s now and take advantage of our unprecedented 'one fee covers all' pricing. Also included in this unbelievable offer is the mercenary's personal equipment at no charge.", */ - L"目标的距离: %d格, 亮度: %d/%d", + //L"目标的距离: %d格, 亮度: %d/%d", L"将发报机装到笔记本电脑上。", L"你无法支付雇佣%s的费用", L"在限定时间内,以上的费用包括了整个行动和下列装备的花费。", @@ -39,7 +39,7 @@ STR16 zNewTacticalMessages[]= */ L"费用", L"在本分区发现有人……", - L"枪的射程: %d格, 命中率: %d%", + //L"枪的射程: %d格, 命中率: %d%", L"显示覆盖物", L"视距", @@ -105,5 +105,20 @@ STR16 gzIronManModeWarningText[]= L"你选择了铁人模式。这将会游戏变得相当有挑战性,因为你无法在敌人占据的分区存档。 这个设置会影响游戏的整个进程。你确认你要在铁人模式下进行游戏吗?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25DutchText.cpp b/Utils/_Ja25DutchText.cpp index b5abdf93..820c8af4 100644 --- a/Utils/_Ja25DutchText.cpp +++ b/Utils/_Ja25DutchText.cpp @@ -18,14 +18,14 @@ void this_is_the_Ja25DutchText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Range to target: %d tiles, Brightness: %d/%d", + //L"Range to target: %d tiles, Brightness: %d/%d", L"Attaching the transmitter to your laptop computer.", L"You cannot afford to hire %s", L"For a limited time, the above fee covers the cost of the entire mission and includes the equipment listed below.", L"Hire %s now and take advantage of our unprecedented 'one fee covers all' pricing. Also included in this unbelievable offer is the mercenary's personal equipment at no charge.", L"Fee", L"There is someone else in the sector...", - L"Gun Range: %d tiles, Chance to hit: %d percent", + //L"Gun Range: %d tiles, Chance to hit: %d percent", L"Display Cover", L"Line of Sight", L"New Recruits cannot arrive there.", @@ -70,5 +70,20 @@ STR16 gzIronManModeWarningText[]= L"You have chosen IRON MAN mode. This setting makes the game considerably more challenging as you will not be able to save your game when in a sector occupied by enemies. This setting will affect the entire course of the game. Are you sure want to play in IRON MAN mode?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25DutchText.h b/Utils/_Ja25DutchText.h index 3df69617..c621b858 100644 --- a/Utils/_Ja25DutchText.h +++ b/Utils/_Ja25DutchText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + // TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25EnglishText.cpp b/Utils/_Ja25EnglishText.cpp index 10dad350..42a2ee2a 100644 --- a/Utils/_Ja25EnglishText.cpp +++ b/Utils/_Ja25EnglishText.cpp @@ -18,14 +18,14 @@ void this_is_the_Ja25EnglishText_public_symbol(void); STR16 zNewTacticalMessages[]= { - L"Range to target: %d tiles, Brightness: %d/%d", + //L"Range to target: %d tiles, Brightness: %d/%d", L"Attaching the transmitter to your laptop computer.", L"You cannot afford to hire %s", L"For a limited time, the above fee covers the cost of the entire mission and includes the equipment listed below.", L"Hire %s now and take advantage of our unprecedented 'one fee covers all' pricing. Also included in this unbelievable offer is the mercenary's personal equipment at no charge.", L"Fee", L"There is someone else in the sector...", - L"Gun Range: %d tiles, Chance to hit: %d percent", + //L"Gun Range: %d tiles, Chance to hit: %d percent", L"Display Cover", L"Line of Sight", L"New Recruits cannot arrive there.", @@ -70,5 +70,19 @@ STR16 gzIronManModeWarningText[]= L"You have chosen IRON MAN mode. This setting makes the game considerably more challenging as you will not be able to save your game when in a sector occupied by enemies. This setting will affect the entire course of the game. Are you sure want to play in IRON MAN mode?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; #endif diff --git a/Utils/_Ja25EnglishText.h b/Utils/_Ja25EnglishText.h index a7553001..96c204fd 100644 --- a/Utils/_Ja25EnglishText.h +++ b/Utils/_Ja25EnglishText.h @@ -1,17 +1,17 @@ -#ifndef _JA25ENGLISHTEXT__H_ + #ifndef _JA25ENGLISHTEXT__H_ #define _JA25ENGLISHTEXT__H_ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, // CPT: not used anymore moved to other array TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, // CPT: not used, moved to other array //TCTL_MSG__RANGE_TO_TARGET_AND_GUN_RANGE, // WANNE: Not used TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, @@ -39,6 +39,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25FrenchText.cpp b/Utils/_Ja25FrenchText.cpp index a4b45bc6..72ac7557 100644 --- a/Utils/_Ja25FrenchText.cpp +++ b/Utils/_Ja25FrenchText.cpp @@ -19,14 +19,14 @@ void this_is_the_Ja25FrenchText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Distance cible: %d tiles, Brightness: %d/%d", + //L"Distance cible: %d tiles, Brightness: %d/%d", L"Attache le transpondeur votre PC portable.", L"Vous n'avez pas les moyens d'engager %s", L"Pour une dure limite, les frais ci-dessus couvrent la mission entire, quipement ci-dessous compris.", L"Engagez %s et dcouvrez ds prsent notre prix \"tout compris\". Aussi inclus dans cette incroyable offerte l'quipement personnel du mercenaire sans frais supplmentaires.", L"Frais", L"Il y a quelqu'un d'autre dans le secteur...", - L"Porte arme: %d tiles, Probabilits: %d pourcent", + //L"Porte arme: %d tiles, Probabilits: %d pourcent", L"Afficher couverture", L"Ligne de vision", L"Les nouvelles recrues ne peuvent arriver ici.", @@ -71,5 +71,20 @@ STR16 gzIronManModeWarningText[]= L"Vous avez choisi le mode IRON MAN. La difficulte du jeu s'en trouveras considerablement augmente du fait de l'imposssiblit de sauvegarder en territoire ennemi. Ce paramtre prendra effet tout au long de la partie. Etes vous vraiment sr de vouloir jouer en mode IRON MAN ?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25FrenchText.h b/Utils/_Ja25FrenchText.h index 3df69617..ad44a04c 100644 --- a/Utils/_Ja25FrenchText.h +++ b/Utils/_Ja25FrenchText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25GermanText.cpp b/Utils/_Ja25GermanText.cpp index a1f1211b..f60b895c 100644 --- a/Utils/_Ja25GermanText.cpp +++ b/Utils/_Ja25GermanText.cpp @@ -17,14 +17,14 @@ void this_is_the_Ja25GermanText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Entfernung zum Ziel: %d Felder, Helligkeit: %d/%d", + //L"Entfernung zum Ziel: %d Felder, Helligkeit: %d/%d", L"Verbinden Sie den Transmitter mit Ihrem Laptop-Computer.", L"Sie haben nicht genug Geld, um %s anzuheuern", L"Das obenstehende Honorar deckt fr einen begrenzten Zeitraum die Kosten der Gesamtmission, und schliet untenstehendes Equipment mit ein.", L"Engagieren Sie %s jetzt und nutzen Sie den Vorteil unseres beispiellosen 'Ein Betrag fr alles'-Honorars. Das persnliche Equipment des Sldners ist gratis in diesem Preis mit inbegriffen.", L"Honorar", L"Da ist noch jemand im Sektor...", - L"Waffen-Rchwt.: %d Felder, Trefferwahrsch.: %d Prozent", + //L"Waffen-Rchwt.: %d Felder, Trefferwahrsch.: %d Prozent", L"Deckung anzeigen", L"Sichtfeld", L"Neue Rekruten knnen dort nicht hinkommen.", @@ -70,5 +70,20 @@ STR16 gzIronManModeWarningText[]= L"Sie haben sich fr den Ironman- Modus entschieden. Mit dieser Einstellung knnen Sie das Spiel nicht speichern, wenn Feinde im Sektor sind. Sind Sie sicher, dass Sie im Ironman- Modus spielen wollen?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif \ No newline at end of file diff --git a/Utils/_Ja25GermanText.h b/Utils/_Ja25GermanText.h index 3daff5ab..fe13b484 100644 --- a/Utils/_Ja25GermanText.h +++ b/Utils/_Ja25GermanText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, //TCTL_MSG__RANGE_TO_TARGET_AND_GUN_RANGE, // WANNE: Not used TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, @@ -39,6 +39,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25ItalianText.cpp b/Utils/_Ja25ItalianText.cpp index 7f3909b5..11ea1e54 100644 --- a/Utils/_Ja25ItalianText.cpp +++ b/Utils/_Ja25ItalianText.cpp @@ -19,14 +19,14 @@ void this_is_the_Ja25ItalianText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Distanza dal bersaglio: %d caselle, Luminosit: %d/%d", + //L"Distanza dal bersaglio: %d caselle, Luminosit: %d/%d", L"Colleghi il trasmettitore al tuo computer portatile.", L"Non puoi permetterti di ingaggiare %s", L"Per un periodo limitato, la tariffa qui sopra includer i costi dell'intera missione, oltre all'equipaggiamento indicato sotto.", L"Assolda %s adesso e approfitta della nostra nuova tariffa 'tutto incluso'. Compreso in questa incredibile offerta anche l'equipaggiamento personale del mercenario, senza alcun costo aggiuntivo.", L"Tariffa", L"C' qualcun altro nel settore...", - L"Gittata dell'arma: %d caselle, Probabilit di colpire: %d percent", + //L"Gittata dell'arma: %d caselle, Probabilit di colpire: %d percent", L"Mostra nascondigli", L"Linea di Vista", L"Le nuove reclute non possono arrivare qui.", @@ -71,5 +71,20 @@ STR16 gzIronManModeWarningText[]= L"Hai scelto la modalit IRON MAN. Questa impostazione rende il gioco notevolmente pi impegnativo, poich non potrai salvare la partita in un settore occupato da nemici. Non potrai cambiare questa decisione nel corso della partita. Sei sicuro di voler giocare al livello IRON MAN?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25ItalianText.h b/Utils/_Ja25ItalianText.h index 3df69617..ad44a04c 100644 --- a/Utils/_Ja25ItalianText.h +++ b/Utils/_Ja25ItalianText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25PolishText.cpp b/Utils/_Ja25PolishText.cpp index 3c997671..9413b62f 100644 --- a/Utils/_Ja25PolishText.cpp +++ b/Utils/_Ja25PolishText.cpp @@ -19,14 +19,14 @@ void this_is_the_Ja25PolishText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Odlego od celu (w polach): %d, Jasno = %d/%d", + //L"Odlego od celu (w polach): %d, Jasno = %d/%d", L"Nadajnik zosta podczony do twojego laptopa.", L"Nie moesz zatrudni %s(a)", L"Na okrelony czas, ponisze honorarium pokryje koszt caej misji razem z wyposaeniem zamieszonym poniej.", L"Zatrudnij %s(a) ju teraz i we udzia naszej promocji 'jedno honorarium pokrywa wszystko'. Ponadto w tej niewiarygodnej ofercie cay ekwipunek najemnika dostaniesz za darmo.", L"Honorarium", L"Kto jest w sektorze...", - L"Zasig broni (w polach): %d, Szansa na trafienie: %d procent", + //L"Zasig broni (w polach): %d, Szansa na trafienie: %d procent", L"Poka oson", L"Zasig wzroku", L"Nowi rekruci nie mog tam przyby.", @@ -71,5 +71,20 @@ STR16 gzIronManModeWarningText[]= L"Wybrae tryb CZOWIEK ZE STALI. Opcja ta sprawi, e gra bdzie duo trudniejsza poniewa nie bdzie moliwoci zapisywania gry podczas walki. Bdzie to miao wpyw na cay przebieg rozgrywki. Czy na pewno chcesz gra w trybie CZOWIEK ZE STALI?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25PolishText.h b/Utils/_Ja25PolishText.h index 3df69617..ad44a04c 100644 --- a/Utils/_Ja25PolishText.h +++ b/Utils/_Ja25PolishText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25RussianText.cpp b/Utils/_Ja25RussianText.cpp index 3a1ccb4d..a7ebbc3c 100644 --- a/Utils/_Ja25RussianText.cpp +++ b/Utils/_Ja25RussianText.cpp @@ -17,14 +17,14 @@ void this_is_the_Ja25RussianText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L" : %d ., : %d/%d", + //L" : %d ., : %d/%d", L" .", L" %s", L" , , .", L" %s - ' '. .", L"", L" - ...", - L" : %d ., : %d%%", + //L" : %d ., : %d%%", L" ", L" ", L" .", @@ -70,5 +70,20 @@ STR16 gzIronManModeWarningText[]= L" \" \". , , . . , \" \"?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25RussianText.h b/Utils/_Ja25RussianText.h index 3df69617..ad44a04c 100644 --- a/Utils/_Ja25RussianText.h +++ b/Utils/_Ja25RussianText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif diff --git a/Utils/_Ja25TaiwaneseText.cpp b/Utils/_Ja25TaiwaneseText.cpp index 82652386..66632e99 100644 --- a/Utils/_Ja25TaiwaneseText.cpp +++ b/Utils/_Ja25TaiwaneseText.cpp @@ -18,14 +18,14 @@ void this_is_the_Ja25TaiwaneseText_public_symbol(void){;} STR16 zNewTacticalMessages[]= { - L"Range to target: %d tiles, Brightness: %d/%d", + //L"Range to target: %d tiles, Brightness: %d/%d", L"Attaching the transmitter to your laptop computer.", L"You cannot afford to hire %s", L"For a limited time, the above fee covers the cost of the entire mission and includes the equipment listed below.", L"Hire %s now and take advantage of our unprecedented 'one fee covers all' pricing. Also included in this unbelievable offer is the mercenary's personal equipment at no charge.", L"Fee", L"There is someone else in the sector...", - L"Gun Range: %d tiles, Chance to hit: %d percent", + //L"Gun Range: %d tiles, Chance to hit: %d percent", L"Display Cover", L"Line of Sight", L"New Recruits cannot arrive there.", @@ -70,5 +70,20 @@ STR16 gzIronManModeWarningText[]= L"You have chosen IRON MAN mode. This setting makes the game considerably more challenging as you will not be able to save your game when in a sector occupied by enemies. This setting will affect the entire course of the game. Are you sure want to play in IRON MAN mode?", }; +STR16 gzDisplayCoverText[]= +{ + L"Cover: %d/100 %s, Brightness: %d/100", + L"Gun Range: %d/%d tiles, Chance to hit: %d/100", + L"Disabling Cover Display", + L"Showing Mercenary View", + L"Showing Cover for Mercenary", + L"Wood", // wanted to use jungle , but wood is shorter in german too (dschungel vs wald) + L"Urban", + L"Desert", + L"Snow", // NOT USED!!! + L"Wood and Desert", + L"" // yes empty for now +}; + #endif diff --git a/Utils/_Ja25TaiwaneseText.h b/Utils/_Ja25TaiwaneseText.h index 3df69617..ad44a04c 100644 --- a/Utils/_Ja25TaiwaneseText.h +++ b/Utils/_Ja25TaiwaneseText.h @@ -4,14 +4,14 @@ enum { - TCTL_MSG__RANGE_TO_TARGET, + //TCTL_MSG__RANGE_TO_TARGET, TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP, TACT_MSG__CANNOT_AFFORD_MERC, TACT_MSG__AIMMEMBER_FEE_TEXT, TACT_MSG__AIMMEMBER_ONE_TIME_FEE, TACT_MSG__FEE, TACT_MSG__SOMEONE_ELSE_IN_SECTOR, - TCTL_MSG__GUN_RANGE_AND_CTH, + //TCTL_MSG__GUN_RANGE_AND_CTH, TCTL_MSG__DISPLAY_COVER, TCTL_MSG__LOS, TCTL_MSG__INVALID_DROPOFF_SECTOR, @@ -38,6 +38,24 @@ enum }; extern STR16 gzIronManModeWarningText[]; +// display cover message (for tactical usually, seperated) +// display cover terrain type info (used in cover information) +enum +{ + DC_MSG__COVER_INFORMATION, + DC_MSG__GUN_RANGE_INFORMATION, + DC_MSG__COVER_DRAW_OFF, + DC_MSG__COVER_DRAW_MERC_VIEW, + DC_MSG__COVER_DRAW_ENEMY_VIEW, + DC_TTI__WOOD, + DC_TTI__URBAN, + DC_TTI__DESERT, + DC_TTI__SNOW, + DC_TTI__WOOD_AND_DESERT, + DC_TTI__UNKNOWN +}; +extern STR16 gzDisplayCoverText[]; + #endif