Files
source/Tactical/SoldierTooltips.cpp
T
Wanne f13a096f1e Merged from revision: 7129
Updates/Improvements (by Sevenfm)
1. Quick inventory items:
Press [ALT] + [1..0] for quick access to predefined items in tactical (ja2_options.ini: QUICK_ITEM_0 to QUICK_ITEM_9)

Press [ALT] + [`] (tilde key left to [1]) to put item back to inventory and switch hands.
The item will be put in the same slot it was taken from (unless it was stacked or game was reloaded).

2. Also a few quick hotkeys:
[ALT] + [q] - switch to sling (same as [SHIFT] + [k])
[CTRL] + [q] - switch hands
[SHIFT] + [q] - drop item from main hand to the ground

Additional info:
-some hotkeys do not work in cheat mode
-only NIV
-only one-handed items supported
-stacked items currently not supported
-remembered item slot is lost when you reload game

3. A few small fixes for dynamic tooltips and other things


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7130 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2014-03-31 09:33:51 +00:00

662 lines
27 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include "Types.h"
#include "Windows.h"
//#include "Soldier Control.h"
#include "Input.h"
#include "english.h"
#include "Isometric Utils.h"
#include "GameSettings.h"
#include "Overhead.h"
#include "Game Clock.h"
#include "Text.h"
#include "lighting.h"
#include "Interface.h"
#include "weapons.h"
#include "renderworld.h"
#include "Font Control.h"
#include "font.h"
#include "local.h"
#include "vsurface.h"
#include "line.h"
#include "los.h"
// added by SANDRO
#include "SkillCheck.h"
#include "soldier profile type.h"
#include "Soldier macros.h"
#include "Encyclopedia_new.h" ///< Encyclopedia item visibility
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
struct MOUSETT
{
CHAR16 FastHelpText[ 1024 ];
INT32 iX;
INT32 iY;
INT32 iW;
};
extern struct MOUSETT mouseTT;
extern BOOL mouseTTrender,mouseTTdone;
const int DL_Limited = 1;
const int DL_Basic = 2;
const int DL_Full = 3;
const int DL_Debug = 4;
void DisplayWeaponInfo( SOLDIERTYPE*, CHAR16*, UINT8, UINT8 );
void DrawMouseTooltip(void);
#define MAX(a, b) (a > b ? a : b)
void SoldierTooltip( SOLDIERTYPE* pSoldier )
{
if(!pSoldier)
return;
// WANNE: No tooltips on bloodcats, bugs, tanks, roboter
if ( CREATURE_OR_BLOODCAT( pSoldier ) || TANK ( pSoldier ) ||
AM_A_ROBOT( pSoldier))
{
return;
}
SGPRect aRect;
extern void GetSoldierScreenRect(SOLDIERTYPE*,SGPRect*);
GetSoldierScreenRect( pSoldier, &aRect );
INT16 a1,a2;
BOOLEAN fDrawTooltip = FALSE;
// sevenfm: do not show tooltip if ALT is pressed for adding autofire bullets
// EDIT: commented this out because with default autofire bullets> 1 it will confuse players
//SOLDIERTYPE *pShooter;
//GetSoldier( &pShooter, gusSelectedSoldier );
//if(gfUICtHBar && pShooter && pShooter->bDoAutofire > 1)
// return;
if ( gfKeyState[ALT] && pSoldier &&
IsPointInScreenRectWithRelative( gusMouseXPos, gusMouseYPos, &aRect, &a1, &a2 ) )
{
MOUSETT *pRegion = &mouseTT;
CHAR16 pStrInfo[ sizeof( pRegion->FastHelpText ) ];
int iNVG = 0;
INT32 usSoldierGridNo;
BOOLEAN fDisplayBigSlotItem = FALSE;
BOOLEAN fMercIsUsingScope = FALSE;
UINT16 iCarriedRL = 0;
INT32 iRangeToTarget = 0;
UINT8 ubTooltipDetailLevel = gGameExternalOptions.ubSoldierTooltipDetailLevel;
UINT32 uiMaxTooltipDistance = gGameExternalOptions.ubStraightSightRange;
fDrawTooltip = TRUE;
// get the gridno the cursor is at
GetMouseMapPos( &usSoldierGridNo );
// get the distance to enemy's tile from the selected merc
if ( gusSelectedSoldier != NOBODY && gusUIFullTargetID != NOBODY )
{
//CHRISL: Changed the second parameter to use the same information as the 'F' hotkey uses.
//iRangeToTarget = GetRangeInCellCoordsFromGridNoDiff( MercPtrs[ gusSelectedSoldier ]->sGridNo, sSoldierGridNo ) / 10;
iRangeToTarget = GetRangeInCellCoordsFromGridNoDiff( MercPtrs[ gusSelectedSoldier ]->sGridNo, MercPtrs[ gusUIFullTargetID ]->sGridNo ) / 10;
}
// WANNE: If we want to show the tooltip of milita and no merc is present in the sector
else
{
return;
}
//SCORE: If UDT range, we work it out as half actual LOS
// SANDRO - don't use this if detail set to debug!
if ( gGameExternalOptions.gfAllowUDTRange && gGameExternalOptions.ubSoldierTooltipDetailLevel != DL_Debug && !(gTacticalStatus.uiFlags & SHOW_ALL_MERCS) )
{
uiMaxTooltipDistance = (UINT32)( MercPtrs[ gusSelectedSoldier ]->GetMaxDistanceVisible(MercPtrs[ gusUIFullTargetID ]->sGridNo, 0, CALC_FROM_WANTED_DIR) * (gGameExternalOptions.ubUDTModifier));
uiMaxTooltipDistance /= 100;
}
//SCORE: Otherwise if we're using dynamics then do this
// SANDRO - don't use this if detail set to debug!
else if ( gGameExternalOptions.fEnableDynamicSoldierTooltips && gGameExternalOptions.ubSoldierTooltipDetailLevel != DL_Debug && !(gTacticalStatus.uiFlags & SHOW_ALL_MERCS) )
{
OBJECTTYPE* pObject = &(MercPtrs[gusSelectedSoldier]->inv[HANDPOS]);
for (attachmentList::iterator iter = (*pObject)[0]->attachments.begin(); iter != (*pObject)[0]->attachments.end(); ++iter) {
if ( Item[iter->usItem].visionrangebonus > 0 && iter->exists())
{
fMercIsUsingScope = TRUE;
break;
}
}
if ( fMercIsUsingScope )
{
// set detail level to (at least) Full
ubTooltipDetailLevel = MAX(DL_Full,ubTooltipDetailLevel);
}
}
//SCORE: removed to enable scopes to affect range of tooltips.
//else
//{
//If we're using original settings and no scope, we do this
if (gGameExternalOptions.fEnableDynamicSoldierTooltips && fMercIsUsingScope == 0 && !gGameExternalOptions.gfAllowUDTRange)
{
// add 10% to max tooltip viewing distance per level of the merc
// sevenfm: fixed incorrect integer calculation
uiMaxTooltipDistance = (INT32)( uiMaxTooltipDistance * ( 1 + ( (FLOAT)( EffectiveExpLevel( MercPtrs[ gusSelectedSoldier ] ) ) / 10.0 ) ) ); // SANDRO - changed to effective level calc
// sevenfm: this calculation doesn't make sense: disabled
//if ( gGameExternalOptions.gfAllowLimitedVision )
// uiMaxTooltipDistance *= 1 - (gGameExternalOptions.ubVisDistDecreasePerRainIntensity / 100);
if ( !(Item[MercPtrs[gusSelectedSoldier]->inv[HEAD1POS].usItem].nightvisionrangebonus > 0) &&
!(Item[MercPtrs[gusSelectedSoldier]->inv[HEAD2POS].usItem].nightvisionrangebonus > 0) &&
!DayTime() )
{
// if night reduce max tooltip viewing distance by a factor of 4 if merc is not wearing NVG
uiMaxTooltipDistance >>= 2;
}
}
//SCORE: Dynamic detail, otherwise do what we usually do
// SANDRO - don't use this if detail set to debug!
if ( gGameExternalOptions.gfAllowUDTDetail && gGameExternalOptions.ubSoldierTooltipDetailLevel != DL_Debug && !(gTacticalStatus.uiFlags & SHOW_ALL_MERCS) )
{
//Check range. Less than a third? Full. Less than 2 thirds? Basic. Otherwise Limited.
if ( iRangeToTarget <= (INT32)(uiMaxTooltipDistance / 3) )
{
ubTooltipDetailLevel = DL_Full;
}
else if ( iRangeToTarget <= (INT32)((uiMaxTooltipDistance / 3)*2) )
{
ubTooltipDetailLevel = DL_Basic;
}
else if ( iRangeToTarget <= (INT32)uiMaxTooltipDistance )
{
ubTooltipDetailLevel = DL_Limited;
}
else
{
return;
}
}
else
{
if ( iRangeToTarget <= (INT32)(uiMaxTooltipDistance / 2) )
{
// at under half the maximum view distance set tooltip detail to (at least) Basic
ubTooltipDetailLevel = MAX(DL_Basic,ubTooltipDetailLevel);
}
else if ( iRangeToTarget <= (INT32)uiMaxTooltipDistance )
{
// at under the maximum view distance set tooltip detail to (at least) Limited
ubTooltipDetailLevel = MAX(DL_Limited,ubTooltipDetailLevel);
}
else
{
// beyond visual range, do not display tooltip if player has not chosen full or debug details
if ( ubTooltipDetailLevel < DL_Full )
return;
}
}
//} // fMercIsUsingScope is false
// gGameExternalOptions.fEnableDynamicSoldierTooltips
// WANNE: Check if enemy soldier is in line of sight but only if player has not choosen debug details
if ( ubTooltipDetailLevel < DL_Full)
{
// Get the current selected merc
SOLDIERTYPE* pMerc = MercPtrs[ gusSelectedSoldier ];
if ( pMerc->aiData.bOppList[pSoldier->ubID] != SEEN_CURRENTLY )
{
// We do not see the enemy. Return and do not display the tooltip.
return;
}
}
swprintf( pStrInfo, L"" );
if ( ubTooltipDetailLevel == DL_Debug )
{
// display "debug" info
if ( gGameExternalOptions.fEnableSoldierTooltipLocation )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_LOCATION], pStrInfo, usSoldierGridNo );
if ( gGameExternalOptions.fEnableSoldierTooltipBrightness )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_BRIGHTNESS], pStrInfo, SHADE_MIN - LightTrueLevel( usSoldierGridNo, gsInterfaceLevel ), SHADE_MIN );
if ( gGameExternalOptions.fEnableSoldierTooltipRangeToTarget )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_RANGE_TO_TARGET], pStrInfo, iRangeToTarget );
if ( gGameExternalOptions.fEnableSoldierTooltipID )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ID], pStrInfo, pSoldier->ubID );
if ( gGameExternalOptions.fEnableSoldierTooltipOrders )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ORDERS], pStrInfo, pSoldier->aiData.bOrders );
if ( gGameExternalOptions.fEnableSoldierTooltipAttitude )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ATTITUDE], pStrInfo, pSoldier->aiData.bAttitude );
if ( gGameExternalOptions.fEnableSoldierTooltipActionPoints )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_CURRENT_APS], pStrInfo, pSoldier->bActionPoints );
if ( gGameExternalOptions.fEnableSoldierTooltipHealth )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_CURRENT_HEALTH], pStrInfo, pSoldier->stats.bLife );
if ( gGameExternalOptions.fEnableSoldierTooltipEnergy )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_CURRENT_ENERGY], pStrInfo, pSoldier->bBreath );
if ( gGameExternalOptions.fEnableSoldierTooltipMorale )
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_CURRENT_MORALE], pStrInfo, pSoldier->aiData.bMorale );
//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->ubLastSuppression );
// sevenfm: show additional suppression info
if ( gGameExternalOptions.fEnableSoldierTooltipSuppressionInfo )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SUPPRESSION_AP], pStrInfo, pSoldier->ubAPsLostToSuppression );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SUPPRESSION_TOLERANCE], pStrInfo, CalcSuppressionTolerance( pSoldier ) );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_EFFECTIVE_SHOCK], pStrInfo, CalcEffectiveShockLevel( pSoldier ) );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_AI_MORALE], pStrInfo, pSoldier->aiData.bAIMorale );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Added by SANDRO - show enemy skills
if ( gGameExternalOptions.fEnableSoldierTooltipTraits )
{
if ( gGameOptions.fNewTraitSystem )
{
if (( pSoldier->stats.ubSkillTraits[0] == pSoldier->stats.ubSkillTraits[1] ) && pSoldier->stats.ubSkillTraits[0] != 0 )
{
CHAR16 pStrAux[50];
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[0] ]);
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[1] + NEWTRAIT_MERCSKILL_EXPERTOFFSET ] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[2] ] );
//swprintf( pStrInfo, L"%s\n", pStrInfo );
}
else if (( pSoldier->stats.ubSkillTraits[1] == pSoldier->stats.ubSkillTraits[2] ) && pSoldier->stats.ubSkillTraits[1] != 0 )
{
CHAR16 pStrAux[50];
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[1] ]);
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[2] + NEWTRAIT_MERCSKILL_EXPERTOFFSET ] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[0] ] );
}
else if (( pSoldier->stats.ubSkillTraits[0] == pSoldier->stats.ubSkillTraits[2] ) && pSoldier->stats.ubSkillTraits[0] != 0 )
{
CHAR16 pStrAux[50];
swprintf( pStrAux, L"(%s)", gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[0] ]);
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, pStrAux );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[2] + NEWTRAIT_MERCSKILL_EXPERTOFFSET ] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[1] ] );
}
else
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[0] ] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[1] ] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_3], pStrInfo, gzMercSkillTextNew[ pSoldier->stats.ubSkillTraits[2] ] );
}
}
else
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_1], pStrInfo, gzMercSkillText[pSoldier->stats.ubSkillTraits[0]] );
swprintf( pStrInfo, gzTooltipStrings[STR_TT_SKILL_TRAIT_2], pStrInfo, gzMercSkillText[pSoldier->stats.ubSkillTraits[1]] );
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
// armor info code block start
if ( ubTooltipDetailLevel >= DL_Full )
{
if ( gGameExternalOptions.fEnableSoldierTooltipHelmet )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_HELMET], pStrInfo, pSoldier->inv[HELMETPOS].usItem ? ItemNames[ pSoldier->inv[HELMETPOS].usItem ] : gzTooltipStrings[STR_TT_NO_HELMET] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[HELMETPOS].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[HELMETPOS].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
if ( gGameExternalOptions.fEnableSoldierTooltipVest )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_VEST], pStrInfo, pSoldier->inv[VESTPOS].usItem ? ItemNames[ pSoldier->inv[VESTPOS].usItem ] : gzTooltipStrings[STR_TT_NO_VEST] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[VESTPOS].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[VESTPOS].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
if ( gGameExternalOptions.fEnableSoldierTooltipLeggings )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_LEGGINGS], pStrInfo, pSoldier->inv[LEGPOS].usItem ? ItemNames[ pSoldier->inv[LEGPOS].usItem ] : gzTooltipStrings[STR_TT_NO_LEGGING] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[LEGPOS].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[LEGPOS].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
}
else
{
if ( !( !gGameExternalOptions.fEnableSoldierTooltipHelmet &&
!gGameExternalOptions.fEnableSoldierTooltipVest &&
!gGameExternalOptions.fEnableSoldierTooltipLeggings) )
// do not display the armor line if all the armor toggles are set to false
{
if ( ArmourPercent( pSoldier ) )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ARMOR] );
if ( ubTooltipDetailLevel == DL_Basic )
{
if ( gGameExternalOptions.fEnableSoldierTooltipHelmet && pSoldier->inv[HELMETPOS].usItem )
swprintf( pStrInfo, L"%s%s ", pStrInfo, gzTooltipStrings[STR_TT_HELMET] );
if ( gGameExternalOptions.fEnableSoldierTooltipVest && pSoldier->inv[VESTPOS].usItem )
swprintf( pStrInfo, L"%s%s ", pStrInfo, gzTooltipStrings[STR_TT_VEST] );
if ( gGameExternalOptions.fEnableSoldierTooltipLeggings && pSoldier->inv[LEGPOS].usItem )
swprintf( pStrInfo, L"%s%s", pStrInfo, gzTooltipStrings[STR_TT_LEGGINGS] );
wcscat( pStrInfo, L"\n" );
}
else // ubTooltipDetailLevel == DL_Limited
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ARMOR_2], gzTooltipStrings[STR_TT_WORN] );
}
}
else
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_ARMOR_2], gzTooltipStrings[STR_TT_NO_ARMOR] );
}
}
}
// armor info code block end
// head slots info code block start
if ( ubTooltipDetailLevel != DL_Debug )
{
if( Item[pSoldier->inv[HEAD1POS].usItem].nightvisionrangebonus > 0 )
iNVG = HEAD1POS;
else if( Item[pSoldier->inv[HEAD2POS].usItem].nightvisionrangebonus > 0 )
iNVG = HEAD2POS;
if ( !( !gGameExternalOptions.fEnableSoldierTooltipHeadItem1 &&
!gGameExternalOptions.fEnableSoldierTooltipHeadItem2) )
// do not display the NVG/mask lines if both head slot toggles are set to false
{
if ( ubTooltipDetailLevel >= DL_Full )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_NVG], pStrInfo,
iNVG ? ItemNames[ pSoldier->inv[ iNVG ].usItem ] : gzTooltipStrings[STR_TT_NO_NVG] );
//Moa: encyclopedia item visibility
if ( iNVG )
EncyclopediaSetItemAsVisible( pSoldier->inv[ iNVG ].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
else
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_NVG], pStrInfo, iNVG ? gzTooltipStrings[STR_TT_WORN] : gzTooltipStrings[STR_TT_NO_NVG] );
}
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_GAS_MASK], pStrInfo,
( FindGasMask(pSoldier) != NO_SLOT ) ? gzTooltipStrings[STR_TT_WORN] : gzTooltipStrings[STR_TT_NO_MASK] );
}
}
else // gGameExternalOptions.ubSoldierTooltipDetailLevel == DL_Debug
{
if ( gGameExternalOptions.fEnableSoldierTooltipHeadItem1 )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_HEAD_POS_1], pStrInfo, ItemNames[ pSoldier->inv[HEAD1POS].usItem ] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[HEAD1POS].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[ HEAD1POS ].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
if ( gGameExternalOptions.fEnableSoldierTooltipHeadItem2 )
{
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_HEAD_POS_2], pStrInfo, ItemNames[ pSoldier->inv[HEAD2POS].usItem ] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[HEAD2POS].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[ HEAD2POS ].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
}
// head slots info code block end
// weapon in primary hand info code block start
if ( gGameExternalOptions.fEnableSoldierTooltipWeapon )
{
DisplayWeaponInfo( pSoldier, pStrInfo, HANDPOS, ubTooltipDetailLevel );
} // gGameExternalOptions.fEnableSoldierTooltipWeapon
// weapon in primary hand info code block end
// weapon in off hand info code block start
if ( gGameExternalOptions.fEnableSoldierTooltipSecondHand )
{
if ( pSoldier->inv[SECONDHANDPOS].usItem )
{
// if there's something in the slot display it
wcscat( pStrInfo, L"\n" );
DisplayWeaponInfo( pSoldier, pStrInfo, SECONDHANDPOS, ubTooltipDetailLevel );
}
}
// weapon in off hand info code block end
// large objects in big inventory slots info code block start
for ( UINT8 BigSlot = BIGPOCKSTART; BigSlot < BIGPOCKFINAL; BigSlot++ )
{
if ( pSoldier->inv[ BigSlot ].exists() == false )
continue; // slot is empty, move on to the next slot
switch( BigSlot )
{
// if display of this big slot is toggled off then move on to the next slot
case BIGPOCK1POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot1 )
continue;
break;
case BIGPOCK2POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot2 )
continue;
break;
case BIGPOCK3POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot3 )
continue;
break;
case BIGPOCK4POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot4 )
continue;
break;
// CHRISL: Added new large pockets introduced by new inventory system
case BIGPOCK5POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot5 )
continue;
break;
case BIGPOCK6POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot6 )
continue;
break;
case BIGPOCK7POS:
if ( !gGameExternalOptions.fEnableSoldierTooltipBigSlot7 )
continue;
break;
}
if ( Item[ pSoldier->inv[ BigSlot ].usItem ].rocketlauncher )
iCarriedRL = pSoldier->inv[ BigSlot ].usItem; // remember that enemy is carrying a rocket launcher when check for rocket ammo is made later on
if ( ( Item[ pSoldier->inv[ BigSlot ].usItem ].usItemClass == IC_LAUNCHER ) ||
( Item[ pSoldier->inv[ BigSlot ].usItem ].usItemClass == IC_GUN ) )
{
// it's a firearm
if ( ( Weapon[pSoldier->inv[ BigSlot ].usItem].ubWeaponClass != HANDGUNCLASS ) &&
( Weapon[pSoldier->inv[ BigSlot ].usItem].ubWeaponClass != SMGCLASS ) )
{
// it's a long gun or heavy weapon
fDisplayBigSlotItem = TRUE;
}
}
else
{
// check for rocket ammo
if ( ( iCarriedRL != 0 ) && // soldier is carrying a RL ...
ValidLaunchable( pSoldier->inv[ BigSlot ].usItem, iCarriedRL ) ) // this item is launchable by the RL
{
fDisplayBigSlotItem = TRUE;
}
}
if ( fDisplayBigSlotItem )
{
wcscat( pStrInfo, gzTooltipStrings[STR_TT_IN_BACKPACK] );
DisplayWeaponInfo( pSoldier, pStrInfo, BigSlot, ubTooltipDetailLevel );
fDisplayBigSlotItem = FALSE;
}
}
// large objects in big inventory slots info code block end
pRegion->iX = gusMouseXPos;
pRegion->iY = gusMouseYPos;
// if ( gGameExternalOptions.ubSoldierTooltipDetailLevel == DL_Debug )
// swprintf( pRegion->FastHelpText, L"%s\n|String |Length|: %d", pStrInfo, wcslen(pStrInfo) );
// else
wcscpy( pRegion->FastHelpText, pStrInfo );
}
if ( gfKeyState[ ALT ] && fDrawTooltip )
{
DrawMouseTooltip();
SetRenderFlags( RENDER_FLAG_FULL );
}
} // SoldierTooltip(SOLDIERTYPE* pSoldier)
void DisplayWeaponInfo( SOLDIERTYPE* pSoldier, CHAR16* pStrInfo, UINT8 ubSlot, UINT8 ubTooltipDetailLevel )
{
INT32 iNumAttachments = 0;
BOOLEAN fDisplayAttachment = FALSE;
if ( ubTooltipDetailLevel >= DL_Full )
{
// display exact weapon model
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo,
WeaponInHand( pSoldier ) ? ItemNames[ pSoldier->inv[ubSlot].usItem ] : gzTooltipStrings[STR_TT_NO_WEAPON] );
//Moa: encyclopedia item visibility
if ( pSoldier->inv[ubSlot].usItem )
EncyclopediaSetItemAsVisible( pSoldier->inv[ ubSlot ].usItem, ENC_ITEM_DISCOVERED_NOT_REACHABLE );
}
else
{
if ( ubTooltipDetailLevel == DL_Limited )
{
// display general weapon class
switch( Weapon[pSoldier->inv[ubSlot].usItem].ubWeaponClass )
{
case HANDGUNCLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_HANDGUN] );
break;
case SMGCLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_SMG] );
break;
case RIFLECLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_RIFLE] );
break;
case MGCLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_MG] );
break;
case SHOTGUNCLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_SHOTGUN] );
break;
case KNIFECLASS:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_KNIFE] );
break;
default:
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo, gzTooltipStrings[STR_TT_HEAVY_WEAPON] );
break;
}
}
else
{
// display general weapon type
swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_WEAPON], pStrInfo,
WeaponInHand( pSoldier) ? WeaponType[Weapon[pSoldier->inv[ubSlot].usItem].ubWeaponType] : gzTooltipStrings[STR_TT_NO_WEAPON] );
}
}
if ( gGameExternalOptions.ubSoldierTooltipDetailLevel >= DL_Basic )
{
// display weapon attachments
for (attachmentList::iterator iter = pSoldier->inv[ubSlot][0]->attachments.begin(); iter != pSoldier->inv[ubSlot][0]->attachments.end(); ++iter) {
if(iter->exists()){
fDisplayAttachment = FALSE; //Madd: changed this, it was incorrectly showing attachments when it shouldn't be
if ( ubTooltipDetailLevel == DL_Basic || ubTooltipDetailLevel == DL_Full ) // Madd: also hidden attachments should be hidden at the full level as well... unless the mercs have x-ray vision to see that rod&spring inside the gun!! :p
{
// display only externally-visible weapon attachments
if ( Item[iter->usItem].hiddenattachment )
fDisplayAttachment = FALSE;
else
fDisplayAttachment = TRUE;
}
if ( fDisplayAttachment )
{
iNumAttachments++;
if ( iNumAttachments == 1 )
wcscat( pStrInfo, L"\n[" );
else
wcscat( pStrInfo, L", " );
wcscat( pStrInfo, ItemNames[ iter->usItem ] );
}
}
} // for
if ( iNumAttachments > 0 )
wcscat( pStrInfo, pMessageStrings[ MSG_END_ATTACHMENT_LIST ] ); // append ' attached]' to end of string
} // gGameExternalOptions.ubSoldierTooltipDetailLevel >= DL_Basic
}
MOUSETT mouseTT;
BOOL mouseTTrender, mouseTTdone;
void DrawMouseTooltip()
{
UINT8 *pDestBuf;
UINT32 uiDestPitchBYTES;
static INT32 iX, iY, iW, iH;
extern INT16 GetWidthOfString(const STR16);
extern INT16 GetNumberOfLinesInHeight(const STR16);
extern void DisplayHelpTokenizedString(const STR16,INT16,INT16);
extern BOOLEAN initTooltipBuffer();
extern PTR LockTooltipBuffer(UINT32*);
extern void UnlockTooltipBuffer();
extern void DisplayTooltipString( const STR16 pStringA, INT16 sX, INT16 sY );
extern void j_log(PTR,...);
iX = mouseTT.iX;iY = mouseTT.iY;
iW = (INT32)GetWidthOfString( mouseTT.FastHelpText ) + 10;
iH = (INT32)( GetNumberOfLinesInHeight( mouseTT.FastHelpText ) * (GetFontHeight(FONT10ARIAL)+1) + 8 );
if(1)//draw at cursor
{
iY -= (iH / 2);
if (gusMouseXPos > (SCREEN_WIDTH / 2))
iX = gusMouseXPos - iW - 24;
else
iX = gusMouseXPos + 24;
//if (gusMouseYPos > (SCREEN_HEIGHT / 2))
// iY -= 32;
if (iY <= 0) iY += 32;
}
else
{ //draw in panel
//502,485 658,596 160*110 580,540
iX = 580 - (iW / 2);
iY = 540 - (iH/2);
if (iY + iH > SCREEN_HEIGHT) iY = SCREEN_HEIGHT - iH - 3 ;
}
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
RectangleDraw( TRUE, iX + 1, iY + 1, iX + iW - 1, iY + iH - 1, Get16BPPColor( FROMRGB( 65, 57, 15 ) ), pDestBuf );
RectangleDraw( TRUE, iX, iY, iX + iW - 2, iY + iH - 2, Get16BPPColor( FROMRGB( 227, 198, 88 ) ), pDestBuf );
UnLockVideoSurface( FRAME_BUFFER );
ShadowVideoSurfaceRect( FRAME_BUFFER, iX + 2, iY + 2, iX + iW - 3, iY + iH - 3 );
ShadowVideoSurfaceRect( FRAME_BUFFER, iX + 2, iY + 2, iX + iW - 3, iY + iH - 3 );
SetFont( FONT10ARIAL );
SetFontShadow( FONT_NEARBLACK );
DisplayHelpTokenizedString( mouseTT.FastHelpText ,( INT16 )( iX + 5 ), ( INT16 )( iY + 5 ) );
InvalidateRegion( iX, iY, (iX + iW) , (iY + iH) );
//InvalidateScreen();
}