mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
New ability: a disguised spy can distract unalerted enemies, making it easier to sneak by.
For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=20228&goto=352562&#msg_352562 git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8528 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+88
-6
@@ -483,6 +483,86 @@ void BeginCivQuote( SOLDIERTYPE *pCiv, UINT16 ubCivQuoteID, UINT16 ubEntryID, IN
|
||||
gCivQuoteData.pCiv = pCiv;
|
||||
}
|
||||
|
||||
void BeginChatQuote( SOLDIERTYPE *pCiv, INT16 sX, INT16 sY )
|
||||
{
|
||||
VIDEO_OVERLAY_DESC VideoOverlayDesc;
|
||||
|
||||
// OK, do we have another on?
|
||||
if ( gCivQuoteData.bActive )
|
||||
{
|
||||
// Delete?
|
||||
ShutDownQuoteBox( TRUE );
|
||||
}
|
||||
|
||||
if ( pCiv->bTeam == gbPlayerNum )
|
||||
swprintf( gzCivQuote, L"\"%s\"", szChatTextSpy[Random( 24 )] );
|
||||
else
|
||||
swprintf( gzCivQuote, L"\"%s\"", szChatTextEnemy[Random( 24 )] );
|
||||
|
||||
// Create video oeverlay....
|
||||
memset( &VideoOverlayDesc, 0, sizeof( VIDEO_OVERLAY_DESC ) );
|
||||
|
||||
// Prepare text box
|
||||
gCivQuoteData.iDialogueBox = PrepareMercPopupBox( gCivQuoteData.iDialogueBox, BASIC_MERC_POPUP_BACKGROUND, BASIC_MERC_POPUP_BORDER, gzCivQuote, DIALOGUE_DEFAULT_WIDTH, 0, 0, 0, &gusCivQuoteBoxWidth, &gusCivQuoteBoxHeight );
|
||||
|
||||
// Flugente: have the box appear a bit above the soldier. Otherwise it will obstruct us from aiming at him, which is annoying if it happens very often
|
||||
sY -= 30;
|
||||
|
||||
// OK, find center for box......
|
||||
sX = sX - ( gusCivQuoteBoxWidth / 2 );
|
||||
sY = sY - ( gusCivQuoteBoxHeight / 2 );
|
||||
|
||||
// OK, limit to screen......
|
||||
{
|
||||
if ( sX < 0 )
|
||||
{
|
||||
sX = 0;
|
||||
}
|
||||
|
||||
// CHECK FOR LEFT/RIGHT
|
||||
if ( ( sX + gusCivQuoteBoxWidth ) > SCREEN_WIDTH )
|
||||
{
|
||||
sX = SCREEN_WIDTH - gusCivQuoteBoxWidth;
|
||||
}
|
||||
|
||||
// Now check for top
|
||||
if ( sY < gsVIEWPORT_WINDOW_START_Y )
|
||||
{
|
||||
sY = gsVIEWPORT_WINDOW_START_Y;
|
||||
}
|
||||
|
||||
// Check for bottom
|
||||
if ( ( sY + gusCivQuoteBoxHeight ) > ( SCREEN_HEIGHT - INV_INTERFACE_HEIGHT ) )
|
||||
{
|
||||
sY = ( SCREEN_HEIGHT - INV_INTERFACE_HEIGHT ) - gusCivQuoteBoxHeight;
|
||||
}
|
||||
}
|
||||
|
||||
VideoOverlayDesc.sLeft = sX;
|
||||
VideoOverlayDesc.sTop = sY;
|
||||
VideoOverlayDesc.sRight = VideoOverlayDesc.sLeft + gusCivQuoteBoxWidth;
|
||||
VideoOverlayDesc.sBottom = VideoOverlayDesc.sTop + gusCivQuoteBoxHeight;
|
||||
VideoOverlayDesc.sX = VideoOverlayDesc.sLeft;
|
||||
VideoOverlayDesc.sY = VideoOverlayDesc.sTop;
|
||||
VideoOverlayDesc.BltCallback = RenderCivQuoteBoxOverlay;
|
||||
|
||||
gCivQuoteData.iVideoOverlay = RegisterVideoOverlay( 0, &VideoOverlayDesc );
|
||||
|
||||
//Define main region
|
||||
MSYS_DefineRegion( &( gCivQuoteData.MouseRegion ), VideoOverlayDesc.sLeft, VideoOverlayDesc.sTop, VideoOverlayDesc.sRight, VideoOverlayDesc.sBottom, MSYS_PRIORITY_HIGHEST,
|
||||
CURSOR_NORMAL, MSYS_NO_CALLBACK, QuoteOverlayClickCallback );
|
||||
// Add region
|
||||
MSYS_AddRegion( &( gCivQuoteData.MouseRegion ) );
|
||||
|
||||
gCivQuoteData.bActive = TRUE;
|
||||
|
||||
gCivQuoteData.uiTimeOfCreation = GetJA2Clock();
|
||||
|
||||
gCivQuoteData.uiDelayTime = FindDelayForString( gzCivQuote ) + 500;
|
||||
|
||||
gCivQuoteData.pCiv = pCiv;
|
||||
}
|
||||
|
||||
UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLEAN fCanUseHints )
|
||||
{
|
||||
UINT8 ubCivType;
|
||||
@@ -878,7 +958,6 @@ void HandleCivQuote( )
|
||||
void StartCivQuote( SOLDIERTYPE *pCiv )
|
||||
{
|
||||
UINT16 ubCivQuoteID;
|
||||
INT16 sX, sY;
|
||||
UINT16 ubEntryID = 0;
|
||||
INT16 sScreenX, sScreenY;
|
||||
UINT16 ubCivHintToUse;
|
||||
@@ -975,17 +1054,15 @@ void StartCivQuote( SOLDIERTYPE *pCiv )
|
||||
// Determine location...
|
||||
// Get location of civ on screen.....
|
||||
GetSoldierScreenPos( pCiv, &sScreenX, &sScreenY );
|
||||
sX = sScreenX;
|
||||
sY = sScreenY;
|
||||
|
||||
// begin quote
|
||||
BeginCivQuote( pCiv, ubCivQuoteID, ubEntryID, sX, sY );
|
||||
BeginCivQuote( pCiv, ubCivQuoteID, ubEntryID, sScreenX, sScreenY );
|
||||
|
||||
// Increment use
|
||||
if ( ubCivQuoteID != CIV_QUOTE_HINT )
|
||||
{
|
||||
//pCiv->bCurrentCivQuoteDelta++;
|
||||
CivQuoteDelta++;
|
||||
++CivQuoteDelta;
|
||||
/*
|
||||
if ( pCiv->bCurrentCivQuoteDelta == 2 )
|
||||
{
|
||||
@@ -2010,4 +2087,9 @@ void ShowTauntPopupBox( SOLDIERTYPE *pCiv, STR16 gzTauntQuote )
|
||||
gCivQuoteData.uiDelayTime = min( gTauntsSettings.sMaxDelay , max( gTauntsSettings.sMinDelay, FindDelayForString( gzTauntQuote ) + gTauntsSettings.sModDelay ) );
|
||||
|
||||
gCivQuoteData.pCiv = pCiv;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN CivQuoteActive()
|
||||
{
|
||||
return gCivQuoteData.bActive;
|
||||
}
|
||||
|
||||
@@ -172,5 +172,8 @@ BOOLEAN LoadCivQuotesFromLoadGameFile( HWFILE hFile );
|
||||
BOOLEAN ShutDownQuoteBoxIfActive( );
|
||||
|
||||
void BeginCivQuote( SOLDIERTYPE *pCiv, UINT16 ubCivQuoteID, UINT16 ubEntryID, INT16 sX, INT16 sY );
|
||||
void BeginChatQuote( SOLDIERTYPE *pCiv, INT16 sX, INT16 sY );
|
||||
|
||||
BOOLEAN CivQuoteActive();
|
||||
|
||||
#endif
|
||||
+85
-1
@@ -10672,6 +10672,32 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[ STR_PRISONER_REFUSE_TAKE_PRISONERS ] );
|
||||
}
|
||||
}
|
||||
// we distract the enemy by essentially talking them to death
|
||||
else if ( ubExitValue == 3 )
|
||||
{
|
||||
// Flugente: if we are disguised and talk to a non-profile NPC, we will continue to 'chat' with the enemy as long as we aren't ordered to do something else.
|
||||
// This way we can easily order our spies to 'distract 'enemies'
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) &&
|
||||
pSoldier->bTeam == gbPlayerNum &&
|
||||
MercPtrs[prisonerdialoguetargetID] &&
|
||||
MercPtrs[prisonerdialoguetargetID]->bTeam == ENEMY_TEAM &&
|
||||
MercPtrs[prisonerdialoguetargetID]->ubProfile == NO_PROFILE &&
|
||||
MercPtrs[prisonerdialoguetargetID]->aiData.bAlertStatus < STATUS_RED &&
|
||||
!MercPtrs[prisonerdialoguetargetID]->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
{
|
||||
// both soldiers face each other
|
||||
pSoldier->EVENT_SetSoldierDesiredDirection( GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, MercPtrs[prisonerdialoguetargetID]->sGridNo ) );
|
||||
MercPtrs[prisonerdialoguetargetID]->EVENT_SetSoldierDesiredDirection( GetDirectionToGridNoFromGridNo( MercPtrs[prisonerdialoguetargetID]->sGridNo, pSoldier->sGridNo ) );
|
||||
|
||||
MercPtrs[prisonerdialoguetargetID]->usChatPartnerID = gusSelectedSoldier;
|
||||
pSoldier->usChatPartnerID = prisonerdialoguetargetID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal dialog
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal dialog
|
||||
@@ -10681,6 +10707,50 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
ReduceAttackBusyCount( );
|
||||
}
|
||||
|
||||
// Flugente: disguised mercs can distract enemies by talking to them. In order to display that, we sometimes display excerpts of their 'chats'
|
||||
void CheckChatPartners()
|
||||
{
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
{
|
||||
if ( !CivQuoteActive() )
|
||||
{
|
||||
static BOOLEAN fMercQuoteThisTime = TRUE;
|
||||
|
||||
SOLDIERTYPE* pSoldier = NULL;
|
||||
|
||||
for ( int ubLoop = gTacticalStatus.Team[gbPlayerNum].bFirstID; ubLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++ubLoop )
|
||||
{
|
||||
pSoldier = MercPtrs[ubLoop];
|
||||
|
||||
if ( pSoldier && pSoldier->bVisible && pSoldier->usChatPartnerID != NOBODY && MercPtrs[pSoldier->usChatPartnerID]->bVisible )
|
||||
{
|
||||
INT16 sScreenX, sScreenY;
|
||||
|
||||
if ( fMercQuoteThisTime )
|
||||
GetSoldierScreenPos( pSoldier, &sScreenX, &sScreenY );
|
||||
else
|
||||
GetSoldierScreenPos( MercPtrs[pSoldier->usChatPartnerID], &sScreenX, &sScreenY );
|
||||
|
||||
if ( gsVIEWPORT_START_X <= sScreenX &&
|
||||
gsVIEWPORT_END_X >= sScreenX &&
|
||||
gsVIEWPORT_WINDOW_START_Y <= sScreenY &&
|
||||
gsVIEWPORT_WINDOW_END_Y >= sScreenY )
|
||||
{
|
||||
if ( fMercQuoteThisTime )
|
||||
BeginChatQuote( pSoldier, sScreenX, sScreenY );
|
||||
else
|
||||
BeginChatQuote( MercPtrs[pSoldier->usChatPartnerID], sScreenX, sScreenY );
|
||||
|
||||
fMercQuoteThisTime = !fMercQuoteThisTime;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: offer the enemy the chance to surrender
|
||||
void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
{
|
||||
@@ -10694,7 +10764,21 @@ void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
// open a dialogue box and see wether we really want to offer this, or just talk
|
||||
wcscpy( gzUserDefinedButton[0], TacticalStr[ PRISONER_DEMAND_SURRENDER_STR ] );
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[ PRISONER_OFFER_SURRENDER_STR ] );
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[ PRISONER_TALK_STR ] );
|
||||
|
||||
SOLDIERTYPE* pTargetSoldier = NULL;
|
||||
if ( GetSoldier( &pTargetSoldier, prisonerdialoguetargetID ) &&
|
||||
pTargetSoldier->bTeam == ENEMY_TEAM &&
|
||||
pTargetSoldier->ubProfile == NO_PROFILE &&
|
||||
pTargetSoldier->aiData.bAlertStatus < STATUS_RED &&
|
||||
!pTargetSoldier->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
{
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[PRISONER_DISTRACT_STR] );
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[PRISONER_TALK_STR] );
|
||||
}
|
||||
|
||||
wcscpy( gzUserDefinedButton[3], TacticalStr[ PRISONER_TALK_STR ] );
|
||||
DoMessageBox( MSG_BOX_BASIC_MEDIUM_BUTTONS, TacticalStr[ PRISONER_OFFER_SURRENDER ], guiCurrentScreen, MSG_BOX_FLAG_GENERIC_FOUR_BUTTONS, PrisonerSurrenderMessageBoxCallBack, NULL );
|
||||
}
|
||||
|
||||
@@ -357,6 +357,9 @@ extern UINT8 NumZombiesInSector();
|
||||
// Flugente: offer the enemy the chance to surrender
|
||||
void HandleSurrenderOffer( SOLDIERTYPE* pSoldier );
|
||||
|
||||
// Flugente: disguised mercs can distract enemies by talking to them. In order to display that, we sometimes display excerpts of their 'chats'
|
||||
void CheckChatPartners();
|
||||
|
||||
// Flugente: order a team to drop gear, or pick it up
|
||||
// setting fForce to TRUE allows dropping of gear in combat (used in auto-resolve instances)
|
||||
void TeamDropAll(UINT8 bTeam, BOOLEAN fForce = FALSE);
|
||||
|
||||
@@ -923,6 +923,8 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ub
|
||||
// if we are temporarily overt
|
||||
if ( pSoldier->usSoldierFlagMask & SOLDIER_COVERT_TEMPORARY_OVERT && pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_COVERTOPS_TEMPORARYOVERT_APS] > 0 )
|
||||
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_COVERTOPS_TEMPORARYOVERT_APS] = max( 0, (INT16)(pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_COVERTOPS_TEMPORARYOVERT_APS] - sAPCost) );
|
||||
|
||||
pSoldier->StopChatting();
|
||||
}
|
||||
|
||||
// in real time, there IS no AP cost, (only breath cost)
|
||||
|
||||
@@ -19968,6 +19968,17 @@ FLOAT SOLDIERTYPE::GetIntelGain()
|
||||
return totalvalue;
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::StopChatting()
|
||||
{
|
||||
if ( this->usChatPartnerID != NOBODY )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[DISTRACT_STOP_STR], this->GetName(), MercPtrs[this->usChatPartnerID]->GetName() );
|
||||
|
||||
MercPtrs[this->usChatPartnerID]->usChatPartnerID = NOBODY;
|
||||
this->usChatPartnerID = NOBODY;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
|
||||
@@ -1506,7 +1506,7 @@ public:
|
||||
//INT16 bUnusedINT16_4;
|
||||
INT16 sDragCorpseID; // Flugente: id of corpse we are dragging
|
||||
|
||||
INT16 bUnusedINT16_5;
|
||||
UINT16 usChatPartnerID; // Flugente: the id of another merc we are 'chatting' with
|
||||
|
||||
// Flugente: new variables for extra stats
|
||||
INT16 bExtraStrength; // additional strength gained via power armor
|
||||
@@ -1979,6 +1979,8 @@ public:
|
||||
// Flugente: spy assignments
|
||||
UINT8 GetUncoverRisk();
|
||||
FLOAT GetIntelGain();
|
||||
|
||||
void StopChatting();
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
Reference in New Issue
Block a user