#include "Militia Control.h" #include "Town Militia.h" #include "Soldier Init List.h" #include "Campaign Types.h" #include "Overhead.h" #include "strategicmap.h" #include "PreBattle Interface.h" #include "Map Screen Interface.h" #include "Queen Command.h" #include "strategic.h" #include "popupbox.h" #include "interface control.h" #include "Map Screen Interface Map.h" #include "renderworld.h" #include "Text.h" #include "utilities.h" #include "Interface.h" #include "GameSettings.h" #include "Input.h" #include "opplist.h" #include "los.h" #include "Items.h" #include "Animation Control.h" #include "points.h" #include "Campaign.h" #include "ai.h" #include "Isometric Utils.h" #include "MilitiaSquads.h" #include "MilitiaIndividual.h" // added by Flugente #include "CampaignStats.h" // added by Flugente //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; BOOLEAN gfStrategicMilitiaChangesMade = FALSE; BOOLEAN fFirstClickInMilitiaControlScreenMask = FALSE; BOOLEAN gfMSResetMilitia = FALSE; // render pre battle interface? extern BOOLEAN gfRenderPBInterface; extern BOOLEAN fMapScreenBottomDirty; // PopUp Box Handles INT32 ghMilitiaControlBox = -1; //INT32 ghTalkToAllBox = -1; // the x,y position of assignment pop up in tactical INT16 gsMilitiaControlBoxesX, gsMilitiaControlBoxesY; //INT16 gsTalkToAllBoxesX, gsTalkToAllBoxesY; // assignment menu mouse regions MOUSE_REGION gMilitiaControlMenuRegion[ MAX_MILCON_STRING_COUNT ]; MOUSE_REGION gMilitiaControlScreenMaskRegion; // pop up menu mouse regions void CreateDestroyMouseRegionsForMilitiaControlMenu( void ); void MilitiaControlMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ); void MilitiaControlMenuBtnCallBack( MOUSE_REGION * pRegion, INT32 iReason ); //void CreateDestroyMouseRegionsForTalkToAllMenu( void ); //void TalkToAllMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ); //void TalkToAllMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); // assignment screen mask void MilitiaControlScreenMaskBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ); void CreateDestroyScreenMaskForMilitiaControlMenus( void ); // misc assignment GUI functions void HandleShadingOfLinesForMilitiaControlMenu( void ); //void HandleShadingOfLinesForTalkToAllMenu( void ); void PositionCursorForMilitiaControlBox( void ); void RepositionMouseRegionsForMilitiaControl( void ); void CheckAndUpdateTacticalMilitiaControlPopUpPositions( void ); // create assignments box void CreateMilitiaControlBox( void ); //void CreateTalkToAllBox( void ); // rebuild assignments box void RebuildMilitiaControlBox( void ); //funktions for soldier control extern INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem ); extern SOLDIERTYPE *GetSelectedAssignSoldier( BOOLEAN fNullOK, BOOLEAN fReturnVehicleDriver = TRUE ); extern SOLDIERTYPE *pTMilitiaSoldier; extern BOOLEAN SoldierCanAffordNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance ); void ResetMilitia() { UINT8 ubNumGreen = 0; UINT8 ubNumReg = 0; UINT8 ubNumVet = 0; // if ( gWorldSectorX !=0 && gWorldSectorY != 0 && NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) // fBattleInProgress = TRUE; // 0verhaul: Instead of relying on the "changes made" flag, which isn't even saved in a saved game and therefore not // reliable, we'll just do this the hard way, by taking inventory. // gfStrategicMilitiaChangesMade = FALSE; // for (UINT32 cnt = gTacticalStatus.Team[MILITIA_TEAM].bFirstID; cnt <= gTacticalStatus.Team[MILITIA_TEAM].bLastID; cnt++) // { // if (!MercPtrs[cnt]->bActive) // { // continue; // } // // switch (MercPtrs[cnt]->ubSoldierClass) // { // case SOLDIER_CLASS_GREEN_MILITIA: ubNumGreen++; break; // case SOLDIER_CLASS_REG_MILITIA: ubNumReg++; break; // case SOLDIER_CLASS_ELITE_MILITIA: ubNumVet++; break; // default: ; // } // } // if (MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, GREEN_MILITIA) != ubNumGreen || // MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, REGULAR_MILITIA) != ubNumReg || // MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, ELITE_MILITIA) != ubNumVet) // { // gfStrategicMilitiaChangesMade = TRUE; // } // if (gfStrategicMilitiaChangesMade) { // I truly hope that we remove such inane control methods from the soldier create code when we break the merc slot barrier // Hacks like this really depress me. UINT32 cs = guiCurrentScreen; // Make sure we aren't on the AUTORESOLVE screen for this. Even if we are. We are removing and creating soldiers for // tactical here, not autoresolve. In my opinion the CreateSoldierXXX and TacticalRemoveSoldierXXX functions should take // a flag for autoresolve if different initialization or destruction is desired. guiCurrentScreen = GAME_SCREEN; // Flugente: cause all militia whose equipment is from this sector to drop it TeamDropAll( MILITIA_TEAM ); RemoveMilitiaFromTactical(); ubNumGreen = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, GREEN_MILITIA); ubNumReg = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, REGULAR_MILITIA); ubNumVet = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, ELITE_MILITIA); AddSoldierInitListMilitia( ubNumGreen, ubNumReg, ubNumVet ); // Now restore the original screen setting so the game doesn't go wacky. guiCurrentScreen = cs; gfStrategicMilitiaChangesMade = FALSE; } // if( ( gfStrategicMilitiaChangesMade && !fBattleInProgress ) || gTacticalStatus.uiFlags & LOADING_SAVED_GAME || gfMSResetMilitia ) // if(gfMSResetMilitia ) // { // if( !gfMSResetMilitia ) // RemoveMilitiaFromTactical(); // PrepareMilitiaForTactical(); // gfMSResetMilitia = FALSE; // } } void RemoveMilitiaFromTactical() { SOLDIERINITNODE *curr; INT32 i; for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) { if( MercPtrs[ i ]->bActive ) { TacticalRemoveSoldier( MercPtrs[ i ]->ubID ); } } curr = gSoldierInitHead; while( curr ) { if( curr->pBasicPlacement->bTeam == MILITIA_TEAM ) { curr->pSoldier = NULL; } curr = curr->next; } } void PrepareMilitiaForTactical( BOOLEAN fPrepareAll) { SECTORINFO *pSector; INT32 x; UINT8 ubGreen, ubRegs, ubElites; if( gbWorldSectorZ > 0 ) return; // Do we have a loaded sector? if ( gWorldSectorX == 0 && gWorldSectorY == 0 ) return; pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ]; // Prevent militia from just waiting on the border gTacticalStatus.Team[MILITIA_TEAM].bAwareOfOpposition = ( pSector->uiFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE ) != 0; ubGreen = MilitiaInSectorOfRankStationary( gWorldSectorX, gWorldSectorY, GREEN_MILITIA ); ubRegs = MilitiaInSectorOfRankStationary( gWorldSectorX, gWorldSectorY, REGULAR_MILITIA ); ubElites = MilitiaInSectorOfRankStationary( gWorldSectorX, gWorldSectorY, ELITE_MILITIA ); // Flugente: if we are entering combat, have militia groups that arrived from other sectors start at the edges. // As the arrival time is no longer set, we try to deduct that from the previous sectors of the groups. // If that isn't set, too bad, have them insert in the center then. if ( fPrepareAll && !guiDirNumber && NumHostilesInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) > 0 )//(gTacticalStatus.uiFlags & INCOMBAT) ) { guiDirNumber = 5; ZeroMemory( gpAttackDirs, sizeof( gpAttackDirs ) ); gpAttackDirs[0][0] += ubGreen; gpAttackDirs[0][1] += ubRegs; gpAttackDirs[0][2] += ubElites; GROUP *pGroup = gpGroupList; while ( pGroup ) { if ( pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY ) { if ( pGroup->ubPrevX > 0 && pGroup->ubPrevY > 0 ) { if ( pGroup->ubPrevX < gWorldSectorX ) { gpAttackDirs[4][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[4][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[4][2] += pGroup->pEnemyGroup->ubNumElites; gpAttackDirs[4][3] = INSERTION_CODE_WEST; } else if ( pGroup->ubPrevX > gWorldSectorX ) { gpAttackDirs[2][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[2][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[2][2] += pGroup->pEnemyGroup->ubNumElites; gpAttackDirs[2][3] = INSERTION_CODE_EAST; } else if ( pGroup->ubPrevY < gWorldSectorY ) { gpAttackDirs[1][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[1][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[1][2] += pGroup->pEnemyGroup->ubNumElites; gpAttackDirs[1][3] = INSERTION_CODE_NORTH; } else if ( pGroup->ubPrevY > gWorldSectorY ) { gpAttackDirs[3][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[3][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[3][2] += pGroup->pEnemyGroup->ubNumElites; gpAttackDirs[3][3] = INSERTION_CODE_SOUTH; } else { gpAttackDirs[0][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[0][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[0][2] += pGroup->pEnemyGroup->ubNumElites; } } else { gpAttackDirs[0][0] += pGroup->pEnemyGroup->ubNumAdmins; gpAttackDirs[0][1] += pGroup->pEnemyGroup->ubNumTroops; gpAttackDirs[0][2] += pGroup->pEnemyGroup->ubNumElites; } } pGroup = pGroup->next; } } else { ubGreen += MilitiaInSectorOfRankInGroups( gWorldSectorX, gWorldSectorY, GREEN_MILITIA ); ubRegs += MilitiaInSectorOfRankInGroups( gWorldSectorX, gWorldSectorY, REGULAR_MILITIA ); ubElites += MilitiaInSectorOfRankInGroups( gWorldSectorX, gWorldSectorY, ELITE_MILITIA ); } if(guiDirNumber) { if (fPrepareAll) { AddSoldierInitListMilitia( gpAttackDirs[ 0 ][0], gpAttackDirs[ 0 ][1], gpAttackDirs[ 0 ][2] ); } // If the sector is already loaded, don't add the existing militia for( x = 1; x < guiDirNumber ; ++x ) { AddSoldierInitListMilitiaOnEdge( gpAttackDirs[ x ][ 3 ], gpAttackDirs[ x ][0], gpAttackDirs[ x ][1], gpAttackDirs[ x ][2] ); } guiDirNumber = 0; } else if (fPrepareAll) { AddSoldierInitListMilitia( ubGreen, ubRegs, ubElites ); } // for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) // { // if( MercPtrs[ i ]->bInSector ) // { // MercPtrs[ i ]->bOrders = SEEKENEMY; //// MercPtrs[ i ]->bAttitude = AGGRESSIVE; // } // } //for (int i=0; ibActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds(MercPtrs[i]->sGridNo)); } } void HandleMilitiaPromotions( void ) { UINT8 cnt; SOLDIERTYPE* pTeamSoldier; gbGreenToElitePromotions = 0; gbGreenToRegPromotions = 0; gbRegToElitePromotions = 0; gbMilitiaPromotions = 0; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; ++cnt, ++pTeamSoldier) { if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 ) { // Flugente: take care of promotions and individual militia update HandlePossibleMilitiaPromotion( pTeamSoldier, FALSE ); } } if( gbMilitiaPromotions ) { // ATE: Problems here with bringing up message box... // CHAR16 str[ 512 ]; // BuildMilitiaPromotionsString( str ); // DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); } if (gfStrategicMilitiaChangesMade) { ResetMilitia(); } } //lal void RebuildMilitiaControlBox( void ) { // destroy and recreate MilitiaControls box if ( ghMilitiaControlBox != -1 ) { RemoveBox( ghMilitiaControlBox ); ghMilitiaControlBox = -1; } CreateMilitiaControlBox( ); } void MilitiaControlMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ) { // mvt callback handler for MilitiaControl region INT32 iValue = -1; iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { // highlight string if( GetBoxShadeFlag( ghMilitiaControlBox, iValue ) == FALSE ) { // get the string line handle HighLightBoxLine( ghMilitiaControlBox, iValue ); } } else if (iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { // unhighlight all strings in box UnHighLightBox( ghMilitiaControlBox ); } } void DetermineWhichMilitiaControlMenusCanBeShown( void ) { BOOLEAN fCharacterNoLongerValid = FALSE; if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) { if( fShowMapScreenMovementList == TRUE ) { if( GetSelectedDestChar() == -1 ) { fCharacterNoLongerValid = TRUE; //HandleShowingOfMovementBox( ); //laltodo } else { fShowMapScreenMovementList = FALSE; fCharacterNoLongerValid = TRUE; } } else if( bSelectedAssignChar == -1 ) { fCharacterNoLongerValid = TRUE; } // update the assignment positions UpdateMapScreenMilitiaControlPositions( ); } //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"start DetermineWhichMilitiaControlMenusCanBeShown" ); // determine which assign menu needs to be shown if( ( ( fShowMilitiaControlMenu == FALSE ) )||( fCharacterNoLongerValid == TRUE ) ) { // reset show MilitiaControl menu fShowMilitiaControlMenu = FALSE; //fShowTalkToAllMenu = FALSE; //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"ShowMilitiaControlMenu = FALSE" ); // destroy mask, if needed CreateDestroyScreenMaskForMilitiaControlMenus( ); // destroy menu if needed CreateDestroyMouseRegionsForMilitiaControlMenu( ); //CreateDestroyMouseRegionsForTalkToAllMenu( ); if ( IsBoxShown( ghMilitiaControlBox ) ) { HideBox( ghMilitiaControlBox ); fTeamPanelDirty = TRUE; gfRenderPBInterface = TRUE; } //if ( IsBoxShown( ghTalkToAllBox ) ) //{ // HideBox( ghTalkToAllBox ); // fTeamPanelDirty = TRUE; // gfRenderPBInterface = TRUE; //} // no menus, leave return; } // update the assignment positions UpdateMapScreenMilitiaControlPositions( ); // create mask, if needed CreateDestroyScreenMaskForMilitiaControlMenus( ); // created assignment menu if needed CreateDestroyMouseRegionsForMilitiaControlMenu( ); //CreateDestroyMouseRegionsForTalkToAllMenu( ); // Militia Command menu if( fShowMilitiaControlMenu == TRUE ) { HandleShadingOfLinesForMilitiaControlMenu( ); ShowBox( ghMilitiaControlBox ); } else { if( IsBoxShown( ghMilitiaControlBox ) ) { HideBox( ghMilitiaControlBox ); fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; gfRenderPBInterface = TRUE; } } // Talk to all menu //if( fShowTalkToAllMenu == TRUE ) //{ // HandleShadingOfLinesForTalkToAllMenu( ); // ShowBox( ghTalkToAllBox ); //} //else //{ // if( IsBoxShown( ghTalkToAllBox ) ) // { // HideBox( ghTalkToAllBox ); // fTeamPanelDirty = TRUE; // fMapPanelDirty = TRUE; // gfRenderPBInterface = TRUE; // } //} return; } void CreateDestroyScreenMaskForMilitiaControlMenus( void ) { static BOOLEAN fCreated = FALSE; // will create a screen mask to catch mouse input to disable MilitiaControl menus // not created, create if( ( fCreated == FALSE ) && ( fShowMilitiaControlMenu == TRUE ) ) { MSYS_DefineRegion( &gMilitiaControlScreenMaskRegion, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGHEST - 4 , MSYS_NO_CURSOR, MSYS_NO_CALLBACK, MilitiaControlScreenMaskBtnCallback ); // created fCreated = TRUE; if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) { MSYS_ChangeRegionCursor( &gMilitiaControlScreenMaskRegion, 0 ); } } else if( ( fCreated == TRUE ) && ( fShowMilitiaControlMenu == FALSE ) ) { // created, get rid of it MSYS_RemoveRegion( &gMilitiaControlScreenMaskRegion ); // not created fCreated = FALSE; } return; } void MilitiaControlScreenMaskBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ) { // btn callback handler for MilitiaControl screen mask region if( ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) || ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) ) { if( fFirstClickInMilitiaControlScreenMask == TRUE ) { fFirstClickInMilitiaControlScreenMask = FALSE; return; } // button event, stop showing menus fShowMilitiaControlMenu = FALSE; // update mapscreen fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; gfRenderPBInterface = TRUE; SetRenderFlags( RENDER_FLAG_FULL ); } return; } void CreateDestroyMouseRegionsForMilitiaControlMenu( void ) { static BOOLEAN fCreated = FALSE; UINT32 iCounter = 0; INT32 iFontHeight = 0; INT32 iBoxXPosition = 0; INT32 iBoxYPosition = 0; SGPPoint pPosition; INT32 iBoxWidth = 0; SGPRect pDimensions; static BOOLEAN fShowRemoveMenu = FALSE; if( ( fShowMilitiaControlMenu == TRUE ) && ( fCreated == FALSE ) ) { gfIgnoreScrolling = FALSE; if( ( fShowMilitiaControlMenu ) && ( guiCurrentScreen == MAP_SCREEN ) ) { SetBoxPosition( ghMilitiaControlBox, MilitiaControlPosition ); } //pSoldier = GetSelectedAssignSoldier( FALSE ); //if( pSoldier -> ubWhatKindOfMercAmI != MERC_TYPE__EPC ) //laltodo { // grab height of font iFontHeight = GetLineSpace( ghMilitiaControlBox ) + GetFontHeight( GetBoxFont( ghMilitiaControlBox ) ); // get x.y position of box GetBoxPosition( ghMilitiaControlBox, &pPosition); // grab box x and y position iBoxXPosition = pPosition.iX; iBoxYPosition = pPosition.iY; // get dimensions..mostly for width GetBoxSize( ghMilitiaControlBox, &pDimensions ); // get width iBoxWidth = pDimensions.iRight; SetCurrentBox( ghMilitiaControlBox ); } // define regions for( iCounter = 0; iCounter < GetNumberOfLinesOfTextInBox( ghMilitiaControlBox ); iCounter++ ) { // add mouse region for each line of text..and set user data MSYS_DefineRegion( &gMilitiaControlMenuRegion[ iCounter ], ( INT16 )( iBoxXPosition ), ( INT16 )( iBoxYPosition + GetTopMarginSize( ghMilitiaControlBox ) + ( iFontHeight ) * iCounter ), ( INT16 )( iBoxXPosition + iBoxWidth ), ( INT16 )( iBoxYPosition + GetTopMarginSize( ghMilitiaControlBox ) + ( iFontHeight ) * ( iCounter + 1 ) ), MSYS_PRIORITY_HIGHEST - 4 , MSYS_NO_CURSOR, MilitiaControlMenuMvtCallBack, MilitiaControlMenuBtnCallBack ); MSYS_SetRegionUserData( &gMilitiaControlMenuRegion[ iCounter ], 0, iCounter ); } // created fCreated = TRUE; // unhighlight all strings in box UnHighLightBox( ghMilitiaControlBox ); CheckAndUpdateTacticalMilitiaControlPopUpPositions( ); //PositionCursorForMilitiaControlBox( ); } else if( ( fShowMilitiaControlMenu == FALSE ) && ( fCreated == TRUE ) ) { // destroy for( iCounter = 0; iCounter < GetNumberOfLinesOfTextInBox( ghMilitiaControlBox ); iCounter++ ) { MSYS_RemoveRegion( &gMilitiaControlMenuRegion[ iCounter ] ); } // not created fCreated = FALSE; SetRenderFlags( RENDER_FLAG_FULL ); } } void CreateMilitiaControlBox( void ) { UINT32 hStringHandle; UINT32 uiCounter; CHAR16 sString[ 128 ]; //SOLDIERTYPE *pSoldier = NULL; // will create attribute pop up menu for mapscreen MilitiaControls MilitiaControlPosition.iX = OrigMilitiaControlPosition.iX; if( giBoxY != 0 ) { MilitiaControlPosition.iY = giBoxY; } //pSoldier = GetSelectedAssignSoldier( TRUE ); // pSoldier NULL is legal here! Gets called during every mapscreen initialization even when nobody is assign char // create basic box CreatePopUpBox(&ghMilitiaControlBox, MilitiaControlDimensions, MilitiaControlPosition, (POPUP_BOX_FLAG_CLIP_TEXT|POPUP_BOX_FLAG_CENTER_TEXT|POPUP_BOX_FLAG_RESIZE )); // which buffer will box render to SetBoxBuffer(ghMilitiaControlBox, FRAME_BUFFER); // border type? SetBorderType(ghMilitiaControlBox,guiPOPUPBORDERS); // background texture SetBackGroundSurface(ghMilitiaControlBox, guiPOPUPTEX); // margin sizes SetMargins(ghMilitiaControlBox, 6, 6, 4, 4 ); // space between lines SetLineSpace(ghMilitiaControlBox, 2); // set current box to this one SetCurrentBox( ghMilitiaControlBox ); // add strings for box for(uiCounter=0; uiCounter < MAX_MILCON_STRING_COUNT; uiCounter++) { swprintf( sString, pMilitiaControlMenuStrings[uiCounter] ); AddMonoString(&hStringHandle, sString ); // make sure it is unhighlighted UnHighLightLine(hStringHandle); } // set font type SetBoxFont(ghMilitiaControlBox, MAP_SCREEN_FONT); // set highlight color SetBoxHighLight(ghMilitiaControlBox, FONT_WHITE); // unhighlighted color SetBoxForeground(ghMilitiaControlBox, FONT_LTGREEN); // background color SetBoxBackground(ghMilitiaControlBox, FONT_BLACK); // shaded color..for darkened text SetBoxShade( ghMilitiaControlBox, FONT_GRAY7 ); SetBoxSecondaryShade( ghMilitiaControlBox, FONT_YELLOW ); // resize box to text ResizeBoxToText( ghMilitiaControlBox ); //DetermineMilitiaControlBoxPositions( ); //laltodo } BOOLEAN CreateDestroyMilitiaControlPopUpBoxes( void ) { static BOOLEAN fCreated= FALSE; VSURFACE_DESC vs_desc; VOBJECT_DESC VObjectDesc; if( ( fShowMilitiaControlMenu == TRUE ) && ( fCreated == FALSE ) ) { VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\popup.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiPOPUPBORDERS)); vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE; strcpy(vs_desc.ImageFile, "INTERFACE\\popupbackground.pcx"); CHECKF(AddVideoSurface(&vs_desc, &guiPOPUPTEX)); // these boxes are always created while in mapscreen... CreateMilitiaControlBox( ); //CreateTalkToAllBox( ); UpdateMapScreenMilitiaControlPositions( ); fCreated = TRUE; } else if( ( fShowMilitiaControlMenu == FALSE ) && ( fCreated == TRUE ) ) { DeleteVideoObjectFromIndex(guiPOPUPBORDERS); DeleteVideoSurfaceFromIndex(guiPOPUPTEX); RemoveBox(ghMilitiaControlBox); ghMilitiaControlBox = -1; //RemoveBox(ghTalkToAllBox); //ghTalkToAllBox = -1; fCreated = FALSE; gfIgnoreScrolling = FALSE; } return( TRUE ); } void DetermineMilitiaControlBoxPositions( void ) { // depending on how many boxes there are, reposition as needed SGPPoint pPoint; SGPPoint pNewPoint; SGPRect pDimensions; SOLDIERTYPE *pSoldier = NULL; if( ( fShowMilitiaControlMenu == FALSE ) || ( ghMilitiaControlBox == -1 ) ) { return; } pSoldier = GetSelectedAssignSoldier( TRUE ); // pSoldier NULL is legal here! Gets called during every mapscreen initialization even when nobody is assign char if ( pSoldier == NULL ) { return; } if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) { GetBoxPosition( ghMilitiaControlBox, &pPoint ); gsMilitiaControlBoxesX = ( INT16 )pPoint.iX; gsMilitiaControlBoxesY = ( INT16 )pPoint.iY; } pPoint.iX = gsMilitiaControlBoxesX; pPoint.iY = gsMilitiaControlBoxesY; SetBoxPosition( ghMilitiaControlBox, pPoint ); GetBoxSize( ghMilitiaControlBox, &pDimensions ); // hang it right beside the MilitiaControl/EPC box menu pNewPoint.iX = pPoint.iX + pDimensions.iRight; pNewPoint.iY = pPoint.iY; //if( ( fShowTalkToAllMenu == TRUE ) && ( ghTalkToAllBox != -1 ) ) //{ // pNewPoint.iY += ( ( GetFontHeight( MAP_SCREEN_FONT ) + 2 ) * MILCON_MENU_ALL ); // SetBoxPosition( ghTalkToAllBox, pNewPoint ); // TrainPosition.iX = pNewPoint.iX; // TrainPosition.iY = pNewPoint.iY; // OrigTrainPosition.iY = pNewPoint.iY; // OrigTrainPosition.iX = pNewPoint.iX; // GetBoxSize( ghTalkToAllBox, &pDimensions ); // GetBoxPosition( ghTalkToAllBox, &pPoint ); //} return; } void SetTacticalPopUpMilitiaControlBoxXY( SOLDIERTYPE *pSoldier ) { INT16 sX, sY; //SOLDIERTYPE *pSoldier; //get the soldier //pSoldier = GetSelectedAssignSoldier( FALSE ); //gives wrong position (0,0) when cursor moved //if ( !GetSoldier( &pSoldier, gusSelectedSoldier ) ) //{ // //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"No Soldier" ); // return; //} // grab soldier's x,y screen position GetSoldierScreenPos( pSoldier, &sX, &sY ); //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"X-Position: %d", sX ); //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"Y-Position: %d", sY ); if( sX < 0 ) { sX = 0; } gsMilitiaControlBoxesX = sX + 30; if( sY < 0 ) { sY = 0; } gsMilitiaControlBoxesY = sY; // ATE: Check if we are past tactical viewport.... // Use estimate width's/heights if ( ( gsMilitiaControlBoxesX + 100 ) > SCREEN_WIDTH ) { gsMilitiaControlBoxesX = SCREEN_WIDTH - 100; } if ( ( gsMilitiaControlBoxesY + 130 ) > SCREEN_HEIGHT ) { gsMilitiaControlBoxesY = SCREEN_HEIGHT - 190; } return; } void CheckAndUpdateTacticalMilitiaControlPopUpPositions( void ) { SGPRect pDimensions2; SGPPoint pPoint; //SOLDIERTYPE *pSoldier = NULL; if( fShowMilitiaControlMenu == FALSE ) { return; } if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) { return; } //get the soldier //pSoldier = GetSelectedAssignSoldier( FALSE ); //if( pSoldier -> ubWhatKindOfMercAmI == MERC_TYPE__EPC ) //laltodo { GetBoxSize( ghMilitiaControlBox, &pDimensions2 ); } // just the MilitiaControl box if( gsMilitiaControlBoxesX + pDimensions2.iRight >= SCREEN_WIDTH ) { gsMilitiaControlBoxesX = ( INT16 ) ( SCREEN_WIDTH - 1 - ( pDimensions2.iRight ) ); SetRenderFlags( RENDER_FLAG_FULL ); } if( gsMilitiaControlBoxesY + pDimensions2.iBottom >= SCREEN_HEIGHT-120 ) { gsMilitiaControlBoxesY = ( INT16 )( SCREEN_HEIGHT - 121 - ( pDimensions2.iBottom ) ); SetRenderFlags( RENDER_FLAG_FULL ); } pPoint.iX = gsMilitiaControlBoxesX; pPoint.iY = gsMilitiaControlBoxesY; //if( pSoldier -> ubWhatKindOfMercAmI != MERC_TYPE__EPC) //laltodo { SetBoxPosition( ghMilitiaControlBox, pPoint ); } RepositionMouseRegionsForMilitiaControl( ); } void RepositionMouseRegionsForMilitiaControl( void ) { INT16 sDeltaX, sDeltaY; INT32 iCounter = 0; if( fShowMilitiaControlMenu == TRUE ) { sDeltaX = gsMilitiaControlBoxesX - gMilitiaControlMenuRegion[ 0 ].RegionTopLeftX; sDeltaY = ( INT16 ) ( gsMilitiaControlBoxesY - gMilitiaControlMenuRegion[ 0 ].RegionTopLeftY + GetTopMarginSize( ghMilitiaControlBox ) ); // find the delta from the old to the new, and alter values accordingly for( iCounter = 0; iCounter < ( INT32 )GetNumberOfLinesOfTextInBox( ghMilitiaControlBox ); iCounter++ ) { gMilitiaControlMenuRegion[ iCounter ].RegionTopLeftX += sDeltaX; gMilitiaControlMenuRegion[ iCounter ].RegionTopLeftY += sDeltaY; gMilitiaControlMenuRegion[ iCounter ].RegionBottomRightX += sDeltaX; gMilitiaControlMenuRegion[ iCounter ].RegionBottomRightY += sDeltaY; } gfPausedTacticalRenderFlags = RENDER_FLAG_FULL; } } void PositionCursorForMilitiaControlBox( void ) { // position cursor over y of on duty in tactical assignments SGPPoint pPosition; SGPRect pDimensions; INT32 iFontHeight; // get x.y position of box GetBoxPosition( ghMilitiaControlBox, &pPosition); // get dimensions..mostly for width GetBoxSize( ghMilitiaControlBox, &pDimensions ); iFontHeight = GetLineSpace( ghMilitiaControlBox ) + GetFontHeight( GetBoxFont( ghMilitiaControlBox ) ); if( gGameSettings.fOptions[ TOPTION_DONT_MOVE_MOUSE ] == FALSE ) { SimulateMouseMovement( pPosition.iX + pDimensions.iRight - 6, pPosition.iY + ( iFontHeight / 2 ) + 2 ); } } void HandleShadingOfLinesForMilitiaControlMenu( void ) { SOLDIERTYPE *pSoldier = NULL; // check if valid if( ( fShowMilitiaControlMenu == FALSE ) || ( ghMilitiaControlBox == - 1 ) ) { return; } if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { // Check LOS! // Flugente: active radio sets allows us to give individual orders even without a line of sight if (pSoldier->CanUseRadio() || SoldierToSoldierLineOfSightTest(pSoldier, pTMilitiaSoldier, TRUE, CALC_FROM_ALL_DIRS)) { UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ATTACK ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_HOLD ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_RETREAT ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_COMETOME ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_GETDOWN ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_CROUCH ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_TAKE_COVER ); if ((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT)) ShadeStringInBox(ghMilitiaControlBox, MILCON_MENU_MOVE_TO); else UnShadeStringInBox(ghMilitiaControlBox, MILCON_MENU_MOVE_TO); } else { ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ATTACK ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_HOLD ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_RETREAT ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_COMETOME ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_GETDOWN ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_CROUCH ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_TAKE_COVER ); ShadeStringInBox(ghMilitiaControlBox, MILCON_MENU_MOVE_TO); } } if ( CheckIfRadioIsEquipped() ) { UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_ATTACK ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_HOLD ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_RETREAT ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_COMETOME ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_SPREAD ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_GETDOWN ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_CROUCH ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_TAKE_COVER ); //UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_TAKE_ITEMS ); } else { ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_ATTACK ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_HOLD ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_RETREAT ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_COMETOME ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_SPREAD ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_GETDOWN ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_CROUCH ); ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_TAKE_COVER ); //ShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ALL_TAKE_ITEMS ); } return; } BOOLEAN CheckIfRadioIsEquipped( void ) { SOLDIERTYPE *pSoldier = NULL; INT8 bSlot = NO_SLOT; if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { // Flugente: active radio sets also count as radio if ( pSoldier->CanUseRadio(FALSE) ) return TRUE; bSlot = FindHearingAid(pSoldier); } if (bSlot == HEAD1POS || bSlot == HEAD2POS) { return TRUE; } return FALSE; } void MilitiaControlMenuBtnCallBack( MOUSE_REGION * pRegion, INT32 iReason ) { // btn callback handler for MilitiaControl region INT32 iValue = -1; SOLDIERTYPE * pSoldier = NULL; UINT8 ubVolume = 10; BOOLEAN fAllowSectorOrder = FALSE; BOOLEAN fCanCommunicate = FALSE; iValue = MSYS_GetRegionUserData( pRegion, 0 ); GetSoldier(&pSoldier, gusSelectedSoldier); if (pSoldier && pTMilitiaSoldier) { if (pSoldier->CanUseRadio() || SoldierToSoldierLineOfSightTest(pSoldier, pTMilitiaSoldier, TRUE, CALC_FROM_ALL_DIRS)) fCanCommunicate = TRUE; if (CheckIfRadioIsEquipped()) fAllowSectorOrder = TRUE; } if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { //if( ( fShowTalkToAllMenu ) ) //{ // return; //} UnHighLightBox( ghMilitiaControlBox ); //if( pSoldier -> ubWhatKindOfMercAmI != MERC_TYPE__EPC ) //laltodo if (pSoldier) { switch( iValue ) { case( MILCON_MENU_ATTACK ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); // Attack !!! pTMilitiaSoldier->aiData.bOrders = SEEKENEMY; pTMilitiaSoldier->aiData.bAttitude = AGGRESSIVE; pTMilitiaSoldier->usUIMovementMode = RUNNING; MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_SCREAM); } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_HOLD ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); //Hold Position !!! //ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"Hold Position" ); pTMilitiaSoldier->aiData.bOrders = STATIONARY; //pTMilitiaSoldier->bAttitude = DEFENSIVE; } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_RETREAT ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); INT16 sActionGridNo; pTMilitiaSoldier->aiData.bOrders = FARPATROL; pTMilitiaSoldier->aiData.bAttitude = DEFENSIVE; pTMilitiaSoldier->usUIMovementMode = RUNNING; pTMilitiaSoldier->RetreatCounterStart(2); // set up next action to run away sActionGridNo = FindSpotMaxDistFromOpponents( pTMilitiaSoldier ); pTMilitiaSoldier->aiData.usNextActionData = sActionGridNo; if (!TileIsOutOfBounds(pTMilitiaSoldier->aiData.usNextActionData)) { // sevenfm: use TAKE_COVER order to stop soldier from retreating pTMilitiaSoldier->aiData.bNextAction = AI_ACTION_TAKE_COVER; //pTMilitiaSoldier->aiData.bNextAction = AI_ACTION_RUN_AWAY; pTMilitiaSoldier->aiData.usActionData = ANIM_STAND; // SEND PENDING ACTION pTMilitiaSoldier->aiData.sPendingActionData2 = sActionGridNo; pTMilitiaSoldier->aiData.ubPendingActionAnimCount = 0; } if ( pTMilitiaSoldier->sGridNo != sActionGridNo ) { SendGetNewSoldierPathEvent( pTMilitiaSoldier, sActionGridNo, pTMilitiaSoldier->usUIMovementMode ); } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_COMETOME ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); INT32 sActionGridNo, sGridNo, sAdjustedGridNo; UINT8 ubDirection; // OK, find an adjacent gridno.... sGridNo = pSoldier->sGridNo; // See if we can get there sActionGridNo = FindAdjacentGridEx(pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE); if (sActionGridNo != -1) { // SEND PENDING ACTION //pTMilitiaSoldier->ubPendingAction = MERC_STEAL; pTMilitiaSoldier->aiData.sPendingActionData2 = pSoldier->sGridNo; //pTMilitiaSoldier->bPendingActionData3 = ubDirection; pTMilitiaSoldier->aiData.ubPendingActionAnimCount = 0; pTMilitiaSoldier->usUIMovementMode = RUNNING; // CHECK IF WE ARE AT THIS GRIDNO NOW if (pTMilitiaSoldier->sGridNo != sActionGridNo) { // WALK UP TO DEST FIRST SendGetNewSoldierPathEvent(pTMilitiaSoldier, sActionGridNo, pTMilitiaSoldier->usUIMovementMode); } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_GETDOWN ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); if (pTMilitiaSoldier->InternalIsValidStance(pTMilitiaSoldier->ubDirection, ANIM_PRONE)) { SendChangeSoldierStanceEvent( pTMilitiaSoldier, ANIM_PRONE ); } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_CROUCH ): if (fCanCommunicate) { if ((pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE)) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); if (pTMilitiaSoldier->InternalIsValidStance(pTMilitiaSoldier->ubDirection, ANIM_CROUCH)) { SendChangeSoldierStanceEvent(pTMilitiaSoldier, ANIM_CROUCH); } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_TAKE_COVER ): if (fCanCommunicate) { if ( (pTMilitiaSoldier->bActive) && (pTMilitiaSoldier->bInSector) && (pTMilitiaSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); INT16 sActionGridNo; INT32 iDummy; sActionGridNo = FindBestNearbyCover(pTMilitiaSoldier,pTMilitiaSoldier->aiData.bAIMorale,&iDummy); if (!TileIsOutOfBounds(sActionGridNo)) { // SEND PENDING ACTION pTMilitiaSoldier->aiData.sPendingActionData2 = sActionGridNo; pTMilitiaSoldier->aiData.ubPendingActionAnimCount = 0; pTMilitiaSoldier->usUIMovementMode = RUNNING; // CHECK IF WE ARE AT THIS GRIDNO NOW if ( pTMilitiaSoldier->sGridNo != sActionGridNo ) { SendGetNewSoldierPathEvent( pTMilitiaSoldier, sActionGridNo, pTMilitiaSoldier->usUIMovementMode ); } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_MOVE_TO ): if (!((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT))) { // sevenfm: stop any AI pTMilitiaSoldier->EVENT_StopMerc(pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->ubDirection); CancelAIAction(pTMilitiaSoldier, TRUE); DeductPoints(pSoldier, APBPConstants[AP_TALK], 0); StatChange(pSoldier, LDRAMT, 1, FALSE); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; guiPendingOverrideEvent = R_CHANGE_TO_RADIO; } break; case( MILCON_MENU_ALL_ATTACK ): if (fAllowSectorOrder) { UINT8 cnt; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); pTeamSoldier->aiData.bOrders = SEEKENEMY; pTeamSoldier->aiData.bAttitude = AGGRESSIVE; pTeamSoldier->usUIMovementMode = RUNNING; } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_HOLD ): if (fAllowSectorOrder) { UINT8 cnt; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); pTeamSoldier->aiData.bOrders = STATIONARY; pTeamSoldier->aiData.bAttitude = DEFENSIVE; } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_RETREAT ): if (fAllowSectorOrder) { UINT8 cnt; INT16 sActionGridNo; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); pTeamSoldier->aiData.bOrders = FARPATROL; pTeamSoldier->aiData.bAttitude = DEFENSIVE; pTeamSoldier->usUIMovementMode = RUNNING; pTeamSoldier->RetreatCounterStart(2); // set up next action to run away sActionGridNo = FindSpotMaxDistFromOpponents( pTeamSoldier ); pTeamSoldier->aiData.usNextActionData = sActionGridNo; if ( !TileIsOutOfBounds(pTeamSoldier->aiData.usNextActionData) ) { // sevenfm: use TAKE_COVER order to stop soldier from retreating //pTeamSoldier->aiData.bNextAction = AI_ACTION_RUN_AWAY; pTeamSoldier->aiData.bNextAction = AI_ACTION_TAKE_COVER; pTeamSoldier->aiData.usActionData = ANIM_STAND; // SEND PENDING ACTION pTeamSoldier->aiData.sPendingActionData2 = sActionGridNo; pTeamSoldier->aiData.ubPendingActionAnimCount = 0; } if ( pTeamSoldier->sGridNo != sActionGridNo ) { SendGetNewSoldierPathEvent( pTeamSoldier, sActionGridNo, pTeamSoldier->usUIMovementMode ); } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_COMETOME ): if (fAllowSectorOrder) { UINT8 cnt, ubDirection; INT32 sActionGridNo, sGridNo, sAdjustedGridNo; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); // OK, find an adjacent gridno.... sGridNo = pSoldier->sGridNo; // See if we can get there sActionGridNo = FindAdjacentGridEx(pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE); if (sActionGridNo != -1) { // SEND PENDING ACTION pTeamSoldier->aiData.sPendingActionData2 = pSoldier->sGridNo; //pTeamSoldier->bPendingActionData3 = ubDirection; pTeamSoldier->aiData.ubPendingActionAnimCount = 0; pTeamSoldier->usUIMovementMode = RUNNING; // CHECK IF WE ARE AT THIS GRIDNO NOW if (pTeamSoldier->sGridNo != sActionGridNo) { // WALK UP TO DEST FIRST SendGetNewSoldierPathEvent(pTeamSoldier, sActionGridNo, pTeamSoldier->usUIMovementMode); } } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_SPREAD ): if (fAllowSectorOrder) { UINT8 cnt; INT32 sActionGridNo; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); // See if we can get there sActionGridNo = RandDestWithinRange( pTeamSoldier ); if ( sActionGridNo != -1 ) { // SEND PENDING ACTION pTeamSoldier->aiData.sPendingActionData2 = sActionGridNo; //pTeamSoldier->bPendingActionData3 = ubDirection; pTeamSoldier->aiData.ubPendingActionAnimCount = 0; pTeamSoldier->usUIMovementMode = RUNNING; // CHECK IF WE ARE AT THIS GRIDNO NOW if ( pTeamSoldier->sGridNo != sActionGridNo ) { // WALK UP TO DEST FIRST SendGetNewSoldierPathEvent( pTeamSoldier, sActionGridNo, pTeamSoldier->usUIMovementMode ); } } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_GETDOWN ): if (fAllowSectorOrder) { UINT8 cnt; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); if (pTeamSoldier->InternalIsValidStance(pTeamSoldier->ubDirection, ANIM_PRONE)) { SendChangeSoldierStanceEvent( pTeamSoldier, ANIM_PRONE ); } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_CROUCH ): if (fAllowSectorOrder) { UINT8 cnt; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; ++cnt, ++pTeamSoldier) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); if (pTeamSoldier->InternalIsValidStance(pTeamSoldier->ubDirection, ANIM_CROUCH)) { SendChangeSoldierStanceEvent(pTeamSoldier, ANIM_CROUCH); } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_ALL_TAKE_COVER ): if (fAllowSectorOrder) { UINT8 cnt; INT16 sActionGridNo; INT32 iDummy; SOLDIERTYPE *pTeamSoldier; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) { if ( (pTeamSoldier->bActive) && (pTeamSoldier->bInSector) && (pTeamSoldier->stats.bLife >= OKLIFE) ) { // sevenfm: stop any AI pTeamSoldier->EVENT_StopMerc(pTeamSoldier->sGridNo, pTeamSoldier->ubDirection); CancelAIAction(pTeamSoldier, TRUE); // See if we can get there sActionGridNo = FindBestNearbyCover(pTeamSoldier,pTeamSoldier->aiData.bAIMorale,&iDummy); if (!TileIsOutOfBounds(sActionGridNo)) { // SEND PENDING ACTION pTeamSoldier->aiData.sPendingActionData2 = sActionGridNo; //pTeamSoldier->bPendingActionData3 = ubDirection; pTeamSoldier->aiData.ubPendingActionAnimCount = 0; pTeamSoldier->usUIMovementMode = RUNNING; // CHECK IF WE ARE AT THIS GRIDNO NOW if ( pTeamSoldier->sGridNo != sActionGridNo ) { // WALK UP TO DEST FIRST SendGetNewSoldierPathEvent( pTeamSoldier, sActionGridNo, pTeamSoldier->usUIMovementMode ); } } } } DeductPoints( pSoldier, APBPConstants[AP_TALK], 0 ); StatChange( pSoldier, LDRAMT, 1, FALSE ); // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; pSoldier->StartRadioAnimation(); } break; case( MILCON_MENU_CANCEL ): { // stop showing menu fShowMilitiaControlMenu = FALSE; giAssignHighLine = -1; // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; // reset list of characters ResetSelectedListForMapScreen( ); } break; } } gfRenderPBInterface = TRUE; } else if( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) { //if( ( fShowTalkToAllMenu ) ) //{ // fShowTalkToAllMenu = FALSE; // // rerender tactical stuff // gfRenderPBInterface = TRUE; // // set dirty flag // fTeamPanelDirty = TRUE; // fMapScreenBottomDirty = TRUE; // return; //} } }