From 534af956c8bed473f084f1ad3be636eecc1a26b0 Mon Sep 17 00:00:00 2001 From: Wanne Date: Tue, 10 Dec 2013 11:04:59 +0000 Subject: [PATCH] Small visual changes (by Sevenfm) see: http://www.bears-pit.com/board/ubbthreads.php/topics/172712/16/Code_Snippets.html 1) ENEMY_HIT_COUNT in ja2_options.ini accepts 2 new parameters: 3 - show damage as white asterisks 4 - show damage as red asterisks Number of asterisks is scaled (maximum 5): >0, >10, >30, >60, >100 2) Suppression tactical tooltip now shows suppression points from last attacks. Previously it was always = 0 because ubSuppressionPoints value is cleared after each attack. 3) It is now possible to show suppression values above soldier, just as hit count. There are new options in ja2_options.ini Possible values: 0 - do not show 1 - show on moving hit counter 2 - show above soldier The values are color coded: Suppression is light gray Shock is yellow AP loss is blue Morale hit is green SHOW_SUPPRESSION_COUNT = 0 SHOW_SHOCK_COUNT = 0 SHOW_AP_COUNT = 0 SHOW_MORALE_COUNT = 0 This option defines if values are shown as numbers or asterisks (1..5, using scale) SHOW_SUPPRESSION_USE_ASTERISK = FALSE This option defines if only 1 asterisk is shown or several (1..5) to represent value SHOW_SUPPRESSION_SCALE_ASTERISK = TRUE Show suppression above soldier during enemy attack. All other values are shown after attack, when HandleSuppressionFire function is calculated. SHOW_SUPPRESSION_COUNT_ALT = TRUE git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6689 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 11 +- GameSettings.h | 9 ++ SaveLoadGame.cpp | 10 ++ Tactical/Interface Control.cpp | 236 ++++++++++++++++++++++++++++++++- Tactical/Interface Control.h | 19 +++ Tactical/Overhead.cpp | 41 +++++- Tactical/Soldier Control.cpp | 56 +++++++- Tactical/Soldier Control.h | 11 ++ Tactical/SoldierTooltips.cpp | 4 +- 9 files changed, 389 insertions(+), 8 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 23ac3f2d..d1dd0c57 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1029,7 +1029,16 @@ void LoadGameExternalOptions() gGameExternalOptions.fShowHealthBarsOnHead = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_HEALTHBARSOVERHEAD", TRUE); // WANNE: Hide the hit count when enemy gets hit - gGameExternalOptions.ubEnemyHitCount = iniReader.ReadInteger("Tactical Interface Settings","ENEMY_HIT_COUNT", 0, 0, 2); + gGameExternalOptions.ubEnemyHitCount = iniReader.ReadInteger("Tactical Interface Settings","ENEMY_HIT_COUNT", 0, 0, 4); + + // sevenfm: show additional suppression info above soldier + gGameExternalOptions.ubShowSuppressionCount = iniReader.ReadInteger("Tactical Interface Settings","SHOW_SUPPRESSION_COUNT", 0, 0, 2); + gGameExternalOptions.ubShowShockCount = iniReader.ReadInteger("Tactical Interface Settings","SHOW_SHOCK_COUNT", 0, 0, 2); + gGameExternalOptions.ubShowAPCount = iniReader.ReadInteger("Tactical Interface Settings","SHOW_AP_COUNT", 0, 0, 2); + gGameExternalOptions.ubShowMoraleCount = iniReader.ReadInteger("Tactical Interface Settings","SHOW_MORALE_COUNT", 0, 0, 2); + gGameExternalOptions.ubShowSuppressionUseAsterisks = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_SUPPRESSION_USE_ASTERISK", FALSE); + gGameExternalOptions.ubShowSuppressionCountAlt = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_SUPPRESSION_COUNT_ALT", FALSE); + gGameExternalOptions.ubShowSuppressionScaleAsterisk = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_SUPPRESSION_SCALE_ASTERISK", FALSE); //################# Tactical Difficulty Settings ################# diff --git a/GameSettings.h b/GameSettings.h index b7951711..905c9fd6 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1198,6 +1198,15 @@ typedef struct UINT8 ubEnemyHitCount; + // sevenfm: new additional info above soldier + UINT8 ubShowSuppressionCount; + UINT8 ubShowShockCount; + UINT8 ubShowAPCount; + UINT8 ubShowMoraleCount; + BOOLEAN ubShowSuppressionUseAsterisks; + BOOLEAN ubShowSuppressionCountAlt; + BOOLEAN ubShowSuppressionScaleAsterisk; + FLOAT gMercLevelUpSalaryIncreasePercentage; UINT8 ubChanceTonyAvailable; // silversurfer/SANDRO diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index a72cc78b..13e6e006 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -2603,6 +2603,16 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile) */ //assume checksum is ok } + + // sevenfm: initialize other SOLDIERTYPE data + this->ubLastShock=0; + this->ubLastSuppression=0; + this->ubLastAP=0; + this->ubLastMorale=0; + this->ubLastShockFromHit=0; + this->ubLastAPFromHit=0; + this->ubLastMoraleFromHit=0; + return TRUE; } diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp index 86db69a6..0d4eab87 100644 --- a/Tactical/Interface Control.cpp +++ b/Tactical/Interface Control.cpp @@ -738,13 +738,81 @@ void RenderTopmostTacticalInterface( ) DrawSelectedUIAboveGuy((UINT16)pSoldier->ubID); } - if ( pSoldier->flags.fDisplayDamage ) - { - // Display damage - // Use world coordinates! INT16 sMercScreenX, sMercScreenY, sOffsetX, sOffsetY, sDamageX, sDamageY; + // sevenfm: added for suppression counters + INT16 sSuppressionX, sSuppressionY; + UINT16 widthDamage = 0; + UINT16 widthSuppression = 0; + UINT16 height = 0; + BOOLEAN printDamage = FALSE; // determines if any value is printed after standart moving damage counter + BOOLEAN printSuppression = FALSE; // determines if any value is printed above soldier (only for new suppression counters) + + if ( gGameExternalOptions.ubShowSuppressionCount == 1 || + gGameExternalOptions.ubShowShockCount == 1 || + gGameExternalOptions.ubShowAPCount == 1 || + gGameExternalOptions.ubShowMoraleCount == 1 ) + printDamage = TRUE; + if ( gGameExternalOptions.ubShowSuppressionCountAlt || + gGameExternalOptions.ubShowSuppressionCount == 2 || + gGameExternalOptions.ubShowShockCount == 2 || + gGameExternalOptions.ubShowAPCount == 2 || + gGameExternalOptions.ubShowMoraleCount == 2 ) + printSuppression = TRUE; + + if (!TileIsOutOfBounds(pSoldier->sGridNo) && pSoldier->bVisible != -1 ) + { + // coordinates for suppression counter + GetSoldierScreenPos( pSoldier, &sMercScreenX, &sMercScreenY ); + GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY ); + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + sSuppressionX = sMercScreenX - pSoldier->sBoundingBoxOffsetX; + sSuppressionY = sMercScreenY - pSoldier->sBoundingBoxOffsetY; + sSuppressionX += 25; + sSuppressionY += 10; + } + else + { + sSuppressionX = sOffsetX + (INT16)(sMercScreenX + ( 2 * 30 / 3 ) ); + sSuppressionY = sOffsetY + (INT16)(sMercScreenY - 5 ); + sSuppressionX -= sOffsetX; + sSuppressionY -= sOffsetY; + if ( sSuppressionY < gsVIEWPORT_WINDOW_START_Y ) + { + sSuppressionY = ( sMercScreenY - sOffsetY ); + } + } + // if showing suppression - move damage counter higher on screen + //if( printSuppression) + // height = WFGetFontHeight ( TINYFONT1 ); + + // print current ubSuppressionPoints counter + if( gGameExternalOptions.ubShowSuppressionCountAlt && pSoldier->stats.bLife >= OKLIFE ) + { + if( pSoldier->ubSuppressionPoints >0 ) + { + UINT8 scale = PRINT_SCALE_PLAIN_NUMBER; + if( gGameExternalOptions.ubShowSuppressionUseAsterisks ) + { + // print multi asterisk only if no other suppression counter will be printed + /*if ( gGameExternalOptions.ubShowShockCount <2 && + gGameExternalOptions.ubShowAPCount <2 && + gGameExternalOptions.ubShowMoraleCount <2 ) + scale = PRINT_SCALE_ASTERISK_SUPPRESSION; + else + scale = PRINT_SCALE_ASTERISK;*/ + scale = PRINT_SCALE_ASTERISK_SUPPRESSION; + } + PrintSuppressionCounter( sSuppressionX, sSuppressionY, pSoldier->ubSuppressionPoints, widthSuppression, FONT_MCOLOR_LTGRAY, scale ); + } + } + } + + if ( pSoldier->flags.fDisplayDamage ) + { + // Display damage if (!TileIsOutOfBounds(pSoldier->sGridNo) && pSoldier->bVisible != -1 ) { GetSoldierScreenPos( pSoldier, &sMercScreenX, &sMercScreenY ); @@ -771,8 +839,12 @@ void RenderTopmostTacticalInterface( ) sDamageY = ( sMercScreenY - sOffsetY ); } } + // if showing suppression - move damage counter higher on screen + if( printSuppression) + sDamageY -= WFGetFontHeight ( TINYFONT1 ); SetFont( TINYFONT1 ); + SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( FONT_MCOLOR_WHITE ); @@ -784,17 +856,33 @@ void RenderTopmostTacticalInterface( ) { if ( pSoldier->sDamage >= 0 ) { + // print moving damage counter + if( pSoldier->sDamage > 0 ) + { + if ( printDamage ) + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->sDamage, widthDamage, FONT_MCOLOR_WHITE, PRINT_SCALE_PLAIN_NUMBER ); + else // original code + { gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage ); mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage ); + } + } } else // Flugente: it is possible that someone might regain negative damage as zombies can regenerate health through bleeding { + if( printDamage ) + { + PrintSuppressionCounter( sDamageX, sDamageY, -pSoldier->sDamage, widthDamage, FONT_MCOLOR_LTGREEN, PRINT_SCALE_PLAIN_NUMBER ); + } + else // original code + { SetFontForeground( FONT_MCOLOR_LTGREEN ); gprintfdirty( sDamageX, sDamageY, L"+%d", -pSoldier->sDamage ); mprintf( sDamageX, sDamageY, L"+%d", -pSoldier->sDamage ); SetFontForeground( FONT_MCOLOR_WHITE ); } } + } else { if (gGameExternalOptions.ubEnemyHitCount == 1) @@ -802,16 +890,58 @@ void RenderTopmostTacticalInterface( ) gprintfdirty( sDamageX, sDamageY, L"%s", gzHiddenHitCountStr[0]); mprintf( sDamageX, sDamageY, L"%s", gzHiddenHitCountStr[0]); } + else if (gGameExternalOptions.ubEnemyHitCount == 3) // print white asterisks + { + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->sDamage, widthDamage, FONT_MCOLOR_WHITE, PRINT_SCALE_ASTERISK_DAMAGE ); + } + else if (gGameExternalOptions.ubEnemyHitCount == 4) // print red asterisks + { + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->sDamage, widthDamage, FONT_MCOLOR_DKRED, PRINT_SCALE_ASTERISK_DAMAGE ); + } else { gprintfdirty( sDamageX, sDamageY, L""); mprintf( sDamageX, sDamageY, L""); } } + if ( pSoldier->stats.bLife >= OKLIFE ) + { + // replace ubLastSuppression count on screen + if( gGameExternalOptions.ubShowSuppressionCountAlt && gGameExternalOptions.ubShowSuppressionCount == 2 && pSoldier->ubLastSuppression > 0 ) + widthSuppression = 0; + // display suppression from last attack + if( gGameExternalOptions.ubShowSuppressionCount == 1 ) // show after damage counter + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->ubLastSuppression, widthDamage, FONT_MCOLOR_LTGRAY, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_SUPPRESSION : PRINT_SCALE_PLAIN_NUMBER ); + if( gGameExternalOptions.ubShowSuppressionCount == 2 ) // show after suppression counter + PrintSuppressionCounter( sSuppressionX, sSuppressionY, pSoldier->ubLastSuppression, widthSuppression, FONT_MCOLOR_LTGRAY, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_SUPPRESSION : PRINT_SCALE_PLAIN_NUMBER ); + // display shock from last attack + if( gGameExternalOptions.ubShowShockCount == 1 ) // show after damage counter + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->ubLastShock + pSoldier->ubLastShockFromHit, widthDamage, FONT_MCOLOR_LTYELLOW, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_SHOCK : PRINT_SCALE_PLAIN_NUMBER ); + if( gGameExternalOptions.ubShowShockCount == 2 ) // show after suppression counter + PrintSuppressionCounter( sSuppressionX, sSuppressionY, pSoldier->ubLastShock + pSoldier->ubLastShockFromHit, widthSuppression, FONT_MCOLOR_LTYELLOW, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_SHOCK : PRINT_SCALE_PLAIN_NUMBER ); + // display morale hit from last attack + if( gGameExternalOptions.ubShowMoraleCount == 1 ) // show after damage counter + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->ubLastMorale + pSoldier->ubLastMoraleFromHit, widthDamage, FONT_MCOLOR_LTGREEN, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_MORALE : PRINT_SCALE_PLAIN_NUMBER ); + if( gGameExternalOptions.ubShowMoraleCount == 2 ) // show after suppression counter + PrintSuppressionCounter( sSuppressionX, sSuppressionY, pSoldier->ubLastMorale + pSoldier->ubLastMoraleFromHit, widthSuppression, FONT_MCOLOR_LTGREEN, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_MORALE : PRINT_SCALE_PLAIN_NUMBER ); + // display AP loss from last attack + if( gGameExternalOptions.ubShowAPCount == 1 ) // show after damage counter + PrintSuppressionCounter( sDamageX, sDamageY, pSoldier->ubLastAP + pSoldier->ubLastAPFromHit, widthDamage, FONT_MCOLOR_LTBLUE, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_AP : PRINT_SCALE_PLAIN_NUMBER ); + if( gGameExternalOptions.ubShowAPCount == 2 ) // show after suppression counter + PrintSuppressionCounter( sSuppressionX, sSuppressionY, pSoldier->ubLastAP + pSoldier->ubLastAPFromHit, widthSuppression, FONT_MCOLOR_LTBLUE, + gGameExternalOptions.ubShowSuppressionUseAsterisks ? PRINT_SCALE_ASTERISK_AP : PRINT_SCALE_PLAIN_NUMBER ); } } } } + } if ( gusSelectedSoldier != NOBODY ) { @@ -1120,3 +1250,101 @@ BOOLEAN InterfaceOKForMeanwhilePopup() return( TRUE ); } + +void PrintSuppressionCounter( INT16 x, INT16 y, INT16 data, UINT16 &width, UINT8 ubForegound, UINT8 scale ) +{ + CHAR16 pStr[100]; + UINT8 num = 0; + UINT8 i; + + if( data == 0) + return; + + switch ( scale ) + { + case PRINT_SCALE_ASTERISK_SUPPRESSION: + num = CalcScaleSuppression( data ); + break; + case PRINT_SCALE_ASTERISK_DAMAGE: + num = CalcScaleDamage( data ); + break; + case PRINT_SCALE_ASTERISK_MORALE: + num = CalcScaleMorale( data ); + break; + case PRINT_SCALE_ASTERISK_AP: + num = CalcScaleAP( data ); + break; + case PRINT_SCALE_ASTERISK_SHOCK: + num = CalcScaleShock( data ); + break; + default: + num = 1; + } + if ( !gGameExternalOptions.ubShowSuppressionScaleAsterisk ) + num = 1; + + SetFontBackground( FONT_MCOLOR_BLACK ); + SetFontForeground( ubForegound ); + // scale = 0 - print numbers + // scale = 1 - print one asterisk + // scale > 1 - print num asterisks + if( scale > PRINT_SCALE_PLAIN_NUMBER ) + { + swprintf( pStr, L"*" ); + for ( i = 1; i 20 ) return 5; + if( data > 15 ) return 4; + if( data > 10 ) return 3; + if( data > 5 ) return 2; + return 1; +} + +UINT8 CalcScaleDamage( INT16 data ) +{ + if( data > 100 ) return 5; + if( data > 60 ) return 4; + if( data > 30 ) return 3; + if( data > 10 ) return 2; + return 1; +} + +UINT8 CalcScaleMorale( INT16 data ) +{ + return __min( 5, data ); +} +UINT8 CalcScaleAP( INT16 data ) +{ + if( data > 100 ) return 5; + if( data > 60 ) return 4; + if( data > 30 ) return 3; + if( data > 10 ) return 2; + return 1; +} +UINT8 CalcScaleShock( INT16 data ) +{ + if( data > 20 ) return 5; + if( data > 12 ) return 4; + if( data > 7 ) return 3; + if( data > 3 ) return 2; + return 1; +} diff --git a/Tactical/Interface Control.h b/Tactical/Interface Control.h index 898d3587..299ad7bf 100644 --- a/Tactical/Interface Control.h +++ b/Tactical/Interface Control.h @@ -42,5 +42,24 @@ void HandleTacticalPanelSwitch( ); BOOLEAN InterfaceOKForMeanwhilePopup(); +// sevenfm: these values are used to calculate scale for displaying values as asterisks (no more than 5 asterisks for any value) +enum{ + PRINT_SCALE_PLAIN_NUMBER, + PRINT_SCALE_ASTERISK, + PRINT_SCALE_ASTERISK_SUPPRESSION, + PRINT_SCALE_ASTERISK_DAMAGE, + PRINT_SCALE_ASTERISK_MORALE, + PRINT_SCALE_ASTERISK_AP, + PRINT_SCALE_ASTERISK_SHOCK, +}; +UINT8 CalcScaleSuppression( INT16 data ); +UINT8 CalcScaleDamage( INT16 data ); +UINT8 CalcScaleMorale( INT16 data ); +UINT8 CalcScaleAP( INT16 data ); +UINT8 CalcScaleShock( INT16 data ); + +// print counter as number or asterisks ( applying provided scale when displaying asterisks ) +// width is updated as X offset after printing +void PrintSuppressionCounter( INT16 x, INT16 y, INT16 data, UINT16 &width, UINT8 ubForegound, UINT8 scale = PRINT_SCALE_PLAIN_NUMBER ); #endif \ No newline at end of file diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 77146d4d..ca6a83ee 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -8246,8 +8246,12 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // To turn off the entire Suppression system, simply set the INI value to 0. (0% AP Loss) // The default is obviously 100%. You can increase or decrease it, at will. // PLEASE NOTE that AP loss governs ALL OTHER SUPPRESSION EFFECTS. - ubPointsLost = ( ubPointsLost * sFinalSuppressionEffectiveness ) / 100; + // sevenfm: commented out duplicated code: we don't want to apply ubFinalSuppressionEffectivness twice + // ubPointsLost = ( ubPointsLost * sFinalSuppressionEffectiveness ) / 100; + // This is an upper cap for the number of APs we can lose per attack. + // sevenfm: commented out duplicated code: + /* if (usLimitSuppressionAPsLostPerAttack > 0) { if (ubPointsLost > usLimitSuppressionAPsLostPerAttack) @@ -8257,6 +8261,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) ubPointsLost = __min(255,(UINT8)usLimitSuppressionAPsLostPerAttack); } } + */ // INI-Controlled intensity. SuppressionEffectiveness acts as a percentage applied to the number of lost APs. // To turn off the entire Suppression system, simply set the INI value to 0. (0% AP Loss) @@ -8290,6 +8295,8 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // difficult to perform certain manual tasks. Additionally, he also becomes harder to hit, because the fear // causes him to hide as best as he can from incoming fire. // Shock is sliced in half at the start of every turn. Also note that shock may cause "cowering" (see below). + + pSoldier->ubLastShock = 0; if (gGameExternalOptions.usSuppressionShockEffect > 0) { // Can't get shock if we haven't lost APs. @@ -8314,6 +8321,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // from suppression and/or wounds. It is possible to breach the maximum after a good suppressive // attack. + UINT8 oldShock = pSoldier->aiData.bShock; if ( pSoldier->aiData.bShock + bShockValue <= bShockLimit ) { // Shock limit not yet breached. Add shock to character. @@ -8324,6 +8332,8 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // Original shock was lower than the limit, so add extra shock and breach the limit. pSoldier->aiData.bShock = __min(127, pSoldier->aiData.bShock + bShockValue); } + // sevenfm: update ubLastShock + pSoldier->ubLastShock = __min(255, pSoldier->aiData.bShock - oldShock ); // Else, original shock was already over the limit. No more shock is added. } // HEADROCK: Cowering is the panic that grips a character due to suffering too much suppression shock. If @@ -8365,6 +8375,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) } } + pSoldier->ubLastMorale = 0; // Suppression reduces morale. For every X APs lost, morale goes down by a point. X is defined by INI. DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: check for morale effects")); if (APBPConstants[AP_LOST_PER_MORALE_DROP] > 0 && ubPointsLost > 0) @@ -8372,6 +8383,8 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) for ( ubLoop2 = 0; ubLoop2 < (ubPointsLost / APBPConstants[AP_LOST_PER_MORALE_DROP]); ubLoop2++ ) { HandleMoraleEvent( pSoldier, MORALE_SUPPRESSED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); + // sevenfm: update ubLastMorale + pSoldier->ubLastMorale++; } } @@ -8587,6 +8600,32 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) pSoldier->flags.fDontChargeAPsForStanceChange = TRUE; } + // sevenfm: update suppression, AP values for displaying above soldier + pSoldier->ubLastSuppression = pSoldier->ubSuppressionPoints; + pSoldier->ubLastAP = ubPointsLost; + + // add suppression valued from hit to shock valued calculated in this function + pSoldier->ubLastShock += pSoldier->ubLastShockFromHit; + pSoldier->ubLastShockFromHit = 0; + pSoldier->ubLastAP += pSoldier->ubLastAPFromHit; + pSoldier->ubLastAPFromHit = 0; + pSoldier->ubLastMorale += pSoldier->ubLastMoraleFromHit; + pSoldier->ubLastMoraleFromHit = 0; + + if( ubPointsLost > 0 ) + { + if( pSoldier->flags.fDisplayDamage ) + { + // prolongate damage show time + pSoldier->bDisplayDamageCount = 0; + } + else + { + // start new damage show counter + SetDamageDisplayCounter( pSoldier ); + } + } + // HEADROCK HAM 3.5: After sufficient testing, suppression clearing now works immediately at the end of // the attack. ubAPsLostToSuppression is only cleared at the end of the turn, but no longer plays a role // in affecting the number of APs lost, so it is largely irrelevant now. diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 8eee63f4..e3476f83 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -1027,6 +1027,15 @@ SOLDIERTYPE& SOLDIERTYPE::operator=(const OLDSOLDIERTYPE_101& src) this->usAISkillUse = 0; for (UINT8 i = 0; i < SOLDIER_COUNTER_MAX; ++i) this->usSkillCounter[i] = 0; for (UINT8 i = 0; i < SOLDIER_COOLDOWN_MAX; ++i) this->usSkillCooldown[i] = 0; + + this->ubLastShock = 0; + this->ubLastSuppression = 0; + this->ubLastAP = 0; + this->ubLastMorale = 0; + this->ubLastShockFromHit = 0; + this->ubLastMoraleFromHit = 0; + this->ubLastAPFromHit = 0; + } return *this; } @@ -5676,10 +5685,12 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1 if ( this->ubAttackerID != NOBODY && MercPtrs[ this->ubAttackerID ]->bTeam == gbPlayerNum ) { HandleMoraleEvent( MercPtrs[ this->ubAttackerID ], MORALE_DID_LOTS_OF_DAMAGE, MercPtrs[ this->ubAttackerID ]->sSectorX, MercPtrs[ this->ubAttackerID ]->sSectorY, MercPtrs[ this->ubAttackerID ]->bSectorZ ); + this->ubLastMoraleFromHit++; } if (this->bTeam == gbPlayerNum) { HandleMoraleEvent( this, MORALE_TOOK_LOTS_OF_DAMAGE, this->sSectorX, this->sSectorY, this->bSectorZ ); + this->ubLastMoraleFromHit++; } } @@ -7732,6 +7743,13 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou // HEADROCK HAM 3.5: After considerable testing, suppression is now cleared after every attack. Total APs lost // is cleared every turn (here) and only acts as reference now (no effect on AP loss). this->ubAPsLostToSuppression = 0; + this->ubLastShock = 0; + this->ubLastSuppression = 0; + this->ubLastAP = 0; + this->ubLastMorale = 0; + this->ubLastAPFromHit = 0; + this->ubLastShockFromHit = 0; + this->ubLastMoraleFromHit = 0; this->flags.fCloseCall = FALSE; @@ -9888,6 +9906,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo if ( !AM_A_ROBOT( this ) ) { DeductPoints( this, sAPCost, sBreathLoss, DISABLED_INTERRUPT ); + this->ubLastAPFromHit += sAPCost; } ubCombinedLoss = (UINT8) sLifeDeduct / 10 + sBreathLoss / 2000; @@ -9896,6 +9915,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo if ( !AM_A_ROBOT( this ) ) { this->aiData.bShock += ubCombinedLoss; + this->ubLastShockFromHit += ubCombinedLoss; } // start the stopwatch - the blood is gushing! @@ -9906,13 +9926,13 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo // If we are already dead, don't show damage! if ( bOldLife != 0 && fShowDamage && sLifeDeduct != 0 && sLifeDeduct < 1000 ) { + /* // Display damage INT16 sOffsetX, sOffsetY; // Set Damage display counter this->flags.fDisplayDamage = TRUE; this->bDisplayDamageCount = 0; - if ( this->ubBodyType == QUEENMONSTER ) { this->sDamageX = 0; @@ -9924,6 +9944,14 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo this->sDamageX = sOffsetX; this->sDamageY = sOffsetY; } + */ + // sevenfm: moved code to function + SetDamageDisplayCounter(this); + // zero suppression valued stored from last attack + this->ubLastShock = 0; + this->ubLastSuppression = 0; + this->ubLastMorale = 0; + this->ubLastAP = 0; } } @@ -21242,3 +21270,29 @@ BOOLEAN PlayerTeamIsScanning() return FALSE; } + +void SetDamageDisplayCounter(SOLDIERTYPE* pSoldier) +{ + INT16 sOffsetX, sOffsetY; + + if( pSoldier->flags.fDisplayDamage ) + { + return; + } + + pSoldier->flags.fDisplayDamage = TRUE; + pSoldier->bDisplayDamageCount = 0; + + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + pSoldier->sDamageX = 0; + pSoldier->sDamageY = 0; + } + else + { + GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY ); + pSoldier->sDamageX = sOffsetX; + pSoldier->sDamageY = sOffsetY; + } +} + diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 969d19f5..02434bd6 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1481,6 +1481,16 @@ public: INT32 sPlotSrcGrid; //std::vector CTH; + // sevenfm: remember suppression points, shock from last attack + // these counters are used only for showing suppression values above soldier (similar to damage counter) + // these values are not saved + UINT8 ubLastShock; + UINT8 ubLastSuppression; + UINT8 ubLastAP; + UINT8 ubLastMorale; + UINT8 ubLastShockFromHit; + UINT8 ubLastAPFromHit; + UINT8 ubLastMoraleFromHit; public: // CREATION FUNCTIONS @@ -2631,6 +2641,7 @@ public: void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReason ); +void SetDamageDisplayCounter(SOLDIERTYPE* pSoldier); #endif diff --git a/Tactical/SoldierTooltips.cpp b/Tactical/SoldierTooltips.cpp index 962ac3d0..fc8eef31 100644 --- a/Tactical/SoldierTooltips.cpp +++ b/Tactical/SoldierTooltips.cpp @@ -234,8 +234,10 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier ) //Moa: show shock and suppression values in debug tooltip if ( gGameExternalOptions.fEnableSoldierTooltipShock ) swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_SHOCK], pStrInfo, pSoldier->aiData.bShock ); + // sevenfm: ubSuppressionPoints always show 0 because this value is cleared after each attack + // changed this to ubLastSuppression - it stores suppression points from last attack if ( gGameExternalOptions.fEnableSoldierTooltipSuppressionPoints ) - swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_SUPPRESION], pStrInfo, pSoldier->ubSuppressionPoints ); + swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_SUPPRESION], pStrInfo, pSoldier->ubLastSuppression ); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Added by SANDRO - show enemy skills if ( gGameExternalOptions.fEnableSoldierTooltipTraits )