mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
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
1058 lines
27 KiB
C++
1058 lines
27 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "Tactical All.h"
|
|
#else
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#include "sgp.h"
|
|
#include "gameloop.h"
|
|
#include "himage.h"
|
|
#include "vobject.h"
|
|
#include "sysutil.h"
|
|
#include "overhead.h"
|
|
#include "mousesystem.h"
|
|
#include "Button System.h"
|
|
#include "interface.h"
|
|
#include "vsurface.h"
|
|
#include "wcheck.h"
|
|
#include "input.h"
|
|
#include "Handle UI.h"
|
|
#include "Animation Control.h"
|
|
#include "Animation Data.h"
|
|
#include "renderworld.h"
|
|
#include "sys globals.h"
|
|
#include "cursors.h"
|
|
#include "radar screen.h"
|
|
#include "worldman.h"
|
|
#include "Font Control.h"
|
|
#include "render dirty.h"
|
|
#include "utilities.h"
|
|
#include "interface cursors.h"
|
|
#include "Sound Control.h"
|
|
#include "lighting.h"
|
|
#include "Interface Panels.h"
|
|
#include "pathai.h"
|
|
#include "vobject_blitters.h"
|
|
#include "faces.h"
|
|
#include "Handle UI Plan.h"
|
|
#include "interface control.h"
|
|
#include "interface items.h"
|
|
#include "interface dialogue.h"
|
|
#include "interactive tiles.h"
|
|
#include "Game Clock.h"
|
|
#include "Strategic Exit GUI.h"
|
|
#include "PopUpBox.h"
|
|
#include "Assignments.h"
|
|
#include "spread burst.h"
|
|
#include "squads.h"
|
|
#include "line.h"
|
|
#include "Militia Control.h"
|
|
#include "Map Screen Interface.h"
|
|
#include "civ quotes.h"
|
|
#endif
|
|
|
|
/* I deleted here declaration of clock coords for tactical screen i will declare them
|
|
* in functions that Initialize coord for SMPanet and TEAMPanel
|
|
* any questions? joker
|
|
*/
|
|
SGPRect gOldClippingRect, gOldDirtyClippingRect;
|
|
|
|
UINT32 guiTacticalInterfaceFlags;
|
|
|
|
UINT16 gusUICurIntTileEffectIndex;
|
|
INT16 gsUICurIntTileEffectGridNo;
|
|
UINT8 gsUICurIntTileOldShade;
|
|
|
|
BOOLEAN gfRerenderInterfaceFromHelpText = FALSE;
|
|
|
|
MOUSE_REGION gLockPanelOverlayRegion;
|
|
|
|
extern void RenderTownIDString( );
|
|
extern BOOLEAN gfUIOverItemPool;
|
|
extern INT16 gfUIOverItemPoolGridNo;
|
|
extern BOOLEAN gfInMovementMenu;
|
|
extern BOOLEAN gfInItemPickupMenu;
|
|
extern BOOLEAN gfInOpenDoorMenu;
|
|
extern UINT32 guiUIMessageTimeDelay;
|
|
|
|
|
|
BOOLEAN gfPausedTacticalRenderInterfaceFlags = FALSE;
|
|
BOOLEAN gfPausedTacticalRenderFlags = FALSE;
|
|
|
|
// which assignment menu can be shown?
|
|
extern void DetermineWhichAssignmentMenusCanBeShown( void );
|
|
extern void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lal
|
|
extern void HandleAnyMercInSquadHasCompatibleStuff( UINT8 ubSquad, OBJECTTYPE *pObject, BOOLEAN fReset );
|
|
extern BOOLEAN RemoveFlashItemSlot( ITEM_POOL *pItemPool );
|
|
|
|
|
|
void SetTacticalInterfaceFlags( UINT32 uiFlags )
|
|
{
|
|
guiTacticalInterfaceFlags = uiFlags;
|
|
}
|
|
|
|
void HandleTacticalPanelSwitch( )
|
|
{
|
|
if ( gfSwitchPanel )
|
|
{
|
|
SetCurrentInterfacePanel( gbNewPanel );
|
|
SetCurrentTacticalPanelCurrentMerc( gubNewPanelParam );
|
|
gfSwitchPanel = FALSE;
|
|
|
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_NORENDERBUTTONS ) && !( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
|
|
{
|
|
RenderButtons( );
|
|
}
|
|
}
|
|
}
|
|
|
|
void RenderTacticalInterface( )
|
|
{
|
|
|
|
// handle paused render of tactical
|
|
HandlePausedTacticalRender( );
|
|
|
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
|
{
|
|
HandleFlashingItems( );
|
|
|
|
HandleMultiPurposeLocator( );
|
|
|
|
}
|
|
|
|
// Handle degrading new items...
|
|
DegradeNewlyAddedItems( );
|
|
|
|
switch( gsCurInterfacePanel )
|
|
{
|
|
case SM_PANEL:
|
|
RenderSMPanel( &fInterfacePanelDirty );
|
|
break;
|
|
|
|
case TEAM_PANEL:
|
|
RenderTEAMPanel( fInterfacePanelDirty );
|
|
break;
|
|
}
|
|
|
|
// Handle faces
|
|
if( !(guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
|
|
HandleAutoFaces( );
|
|
|
|
}
|
|
|
|
|
|
void HandlePausedTacticalRender( void )
|
|
{
|
|
|
|
// for a one frame paused render of tactical
|
|
if( gfPausedTacticalRenderFlags )
|
|
{
|
|
gRenderFlags|=gfPausedTacticalRenderFlags;
|
|
|
|
gfPausedTacticalRenderFlags = FALSE;
|
|
}
|
|
|
|
if ( gfPausedTacticalRenderInterfaceFlags )
|
|
{
|
|
fInterfacePanelDirty = gfPausedTacticalRenderInterfaceFlags;
|
|
gfPausedTacticalRenderInterfaceFlags = FALSE;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void RenderTacticalInterfaceWhileScrolling( )
|
|
{
|
|
RenderButtons( );
|
|
|
|
switch( gsCurInterfacePanel )
|
|
{
|
|
case SM_PANEL:
|
|
RenderSMPanel( &fInterfacePanelDirty );
|
|
break;
|
|
|
|
case TEAM_PANEL:
|
|
RenderTEAMPanel( fInterfacePanelDirty );
|
|
break;
|
|
}
|
|
|
|
// Handle faces
|
|
HandleAutoFaces( );
|
|
|
|
}
|
|
|
|
void SetUpInterface( )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
LEVELNODE *pIntTile;
|
|
|
|
if ( ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
DrawUICursor( );
|
|
|
|
SetupPhysicsTrajectoryUI( );
|
|
|
|
|
|
if ( giUIMessageOverlay != -1 )
|
|
{
|
|
if ( ( GetJA2Clock( ) - guiUIMessageTime ) > guiUIMessageTimeDelay )
|
|
{
|
|
EndUIMessage( );
|
|
}
|
|
}
|
|
|
|
if ( gusSelectedSoldier != NO_SOLDIER )
|
|
{
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
}
|
|
|
|
|
|
if ( gCurrentUIMode == OPENDOOR_MENU_MODE )
|
|
{
|
|
HandleOpenDoorMenu( );
|
|
}
|
|
|
|
HandleTalkingMenu( );
|
|
|
|
if ( gCurrentUIMode == EXITSECTORMENU_MODE )
|
|
{
|
|
HandleSectorExitMenu( );
|
|
}
|
|
|
|
// FOR THE MOST PART - SHUTDOWN INTERFACE WHEN IT'S THE ENEMY'S TURN
|
|
if ( gTacticalStatus.ubCurrentTeam != gbPlayerNum )
|
|
{
|
|
return;
|
|
}
|
|
|
|
HandleInterfaceBackgrounds( );
|
|
|
|
|
|
if ( gfUIHandleSelection == NONSELECTED_GUY_SELECTION )
|
|
{
|
|
if ( gsSelectedLevel > 0 )
|
|
{
|
|
AddRoofToHead( gsSelectedGridNo, GOODRING1 );
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
|
|
}
|
|
else
|
|
{
|
|
AddObjectToHead( gsSelectedGridNo, GOODRING1 );
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
|
|
}
|
|
|
|
if ( gfUIHandleSelection == SELECTED_GUY_SELECTION )
|
|
{
|
|
if ( gsSelectedLevel > 0 )
|
|
{
|
|
//AddRoofToHead( gsSelectedGridNo, SELRING1 );
|
|
AddRoofToHead( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
|
|
}
|
|
else
|
|
{
|
|
//AddObjectToHead( gsSelectedGridNo, SELRING1 );
|
|
AddObjectToHead( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if ( gfUIHandleSelection == ENEMY_GUY_SELECTION )
|
|
{
|
|
if ( gsSelectedLevel > 0 )
|
|
{
|
|
AddRoofToHead( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pRoofHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
|
|
}
|
|
else
|
|
{
|
|
AddObjectToHead( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsSelectedGridNo].pObjectHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
|
|
}
|
|
|
|
if ( gfUIHandleShowMoveGrid )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if ( MercPtrs[ gusSelectedSoldier ]->sGridNo != gsUIHandleShowMoveGridLocation )
|
|
{
|
|
if ( gfUIHandleShowMoveGrid == 2 )
|
|
{
|
|
AddTopmostToHead( gsUIHandleShowMoveGridLocation, GetSnapCursorIndex( FIRSTPOINTERS4 ) );
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
else
|
|
{
|
|
if ( MercPtrs[ gusSelectedSoldier ]->bStealthMode )
|
|
{
|
|
AddTopmostToHead( gsUIHandleShowMoveGridLocation, GetSnapCursorIndex( FIRSTPOINTERS9 ) );
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
else
|
|
{
|
|
AddTopmostToHead( gsUIHandleShowMoveGridLocation, GetSnapCursorIndex( FIRSTPOINTERS2 ) );
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
gpWorldLevelData[gsUIHandleShowMoveGridLocation].pTopmostHead->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if we are over an interactive tile...
|
|
if ( gfUIShowCurIntTile )
|
|
{
|
|
pIntTile = GetCurInteractiveTileGridNo( &gsUICurIntTileEffectGridNo );
|
|
|
|
if ( pIntTile != NULL )
|
|
{
|
|
gusUICurIntTileEffectIndex = pIntTile->usIndex;
|
|
|
|
// Shade green
|
|
gsUICurIntTileOldShade = pIntTile->ubShadeLevel;
|
|
pIntTile->ubShadeLevel = 0;
|
|
pIntTile->uiFlags |= LEVELNODE_DYNAMIC;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ResetInterface( )
|
|
{
|
|
LEVELNODE *pNode;
|
|
|
|
if ( ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// find out if we need to show any menus
|
|
DetermineWhichAssignmentMenusCanBeShown();
|
|
CreateDestroyAssignmentPopUpBoxes( );
|
|
|
|
DetermineWhichMilitiaControlMenusCanBeShown( ); //lal
|
|
CreateDestroyMilitiaControlPopUpBoxes( );
|
|
|
|
|
|
HideUICursor( );
|
|
|
|
ResetPhysicsTrajectoryUI( );
|
|
|
|
if ( gfUIHandleSelection )
|
|
{
|
|
if ( gsSelectedLevel > 0 )
|
|
{
|
|
RemoveRoof( gsSelectedGridNo, GOODRING1 );
|
|
RemoveRoof( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
}
|
|
else
|
|
{
|
|
RemoveObject( gsSelectedGridNo, FIRSTPOINTERS2 );
|
|
RemoveObject( gsSelectedGridNo, GOODRING1 );
|
|
|
|
}
|
|
}
|
|
|
|
if ( gfUIHandleShowMoveGrid )
|
|
{
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS4 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS9 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS2 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS13 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS15 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS19 );
|
|
RemoveTopmost( gsUIHandleShowMoveGridLocation, FIRSTPOINTERS20 );
|
|
}
|
|
|
|
if ( fInterfacePanelDirty )
|
|
{
|
|
fInterfacePanelDirty = FALSE;
|
|
}
|
|
|
|
|
|
// Reset int tile cursor stuff
|
|
if ( gfUIShowCurIntTile )
|
|
{
|
|
if ( gsUICurIntTileEffectGridNo != NOWHERE )
|
|
{
|
|
//Find our tile!
|
|
pNode = gpWorldLevelData[ gsUICurIntTileEffectGridNo].pStructHead;
|
|
|
|
while( pNode != NULL )
|
|
{
|
|
if ( pNode->usIndex == gusUICurIntTileEffectIndex )
|
|
{
|
|
pNode->ubShadeLevel = gsUICurIntTileOldShade;
|
|
pNode->uiFlags &= (~LEVELNODE_DYNAMIC);
|
|
break;
|
|
}
|
|
|
|
pNode = pNode->pNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
extern BOOLEAN AnyItemsVisibleOnLevel( ITEM_POOL *pItemPool, INT8 bZLevel );
|
|
|
|
|
|
UINT32 guiColors[ 12 ] =
|
|
{
|
|
FROMRGB( 198, 163, 0 ),
|
|
FROMRGB( 185, 150, 0 ),
|
|
FROMRGB( 172, 136, 0 ),
|
|
FROMRGB( 159, 123, 0 ),
|
|
FROMRGB( 146, 110, 0 ),
|
|
FROMRGB( 133, 96, 0 ),
|
|
FROMRGB( 120, 83, 0 ),
|
|
FROMRGB( 133, 96, 0 ),
|
|
FROMRGB( 146, 110, 0 ),
|
|
FROMRGB( 159, 123, 0 ),
|
|
FROMRGB( 172, 136, 0 ),
|
|
FROMRGB( 185, 150, 0 )
|
|
};
|
|
|
|
void RenderRubberBanding( )
|
|
{
|
|
UINT16 usLineColor;
|
|
UINT32 uiDestPitchBYTES;
|
|
UINT8 *pDestBuf;
|
|
INT16 iLeft, iRight, iTop, iBottom;
|
|
INT32 iBack = -1;
|
|
static INT32 iFlashColor = 0;
|
|
static INT32 uiTimeOfLastUpdate = 0;
|
|
|
|
if ( !gRubberBandActive )
|
|
return;
|
|
|
|
iLeft = (INT16)gRubberBandRect.iLeft;
|
|
iRight = (INT16)gRubberBandRect.iRight;
|
|
iTop = (INT16)gRubberBandRect.iTop;
|
|
iBottom = (INT16)gRubberBandRect.iBottom;
|
|
|
|
if ( iLeft == iRight && iTop == iBottom )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( ( GetJA2Clock( ) - uiTimeOfLastUpdate ) > 60 )
|
|
{
|
|
uiTimeOfLastUpdate = GetJA2Clock( );
|
|
iFlashColor++;
|
|
|
|
if ( iFlashColor == 12 )
|
|
{
|
|
iFlashColor = 0;
|
|
}
|
|
}
|
|
|
|
// Draw rectangle.....
|
|
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
|
|
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y );
|
|
|
|
usLineColor = Get16BPPColor( guiColors[ iFlashColor ] );
|
|
|
|
if ( ( iRight - iLeft ) > 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iTop, iRight, iTop, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iLeft, iTop, (INT16)( iRight + 1 ), (INT16)( iTop + 1 ) );
|
|
}
|
|
else if ( ( iRight - iLeft ) < 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iTop, iRight, iTop, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iRight, iTop, (INT16)( iLeft + 1 ), (INT16)( iTop + 1 ) );
|
|
}
|
|
|
|
if ( iBack != -1 )
|
|
{
|
|
SetBackgroundRectFilled( iBack );
|
|
}
|
|
|
|
|
|
iBack = -1;
|
|
|
|
if ( ( iRight - iLeft ) > 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iBottom, iRight, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iLeft, iBottom, (INT16)( iRight +1 ), (INT16)( iBottom + 1 ) );
|
|
}
|
|
else if ( ( iRight - iLeft ) < 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iBottom, iRight, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iRight, iBottom, (INT16)( iLeft + 1 ), (INT16)( iBottom + 1 ) );
|
|
}
|
|
|
|
if ( iBack != -1 )
|
|
{
|
|
SetBackgroundRectFilled( iBack );
|
|
}
|
|
|
|
|
|
|
|
iBack = -1;
|
|
|
|
if ( ( iBottom - iTop ) > 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iTop, iLeft, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iLeft, iTop, (INT16)( iLeft +1 ), iBottom );
|
|
}
|
|
else if ( ( iBottom - iTop ) < 0 )
|
|
{
|
|
LineDraw( TRUE, iLeft, iTop, iLeft, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iLeft, iBottom, (INT16)( iLeft + 1 ), iTop );
|
|
}
|
|
|
|
if ( iBack != -1 )
|
|
{
|
|
SetBackgroundRectFilled( iBack );
|
|
}
|
|
|
|
|
|
iBack = -1;
|
|
|
|
if ( ( iBottom - iTop ) > 0 )
|
|
{
|
|
LineDraw( TRUE, iRight, iTop, iRight, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iRight, iTop, (INT16)( iRight +1 ), iBottom );
|
|
}
|
|
else if ( ( iBottom - iTop ) < 0 )
|
|
{
|
|
LineDraw( TRUE, iRight, iTop, iRight, iBottom, usLineColor, pDestBuf );
|
|
iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, iRight, iBottom, (INT16)( iRight + 1 ), iTop );
|
|
}
|
|
|
|
if ( iBack != -1 )
|
|
{
|
|
SetBackgroundRectFilled( iBack );
|
|
}
|
|
|
|
|
|
|
|
UnLockVideoSurface( FRAME_BUFFER );
|
|
}
|
|
|
|
void RenderTopmostTacticalInterface( )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
UINT32 cnt;
|
|
static UINT32 uiBogTarget = 0;
|
|
VOBJECT_DESC VObjectDesc;
|
|
INT16 sX, sY;
|
|
INT16 sOffsetX, sOffsetY, sTempY_S, sTempX_S;
|
|
UINT16 usMapPos;
|
|
ITEM_POOL *pItemPool;
|
|
|
|
|
|
if ( gfRerenderInterfaceFromHelpText == TRUE )
|
|
{
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
|
|
switch( gsCurInterfacePanel )
|
|
{
|
|
case SM_PANEL:
|
|
RenderSMPanel( &fInterfacePanelDirty );
|
|
break;
|
|
|
|
case TEAM_PANEL:
|
|
RenderTEAMPanel( fInterfacePanelDirty );
|
|
break;
|
|
}
|
|
gfRerenderInterfaceFromHelpText = FALSE;
|
|
}
|
|
|
|
if ( ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
|
{
|
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_NORENDERBUTTONS ) )
|
|
{
|
|
// If we want to rederaw whole screen, dirty all buttons!
|
|
if ( fInterfacePanelDirty == DIRTYLEVEL2 )
|
|
{
|
|
MarkButtonsDirty( );
|
|
}
|
|
|
|
|
|
RenderButtons( );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ( InItemStackPopup( ) )
|
|
{
|
|
if ( fInterfacePanelDirty == DIRTYLEVEL2 )
|
|
{
|
|
RenderItemStackPopup( TRUE );
|
|
}
|
|
else
|
|
{
|
|
RenderItemStackPopup( FALSE );
|
|
}
|
|
}
|
|
|
|
if( ( InKeyRingPopup() ) && ( !InItemDescriptionBox( ) ) )
|
|
{
|
|
RenderKeyRingPopup( ( BOOLEAN )( fInterfacePanelDirty == DIRTYLEVEL2 ) );
|
|
}
|
|
|
|
if ( gfInMovementMenu )
|
|
{
|
|
RenderMovementMenu( );
|
|
}
|
|
|
|
|
|
|
|
// if IN PLAN MODE AND WE HAVE TARGETS, draw black targets!
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
// Zero out any planned soldiers
|
|
for( cnt = MAX_NUM_SOLDIERS; cnt < TOTAL_SOLDIERS; cnt++ )
|
|
{
|
|
if ( MercPtrs[ cnt ]->bActive )
|
|
{
|
|
if ( MercPtrs[ cnt ]->sPlannedTargetX != -1 )
|
|
{
|
|
// Blit bogus target
|
|
if ( uiBogTarget == 0 )
|
|
{
|
|
//Loadup cursor!
|
|
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
|
FilenameForBPP( "CURSORS\\targblak.sti", VObjectDesc.ImageFile);
|
|
AddVideoObject( &VObjectDesc, &uiBogTarget );
|
|
}
|
|
|
|
if ( GridNoOnScreen( (INT16)MAPROWCOLTOPOS( ( MercPtrs[ cnt ]->sPlannedTargetY/CELL_Y_SIZE), ( MercPtrs[ cnt ]->sPlannedTargetX / CELL_X_SIZE ) ) ) )
|
|
{
|
|
// GET SCREEN COORDINATES
|
|
sOffsetX = (MercPtrs[ cnt ]->sPlannedTargetX - gsRenderCenterX);
|
|
sOffsetY = (MercPtrs[ cnt ]->sPlannedTargetY - gsRenderCenterY);
|
|
|
|
FromCellToScreenCoordinates( sOffsetX, sOffsetY, &sTempX_S, &sTempY_S );
|
|
|
|
sX = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + sTempX_S;
|
|
sY = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + sTempY_S;
|
|
|
|
// Adjust for offset position on screen
|
|
sX -= gsRenderWorldOffsetX;
|
|
sY -= gsRenderWorldOffsetY;
|
|
|
|
sX -= 10;
|
|
sY -= 10;
|
|
|
|
BltVideoObjectFromIndex( FRAME_BUFFER, uiBogTarget, 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
|
|
InvalidateRegion( sX, sY, sX + 20, sY + 20 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if ( gfUIInDeadlock )
|
|
{
|
|
SetFont( LARGEFONT1 );
|
|
SetFontBackground( FONT_MCOLOR_BLACK );
|
|
SetFontForeground( FONT_MCOLOR_WHITE );
|
|
gprintfdirty( 0, 300, L"OPPONENT %d DEADLOCKED - 'Q' TO DEBUG, <ALT><ENTER> END OPP TURN", gUIDeadlockedSoldier );
|
|
mprintf( 0, 300, L"OPPONENT %d DEADLOCKED - 'Q' TO DEBUG, <ALT><ENTER> END OPP TURN", gUIDeadlockedSoldier );
|
|
|
|
}
|
|
|
|
|
|
// Syncronize for upcoming soldier counters
|
|
SYNCTIMECOUNTER( );
|
|
|
|
|
|
// Setup system for video overlay ( text and blitting ) Sets clipping rects, etc
|
|
StartViewportOverlays( );
|
|
|
|
RenderTopmostFlashingItems( );
|
|
|
|
RenderTopmostMultiPurposeLocator( );
|
|
|
|
RenderAccumulatedBurstLocations( );
|
|
|
|
// Loop through all mercs and make go
|
|
for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
|
|
{
|
|
pSoldier = MercSlots[ cnt ];
|
|
|
|
if (pSoldier != NULL )
|
|
{
|
|
if ( pSoldier->ubID == gsSelectedGuy && gfUIHandleSelectionAboveGuy )
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
DrawSelectedUIAboveGuy((UINT16)pSoldier->ubID);
|
|
}
|
|
|
|
if ( pSoldier->fDisplayDamage )
|
|
{
|
|
// Display damage
|
|
|
|
// Use world coordinates!
|
|
INT16 sMercScreenX, sMercScreenY, sOffsetX, sOffsetY, sDamageX, sDamageY;
|
|
|
|
if ( pSoldier->sGridNo != NOWHERE && pSoldier->bVisible != -1 )
|
|
{
|
|
GetSoldierScreenPos( pSoldier, &sMercScreenX, &sMercScreenY );
|
|
GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY );
|
|
|
|
if ( pSoldier->ubBodyType == QUEENMONSTER )
|
|
{
|
|
sDamageX = sMercScreenX + pSoldier->sDamageX - pSoldier->sBoundingBoxOffsetX;
|
|
sDamageY = sMercScreenY + pSoldier->sDamageY - pSoldier->sBoundingBoxOffsetY;
|
|
|
|
sDamageX += 25;
|
|
sDamageY += 10;
|
|
}
|
|
else
|
|
{
|
|
sDamageX = pSoldier->sDamageX + (INT16)(sMercScreenX + ( 2 * 30 / 3 ) );
|
|
sDamageY = pSoldier->sDamageY + (INT16)(sMercScreenY - 5 );
|
|
|
|
sDamageX -= sOffsetX;
|
|
sDamageY -= sOffsetY;
|
|
|
|
if ( sDamageY < gsVIEWPORT_WINDOW_START_Y )
|
|
{
|
|
sDamageY = ( sMercScreenY - sOffsetY );
|
|
}
|
|
}
|
|
|
|
SetFont( TINYFONT1 );
|
|
SetFontBackground( FONT_MCOLOR_BLACK );
|
|
SetFontForeground( FONT_MCOLOR_WHITE );
|
|
|
|
gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
|
mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
DrawSelectedUIAboveGuy( gusSelectedSoldier );
|
|
}
|
|
|
|
if ( gfUIHandleSelectionAboveGuy && gsSelectedGuy != NOBODY )
|
|
{
|
|
DrawSelectedUIAboveGuy((UINT16)gsSelectedGuy );
|
|
}
|
|
|
|
// FOR THE MOST PART, DISABLE INTERFACE STUFF WHEN IT'S ENEMY'S TURN
|
|
if ( gTacticalStatus.ubCurrentTeam == gbPlayerNum )
|
|
{
|
|
RenderArrows( );
|
|
}
|
|
|
|
RenderAimCubeUI( );
|
|
|
|
EndViewportOverlays( );
|
|
|
|
RenderRubberBanding( );
|
|
|
|
if ( !gfInItemPickupMenu && gpItemPointer == NULL )
|
|
{
|
|
HandleAnyMercInSquadHasCompatibleStuff( (INT8) CurrentSquad( ), NULL, TRUE );
|
|
}
|
|
|
|
// CHECK IF OUR CURSOR IS OVER AN INV POOL
|
|
if( GetMouseMapPos( &usMapPos) )
|
|
{
|
|
if ( gfUIOverItemPool )
|
|
{
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// Check if we are over an item pool
|
|
if ( GetItemPool( gfUIOverItemPoolGridNo, &pItemPool, pSoldier->bLevel ) )
|
|
{
|
|
STRUCTURE *pStructure = NULL;
|
|
INT16 sIntTileGridNo;
|
|
INT8 bZLevel = 0;
|
|
INT16 sActionGridNo = usMapPos;
|
|
|
|
// Get interactive tile...
|
|
if ( ConditionalGetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo , &pStructure, FALSE ) )
|
|
{
|
|
sActionGridNo = sIntTileGridNo;
|
|
}
|
|
|
|
bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, pSoldier->bLevel, pStructure );
|
|
|
|
if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) )
|
|
{
|
|
DrawItemPoolList( pItemPool, gfUIOverItemPoolGridNo , ITEMLIST_DISPLAY, bZLevel, gusMouseXPos, gusMouseYPos );
|
|
|
|
// ATE: If over items, remove locator....
|
|
RemoveFlashItemSlot( pItemPool );
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT8 bCheckLevel;
|
|
|
|
// ATE: Allow to see list if a different level....
|
|
if ( pSoldier->bLevel == 0 )
|
|
{
|
|
bCheckLevel = 1;
|
|
}
|
|
else
|
|
{
|
|
bCheckLevel = 0;
|
|
}
|
|
|
|
// Check if we are over an item pool
|
|
if ( GetItemPool( gfUIOverItemPoolGridNo, &pItemPool, bCheckLevel ) )
|
|
{
|
|
STRUCTURE *pStructure = NULL;
|
|
INT16 sIntTileGridNo;
|
|
INT8 bZLevel = 0;
|
|
INT16 sActionGridNo = usMapPos;
|
|
|
|
// Get interactive tile...
|
|
if ( ConditionalGetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo , &pStructure, FALSE ) )
|
|
{
|
|
sActionGridNo = sIntTileGridNo;
|
|
}
|
|
|
|
bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, bCheckLevel, pStructure );
|
|
|
|
if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) )
|
|
{
|
|
DrawItemPoolList( pItemPool, gfUIOverItemPoolGridNo , ITEMLIST_DISPLAY, bZLevel, gusMouseXPos, gusMouseYPos );
|
|
|
|
// ATE: If over items, remove locator....
|
|
RemoveFlashItemSlot( pItemPool );
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if we should render item selection window
|
|
if ( gCurrentUIMode == GETTINGITEM_MODE )
|
|
{
|
|
SetItemPickupMenuDirty( DIRTYLEVEL2 );
|
|
// Handle item pickup will return true if it's been closed
|
|
RenderItemPickupMenu( );
|
|
}
|
|
|
|
// Check if we should render item selection window
|
|
if ( gCurrentUIMode == OPENDOOR_MENU_MODE )
|
|
{
|
|
RenderOpenDoorMenu( );
|
|
}
|
|
|
|
if ( gfInTalkPanel )
|
|
{
|
|
SetTalkingMenuDirty( DIRTYLEVEL2 );
|
|
// Handle item pickup will return true if it's been closed
|
|
RenderTalkingMenu( );
|
|
}
|
|
|
|
if ( gfInSectorExitMenu )
|
|
{
|
|
RenderSectorExitMenu( );
|
|
}
|
|
|
|
if( fRenderRadarScreen == TRUE )
|
|
{
|
|
// Render clock
|
|
/* Here we was rendering closk and position string now i moved it to functions
|
|
* that render SM or TEAM panel it will be usefull when RenderTownIDString will
|
|
* take position where render i will fix that
|
|
* any questions?? joker
|
|
*/
|
|
// RenderClock( CLOCK_X, CLOCK_Y );
|
|
// RenderTownIDString( );
|
|
// CreateMouseRegionForPauseOfClock( CLOCK_X, CLOCK_Y );
|
|
}
|
|
else
|
|
{
|
|
RemoveMouseRegionForPauseOfClock( );
|
|
}
|
|
|
|
|
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_NORENDERBUTTONS ) )
|
|
{
|
|
// If we want to rederaw whole screen, dirty all buttons!
|
|
if ( fInterfacePanelDirty == DIRTYLEVEL2 )
|
|
{
|
|
MarkButtonsDirty( );
|
|
}
|
|
|
|
|
|
RenderButtons( );
|
|
RenderPausedGameBox( );
|
|
}
|
|
|
|
// mark all pop ups as dirty
|
|
MarkAllBoxesAsAltered( );
|
|
|
|
HandleShowingOfTacticalInterfaceFastHelpText( );
|
|
HandleShadingOfLinesForAssignmentMenus( );
|
|
DetermineBoxPositions( );
|
|
DisplayBoxes( FRAME_BUFFER );
|
|
}
|
|
|
|
|
|
|
|
void StartViewportOverlays( )
|
|
{
|
|
|
|
// Set Clipping Rect to be the viewscreen
|
|
// Save old one
|
|
memcpy( &gOldClippingRect, &ClippingRect, sizeof( gOldClippingRect ) );
|
|
|
|
// Save old dirty clipping rect
|
|
memcpy( &gOldDirtyClippingRect, &ClippingRect, sizeof( gOldDirtyClippingRect ) );
|
|
|
|
// Set bottom clipping value for blitter clipping rect
|
|
ClippingRect.iLeft = INTERFACE_START_X;
|
|
ClippingRect.iTop = gsVIEWPORT_WINDOW_START_Y;
|
|
ClippingRect.iRight = SCREEN_WIDTH;
|
|
ClippingRect.iBottom = gsVIEWPORT_WINDOW_END_Y;
|
|
|
|
// Set values for dirty rect clipping rect
|
|
gDirtyClipRect.iLeft = INTERFACE_START_X;
|
|
gDirtyClipRect.iTop = gsVIEWPORT_WINDOW_START_Y;
|
|
gDirtyClipRect.iRight = SCREEN_WIDTH;
|
|
gDirtyClipRect.iBottom = gsVIEWPORT_WINDOW_END_Y;
|
|
|
|
SaveFontSettings( );
|
|
SetFontDestBuffer( FRAME_BUFFER, 0, gsVIEWPORT_WINDOW_START_Y, SCREEN_WIDTH, gsVIEWPORT_WINDOW_END_Y, FALSE );
|
|
|
|
}
|
|
|
|
void EndViewportOverlays( )
|
|
{
|
|
// Reset clipping rect
|
|
memcpy( &ClippingRect, &gOldClippingRect, sizeof( gOldClippingRect ) );
|
|
memcpy( &gDirtyClipRect, &gOldDirtyClippingRect, sizeof( gOldDirtyClippingRect ) );
|
|
RestoreFontSettings( );
|
|
|
|
}
|
|
|
|
void LockTacticalInterface( )
|
|
{
|
|
// OK, check and see if we are not locked, if so
|
|
// 1) create a mouse region over the entrie interface panel
|
|
// 2) set flag for use in tactical to indicate we are locked
|
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_LOCKEDLEVEL1 ) )
|
|
{
|
|
MSYS_DefineRegion( &gLockPanelOverlayRegion, 0, gsVIEWPORT_WINDOW_END_Y ,SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGHEST,
|
|
CURSOR_NORMAL, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
|
|
// Add region
|
|
MSYS_AddRegion( &gLockPanelOverlayRegion);
|
|
|
|
guiTacticalInterfaceFlags |= INTERFACE_LOCKEDLEVEL1;
|
|
}
|
|
}
|
|
|
|
|
|
void UnLockTacticalInterface( )
|
|
{
|
|
if ( (guiTacticalInterfaceFlags & INTERFACE_LOCKEDLEVEL1 ) )
|
|
{
|
|
// Remove region
|
|
MSYS_RemoveRegion( &gLockPanelOverlayRegion);
|
|
|
|
guiTacticalInterfaceFlags &= (~INTERFACE_LOCKEDLEVEL1);
|
|
}
|
|
|
|
}
|
|
|
|
void EraseInterfaceMenus( BOOLEAN fIgnoreUIUnLock )
|
|
{
|
|
// ATE: If we are currently talking, setup this flag so that the
|
|
// automatic handler in handledialogue doesn't adjust the UI setting
|
|
if ( ( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) && fIgnoreUIUnLock )
|
|
{
|
|
gTacticalStatus.uiFlags |= IGNORE_ENGAGED_IN_CONV_UI_UNLOCK;
|
|
}
|
|
|
|
// Remove item pointer if one active
|
|
CancelItemPointer( );
|
|
|
|
ShutDownQuoteBoxIfActive( );
|
|
PopDownMovementMenu( );
|
|
PopDownOpenDoorMenu( );
|
|
DeleteTalkingMenu( );
|
|
}
|
|
|
|
|
|
BOOLEAN AreWeInAUIMenu( )
|
|
{
|
|
if ( gfInMovementMenu || gfInOpenDoorMenu || gfInItemPickupMenu || gfInSectorExitMenu || gfInTalkPanel )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
void ResetInterfaceAndUI( )
|
|
{
|
|
// Erase menus
|
|
EraseInterfaceMenus( FALSE );
|
|
|
|
EraseRenderArrows( );
|
|
|
|
EndRubberBanding( );
|
|
|
|
//ResetMultiSelection( );
|
|
|
|
if ( giUIMessageOverlay != -1 )
|
|
{
|
|
RemoveVideoOverlay( giUIMessageOverlay );
|
|
giUIMessageOverlay = -1;
|
|
}
|
|
|
|
// Set UI back to movement...
|
|
guiPendingOverrideEvent = M_ON_TERRAIN;
|
|
HandleTacticalUI( );
|
|
}
|
|
|
|
BOOLEAN InterfaceOKForMeanwhilePopup()
|
|
{
|
|
if ( gfSwitchPanel )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
} |