Files
source/TileEngine/Tactical Placement GUI.cpp
T
00fb898600 Delete builddefines.h
Nothing was left in it but the include of profiler.h, and 132 translation units
were including it for that alone. Fifteen files were leaning on profiler.h to
drag in <set>, <vector> and <ostream> for them; those now include what they use.

This is the commit that moves line numbers. Removing an include line shifts
__LINE__ by one for everything below it, and __LINE__ is an immediate operand in
every Assert() and DebugMsg() call, so the four game executables differ from
their predecessors by roughly a thousand 32-bit constants each. Every one of
those is accounted for: each is a single immediate that moved by -1 where the
builddefines.h include went away, or +1 where a <set>/<vector> include was
added. Nothing else in .text, .rdata or .data moves, no object file's section
sizes change, and symbolize_crash and Ja2Export stay bit-identical.

The one non-immediate difference is that the 24 Editor translation units of the
non-editor apps stop emitting __Avx2WmemEnabledWeakValue, a 4-byte weak COMDAT
they only ever instantiated through profiler.h's <vector>. It is a UCRT weak
default that other translation units still provide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 01:07:26 -03:00

2253 lines
76 KiB
C++

// WANNE 2 <changed some lines>
//sgp
#include "english.h"
#include "DEBUG.H"
#include "video.h"
#include "vobject_blitters.h"
#include "line.h"
//ja2
#include "Tactical Placement GUI.h"
#include "overhead map.h"
#include "strategicmap.h"
#include "Interface.h"
#include "Overhead.h"
#include "Render Dirty.h"
#include "sysutil.h"
#include "PreBattle Interface.h"
#include "Soldier Profile.h"
#include "Map Edgepoints.h"
#include "gameloop.h"
#include "message.h"
#include "Map Information.h"
#include "Soldier Add.h"
#include "Cursors.h"
#include "Cursor Control.h"
#include "MessageBoxScreen.h"
#include "Text.h"
#include "WordWrap.h"
#include "Game Clock.h"
#include "Isometric Utils.h"
#include "connect.h"
#include "renderworld.h"//dnl ch45 051009
#include "merc entering.h"
#include "CampaignStats.h" // added by Flugente
#include "Rebel Command.h"
typedef struct MERCPLACEMENT
{
SOLDIERTYPE *pSoldier;
UINT32 uiVObjectID;
MOUSE_REGION region;
UINT8 ubStrategicInsertionCode;
BOOLEAN fPlaced;
}MERCPLACEMENT;
MERCPLACEMENT *gMercPlacement = NULL;
UINT8 gfirstMercIndex = 0; // Index into gMercPlacement for the first visible merc face that is rendered
UINT16 gFacePanelXStart; // Defines the area for mouse wheel scrolling
UINT16 gFacePanelXEnd;
UINT16 gFacePanelYStart;
UINT16 gFacePanelYEnd;
enum
{
DONE_BUTTON,
SPREAD_BUTTON,
GROUP_BUTTON,
CLEAR_BUTTON,
NUM_TP_BUTTONS
};
UINT32 iTPButtons[ NUM_TP_BUTTONS ];
//dnl ch45 051009
#define PLACEMENT_OFFSET 150
extern INT32 giXA, giYA;
extern BOOLEAN gfOverheadMapDirty;
extern BOOLEAN GetOverheadMouseGridNo( INT32 *psGridNo );
extern UINT16 iOffsetHorizontal;
extern UINT16 iOffsetVertical;
int islocked;
UINT8 gubDefaultButton = CLEAR_BUTTON;
BOOLEAN gfTacticalPlacementGUIActive = FALSE;
BOOLEAN gfTacticalPlacementFirstTime = FALSE;
BOOLEAN gfEnterTacticalPlacementGUI = FALSE;
BOOLEAN gfKillTacticalGUI = FALSE;
INT32 giOverheadPanelImage = 0;
INT32 giOverheadButtonImages[ NUM_TP_BUTTONS ];
INT32 giMercPanelImage = 0;
INT32 giPlacements = 0;
BOOLEAN gfTacticalPlacementGUIDirty = FALSE;
BOOLEAN gfValidLocationsChanged = FALSE;
SGPRect gTPClipRect = {0,0,0,0};
// WANNE - MP: Center
SGPRect gTPClipRectCenterLeft = {0,0,0,0};
SGPRect gTPClipRectCenterTop = {0,0,0,0};
SGPRect gTPClipRectCenterRight = {0,0,0,0};
SGPRect gTPClipRectCenterBottom = {0,0,0,0};
BOOLEAN gfValidCursor = FALSE;
BOOLEAN gfEveryonePlaced = FALSE;
UINT8 gubSelectedGroupID = 0;
UINT8 gubHilightedGroupID = 0;
UINT8 gubCursorGroupID = 0;
INT8 gbSelectedMercID = -1;
INT8 gbHilightedMercID = -1;
INT8 gbCursorMercID = -1;
SOLDIERTYPE *gpTacticalPlacementSelectedSoldier = NULL;
SOLDIERTYPE *gpTacticalPlacementHilightedSoldier = NULL;
// WANNE - MP: Center
BOOLEAN gfCenter;
extern BOOLEAN GetOverheadScreenXYFromGridNo( INT32 sGridNo, INT16* psScreenX, INT16* psScreenY );
void DoneOverheadPlacementClickCallback( GUI_BUTTON *btn, INT32 reason );
void SpreadPlacementsCallback ( GUI_BUTTON *btn, INT32 reason );
void GroupPlacementsCallback( GUI_BUTTON *btn, INT32 reason );
void ClearPlacementsCallback( GUI_BUTTON *btn, INT32 reason );
void MercMoveCallback( MOUSE_REGION *reg, INT32 reason );
void MercClickCallback( MOUSE_REGION *reg, INT32 reason );
void PlaceMercs();
void FastHelpRemovedCallback();
void FastHelpRemoved2Callback();
void DialogRemoved( UINT8 ubResult );
void PutDownMercPiece( INT32 iPlacement );
void PickUpMercPiece( INT32 iPlacement );
void SetCursorMerc( INT8 bPlacementID );
void SelectNextUnplacedUnit();
// WANNE: Made methods available for Release build, because we need them in multiplayer
//#ifdef JA2BETAVERSION
BOOLEAN gfNorthValid, gfEastValid, gfSouthValid, gfWestValid;
BOOLEAN gfChangedEntrySide = FALSE;
static void FindValidInsertionCode( UINT8 *pubStrategicInsertionCode )
{
if( gMapInformation.sNorthGridNo == -1 &&
gMapInformation.sEastGridNo == -1 &&
gMapInformation.sSouthGridNo == -1 &&
gMapInformation.sWestGridNo == -1 )
{
AssertMsg( 0, "Map has no entry points at all. Can't generate edge points. LC:1" );
}
if( gMapInformation.sNorthGridNo != -1 && !gps1stNorthEdgepointArray ||
gMapInformation.sEastGridNo != -1 && !gps1stEastEdgepointArray ||
gMapInformation.sSouthGridNo != -1 && !gps1stSouthEdgepointArray ||
gMapInformation.sWestGridNo != -1 && !gps1stWestEdgepointArray )
{
InvalidateScreen();
DrawTextToScreen( L"Map doesn't has entrypoints without corresponding edgepoints. LC:1",
iOffsetHorizontal + 30, iOffsetVertical + 150, 600, FONT10ARIALBOLD, FONT_RED, FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED );
DrawTextToScreen( L"GENERATING MAP EDGEPOINTS! Please wait...",
iOffsetHorizontal + 30, iOffsetVertical + 160, 600, FONT10ARIALBOLD, FONT_YELLOW, FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED );
RefreshScreen( NULL );
GenerateMapEdgepoints(TRUE);//dnl ch43 290909
switch( *pubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH:
if( !gps1stNorthEdgepointArray )
AssertMsg( 0, "Map Edgepoint generation failed. KM : 0 -- send map" );
break;
case INSERTION_CODE_EAST:
if( !gps1stEastEdgepointArray )
AssertMsg( 0, "Map Edgepoint generation failed. KM : 0 -- send map" );
break;
case INSERTION_CODE_SOUTH:
if( !gps1stSouthEdgepointArray )
AssertMsg( 0, "Map Edgepoint generation failed. KM : 0 -- send map" );
break;
case INSERTION_CODE_WEST:
if( !gps1stWestEdgepointArray )
AssertMsg( 0, "Map Edgepoint generation failed. KM : 0 -- send map" );
break;
}
return;
}
if( gMapInformation.sNorthGridNo != -1 )
{
*pubStrategicInsertionCode = INSERTION_CODE_NORTH;
gfChangedEntrySide = TRUE;
}
else if( gMapInformation.sEastGridNo != -1 )
{
*pubStrategicInsertionCode = INSERTION_CODE_EAST;
gfChangedEntrySide = TRUE;
}
else if( gMapInformation.sSouthGridNo != -1 )
{
*pubStrategicInsertionCode = INSERTION_CODE_SOUTH;
gfChangedEntrySide = TRUE;
}
else if( gMapInformation.sWestGridNo != -1 )
{
*pubStrategicInsertionCode = INSERTION_CODE_WEST;
gfChangedEntrySide = TRUE;
}
else
{
AssertMsg( 0, "No maps edgepoints at all! KM, LC : 1" );
}
}
static void CheckForValidMapEdge( UINT8 *pubStrategicInsertionCode )
{
switch( *pubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH:
if( !gps1stNorthEdgepointArray )
FindValidInsertionCode( pubStrategicInsertionCode );
break;
case INSERTION_CODE_EAST:
if( !gps1stEastEdgepointArray )
FindValidInsertionCode( pubStrategicInsertionCode );
break;
case INSERTION_CODE_SOUTH:
if( !gps1stSouthEdgepointArray )
FindValidInsertionCode( pubStrategicInsertionCode );
break;
case INSERTION_CODE_WEST:
if( !gps1stWestEdgepointArray )
FindValidInsertionCode( pubStrategicInsertionCode );
break;
}
}
static UINT8 MaxRenderedFaces()
{
// Based on OverheadInterface.sti files
if ( iResolution >= _640x480 && iResolution < _800x600 )
{
return 20;
}
else if ( iResolution < _1024x768 )
{
return 26;
}
else
{
return 34;
}
}
static void InitializeMercScrollArea()
{
// Based on OverheadInterface.sti files
gFacePanelXStart = 88 + xResOffset;
gFacePanelXEnd = SCREEN_WIDTH - xResOffset;
gFacePanelYStart = SCREEN_HEIGHT - 120;
gFacePanelYEnd = SCREEN_HEIGHT;
}
UINT32 gTacticalPlacementGUIPrevNextButtons[2];
UINT32 gTacticalPlacementGUIPrevNextButtonImages[2];
UINT32 gTacticalPlacementGUISliderBar;
MOUSE_REGION gTacticalPlacementGUISliderBarRegion;
UINT16 gScrollAreaXStart;
UINT16 gScrollAreaXEnd;
UINT16 gScrollAreaYStart;
UINT16 gScrollAreaYEnd;
UINT32 gScrollAreaGfx;
static void IncreaseMercIndex()
{
if ( gfirstMercIndex < (giPlacements - MaxRenderedFaces()) )
{
if ( gfirstMercIndex + MaxRenderedFaces() >= giPlacements - 1 )
{
gfirstMercIndex += 1;
}
else
{
gfirstMercIndex += 2;
}
gfTacticalPlacementGUIDirty = TRUE;
}
}
static void DecreaseMercIndex()
{
if ( gfirstMercIndex > 0 )
{
if ( gfirstMercIndex == 1 )
{
gfirstMercIndex -= 1;
}
else
{
gfirstMercIndex -= 2;
}
gfTacticalPlacementGUIDirty = TRUE;
}
}
static void BtnTacticalPlacementNextCallback( GUI_BUTTON *btn, INT32 reason )
{
if ( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
gfTacticalPlacementGUIDirty = TRUE;
btn->uiFlags |= (BUTTON_CLICKED_ON);
}
else if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if ( btn->uiFlags & BUTTON_CLICKED_ON )
{
btn->uiFlags &= ~(BUTTON_CLICKED_ON);
IncreaseMercIndex();
}
}
}
static void BtnTacticalPlacementPrevCallback( GUI_BUTTON *btn, INT32 reason )
{
if ( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
gfTacticalPlacementGUIDirty = TRUE;
btn->uiFlags |= (BUTTON_CLICKED_ON);
}
else if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if ( btn->uiFlags & BUTTON_CLICKED_ON )
{
btn->uiFlags &= ~(BUTTON_CLICKED_ON);
DecreaseMercIndex();
}
}
}
static void InitializeMercScrollButtons()
{
UINT16 xPrev, xNext, y;
// Button locations based on OverheadInterface.sti files
xNext = SCREEN_WIDTH - 17 - xResOffset;
xPrev = 89 + xResOffset;
y = SCREEN_HEIGHT - 19;
// time compression buttons
gTacticalPlacementGUIPrevNextButtonImages[0] = LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti", 10, 1, -1, 3, -1 );
gTacticalPlacementGUIPrevNextButtonImages[1] = LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti", 9, 0, -1, 2, -1 );
gTacticalPlacementGUIPrevNextButtons[0] = QuickCreateButton( gTacticalPlacementGUIPrevNextButtonImages[0], xNext, y,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 2,
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnTacticalPlacementNextCallback );
gTacticalPlacementGUIPrevNextButtons[1] = QuickCreateButton( gTacticalPlacementGUIPrevNextButtonImages[1], xPrev, y,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 2,
(GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnTacticalPlacementPrevCallback );
SetButtonCursor( gTacticalPlacementGUIPrevNextButtons[0], MSYS_NO_CURSOR );
SetButtonCursor( gTacticalPlacementGUIPrevNextButtons[1], MSYS_NO_CURSOR );
}
static void LoadSliderBar( void )
{
VOBJECT_DESC VObjectDesc;
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
sprintf( VObjectDesc.ImageFile, "INTERFACE\\map_screen_bottom_arrows.sti" );
if ( !AddVideoObject( &VObjectDesc, &gTacticalPlacementGUISliderBar ) )
{
AssertMsg( 0, "Failed to load Interface\\map_screen_bottom_arrows.sti" );
}
sprintf( VObjectDesc.ImageFile, "INTERFACE\\OverheadInterface_scrollarea.sti" );
if ( !AddVideoObject( &VObjectDesc, &gScrollAreaGfx ) )
{
AssertMsg( 0, "Failed to load Interface\\OverheadInterface_scrollarea.sti" );
}
}
static void TacticalPlacementScrollBarCallBack( MOUSE_REGION *pRegion, INT32 iReason )
{
POINT MousePos;
UINT16 desiredMercIndex;
const UINT8 sliderWidth = 11;
const UINT16 sliderBarRange = gScrollAreaXEnd - gScrollAreaXStart - sliderWidth;
if ( iReason & MSYS_CALLBACK_REASON_INIT )
{
return;
}
if ( iReason & (MSYS_CALLBACK_REASON_LBUTTON_DWN | MSYS_CALLBACK_REASON_LBUTTON_REPEAT) )
{
// region is supposed to be disabled if there aren't enough messages to scroll. Formulas assume this
if ( giPlacements > MaxRenderedFaces() )
{
// where is the mouse?
GetCursorPos( &MousePos );
ScreenToClient( ghWindow, &MousePos ); // In window coords!
const UINT16 ubMouseXOffset = (UINT16)MousePos.x - gScrollAreaXStart;
// if clicking in the top 5 pixels of the slider bar
if ( ubMouseXOffset < (sliderWidth / 2) )
{
// scroll all the way to the top
desiredMercIndex = 0;
}
// if clicking in the bottom 6 pixels of the slider bar
else if ( ubMouseXOffset >= ((gScrollAreaXEnd - gScrollAreaXStart) - (sliderWidth / 2)) )
{
// scroll all the way to the bottom
desiredMercIndex = giPlacements - MaxRenderedFaces();
}
else
{
// somewhere in between
const UINT16 desiredSliderOffset = ubMouseXOffset - (sliderWidth / 2);
Assert( desiredSliderOffset <= sliderBarRange );
// calculate what the index should be to place the slider at this offset (round fractions of .5+ up)
desiredMercIndex = ((desiredSliderOffset * (giPlacements - MaxRenderedFaces())) + (sliderBarRange / 2)) / sliderBarRange;
}
// if it's a change
if ( desiredMercIndex != gfirstMercIndex )
{
gfirstMercIndex = desiredMercIndex;
gfTacticalPlacementGUIDirty = TRUE;
}
}
}
}
static void CreateTacticalPlacementGUIScrollBarRegion( void )
{
// Locations based on OverheadInterface.sti files
gScrollAreaXStart = 104 + xResOffset;
gScrollAreaXEnd = SCREEN_WIDTH - 18 - xResOffset;
gScrollAreaYStart = SCREEN_HEIGHT - 19;
gScrollAreaYEnd = gScrollAreaYStart + 11; //SLIDER_HEIGHT / SLIDER_WIDTH in Map Screen Interface Bottom.cpp;
MSYS_DefineRegion( &gTacticalPlacementGUISliderBarRegion,
gScrollAreaXStart,
gScrollAreaYStart,
gScrollAreaXEnd,
gScrollAreaYEnd,
MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, TacticalPlacementScrollBarCallBack
);
}
static void DisplayTacticalPlacementSlider()
{
// will display the scroll bar icon
HVOBJECT hHandle;
// only show the slider if there are more messages than will fit on screen
if ( giPlacements > MaxRenderedFaces() )
{
// Slider bar area graphics
UINT16 imageIndex;
if ( (iResolution >= _640x480 && iResolution < _800x600) )
{
imageIndex = 0;
}
else if ( iResolution < _1024x768 )
{
imageIndex = 1;
}
else
{
imageIndex = 2;
}
GetVideoObject( &hHandle, gScrollAreaGfx );
BltVideoObject( FRAME_BUFFER, hHandle, imageIndex, gScrollAreaXStart, gScrollAreaYStart, VO_BLT_SRCTRANSPARENCY, NULL );
// calculate where slider should be positioned
UINT8 sliderWidth = 11;
UINT16 sliderBarRange = gScrollAreaXEnd - gScrollAreaXStart - sliderWidth;
UINT16 ubSliderOffset = (sliderBarRange * gfirstMercIndex) / (giPlacements - MaxRenderedFaces());
GetVideoObject( &hHandle, gTacticalPlacementGUISliderBar );
BltVideoObject( FRAME_BUFFER, hHandle, 8, gScrollAreaXStart + ubSliderOffset, gScrollAreaYStart + 1 , VO_BLT_SRCTRANSPARENCY, NULL );
}
}
static void EnableDisableTacticalPlacementScrollButtonsAndRegions( void )
{
// if no scrolling required, or already showing the first merc
if ( (giPlacements <= MaxRenderedFaces()) || (gfirstMercIndex == 0) )
{
DisableButton( gTacticalPlacementGUIPrevNextButtons[1] );
ButtonList[gTacticalPlacementGUIPrevNextButtons[1]]->uiFlags &= ~(BUTTON_CLICKED_ON);
}
else
{
EnableButton( gTacticalPlacementGUIPrevNextButtons[1] );
ShowButton( gTacticalPlacementGUIPrevNextButtons[1] );
}
// if no scrolling required, or already showing the last merc
if ( giPlacements <= MaxRenderedFaces() ||
((gfirstMercIndex + MaxRenderedFaces()) >= giPlacements) )
{
DisableButton( gTacticalPlacementGUIPrevNextButtons[0] );
ButtonList[gTacticalPlacementGUIPrevNextButtons[0]]->uiFlags &= ~(BUTTON_CLICKED_ON);
}
else
{
EnableButton( gTacticalPlacementGUIPrevNextButtons[0] );
ShowButton( gTacticalPlacementGUIPrevNextButtons[0] );
}
if ( giPlacements <= MaxRenderedFaces())
{
MSYS_DisableRegion( &gTacticalPlacementGUISliderBarRegion );
HideButton( gTacticalPlacementGUIPrevNextButtons[0] );
HideButton( gTacticalPlacementGUIPrevNextButtons[1] );
}
else
{
MSYS_EnableRegion( &gTacticalPlacementGUISliderBarRegion );
}
}
extern BOOLEAN gfTacticalDoHeliRun;
void InitTacticalPlacementGUI()
{
islocked=0;//hayden
VOBJECT_DESC VObjectDesc;
INT32 xp, yp;
UINT8 ubFaceIndex;
gfTacticalPlacementGUIActive = TRUE;
gfTacticalPlacementGUIDirty = TRUE;
gfValidLocationsChanged = TRUE;
gfTacticalPlacementFirstTime = TRUE;
gfirstMercIndex = 0;
// WANNE - MP: Center
gfCenter = FALSE;
#ifdef JA2BETAVERSION
gfNorthValid = gfEastValid = gfSouthValid = gfWestValid = FALSE;
gfChangedEntrySide = FALSE;
#endif
// WANNE: Make a black background color for the whole screen
ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
//Enter overhead map
GoIntoOverheadMap();
MSYS_DisableRegion( &gRadarRegion ); // So it doesn't interfere with selecting mercs
InitializeMercScrollArea();
LoadSliderBar();
//Load the images
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
if (iResolution >= _640x480 && iResolution < _800x600)
{
sprintf( VObjectDesc.ImageFile, "Interface\\OverheadInterface.sti" );
if( !AddVideoObject( &VObjectDesc, (UINT32 *)&giOverheadPanelImage ) )
{
AssertMsg( 0, "Failed to load Interface\\OverheadInterface.sti" );
}
}
else if (iResolution < _1024x768)
{
sprintf( VObjectDesc.ImageFile, "Interface\\OverheadInterface_800x600.sti" );
if( !AddVideoObject( &VObjectDesc, (UINT32 *)&giOverheadPanelImage ) )
{
AssertMsg( 0, "Failed to load Interface\\OverheadInterface_800x600.sti" );
}
}
else
{
sprintf( VObjectDesc.ImageFile, "Interface\\OverheadInterface_1024x768.sti" );
if( !AddVideoObject( &VObjectDesc, (UINT32 *)&giOverheadPanelImage ) )
{
AssertMsg( 0, "Failed to load Interface\\OverheadInterface_1024x768.sti" );
}
}
sprintf( VObjectDesc.ImageFile, "Interface\\panels.sti" );
if( !AddVideoObject( &VObjectDesc, (UINT32 *)&giMercPanelImage ) )
{
AssertMsg( 0, "Failed to load Interface\\panels.sti" );
}
giOverheadButtonImages[ DONE_BUTTON ] = LoadButtonImage( "Interface\\OverheadUIButtons.sti", -1, 0, -1, 1, -1 );
if( giOverheadButtonImages[ DONE_BUTTON ] == -1 )
{
AssertMsg( 0, "Failed to load Interface\\OverheadUIButtons.sti" );
}
giOverheadButtonImages[ SPREAD_BUTTON ] = UseLoadedButtonImage( giOverheadButtonImages[ DONE_BUTTON ], -1, 0, -1, 1, -1 );
giOverheadButtonImages[ GROUP_BUTTON ] = UseLoadedButtonImage( giOverheadButtonImages[ DONE_BUTTON ], -1, 0, -1, 1, -1 );
giOverheadButtonImages[ CLEAR_BUTTON ] = UseLoadedButtonImage( giOverheadButtonImages[ DONE_BUTTON ], -1, 0, -1, 1, -1 );
//Create the buttons which provide automatic placements.
iTPButtons[ CLEAR_BUTTON ] =
QuickCreateButton( giOverheadButtonImages[ CLEAR_BUTTON ], 11 + xResOffset, SCREEN_HEIGHT - 148, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, ClearPlacementsCallback );
SpecifyGeneralButtonTextAttributes( iTPButtons[ CLEAR_BUTTON ], gpStrategicString[ STR_TP_CLEAR ], BLOCKFONT, FONT_BEIGE, 141 );
SetButtonFastHelpText( iTPButtons[ CLEAR_BUTTON ], gpStrategicString[ STR_TP_CLEARHELP ] );
SetBtnHelpEndCallback( iTPButtons[ CLEAR_BUTTON ], FastHelpRemoved2Callback );
iTPButtons[ SPREAD_BUTTON ] =
QuickCreateButton( giOverheadButtonImages[ SPREAD_BUTTON ], 11 + xResOffset, SCREEN_HEIGHT - 113, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, SpreadPlacementsCallback );
SpecifyGeneralButtonTextAttributes( iTPButtons[ SPREAD_BUTTON ], gpStrategicString[ STR_TP_SPREAD ], BLOCKFONT, FONT_BEIGE, 141 );
SetButtonFastHelpText( iTPButtons[ SPREAD_BUTTON ], gpStrategicString[ STR_TP_SPREADHELP ] );
SetBtnHelpEndCallback( iTPButtons[ SPREAD_BUTTON ], FastHelpRemovedCallback );
iTPButtons[ GROUP_BUTTON ] =
QuickCreateButton( giOverheadButtonImages[ GROUP_BUTTON ], 11 + xResOffset, SCREEN_HEIGHT - 78, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, GroupPlacementsCallback );
SpecifyGeneralButtonTextAttributes( iTPButtons[ GROUP_BUTTON ], gpStrategicString[ STR_TP_GROUP ], BLOCKFONT, FONT_BEIGE, 141 );
SetButtonFastHelpText( iTPButtons[ GROUP_BUTTON ], gpStrategicString[ STR_TP_GROUPHELP ] );
SetBtnHelpEndCallback( iTPButtons[ GROUP_BUTTON ], FastHelpRemovedCallback );
iTPButtons[ DONE_BUTTON ] =
QuickCreateButton( giOverheadButtonImages[ DONE_BUTTON ], 11 + xResOffset, SCREEN_HEIGHT - 43, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, DoneOverheadPlacementClickCallback );
SpecifyGeneralButtonTextAttributes( iTPButtons[ DONE_BUTTON ], gpStrategicString[ STR_TP_DONE ], BLOCKFONT, FONT_BEIGE, 141 );
SetButtonFastHelpText( iTPButtons[ DONE_BUTTON ], gpStrategicString[ STR_TP_DONEHELP ] );
SetBtnHelpEndCallback( iTPButtons[ DONE_BUTTON ], FastHelpRemovedCallback );
AllowDisabledButtonFastHelp( iTPButtons[ DONE_BUTTON ], TRUE );
SpecifyButtonHilitedTextColors( iTPButtons[ CLEAR_BUTTON ], FONT_WHITE, FONT_NEARBLACK );
SpecifyButtonHilitedTextColors( iTPButtons[ SPREAD_BUTTON ], FONT_WHITE, FONT_NEARBLACK );
SpecifyButtonHilitedTextColors( iTPButtons[ GROUP_BUTTON ], FONT_WHITE, FONT_NEARBLACK );
SpecifyButtonHilitedTextColors( iTPButtons[ DONE_BUTTON ], FONT_WHITE, FONT_NEARBLACK );
//First pass: Count the number of mercs that are going to be placed by the player.
// This determines the size of the array we will allocate.
giPlacements = 0;
for( SoldierID i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++i )
{
SOLDIERTYPE *pSoldier = i;
if( pSoldier->bActive && !pSoldier->flags.fBetweenSectors &&
CurrentBattleSectorIs( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ) &&
!( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE ) ) && // ATE Ignore vehicles
pSoldier->bAssignment != ASSIGNMENT_POW &&
pSoldier->bAssignment != ASSIGNMENT_MINIEVENT &&
pSoldier->bAssignment != ASSIGNMENT_REBELCOMMAND &&
!( pSoldier->usSoldierFlagMask2 & SOLDIER_CONCEALINSERTION ) &&
pSoldier->bAssignment != IN_TRANSIT )
{
++giPlacements;
}
}
//Allocate the array based on how many mercs there are.
gMercPlacement = (MERCPLACEMENT*)MemAlloc( sizeof( MERCPLACEMENT ) * giPlacements );
Assert( gMercPlacement );
//Second pass: Assign the mercs to their respective slots.
giPlacements = 0;
for( SoldierID i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++i )
{
SOLDIERTYPE *pSoldier = i;
if( pSoldier->bActive && pSoldier->stats.bLife && !pSoldier->flags.fBetweenSectors &&
CurrentBattleSectorIs( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ) &&
pSoldier->bAssignment != ASSIGNMENT_POW &&
pSoldier->bAssignment != ASSIGNMENT_MINIEVENT &&
pSoldier->bAssignment != ASSIGNMENT_REBELCOMMAND &&
!( pSoldier->usSoldierFlagMask2 & SOLDIER_CONCEALINSERTION ) &&
pSoldier->bAssignment != IN_TRANSIT &&
!( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE ) ) ) // ATE Ignore vehicles
{
// Flugente: if options allow it and we entered this sector - in combat - via helicopter, then allow us free selection of our entry point, and drop us from the helicopter
if ( pSoldier->bTeam == gbPlayerNum && (gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
{
AddMercToHeli( pSoldier->ubID );
DisableButton(iTPButtons[SPREAD_BUTTON]);
gMercPlacement[ giPlacements ].ubStrategicInsertionCode = INSERTION_CODE_CHOPPER;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CHOPPER;
gfCenter = TRUE;
}
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE )
{
gMercPlacement[giPlacements].ubStrategicInsertionCode = INSERTION_CODE_CENTER;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CENTER;
gfCenter = TRUE;
}
// WANNE - MP: Check if the desired insertion direction is valid on the map. If not, choose another entry direction!
if (is_networked)
{
pSoldier->ubStrategicInsertionCode = GetValidInsertionDirectionForMP(pSoldier->ubStrategicInsertionCode);
}
// ATE: If we are in a vehicle - remove ourselves from it!
//if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
//{
// RemoveSoldierFromVehicle( pSoldier, pSoldier->bVehicleID );
//}
if( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_PRIMARY_EDGEINDEX ||
pSoldier->ubStrategicInsertionCode == INSERTION_CODE_SECONDARY_EDGEINDEX )
{
pSoldier->ubStrategicInsertionCode = (UINT8)pSoldier->usStrategicInsertionData;
}
gMercPlacement[ giPlacements ].pSoldier = pSoldier;
gMercPlacement[ giPlacements ].ubStrategicInsertionCode = pSoldier->ubStrategicInsertionCode;
gMercPlacement[ giPlacements ].fPlaced = FALSE;
// WANNE: We always want to have edgepoints
CheckForValidMapEdge( &pSoldier->ubStrategicInsertionCode );
// Flugente: campaign stats
switch( pSoldier->ubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH:
gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_NORTH;
break;
case INSERTION_CODE_EAST:
gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_EAST;
break;
case INSERTION_CODE_SOUTH:
gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_SOUTH;
break;
case INSERTION_CODE_WEST:
gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_WEST;
break;
}
// WANNE - MP: Center
if (is_networked && pSoldier->ubStrategicInsertionCode == INSERTION_CODE_CENTER)
{
gfCenter = TRUE;
}
++giPlacements;
}
}
//add all the faces now
for( INT32 i = 0; i < giPlacements; ++i )
{
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
//Load the faces
{
ubFaceIndex = gMercProfiles[ gMercPlacement[ i ].pSoldier->ubProfile ].ubFaceIndex;
if ( ( ubFaceIndex < 100 ) && gMercProfiles[gMercPlacement[i].pSoldier->ubProfile].Type == PROFILETYPE_IMP )
{
sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%02d.sti", ubFaceIndex );
}
else if ( ( ubFaceIndex > 99 ) && gMercProfiles[gMercPlacement[i].pSoldier->ubProfile].Type == PROFILETYPE_IMP )
{
sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%03d.sti", ubFaceIndex );
}
else if( ubFaceIndex < 100 )
{
sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%02d.sti", ubFaceIndex );
}
else if( ubFaceIndex > 99 )
{
sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%03d.sti", ubFaceIndex );
}
}
if( !AddVideoObject( &VObjectDesc, &gMercPlacement[ i ].uiVObjectID ) )
{
sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\speck.sti" );
if( !AddVideoObject( &VObjectDesc, &gMercPlacement[ i ].uiVObjectID ) )
{
AssertMsg( 0, String("Failed to load %Faces\\65Face\\%03d.sti or it's placeholder, speck.sti", gMercProfiles[ gMercPlacement[ i ].pSoldier->ubProfile ].ubFaceIndex) );
}
}
xp = (xResOffset) + 91 + (i / 2) * 54;
if (i % 2)
{
yp = SCREEN_HEIGHT - 68;
}
else
{
yp = SCREEN_HEIGHT - 119;
}
//yp = (i % 2) ? 412 : 361;
MSYS_DefineRegion( &gMercPlacement[ i ].region, (UINT16)xp, (UINT16)yp, (UINT16)(xp + 54), (UINT16)(yp + 51), MSYS_PRIORITY_HIGH, 0, MercMoveCallback, MercClickCallback );
}
if(!is_client)
PlaceMercs();//hayden
if( gubDefaultButton == GROUP_BUTTON )
{
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_CLICKED_ON;
for( INT32 i = 0; i < giPlacements; ++i )
{ //go from the currently selected soldier to the end
if( !gMercPlacement[ i ].fPlaced )
{ //Found an unplaced merc. Select him.
gbSelectedMercID = (INT8)i;
if( gubDefaultButton == GROUP_BUTTON )
gubSelectedGroupID = gMercPlacement[ i ].pSoldier->ubGroupID;
gfTacticalPlacementGUIDirty = TRUE;
SetCursorMerc( (INT8)i );
gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier;
break;
}
}
}
InitializeMercScrollButtons();
CreateTacticalPlacementGUIScrollBarRegion();
}
// WANNE - MP: This method checks, if the desired entry direction (N, E, S, W) on the map is valid. If not it chooses the next valid diretion
UINT8 GetValidInsertionDirectionForMP(UINT8 currentInsertionPoint)
{
bool foundValidDirection = false;
UINT8 validInsertionDirection = currentInsertionPoint;
// Check if current insertion direction is valid
switch (currentInsertionPoint)
{
case INSERTION_CODE_NORTH:
if (gus1stNorthEdgepointArraySize > 0 || gus2ndNorthEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_NORTH;
}
break;
case INSERTION_CODE_SOUTH:
if (gus1stSouthEdgepointArraySize > 0 || gus2ndSouthEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_SOUTH;
}
break;
case INSERTION_CODE_EAST:
if (gus1stEastEdgepointArraySize > 0 || gus2ndEastEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_EAST;
}
break;
case INSERTION_CODE_WEST:
if (gus1stWestEdgepointArraySize > 0 || gus2ndWestEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_WEST;
}
break;
// WANNE - MP: Center
case INSERTION_CODE_CENTER:
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_CENTER;
break;
case INSERTION_CODE_CHOPPER:
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_CHOPPER;
break;
}
// Find alternate insertion direction by looping through all directions (N, S, E, W)
if (!foundValidDirection)
{
UINT8 direction = 0;
// Find NEXT valid direction
for (int i = currentInsertionPoint; (i < currentInsertionPoint + 4); i++)
{
// First iteration, start with current insertion direction
if (i == currentInsertionPoint)
direction = i;
else
{
if (i <= 3)
direction = i;
else
{
direction = 4 - i;
}
}
switch (direction)
{
case INSERTION_CODE_NORTH:
if (gus1stNorthEdgepointArraySize > 0 || gus2ndNorthEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_NORTH;
}
break;
case INSERTION_CODE_SOUTH:
if (gus1stSouthEdgepointArraySize > 0 || gus2ndSouthEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_SOUTH;
}
break;
case INSERTION_CODE_EAST:
if (gus1stEastEdgepointArraySize > 0 || gus2ndEastEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_EAST;
}
break;
case INSERTION_CODE_WEST:
if (gus1stWestEdgepointArraySize > 0 || gus2ndWestEdgepointArraySize > 0)
{
foundValidDirection = true;
validInsertionDirection = INSERTION_CODE_WEST;
}
break;
}
// Exit loop condition
if (foundValidDirection)
break;
}
}
return validInsertionDirection;
}
static void DisableFaceMouseRegions()
{
for ( size_t i = 0; i < giPlacements; i++ )
{
MSYS_DisableRegion( &gMercPlacement[i].region );
}
}
void RenderTacticalPlacementGUI()
{
INT32 i, xp, yp, width, height;
INT32 iStartY;
SOLDIERTYPE *pSoldier;
UINT32 uiDestPitchBYTES;
UINT16 usHatchColor;
CHAR16 str[ 128 ];
UINT8 *pDestBuf;
UINT8 ubColor;
const UINT8 maxFaces = MaxRenderedFaces();
if( gfTacticalPlacementFirstTime )
{
gfTacticalPlacementFirstTime = FALSE;
DisableScrollMessages();
}
EnableDisableTacticalPlacementScrollButtonsAndRegions();
//Check to make sure that if we have a hilighted merc (not selected) and the mouse has moved out
//of it's region, then we will clear the hilighted ID, and refresh the display.
if( !gfTacticalPlacementGUIDirty && gbHilightedMercID != -1 )
{
// Shift the index so we render the faces at the right locations
UINT8 highlightedMercIndex = gbHilightedMercID - gfirstMercIndex;
xp = xResOffset + 91 + (highlightedMercIndex / 2) * 54;
if ( highlightedMercIndex % 2)
{
yp = SCREEN_HEIGHT - 71;
}
else
{
yp = SCREEN_HEIGHT - 122;
}
//yp = (gbHilightedMercID % 2) ? 412 : 361;
if( gusMouseXPos < xp || gusMouseXPos > xp + 54 || gusMouseYPos < yp || gusMouseYPos > yp + 62 )
{
gbHilightedMercID = -1;
gubHilightedGroupID = 0;
SetCursorMerc( gbSelectedMercID );
gpTacticalPlacementHilightedSoldier = NULL;
}
}
//If the display is dirty render the entire panel.
if( gfTacticalPlacementGUIDirty )
{
BltVideoObjectFromIndex( FRAME_BUFFER, giOverheadPanelImage, 0, xResOffset, SCREEN_HEIGHT - 160, VO_BLT_SRCTRANSPARENCY, 0 );
InvalidateRegion( 0 + xResOffset, SCREEN_HEIGHT - 160, SCREEN_WIDTH, SCREEN_HEIGHT );
gfTacticalPlacementGUIDirty = FALSE;
MarkButtonsDirty();
//DisableHilightsAndHelpText();
//RenderButtons();
//EnableHilightsAndHelpText();
DisableFaceMouseRegions();
UINT8 end = min(giPlacements, gfirstMercIndex + maxFaces);
for( UINT8 j = gfirstMercIndex; j < end; ++j )
{
//Render the mercs
pSoldier = gMercPlacement[ j ].pSoldier;
// Shift the index so we render the faces at the right locations
i = j - gfirstMercIndex;
xp = xResOffset + 95 + (i / 2) * 54;
if (i % 2)
{
yp = SCREEN_HEIGHT - 61;
}
else
{
yp = SCREEN_HEIGHT - 112;
}
// Shift the mouse region as well
gMercPlacement[j].region.RegionTopLeftX = xp;
gMercPlacement[j].region.RegionTopLeftY = yp;
gMercPlacement[j].region.RegionBottomRightX = xp + 54;
gMercPlacement[j].region.RegionBottomRightY = yp + 51;
MSYS_EnableRegion( &gMercPlacement[j].region );
//yp = (i % 2) ? 422 : 371;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, yp+2, xp+44, yp+30, 0 );
BltVideoObjectFromIndex( FRAME_BUFFER, giMercPanelImage, 0, xp, yp, VO_BLT_SRCTRANSPARENCY, NULL );
BltVideoObjectFromIndex( FRAME_BUFFER, gMercPlacement[ j ].uiVObjectID, 0, xp+2, yp+2, VO_BLT_SRCTRANSPARENCY, NULL );
//HEALTH BAR
if( !pSoldier->stats.bLife )
continue;
//yellow one for bleeding
iStartY = yp + 29 - 27*pSoldier->stats.bLifeMax/100;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 107, 107, 57 ) ) );
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 222, 181, 115 ) ) );
//pink one for bandaged.
iStartY = yp + 29 - 27*(pSoldier->stats.bLifeMax - pSoldier->bBleeding)/100;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 156, 57, 57 ) ) );
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 222, 132, 132 ) ) );
//red one for actual health
iStartY = yp + 29 - 27*pSoldier->stats.bLife/100;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+36, iStartY, xp+37, yp+29, Get16BPPColor( FROMRGB( 107, 8, 8 ) ) );
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+37, iStartY, xp+38, yp+29, Get16BPPColor( FROMRGB( 206, 0, 0 ) ) );
//BREATH BAR
iStartY = yp + 29 - 27*pSoldier->bBreathMax/100;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+39, iStartY, xp+40, yp+29, Get16BPPColor( FROMRGB( 8, 8, 132 ) ) );
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+40, iStartY, xp+41, yp+29, Get16BPPColor( FROMRGB( 8, 8, 107 ) ) );
//MORALE BAR
iStartY = yp + 29 - 27*pSoldier->aiData.bMorale/100;
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+42, iStartY, xp+43, yp+29, Get16BPPColor( FROMRGB( 8, 156, 8 ) ) );
ColorFillVideoSurfaceArea( FRAME_BUFFER, xp+43, iStartY, xp+44, yp+29, Get16BPPColor( FROMRGB( 8, 107, 8 ) ) );
}
SetFont( BLOCKFONT );
SetFontForeground( FONT_BEIGE );
SetFontShadow( 141 );
GetSectorIDString( gubPBSectorX, gubPBSectorY, gubPBSectorZ, str, TRUE );
mprintf(120 + xResOffset, SCREEN_HEIGHT - 145, L"%s %s -- %s...", gpStrategicString[ STR_TP_SECTOR ], str, gpStrategicString[ STR_TP_CHOOSEENTRYPOSITIONS ] );
//Shade out the part of the tactical map that isn't considered placable.
BlitBufferToBuffer(FRAME_BUFFER, guiSAVEBUFFER, 0, SCREEN_HEIGHT - 160, SCREEN_WIDTH, 160);
DisplayTacticalPlacementSlider();
}
if( gfValidLocationsChanged )
{
if( DayTime() )
{ //6AM to 9PM is black
usHatchColor = 0; //Black
}
else
{ //9PM to 6AM is gray (black is too dark to distinguish)
usHatchColor = Get16BPPColor( FROMRGB( 63, 31, 31 ) );
}
--gfValidLocationsChanged;
//DBrot bigger map code
if(gfUseBiggerOverview)
{
BlitBufferToBuffer( guiSAVEBUFFER, FRAME_BUFFER, iOffsetHorizontal, iOffsetVertical, 1434, 716 );
InvalidateRegion( iOffsetHorizontal, iOffsetVertical, iOffsetHorizontal + 1434, iOffsetVertical + 716 );
gTPClipRect.iLeft = iOffsetHorizontal + 1;
gTPClipRect.iTop = iOffsetVertical + 1;
gTPClipRect.iBottom = iOffsetVertical + 716;// 318;
gTPClipRect.iRight = iOffsetHorizontal + 1434; //634;
}
else
{
BlitBufferToBuffer( guiSAVEBUFFER, FRAME_BUFFER, iOffsetHorizontal, iOffsetVertical, 640, 320 );
InvalidateRegion( iOffsetHorizontal, iOffsetVertical, iOffsetHorizontal + 640, iOffsetVertical + 320 );
//dnl ch45 051009
gTPClipRect.iLeft = iOffsetHorizontal + 1;
gTPClipRect.iTop = iOffsetVertical + 1;
gTPClipRect.iBottom = iOffsetVertical + 318;
gTPClipRect.iRight = iOffsetHorizontal + 634;
}
if( gbCursorMercID == -1 )
{
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE || (gfCenter && gGameExternalOptions.ubSkyriderHotLZ == 1))
{
INT16 sCellX = 0;
INT16 sCellY = 0;
GetOverheadScreenXYFromGridNo( gMapInformation.sCenterGridNo, &sCellX, &sCellY );
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + sCellX - 5 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + sCellY - 3 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + sCellX + 5 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + sCellY + 3 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
// WANNE - MP: Center
else if (is_networked && gfCenter)
{
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + CENTERENTRYPTS_LEFT_X;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + CENTERENTRYPTS_TOP_Y;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + CENTERENTRYPTS_RIGHT_X;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + CENTERENTRYPTS_BOTTOM_Y;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
// Flugente airdrop
else if ( gfCenter && gGameExternalOptions.ubSkyriderHotLZ == 3 )
{
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + AIRDROPENTRYPTS_LEFT_X;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + AIRDROPENTRYPTS_TOP_Y;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + AIRDROPENTRYPTS_RIGHT_X;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + AIRDROPENTRYPTS_BOTTOM_Y;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
}
else
{
if (is_networked)
{
gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode = GetValidInsertionDirectionForMP(gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode);
}
//dnl ch45 051009
INT16 sWorldScreenX, sX;
INT16 sWorldScreenY, sY;
sX = giXA;
sY = giYA;
GetWorldXYAbsoluteScreenXY(sX, sY, &sWorldScreenX, &sWorldScreenY);
sWorldScreenX += 20;// Correction from invisible area X
sWorldScreenY += 35;// Correction from invisible area Y
//DBrot: adjust offsets for big maps
if(gfUseBiggerOverview)
{
switch(gMercPlacement[gbCursorMercID].ubStrategicInsertionCode)
{
case INSERTION_CODE_NORTH:
//if(sWorldScreenY <= PLACEMENT_OFFSET){
//sY = (PLACEMENT_OFFSET - sWorldScreenY) / 5;
//gTPClipRect.iTop += sY;
gTPClipRect.iTop += PLACEMENT_OFFSET/5;
//}
break;
case INSERTION_CODE_EAST:
//if((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) >= (MAPWIDTH - PLACEMENT_OFFSET)){
//sX = ((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) - (MAPWIDTH - PLACEMENT_OFFSET)) / 5;
//gTPClipRect.iRight -= sX;
gTPClipRect.iRight -= PLACEMENT_OFFSET/5;
//}
break;
case INSERTION_CODE_SOUTH:
//if((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) >= (MAPHEIGHT - PLACEMENT_OFFSET)){
//sY = ((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) - (MAPHEIGHT - PLACEMENT_OFFSET)) / 5;
//gTPClipRect.iBottom -= sY;
gTPClipRect.iBottom -= PLACEMENT_OFFSET/5;
//}
break;
case INSERTION_CODE_WEST:
//if(sWorldScreenX <= PLACEMENT_OFFSET){
//sX = (PLACEMENT_OFFSET - sWorldScreenX) / 5;
//gTPClipRect.iLeft += sX;
gTPClipRect.iLeft += PLACEMENT_OFFSET/5;
//}
break;
}
}
else
{
switch(gMercPlacement[gbCursorMercID].ubStrategicInsertionCode)
{
case INSERTION_CODE_NORTH:
if(sWorldScreenY <= PLACEMENT_OFFSET)
{
sY = (PLACEMENT_OFFSET - sWorldScreenY) / 5;
sY += RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_NORTH)/5;
gTPClipRect.iTop += sY;
}
break;
case INSERTION_CODE_EAST:
if((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) >= (MAPWIDTH - PLACEMENT_OFFSET))
{
sX = ((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) - (MAPWIDTH - PLACEMENT_OFFSET)) / 5;
sX += RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_EAST)/5;
gTPClipRect.iRight -= sX;
}
break;
case INSERTION_CODE_SOUTH:
if((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) >= (MAPHEIGHT - PLACEMENT_OFFSET))
{
sY = ((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) - (MAPHEIGHT - PLACEMENT_OFFSET)) / 5;
sY += RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_SOUTH)/5;
gTPClipRect.iBottom -= sY;
}
break;
case INSERTION_CODE_WEST:
if(sWorldScreenX <= PLACEMENT_OFFSET)
{
sX = (PLACEMENT_OFFSET - sWorldScreenX) / 5;
sX += RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_WEST)/5;
gTPClipRect.iLeft += sX;
}
break;
}
}
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE || (gfCenter && gGameExternalOptions.ubSkyriderHotLZ == 1 && gbSelectedMercID >= 0 && gMercPlacement[gbSelectedMercID].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP))
{
INT16 sCellX = 0;
INT16 sCellY = 0;
GetOverheadScreenXYFromGridNo( gMapInformation.sCenterGridNo, &sCellX, &sCellY );
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + sCellX - 5 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + sCellY - 3 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + sCellX + 5 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + sCellY + 3 * gGameExternalOptions.usAmbushSpreadRadiusMercs;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
// WANNE - MP: Center
else if (is_networked && gfCenter)
{
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + CENTERENTRYPTS_LEFT_X;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + CENTERENTRYPTS_TOP_Y;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + CENTERENTRYPTS_RIGHT_X;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + CENTERENTRYPTS_BOTTOM_Y;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
// Flugente airdrop
else if ( gfCenter && gGameExternalOptions.ubSkyriderHotLZ == 3 && gbSelectedMercID >= 0 && gMercPlacement[ gbSelectedMercID ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
{
// Left black border
gTPClipRectCenterLeft.iLeft = iOffsetHorizontal;
gTPClipRectCenterLeft.iTop = iOffsetVertical + 3;
gTPClipRectCenterLeft.iBottom = iOffsetVertical + 320;
gTPClipRectCenterLeft.iRight = iOffsetHorizontal + AIRDROPENTRYPTS_LEFT_X;
// Top black border
gTPClipRectCenterTop.iLeft = iOffsetHorizontal;
gTPClipRectCenterTop.iTop = iOffsetVertical + 3;
gTPClipRectCenterTop.iBottom = iOffsetVertical + AIRDROPENTRYPTS_TOP_Y;
gTPClipRectCenterTop.iRight = iOffsetHorizontal + 634;
// Right black border
gTPClipRectCenterRight.iLeft = iOffsetHorizontal + AIRDROPENTRYPTS_RIGHT_X;
gTPClipRectCenterRight.iTop = iOffsetVertical + 3;
gTPClipRectCenterRight.iBottom = iOffsetVertical + 320;
gTPClipRectCenterRight.iRight = iOffsetHorizontal + 634;
// Bottom black border
gTPClipRectCenterBottom.iLeft = iOffsetHorizontal;
gTPClipRectCenterBottom.iTop = iOffsetVertical + AIRDROPENTRYPTS_BOTTOM_Y;
gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320;
gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634;
}
}
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
if (!gfCenter || ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gbSelectedMercID >= 0 && !(gMercPlacement[ gbSelectedMercID ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP)) )
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &gTPClipRect, usHatchColor );
// WANNE - MP: Center
else
{
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &gTPClipRectCenterLeft, usHatchColor );
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &gTPClipRectCenterTop, usHatchColor );
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &gTPClipRectCenterRight, usHatchColor );
Blt16BPPBufferLooseHatchRectWithColor( (UINT16*)pDestBuf, uiDestPitchBYTES, &gTPClipRectCenterBottom, usHatchColor );
}
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
if (!gfCenter || ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gbSelectedMercID >= 0 && !(gMercPlacement[ gbSelectedMercID ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP)) )
RectangleDraw( TRUE, gTPClipRect.iLeft, gTPClipRect.iTop, gTPClipRect.iRight, gTPClipRect.iBottom, usHatchColor, pDestBuf );
else
{
RectangleDraw( TRUE, gTPClipRectCenterLeft.iLeft, gTPClipRectCenterLeft.iTop, gTPClipRectCenterLeft.iRight, gTPClipRectCenterLeft.iBottom, usHatchColor, pDestBuf );
RectangleDraw( TRUE, gTPClipRectCenterTop.iLeft, gTPClipRectCenterTop.iTop, gTPClipRectCenterTop.iRight, gTPClipRectCenterTop.iBottom, usHatchColor, pDestBuf );
RectangleDraw( TRUE, gTPClipRectCenterRight.iLeft, gTPClipRectCenterRight.iTop, gTPClipRectCenterRight.iRight, gTPClipRectCenterRight.iBottom, usHatchColor, pDestBuf );
RectangleDraw( TRUE, gTPClipRectCenterBottom.iLeft, gTPClipRectCenterBottom.iTop, gTPClipRectCenterBottom.iRight, gTPClipRectCenterBottom.iBottom, usHatchColor, pDestBuf );
}
UnLockVideoSurface( FRAME_BUFFER );
}
UINT8 end = min( giPlacements, gfirstMercIndex + maxFaces );
for ( UINT8 j = gfirstMercIndex; j < end; ++j )
{
//Render the mercs
pSoldier = gMercPlacement[j].pSoldier;
// Shift the index so we render the faces at the right locations
i = j - gfirstMercIndex;
xp = xResOffset + 95 + (i / 2) * 54;
if (i % 2)
{
yp = SCREEN_HEIGHT - 61;
}
else
{
yp = SCREEN_HEIGHT - 112;
}
//yp = (i % 2) ? 422 : 371;
//NAME
if( gubDefaultButton == GROUP_BUTTON && gMercPlacement[ j ].pSoldier->ubGroupID == gubSelectedGroupID ||
gubDefaultButton != GROUP_BUTTON && j == gbSelectedMercID )
{
ubColor = FONT_YELLOW;
}
else if( gubDefaultButton == GROUP_BUTTON && gMercPlacement[ j ].pSoldier->ubGroupID == gubHilightedGroupID ||
gubDefaultButton != GROUP_BUTTON && j == gbHilightedMercID )
{
ubColor = FONT_WHITE;
}
else
{
ubColor = FONT_GRAY3;
}
SetFont( FONT10ARIALBOLD );
SetFontForeground( ubColor );
SetFontShadow( 141 );
//Render the question mark over the face if the merc hasn't yet been placed.
if( gMercPlacement[ j ].fPlaced )
{
RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, (INT16)(xp + 16), (INT16)(yp + 14), (INT16)(xp + 24), (INT16)(yp + 22) );
}
else
{
mprintf( xp + 16, yp + 14, L"?" );
InvalidateRegion( xp + 16, yp + 14, xp + 24, yp + 22 );
}
SetFont( BLOCKFONT );
width = StringPixLength( pSoldier->name, BLOCKFONT );
height = GetFontHeight( BLOCKFONT );
xp = xp + ( 48 - width ) / 2;
yp = yp + 33;
mprintf( xp, yp, pSoldier->name );
InvalidateRegion( xp, yp, xp + width, yp + width );
}
}
static void EnsureDoneButtonStatus()
{
INT32 i;
//static BOOLEAN fInside = FALSE;
//BOOLEAN fChanged = FALSE;
for( i = 0; i < giPlacements; i++ )
{
if( !gMercPlacement[ i ].fPlaced )
{
if( ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED )
{
DisableButton( iTPButtons[ DONE_BUTTON ] );
SetButtonFastHelpText( iTPButtons[ DONE_BUTTON ], gpStrategicString[ STR_TP_DISABLED_DONEHELP ] );
}
return;
}
}
if( !(ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) )
{ //only enable it when it is disabled, otherwise the button will stay down!
EnableButton( iTPButtons[ DONE_BUTTON ] );
SetButtonFastHelpText( iTPButtons[ DONE_BUTTON ], gpStrategicString[ STR_TP_DONEHELP ] );
}
}
void lockui (bool unlock) //lock onluck ui for lan //hayden
{
if(unlock==0 && islocked==0 && is_client)
{
islocked=1;
DisableButton( iTPButtons[ DONE_BUTTON ] );
DisableButton( iTPButtons[ SPREAD_BUTTON ] );
DisableButton( iTPButtons[ GROUP_BUTTON ] );
DisableButton( iTPButtons[ CLEAR_BUTTON ] );
SGPRect CenterRect = { 100 + xResOffset, 100, SCREEN_WIDTH - 100 - xResOffset, 300 };
DoMessageBox( MSG_BOX_BASIC_STYLE, MPServerMessage[8], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, DialogRemoved, &CenterRect );
//send loaded
send_loaded();
}
if(unlock) //oh yeah ! :)
{
islocked=3;
EnableButton( iTPButtons[ SPREAD_BUTTON ] );
EnableButton( iTPButtons[ GROUP_BUTTON ] );
EnableButton( iTPButtons[ CLEAR_BUTTON ] );
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_DIRTY;
gubDefaultButton = CLEAR_BUTTON;
PlaceMercs();
gMsgBox.bHandled = MSG_BOX_RETURN_OK; //close if still open
}
}
static void HandleMouseWheelScroll( void )
{
// Scroll through pages with regular mouse wheel
SGPPoint MousePos;
GetMousePos( &MousePos );
const auto x = MousePos.iX;
const auto y = MousePos.iY;
if ( (gFacePanelXStart < x && x < gFacePanelXEnd) && (gFacePanelYStart < y && y < gFacePanelYEnd) )
{
const auto Wheelstate = _WheelValue * (gGameSettings.fOptions[TOPTION_INVERT_WHEEL] ? -1 : 1);
if ( Wheelstate < 0 )
{
IncreaseMercIndex();
}
else if ( Wheelstate > 0 )
{
DecreaseMercIndex();
}
_WheelValue = 0;
}
}
void TacticalPlacementHandle()
{
InputAtom InputEvent;
EnsureDoneButtonStatus();
RenderTacticalPlacementGUI();
if (is_networked)
lockui(0);//lockui before placement while clients loading //hayden
if( gfRightButtonState )
{
gbSelectedMercID = -1;
gubSelectedGroupID = 0;
gpTacticalPlacementSelectedSoldier = NULL;
}
while (DequeueEvent(&InputEvent) == TRUE)
{
if( InputEvent.usEvent == KEY_DOWN )
{
switch( InputEvent.usParam )
{
#ifdef JA2TESTVERSION
case ESC:
//if (!is_networked)
KillTacticalPlacementGUI();
break;
#endif
case ENTER:
if( ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED )
{
if(!is_client)KillTacticalPlacementGUI();
if(is_client)send_donegui(0);
}
break;
case 'c':
if(islocked!=1)ClearPlacementsCallback( ButtonList[ iTPButtons[ CLEAR_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP );
break;
case 'g':
if(islocked!=1)GroupPlacementsCallback( ButtonList[ iTPButtons[ GROUP_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP );
break;
case 's':
if(islocked!=1 && ButtonList[iTPButtons[SPREAD_BUTTON]]->uiFlags & BUTTON_ENABLED) SpreadPlacementsCallback( ButtonList[ iTPButtons[ SPREAD_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP );
break;
case 'x':
if( InputEvent.usKeyState & ALT_DOWN )
{
HandleShortCutExitState();
}
break;
}
}
}
gfValidCursor = FALSE;
if(gbSelectedMercID != -1 && ((gusMouseYPos < (iOffsetVertical + 320) && gusMouseYPos > iOffsetVertical && gusMouseXPos > iOffsetHorizontal && gusMouseXPos < (iOffsetHorizontal + 640))||(gfUseBiggerOverview && (gusMouseYPos < (iOffsetVertical + 716) && gusMouseYPos > iOffsetVertical && gusMouseXPos > iOffsetHorizontal && gusMouseXPos < (iOffsetHorizontal + 1432) ))))
{
//dnl ch45 051009
INT16 sWorldScreenX = (gusMouseXPos - iOffsetHorizontal) * 5;
INT16 sWorldScreenY = (gusMouseYPos - iOffsetVertical) * 5;
INT32 iCellX, iCellY;
GetFromAbsoluteScreenXYWorldXY(&iCellX, &iCellY, sWorldScreenX, sWorldScreenY);
iCellX = (iCellX / CELL_X_SIZE) + (giXA - 0);
iCellY = (iCellY / CELL_Y_SIZE) + (giYA - WORLD_ROWS/2);
GetWorldXYAbsoluteScreenXY(iCellX, iCellY, &sWorldScreenX, &sWorldScreenY);
switch(gMercPlacement[gbCursorMercID].ubStrategicInsertionCode)
{
case INSERTION_CODE_NORTH:
if(sWorldScreenY <= (PLACEMENT_OFFSET + RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_NORTH)))
gfValidCursor = TRUE;
break;
case INSERTION_CODE_EAST:
if(sWorldScreenX >= ((MAPWIDTH - PLACEMENT_OFFSET - RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_EAST))))
gfValidCursor = TRUE;
break;
case INSERTION_CODE_SOUTH:
if(sWorldScreenY >= ((MAPHEIGHT - PLACEMENT_OFFSET - RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_SOUTH))))
gfValidCursor = TRUE;
break;
case INSERTION_CODE_WEST:
if(sWorldScreenX <= (PLACEMENT_OFFSET + RebelCommand::GetAdditionalDeployRange(INSERTION_CODE_WEST)))
gfValidCursor = TRUE;
break;
}
// WANNE - MP: Center
if ( gfCenter && (is_networked ||
GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE ||
((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gMercPlacement[gbSelectedMercID].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )) )
{
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE )
{
INT32 testgridno = NOWHERE;
if ( GetOverheadMouseGridNo( &testgridno ) && PythSpacesAway( testgridno, gMapInformation.sCenterGridNo ) < gGameExternalOptions.usAmbushSpreadRadiusMercs )
{
gfValidCursor = TRUE;
}
}
else if( gMercPlacement[gbCursorMercID].ubStrategicInsertionCode == INSERTION_CODE_CENTER || (gGameExternalOptions.ubSkyriderHotLZ == 1 && gMercPlacement[gbCursorMercID].ubStrategicInsertionCode == INSERTION_CODE_CHOPPER))
{
if (gusMouseYPos >= (iOffsetVertical + CENTERENTRYPTS_TOP_Y) && // N
gusMouseYPos <= (iOffsetVertical + CENTERENTRYPTS_BOTTOM_Y) && // S
gusMouseXPos >= (iOffsetHorizontal + CENTERENTRYPTS_LEFT_X) && // W
gusMouseXPos <= (iOffsetHorizontal + CENTERENTRYPTS_RIGHT_X)) // E
{
gfValidCursor = TRUE;
}
}
else if ( gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode == INSERTION_CODE_CHOPPER )
{
if (gusMouseYPos >= (iOffsetVertical + AIRDROPENTRYPTS_TOP_Y) && // N
gusMouseYPos <= (iOffsetVertical + AIRDROPENTRYPTS_BOTTOM_Y) && // S
gusMouseXPos >= (iOffsetHorizontal + AIRDROPENTRYPTS_LEFT_X) && // W
gusMouseXPos <= (iOffsetHorizontal + AIRDROPENTRYPTS_RIGHT_X)) // E
{
gfValidCursor = TRUE;
}
}
}
if( gubDefaultButton == GROUP_BUTTON )
{
if( gfValidCursor )
{
SetCurrentCursorFromDatabase( CURSOR_PLACEGROUP );
}
else
{
SetCurrentCursorFromDatabase( CURSOR_DPLACEGROUP );
}
}
else
{
if( gfValidCursor )
{
SetCurrentCursorFromDatabase( CURSOR_PLACEMERC );
}
else
{
SetCurrentCursorFromDatabase( CURSOR_DPLACEMERC );
}
}
}
else
{
SetCurrentCursorFromDatabase( CURSOR_NORMAL );
}
if( gfKillTacticalGUI == 1 )
{
if(is_client)
{
gfKillTacticalGUI = FALSE;
send_donegui(0);
}
if(!is_client)KillTacticalPlacementGUI();
}
else if( gfKillTacticalGUI == 2 )
{
gfKillTacticalGUI = 1;
}
ScrollOverheadMap();//dnl ch45 021009
HandleMouseWheelScroll();
}
void KillTacticalPlacementGUI()
{
INT32 i;
gbHilightedMercID = -1;
gbSelectedMercID = -1;
gubSelectedGroupID = 0;
gubHilightedGroupID = 0;
gbCursorMercID = -1;
gpTacticalPlacementHilightedSoldier = NULL;
gpTacticalPlacementSelectedSoldier = NULL;
//Destroy the tactical placement gui.
gfEnterTacticalPlacementGUI = FALSE;
gfTacticalPlacementGUIActive = FALSE;
gfKillTacticalGUI = FALSE;
//Delete video objects
DeleteVideoObjectFromIndex( giOverheadPanelImage );
DeleteVideoObjectFromIndex( giMercPanelImage );
//Delete buttons
for( i = 0; i < NUM_TP_BUTTONS; i++ )
{
UnloadButtonImage( giOverheadButtonImages[ i ] );
RemoveButton( iTPButtons[ i ] );
}
//Delete faces and regions
for( i = 0; i < giPlacements; i++ )
{
DeleteVideoObjectFromIndex( gMercPlacement[ i ].uiVObjectID );
MSYS_RemoveRegion( &gMercPlacement[ i ].region );
}
for ( size_t i = 0; i < 2; i++ )
{
UnloadButtonImage( gTacticalPlacementGUIPrevNextButtonImages[i] );
RemoveButton( gTacticalPlacementGUIPrevNextButtons[i] );
}
MSYS_RemoveRegion( &gTacticalPlacementGUISliderBarRegion );
DeleteVideoObjectFromIndex( gTacticalPlacementGUISliderBar );
DeleteVideoObjectFromIndex( gScrollAreaGfx );
if( gsCurInterfacePanel < 0 || gsCurInterfacePanel >= NUM_UI_PANELS )
gsCurInterfacePanel = TEAM_PANEL;
SetCurrentInterfacePanel( (UINT8)gsCurInterfacePanel );
//Leave the overhead map.
KillOverheadMap();
//Recreate the tactical panel.
MSYS_EnableRegion(&gRadarRegion);
SetCurrentInterfacePanel( TEAM_PANEL );
//Initialize the rest of the map (AI, enemies, civs, etc.)
for( i = 0; i < giPlacements; i++ )
{
PickUpMercPiece( i );
}
PrepareLoadedSector();
EnableScrollMessages();
#ifdef JA2BETAVERSION
if( gfChangedEntrySide )
{
ScreenMsg( FONT_RED, MSG_ERROR, L"Substituted different entry side due to invalid entry points or map edgepoints. KM, LC : 1" );
}
#endif
MemFree( gMercPlacement);
}
static void ChooseRandomEdgepoints()
{
INT32 i;
UINT8 lastValidICode = INSERTION_CODE_GRIDNO;
for( i = 0; i < giPlacements; i++ )
{
if ( !( gMercPlacement[ i ].pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
{
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE )
{
UINT8 ubDirection;
gMercPlacement[i].pSoldier->usStrategicInsertionData = FindRandomGridNoFromSweetSpotExcludingSweetSpot( gMercPlacement[i].pSoldier, gMapInformation.sCenterGridNo, gGameExternalOptions.usAmbushSpreadRadiusMercs, &ubDirection );
// have the merc look outward. We add + 100 because later on we use this to signify that we want really enforce this direction
gMercPlacement[i].pSoldier->ubInsertionDirection = (UINT8)GetDirectionToGridNoFromGridNo( gMapInformation.sCenterGridNo, gMercPlacement[i].pSoldier->usStrategicInsertionData ) + 100;
}
else
{
gMercPlacement[ i ].pSoldier->usStrategicInsertionData = ChooseMapEdgepoint( &gMercPlacement[ i ].ubStrategicInsertionCode, lastValidICode );
}
if( !TileIsOutOfBounds(gMercPlacement[ i ].pSoldier->usStrategicInsertionData))
{
gMercPlacement[ i ].pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
lastValidICode = gMercPlacement[ i ].ubStrategicInsertionCode;
}
else
{
gMercPlacement[ i ].pSoldier->ubStrategicInsertionCode = gMercPlacement[ i ].ubStrategicInsertionCode;
}
}
PutDownMercPiece( i );
}
gfEveryonePlaced = TRUE;
}
void PlaceMercs()
{
INT32 i;
switch( gubDefaultButton )
{
case SPREAD_BUTTON: //Place mercs randomly along their side using map edgepoints.
ChooseRandomEdgepoints();
break;
case CLEAR_BUTTON:
for( i = 0; i < giPlacements; i++ )
{
PickUpMercPiece( i );
}
if (ButtonList[iTPButtons[SPREAD_BUTTON]]->uiFlags & BUTTON_ENABLED)
{
gubSelectedGroupID = 0;
gbSelectedMercID = 0;
SetCursorMerc(0);
}
else//spread button disabled mean hotdrop
{
gubSelectedGroupID = gMercPlacement[0].pSoldier->ubGroupID;
ButtonList[iTPButtons[GROUP_BUTTON]]->uiFlags |= BUTTON_CLICKED_ON | BUTTON_DIRTY;
gubDefaultButton = GROUP_BUTTON;
gbSelectedMercID = 0;
SetCursorMerc(gbSelectedMercID);
}
gfEveryonePlaced = FALSE;
break;
default:
return;
}
gfTacticalPlacementGUIDirty = TRUE;
}
void DoneOverheadPlacementClickCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
gfKillTacticalGUI = 2;
}
}
void SpreadPlacementsCallback ( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
gubDefaultButton = SPREAD_BUTTON;
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_DIRTY;
PlaceMercs();
gubSelectedGroupID = 0;
gbSelectedMercID = -1;
SetCursorMerc( -1 );
}
}
void GroupPlacementsCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
if( gubDefaultButton == GROUP_BUTTON )
{
btn->uiFlags &= ~BUTTON_CLICKED_ON;
btn->uiFlags |= BUTTON_DIRTY;
if (ButtonList[iTPButtons[SPREAD_BUTTON]]->uiFlags & BUTTON_ENABLED)
{
gubDefaultButton = CLEAR_BUTTON;
gubSelectedGroupID = 0;
}
else//spread button disabled mean hotdrop
{
gubDefaultButton = CLEAR_BUTTON;
gubSelectedGroupID = 0;
gbSelectedMercID = -1;
SetCursorMerc(gbSelectedMercID);
}
}
else
{
btn->uiFlags |= BUTTON_CLICKED_ON | BUTTON_DIRTY;
gubDefaultButton = GROUP_BUTTON;
gbSelectedMercID = 0;
SetCursorMerc( gbSelectedMercID );
gubSelectedGroupID = gMercPlacement[ gbSelectedMercID ].pSoldier->ubGroupID;
}
}
}
void ClearPlacementsCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_DIRTY;
gubDefaultButton = CLEAR_BUTTON;
PlaceMercs();
}
}
void MercMoveCallback( MOUSE_REGION *reg, INT32 reason )
{
if( reg->uiFlags & MSYS_MOUSE_IN_AREA )
{
INT8 i;
for( i = 0; i < giPlacements; i++ )
{
if( &gMercPlacement[ i ].region == reg )
{
if( gbHilightedMercID != i )
{
gbHilightedMercID = i;
if( gubDefaultButton == GROUP_BUTTON )
gubHilightedGroupID = gMercPlacement[ i ].pSoldier->ubGroupID;
SetCursorMerc( i );
gpTacticalPlacementHilightedSoldier = gMercPlacement[ i ].pSoldier;
}
return;
}
}
}
}
void MercClickCallback( MOUSE_REGION *reg, INT32 reason )
{
if(islocked != 1)//hayden
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
INT8 i;
for( i = 0; i < giPlacements; i++ )
{
if( &gMercPlacement[ i ].region == reg )
{
if( gbSelectedMercID != i )
{
if ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gMercPlacement[ i ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
gubDefaultButton = GROUP_BUTTON;
gbSelectedMercID = i;
gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier;
if( gubDefaultButton == GROUP_BUTTON )
{
gubSelectedGroupID = gpTacticalPlacementSelectedSoldier->ubGroupID;
}
}
return;
}
}
}
}
}
void SelectNextUnplacedUnit()
{
INT32 i;
if( gbSelectedMercID == -1 )
return;
if ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gMercPlacement[ gbSelectedMercID ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
gubDefaultButton = GROUP_BUTTON;
for( i = gbSelectedMercID; i < giPlacements; ++i )
{ //go from the currently selected soldier to the end
if( !gMercPlacement[ i ].fPlaced )
{ //Found an unplaced merc. Select him.
gbSelectedMercID = (INT8)i;
if( gubDefaultButton == GROUP_BUTTON )
gubSelectedGroupID = gMercPlacement[ i ].pSoldier->ubGroupID;
gfTacticalPlacementGUIDirty = TRUE;
SetCursorMerc( (INT8)i );
gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier;
return;
}
}
for( i = 0; i < gbSelectedMercID; ++i )
{ //go from the beginning to the currently selected soldier
if( !gMercPlacement[ i ].fPlaced )
{ //Found an unplaced merc. Select him.
gbSelectedMercID = (INT8)i;
if( gubDefaultButton == GROUP_BUTTON )
gubSelectedGroupID = gMercPlacement[ i ].pSoldier->ubGroupID;
gfTacticalPlacementGUIDirty = TRUE;
SetCursorMerc( (INT8)i );
gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier;
return;
}
}
//checked the whole array, and everybody has been placed. Select nobody.
if( !gfEveryonePlaced )
{
gfEveryonePlaced = TRUE;
SetCursorMerc( -1 );
gbSelectedMercID = -1;
gubSelectedGroupID = 0;
gfTacticalPlacementGUIDirty = TRUE;
gfValidLocationsChanged = TRUE;
gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier;
}
}
void HandleTacticalPlacementClicksInOverheadMap( MOUSE_REGION *reg, INT32 reason )
{
INT32 i;
INT32 sGridNo;
BOOLEAN fInvalidArea = FALSE;
UINT8 lastValidICode = INSERTION_CODE_GRIDNO;
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{ //if we have a selected merc, move him to the new closest map edgepoint of his side.
if( gfValidCursor )
{
if( gbSelectedMercID != -1 )
{
if ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && gMercPlacement[ gbSelectedMercID ].pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
gubDefaultButton = GROUP_BUTTON;
if( GetOverheadMouseGridNo( &sGridNo ) )
{ //we have clicked within a valid part of the map.
BeginMapEdgepointSearch();
if( gubDefaultButton == GROUP_BUTTON )
{ //We are placing a whole group.
for( i = 0; i < giPlacements; i++ )
{ //Find locations of each member of the group, but don't place them yet. If
//one of the mercs can't be placed, then we won't place any, and tell the user
//the problem. If everything's okay, we will place them all.
if( gMercPlacement[ i ].pSoldier->ubGroupID == gubSelectedGroupID )
{
gMercPlacement[ i ].pSoldier->usStrategicInsertionData = SearchForClosestPrimaryMapEdgepoint( sGridNo, gMercPlacement[ i ].ubStrategicInsertionCode, lastValidICode, &gMercPlacement[ i ].ubStrategicInsertionCode );
if(TileIsOutOfBounds(gMercPlacement[ i ].pSoldier->usStrategicInsertionData))
{
fInvalidArea = TRUE;
break;
}
else
lastValidICode = gMercPlacement[ i ].ubStrategicInsertionCode;
}
}
if( !fInvalidArea )
{ //One or more of the mercs in the group didn't get gridno assignments, so we
//report an error.
for( i = 0; i < giPlacements; i++ )
{
gMercPlacement[ i ].pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
if( gMercPlacement[ i ].pSoldier->ubGroupID == gubSelectedGroupID )
{
PutDownMercPiece( i );
}
}
}
}
else
{ //This is a single merc placement. If valid, then place him, else report error.
gMercPlacement[ gbSelectedMercID ].pSoldier->usStrategicInsertionData = SearchForClosestPrimaryMapEdgepoint( sGridNo, gMercPlacement[ gbSelectedMercID ].ubStrategicInsertionCode );
if( !TileIsOutOfBounds(gMercPlacement[ gbSelectedMercID ].pSoldier->usStrategicInsertionData))
{
gMercPlacement[ gbSelectedMercID ].pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
PutDownMercPiece( gbSelectedMercID );
}
else
{
fInvalidArea = TRUE;
}
//gbSelectedMercID++;
//if( gbSelectedMercID == giPlacements )
// gbSelectedMercID = 0;
//gpTacticalPlacementSelectedSoldier = gMercPlacement[ gbSelectedMercID ].pSoldier;
gfTacticalPlacementGUIDirty = TRUE;
//SetCursorMerc( gbSelectedMercID );
}
EndMapEdgepointSearch();
if( fInvalidArea )
{
// Only display the error message, when the cursor is on the overview map
if (gusMouseYPos < (iOffsetVertical + 320) && gusMouseYPos > iOffsetVertical
&& gusMouseXPos > iOffsetHorizontal && gusMouseXPos < (iOffsetHorizontal + 640))
{
//Report error due to invalid placement.
SGPRect CenterRect = { 100 + xResOffset, 100 + 0, SCREEN_WIDTH - 100 - xResOffset, 300 };
DoMessageBox( MSG_BOX_BASIC_STYLE, gpStrategicString[ STR_TP_INACCESSIBLE_MESSAGE ], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, DialogRemoved, &CenterRect );
}
}
else
{ //Placement successful, so select the next unplaced unit (single or group).
SelectNextUnplacedUnit();
}
}
}
}
else
{ //not a valid cursor location...
if( gbCursorMercID != - 1 )
{
// Only display the error message, when the cursor is on the overview map
if (gusMouseYPos < (iOffsetVertical + 320) && gusMouseYPos > iOffsetVertical
&& gusMouseXPos > iOffsetHorizontal && gusMouseXPos < (iOffsetHorizontal + 640))
{
SGPRect CenterRect = { 100 + xResOffset, 100, SCREEN_WIDTH - 100 - xResOffset, 300 };
DoMessageBox( MSG_BOX_BASIC_STYLE, gpStrategicString[ STR_TP_INVALID_MESSAGE ], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, DialogRemoved, &CenterRect );
}
}
}
}
}
void SetCursorMerc( INT8 bPlacementID )
{
if( gbCursorMercID != bPlacementID )
{
if( gbCursorMercID == -1 || bPlacementID == -1 ||
gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode != gMercPlacement[ bPlacementID ].ubStrategicInsertionCode )
gfValidLocationsChanged = TRUE;
gbCursorMercID = bPlacementID;
}
}
void PutDownMercPiece( INT32 iPlacement )
{
INT32 sGridNo;
INT16 sCellX, sCellY;
UINT8 ubDirection;
SOLDIERTYPE *pSoldier;
pSoldier = gMercPlacement[ iPlacement ].pSoldier;
switch( pSoldier->ubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH:
pSoldier->sInsertionGridNo = gMapInformation.sNorthGridNo;
break;
case INSERTION_CODE_SOUTH:
pSoldier->sInsertionGridNo = gMapInformation.sSouthGridNo;
break;
case INSERTION_CODE_EAST:
pSoldier->sInsertionGridNo = gMapInformation.sEastGridNo;
break;
case INSERTION_CODE_WEST:
pSoldier->sInsertionGridNo = gMapInformation.sWestGridNo;
break;
case INSERTION_CODE_GRIDNO:
pSoldier->sInsertionGridNo = pSoldier->usStrategicInsertionData;
break;
case INSERTION_CODE_CHOPPER:
pSoldier->sInsertionGridNo = pSoldier->usStrategicInsertionData;
break;
default:
Assert( 0 );
break;
}
if( gMercPlacement[ iPlacement ].fPlaced )
PickUpMercPiece( iPlacement );
sGridNo = FindGridNoFromSweetSpot( pSoldier, pSoldier->sInsertionGridNo, 4, &ubDirection );
if(!TileIsOutOfBounds(sGridNo))
{
// Flugente: initiate airdrop, place merc on roof if necessary
if ((gGameExternalOptions.ubSkyriderHotLZ == 1 || gGameExternalOptions.ubSkyriderHotLZ == 3) && pSoldier->usSoldierFlagMask & SOLDIER_AIRDROP )
{
// hideous hack
gfTacticalDoHeliRun = TRUE;
SetHelicopterDroppoint(sGridNo);
pSoldier->usStrategicInsertionData = sGridNo;
if ( FindStructure( sGridNo, STRUCTURE_NORMAL_ROOF ) != NULL && NewOKDestination( pSoldier, sGridNo, false, 1 ) )
{
pSoldier->SetSoldierHeight( (FLOAT)58 );
}
}
ConvertGridNoToCellXY( sGridNo, &sCellX, &sCellY );
FLOAT scX = (FLOAT)sCellX;
FLOAT scY = (FLOAT)sCellY;//hayden
if (is_networked)
{
pSoldier->EVENT_SetSoldierPosition( scX, scY );
}
else
{
pSoldier->EVENT_SetSoldierPosition( (FLOAT)sCellX, (FLOAT)sCellY );
}
if ( GetEnemyEncounterCode() == ENEMY_AMBUSH_DEPLOYMENT_CODE )
{
ubDirection = (UINT8)GetDirectionToGridNoFromGridNo( gMapInformation.sCenterGridNo, sGridNo );
}
pSoldier->EVENT_SetSoldierDirection( ubDirection );
ubDirection += 100;
pSoldier->ubInsertionDirection = ubDirection;
gMercPlacement[ iPlacement ].fPlaced = TRUE;
gMercPlacement[ iPlacement ].pSoldier->bInSector = TRUE;
//hayden
if(is_client)send_gui_pos(pSoldier, scX, scY);
if(is_client)send_gui_dir(pSoldier, ubDirection);
}
}
void PickUpMercPiece( INT32 iPlacement )
{
gMercPlacement[ iPlacement ].pSoldier->RemoveSoldierFromGridNo( );
gMercPlacement[ iPlacement ].fPlaced = FALSE;
gMercPlacement[ iPlacement ].pSoldier->bInSector = FALSE;
}
void FastHelpRemovedCallback()
{
gfTacticalPlacementGUIDirty = TRUE;
}
void FastHelpRemoved2Callback()
{
gfTacticalPlacementGUIDirty = TRUE;
gfValidLocationsChanged = 2; //because fast help text covers it.
}
void DialogRemoved( UINT8 ubResult )
{
gfTacticalPlacementGUIDirty = TRUE;
gfValidLocationsChanged = TRUE;
}