/* FinalSun/FinalAlert 2 Mission Editor Copyright (C) 1999-2024 Electronic Arts, Inc. Authored by Matthias Wagner This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ // // Main dialog implementation // #include "stdafx.h" #include "structs.h" #include "FinalSun.h" #include "FinalSunDlg.h" #include "tsoptions.h" #include "info.h" #include "loading.h" #include "MapOpenDialog.h" //#include "NewMap->h" #include "newmapcreatedlg.h" #include "newmapcreatenewdlg.h" #include "newmapimportdlg.h" #include "newmapspdlg.h" #include "newmaptypedlg.h" #include "MapValidator.h" #include "ShutDownDlg.h" #include "SavingDlg.h" #include "functions.h" #include "mapdata.h" #include "variables.h" #include "GlobalsDlg.h" #include "savemapoptionsdlg.h" #include "MissionEditorPackLib.h" #include "bitmap2mapconverter.h" #include "multisaveoptionsdlg.h" #include "mmxsavingoptionsdlg.h" #include #include "inlines.h" #include "MapCode.h" #include "SearchWaypointDlg.h" #include "userscriptsdlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include #include #include #include #include using std::endl; extern ACTIONDATA AD; extern BOOL bNoDraw; extern char AppPath[MAX_PATH + 1]; extern const std::string u8AppDataPath; extern BOOL bMiniMapClosedByUser; HCURSOR m_hArrowCursor = NULL; static UINT indicators[] = { ID_SEPARATOR, // Sstatus bar ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; #define ID_STATBAR 26111 ///////////////////////////////////////////////////////////////////////////// // CFinalSunDlg Dialogfeld CFinalSunDlg::CFinalSunDlg(CWnd* pParent /*=NULL*/) : CDialog(CFinalSunDlg::IDD, pParent) { //{{AFX_DATA_INIT(CFinalSunDlg) // HINWEIS: Der Klassenassistent fügt hier Member-Initialisierung ein //}}AFX_DATA_INIT // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_hGameCursor = AfxGetApp()->LoadCursor(MAKEINTRESOURCE(IDC_EDITOR_ARROW)); m_hArrowCursor = m_hGameCursor; } void CFinalSunDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFinalSunDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CFinalSunDlg, CDialog) //{{AFX_MSG_MAP(CFinalSunDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_COMMAND(ID_FILE_QUIT, OnFileQuit) ON_WM_SYSCOMMAND() ON_COMMAND(ID_OPTIONS_TIBERIANSUNOPTIONS, OnOptionsTiberiansunoptions) ON_COMMAND(ID_FILE_OPENMAP, OnFileOpenmap) ON_COMMAND(ID_FILE_SAVEAS, OnFileSaveas) ON_COMMAND(ID_OPTIONS_EXPORTRULESINI, OnOptionsExportrulesini) ON_COMMAND(ID_HELP_INFO, OnHelpInfo) ON_WM_SHOWWINDOW() ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_WM_MENUSELECT() ON_COMMAND(ID_FILE_RUNTIBERIANSUN, OnFileRuntiberiansun) ON_COMMAND(ID_FILE_IMPORTMOD, OnFileImportmod) ON_COMMAND(ID_DEBUG_EXPORTMAPPACKNOSECTIONS, OnDebugExportmappacknosections) ON_COMMAND(ID_DEBUG_EXPORTMAPPACK, OnDebugExportmappack) ON_COMMAND(ID_FILE_NEW, OnFileNew) ON_COMMAND(ID_HELP_TIPOFTHEDAY, OnHelpTipoftheday) ON_COMMAND(ID_OPTIONS_SIMPLEVIEW, OnOptionsSimpleview) ON_COMMAND(ID_OPTIONS_SHOWMINIMAP, OnOptionsShowminimap) ON_COMMAND(ID_FILE_VALIDATEMAP, OnFileValidatemap) ON_WM_ENTERIDLE() ON_COMMAND(ID_EDIT_BASICSETTINGS, OnEditBasicsettings) ON_COMMAND(ID_EDIT_SINGLEPLAYERSETTINGS, OnEditSingleplayersettings) ON_WM_SIZING() ON_WM_SIZE() ON_COMMAND(ID_EDIT_HOUSES, OnEditHouses) ON_COMMAND(ID_EDIT_AITRIGGERS, OnEditAitriggers) ON_COMMAND(ID_EDIT_AITRIGGERENABLING, OnEditAitriggerenabling) ON_COMMAND(ID_EDIT_INIEDITING, OnEditIniediting) ON_COMMAND(ID_EDIT_LIGHTING, OnEditLighting) ON_COMMAND(ID_EDIT_MAP, OnEditMap) ON_COMMAND(ID_EDIT_SCRIPTS, OnEditScripts) ON_COMMAND(ID_EDIT_SPECIALFLAGS, OnEditSpecialflags) ON_COMMAND(ID_EDIT_TAGS, OnEditTags) ON_COMMAND(ID_EDIT_TASKFORCES, OnEditTaskforces) ON_COMMAND(ID_EDIT_TEAMS, OnEditTeams) ON_COMMAND(ID_EDIT_TRIGGERS, OnEditTriggers) ON_WM_SETFOCUS() ON_COMMAND(ID_TERRAIN_HEIGHTENGROUND, OnTerrainHeightenground) ON_COMMAND(ID_TERRAIN_LOWERGROUND, OnTerrainLowerground) ON_COMMAND(ID_TERRAIN_LOWERTILE, OnTerrainLowertile) ON_COMMAND(ID_TERRAIN_RAISETILE, OnTerrainRaisetile) ON_COMMAND(ID_TERRAIN_FLATTEN, OnTerrainFlatten) ON_COMMAND(ID_TERRAIN_CLOAK, OnTerrainCloak) ON_COMMAND(ID_TERRAIN_SHOWEVERYTILE, OnTerrainShoweverytile) ON_COMMAND(ID_TERRAIN_SHOWALLFIELDS, OnTerrainShowallfields) ON_COMMAND(ID_TERRAIN_HIDEFIELD, OnTerrainHidefield) ON_COMMAND(ID_EDIT_TRIGGEREDITOR, OnEditTriggereditor) ON_WM_KEYDOWN() ON_COMMAND(ID_MAPTOOLS_CHANGEMAPHEIGHT, OnMaptoolsChangemapheight) ON_COMMAND(ID_EDIT_GLOBALVARIABLES, OnEditGlobalvariables) ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) ON_COMMAND(ID_HELP, OnHelpManual) ON_COMMAND(ID_HELP_SHOWLOGS, &CFinalSunDlg::OnHelpShowlogs) ON_COMMAND(ID_MAPTOOLS_AUTOLEVEL, OnMaptoolsAutolevel) ON_UPDATE_COMMAND_UI(ID_EDIT_AITRIGGERENABLING, OnUpdateEditAitriggerenabling) ON_UPDATE_COMMAND_UI(ID_EDIT_AITRIGGERS, OnUpdateEditAitriggers) ON_UPDATE_COMMAND_UI(ID_EDIT_BASICSETTINGS, OnUpdateEditBasicsettings) ON_UPDATE_COMMAND_UI(ID_EDIT_GLOBALVARIABLES, OnUpdateEditGlobalvariables) ON_UPDATE_COMMAND_UI(ID_EDIT_HOUSES, OnUpdateEditHouses) ON_UPDATE_COMMAND_UI(ID_EDIT_INIEDITING, OnUpdateEditIniediting) ON_UPDATE_COMMAND_UI(ID_EDIT_LIGHTING, OnUpdateEditLighting) ON_UPDATE_COMMAND_UI(ID_EDIT_MAP, OnUpdateEditMap) ON_UPDATE_COMMAND_UI(ID_EDIT_SCRIPTS, OnUpdateEditScripts) ON_UPDATE_COMMAND_UI(ID_EDIT_SINGLEPLAYERSETTINGS, OnUpdateEditSingleplayersettings) ON_UPDATE_COMMAND_UI(ID_EDIT_SPECIALFLAGS, OnUpdateEditSpecialflags) ON_UPDATE_COMMAND_UI(ID_EDIT_TAGS, OnUpdateEditTags) ON_UPDATE_COMMAND_UI(ID_EDIT_TASKFORCES, OnUpdateEditTaskforces) ON_UPDATE_COMMAND_UI(ID_EDIT_TEAMS, OnUpdateEditTeams) ON_UPDATE_COMMAND_UI(ID_EDIT_TRIGGEREDITOR, OnUpdateEditTriggereditor) ON_UPDATE_COMMAND_UI(ID_EDIT_TRIGGERS, OnUpdateEditTriggers) ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave) ON_UPDATE_COMMAND_UI(ID_FILE_SAVEAS, OnUpdateFileSaveas) ON_UPDATE_COMMAND_UI(ID_FILE_VALIDATEMAP, OnUpdateFileValidatemap) ON_UPDATE_COMMAND_UI(ID_MAPTOOLS_AUTOLEVEL, OnUpdateMaptoolsAutolevel) ON_UPDATE_COMMAND_UI(ID_MAPTOOLS_CHANGEMAPHEIGHT, OnUpdateMaptoolsChangemapheight) ON_UPDATE_COMMAND_UI(ID_OPTIONS_SHOWMINIMAP, OnUpdateOptionsShowminimap) ON_UPDATE_COMMAND_UI(ID_TERRAIN_CLOAK, OnUpdateTerrainCloak) ON_UPDATE_COMMAND_UI(ID_TERRAIN_FLATTEN, OnUpdateTerrainFlatten) ON_UPDATE_COMMAND_UI(ID_TERRAIN_HEIGHTENGROUND, OnUpdateTerrainHeightenground) ON_UPDATE_COMMAND_UI(ID_TERRAIN_HIDEFIELD, OnUpdateTerrainHidefield) ON_UPDATE_COMMAND_UI(ID_TERRAIN_LOWERGROUND, OnUpdateTerrainLowerground) ON_UPDATE_COMMAND_UI(ID_TERRAIN_LOWERTILE, OnUpdateTerrainLowertile) ON_UPDATE_COMMAND_UI(ID_TERRAIN_RAISETILE, OnUpdateTerrainRaisetile) ON_UPDATE_COMMAND_UI(ID_TERRAIN_SHOWALLFIELDS, OnUpdateTerrainShowallfields) ON_UPDATE_COMMAND_UI(ID_TERRAIN_SHOWEVERYTILE, OnUpdateTerrainShoweverytile) ON_COMMAND(ID_MAPTOOLS_FRONTCLIFF, OnMaptoolsFrontcliff) ON_COMMAND(ID_MAPTOOLS_BACKCLIFF, OnMaptoolsBackcliff) ON_COMMAND(ID_EDIT_REDO, OnEditRedo) ON_COMMAND(ID_MAPTOOLS_AUTOCREATESHORES, OnMaptoolsAutocreateshores) ON_COMMAND(ID_OPTIONS_DISABLEAUTOSHORE, OnOptionsDisableautoshore) ON_COMMAND(ID_OPTIONS_DISABLEAUTOLAT, OnOptionsDisableautolat) ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_COMMAND(ID_EDIT_COPYWHOLEMAP, OnEditCopywholemap) ON_COMMAND(ID_EDIT_PASTEWHOLEMAP, OnEditPastewholemap) ON_COMMAND(ID_MARBLEMADNESS, OnMarblemadness) ON_COMMAND(ID_OPTIONS_SOUNDS, OnOptionsSounds) ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUNDS, OnUpdateOptionsSounds) ON_COMMAND(ID_OPTIONS_DISABLESLOPECORRECTION, OnOptionsDisableslopecorrection) ON_COMMAND(ID_OPTIONS_SHOWBUILDINGOUTLINE, OnOptionsShowbuildingoutline) ON_COMMAND_EX(ID_FILE_FILE1, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE2, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE3, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE4, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE5, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE6, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE7, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE8, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE9, OnRecentFileClicked) ON_COMMAND_EX(ID_FILE_FILE10, OnRecentFileClicked) ON_COMMAND(ID_MAPTOOLS_SEARCHWAYPOINT, OnMaptoolsSearchwaypoint) ON_COMMAND(ID_MAPTOOLS_TOOLSCRIPTS, OnMaptoolsToolscripts) //}}AFX_MSG_MAP ON_COMMAND(ID_OPTIONS_SMOOTHZOOM, &CFinalSunDlg::OnOptionsSmoothzoom) ON_WM_SETCURSOR() ON_COMMAND(ID_OPTIONS_USEDEFAULTMOUSECURSOR, &CFinalSunDlg::OnOptionsUsedefaultmousecursor) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFinalSunDlg message handler BOOL CFinalSunDlg::OnInitDialog() { CDialog::OnInitDialog(); m_hArrowCursor = theApp.m_Options.useDefaultMouseCursor ? LoadCursor(NULL, IDC_ARROW) : m_hGameCursor; errstream << "CFinalSunDlg::OnInitDialog() called" << endl; errstream.flush(); ShowWindow(SW_HIDE); SetWindowPos(NULL, 0, 0, GetSystemMetrics(SM_CXFULLSCREEN), GetSystemMetrics(SM_CYFULLSCREEN), 0); SetIcon(m_hIcon, TRUE); // use big symbol SetIcon(m_hIcon, FALSE); // use small symbol CString cap; #ifndef RA2_MODE cap = GetLanguageStringACP("MainDialogCaption"); #else cap = GetLanguageStringACP("MainDialogCaptionRA2"); #endif cap += " ("; cap += GetLanguageStringACP("NoMapLoaded"); cap += ")"; SetWindowText(cap); // Matze: // July 9th: // Added toolbars auto success = true; RECT r; SIZE size_mainbar; SIZE size_terrainbar; GetClientRect(&r); r.top += 32; success = success && m_view.Create(NULL, GetLanguageStringACP("IsoCaption"), WS_CHILD, r, this); r.top = 0; r.bottom = 32; success = success && m_bar.Create(RBS_AUTOSIZE, r, this, 5000); success = success && m_maintoolbar.Create(this); success = success && m_maintoolbar.LoadToolBar(IDR_MAINFRAME); m_maintoolbar.GetToolBarCtrl().SetStyle(m_maintoolbar.GetToolBarCtrl().GetStyle() | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS); success = success && m_maintoolbar.GetToolBarCtrl().GetMaxSize(&size_mainbar); success = success && m_terraintoolbar.Create(this); success = success && m_terraintoolbar.LoadToolBar(IDR_TERRAINBAR); m_terraintoolbar.GetToolBarCtrl().SetStyle(m_terraintoolbar.GetToolBarCtrl().GetStyle() | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS); success = success && m_terraintoolbar.GetToolBarCtrl().GetMaxSize(&size_terrainbar); m_terraintoolbar.SetBarStyle(m_terraintoolbar.GetBarStyle()); success = success && m_clifftoolbar.Create(this); success = success && m_clifftoolbar.LoadToolBar(IDR_CLIFFBAR); m_clifftoolbar.GetToolBarCtrl().SetStyle(m_clifftoolbar.GetToolBarCtrl().GetStyle() | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS); m_clifftoolbar.SetBarStyle(m_terraintoolbar.GetBarStyle()); success = success && m_settingsbar.Create(this, IDD_TOOLSETTINGS, CBRS_TOP, 6000); REBARBANDINFO rbi = { 0 }; rbi.cbSize = sizeof(REBARBANDINFO); rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_TEXT /*| RBBIM_SIZE*/ | RBBIM_IDEALSIZE; rbi.fStyle = RBBS_GRIPPERALWAYS; rbi.cxMinChild = size_mainbar.cx + 30; rbi.cyMinChild = 30; rbi.cch = 0; rbi.cx = size_mainbar.cx + 30; rbi.cxIdeal = size_mainbar.cx + 30; rbi.hbmBack = NULL; rbi.hwndChild = (HWND)m_maintoolbar; success = success && m_bar.InsertBand(0, &rbi); rbi.hwndChild = (HWND)m_terraintoolbar; rbi.cx = size_terrainbar.cx + 30; rbi.cxIdeal = size_terrainbar.cx + 30; rbi.cxMinChild = size_terrainbar.cx + 30; success = success && m_bar.InsertBand(1, &rbi); rbi.hwndChild = (HWND)m_clifftoolbar; rbi.cx = 560; rbi.cxMinChild = 170; rbi.cxIdeal = 560; success = success && m_bar.InsertBand(2, &rbi); rbi.hwndChild = (HWND)m_settingsbar; rbi.cxMinChild = 170; rbi.cx = 170; rbi.cxIdeal = 170; success = success && m_bar.InsertBand(3, &rbi); m_bar.ShowWindow(SW_SHOW); m_maintoolbar.ShowWindow(SW_SHOW); m_terraintoolbar.ShowWindow(SW_SHOW); m_settingsbar.ShowWindow(SW_SHOW); m_bar.MinimizeBand(0); m_bar.MaximizeBand(3); if (!success) { // sometimes, insufficient resources are available. // this is a very rare case - but it happened on Win9x // especially when running the developer studio and IE5, this happens often // 04/02/2000: Should not anymore occur. MessageBox(GetLanguageStringACP("Err_InsufficientResources")); exit(-5); } errstream << "Updating menu" << endl; errstream.flush(); if (theApp.m_Options.bEasy && GetMenu()) GetMenu()->CheckMenuItem(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND | MF_CHECKED); UpdateStrings(); // Matze: // June 21, CLoading now non-modal. // CLoading will free itself // September 6th, CLoading will not free itself as it is a member of CFinalSunApp if (theApp.m_loading->m_hWnd == NULL) { MessageBox("Loading dialog could not be created. Please close any programs and start again."); exit(-99); } theApp.m_loading->ShowWindow(SW_SHOW); theApp.m_loading->UpdateWindow(); theApp.m_loading->Load(); if (!theApp.m_Options.bSupportMarbleMadness) { TBBUTTON b; m_terraintoolbar.GetToolBarCtrl().GetButton(9, &b); m_terraintoolbar.GetToolBarCtrl().HideButton(b.idCommand); m_terraintoolbar.GetToolBarCtrl().HideButton(ID_MARBLEMADNESS); } ShowWindow(SW_SHOWMAXIMIZED); CDialog::BringWindowToTop(); if (strlen(currentMapFile) == 0) // no map file specified { // ok, let the user choose a map! // hmm... no, don´t let him. we already have our tips dialog. // OnFileOpenmap(); theApp.ShowTipAtStartup(); } else // yah, map file specified { CString str = GetLanguageStringACP("MainDialogCaption"); str += " ("; str += currentMapFile; str += ")"; this->SetWindowText(str); SetCursor(LoadCursor(NULL, IDC_WAIT)); Map->LoadMap(currentMapFile); SetCursor(m_hArrowCursor); } UpdateDialogs(); #ifndef RA2_MODE CTime t = t.GetCurrentTime(); if (t.GetDay() >= 24 && t.GetDay() <= 26 && t.GetMonth() == 12) { CString str; GetWindowText(str); SetWindowText(str + " Merry Christmas! Fröhliche Weihnachten!"); } #endif return TRUE; } void CFinalSunDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // DC for painting SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0); // center symbol int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // draw symbol dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CFinalSunDlg::OnQueryDragIcon() { return (HCURSOR)m_hIcon; } void CFinalSunDlg::OnFileQuit() { UnloadAll(); } void CFinalSunDlg::OnSysCommand(UINT nID, LPARAM lParam) { if (nID == SC_CLOSE) { UnloadAll(); return; } CDialog::OnSysCommand(nID, lParam); } void CFinalSunDlg::OnOK() { //just do nothing... // this is a stub } void CFinalSunDlg::OnCancel() { //do nothing... // stub } void CFinalSunDlg::OnOptionsTiberiansunoptions() { CIniFile optini; ShowOptionsDialog(optini); } void CFinalSunDlg::OnFileOpenmap() { //CMapOpenDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST, "TS maps|*.mpr;*.map|TS multi maps|*.mpr|TS single maps|*.map|"); CString r = GetLanguageStringACP("SAVEDLG_FILETYPES"); if (yuri_mode) { r = GetLanguageStringACP("SAVEDLG_FILETYPES_YR"); } r = TranslateStringVariables(8, r, ";"); if (!yuri_mode) r.Replace(".yrm", ".mpr"); CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST, r); char cuPath[MAX_PATH]; GetCurrentDirectory(MAX_PATH, cuPath); dlg.m_ofn.lpstrInitialDir = cuPath; if (theApp.m_Options.TSExe.GetLength()) dlg.m_ofn.lpstrInitialDir = (char*)(LPCTSTR)theApp.m_Options.TSExe; if (dlg.DoModal() == IDCANCEL) return; m_PKTHeader.Clear(); CString fileToOpen = dlg.GetPathName(); fileToOpen.MakeLower(); CString ext = dlg.GetFileExt(); ext.MakeLower(); BOOL bLoadedFromMMX = FALSE; if (ext == "mmx") { HMIXFILE hMix = FSunPackLib::XCC_OpenMix(fileToOpen, NULL); fileToOpen.Replace(".mmx", ".map"); if (fileToOpen.ReverseFind('\\') >= 0) fileToOpen = fileToOpen.Right(fileToOpen.GetLength() - fileToOpen.ReverseFind('\\') - 1); CString extractFile = u8AppDataPath.c_str(); CString pktFile = fileToOpen; pktFile.Replace(".map", ".pkt"); extractFile += "\\mmx_tmp.pkt"; FSunPackLib::XCC_ExtractFile(pktFile, extractFile, hMix); m_PKTHeader.LoadFile(extractFile, TRUE); fileToOpen = m_PKTHeader.GetString("MultiMaps", "1") + ".map"; extractFile = u8AppDataPath.c_str(); extractFile += "\\mmx_tmp.map"; FSunPackLib::XCC_ExtractFile(fileToOpen, extractFile, hMix); fileToOpen = extractFile; FSunPackLib::XCC_CloseMix(hMix); bLoadedFromMMX = TRUE; } CIniFile f; f.InsertFile(fileToOpen, "Map"); auto const& theaterType = f.GetString("Map", "Theater"); if ((theaterType == THEATER0 && theApp.m_Options.bDoNotLoadTemperateGraphics) || (theaterType == THEATER1 && theApp.m_Options.bDoNotLoadSnowGraphics)) { MessageBox("You have selected to don´t show temperate or snow theater, but this map uses this theater. You cannot load it without restarting FinalSun/FinalAlert 2 with this theater enabled.", "Error"); return; } bNoDraw = TRUE; CString str; str = GetLanguageStringACP("MainDialogCaption"); str += " ("; str += (char*)(LPCTSTR)dlg.GetPathName(); str += ")"; // MW 07/20/01: Update prev. files InsertPrevFile(dlg.GetPathName()); this->SetWindowText(str); SetCursor(LoadCursor(NULL, IDC_WAIT)); errstream << "Map->LoadMap() will be called" << endl; errstream.flush(); Map->LoadMap((char*)(LPCTSTR)fileToOpen); BOOL bNoMapFile = FALSE; if (!Map->CheckMapPackData()) { int res = MessageBox("This map seems to be corrupt. Do you want to try repairing it? If you click cancel, a empty map will be created, if you click no, it will load the map as it is", "Corrupt", MB_YESNOCANCEL); if (res == IDCANCEL) { Map->CreateMap(32, 32, THEATER0, 0); bNoMapFile = TRUE; } else { if (res == IDYES) // try repair { int fielddata_size = Map->GetIsoSize() * Map->GetIsoSize(); int i; for (i = 0; i < fielddata_size; i++) { int gr = Map->GetFielddataAt(i)->wGround; if (gr == 0xFFFF) gr = 0; if (gr >= (*tiledata_count)) { Map->SetTileAt(i, 0, 0); } else { if ((*tiledata)[gr].wTileCount <= Map->GetFielddataAt(i)->bSubTile) { Map->SetTileAt(i, 0, 0); } } } } } } if (!bNoMapFile) { if (bLoadedFromMMX) { //currentMapFile[0]=0; strcpy(currentMapFile, dlg.GetPathName()); } else strcpy(currentMapFile, fileToOpen); } Sleep(200); SetCursor(m_hArrowCursor); bNoDraw = FALSE; m_view.m_isoview->UpdateDialog(TRUE); UpdateDialogs(); } void CFinalSunDlg::UpdateDialogs(BOOL bOnlyMissionControl, BOOL bNoRepos) { RepairRulesHouses(); OutputDebugString("Dialogs updated\n"); if (m_basic.m_hWnd) { m_basic.UpdateDialog(); } if (m_all.m_hWnd) { m_all.UpdateDialog(); } if (m_map.m_hWnd) { m_map.UpdateDialog(); } if (m_lighting.m_hWnd) { m_lighting.UpdateDialog(); } if (m_specialflags.m_hWnd) { m_specialflags.UpdateDialog(); } if (m_teamtypes.m_hWnd) { m_teamtypes.UpdateDialog(); } if (m_houses.m_hWnd) { m_houses.UpdateDialog(); } if (m_taskforces.m_hWnd) { m_taskforces.UpdateDialog(); } if (m_Scripttypes.m_hWnd) { m_Scripttypes.UpdateDialog(); } if (m_triggereditor.m_hWnd) { m_triggereditor.UpdateDialog(); } if (m_tags.m_hWnd) { m_tags.UpdateDialog(); } if (m_aitriggertypesenable.m_hWnd) { m_aitriggertypesenable.UpdateDialog(); } if (m_aitriggertypes.m_hWnd) { m_aitriggertypes.UpdateDialog(); } if (m_singleplayersettings.m_hWnd) { m_singleplayersettings.UpdateDialog(); } CIniFile& ini = Map->GetIniFile(); currentOwner = "Neutral"; auto const& houseSec = ini[MAPHOUSES]; if (houseSec.Size() > 0) { if (!houseSec.HasValue("Neutral")) { currentOwner = ini[MAPHOUSES].Nth(0).second; } } if (!bOnlyMissionControl) { UpdateWindow(); UpdateStrings(); m_view.m_isoview->UpdateDialog(!bNoRepos); m_view.m_objectview->UpdateDialog(); m_view.m_minimap->UpdateView(); if (tiles != NULL && tiledata != NULL && tiledata_count != NULL) { m_view.m_browser->m_bar.Update(); } } AD.reset(); } void CFinalSunDlg::OnFileSaveas() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } CMapValidator validator; int iCancel = validator.DoModal(); if (iCancel == IDCANCEL) return; CString r = GetLanguageStringACP("SAVEDLG_FILETYPES"); if (yuri_mode) { r = GetLanguageStringACP("SAVEDLG_FILETYPES_YR"); } r = TranslateStringVariables(8, r, ";"); auto const ext = ".map"; auto const fname = "noname.map"; CFileDialog dlg(FALSE, ext, /*fname*/ NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, r); char cuPath[MAX_PATH]; GetCurrentDirectory(MAX_PATH, cuPath); dlg.m_ofn.lpstrInitialDir = cuPath; if (theApp.m_Options.TSExe.GetLength()) dlg.m_ofn.lpstrInitialDir = (char*)(LPCTSTR)theApp.m_Options.TSExe; if (dlg.DoModal() != IDCANCEL) { strcpy(currentMapFile, dlg.GetPathName()); CString str = GetLanguageStringACP("MainDialogCaption"); str += " ("; str += (char*)(LPCTSTR)dlg.GetPathName(); str += ")"; this->SetWindowText(str); SaveMap(dlg.GetPathName()); } SetCursor(m_hArrowCursor); } void CFinalSunDlg::OnOptionsExportrulesini() { int res = MessageBox("This will export the Rules.Ini of Tiberian Sun V1.13 MMX. ou should not modify this rules.ini because you won´t be able to play online then and ecause this could cause compatibility problems.\nIf you want to modify the rules.ini, you need to rename it before you play online.", "Export Rules.INI", MB_OK); CFileDialog dlg(FALSE, ".ini", "rules.ini", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Rules.INI|rules.ini|"); char cuPath[MAX_PATH]; BOOL hidePreview = FALSE; BOOL previewPrinted = FALSE; GetCurrentDirectory(MAX_PATH, cuPath); dlg.m_ofn.lpstrInitialDir = cuPath; if (theApp.m_Options.TSExe.GetLength()) dlg.m_ofn.lpstrInitialDir = (char*)(LPCTSTR)theApp.m_Options.TSExe; if (dlg.DoModal() != IDCANCEL) { SetCursor(LoadCursor(NULL, IDC_WAIT)); HRSRC r; r = FindResource(NULL, MAKEINTRESOURCE(IDR_RULES), "TEXTFILE"); if (r == 0) { MessageBox("FindResource() failed to find IDR_RULES", "DEBUG"); return; } HGLOBAL hres = LoadResource(NULL, r); if (hres == 0) { MessageBox("LoadResource() failed to load IDR_RULES", "DEBUG"); return; } char* data = (char*)LockResource(hres); int hfile = _open((char*)(LPCTSTR)dlg.GetPathName(), _O_BINARY | _O_CREAT | _O_WRONLY, _S_IREAD | _S_IWRITE); if (hfile == -1) { MessageBox("File could not be opened", "DEBUG"); return; } _write(hfile, (void*)data, strlen(data)); _close(hfile); SetCursor(m_hArrowCursor); } } void CFinalSunDlg::OnHelpInfo() { // handle the help dialog CInfo info; info.DoModal(); } void CFinalSunDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CDialog::OnShowWindow(bShow, nStatus); m_view.ShowWindow(SW_SHOW); if (!bShow) return; } void CFinalSunDlg::OnFileSave() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (strlen(currentMapFile) == 0) { OnFileSaveas(); return; } CMapValidator validator; int iCancel = validator.DoModal(); if (iCancel == IDCANCEL) return; SaveMap(currentMapFile); } void CFinalSunDlg::SaveMap(CString FileName_) { SetCursor(LoadCursor(NULL, IDC_WAIT)); errstream << "SaveMap() called" << endl; errstream.flush(); BOOL bSaveAsMMX = FALSE; BOOL hidePreview = FALSE; BOOL previewPrinted = FALSE; FileName_.MakeLower(); FileName_ = (LPCSTR)FileName_; // GetLength() needs to return proper size CString CoreName = FileName_; CString Description; int minplayers; int maxplayers; BOOL standard; BOOL meatgrind; BOOL navalwar; BOOL nukewar; BOOL airwar; BOOL megawealth; BOOL duel; BOOL cooperative; // MW Apr 17th, 2002: Added Teamgame! BOOL teamgame; if (CoreName.ReverseFind('\\') >= 0) CoreName = CoreName.Right(CoreName.GetLength() - CoreName.ReverseFind('\\') - 1); if (CoreName.Find(".") >= 0) CoreName = CoreName.Left(CoreName.Find(".")); #ifdef RA2_MODE if (Map->IsMultiplayer()) { if (FileName_.Find(".mmx") >= 0) bSaveAsMMX = TRUE; else bSaveAsMMX = FALSE; // MW 07/27/01: Check for YRM if (FileName_.Find(".mpr") >= 0 && Map->IsYRMap()) FileName_.Replace(".mpr", ".yrm"); // MW 07/28/01: Create [Header] int i; int wp_count = 0; int xw[8] = { 0,0,0,0,0,0,0,0 }; int yw[8] = { 0,0,0,0,0,0,0,0 }; for (i = 0; i < Map->GetWaypointCount(); i++) { CString id; DWORD pos; Map->GetNthWaypointData(i, &id, &pos); int idi; idi = atoi(id); if (idi != i) break; if (idi >= 0 && idi < 8) { int x, y; x = pos / Map->GetIsoSize(); y = pos % Map->GetIsoSize(); //PosToXY(pos, x,y); xw[wp_count] = calcXPos(x, y); yw[wp_count] = calcYPos(x, y); wp_count++; } } char c[50]; CIniFile& ini = Map->GetIniFile(); auto& sec = ini.AddSection("Header"); sec.SetInteger("NumberStartingPoints", wp_count); for (i = 0; i < 8; i++) { CString key = "Waypoint"; itoa(i + 1, c, 10); key += c; itoa(xw[i], c, 10); CString val = c; val += ","; itoa(yw[i], c, 10); val += c; sec.SetString(key, val); } int startx, starty, width, height; MC_GetHeaderRect(startx, starty, width, height); sec.SetInteger("Height", height); sec.SetInteger("Width", width); //CIniFile& ini=Map->GetIniFile(); auto const& localSizeStr = ini.GetString("Map", "LocalSize"); CString left = GetParam(localSizeStr, 0); CString top = GetParam(localSizeStr, 1); //startx=1;//Map->GetHeight()/2;//atoi(left);//Map->GetIsoSize()/2-Map->GetWidth()/2;//198/2-50;//Map->GetIsoSize()/2-Map->GetHeight()/2;//Map->GetWidth()/2-50; //starty=Map->GetWidth();//Map->GetIsoSize()/2-Map->GetWidth()/2;//198/2-50;//Map->GetIsoSize()/2-Map->GetWidth()/2;//Map->GetHeight()/2-50; itoa(startx, c, 10); sec.SetInteger("StartX", startx); sec.SetInteger("StartY", starty); /*CMultiSaveOptionsDlg mso; if(FileName.Find(".mmx")>=0) mso.m_mmx=0; else mso.m_mmx=1; if(mso.DoModal()==IDCANCEL) return; if(mso.m_mmx==0) { FileName.Replace(".mpr", ".map"); //FileName.Replace(" ", ""); if(CoreName.GetLength()>8) { CoreName=CoreName.Left(8); FileName=CoreName+".map"; CString s="The maximum filename length for MMX files is 8 chars, do you want to save the map as "; s+=CoreName; s+=".mmx?"; int res=MessageBox(s,"Error", MB_YESNO); if(res!=IDYES) return; } bSaveAsMMX=TRUE; } else { FileName.Replace(".mmx", ".mpr"); bSaveAsMMX=FALSE; }*/ } #endif CString MMXFileName = CoreName; MMXFileName += ".mmx"; CString PKTFileName = CoreName; PKTFileName += ".pkt"; CString MAPFileName = CoreName; MAPFileName += ".map"; DWORD dwFlags = MAPDATA_UPDATE_TO_INI_ALL; if (!bSaveAsMMX) { CSaveMapOptionsDlg opt; CString gm = Map->GetIniFile().GetString("Basic", "GameMode"); gm.MakeLower(); if (gm.GetLength()) { opt.m_Standard = gm.Find("standard") >= 0; opt.m_AirWar = gm.Find("airwar") >= 0; opt.m_Cooperative = gm.Find("cooperative") >= 0; opt.m_Duel = gm.Find("duel") >= 0; opt.m_Navalwar = gm.Find("navalwar") >= 0; opt.m_Nukewar = gm.Find("nukewar") >= 0; opt.m_Meatgrind = gm.Find("meatgrind") >= 0; opt.m_Megawealth = gm.Find("megawealth") >= 0; opt.m_TeamGame = gm.Find("teamgame") >= 0; } else { opt.m_Standard = TRUE; } if (opt.DoModal() == IDCANCEL) { return; } gm = ""; if (opt.m_Standard) { gm += "standard, "; } if (opt.m_Meatgrind) { gm += "meatgrind, "; } if (opt.m_Navalwar) { gm += "navalwar, "; } if (opt.m_Nukewar) { gm += "nukewar, "; } if (opt.m_AirWar) { gm += "airwar, "; } if (opt.m_Megawealth) { gm += "megawealth, "; } if (opt.m_Duel) { gm += "duel, "; } if (opt.m_Cooperative) { gm += "cooperative, "; } if (opt.m_TeamGame) { gm += "teamgame, "; } if (gm.ReverseFind(',') >= 0) { gm = gm.Left(gm.ReverseFind(',')); } if (gm.GetLength() == 0) { gm = "standard"; } Map->GetIniFile().SetString("Basic", "Name", opt.m_MapName); Map->GetIniFile().SetString("Basic", "GameMode", gm); int i; int count = 0; for (i = 0; i < Map->GetWaypointCount(); i++) { CString id; DWORD pos; Map->GetNthWaypointData(i, &id, &pos); int idi; idi = atoi(id); if (idi != i) { break; } if (idi >= 0 && idi < 8) { count++; } } if (count < 1) { count = 1; } // TODO: control from dialog Map->GetIniFile().SetInteger("Basic", "MinPlayer", opt.m_MinPlayers); Map->GetIniFile().SetInteger("Basic", "MaxPlayer", count); if (opt.m_Compress == 0) { dwFlags |= MAPDATA_UPDATE_TO_INI_ALL_COMPRESSED; } if (opt.m_PreviewMode == CSaveMapOptionsDlg::PREVIEW_MINIMAP) { dwFlags |= MAPDATA_UPDATE_TO_INI_ALL_PREVIEW; } if (opt.m_PreviewMode == CSaveMapOptionsDlg::PREVIEW_STRIP) { hidePreview = TRUE; } } else { CMMXSavingOptionsDlg opt; // old pkt header exists if (m_PKTHeader.Size() > 0) { auto const& sec = m_PKTHeader[m_PKTHeader.GetString("MultiMaps", "1")]; auto const& desc = sec.GetString("Description"); if (!desc.IsEmpty()) { opt.m_Description = desc; } opt.m_MinPlayers = sec.GetInteger("MinPlayers") - 2; opt.m_Maxplayers = sec.GetInteger("MaxPlayers") - 2; CString gm = sec["GameMode"]; gm.MakeLower(); opt.m_Standard = gm.Find("standard") >= 0; opt.m_AirWar = gm.Find("airwar") >= 0; opt.m_Cooperative = gm.Find("cooperative") >= 0; opt.m_Duel = gm.Find("duel") >= 0; opt.m_NavalWar = gm.Find("navalwar") >= 0; opt.m_NukeWar = gm.Find("nukewar") >= 0; opt.m_Meatgrind = gm.Find("meatgrind") >= 0; opt.m_MegaWealth = gm.Find("megawealth") >= 0; } if (opt.DoModal() == IDCANCEL) { return; } Description = opt.m_Description; standard = opt.m_Standard; airwar = opt.m_AirWar; cooperative = opt.m_Cooperative; duel = opt.m_Duel; navalwar = opt.m_NavalWar; nukewar = opt.m_NukeWar; meatgrind = opt.m_Meatgrind; megawealth = opt.m_MegaWealth; maxplayers = opt.m_Maxplayers + 2; minplayers = opt.m_MinPlayers + 2; dwFlags |= MAPDATA_UPDATE_TO_INI_ALL_PREVIEW; Map->GetIniFile().SetBool("Basic", "Official", "Yes"); // Map->GetIniFile().sections["Basic"].values["Name"]=opt.m_Description; } SetText("Packing data..."); UpdateWindow(); errstream << "Calling UpdateIniFile()" << endl; CSavingDlg dlg; dlg.ShowWindow(SW_SHOW); dlg.BringWindowToTop(); dlg.UpdateWindow(); Map->UpdateIniFile(dwFlags); CIniFile& ini = Map->GetIniFile(); // delete invalid ini sections for (auto it = ini.begin(); it != ini.end();) { if (it->second.Size() == 0 || it->first.IsEmpty()) { it = ini.DeleteAt(it); } ++it; } // why need this trim? we should handle it in the first place #if 0 for (auto& sec : ini) { int e; if (sec.first == "IsoMapPack5") { continue; } for (e = 0; e < sec.values.size(); e++) { sec.GetValue(e)->TrimLeft(); { CString value = *sec.GetValue(e); CString name = *sec.GetValueName(e); sec.values.erase(name); name.TrimLeft(); sec.values[name] = value; } } } for (i = 0; i < ini.sections.size(); i++) { CIniFileSection& sec = *ini.GetSection(i); int e; if (*ini.GetSectionName(i) != "IsoMapPack5") for (e = 0; e < sec.values.size(); e++) { sec.GetValue(e)->TrimRight(); { CString value = *sec.GetValue(e); CString name = *sec.GetValueName(e); sec.values.erase(name); name.TrimRight(); sec.values[name] = value; } } } #endif SetText("Saving..."); UpdateWindow(); std::wstring FileName = utf8ToUtf16(FileName_.GetString()); map rulessections; std::string tempfile = u8AppDataPath; tempfile += "\\TmpMap.map"; std::wstring u16tempfile = utf8ToUtf16(tempfile); CString fi; deleteFile(tempfile); HANDLE hFile = CreateFileW(u16tempfile.c_str(), GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); CloseHandle(hFile); hFile = CreateFileW(u16tempfile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); DWORD bwr; #ifdef TS_MODE fi = "; Map created with FinalSun Mission Editor"; fi += "\n"; fi += "; note that all comments were truncated"; fi += "\n"; fi += "\n"; #else fi = "; Map created with FinalAlert 2 Mission Editor"; fi += "\n"; fi += "; note that all comments were truncated"; fi += "\n"; fi += "\n"; #endif WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); fi = ""; // MW 07/28/01: Header saving at top { auto const headerSecName = "Header"; auto const& headerSec = ini[headerSecName]; rulessections[headerSecName] = TRUE; fi = "["; fi += headerSecName; fi += "]"; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); char c[50]; for (auto e = 0; e < headerSec.Size(); e++) { auto const& [key, value] = headerSec.Nth(e); fi = key; fi += "="; fi += value; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); if (e % 500 == 0) { int percent = e * 100 / headerSec.Size(); itoa(percent, c, 10); SetText((CString)"Saving... " + headerSecName + "( " + c + "% )"); UpdateWindow(); } } fi = "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); } for (auto const& [secName, sec] : ini) { if (!Map->IsRulesSection(secName)) { continue; } rulessections[secName] = TRUE; fi = "["; fi += secName; fi += "]"; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); char c[50]; for (auto e = 0; e < sec.Size(); e++) { auto const& [key, value] = sec.Nth(e); // restore += format fi = key[0] != '+' ? key : '+'; fi += "="; fi += value; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); if (e % 500 == 0) { int percent = e * 100 / sec.Size(); itoa(percent, c, 10); SetText((CString)"Saving... " + secName + "( " + c + "% )"); UpdateWindow(); } } fi = "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); } // the preview must be before map data... if (hidePreview) { fi += "; this is a hidden preview"; fi += "\n"; fi += "[Preview]"; fi += "\n"; fi += "Size=0,0,106,61"; fi += "\n"; fi += "\n"; fi += "[PreviewPack]"; fi += "\n"; fi += "2=BIACcgAEwBtAMnRABAAaQCSANMAVQASAAnIABMAbQDJ0QAQAGkAkgDTAFUAEgAJyAATAG0"; fi += "\n"; fi += "1=yAsAIAXQ5PDQ5PDQ6JQATAEE6PDQ4PDI4JgBTAFEAkgAJyAATAG0AydEAEABpAJIA0wBVA"; fi += "\n"; fi += "\n"; } else { fi += "[Preview]"; fi += "\n"; for (auto const& [key, value] : ini["Preview"]) { fi += key; fi += "="; fi += value; fi += "\n"; } fi += "\n"; fi += "[PreviewPack]"; fi += "\n"; for (auto const& [key, value] : ini["PreviewPack"]) { fi += key; fi += "="; fi += value; fi += "\n"; } fi += "\n"; } WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); auto alreadyHandledSections = [&rulessections](const CString& secName) { const char* handledSections[] = { "Digest", "PreviewPack", "Preview", "Header" }; if (rulessections.find(secName) != rulessections.end()) { return true; } for (auto const pSec : handledSections) { if (pSec == secName) { return true; } } return false; }; for (auto const& [secName, sec] : ini) { if (alreadyHandledSections(secName)) { continue; } if (!secName.IsEmpty()) { //MessageBox(secName); //its a standard section: fi = "["; fi += secName; fi += "]"; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); char c[50]; for (auto e = 0; e < sec.Size(); e++) { auto const& [key, value] = sec.Nth(e); fi = key; fi += "="; fi += value; fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); if (e % 500 == 0) { int percent = e * 100 / sec.Size(); itoa(percent, c, 10); SetText((CString)"Saving... " + secName + "( " + c + "% )"); UpdateWindow(); } } fi = "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); } } fi += "\n"; fi += "[Digest]"; fi += "\n"; for (auto const& [key, value] : ini["Digest"]) { fi += key; fi += "="; fi += value; fi += "\n"; } fi += "\n"; WriteFile(hFile, fi, fi.GetLength(), &bwr, NULL); CloseHandle(hFile); dlg.DestroyWindow(); auto DestName = FileName; if (bSaveAsMMX) { MAPFileName.Replace(" ", ""); MMXFileName.Replace(" ", ""); PKTFileName.Replace(" ", ""); CoreName.Replace(" ", ""); } if (bSaveAsMMX) FileName = utf8ToUtf16(MAPFileName.GetString()); const auto u8FileName = utf16ToUtf8(FileName); if (!CopyFileW(u16tempfile.c_str(), FileName.c_str(), FALSE)) { MessageBox("Error: file cannot be saved. Make sure the file is not read only", "Error", MB_OK); } else { SetText(TranslateStringVariables(1, GetLanguageStringACP("FileSaved"), u8FileName.c_str())); if (bSaveAsMMX) { SetText(TranslateStringVariables(1, GetLanguageStringACP("FileSaved"), MMXFileName)); // MW 07/20/01: InsertPrevFile(MMXFileName); CIniFile f; //CoreName.Replace(" ", ""); //Description.Replace(" ",""); f.SetString("MultiMaps", "1", CoreName); f.SetString(CoreName, "Description", Description); CString gm; if (standard) { gm += "standard, "; } if (meatgrind) { gm += "meatgrind, "; } if (navalwar) { gm += "navalwar, "; } if (nukewar) { gm += "nukewar, "; } if (airwar) { gm += "airwar, "; } if (megawealth) { gm += "megawealth, "; } if (duel) { gm += "duel, "; } if (cooperative) { gm += "cooperative, "; } if (gm.ReverseFind(',') >= 0) { gm = gm.Left(gm.ReverseFind(',')); } f.SetString(CoreName, "GameMode", gm); char c[50]; f.SetInteger(CoreName, "MaxPlayers", maxplayers); f.SetInteger(CoreName, "MinPlayers", minplayers); f.SetString(CoreName, "CD", "0,1"); f.SaveFile(PKTFileName); LPCSTR files[2]; files[0] = (LPCSTR)PKTFileName; files[1] = (LPCSTR)MAPFileName; #ifdef RA2_MODE auto game = yuri_mode ? FSunPackLib::Game::RA2_YR : FSunPackLib::Game::RA2; #else auto game = FSunPackLib::Game::TS; #endif FSunPackLib::WriteMixFile(MMXFileName, files, 2, game); DeleteFile(PKTFileName); DeleteFile(MAPFileName); } else { // MW 07/20/01: InsertPrevFile(u8FileName.c_str()); } } deleteFile(tempfile); SetCursor(m_hArrowCursor); //SetReady(); } void CFinalSunDlg::SetReady() { m_view.m_statbar.GetStatusBarCtrl().SetText(TranslateStringACP("Ready"), 0, 0); } void CFinalSunDlg::SetText(const char* text) { m_view.m_statbar.GetStatusBarCtrl().SetText(text, 0, 0); } void CFinalSunDlg::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) { CDialog::OnMenuSelect(nItemID, nFlags, hSysMenu); switch (nItemID) { case ID_FILE_OPENMAP: SetText(GetLanguageStringACP("FileOpenHelp")); break; case ID_FILE_SAVE: SetText(GetLanguageStringACP("FileSaveHelp")); break; case ID_FILE_SAVEAS: SetText(GetLanguageStringACP("FileSaveAsHelp")); break; case ID_FILE_IMPORTMOD: SetText(GetLanguageStringACP("FileImportModHelp")); break; case ID_FILE_QUIT: SetText(GetLanguageStringACP("FileQuitHelp")); break; case ID_FILE_VALIDATEMAP: SetText(GetLanguageStringACP("FileCheckMapHelp")); break; case ID_FILE_RUNTIBERIANSUN: SetText(GetLanguageStringACP("FileRunTiberianSunHelp")); break; case ID_FILE_NEW: SetText(GetLanguageStringACP("FileNewHelp")); break; case ID_MAPVIEW: SetText(GetLanguageStringACP("OptionsShowMapViewHelp")); break; case ID_HELP_INFO: SetText(GetLanguageStringACP("HelpInfoHelp")); break; case ID_HELP_TIPOFTHEDAY: SetText(GetLanguageStringACP("HelpTipOfTheDayHelp")); break; case ID_OPTIONS_EXPORTRULESINI: SetText("Export the file rules.ini"); break; default: SetReady(); } } void se_translator(unsigned int e, _EXCEPTION_POINTERS* p) { throw(unsigned int)(e); } void CFinalSunDlg::OnFileRuntiberiansun() // or RA2 { PROCESS_INFORMATION pi; STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); CString exe = theApp.m_Options.TSExe; exe.MakeLower(); if (yuri_mode) { exe.Replace("ra2.exe", "ra2md.exe"); } BOOL success = CreateProcess(exe, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); } void CFinalSunDlg::OnFileImportmod() { /*CImportModDlg dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST, "TS maps|*.mpr;*.map|TS multi maps|*.mpr|TS single maps|*.map|"); char cuPath[MAX_PATH]; GetCurrentDirectory(MAX_PATH, cuPath); dlg.m_ofn.lpstrInitialDir=cuPath; //if(theApp.m_Options.TSExe.GetLength()) dlg.m_ofn.lpstrInitialDir=(char*)(LPCTSTR)theApp.m_Options.TSExe; if(dlg.DoModal()==IDCANCEL) return; */ } void CFinalSunDlg::OnDebugExportmappacknosections() { CIniFile& ini = Map->GetIniFile(); CString ovrl; int i; ovrl = ""; for (auto const& [key, val] : ini["IsoMapPack5"]) { ovrl += val; } BYTE hex[400000]; BYTE values[400000]; //int hexlen=ConvertToHex((BYTE*)(LPCTSTR)ovrl, hex); //ExtractIsoMapPack5(hex,hexlen, values); HANDLE hFile = CreateFile("c:\\MAPPACKNOSECTIONS.BIN", GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); CloseHandle(hFile); hFile = CreateFile("c:\\MAPPACKNOSECTIONS.BIN", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); DWORD dw; WriteFile(hFile, values, 400000, &dw, NULL); CloseHandle(hFile); } void CFinalSunDlg::OnDebugExportmappack() { } void deleteTypeListFromIni(CIniFile& ini, const CString& SectionType) { for (auto const& [seq, id] : ini[SectionType]) { ini.DeleteSection(id); } ini.DeleteSection(SectionType); } void DeleteTypeList(const CString& SectionType) { deleteTypeListFromIni(Map->GetIniFile(), SectionType); } void CFinalSunDlg::OnFileNew() { CNewMapTypeDlg typedlg; if (typedlg.DoModal() == IDCANCEL) return; BOOL bSingleplayer = !typedlg.m_Singleplayer; CNewMapCreateDlg createdlg; if (createdlg.DoModal() == IDCANCEL) return; BOOL bCreateNew = !createdlg.m_CreateType; int width, height, theater, stdheight; CString importmap; BOOL bImportTrees, bImportUnits, bImportOverlay; if (bCreateNew) { CNewMapCreateNewDlg createnewdlg; if (createnewdlg.DoModal() == IDCANCEL) return; width = createnewdlg.m_Width; height = createnewdlg.m_Height; stdheight = createnewdlg.m_StartingHeight; theater = createnewdlg.m_Theater; } else { while (!DoesFileExist(importmap)) { CNewMapImportDlg impdlg; if (impdlg.DoModal() == IDCANCEL) return; importmap = impdlg.m_ImportFile; bImportTrees = impdlg.m_ImportTrees; bImportUnits = impdlg.m_ImportUnits; bImportOverlay = impdlg.m_ImportOverlay; } } CString plhouse; BOOL bPrepareHouses = FALSE; BOOL bAutoProd = FALSE; if (bSingleplayer) { CNewMapSpDlg spdlg; if (spdlg.DoModal() == IDCANCEL) { return; } bPrepareHouses = spdlg.m_PrepareHouses; bAutoProd = spdlg.m_AutoProd; plhouse = rules[HOUSES].Nth(spdlg.m_House).second; } bNoDraw = TRUE; m_PKTHeader.Clear(); // first hide the terrain browser window m_TerrainDlg.DestroyWindow(); // set currentMapFile to nothing and update window caption strcpy(currentMapFile, ""); CString cap; cap = GetLanguageStringACP("MainDialogCaption"); cap += " ("; cap += GetLanguageStringACP("NewMap"); cap += ")"; SetWindowText(cap); // set cursor to wait SetCursor(LoadCursor(NULL, IDC_WAIT)); if (!bCreateNew) { CString file = importmap; file.MakeLower(); if (file.Find(".bmp") >= 0) { CBitmap2MapConverter conv; HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, utf8ToUtf16(file.GetString()).c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); conv.Convert(hBitmap, *Map); DeleteObject(hBitmap); } else { Map->LoadMap(file.GetString()); if (!bImportOverlay) { Map->ClearOverlay(); Map->ClearOverlayData(); } CIniFile& ini = Map->GetIniFile(); int i; int count = Map->GetTerrainCount(); if (!bImportTrees) { for (i = 0; i < count; i++) Map->DeleteTerrain(0); } if (!bImportUnits) { count = Map->GetInfantryCount(); for (i = 0; i < count; i++) Map->DeleteInfantry(0); count = Map->GetUnitCount(); for (i = 0; i < count; i++) Map->DeleteUnit(0); count = Map->GetStructureCount(); for (i = 0; i < count; i++) Map->DeleteStructure(0); count = Map->GetAircraftCount(); for (i = 0; i < count; i++) Map->DeleteAircraft(0); } ini.SetString("Basic", "Name", "Noname"); deleteTypeListFromIni(ini, MAPHOUSES); deleteTypeListFromIni(ini, HOUSES); if (TRUE) { ini.DeleteSection("Tags"); ini.DeleteSection("Triggers"); ini.DeleteSection("Actions"); ini.DeleteSection("Events"); DeleteTypeList("TeamTypes"); DeleteTypeList("TaskForces"); DeleteTypeList("ScriptTypes"); ini.DeleteSection("CellTags"); // ini.sections.erase("AITriggerTypesEnable"); // ini.sections.erase("AITriggerTypes"); } } } else { // ok, create a new map CString theater_s; if (theater == 0) theater_s = THEATER0; else if (theater == 1) theater_s = THEATER1; else if (theater == 2) theater_s = THEATER2; else if (theater == 3) theater_s = THEATER3; else if (theater == 4) theater_s = THEATER4; else if (theater == 5) theater_s = THEATER5; Map->CreateMap(width, height, theater_s, stdheight); if (!bSingleplayer) { last_succeeded_operation = 11003; // create map function was created for SP. Fix it here; Map->DeleteWaypoint(98); Map->DeleteWaypoint(99); int midx = Map->GetIsoSize() / 2; int midy = Map->GetIsoSize() / 2; Map->AddWaypoint("0", midx + midy * Map->GetIsoSize()); Map->AddWaypoint("1", midx + 1 + midy * Map->GetIsoSize()); Map->AddWaypoint("2", midx + 2 + midy * Map->GetIsoSize()); Map->AddWaypoint("3", midx + 3 + midy * Map->GetIsoSize()); Map->AddWaypoint("4", midx + (midy + 1) * Map->GetIsoSize()); Map->AddWaypoint("5", midx + 1 + (midy + 1) * Map->GetIsoSize()); Map->AddWaypoint("6", midx + 2 + (midy + 1) * Map->GetIsoSize()); Map->AddWaypoint("7", midx + 3 + (midy + 1) * Map->GetIsoSize()); } } last_succeeded_operation = 11004; CIniFile& ini = Map->GetIniFile(); if (!bSingleplayer) { ini.SetString("Basic", "MultiplayerOnly", "1"); } if (bSingleplayer) { ini.SetString("Basic", "MultiplayerOnly", "0"); ini.DeleteSection("Preview"); ini.DeleteSection("PreviewPack"); if (bPrepareHouses) { //CString plhouse; //plhouse=GetHouseSectionName(dlg.m_House); plhouse += " House"; ini.SetString("Basic", "Player", plhouse); auto const& rulesHouseSec = rules[HOUSES]; for (auto idx = 0; idx < rulesHouseSec.Size(); idx++) { #ifdef RA2_MODE auto const& country = rulesHouseSec.Nth(idx).second; if (!country.CompareNoCase("nod") || !country.CompareNoCase("gdi")) { continue; } #endif char idxStr[50]; itoa(idx, idxStr, 10); CString house = GetHouseSectionName(country); ini.SetString(MAPHOUSES, idxStr, house); #ifdef RA2_MODE ini.SetString(HOUSES, idxStr, country); #endif // is it a player house or a ai house? if (house != plhouse) { ini.SetInteger(house, "IQ", 5); ini.SetBool(house, "PlayerControl", false); // now, if the user wants to, check if this house is a passive or active house if (!rules.GetBool(house, "MultiplayPassive") && bAutoProd) { CString id = GetFreeID(); #ifdef RA2_MODE //k=i+rules.sections[HOUSES].values.size(); //itoa(k,c,10); #endif CString triggerContent = country; triggerContent += ",,AI Auto Production "; triggerContent += TranslateHouse(country, TRUE); triggerContent += ",0,1,1,1,0"; ini.SetString("Triggers", id, triggerContent); ini.SetString("Events", id, "1,13,0,10"); // after 10 secs, start prod. CString actionContent = "3,3,0,"; actionContent += idxStr; actionContent += ",0,0,0,0,A,13,0,"; actionContent += idxStr; actionContent += ",0,0,0,0,A,74,0,"; actionContent += idxStr; actionContent += ",0,0,0,0,A"; ini.SetString("Actions", id, actionContent); CString ID_TAG = GetFreeID(); CString tagContent = "0,AI Auto Production "; tagContent += TranslateHouse(house, TRUE); tagContent += ","; tagContent += id; ini.SetString("Tags", ID_TAG, tagContent); } } else { ini.SetInteger(house, "IQ", 0); ini.SetBool(house, "PlayerControl", true); } #ifndef RA2_MODE ini.sections[house].values["ActsLike"] = c; ini.sections[house].values["Side"] = house; #else ini.SetString(house, "Country", country); #endif ini.SetString(house, "Edge", "North"); auto const& countrySec = rules[country]; ini.SetString(house, "Color", countrySec.GetString("Color")); ini.SetString(house, "Allies", house); ini.SetInteger(house, "Credits", 0); ini.SetInteger(house, "NodeCount", 0); ini.SetInteger(house, "TechLevel", 10); ini.SetInteger(house, "PercentBuilt", 100); #ifdef RA2_MODE ini.SetString(country, "ParentCountry", country); ini.SetString(country, "Name", country); ini.SetString(country, "Suffix", countrySec.GetString("Suffix")); ini.SetString(country, "Prefix", countrySec.GetString("Prefix")); ini.SetString(country, "Color", countrySec.GetString("Color")); ini.SetString(country, "Side", countrySec.GetString("Side")); ini.SetString(country, "SmartAI", countrySec.GetString("SmartAI")); ini.SetInteger(country, "CostUnitsMult", 1);// this is actual a float value #endif } } } else { // for RA2, we create standard houses #ifdef RA2_MODE auto const& rulesHouseSec = rules[HOUSES]; for (auto idx = 0; idx < rulesHouseSec.Size(); idx++) { char c[50]; int k = idx; itoa(k, c, 10); auto const& country = rulesHouseSec.Nth(idx).second; if (country.IsEmpty()) { continue; // make sure we don´t have an empty entry } // we now create a HOUSE with the same name as the current rules house ini.SetString(MAPHOUSES, c, country); ini.SetInteger(country, "IQ", 0); ini.SetString(country, "Edge", "North"); ini.SetString(country, "Color", rules.GetString(country, "Color")); ini.SetString(country, "Allies", country); ini.SetString(country, "Country", country); ini.SetInteger(country, "Credits", 0); ini.SetInteger(country, "NodeCount", 0); ini.SetInteger(country, "TechLevel", 1); ini.SetInteger(country, "PercentBuilt", 0); ini.SetBool(country, "PlayerControl", false); } #endif } // MW: added March 31st // now allow automatic ai trigger enabling if (createdlg.m_AITriggers) { for (auto const& [id, _] : ai["AITriggerTypes"]) { ini.SetBool("AITriggerTypesEnable", id, true); } } last_succeeded_operation = 11000; Map->UpdateIniFile(MAPDATA_UPDATE_FROM_INI); last_succeeded_operation = 11001; Sleep(200); SetCursor(m_hArrowCursor); bNoDraw = FALSE; //if(RepairRulesHouses()) // MessageBox("Repaired houses"); m_view.m_isoview->UpdateDialog(TRUE); m_view.m_minimap->RedrawWindow(); UpdateDialogs(); last_succeeded_operation = 11002; } /* UpdateStrings(); Updates all dialog CStrings, and the CStrings from the isoview object list and the child dialogs */ void CFinalSunDlg::UpdateStrings() { last_succeeded_operation = 20; CString str; // update the menu CMenu* menu = GetMenu(); // destroy the old menu if (menu) menu->DestroyMenu(); // if(menu) delete menu; CMenu* my_menu = new(CMenu); // first, we load the original menu (we can´t translate from for example german!) my_menu->LoadMenu(IDR_MAIN); int idx, e; for (idx = 0; idx < my_menu->GetMenuItemCount(); idx++) { MENUITEMINFO mii; ZeroMemory(&mii, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE; my_menu->GetMenuItemInfo(idx, &mii, TRUE); my_menu->GetMenuString(idx, str, MF_BYPOSITION); my_menu->ModifyMenu(idx, mii.fState | mii.fType | MF_BYPOSITION | MF_STRING, mii.wID, TranslateStringACP((LPCTSTR)str)); for (e = 0; e < my_menu->GetSubMenu(idx)->GetMenuItemCount(); e++) { int id = my_menu->GetSubMenu(idx)->GetMenuItemID(e); ZeroMemory(&mii, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE; my_menu->GetSubMenu(idx)->GetMenuItemInfo(e, &mii, TRUE); my_menu->GetSubMenu(idx)->GetMenuString(e, str, MF_BYPOSITION); my_menu->GetSubMenu(idx)->ModifyMenu(e, mii.fState | mii.fType | MF_BYPOSITION | MF_STRING, mii.wID, TranslateStringACP((LPCTSTR)str)); } } if (theApp.m_Options.bEasy) my_menu->CheckMenuItem(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND | MF_CHECKED); if (theApp.m_Options.bDisableAutoShore) my_menu->CheckMenuItem(ID_OPTIONS_DISABLEAUTOSHORE, MF_BYCOMMAND | MF_CHECKED); if (theApp.m_Options.bDisableAutoLat) my_menu->CheckMenuItem(ID_OPTIONS_DISABLEAUTOLAT, MF_BYCOMMAND | MF_CHECKED); if (theApp.m_Options.bDisableSlopeCorrection) my_menu->CheckMenuItem(ID_OPTIONS_DISABLESLOPECORRECTION, MF_BYCOMMAND | MF_CHECKED); if (theApp.m_Options.bShowCells) my_menu->CheckMenuItem(ID_OPTIONS_SHOWBUILDINGOUTLINE, MF_BYCOMMAND | MF_CHECKED); if (theApp.m_Options.useDefaultMouseCursor) my_menu->CheckMenuItem(ID_OPTIONS_USEDEFAULTMOUSECURSOR, MF_BYCOMMAND | MF_CHECKED); if (!theApp.m_Options.viewScaleUseSteps) my_menu->CheckMenuItem(ID_OPTIONS_SMOOTHZOOM, MF_BYCOMMAND | MF_CHECKED); // MW 07/20/01: Show prev. opened files int prev_maps_count = 0; for (idx = 0; idx < RecentFilesSlots; idx++) { if (theApp.m_Options.prev_maps[idx].GetLength() > 0) { prev_maps_count++; CString str = "bla"; str = theApp.m_Options.prev_maps[idx]; auto const id = idx + ID_FILE_FILE1; my_menu->GetSubMenu(0)->InsertMenu(10 + prev_maps_count, MF_BYPOSITION | MF_STRING, id, str); } } #ifdef RA2_MODE // my_menu->DeleteMenu(4, MF_BYPOSITION); #endif if (theApp.m_Options.bEasy) my_menu->GetSubMenu(3)->DeleteMenu(0, MF_BYPOSITION); if (theApp.m_Options.bEasy) { CMenu* edit_my_menu = my_menu->GetSubMenu(1); for (idx = edit_my_menu->GetMenuItemCount() - 1; idx >= 11; idx--) // MW 07/17/2001: i>=9 changed to i>=10 so Basic dialog is always available { edit_my_menu->DeleteMenu(idx, MF_BYPOSITION); } CMenu* terrain_my_menu = my_menu->GetSubMenu(2); for (idx = terrain_my_menu->GetMenuItemCount() - 1; idx >= 8; idx--) { terrain_my_menu->DeleteMenu(idx, MF_BYPOSITION); } } #ifndef SCRIPT_SUPPORT my_menu->GetSubMenu(3)->DeleteMenu(ID_MAPTOOLS_TOOLSCRIPTS, MF_BYCOMMAND); #endif // now attach this my_menu to the window SetMenu(my_menu); // update the tabs /*TCITEM tci; memset(&tci, 0, sizeof(TCITEM)); tci.mask=TCIF_TEXT; tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabBasic"); m_TabCtrl.SetItem(TAB_BASIC, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabSingleplayerSettings"); m_TabCtrl.SetItem(TAB_SINGLEPLAYERSETTINGS, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabMap"); m_TabCtrl.SetItem(TAB_MAP, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabLighting"); m_TabCtrl.SetItem(TAB_LIGHTNING, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabSpecial"); m_TabCtrl.SetItem(TAB_SPECIALFLAGS, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabHouses"); m_TabCtrl.SetItem(TAB_HOUSES, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabTaskForces"); m_TabCtrl.SetItem(TAB_TASKFORCES, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabScriptTypes"); m_TabCtrl.SetItem(TAB_SCRIPTTYPES, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabTeamTypes"); m_TabCtrl.SetItem(TAB_TEAMTYPES, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabTriggers"); m_TabCtrl.SetItem(TAB_TRIGGERS, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabTags"); m_TabCtrl.SetItem(TAB_TAGS, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabAITriggers"); m_TabCtrl.SetItem(TAB_AITRIGGERTYPES, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabAITriggerEnable"); m_TabCtrl.SetItem(TAB_AITRIGGERTYPESENABLE, &tci); tci.pszText=(char*)(LPCTSTR)GetLanguageStringACP("TabOther"); m_TabCtrl.SetItem(TAB_OTHER, &tci); */ // now the child windows and the iso view m_view.m_objectview->UpdateDialog(); m_view.m_browser->m_bar.Update(); if (m_basic.m_hWnd) { m_basic.UpdateStrings(); } if (m_houses.m_hWnd) { m_houses.UpdateStrings(); } if (m_map.m_hWnd) { m_map.UpdateStrings(); } if (m_singleplayersettings.m_hWnd) { m_singleplayersettings.UpdateStrings(); } // we need to check SimpleView if using easy view if (theApp.m_Options.bEasy) GetMenu()->CheckMenuItem(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND | MF_CHECKED); if (!theApp.m_Options.bNoSounds) GetMenu()->CheckMenuItem(ID_OPTIONS_SOUNDS, MF_BYCOMMAND | MF_CHECKED); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); } void CFinalSunDlg::OnHelpTipoftheday() { CTipDlg tip; tip.DoModal(); } void CFinalSunDlg::UnloadAll() { int iQuit = MessageBox(GetLanguageStringACP("MainDialogExitQuestion"), GetLanguageStringACP("MainDialogExitQuestionCap"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2); if (iQuit == IDNO) { return; } try { CShutDownDlg dlg(this); dlg.ShowWindow(SW_SHOW); dlg.UpdateWindow(); tiledata = nullptr; theApp.m_loading->FreeAll(); rules.Clear(); ai.Clear(); art.Clear(); tiles_t.Clear(); tiles_s.Clear(); tiles_u.Clear(); Map->GetIniFile().Clear(); sound.Clear(); tutorial.Clear(); g_data.Clear(); language.Clear(); m_view.m_minimap.reset(); DestroyWindow(); } catch (...) { DestroyWindow(); } } void CFinalSunDlg::OnOptionsSimpleview() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bEasy = FALSE; Options.SetInteger("UserInterface", "EasyView", 0); // hide all dialogs: HideAllDialogs(); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_SIMPLEVIEW, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bEasy = TRUE; Options.SetInteger("UserInterface", "EasyView", 1); } UpdateStrings(); #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif UpdateDialogs(); } void CFinalSunDlg::OnOptionsShowminimap() { bMiniMapClosedByUser = FALSE; this->m_view.m_minimap->UpdateView(); } void CFinalSunDlg::HideAllDialogs() { if (m_aitriggertypes) m_aitriggertypes.ShowWindow(SW_HIDE); if (m_aitriggertypesenable) m_aitriggertypesenable.ShowWindow(SW_HIDE); if (m_all) m_all.ShowWindow(SW_HIDE); if (m_basic) m_basic.ShowWindow(SW_HIDE); if (m_houses) m_houses.ShowWindow(SW_HIDE); if (m_lighting) m_lighting.ShowWindow(SW_HIDE); if (m_map) m_map.ShowWindow(SW_HIDE); if (m_Scripttypes) m_Scripttypes.ShowWindow(SW_HIDE); if (m_singleplayersettings) m_singleplayersettings.ShowWindow(SW_HIDE); if (m_specialflags) m_specialflags.ShowWindow(SW_HIDE); if (m_tags) m_tags.ShowWindow(SW_HIDE); if (m_taskforces) m_taskforces.ShowWindow(SW_HIDE); if (m_teamtypes) m_teamtypes.ShowWindow(SW_HIDE); } void CFinalSunDlg::OnFileValidatemap() { CMapValidator validator; int iCancel = validator.DoModal(); if (iCancel == IDCANCEL) return; } void CFinalSunDlg::OnEnterIdle(UINT nWhy, CWnd* pWho) { CDialog::OnEnterIdle(nWhy, pWho); } void CFinalSunDlg::OnEditBasicsettings() { if (m_basic.m_hWnd == NULL) { if (!m_basic.Create(CBasic::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_basic.m_hWnd != NULL) { m_basic.UpdateStrings(); m_basic.UpdateDialog(); m_basic.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditSingleplayersettings() { if (m_singleplayersettings.m_hWnd == NULL) { if (!m_singleplayersettings.Create(CSingleplayerSettings::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_singleplayersettings.m_hWnd != NULL) { m_singleplayersettings.UpdateStrings(); m_singleplayersettings.UpdateDialog(); m_singleplayersettings.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnSizing(UINT fwSide, LPRECT pRect) { CDialog::OnSizing(fwSide, pRect); } void CFinalSunDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); if (nType == SIZE_MINIMIZED) { if (!bMiniMapClosedByUser) m_view.m_minimap->ShowWindow(SW_MINIMIZE); } else if (nType == SIZE_MAXIMIZED) { if (!bMiniMapClosedByUser) m_view.m_minimap->ShowWindow(SW_RESTORE); } RecalcLayout(); } void CFinalSunDlg::OnEditHouses() { if (m_houses.m_hWnd == NULL) { if (!m_houses.Create(CHouses::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_houses.m_hWnd != NULL) { m_houses.UpdateStrings(); m_houses.UpdateDialog(); m_houses.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditAitriggers() { if (m_aitriggertypes.m_hWnd == NULL) { if (!m_aitriggertypes.Create(CAITriggerTypes::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_aitriggertypes.m_hWnd != NULL) { //m_aitriggertypes.UpdateStrings(); m_aitriggertypes.UpdateDialog(); m_aitriggertypes.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditAitriggerenabling() { if (m_aitriggertypesenable.m_hWnd == NULL) { if (!m_aitriggertypesenable.Create(CAiTriggerTypesEnable::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_aitriggertypesenable.m_hWnd != NULL) { //m_aitriggertypesenable.UpdateStrings(); m_aitriggertypesenable.UpdateDialog(); m_aitriggertypesenable.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditIniediting() { if (m_all.m_hWnd == NULL) { if (!m_all.Create(CAll::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_all.m_hWnd != NULL) { //m_all.UpdateStrings(); m_all.UpdateDialog(); m_all.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditLighting() { if (m_lighting.m_hWnd == NULL) { if (!m_lighting.Create(CLighting::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_lighting.m_hWnd != NULL) { //m_lighting.UpdateStrings(); m_lighting.UpdateDialog(); m_lighting.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditMap() { if (m_map.m_hWnd == NULL) { if (!m_map.Create(CMapD::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_map.m_hWnd != NULL) { m_map.UpdateStrings(); m_map.UpdateDialog(); m_map.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditScripts() { if (m_Scripttypes.m_hWnd == NULL) { if (!m_Scripttypes.Create(CScriptTypes::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_Scripttypes.m_hWnd != NULL) { //m_Scripttypes.UpdateStrings(); m_Scripttypes.UpdateDialog(); m_Scripttypes.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditSpecialflags() { if (m_specialflags.m_hWnd == NULL) { if (!m_specialflags.Create(CSpecialFlags::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_specialflags.m_hWnd != NULL) { //m_specialflags.UpdateStrings(); m_specialflags.UpdateDialog(); m_specialflags.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditTags() { if (m_tags.m_hWnd == NULL) { if (!m_tags.Create(CTags::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_tags.m_hWnd != NULL) { //m_tags.UpdateStrings(); m_tags.UpdateDialog(); m_tags.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditTaskforces() { if (m_taskforces.m_hWnd == NULL) { if (!m_taskforces.Create(CTaskForce::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_taskforces.m_hWnd != NULL) { //m_taskforces.UpdateStrings(); m_taskforces.UpdateDialog(); m_taskforces.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditTeams() { if (m_teamtypes.m_hWnd == NULL) { if (!m_teamtypes.Create(CTeamTypes::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_teamtypes.m_hWnd != NULL) { //m_teamtypes.UpdateStrings(); m_teamtypes.UpdateDialog(); m_teamtypes.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnEditTriggers() { } void CFinalSunDlg::OnSetFocus(CWnd* pOldWnd) { CDialog::OnSetFocus(pOldWnd); SetForegroundWindow(); } BOOL CFinalSunDlg::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) { // return CDialog::OnChildNotify(message, wParam, lParam, pLResult); } void CFinalSunDlg::RecalcLayout() { if (m_bar.m_hWnd == NULL) return; RECT r, rr; GetClientRect(&r); m_bar.GetWindowRect(&rr); int h = rr.bottom - rr.top + 2; m_bar.GetClientRect(&rr); rr.right = r.right; m_view.SetWindowPos(NULL, 0, h, r.right, r.bottom - h, SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); m_bar.SetWindowPos(NULL, 0, 0, rr.right, rr.bottom, SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); m_bar.ShowBand(0, TRUE); m_bar.ShowBand(1, TRUE); } BOOL CFinalSunDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { NMHDR* pHead = (NMHDR*)lParam; if (pHead->hwndFrom == m_bar.m_hWnd && pHead->code == RBN_HEIGHTCHANGE) { RecalcLayout(); } if (pHead->code == TTN_NEEDTEXT) { TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pHead; auto nID = pHead->idFrom; if (pTTT->uFlags & TTF_IDISHWND) { // idFrom ist der HWND des Tools nID = ::GetDlgCtrlID((HWND)nID); } if (nID) { CString s; char c[50]; itoa(nID, c, 10); s.LoadString(nID); s = TranslateStringACP(s); //pTTT->lpszText = s; if (s.GetLength() > 80) s.SetAt(80, 0); strcpy(pTTT->szText, s); pTTT->hinst = NULL; return(TRUE); } } return CDialog::OnNotify(wParam, lParam, pResult); } void CFinalSunDlg::OnTerrainHeightenground() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (AD.mode != ACTIONMODE_HEIGHTEN) { m_settingsbar.m_BrushSize = 1; m_settingsbar.UpdateData(FALSE); m_view.m_isoview->m_BrushSize_x = 2; m_view.m_isoview->m_BrushSize_y = 2; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_HEIGHTEN; } void CFinalSunDlg::OnTerrainLowerground() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (AD.mode != ACTIONMODE_LOWER) { m_settingsbar.m_BrushSize = 1; m_settingsbar.UpdateData(FALSE); m_view.m_isoview->m_BrushSize_x = 2; m_view.m_isoview->m_BrushSize_y = 2; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_LOWER; } //DEL void CFinalSunDlg::OnTerrainPaint() //DEL { //DEL if(m_TerrainDlg.m_hWnd==NULL) //DEL { //DEL if(!m_TerrainDlg.Create(NULL, "Terrain-Browser", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, NULL, 0)) //DEL { //DEL MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); //DEL } //DEL } //DEL //DEL if(m_TerrainDlg.m_hWnd!=NULL) //DEL { //DEL m_TerrainDlg.ShowWindow(SW_SHOW); //DEL m_TerrainDlg.ActivateFrame(SW_SHOW); //DEL m_TerrainDlg.m_bar.Update(); //DEL } //DEL } void CFinalSunDlg::OnTerrainLowertile() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (AD.mode != ACTIONMODE_LOWERTILE) { m_settingsbar.m_BrushSize = 0; m_settingsbar.UpdateData(FALSE); m_view.m_isoview->m_BrushSize_x = 1; m_view.m_isoview->m_BrushSize_y = 1; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_LOWERTILE; } void CFinalSunDlg::OnTerrainRaisetile() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (AD.mode != ACTIONMODE_HEIGHTENTILE) { m_settingsbar.m_BrushSize = 0; m_settingsbar.UpdateData(FALSE); m_view.m_isoview->m_BrushSize_x = 1; m_view.m_isoview->m_BrushSize_y = 1; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_HEIGHTENTILE; } void CFinalSunDlg::OnTerrainFlatten() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (AD.mode != ACTIONMODE_FLATTENGROUND) { m_settingsbar.m_BrushSize = 1; m_settingsbar.UpdateData(FALSE); m_view.m_isoview->m_BrushSize_x = 2; m_view.m_isoview->m_BrushSize_y = 2; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_FLATTENGROUND; } void CFinalSunDlg::OnTerrainCloak() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } AD.mode = ACTIONMODE_HIDETILESET; Sound(SOUND_POSITIVE); } void CFinalSunDlg::OnTerrainShoweverytile() { if (!Map->GetIsoSize()) { Sound(SOUND_NEGATIVE); return; } m_view.m_isoview->ShowAllTileSets(); m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Sound(SOUND_POSITIVE); } void CFinalSunDlg::OnTerrainShowallfields() { if (!Map->GetIsoSize()) { Sound(SOUND_NEGATIVE); return; } int idx; for (idx = 0; idx < Map->GetIsoSize() * Map->GetIsoSize(); idx++) { Map->HideField(idx, FALSE); } m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Sound(SOUND_POSITIVE); } void CFinalSunDlg::OnTerrainHidefield() { if (!Map->GetIsoSize()) { Sound(SOUND_NEGATIVE); return; } AD.mode = ACTIONMODE_HIDEFIELD; Sound(SOUND_POSITIVE); } void CFinalSunDlg::OnEditTriggereditor() { if (m_triggereditor.m_hWnd == NULL) { if (!m_triggereditor.Create(CTriggerEditorDlg::IDD, NULL)) { MessageBox(GetLanguageStringACP("Err_CreateErr"), "Error"); } } if (m_triggereditor.m_hWnd != NULL) { //m_all.UpdateStrings(); m_triggereditor.UpdateDialog(); m_triggereditor.ShowWindow(SW_SHOW); Sound(SOUND_POSITIVE); } } void CFinalSunDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { CDialog::OnKeyDown(nChar, nRepCnt, nFlags); } void CFinalSunDlg::OnMaptoolsChangemapheight() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); int vmin = -MAXHEIGHT; int vmax = MAXHEIGHT; int isosize = Map->GetIsoSize(); int mapsize = isosize * isosize; int mapwidth = Map->GetWidth(); int mapheight = Map->GetHeight(); int max = Map->GetIsoSize() * Map->GetIsoSize(); int idx; for (idx = 0; idx < max; idx++) { int dwX = idx % isosize; int dwY = idx / isosize; //if(dwX==0 || dwY==0 || dwX+dwYmapwidth+mapheight*2 || (dwY+1>mapwidth && dwXmapwidth && dwY+mapwidthmapwidth+mapheight*2 || (dwY+2>mapwidth && dwX-2mapwidth && dwY+mapwidth-2mapwidth + mapheight * 2 || (dwY + 1 > mapwidth && dwX - 1 < dwY - mapwidth) || (dwX + 1 > mapwidth && dwY + mapwidth - 1 < dwX)) { } else { int v = Map->GetHeightAt(idx); if (v + vmin < 0) { vmin = -v; } if (v + vmax > MAXHEIGHT) { vmax = MAXHEIGHT - v; } } } CString p = GetLanguageStringACP("StrChangeHeight"); char c[50]; itoa(vmin, c, 10); p = TranslateStringVariables(1, p, c); itoa(vmax, c, 10); p = TranslateStringVariables(2, p, c); CString res = InputBox(p, GetLanguageStringACP("StrChangeHeightCap")); if (res.GetLength() < 0) return; int a = atoi(res); if (a == 0) return; for (idx = 0; idx < max; idx++) { int dwX = idx % isosize; int dwY = idx / isosize; //if(dwX==0 || dwY==0 || dwX+dwYmapwidth+mapheight*2 || (dwY+1>mapwidth && dwXmapwidth && dwY+mapwidthmapwidth+mapheight*2 || (dwY+2>mapwidth && dwX-2mapwidth && dwY+mapwidth-2mapwidth + mapheight * 2 || (dwY + 1 > mapwidth && dwX - 1 < dwY - mapwidth) || (dwX + 1 > mapwidth && dwY + mapwidth - 1 < dwX)) { } else { int v = Map->GetHeightAt(idx); if (v + a <0 || v + a>MAXHEIGHT) { MessageBox(GetLanguageStringACP("StrChangeHeightErr"), GetLanguageStringACP("StrChangeHeightErrCap"), MB_ICONSTOP); return; } } } for (idx = 0; idx < max; idx++) { int v = Map->GetHeightAt(idx); Map->SetHeightAt(idx, v + a); } this->m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CFinalSunDlg::OnEditGlobalvariables() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); CGlobalsDlg dlg; dlg.DoModal(); UpdateDialogs(TRUE); } BOOL CFinalSunDlg::PreTranslateMessage(MSG* pMsg) { // CG: Der folgende Block wurde von der Komponente "QuickInfo" hinzugefügt. { // Diese Nachricht von QuickInfo verarbeiten lassen. //m_tooltip.RelayEvent(pMsg); } return CDialog::PreTranslateMessage(pMsg); // CG: Dies wurde von der Komponente "QuickInfo" hinzugefügt. } void CFinalSunDlg::OnEditUndo() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } //int a=0; //int b=2/a; //memcpy( (void*)0xddffeedd,&a, 1); Sound(SOUND_POSITIVE); Map->Undo(); //UpdateDialogs(FALSE); m_view.m_isoview->SendMessage(WM_RBUTTONUP); m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CFinalSunDlg::OnHelpManual() { Sound(SOUND_POSITIVE); if (ShellExecuteW(0, NULL, (utf8ToUtf16(AppPath) + L"\\HelpManual.pdf").c_str(), NULL, NULL, SW_NORMAL) == 0) { MessageBox((CString)"Could not open HelpManual.pdf! Try opening " + (CString)AppPath + (CString)"\\HelpManual manually."); } } LONG __stdcall ExceptionHandler( _EXCEPTION_POINTERS* ExceptionInfo // address of // exception info ) { CString s; CString s2; CString s_add; char adress[50]; char c[50]; itoa((std::ptrdiff_t)ExceptionInfo->ExceptionRecord->ExceptionAddress, adress, 16); s = "Unknown exception"; switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: s = "EXCEPTION_ACCESS_VIOLATION"; s2 = "Thread did not have read or write access to the virtual address."; if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) { s_add = "\nAdditional information: Write access to 0x"; } else s_add = "\nAdditional information: Read access from 0x"; itoa(ExceptionInfo->ExceptionRecord->ExceptionInformation[1], c, 16); s_add += c; break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: s = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; s2 = "Thread tried to access an array out of bounds."; break; case EXCEPTION_BREAKPOINT: s = "EXCEPTION_BREAKPOINT"; s2 = "Encountered breakpoint."; break; case EXCEPTION_DATATYPE_MISALIGNMENT: s = "EXCEPTION_DATATYPE_MISALIGNMENT"; s2 = "Access to memory was misaligned for the given datatype."; break; case EXCEPTION_FLT_DENORMAL_OPERAND: s = "EXCEPTION_FLT_DENORMAL_OPERAND"; s2 = "Denormal operand in floating point operation."; break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: s = "EXCEPTION_FLT_DIVIDE_BY_ZERO"; s2 = "Thread divided by zero in a floating point operation."; break; case EXCEPTION_FLT_INEXACT_RESULT: s = "EXCEPTION_FLT_INEXACT_RESULT"; s2 = "Floating point operation result not representable with exact decimal fraction."; break; case EXCEPTION_FLT_INVALID_OPERATION: s = "EXCEPTION_FLT_INVALID_OPERATION"; s2 = "Invalid floating point operation."; break; case EXCEPTION_FLT_OVERFLOW: s = "EXCEPTION_FLT_OVERFLOW"; s2 = "Floating point overflow error."; break; case EXCEPTION_FLT_STACK_CHECK: s = "EXCEPTION_FLT_STACK_CHECK"; s2 = "Floating point operation caused stack overflow or underflow."; break; case EXCEPTION_FLT_UNDERFLOW: s = "EXCEPTION_FLT_UNDERFLOW"; s2 = "Floating point underflow error."; break; case EXCEPTION_ILLEGAL_INSTRUCTION: s = "EXCEPTION_ILLEGAL_INSTRUCTION"; s2 = "Thread executed illegal instruction."; break; case EXCEPTION_IN_PAGE_ERROR: s = "EXCEPTION_IN_PAGE_ERROR"; s2 = "Thread tried to access a page that could not be retrieved by the system."; break; case EXCEPTION_INT_DIVIDE_BY_ZERO: s = "EXCEPTION_INT_DIVIDE_BY_ZERO"; s2 = "Thread divided by zero in an integer operation."; break; case EXCEPTION_INT_OVERFLOW: s = "EXCEPTION_INT_OVERFLOW"; s2 = "Integer operation caused overflow."; break; case EXCEPTION_INVALID_DISPOSITION: s = "EXCEPTION_INVALID_DISPOSITION"; s2 = "Exception handler returned invalid disposition."; break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: s = "EXCEPTION_NONCONTINUABLE_EXCEPTION"; s2 = "Cannot continue execution after a noncontinuable exception."; break; case EXCEPTION_PRIV_INSTRUCTION: s = "EXCEPTION_PRIV_INSTRUCTION"; s2 = "Instruction not valid in the current machine mode."; break; case EXCEPTION_SINGLE_STEP: s = "EXCEPTION_SINGLE_STEP"; s2 = "Instruction step has been executed."; break; case EXCEPTION_STACK_OVERFLOW: s = "EXCEPTION_STACK_OVERFLOW"; s2 = "Stack overflow."; } CString s3; #ifdef TS_MODE s3 = "INTERNAL APPLICATION ERROR\n\nApplication will now try to free memory, save the current map as \"fcrash_backup.map\" in the FinalSun directory and quit.\n\n\n"; #else // RA2_MODE s3 = "INTERNAL APPLICATION ERROR\n\nApplication will now try to free memory, save the current map as \"fcrash_backup.map\" in the FinalAlert 2 directory and quit.\n\n\n"; #endif s3 += "Important: If this error has occured while loading graphics, it can very often be fixed by using another system color resolution (16, 24 or 32 bit)."; s3 += "\n\nThe following information is available, please note every line below:\n\n"; s3 += "Last succeeded operation: "; itoa(last_succeeded_operation, c, 10); s3 += c; s3 += ""; s3 += "\nLast library operation: "; itoa(FSunPackLib::last_succeeded_operation, c, 10); s3 += c; s3 += "\n"; s3 += "\nException data:\n"; s3 += s; s3 += "\n"; s3 += s2; s3 += "\nAt address: "; s3 += adress; s3 += s_add; errstream << "Exception occured. Current data:" << endl; errstream << "Last succeeded operation:" << last_succeeded_operation << endl; errstream << "Last succeeded library operation:" << FSunPackLib::last_succeeded_operation << endl; errstream << "Trying to save current map" << endl; errstream.flush(); if (MessageBox(0, s3, "Fatal error", MB_OKCANCEL) == IDOK) { return EXCEPTION_CONTINUE_EXECUTION; } std::string file = u8AppDataPath; file += "\\fcrash_backup.map"; ((CFinalSunDlg*)theApp.m_pMainWnd)->SaveMap(file.c_str()); theApp.m_loading->FreeAll(); rules.Clear(); ai.Clear(); art.Clear(); tiles_t.Clear(); tiles_s.Clear(); tiles_u.Clear(); Map->GetIniFile().Clear(); sound.Clear(); tutorial.Clear(); g_data.Clear(); language.Clear(); #ifdef _DEBUG return EXCEPTION_CONTINUE_SEARCH; #endif return EXCEPTION_EXECUTE_HANDLER;//EXCEPTION_CONTINUE_SEARCH;//EXCEPTION_EXECUTE_HANDLER; } INT_PTR CFinalSunDlg::DoModal() { int res = 0; SetUnhandledExceptionFilter(ExceptionHandler); res = CDialog::DoModal(); return res; } void CFinalSunDlg::OnMaptoolsAutolevel() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); auto const txt = TranslateStringACP("AutoLevelerDlgDesc"); MessageBox(EscapeString(txt), TranslateStringACP("Auto Leveler")); m_view.m_isoview->AutoLevel(); } void CFinalSunDlg::OnUpdateEditAitriggerenabling(CCmdUI* pCmdUI) { /*if(Map->GetIsoSize()==0) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE);*/ } void CFinalSunDlg::OnUpdateEditAitriggers(CCmdUI* pCmdUI) { /*if(Map->GetIsoSize()==0) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE);*/ } void CFinalSunDlg::OnUpdateEditBasicsettings(CCmdUI* pCmdUI) { /*if(Map->GetIsoSize()==0) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE);*/ } void CFinalSunDlg::OnUpdateEditGlobalvariables(CCmdUI* pCmdUI) { /*if(Map->GetIsoSize()==0) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE);*/ } void CFinalSunDlg::OnUpdateEditHouses(CCmdUI* pCmdUI) { CheckAvail(pCmdUI); } void CFinalSunDlg::OnUpdateEditIniediting(CCmdUI* pCmdUI) { CheckAvail(pCmdUI); } void CFinalSunDlg::OnUpdateEditLighting(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditMap(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditScripts(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditSingleplayersettings(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditSpecialflags(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditTags(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditTaskforces(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditTeams(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditTriggereditor(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditTriggers(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateEditUndo(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateFileSave(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateFileSaveas(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateFileValidatemap(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateMaptoolsAutolevel(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateMaptoolsChangemapheight(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateOptionsShowminimap(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainCloak(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainFlatten(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainHeightenground(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainHidefield(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainLowerground(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainLowertile(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainRaisetile(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainShowallfields(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnUpdateTerrainShoweverytile(CCmdUI* pCmdUI) { // TODO: Code für die Befehlsbehandlungsroutine zum Aktualisieren der Benutzeroberfläche hier einfügen } void CFinalSunDlg::OnMaptoolsFrontcliff() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (Map->GetTheater() == THEATER4) { MessageBox("There are no cliffs in the Lunar theater"); return; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_CLIFFFRONT; } void CFinalSunDlg::OnMaptoolsBackcliff() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } if (Map->GetTheater() == THEATER4) { MessageBox("There are no cliffs in the Lunar theater"); return; } Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_CLIFFBACK; } void CFinalSunDlg::OnEditRedo() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); Map->Redo(); m_view.m_isoview->SendMessage(WM_RBUTTONUP); m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CFinalSunDlg::OnMaptoolsAutocreateshores() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); Map->TakeSnapshot(); Map->CreateShore(0, 0, Map->GetIsoSize(), Map->GetIsoSize()); m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Map->TakeSnapshot(); Map->Undo(); } void CFinalSunDlg::OnOptionsDisableautoshore() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_DISABLEAUTOSHORE, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLEAUTOSHORE, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bDisableAutoShore = FALSE; Options.SetBool("UserInterface", "DisableAutoShore", false); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLEAUTOSHORE, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bDisableAutoShore = TRUE; Options.SetBool("UserInterface", "DisableAutoShore", true); } #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } //DEL void CFinalSunDlg::OnNcPaint() //DEL { //DEL CBitmap b; //DEL b.LoadBitmap(IDB_TEXTURE1); //DEL CDC dc; //DEL //DEL //DEL CDC* target=GetWindowDC(); //DEL dc.CreateCompatibleDC(target); //DEL dc.SelectObject(b); //DEL //DEL BITMAP bd; //DEL b.GetBitmap(&bd); //DEL //DEL RECT r; //DEL GetWindowRect(&r); //DEL //DEL int count=(r.right-r.left)/bd.bmWidth+1; //DEL int i; //DEL for(i=0;iBitBlt(i*bd.bmWidth,0,bd.bmWidth, bd.bmHeight-1, &dc, 0, 0, SRCCOPY); //DEL } //DEL //DEL ReleaseDC(target); //DEL //DEL CMenu* m=GetMenu(); //DEL if(m) //DEL { //DEL count=m->GetMenuItemCount(); //DEL for(i=0;iGetMenuItemID(i); //DEL t.itemAction=ODA_DRAWENTIRE; //DEL t.itemState=ODS_DEFAULT; //DEL t.hwndItem=(HWND)m->m_hMenu; //DEL t.rcItem=r; //DEL CString text; //DEL m->GetMenuString(t.itemID, text, MF_BYCOMMAND); //DEL t.itemData=(int)(LPCSTR)text; //DEL //DEL m->DrawItem(&t); //DEL } //DEL } //DEL //DEL //DEL //DEL dc.DeleteDC(); //DEL b.DeleteObject(); //DEL //DEL // Kein Aufruf von CDialog::OnNcPaint() für Zeichnungsnachrichten //DEL } void CFinalSunDlg::OnOptionsDisableautolat() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_DISABLEAUTOLAT, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLEAUTOLAT, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bDisableAutoLat = FALSE; Options.SetBool("UserInterface", "DisableAutoLat", false); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLEAUTOLAT, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bDisableAutoLat = TRUE; Options.SetBool("UserInterface", "DisableAutoLat", true); } #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } void CFinalSunDlg::OnEditPaste() { Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_PASTE; AD.z_data = 0; } void CFinalSunDlg::OnEditCopy() { Sound(SOUND_POSITIVE); AD.mode = ACTIONMODE_COPY; } void CFinalSunDlg::OnEditCopywholemap() { Sound(SOUND_POSITIVE); Map->Copy(); } void CFinalSunDlg::OnEditPastewholemap() { Sound(SOUND_POSITIVE); Map->Paste(Map->GetIsoSize() / 2, Map->GetIsoSize() / 2, 0); m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CFinalSunDlg::OnMarblemadness() { if (Map->GetIsoSize() == 0) { Sound(SOUND_NEGATIVE); return; } Sound(SOUND_POSITIVE); theApp.m_Options.bMarbleMadness = !theApp.m_Options.bMarbleMadness; m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); m_view.m_browser->m_view.SetTileSet(m_view.m_browser->m_view.m_currentTileSet, TRUE); } void CFinalSunDlg::CheckAvail(CCmdUI* pCmdUI) { /*if(Map->GetIsoSize()==0) { pCmdUI->Enable(FALSE); if(pCmdUI->m_pMenu) { pCmdUI->m_pMenu->DeleteMenu(pCmdUI->m_nIndex, MF_BYPOSITION); } } else { pCmdUI->Enable(TRUE); if(pCmdUI->m_pMenu) { pCmdUI->m_pMenu->ModifyMenu(pCmdUI->m_nID, MF_BYCOMMAND | MF_ENABLED); } }*/ } void CFinalSunDlg::OnOptionsSounds() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_SOUNDS, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_SOUNDS, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bNoSounds = TRUE; Options.SetBool("UserInterface", "Sounds", false); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_SOUNDS, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bNoSounds = FALSE; Options.SetBool("UserInterface", "Sounds", true); } #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } void CFinalSunDlg::OnUpdateOptionsSounds(CCmdUI* pCmdUI) { pCmdUI->SetCheck(theApp.m_Options.bNoSounds ? 0 : 1); } void CFinalSunDlg::OnOptionsDisableslopecorrection() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_DISABLESLOPECORRECTION, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLESLOPECORRECTION, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bDisableSlopeCorrection = FALSE; Options.SetBool("UserInterface", "DisableSlopeCorrection", false); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_DISABLESLOPECORRECTION, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bDisableSlopeCorrection = TRUE; Options.SetBool("UserInterface", "DisableSlopeCorrection", true); } #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } void CFinalSunDlg::OnOptionsShowbuildingoutline() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_SHOWBUILDINGOUTLINE, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_SHOWBUILDINGOUTLINE, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.bShowCells = FALSE; Options.SetBool("UserInterface", "ShowBuildingCells", false); } else { GetMenu()->CheckMenuItem(ID_OPTIONS_SHOWBUILDINGOUTLINE, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.bShowCells = TRUE; Options.SetBool("UserInterface", "ShowBuildingCells", true); } m_view.m_isoview->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } BOOL CFinalSunDlg::OnRecentFileClicked(UINT nID) { auto const idx = nID - ID_FILE_FILE1; if (nID < 0 || nID >= ID_FILE_FILE1 + RecentFilesSlots) { return FALSE; } auto const& path = theApp.m_Options.prev_maps[idx]; if (DoesFileExist(path)) { OpenMap(path); } return TRUE; } // MW 07/20/01: Checks if file already exists in prev. files list. If not, adds it (may delete old ones) void CFinalSunDlg::InsertPrevFile(CString lpFilename) { //int free_at=-1; for (auto idx = 0; idx < RecentFilesSlots; idx++) { if (!lpFilename.CompareNoCase(theApp.m_Options.prev_maps[idx])) { return; } /*if(free_at<0) { if(theApp.m_Options.prev_maps[i].GetLength()==0) { free_at=i; } }*/ } CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif for (auto idx = RecentFilesSlots - 1; idx > 0; idx--) { theApp.m_Options.prev_maps[idx] = theApp.m_Options.prev_maps[idx - 1]; } theApp.m_Options.prev_maps[0] = lpFilename; CString e; Options.SetString("Files", "0", theApp.m_Options.prev_maps[0]); for (auto idx = 1; idx < RecentFilesSlots; idx++) { e.Format("%d", idx); Options.SetString("Files", e, theApp.m_Options.prev_maps[idx]); } #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif UpdateStrings(); } // MW 07/20/01: New: for files clicked in the file list... copied from OnFileOpenmap(); void CFinalSunDlg::OpenMap(LPCSTR lpFilename) { CString r = GetLanguageStringACP("SAVEDLG_FILETYPES"); r = TranslateStringVariables(8, r, ";"); //CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST, r); char cuPath[MAX_PATH]; GetCurrentDirectory(MAX_PATH, cuPath); //dlg.m_ofn.lpstrInitialDir=cuPath; //if(theApp.m_Options.TSExe.GetLength()) dlg.m_ofn.lpstrInitialDir=(char*)(LPCTSTR)theApp.m_Options.TSExe; //if(dlg.DoModal()==IDCANCEL) return; m_PKTHeader.Clear(); CString fileToOpen = lpFilename;//dlg.GetPathName(); fileToOpen.MakeLower(); CString ext = fileToOpen.Right(fileToOpen.GetLength() - fileToOpen.ReverseFind('.') - 1); //dlg.GetFileExt(); ext.MakeLower(); BOOL bLoadedFromMMX = FALSE; if (ext == "mmx") { HMIXFILE hMix = FSunPackLib::XCC_OpenMix(fileToOpen, NULL); fileToOpen.Replace(".mmx", ".map"); if (fileToOpen.ReverseFind('\\') >= 0) fileToOpen = fileToOpen.Right(fileToOpen.GetLength() - fileToOpen.ReverseFind('\\') - 1); CString extractFile = u8AppDataPath.c_str(); CString pktFile = fileToOpen; pktFile.Replace(".map", ".pkt"); extractFile += "\\mmx_tmp.pkt"; FSunPackLib::XCC_ExtractFile(pktFile, extractFile, hMix); m_PKTHeader.LoadFile(extractFile, TRUE); fileToOpen = m_PKTHeader.GetString("MultiMaps", "1") + ".map"; extractFile = u8AppDataPath.c_str(); extractFile += "\\mmx_tmp.map"; FSunPackLib::XCC_ExtractFile(fileToOpen, extractFile, hMix); fileToOpen = extractFile; FSunPackLib::XCC_CloseMix(hMix); bLoadedFromMMX = TRUE; } CIniFile f; f.InsertFile(fileToOpen, "Map"); auto const& theaterType = f.GetString("Map", "Theater"); if ((theaterType == THEATER0 && theApp.m_Options.bDoNotLoadTemperateGraphics) || (theaterType == THEATER1 && theApp.m_Options.bDoNotLoadSnowGraphics)) { MessageBox("You have selected to don´t show temperate or snow theater, but this map uses this theater. You cannot load it without restarting FinalSun/FinalAlert 2 with this theater enabled.", "Error"); return; } bNoDraw = TRUE; CString str = GetLanguageStringACP("MainDialogCaption"); str += " ("; str += (char*)(LPCTSTR)lpFilename; str += ")"; // MW 07/20/01: Update prev. files InsertPrevFile(lpFilename); this->SetWindowText(str); SetCursor(LoadCursor(NULL, IDC_WAIT)); errstream << "Map->LoadMap() will be called" << endl; errstream.flush(); Map->LoadMap((char*)(LPCTSTR)fileToOpen); BOOL bNoMapFile = FALSE; if (!Map->CheckMapPackData()) { int res = MessageBox("This map seems to be corrupt. Do you want to try repairing it? If you click cancel, a empty map will be created, if you click no, it will load the map as it is", "Corrupt", MB_YESNOCANCEL); if (res == IDCANCEL) { Map->CreateMap(32, 32, THEATER0, 0); bNoMapFile = TRUE; } else { if (res == IDYES) // try repair { int fielddata_size = Map->GetIsoSize() * Map->GetIsoSize(); int idx; for (idx = 0; idx < fielddata_size; idx++) { int gr = Map->GetFielddataAt(idx)->wGround; if (gr == 0xFFFF) gr = 0; if (gr >= (*tiledata_count)) { Map->SetTileAt(idx, 0, 0); } else { if ((*tiledata)[gr].wTileCount <= Map->GetFielddataAt(idx)->bSubTile) { Map->SetTileAt(idx, 0, 0); } } } } } } if (!bNoMapFile) { if (bLoadedFromMMX) { //currentMapFile[0]=0; strcpy(currentMapFile, lpFilename); } else strcpy(currentMapFile, fileToOpen); } Sleep(200); SetCursor(m_hArrowCursor); bNoDraw = FALSE; m_view.m_isoview->UpdateDialog(TRUE); UpdateDialogs(); } void CFinalSunDlg::OnMaptoolsSearchwaypoint() { if (Map->GetIsoSize() == 0) return; CSearchWaypointDlg dlg; if (dlg.DoModal() == IDCANCEL) return; if (dlg.m_WaypointIndex < 0) return; m_view.m_isoview->FocusWaypoint(dlg.m_WaypointIndex); } void CFinalSunDlg::OnMaptoolsToolscripts() { if (Map->GetIsoSize() == 0) return; CUserScriptsDlg dlg; dlg.DoModal(); } void CFinalSunDlg::OnHelpShowlogs() { // TODO: Fügen Sie hier Ihren Befehlshandlercode ein. Sound(SOUND_POSITIVE); errstream.flush(); auto f = utf8ToUtf16(theApp.getLogFileName()); if (ShellExecuteW(0, NULL, f.c_str(), NULL, NULL, SW_NORMAL) == 0) { MessageBoxW(nullptr, (std::wstring(L"Could not open log! Try opening ") + f + L" manually").c_str(), L"Cannot open log", MB_ICONEXCLAMATION); } } void CFinalSunDlg::OnOptionsSmoothzoom() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_SMOOTHZOOM, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_SMOOTHZOOM, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.viewScaleUseSteps = true; } else { GetMenu()->CheckMenuItem(ID_OPTIONS_SMOOTHZOOM, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.viewScaleUseSteps = false; } Options.SetBool("UserInterface", "ViewScaleUseSteps", theApp.m_Options.viewScaleUseSteps); #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif } BOOL CFinalSunDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (!CDialog::OnSetCursor(pWnd, nHitTest, message)) SetCursor(m_hArrowCursor); return TRUE; } void CFinalSunDlg::OnOptionsUsedefaultmousecursor() { CIniFile Options; Options.LoadFile(u8AppDataPath + "\\FinalSun.ini"); #ifdef RA2_MODE Options.LoadFile(u8AppDataPath + "\\FinalAlert.ini"); #endif if (GetMenu()->GetMenuState(ID_OPTIONS_USEDEFAULTMOUSECURSOR, MF_BYCOMMAND) & MF_CHECKED) { GetMenu()->CheckMenuItem(ID_OPTIONS_USEDEFAULTMOUSECURSOR, MF_BYCOMMAND | MF_UNCHECKED); theApp.m_Options.useDefaultMouseCursor = false; m_hArrowCursor = m_hGameCursor; } else { GetMenu()->CheckMenuItem(ID_OPTIONS_USEDEFAULTMOUSECURSOR, MF_BYCOMMAND | MF_CHECKED); theApp.m_Options.useDefaultMouseCursor = true; m_hArrowCursor = LoadCursor(NULL, IDC_ARROW); } Options.SetBool("UserInterface", "UseDefaultMouseCursor", theApp.m_Options.useDefaultMouseCursor); #ifndef RA2_MODE Options.SaveFile(u8AppDataPath + "\\FinalSun.ini"); #else Options.SaveFile(u8AppDataPath + "\\FinalAlert.ini"); #endif }