diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3897f196..cfda1a64 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# FINALALERT2 - SP CHANGELOG
+## RELEASE 1.6.3 (2023-11-22)
+- New ***ExtConfig*** : `ExtVariables` = **BOOLEAN**, defaults to false
+- New ***ExtConfig*** : `FileWatcher` = **BOOLEAN**, defaults to true
+- Add shortcuts to some online websites
+ - [FA2sp Github Page](https://github.com/secsome/FA2sp), translation key: `Menu.Online.FA2sp`
+ - [Phobos Github Page](https://github.com/Phobos-developers/Phobos), translation key: `Menu.Online.Phobos`
+ - [PPM Forum MainPage](https://www.ppmforums.com/), translation key: `Menu.Online.PPM`
+ - [ModEnc MainPage](https://modenc.renegadeprojects.com/Main_Page), translation key: `Menu.Online.ModEnc`
+ - You can also add your own shortcuts (3 at max) by editing `FAData.ini` section `[Online]`
+ - This feature might be vulnerable in some cases, so it is disabled by default, you can enable it by setting ***ExtConfig*** : `CustomOnlineWebsites` = **BOOLEAN**, defaults to false
+ ```ini
+ ; In `FAData.ini`
+ [OnlineWebsites]
+ Custom1=My Website Name 1,https://website1.com
+ Custom2=My Website Name 2,https://website2.com
+ Custom3=My Website Name 3,https://website3.com
+ ```
+
## RELEASE 1.6.2 (2023-07-18)
- Renamed ***ExtConfig*** : `BrowserRedraw.GuessMode` to `ObjectBrowser.GuessMode`
- Renamed ***ExtConfig*** : `BrowserRedraw.CleanUp` to `ObjectBrowser.CleanUp`
diff --git a/DOCUMENT.md b/DOCUMENT.md
index 75fd1322..b95e074d 100644
--- a/DOCUMENT.md
+++ b/DOCUMENT.md
@@ -73,7 +73,10 @@ Now this feature supports RaiseSingleTile/LowerSingleTile (though they are not "
- `EnableMultiSelection` = **BOOLEAN** ; Determines if FA2sp will enable expermental multi-selection features, defaults to **false**
- `ExtendedValidationNoError` = **BOOLEAN** ; If this value is true, then extended map validation won't be shown as error but warning, defaults to **false**
- `HideNoRubbleBuilding` = **BOOLEAN** ; If this value is true, then building whose HP = 0 with `LeaveRubble=no` won't be rendered, defaults to **false**
- - **`[Sides]`** (**x** means this item is **essensial**, fa2sp need this section to work properly)
+ - `ExtVariables` = **BOOLEAN** ; Determines if FA2sp supports unlimited count of local variables, defaults to **false** (Phobos required)
+ - `FileWatcher` = **BOOLEAN** ; Determines if FA2sp will detect if map file is modified external, defaults to **true**
+ - `CustomOnlineWebsites` = **BOOLEAN** ; Determines if FA2sp will read custom online websites
+ - - **`[Sides]`** (**x** means this item is **essensial**, fa2sp need this section to work properly)
- Contains a list of sides registered in rules
```ini
[Sides]
@@ -371,6 +374,14 @@ Now this feature supports RaiseSingleTile/LowerSingleTile (though they are not "
Index = RegName
; Like 0=INORANLAMP, value must be a valid building regname
```
+
+ - `[OnlineWebsites]`
+ ```ini
+ [OnlineWebsites]
+ Custom1=My Website Name 1,https://website1.com
+ Custom2=My Website Name 2,https://website2.com
+ Custom3=My Website Name 3,ahttps://website3.com
+ ```
- `FALanguage.ini`
```ini
[CURRENTLANGUAGE-StringsRA2]
@@ -432,9 +443,10 @@ Now this feature supports RaiseSingleTile/LowerSingleTile (though they are not "
Menu.MapTools.NavigateCoordinate = TEXT
Menu.MapTools.ToolScripts = TEXT
Menu.Online = TEXT
- Menu.Online.Westwood = TEXT
- Menu.Online.FA2Fansite = TEXT
- Menu.Online.FA2Forum = TEXT
+ Menu.Online.FA2sp = TEXT
+ Menu.Online.Phobos = TEXT
+ Menu.Online.PPM = TEXT
+ Menu.Online.ModEnc = TEXT
Menu.Options = TEXT
Menu.Options.Settings = TEXT
Menu.Options.ShowMinimap = TEXT
diff --git a/FA2pp b/FA2pp
index e4230163..0f7f53e0 160000
--- a/FA2pp
+++ b/FA2pp
@@ -1 +1 @@
-Subproject commit e4230163342b12b7e826c72677110cab77b6f911
+Subproject commit 0f7f53e083f6f6424d670a2381d2c52300f29714
diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj
index ec07fa28..14161d70 100644
--- a/FA2sp.vcxproj
+++ b/FA2sp.vcxproj
@@ -205,7 +205,9 @@
+
+
diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters
index 39c2d616..bf366302 100644
--- a/FA2sp.vcxproj.filters
+++ b/FA2sp.vcxproj.filters
@@ -524,6 +524,12 @@
源文件
+
+ 源文件
+
+
+ 源文件
+
diff --git a/FA2sp/Ext/CFinalSunApp/Body.cpp b/FA2sp/Ext/CFinalSunApp/Body.cpp
index 2d06b32d..fed4529c 100644
--- a/FA2sp/Ext/CFinalSunApp/Body.cpp
+++ b/FA2sp/Ext/CFinalSunApp/Body.cpp
@@ -9,9 +9,21 @@
#include "../../Miscs/FileWatcher.h"
#include "../../Miscs/SaveMap.h"
+#include
+
#pragma warning(disable : 6262)
std::vector CFinalSunAppExt::RecentFilesExt;
+std::array, 7> CFinalSunAppExt::ExternalLinks
+{
+ std::make_pair("https://github.com/secsome/FA2sp", ""),
+ std::make_pair("https://github.com/Phobos-developers/Phobos", ""),
+ std::make_pair("https://www.ppmforums.com/", ""),
+ std::make_pair("https://modenc.renegadeprojects.com/Main_Page", ""),
+ std::make_pair("", ""),
+ std::make_pair("", ""),
+ std::make_pair("", "")
+};
CFinalSunAppExt* CFinalSunAppExt::GetInstance()
{
diff --git a/FA2sp/Ext/CFinalSunApp/Body.h b/FA2sp/Ext/CFinalSunApp/Body.h
index 78fdbd72..37410105 100644
--- a/FA2sp/Ext/CFinalSunApp/Body.h
+++ b/FA2sp/Ext/CFinalSunApp/Body.h
@@ -2,6 +2,7 @@
#include
+#include
#include
#include
@@ -15,4 +16,5 @@ class NOVTABLE CFinalSunAppExt : public CFinalSunApp
BOOL InitInstanceExt();
static std::vector RecentFilesExt;
+ static std::array, 7> ExternalLinks;
};
\ No newline at end of file
diff --git a/FA2sp/Ext/CFinalSunDlg/Body.cpp b/FA2sp/Ext/CFinalSunDlg/Body.cpp
index f8a18eb8..e8391115 100644
--- a/FA2sp/Ext/CFinalSunDlg/Body.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Body.cpp
@@ -125,6 +125,25 @@ BOOL CFinalSunDlgExt::OnCommandExt(WPARAM wParam, LPARAM lParam)
}
break;
}
+ case 33000:
+ case 33001:
+ case 33002:
+ case 33003:
+ case 33004:
+ case 33005:
+ case 33006:
+ {
+ const auto& url = CFinalSunAppExt::ExternalLinks[wmID - 33000].first;
+ if (url.empty())
+ break;
+ if (!ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL))
+ {
+ std::string buffer = "Failed to open url, try manually: ";
+ buffer += url;
+ MessageBox(buffer.c_str());
+ }
+ break;
+ }
default:
break;
}
diff --git a/FA2sp/Ext/CFinalSunDlg/Hooks.cpp b/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
index e6cf7c65..a66895a8 100644
--- a/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
@@ -77,6 +77,12 @@ DEFINE_HOOK(432380, CFinalSunDlg_Update_RecentFiles, A)
pMenu->GetSubMenu(0)->InsertMenu(10 + i, MF_BYPOSITION, 40140 + i, CFinalSunAppExt::RecentFilesExt[i].c_str());
}
+ for (size_t i = 4; i < 7; ++i)
+ {
+ if (!CFinalSunAppExt::ExternalLinks[i].first.empty())
+ pMenu->GetSubMenu(4)->InsertMenu(3 + i, MF_BYPOSITION, 33000 + i, CFinalSunAppExt::ExternalLinks[i].second.c_str());
+ }
+
R->EDI(::CheckMenuItem);
return 0x432442;
@@ -162,13 +168,11 @@ DEFINE_HOOK(43209D, CFinalSunDlg_Update_TranslateMenuItems, A)
translateMenuItem(40134, "Menu.MapTools.NavigateCoordinate");
translateMenuItem(40135, "Menu.MapTools.ToolScripts");
- if (0)
- {
- translateSubMenu(i++, "Menu.Online");
- translateMenuItem(40078, "Menu.Online.Westwood");
- translateMenuItem(40081, "Menu.Online.FA2Fansite");
- translateMenuItem(40119, "Menu.Online.FA2Forum");
- }
+ translateSubMenu(i++, "Menu.Online");
+ translateMenuItem(33000, "Menu.Online.FA2sp");
+ translateMenuItem(33001, "Menu.Online.Phobos");
+ translateMenuItem(33002, "Menu.Online.PPM");
+ translateMenuItem(33003, "Menu.Online.ModEnc");
translateSubMenu(i++, "Menu.Options");
translateMenuItem(40004, "Menu.Options.Settings");
diff --git a/FA2sp/Ext/CLoading/Body.LoadObjects.cpp b/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
index 5ec7734d..9f182833 100644
--- a/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
+++ b/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
@@ -1199,6 +1199,16 @@ void CLoadingExt::SetValidBuffer(ImageDataClass* pData, int Width, int Height)
void CLoadingExt::GetFullPaletteName(ppmfc::CString& PaletteName)
{
+ const int len = PaletteName.GetLength();
+ if (len >= 4 &&
+ PaletteName[len - 4] == '.' &&
+ (PaletteName[len - 3] == 'p' || PaletteName[len - 3] == 'P') &&
+ (PaletteName[len - 2] == 'a' || PaletteName[len - 2] == 'A') &&
+ (PaletteName[len - 1] == 'l' || PaletteName[len - 1] == 'L'))
+ {
+ return;
+ }
+
switch (this->TheaterIdentifier)
{
case 'A':
diff --git a/FA2sp/Ext/CMapValidator/Body.cpp b/FA2sp/Ext/CMapValidator/Body.cpp
index c4cb20b4..c04770da 100644
--- a/FA2sp/Ext/CMapValidator/Body.cpp
+++ b/FA2sp/Ext/CMapValidator/Body.cpp
@@ -36,13 +36,21 @@ void CMapValidatorExt::ValidateStructureOverlapping(BOOL& result)
for (int dx = 0; dx < DataExt.Height; ++dx)
{
for (int dy = 0; dy < DataExt.Width; ++dy)
- Occupied[CMapData::Instance->GetCoordIndex(X + dx, Y + dy)].emplace_back(splits[1].m_pchData);
+ {
+ MapCoord coord = { X + dx, Y + dy };
+ if (CMapData::Instance->IsCoordInMap(coord.X, coord.Y))
+ Occupied[CMapData::Instance->GetCoordIndex(coord.X, coord.Y)].emplace_back(splits[1].m_pchData);
+ }
}
}
else
{
for (const auto& block : *DataExt.Foundations)
- Occupied[CMapData::Instance->GetCoordIndex(X + block.Y, Y + block.X)].emplace_back(splits[1].m_pchData);
+ {
+ MapCoord coord = { X + block.Y, Y + block.X };
+ if (CMapData::Instance->IsCoordInMap(coord.X, coord.Y))
+ Occupied[CMapData::Instance->GetCoordIndex(coord.X, coord.Y)].emplace_back(splits[1].m_pchData);
+ }
}
}
}
diff --git a/FA2sp/Ext/CPropertyBuilding/Hooks.cpp b/FA2sp/Ext/CPropertyBuilding/Hooks.cpp
index af3ce9e6..7d4950d7 100644
--- a/FA2sp/Ext/CPropertyBuilding/Hooks.cpp
+++ b/FA2sp/Ext/CPropertyBuilding/Hooks.cpp
@@ -68,7 +68,7 @@ DEFINE_HOOK(417F40, CPropertyBuilding_OnInitDialog, 7)
for (const auto& upgrade : upgrades)
{
const auto UIName = CMapData::Instance->GetUIName(upgrade.c_str());
- const auto name = std::format("{} ({})", upgrade, UIName);
+ const auto name = std::format("{} ({})", upgrade, UIName.m_pchData);
for (int i = 0; i < nUpgrades; ++i)
pUpgrades[i]->AddString(name.c_str());
diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h
index c3037935..a57753a5 100644
--- a/FA2sp/FA2sp.Constants.h
+++ b/FA2sp/FA2sp.Constants.h
@@ -5,7 +5,7 @@
#define PRODUCT_MAJOR 1
#define PRODUCT_MINOR 6
-#define PRODUCT_REVISION 2
+#define PRODUCT_REVISION 3
#ifdef NDEBUG
#define PRODUCT_STR __str(PRODUCT_MAJOR) "." __str(PRODUCT_MINOR) "." __str(PRODUCT_REVISION)
diff --git a/FA2sp/FA2sp.cpp b/FA2sp/FA2sp.cpp
index bd3f4266..c09f3c4b 100644
--- a/FA2sp/FA2sp.cpp
+++ b/FA2sp/FA2sp.cpp
@@ -3,10 +3,13 @@
#include "Helpers/MutexHelper.h"
#include "Helpers/InstructionSet.h"
+#include "Helpers/STDHelpers.h"
#include "Miscs/Palettes.h"
#include "Miscs/VoxelDrawer.h"
#include "Miscs/Exception.h"
+#include "Ext/CFinalSunApp/Body.h"
+
#include
#include
@@ -60,6 +63,9 @@ bool ExtConfigs::EnableMultiSelection;
bool ExtConfigs::ExtendedValidationNoError;
bool ExtConfigs::HideNoRubbleBuilding;
bool ExtConfigs::ModernObjectBrowser;
+bool ExtConfigs::ExtVariables;
+bool ExtConfigs::FileWatcher;
+bool ExtConfigs::CustomOnlineWebsites;
MultimapHelper Variables::Rules = { &CINI::Rules(), &CINI::CurrentDocument() };
MultimapHelper Variables::FAData = { &CINI::FAData() };
@@ -150,6 +156,42 @@ void FA2sp::ExtConfigsInitialize()
ExtConfigs::ExtendedValidationNoError = CINI::FAData->GetBool("ExtConfigs", "ExtendedValidationNoError");
ExtConfigs::HideNoRubbleBuilding = CINI::FAData->GetBool("ExtConfigs", "HideNoRubbleBuilding");
+
+ ExtConfigs::ExtVariables = CINI::FAData->GetBool("ExtConfigs", "ExtVariables");
+
+ ExtConfigs::FileWatcher = CINI::FAData->GetBool("ExtConfigs", "FileWatcher", true);
+
+ ExtConfigs::CustomOnlineWebsites = CINI::FAData->GetBool("ExtConfigs", "CustomOnlineWebsites");
+ if (ExtConfigs::CustomOnlineWebsites)
+ {
+ if (auto pStr = CINI::FAData->TryGetString("OnlineWebsites", "Custom1"))
+ {
+ auto res = STDHelpers::SplitString(*pStr);
+ if (res.size() == 2)
+ {
+ CFinalSunAppExt::ExternalLinks[4].first = res[1];
+ CFinalSunAppExt::ExternalLinks[4].second = res[0];
+ }
+ }
+ if (auto pStr = CINI::FAData->TryGetString("OnlineWebsites", "Custom2"))
+ {
+ auto res = STDHelpers::SplitString(*pStr);
+ if (res.size() == 2)
+ {
+ CFinalSunAppExt::ExternalLinks[5].first = res[1];
+ CFinalSunAppExt::ExternalLinks[5].second = res[0];
+ }
+ }
+ if (auto pStr = CINI::FAData->TryGetString("OnlineWebsites", "Custom3"))
+ {
+ auto res = STDHelpers::SplitString(*pStr);
+ if (res.size() == 2)
+ {
+ CFinalSunAppExt::ExternalLinks[6].first = res[1];
+ CFinalSunAppExt::ExternalLinks[6].second = res[0];
+ }
+ }
+ }
}
// DllMain
diff --git a/FA2sp/FA2sp.h b/FA2sp/FA2sp.h
index 7fa7c8ca..5cdff599 100644
--- a/FA2sp/FA2sp.h
+++ b/FA2sp/FA2sp.h
@@ -67,6 +67,9 @@ class ExtConfigs
static bool ExtendedValidationNoError;
static bool HideNoRubbleBuilding;
static bool ModernObjectBrowser;
+ static bool ExtVariables;
+ static bool FileWatcher;
+ static bool CustomOnlineWebsites;
};
class Variables
diff --git a/FA2sp/Hooks.Debug.cpp b/FA2sp/Hooks.Debug.cpp
index a75790ba..fff8011b 100644
--- a/FA2sp/Hooks.Debug.cpp
+++ b/FA2sp/Hooks.Debug.cpp
@@ -11,247 +11,4 @@
#include "Logger.h"
-//DEFINE_HOOK(48EE60, CLoading_DrawOverlay, 7)
-//{
-// GET(CLoading*, pThis, ECX);
-// GET_STACK(LPCSTR, ID, 0x4);
-// GET_STACK(int, nOverlayIndex, 0x8);
-//
-// CFinalSunDlg::LastSucceededOperation = 11;
-//
-// ppmfc::CString id = ID;
-// id.Trim();
-//
-// int nPal = pThis->GetPaletteISO();
-// if (
-// CINI::Rules->GetBool(id, "IsVeinholeMonster") ||
-// CINI::Rules->GetBool(id, "Tiberium") ||
-// CINI::Rules->GetBool(id, "IsVeins")
-// )
-// {
-// nPal = pThis->PAL_TEMPERAT;
-// }
-//
-// if (auto ppStr = CINI::Rules->TryGetString(id, "Image"))
-// id = *ppStr;
-//
-// ppmfc::CString imageName = id;
-// if (auto ppStr = CINI::Art->TryGetString(id, "Image"))
-// imageName = *ppStr;
-//
-// // Now id holds Art section name, imageName holds assert's name
-//
-//
-//
-// return 0x4909FE;
-//}
-
-//DEFINE_HOOK(4C37E7, CopyDataTest, 6)
-//{
-// GET_STACK(CopyPasteDataHeader*, pHeader, STACK_OFFS(0x54, 0x3C));
-// pHeader = &pHeader[-1];
-//
-// CopyPasteData* pDatas = (CopyPasteData*)(&pHeader[1]);
-//
-// Logger::FormatLog("CopyPasteData Width = {}, Height = {}\n", pHeader->Width, pHeader->Height);
-// for (int i = 0; i < pHeader->Width; ++i)
-// for (int j = 0; j < pHeader->Height; ++j)
-// {
-// int idx = i * pHeader->Height + j;
-// Logger::FormatLog(
-// "Data {0:d}: ({1:d}, {2:d})\n"
-// "IgnoreAltImages = {3:d}\n"
-// "Overlay, Data = {4:d}, {5:d}\n"
-// "TileIndex = {6:d}, Short30 = {7:d}, TilesubIndex= {8:d}, Height = {9:d}\n"
-// "IceGrowth = {10:d}, Unknown_C = {11:d}, TileSet = {12:d}, NthTileSetFile = {13:d}\n\n"
-// , idx, i, j, pDatas[idx].IgnoreAltImages, pDatas[idx].Overlay, pDatas[idx].OverlayData,
-// pDatas[idx].TileIndex, pDatas[idx]._8_Short_30, pDatas[idx].TileSubIndex, pDatas[idx].Height,
-// pDatas[idx].IceGrowth, pDatas[idx].Unknown_D, pDatas[idx].TileSet, pDatas[idx].NthTileSetFile);
-// }
-//
-// return 0;
-//}
-
-//DEFINE_HOOK(49C2B8, CMapData_UpdateINIFile_LoadFromINI, 7)
-//{
-// CMapData::Instance->UpdateSize();
-// CMapData::Instance->InitMinimap();
-//
-// CMapData::Instance->SlopeSetPieces = CINI::CurrentTheater->GetInteger("General", "SlopeSetPieces");
-// CMapData::Instance->RampBase = CINI::CurrentTheater->GetInteger("General", "RampBase");
-// CMapData::Instance->RampSmooth = CINI::CurrentTheater->GetInteger("General", "RampSmooth");
-// CMapData::Instance->CliffSet = CINI::CurrentTheater->GetInteger("General", "CliffSet");
-// CMapData::Instance->WaterSet = CINI::CurrentTheater->GetInteger("General", "WaterSet");
-// CMapData::Instance->ShorePieces = CINI::CurrentTheater->GetInteger("General", "ShorePieces");
-// CMapData::Instance->RampBase = CINI::CurrentTheater->GetInteger("General", "RampBase");
-// CMapData::Instance->Ramps2 = CINI::CurrentTheater->GetInteger("NewUrbanInfo", "Ramps2");
-// CMapData::Instance->Morphable2= CINI::CurrentTheater->GetInteger("NewUrbanInfo", "Morphable2");
-// CMapData::Instance->Cliff2 = CINI::CurrentTheater->GetInteger("NewUrbanInfo", "Cliffs2");
-// CMapData::Instance->CliffWaters2= CINI::CurrentTheater->GetInteger("NewUrbanInfo", "CliffsWaters");
-//
-// CMapData::Instance->CliffSetCount = CTileTypeClass::GetTileIndex(CMapData::Instance->CliffSet, 0);
-// CMapData::Instance->RampBaseCount = CTileTypeClass::GetTileIndex(CMapData::Instance->RampBase, 0);
-// CMapData::Instance->Ramps2Count = CTileTypeClass::GetTileIndex(CMapData::Instance->Ramps2, 0);
-// CMapData::Instance->Morphable2Count = CTileTypeClass::GetTileIndex(CMapData::Instance->Morphable2, 0);
-// CMapData::Instance->Cliffs2Count = CTileTypeClass::GetTileIndex(CMapData::Instance->Cliff2, 0);
-//
-//
-// CMapData::Instance->TypesInit_4AD930();
-// CMapData::Instance->InitializeBuildingTypes(nullptr);
-// CMapData::Instance->InitializeTerrainTypes(nullptr);
-// CMapData::Instance->InitializeSmudges(nullptr);
-// CMapData::Instance->UpdateMapFieldData_Field(false);
-// CMapData::Instance->UpdateMapFieldData_Aircraft(false);
-//
-// R->EBP(R->Stack32(STACK_OFFS(0x110, 0x74)));
-//
-// return 0x49D121;
-//}
-
-//DEFINE_HOOK(4B9C39, CMapData_UpdateIniFile_Debug, 5)
-//{
-// return 0;
-//}
-
-//
-//DEFINE_HOOK(438DB0, CrashMePlease, 6)
-//{
-// return 0x114514;
-//}
-
-//DEFINE_HOOK(45AF76, CIsoView_OnMouseMove_DebugCurrentCellData, 5)
-//{
-// GET(int, Y, EDI);
-// GET(int, X, EBX);
-//
-// auto& cell = CMapData::Instance->CellDatas[CMapData::Instance->GetCoordIndex(X, Y)];
-//
-// ppmfc::CString buffer;
-// char format[] =
-// "[%d, %d]\n"
-// "Unit = %d "
-// "Infantry = {%d, %d, %d}\n"
-// "Aircraft = %d "
-// "Structure = %d\n"
-// "TypeListIndex = %d\n"
-// "TerrainType = %d\n"
-// "Smudge = %d\n"
-// "SmudgeType = %d\n"
-// "Waypoint = %d\n"
-// "BaseNode = {%d, %d, %s}\n"
-// "Overlay = {%d, %d}\n"
-// "TileIndex = %d "
-// "Short_30 = %d "
-// "TileSubIndex = %d "
-// "Height = %d "
-// "IceGrowth = %d\n"
-// "CellTag = %d "
-// "Tube = %d "
-// "TubeDir = %d\n"
-// "StatusFlag = %d "
-// "LAT = %d";
-//
-// buffer.Format(format,
-// X, Y,
-// cell.Unit, cell.Infantry[0], cell.Infantry[1], cell.Infantry[2],
-// cell.Aircraft, cell.Structure,
-// cell.TypeListIndex,
-// cell.TerrainType,
-// cell.Smudge,
-// cell.SmudgeType,
-// cell.Waypoint,
-// cell.BaseNode.BuildingID, cell.BaseNode.BasenodeID, cell.BaseNode.House,
-// cell.Overlay, cell.OverlayData,
-// cell.TileIndex, cell.Short_30, cell.TileSubIndex, cell.Height, cell.IceGrowth,
-// cell.CellTag, cell.Tube, cell.TubeDataIndex,
-// cell.StatusFlag, cell.LAT);
-//
-// auto pDC = CFinalSunDlg::Instance->MyViewFrame.pIsoView->GetDC();
-// RECT rect{ 0,35,0,0 };
-// pDC->SetBkMode(OPAQUE);
-// pDC->DrawText((LPCSTR)buffer, &rect, DT_CALCRECT);
-// pDC->DrawText((LPCSTR)buffer, &rect, NULL);
-//
-// return 0;
-//}
-//
-//DEFINE_HOOK(438DB0, DebugTilesetDatas, 6)
-//{
-// struct TileBlockData
-// {
-// int Unknown_0;
-// ImageDataClass* NormalImage;
-// void* Pointer_8;
-// int Unknown_C;
-// int Unknown_10;
-// unsigned char Height;
-// unsigned char Byte_15;
-// unsigned char Byte_16;
-// unsigned char ColorLeft_Red;
-// unsigned char ColorLeft_Green;
-// unsigned char ColorLeft_Blue;
-// unsigned char ColorRight_Red;
-// unsigned char ColorRight_Green;
-// unsigned char ColorRight_Blue;
-// unsigned char Byte_1D;
-// unsigned char Byte_1E;
-// unsigned char Byte_1F;
-// };
-//
-// struct TheaterRelatedData
-// {
-// int TileSet;
-// TileBlockData* SubTileDatas;
-// __int16 SubTileCount;
-// __int16 Short_A;
-// int Unknown_C;
-// int Unknown_10;
-// int Unknown_14;
-// int Unknown_18;
-// int Unknown_1C;
-// int Unknown_20;
-// int Unknown_24;
-// int Unknown_28;
-// int Unknown_2C;
-// int Unknown_30;
-// int Unknown_34;
-// TheaterRelatedData* Next_38;
-// unsigned __int8 Byte_3C;
-// unsigned __int8 Byte_3D;
-// unsigned __int8 Byte_3E;
-// unsigned __int8 Byte_3F;
-// };
-//
-// Logger::Raw(__FUNCTION__" Runs.\n");
-// auto datas = *(TheaterRelatedData**)0x7EE070;
-// int dwTileIndexCount = ((unsigned short*)0x7EE074)[1];
-//
-// Logger::Raw("count = %d\n", dwTileIndexCount);
-//
-// for (int i = 0; i < dwTileIndexCount; ++i)
-// {
-// auto& pData = datas[i];
-// Logger::Raw("\n\n===Tileset = %d(%d)===\n", pData.TileSet, i);
-// for (int j = 0; j < pData.SubTileCount; ++j)
-// {
-// auto& pSubData = pData.SubTileDatas[j];
-// Logger::Raw(" ---Subtile = %d---\n", j);
-// Logger::Raw(" 0x0 = %d, 0x4 = %p, 0x8 = %p, 0xC = %d, 0x10 = %d\n",
-// pSubData.Unknown_0, pSubData.NormalImage, pSubData.Pointer_8, pSubData.Unknown_C, pSubData.Unknown_10);
-// Logger::Raw(" Height = %d, 0x15 = %d, 0x16 = %d\n", pSubData.Height, pSubData.Byte_15, pSubData.Byte_16);
-// Logger::Raw(" Left Color = (%d %d %d), Right Color = (%d %d %d)\n",
-// pSubData.ColorLeft_Red, pSubData.ColorLeft_Green, pSubData.ColorLeft_Blue,
-// pSubData.ColorRight_Red, pSubData.ColorRight_Green, pSubData.ColorRight_Blue);
-// Logger::Raw(" 0x1D = %d, 0x1E = %d, 0x1F = %d\n", pSubData.Byte_1D, pSubData.Byte_1E, pSubData.Byte_1F);
-// }
-// Logger::Raw("0xA = %d\n", pData.Short_A);
-// Logger::Raw("0xC = %d, 0x10 = %d, 0x14 = %d, 0x18 = %d\n", pData.Unknown_C, pData.Unknown_10, pData.Unknown_14, pData.Unknown_18);
-// Logger::Raw("0x1C = %d, 0x20 = %d, 0x24 = %d, 0x28 = %d\n", pData.Unknown_1C, pData.Unknown_20, pData.Unknown_24, pData.Unknown_28);
-// Logger::Raw("0x2C = %d, 0x30 = %d, 0x34 = %d, 0x38 = %p\n", pData.Unknown_2C, pData.Unknown_30, pData.Unknown_34, pData.Next_38);
-// Logger::Raw("0x3C = %d, 0x3D = %d, 0x3E = %d, 0x3F = %d\n", pData.Byte_3C, pData.Byte_3D, pData.Byte_3E, pData.Byte_3F);
-// }
-//
-// return 0x438E4E;
-//}
-
#endif
\ No newline at end of file
diff --git a/FA2sp/Miscs/FileWatcher.cpp b/FA2sp/Miscs/FileWatcher.cpp
index 0be84709..a445f3b1 100644
--- a/FA2sp/Miscs/FileWatcher.cpp
+++ b/FA2sp/Miscs/FileWatcher.cpp
@@ -1,15 +1,14 @@
#include "FileWatcher.h"
-#include
-
#include "../Ext/CFinalSunApp/Body.h"
#include "../Ext/CFinalSunDlg/Body.h"
-#include
-#include
+#include "../FA2sp.h"
#include "../Helpers/Translations.h"
+#include
+
FileWatcher::FileWatcher(const char* path, std::chrono::milliseconds delay, bool& running,
std::optional& savemap_time)
: path_{ path }
@@ -47,6 +46,9 @@ void FileWatcher::start(const std::function& action)
{
std::this_thread::sleep_for(delay_);
+ if (!ExtConfigs::FileWatcher)
+ return;
+
const std::string curr_path = path_;
if (curr_path != previous_path_)
{
diff --git a/FA2sp/Miscs/Hooks.DialogStyle.cpp b/FA2sp/Miscs/Hooks.DialogStyle.cpp
new file mode 100644
index 00000000..6e9972f6
--- /dev/null
+++ b/FA2sp/Miscs/Hooks.DialogStyle.cpp
@@ -0,0 +1,17 @@
+#include
+
+// DEFINE_HOOK(54FC1E, CFileDialog_EnableExplorerStyle, 7)
+// {
+// GET(CFileDialog*, pDialog, ESI);
+//
+// OPENFILENAME ofn = pDialog->m_ofn;
+//
+// ofn.Flags &= ~OFN_ENABLEHOOK;
+//
+// if (ofn.pvReserved)
+// R->EAX(GetOpenFileNameA(&ofn));
+// else
+// R->EAX(GetSaveFileNameA(&ofn));
+//
+// return 0x54FC37;
+// }
\ No newline at end of file
diff --git a/FA2sp/Miscs/Hooks.ExtLocalVariables.cpp b/FA2sp/Miscs/Hooks.ExtLocalVariables.cpp
new file mode 100644
index 00000000..22ad76df
--- /dev/null
+++ b/FA2sp/Miscs/Hooks.ExtLocalVariables.cpp
@@ -0,0 +1,11 @@
+#include
+
+#include "../FA2sp.h"
+
+DEFINE_HOOK(4483B1, CLocalVariables_UpdateDialog_ExtVariables, 9)
+{
+ if (ExtConfigs::ExtVariables || R->EBP() < 100)
+ return 0x448148;
+ else
+ return 0x4483C1;
+}
\ No newline at end of file
diff --git a/FA2sp/UI/CMenu.rc b/FA2sp/UI/CMenu.rc
index 8bb635f8..62508c9f 100644
--- a/FA2sp/UI/CMenu.rc
+++ b/FA2sp/UI/CMenu.rc
@@ -81,12 +81,13 @@ POPUP "Map tools"
MENUITEM SEPARATOR
MENUITEM "Tool Scripts", 40135
}
-//POPUP "Online"
-//{
-// MENUITEM "Westwood.com", 40078
-// MENUITEM "FinalAlert 2(tm) Fansite link", 40081
-// MENUITEM "FinalAlert 2(tm) Forum", 40119
-//}
+POPUP "Online"
+{
+ MENUITEM "FA2sp Github Page", 33000
+ MENUITEM "Phobos Github Page", 33001
+ MENUITEM "PPM Forum MainPage", 33002
+ MENUITEM "ModEnc MainPage", 33003
+}
POPUP "Options"
{
MENUITEM "Settings", 40004