/*
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
}