#ifdef PRECOMPILEDHEADERS #include "Editor All.h" #else #include "builddefines.h" #endif #ifdef JA2EDITOR #ifndef PRECOMPILEDHEADERS #include #include "types.h" #include "Sector Summary.h" #include "Timer Control.h" #include "vsurface.h" #include "Button System.h" #include "Font Control.h" #include "Simple Render Utils.h" #include "Editor Taskbar Utils.h" #include "line.h" #include "input.h" #include "vobject_blitters.h" #include "loadscreen.h" #include "Text Input.h" #include "mousesystem.h" #include "strategicmap.h" #include "Fileman.h" #include "Exit Grids.h" #include "Map Information.h" #include "Summary Info.h" #include "Animated ProgressBar.h" #include "worlddef.h" #include "worlddat.h" #include "EditorDefines.h" #include "editscreen.h" #include "english.h" #include "World Items.h" #include "text.h" #include "Soldier Create.h" #include "GameVersion.h" #include "Campaign Types.h" #include "GameSettings.h" #endif #include #include extern BOOLEAN gfOverheadMapDirty; #define MAP_SIZE 208 #define MAP_LEFT (iScreenWidthOffset + 417) #define MAP_TOP (iScreenHeightOffset + 15) #define MAP_RIGHT (MAP_LEFT+MAP_SIZE) #define MAP_BOTTOM (MAP_TOP+MAP_SIZE) enum{ PRE_ALPHA, ALPHA, DEMO, BETA, RELEASE }; CHAR16 gszVersionType[5][10] = { L"Pre-Alpha", L"Alpha", L"Demo", L"Beta", L"Release" }; #define GLOBAL_SUMMARY_STATE RELEASE //Regular masks #define GROUND_LEVEL_MASK 0x01 #define BASEMENT1_LEVEL_MASK 0x02 #define BASEMENT2_LEVEL_MASK 0x04 #define BASEMENT3_LEVEL_MASK 0x08 #define ALL_LEVELS_MASK 0x0f //Alternate masks #define ALTERNATE_GROUND_MASK 0x10 #define ALTERNATE_B1_MASK 0x20 #define ALTERNATE_B2_MASK 0x40 #define ALTERNATE_B3_MASK 0x80 #define ALTERNATE_LEVELS_MASK 0xf0 void ExtractTempFilename(); INT32 giCurrLevel; BOOLEAN gfOutdatedDenied; UINT16 gusNumEntriesWithOutdatedOrNoSummaryInfo; void UpdateMasterProgress(); BOOLEAN gfUpdatingNow; UINT16 gusTotal, gusCurrent; BOOLEAN gfMustForceUpdateAllMaps = FALSE; UINT16 gusNumberOfMapsToBeForceUpdated = 0; BOOLEAN gfMajorUpdate = FALSE; BOOLEAN LoadSummary(STR8 pSector, UINT8 ubLevel, FLOAT dMajorMapVersion);//dnl ch28 240909 void RegenerateSummaryInfoForAllOutdatedMaps(); void SetupItemDetailsMode( BOOLEAN fAllowRecursion ); INT32 giCurrentViewLevel = ALL_LEVELS_MASK; BOOLEAN gbSectorLevels[16][16]; BOOLEAN gfGlobalSummaryLoaded = FALSE; SUMMARYFILE *gpSectorSummary[16][16][8] = {}; SUMMARYFILE *gpCurrentSectorSummary; SUMMARYFILE gCustomFileSectorSummary;//dnl ch30 150909 MOUSE_REGION MapRegion; extern INT8 gbMercSlotTypes[9]; extern void UpdateSummaryInfo( SUMMARYFILE *pSummary ); void SummaryOkayCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryToggleGridCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryToggleProgressCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryToggleLevelCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryLoadMapCallback( GUI_BUTTON *btn, INT32 reason ); void SummarySaveMapCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryOverrideCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryNewGroundLevelCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryNewBasementLevelCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryNewCaveLevelCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryUpdateCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryToggleAlternateCallback( GUI_BUTTON *btn, INT32 reason ); void SummarySciFiCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryRealCallback( GUI_BUTTON *btn, INT32 reason ); void SummaryEnemyCallback( GUI_BUTTON *btn, INT32 reason ); void MapMoveCallback( MOUSE_REGION *reg, INT32 reason ); void MapClickCallback( MOUSE_REGION *reg, INT32 reason ); //Set if there is an existing global summary. The first time this is run on your computer, it //will not exist, and will have to be generated before this will be set. BOOLEAN gfGlobalSummaryExists; //If you don't wish to create a global summary, you can deny it. This safely locks the system //from generating one. BOOLEAN gfDeniedSummaryCreation; //Set whenever the entire display is to be marked dirty. BOOLEAN gfRenderSummary; //Used externally to determine if the summary window is up or not. BOOLEAN gfSummaryWindowActive; //When set, the summary window stays up until told otherwise. When clear, the summary will disappear //when the assigned key (F5) is released. The latter mode is initiated when F5 is held down for longer //than .4 seconds, and is useful for quickly looking at the information in the current map being edited. BOOLEAN gfPersistantSummary; //When set, a grid is overlayed on top of the sector. This grid defines each of the 256 sectors. It is //on by default. BOOLEAN gfRenderGrid; //When set, parts of the map are darkened, showing that those sectors don't exist in the currently selected //layer. When clear, the entire map is shown in full color. BOOLEAN gfRenderProgress; //When set, only the map section is rerendered. extern BOOLEAN gfRenderMap; // symbol already declared globally in AI Viewer.cpp (jonathanl) //Set whenever the ctrl key is held down. This is used in conjunction with gfFileIO to determine whether the //selected sector is to be saved instead of loaded when clear. BOOLEAN gfCtrlPressed; //When set, it is time to load or save the selected sector. If gfCtrlPressed is set, the the map is saved, //instead of loaded. It is impossible to load a map that doesn't exist. BOOLEAN gfFileIO; //When set, then we are overriding the ability to use normal methods for selecting sectors for saving and //loading. Immediately upon entering the text input mode; for the temp file; then we are assuming that //the user will type in a name that doesn't follow standard naming conventions for the purposes of the //campaign editor. This is useful for naming a temp file for saving or loading. BOOLEAN gfTempFile; //When set, only the alternate version of the maps will be displayed. This is used for alternate maps in //particular sectors, such as the SkyRider quest which could be located at one of four maps randomly. If //that particular map is chosen, then the alternate map will be used. BOOLEAN gfAlternateMaps = FALSE; enum { ITEMMODE_SCIFI, ITEMMODE_REAL, ITEMMODE_ENEMY, }; UINT8 gubSummaryItemMode = ITEMMODE_SCIFI; BOOLEAN gfItemDetailsMode = FALSE; WORLDITEM *gpWorldItemsSummaryArray = NULL; UINT16 gusWorldItemsSummaryArraySize = 0; OBJECTTYPE *gpPEnemyItemsSummaryArray = NULL; UINT16 gusPEnemyItemsSummaryArraySize = 0; OBJECTTYPE *gpNEnemyItemsSummaryArray = NULL; UINT16 gusNEnemyItemsSummaryArraySize = 0; BOOLEAN gfSetupItemDetailsMode = TRUE; BOOLEAN gfUpdateSummaryInfo; UINT16 usNumSummaryFilesOutOfDate; BOOLEAN gfMapFileDirty; //Override status. Hide is when there is nothing to override, readonly, when checked is to override a //readonly status file, so that you can write to it, and overwrite, when checked, allows you to save, //replacing the existing file. These states are not persistant, which forces the user to check the //box before saving. enum{ INACTIVE, READONLY, OVERWRITE }; UINT8 gubOverrideStatus; //Set when the a new sector/level is selected, forcing the user to reselect the override status. BOOLEAN gfOverrideDirty; //The state of the override button, true if overriden intended. BOOLEAN gfOverride; //The sector coordinates of the map currently loaded in memory (blue) INT16 gsSectorX, gsSectorY; //The layer of the sector that is currently loaded in memory. INT32 gsSectorLayer; //The sector coordinates of the mouse position (yellow) extern INT16 gsHiSectorX; // symbol already declared globally in AI Viewer.cpp (jonathanl) extern INT16 gsHiSectorY; // symbol already declared globally in AI Viewer.cpp (jonathanl) //The sector coordinates of the selected sector (red) extern INT16 gsSelSectorX; // symbol already declared globally in AI Viewer.cpp (jonathanl) extern INT16 gsSelSectorY; // symbol already declared globally in AI Viewer.cpp (jonathanl) //Used to determine how long the F5 key has been held down for to determine whether or not the //summary is going to be persistant or not. UINT32 giInitTimer; //dnl ch39 190909 CHAR16 gszFilename[FILENAME_BUFLEN]; CHAR16 gszTempFilename[FILENAME_BUFLEN]; CHAR16 gszDisplayName[FILENAME_BUFLEN]; void CalculateOverrideStatus(); enum{ SUMMARY_BACKGROUND, SUMMARY_OKAY, SUMMARY_GRIDCHECKBOX, SUMMARY_PROGRESSCHECKBOX, SUMMARY_ALL, SUMMARY_G, SUMMARY_B1, SUMMARY_B2, SUMMARY_B3, SUMMARY_ALTERNATE, SUMMARY_LOAD, SUMMARY_SAVE, SUMMARY_OVERRIDE, #if 0 SUMMARY_NEW_GROUNDLEVEL, SUMMARY_NEW_BASEMENTLEVEL, SUMMARY_NEW_CAVELEVEL, #endif SUMMARY_UPDATE, SUMMARY_SCIFI, SUMMARY_REAL, SUMMARY_ENEMY, NUM_SUMMARY_BUTTONS }; INT32 iSummaryButton[ NUM_SUMMARY_BUTTONS ]; void CreateSummaryWindow() { INT32 i; if( !gfGlobalSummaryLoaded ) { LoadGlobalSummary(); gfGlobalSummaryLoaded = TRUE; } if( gfSummaryWindowActive ) return; DisableEditorTaskbar(); DisableAllTextFields(); GetCurrentWorldSector( &gsSectorX, &gsSectorY ); gsSelSectorX = gsSectorX; gsSelSectorY = gsSectorY; gfSummaryWindowActive = TRUE; gfPersistantSummary = FALSE; giInitTimer = GetJA2Clock(); gfDeniedSummaryCreation = FALSE; gfRenderSummary = TRUE; if( gfWorldLoaded ) gfMapFileDirty = TRUE; //Create all of the buttons here iSummaryButton[ SUMMARY_BACKGROUND ] = CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 120, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK ); SpecifyDisabledButtonStyle( iSummaryButton[ SUMMARY_BACKGROUND ], DISABLED_STYLE_NONE ); DisableButton( iSummaryButton[ SUMMARY_BACKGROUND ] ); iSummaryButton[ SUMMARY_OKAY ] = CreateTextButton(L"Okay", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+160, MAP_BOTTOM+99, 50, 30, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryOkayCallback);//dnl ch36 190909 //GiveButtonDefaultStatus( iSummaryButton[ SUMMARY_OKAY ], DEFAULT_STATUS_WINDOWS95 ); iSummaryButton[ SUMMARY_GRIDCHECKBOX ] = CreateCheckBoxButton( MAP_LEFT, ( INT16 ) ( MAP_BOTTOM + 5 ), "EDITOR//smcheckbox.sti", MSYS_PRIORITY_HIGH, SummaryToggleGridCallback ); ButtonList[ iSummaryButton[ SUMMARY_GRIDCHECKBOX ] ]->uiFlags |= BUTTON_CLICKED_ON; gfRenderGrid = TRUE; iSummaryButton[ SUMMARY_PROGRESSCHECKBOX ] = CreateCheckBoxButton( ( INT16 ) ( MAP_LEFT + 50 ), ( INT16 ) ( MAP_BOTTOM + 5 ), "EDITOR//smcheckbox.sti", MSYS_PRIORITY_HIGH, SummaryToggleProgressCallback ); ButtonList[ iSummaryButton[ SUMMARY_PROGRESSCHECKBOX ] ]->uiFlags |= BUTTON_CLICKED_ON; gfRenderProgress = TRUE; iSummaryButton[ SUMMARY_ALL ] = CreateTextButton( L"A", SMALLCOMPFONT, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+110, MAP_BOTTOM+5, 16, 16, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryToggleLevelCallback ); if( giCurrentViewLevel == ALL_LEVELS_MASK || giCurrentViewLevel == ALTERNATE_LEVELS_MASK ) ButtonList[ iSummaryButton[ SUMMARY_ALL ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_G ] = CreateTextButton( L"G", SMALLCOMPFONT, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+128, MAP_BOTTOM+5, 16, 16, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryToggleLevelCallback ); if( giCurrentViewLevel == GROUND_LEVEL_MASK || giCurrentViewLevel == ALTERNATE_GROUND_MASK ) ButtonList[ iSummaryButton[ SUMMARY_G ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_B1 ] = CreateTextButton( L"B1", SMALLCOMPFONT, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+146, MAP_BOTTOM+5, 16, 16, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryToggleLevelCallback ); if( giCurrentViewLevel == BASEMENT1_LEVEL_MASK || giCurrentViewLevel == ALTERNATE_B1_MASK ) ButtonList[ iSummaryButton[ SUMMARY_B1 ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_B2 ] = CreateTextButton( L"B2", SMALLCOMPFONT, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+164, MAP_BOTTOM+5, 16, 16, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryToggleLevelCallback ); if( giCurrentViewLevel == BASEMENT2_LEVEL_MASK || giCurrentViewLevel == ALTERNATE_B2_MASK ) ButtonList[ iSummaryButton[ SUMMARY_B2 ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_B3 ] = CreateTextButton( L"B3", SMALLCOMPFONT, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+182, MAP_BOTTOM+5, 16, 16, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryToggleLevelCallback ); if( giCurrentViewLevel == BASEMENT3_LEVEL_MASK || giCurrentViewLevel == ALTERNATE_B3_MASK ) ButtonList[ iSummaryButton[ SUMMARY_B3 ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_ALTERNATE ] = CreateCheckBoxButton( MAP_LEFT, ( INT16 ) ( MAP_BOTTOM + 25 ), "EDITOR//smcheckbox.sti", MSYS_PRIORITY_HIGH, SummaryToggleAlternateCallback ); if( gfAlternateMaps ) ButtonList[ iSummaryButton[ SUMMARY_ALTERNATE ] ]->uiFlags |= BUTTON_CLICKED_ON; iSummaryButton[ SUMMARY_LOAD ] = CreateTextButton( L"LOAD", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT, MAP_BOTTOM+45, 50, 26, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryLoadMapCallback ); iSummaryButton[ SUMMARY_SAVE ] = CreateTextButton( L"SAVE", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, MAP_LEFT+55, MAP_BOTTOM+45, 50, 26, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummarySaveMapCallback ); iSummaryButton[ SUMMARY_OVERRIDE ] = CreateCheckBoxButton( ( INT16 ) ( MAP_LEFT + 110 ), ( INT16 ) ( MAP_BOTTOM + 59 ), "EDITOR\\smcheckbox.sti", MSYS_PRIORITY_HIGH, SummaryOverrideCallback ); #if 0 iSummaryButton[ SUMMARY_NEW_GROUNDLEVEL ] = CreateSimpleButton( MAP_LEFT, MAP_BOTTOM+58, "EDITOR\\new.sti", BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, SummaryNewGroundLevelCallback ); SetButtonFastHelpText( iSummaryButton[ SUMMARY_NEW_GROUNDLEVEL ], L"New map" ); iSummaryButton[ SUMMARY_NEW_BASEMENTLEVEL ] = CreateSimpleButton( MAP_LEFT+32, MAP_BOTTOM+58, "EDITOR\\new.sti", BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, SummaryNewBasementLevelCallback ); SetButtonFastHelpText( iSummaryButton[ SUMMARY_NEW_BASEMENTLEVEL ], L"New basement" ); iSummaryButton[ SUMMARY_NEW_CAVELEVEL ] = CreateSimpleButton( MAP_LEFT+64, MAP_BOTTOM+58, "EDITOR\\new.sti", BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, SummaryNewCaveLevelCallback ); SetButtonFastHelpText( iSummaryButton[ SUMMARY_NEW_CAVELEVEL ], L"New cave level" ); #endif iSummaryButton[ SUMMARY_UPDATE ] = CreateTextButton( L"Update", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT, iScreenWidthOffset + 255, iScreenHeightOffset + 15, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, SummaryUpdateCallback ); iSummaryButton[ SUMMARY_REAL ] = CreateCheckBoxButton( iScreenWidthOffset + 350, iScreenHeightOffset + 47, "EDITOR\\radiobutton.sti", MSYS_PRIORITY_HIGH, SummaryRealCallback ); iSummaryButton[ SUMMARY_SCIFI ] = CreateCheckBoxButton( iScreenWidthOffset + 376, iScreenHeightOffset + 47, "EDITOR\\radiobutton.sti", MSYS_PRIORITY_HIGH, SummarySciFiCallback ); iSummaryButton[ SUMMARY_ENEMY ] = CreateCheckBoxButton( iScreenWidthOffset + 350, iScreenHeightOffset + 60, "EDITOR\\radiobutton.sti", MSYS_PRIORITY_HIGH, SummaryEnemyCallback ); //SetButtonFastHelpText( iSummaryButton[ SUMMARY_SCIFI ], L"Display items that appear in SciFi mode." ); //SetButtonFastHelpText( iSummaryButton[ SUMMARY_REAL ], L"Display items that appear in Realistic mode." ); switch( gubSummaryItemMode ) { case ITEMMODE_SCIFI: ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags |= BUTTON_CLICKED_ON; break; case ITEMMODE_REAL: ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags |= BUTTON_CLICKED_ON; break; case ITEMMODE_ENEMY: ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags |= BUTTON_CLICKED_ON; break; } //Init the textinput field. InitTextInputModeWithScheme( DEFAULT_SCHEME ); AddUserInputField( NULL ); //just so we can use short cut keys while not typing. AddTextInputField(MAP_LEFT+110, MAP_BOTTOM+75, 100, 18, MSYS_PRIORITY_HIGH, L"", (FILENAME_BUFLEN-4-1), INPUTTYPE_EXCLUSIVE_DOSFILENAME);//dnl ch39 190909 for( i = 1; i < NUM_SUMMARY_BUTTONS; i++ ) HideButton( iSummaryButton[ i ] ); MSYS_DefineRegion( &MapRegion, MAP_LEFT, MAP_TOP, MAP_RIGHT, MAP_BOTTOM, MSYS_PRIORITY_HIGH, 0, MapMoveCallback, MapClickCallback ); MSYS_DisableRegion( &MapRegion ); //if( gfItemDetailsMode ) // { gfItemDetailsMode = FALSE; // gfSetupItemDetailsMode = TRUE; //} if( !gfWorldLoaded ) { gfConfirmExitFirst = FALSE; ReleaseSummaryWindow(); DisableButton( iSummaryButton[ SUMMARY_OKAY ] ); DisableButton( iSummaryButton[ SUMMARY_SAVE ] ); } if( gfAutoLoadA9 ) { gfAutoLoadA9++; gsSelSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;//9; gsSelSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;//1; //gpCurrentSectorSummary = gpSectorSummary[ 8 ][ 0 ][ 0 ]; gpCurrentSectorSummary = gpSectorSummary[ gGameExternalOptions.ubDefaultArrivalSectorX - 1 ][ gGameExternalOptions.ubDefaultArrivalSectorY - 1 ][ 0 ]; ButtonList[ iSummaryButton[ SUMMARY_LOAD ] ]->uiFlags |= BUTTON_CLICKED_ON; } } void AutoLoadMap() { SummaryLoadMapCallback( ButtonList[ iSummaryButton[ SUMMARY_LOAD ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); ButtonList[ iSummaryButton[ SUMMARY_LOAD ] ]->uiFlags &= ~BUTTON_CLICKED_ON;//dnl ch36 210909 if( gfWorldLoaded ) DestroySummaryWindow(); gfAutoLoadA9 = FALSE; gfConfirmExitFirst = TRUE; } void ReleaseSummaryWindow() { INT32 i; UINT32 uiCurrTimer; if( !gfSummaryWindowActive || gfPersistantSummary ) return; uiCurrTimer = GetJA2Clock(); if( !gfWorldLoaded || uiCurrTimer - giInitTimer < 400 ) { //make window persistant for( i = 1; i < NUM_SUMMARY_BUTTONS; i++ ) ShowButton( iSummaryButton[ i ] ); HideButton( iSummaryButton[ SUMMARY_UPDATE ] ); HideButton( iSummaryButton[ SUMMARY_OVERRIDE ] ); HideButton( iSummaryButton[ SUMMARY_REAL ] ); HideButton( iSummaryButton[ SUMMARY_SCIFI ] ); HideButton( iSummaryButton[ SUMMARY_ENEMY ] ); MSYS_EnableRegion( &MapRegion ); gfPersistantSummary = TRUE; gfOverrideDirty = TRUE; gfRenderSummary = TRUE; } else { DestroySummaryWindow(); } } void DestroySummaryWindow() { INT32 i; if( !gfSummaryWindowActive ) return; for( i = 0; i < NUM_SUMMARY_BUTTONS; i++ ) { RemoveButton( iSummaryButton[ i ] ); } MSYS_RemoveRegion( &MapRegion ); gfRenderTaskbar = TRUE;//dnl ch52 091009 gfSummaryWindowActive = FALSE; gfPersistantSummary = FALSE; MarkWorldDirty(); KillTextInputMode(); EnableEditorTaskbar(); EnableAllTextFields(); if( gpWorldItemsSummaryArray ) { delete[]( gpWorldItemsSummaryArray ); gpWorldItemsSummaryArray = NULL; gusWorldItemsSummaryArraySize = 0; } if( gpPEnemyItemsSummaryArray ) { delete[]( gpPEnemyItemsSummaryArray ); gpPEnemyItemsSummaryArray = NULL; gusPEnemyItemsSummaryArraySize = 0; } if( gpNEnemyItemsSummaryArray ) { delete[]( gpNEnemyItemsSummaryArray ); gpNEnemyItemsSummaryArray = NULL; gusNEnemyItemsSummaryArraySize = 0; } if( gfWorldLoaded ) { gfConfirmExitFirst = TRUE; } } void RenderSectorInformation() { //CHAR16 str[ 100 ]; MAPCREATE_STRUCT *m; SUMMARYFILE *s; UINT8 ePoints = 0; UINT16 usLine = 35; INT32 iOverall; SetFont( FONT10ARIAL ); SetFontShadow( FONT_NEARBLACK ); s = gpCurrentSectorSummary; m = &gpCurrentSectorSummary->MapInfo; if( m->sNorthGridNo != -1 ) ePoints++; if( m->sEastGridNo != -1 ) ePoints++; if( m->sSouthGridNo != -1 ) ePoints++; if( m->sWestGridNo != -1 ) ePoints++; if( m->sCenterGridNo != -1 ) ePoints++; if( m->sIsolatedGridNo != -1 ) ePoints++; //start at 10,35 SetFontForeground( FONT_ORANGE ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 32, L"Tileset: %s", gTilesets[ s->ubTilesetID ].zName ); if( m->ubMapVersion < 10 ) SetFontForeground( FONT_RED ); mprintf(iScreenWidthOffset+10, iScreenHeightOffset+42, L"Version Info: Summary: 1.%02d, Map: %1.2f / %02d", s->ubSummaryVersion, s->dMajorMapVersion, m->ubMapVersion);//dnl ch30 240909 SetFontForeground( FONT_GRAY2 ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 55, L"Number of items: %d", s->usNumItems ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 65, L"Number of lights: %d", s->usNumLights ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 75, L"Number of entry points: %d", ePoints ); if( ePoints ) { INT32 x; x = iScreenWidthOffset + 140; mprintf( x, iScreenHeightOffset + 75, L"(" ); x += StringPixLength( L"(", FONT10ARIAL ) + 2; if( m->sNorthGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"N" ); x += StringPixLength( L"N", FONT10ARIAL ) + 2; } if( m->sEastGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"E" ); x += StringPixLength( L"E", FONT10ARIAL ) + 2; } if( m->sSouthGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"S" ); x += StringPixLength( L"S", FONT10ARIAL ) + 2; } if( m->sWestGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"W" ); x += StringPixLength( L"W", FONT10ARIAL ) + 2; } if( m->sCenterGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"C" ); x += StringPixLength( L"C", FONT10ARIAL ) + 2; } if( m->sIsolatedGridNo != -1 ) { mprintf( x, iScreenHeightOffset + 75, L"I" ); x += StringPixLength( L"I", FONT10ARIAL ) + 2; } mprintf( x, iScreenHeightOffset + 75, L")" ); } mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 85, L"Number of rooms: %d", s->ubNumRooms ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 95, L"Total map population: %d", m->ubNumIndividuals ); mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 105, L"Enemies: %d", s->EnemyTeam.ubTotal ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 115, L"Admins: %d", s->ubNumAdmins ); if( s->ubNumAdmins ) mprintf( iScreenWidthOffset + 100, iScreenHeightOffset + 115, L"(%d detailed, %d profile -- %d have priority existance)", s->ubAdminDetailed, s->ubAdminProfile, s->ubAdminExistance ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 125, L"Troops: %d", s->ubNumTroops ); if( s->ubNumTroops ) mprintf( iScreenWidthOffset + 100, iScreenHeightOffset + 125, L"(%d detailed, %d profile -- %d have priority existance)", s->ubTroopDetailed, s->ubTroopProfile, s->ubTroopExistance ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 135, L"Elites: %d", s->ubNumElites ); if( s->ubNumElites ) mprintf( iScreenWidthOffset + 100, iScreenHeightOffset + 135, L"(%d detailed, %d profile -- %d have priority existance)", s->ubEliteDetailed, s->ubEliteProfile, s->ubEliteExistance ); mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 145, L"Civilians: %d", s->CivTeam.ubTotal ); if( s->CivTeam.ubTotal ) mprintf( iScreenWidthOffset + 100, iScreenHeightOffset + 145, L"(%d detailed, %d profile -- %d have priority existance)", s->CivTeam.ubDetailed, s->CivTeam.ubProfile, s->CivTeam.ubExistance ); if( s->ubSummaryVersion >= 9 ) { mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 155, L"Humans: %d", s->CivTeam.ubTotal - s->ubCivCows - s->ubCivBloodcats ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 165, L"Cows: %d", s->ubCivCows ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 175, L"Bloodcats: %d", s->ubCivBloodcats ); } mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 185, L"Creatures: %d", s->CreatureTeam.ubTotal ); if( s->ubSummaryVersion >= 9 ) { mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 195, L"Monsters: %d", s->CreatureTeam.ubTotal - s->CreatureTeam.ubNumAnimals ); mprintf( iScreenWidthOffset + 30, iScreenHeightOffset + 205, L"Bloodcats: %d", s->CreatureTeam.ubNumAnimals ); } mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 215, L"Number of locked and/or trapped doors: %d", s->ubNumDoors ); mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 225, L"Locked: %d", s->ubNumDoorsLocked ); mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 235, L"Trapped: %d", s->ubNumDoorsTrapped ); mprintf( iScreenWidthOffset + 20, iScreenHeightOffset + 245, L"Locked & Trapped: %d", s->ubNumDoorsLockedAndTrapped ); if( s->ubSummaryVersion >= 8 ) mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 255, L"Civilians with schedules: %d", s->ubCivSchedules ); if( s->ubSummaryVersion >= 10 ) { if( s->fTooManyExitGridDests ) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"Too many exit grid destinations (more than 4)..."); } else { UINT8 i; UINT8 ubNumInvalid = 0; for( i = 0; i < 4; i++ ) { if( s->fInvalidDest[i] ) ubNumInvalid++; } if( ubNumInvalid ) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: %d (%d with a long distance destination)", s->ubNumExitGridDests, ubNumInvalid ); } else switch( s->ubNumExitGridDests ) { case 0: mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: none" ); break; case 1: mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: 1 destination using %d exitgrids", s->usExitGridSize[0] ); break; case 2: mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: 2 -- 1) Qty: %d, 2) Qty: %d", s->usExitGridSize[0], s->usExitGridSize[1] ); break; case 3: mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: 3 -- 1) Qty: %d, 2) Qty: %d, 3) Qty: %d", s->usExitGridSize[0], s->usExitGridSize[1], s->usExitGridSize[2] ); break; case 4: mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 265, L"ExitGrids: 3 -- 1) Qty: %d, 2) Qty: %d, 3) Qty: %d, 4) Qty: %d", s->usExitGridSize[0], s->usExitGridSize[1], s->usExitGridSize[2], s->usExitGridSize[3] ); break; } } } iOverall = - ( 2 * s->EnemyTeam.ubBadA ) - s->EnemyTeam.ubPoorA + s->EnemyTeam.ubGoodA + ( 2 * s->EnemyTeam.ubGreatA ); usLine = iScreenHeightOffset + 275; mprintf( iScreenWidthOffset + 10, usLine, L"Enemy Relative Attributes: %d bad, %d poor, %d norm, %d good, %d great (%+d Overall)", s->EnemyTeam.ubBadA, s->EnemyTeam.ubPoorA, s->EnemyTeam.ubAvgA, s->EnemyTeam.ubGoodA, s->EnemyTeam.ubGreatA, iOverall ); iOverall = - ( 2 * s->EnemyTeam.ubBadE ) - s->EnemyTeam.ubPoorE + s->EnemyTeam.ubGoodE + ( 2 * s->EnemyTeam.ubGreatE ); usLine += 10; mprintf( iScreenWidthOffset + 10, usLine, L"Enemy Relative Equipment: %d bad, %d poor, %d norm, %d good, %d great (%+d Overall)", s->EnemyTeam.ubBadE, s->EnemyTeam.ubPoorE, s->EnemyTeam.ubAvgE, s->EnemyTeam.ubGoodE, s->EnemyTeam.ubGreatE, iOverall ); usLine += 10; if( s->ubSummaryVersion >= 11 ) { if( s->ubEnemiesReqWaypoints ) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 10, usLine, L"%d placements have patrol orders without any waypoints defined.", s->ubEnemiesReqWaypoints ); usLine += 10; } } if( s->ubSummaryVersion >= 13 ) { if( s->ubEnemiesHaveWaypoints ) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 10, usLine, L"%d placements have waypoints, but without any patrol orders.", s->ubEnemiesHaveWaypoints ); usLine += 10; } } if( s->ubSummaryVersion >= 12 ) { if( s->usWarningRoomNums ) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 10, usLine, L"%d gridnos have questionable room numbers. Please validate.", s->usWarningRoomNums ); } } } //2) CODE TRIGGER/ACTION NAMES void RenderItemDetails() { FLOAT dAvgExistChance, dAvgStatus; OBJECTTYPE *pItem; INT32 index, i; CHAR16 str[100]; UINT32 uiQuantity, uiExistChance, uiStatus; UINT32 uiTriggerQuantity[8], uiActionQuantity[8], uiTriggerExistChance[8], uiActionExistChance[8]; UINT32 xp, yp; INT8 bFreqIndex; SetFont( FONT10ARIAL ); SetFontForeground( FONT_GRAY2 ); SetFontShadow( FONT_NEARBLACK ); mprintf( iScreenWidthOffset + 364, iScreenHeightOffset + 49, L"R" ); mprintf( iScreenWidthOffset + 390, iScreenHeightOffset + 49, L"S" ); mprintf( iScreenWidthOffset + 364, iScreenHeightOffset + 62, L"Enemy" ); xp = iScreenWidthOffset + 5; yp = iScreenHeightOffset + 20; if( gubSummaryItemMode != ITEMMODE_ENEMY && gpWorldItemsSummaryArray ) { memset( uiTriggerQuantity, 0, 32 ); memset( uiActionQuantity, 0, 32 ); memset( uiTriggerExistChance, 0, 32 ); memset( uiActionExistChance, 0, 32 ); for( index = 1; index < MAXITEMS; index++ ) { if ( Item[index].usItemClass == 0 ) break; uiQuantity = 0; uiExistChance = 0; uiStatus = 0; for( i = 0; i < gusWorldItemsSummaryArraySize; i++ ) { if( index == SWITCH || index == ACTION_ITEM ) { if( gpWorldItemsSummaryArray[ i ].object.usItem == index ) { if( gubSummaryItemMode == ITEMMODE_SCIFI && !(gpWorldItemsSummaryArray[ i ].usFlags & WORLD_ITEM_REALISTIC_ONLY) || gubSummaryItemMode == ITEMMODE_REAL && !(gpWorldItemsSummaryArray[ i ].usFlags & WORLD_ITEM_SCIFI_ONLY) ) { pItem = &gpWorldItemsSummaryArray[ i ].object; if( !(*pItem)[0]->data.misc.bFrequency ) bFreqIndex = 7; else if( (*pItem)[0]->data.misc.bFrequency == PANIC_FREQUENCY ) bFreqIndex = 0; else if( (*pItem)[0]->data.misc.bFrequency == PANIC_FREQUENCY_2 ) bFreqIndex = 1; else if( (*pItem)[0]->data.misc.bFrequency == PANIC_FREQUENCY_3 ) bFreqIndex = 2; else if( (*pItem)[0]->data.misc.bFrequency == FIRST_MAP_PLACED_FREQUENCY + 1 ) bFreqIndex = 3; else if( (*pItem)[0]->data.misc.bFrequency == FIRST_MAP_PLACED_FREQUENCY + 2 ) bFreqIndex = 4; else if( (*pItem)[0]->data.misc.bFrequency == FIRST_MAP_PLACED_FREQUENCY + 3 ) bFreqIndex = 5; else if( (*pItem)[0]->data.misc.bFrequency == FIRST_MAP_PLACED_FREQUENCY + 4 ) bFreqIndex = 6; else continue; if( index == SWITCH ) { uiTriggerQuantity[ bFreqIndex ]++; uiTriggerExistChance[ bFreqIndex ] += 100 - gpWorldItemsSummaryArray[ i ].ubNonExistChance; } else { uiActionQuantity[ bFreqIndex ]++; uiActionExistChance[ bFreqIndex ] += 100 - gpWorldItemsSummaryArray[ i ].ubNonExistChance; } } } continue; } if( gpWorldItemsSummaryArray[ i ].object.usItem == index ) { if( gubSummaryItemMode == ITEMMODE_SCIFI && !(gpWorldItemsSummaryArray[ i ].usFlags & WORLD_ITEM_REALISTIC_ONLY) || gubSummaryItemMode == ITEMMODE_REAL && !(gpWorldItemsSummaryArray[ i ].usFlags & WORLD_ITEM_SCIFI_ONLY) ) { pItem = &gpWorldItemsSummaryArray[ i ].object; uiExistChance += (100 - gpWorldItemsSummaryArray[ i ].ubNonExistChance) * pItem->ubNumberOfObjects; uiStatus += (*pItem)[0]->data.objectStatus; uiQuantity += pItem->ubNumberOfObjects; } } } if( uiQuantity ) { if( !(yp % 20) ) SetFontForeground( FONT_LTKHAKI ); else SetFontForeground( FONT_GRAY2 ); //calc averages dAvgExistChance = (FLOAT)(uiExistChance / 100.0); dAvgStatus = uiStatus / (FLOAT)uiQuantity; //Display stats. LoadShortNameItemInfo( (UINT16)index, str ); mprintf( xp, yp, L"%s", str ); mprintf( xp + 85, yp, L"%3.02f", dAvgExistChance ); mprintf( xp + 110, yp, L"@ %3.02f%%", dAvgStatus ); yp += 10; if( yp >= (UINT32)(iScreenHeightOffset + 355 )) { xp += 170; yp = iScreenHeightOffset + 20; if( xp >= (UINT32)(iScreenWidthOffset + 300 )) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 350, iScreenHeightOffset + 350, L"TOO MANY ITEMS TO DISPLAY!"); return; } } } } //Now list the number of actions/triggers of each type for( i = 0; i < 8; i++ ) { if( uiTriggerQuantity[i] || uiActionQuantity[i] ) { if( i == 7 ) SetFontForeground( FONT_DKYELLOW ); else if( !uiTriggerQuantity[i] || !uiActionQuantity[i] ) SetFontForeground( FONT_RED ); else SetFontForeground( 77 ); switch( i ) { case 0: swprintf( str, L"Panic1" ); break; case 1: swprintf( str, L"Panic2" ); break; case 2: swprintf( str, L"Panic3" ); break; case 3: swprintf( str, L"Norm1" ); break; case 4: swprintf( str, L"Norm2" ); break; case 5: swprintf( str, L"Norm3" ); break; case 6: swprintf( str, L"Norm4" ); break; case 7: swprintf( str, L"Pressure Actions" ); break; } if( i < 7 ) { dAvgExistChance = (FLOAT)(uiTriggerExistChance[i] / 100.0); dAvgStatus = (FLOAT)(uiActionExistChance[i] / 100.0); mprintf( xp, yp, L"%s: %3.02f trigger(s), %3.02f action(s)", str, dAvgExistChance, dAvgStatus ); } else { dAvgExistChance = (FLOAT)(uiActionExistChance[i] / 100.0); mprintf( xp, yp, L"%s: %3.02f", str, dAvgExistChance ); } yp += 10; if( yp >= (UINT32)(iScreenHeightOffset + 355 )) { xp += 170; yp = iScreenHeightOffset + 20; if( xp >= (UINT32)(iScreenWidthOffset + 300 )) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 350, iScreenHeightOffset + 350, L"TOO MANY ITEMS TO DISPLAY!"); return; } } } } } else if( gubSummaryItemMode == ITEMMODE_ENEMY ) { SetFontForeground( FONT_YELLOW ); mprintf( xp, yp, L"PRIORITY ENEMY DROPPED ITEMS" ); yp += 10; //Do the priority existance guys first if( !gpPEnemyItemsSummaryArray ) { SetFontForeground( FONT_DKYELLOW ); mprintf( xp, yp, L"None" ); yp += 10; } else for( index = 1; index < MAXITEMS; index++ ) { if ( Item[index].usItemClass == 0 ) break; uiQuantity = 0; uiExistChance = 0; uiStatus = 0; for( i = 0; i < gusPEnemyItemsSummaryArraySize; i++ ) { if( gpPEnemyItemsSummaryArray[ i ].usItem == index ) { pItem = &gpPEnemyItemsSummaryArray[ i ]; uiExistChance += 100 * pItem->ubNumberOfObjects; uiStatus += (*pItem)[0]->data.objectStatus; uiQuantity += pItem->ubNumberOfObjects; } } if( uiQuantity ) { if( !(yp % 20) ) SetFontForeground( FONT_LTKHAKI ); else SetFontForeground( FONT_GRAY2 ); //calc averages dAvgExistChance = (FLOAT)(uiExistChance / 100.0); dAvgStatus = uiStatus / (FLOAT)uiQuantity; //Display stats. LoadShortNameItemInfo( (UINT16)index, str ); mprintf( xp, yp, L"%s", str ); mprintf( xp + 85, yp, L"%3.02f", dAvgExistChance ); mprintf( xp + 110, yp, L"@ %3.02f%%", dAvgStatus ); yp += 10; if( yp >= (UINT32)(iScreenHeightOffset + 355 )) { xp += 170; yp = (iScreenHeightOffset + 20); if( xp >= (UINT32)(iScreenWidthOffset + 300 )) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 350, iScreenHeightOffset + 350, L"TOO MANY ITEMS TO DISPLAY!"); return; } } } } yp += 5; SetFontForeground( FONT_YELLOW ); mprintf( xp, yp, L"NORMAL ENEMY DROPPED ITEMS" ); yp += 10; if( yp >= (UINT32)(iScreenHeightOffset + 355 )) { xp += 170; yp = (iScreenHeightOffset + 20); if( xp >= (UINT32)(iScreenWidthOffset + 300 )) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 350, iScreenHeightOffset + 350, L"TOO MANY ITEMS TO DISPLAY!"); return; } } //Do the priority existance guys first if( !gpNEnemyItemsSummaryArray ) { SetFontForeground( FONT_DKYELLOW ); mprintf( xp, yp, L"None" ); yp += 10; } for( index = 1; index < MAXITEMS; index++ ) { if ( Item[index].usItemClass == 0 ) break; uiQuantity = 0; uiExistChance = 0; uiStatus = 0; for( i = 0; i < gusNEnemyItemsSummaryArraySize; i++ ) { if( gpNEnemyItemsSummaryArray[ i ].usItem == index ) { pItem = &gpNEnemyItemsSummaryArray[ i ]; uiExistChance += 100 * pItem->ubNumberOfObjects; uiStatus += (*pItem)[0]->data.objectStatus; uiQuantity += pItem->ubNumberOfObjects; } } if( uiQuantity ) { if( !(yp % 20) ) SetFontForeground( FONT_LTKHAKI ); else SetFontForeground( FONT_GRAY2 ); //calc averages dAvgExistChance = (FLOAT)(uiExistChance / 100.0); dAvgStatus = uiStatus / (FLOAT)uiQuantity; //Display stats. LoadShortNameItemInfo( (UINT16)index, str ); mprintf( xp, yp, L"%s", str ); mprintf( xp + 85, yp, L"%3.02f", dAvgExistChance ); mprintf( xp + 110, yp, L"@ %3.02f%%", dAvgStatus ); yp += 10; if( yp >= (UINT32)(iScreenHeightOffset + 355 )) { xp += 170; yp = iScreenHeightOffset + 20; if( xp >= (UINT32)(iScreenWidthOffset + 300 )) { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 350, iScreenHeightOffset + 350, L"TOO MANY ITEMS TO DISPLAY!"); return; } } } } } else { SetFontForeground( FONT_RED ); mprintf( iScreenWidthOffset + 5, iScreenHeightOffset + 50, L"ERROR: Can't load the items for this map. Reason unknown." ); } } void RenderSummaryWindow() { UINT8 *pDestBuf; UINT32 uiDestPitchBYTES; SGPRect ClipRect; INT32 i, x, y; if( (GetActiveFieldID() == 1 ) != gfTempFile ) { gfTempFile ^= 1; SetInputFieldStringWith16BitString( 1, L"" ); gfRenderSummary = TRUE; } if( gfTempFile ) //constantly extract the temp filename for updating purposes. ExtractTempFilename(); if( gfRenderSummary ) { gfRenderSummary = FALSE; gfRenderMap = TRUE; for( i = 1; i < NUM_SUMMARY_BUTTONS; i++ ) { MarkAButtonDirty( iSummaryButton[ i ] ); } DrawButton( iSummaryButton[ SUMMARY_BACKGROUND ] ); InvalidateRegion( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 120 ); SetFont( BLOCKFONT2 ); SetFontForeground( FONT_LTKHAKI ); SetFontShadow( FONT_DKKHAKI ); SetFontBackground( 0 ); if( !gfItemDetailsMode ) { mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 5, L"CAMPAIGN EDITOR -- %s Version 1.%02d", gszVersionType[ GLOBAL_SUMMARY_STATE ], GLOBAL_SUMMARY_VERSION ); } //This section builds the proper header to be displayed for an existing global summary. if( !gfWorldLoaded ) { SetFontForeground( FONT_RED ); SetFontShadow( FONT_NEARBLACK ); mprintf( iScreenWidthOffset + 270, iScreenHeightOffset + 5, L"(NO MAP LOADED)."); } SetFont( FONT10ARIAL ); SetFontShadow( FONT_NEARBLACK ); if( gfGlobalSummaryExists ) { CHAR16 str[100]; BOOLEAN fSectorSummaryExists = FALSE; if( gusNumEntriesWithOutdatedOrNoSummaryInfo && !gfOutdatedDenied ) { DisableButton( iSummaryButton[ SUMMARY_LOAD ] ); SetFontForeground( FONT_YELLOW ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"You currently have %d outdated maps.", gusNumEntriesWithOutdatedOrNoSummaryInfo); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 30, L"The more maps that need to be updated, the longer it takes. It'll take "); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 40, L"approximately 4 minutes on a P200MMX to analyse 100 maps, so"); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 50, L"depending on your computer, it may vary."); SetFontForeground( FONT_LTRED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 65, L"Do you wish to regenerate info for ALL these maps at this time (y/n)?" ); } else if( !gsSelSectorX && !gsSectorX || gfTempFile ) { DisableButton( iSummaryButton[ SUMMARY_LOAD ] ); SetFontForeground( FONT_LTRED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"There is no sector currently selected." ); if( gfTempFile ) { SetFontForeground( FONT_YELLOW ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 30, L"Entering a temp file name that doesn't follow campaign editor conventions..." ); goto SPECIALCASE_LABEL; //OUCH!!! } else if( !gfWorldLoaded ) { SetFontForeground( FONT_YELLOW ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 30, L"You need to either load an existing map or create a new map before being" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 40, L"able to enter the editor, or you can quit (ESC or Alt+x)."); } else if(gCustomFileSectorSummary.ubSummaryVersion)//dnl ch30 150909 { gpCurrentSectorSummary = &gCustomFileSectorSummary; RenderSectorInformation(); } } else { //Build sector string if( gsSelSectorX ) x = gsSelSectorX - 1, y = gsSelSectorY - 1; else x = gsSectorX - 1, y = gsSectorY - 1; swprintf( str, L"%c%d", y + 'A', x + 1 ); swprintf( gszFilename, str ); giCurrLevel = giCurrentViewLevel; switch( giCurrentViewLevel ) { case ALL_LEVELS_MASK: //search for the highest level fSectorSummaryExists = TRUE; if( gbSectorLevels[x][y] & GROUND_LEVEL_MASK ) giCurrLevel = GROUND_LEVEL_MASK; else if( gbSectorLevels[x][y] & BASEMENT1_LEVEL_MASK ) giCurrLevel = BASEMENT1_LEVEL_MASK; else if( gbSectorLevels[x][y] & BASEMENT2_LEVEL_MASK ) giCurrLevel = BASEMENT2_LEVEL_MASK; else if( gbSectorLevels[x][y] & BASEMENT3_LEVEL_MASK ) giCurrLevel = BASEMENT3_LEVEL_MASK; else fSectorSummaryExists = FALSE; break; case ALTERNATE_LEVELS_MASK: //search for the highest alternate level fSectorSummaryExists = TRUE; if( gbSectorLevels[x][y] & ALTERNATE_GROUND_MASK ) giCurrLevel = ALTERNATE_GROUND_MASK; else if( gbSectorLevels[x][y] & ALTERNATE_B1_MASK ) giCurrLevel = ALTERNATE_B1_MASK; else if( gbSectorLevels[x][y] & ALTERNATE_B2_MASK ) giCurrLevel = ALTERNATE_B2_MASK; else if( gbSectorLevels[x][y] & ALTERNATE_B3_MASK ) giCurrLevel = ALTERNATE_B3_MASK; else fSectorSummaryExists = FALSE; break; case GROUND_LEVEL_MASK: if( gbSectorLevels[x][y] & GROUND_LEVEL_MASK ) fSectorSummaryExists = TRUE; break; case BASEMENT1_LEVEL_MASK: if( gbSectorLevels[x][y] & BASEMENT1_LEVEL_MASK ) fSectorSummaryExists = TRUE; break; case BASEMENT2_LEVEL_MASK: if( gbSectorLevels[x][y] & BASEMENT2_LEVEL_MASK ) fSectorSummaryExists = TRUE; break; case BASEMENT3_LEVEL_MASK: if( gbSectorLevels[x][y] & BASEMENT3_LEVEL_MASK ) fSectorSummaryExists = TRUE; break; case ALTERNATE_GROUND_MASK: if( gbSectorLevels[x][y] & ALTERNATE_GROUND_MASK ) fSectorSummaryExists = TRUE; break; case ALTERNATE_B1_MASK: if( gbSectorLevels[x][y] & ALTERNATE_B1_MASK ) fSectorSummaryExists = TRUE; break; case ALTERNATE_B2_MASK: if( gbSectorLevels[x][y] & ALTERNATE_B2_MASK ) fSectorSummaryExists = TRUE; break; case ALTERNATE_B3_MASK: if( gbSectorLevels[x][y] & ALTERNATE_B3_MASK ) fSectorSummaryExists = TRUE; break; } if( gbSectorLevels[x][y] ) { switch( giCurrLevel ) { case GROUND_LEVEL_MASK: giCurrLevel = 0; wcscat( str, L", ground level" ); gpCurrentSectorSummary = gpSectorSummary[x][y][0]; break; case BASEMENT1_LEVEL_MASK: giCurrLevel = 1; wcscat( str, L", underground level 1" ); gpCurrentSectorSummary = gpSectorSummary[x][y][1]; break; case BASEMENT2_LEVEL_MASK: giCurrLevel = 2; wcscat( str, L", underground level 2" ); gpCurrentSectorSummary = gpSectorSummary[x][y][2]; break; case BASEMENT3_LEVEL_MASK: giCurrLevel = 3; wcscat( str, L", underground level 3" ); gpCurrentSectorSummary = gpSectorSummary[x][y][3]; break; case ALTERNATE_GROUND_MASK: giCurrLevel = 4; wcscat( str, L", alternate G level" ); gpCurrentSectorSummary = gpSectorSummary[x][y][4]; break; case ALTERNATE_B1_MASK: giCurrLevel = 5; wcscat( str, L", alternate B1 level" ); gpCurrentSectorSummary = gpSectorSummary[x][y][5]; break; case ALTERNATE_B2_MASK: giCurrLevel = 6; wcscat( str, L", alternate B2 level" ); gpCurrentSectorSummary = gpSectorSummary[x][y][6]; break; case ALTERNATE_B3_MASK: giCurrLevel = 7; wcscat( str, L", alternate B3 level" ); gpCurrentSectorSummary = gpSectorSummary[x][y][7]; break; } } else { DisableButton( iSummaryButton[ SUMMARY_LOAD ] ); } if( fSectorSummaryExists ) { switch( giCurrLevel ) { case 0: wcscat( gszFilename, L".dat" ); break; case 1: wcscat( gszFilename, L"_b1.dat" ); break; case 2: wcscat( gszFilename, L"_b2.dat" ); break; case 3: wcscat( gszFilename, L"_b3.dat" ); break; case 4: wcscat( gszFilename, L"_a.dat" ); break; case 5: wcscat( gszFilename, L"_b1_a.dat" ); break; case 6: wcscat( gszFilename, L"_b2_a.dat" ); break; case 7: wcscat( gszFilename, L"_b3_a.dat" ); break; } swprintf( gszDisplayName, gszFilename ); EnableButton( iSummaryButton[ SUMMARY_LOAD ] ); if( gpCurrentSectorSummary ) { if( gpCurrentSectorSummary->ubSummaryVersion < GLOBAL_SUMMARY_VERSION ) ShowButton( iSummaryButton[ SUMMARY_UPDATE ] ); else HideButton( iSummaryButton[ SUMMARY_UPDATE ] ); if( !gfAlternateMaps ) SetFontForeground( FONT_YELLOW ); else SetFontForeground( FONT_LTBLUE ); if( gfItemDetailsMode ) { if( gfSetupItemDetailsMode ) { SetupItemDetailsMode( TRUE ); gfSetupItemDetailsMode = FALSE; } mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 5, L"ITEM DETAILS -- sector %s", str ); RenderItemDetails(); } else { mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"Summary Information for sector %s:", str ); HideButton( iSummaryButton[ SUMMARY_REAL ] ); HideButton( iSummaryButton[ SUMMARY_SCIFI ] ); HideButton( iSummaryButton[ SUMMARY_ENEMY ] ); RenderSectorInformation(); } } else { SetFontForeground( FONT_RED ); if( gfItemDetailsMode ) { mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 5, L"Summary Information for sector %s" , str ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 15, L"does not exist." ); } else { mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"Summary Information for sector %s" , str ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 30, L"does not exist." ); } ShowButton( iSummaryButton[ SUMMARY_UPDATE ] ); } } else { if( !gfAlternateMaps ) SetFontForeground( FONT_ORANGE ); else { SetFontForeground( FONT_DKBLUE ); SetFontShadow( 0 ); } if( gfItemDetailsMode ) mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 5, L"No information exists for sector %s.", str ); else mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"No information exists for sector %s.", str ); SetFontShadow( FONT_NEARBLACK ); switch( giCurrentViewLevel ) { case ALL_LEVELS_MASK: case GROUND_LEVEL_MASK: wcscat( gszFilename, L".dat" ); break; case BASEMENT1_LEVEL_MASK: wcscat( gszFilename, L"_b1.dat" ); break; case BASEMENT2_LEVEL_MASK: wcscat( gszFilename, L"_b2.dat" ); break; case BASEMENT3_LEVEL_MASK: wcscat( gszFilename, L"_b3.dat" ); break; case ALTERNATE_LEVELS_MASK: case ALTERNATE_GROUND_MASK: wcscat( gszFilename, L"_a.dat" ); break; case ALTERNATE_B1_MASK: wcscat( gszFilename, L"_b1_a.dat" ); break; case ALTERNATE_B2_MASK: wcscat( gszFilename, L"_b2_a.dat" ); break; case ALTERNATE_B3_MASK: wcscat( gszFilename, L"_b3_a.dat" ); break; } swprintf( gszDisplayName, gszFilename ); DisableButton( iSummaryButton[ SUMMARY_LOAD ] ); } SPECIALCASE_LABEL: if( gfOverrideDirty && gfPersistantSummary ) CalculateOverrideStatus(); if( gubOverrideStatus == INACTIVE ) { if( !gfAlternateMaps ) SetFontForeground( FONT_LTKHAKI ); else SetFontForeground( FONT_LTBLUE ); mprintf( MAP_LEFT+110, MAP_BOTTOM+55, L"FILE: %s", gszDisplayName ); } else //little higher to make room for the override checkbox and text. { if( !gfAlternateMaps ) SetFontForeground( FONT_LTKHAKI ); else SetFontForeground( FONT_LTBLUE ); mprintf( MAP_LEFT+110, MAP_BOTTOM+46, L"FILE: %s", gszDisplayName ); if( gubOverrideStatus == READONLY ) { SetFontForeground( (UINT8)(gfOverride ? FONT_YELLOW : FONT_LTRED) ); mprintf( MAP_LEFT+124, MAP_BOTTOM+61, L"Override READONLY" ); } else { SetFontForeground( (UINT8)(gfOverride ? FONT_YELLOW: FONT_ORANGE ) ); mprintf( MAP_LEFT+124, MAP_BOTTOM+61, L"Overwrite File"); } } } } else if( !gfDeniedSummaryCreation ) { SetFontForeground( FONT_GRAY1 ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"You currently have no summary data. By creating one, you will be able to keep track" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 30, L"of information pertaining to all of the sectors you edit and save. The creation process" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 40, L"will analyse all maps in your \\MAPS directory, and generate a new one. This could" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 50, L"take a few minutes depending on how many valid maps you have. Valid maps are" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 60, L"maps following the proper naming convention from a1.dat - p16.dat. Underground maps" ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 70, L"are signified by appending _b1 to _b3 before the .dat (ex: a9_b1.dat). "); SetFontForeground( FONT_LTRED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 85, L"Do you wish to do this now (y/n)?" ); } else { SetFontForeground( FONT_LTRED ); mprintf( iScreenWidthOffset + 10, iScreenHeightOffset + 20, L"No summary info. Creation denied." ); } SetFont( FONT10ARIAL ); SetFontForeground( FONT_GRAY3 ); mprintf( MAP_LEFT + 15, MAP_BOTTOM + 7, L"Grid" ); mprintf( MAP_LEFT + 65, MAP_BOTTOM + 7, L"Progress" ); mprintf( MAP_LEFT + 15, MAP_BOTTOM + 27, L"Use Alternate Maps" ); //Draw the mode tabs SetFontForeground( FONT_YELLOW ); mprintf( iScreenWidthOffset + 354, iScreenHeightOffset + 18, L"Summary" ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); RectangleDraw( TRUE, iScreenWidthOffset + 350, iScreenHeightOffset + 15, iScreenWidthOffset + 405, iScreenHeightOffset + 28, 0, pDestBuf ); UnLockVideoSurface( FRAME_BUFFER ); ShadowVideoSurfaceRectUsingLowPercentTable( FRAME_BUFFER, iScreenWidthOffset + 351, iScreenHeightOffset + 16, iScreenWidthOffset + 404, iScreenHeightOffset + 27 ); if( gpCurrentSectorSummary ) /*&& gpCurrentSectorSummary->usNumItems || gpPEnemyItemsSummaryArray && gusPEnemyItemsSummaryArraySize || gpNEnemyItemsSummaryArray && gusNEnemyItemsSummaryArraySize )*/ { SetFontForeground( FONT_YELLOW ); } else { SetFontForeground( FONT_RED ); } mprintf( iScreenWidthOffset + 354, iScreenHeightOffset + 33, L"Items" ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); RectangleDraw( TRUE, iScreenWidthOffset + 350, iScreenHeightOffset + 30, iScreenWidthOffset + 405, iScreenHeightOffset + 43, 0, pDestBuf ); UnLockVideoSurface( FRAME_BUFFER ); if( gpCurrentSectorSummary ) /*&& gpCurrentSectorSummary->usNumItems || gpPEnemyItemsSummaryArray && gusPEnemyItemsSummaryArraySize || gpNEnemyItemsSummaryArray && gusNEnemyItemsSummaryArraySize ) */ { ShadowVideoSurfaceRectUsingLowPercentTable( FRAME_BUFFER, iScreenWidthOffset + 351, iScreenHeightOffset + 31, iScreenWidthOffset + 404, iScreenHeightOffset + 42 ); } else { ShadowVideoSurfaceRect( FRAME_BUFFER, iScreenWidthOffset + 351, iScreenHeightOffset + 31, iScreenWidthOffset + 404, iScreenHeightOffset + 42 ); } SetFontForeground( FONT_GRAY2 ); } RenderButtons(); if( gfRenderMap ) { gfRenderMap = FALSE; BltVideoObjectFromIndex( FRAME_BUFFER, guiOmertaMap, 0, MAP_LEFT-2, MAP_TOP-2, VO_BLT_SRCTRANSPARENCY, NULL ); InvalidateRegion( MAP_LEFT-1, MAP_TOP-1, MAP_RIGHT+1, MAP_BOTTOM+1 ); //Draw the coordinates SetFont( SMALLCOMPFONT ); SetFontForeground( FONT_BLACK ); for( y = 0; y < 16; y++ ) { mprintf( MAP_LEFT-8, MAP_TOP+4+y*13, L"%c", 65 + y ); } for( x = 1; x <= 16; x++ ) { CHAR16 str[3]; swprintf( str, L"%d", x ); mprintf( MAP_LEFT+x*13-(13+StringPixLength( str, SMALLCOMPFONT ))/2, MAP_TOP-8, str ); } if( gfRenderGrid ) { UINT16 pos; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); for( i = 1; i <= 15; i++ ) { //draw vertical lines pos = (UINT16)(i * 13 + MAP_LEFT); LineDraw( TRUE, pos, MAP_TOP, pos, MAP_BOTTOM-1, 0, pDestBuf ); //draw horizontal lines pos = (UINT16)(i * 13 + MAP_TOP); LineDraw( TRUE, MAP_LEFT, pos, MAP_RIGHT-1, pos, 0, pDestBuf ); } UnLockVideoSurface( FRAME_BUFFER ); } if( gfRenderProgress ) { UINT8 ubNumUndergroundLevels; CHAR16 str[2]; for( y = 0; y < 16; y++ ) { ClipRect.iTop = MAP_TOP + y*13; ClipRect.iBottom = ClipRect.iTop + 12; for( x = 0; x < 16; x++ ) { if( giCurrentViewLevel == ALL_LEVELS_MASK ) { ubNumUndergroundLevels = 0; if( gbSectorLevels[x][y] & BASEMENT1_LEVEL_MASK ) ubNumUndergroundLevels++; if( gbSectorLevels[x][y] & BASEMENT2_LEVEL_MASK ) ubNumUndergroundLevels++; if( gbSectorLevels[x][y] & BASEMENT3_LEVEL_MASK ) ubNumUndergroundLevels++; if( ubNumUndergroundLevels ) { //display the number of underground levels. If there //is no ground level, then it'll be shadowed. SetFont( SMALLCOMPFONT ); SetFontForeground( FONT_YELLOW ); swprintf( str, L"%d", ubNumUndergroundLevels ); mprintf( MAP_LEFT + x*13 + 4, ClipRect.iTop + 4, str ); } if( gbSectorLevels[x][y] & GROUND_LEVEL_MASK ) { if( !gfItemDetailsMode || !gpSectorSummary[x][y][0] || gpSectorSummary[x][y][0]->usNumItems ) continue; } } else if( giCurrentViewLevel == ALTERNATE_LEVELS_MASK ) { ubNumUndergroundLevels = 0; if( gbSectorLevels[x][y] & ALTERNATE_B1_MASK ) ubNumUndergroundLevels++; if( gbSectorLevels[x][y] & ALTERNATE_B2_MASK ) ubNumUndergroundLevels++; if( gbSectorLevels[x][y] & ALTERNATE_B3_MASK ) ubNumUndergroundLevels++; if( ubNumUndergroundLevels ) { //display the number of underground levels. If there //is no ground level, then it'll be shadowed. SetFont( SMALLCOMPFONT ); SetFontForeground( FONT_YELLOW ); swprintf( str, L"%d", ubNumUndergroundLevels ); mprintf( MAP_LEFT + x*13 + 4, ClipRect.iTop + 4, str ); } if( gbSectorLevels[x][y] & ALTERNATE_GROUND_MASK ) { if( !gfItemDetailsMode || !gpSectorSummary[x][y][4] || gpSectorSummary[x][y][4]->usNumItems ) continue; } } else if( gbSectorLevels[x][y] & giCurrentViewLevel ) { if( !gfItemDetailsMode || !gpSectorSummary[x][y][giCurrLevel] || gpSectorSummary[x][y][giCurrLevel]->usNumItems ) continue; } ClipRect.iLeft = MAP_LEFT + x*13; ClipRect.iRight = ClipRect.iLeft + 12; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); Blt16BPPBufferShadowRect( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect ); if( giCurrentViewLevel == BASEMENT1_LEVEL_MASK || giCurrentViewLevel == BASEMENT2_LEVEL_MASK || giCurrentViewLevel == BASEMENT3_LEVEL_MASK || giCurrentViewLevel == ALTERNATE_B1_MASK || giCurrentViewLevel == ALTERNATE_B2_MASK || giCurrentViewLevel == ALTERNATE_B3_MASK ) Blt16BPPBufferShadowRect( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect ); UnLockVideoSurface( FRAME_BUFFER ); } } } } if( gfGlobalSummaryExists ) { pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); //Render the grid for the map currently residing in memory (blue). if( gfWorldLoaded && !gfTempFile && gsSectorX ) { x = MAP_LEFT + (gsSectorX-1) * 13 + 1; y = MAP_TOP + (gsSectorY-1) * 13 + 1; RectangleDraw( TRUE, x, y, x+11, y+11, Get16BPPColor( FROMRGB( 50, 50, 200 ) ), pDestBuf ); } //Render the grid for the sector currently in focus (red). if( gsSelSectorX > 0 && !gfTempFile ) { x = MAP_LEFT + (gsSelSectorX-1) * 13 ; y = MAP_TOP + (gsSelSectorY-1) * 13 ; RectangleDraw( TRUE, x, y, x+13, y+13, Get16BPPColor( FROMRGB( 200, 50, 50 ) ), pDestBuf ); } //Render the grid for the sector if the mouse is over it (yellow). if( gsHiSectorX > 0 ) { x = MAP_LEFT + (gsHiSectorX-1) * 13 - 1; y = MAP_TOP + (gsHiSectorY-1) * 13 - 1; RectangleDraw( TRUE, x, y, x+15, y+15, Get16BPPColor( FROMRGB( 200, 200, 50 ) ), pDestBuf ); } UnLockVideoSurface( FRAME_BUFFER ); } //Check to see if the user clicked on one of the hot spot mode change areas. if( gfLeftButtonState ) { if( !gfItemDetailsMode ) { if( gpCurrentSectorSummary ) /*&& gpCurrentSectorSummary->usNumItems || gpPEnemyItemsSummaryArray && gusPEnemyItemsSummaryArraySize || gpNEnemyItemsSummaryArray && gusNEnemyItemsSummaryArraySize )*/ { if( gusMouseXPos >= (iScreenWidthOffset + 350) && gusMouseYPos >= (iScreenHeightOffset + 30) && gusMouseXPos <= (iScreenWidthOffset + 404) && gusMouseYPos <= (iScreenHeightOffset + 42) ) { gfItemDetailsMode = TRUE; gfSetupItemDetailsMode = TRUE; gfRenderSummary = TRUE; } } } else if( gfItemDetailsMode && gusMouseXPos >= (iScreenWidthOffset + 350) && gusMouseYPos >= (iScreenHeightOffset + 15) && gusMouseXPos <= (iScreenWidthOffset + 404) && gusMouseYPos <= (iScreenHeightOffset + 27) ) { gfItemDetailsMode = FALSE; gfRenderSummary = TRUE; } } } //dnl ch30 150909 void ResetCustomFileSectorSummary(void) { memset(&gCustomFileSectorSummary, 0, sizeof(SUMMARYFILE)); } //dnl ch31 150909 void GetSectorFromFileName(STR16 szFileName, INT16& sSectorX, INT16& sSectorY, INT8& bSectorZ, BOOLEAN& fAltMap) { const int strsz = 16; CHAR16 str[strsz] = L""; if(szFileName[2] == L'.' || szFileName[2] == L'_') { str[0] = szFileName[0]; str[1] = L'0'; wmemcpy(str+2, szFileName+1, strsz-2); } else if(szFileName[1] == L'1') wmemcpy(str, szFileName, strsz); for(int i=0; i= L'A' && str[0] <= L'P') && (str[1] >= L'0' && str[1] <= L'9') && (str[2] >= L'0' && str[2] <= L'9')) { sSectorX = (str[1] - L'0') * 10 + str[2] - L'0'; sSectorY = str[0] - L'A' + 1; bSectorZ = 0; fAltMap = FALSE; if(!(sSectorX < 1 || sSectorX > 16 || sSectorY < 1 || sSectorY > 16)) { if(wcscmp(&str[3], L".DAT") == 0) return; else if(wcscmp(&str[3], L"_A.DAT") == 0) { fAltMap = TRUE;// Alternate Ground Map return; } else if(str[3] == L'_' && str[4] == L'B' && str[5] >= L'1' && str[5] <= L'3') { bSectorZ = str[5] - L'0'; if(wcscmp(&str[6], L".DAT") == 0) return; else if(wcscmp(&str[6], L"_A.DAT") == 0) { fAltMap = TRUE;// Alternate Underground Map return; } } } } sSectorX = 0; sSectorY = 0; bSectorZ = 0; fAltMap = FALSE; } void UpdateSectorSummary( STR16 gszFilename, BOOLEAN fUpdate ) { CHAR16 str[50]; CHAR8 szCoord[40]; //dnl ch31 130909 INT8 bSectorZ; BOOLEAN fAltMap; GetSectorFromFileName(gszFilename, gsSelSectorX, gsSelSectorY, bSectorZ, fAltMap); gfRenderSummary = TRUE; gfMapFileDirty = FALSE; gsSectorX = gsSelSectorX; gsSectorY = gsSelSectorY; if(!gsSectorX) { CHAR8 ubNewFilename[50]; sprintf(ubNewFilename, "%S", gszFilename); ReEvaluateWorld(ubNewFilename);//dnl ch30 150909 return; } switch(bSectorZ) { case 0: if(fAltMap) { gsSectorLayer = ALTERNATE_GROUND_MASK; giCurrLevel = 4; } else { gsSectorLayer = GROUND_LEVEL_MASK; giCurrLevel = 0; } break; case 1: if(fAltMap) { gsSectorLayer = ALTERNATE_B1_MASK; giCurrLevel = 5; } else { gsSectorLayer = BASEMENT1_LEVEL_MASK; giCurrLevel = 1; } break; case 2: if(fAltMap) { gsSectorLayer = ALTERNATE_B2_MASK; giCurrLevel = 6; } else { gsSectorLayer = BASEMENT2_LEVEL_MASK; giCurrLevel = 2; } break; case 3: if(fAltMap) { gsSectorLayer = ALTERNATE_B3_MASK; giCurrLevel = 7; } else { gsSectorLayer = BASEMENT3_LEVEL_MASK; giCurrLevel = 3; } break; } giCurrentViewLevel = gsSectorLayer; if( !(gbSectorLevels[gsSectorX-1][gsSectorY-1] & gsSectorLayer) ) { //new sector map saved, so update the global file. gbSectorLevels[gsSectorX-1][gsSectorY-1] |= gsSectorLayer; } if( fUpdate ) { SetFont( FONT10ARIAL ); SetFontForeground( FONT_LTKHAKI ); SetFontShadow( FONT_NEARBLACK ); swprintf( str, L"Analyzing map: %s...", gszFilename ); if( gfSummaryWindowActive ) { mprintf( MAP_LEFT, MAP_BOTTOM+100, str ); InvalidateRegion( MAP_LEFT, MAP_BOTTOM+100, MAP_LEFT+150, MAP_BOTTOM+110 ); CreateProgressBar( 0, MAP_LEFT, MAP_BOTTOM+110, MAP_LEFT+140, MAP_BOTTOM+120 ); } else { mprintf( (iScreenWidthOffset + 320) - StringPixLength( str, FONT10ARIAL )/2, iScreenHeightOffset + 190, str ); InvalidateRegion( iScreenWidthOffset + 200, iScreenHeightOffset + 190, iScreenWidthOffset + 400, iScreenHeightOffset + 200 ); CreateProgressBar( 0, iScreenWidthOffset + 250, iScreenHeightOffset + 200, iScreenWidthOffset + 390, iScreenHeightOffset + 210 ); } sprintf( szCoord, "%S", gszFilename ); if( gsSectorX > 9 ) szCoord[3] = '\0'; else szCoord[2] = '\0'; gusNumEntriesWithOutdatedOrNoSummaryInfo++; EvaluateWorld( szCoord, (UINT8)giCurrLevel ); RemoveProgressBar( 0 ); } else gusNumEntriesWithOutdatedOrNoSummaryInfo++; } void SummaryOkayCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { DestroySummaryWindow(); } } void SummaryToggleGridCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gfRenderGrid = (BOOLEAN)(btn->uiFlags & BUTTON_CLICKED_ON); gfRenderMap = TRUE; } } void SummaryToggleAlternateCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if( btn->uiFlags & BUTTON_CLICKED_ON ) { giCurrentViewLevel <<= 4; gfAlternateMaps = TRUE; } else { giCurrentViewLevel >>= 4; gfAlternateMaps = FALSE; } gfRenderSummary = TRUE; } } void SummarySciFiCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags |= (BUTTON_CLICKED_ON | BUTTON_DIRTY); ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags |= BUTTON_DIRTY; ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags |= BUTTON_DIRTY; gubSummaryItemMode = ITEMMODE_SCIFI; gfRenderSummary = TRUE; } } void SummaryRealCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags |= BUTTON_DIRTY; ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags |= (BUTTON_CLICKED_ON | BUTTON_DIRTY); ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags |= BUTTON_DIRTY; gubSummaryItemMode = ITEMMODE_REAL; gfRenderSummary = TRUE; } } void SummaryEnemyCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_SCIFI ] ]->uiFlags |= BUTTON_DIRTY; ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags &= ~BUTTON_CLICKED_ON; ButtonList[ iSummaryButton[ SUMMARY_REAL ] ]->uiFlags |= BUTTON_DIRTY; ButtonList[ iSummaryButton[ SUMMARY_ENEMY ] ]->uiFlags |= (BUTTON_CLICKED_ON | BUTTON_DIRTY); gubSummaryItemMode = ITEMMODE_ENEMY; gfRenderSummary = TRUE; } } void SummaryToggleProgressCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gfRenderProgress = (BOOLEAN)(btn->uiFlags & BUTTON_CLICKED_ON); gfRenderMap = TRUE; } } #include "Tile Surface.h" void PerformTest() { #if 0 OutputDebugString( "PERFORMING A NEW TEST -------------------------------------------------\n" ); memset( gbDefaultSurfaceUsed, 0, sizeof( gbDefaultSurfaceUsed ) ); giCurrentTilesetID = -1; switch( Random( 3 ) ) { case 0: LoadWorld( "J9.dat" ); break; case 1: LoadWorld( "J9_b1.dat" ); break; case 2: LoadWorld( "J9_b2.dat" ); break; } #endif } BOOLEAN HandleSummaryInput( InputAtom *pEvent ) { if( !gfSummaryWindowActive ) return FALSE; gfCtrlPressed = pEvent->usKeyState & CTRL_DOWN; if( !HandleTextInput( pEvent ) && pEvent->usEvent == KEY_DOWN || pEvent->usEvent == KEY_REPEAT ) { INT32 x; switch( pEvent->usParam ) { case ESC: if( !gfWorldLoaded ) { DestroySummaryWindow(); pEvent->usParam = 'x'; pEvent->usKeyState |= ALT_DOWN; gfOverheadMapDirty = TRUE; return FALSE; } case ENTER: if( GetActiveFieldID() == 1 ) SelectNextField(); else if( gfWorldLoaded ) DestroySummaryWindow(); break; case F6: PerformTest(); break; case F7: for( x = 0; x < 10; x++ ) PerformTest(); break; case F8: for( x = 0; x < 100; x++ ) PerformTest(); break; case 'y':case 'Y': if( gusNumEntriesWithOutdatedOrNoSummaryInfo && !gfOutdatedDenied ) { gfRenderSummary = TRUE; RegenerateSummaryInfoForAllOutdatedMaps(); } if( !gfGlobalSummaryExists && !gfDeniedSummaryCreation ) { gfGlobalSummaryExists = TRUE; CreateGlobalSummary(); gfRenderSummary = TRUE; } break; case 'n':case 'N': if( gusNumEntriesWithOutdatedOrNoSummaryInfo && !gfOutdatedDenied ) { gfOutdatedDenied = TRUE; gfRenderSummary = TRUE; } if( !gfGlobalSummaryExists && !gfDeniedSummaryCreation ) { gfDeniedSummaryCreation = TRUE; gfRenderSummary = TRUE; } break; case 'x': if (pEvent->usKeyState & ALT_DOWN ) { DestroySummaryWindow(); return FALSE; } break; case RIGHTARROW: gfRenderSummary = TRUE; if( !gsSelSectorY ) gsSelSectorY = 1; gsSelSectorX++; if( gsSelSectorX > 16 ) gsSelSectorX = 1; break; case LEFTARROW: gfRenderSummary = TRUE; if( !gsSelSectorY ) gsSelSectorY = 1; gsSelSectorX--; if( gsSelSectorX < 1 ) gsSelSectorX = 16; break; case UPARROW: gfRenderSummary = TRUE; if( !gsSelSectorX ) gsSelSectorX = 1; gsSelSectorY--; if( gsSelSectorY < 1 ) gsSelSectorY = 16; break; case DNARROW: gfRenderSummary = TRUE; if( !gsSelSectorX ) gsSelSectorX = 1; gsSelSectorY++; if( gsSelSectorY > 16 ) gsSelSectorY = 1; break; case SHIFT_LEFTARROW: break; case SHIFT_RIGHTARROW: break; } } else if( pEvent->usEvent == KEY_UP ) { //for releasing modes requiring persistant state keys switch( pEvent->usParam ) { case F5: ReleaseSummaryWindow(); break; } } return TRUE; } void CreateGlobalSummary() { #ifndef USE_VFS FILE *fp; STRING512 Dir; STRING512 ExecDir; #endif OutputDebugString( "Generating GlobalSummary Information...\n" ); gfGlobalSummaryExists = FALSE; //Set current directory to JA2\DevInfo which contains all of the summary data #ifndef USE_VFS GetExecutableDirectory( ExecDir ); sprintf( Dir, "%s\\DevInfo", ExecDir ); // Snap: save current directory //GetFileManCurrentDirectory( DataDir ); //Directory doesn't exist, so create it, and continue. if( !MakeFileManDirectory( Dir ) ) AssertMsg( 0, "Can't create new directory, JA2\\DevInfo for summary information." ); if( !SetFileManCurrentDirectory( Dir ) ) AssertMsg( 0, "Can't set to new directory, JA2\\DevInfo for summary information." ); //Generate a simple readme file. fp = fopen( "readme.txt", "w" ); Assert( fp ); fprintf( fp, "%s\n%s\n", "This information is used in conjunction with the editor.", "This directory or it's contents shouldn't be included with final release." ); fclose( fp ); #else vfs::COpenWriteFile wfile(L"DevInfo\\readme.txt",true,true); std::string str = "This information is used in conjunction with the editor.\n"; str += "This directory or it's contents shouldn't be included with final release.\n"; SGP_TRYCATCH_RETHROW( wfile->write(str.c_str(), str.length()), L"" ); #endif // Snap: Restore the data directory once we are finished. //SetFileManCurrentDirectory( DataDir ); //sprintf( Dir, "%s\\Data", ExecDir ); //SetFileManCurrentDirectory( Dir ); LoadGlobalSummary(); RegenerateSummaryInfoForAllOutdatedMaps(); gfRenderSummary = TRUE; OutputDebugString( "GlobalSummary Information generated successfully.\n" ); } void MapMoveCallback( MOUSE_REGION *reg, INT32 reason ) { static INT16 gsPrevX = 0, gsPrevY = 0; //calc current sector highlighted. if( reason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { gsPrevX = gsHiSectorX = 0; gsPrevY = gsHiSectorY = 0; gfRenderMap = TRUE; return; } gsHiSectorX = min( (reg->RelativeXPos / 13) + 1, 16 ); gsHiSectorY = min( (reg->RelativeYPos / 13) + 1, 16 ); if( gsPrevX != gsHiSectorX || gsPrevY != gsHiSectorY ) { gsPrevX = gsHiSectorX; gsPrevY = gsHiSectorY; gfRenderMap = TRUE; } } void MapClickCallback( MOUSE_REGION *reg, INT32 reason ) { static INT16 sLastX = -1, sLastY = -1; static INT32 iLastClickTime = 0; //calc current sector selected. if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if( GetActiveFieldID() == 1 ) { gsSelSectorX = 0; SelectNextField(); } gsSelSectorX = min( (reg->RelativeXPos / 13) + 1, 16 ); gsSelSectorY = min( (reg->RelativeYPos / 13) + 1, 16 ); if( gsSelSectorX != sLastX || gsSelSectorY != sLastY ) { //clicked in a new sector gfOverrideDirty = TRUE; sLastX = gsSelSectorX; sLastY = gsSelSectorY; iLastClickTime = GetJA2Clock(); switch( giCurrentViewLevel ) { case ALL_LEVELS_MASK: if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 0 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 0 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 1 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 1 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 2 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 2 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 3 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 3 ]; else gpCurrentSectorSummary = NULL; break; case GROUND_LEVEL_MASK: //already pointing to the correct level gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 0 ]; break; case BASEMENT1_LEVEL_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 1 ]; break; case BASEMENT2_LEVEL_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 2 ]; break; case BASEMENT3_LEVEL_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 3 ]; break; case ALTERNATE_LEVELS_MASK: if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 4 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 4 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 5 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 5 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 6 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 6 ]; else if( gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 7 ] ) gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 7 ]; else gpCurrentSectorSummary = NULL; break; case ALTERNATE_GROUND_MASK: //already pointing to the correct level gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 4 ]; break; case ALTERNATE_B1_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 5 ]; break; case ALTERNATE_B2_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 6 ]; break; case ALTERNATE_B3_MASK: gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1 ][ gsSelSectorY - 1 ][ 7 ]; break; } if( gpWorldItemsSummaryArray ) { delete[]( gpWorldItemsSummaryArray ); gpWorldItemsSummaryArray = NULL; gusWorldItemsSummaryArraySize = 0; } if( gfItemDetailsMode ) { if( gpCurrentSectorSummary ) /*&& gpCurrentSectorSummary->usNumItems || gpPEnemyItemsSummaryArray && gusPEnemyItemsSummaryArraySize || gpNEnemyItemsSummaryArray && gusNEnemyItemsSummaryArraySize )*/ { gfSetupItemDetailsMode = TRUE; } } } else { //clicked in same sector, check for double click INT32 iNewClickTime = GetJA2Clock(); if( iNewClickTime - iLastClickTime < 400 ) { gfFileIO = TRUE; } iLastClickTime = iNewClickTime; } gfRenderSummary = TRUE; } } void SummaryToggleLevelCallback( GUI_BUTTON *btn, INT32 reason ) { INT8 i; if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if( GetActiveFieldID() == 1 ) SelectNextField(); gfRenderSummary = TRUE; for( i = SUMMARY_ALL; i <= SUMMARY_B3; i++ ) { if( btn->IDNum == iSummaryButton[ i ] ) { switch( i ) { case SUMMARY_ALL: giCurrentViewLevel = ALL_LEVELS_MASK; break; case SUMMARY_G: giCurrentViewLevel = GROUND_LEVEL_MASK; break; case SUMMARY_B1: giCurrentViewLevel = BASEMENT1_LEVEL_MASK; break; case SUMMARY_B2: giCurrentViewLevel = BASEMENT2_LEVEL_MASK; break; case SUMMARY_B3: giCurrentViewLevel = BASEMENT3_LEVEL_MASK; break; } if( gfAlternateMaps ) giCurrentViewLevel <<= 4; } else { ButtonList[ iSummaryButton[ i ] ]->uiFlags &= (~BUTTON_CLICKED_ON); } } } } void SummaryLoadMapCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { STR16 ptr; CHAR16 str[ 50 ]; gfRenderSummary = TRUE; SetFont( FONT10ARIAL ); SetFontForeground( FONT_LTKHAKI ); SetFontShadow( FONT_NEARBLACK ); fNewMapSaved = TRUE; //swprintf( str, L"Loading map: %s...", gszDisplayName ); //mprintf( MAP_LEFT, MAP_BOTTOM+100, str ); //InvalidateRegion( MAP_LEFT, MAP_BOTTOM+100, MAP_LEFT+150, MAP_BOTTOM+110 ); CreateProgressBar( 0, MAP_LEFT+5, MAP_BOTTOM+110, iScreenWidthOffset + 573, MAP_BOTTOM+120 ); //DefineProgressBarPanel( 0, 65, 79, 94, MAP_LEFT, iScreenHeightOffset + 318, iScreenWidthOffset + 578, iScreenHeightOffset + 356 ); DefineProgressBarPanel( 0, 65, 79, 94, MAP_LEFT, iScreenHeightOffset + 318, MAP_LEFT + 161, iScreenHeightOffset + 356 ); swprintf( str, L"Loading map: %s", gszDisplayName ); SetProgressBarTitle( 0, str, BLOCKFONT2, FONT_RED, FONT_NEARBLACK ); SetProgressBarMsgAttributes( 0, SMALLCOMPFONT, FONT_BLACK, FONT_BLACK ); if( ExternalLoadMap( gszDisplayName ) ) { EnableButton( iSummaryButton[ SUMMARY_OKAY ] ); gsSectorX = gsSelSectorX; gsSectorY = gsSelSectorY; gfOverrideDirty = TRUE; gfMapFileDirty = FALSE; } RemoveProgressBar( 0 ); ptr = wcsstr( gszDisplayName, L"_b" ); if( !ptr || ptr[3] != L'.' ) { gsSectorLayer = GROUND_LEVEL_MASK; giCurrLevel = 0; } else { switch( ptr[2] - L'0' ) { case 1: gsSectorLayer = BASEMENT1_LEVEL_MASK; break; case 2: gsSectorLayer = BASEMENT2_LEVEL_MASK; break; case 3: gsSectorLayer = BASEMENT3_LEVEL_MASK; break; default: gsSectorLayer = GROUND_LEVEL_MASK; break; } } } } void SummarySaveMapCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gfRenderSummary = TRUE; if( gubOverrideStatus == INACTIVE || gfOverride == TRUE ) { if( gubOverrideStatus == READONLY ) { CHAR8 filename[40]; sprintf( filename, "MAPS\\%S", gszDisplayName ); FileClearAttributes( filename ); } if( ExternalSaveMap( gszDisplayName ) ) { if( gsSelSectorX && gsSelSectorY ) { gsSectorX = gsSelSectorX; gsSectorY = gsSelSectorY; gfMapFileDirty = FALSE; gfOverrideDirty = TRUE; } } } } } void SummaryOverrideCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gfOverride ^= TRUE; gfRenderSummary = TRUE; if( gfOverride ) EnableButton( iSummaryButton[ SUMMARY_SAVE ] ); else DisableButton( iSummaryButton[ SUMMARY_SAVE ] ); } } void CalculateOverrideStatus() { GETFILESTRUCT FileInfo; CHAR8 szFilename[40]; gfOverrideDirty = FALSE; gfOverride = FALSE; if( gfTempFile ) { CHAR8 *ptr; sprintf( szFilename, "MAPS\\%S", gszTempFilename ); if( strlen( szFilename ) == 5 ) strcat( szFilename, "test.dat" ); ptr = strstr( szFilename, "." ); if( !ptr ) strcat( szFilename, ".dat" ); else sprintf( ptr, ".dat" ); } else sprintf( szFilename, "MAPS\\%S", gszFilename ); swprintf( gszDisplayName, L"%S", &(szFilename[5]) ); if( GetFileFirst( szFilename, &FileInfo) ) { if( gfWorldLoaded ) { if( FileInfo.uiFileAttribs & ( FILE_IS_READONLY | FILE_IS_SYSTEM ) ) gubOverrideStatus = READONLY; else gubOverrideStatus = OVERWRITE; ShowButton( iSummaryButton[ SUMMARY_OVERRIDE ] ); ButtonList[ iSummaryButton[ SUMMARY_OVERRIDE ] ]->uiFlags &= (~BUTTON_CLICKED_ON); GetFileClose(&FileInfo); DisableButton( iSummaryButton[ SUMMARY_SAVE ] ); } if( gfTempFile ) EnableButton( iSummaryButton[ SUMMARY_LOAD ] ); } else { gubOverrideStatus = INACTIVE; HideButton( iSummaryButton[ SUMMARY_OVERRIDE ] ); if( gfWorldLoaded ) EnableButton( iSummaryButton[ SUMMARY_SAVE ] ); } } void LoadGlobalSummary() { HWFILE hfile; #ifndef USE_VFS STRING512 DataDir; STRING512 ExecDir; STRING512 DevInfoDir; STRING512 MapsDir; #endif UINT32 uiNumBytesRead; FLOAT dMajorVersion; INT32 x,y; CHAR8 szFilename[40]; CHAR8 szSector[6]; OutputDebugString( "Executing LoadGlobalSummary()...\n" ); // Snap: save current directory #ifndef USE_VFS GetFileManCurrentDirectory( DataDir ); #endif gfMustForceUpdateAllMaps = FALSE; gusNumberOfMapsToBeForceUpdated = 0; gfGlobalSummaryExists = FALSE; //Set current directory to JA2\DevInfo which contains all of the summary data #ifndef USE_VFS GetExecutableDirectory( ExecDir ); sprintf( DevInfoDir, "%s\\DevInfo", ExecDir ); sprintf( MapsDir, "%s\\Maps", DataDir ); //Check to make sure we have a DevInfo directory. If we don't create one! if( !SetFileManCurrentDirectory( DevInfoDir ) ) { OutputDebugString( "LoadGlobalSummary() aborted -- doesn't exist on this local computer.\n"); return; } #endif //TEMP #ifndef USE_VFS FileDelete( "_global.sum" ); #else if(FileExists("DevInfo\\_global.sum")) { FileDelete( "DevInfo\\_global.sum" ); } #endif gfGlobalSummaryExists = TRUE; //Analyse all sectors to see if matching maps exist. For any maps found, the information //will be stored in the gbSectorLevels array. Also, it attempts to load summaries for those //maps. If the summary information isn't found, then the occurrences are recorded and reported //to the user when finished to give the option to generate them. for( y = 0; y < 16; y++ ) { for( x = 0; x < 16; x++ ) { gbSectorLevels[x][y] = 0; sprintf( szSector, "%c%d", 'A' + y, x + 1 ); //main ground level #ifndef USE_VFS sprintf( szFilename, "%c%d.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= GROUND_LEVEL_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 0, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s.sum", szSector ); #endif FileDelete( szFilename ); } //main B1 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b1.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b1.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= BASEMENT1_LEVEL_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 1, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b1.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b1.sum", szSector ); #endif FileDelete( szFilename ); } //main B2 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b2.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b2.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= BASEMENT2_LEVEL_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 2, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b2.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b2.sum", szSector ); #endif FileDelete( szFilename ); } //main B3 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b3.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b3.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= BASEMENT3_LEVEL_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 3, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b3.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b3.sum", szSector ); #endif FileDelete( szFilename ); } //alternate ground level #ifndef USE_VFS sprintf( szFilename, "%c%d_a.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_a.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= ALTERNATE_GROUND_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 4, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_a.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_a.sum", szSector ); #endif FileDelete( szFilename ); } //alternate B1 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b1_a.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b1_a.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= ALTERNATE_B1_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 5, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b1_a.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b1_a.sum", szSector ); #endif FileDelete( szFilename ); } //alternate B2 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b2_a.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b2_a.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= ALTERNATE_B2_MASK; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 6, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b2_a.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b2_a.sum", szSector ); #endif FileDelete( szFilename ); } //alternate B3 level #ifndef USE_VFS sprintf( szFilename, "%c%d_b3_a.dat", 'A' + y, x + 1 ); SetFileManCurrentDirectory( MapsDir ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); SetFileManCurrentDirectory( DevInfoDir ); #else sprintf( szFilename, "Maps\\%c%d_b3_a.dat", 'A' + y, x + 1 ); hfile = NULL; if(FileExists(szFilename)) { hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); } #endif if( hfile ) { gbSectorLevels[x][y] |= ALTERNATE_B1_MASK;; FileRead( hfile, &dMajorVersion, sizeof( FLOAT ), &uiNumBytesRead ); FileClose( hfile ); LoadSummary( szSector, 7, dMajorVersion ); } else { #ifndef USE_VFS sprintf( szFilename, "%s_b3_a.sum", szSector ); #else sprintf( szFilename, "DevInfo\\%s_b3_a.sum", szSector ); #endif FileDelete( szFilename ); } } OutputDebugString( (LPCSTR)String("Sector Row %c complete... \n", y + 'A') ); } #ifndef USE_VFS // Snap: Restore the data directory once we are finished. SetFileManCurrentDirectory( DataDir ); #endif //sprintf( MapsDir, "%s\\Data", ExecDir ); //SetFileManCurrentDirectory( MapsDir ); if( gfMustForceUpdateAllMaps ) { OutputDebugString( (LPCSTR)String( "A MAJOR MAP UPDATE EVENT HAS BEEN DETECTED FOR %d MAPS!!!!.\n", gusNumberOfMapsToBeForceUpdated ) ); //ADB update it! ApologizeOverrideAndForceUpdateEverything(); } OutputDebugString( "LoadGlobalSummary() finished...\n" ); } void GenerateSummaryList() { #ifndef USE_VFS FILE *fp; STRING512 DataDir; STRING512 ExecDir; STRING512 Dir; // Snap: save current directory GetFileManCurrentDirectory( DataDir ); //Set current directory to JA2\DevInfo which contains all of the summary data GetExecutableDirectory( ExecDir ); sprintf( Dir, "%s\\DevInfo", ExecDir ); if( !SetFileManCurrentDirectory( Dir ) ) { //Directory doesn't exist, so create it, and continue. if( !MakeFileManDirectory( Dir ) ) AssertMsg( 0, "Can't create new directory, JA2\\DevInfo for summary information." ); if( !SetFileManCurrentDirectory( Dir ) ) AssertMsg( 0, "Can't set to new directory, JA2\\DevInfo for summary information." ); //Generate a simple readme file. fp = fopen( "readme.txt", "w" ); Assert( fp ); fprintf( fp, "%s\n%s\n", "This information is used in conjunction with the editor.", "This directory or it's contents shouldn't be included with final release." ); fclose( fp ); } // Snap: Restore the data directory once we are finished. SetFileManCurrentDirectory( DataDir ); //Set current directory back to data directory! //sprintf( Dir, "%s\\Data", ExecDir ); //SetFileManCurrentDirectory( Dir ); #else try { vfs::COpenWriteFile wfile(L"DevInfo/readme.txt",true,true); std::string str = "This information is used in conjunction with the editor.\n"; str += "This directory or it's contents shouldn't be included with final release.\n"; SGP_TRYCATCH_RETHROW( wfile->write(str.c_str(), str.length()), L""); } catch(std::exception &ex) { SGP_RETHROW(L"Could not create readme.txt", ex); } #endif } //dnl ch28 260909 void WriteSectorSummaryUpdate(STR8 sFileName, UINT8 ubLevel, SUMMARYFILE* pSummaryFileInfo) { CHAR8 cFileName[2*FILENAME_BUFLEN]; sprintf(cFileName, "DevInfo\\%s", sFileName); // Presumption is that file came with dat extension strcpy(cFileName+strlen(cFileName)-4, ".sum"); if(!pSummaryFileInfo->Save(cFileName)) return; UpdateMasterProgress(); INT16 sSectorX, sSectorY; INT8 x, y, bSectorZ; BOOLEAN fAltMap; CHAR16 szFileName[FILENAME_BUFLEN]; swprintf(szFileName, L"%S", sFileName); GetSectorFromFileName(szFileName, sSectorX, sSectorY, bSectorZ, fAltMap); if(!sSectorX) gCustomFileSectorSummary = *pSummaryFileInfo;//dnl ch30 150909 else { if(gusNumEntriesWithOutdatedOrNoSummaryInfo > 0) gusNumEntriesWithOutdatedOrNoSummaryInfo--; x = sSectorX - 1; y = sSectorY - 1; if(gpSectorSummary[x][y][ubLevel]) { MemFree(gpSectorSummary[x][y][ubLevel]); gpSectorSummary[x][y][ubLevel] = NULL; } gpSectorSummary[x][y][ubLevel] = pSummaryFileInfo; } } void SummaryNewGroundLevelCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gfPendingBasement = FALSE; gfPendingCaves = FALSE; if( gfWorldLoaded ) { iCurrentAction = ACTION_NEW_MAP; } else { CreateNewMap(); } } } void SummaryNewBasementLevelCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { } } void SummaryNewCaveLevelCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { } } //dnl ch28 260909 SUMMARYFILE& SUMMARYFILE::operator=(const _OLD_SUMMARYFILE& src) { if((void*)this != (void*)&src) { ubSummaryVersion = src.ubSummaryVersion; ubSpecial = src.ubSpecial; ubNumRooms = src.ubNumRooms; dMajorMapVersion = src.dMajorMapVersion; ubTilesetID = src.ubTilesetID; usNumItems = src.usNumItems; usNumLights = src.usNumLights; ubNumDoors = src.ubNumDoors; ubNumDoorsLocked = src.ubNumDoorsLocked; ubNumDoorsTrapped = src.ubNumDoorsTrapped; ubNumDoorsLockedAndTrapped = src.ubNumDoorsLockedAndTrapped; ubNumElites = src.ubNumElites; ubNumAdmins = src.ubNumAdmins; ubNumTroops = src.ubNumTroops; ubEliteDetailed = src.ubEliteDetailed; ubAdminDetailed = src.ubAdminDetailed; ubTroopDetailed = src.ubTroopDetailed; ubEliteProfile = src.ubEliteProfile; ubAdminProfile = src.ubAdminProfile; ubTroopProfile = src.ubTroopProfile; ubEliteExistance = src.ubEliteExistance; ubAdminExistance = src.ubAdminExistance; ubTroopExistance = src.ubTroopExistance; ubCivSchedules = src.ubCivSchedules; ubCivCows = src.ubCivCows; ubCivBloodcats = src.ubCivBloodcats; ubEnemiesReqWaypoints = src.ubEnemiesReqWaypoints; usWarningRoomNums = src.usWarningRoomNums; ubEnemiesHaveWaypoints = src.ubEnemiesHaveWaypoints; uiNumItemsPosition = src.uiNumItemsPosition; uiEnemyPlacementPosition = src.uiEnemyPlacementPosition; EnemyTeam = src.EnemyTeam; CreatureTeam = src.CreatureTeam; RebelTeam = src.RebelTeam; CivTeam = src.CivTeam; MapInfo = src.MapInfo; for(int i=0; i<4; i++) ExitGrid[i] = src.ExitGrid[i]; TranslateArrayFields(usExitGridSize, src.usExitGridSize, 4, UINT16_UINT16); TranslateArrayFields(fInvalidDest, src.fInvalidDest, 4, UINT8_UINT8); ubNumExitGridDests = src.ubNumExitGridDests; fTooManyExitGridDests = src.fTooManyExitGridDests; } return(*this); } BOOLEAN SUMMARYFILE::Load(STR sFileName) { if(!FileExists(sFileName)) { return FALSE; } HWFILE hFile = FileOpen(sFileName, FILE_ACCESS_READ, FALSE); if(!hFile) { return(FALSE); } UINT8 ubSummaryVersion = 0; UINT32 uiBytesRead = 0; FileRead(hFile, &ubSummaryVersion, sizeof(ubSummaryVersion), &uiBytesRead); if(ubSummaryVersion < 14 || ubSummaryVersion > GLOBAL_SUMMARY_VERSION) { FileClose(hFile); return(FALSE); } FileSeek(hFile, 0L, FILE_SEEK_FROM_START); if(ubSummaryVersion == 14) { _OLD_SUMMARYFILE OldSummaryFile; FileRead(hFile, &OldSummaryFile, sizeof(_OLD_SUMMARYFILE), &uiBytesRead); *this = OldSummaryFile; } else { FileRead(hFile, this, sizeof(SUMMARYFILE), &uiBytesRead); } FileClose(hFile); if(uiBytesRead == sizeof(_OLD_SUMMARYFILE) || uiBytesRead == sizeof(SUMMARYFILE)) { return(TRUE); } return(FALSE); } BOOLEAN SUMMARYFILE::Save(STR sFileName) { HWFILE hFile = FileOpen(sFileName, FILE_ACCESS_WRITE|FILE_CREATE_ALWAYS, FALSE); if(!hFile) return(FALSE); UINT32 uiBytesWritten = 0; FileWrite(hFile, this, sizeof(SUMMARYFILE), &uiBytesWritten); FileClose(hFile); if(uiBytesWritten != sizeof(SUMMARYFILE)) return(FALSE); return(TRUE); } BOOLEAN LoadSummary(STR8 pSector, UINT8 ubLevel, FLOAT dMajorMapVersion) { INT32 x, y; CHAR8 sFileName[2*FILENAME_BUFLEN]; SUMMARYFILE SummaryFile; sprintf(sFileName, "DevInfo\\%s", pSector); if(ubLevel % 4) { CHAR8 str[4]; sprintf(str, "_b%d", ubLevel%4); strcat(sFileName, str); } if(ubLevel >= 4) strcat(sFileName, "_a"); strcat(sFileName, ".sum"); if(!SummaryFile.Load(sFileName)) return(FALSE); y = pSector[0] - 'A'; if(pSector[2] >= '0' && pSector[2] <= '9') x = (pSector[1] - '0') * 10 + pSector[2] - '0' - 1; else x = pSector[1] - '0' - 1; if(gpSectorSummary[x][y][ubLevel]) { MemFree(gpSectorSummary[x][y][ubLevel]); gpSectorSummary[x][y][ubLevel] = NULL; } gpSectorSummary[x][y][ubLevel] = (SUMMARYFILE*)MemAlloc(sizeof(SUMMARYFILE)); if(gpSectorSummary[x][y][ubLevel]) memcpy(gpSectorSummary[x][y][ubLevel], &SummaryFile, sizeof(SUMMARYFILE)); if(gpSectorSummary[x][y][ubLevel]->ubSummaryVersion < GLOBAL_SUMMARY_VERSION) gusNumEntriesWithOutdatedOrNoSummaryInfo++; return(TRUE); } double MasterStart, MasterEnd; void UpdateMasterProgress() { if( gfUpdatingNow && gusTotal ) { MasterStart = (gusCurrent / (double)gusTotal) * 100.0; gusCurrent++; MasterEnd = (gusCurrent / (double)gusTotal) * 100.0; if( gfMajorUpdate ) { SetRelativeStartAndEndPercentage( 2, (UINT16)MasterStart, (UINT16)MasterEnd, NULL ); RenderProgressBar( 2, 0 ); } else SetRelativeStartAndEndPercentage( 1, (UINT16)MasterStart, (UINT16)MasterEnd, NULL ); } } void ReportError( STR8 pSector, UINT8 ubLevel ) { static INT32 yp = iScreenHeightOffset + 180; CHAR16 str[40]; CHAR16 temp[10]; //Make sure the file exists... if not, then return false swprintf( str, L"%S", pSector ); if( ubLevel % 4 ) { swprintf( temp, L"_b%d.dat", ubLevel % 4 ); wcscat( str, temp ); } mprintf( iScreenWidthOffset + 10, yp, L"Skipping update for %s. Probably due to tileset conflicts...", str ); InvalidateScreen(); yp++; } void RegenerateSummaryInfoForAllOutdatedMaps() { INT32 x, y; CHAR8 str[40]; SUMMARYFILE *pSF; //CreateProgressBar( 0, 20, 120, 300, 132 ); //slave (individual) //CreateProgressBar( 1, 20, 100, 300, 112 ); //master (total) //DefineProgressBarPanel( 0, 65, 79, 94, 10, 80, 310, 152 ); CreateProgressBar( 0, iScreenWidthOffset + 20, iScreenHeightOffset + 100, iScreenWidthOffset + 300, iScreenHeightOffset + 112 ); //master (total) DefineProgressBarPanel( 0, 65, 79, 94, iScreenWidthOffset + 10, iScreenHeightOffset + 80, iScreenWidthOffset + 310, iScreenHeightOffset + 132 ); SetProgressBarTitle( 0, L"Generating map information", BLOCKFONT2, FONT_RED, FONT_NEARBLACK ); SetProgressBarMsgAttributes( 0, SMALLCOMPFONT, FONT_BLACK, FONT_BLACK ); gfUpdatingNow = TRUE; gusCurrent = 0; gusTotal = gusNumEntriesWithOutdatedOrNoSummaryInfo; UpdateMasterProgress(); for( y = 0; y < 16; y++ ) for( x = 0; x < 16; x++ ) { sprintf( str, "%c%d", y + 'A', x + 1 ); if( gbSectorLevels[x][y] & GROUND_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][0]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 0 ) ) ReportError( str, 0 ); } if( gbSectorLevels[x][y] & BASEMENT1_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][1]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 1 ) ) ReportError( str, 1 ); } if( gbSectorLevels[x][y] & BASEMENT2_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][2]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 2 ) ) ReportError( str, 2 ); } if( gbSectorLevels[x][y] & BASEMENT3_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][3]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 3 ) ) ReportError( str, 3 ); } if( gbSectorLevels[x][y] & ALTERNATE_GROUND_MASK ) { pSF = gpSectorSummary[x][y][4]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 4 ) ) ReportError( str, 4 ); } if( gbSectorLevels[x][y] & ALTERNATE_B1_MASK ) { pSF = gpSectorSummary[x][y][5]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 5 ) ) ReportError( str, 5 ); } if( gbSectorLevels[x][y] & ALTERNATE_B2_MASK ) { pSF = gpSectorSummary[x][y][6]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 6 ) ) ReportError( str, 6 ); } if( gbSectorLevels[x][y] & ALTERNATE_B3_MASK ) { pSF = gpSectorSummary[x][y][7]; if( !pSF || pSF->ubSummaryVersion != GLOBAL_SUMMARY_VERSION ) if( !EvaluateWorld( str, 7 ) ) ReportError( str, 7 ); } } RemoveProgressBar( 0 ); RemoveProgressBar( 1 ); gfUpdatingNow = FALSE; } void SummaryUpdateCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { CHAR8 str[40]; CreateProgressBar( 0, iScreenWidthOffset + 20, iScreenHeightOffset + 100, iScreenWidthOffset + 300, iScreenHeightOffset + 112 ); //slave (individual) DefineProgressBarPanel( 0, 65, 79, 94, iScreenWidthOffset + 10, iScreenHeightOffset + 80, iScreenWidthOffset + 310, iScreenHeightOffset + 132 ); SetProgressBarTitle( 0, L"Generating map summary", BLOCKFONT2, FONT_RED, FONT_NEARBLACK ); SetProgressBarMsgAttributes( 0, SMALLCOMPFONT, FONT_BLACK, FONT_BLACK ); #if 0 // 0verhaul: This should NOT be freed. An array index can be freed when it is recalculated, // as this function is about to do. And then it SHOULD be freed first, which it wasn't doing. // Either way, using this pointer is not a safe way to free the current sector's summary data. if( gpCurrentSectorSummary ) { MemFree( gpCurrentSectorSummary ); gpCurrentSectorSummary = NULL; } #endif sprintf( str, "%c%d", gsSelSectorY + 'A' - 1, gsSelSectorX ); EvaluateWorld( str, (UINT8)giCurrLevel ); // ADB: The current sector summary should be set to the array value, not the other way around. // Also the sector X and Y values are 1-based and the array is 0-based. So subtract 1 from X and Y gpCurrentSectorSummary = gpSectorSummary[ gsSelSectorX - 1][ gsSelSectorY - 1][ giCurrLevel ]; gfRenderSummary = TRUE; RemoveProgressBar( 0 ); } } void ExtractTempFilename() { //dnl ch39 190909 CHAR16 str[FILENAME_BUFLEN-4]; Get16BitStringFromField(1, str, FILENAME_BUFLEN-4); if( wcscmp( gszTempFilename, str ) ) { wcscpy( gszTempFilename, str ); gfRenderSummary = TRUE; gfOverrideDirty = TRUE; } if( !wcslen( str ) ) swprintf( gszDisplayName, L"test.dat" ); } //dnl ch30 170909 BOOLEAN ReEvaluateWorld(const STR8 puiFilename) { UINT8 ubLevel; CHAR8 name[50]; INT16 sSectorX, sSectorY; INT8 bSectorZ; BOOLEAN fAltMap; CHAR16 szFileName[50]; swprintf(szFileName, L"%S", puiFilename); GetSectorFromFileName(szFileName, sSectorX, sSectorY, bSectorZ, fAltMap); /* switch(bSector) { case 1: ubLevel = 1; if(fAltMap) ubLevel = 5; break; case 2: ubLevel = 2; if(fAltMap) ubLevel = 6; break; case 3: ubLevel = 3; if(fAltMap) ubLevel = 7; break; default: ubLevel = 0; if(fAltMap) ubLevel = 4; break; } */ ubLevel = bSectorZ; if(fAltMap) ubLevel += 4; if(sSectorX) sprintf(name, "%c%d", (sSectorY-1+'A'), sSectorX); else strcpy(name, puiFilename); if(!EvaluateWorld(name, ubLevel)) return(FALSE); return(TRUE); } void ApologizeOverrideAndForceUpdateEverything() { INT32 x, y; CHAR16 str[ 128 ]; CHAR8 name[50]; SUMMARYFILE *pSF; //Create one huge assed button gfMajorUpdate = TRUE; iSummaryButton[ SUMMARY_BACKGROUND ] = CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK ); SpecifyDisabledButtonStyle( iSummaryButton[ SUMMARY_BACKGROUND ], DISABLED_STYLE_NONE ); DisableButton( iSummaryButton[ SUMMARY_BACKGROUND ] ); //Draw it DrawButton( iSummaryButton[ SUMMARY_BACKGROUND ] ); InvalidateRegion( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); SetFont( HUGEFONT ); SetFontForeground( FONT_RED ); SetFontShadow( FONT_NEARBLACK ); swprintf( str, L"MAJOR VERSION UPDATE" ); mprintf( (iScreenWidthOffset + 320) - StringPixLength( str, HUGEFONT )/2, iScreenHeightOffset + 105, str ); SetFont( FONT10ARIAL ); SetFontForeground( FONT_YELLOW ); swprintf( str, L"There are %d maps requiring a major version update.", gusNumberOfMapsToBeForceUpdated ); mprintf( (iScreenWidthOffset + 320) - StringPixLength( str, FONT10ARIAL )/2, iScreenHeightOffset + 130, str ); CreateProgressBar( 2, iScreenWidthOffset + 120, iScreenHeightOffset + 170, iScreenWidthOffset + 520, iScreenHeightOffset + 202 ); DefineProgressBarPanel( 2, 65, 79, 94, iScreenWidthOffset + 100, iScreenHeightOffset + 150, iScreenWidthOffset + 540, iScreenHeightOffset + 222 ); SetProgressBarTitle( 2, L"Updating all outdated maps", BLOCKFONT2, FONT_RED, 0 ); SetProgressBarMsgAttributes( 2, SMALLCOMPFONT, FONT_BLACK, FONT_BLACK ); gusCurrent = 0; gusTotal = gusNumberOfMapsToBeForceUpdated; gfUpdatingNow = TRUE; UpdateMasterProgress(); for( y = 0; y < 16; y++ ) for( x = 0; x < 16; x++ ) { sprintf( name, "%c%d", y + 'A', x + 1 ); if( gbSectorLevels[x][y] & GROUND_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][0]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 0 ) ) return; } } if( gbSectorLevels[x][y] & BASEMENT1_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][1]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 1 ) ) return; } } if( gbSectorLevels[x][y] & BASEMENT2_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][2]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 2 ) ) return; } } if( gbSectorLevels[x][y] & BASEMENT3_LEVEL_MASK ) { pSF = gpSectorSummary[x][y][3]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 3 ) ) return; } } if( gbSectorLevels[x][y] & ALTERNATE_GROUND_MASK ) { pSF = gpSectorSummary[x][y][4]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 4 ) ) return; } } if( gbSectorLevels[x][y] & ALTERNATE_B1_MASK ) { pSF = gpSectorSummary[x][y][5]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 5 ) ) return; } } if( gbSectorLevels[x][y] & ALTERNATE_B2_MASK ) { pSF = gpSectorSummary[x][y][6]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 6 ) ) return; } } if( gbSectorLevels[x][y] & ALTERNATE_B3_MASK ) { pSF = gpSectorSummary[x][y][7]; if( !pSF || pSF->ubSummaryVersion < MINIMUMVERSION || pSF->dMajorMapVersion < gdMajorMapVersion ) { gpCurrentSectorSummary = pSF; if( !EvaluateWorld( name, 7 ) ) return; } } } // ADB: The call to EvaluateWorld does not use the .dat extension EvaluateWorld( "A9", 0 ); RemoveProgressBar( 2 ); gfUpdatingNow = FALSE; InvalidateScreen(); RemoveButton( iSummaryButton[ SUMMARY_BACKGROUND ] ); gfMajorUpdate = FALSE; gfMustForceUpdateAllMaps = FALSE; gusNumberOfMapsToBeForceUpdated = 0; } //CHRISL: ADB changed the way this load file is handled extern int gEnemyPreservedTempFileVersion[256]; extern int gCivPreservedTempFileVersion[256]; void SetupItemDetailsMode( BOOLEAN fAllowRecursion ) { HWFILE hfile; UINT32 uiNumBytesRead; UINT32 uiNumItems; CHAR8 szFilename[40]; BASIC_SOLDIERCREATE_STRUCT basic; SOLDIERCREATE_STRUCT priority; INT32 i, j; UINT16 usNumItems; OBJECTTYPE *pItem; UINT16 usPEnemyIndex, usNEnemyIndex; SUMMARYFILE *s = gpCurrentSectorSummary; MAPCREATE_STRUCT *m = &gpCurrentSectorSummary->MapInfo; //Clear memory for all the item summaries loaded if( gpWorldItemsSummaryArray ) { delete[]( gpWorldItemsSummaryArray ); gpWorldItemsSummaryArray = NULL; gusWorldItemsSummaryArraySize = 0; } if( gpPEnemyItemsSummaryArray ) { delete[]( gpPEnemyItemsSummaryArray ); gpPEnemyItemsSummaryArray = NULL; gusPEnemyItemsSummaryArraySize = 0; } if( gpNEnemyItemsSummaryArray ) { delete[]( gpNEnemyItemsSummaryArray ); gpNEnemyItemsSummaryArray = NULL; gusNEnemyItemsSummaryArraySize = 0; } if( !gpCurrentSectorSummary->uiNumItemsPosition ) { //Don't have one, so generate them if( gpCurrentSectorSummary->ubSummaryVersion == GLOBAL_SUMMARY_VERSION ) gusNumEntriesWithOutdatedOrNoSummaryInfo++; SummaryUpdateCallback( ButtonList[ iSummaryButton[ SUMMARY_UPDATE ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); } //Open the original map for the sector sprintf( szFilename, "MAPS\\%S", gszFilename ); hfile = FileOpen( szFilename, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); if( !hfile ) { //The file couldn't be found! return; } // ADB: The uiNumItemsPosition may be 0 here due to the recursion further down. // If so, skip the read uiNumItems = 0; if (gpCurrentSectorSummary->uiNumItemsPosition) { //Now fileseek directly to the file position where the number of world items are stored if( !FileSeek( hfile, gpCurrentSectorSummary->uiNumItemsPosition, FILE_SEEK_FROM_START ) ) { //Position couldn't be found! FileClose( hfile ); return; } //Now load the number of world items from the map. FileRead( hfile, &uiNumItems, 4, &uiNumBytesRead ); if( uiNumBytesRead != 4 ) { //Invalid situation. FileClose( hfile ); return; } } //Now compare this number with the number the summary thinks we should have. If they are different, //then the summary doesn't match the map. What we will do is force regenerate the map so that they do //match if( uiNumItems != gpCurrentSectorSummary->usNumItems && fAllowRecursion ) { FileClose( hfile ); gpCurrentSectorSummary->uiNumItemsPosition = 0; SetupItemDetailsMode( FALSE ); return; } //Passed the gauntlet, so now allocate memory for it, and load all the world items into this array. ShowButton( iSummaryButton[ SUMMARY_SCIFI ] ); ShowButton( iSummaryButton[ SUMMARY_REAL ] ); ShowButton( iSummaryButton[ SUMMARY_ENEMY ] ); gpWorldItemsSummaryArray = new WORLDITEM[ uiNumItems ]; gusWorldItemsSummaryArraySize = gpCurrentSectorSummary->usNumItems; for (unsigned int x = 0; x < uiNumItems; ++x) { gpWorldItemsSummaryArray[x].Load(hfile, s->dMajorMapVersion, m->ubMapVersion); } //NOW, do the enemy's items! //We need to do two passes. The first pass simply processes all the enemies and counts all the droppable items //keeping track of two different values. The first value is the number of droppable items that come off of //enemy detailed placements, the other counter keeps track of the number of droppable items that come off of //normal enemy placements. After doing this, the memory is allocated for the tables that will store all the item //summary information, then the second pass will repeat the process, except it will record the actual items. //PASS #1 if( !FileSeek( hfile, gpCurrentSectorSummary->uiEnemyPlacementPosition, FILE_SEEK_FROM_START ) ) { //Position couldn't be found! FileClose( hfile ); return; } for( i = 0; i < gpCurrentSectorSummary->MapInfo.ubNumIndividuals ; i++ ) { FileRead( hfile, &basic, sizeof( BASIC_SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( BASIC_SOLDIERCREATE_STRUCT ) ) { //Invalid situation. FileClose( hfile ); return; } if( basic.fDetailedPlacement ) { //skip static priority placement if ( !priority.Load(hfile, SAVE_GAME_VERSION, false) ) { //Invalid situation. FileClose( hfile ); return; } } else { //non detailed placements don't have items, so skip continue; } if( basic.bTeam == ENEMY_TEAM ) { //Count the items that this enemy placement drops usNumItems = 0; for( j = 0; j < 9; j++ ) { pItem = &priority.Inv[ gbMercSlotTypes[ j ] ]; if( pItem->exists() == true && !( (*pItem).fFlags & OBJECT_UNDROPPABLE ) ) { usNumItems++; } } if( basic.fPriorityExistance ) { gusPEnemyItemsSummaryArraySize += usNumItems; } else { gusNEnemyItemsSummaryArraySize += usNumItems; } } } //Pass 1 completed, so now allocate enough space to hold all the items if( gusPEnemyItemsSummaryArraySize ) { gpPEnemyItemsSummaryArray = new OBJECTTYPE[ gusPEnemyItemsSummaryArraySize ]; } if( gusNEnemyItemsSummaryArraySize ) { gpNEnemyItemsSummaryArray = new OBJECTTYPE[ gusNEnemyItemsSummaryArraySize ]; } //PASS #2 //During this pass, simply copy all the data instead of counting it, now that we have already done so. usPEnemyIndex = usNEnemyIndex = 0; if( !FileSeek( hfile, gpCurrentSectorSummary->uiEnemyPlacementPosition, FILE_SEEK_FROM_START ) ) { //Position couldn't be found! FileClose( hfile ); return; } for( i = 0; i < gpCurrentSectorSummary->MapInfo.ubNumIndividuals ; i++ ) { FileRead( hfile, &basic, sizeof( BASIC_SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( BASIC_SOLDIERCREATE_STRUCT ) ) { //Invalid situation. FileClose( hfile ); return; } if( basic.fDetailedPlacement ) { //skip static priority placement if ( !priority.Load(hfile, SAVE_GAME_VERSION, false) ) { //Invalid situation. FileClose( hfile ); return; } } else { //non detailed placements don't have items, so skip continue; } if( basic.bTeam == ENEMY_TEAM ) { //Copy the items that this enemy placement drops usNumItems = 0; for( j = 0; j < 9; j++ ) { pItem = &priority.Inv[ gbMercSlotTypes[ j ] ]; if( pItem->exists() == true && !( (*pItem).fFlags & OBJECT_UNDROPPABLE ) ) { if( basic.fPriorityExistance ) { gpPEnemyItemsSummaryArray[ usPEnemyIndex ] = *pItem; usPEnemyIndex++; } else { gpNEnemyItemsSummaryArray[ usNEnemyIndex ] = *pItem; usNEnemyIndex++; } } } } } FileClose( hfile ); } UINT8 GetCurrentSummaryVersion() { if( gpCurrentSectorSummary ) { return gpCurrentSectorSummary->MapInfo.ubMapVersion; } return 0; } void ClearSummaryInfo() { for (int x = 0; x < 16; x++) { for (int y=0; y < 16; y++) { for (int z=0; z < 8; z++) { if (gpSectorSummary[x][y][z]) { MemFree( gpSectorSummary[x][y][z]); gpSectorSummary[x][y][z] = NULL; } } } } } #endif