Files
source/Laptop/IMP Voices.cpp
T
Overhaul 7a27e7105d New attack busy system
Added missing #includes

Added LUA scripting and console

Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain

Fixed signedness of many grid variables used in GetMouseMapPos calls

Fixed enemy weapon choosing:  Sometimes a mortar is chosen but later rejected, but the grenade class was not reset.  Caused assertion failure

Added checks so enemies don't try to chuck RPG grenades with their hands

Now possible to shoot a someone in the head if he's in water

Fixed InitSightArrays to also clear soldier interrupt duel points.  This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called.

Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have

Removed early setting of muzzle flash.  This would allow enemies to get an interrupt before you even fired.

Fixed item dropping by AI.  If AI tried to drop something while standing it would cause deadlock

Change to greatly speed up closing the sector inventory window in an unloaded sector

Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting


Check builddefines.h for the conditional flags.  Of greatest interest might be LUA_CONSOLE.  This will cause the game to bring up a command console when run.  However this console is severely lacking in many areas.  If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated.  The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus.

LUA scripting is very limited, basically just proof of concept.  There is one global variable, the Soldiers array.  An array index gives you the soldier in that slot in the currently loaded sector.  The soldier has a few things that can be accessed:  name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid)


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2007-06-09 09:01:04 +00:00

513 lines
12 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Laptop All.h"
#else
#include "CharProfile.h"
#include "IMP Voices.h"
#include "IMP MainPage.h"
#include "IMP HomePage.h"
#include "IMPVideoObjects.h"
#include "Utilities.h"
#include "WCheck.h"
#include "input.h"
#include "Isometric Utils.h"
#include "Debug.h"
#include "WordWrap.h"
#include "Render Dirty.h"
#include "Encrypted File.h"
#include "cursors.h"
#include "laptop.h"
#include "Sound Control.h"
#include "IMP Text System.h"
#include "text.h"
#include "soldier profile type.h"
#include "GameSettings.h"
#include "LaptopSave.h"
#endif
INT32 iCurrentVoice = 0;
UINT32 uiVocVoiceSound = 0;
// buttons needed for the IMP Voices screen
INT32 giIMPVoicesButton[ 3 ];
INT32 giIMPVoicesButtonImage[ 3 ];
// hacks to be removeed later
BOOLEAN fVoiceAVisited = FALSE, fVoiceBVisited = FALSE, fVoiceCVisited = FALSE;
// redraw protrait screen
BOOLEAN fReDrawVoicesScreenFlag = FALSE;
// the portrait region, for player to click on and re-hear voice
MOUSE_REGION gVoicePortraitRegion;
// function definitions
void IncrementVoice( void );
void DecrementVoice( void );
void CreateIMPVoicesButtons( void );
void DestroyIMPVoicesButtons( void );
void CreateIMPVoiceMouseRegions( void );
void DestroyIMPVoiceMouseRegions( void );
void RenderVoiceIndex( void );
BOOLEAN CameBackToVoicePageButNotFinished();
// callbacks
void BtnIMPVoicesNextCallback(GUI_BUTTON *btn,INT32 reason);
void BtnIMPVoicesPreviousCallback(GUI_BUTTON *btn,INT32 reason);
void BtnIMPVoicesDoneCallback(GUI_BUTTON *btn,INT32 reason);
void IMPPortraitRegionButtonCallback(MOUSE_REGION * pRegion, INT32 iReason );
void EnterIMPVoices( void )
{
fVoiceAVisited = FALSE;
fVoiceBVisited = FALSE;
fVoiceCVisited = FALSE;
// Set the initial voice
if (fCharacterIsMale == TRUE)
{
iCurrentVoice = GetFirstFreeSlot(MALE);
}
else
{
iCurrentVoice = GetFirstFreeSlot(FEMALE);
}
// create buttons
CreateIMPVoicesButtons( );
// create mouse regions
CreateIMPVoiceMouseRegions( );
// render background
RenderIMPVoices( );
// play voice once
uiVocVoiceSound = PlayVoice( );
return;
}
void RenderIMPVoices( void )
{
// render background
RenderProfileBackGround( );
// the Voices frame
RenderPortraitFrame( 191, 167 );
// the sillouette
RenderLargeSilhouette( 200, 176 );
// indent for the text
RenderAttrib1IndentFrame( 128, 65);
// render voice index value
RenderVoiceIndex( );
// text
PrintImpText( );
return;
}
void ExitIMPVoices( void )
{
// destroy buttons for IMP Voices page
DestroyIMPVoicesButtons( );
// destroy mouse regions for this screen
DestroyIMPVoiceMouseRegions( );
return;
}
void HandleIMPVoices( void )
{
// do we need to re write screen
if ( fReDrawVoicesScreenFlag == TRUE )
{
RenderIMPVoices( );
// reset redraw flag
fReDrawVoicesScreenFlag = FALSE;
}
return;
}
// WDS: Allow flexible numbers of IMPs of each sex
// Ensure the voice is within the valid range
void FixVoiceRange()
{
if (fCharacterIsMale == TRUE)
{
if (iCurrentVoice > GetLastMaleSlot())
iCurrentVoice = GetFirstMaleSlot();
else if (iCurrentVoice < GetFirstMaleSlot())
iCurrentVoice = GetLastMaleSlot();
}
else
{
if (iCurrentVoice > GetLastFemaleSlot())
iCurrentVoice = GetFirstFemaleSlot();
else if (iCurrentVoice < GetFirstFemaleSlot())
iCurrentVoice = GetLastFemaleSlot();
}
}
// WANNE NEW
void IncrementVoice( void )
{
INT32 iIMPIndex = -1;
INT32 i;
iCurrentVoice++;
FixVoiceRange();
// Just to be safe (so we use no endless loop)
for (i = 0; i < CountIMPSlots(); i++)
{
if (IsIMPSlotFree(gGameExternalOptions.iaIMPSlots[iCurrentVoice]) == TRUE)
{
// This is a free imp index
iIMPIndex = gGameExternalOptions.iaIMPSlots[iCurrentVoice];
break;
}
iCurrentVoice++;
FixVoiceRange();
}
}
void DecrementVoice( void )
{
INT32 iIMPIndex = -1;
INT32 i;
iCurrentVoice--;
FixVoiceRange();
// Just to be safe (so we use no endless loop)
for (i = 0; i < CountIMPSlots(); i++)
{
if (IsIMPSlotFree(gGameExternalOptions.iaIMPSlots[iCurrentVoice]) == TRUE)
{
// This is the free imp index
iIMPIndex = gGameExternalOptions.iaIMPSlots[iCurrentVoice];
break;
}
iCurrentVoice--;
FixVoiceRange();
}
}
void CreateIMPVoicesButtons( void )
{
// will create buttons need for the IMP Voices screen
// next button
giIMPVoicesButtonImage[0]= LoadButtonImage( "LAPTOP\\voicearrows.sti" ,-1,1,-1,3,-1 );
/*giIMPVoicesButton[0] = QuickCreateButton( giIMPVoicesButtonImage[0], LAPTOP_SCREEN_UL_X + ( 18 ), LAPTOP_SCREEN_WEB_UL_Y + ( 184 ),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesNextCallback );
*/
giIMPVoicesButton[0] = CreateIconAndTextButton( giIMPVoicesButtonImage[0], pImpButtonText[ 13 ], FONT12ARIAL,
FONT_WHITE, DEFAULT_SHADOW,
FONT_WHITE, DEFAULT_SHADOW,
TEXT_CJUSTIFIED,
LAPTOP_SCREEN_UL_X + ( 343 ), LAPTOP_SCREEN_WEB_UL_Y + ( 205 ),BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesNextCallback);
// previous button
giIMPVoicesButtonImage[ 1 ]= LoadButtonImage( "LAPTOP\\voicearrows.sti" ,-1,0,-1,2,-1 );
/* giIMPVoicesButton[ 1 ] = QuickCreateButton( giIMPVoicesButtonImage[ 1 ], LAPTOP_SCREEN_UL_X + ( 18 ), LAPTOP_SCREEN_WEB_UL_Y + ( 254 ),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesPreviousCallback );
*/
giIMPVoicesButton[ 1 ] = CreateIconAndTextButton( giIMPVoicesButtonImage[ 1 ], pImpButtonText[ 12 ], FONT12ARIAL,
FONT_WHITE, DEFAULT_SHADOW,
FONT_WHITE, DEFAULT_SHADOW,
TEXT_CJUSTIFIED,
LAPTOP_SCREEN_UL_X + ( 93), LAPTOP_SCREEN_WEB_UL_Y + ( 205 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesPreviousCallback);
// done button
giIMPVoicesButtonImage[ 2 ]= LoadButtonImage( "LAPTOP\\button_5.sti" ,-1,0,-1,1,-1 );
/* giIMPVoicesButton[ 2 ] = QuickCreateButton( giIMPVoicesButtonImage[ 1 ], LAPTOP_SCREEN_UL_X + ( 349 ), LAPTOP_SCREEN_WEB_UL_Y + ( 220 ),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesDoneCallback );
*/
giIMPVoicesButton[ 2 ] = CreateIconAndTextButton( giIMPVoicesButtonImage[ 2 ], pImpButtonText[ 11 ], FONT12ARIAL,
FONT_WHITE, DEFAULT_SHADOW,
FONT_WHITE, DEFAULT_SHADOW,
TEXT_CJUSTIFIED,
LAPTOP_SCREEN_UL_X + ( 187 ), LAPTOP_SCREEN_WEB_UL_Y + ( 330 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPVoicesDoneCallback);
SetButtonCursor(giIMPVoicesButton[0], CURSOR_WWW);
SetButtonCursor(giIMPVoicesButton[1], CURSOR_WWW);
SetButtonCursor(giIMPVoicesButton[2], CURSOR_WWW);
}
void DestroyIMPVoicesButtons( void )
{
// will destroy buttons created for IMP Voices screen
// the next button
RemoveButton(giIMPVoicesButton[ 0 ] );
UnloadButtonImage(giIMPVoicesButtonImage[ 0 ] );
// the previous button
RemoveButton(giIMPVoicesButton[ 1 ] );
UnloadButtonImage(giIMPVoicesButtonImage[ 1 ] );
// the done button
RemoveButton(giIMPVoicesButton[ 2 ] );
UnloadButtonImage(giIMPVoicesButtonImage[ 2 ] );
return;
}
void BtnIMPVoicesNextCallback(GUI_BUTTON *btn,INT32 reason)
{
// btn callback for IMP attrbite begin button
if (!(btn->uiFlags & BUTTON_ENABLED))
return;
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags|=(BUTTON_CLICKED_ON);
}
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if (btn->uiFlags & BUTTON_CLICKED_ON)
{
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// next voice!!
IncrementVoice( );
// play voice
if( ! SoundIsPlaying( uiVocVoiceSound ) )
{
uiVocVoiceSound = PlayVoice( );
}
else
{
SoundStop( uiVocVoiceSound );
uiVocVoiceSound = PlayVoice( );
}
fReDrawVoicesScreenFlag = TRUE;
}
}
}
void BtnIMPVoicesPreviousCallback(GUI_BUTTON *btn,INT32 reason)
{
// btn callback for IMP attrbite begin button
if (!(btn->uiFlags & BUTTON_ENABLED))
return;
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags|=(BUTTON_CLICKED_ON);
}
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if (btn->uiFlags & BUTTON_CLICKED_ON)
{
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// previous voice, please!!!
DecrementVoice( );
// play voice
if( ! SoundIsPlaying( uiVocVoiceSound ) )
{
uiVocVoiceSound = PlayVoice( );
}
else
{
SoundStop( uiVocVoiceSound );
uiVocVoiceSound = PlayVoice( );
}
fReDrawVoicesScreenFlag = TRUE;
}
}
}
void BtnIMPVoicesDoneCallback(GUI_BUTTON *btn,INT32 reason)
{
// btn callback for IMP attrbite begin button
if (!(btn->uiFlags & BUTTON_ENABLED))
return;
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags|=(BUTTON_CLICKED_ON);
}
else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if (btn->uiFlags & BUTTON_CLICKED_ON)
{
btn->uiFlags&=~(BUTTON_CLICKED_ON);
// go to main page
iCurrentImpPage = IMP_MAIN_PAGE;
// if we are already done, leave
if( iCurrentProfileMode == IMP__FINISH )
{
iCurrentImpPage = IMP_FINISH;
}
else
{
if( CameBackToVoicePageButNotFinished() )
{
iCurrentImpPage = IMP_MAIN_PAGE;
}
else
{
iCurrentProfileMode = IMP__PERSONALITY;
}
}
/*
// current mode now is voice
else if( iCurrentProfileMode < IMP__PORTRAIT )
{
iCurrentProfileMode = IMP__PORTRAIT;
}
else if( iCurrentProfileMode == IMP__PORTRAIT )
{
// all done profiling
iCurrentProfileMode = IMP__VOICE;
iCurrentImpPage = IMP_FINISH;
}
*/
// set voice id, to grab character slot
// WANNE 10:
// WDS: Allow flexible numbers of IMPs of each sex
LaptopSaveInfo.iIMPIndex = gGameExternalOptions.iaIMPSlots[iCurrentVoice];
// set button up image pending
fButtonPendingFlag = TRUE;
}
}
}
BOOLEAN CameBackToVoicePageButNotFinished()
{
//if we are in a page that comes after this one
if( iCurrentProfileMode == IMP__PERSONALITY ||
iCurrentProfileMode == IMP__ATTRIBUTES )
{
return( TRUE );
}
else
{
return( FALSE );
}
}
UINT32 PlayVoice( void )
{
INT32 iSlot = gGameExternalOptions.iaIMPSlots[iCurrentVoice];
char caVoiceSample[] = "Speech\\%03d_001.wav";
Assert((iSlot >= 0) && (iSlot <= 999));
sprintf(caVoiceSample, caVoiceSample, iSlot);
return( PlayJA2SampleFromFile( caVoiceSample, RATE_11025, MIDVOLUME, 1 , MIDDLEPAN ) );
}
void CreateIMPVoiceMouseRegions( void )
{
// will create mouse regions needed for the IMP voices page
MSYS_DefineRegion( &gVoicePortraitRegion, LAPTOP_SCREEN_UL_X + 200, LAPTOP_SCREEN_WEB_UL_Y + 176 ,LAPTOP_SCREEN_UL_X + 200 + 100, LAPTOP_SCREEN_WEB_UL_Y + 176 + 100,MSYS_PRIORITY_HIGH,
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, IMPPortraitRegionButtonCallback );
MSYS_AddRegion( &gVoicePortraitRegion );
return;
}
void DestroyIMPVoiceMouseRegions( void )
{
// will destroy already created mouse reiogns for IMP voices page
MSYS_RemoveRegion( &gVoicePortraitRegion );
return;
}
void IMPPortraitRegionButtonCallback(MOUSE_REGION * pRegion, INT32 iReason )
{
// callback handler for imp portrait region button events
if (iReason & MSYS_CALLBACK_REASON_INIT)
{
return;
}
if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
{
if( ! SoundIsPlaying( uiVocVoiceSound ) )
{
uiVocVoiceSound = PlayVoice( );
}
}
return;
}
void RenderVoiceIndex( void )
{
CHAR16 sString[ 32 ];
INT16 sX, sY;
// render the voice index value on the the blank portrait
swprintf( sString, L"%s %d", pIMPVoicesStrings[ 0 ], GetVoiceCountFromVoiceSlot(iCurrentVoice));
FindFontCenterCoordinates( 290 + LAPTOP_UL_X, 0, 100, 0, sString, FONT12ARIAL, &sX, &sY );
SetFont( FONT12ARIAL );
SetFontForeground( FONT_WHITE );
SetFontBackground( FONT_BLACK );
mprintf( sX, iScreenHeightOffset + 320, sString );
return;
}