mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
* More unused stuff removal
delete:
- giant 'metaheaders' (JA2 All.h, Laptop All.h, etc), preferring to add #includes directly where needed
- unused ExceptionHandling and DbMan translation units
- unused WizShare.h, Bitmap.h, trle.h, video_private.h headers
* remove mentions from vc proj files too
* remove preprocessor conditionals for unused definitions
find . -iname '*.h' -o -iname '*.cpp' -exec unifdef.exe -m -UPRECOMPILED_HEADERS -UJA2_PRECOMPILED_HEADERS -UWIZ8_PRECOMPILED_HEADERS -UPRECOMPILEDHEADERS {} ';'
then manually fixed a couple files the tool errored out on
* yes, the comments too
as title
3312 lines
97 KiB
C++
3312 lines
97 KiB
C++
#include "laptop.h"
|
|
#include "mercs.h"
|
|
#include "Utilities.h"
|
|
#include "WCheck.h"
|
|
#include "WordWrap.h"
|
|
#include "Cursors.h"
|
|
#include "Overhead.h"
|
|
#include "Soldier Add.h"
|
|
#include "Email.h"
|
|
#include "Game Clock.h"
|
|
#include "Faces.h"
|
|
#include "dialogue control.h"
|
|
#include "MercTextBox.h"
|
|
#include "Merc Hiring.h"
|
|
#include "Random.h"
|
|
#include "LaptopSave.h"
|
|
#include "GameSettings.h"
|
|
#include "Text.h"
|
|
#include "Speck Quotes.h"
|
|
#include "mercs Account.h"
|
|
#include "Soldier Profile.h"
|
|
#include "Game Event Hook.h"
|
|
#include "Quests.h"
|
|
#include "AimMembers.h"
|
|
|
|
#ifdef JA2UB
|
|
#include "Ja25_Tactical.h"
|
|
#include "Ja25 Strategic Ai.h"
|
|
#include "Speck Quotes.h"
|
|
#endif
|
|
|
|
#include "connect.h"
|
|
|
|
UINT8 NUMBER_OF_MERCS = 0;
|
|
UINT8 LAST_MERC_ID = -1;
|
|
UINT8 NUMBER_OF_BAD_MERCS = -1;
|
|
|
|
#define MERC_TEXT_FONT FONT12ARIAL
|
|
#define MERC_TEXT_COLOR FONT_MCOLOR_WHITE
|
|
|
|
#define MERC_VIDEO_TITLE_FONT FONT10ARIAL
|
|
#define MERC_VIDEO_TITLE_COLOR FONT_MCOLOR_LTYELLOW
|
|
|
|
#define MERC_BACKGROUND_WIDTH 125
|
|
#define MERC_BACKGROUND_HEIGHT 100
|
|
|
|
#define MERC_TITLE_X LAPTOP_SCREEN_UL_X + 135
|
|
#define MERC_TITLE_Y LAPTOP_SCREEN_WEB_UL_Y + 20
|
|
|
|
#define MERC_PORTRAIT_X LAPTOP_SCREEN_UL_X + 198
|
|
#define MERC_PORTRAIT_Y LAPTOP_SCREEN_WEB_UL_Y + 96
|
|
#define MERC_PORTRAIT_TEXT_X MERC_PORTRAIT_X
|
|
#define MERC_PORTRAIT_TEXT_Y MERC_PORTRAIT_Y + 109
|
|
#define MERC_PORTRAIT_TEXT_WIDTH 115
|
|
|
|
#define MERC_ACCOUNT_BOX_X LAPTOP_SCREEN_UL_X + 138
|
|
#define MERC_ACCOUNT_BOX_Y LAPTOP_SCREEN_WEB_UL_Y + 251
|
|
|
|
#define MERC_ACCOUNT_BOX_TEXT_X MERC_ACCOUNT_BOX_X
|
|
#define MERC_ACCOUNT_BOX_TEXT_Y MERC_ACCOUNT_BOX_Y + 20
|
|
#define MERC_ACCOUNT_BOX_TEXT_WIDTH 110
|
|
|
|
#define MERC_ACCOUNT_ARROW_X MERC_ACCOUNT_BOX_X + 125
|
|
#define MERC_ACCOUNT_ARROW_Y MERC_ACCOUNT_BOX_Y + 18
|
|
|
|
#define MERC_ACCOUNT_BUTTON_X MERC_ACCOUNT_BOX_X + 133
|
|
#define MERC_ACCOUNT_BUTTON_Y MERC_ACCOUNT_BOX_Y + 8
|
|
|
|
#define MERC_FILE_BOX_X MERC_ACCOUNT_BOX_X
|
|
#define MERC_FILE_BOX_Y LAPTOP_SCREEN_WEB_UL_Y + 321
|
|
|
|
#define MERC_FILE_BOX_TEXT_X MERC_FILE_BOX_X
|
|
#define MERC_FILE_BOX_TEXT_Y MERC_FILE_BOX_Y + 20
|
|
#define MERC_FILE_BOX_TEXT_WIDTH MERC_ACCOUNT_BOX_TEXT_WIDTH
|
|
|
|
#define MERC_FILE_ARROW_X MERC_FILE_BOX_X + 125
|
|
#define MERC_FILE_ARROW_Y MERC_FILE_BOX_Y + 18
|
|
|
|
#define MERC_FILE_BUTTON_X MERC_ACCOUNT_BUTTON_X
|
|
#define MERC_FILE_BUTTON_Y MERC_FILE_BOX_Y + 8
|
|
|
|
|
|
|
|
// Video Conference Defines
|
|
#define MERC_VIDEO_BACKGROUND_X MERC_PORTRAIT_X
|
|
#define MERC_VIDEO_BACKGROUND_Y MERC_PORTRAIT_Y
|
|
#define MERC_VIDEO_BACKGROUND_WIDTH 116
|
|
#define MERC_VIDEO_BACKGROUND_HEIGHT 108
|
|
|
|
#define MERC_VIDEO_FACE_X MERC_VIDEO_BACKGROUND_X + 10
|
|
#define MERC_VIDEO_FACE_Y MERC_VIDEO_BACKGROUND_Y + 17
|
|
#define MERC_VIDEO_FACE_WIDTH 96
|
|
#define MERC_VIDEO_FACE_HEIGHT 86
|
|
#define MERC_X_TO_CLOSE_VIDEO_X MERC_VIDEO_BACKGROUND_X + 104
|
|
#define MERC_X_TO_CLOSE_VIDEO_Y MERC_VIDEO_BACKGROUND_Y + 3
|
|
#define MERC_X_VIDEO_TITLE_X MERC_VIDEO_BACKGROUND_X + 5
|
|
#define MERC_X_VIDEO_TITLE_Y MERC_VIDEO_BACKGROUND_Y + 3
|
|
|
|
#define MERC_INTRO_TIME 1000
|
|
#define MERC_EXIT_TIME 500
|
|
#define MERC_VIDEO_MERC_ID_FOR_SPECKS 159//255
|
|
|
|
#define MERC_TEXT_BOX_POS_Y iScreenHeightOffset + 255
|
|
|
|
#define SPECK_IDLE_CHAT_DELAY 10000
|
|
|
|
#ifdef JA2UB
|
|
#define MERC_NUMBER_OF_RANDOM_QUOTES 20//19//14
|
|
#else
|
|
#define MERC_NUMBER_OF_RANDOM_QUOTES 19//14
|
|
#endif
|
|
|
|
|
|
#define MERC_FIRST_MERC BIFF
|
|
#define MERC_LAST_MERC BUBBA
|
|
|
|
|
|
//number of payment days ( # of merc days paid ) to get next set of mercs
|
|
#define MERC_NUM_DAYS_TILL_FIRST_MERC_AVAILABLE 10
|
|
#define MERC_NUM_DAYS_TILL_SECOND_MERC_AVAILABLE 16
|
|
#define MERC_NUM_DAYS_TILL_THIRD_MERC_AVAILABLE 24
|
|
#define MERC_NUM_DAYS_TILL_FOURTH_MERC_AVAILABLE 30
|
|
|
|
#define MERC__AMOUNT_OF_MONEY_FOR_BUBBA 6000
|
|
#define MERC__DAY_WHEN_BUBBA_CAN_BECOME_AVAILABLE 10
|
|
|
|
CONTITION_FOR_MERC_AVAILABLE_TEMP gConditionsForMercAvailabilityTemp[ NUM_PROFILES ];
|
|
CONTITION_FOR_MERC_AVAILABLE gConditionsForMercAvailability[ NUM_PROFILES ]; //NUM_MERC_ARRIVALS ]; //=
|
|
/*
|
|
{
|
|
5000, 8, 6, //BUBBA
|
|
10000, 15, 7, //Larry
|
|
15000, 20, 9, //Numb
|
|
16000, 21, 10, //Tex
|
|
18000, 23, 11, //Biggens
|
|
20000, 25, 12, //Cougar
|
|
25000, 30, 13, //Gaston
|
|
26000, 31, 14, //Stogie
|
|
|
|
};
|
|
*/
|
|
|
|
enum
|
|
{
|
|
MERC_DISTORTION_NO_DISTORTION,
|
|
MERC_DISTORTION_PIXELATE_UP,
|
|
MERC_DISTORTION_PIXELATE_DOWN,
|
|
MERC_DISRTORTION_DISTORT_IMAGE,
|
|
};
|
|
|
|
|
|
enum
|
|
{
|
|
MERC_SITE_NEVER_VISITED,
|
|
MERC_SITE_FIRST_VISIT,
|
|
MERC_SITE_SECOND_VISIT,
|
|
MERC_SITE_THIRD_OR_MORE_VISITS,
|
|
};
|
|
|
|
|
|
// Image Indetifiers
|
|
|
|
UINT32 guiAccountBox;
|
|
UINT32 guiArrow;
|
|
UINT32 guiFilesBox;
|
|
UINT32 guiMercSymbol;
|
|
UINT32 guiSpecPortrait;
|
|
UINT32 guiMercBackGround;
|
|
UINT32 guiMercVideoFaceBackground;
|
|
UINT32 guiMercVideoPopupBackground;
|
|
|
|
UINT8 gubMercArray[ NUM_PROFILES ]; //MAX_NUMBER_OF_MERCS
|
|
UINT8 gubCurMercIndex;
|
|
|
|
INT32 iMercPopUpBox = -1;
|
|
|
|
UINT16 gusPositionOfSpecksDialogBox_X;
|
|
CHAR16 gsSpeckDialogueTextPopUp[ 900 ];
|
|
UINT16 gusSpeckDialogueX;
|
|
UINT16 gusSpeckDialogueActualWidth;
|
|
|
|
BOOLEAN gfInMercSite=FALSE; //this flag is set when inide of the merc site
|
|
|
|
//Merc Video Conferencing Mode
|
|
enum
|
|
{
|
|
MERC_VIDEO_NO_VIDEO_MODE,
|
|
MERC_VIDEO_INIT_VIDEO_MODE,
|
|
MERC_VIDEO_VIDEO_MODE,
|
|
MERC_VIDEO_EXIT_VIDEO_MODE,
|
|
};
|
|
|
|
UINT8 gubCurrentMercVideoMode;
|
|
BOOLEAN gfMercVideoIsBeingDisplayed;
|
|
INT32 giVideoSpeckFaceIndex;
|
|
UINT16 gusMercVideoSpeckSpeech;
|
|
|
|
BOOLEAN gfDisplaySpeckTextBox=FALSE;
|
|
|
|
BOOLEAN gfJustEnteredMercSite=FALSE;
|
|
UINT8 gubArrivedFromMercSubSite=MERC_CAME_FROM_OTHER_PAGE; //the merc is arriving from one of the merc sub pages
|
|
BOOLEAN gfDoneIntroSpeech=TRUE;
|
|
|
|
BOOLEAN gfMercSiteScreenIsReDrawn=FALSE;
|
|
|
|
BOOLEAN gfJustHiredAMercMerc=FALSE;
|
|
|
|
BOOLEAN fMercHireOverPlayerLimitMerc=FALSE;
|
|
|
|
BOOLEAN gfRedrawMercSite=FALSE;
|
|
|
|
BOOLEAN gfFirstTimeIntoMERCSiteSinceEnteringLaptop=FALSE;
|
|
|
|
//used for the random quotes to try to balance the ones that are said
|
|
typedef struct
|
|
{
|
|
UINT8 ubQuoteID;
|
|
UINT32 uiNumberOfTimesQuoteSaid;
|
|
|
|
} NUMBER_TIMES_QUOTE_SAID;
|
|
NUMBER_TIMES_QUOTE_SAID gNumberOfTimesQuoteSaid[ MERC_NUMBER_OF_RANDOM_QUOTES ] =
|
|
{
|
|
#ifdef JA2UB
|
|
{ SPECK_QUOTE_BIFF_DEAD_WHEN_IMPORTING, 0 },
|
|
#endif
|
|
{ SPECK_QUOTE_RANDOM_CHIT_CHAT_1, 0 },
|
|
{ SPECK_QUOTE_RANDOM_CHIT_CHAT_2, 0 },
|
|
|
|
#ifdef JA2UB
|
|
{ SPECK_QUOTE_RANDOM_CHIT_CHAT_3, 0 },
|
|
#endif
|
|
|
|
{ SPECK_QUOTE_ADVERTISE_GASTON, 0 },
|
|
{ SPECK_QUOTE_ADVERTISE_STOGIE, 0 },
|
|
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_BIFF, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_HAYWIRE, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_GASKET, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_RAZOR, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_FLO, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_GUMPY, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_LARRY, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_COUGER, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_NUMB, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_BUBBA, 0 },
|
|
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_AIM_SLANDER_1, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_AIM_SLANDER_2, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_AIM_SLANDER_3, 0 },
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_AIM_SLANDER_4, 0 },
|
|
|
|
#ifdef JA2UB
|
|
#else
|
|
{ SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_HIMSELF, 0 },
|
|
#endif
|
|
};
|
|
|
|
|
|
//
|
|
// Buttons
|
|
//
|
|
|
|
// The Account Box button
|
|
void BtnAccountBoxButtonCallback(GUI_BUTTON *btn,INT32 reason);
|
|
UINT32 guiAccountBoxButton;
|
|
INT32 guiAccountBoxButtonImage;
|
|
|
|
//File Box
|
|
UINT32 guiFileBoxButton;
|
|
void BtnFileBoxButtonCallback(GUI_BUTTON *btn,INT32 reason);
|
|
|
|
// The 'X' to close the video conf window button
|
|
void BtnXToCloseMercVideoButtonCallback(GUI_BUTTON *btn,INT32 reason);
|
|
UINT32 guiXToCloseMercVideoButton;
|
|
INT32 guiXToCloseMercVideoButtonImage;
|
|
|
|
|
|
//Mouse region for the subtitles region when the merc is talking
|
|
MOUSE_REGION gMercSiteSubTitleMouseRegion;
|
|
void MercSiteSubTitleRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason );
|
|
|
|
|
|
BOOLEAN LoadNewMercsFromLoadGameFile( HWFILE hFile );
|
|
BOOLEAN SaveNewMercsToSaveGameFile( HWFILE hFile );
|
|
|
|
|
|
//*******************************
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
//*******************************
|
|
|
|
BOOLEAN StartSpeckTalking(UINT16 usQuoteNum);
|
|
void InitMercVideoFace();
|
|
BOOLEAN HandleSpeckTalking( BOOLEAN fReset );
|
|
//BOOLEAN PixelateVideoMercImage();
|
|
BOOLEAN PixelateVideoMercImage( BOOLEAN fUp, UINT16 usPosX, UINT16 usPosY, UINT16 usWidth, UINT16 usHeight);
|
|
BOOLEAN InitDestroyXToCloseVideoWindow( BOOLEAN fCreate );
|
|
BOOLEAN DisplayMercVideoIntro( UINT16 usTimeTillFinish );
|
|
void HandleCurrentMercDistortion();
|
|
void HandleTalkingSpeck();
|
|
//BOOLEAN DistortVideoMercImage();
|
|
BOOLEAN DistortVideoMercImage( UINT16 usPosX, UINT16 usPosY, UINT16 usWidth, UINT16 usHeight );
|
|
BOOLEAN IsAnyMercMercsHired( );
|
|
BOOLEAN IsAnyMercMercsDead();
|
|
UINT8 CountNumberOfMercMercsHired();
|
|
UINT8 CountNumberOfMercMercsWhoAreDead();
|
|
BOOLEAN GetSpeckConditionalOpening( BOOLEAN fJustEnteredScreen );
|
|
void RemoveSpeckPopupTextBox();
|
|
BOOLEAN ShouldSpeckStartTalkingDueToActionOnSubPage();
|
|
BOOLEAN ShouldSpeckSayAQuote();
|
|
void HandleSpeckIdleConversation( BOOLEAN fReset );
|
|
INT16 GetRandomQuoteThatHasBeenSaidTheLeast( );
|
|
void StopSpeckFromTalking( );
|
|
BOOLEAN HasLarryRelapsed();
|
|
void IncreaseMercRandomQuoteValue( UINT8 ubQuoteID, UINT8 ubValue );
|
|
BOOLEAN ShouldTheMercSiteServerGoDown();
|
|
void DrawMercVideoBackGround();
|
|
BOOLEAN CanMercQuoteBeSaid( UINT32 uiQuoteID );
|
|
UINT8 NumberOfMercMercsDead();
|
|
//void MakeBiffAwayForCoupleOfDays(); // anv: moved to mercs.h
|
|
BOOLEAN AreAnyOfTheNewMercsAvailable();
|
|
void ShouldAnyNewMercMercBecomeAvailable();
|
|
BOOLEAN CanMercBeAvailableYet( UINT8 ubMercToCheck );
|
|
UINT32 CalcMercDaysServed();
|
|
void RevaluateMercArray(); // silversurfer: for better savegame compatibility
|
|
#ifdef JA2UB
|
|
void MarkSpeckImportantQuoteUsed( UINT32 uiQuoteNum );
|
|
BOOLEAN HasImportantSpeckQuoteBeingSaid( UINT32 uiQuoteNum );
|
|
INT8 IsSpeckQuoteImportantQuote( UINT32 uiQuoteNum );
|
|
#endif
|
|
//ppp
|
|
|
|
BOOLEAN SaveNewMercsToSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
FileWrite( hFile, &gConditionsForMercAvailability, sizeof( gConditionsForMercAvailability), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( gConditionsForMercAvailability ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN LoadNewMercsFromLoadGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
CONTITION_FOR_MERC_AVAILABLE ConditionsForMercAvailabilityLoad[ NUM_PROFILES ];
|
|
|
|
FileRead( hFile, &ConditionsForMercAvailabilityLoad, sizeof( ConditionsForMercAvailabilityLoad ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( ConditionsForMercAvailabilityLoad ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// silversurfer: Now update the true gConditionsForMercAvailability array with the data from the savegame.
|
|
// Take every index of gConditionsForMercAvailability array that we initialized in GameInitMercs() and see
|
|
// if we can find a matching profile ID in ConditionsForMercAvailabilityLoad array that we loaded from the savegame.
|
|
// This prevents some issues when old savegames are loaded with updated MercAvailability.xml.
|
|
for ( UINT8 i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].ProfilId != 0 )
|
|
{
|
|
for ( UINT8 ilook=0; ilook<NUM_PROFILES; ilook++)
|
|
{
|
|
if ( ConditionsForMercAvailabilityLoad[ilook].ProfilId == gConditionsForMercAvailability[i].ProfilId )
|
|
{
|
|
// found a match! Now copy the data from the savegame to the gConditionsForMercAvailability array but ONLY relevant data!
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = ConditionsForMercAvailabilityLoad[ilook].NewMercsAvailable;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = ConditionsForMercAvailabilityLoad[ilook].StartMercsAvailable;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update list of mercs for M.E.R.C website
|
|
RevaluateMercArray();
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
// silversurfer: this function updates the list of available mercs (gubMercArray) and makes sure that
|
|
// it matches the contents of gConditionsForMercAvailability array
|
|
void RevaluateMercArray()
|
|
{
|
|
UINT8 i;
|
|
|
|
NUMBER_OF_MERCS = 0;
|
|
LAST_MERC_ID = -1;
|
|
NUMBER_OF_BAD_MERCS = -1;
|
|
|
|
// first clear gubMercArray
|
|
for ( i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
gubMercArray[ i ] = 0;
|
|
}
|
|
|
|
// now fill it again with the mercs from the savegame
|
|
for(i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].ProfilId != 0 )
|
|
{
|
|
NUMBER_OF_MERCS = NUMBER_OF_MERCS + 1;
|
|
LAST_MERC_ID = LAST_MERC_ID + 1;
|
|
gubMercArray[ i ] = gConditionsForMercAvailability[i].ProfilId;
|
|
}
|
|
}
|
|
|
|
// check how many mercs are supposed to be available
|
|
for(i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
// silversurfer: When a merc becomes available after money and time "NewMercsAvailable" is set to TRUE for him and saved to the savegame
|
|
// Therefore we should not check here if this tag is FALSE because it can't be false for him. "StartMercsAvailable" is also set to TRUE
|
|
// when he becomes available so we check only for this tag.
|
|
if ( gConditionsForMercAvailability[i].StartMercsAvailable == TRUE ) // && gConditionsForMercAvailability[i].NewMercsAvailable == FALSE )
|
|
NUMBER_OF_BAD_MERCS = NUMBER_OF_BAD_MERCS + 1;
|
|
}
|
|
|
|
// usually MERC_WEBSITE_ALL_MERCS_AVAILABLE could only be set on game start but now we can do it here too
|
|
if(!gGameExternalOptions.fAllMercsAvailable)
|
|
{
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_OF_BAD_MERCS;
|
|
}
|
|
else
|
|
{
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
if( CanMercBeAvailableDuringInit(i) )
|
|
{
|
|
// mercs that were not unlocked will now be unlocked
|
|
gConditionsForMercAvailabilityTemp[i].StartMercsAvailable = TRUE;
|
|
gConditionsForMercAvailabilityTemp[i].NewMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = TRUE;
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = FALSE;
|
|
}
|
|
else
|
|
{
|
|
// make sure that we don't accidentally lock an already unlocked merc
|
|
if ( gConditionsForMercAvailability[i].StartMercsAvailable == FALSE )
|
|
{
|
|
gConditionsForMercAvailabilityTemp[i].StartMercsAvailable = FALSE;
|
|
gConditionsForMercAvailabilityTemp[i].NewMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = FALSE;
|
|
LAST_MERC_ID--;
|
|
}
|
|
}
|
|
}
|
|
LaptopSaveInfo.gubLastMercIndex = LAST_MERC_ID;
|
|
}
|
|
}
|
|
|
|
BOOLEAN CanMercBeAvailableDuringInit( UINT8 ubMercToCheck )// anv: for all mercs available
|
|
{
|
|
if( gConditionsForMercAvailability[ubMercToCheck].Drunk == TRUE )
|
|
return ( FALSE );
|
|
if( gGameExternalOptions.fEnableRecruitableJA1Natives == FALSE )
|
|
{
|
|
if( gConditionsForMercAvailability[ubMercToCheck].ProfilId == ELIO ||
|
|
gConditionsForMercAvailability[ubMercToCheck].ProfilId == JUAN ||
|
|
gConditionsForMercAvailability[ubMercToCheck].ProfilId == WAHAN )
|
|
return ( FALSE );
|
|
}
|
|
if( gGameExternalOptions.fEnableRecruitableSpeck == FALSE )
|
|
{
|
|
if( gConditionsForMercAvailability[ubMercToCheck].ProfilId == SPECK_PLAYABLE )
|
|
return ( FALSE );
|
|
}
|
|
|
|
#ifdef JA25
|
|
#else
|
|
if( gConditionsForMercAvailability[ubMercToCheck].ProfilId == JOHN_MERC )
|
|
return ( FALSE );
|
|
#endif
|
|
|
|
return ( TRUE );
|
|
}
|
|
|
|
void GameInitMercs()
|
|
{
|
|
UINT8 i;
|
|
|
|
NUMBER_OF_MERCS = 0;
|
|
LAST_MERC_ID = -1;
|
|
NUMBER_OF_BAD_MERCS = -1;
|
|
|
|
for(i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].ProfilId != 0 )
|
|
{
|
|
NUMBER_OF_MERCS = NUMBER_OF_MERCS + 1;
|
|
LAST_MERC_ID = LAST_MERC_ID + 1;
|
|
gubMercArray[ i ] = gConditionsForMercAvailability[i].ProfilId;
|
|
}
|
|
}
|
|
|
|
for(i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].StartMercsAvailable == TRUE && gConditionsForMercAvailability[i].NewMercsAvailable == FALSE )
|
|
NUMBER_OF_BAD_MERCS = NUMBER_OF_BAD_MERCS + 1;
|
|
}
|
|
|
|
// anv: if all merc should be availabe, then set their availability info
|
|
if(gGameExternalOptions.fAllMercsAvailable == TRUE)
|
|
{
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
if( CanMercBeAvailableDuringInit(i) )
|
|
{
|
|
gConditionsForMercAvailabilityTemp[i].StartMercsAvailable = TRUE;
|
|
gConditionsForMercAvailabilityTemp[i].NewMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = TRUE;
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = FALSE;
|
|
}
|
|
else
|
|
{
|
|
gConditionsForMercAvailabilityTemp[i].StartMercsAvailable = FALSE;
|
|
gConditionsForMercAvailabilityTemp[i].NewMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = FALSE;
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = FALSE;
|
|
LAST_MERC_ID--;
|
|
}
|
|
}
|
|
}
|
|
|
|
LaptopSaveInfo.gubPlayersMercAccountStatus = MERC_NO_ACCOUNT;
|
|
gubCurMercIndex = 0;
|
|
|
|
if(!gGameExternalOptions.fAllMercsAvailable)
|
|
{
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_OF_BAD_MERCS; // LAST_MERC_ID;
|
|
}
|
|
else
|
|
{
|
|
LaptopSaveInfo.gubLastMercIndex = LAST_MERC_ID; //NUMBER_OF_BAD_MERCS;
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//Ja25. create an account immediately
|
|
{
|
|
//open an account
|
|
LaptopSaveInfo.gubPlayersMercAccountStatus = MERC_ACCOUNT_VALID;
|
|
|
|
//Get an account number
|
|
LaptopSaveInfo.guiPlayersMercAccountNumber = Random( 99999 );
|
|
}
|
|
#endif
|
|
|
|
gubCurrentMercVideoMode = MERC_VIDEO_NO_VIDEO_MODE;
|
|
gfMercVideoIsBeingDisplayed = FALSE;
|
|
|
|
LaptopSaveInfo.guiNumberOfMercPaymentsInDays = 0;
|
|
|
|
gusMercVideoSpeckSpeech = 0;
|
|
|
|
/*
|
|
for( i=0; i<MERC_NUMBER_OF_RANDOM_QUOTES; i++ )
|
|
{
|
|
gNumberOfTimesQuoteSaid[i] = 0;
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
BOOLEAN EnterMercs()
|
|
{
|
|
VOBJECT_DESC VObjectDesc;
|
|
VSURFACE_DESC vs_desc;
|
|
|
|
SetBookMark( MERC_BOOKMARK );
|
|
|
|
//Reset a static variable
|
|
HandleSpeckTalking( TRUE );
|
|
|
|
InitMercBackGround();
|
|
|
|
// load the Account box graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\AccountBox.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiAccountBox));
|
|
|
|
// load the files Box graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\FilesBox.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiFilesBox));
|
|
|
|
// load the MercSymbol graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\MERCSymbol.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiMercSymbol));
|
|
|
|
// load the SpecPortrait graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\SpecPortrait.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiSpecPortrait));
|
|
|
|
// load the Arrow graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\Arrow.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiArrow));
|
|
|
|
// load the Merc video conf background graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\SpeckComWindow.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiMercVideoPopupBackground));
|
|
|
|
|
|
// Account Box button
|
|
guiAccountBoxButtonImage = LoadButtonImage("LAPTOP\\SmallButtons.sti", -1,0,-1,1,-1 );
|
|
#ifdef JA2UB
|
|
// no UB
|
|
#else
|
|
guiAccountBoxButton = QuickCreateButton(guiAccountBoxButtonImage, MERC_ACCOUNT_BUTTON_X, MERC_ACCOUNT_BUTTON_Y,
|
|
BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
|
|
DEFAULT_MOVE_CALLBACK, BtnAccountBoxButtonCallback);
|
|
SetButtonCursor(guiAccountBoxButton, CURSOR_LAPTOP_SCREEN);
|
|
SpecifyDisabledButtonStyle( guiAccountBoxButton, DISABLED_STYLE_SHADED);
|
|
|
|
#endif
|
|
guiFileBoxButton = QuickCreateButton(guiAccountBoxButtonImage, MERC_FILE_BUTTON_X, MERC_FILE_BUTTON_Y,
|
|
BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
|
|
DEFAULT_MOVE_CALLBACK, BtnFileBoxButtonCallback);
|
|
SetButtonCursor(guiFileBoxButton, CURSOR_LAPTOP_SCREEN);
|
|
SpecifyDisabledButtonStyle( guiFileBoxButton, DISABLED_STYLE_SHADED);
|
|
|
|
//if the player doesnt have an account disable it
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_NO_ACCOUNT )
|
|
{
|
|
DisableButton( guiFileBoxButton );
|
|
}
|
|
|
|
|
|
//
|
|
// Video Conferencing stuff
|
|
//
|
|
|
|
// Create a background video surface to blt the face onto
|
|
vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
|
|
vs_desc.usWidth = MERC_VIDEO_FACE_WIDTH;
|
|
vs_desc.usHeight = MERC_VIDEO_FACE_HEIGHT;
|
|
vs_desc.ubBitDepth = 16;
|
|
CHECKF( AddVideoSurface( &vs_desc, &guiMercVideoFaceBackground) );
|
|
|
|
|
|
RenderMercs();
|
|
|
|
//init the face
|
|
|
|
gfJustEnteredMercSite = TRUE;
|
|
|
|
//Display a popup msg box telling the user when and where the merc will arrive after hire
|
|
if( gfJustHiredAMercMerc == TRUE )
|
|
DisplayPopUpBoxExplainingMercArrivalLocationAndTime();
|
|
//Display a popup msg box for max hire limit reached
|
|
else if( fMercHireOverPlayerLimitMerc == TRUE )
|
|
{
|
|
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, MercInfo[ MERC_FILES_HIRE_TO_MANY_PEOPLE_WARNING ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
|
|
fMercHireOverPlayerLimitMerc = FALSE;
|
|
}
|
|
|
|
//if NOT entering from a subsite
|
|
if( gubArrivedFromMercSubSite == MERC_CAME_FROM_OTHER_PAGE )
|
|
{
|
|
//Set that we have been here before
|
|
if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_NEVER_VISITED )
|
|
LaptopSaveInfo.ubPlayerBeenToMercSiteStatus = MERC_SITE_FIRST_VISIT;
|
|
else if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_FIRST_VISIT )
|
|
LaptopSaveInfo.ubPlayerBeenToMercSiteStatus = MERC_SITE_SECOND_VISIT;
|
|
else
|
|
LaptopSaveInfo.ubPlayerBeenToMercSiteStatus = MERC_SITE_THIRD_OR_MORE_VISITS;
|
|
|
|
//Reset the speech variable
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
}
|
|
|
|
|
|
GetSpeckConditionalOpening( TRUE );
|
|
// gubArrivedFromMercSubSite = MERC_CAME_FROM_OTHER_PAGE;
|
|
|
|
//if Speck should start talking
|
|
if( ShouldSpeckSayAQuote() )
|
|
{
|
|
gubCurrentMercVideoMode = MERC_VIDEO_INIT_VIDEO_MODE;
|
|
}
|
|
|
|
//Reset the some variables
|
|
HandleSpeckIdleConversation( TRUE );
|
|
|
|
//Since we are in the site, set the flag
|
|
gfInMercSite = TRUE;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
void ExitMercs()
|
|
{
|
|
StopSpeckFromTalking( );
|
|
|
|
if( gfMercVideoIsBeingDisplayed )
|
|
{
|
|
gfMercVideoIsBeingDisplayed = FALSE;
|
|
DeleteFace( giVideoSpeckFaceIndex );
|
|
InitDestroyXToCloseVideoWindow( FALSE );
|
|
gubCurrentMercVideoMode = MERC_VIDEO_NO_VIDEO_MODE;
|
|
}
|
|
|
|
DeleteVideoObjectFromIndex(guiAccountBox);
|
|
DeleteVideoObjectFromIndex(guiFilesBox);
|
|
DeleteVideoObjectFromIndex(guiMercSymbol);
|
|
DeleteVideoObjectFromIndex(guiSpecPortrait);
|
|
DeleteVideoObjectFromIndex(guiArrow);
|
|
DeleteVideoObjectFromIndex(guiMercVideoPopupBackground);
|
|
|
|
UnloadButtonImage( guiAccountBoxButtonImage );
|
|
RemoveButton( guiFileBoxButton );
|
|
#ifdef JA2UB
|
|
//JA25: removed RemoveButton( guiAccountBoxButton );
|
|
#else
|
|
RemoveButton( guiAccountBoxButton );
|
|
#endif
|
|
RemoveMercBackGround();
|
|
|
|
DeleteVideoSurfaceFromIndex( guiMercVideoFaceBackground );
|
|
|
|
/*
|
|
//Set that we have been here before
|
|
if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_FIRST_VISIT )
|
|
LaptopSaveInfo.ubPlayerBeenToMercSiteStatus = MERC_SITE_SECOND_VISIT;
|
|
else
|
|
LaptopSaveInfo.ubPlayerBeenToMercSiteStatus = MERC_SITE_THIRD_OR_MORE_VISITS;
|
|
*/
|
|
|
|
gfJustEnteredMercSite = TRUE;
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
|
|
//Remove the merc text box if one is available
|
|
RemoveSpeckPopupTextBox();
|
|
|
|
//Set up so next time we come in, we know we came from a differnt page
|
|
gubArrivedFromMercSubSite = MERC_CAME_FROM_OTHER_PAGE;
|
|
|
|
gfJustHiredAMercMerc = FALSE;
|
|
|
|
//Since we are leaving the site, set the flag
|
|
gfInMercSite = TRUE;
|
|
|
|
//Empty the Queue cause Speck could still have a quote in waiting
|
|
EmptyDialogueQueue( );
|
|
}
|
|
|
|
void HandleMercs()
|
|
{
|
|
if( gfRedrawMercSite )
|
|
{
|
|
RenderMercs();
|
|
gfRedrawMercSite = FALSE;
|
|
gfMercSiteScreenIsReDrawn = TRUE;
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
#else
|
|
// anv: stop, Speck can't say anything because he's out of reach
|
|
if( !IsSpeckComAvailable() )
|
|
{
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
gubCurrentMercVideoMode = MERC_VIDEO_NO_VIDEO_MODE;
|
|
RenderMercs();
|
|
gfRedrawMercSite = TRUE;
|
|
}
|
|
#endif
|
|
|
|
//if Speck has something to say, say it
|
|
if( gusMercVideoSpeckSpeech != MERC_VIDEO_SPECK_SPEECH_NOT_TALKING )// && !gfDoneIntroSpeech )
|
|
{
|
|
//if the face isnt active, make it so
|
|
if( !gfMercVideoIsBeingDisplayed )
|
|
{
|
|
// Blt the video window background
|
|
DrawMercVideoBackGround();
|
|
|
|
InitDestroyXToCloseVideoWindow( TRUE );
|
|
|
|
InitMercVideoFace();
|
|
gubCurrentMercVideoMode = MERC_VIDEO_INIT_VIDEO_MODE;
|
|
|
|
// gfMercSiteScreenIsReDrawn = TRUE;
|
|
}
|
|
}
|
|
|
|
//if the page is redrawn, and we are in video conferencing, redraw the VC backgrund graphic
|
|
if( gfMercVideoIsBeingDisplayed && gfMercSiteScreenIsReDrawn )
|
|
{
|
|
// Blt the video window background
|
|
DrawMercVideoBackGround();
|
|
|
|
gfMercSiteScreenIsReDrawn = FALSE;
|
|
}
|
|
|
|
|
|
//if Specks should be video conferencing...
|
|
if( gubCurrentMercVideoMode != MERC_VIDEO_NO_VIDEO_MODE )
|
|
{
|
|
HandleTalkingSpeck();
|
|
}
|
|
|
|
//Reset the some variables
|
|
HandleSpeckIdleConversation( FALSE );
|
|
|
|
if( fCurrentlyInLaptop == FALSE )
|
|
{
|
|
//if we are exiting the laptop screen, shut up the speck
|
|
StopSpeckFromTalking( );
|
|
}
|
|
}
|
|
|
|
void RenderMercs()
|
|
{
|
|
HVOBJECT hPixHandle;
|
|
|
|
DrawMecBackGround();
|
|
|
|
// Title
|
|
GetVideoObject(&hPixHandle, guiMercSymbol);
|
|
BltVideoObject(FRAME_BUFFER, hPixHandle, 0,MERC_TITLE_X, MERC_TITLE_Y, VO_BLT_SRCTRANSPARENCY,NULL);
|
|
|
|
// Speck Portrait
|
|
GetVideoObject(&hPixHandle, guiSpecPortrait);
|
|
BltVideoObject(FRAME_BUFFER, hPixHandle, 0,MERC_PORTRAIT_X, MERC_PORTRAIT_Y, VO_BLT_SRCTRANSPARENCY,NULL);
|
|
|
|
// Account Box
|
|
GetVideoObject(&hPixHandle, guiAccountBox);
|
|
BltVideoObject(FRAME_BUFFER, hPixHandle, 0,MERC_ACCOUNT_BOX_X, MERC_ACCOUNT_BOX_Y, VO_BLT_SRCTRANSPARENCY,NULL);
|
|
|
|
// Files Box
|
|
GetVideoObject(&hPixHandle, guiFilesBox);
|
|
BltVideoObject(FRAME_BUFFER, hPixHandle, 0, MERC_FILE_BOX_X, MERC_FILE_BOX_Y, VO_BLT_SRCTRANSPARENCY,NULL);
|
|
|
|
//Text on the Speck Portrait
|
|
DisplayWrappedString(MERC_PORTRAIT_TEXT_X, MERC_PORTRAIT_TEXT_Y, MERC_PORTRAIT_TEXT_WIDTH, 2, MERC_TEXT_FONT, MERC_TEXT_COLOR, MercHomePageText[MERC_SPECK_OWNER], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
|
|
|
|
#ifdef JA2UB
|
|
//Display the "ask about or special offer
|
|
DisplayWrappedString(MERC_ACCOUNT_BOX_TEXT_X, MERC_ACCOUNT_BOX_TEXT_Y, 230, 2, MERC_TEXT_FONT, MERC_TEXT_COLOR, gzNewLaptopMessages[ LPTP_MSG__MERC_SPECIAL_OFFER ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
|
|
#else
|
|
/* ja25:*/
|
|
//Text on the Account Box
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_NO_ACCOUNT )
|
|
DisplayWrappedString(MERC_ACCOUNT_BOX_TEXT_X, MERC_ACCOUNT_BOX_TEXT_Y, MERC_ACCOUNT_BOX_TEXT_WIDTH, 2, MERC_TEXT_FONT, MERC_TEXT_COLOR, MercHomePageText[MERC_OPEN_ACCOUNT], FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
|
|
else
|
|
DisplayWrappedString(MERC_ACCOUNT_BOX_TEXT_X, MERC_ACCOUNT_BOX_TEXT_Y, MERC_ACCOUNT_BOX_TEXT_WIDTH, 2, MERC_TEXT_FONT, MERC_TEXT_COLOR, MercHomePageText[MERC_VIEW_ACCOUNT], FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
|
|
#endif
|
|
//Text on the Files Box
|
|
DisplayWrappedString(MERC_FILE_BOX_TEXT_X, MERC_FILE_BOX_TEXT_Y, MERC_FILE_BOX_TEXT_WIDTH, 2, MERC_TEXT_FONT, MERC_TEXT_COLOR, MercHomePageText[MERC_VIEW_FILES], FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
|
|
|
|
//If the Specks popup dioalogue box is active, display it.
|
|
if( iMercPopUpBox != -1 )
|
|
{
|
|
|
|
#ifdef JA2UB
|
|
//JA25: removed DrawButton( guiAccountBoxButton );
|
|
// ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#else
|
|
DrawButton( guiAccountBoxButton );
|
|
ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#endif
|
|
RenderMercPopUpBoxFromIndex( iMercPopUpBox, gusSpeckDialogueX, MERC_TEXT_BOX_POS_Y, FRAME_BUFFER);
|
|
}
|
|
|
|
MarkButtonsDirty( );
|
|
RenderWWWProgramTitleBar( );
|
|
|
|
//if the page is redrawn, and we are in video conferencing, redraw the VC backgrund graphic
|
|
gfMercSiteScreenIsReDrawn = TRUE;
|
|
#ifdef JA2UB
|
|
//JA25: removed ButtonList[ guiAccountBoxButton ]->uiFlags &= ~BUTTON_FORCE_UNDIRTY;
|
|
#else
|
|
ButtonList[ guiAccountBoxButton ]->uiFlags &= ~BUTTON_FORCE_UNDIRTY;
|
|
#endif
|
|
InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y);
|
|
}
|
|
|
|
|
|
BOOLEAN InitMercBackGround()
|
|
{
|
|
VOBJECT_DESC VObjectDesc;
|
|
|
|
// load the Merc background graphic and add it
|
|
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP("LAPTOP\\MERCBackGround.sti", VObjectDesc.ImageFile);
|
|
CHECKF(AddVideoObject(&VObjectDesc, &guiMercBackGround));
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOLEAN DrawMecBackGround()
|
|
{
|
|
WebPageTileBackground(4, 4, MERC_BACKGROUND_WIDTH, MERC_BACKGROUND_HEIGHT, guiMercBackGround);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOLEAN RemoveMercBackGround()
|
|
{
|
|
DeleteVideoObjectFromIndex(guiMercBackGround);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
#ifdef JA2UB
|
|
//no UB
|
|
#else
|
|
void BtnAccountBoxButtonCallback(GUI_BUTTON *btn,INT32 reason)
|
|
{
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
|
{
|
|
btn->uiFlags |= BUTTON_CLICKED_ON;
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
|
|
{
|
|
if (btn->uiFlags & BUTTON_CLICKED_ON)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_NO_ACCOUNT )
|
|
guiCurrentLaptopMode = LAPTOP_MODE_MERC_NO_ACCOUNT;
|
|
else
|
|
guiCurrentLaptopMode = LAPTOP_MODE_MERC_ACCOUNT;
|
|
|
|
if( iMercPopUpBox != -1 )
|
|
{
|
|
ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
|
|
RenderMercPopUpBoxFromIndex( iMercPopUpBox, gusSpeckDialogueX, MERC_TEXT_BOX_POS_Y, FRAME_BUFFER);
|
|
}
|
|
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void BtnFileBoxButtonCallback(GUI_BUTTON *btn,INT32 reason)
|
|
{
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
|
{
|
|
btn->uiFlags |= BUTTON_CLICKED_ON;
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
|
|
{
|
|
if (btn->uiFlags & BUTTON_CLICKED_ON)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
|
|
guiCurrentLaptopMode = LAPTOP_MODE_MERC_FILES;
|
|
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
|
|
|
|
void DailyUpdateOfMercSite( UINT16 usDate)
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT16 sSoldierID, i;
|
|
UINT8 ubMercID;
|
|
INT32 iNumDays;
|
|
|
|
//if its the first day, leave
|
|
if( usDate == 1 )
|
|
return;
|
|
|
|
iNumDays = 0;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; ++i )
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( (UINT8) i );
|
|
if( IsMercOnTeam( ubMercID, FALSE, FALSE ) )
|
|
{
|
|
// WANNE: If we have drunken merc, then skip otherwise is will exist 2 times!
|
|
if (gConditionsForMercAvailability[ i ].Drunk)
|
|
continue;
|
|
|
|
//// WANNE.LARRY
|
|
////if it larry Roach burn advance. ( cause larry is in twice, a sober larry and a stoned larry )
|
|
//if( i == MERC_LARRY_ROACHBURN )
|
|
// continue;
|
|
|
|
sSoldierID = GetSoldierIDFromMercID( ubMercID );
|
|
pSoldier = MercPtrs[ sSoldierID ];
|
|
|
|
//if the merc is dead, dont advance the contract length
|
|
if( !IsMercDead( pSoldier->ubProfile ) )
|
|
{
|
|
gMercProfiles[ pSoldier->ubProfile ].iMercMercContractLength += 1;
|
|
// pSoldier->iTotalContractLength++;
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//JA25: MERC does a 1 time fee, no longer pay as you go
|
|
#else
|
|
|
|
//Get the longest time
|
|
if( gMercProfiles[ pSoldier->ubProfile ].iMercMercContractLength > iNumDays )
|
|
iNumDays = gMercProfiles[ pSoldier->ubProfile ].iMercMercContractLength;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//JA25: No longer pay as you go, now pay up front
|
|
#else
|
|
//if the players hasnt paid for a while, get email him to tell him to pay
|
|
//iTotalContractLength
|
|
if( iNumDays > MERC_NUM_DAYS_TILL_ACCOUNT_INVALID )
|
|
{
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus != MERC_ACCOUNT_INVALID )
|
|
{
|
|
LaptopSaveInfo.gubPlayersMercAccountStatus = MERC_ACCOUNT_INVALID;
|
|
if( IsSpeckComAvailable() )
|
|
{
|
|
AddEmail( MERC_INVALID, MERC_INVALID_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT);
|
|
}
|
|
else
|
|
{
|
|
// anv: Have speck complain personally
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ) , SPECK_PLAYABLE_QUOTE_PLAYER_OWES_SPECK_ACCOUNT_SUSPENDED );
|
|
}
|
|
}
|
|
}
|
|
else if( iNumDays > MERC_NUM_DAYS_TILL_ACCOUNT_SUSPENDED )
|
|
{
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus != MERC_ACCOUNT_SUSPENDED )
|
|
{
|
|
LaptopSaveInfo.gubPlayersMercAccountStatus = MERC_ACCOUNT_SUSPENDED;
|
|
if( IsSpeckComAvailable() )
|
|
{
|
|
AddEmail( MERC_WARNING, MERC_WARNING_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT);
|
|
|
|
// Have speck complain next time player come to site
|
|
LaptopSaveInfo.uiSpeckQuoteFlags |= SPECK_QUOTE__SENT_EMAIL_ABOUT_LACK_OF_PAYMENT;
|
|
}
|
|
else
|
|
{
|
|
// anv: Have speck complain personally
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ) , SPECK_PLAYABLE_QUOTE_PLAYER_OWES_SPECK_ALMOST_BANKRUPT_2);
|
|
}
|
|
}
|
|
}
|
|
else if( iNumDays > MERC_NUM_DAYS_TILL_FIRST_WARNING)
|
|
{
|
|
if( LaptopSaveInfo.gubPlayersMercAccountStatus != MERC_ACCOUNT_VALID_FIRST_WARNING )
|
|
{
|
|
LaptopSaveInfo.gubPlayersMercAccountStatus = MERC_ACCOUNT_VALID_FIRST_WARNING;
|
|
if( IsSpeckComAvailable() )
|
|
{
|
|
AddEmail( MERC_FIRST_WARNING, MERC_FIRST_WARNING_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT);
|
|
|
|
// Have speck complain next time player come to site
|
|
LaptopSaveInfo.uiSpeckQuoteFlags |= SPECK_QUOTE__SENT_EMAIL_ABOUT_LACK_OF_PAYMENT;
|
|
}
|
|
else
|
|
{
|
|
// anv: Have speck complain personally
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ) , SPECK_PLAYABLE_QUOTE_PLAYER_OWES_SPECK_ALMOST_BANKRUPT_1 );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//Check and act if any new Merc Mercs should become available
|
|
ShouldAnyNewMercMercBecomeAvailable();
|
|
|
|
/*
|
|
//If we should advacne the number of days that the good mercs arrive
|
|
// if( LaptopSaveInfo.guiNumberOfMercPaymentsInDays > 4 )
|
|
{
|
|
UINT8 ubNumDays;
|
|
|
|
// ubNumDays = (UINT8) LaptopSaveInfo.guiNumberOfMercPaymentsInDays / 4;
|
|
ubNumDays = (UINT8) LaptopSaveInfo.guiNumberOfMercPaymentsInDays;
|
|
|
|
// LaptopSaveInfo.guiNumberOfMercPaymentsInDays = LaptopSaveInfo.guiNumberOfMercPaymentsInDays % 4;
|
|
LaptopSaveInfo.guiNumberOfMercPaymentsInDays = 0;
|
|
|
|
//for the first merc
|
|
//if the merc is not already here
|
|
if( LaptopSaveInfo.gbNumDaysTillFirstMercArrives != -1 )
|
|
{
|
|
//We advance the day the merc arrives on
|
|
if( LaptopSaveInfo.gbNumDaysTillFirstMercArrives > ubNumDays )
|
|
{
|
|
LaptopSaveInfo.gbNumDaysTillFirstMercArrives -= ubNumDays;
|
|
}
|
|
else
|
|
{
|
|
//its time to add the new mercs
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_MERCS_AFTER_FIRST_MERC_ARRIVES;
|
|
|
|
//Set the fact that there are new mercs available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
|
|
//if we havent already sent an email this turn
|
|
if( !fAlreadySentEmailToPlayerThisTurn )
|
|
{
|
|
AddEmail( NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), TYPE_EMAIL_EMAIL_EDT);
|
|
fAlreadySentEmailToPlayerThisTurn = TRUE;
|
|
}
|
|
LaptopSaveInfo.gbNumDaysTillFirstMercArrives = -1;
|
|
}
|
|
}
|
|
|
|
|
|
//for the Second merc
|
|
//if the merc is not already here
|
|
if( LaptopSaveInfo.gbNumDaysTillSecondMercArrives != -1 )
|
|
{
|
|
//We advance the day the merc arrives on
|
|
if( LaptopSaveInfo.gbNumDaysTillSecondMercArrives > ubNumDays )
|
|
{
|
|
LaptopSaveInfo.gbNumDaysTillSecondMercArrives -= ubNumDays;
|
|
}
|
|
else
|
|
{
|
|
//its time to add the new mercs
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_MERCS_AFTER_SECOND_MERC_ARRIVES;
|
|
|
|
//Set the fact that there are new mercs available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
|
|
//if we havent already sent an email this turn
|
|
if( !fAlreadySentEmailToPlayerThisTurn )
|
|
{
|
|
AddEmail( NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin());
|
|
fAlreadySentEmailToPlayerThisTurn = TRUE;
|
|
}
|
|
LaptopSaveInfo.gbNumDaysTillSecondMercArrives = -1;
|
|
}
|
|
}
|
|
|
|
//for the Third merc
|
|
//if the merc is not already here
|
|
if( LaptopSaveInfo.gbNumDaysTillThirdMercArrives != -1 )
|
|
{
|
|
//We advance the day the merc arrives on
|
|
if( LaptopSaveInfo.gbNumDaysTillThirdMercArrives > ubNumDays )
|
|
{
|
|
LaptopSaveInfo.gbNumDaysTillThirdMercArrives -= ubNumDays;
|
|
}
|
|
else
|
|
{
|
|
//its time to add the new mercs
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_MERCS_AFTER_THIRD_MERC_ARRIVES;
|
|
|
|
//Set the fact that there are new mercs available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
|
|
//if we havent already sent an email this turn
|
|
if( !fAlreadySentEmailToPlayerThisTurn )
|
|
{
|
|
AddEmail( NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin());
|
|
fAlreadySentEmailToPlayerThisTurn = TRUE;
|
|
}
|
|
LaptopSaveInfo.gbNumDaysTillThirdMercArrives = -1;
|
|
}
|
|
}
|
|
|
|
//for the Fourth merc
|
|
//if the merc is not already here
|
|
if( LaptopSaveInfo.gbNumDaysTillFourthMercArrives != -1 )
|
|
{
|
|
//We advance the day the merc arrives on
|
|
if( LaptopSaveInfo.gbNumDaysTillFourthMercArrives > ubNumDays )
|
|
{
|
|
LaptopSaveInfo.gbNumDaysTillFourthMercArrives -= ubNumDays;
|
|
}
|
|
else
|
|
{
|
|
//its time to add the new mercs
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_MERCS_AFTER_FOURTH_MERC_ARRIVES;
|
|
|
|
//Set the fact that there are new mercs available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
|
|
//if we havent already sent an email this turn
|
|
if( !fAlreadySentEmailToPlayerThisTurn )
|
|
{
|
|
AddEmail( NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin());
|
|
fAlreadySentEmailToPlayerThisTurn = TRUE;
|
|
}
|
|
LaptopSaveInfo.gbNumDaysTillFourthMercArrives = -1;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
// If the merc site has never gone down, the number of MERC payment days is above 'X',
|
|
// and the players account status is ok ( cant have the merc site going down when the player owes him money, player may lose account that way )
|
|
#ifdef JA2UB
|
|
// no UB
|
|
#else
|
|
if( ShouldTheMercSiteServerGoDown() )
|
|
{
|
|
UINT32 uiTimeInMinutes=0;
|
|
|
|
|
|
//Set the fact the site has gone down
|
|
LaptopSaveInfo.fMercSiteHasGoneDownYet = TRUE;
|
|
|
|
//No lnger removing the bookmark, leave it up, and the user will go to the broken link page
|
|
//Remove the book mark
|
|
// RemoveBookMark( MERC_BOOKMARK );
|
|
|
|
//Get the site up the next day at 6:00 pm
|
|
uiTimeInMinutes = GetMidnightOfFutureDayInMinutes( 1 ) + 18 * 60;
|
|
|
|
//Add an event that will get the site back up and running
|
|
AddStrategicEvent( EVENT_MERC_SITE_BACK_ONLINE, uiTimeInMinutes, 0 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
// anv: Gets the actually available merc. For use in displaying unlocked mercs on MERC website.
|
|
UINT8 GetAvailableMercIndex(UINT8 gubCurMercIndex)
|
|
{
|
|
UINT8 returnID = 0;
|
|
if( gubCurMercIndex <= NUM_PROFILES )
|
|
{
|
|
UINT8 availableID = 0;
|
|
UINT8 ID = 0;
|
|
//go through mercs, but only consider those unlocked
|
|
while( availableID < gubCurMercIndex )
|
|
{
|
|
ID++;
|
|
if( gConditionsForMercAvailability[ ID ].StartMercsAvailable == TRUE )
|
|
availableID++;
|
|
|
|
}
|
|
returnID = ID;
|
|
}
|
|
|
|
// Is this a drunken merc (e.g Larry) and has an additional drunken profile
|
|
if( gConditionsForMercAvailability[ returnID ].Drunk == TRUE && gConditionsForMercAvailability[ returnID ].uiAlternateIndex != 255)
|
|
{
|
|
if ( HasLarryRelapsed() )
|
|
{
|
|
// Drunken Larry
|
|
if (gConditionsForMercAvailability[ returnID ].uiIndex <= NUM_PROFILES)
|
|
{
|
|
returnID = gConditionsForMercAvailability[ returnID ].uiIndex;
|
|
}
|
|
else
|
|
{
|
|
Assert(0);
|
|
return( TRUE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Normal Larry (Normal Profile is one
|
|
returnID = gConditionsForMercAvailability[ returnID ].uiAlternateIndex;
|
|
}
|
|
}
|
|
return returnID;
|
|
}
|
|
|
|
UINT8 GetAvailableMercIDFromMERCArray(UINT8 ubMercID)
|
|
{
|
|
return gubMercArray[GetAvailableMercIndex(ubMercID)];
|
|
}
|
|
|
|
//Gets the actual merc id from the array
|
|
UINT8 GetMercIDFromMERCArray(UINT8 ubMercID)
|
|
{
|
|
// Is this a drunken merc (e.g Larry) and has an additional drunken profile
|
|
if( gConditionsForMercAvailability[ ubMercID ].Drunk == TRUE && gConditionsForMercAvailability[ ubMercID ].uiAlternateIndex != 255)
|
|
{
|
|
if ( HasLarryRelapsed() )
|
|
{
|
|
// Drunken Larry
|
|
if (gConditionsForMercAvailability[ ubMercID ].uiIndex <= NUM_PROFILES)
|
|
{
|
|
return( gubMercArray[ gConditionsForMercAvailability[ ubMercID ].uiIndex ] );
|
|
}
|
|
else
|
|
{
|
|
Assert(0);
|
|
return( TRUE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Normal Larry (Normal Profile is one
|
|
return( gubMercArray[ gConditionsForMercAvailability[ ubMercID ].uiAlternateIndex ] );
|
|
}
|
|
}
|
|
// Merc is not drunken
|
|
else if( ubMercID <= NUM_PROFILES )
|
|
{
|
|
return( gubMercArray[ ubMercID ] );
|
|
}
|
|
//else its an error
|
|
else
|
|
{
|
|
Assert(0);
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
BOOLEAN InitDeleteMercVideoConferenceMode()
|
|
{
|
|
static BOOLEAN fVideoConfModeCreated = FALSE;
|
|
|
|
if( !fVideoConfModeCreated && gubCurrentMercVideoMode == MERC_VIDEO_INIT_VIDEO_MODE )
|
|
{
|
|
// InitMercVideoFace();
|
|
}
|
|
|
|
if( fVideoConfModeCreated && gubCurrentMercVideoMode == MERC_VIDEO_EXIT_VIDEO_MODE )
|
|
{
|
|
//If merc is talking, stop him from talking
|
|
ShutupaYoFace( giVideoSpeckFaceIndex );
|
|
|
|
//Delete the face
|
|
DeleteFace( giVideoSpeckFaceIndex );
|
|
|
|
gfMercVideoIsBeingDisplayed = FALSE;
|
|
}
|
|
|
|
|
|
return(TRUE);
|
|
}
|
|
*/
|
|
|
|
void InitMercVideoFace()
|
|
{
|
|
//Alocates space, and loads the sti for SPECK
|
|
// giVideoSpeckFaceIndex = InternalInitFace( NO_PROFILE, NOBODY, 0, MERC_VIDEO_MERC_ID_FOR_SPECKS, 3000, 2000 );
|
|
giVideoSpeckFaceIndex = InitFace( MERC_VIDEO_MERC_ID_FOR_SPECKS, NOBODY, 0 );
|
|
|
|
// Sets up the eyes blinking and the mouth moving
|
|
// InternalSetAutoFaceActive( guiMercVideoFaceBackground, FACE_AUTO_RESTORE_BUFFER , giVideoSpeckFaceIndex, 0, 0, 8, 9, 7, 25 );
|
|
SetAutoFaceActive( guiMercVideoFaceBackground, FACE_AUTO_RESTORE_BUFFER , giVideoSpeckFaceIndex, 0, 0);
|
|
|
|
|
|
//Renders the face to the background
|
|
RenderAutoFace( giVideoSpeckFaceIndex );
|
|
|
|
//enables the global flag indicating the the video is being displayed
|
|
gfMercVideoIsBeingDisplayed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
BOOLEAN StartSpeckTalking(UINT16 usQuoteNum)
|
|
{
|
|
|
|
if(is_networked)
|
|
return( FALSE );
|
|
|
|
if( usQuoteNum == MERC_VIDEO_SPECK_SPEECH_NOT_TALKING || usQuoteNum == MERC_VIDEO_SPECK_HAS_TO_TALK_BUT_QUOTE_NOT_CHOSEN_YET )
|
|
return( FALSE );
|
|
|
|
//Reset the time for when speck starts to do the random quotes
|
|
HandleSpeckIdleConversation( TRUE );
|
|
|
|
//Start Speck talking
|
|
if(!CharacterDialogue( MERC_VIDEO_MERC_ID_FOR_SPECKS, usQuoteNum, giVideoSpeckFaceIndex, DIALOGUE_SPECK_CONTACT_PAGE_UI, FALSE, FALSE ) )
|
|
{
|
|
Assert(0);
|
|
return(FALSE);
|
|
}
|
|
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
// Performs the frame by frame update
|
|
BOOLEAN HandleSpeckTalking( BOOLEAN fReset )
|
|
{
|
|
static BOOLEAN fWasTheMercTalking=FALSE;
|
|
BOOLEAN fIsTheMercTalking;
|
|
SGPRect SrcRect;
|
|
SGPRect DestRect;
|
|
|
|
if( fReset )
|
|
{
|
|
fWasTheMercTalking = FALSE;
|
|
return( TRUE );
|
|
}
|
|
|
|
SrcRect.iLeft = 0;
|
|
SrcRect.iTop = 0;
|
|
SrcRect.iRight = 48;
|
|
SrcRect.iBottom = 43;
|
|
|
|
DestRect.iLeft = MERC_VIDEO_FACE_X;
|
|
DestRect.iTop = MERC_VIDEO_FACE_Y;
|
|
DestRect.iRight = DestRect.iLeft + MERC_VIDEO_FACE_WIDTH;
|
|
DestRect.iBottom = DestRect.iTop + MERC_VIDEO_FACE_HEIGHT;
|
|
|
|
HandleDialogue();
|
|
HandleAutoFaces( );
|
|
HandleTalkingAutoFaces( );
|
|
|
|
//Blt the face surface to the video background surface
|
|
if( !BltStretchVideoSurface(FRAME_BUFFER, guiMercVideoFaceBackground, 0, 0, VO_BLT_SRCTRANSPARENCY, &SrcRect, &DestRect ) )
|
|
return(FALSE);
|
|
|
|
//HandleCurrentMercDistortion();
|
|
|
|
InvalidateRegion(MERC_VIDEO_BACKGROUND_X, MERC_VIDEO_BACKGROUND_Y, (MERC_VIDEO_BACKGROUND_X + MERC_VIDEO_BACKGROUND_WIDTH), (MERC_VIDEO_BACKGROUND_Y + MERC_VIDEO_BACKGROUND_HEIGHT) );
|
|
|
|
//find out if the merc just stopped talking
|
|
fIsTheMercTalking = gFacesData[ giVideoSpeckFaceIndex ].fTalking;
|
|
|
|
//if the merc just stopped talking
|
|
if(fWasTheMercTalking && !fIsTheMercTalking)
|
|
{
|
|
fWasTheMercTalking = FALSE;
|
|
|
|
if( DialogueQueueIsEmpty( ) )
|
|
{
|
|
RemoveSpeckPopupTextBox();
|
|
|
|
gfDisplaySpeckTextBox = FALSE;
|
|
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
|
|
//Reset the time for when speck starts to do the random quotes
|
|
HandleSpeckIdleConversation( TRUE );
|
|
}
|
|
else
|
|
fIsTheMercTalking = TRUE;
|
|
}
|
|
|
|
fWasTheMercTalking = fIsTheMercTalking;
|
|
|
|
return(fIsTheMercTalking);
|
|
}
|
|
|
|
|
|
void HandleCurrentMercDistortion()
|
|
{
|
|
static UINT8 ubCurrentMercDistortionMode = MERC_DISTORTION_NO_DISTORTION;
|
|
BOOLEAN fReturnStatus;
|
|
|
|
//if there is no current distortion mode, randomly choose one
|
|
if( ubCurrentMercDistortionMode == MERC_DISTORTION_NO_DISTORTION )
|
|
{
|
|
UINT8 ubRandom;
|
|
|
|
ubRandom = (UINT8)Random(200);
|
|
|
|
if( ubRandom < 40 )
|
|
{
|
|
ubRandom = (UINT8)Random(100);
|
|
if( ubRandom < 10 )
|
|
ubCurrentMercDistortionMode = MERC_DISRTORTION_DISTORT_IMAGE;
|
|
else if( ubRandom < 30 )
|
|
ubCurrentMercDistortionMode = MERC_DISTORTION_PIXELATE_UP;
|
|
}
|
|
}
|
|
|
|
// Perform whichever video distortion mode is current
|
|
switch( ubCurrentMercDistortionMode )
|
|
{
|
|
case MERC_DISTORTION_NO_DISTORTION:
|
|
break;
|
|
|
|
case MERC_DISTORTION_PIXELATE_UP:
|
|
// fReturnStatus = PixelateVideoMercImage( TRUE );
|
|
fReturnStatus = PixelateVideoMercImage( TRUE, MERC_VIDEO_FACE_X, MERC_VIDEO_FACE_Y, MERC_VIDEO_FACE_WIDTH, MERC_VIDEO_FACE_HEIGHT );
|
|
if( fReturnStatus )
|
|
ubCurrentMercDistortionMode = MERC_DISTORTION_PIXELATE_DOWN;
|
|
break;
|
|
|
|
case MERC_DISTORTION_PIXELATE_DOWN:
|
|
// fReturnStatus = PixelateVideoMercImage( FALSE );
|
|
fReturnStatus = PixelateVideoMercImage( FALSE, MERC_VIDEO_FACE_X, MERC_VIDEO_FACE_Y, MERC_VIDEO_FACE_WIDTH, MERC_VIDEO_FACE_HEIGHT );
|
|
if( fReturnStatus )
|
|
ubCurrentMercDistortionMode = MERC_DISTORTION_NO_DISTORTION;
|
|
break;
|
|
|
|
case MERC_DISRTORTION_DISTORT_IMAGE:
|
|
// fReturnStatus = DistortVideoMercImage();
|
|
fReturnStatus = DistortVideoMercImage( MERC_VIDEO_FACE_X, MERC_VIDEO_FACE_Y, MERC_VIDEO_FACE_WIDTH, MERC_VIDEO_FACE_HEIGHT );
|
|
|
|
if( fReturnStatus )
|
|
ubCurrentMercDistortionMode = MERC_DISTORTION_NO_DISTORTION;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN PixelateVideoMercImage( BOOLEAN fUp, UINT16 usPosX, UINT16 usPosY, UINT16 usWidth, UINT16 usHeight)
|
|
{
|
|
static UINT32 uiLastTime;
|
|
UINT32 uiCurTime = GetJA2Clock();
|
|
UINT16 *pBuffer=NULL, DestColor;
|
|
UINT32 uiPitch;
|
|
UINT16 i, j;
|
|
static UINT8 ubPixelationAmount=255;
|
|
BOOLEAN fReturnStatus=FALSE;
|
|
i=0;
|
|
|
|
pBuffer = (UINT16*)LockVideoSurface( FRAME_BUFFER, &uiPitch );
|
|
Assert( pBuffer );
|
|
|
|
if( ubPixelationAmount == 255 )
|
|
{
|
|
if( fUp )
|
|
ubPixelationAmount = 1;
|
|
else
|
|
ubPixelationAmount = 4;
|
|
uiLastTime = GetJA2Clock();
|
|
}
|
|
|
|
//is it time to change the animation
|
|
if( ( uiCurTime - uiLastTime ) > 100 )
|
|
{
|
|
//if we are starting to pixelate the image
|
|
if( fUp )
|
|
{
|
|
//the varying degrees of pixelation
|
|
if( ubPixelationAmount <= 4 )
|
|
{
|
|
ubPixelationAmount++;
|
|
fReturnStatus = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ubPixelationAmount = 255;
|
|
fReturnStatus = TRUE;
|
|
}
|
|
}
|
|
//else we are pixelating down
|
|
else
|
|
{
|
|
if( ubPixelationAmount > 1 )
|
|
{
|
|
ubPixelationAmount--;
|
|
fReturnStatus = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ubPixelationAmount = 255;
|
|
fReturnStatus = TRUE;
|
|
}
|
|
}
|
|
uiLastTime = GetJA2Clock();
|
|
}
|
|
else
|
|
i=i;
|
|
|
|
uiPitch /= 2;
|
|
i=j=0;
|
|
DestColor = pBuffer[ (j*uiPitch) + i ];
|
|
|
|
for(j=usPosY; j<usPosY+usHeight; j++)
|
|
{
|
|
for(i=usPosX; i<usPosX+usWidth; i++)
|
|
{
|
|
//get the next color
|
|
if( !(i % ubPixelationAmount) )
|
|
{
|
|
if( i < usPosX+usWidth-ubPixelationAmount)
|
|
DestColor = pBuffer[ (j*uiPitch) + i+ubPixelationAmount/2];
|
|
else
|
|
DestColor = pBuffer[ (j*uiPitch) + i];
|
|
}
|
|
|
|
pBuffer[ (j*uiPitch) + i] = DestColor;
|
|
}
|
|
}
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
return( fReturnStatus );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN DistortVideoMercImage( UINT16 usPosX, UINT16 usPosY, UINT16 usWidth, UINT16 usHeight )
|
|
{
|
|
UINT32 uiPitch;
|
|
UINT16 i, j;
|
|
UINT16 *pBuffer=NULL, DestColor;
|
|
UINT32 uiColor;
|
|
UINT8 red, green, blue;
|
|
static UINT16 usDistortionValue=255;
|
|
UINT8 uiReturnValue;
|
|
UINT16 usEndOnLine=0;
|
|
|
|
pBuffer = (UINT16*)LockVideoSurface( FRAME_BUFFER, &uiPitch );
|
|
Assert( pBuffer );
|
|
|
|
uiPitch /= 2;
|
|
j=MERC_VIDEO_FACE_Y;
|
|
i=MERC_VIDEO_FACE_X;
|
|
|
|
DestColor = pBuffer[ (j*uiPitch) + i ];
|
|
|
|
if( usDistortionValue >= usPosY+usHeight )
|
|
{
|
|
usDistortionValue = 0;
|
|
uiReturnValue = TRUE;
|
|
}
|
|
else
|
|
{
|
|
usDistortionValue++;
|
|
|
|
uiReturnValue = FALSE;
|
|
|
|
|
|
if( usDistortionValue + 10 >= usHeight )
|
|
usEndOnLine = usHeight-1;
|
|
else
|
|
usEndOnLine = usDistortionValue + 10;
|
|
|
|
|
|
for(j=usPosY+usDistortionValue; j<usPosY+usEndOnLine; j++)
|
|
{
|
|
for(i=usPosX; i<usPosX+usWidth; i++)
|
|
{
|
|
DestColor = pBuffer[ (j*uiPitch) + i ];
|
|
|
|
uiColor = GetRGBColor( DestColor );
|
|
|
|
red = (UINT8)uiColor;
|
|
green = (UINT8)(uiColor >> 8);
|
|
blue = (UINT8)(uiColor >> 16);
|
|
|
|
DestColor = Get16BPPColor(FROMRGB( 255-red, 250-green, 250-blue) );
|
|
|
|
pBuffer[ (j*uiPitch) + i ] = DestColor;
|
|
}
|
|
}
|
|
}
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
|
|
return(uiReturnValue);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN InitDestroyXToCloseVideoWindow( BOOLEAN fCreate )
|
|
{
|
|
static BOOLEAN fButtonCreated=FALSE;
|
|
|
|
//if we are asked to create the buttons and the button isnt already created
|
|
if( fCreate && !fButtonCreated )
|
|
{
|
|
guiXToCloseMercVideoButtonImage = LoadButtonImage("LAPTOP\\CloseButton.sti", -1,0,-1,1,-1 );
|
|
|
|
guiXToCloseMercVideoButton = QuickCreateButton( guiXToCloseMercVideoButtonImage, MERC_X_TO_CLOSE_VIDEO_X, MERC_X_TO_CLOSE_VIDEO_Y,
|
|
BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
|
|
DEFAULT_MOVE_CALLBACK, BtnXToCloseMercVideoButtonCallback);
|
|
SetButtonCursor(guiXToCloseMercVideoButton, CURSOR_LAPTOP_SCREEN);
|
|
|
|
fButtonCreated = TRUE;
|
|
}
|
|
|
|
//if we are asked to destroy the buttons and the buttons are created
|
|
if( !fCreate && fButtonCreated )
|
|
{
|
|
UnloadButtonImage( guiXToCloseMercVideoButtonImage );
|
|
RemoveButton( guiXToCloseMercVideoButton );
|
|
fButtonCreated = FALSE;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
void BtnXToCloseMercVideoButtonCallback(GUI_BUTTON *btn,INT32 reason)
|
|
{
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
|
|
{
|
|
btn->uiFlags |= BUTTON_CLICKED_ON;
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
|
|
{
|
|
if (btn->uiFlags & BUTTON_CLICKED_ON)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
|
|
//Stop speck from talking
|
|
// ShutupaYoFace( giVideoSpeckFaceIndex );
|
|
StopSpeckFromTalking( );
|
|
|
|
//make sure we are done the intro speech
|
|
gfDoneIntroSpeech = TRUE;
|
|
|
|
//remove the video conf mode
|
|
gubCurrentMercVideoMode = MERC_VIDEO_EXIT_VIDEO_MODE;
|
|
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
|
|
{
|
|
btn->uiFlags &= (~BUTTON_CLICKED_ON );
|
|
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN DisplayMercVideoIntro( UINT16 usTimeTillFinish )
|
|
{
|
|
UINT32 uiCurTime = GetJA2Clock();
|
|
static UINT32 uiLastTime=0;
|
|
|
|
//init variable
|
|
if( uiLastTime == 0 )
|
|
uiLastTime = uiCurTime;
|
|
|
|
|
|
ColorFillVideoSurfaceArea( FRAME_BUFFER, MERC_VIDEO_FACE_X, MERC_VIDEO_FACE_Y, MERC_VIDEO_FACE_X+MERC_VIDEO_FACE_WIDTH, MERC_VIDEO_FACE_Y+MERC_VIDEO_FACE_HEIGHT, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
|
|
|
|
//if the intro is done
|
|
if( (uiCurTime - uiLastTime) > usTimeTillFinish )
|
|
{
|
|
uiLastTime = 0;
|
|
return(TRUE);
|
|
}
|
|
else
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
void HandleTalkingSpeck()
|
|
{
|
|
BOOLEAN fIsSpeckTalking = TRUE;
|
|
|
|
switch( gubCurrentMercVideoMode )
|
|
{
|
|
//Init the video conferencing
|
|
case MERC_VIDEO_INIT_VIDEO_MODE:
|
|
//perform some opening animation. When its done start Speck talking
|
|
|
|
//if the intro is finished
|
|
if( DisplayMercVideoIntro( MERC_INTRO_TIME ) )
|
|
{
|
|
//NULL out the string
|
|
gsSpeckDialogueTextPopUp[0] = '\0';
|
|
|
|
//Start speck talking
|
|
if( gusMercVideoSpeckSpeech != MERC_VIDEO_SPECK_SPEECH_NOT_TALKING && gusMercVideoSpeckSpeech != MERC_VIDEO_SPECK_HAS_TO_TALK_BUT_QUOTE_NOT_CHOSEN_YET )
|
|
StartSpeckTalking( gusMercVideoSpeckSpeech );
|
|
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
gubCurrentMercVideoMode = MERC_VIDEO_VIDEO_MODE;
|
|
}
|
|
break;
|
|
|
|
//Display his talking and blinking face
|
|
case MERC_VIDEO_VIDEO_MODE:
|
|
|
|
//Make sure the accounts button does not overwrite the dialog text
|
|
// ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
//def:
|
|
|
|
if( gfJustEnteredMercSite && gubArrivedFromMercSubSite != MERC_CAME_FROM_OTHER_PAGE || gfFirstTimeIntoMERCSiteSinceEnteringLaptop )
|
|
{
|
|
gfFirstTimeIntoMERCSiteSinceEnteringLaptop = FALSE;
|
|
GetSpeckConditionalOpening( FALSE );
|
|
gfJustEnteredMercSite = FALSE;
|
|
}
|
|
else
|
|
{
|
|
fIsSpeckTalking = HandleSpeckTalking( FALSE );
|
|
|
|
if( !fIsSpeckTalking )
|
|
fIsSpeckTalking = GetSpeckConditionalOpening( FALSE );
|
|
|
|
//if speck didnt start talking, see if he just hired someone
|
|
if( !fIsSpeckTalking )
|
|
{
|
|
fIsSpeckTalking = ShouldSpeckStartTalkingDueToActionOnSubPage();
|
|
}
|
|
}
|
|
|
|
if( !fIsSpeckTalking )
|
|
gubCurrentMercVideoMode = MERC_VIDEO_EXIT_VIDEO_MODE;
|
|
|
|
if( gfDisplaySpeckTextBox && gGameSettings.fOptions[ TOPTION_SUBTITLES ] )
|
|
{
|
|
if( !gfInMercSite )
|
|
{
|
|
StopSpeckFromTalking( );
|
|
return;
|
|
}
|
|
|
|
|
|
if( gsSpeckDialogueTextPopUp[0] != L'\0' )
|
|
{
|
|
// DrawButton( guiAccountBoxButton );
|
|
// ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
|
|
if( iMercPopUpBox != -1 )
|
|
{
|
|
#ifdef JA2UB
|
|
//JA25: removed DrawButton( guiAccountBoxButton );
|
|
//JA25: removed ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#else
|
|
DrawButton( guiAccountBoxButton );
|
|
ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#endif
|
|
|
|
RenderMercPopUpBoxFromIndex( iMercPopUpBox, gusSpeckDialogueX, MERC_TEXT_BOX_POS_Y, FRAME_BUFFER);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
// shut down the video conferencing
|
|
case MERC_VIDEO_EXIT_VIDEO_MODE:
|
|
|
|
//if the exit animation is finished, exit the video conf window
|
|
if( DisplayMercVideoIntro( MERC_EXIT_TIME ) )
|
|
{
|
|
StopSpeckFromTalking( );
|
|
|
|
//Delete the face
|
|
DeleteFace( giVideoSpeckFaceIndex );
|
|
InitDestroyXToCloseVideoWindow( FALSE );
|
|
|
|
gfRedrawMercSite = TRUE;
|
|
gfMercVideoIsBeingDisplayed = FALSE;
|
|
|
|
//Remove the merc popup
|
|
RemoveSpeckPopupTextBox();
|
|
|
|
//maybe display ending animation
|
|
gubCurrentMercVideoMode = MERC_VIDEO_NO_VIDEO_MODE;
|
|
}
|
|
else
|
|
{
|
|
//else we are done the exit animation. The area is not being invalidated anymore
|
|
InvalidateRegion( MERC_VIDEO_FACE_X, MERC_VIDEO_FACE_Y, MERC_VIDEO_FACE_X+MERC_VIDEO_FACE_WIDTH, MERC_VIDEO_FACE_Y+MERC_VIDEO_FACE_HEIGHT );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DisplayTextForSpeckVideoPopUp(STR16 pString)
|
|
{
|
|
UINT16 usActualHeight;
|
|
INT32 iOldMercPopUpBoxId = iMercPopUpBox;
|
|
|
|
//If the user has selected no subtitles
|
|
if( !gGameSettings.fOptions[ TOPTION_SUBTITLES ] )
|
|
return;
|
|
|
|
// wcscpy(gsSpeckDialogueTextPopUp, pString);
|
|
//add the "" around the speech.
|
|
swprintf( gsSpeckDialogueTextPopUp, L"\"%s\"", pString );
|
|
|
|
gfDisplaySpeckTextBox = TRUE;
|
|
|
|
//Set this so the popup box doesnt render in RenderMercs()
|
|
iMercPopUpBox = -1;
|
|
|
|
//Render the screen to get rid of any old text popup boxes
|
|
RenderMercs();
|
|
|
|
iMercPopUpBox = iOldMercPopUpBoxId;
|
|
|
|
if( gfMercVideoIsBeingDisplayed && gfMercSiteScreenIsReDrawn )
|
|
{
|
|
DrawMercVideoBackGround();
|
|
}
|
|
|
|
//never use it anymore
|
|
//SET_USE_WINFONTS( TRUE );
|
|
//SET_WINFONT( giSubTitleWinFont );
|
|
//Create the popup box
|
|
iMercPopUpBox = PrepareMercPopupBox( iMercPopUpBox, BASIC_MERC_POPUP_BACKGROUND, BASIC_MERC_POPUP_BORDER, gsSpeckDialogueTextPopUp, 300, 0, 0, 0, &gusSpeckDialogueActualWidth, &usActualHeight);
|
|
//SET_USE_WINFONTS( FALSE );
|
|
|
|
gusSpeckDialogueX = iScreenWidthOffset + 111 + ((640 - 111) / 2 - (gusSpeckDialogueActualWidth / 2));
|
|
|
|
//Render the pop box
|
|
RenderMercPopUpBoxFromIndex( iMercPopUpBox, gusSpeckDialogueX, MERC_TEXT_BOX_POS_Y, FRAME_BUFFER);
|
|
|
|
//check to make sure the region is not already initialized
|
|
if( !( gMercSiteSubTitleMouseRegion.uiFlags & MSYS_REGION_EXISTS ) )
|
|
{
|
|
MSYS_DefineRegion( &gMercSiteSubTitleMouseRegion, gusSpeckDialogueX, MERC_TEXT_BOX_POS_Y, (INT16)(gusSpeckDialogueX + gusSpeckDialogueActualWidth), (INT16)(MERC_TEXT_BOX_POS_Y + usActualHeight), MSYS_PRIORITY_HIGH,
|
|
CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, MercSiteSubTitleRegionCallBack );
|
|
MSYS_AddRegion( &gMercSiteSubTitleMouseRegion );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CheatToGetAll5Merc()
|
|
{
|
|
LaptopSaveInfo.guiNumberOfMercPaymentsInDays += 20;
|
|
|
|
/*
|
|
LaptopSaveInfo.gbNumDaysTillFirstMercArrives = 1;
|
|
LaptopSaveInfo.gbNumDaysTillSecondMercArrives = 1;
|
|
LaptopSaveInfo.gbNumDaysTillThirdMercArrives = 1;
|
|
LaptopSaveInfo.gbNumDaysTillFourthMercArrives = 1;
|
|
*/
|
|
LaptopSaveInfo.gubLastMercIndex = NUMBER_MERCS_AFTER_FOURTH_MERC_ARRIVES;
|
|
}
|
|
|
|
|
|
BOOLEAN GetSpeckConditionalOpening( BOOLEAN fJustEnteredScreen )
|
|
{
|
|
static UINT16 usQuoteToSay=MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
UINT8 ubCnt;
|
|
BOOLEAN fCanSayLackOfPaymentQuote = TRUE;
|
|
BOOLEAN fCanUseIdleTag = FALSE;
|
|
|
|
//If we just entered the screen, reset some variables
|
|
if( fJustEnteredScreen )
|
|
{
|
|
gfDoneIntroSpeech = FALSE;
|
|
#ifdef JA2UB
|
|
usQuoteToSay = SPECK_QUOTE_NEW_INTRO_1;
|
|
#else
|
|
usQuoteToSay = 0;
|
|
#endif
|
|
return( FALSE );
|
|
}
|
|
|
|
//if we are done the intro speech, or arrived from a sub page, get out of the function
|
|
if( gfDoneIntroSpeech || gubArrivedFromMercSubSite != MERC_CAME_FROM_OTHER_PAGE )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
gfDoneIntroSpeech = TRUE;
|
|
|
|
//set the opening quote based on if the player has been here before
|
|
|
|
#ifdef JA2UB
|
|
if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_FIRST_VISIT && usQuoteToSay <= SPECK_QUOTE_NEW_INTRO_7 ) //!= 0 )
|
|
#else
|
|
if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_FIRST_VISIT && usQuoteToSay <= 8 ) //!= 0 )
|
|
#endif
|
|
{
|
|
StartSpeckTalking( usQuoteToSay );
|
|
usQuoteToSay++;
|
|
#ifdef JA2UB
|
|
if( usQuoteToSay <= SPECK_QUOTE_NEW_INTRO_7 )
|
|
#else
|
|
if( usQuoteToSay <= 8 )
|
|
#endif
|
|
gfDoneIntroSpeech = FALSE;
|
|
}
|
|
#ifdef JA2UB
|
|
//else if its the first time back since the laptop went down
|
|
else if( gJa25SaveStruct.fHaveAimandMercOffferItems && !HasImportantSpeckQuoteBeingSaid( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_1 ) )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_1 );
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_2 );
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_3 );
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_4 );
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_5 );
|
|
StartSpeckTalking( SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_6 );
|
|
}
|
|
#else
|
|
//if its the players second visit
|
|
else if( LaptopSaveInfo.ubPlayerBeenToMercSiteStatus == MERC_SITE_SECOND_VISIT )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_1_TOUGH_START );
|
|
fCanUseIdleTag = TRUE;
|
|
}
|
|
#endif
|
|
// We have been here at least 2 times before, Check which quote we should use
|
|
else
|
|
{
|
|
//if the player has not hired any MERC mercs before
|
|
// CJC Dec 1 2002: fixing this, so near-bankrupt msg will play
|
|
#ifdef JA2UB
|
|
if( !IsAnyMercMercsHired( ) && CalcMercDaysServed() == 0)
|
|
StartSpeckTalking( SPECK_QUOTE_DEFAULT_INTRO_HAVENT_HIRED_MERCS );
|
|
else
|
|
StartSpeckTalking( SPECK_QUOTE_DEFAULT_INTRO_HAVE_HIRED_MERCS );
|
|
#endif
|
|
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//if the player has not hired any MERC mercs before
|
|
if( !IsAnyMercMercsHired( ) && CalcMercDaysServed() == 0)
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_2_BUSINESS_BAD );
|
|
}
|
|
#endif
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//else if it is the first visit since the server went down
|
|
else if( LaptopSaveInfo.fFirstVisitSinceServerWentDown == TRUE )
|
|
{
|
|
LaptopSaveInfo.fFirstVisitSinceServerWentDown = 2;
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_9_FIRST_VISIT_SINCE_SERVER_WENT_DOWN );
|
|
fCanUseIdleTag = TRUE;
|
|
}
|
|
#endif
|
|
/*
|
|
//else if new mercs are available
|
|
else if( LaptopSaveInfo.fNewMercsAvailableAtMercSite )
|
|
{
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = FALSE;
|
|
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_11_NEW_MERCS_AVAILABLE );
|
|
}
|
|
*/
|
|
//else if lots of MERC mercs are DEAD, and speck can say the quote ( dont want him to continously say it )
|
|
#ifdef JA2UB
|
|
if( CountNumberOfMercMercsWhoAreDead() >= 2 && LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote )
|
|
#else
|
|
else if( CountNumberOfMercMercsWhoAreDead() >= 2 && LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote )
|
|
#endif
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_12_PLAYERS_LOST_MERCS );
|
|
|
|
//Set it so speck Wont say the quote again till someone else dies
|
|
LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote = 0;
|
|
}
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//else if player owes lots of money
|
|
else if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_SUSPENDED )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_5_PLAYER_OWES_SPECK_ACCOUNT_SUSPENDED );
|
|
|
|
fCanSayLackOfPaymentQuote = FALSE;
|
|
}
|
|
#endif
|
|
//else if the player owes speck a large sum of money, have speck say so
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
else if ( CalculateHowMuchPlayerOwesSpeck( ) > gGameExternalOptions.usMERCBankruptWarning )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_6_PLAYER_OWES_SPECK_ALMOST_BANKRUPT_1 );
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_6_PLAYER_OWES_SPECK_ALMOST_BANKRUPT_2 );
|
|
|
|
fCanSayLackOfPaymentQuote = FALSE;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
#ifdef JA2UB
|
|
UINT8 ubNumMercsDead = NumberOfMercMercsDead();
|
|
BOOLEAN fCanUseIdleTag = FALSE;
|
|
#endif
|
|
UINT8 ubRandom = ( UINT8 ) Random( 100 );
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//if business is good
|
|
// if( ubRandom < 40 && ubNumMercsDead < 2 && CountNumberOfMercMercsHired() > 1 )
|
|
if( ubRandom < 40 && AreAnyOfTheNewMercsAvailable() && CountNumberOfMercMercsHired() > 1 )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_3_BUSINESS_GOOD );
|
|
fCanUseIdleTag = TRUE;
|
|
}
|
|
#endif
|
|
//or if still trying to recruit ( the last recruit hasnt arrived and the player has paid for some of his mercs )
|
|
// else if( ubRandom < 80 && LaptopSaveInfo.gbNumDaysTillFourthMercArrives != -1 && LaptopSaveInfo.gbNumDaysTillFirstMercArrives < MERC_NUM_DAYS_TILL_FIRST_MERC_AVAILABLE )
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
else if( ubRandom < 80 && gConditionsForMercAvailability[ LaptopSaveInfo.ubLastMercAvailableId ].usMoneyPaid <= LaptopSaveInfo.uiTotalMoneyPaidToSpeck && CanMercBeAvailableYet( LaptopSaveInfo.ubLastMercAvailableId ) )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_4_TRYING_TO_RECRUIT );
|
|
fCanUseIdleTag = TRUE;
|
|
}
|
|
|
|
//else use the generic opening
|
|
else
|
|
#endif
|
|
{
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_10_GENERIC_OPENING );
|
|
|
|
fCanUseIdleTag = TRUE;
|
|
|
|
//JA25: not using quote quote
|
|
//if the merc hasnt said the line before
|
|
if( !LaptopSaveInfo.fSaidGenericOpeningInMercSite )
|
|
{
|
|
LaptopSaveInfo.fSaidGenericOpeningInMercSite = TRUE;
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_10_TAG_FOR_20 );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
#ifdef JA2UB
|
|
//no UB
|
|
#else
|
|
if( fCanUseIdleTag )
|
|
{
|
|
UINT8 ubRandom = Random( 100 );
|
|
|
|
if( ubRandom < 50 )
|
|
{
|
|
ubRandom = Random( 4 );
|
|
|
|
switch( ubRandom )
|
|
{
|
|
case 0:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_ON_AFTER_OTHER_TAGS_1 );
|
|
break;
|
|
case 1:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_ON_AFTER_OTHER_TAGS_2 );
|
|
break;
|
|
case 2:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_ON_AFTER_OTHER_TAGS_3 );
|
|
break;
|
|
case 3:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_ON_AFTER_OTHER_TAGS_4 );
|
|
break;
|
|
default:
|
|
Assert( 0 );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//If Speck has sent an email to the player, and the player still hasnt paid, has speck complain about it.
|
|
// CJC Dec 1 2002 ACTUALLY HOOKED IN THAT CHECK
|
|
if (fCanSayLackOfPaymentQuote)
|
|
{
|
|
if( LaptopSaveInfo.uiSpeckQuoteFlags & SPECK_QUOTE__SENT_EMAIL_ABOUT_LACK_OF_PAYMENT )
|
|
{
|
|
LaptopSaveInfo.uiSpeckQuoteFlags &= ~SPECK_QUOTE__SENT_EMAIL_ABOUT_LACK_OF_PAYMENT;
|
|
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_PLAYER_OWES_MONEY );
|
|
}
|
|
}
|
|
|
|
//if new mercs are available
|
|
if( LaptopSaveInfo.fNewMercsAvailableAtMercSite )
|
|
{
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = FALSE;
|
|
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_11_NEW_MERCS_AVAILABLE );
|
|
}
|
|
#endif
|
|
|
|
//if any mercs are dead
|
|
if( IsAnyMercMercsDead() )
|
|
{
|
|
UINT8 ubMercID;
|
|
//if no merc has died before
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
if( !LaptopSaveInfo.fHasAMercDiedAtMercSite )
|
|
{
|
|
LaptopSaveInfo.fHasAMercDiedAtMercSite = TRUE;
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_FIRST_MERC_DIES );
|
|
}
|
|
#endif
|
|
//loop through all the mercs and see if any are dead and the quote is not said
|
|
for( ubCnt=0; ubCnt<NUMBER_OF_MERCS; ubCnt++ )
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( (UINT8) ubCnt );
|
|
//if the merc is dead
|
|
if( IsMercDead( ubMercID ) )
|
|
{
|
|
//if the quote has not been said
|
|
if( !( gMercProfiles[ ubMercID ].ubMiscFlags3 & PROFILE_MISC_FLAG3_MERC_MERC_IS_DEAD_AND_QUOTE_SAID ) )
|
|
{
|
|
//set the flag
|
|
gMercProfiles[ ubMercID ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_MERC_MERC_IS_DEAD_AND_QUOTE_SAID;
|
|
|
|
#ifdef JA2UB
|
|
if ( ubMercID == GASTON_UB )
|
|
StartSpeckTalking( SPECK_QUOTE_GASTON_DEAD );
|
|
else if ( ubMercID == STOGIE_UB )
|
|
StartSpeckTalking( SPECK_QUOTE_STOGIE_DEAD );
|
|
#endif
|
|
|
|
switch( ubMercID )
|
|
{
|
|
case BIFF:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_BIFF_IS_DEAD );
|
|
break;
|
|
case HAYWIRE:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_HAYWIRE_IS_DEAD );
|
|
break;
|
|
case GASKET:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_GASKET_IS_DEAD );
|
|
break;
|
|
case RAZOR:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_RAZOR_IS_DEAD );
|
|
break;
|
|
case FLO:
|
|
//if biff is dead
|
|
if( IsMercDead( BIFF ) )
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_FLO_IS_DEAD_BIFF_IS_DEAD );
|
|
else
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_FLO_IS_DEAD_BIFF_ALIVE );
|
|
MakeBiffAwayForCoupleOfDays();
|
|
}
|
|
break;
|
|
|
|
case GUMPY:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_GUMPY_IS_DEAD );
|
|
break;
|
|
case LARRY_NORMAL:
|
|
case LARRY_DRUNK:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_LARRY_IS_DEAD );
|
|
break;
|
|
case COUGAR:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_COUGER_IS_DEAD );
|
|
break;
|
|
case NUMB:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_NUMB_IS_DEAD );
|
|
break;
|
|
case BUBBA:
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_BUBBA_IS_DEAD );
|
|
break;
|
|
#ifdef JA2UB
|
|
|
|
#else
|
|
case GASTON:
|
|
StartSpeckTalking( SPECK_QUOTE_GASTON_DEAD );
|
|
break;
|
|
case STOGIE:
|
|
StartSpeckTalking( SPECK_QUOTE_STOGIE_DEAD );
|
|
break;
|
|
#endif
|
|
};
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//JA25: not using quote quote
|
|
#else
|
|
//if flo has married the cousin
|
|
if( gubFact[ FACT_PC_MARRYING_DARYL_IS_FLO ] )
|
|
{
|
|
//if speck hasnt said the quote before, and Biff is NOT dead
|
|
if( !LaptopSaveInfo.fSpeckSaidFloMarriedCousinQuote && !IsMercDead( BIFF ) )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_FLO_MARRIED_A_COUSIN_BIFF_IS_ALIVE );
|
|
LaptopSaveInfo.fSpeckSaidFloMarriedCousinQuote = TRUE;
|
|
|
|
MakeBiffAwayForCoupleOfDays();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//if larry has relapsed
|
|
if( HasLarryRelapsed() && !( LaptopSaveInfo.uiSpeckQuoteFlags & SPECK_QUOTE__ALREADY_TOLD_PLAYER_THAT_LARRY_RELAPSED ) )
|
|
{
|
|
LaptopSaveInfo.uiSpeckQuoteFlags |= SPECK_QUOTE__ALREADY_TOLD_PLAYER_THAT_LARRY_RELAPSED;
|
|
|
|
StartSpeckTalking( SPECK_QUOTE_ALTERNATE_OPENING_TAG_LARRY_RELAPSED );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN IsAnyMercMercsHired( )
|
|
{
|
|
UINT8 ubMercID;
|
|
UINT8 i;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; ++i)
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( i );
|
|
if( IsMercOnTeam( ubMercID, FALSE, FALSE ) )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
BOOLEAN IsAnyMercMercsDead()
|
|
{
|
|
UINT8 i;
|
|
UINT8 ubMercID;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( (UINT8) i );
|
|
if( gMercProfiles[ ubMercID ].bMercStatus == MERC_IS_DEAD )
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
UINT8 NumberOfMercMercsDead()
|
|
{
|
|
UINT8 i;
|
|
UINT8 ubNumDead = 0;
|
|
UINT8 ubMercID;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( (UINT8) i );
|
|
if( gMercProfiles[ ubMercID ].bMercStatus == MERC_IS_DEAD )
|
|
ubNumDead++;
|
|
}
|
|
|
|
return( ubNumDead );
|
|
}
|
|
|
|
|
|
|
|
UINT8 CountNumberOfMercMercsHired()
|
|
{
|
|
UINT8 ubMercID;
|
|
UINT8 i;
|
|
UINT8 ubCount=0;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; ++i)
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( i );
|
|
if( IsMercOnTeam( ubMercID, FALSE, FALSE ) )
|
|
{
|
|
++ubCount;
|
|
}
|
|
}
|
|
|
|
return( ubCount );
|
|
}
|
|
|
|
|
|
UINT8 CountNumberOfMercMercsWhoAreDead()
|
|
{
|
|
UINT8 i;
|
|
UINT8 ubCount=0;
|
|
UINT8 ubMercID;
|
|
|
|
//loop through all of the hired mercs from M.E.R.C.
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( (UINT8) i );
|
|
|
|
if( gMercProfiles[ ubMercID ].bMercStatus == MERC_IS_DEAD )
|
|
{
|
|
ubCount++;
|
|
}
|
|
}
|
|
|
|
return( ubCount );
|
|
}
|
|
|
|
|
|
|
|
|
|
//Mouse Call back for the pop up text box
|
|
void MercSiteSubTitleRegionCallBack( MOUSE_REGION * pRegion, INT32 iReason )
|
|
{
|
|
if (iReason & MSYS_CALLBACK_REASON_INIT)
|
|
{
|
|
}
|
|
else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP || iReason & MSYS_CALLBACK_REASON_RBUTTON_UP)
|
|
{
|
|
StopSpeckFromTalking( );
|
|
}
|
|
}
|
|
|
|
|
|
void RemoveSpeckPopupTextBox()
|
|
{
|
|
if( iMercPopUpBox == -1 )
|
|
return;
|
|
|
|
if( gMercSiteSubTitleMouseRegion.uiFlags & MSYS_REGION_EXISTS )
|
|
MSYS_RemoveRegion( &gMercSiteSubTitleMouseRegion );
|
|
|
|
if( RemoveMercPopupBoxFromIndex( iMercPopUpBox ) )
|
|
{
|
|
iMercPopUpBox = -1;
|
|
}
|
|
|
|
//redraw the screen
|
|
gfRedrawMercSite = TRUE;
|
|
}
|
|
|
|
|
|
|
|
void HandlePlayerHiringMerc( UINT8 ubHiredMercID )
|
|
{
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
|
|
//if the players is in good finacial standing
|
|
//DEF: 3/19/99: Dont know why this was done
|
|
// if( LaptopSaveInfo.iCurrentBalance >= 2000 )
|
|
{
|
|
#ifdef JA2UB
|
|
//Gaston is hired
|
|
if ( ubHiredMercID == GASTON_UB )
|
|
{
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( FLO ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_GASTON );
|
|
}
|
|
//Stogie is hired
|
|
else if ( ubHiredMercID == STOGIE_UB )
|
|
{
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( BIFF ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_STOGIE );
|
|
}
|
|
#endif
|
|
//determine which quote to say based on the merc that was hired
|
|
switch( ubHiredMercID )
|
|
{
|
|
//Biff is hired
|
|
case BIFF:
|
|
//if Larry is available, advertise for larry
|
|
if( IsMercMercAvailable( LARRY_NORMAL ) || IsMercMercAvailable( LARRY_DRUNK ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_BIFF_SPECK_PLUGS_LARRY );
|
|
|
|
//if flo is available, advertise for flo
|
|
if( IsMercMercAvailable( FLO ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_BIFF_SPECK_PLUGS_FLO );
|
|
break;
|
|
|
|
//haywire is hired
|
|
case HAYWIRE:
|
|
//if razor is available, advertise for razor
|
|
if( IsMercMercAvailable( RAZOR ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_HAYWIRE_SPECK_PLUGS_RAZOR );
|
|
break;
|
|
|
|
//razor is hired
|
|
case RAZOR:
|
|
//if haywire is available, advertise for haywire
|
|
if( IsMercMercAvailable( HAYWIRE ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_RAZOR_SPECK_PLUGS_HAYWIRE );
|
|
break;
|
|
|
|
|
|
//flo is hired
|
|
case FLO:
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( BIFF ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_FLO_SPECK_PLUGS_BIFF );
|
|
break;
|
|
|
|
|
|
//larry is hired
|
|
case LARRY_NORMAL:
|
|
case LARRY_DRUNK:
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( BIFF ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYERS_HIRES_LARRY_SPECK_PLUGS_BIFF );
|
|
break;
|
|
#ifdef JA2UB
|
|
|
|
#else
|
|
//Gaston is hired
|
|
case GASTON:
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( FLO ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_GASTON );
|
|
break;
|
|
|
|
//Stogie is hired
|
|
case STOGIE:
|
|
//if biff is available, advertise for biff
|
|
if( IsMercMercAvailable( BIFF ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_STOGIE );
|
|
break;
|
|
|
|
// anv: Speck is hired
|
|
case SPECK_PLAYABLE:
|
|
if( IsMercOnTeam( VICKI, FALSE, FALSE ) )
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_SPECK_TOGETHER_WITH_VICKI );
|
|
else
|
|
StartSpeckTalking( SPECK_QUOTE_PLAYER_HIRES_SPECK );
|
|
break;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
gubArrivedFromMercSubSite = MERC_CAME_FROM_HIRE_PAGE;
|
|
}
|
|
|
|
|
|
BOOLEAN IsMercMercAvailable( UINT8 ubMercID )
|
|
{
|
|
UINT8 cnt;
|
|
|
|
//loop through the array of mercs
|
|
for( cnt=0; cnt<NUM_PROFILES; cnt++ ) //LaptopSaveInfo.gubLastMercIndex; cnt++ )
|
|
{
|
|
//if this is the merc
|
|
if( GetMercIDFromMERCArray( cnt ) == ubMercID )
|
|
{
|
|
//if the merc is available, and Not dead
|
|
// if( gMercProfiles[ ubMercID ].bMercStatus == 0 && !IsMercDead( ubMercID ) )
|
|
if( IsMercHireable( ubMercID ) )
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
BOOLEAN ShouldSpeckStartTalkingDueToActionOnSubPage()
|
|
{
|
|
//if the merc came from the hire screen
|
|
if( gfJustHiredAMercMerc )
|
|
{
|
|
|
|
HandlePlayerHiringMerc( GetAvailableMercIDFromMERCArray( gubCurMercIndex ) );
|
|
|
|
#ifdef JA2UB
|
|
#else
|
|
if( IsSpeckComAvailable() )
|
|
#endif
|
|
{
|
|
#ifdef JA2UB
|
|
//if it hasnt been said, say the better equipment quote
|
|
if( !HasImportantSpeckQuoteBeingSaid( SPECK_QUOTE_BETTER_STARTING_EQPMNT_TAG_ON ) )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_BETTER_STARTING_EQPMNT_TAG_ON );
|
|
}
|
|
#endif
|
|
//get speck to say the thank you
|
|
if( Random( 100 ) > 50 )
|
|
StartSpeckTalking( SPECK_QUOTE_GENERIC_THANKS_FOR_HIRING_MERCS_1 );
|
|
else
|
|
StartSpeckTalking( SPECK_QUOTE_GENERIC_THANKS_FOR_HIRING_MERCS_2 );
|
|
#ifdef JA2UB
|
|
//if it hasnt been said, say the encouraged to shop quote
|
|
if( !HasImportantSpeckQuoteBeingSaid( SPECK_QUOTE_ENCOURAGE_SHOP_TAG_ON ) )
|
|
{
|
|
StartSpeckTalking( SPECK_QUOTE_ENCOURAGE_SHOP_TAG_ON );
|
|
}
|
|
#endif
|
|
}
|
|
gfJustHiredAMercMerc = FALSE;
|
|
// gfDoneIntroSpeech = TRUE;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
#else
|
|
BOOLEAN IsSpeckComAvailable() // anv: Prevent Speck from talking if his playable version is out of reach
|
|
{
|
|
//he's hired, travelling, dead or POW, he cant' talk
|
|
if( ( ( IsMercOnTeam( SPECK_PLAYABLE, FALSE, FALSE )
|
|
|| gMercProfiles[ SPECK_PLAYABLE ].bMercStatus == MERC_IS_DEAD
|
|
|| gMercProfiles[ SPECK_PLAYABLE ].bMercStatus == MERC_RETURNING_HOME
|
|
|| gMercProfiles[ SPECK_PLAYABLE ].bMercStatus == MERC_FIRED_AS_A_POW ) )
|
|
|
|
//he still can talk if he was just hired, so he can say his recruitment quote
|
|
&& ( GetAvailableMercIDFromMERCArray( gubCurMercIndex ) != SPECK_PLAYABLE
|
|
|| gusMercVideoSpeckSpeech == SPECK_QUOTE_PLAYER_TRIES_TO_HIRE_ALREADY_HIRED_MERC
|
|
|| gusMercVideoSpeckSpeech == SPECK_QUOTE_BIFF_UNAVALIABLE
|
|
|| gusMercVideoSpeckSpeech == SPECK_QUOTE_SPECK_UNAVAILABLE
|
|
) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
void HandleSpeckWitnessingEmployeeDeath( SOLDIERTYPE* pSoldier ) // anv: handle playable Speck witnessing his employee death
|
|
{
|
|
if(pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC)
|
|
{
|
|
// first blood
|
|
if( !LaptopSaveInfo.fHasAMercDiedAtMercSite )
|
|
{
|
|
LaptopSaveInfo.fHasAMercDiedAtMercSite = TRUE;
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_FIRST_MERC_DIES );
|
|
}
|
|
// numerous casualties, Speck whines...
|
|
else if( CountNumberOfMercMercsWhoAreDead() >= 2 && LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote )
|
|
{
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_PLAYERS_LOST_MERCS );
|
|
//Set it so speck Wont say the quote again till someone else dies
|
|
LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote = 0;
|
|
}
|
|
// merc specific requiem
|
|
switch( pSoldier->ubProfile )
|
|
{
|
|
case BIFF:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_BIFF_IS_DEAD );
|
|
break;
|
|
case HAYWIRE:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_HAYWIRE_IS_DEAD);
|
|
break;
|
|
case GASKET:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_GASKET_IS_DEAD );
|
|
break;
|
|
case RAZOR:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_RAZOR_IS_DEAD );
|
|
break;
|
|
case FLO:
|
|
//if biff is dead
|
|
if( IsMercDead( BIFF ) )
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_FLO_IS_DEAD_BIFF_IS_DEAD );
|
|
else
|
|
{
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_FLO_IS_DEAD_BIFF_ALIVE);
|
|
MakeBiffAwayForCoupleOfDays();
|
|
}
|
|
break;
|
|
|
|
case GUMPY:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_GUMPY_IS_DEAD);
|
|
break;
|
|
case LARRY_NORMAL:
|
|
case LARRY_DRUNK:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_LARRY_IS_DEAD);
|
|
break;
|
|
case COUGAR:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_COUGER_IS_DEAD);
|
|
break;
|
|
case NUMB:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_NUMB_IS_DEAD);
|
|
break;
|
|
case BUBBA:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_BUBBA_IS_DEAD);
|
|
break;
|
|
|
|
case GASTON:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_GASTON_DEAD);
|
|
break;
|
|
case STOGIE:
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_STOGIE_DEAD);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void AddJohnAsMerc() // anv: add John as playable merc after escorting Kulbas out of country
|
|
{
|
|
LaptopSaveInfo.bJohnEscorted = TRUE;
|
|
LaptopSaveInfo.uiJohnEscortedDate = GetWorldDay();
|
|
return;
|
|
}
|
|
|
|
BOOLEAN ShouldSpeckSayAQuote()
|
|
{
|
|
//if we are entering from anywhere except a sub page, and we should say the opening quote
|
|
if( gfJustEnteredMercSite && gubArrivedFromMercSubSite == MERC_CAME_FROM_OTHER_PAGE )
|
|
{
|
|
//if the merc has something to say
|
|
if( gusMercVideoSpeckSpeech != MERC_VIDEO_SPECK_SPEECH_NOT_TALKING )
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
//if the player just hired a merc
|
|
if( gfJustHiredAMercMerc )
|
|
{
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_HAS_TO_TALK_BUT_QUOTE_NOT_CHOSEN_YET;
|
|
return( TRUE );
|
|
|
|
/*
|
|
//if the merc has something to say
|
|
if( gusMercVideoSpeckSpeech != MERC_VIDEO_SPECK_SPEECH_NOT_TALKING )
|
|
return( TRUE );
|
|
else
|
|
{
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_HAS_TO_TALK_BUT_QUOTE_NOT_CHOSEN_YET;
|
|
return( TRUE );
|
|
}
|
|
*/
|
|
}
|
|
|
|
//If it is the first time into the merc site
|
|
if( gfFirstTimeIntoMERCSiteSinceEnteringLaptop )
|
|
{
|
|
// gfFirstTimeIntoMERCSiteSinceEnteringLaptop = FALSE;
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_HAS_TO_TALK_BUT_QUOTE_NOT_CHOSEN_YET;
|
|
return( TRUE );
|
|
}
|
|
|
|
/*
|
|
//if we are entering from anywhere except a sub page
|
|
if( gubArrivedFromMercSubSite == MERC_CAME_FROM_OTHER_PAGE )
|
|
{
|
|
GetSpeckConditionalOpening( FALSE );
|
|
return( TRUE );
|
|
}
|
|
*/
|
|
return( FALSE );
|
|
}
|
|
|
|
void HandleSpeckIdleConversation( BOOLEAN fReset )
|
|
{
|
|
static UINT32 uiLastTime=0;
|
|
UINT32 uiCurTime = GetJA2Clock();
|
|
INT16 sLeastSaidQuote;
|
|
|
|
//if we should reset the variables
|
|
if( fReset )
|
|
{
|
|
uiLastTime = GetJA2Clock();
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
if( ( uiCurTime - uiLastTime ) > SPECK_IDLE_CHAT_DELAY )
|
|
{
|
|
|
|
//if Speck is not talking
|
|
if( !gfMercVideoIsBeingDisplayed )
|
|
{
|
|
sLeastSaidQuote = GetRandomQuoteThatHasBeenSaidTheLeast( );
|
|
|
|
if( sLeastSaidQuote != -1 )
|
|
gusMercVideoSpeckSpeech = (UINT8)sLeastSaidQuote;
|
|
|
|
//Say the aim slander quotes the least
|
|
if( sLeastSaidQuote >= 47 && sLeastSaidQuote <= 57 )
|
|
{
|
|
IncreaseMercRandomQuoteValue( (UINT8)sLeastSaidQuote, 1 );
|
|
}
|
|
#ifdef JA2UB
|
|
//if its the biff is dead quote, only say the quote once
|
|
else if( sLeastSaidQuote == SPECK_QUOTE_BIFF_DEAD_WHEN_IMPORTING )
|
|
IncreaseMercRandomQuoteValue( (UINT8)sLeastSaidQuote, 255 );
|
|
#endif
|
|
else if( sLeastSaidQuote != -1 )
|
|
IncreaseMercRandomQuoteValue( (UINT8)sLeastSaidQuote, 3 );
|
|
}
|
|
|
|
uiLastTime = GetJA2Clock();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
INT16 GetRandomQuoteThatHasBeenSaidTheLeast( )
|
|
{
|
|
UINT8 cnt;
|
|
INT16 sSmallestNumber=255;
|
|
|
|
for( cnt=0; cnt<MERC_NUMBER_OF_RANDOM_QUOTES; cnt++)
|
|
{
|
|
//if the quote can be said ( the merc has not been hired )
|
|
if( CanMercQuoteBeSaid( gNumberOfTimesQuoteSaid[cnt].ubQuoteID ) )
|
|
{
|
|
//if this quote has been said less times then the last one
|
|
if( sSmallestNumber==255 || gNumberOfTimesQuoteSaid[cnt].uiNumberOfTimesQuoteSaid < gNumberOfTimesQuoteSaid[ sSmallestNumber ].uiNumberOfTimesQuoteSaid )
|
|
{
|
|
sSmallestNumber = cnt;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( sSmallestNumber == 255 )
|
|
return( -1 );
|
|
else
|
|
return( gNumberOfTimesQuoteSaid[ sSmallestNumber ].ubQuoteID );
|
|
}
|
|
|
|
void IncreaseMercRandomQuoteValue( UINT8 ubQuoteID, UINT8 ubValue )
|
|
{
|
|
UINT8 cnt;
|
|
|
|
for( cnt=0; cnt<MERC_NUMBER_OF_RANDOM_QUOTES; cnt++)
|
|
{
|
|
if( gNumberOfTimesQuoteSaid[ cnt ].ubQuoteID == ubQuoteID )
|
|
{
|
|
if( gNumberOfTimesQuoteSaid[ cnt ].uiNumberOfTimesQuoteSaid + ubValue > 255 )
|
|
gNumberOfTimesQuoteSaid[ cnt ].uiNumberOfTimesQuoteSaid = 255;
|
|
else
|
|
gNumberOfTimesQuoteSaid[ cnt ].uiNumberOfTimesQuoteSaid += ubValue;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void StopSpeckFromTalking( )
|
|
{
|
|
if( giVideoSpeckFaceIndex == -1 )
|
|
return;
|
|
|
|
//Stop speck from talking
|
|
ShutupaYoFace( giVideoSpeckFaceIndex );
|
|
|
|
RemoveSpeckPopupTextBox();
|
|
|
|
gusMercVideoSpeckSpeech = MERC_VIDEO_SPECK_SPEECH_NOT_TALKING;
|
|
}
|
|
|
|
BOOLEAN HasLarryRelapsed()
|
|
{
|
|
return( CheckFact( FACT_LARRY_CHANGED, 0 ) );
|
|
}
|
|
|
|
|
|
//Gets Called on each enter into laptop.
|
|
void EnterInitMercSite()
|
|
{
|
|
gfFirstTimeIntoMERCSiteSinceEnteringLaptop = TRUE;
|
|
gubCurMercIndex = 0;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN ShouldTheMercSiteServerGoDown()
|
|
{
|
|
UINT32 uiDay = GetWorldDay();
|
|
|
|
// If the merc site has never gone down, the first new merc has shown ( which shows the player is using the site ),
|
|
// and the players account status is ok ( cant have the merc site going down when the player owes him money, player may lose account that way )
|
|
// if( !LaptopSaveInfo.fMercSiteHasGoneDownYet && LaptopSaveInfo.gbNumDaysTillThirdMercArrives <= 6 && LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_VALID )
|
|
if( !LaptopSaveInfo.fMercSiteHasGoneDownYet && LaptopSaveInfo.ubLastMercAvailableId >= 1 && LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_VALID )
|
|
{
|
|
if( Random( 100 ) < ( uiDay * 2 + 10 ) )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef JA2UB
|
|
//no UB
|
|
#else
|
|
void GetMercSiteBackOnline()
|
|
{
|
|
if( IsSpeckComAvailable() )
|
|
{
|
|
//Add an email telling the user the site is back up
|
|
AddEmail( MERC_NEW_SITE_ADDRESS, MERC_NEW_SITE_ADDRESS_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1 , TYPE_EMAIL_EMAIL_EDT);
|
|
|
|
//Set a flag indicating that the server just went up ( so speck can make a comment when the player next visits the site )
|
|
LaptopSaveInfo.fFirstVisitSinceServerWentDown = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// anv: Have Speck inform player personally
|
|
TacticalCharacterDialogue( FindSoldierByProfileID( SPECK_PLAYABLE , TRUE ), SPECK_PLAYABLE_QUOTE_SERVER_WENT_DOWN );
|
|
// don't bring this up again
|
|
LaptopSaveInfo.fFirstVisitSinceServerWentDown = 2;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void DrawMercVideoBackGround()
|
|
{
|
|
HVOBJECT hPixHandle;
|
|
|
|
GetVideoObject(&hPixHandle, guiMercVideoPopupBackground);
|
|
BltVideoObject(FRAME_BUFFER, hPixHandle, 0,MERC_VIDEO_BACKGROUND_X, MERC_VIDEO_BACKGROUND_Y, VO_BLT_SRCTRANSPARENCY, NULL);
|
|
|
|
//put the title on the window
|
|
DrawTextToScreen(MercHomePageText[MERC_SPECK_COM], MERC_X_VIDEO_TITLE_X, MERC_X_VIDEO_TITLE_Y, 0, MERC_VIDEO_TITLE_FONT, MERC_VIDEO_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
|
|
InvalidateRegion(MERC_VIDEO_BACKGROUND_X, MERC_VIDEO_BACKGROUND_Y, (MERC_VIDEO_BACKGROUND_X + MERC_VIDEO_BACKGROUND_WIDTH), (MERC_VIDEO_BACKGROUND_Y + MERC_VIDEO_BACKGROUND_HEIGHT) );
|
|
}
|
|
|
|
void DisableMercSiteButton()
|
|
{
|
|
if( iMercPopUpBox != -1 )
|
|
{
|
|
#ifdef JA2UB
|
|
//JA25: removed ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#else
|
|
ButtonList[ guiAccountBoxButton ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
BOOLEAN CanMercQuoteBeSaid( UINT32 uiQuoteID )
|
|
{
|
|
BOOLEAN fRetVal = TRUE;
|
|
|
|
//switch onb the quote being said, if hes plugging a merc that has already been hired, dont say it
|
|
switch( uiQuoteID )
|
|
{
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_BIFF:
|
|
if( !IsMercMercAvailable( BIFF ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_HAYWIRE:
|
|
if( !IsMercMercAvailable( HAYWIRE ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_GASKET:
|
|
if( !IsMercMercAvailable( GASKET ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_RAZOR:
|
|
if( !IsMercMercAvailable( RAZOR ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_FLO:
|
|
if( !IsMercMercAvailable( FLO ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_GUMPY:
|
|
if( !IsMercMercAvailable( GUMPY ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_LARRY:
|
|
if( !IsMercMercAvailable( LARRY_NORMAL ) || IsMercMercAvailable( LARRY_DRUNK ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_COUGER:
|
|
if( !IsMercMercAvailable( COUGAR ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_NUMB:
|
|
if( !IsMercMercAvailable( NUMB ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_BUBBA:
|
|
if( !IsMercMercAvailable( BUBBA ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
#ifdef JA2UB
|
|
#else
|
|
//anv: playable Speck
|
|
case SPECK_QUOTE_PLAYER_NOT_DOING_ANYTHING_SPECK_SELLS_HIMSELF:
|
|
if( !IsMercMercAvailable( SPECK_PLAYABLE ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
#endif
|
|
|
|
#ifdef JA2UB
|
|
case SPECK_QUOTE_BIFF_DEAD_WHEN_IMPORTING:
|
|
if( !gJa25SaveStruct.fBiffWasKilledWhenImportingSave )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_ADVERTISE_GASTON:
|
|
if( !IsMercMercAvailable( GASTON_UB ) )//GASTON
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_ADVERTISE_STOGIE:
|
|
if( !IsMercMercAvailable( STOGIE_UB ) )//STOGIE
|
|
fRetVal = FALSE;
|
|
break;
|
|
#else
|
|
case SPECK_QUOTE_ADVERTISE_GASTON:
|
|
if( !IsMercMercAvailable( GASTON ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
|
|
case SPECK_QUOTE_ADVERTISE_STOGIE:
|
|
if( !IsMercMercAvailable( STOGIE ) )
|
|
fRetVal = FALSE;
|
|
break;
|
|
#endif
|
|
}
|
|
|
|
|
|
return( fRetVal );
|
|
}
|
|
|
|
|
|
void InitializeNumDaysMercArrive()
|
|
{
|
|
/*
|
|
LaptopSaveInfo.gbNumDaysTillFirstMercArrives = MERC_NUM_DAYS_TILL_FIRST_MERC_AVAILABLE;
|
|
LaptopSaveInfo.gbNumDaysTillSecondMercArrives = MERC_NUM_DAYS_TILL_SECOND_MERC_AVAILABLE;
|
|
LaptopSaveInfo.gbNumDaysTillThirdMercArrives = MERC_NUM_DAYS_TILL_THIRD_MERC_AVAILABLE;
|
|
LaptopSaveInfo.gbNumDaysTillFourthMercArrives = MERC_NUM_DAYS_TILL_FOURTH_MERC_AVAILABLE;
|
|
*/
|
|
}
|
|
|
|
|
|
void MakeBiffAwayForCoupleOfDays()
|
|
{
|
|
gMercProfiles[ BIFF ].uiDayBecomesAvailable = Random( 2 ) + 2;
|
|
}
|
|
|
|
|
|
BOOLEAN AreAnyOfTheNewMercsAvailable()
|
|
{
|
|
UINT8 ubMercID;
|
|
|
|
if( LaptopSaveInfo.fNewMercsAvailableAtMercSite )
|
|
return( FALSE );
|
|
|
|
for(UINT8 i=0; i<NUM_PROFILES; ++i)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].NewMercsAvailable == FALSE && gMercProfiles[i].Type == PROFILETYPE_MERC )
|
|
{
|
|
ubMercID = GetMercIDFromMERCArray( i );
|
|
if( IsMercMercAvailable( ubMercID ) )
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
void ShouldAnyNewMercMercBecomeAvailable()
|
|
{
|
|
//Kaiden: Added this if test to make sure that the "New Mercs Available"
|
|
// e-mail doesn't show up and no unneccessary checks are made when you
|
|
// have the ALL_MERCS_AT_MERC set to TRUE in the INI file.
|
|
// anv: ALL_MERCS_AT_MERC doesn't cover mercs that can be unlocked depending on in-campaign conditions (e.g. Kulba)
|
|
// if ALL_MERCS_AT_MERC is on, .StartMercsAvailable = TRUE anyway, so there won't be any conflicts or unnecessary emails
|
|
//if(!gGameExternalOptions.fAllMercsAvailable)
|
|
{
|
|
for(UINT8 i=0; i<NUM_PROFILES; i++)
|
|
{
|
|
if ( gConditionsForMercAvailability[i].ProfilId != 0 && gConditionsForMercAvailability[i].NewMercsAvailable == FALSE && gConditionsForMercAvailability[i].StartMercsAvailable == FALSE )
|
|
{
|
|
if( CanMercBeAvailableYet( gConditionsForMercAvailability[i].uiIndex ) )
|
|
{
|
|
//Set up an event to add the merc in x days
|
|
AddStrategicEvent( EVENT_MERC_SITE_NEW_MERC_AVAILABLE, GetMidnightOfFutureDayInMinutes( 1 ) + 420 + Random( 3 * 60 ), 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOLEAN CanMercBeAvailableYet( UINT8 ubMercToCheck )
|
|
{
|
|
// WANNE: If we have a drunken profile, skip
|
|
if (gConditionsForMercAvailability[ ubMercToCheck ].Drunk)
|
|
return ( FALSE );
|
|
|
|
//if the merc is already hired
|
|
//if( !IsMercHireable( GetMercIDFromMERCArray( gConditionsForMercAvailability[ ubMercToCheck ].ubMercArrayID ) ) )
|
|
// return( FALSE );
|
|
|
|
// anv: John Kulba should be recruitable after escort quest
|
|
#ifdef JA2UB
|
|
// too many Kulbas
|
|
#else
|
|
// if merc is Kulba, he was escorted as a civilian and enough days passed
|
|
if( gConditionsForMercAvailability[ ubMercToCheck ].ProfilId == JOHN_MERC )
|
|
{
|
|
if(gGameExternalOptions.fEnableRecruitableJohnKulba == TRUE)
|
|
{
|
|
if( LaptopSaveInfo.bJohnEscorted == TRUE
|
|
&& LaptopSaveInfo.uiJohnEscortedDate + gGameExternalOptions.ubRecruitableJohnKulbaDelay <= GetWorldDay() )
|
|
{
|
|
return( TRUE );
|
|
} else
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
// anv: if JA1 natives are turned off, prevent them from being be available
|
|
if(gGameExternalOptions.fEnableRecruitableJA1Natives == FALSE)
|
|
{
|
|
if( gConditionsForMercAvailability[ ubMercToCheck ].ProfilId == ELIO ||
|
|
gConditionsForMercAvailability[ ubMercToCheck ].ProfilId == JUAN ||
|
|
gConditionsForMercAvailability[ ubMercToCheck ].ProfilId == WAHAN )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
// anv: if recruitable Speck is turned off, prevent him from being available
|
|
if(gGameExternalOptions.fEnableRecruitableSpeck == FALSE)
|
|
{
|
|
if( gConditionsForMercAvailability[ ubMercToCheck ].ProfilId == SPECK_PLAYABLE )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
//if player has paid enough money for the merc to be available, and the it is after the current day
|
|
if( gConditionsForMercAvailability[ ubMercToCheck ].usMoneyPaid <= LaptopSaveInfo.uiTotalMoneyPaidToSpeck &&
|
|
gConditionsForMercAvailability[ ubMercToCheck ].usDay <= GetWorldDay() )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
void NewMercsAvailableAtMercSiteCallBack()
|
|
{
|
|
// rftr: don't spam the user's email when MERC has multiple new personnel available on the same day
|
|
bool sentNewMercsEmail = false;
|
|
|
|
for (UINT8 i = 0; i < NUM_PROFILES; i++)
|
|
{
|
|
if (gConditionsForMercAvailability[i].ProfilId != 0 && gConditionsForMercAvailability[i].NewMercsAvailable == FALSE && gConditionsForMercAvailability[i].StartMercsAvailable == FALSE)
|
|
{
|
|
if (CanMercBeAvailableYet(gConditionsForMercAvailability[i].uiIndex))
|
|
{
|
|
gConditionsForMercAvailability[i].NewMercsAvailable = TRUE;
|
|
|
|
//if ( gConditionsForMercAvailability[ gConditionsForMercAvailability[i].uiIndex ].Drunk == TRUE )
|
|
if (gConditionsForMercAvailability[i].Drunk == TRUE)
|
|
{
|
|
LaptopSaveInfo.gubLastMercIndex = gConditionsForMercAvailability[gConditionsForMercAvailability[i].uiAlternateIndex].uiIndex;
|
|
}
|
|
else
|
|
{
|
|
// If Previous merc has alternate index
|
|
if (i > 0 && gConditionsForMercAvailability[gConditionsForMercAvailability[i - 1].uiIndex].uiAlternateIndex != 255)
|
|
{
|
|
// Previous merc has alternate (drunk) merc, skip his one!
|
|
//LaptopSaveInfo.gubLastMercIndex = LaptopSaveInfo.gubLastMercIndex + 2;
|
|
LaptopSaveInfo.gubLastMercIndex = LaptopSaveInfo.gubLastMercIndex++;
|
|
}
|
|
else
|
|
{
|
|
LaptopSaveInfo.gubLastMercIndex++;
|
|
}
|
|
}
|
|
//gConditionsForMercAvailability[gConditionsForMercAvailability[i].uiIndex].NewMercsAvailable = TRUE; LaptopSaveInfo.ubLastMercAvailableId = gConditionsForMercAvailability[i].uiIndex;
|
|
gConditionsForMercAvailability[i].StartMercsAvailable = TRUE;
|
|
|
|
#ifdef JA2UB
|
|
if (!sentNewMercsEmail)
|
|
{
|
|
sentNewMercsEmail = true;
|
|
AddEmail(NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT);
|
|
}
|
|
|
|
//new mercs are available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
#else
|
|
if (IsSpeckComAvailable())
|
|
{
|
|
if (!sentNewMercsEmail)
|
|
{
|
|
sentNewMercsEmail = true;
|
|
AddEmail(NEW_MERCS_AT_MERC, NEW_MERCS_AT_MERC_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT);
|
|
}
|
|
|
|
//new mercs are available
|
|
LaptopSaveInfo.fNewMercsAvailableAtMercSite = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// anv: Have speck inform player personally
|
|
TacticalCharacterDialogue(FindSoldierByProfileID(SPECK_PLAYABLE, TRUE), SPECK_PLAYABLE_QUOTE_NEW_MERCS_AVAILABLE);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//used for older saves
|
|
void CalcAproximateAmountPaidToSpeck()
|
|
{
|
|
UINT8 i, ubMercID;
|
|
|
|
//loop through all the mercs and tally up the amount speck should have been paid
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
//get the id
|
|
ubMercID = GetMercIDFromMERCArray( i );
|
|
|
|
//increment the amount
|
|
LaptopSaveInfo.uiTotalMoneyPaidToSpeck += gMercProfiles[ ubMercID ].uiTotalCostToDate;
|
|
}
|
|
}
|
|
|
|
// CJC Dec 1 2002: calculate whether any MERC characters have been used at all
|
|
UINT32 CalcMercDaysServed()
|
|
{
|
|
UINT8 i, ubMercID;
|
|
UINT32 uiDaysServed = 0;
|
|
|
|
for(i=0; i<NUMBER_OF_MERCS; i++)
|
|
{
|
|
//get the id
|
|
ubMercID = GetMercIDFromMERCArray( i );
|
|
|
|
uiDaysServed += gMercProfiles[ ubMercID ].usTotalDaysServed;
|
|
|
|
}
|
|
return( uiDaysServed );
|
|
}
|
|
#ifdef JA2UB
|
|
INT8 IsSpeckQuoteImportantQuote( UINT32 uiQuoteNum )
|
|
{
|
|
INT32 iFlag=-1;
|
|
switch( uiQuoteNum )
|
|
{
|
|
case SPECK_QUOTE_BETTER_STARTING_EQPMNT_TAG_ON:
|
|
iFlag = SPECK__BETTER_EQUIPMENT;
|
|
break;
|
|
case SPECK_QUOTE_ENCOURAGE_SHOP_TAG_ON:
|
|
iFlag = SPECK__ENCOURAGE_POAYER_TO_KEEP_SHOPPING;
|
|
break;
|
|
case SPECK_QUOTE_2ND_INTRO_LAPTOP_WORKING_AGAIN_1:
|
|
iFlag = SPECK__SECOND_INTRO_BEEN_SAID;
|
|
break;
|
|
}
|
|
|
|
return( (INT8) iFlag );
|
|
}
|
|
|
|
BOOLEAN HasImportantSpeckQuoteBeingSaid( UINT32 uiQuoteNum )
|
|
{
|
|
INT8 iFlag;
|
|
|
|
iFlag = IsSpeckQuoteImportantQuote( uiQuoteNum );
|
|
if( iFlag == -1 )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
//has the quote been said
|
|
return( ( gJa25SaveStruct.ubImportantSpeckQuotesSaidBefore & ( 1 << iFlag ) ) != 0 );
|
|
}
|
|
|
|
//if the quote is a special quote, mark it said so we dont say it again
|
|
void MarkSpeckImportantQuoteUsed( UINT32 uiQuoteNum )
|
|
{
|
|
INT8 iFlag;
|
|
|
|
iFlag = IsSpeckQuoteImportantQuote( uiQuoteNum );
|
|
if( iFlag == -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
gJa25SaveStruct.ubImportantSpeckQuotesSaidBefore |= ( 1 << iFlag );
|
|
}
|
|
#endif
|