From 533cf9c6cd2cbac32840355c01e7ae9603ff6052 Mon Sep 17 00:00:00 2001
From: secsome <302702960@qq.com>
Date: Fri, 31 Dec 2021 12:01:49 +0800
Subject: [PATCH] Merge branch 'develop'
---
FA2sp.vcxproj | 27 +-
FA2sp.vcxproj.filters | 31 +-
FA2sp/Ext/CAITriggerTypes/Body.cpp | 3 +-
.../Body.ObjectBrowserControl.cpp | 83 ++++-
FA2sp/Ext/CFinalSunDlg/Body.cpp | 56 +++-
FA2sp/Ext/CFinalSunDlg/Body.h | 3 +
.../Hooks.ObjectBrowserControl.cpp | 3 +
FA2sp/Ext/CFinalSunDlg/Hooks.cpp | 15 +-
FA2sp/Ext/CHouses/Body.cpp | 8 +-
FA2sp/Ext/CIsoView/Body.cpp | 18 +-
FA2sp/Ext/CIsoView/Body.h | 2 +-
FA2sp/Ext/CIsoView/Hooks.cpp | 85 +++--
FA2sp/Ext/CLoading/Body.LoadObjects.cpp | 18 +-
FA2sp/Ext/CMapData/Body.cpp | 313 ++++++++++++++++++
FA2sp/Ext/CMapData/Body.h | 14 +
FA2sp/Ext/CMapData/Hooks.cpp | 17 +
FA2sp/Ext/CPropertyAircraft/Hooks.cpp | 18 +
FA2sp/Ext/CPropertyBuilding/Hooks.cpp | 83 +++++
FA2sp/Ext/CPropertyInfantry/Hooks.cpp | 18 +
FA2sp/Ext/CPropertyUnit/Hooks.cpp | 18 +
FA2sp/Ext/CScriptTypes/Body.CurrentScript.cpp | 8 +-
FA2sp/Ext/CScriptTypes/Body.cpp | 16 +-
FA2sp/Ext/CScriptTypes/Functional.h | 135 ++++----
.../TabPages/TriggerSort.cpp | 2 +-
FA2sp/Ext/CTriggerFrame/Hooks.cpp | 10 +-
.../ExtraWindow/CAllieEditor/CAllieEditor.cpp | 18 +
.../ExtraWindow/CAllieEditor/CAllieEditor.rc | 4 +-
.../ExtraWindow/CTileManager/CTileManager.cpp | 102 +++---
FA2sp/ExtraWindow/CTileManager/CTileManager.h | 19 +-
FA2sp/FA2sp.Constants.h | 4 +-
FA2sp/FA2sp.cpp | 4 +
FA2sp/FA2sp.h | 2 +
FA2sp/Helpers/ControlHelpers.cpp | 29 +-
FA2sp/Helpers/ControlHelpers.h | 3 +-
FA2sp/Helpers/INIParser.h | 82 -----
FA2sp/Helpers/MultimapHelper.cpp | 2 +-
FA2sp/Helpers/Translations.cpp | 4 +-
FA2sp/Hooks.Debug.cpp | 8 +-
FA2sp/Logger.cpp | 7 +
FA2sp/Logger.h | 9 +
FA2sp/Miscs/Exception.cpp | 75 ++++-
FA2sp/Miscs/Hooks.BugFixes.cpp | 39 ++-
FA2sp/Miscs/Hooks.LoadParams.cpp | 152 +++++++--
FA2sp/Miscs/Hooks.Mix.cpp | 8 +-
FA2sp/Miscs/Hooks.Palette.cpp | 68 ++++
FA2sp/Miscs/Hooks.RemapColor.cpp | 47 ---
FA2sp/Miscs/Palettes.cpp | 260 +++++++++++----
FA2sp/Miscs/Palettes.h | 88 ++++-
FA2sp/Miscs/SaveMap.cpp | 23 +-
...{Hooks.TheaterInfo.cpp => TheaterInfo.cpp} | 86 +++--
FA2sp/Miscs/TheaterInfo.h | 20 ++
FA2sp/UI/CMenu.rc | 9 +-
README.md | 43 ++-
53 files changed, 1636 insertions(+), 583 deletions(-)
create mode 100644 FA2sp/Ext/CMapData/Body.cpp
create mode 100644 FA2sp/Ext/CMapData/Body.h
create mode 100644 FA2sp/Ext/CMapData/Hooks.cpp
create mode 100644 FA2sp/Ext/CPropertyAircraft/Hooks.cpp
create mode 100644 FA2sp/Ext/CPropertyBuilding/Hooks.cpp
create mode 100644 FA2sp/Ext/CPropertyInfantry/Hooks.cpp
create mode 100644 FA2sp/Ext/CPropertyUnit/Hooks.cpp
delete mode 100644 FA2sp/Helpers/INIParser.h
create mode 100644 FA2sp/Miscs/Hooks.Palette.cpp
delete mode 100644 FA2sp/Miscs/Hooks.RemapColor.cpp
rename FA2sp/Miscs/{Hooks.TheaterInfo.cpp => TheaterInfo.cpp} (77%)
create mode 100644 FA2sp/Miscs/TheaterInfo.h
diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj
index e670ddf..d5530c4 100644
--- a/FA2sp.vcxproj
+++ b/FA2sp.vcxproj
@@ -15,20 +15,20 @@
Win32Proj
{3bbea2d2-97da-4b96-9516-36a6c8d3b4a3}
FA2sp
- 7.0
+ 10.0
DynamicLibrary
false
- v141_xp
+ v143
true
MultiByte
DynamicLibrary
false
- v141_xp
+ v143
true
MultiByte
@@ -66,7 +66,7 @@
false
- 4065;4530;4731;4244;4114;4172;4018;4390;4091
+ 4065;4530;4731;4244;4114;4172;4018;4390;4091;6269;28159;26812;28251;26495;
$(IntDir)%(RelativeDir)
MultiThreaded
@@ -74,7 +74,7 @@
true
false
-DISOLATION_AWARE_ENABLED %(AdditionalOptions)
- stdcpp14
+ stdcpplatest
false
MaxSpeed
@@ -101,7 +101,7 @@
false
- 4065;4530;4731;4244;4114;4172;4018;4390;4091
+ 4065;4530;4731;4244;4114;4172;4018;4390;4091;6269;28159;26812;28251;26495;
$(IntDir)%(RelativeDir)
MultiThreaded
@@ -109,7 +109,7 @@
true
false
-DISOLATION_AWARE_ENABLED %(AdditionalOptions)
- stdcpp14
+ stdcpplatest
false
Disabled
@@ -144,11 +144,17 @@
+
+
+
+
+
+
@@ -170,7 +176,7 @@
-
+
@@ -190,7 +196,7 @@
-
+
@@ -204,6 +210,7 @@
+
@@ -224,7 +231,6 @@
-
@@ -234,6 +240,7 @@
+
diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters
index e211446..b75fa4a 100644
--- a/FA2sp.vcxproj.filters
+++ b/FA2sp.vcxproj.filters
@@ -45,9 +45,6 @@
头文件
-
- 头文件
-
头文件
@@ -144,6 +141,12 @@
头文件
+
+ 头文件
+
+
+ 头文件
+
@@ -254,7 +257,7 @@
源文件
-
+
源文件
@@ -350,7 +353,25 @@
源文件
-
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
源文件
diff --git a/FA2sp/Ext/CAITriggerTypes/Body.cpp b/FA2sp/Ext/CAITriggerTypes/Body.cpp
index 18eaf40..b17f801 100644
--- a/FA2sp/Ext/CAITriggerTypes/Body.cpp
+++ b/FA2sp/Ext/CAITriggerTypes/Body.cpp
@@ -4,6 +4,7 @@
#include "../../Helpers/STDHelpers.h"
#include "../../Helpers/Translations.h"
+#include "..\CMapData\Body.h"
void CAITriggerTypesExt::ProgramStartupInit()
{
@@ -54,7 +55,7 @@ BOOL CAITriggerTypesExt::OnInitDialogExt()
int i = 1;
if (auto sides = CINI::FAData->GetSection("Sides"))
{
- for (auto& itr : sides->EntitiesDictionary)
+ for (auto& itr : sides->GetEntities())
{
ppmfc::CString buffer;
buffer.Format("%d - %s", i++, itr.second);
diff --git a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp
index 3b3b186..7941d30 100644
--- a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp
@@ -3,11 +3,14 @@
#include "../../Helpers/Translations.h"
#include "../../Helpers/STDHelpers.h"
+#include "../../Miscs/TheaterInfo.h"
+
#include "../../FA2sp.h"
#include
#include
#include
+#include
std::array ObjectBrowserControlExt::ExtNodes;
std::set ObjectBrowserControlExt::IgnoreSet;
@@ -24,6 +27,7 @@ bool ObjectBrowserControlExt::BuildingBrushBools[14];
bool ObjectBrowserControlExt::InfantryBrushBools[10];
bool ObjectBrowserControlExt::VehicleBrushBools[11];
bool ObjectBrowserControlExt::AircraftBrushBools[9];
+bool ObjectBrowserControlExt::InitPropertyDlgFromProperty{ false };
HTREEITEM ObjectBrowserControlExt::InsertString(const char* pString, DWORD dwItemData,
HTREEITEM hParent, HTREEITEM hInsertAfter)
@@ -109,7 +113,7 @@ void ObjectBrowserControlExt::Redraw_Initialize()
if (auto knownSection = fadata.GetSection("ForceSides"))
{
- for (auto& item : knownSection->EntitiesDictionary)
+ for (auto& item : knownSection->GetEntities())
{
int sideIndex = STDHelpers::ParseToInt(item.second, -1);
if (sideIndex >= fadata.GetKeyCount("Sides"))
@@ -121,11 +125,11 @@ void ObjectBrowserControlExt::Redraw_Initialize()
}
if (auto ignores = fadata.GetSection("IgnoreRA2"))
- for (auto& item : ignores->EntitiesDictionary)
+ for (auto& item : ignores->GetEntities())
IgnoreSet.insert(item.second);
if (auto forcenames = fadata.GetSection("ForceName"))
- for (auto& item : forcenames->EntitiesDictionary)
+ for (auto& item : forcenames->GetEntities())
ForceName.insert(item.second);
}
@@ -172,8 +176,23 @@ void ObjectBrowserControlExt::Redraw_Ground()
this->InsertTranslatedString("GroundPaveObList" + suffix, 66, hGround);
this->InsertTranslatedString("GroundWaterObList", 64, hGround);
- if(theater == "UBN")
- this->InsertTranslatedString("GroundPave2ObListUBN", 67, hGround);
+ if (CINI::CurrentTheater)
+ {
+ int i = 67;
+ for (auto& morphables : TheaterInfo::CurrentInfo)
+ {
+ auto InsertTile = [&](int nTileset)
+ {
+ FA2sp::Buffer.Format("TileSet%04d", nTileset);
+ FA2sp::Buffer = CINI::CurrentTheater->GetString(FA2sp::Buffer, "SetName", FA2sp::Buffer);
+ ppmfc::CString buffer;
+ Translations::GetTranslationItem(FA2sp::Buffer, FA2sp::Buffer);
+ return this->InsertString(FA2sp::Buffer, i++, hGround, TVI_LAST);
+ };
+
+ InsertTile(morphables.Morphable);
+ }
+ }
}
void ObjectBrowserControlExt::Redraw_Owner()
@@ -204,7 +223,7 @@ void ObjectBrowserControlExt::Redraw_Owner()
{
if (auto pSection = CINI::Rules->GetSection("Countries"))
{
- auto& section = pSection->EntitiesDictionary;
+ auto& section = pSection->GetEntities();
size_t i = 0;
for (auto& itr : section)
this->InsertString(itr.second, Const_House + i++, hOwner);
@@ -214,7 +233,7 @@ void ObjectBrowserControlExt::Redraw_Owner()
{
if (auto pSection = CINI::CurrentDocument->GetSection("Houses"))
{
- auto& section = pSection->EntitiesDictionary;
+ auto& section = pSection->GetEntities();
size_t i = 0;
for (auto& itr : section)
this->InsertString(itr.second, Const_House + i++, hOwner);
@@ -234,7 +253,7 @@ void ObjectBrowserControlExt::Redraw_Infantry()
int i = 0;
if (auto sides = fadata.GetSection("Sides"))
- for (auto& itr : sides->EntitiesDictionary)
+ for (auto& itr : sides->GetEntities())
subNodes[i++] = this->InsertString(itr.second, -1, hInfantry);
else
{
@@ -283,7 +302,7 @@ void ObjectBrowserControlExt::Redraw_Vehicle()
int i = 0;
if (auto sides = fadata.GetSection("Sides"))
- for (auto& itr : sides->EntitiesDictionary)
+ for (auto& itr : sides->GetEntities())
subNodes[i++] = this->InsertString(itr.second, -1, hVehicle);
else
{
@@ -333,7 +352,7 @@ void ObjectBrowserControlExt::Redraw_Aircraft()
int i = 0;
if (auto sides = fadata.GetSection("Sides"))
- for (auto& itr : sides->EntitiesDictionary)
+ for (auto& itr : sides->GetEntities())
subNodes[i++] = this->InsertString(itr.second, -1, hAircraft);
else
{
@@ -383,7 +402,7 @@ void ObjectBrowserControlExt::Redraw_Building()
int i = 0;
if (auto sides = fadata.GetSection("Sides"))
- for (auto& itr : sides->EntitiesDictionary)
+ for (auto& itr : sides->GetEntities())
subNodes[i++] = this->InsertString(itr.second, -1, hBuilding);
else
{
@@ -558,7 +577,7 @@ void ObjectBrowserControlExt::Redraw_Tunnel()
HTREEITEM& hTunnel = ExtNodes[Root_Tunnel];
if (hTunnel == NULL) return;
- if (CINI::FAData().GetBool("Debug", "AllowTunnels"))
+ if (CINI::FAData->GetBool("Debug", "AllowTunnels"))
{
this->InsertTranslatedString("NewTunnelObList", 50, hTunnel);
this->InsertTranslatedString("DelTunnelObList", 51, hTunnel);
@@ -913,6 +932,26 @@ void ObjectBrowserControlExt::OnExeTerminate()
bool ObjectBrowserControlExt::UpdateEngine(int nData)
{
+ do
+ {
+ int nMorphable = nData - 67;
+ if (nMorphable >= 0 && nMorphable < TheaterInfo::CurrentInfo.size())
+ {
+ int i;
+ for (i = 0; i < *CTileTypeClass::InstanceCount; ++i)
+ if ((*CTileTypeClass::Instance)[i].TileSet == TheaterInfo::CurrentInfo[nMorphable].Morphable)
+ {
+ CIsoView::CurrentParam = 0;
+ CIsoView::CurrentHeight = 0;
+ CIsoView::CurrentType = i;
+ CIsoView::CurrentCommand = FACurrentCommand::TileDraw;
+ CBrushSize::UpdateBrushSize(i);
+ return true;
+ }
+ }
+ } while (false);
+
+
int nCode = nData / 10000;
nData %= 10000;
@@ -920,6 +959,8 @@ bool ObjectBrowserControlExt::UpdateEngine(int nData)
{
if (nData == Set_Building)
{
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = true;
+
if (this->DoPropertyBrush_Building())
{
CIsoView::CurrentCommand = 0x17; // PropertyBrush
@@ -927,10 +968,15 @@ bool ObjectBrowserControlExt::UpdateEngine(int nData)
}
else
CIsoView::CurrentCommand = FACurrentCommand::Nothing;
+
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = false;
+
return true;
}
else if (nData == Set_Infantry)
{
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = true;
+
if (this->DoPropertyBrush_Infantry())
{
CIsoView::CurrentCommand = 0x17;
@@ -938,10 +984,15 @@ bool ObjectBrowserControlExt::UpdateEngine(int nData)
}
else
CIsoView::CurrentCommand = FACurrentCommand::Nothing;
+
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = false;
+
return true;
}
else if (nData == Set_Vehicle)
{
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = true;
+
if (this->DoPropertyBrush_Vehicle())
{
CIsoView::CurrentCommand = 0x17;
@@ -949,10 +1000,15 @@ bool ObjectBrowserControlExt::UpdateEngine(int nData)
}
else
CIsoView::CurrentCommand = FACurrentCommand::Nothing;
+
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = false;
+
return true;
}
else if (nData == Set_Aircraft)
{
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = true;
+
if (this->DoPropertyBrush_Aircraft())
{
CIsoView::CurrentCommand = 0x17;
@@ -960,6 +1016,9 @@ bool ObjectBrowserControlExt::UpdateEngine(int nData)
}
else
CIsoView::CurrentCommand = FACurrentCommand::Nothing;
+
+ ObjectBrowserControlExt::InitPropertyDlgFromProperty = false;
+
return true;
}
}
diff --git a/FA2sp/Ext/CFinalSunDlg/Body.cpp b/FA2sp/Ext/CFinalSunDlg/Body.cpp
index a1ce10f..77bf5c8 100644
--- a/FA2sp/Ext/CFinalSunDlg/Body.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Body.cpp
@@ -3,6 +3,10 @@
#include "../../FA2sp.h"
#include "../CIsoView/Body.h"
+#include
+#include "../../Miscs/Palettes.h"
+
+int CFinalSunDlgExt::CurrentLighting = 31000;
void CFinalSunDlgExt::ProgramStartupInit()
{
@@ -16,7 +20,7 @@ BOOL CFinalSunDlgExt::OnCommandExt(WPARAM wParam, LPARAM lParam)
WORD wmMsg = HIWORD(wParam);
HMENU hMenu = *this->GetMenu();
- auto SetMenuStatus = [this, &hMenu](int id, bool& param)
+ auto SetLayerStatus = [this, &hMenu](int id, bool& param)
{
if (GetMenuState(hMenu, id, MF_BYCOMMAND) & MF_CHECKED)
{
@@ -31,47 +35,71 @@ BOOL CFinalSunDlgExt::OnCommandExt(WPARAM wParam, LPARAM lParam)
this->MyViewFrame.RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
};
+ auto SetLightingStatus = [this, &hMenu](int id)
+ {
+ CheckMenuRadioItem(hMenu, 31000, 31003, id, MF_UNCHECKED);
+ if (CFinalSunDlgExt::CurrentLighting != id)
+ {
+ CFinalSunDlgExt::CurrentLighting = id;
+
+ PalettesManager::ManualReloadTMP = true;
+ PalettesManager::CacheAndTintCurrentIso();
+ CLoading::Instance->FreeTMPs();
+ CLoading::Instance->InitTMPs();
+ PalettesManager::RestoreCurrentIso();
+ PalettesManager::ManualReloadTMP = false;
+
+ this->MyViewFrame.RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
+ }
+ };
+
switch (wmID)
{
case 30000:
- SetMenuStatus(30000, CIsoViewExt::DrawStructures);
+ SetLayerStatus(30000, CIsoViewExt::DrawStructures);
return TRUE;
case 30001:
- SetMenuStatus(30001, CIsoViewExt::DrawInfantries);
+ SetLayerStatus(30001, CIsoViewExt::DrawInfantries);
return TRUE;
case 30002:
- SetMenuStatus(30002, CIsoViewExt::DrawUnits);
+ SetLayerStatus(30002, CIsoViewExt::DrawUnits);
return TRUE;
case 30003:
- SetMenuStatus(30003, CIsoViewExt::DrawAircrafts);
+ SetLayerStatus(30003, CIsoViewExt::DrawAircrafts);
return TRUE;
case 30004:
- SetMenuStatus(30004, CIsoViewExt::DrawBasenodes);
+ SetLayerStatus(30004, CIsoViewExt::DrawBasenodes);
return TRUE;
case 30005:
- SetMenuStatus(30005, CIsoViewExt::DrawWaypoints);
+ SetLayerStatus(30005, CIsoViewExt::DrawWaypoints);
return TRUE;
case 30006:
- SetMenuStatus(30006, CIsoViewExt::DrawCelltags);
+ SetLayerStatus(30006, CIsoViewExt::DrawCelltags);
return TRUE;
case 30007:
- SetMenuStatus(30007, CIsoViewExt::DrawMoneyOnMap);
+ SetLayerStatus(30007, CIsoViewExt::DrawMoneyOnMap);
return TRUE;
case 30008:
- SetMenuStatus(30008, CIsoViewExt::DrawOverlays);
+ SetLayerStatus(30008, CIsoViewExt::DrawOverlays);
return TRUE;
case 30009:
- SetMenuStatus(30009, CIsoViewExt::DrawTerrains);
+ SetLayerStatus(30009, CIsoViewExt::DrawTerrains);
return TRUE;
case 30010:
- SetMenuStatus(30010, CIsoViewExt::DrawSmudges);
+ SetLayerStatus(30010, CIsoViewExt::DrawSmudges);
return TRUE;
case 30011:
- SetMenuStatus(30011, CIsoViewExt::DrawTubes);
+ SetLayerStatus(30011, CIsoViewExt::DrawTubes);
return TRUE;
case 30012:
- SetMenuStatus(30012, CIsoViewExt::DrawBounds);
+ SetLayerStatus(30012, CIsoViewExt::DrawBounds);
return TRUE;
+ case 31000:
+ case 31001:
+ case 31002:
+ case 31003:
+ SetLightingStatus(wmID);
+ break;
default:
break;
}
diff --git a/FA2sp/Ext/CFinalSunDlg/Body.h b/FA2sp/Ext/CFinalSunDlg/Body.h
index 7062ef9..fb2743c 100644
--- a/FA2sp/Ext/CFinalSunDlg/Body.h
+++ b/FA2sp/Ext/CFinalSunDlg/Body.h
@@ -18,6 +18,8 @@ class NOVTABLE CFinalSunDlgExt : CFinalSunDlg
public:
static void ProgramStartupInit();
+ static int CurrentLighting;
+
BOOL PreTranslateMessageExt(MSG* pMsg);
BOOL OnCommandExt(WPARAM wParam, LPARAM lParam);
};
@@ -85,6 +87,7 @@ class ObjectBrowserControlExt : public ObjectBrowserControl
static bool InfantryBrushBools[10];
static bool VehicleBrushBools[11];
static bool AircraftBrushBools[9];
+ static bool InitPropertyDlgFromProperty;
void Redraw();
bool UpdateEngine(int nData);
diff --git a/FA2sp/Ext/CFinalSunDlg/Hooks.ObjectBrowserControl.cpp b/FA2sp/Ext/CFinalSunDlg/Hooks.ObjectBrowserControl.cpp
index e9c0449..b7558fb 100644
--- a/FA2sp/Ext/CFinalSunDlg/Hooks.ObjectBrowserControl.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Hooks.ObjectBrowserControl.cpp
@@ -4,7 +4,10 @@
#include
#include "../../FA2sp.h"
+#include "../../Miscs/TheaterInfo.h"
+#include
+#include
#include
DEFINE_HOOK(51CD20, ObjectBrowserControl_Redraw, 7)
diff --git a/FA2sp/Ext/CFinalSunDlg/Hooks.cpp b/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
index 5db7157..8ac43f0 100644
--- a/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
+++ b/FA2sp/Ext/CFinalSunDlg/Hooks.cpp
@@ -3,10 +3,11 @@
#include
#include
+#include
#include "../CIsoView/Body.h"
-DEFINE_HOOK(424654, CFinalSunDlg_OnInitDialog_EnableLayersByDefault, 7)
+DEFINE_HOOK(424654, CFinalSunDlg_OnInitDialog_SetMenuItemStateByDefault, 7)
{
GET(CFinalSunDlg*, pThis, ESI);
@@ -26,6 +27,8 @@ DEFINE_HOOK(424654, CFinalSunDlg_OnInitDialog_EnableLayersByDefault, 7)
pMenu->CheckMenuItem(30011, MF_CHECKED);
pMenu->CheckMenuItem(30012, MF_CHECKED);
+ pMenu->CheckMenuRadioItem(31000, 31003, CFinalSunDlgExt::CurrentLighting, MF_CHECKED);
+
return 0;
}
@@ -52,6 +55,8 @@ DEFINE_HOOK(432304, CFinalSunDlg_Update_LayersVisibility, 5)
SetItemCheckStatus(30011, CIsoViewExt::DrawTubes);
SetItemCheckStatus(30012, CIsoViewExt::DrawBounds);
+ pMenu->CheckMenuRadioItem(31000, 31003, CFinalSunDlgExt::CurrentLighting, MF_CHECKED);
+
return 0;
}
@@ -61,7 +66,7 @@ DEFINE_HOOK(43209D, CFinalSunDlg_Update_TranslateMenuItems, A)
{
// GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x60, 0x3C));
// auto pMenu = pThis->GetMenu();
-
+
GET(CMenu*, pMenu, ESI);
auto translateMenuItem = [&pMenu](int id, ppmfc::CString pSrcName)
@@ -175,6 +180,12 @@ DEFINE_HOOK(43209D, CFinalSunDlg_Update_TranslateMenuItems, A)
translateMenuItem(30011, "Menu.Layers.Tubes");
translateMenuItem(30012, "Menu.Layers.Bounds");
+ translateSubMenu(i++, "Menu.Lighting");
+ translateMenuItem(31000, "Menu.Lighting. ");
+ translateMenuItem(31001, "Menu.Lighting.Normal");
+ translateMenuItem(31002, "Menu.Lighting.Lightning");
+ translateMenuItem(31003, "Menu.Lighting.Dominator");
+
return 0x432304;
}
diff --git a/FA2sp/Ext/CHouses/Body.cpp b/FA2sp/Ext/CHouses/Body.cpp
index bddb6e7..271f79d 100644
--- a/FA2sp/Ext/CHouses/Body.cpp
+++ b/FA2sp/Ext/CHouses/Body.cpp
@@ -13,10 +13,10 @@ void CHousesExt::ProgramStartupInit()
void CHousesExt::UpdateComboboxContents()
{
- while (this->CCBColor.DeleteString(0) != -1);
- while (this->CCBCountry.DeleteString(0) != -1);
- while (this->CCBHouses.DeleteString(0) != -1);
- while (this->CCBHumanHouse.DeleteString(0) != -1);
+ this->CCBColor.DeleteAllStrings();
+ this->CCBCountry.DeleteAllStrings();
+ this->CCBHouses.DeleteAllStrings();
+ this->CCBHumanHouse.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
diff --git a/FA2sp/Ext/CIsoView/Body.cpp b/FA2sp/Ext/CIsoView/Body.cpp
index 5900730..5ee9de8 100644
--- a/FA2sp/Ext/CIsoView/Body.cpp
+++ b/FA2sp/Ext/CIsoView/Body.cpp
@@ -133,16 +133,16 @@ void CIsoViewExt::DrawLockedCellOutline(int X, int Y, int W, int H, COLORREF col
auto encode = [&rect](int x, int y)
{
int c = 0;
- if (x < rect.left) c = c | 0b1;
- else if (x > rect.right) c = c | 0b10;
- if (y > rect.bottom) c = c | 0b100;
- else if (y < rect.top) c = c | 0b1000;
+ if (x < rect.left) c = c | 0x1;
+ else if (x > rect.right) c = c | 0x2;
+ if (y > rect.bottom) c = c | 0x4;
+ else if (y < rect.top) c = c | 0x8;
return c;
};
auto clip = [&rect, encode](int& X1, int& Y1, int& X2, int& Y2) -> bool
{
int code1, code2, code;
- int x, y;
+ int x = 0, y = 0;
code1 = encode(X1, Y1);
code2 = encode(X2, Y2);
while (code1 != 0 || code2 != 0)
@@ -248,11 +248,9 @@ void CIsoViewExt::DrawCelltag(int X, int Y)
this->BltToBackBuffer(ImageDataMapHelper::GetImageDataFromMap("CELLTAG")->lpSurface, X, Y, -1, -1);
}
-void CIsoViewExt::DrawWaypoint(int WPIndex, int X, int Y)
+void CIsoViewExt::DrawWaypointFlag(int X, int Y)
{
- this->BltToBackBuffer(ImageDataMapHelper::GetImageDataFromMap("FLAG")->lpSurface, X, Y - 2, -1, -1);
- if (auto pSection = CINI::CurrentDocument->GetSection("Waypoints"))
- this->DrawText(X + 15, Y + 7, *pSection->GetKeyAt(WPIndex), ExtConfigs::Waypoint_Color);
+ this->BltToBackBuffer(ImageDataMapHelper::GetImageDataFromMap("FLAG")->lpSurface, X + 5, Y, -1, -1);
}
void CIsoViewExt::DrawTube(CellData* pData, int X, int Y)
@@ -261,7 +259,7 @@ void CIsoViewExt::DrawTube(CellData* pData, int X, int Y)
{
auto suffix = pData->TubeDataIndex;
if (pData->TubeDataIndex >= 2)
- suffix = pTubeData->Data[pData->TubeDataIndex] + 2;
+ suffix = pTubeData->Directions[pData->TubeDataIndex - 2] + 2;
FA2sp::Buffer.Format("TUBE%d", suffix);
if (auto lpSurface = ImageDataMapHelper::GetImageDataFromMap(FA2sp::Buffer)->lpSurface)
this->BltToBackBuffer(lpSurface, X + 7, Y + 1, -1, -1);
diff --git a/FA2sp/Ext/CIsoView/Body.h b/FA2sp/Ext/CIsoView/Body.h
index faf5c6b..88dd838 100644
--- a/FA2sp/Ext/CIsoView/Body.h
+++ b/FA2sp/Ext/CIsoView/Body.h
@@ -18,7 +18,7 @@ class NOVTABLE CIsoViewExt : public CIsoView
void DrawLockedCellOutline(int X, int Y, int W, int H, COLORREF color, bool bUseDot, bool bUsePrimary, LPDDSURFACEDESC2 lpDesc);
void DrawCelltag(int X, int Y);
- void DrawWaypoint(int WPIndex, int X, int Y);
+ void DrawWaypointFlag(int X, int Y);
void DrawTube(CellData* pData, int X, int Y);
static bool DrawStructures;
diff --git a/FA2sp/Ext/CIsoView/Hooks.cpp b/FA2sp/Ext/CIsoView/Hooks.cpp
index 5ff06b7..493d41d 100644
--- a/FA2sp/Ext/CIsoView/Hooks.cpp
+++ b/FA2sp/Ext/CIsoView/Hooks.cpp
@@ -109,20 +109,6 @@ DEFINE_HOOK(45ADD0, CIsoView_Draw_CursorSelectionBoundHeightColor, 6)
// return 0x474A67;
//}
-DEFINE_HOOK(4685EA, CIsoView_DrawText, 9)
-{
- if (ExtConfigs::Waypoint_Background)
- {
- GET(HDC, hdc, EDX);
-
- SetBkColor(hdc, ExtConfigs::Waypoint_Background_Color);
- SetBkMode(hdc, OPAQUE);
-
- return 0x4685F3;
- }
- return 0;
-}
-
DEFINE_HOOK(470194, CIsoView_Draw_LayerVisible_Overlay, 8)
{
return CIsoViewExt::DrawOverlays ? 0 : 0x470772;
@@ -354,7 +340,7 @@ DEFINE_HOOK(474B9D, CIsoView_Draw_DrawCelltagAndWaypointAndTube_DrawStuff, 9)
if (CIsoViewExt::DrawCelltags && celldata.CellTag != -1)
pThis->DrawCelltag(X, Y);
if (CIsoViewExt::DrawWaypoints && celldata.Waypoint != -1)
- pThis->DrawWaypoint(celldata.Waypoint, X, Y);
+ pThis->DrawWaypointFlag(X, Y);
if (CIsoViewExt::DrawTubes && celldata.Tube != -1)
pThis->DrawTube(&celldata, X, Y);
@@ -371,26 +357,53 @@ DEFINE_HOOK(474DB7, CIsoView_Draw_DrawCelltagAndWaypointAndTube_SkipOriginUnlock
return 0x474DCE;
}
-#if 0
-// No same random, abandoned.
-DEFINE_HOOK(46BD0C, CISoView_DrawMouseAttachedStuff_RandomTerrain, 5)
+DEFINE_HOOK(474DDF, CIsoView_Draw_WaypointTexts, 5)
{
- GET(int, size, ESI);
-
- static int nLastRand = -1;
-
- // srand(time(nullptr));
-
- int nResult = rand() % size;
- if (size != 1)
- while (nResult == nLastRand)
- nResult = rand() % size;
-
- nLastRand = nResult;
-
- R->ECX(nResult);
- R->EDX(R->EAX());
+ if (CIsoViewExt::DrawWaypoints)
+ {
+ GET(CIsoViewExt*, pThis, EBX);
+
+ GET_STACK(HDC, hDC, STACK_OFFS(0xD18, 0xC68));
+ GET_STACK(int, jMin, STACK_OFFS(0xD18, 0xC10));
+ GET_STACK(int, iMin, STACK_OFFS(0xD18, 0xCBC));
+ GET_STACK(const int, jMax, STACK_OFFS(0xD18, 0xC64));
+ GET_STACK(const int, iMax, STACK_OFFS(0xD18, 0xC18));
+
+ SetTextColor(hDC, ExtConfigs::Waypoint_Color);
+ if (ExtConfigs::Waypoint_Background)
+ {
+ SetBkMode(hDC, OPAQUE);
+ SetBkColor(hDC, ExtConfigs::Waypoint_Background_Color);
+ }
+ else
+ SetBkMode(hDC, TRANSPARENT);
+ SetTextAlign(hDC, TA_CENTER);
+
+ auto pSection = CINI::CurrentDocument->GetSection("Waypoints");
+ for (int j = jMin; j < jMax; ++j)
+ {
+ for (int i = iMin; i < iMax; ++i)
+ {
+ int Y = j, X = i;
+
+ pThis->MapCoord2ScreenCoord(Y, X);
+ auto pCell = CMapData::Instance->TryGetCellAt(i, j);
+
+ int drawX = Y - R->Stack(STACK_OFFS(0xD18, 0xCB0)) + 30;
+ int drawY = X - R->Stack(STACK_OFFS(0xD18, 0xCB8)) - 15;
+
+ if (pCell->Waypoint != -1)
+ {
+ auto pWP = *pSection->GetKeyAt(pCell->Waypoint);
+ TextOut(hDC, drawX, drawY, pWP, strlen(pWP));
+ }
+
+ }
+ }
+
+ SetTextAlign(hDC, TA_LEFT);
+ SetTextColor(hDC, RGB(0, 0, 0));
+ }
- return 0x46BD2C;
-}
-#endif
\ No newline at end of file
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CLoading/Body.LoadObjects.cpp b/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
index 9331f74..9d90d06 100644
--- a/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
+++ b/FA2sp/Ext/CLoading/Body.LoadObjects.cpp
@@ -356,7 +356,7 @@ void CLoadingExt::LoadBuilding(ppmfc::CString ID)
UnionSHP_GetAndClear(pImage, &width1, &height1);
DictName.Format("%s%d", ImageID, i);
- SetImageData(pImage, DictName, width1, height1, Palettes::LoadPalette(PaletteName));
+ SetImageData(pImage, DictName, width1, height1, PalettesManager::LoadPalette(PaletteName));
}
GameDeleteArray(pBuffer, width * height);
@@ -381,7 +381,7 @@ void CLoadingExt::LoadBuilding(ppmfc::CString ID)
UnionSHP_GetAndClear(pImage, &width1, &height1);
DictName.Format("%s%d", ImageID, i);
- SetImageData(pImage, DictName, width1, height1, Palettes::LoadPalette(PaletteName));
+ SetImageData(pImage, DictName, width1, height1, PalettesManager::LoadPalette(PaletteName));
}
GameDelete(pBuffer);
}
@@ -389,7 +389,7 @@ void CLoadingExt::LoadBuilding(ppmfc::CString ID)
else // No turret
{
DictName.Format("%s%d", ImageID, 0);
- SetImageData(pBuffer, DictName, width, height, Palettes::LoadPalette(PaletteName));
+ SetImageData(pBuffer, DictName, width, height, PalettesManager::LoadPalette(PaletteName));
}
}
}
@@ -422,7 +422,7 @@ void CLoadingExt::LoadInfantry(ppmfc::CString ID)
DictName.Format("%s%d", ImageID, i);
ppmfc::CString PaletteName = CINI::Art->GetString(ArtID, "Palette", "unit");
GetFullPaletteName(PaletteName);
- SetImageData(FramesBuffers, DictName, header.Width, header.Height, Palettes::LoadPalette(PaletteName));
+ SetImageData(FramesBuffers, DictName, header.Width, header.Height, PalettesManager::LoadPalette(PaletteName));
}
}
}
@@ -444,7 +444,7 @@ void CLoadingExt::LoadTerrainOrSmudge(ppmfc::CString ID)
DictName.Format("%s%d", ImageID, 0);
ppmfc::CString PaletteName = CINI::Art->GetString(ArtID, "Palette", "iso");
GetFullPaletteName(PaletteName);
- SetImageData(FramesBuffers[0], DictName, header.Width, header.Height, Palettes::LoadPalette(PaletteName));
+ SetImageData(FramesBuffers[0], DictName, header.Width, header.Height, PalettesManager::LoadPalette(PaletteName));
}
}
@@ -553,7 +553,7 @@ void CLoadingExt::LoadVehicleOrAircraft(ppmfc::CString ID)
VXL_GetAndClear(outBuffer, &outW, &outH);
- SetImageData(outBuffer, DictName, outW, outH, Palettes::LoadPalette(PaletteName));
+ SetImageData(outBuffer, DictName, outW, outH, PalettesManager::LoadPalette(PaletteName));
}
}
else
@@ -570,7 +570,7 @@ void CLoadingExt::LoadVehicleOrAircraft(ppmfc::CString ID)
delete[] pImage[i];
VXL_GetAndClear(outBuffer, &outW, &outH);
- SetImageData(outBuffer, DictName, outW, outH, Palettes::LoadPalette(PaletteName));
+ SetImageData(outBuffer, DictName, outW, outH, PalettesManager::LoadPalette(PaletteName));
}
}
}
@@ -630,10 +630,10 @@ void CLoadingExt::LoadVehicleOrAircraft(ppmfc::CString ID)
int outW, outH;
UnionSHP_GetAndClear(outBuffer, &outW, &outH);
- SetImageData(outBuffer, DictName, outW, outH, Palettes::LoadPalette(PaletteName));
+ SetImageData(outBuffer, DictName, outW, outH, PalettesManager::LoadPalette(PaletteName));
}
else
- SetImageData(FramesBuffers[0], DictName, header.Width, header.Height, Palettes::LoadPalette(PaletteName));
+ SetImageData(FramesBuffers[0], DictName, header.Width, header.Height, PalettesManager::LoadPalette(PaletteName));
}
}
}
diff --git a/FA2sp/Ext/CMapData/Body.cpp b/FA2sp/Ext/CMapData/Body.cpp
new file mode 100644
index 0000000..54aba9c
--- /dev/null
+++ b/FA2sp/Ext/CMapData/Body.cpp
@@ -0,0 +1,313 @@
+#include "Body.h"
+
+#include "../../Miscs/SaveMap.h"
+
+#include
+#include
+
+#include
+#include
+#include
+
+bool CMapDataExt::ResizeMapExt(MapRect* const pRect)
+{
+ this->UpdateCurrentDocument();
+
+ const int nNewWidth = pRect->Width;
+ const int nNewHeight = pRect->Height;
+
+ const int nOldWidth = this->Size.Width;
+ const int nOldHeight = this->Size.Height;
+
+ if (nNewWidth < nOldWidth ||
+ nNewHeight < nOldHeight ||
+ nNewWidth - nOldWidth < pRect->Left ||
+ nNewHeight - nOldHeight < pRect->Top)
+ return false;
+
+ const int nOldMapMagic = this->MapWidthPlusHeight;
+ const int nOldCellDataCount = this->CellDataCount;
+ auto pOldCellDatas = this->CellDatas;
+
+ MapCoord coordToMove =
+ MapCoord::Facings[FACING_EAST] * pRect->Left +
+ MapCoord::Facings[FACING_SOUTH] * pRect->Top +
+ MapCoord::Facings[FACING_SOUTHWEST] * (nNewWidth - nOldWidth);
+
+ // Clear UndoRedoDatas
+ for (int i = 0; i < this->UndoRedoDataCount; ++i)
+ {
+ GameDelete(this->UndoRedoData[i].Pointer_10);
+ GameDelete(this->UndoRedoData[i].Pointer_14);
+ GameDelete(this->UndoRedoData[i].Pointer_18);
+ GameDelete(this->UndoRedoData[i].Pointer_1C);
+ GameDelete(this->UndoRedoData[i].Pointer_20);
+ GameDelete(this->UndoRedoData[i].Pointer_24);
+ GameDelete(this->UndoRedoData[i].Pointer_28);
+ GameDelete(this->UndoRedoData[i].Pointer_2C);
+ }
+ GameDelete(this->UndoRedoData);
+ this->UndoRedoCurrentDataIndex = -1;
+ this->UndoRedoData = nullptr;
+ this->UndoRedoDataCount = 0;
+
+ this->CellDatas = nullptr;
+ this->CellDataCount = 0;
+
+ memset(this->Overlay, 0xFF, sizeof(this->Overlay));
+ memset(this->OverlayData, 0, sizeof(this->OverlayData));
+
+ // update the size
+ CINI::CurrentDocument->WriteString("Map", "Size", std::format("0,0,{},{}", nNewWidth, nNewHeight).c_str());
+ CINI::CurrentDocument->WriteString("Map", "LocalSize", std::format("2,4,{},{}", nNewWidth - 4, nNewHeight - 6).c_str());
+
+ this->Size.Left = 0;
+ this->Size.Top = 0;
+ this->Size.Width = nNewWidth;
+ this->Size.Height = nNewHeight;
+
+ this->LocalSize.Left = 2;
+ this->LocalSize.Top = 4;
+ this->LocalSize.Width = nNewWidth - 4;
+ this->LocalSize.Height = nNewHeight - 6;
+
+ this->MapWidthPlusHeight = nNewWidth + nNewHeight;
+
+ this->CellDataCount = (this->MapWidthPlusHeight + 1) * (this->MapWidthPlusHeight + 1);
+ this->CellDatas = GameCreateVector(this->CellDataCount);
+
+ GameDelete(this->IsoPackData);
+ this->IsoPackData = nullptr;
+ this->IsoPackDataCount = 0;
+
+ // updating objects in the vector
+ std::for_each(this->InfantryDatas.begin(), this->InfantryDatas.end(),
+ [coordToMove](CInfantryData& item)
+ {
+ int x = atoi(item.X) + coordToMove.X;
+ int y = atoi(item.Y) + coordToMove.Y;
+ item.X.Format("%d", x);
+ item.Y.Format("%d", y);
+ });
+ std::for_each(this->StructureDatas.begin(), this->StructureDatas.end(),
+ [coordToMove](StructureData& item)
+ {
+ item.X += coordToMove.X;
+ item.Y += coordToMove.Y;
+ });
+ std::for_each(this->TerrainDatas.begin(), this->TerrainDatas.end(),
+ [coordToMove](CTerrainData& item)
+ {
+ item.X += coordToMove.X;
+ item.Y += coordToMove.Y;
+ });
+ std::for_each(this->TubeDatas.begin(), this->TubeDatas.end(),
+ [coordToMove](TubeData& item) {
+ item.EnterX += coordToMove.X;
+ item.ExitX += coordToMove.X;
+ item.EnterY += coordToMove.Y;
+ item.ExitY += coordToMove.Y;
+ });
+
+ // updating objects in the ini
+ auto UpdateObjectsInINIValue = [&](const char* lpSection, int nPos)
+ {
+ if (auto pSection = CINI::CurrentDocument->GetSection(lpSection))
+ {
+ std::vector itemsToRemove;
+ for (auto& pair : pSection->GetEntities())
+ {
+ int nLen = pair.second.GetLength();
+ int nStart, nEnd = -1;
+ for (int i = 0, cnt = 0; i < nLen; ++i)
+ {
+ if (pair.second[i] == ',')
+ ++cnt;
+
+ if (cnt == nPos)
+ {
+ if (nPos == 0) // For Tubes
+ nStart = 0;
+ else
+ nStart = i + 1;
+ cnt = 0;
+ for (int j = nStart; j < nLen; ++j)
+ {
+ if (pair.second[j] == ',')
+ ++cnt;
+
+ if (cnt == 2)
+ {
+ nEnd = j;
+ break;
+ }
+ }
+
+ if (nEnd != -1) // do process
+ {
+ auto prefix = pair.second.Mid(0, nStart);
+ auto suffix = pair.second.Mid(nEnd);
+ auto midpart = pair.second.Mid(nStart, nEnd - nStart);
+ int x, y;
+ if (sscanf_s(midpart, "%d,%d", &x, &y) == 2)
+ {
+ x += coordToMove.X;
+ y += coordToMove.Y;
+ /*if (!this->IsCoordInMap(x, y))
+ itemsToRemove.push_back(pair.first);
+ else*/
+ {
+ midpart.Format("%d,%d", x, y);
+ pair.second = prefix + midpart + suffix;
+ }
+ }
+ break;
+ }
+
+ }
+ }
+ }
+ for (auto& item : itemsToRemove)
+ CINI::CurrentDocument->DeleteKey(pSection, item);
+ }
+ };
+ UpdateObjectsInINIValue("Aircraft", 3);
+ UpdateObjectsInINIValue("Infantry", 3);
+ UpdateObjectsInINIValue("Units", 3);
+ UpdateObjectsInINIValue("Structures", 3);
+ UpdateObjectsInINIValue("Smudge", 1);
+ UpdateObjectsInINIValue("Tubes", 0); // EnterPos
+ UpdateObjectsInINIValue("Tubes", 3); // ExitPos
+
+ auto UpdateObjectsInINIKey = [&](const char* lpSection)
+ {
+ std::map values;
+ if (auto pSection = CINI::CurrentDocument->GetSection(lpSection))
+ {
+ for (auto& pair : pSection->GetEntities())
+ {
+ MapCoord buffer;
+ buffer.X = atoi(pair.first);
+ buffer.Y = buffer.X / 1000;
+ buffer.X %= 1000;
+
+ buffer.X += coordToMove.X;
+ buffer.Y += coordToMove.Y;
+
+ //if(this->IsCoordInMap(buffer.X, buffer.Y))
+ values[buffer] = pair.second.m_pchData;
+ }
+ }
+ CINI::CurrentDocument->DeleteSection(lpSection);
+ if (auto pSection = CINI::CurrentDocument->AddSection(lpSection))
+ {
+ for (auto& value : values)
+ {
+ char buffer[8];
+ _itoa(value.first.X + value.first.Y * 1000, buffer, 10);
+ CINI::CurrentDocument->WriteString(pSection, buffer, value.second.c_str());
+ }
+ }
+ values.clear();
+ };
+ UpdateObjectsInINIKey("CellTags");
+ UpdateObjectsInINIKey("Terrain");
+
+ if (auto pSection = CINI::CurrentDocument->GetSection("Waypoints"))
+ {
+ std::vector itemsToRemove;
+ for (auto& pair : pSection->GetEntities())
+ {
+ MapCoord value;
+ value.X = atoi(pair.second);
+ value.Y = value.X / 1000;
+ value.X %= 1000;
+
+ value.X += coordToMove.X;
+ value.Y += coordToMove.Y;
+
+ /*if (!this->IsCoordInMap(value.X, value.Y))
+ itemsToRemove.push_back(pair.first);
+ else*/
+ pair.second.Format("%d", value.X + value.Y * 1000);
+ }
+
+ for (auto& item : itemsToRemove)
+ CINI::CurrentDocument->DeleteKey(pSection, item);
+ }
+
+ auto CopyCellData = [&](int x, int y)
+ {
+ int nOldIndex = x * nOldMapMagic + y;
+ int nNewIndex = (x + coordToMove.X) * this->MapWidthPlusHeight + y + coordToMove.Y;
+ if (nNewIndex < this->CellDataCount && nNewIndex > this->MapWidthPlusHeight)
+ this->CellDatas[nNewIndex] = pOldCellDatas[nOldIndex];
+ };
+ // Iterate the old map
+ for (int i = 1; i <= nOldWidth; ++i)
+ {
+ if (i != nOldWidth)
+ {
+ for (int j = 1; j <= nOldHeight; ++j)
+ {
+ CopyCellData(i + j - 1, nOldWidth - i + j);
+ CopyCellData(i + j, nOldWidth - i + j);
+ }
+ }
+ else // Last specific column
+ {
+ for (int j = 1; j <= nOldHeight; ++j)
+ CopyCellData(i + j - 1, nOldWidth - i + j);
+ }
+ }
+
+ GameDeleteVector(pOldCellDatas);
+
+ // need further investigation
+ this->InitMinimap();
+
+ this->UpdateMapFieldData_Aircraft(false);
+ this->UpdateMapFieldData_Infantry(false);
+ this->UpdateMapFieldData_Structure(false);
+ this->UpdateMapFieldData_Terrain(false);
+ this->UpdateMapFieldData_Unit(false);
+ this->UpdateMapFieldData_Waypoint(false);
+ this->UpdateMapFieldData_Celltag(false);
+ this->UpdateMapFieldData_Tube(false);
+ this->UpdateMapFieldData_Smudge(false);
+ this->UpdateMapFieldData(SaveMapFlag::UpdatePreview);
+
+ // Update the preview map manually
+ // Now we use a slow way because I didn't find how to update it... for now
+ for (int i = 1; i <= nNewWidth; ++i)
+ {
+ if (i != nNewWidth)
+ {
+ for (int j = 1; j <= nNewHeight; ++j)
+ {
+ this->UpdateMapPreviewAt(nNewWidth - i + j, i + j - 1);
+ this->UpdateMapPreviewAt(nNewWidth - i + j, i + j);
+ }
+ }
+ else // Last specific column
+ {
+ for (int j = 1; j <= nNewHeight; ++j)
+ this->UpdateMapPreviewAt(nNewWidth - i + j, i + j - 1);
+ }
+ }
+
+ /*std::string path = std::format("{}\\resized_map.map", CFinalSunApp::ExePath);
+ SaveMapExt::IsAutoSaving = true;
+ CFinalSunDlg::Instance->SaveMap(path.c_str());
+ SaveMapExt::IsAutoSaving = false;
+
+ MessageBox(
+ NULL,
+ std::format("Resized map has been saved to {}\n! FA2 need restarting before you can continue.", path).c_str(),
+ "FA2sp",
+ MB_OK);
+
+ exit(0);*/
+
+ return true;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CMapData/Body.h b/FA2sp/Ext/CMapData/Body.h
new file mode 100644
index 0000000..8c3bfba
--- /dev/null
+++ b/FA2sp/Ext/CMapData/Body.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include
+
+class CMapDataExt : public CMapData
+{
+public:
+ static CMapDataExt* GetExtension()
+ {
+ return reinterpret_cast(&CMapData::Instance());
+ }
+
+ bool ResizeMapExt(MapRect* const pRect);
+};
\ No newline at end of file
diff --git a/FA2sp/Ext/CMapData/Hooks.cpp b/FA2sp/Ext/CMapData/Hooks.cpp
new file mode 100644
index 0000000..b7ae401
--- /dev/null
+++ b/FA2sp/Ext/CMapData/Hooks.cpp
@@ -0,0 +1,17 @@
+#include "Body.h"
+
+#include
+
+#include "../../FA2sp.h"
+
+DEFINE_HOOK(4C45F0, CMapData_ResizeMap, 6)
+{
+ if (ExtConfigs::FastResize)
+ {
+ LEA_STACK(MapRect* const, pRect, 0x4);
+
+ return CMapDataExt::GetExtension()->ResizeMapExt(pRect) ? 0x4C7DC7 : 0;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CPropertyAircraft/Hooks.cpp b/FA2sp/Ext/CPropertyAircraft/Hooks.cpp
new file mode 100644
index 0000000..74aec0c
--- /dev/null
+++ b/FA2sp/Ext/CPropertyAircraft/Hooks.cpp
@@ -0,0 +1,18 @@
+#include
+
+#include "Body.h"
+
+#include "../CFinalSunDlg/Body.h"
+
+DEFINE_HOOK(401561, CPropertyAircraft_OnInitDialog_HidePropertyBrushCheckes, 7)
+{
+ GET(CPropertyAircraft*, pThis, ESI);
+
+ if (!ObjectBrowserControlExt::InitPropertyDlgFromProperty)
+ {
+ for (int i = 1300; i <= 1308; ++i)
+ pThis->GetDlgItem(i)->ShowWindow(SW_HIDE);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CPropertyBuilding/Hooks.cpp b/FA2sp/Ext/CPropertyBuilding/Hooks.cpp
new file mode 100644
index 0000000..f0fb424
--- /dev/null
+++ b/FA2sp/Ext/CPropertyBuilding/Hooks.cpp
@@ -0,0 +1,83 @@
+#include
+#include
+#include
+
+#include
+
+#include "Body.h"
+#include "../../FA2sp.h"
+
+#include "../CFinalSunDlg/Body.h"
+
+// FA2 Building Property window is fucked
+DEFINE_HOOK(417F40, CPropertyBuilding_OnInitDialog, 7)
+{
+ GET(CPropertyBuilding*, pThis, ECX);
+
+ pThis->FA2CDialog::OnInitDialog();
+
+ CMapData::Instance->UpdateCurrentDocument();
+
+ Miscs::LoadParams::Houses(reinterpret_cast(pThis->GetDlgItem(1079)), false, false, false);
+ Miscs::LoadParams::Tags(reinterpret_cast(pThis->GetDlgItem(1083)), true);
+
+ pThis->CSCStrength.SetRange(0, 256);
+ pThis->CSCStrength.SetPos(atoi(pThis->CString_HealthPoint));
+ pThis->UpdateData(FALSE);
+
+ ppmfc::CComboBox* pUpgrades[3]
+ {
+ (ppmfc::CComboBox*)pThis->GetDlgItem(1089),
+ (ppmfc::CComboBox*)pThis->GetDlgItem(1091),
+ (ppmfc::CComboBox*)pThis->GetDlgItem(1092)
+ };
+
+ if (ObjectBrowserControlExt::InitPropertyDlgFromProperty)
+ {
+ pUpgrades[0]->EnableWindow(TRUE);
+ pUpgrades[1]->EnableWindow(TRUE);
+ pUpgrades[2]->EnableWindow(TRUE);
+ }
+ else
+ {
+ for (int i = 1300; i <= 1313; ++i)
+ pThis->GetDlgItem(i)->ShowWindow(SW_HIDE);
+
+ int nUpgrades = Variables::Rules.GetInteger(pThis->CString_ObjectID, "Upgrades", 0);
+
+ if (!pThis->CString_ObjectID.IsEmpty())
+ {
+ nUpgrades = std::clamp(nUpgrades, 0, 3); // no warning pls
+
+ pUpgrades[0]->EnableWindow(nUpgrades > 0);
+ pUpgrades[1]->EnableWindow(nUpgrades > 1);
+ pUpgrades[2]->EnableWindow(nUpgrades > 2);
+
+ if (nUpgrades > 0)
+ {
+ std::vector upgrades;
+ for (auto& bld : Variables::Rules.GetSection("BuildingTypes"))
+ {
+ if (auto const ppString = Variables::Rules.TryGetString(bld.second, "PowersUpBuilding"))
+ {
+ if (strcmp(*ppString, pThis->CString_ObjectID) == 0)
+ upgrades.push_back(bld.second.m_pchData);
+ }
+ }
+
+ for (const auto& upgrade : upgrades)
+ {
+ const auto UIName = CMapData::Instance->GetUIName(upgrade.c_str());
+ const auto name = std::format("{} ({})", upgrade, UIName);
+
+ for (int i = 0; i < nUpgrades; ++i)
+ pUpgrades[i]->AddString(name.c_str());
+ }
+ }
+ }
+ }
+
+ pThis->Translate();
+
+ return 0x41A4AE;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CPropertyInfantry/Hooks.cpp b/FA2sp/Ext/CPropertyInfantry/Hooks.cpp
new file mode 100644
index 0000000..7d25f2b
--- /dev/null
+++ b/FA2sp/Ext/CPropertyInfantry/Hooks.cpp
@@ -0,0 +1,18 @@
+#include
+
+#include "Body.h"
+
+#include "../CFinalSunDlg/Body.h"
+
+DEFINE_HOOK(451AEC, CPropertyInfantry_OnInitDialog_HidePropertyBrushCheckes, 7)
+{
+ GET(CPropertyInfantry*, pThis, ESI);
+
+ if (!ObjectBrowserControlExt::InitPropertyDlgFromProperty)
+ {
+ for (int i = 1300; i <= 1309; ++i)
+ pThis->GetDlgItem(i)->ShowWindow(SW_HIDE);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CPropertyUnit/Hooks.cpp b/FA2sp/Ext/CPropertyUnit/Hooks.cpp
new file mode 100644
index 0000000..d2a9337
--- /dev/null
+++ b/FA2sp/Ext/CPropertyUnit/Hooks.cpp
@@ -0,0 +1,18 @@
+#include
+
+#include "Body.h"
+
+#include "../CFinalSunDlg/Body.h"
+
+DEFINE_HOOK(50F07C, CPropertyUnit_OnInitDialog_HidePropertyBrushCheckes, 7)
+{
+ GET(CPropertyUnit*, pThis, ESI);
+
+ if (!ObjectBrowserControlExt::InitPropertyDlgFromProperty)
+ {
+ for (int i = 1300; i <= 1310; ++i)
+ pThis->GetDlgItem(i)->ShowWindow(SW_HIDE);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Ext/CScriptTypes/Body.CurrentScript.cpp b/FA2sp/Ext/CScriptTypes/Body.CurrentScript.cpp
index 45366d1..90a6347 100644
--- a/FA2sp/Ext/CScriptTypes/Body.CurrentScript.cpp
+++ b/FA2sp/Ext/CScriptTypes/Body.CurrentScript.cpp
@@ -106,8 +106,8 @@ void CurrentScript::Set(ppmfc::CString id)
for (int i = 0; i < 50; ++i)
{
key.Format("%d", i);
- auto itr = pSection->EntitiesDictionary.find(key);
- if (itr != pSection->EntitiesDictionary.end())
+ auto itr = pSection->GetEntities().find(key);
+ if (itr != pSection->GetEntities().end())
{
key = itr->second;
if (sscanf_s(key, "%d,%d", &this->Actions[count].Type, &this->Actions[count].Param) == 2)
@@ -190,7 +190,7 @@ bool CurrentScript::IsExtraParamEnabledAtLine(int line)
void CurrentScript::LoadExtraParamBox(ppmfc::CComboBox& comboBox, int actionIndex)
{
- while (comboBox.DeleteString(0) != CB_ERR);
+ comboBox.DeleteAllStrings();
if (actionIndex == 46 || actionIndex == 47 || actionIndex == 56 || actionIndex == 58)
{
@@ -291,7 +291,7 @@ void CurrentScript::LoadExtraParamBox(ppmfc::CComboBox& comboBox, int actionInde
else
{
if (auto pSection = CINI::FAData->GetSection(buffer))
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
{
int data;
if (sscanf_s(pair.first, "%d", &data) == 1)
diff --git a/FA2sp/Ext/CScriptTypes/Body.cpp b/FA2sp/Ext/CScriptTypes/Body.cpp
index 0161a91..82ba7f0 100644
--- a/FA2sp/Ext/CScriptTypes/Body.cpp
+++ b/FA2sp/Ext/CScriptTypes/Body.cpp
@@ -62,7 +62,7 @@ void CScriptTypesExt::UpdateParams(int actionIndex)
{
default:
case 0:
- while (this->CCBScriptParameter.DeleteString(0) != -1);
+ this->CCBScriptParameter.DeleteAllStrings();
break;
case 1:
CScriptTypesFunctions::CScriptTypes_LoadParams_Target(this->CCBScriptParameter);
@@ -183,7 +183,7 @@ BOOL CScriptTypesExt::OnInitDialogExt()
Translations::TranslateItem(this, 6305, "ScriptTypesMoveUp");
Translations::TranslateItem(this, 6306, "ScriptTypesMoveDown");
- while (CCBCurrentAction.DeleteString(0) != -1);
+ this->CCBCurrentAction.DeleteAllStrings();
// Initialize defaults
/*const char** pNames = reinterpret_cast(0x5D035C);
@@ -204,7 +204,7 @@ BOOL CScriptTypesExt::OnInitDialogExt()
if (auto entities = fadata.GetSection("ScriptParams"))
{
char* pParseBuffer[2];
- for (auto& pair : entities->EntitiesDictionary)
+ for (auto& pair : entities->GetEntities())
{
int id = atoi(pair.first);
if (id < 0) continue;
@@ -228,7 +228,7 @@ BOOL CScriptTypesExt::OnInitDialogExt()
if (auto entities = fadata.GetSection("ScriptsRA2"))
{
char* pParseBuffer[5];
- for (auto& pair : entities->EntitiesDictionary)
+ for (auto& pair : entities->GetEntities())
{
int id = atoi(pair.first);
if (id < 0) continue;
@@ -269,7 +269,7 @@ BOOL CScriptTypesExt::OnInitDialogExt()
}
auto pCBExtra = (ppmfc::CComboBox*)this->GetDlgItem(6304);
- while (pCBExtra->DeleteString(0) != CB_ERR);
+ pCBExtra->DeleteAllStrings();
ExtCurrentScript = new CurrentScript;
ExtCurrentScript->Unset();
@@ -283,12 +283,12 @@ void CScriptTypesExt::UpdateDialog()
this->CCBCurrentScript.GetWindowText(currentID);
STDHelpers::TrimIndex(currentID);
- while (this->CCBCurrentScript.DeleteString(0) != CB_ERR);
+ this->CCBCurrentScript.DeleteAllStrings();
auto& ini = CINI::CurrentDocument();
if (auto pSection = ini.GetSection("ScriptTypes"))
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
if (auto pName = ini.TryGetString(pair.second, "Name"))
{
FA2sp::Buffer.Format("%s (%s)", pair.second, *pName);
@@ -516,7 +516,7 @@ void CScriptTypesExt::OnBNDeleteScriptClicked()
CINI::CurrentDocument->DeleteSection(this->ExtCurrentScript->ID);
if (auto pScripts = CINI::CurrentDocument->GetSection("ScriptTypes"))
{
- for (auto& pairs : pScripts->EntitiesDictionary)
+ for (auto& pairs : pScripts->GetEntities())
if (strcmp(pairs.second, this->ExtCurrentScript->ID) == 0)
CINI::CurrentDocument->DeleteKey("ScriptTypes", pairs.first);
}
diff --git a/FA2sp/Ext/CScriptTypes/Functional.h b/FA2sp/Ext/CScriptTypes/Functional.h
index 6c877b7..4c7a848 100644
--- a/FA2sp/Ext/CScriptTypes/Functional.h
+++ b/FA2sp/Ext/CScriptTypes/Functional.h
@@ -17,7 +17,7 @@ class CScriptTypesFunctions
// negative
static void CScriptTypes_LoadParams_TypeList(ppmfc::CComboBox& comboBox, int nID)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
ppmfc::CString buffer;
buffer.Format("%d", nID);
@@ -100,7 +100,7 @@ static void CScriptTypes_LoadParams_TypeList(ppmfc::CComboBox& comboBox, int nID
else
{
if (auto pSection = CINI::FAData->GetSection(buffer))
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
{
int data;
if (sscanf_s(pair.first, "%d", &data) == 1)
@@ -115,7 +115,7 @@ static void CScriptTypes_LoadParams_TypeList(ppmfc::CComboBox& comboBox, int nID
// 1
static void CScriptTypes_LoadParams_Target(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
comboBox.SetItemData(comboBox.AddString("0 - Not specified"), 0);
comboBox.SetItemData(comboBox.AddString("1 - Anything (uses auto-targeting)"), 1);
@@ -133,7 +133,7 @@ static void CScriptTypes_LoadParams_Target(ppmfc::CComboBox& comboBox)
// 2
static void CScriptTypes_LoadParams_Waypoint(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
@@ -142,7 +142,7 @@ static void CScriptTypes_LoadParams_Waypoint(ppmfc::CComboBox& comboBox)
int waypoints[702];
memset(waypoints, -1, sizeof waypoints);
if (auto entries = doc.GetSection("Waypoints"))
- for (auto& x : entries->EntitiesDictionary)
+ for (auto& x : entries->GetEntities())
if (x.first != "Name" && !STDHelpers::IsNullOrEmpty(x.second))
{
int l = atoi(x.first);
@@ -164,7 +164,7 @@ static void CScriptTypes_LoadParams_Waypoint(ppmfc::CComboBox& comboBox)
{
std::map waypoints;
if (auto entries = doc.GetSection("Waypoints"))
- for (auto& x : entries->EntitiesDictionary)
+ for (auto& x : entries->GetEntities())
if (x.first != "Name" && !STDHelpers::IsNullOrEmpty(x.second))
{
int l = atoi(x.first);
@@ -192,7 +192,7 @@ static void CScriptTypes_LoadParams_ScriptLine(ppmfc::CComboBox& comboBox, ppmfc
if (cnt > 50)
cnt = 50;
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
@@ -218,7 +218,7 @@ static void CScriptTypes_LoadParams_ScriptLine(ppmfc::CComboBox& comboBox, ppmfc
// 4
static void CScriptTypes_LoadParams_SplitGroup(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
comboBox.SetItemData(comboBox.AddString("0 - Keep Transports, Keep Units"), 0);
comboBox.SetItemData(comboBox.AddString("1 - Keep Transports, Lose Units"), 1);
@@ -229,13 +229,13 @@ static void CScriptTypes_LoadParams_SplitGroup(ppmfc::CComboBox& comboBox)
// 5
static void CScriptTypes_LoadParams_GlobalVariables(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& rules = CINI::Rules();
if (auto entities = rules.GetSection("VariableNames"))
{
CString text;
- for (auto& x : entities->EntitiesDictionary)
+ for (auto& x : entities->GetEntities())
{
if (x.first != "Name" && !STDHelpers::IsNullOrEmpty(x.first))
{
@@ -250,13 +250,13 @@ static void CScriptTypes_LoadParams_GlobalVariables(ppmfc::CComboBox& comboBox)
// 6
static void CScriptTypes_LoadParams_ScriptTypes(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
if (auto entities = doc.GetSection("ScriptTypes"))
{
CString text, finaltext = "";
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (doc.SectionExists(ent.second) && !STDHelpers::IsNullOrEmpty(ent.second))
{
@@ -273,13 +273,13 @@ static void CScriptTypes_LoadParams_ScriptTypes(ppmfc::CComboBox& comboBox)
// 7
static void CScriptTypes_LoadParams_TeamTypes(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
if (auto entities = doc.GetSection("TeamTypes"))
{
CString text, finaltext = "";
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (doc.SectionExists(ent.second) && !STDHelpers::IsNullOrEmpty(ent.second))
{
@@ -302,13 +302,13 @@ static void CScriptTypes_LoadParams_Houses(ppmfc::CComboBox& comboBox)
// 9
static void CScriptTypes_LoadParams_Speechs(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& eva = CINI::Eva();
if (auto entities = eva.GetSection("DialogList"))
{
CString text;
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (eva.SectionExists(ent.second))
{
@@ -324,13 +324,13 @@ static void CScriptTypes_LoadParams_Speechs(ppmfc::CComboBox& comboBox)
// 10
static void CScriptTypes_LoadParams_Sounds(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& sound = CINI::Sound();
if (auto entities = sound.GetSection("SoundList"))
{
CString text;
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (sound.SectionExists(ent.second) && !STDHelpers::IsNullOrEmpty(ent.second))
{
@@ -345,13 +345,13 @@ static void CScriptTypes_LoadParams_Sounds(ppmfc::CComboBox& comboBox)
// 11
static void CScriptTypes_LoadParams_Movies(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& art = CINI::Art();
if (auto entities = art.GetSection("Movies"))
{
CString text;
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (ent.first != "Name")
{
@@ -366,13 +366,13 @@ static void CScriptTypes_LoadParams_Movies(ppmfc::CComboBox& comboBox)
// 12
static void CScriptTypes_LoadParams_Themes(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& theme = CINI::Theme();
if (auto entities = theme.GetSection("Themes"))
{
CString text;
- for (auto& ent : entities->EntitiesDictionary)
+ for (auto& ent : entities->GetEntities())
{
if (theme.SectionExists(ent.second) && !STDHelpers::IsNullOrEmpty(ent.second))
{
@@ -393,13 +393,13 @@ static void CScriptTypes_LoadParams_Countries(ppmfc::CComboBox& comboBox)
// 14
static void CScriptTypes_LoadParams_LocalVariables(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
if (auto entities = doc.GetSection("VariableNames"))
{
CString text;
- for (auto& x : entities->EntitiesDictionary)
+ for (auto& x : entities->GetEntities())
{
if (STDHelpers::IsNullOrEmpty(x.first) || x.first == "Name")
continue;
@@ -413,7 +413,7 @@ static void CScriptTypes_LoadParams_LocalVariables(ppmfc::CComboBox& comboBox)
// 15
static void CScriptTypes_LoadParams_Facing(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
comboBox.SetItemData(comboBox.AddString("0 - NE"), 0);
comboBox.SetItemData(comboBox.AddString("1 - E"), 1);
@@ -440,7 +440,7 @@ static void CScriptTypes_LoadParams_Animations(ppmfc::CComboBox& comboBox)
// 18
static void CScriptTypes_LoadParams_TalkBubble(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
comboBox.SetItemData(comboBox.AddString("0 - None"), 0);
comboBox.SetItemData(comboBox.AddString("1 - Asterisk(*)"), 1);
@@ -451,58 +451,47 @@ static void CScriptTypes_LoadParams_TalkBubble(ppmfc::CComboBox& comboBox)
// 19
static void CScriptTypes_LoadParams_Status(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
-
- const char* pStatus[] =
- {
- "Sleep",
- "Attack nearest enemy",
- "Move",
- "QMove",
- "Retreat home for R&R",
- "Guard",
- "Sticky (never recruit)",
- "Enter object",
- "Capture object",
- "Move into & get eaten",
- "Harvest",
- "Area Guard",
- "Return (to refinery)",
- "Stop",
- "Ambush (wait until discovered)",
- "Hunt",
- "Unload",
- "Sabotage (move in & destroy)",
- "Construction",
- "Deconstruction",
- "Repair",
- "Rescue",
- "Missile",
- "Harmless",
- "Open",
- "Patrol",
- "Paradrop approach drop zone",
- "Paradrop overlay drop zone",
- "Wait",
- "Attack again",
- "Spyplane approach",
- "Spyplane overfly"
- };
-
- for (int i = 0; i < 32; ++i)
- {
- char buffer[0x40];
- sprintf_s(buffer, "%u - %s", i, pStatus[i]);
- int idx = comboBox.AddString(buffer);
- if (idx >= 0)
- comboBox.SetItemData(idx, i);
- }
+ comboBox.DeleteAllStrings();
+
+ int i = 0;
+ comboBox.SetItemData(comboBox.AddString("0 - Sleep"), i++);
+ comboBox.SetItemData(comboBox.AddString("1 - Attack nearest enemy"), i++);
+ comboBox.SetItemData(comboBox.AddString("2 - Move"), i++);
+ comboBox.SetItemData(comboBox.AddString("3 - QMove"), i++);
+ comboBox.SetItemData(comboBox.AddString("4 - Retreat home for R&R"), i++);
+ comboBox.SetItemData(comboBox.AddString("5 - Guard"), i++);
+ comboBox.SetItemData(comboBox.AddString("6 - Sticky (never recruit)"), i++);
+ comboBox.SetItemData(comboBox.AddString("7 - Enter object"), i++);
+ comboBox.SetItemData(comboBox.AddString("8 - Capture object"), i++);
+ comboBox.SetItemData(comboBox.AddString("9 - Move into & get eaten"), i++);
+ comboBox.SetItemData(comboBox.AddString("10 - Harvest"), i++);
+ comboBox.SetItemData(comboBox.AddString("11 - Area Guard"), i++);
+ comboBox.SetItemData(comboBox.AddString("12 - Return (to refinery)"), i++);
+ comboBox.SetItemData(comboBox.AddString("13 - Stop"), i++);
+ comboBox.SetItemData(comboBox.AddString("14 - Ambush (wait until discovered)"), i++);
+ comboBox.SetItemData(comboBox.AddString("15 - Hunt"), i++);
+ comboBox.SetItemData(comboBox.AddString("16 - Unload"), i++);
+ comboBox.SetItemData(comboBox.AddString("17 - Sabotage (move in & destroy)"), i++);
+ comboBox.SetItemData(comboBox.AddString("18 - Construction"), i++);
+ comboBox.SetItemData(comboBox.AddString("19 - Deconstruction"), i++);
+ comboBox.SetItemData(comboBox.AddString("20 - Repair"), i++);
+ comboBox.SetItemData(comboBox.AddString("21 - Rescue"), i++);
+ comboBox.SetItemData(comboBox.AddString("22 - Missile"), i++);
+ comboBox.SetItemData(comboBox.AddString("23 - Harmless"), i++);
+ comboBox.SetItemData(comboBox.AddString("24 - Open"), i++);
+ comboBox.SetItemData(comboBox.AddString("25 - Patrol"), i++);
+ comboBox.SetItemData(comboBox.AddString("26 - Paradrop approach drop zone"), i++);
+ comboBox.SetItemData(comboBox.AddString("27 - Paradrop overlay drop zone"), i++);
+ comboBox.SetItemData(comboBox.AddString("28 - Wait"), i++);
+ comboBox.SetItemData(comboBox.AddString("29 - Attack again"), i++);
+ comboBox.SetItemData(comboBox.AddString("30 - Spyplane approach"), i++);
+ comboBox.SetItemData(comboBox.AddString("31 - Spyplane overfly"), i++);
}
// 20
static void CScriptTypes_LoadParams_Boolean(ppmfc::CComboBox& comboBox)
{
- while (comboBox.DeleteString(0) != -1);
+ comboBox.DeleteAllStrings();
comboBox.SetItemData(comboBox.AddString("0 - FALSE"), 0);
comboBox.SetItemData(comboBox.AddString("1 - TRUE"), 1);
diff --git a/FA2sp/Ext/CTileSetBrowserFrame/TabPages/TriggerSort.cpp b/FA2sp/Ext/CTileSetBrowserFrame/TabPages/TriggerSort.cpp
index 252cffa..c4cfb81 100644
--- a/FA2sp/Ext/CTileSetBrowserFrame/TabPages/TriggerSort.cpp
+++ b/FA2sp/Ext/CTileSetBrowserFrame/TabPages/TriggerSort.cpp
@@ -15,7 +15,7 @@ void TriggerSort::LoadAllTriggers()
// Optimisze the efficiency
if (auto pSection = CINI::CurrentDocument->GetSection("Triggers"))
{
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
{
this->AddTrigger(pair.first);
}
diff --git a/FA2sp/Ext/CTriggerFrame/Hooks.cpp b/FA2sp/Ext/CTriggerFrame/Hooks.cpp
index bbfa4fe..18dad9c 100644
--- a/FA2sp/Ext/CTriggerFrame/Hooks.cpp
+++ b/FA2sp/Ext/CTriggerFrame/Hooks.cpp
@@ -21,13 +21,13 @@ DEFINE_HOOK(4FA450, CTriggerFrame_Update, 7)
if (nCurSel != CB_ERR)
ID = reinterpret_cast(pThis->CCBCurrentTrigger.GetItemDataPtr(nCurSel));
- while (pThis->CCBCurrentTrigger.DeleteString(0) != CB_ERR);
+ pThis->CCBCurrentTrigger.DeleteAllStrings();
pThis->CCBCurrentTrigger.SetWindowText("");
if (auto pSection = CINI::CurrentDocument->GetSection("Triggers"))
{
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
{
auto splits = STDHelpers::SplitString(pair.second, 2);
int nIdx = pThis->CCBCurrentTrigger.AddString(splits[2]);
@@ -141,7 +141,7 @@ DEFINE_HOOK(4FB1B0, CTriggerFrame_OnBNDelTriggerClicked, 6)
if (auto pTagsSection = CINI::CurrentDocument->GetSection("Tags"))
{
std::set TagsToRemove;
- for (auto& pair : pTagsSection->EntitiesDictionary)
+ for (auto& pair : pTagsSection->GetEntities())
{
auto splits = STDHelpers::SplitString(pair.second, 2);
if (strcmp(splits[2], ID) == 0)
@@ -153,7 +153,7 @@ DEFINE_HOOK(4FB1B0, CTriggerFrame_OnBNDelTriggerClicked, 6)
if (auto pCellTagsSection = CINI::CurrentDocument->GetSection("CellTags"))
{
std::vector CellTagsToRemove;
- for (auto& pair : pCellTagsSection->EntitiesDictionary)
+ for (auto& pair : pCellTagsSection->GetEntities())
{
if (TagsToRemove.find(pair.second) != TagsToRemove.end())
CellTagsToRemove.push_back(pair.first);
@@ -194,7 +194,7 @@ DEFINE_HOOK(4FBD10, CTriggerFrame_OnBNPlaceOnMapClicked, 6)
{
if (auto pTagsSection = CINI::CurrentDocument->GetSection("Tags"))
{
- for (auto& pair : pTagsSection->EntitiesDictionary)
+ for (auto& pair : pTagsSection->GetEntities())
{
auto splits = STDHelpers::SplitString(pair.second, 2);
if (strcmp(splits[2], ID) == 0)
diff --git a/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.cpp b/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.cpp
index af1c434..9755081 100644
--- a/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.cpp
+++ b/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.cpp
@@ -3,6 +3,7 @@
#include
#include "../../Helpers/STDHelpers.h"
+#include "../../Helpers/Translations.h"
#include "../../FA2sp.h"
@@ -48,6 +49,23 @@ BOOL CALLBACK CAllieEditor::DlgProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM l
SetWindowText(hETCurrent, currentCountry);
+ // Translate
+ auto translateItem = [&](int nID, const char* lpKey)
+ {
+ ppmfc::CString buf;
+ if (Translations::GetTranslationItem(lpKey, buf))
+ SetWindowText(GetDlgItem(hwnd, nID), buf);
+ };
+
+ translateItem(6305, "AllieEditorEnemies");
+ translateItem(6306, "AllieEditorAllies");
+ translateItem(IDOK, "AllieEditorOK");
+ translateItem(IDCANCEL, "AllieEditorCancel");
+
+ ppmfc::CString buf;
+ if (Translations::GetTranslationItem("AllieEditorTitle", buf))
+ SetWindowText(hwnd, buf);
+
return TRUE;
}
case WM_COMMAND: {
diff --git a/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.rc b/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.rc
index 2f516f1..cacd4b5 100644
--- a/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.rc
+++ b/FA2sp/ExtraWindow/CAllieEditor/CAllieEditor.rc
@@ -7,8 +7,8 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,7,155,50,14
PUSHBUTTON "Cancel",IDCANCEL,252,155,50,14
- LTEXT "Enemies",-1,7,7,21,13,SS_SUNKEN
- LTEXT "Allies",-1,281,7,21,11,SS_SUNKEN
+ LTEXT "Enemies",6305,7,7,21,13,SS_SUNKEN
+ LTEXT "Allies", 6306,281,7,21,11,SS_SUNKEN
LISTBOX 6302,177,19,125,129,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY
LISTBOX 6303,7,19,125,129,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY
PUSHBUTTON "->",6300,137,57,36,14
diff --git a/FA2sp/ExtraWindow/CTileManager/CTileManager.cpp b/FA2sp/ExtraWindow/CTileManager/CTileManager.cpp
index 1b77082..63839dc 100644
--- a/FA2sp/ExtraWindow/CTileManager/CTileManager.cpp
+++ b/FA2sp/ExtraWindow/CTileManager/CTileManager.cpp
@@ -3,27 +3,14 @@
#include "../../FA2sp.h"
#include "../../Helpers/Translations.h"
#include "../../Helpers/STDHelpers.h"
+#include "../../Helpers/MultimapHelper.h"
+
+#include
HWND CTileManager::m_hwnd;
CTileSetBrowserFrame* CTileManager::m_parent;
-
-CTileManager::node_type CTileManager::Nodes = {
- "Cliff",
- "Water",
- "Ramp",
- "Bridge",
- "Road",
- "Feature",
- "Rail",
- "Tunnel",
- "Shore",
- "Pavement",
- "Fix",
- "LAT",
- "Other"
-};
-
-CTileManager::data_type CTileManager::Datas;
+std::vector> CTileManager::Nodes;
+std::vector> CTileManager::Datas;
void CTileManager::Create(CTileSetBrowserFrame* pWnd)
{
@@ -46,21 +33,54 @@ void CTileManager::Create(CTileSetBrowserFrame* pWnd)
void CTileManager::Initialize(HWND& hWnd)
{
+ ppmfc::CString buffer;
+ if (Translations::GetTranslationItem("TileManagerTitle", buffer))
+ SetWindowText(hWnd, buffer);
+
HWND hTileTypes = GetDlgItem(hWnd, 6100);
- for (auto& x : CTileManager::Nodes)
- SendMessage(hTileTypes, LB_ADDSTRING, NULL, (LPARAM)x);
+ InitNodes();
+ for (auto& x : CTileManager::Nodes)
+ SendMessage(hTileTypes, LB_ADDSTRING, NULL, (LPARAM)x.first.c_str());
+
UpdateTypes(hWnd);
}
+void CTileManager::InitNodes()
+{
+ CTileManager::Nodes.clear();
+
+ ppmfc::CString lpKey = "TileManagerData";
+ lpKey += CLoading::Instance->GetTheaterSuffix();
+
+ MultimapHelper mmh;
+ mmh.AddINI(&CINI::FAData);
+ auto const pKeys = mmh.ParseIndicies(lpKey);
+
+ for (auto& key : pKeys)
+ {
+ CTileManager::Nodes.push_back(
+ std::make_pair(key.m_pchData, std::regex(mmh.GetString(lpKey, key), std::regex::icase))
+ );
+ }
+
+ if (!Translations::GetTranslationItem("TileManagerOthers", lpKey))
+ lpKey = "Others";
+
+ CTileManager::Nodes.push_back(std::make_pair(lpKey.m_pchData, std::regex("")));
+
+ CTileManager::Datas.resize(CTileManager::Nodes.size());
+}
+
void CTileManager::Close(HWND& hWnd)
{
EndDialog(hWnd, NULL);
+
CTileManager::m_hwnd = NULL;
CTileManager::m_parent = NULL;
- for (auto& vec : CTileManager::Datas)
- vec.clear();
+ CTileManager::Nodes.clear();
+ CTileManager::Datas.clear();
}
BOOL CALLBACK CTileManager::DlgProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
@@ -164,32 +184,16 @@ void CTileManager::UpdateTypes(HWND hWnd)
tile.Format("TileSet%04d", nTile);
tile = CINI::CurrentTheater->GetString(tile, "SetName", "NO NAME");
bool other = true;
- if (STDHelpers::Contains(tile, "cliff", true))
- { CTileManager::Datas[Nodes_Cliff].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "water", true))
- { CTileManager::Datas[Nodes_Water].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "ramp", true) || STDHelpers::Contains(tile, "slope", true))
- { CTileManager::Datas[Nodes_Ramp].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "bridge", true))
- { CTileManager::Datas[Nodes_Bridge].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "road", true) || STDHelpers::Contains(tile, "highway", true))
- { CTileManager::Datas[Nodes_Road].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "feature", true) || STDHelpers::Contains(tile, "farm", true))
- { CTileManager::Datas[Nodes_Feature].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "rail", true) || STDHelpers::Contains(tile, "train", true))
- { CTileManager::Datas[Nodes_Rail].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "tunnel", true))
- { CTileManager::Datas[Nodes_Tunnel].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "shore", true))
- { CTileManager::Datas[Nodes_Shore].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "pave", true))
- { CTileManager::Datas[Nodes_Pave].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "fix", true))
- { CTileManager::Datas[Nodes_Fix].push_back(idx); other = false; }
- if (STDHelpers::Contains(tile, "lat", true))
- { CTileManager::Datas[Nodes_LAT].push_back(idx); other = false; }
- if(other)
- CTileManager::Datas[Nodes_Other].push_back(idx);
+ for (size_t i = 0; i < CTileManager::Nodes.size() - 1; ++i)
+ {
+ if (std::regex_search((std::string)tile.m_pchData, CTileManager::Nodes[i].second))
+ {
+ CTileManager::Datas[i].push_back(idx);
+ other = false;
+ }
+ }
+ if (other)
+ CTileManager::Datas[CTileManager::Nodes.size() - 1].push_back(idx);
}
CTileManager::UpdateDetails(hWnd);
@@ -201,7 +205,7 @@ void CTileManager::UpdateDetails(HWND hWnd, int kNode)
HWND hTileComboBox = GetDlgItem(hParent, 1366);
HWND hTileDetails = GetDlgItem(hWnd, 6101);
while (SendMessage(hTileDetails, LB_DELETESTRING, 0, NULL) != LB_ERR);
- if (kNode == Nodes_RemoveFlag)
+ if (kNode == -1)
return;
else
{
diff --git a/FA2sp/ExtraWindow/CTileManager/CTileManager.h b/FA2sp/ExtraWindow/CTileManager/CTileManager.h
index ca61a1b..bdd9bff 100644
--- a/FA2sp/ExtraWindow/CTileManager/CTileManager.h
+++ b/FA2sp/ExtraWindow/CTileManager/CTileManager.h
@@ -3,34 +3,27 @@
#include
#include
-#include
#include
+#include
+#include
// A static window class
class CTileManager
{
public:
- enum {
- Nodes_Cliff = 0, Nodes_Water, Nodes_Ramp, Nodes_Bridge,
- Nodes_Road, Nodes_Feature, Nodes_Rail, Nodes_Tunnel, Nodes_Shore,
- Nodes_Pave, Nodes_Fix, Nodes_LAT, Nodes_Other, Nodes_Count, Nodes_RemoveFlag = -1
- };
-
enum { ListBox_Types = 6100, ListBox_Details = 6101 };
- using data_type = std::array, Nodes_Count>;
- using node_type = std::array;
-
static void Create(CTileSetBrowserFrame* pWnd);
static HWND GetHandle()
{ return CTileManager::m_hwnd; }
static void UpdateTypes(HWND hWnd);
- static void UpdateDetails(HWND hWnd, int kNode = Nodes_RemoveFlag);
+ static void UpdateDetails(HWND hWnd, int kNode = -1);
protected:
static void Initialize(HWND& hWnd);
+ static void InitNodes();
static void Close(HWND& hWnd);
static BOOL CALLBACK DlgProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
@@ -41,7 +34,7 @@ class CTileManager
private:
static HWND m_hwnd;
static CTileSetBrowserFrame* m_parent;
- static node_type Nodes;
- static data_type Datas;
+ static std::vector> Nodes;
+ static std::vector> Datas;
};
diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h
index a233e68..8a1dcbc 100644
--- a/FA2sp/FA2sp.Constants.h
+++ b/FA2sp/FA2sp.Constants.h
@@ -4,8 +4,8 @@
#define __str_(x) #x
#define PRODUCT_MAJOR 1
-#define PRODUCT_MINOR 2
-#define PRODUCT_REVISION 2
+#define PRODUCT_MINOR 3
+#define PRODUCT_REVISION 0
#define PRODUCT_STR __str(PRODUCT_MAJOR) "." __str(PRODUCT_MINOR) "." __str(PRODUCT_REVISION)
#define DISPLAY_STR PRODUCT_STR
diff --git a/FA2sp/FA2sp.cpp b/FA2sp/FA2sp.cpp
index 7f88e64..17529a2 100644
--- a/FA2sp/FA2sp.cpp
+++ b/FA2sp/FA2sp.cpp
@@ -11,6 +11,7 @@
#include
HANDLE FA2sp::hInstance;
+std::string FA2sp::STDBuffer;
ppmfc::CString FA2sp::Buffer;
std::map FA2sp::TutorialTextsMap;
void* FA2sp::pExceptionHandler = nullptr;
@@ -42,6 +43,7 @@ int ExtConfigs::SaveMap_AutoSave_Interval;
int ExtConfigs::SaveMap_AutoSave_MaxCount;
bool ExtConfigs::SaveMap_OnlySaveMAP;
bool ExtConfigs::VerticalLayout;
+bool ExtConfigs::FastResize;
MultimapHelper Variables::Rules = { &CINI::Rules(), &CINI::CurrentDocument() };
@@ -104,6 +106,8 @@ void FA2sp::ExtConfigsInitialize()
ExtConfigs::SaveMap_OnlySaveMAP = fadata.GetBool("ExtConfigs", "SaveMap.OnlySaveMAP");
ExtConfigs::VerticalLayout = fadata.GetBool("ExtConfigs", "VerticalLayout");
+
+ ExtConfigs::FastResize = fadata.GetBool("ExtConfigs", "FastResize");
}
// DllMain
diff --git a/FA2sp/FA2sp.h b/FA2sp/FA2sp.h
index 079c352..edc9d14 100644
--- a/FA2sp/FA2sp.h
+++ b/FA2sp/FA2sp.h
@@ -15,6 +15,7 @@ class FA2sp
{
public:
static HANDLE hInstance;
+ static std::string STDBuffer;
static ppmfc::CString Buffer;
static std::map TutorialTextsMap;
static void* pExceptionHandler;
@@ -52,6 +53,7 @@ class ExtConfigs
static int SaveMap_AutoSave_MaxCount;
static bool SaveMap_OnlySaveMAP;
static bool VerticalLayout;
+ static bool FastResize;
};
class Variables
diff --git a/FA2sp/Helpers/ControlHelpers.cpp b/FA2sp/Helpers/ControlHelpers.cpp
index 86583a3..82e2080 100644
--- a/FA2sp/Helpers/ControlHelpers.cpp
+++ b/FA2sp/Helpers/ControlHelpers.cpp
@@ -9,14 +9,9 @@
namespace ControlHelpers
{
- void ComboBox::Clear(ppmfc::CComboBox& combobox)
- {
- while (combobox.DeleteString(0) != -1);
- }
-
void ComboBox::LoadHouses(ppmfc::CComboBox& combobox, bool bShowIndex)
{
- ComboBox::Clear(combobox);
+ combobox.DeleteAllStrings();
auto& entries = Variables::Rules.ParseIndicies("Houses", true);
CString buffer;
@@ -58,7 +53,7 @@ namespace ControlHelpers
void ComboBox::LoadCountries(ppmfc::CComboBox& combobox, bool bShowIndex)
{
- ComboBox::Clear(combobox);
+ combobox.DeleteAllStrings();
auto& doc = CINI::CurrentDocument();
if (CMapData::Instance->IsMultiOnly())
{
@@ -78,18 +73,28 @@ namespace ControlHelpers
}
}
- void ComboBox::LoadGenericList(ppmfc::CComboBox& combobox, const char* pSection, bool bShowRegName, bool bShowIndex)
+ void ComboBox::LoadGenericList(ppmfc::CComboBox& combobox, const char* pSection, bool bShowRegName, bool bShowIndex, bool bRegNameFirst)
{
- ComboBox::Clear(combobox);
+ combobox.DeleteAllStrings();
auto& entries = Variables::Rules.ParseIndicies(pSection, true);
CString buffer;
for (size_t i = 0, sz = entries.size(); i < sz; ++i)
{
- if (bShowIndex)
- buffer.Format("%u - %s", i, CMapData::GetUIName(entries[i]));
+ if (!bRegNameFirst)
+ {
+ if (bShowIndex)
+ buffer.Format("%u - %s", i, CMapData::GetUIName(entries[i]));
+ else
+ buffer = CMapData::GetUIName(entries[i]);
+ }
else
- buffer = CMapData::GetUIName(entries[i]);
+ {
+ if (bShowIndex)
+ buffer.Format("%u - %s", i, entries[i]);
+ else
+ buffer = entries[i];
+ }
if (bShowRegName)
buffer += (" - " + entries[i]);
combobox.SetItemData(combobox.AddString(buffer), i);
diff --git a/FA2sp/Helpers/ControlHelpers.h b/FA2sp/Helpers/ControlHelpers.h
index 75144b5..fbb60d0 100644
--- a/FA2sp/Helpers/ControlHelpers.h
+++ b/FA2sp/Helpers/ControlHelpers.h
@@ -7,10 +7,9 @@ namespace ControlHelpers
class ComboBox
{
public:
- static void Clear(ppmfc::CComboBox& combobox);
static void LoadHouses(ppmfc::CComboBox& combobox, bool bShowIndex = false);
static void LoadCountries(ppmfc::CComboBox& combobox, bool bShowIndex = false);
- static void LoadGenericList(ppmfc::CComboBox& combobox, const char* pSection, bool bShowRegName = false, bool bShowIndex = false);
+ static void LoadGenericList(ppmfc::CComboBox& combobox, const char* pSection, bool bShowRegName = false, bool bShowIndex = false, bool bRegNameFirst = false);
};
diff --git a/FA2sp/Helpers/INIParser.h b/FA2sp/Helpers/INIParser.h
deleted file mode 100644
index 5d2c2af..0000000
--- a/FA2sp/Helpers/INIParser.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-#include "..\FA2sp.h"
-#include "Parser.h"
-
-#include
-#include
-
-class INI_SP {
- INIClass* IniFile;
-
-public:
- explicit INI_SP(INIClass* pIniFile)
- : IniFile(pIniFile)
- { }
-
- char* value() const {
- return INI_SP::readBuffer;
- }
-
- size_t max_size() const {
- return INI_SP::readLength;
- }
-
- bool empty() const {
- return !INI_SP::readBuffer[0];
- }
-
- // basic string reader
- size_t ReadString(const char* pSection, const char* pKey) {
- auto& pValue = IniFile->GetString(pSection, pKey);
- auto const& ret = pValue.GetLength();
- auto const size = std::min(ret + 1, (int)this->max_size());
- memcpy_s(this->value(), size, pValue, size);
- return static_cast(ret);
- }
-
- // parser template
- template
- bool Read(const char* pSection, const char* pKey, T* pBuffer) {
- if (this->ReadString(pSection, pKey)) {
- return Parser::Parse(this->value(), pBuffer) == Count;
- }
- return false;
- }
-
- // helpers
-
- bool ReadBool(const char* pSection, const char* pKey, bool* bBuffer) {
- return Read(pSection, pKey, bBuffer);
- }
-
- bool ReadInteger(const char* pSection, const char* pKey, int* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
- bool Read2Integers(const char* pSection, const char* pKey, int* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
- bool Read3Integers(const char* pSection, const char* pKey, int* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
- bool Read4Integers(const char* pSection, const char* pKey, int* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
- bool Read3Bytes(const char* pSection, const char* pKey, byte* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
- bool ReadDouble(const char* pSection, const char* pKey, double* nBuffer) {
- return Read(pSection, pKey, nBuffer);
- }
-
-
-public:
- static const size_t readLength = 2048;
- static char readBuffer[readLength];
-
-};
diff --git a/FA2sp/Helpers/MultimapHelper.cpp b/FA2sp/Helpers/MultimapHelper.cpp
index d148d91..daad80d 100644
--- a/FA2sp/Helpers/MultimapHelper.cpp
+++ b/FA2sp/Helpers/MultimapHelper.cpp
@@ -127,7 +127,7 @@ std::map MultimapHe
if (pINI)
if (auto section = pINI->GetSection(pSection))
{
- for (auto& pair : section->EntitiesDictionary)
+ for (auto& pair : section->GetEntities())
{
if (STDHelpers::IsNullOrEmpty(pair.first) ||
STDHelpers::IsNullOrEmpty(pair.second) ||
diff --git a/FA2sp/Helpers/Translations.cpp b/FA2sp/Helpers/Translations.cpp
index 9d4160d..645861a 100644
--- a/FA2sp/Helpers/Translations.cpp
+++ b/FA2sp/Helpers/Translations.cpp
@@ -44,8 +44,8 @@ bool Translations::GetTranslationItem(const char* pLabelName, ppmfc::CString& re
for(const auto& language : Translations::pLanguage)
if (auto section = falanguage.GetSection(language))
{
- auto itr = section->EntitiesDictionary.find(pLabelName);
- if (itr != section->EntitiesDictionary.end())
+ auto itr = section->GetEntities().find(pLabelName);
+ if (itr != section->GetEntities().end())
{
ret = itr->second;
return true;
diff --git a/FA2sp/Hooks.Debug.cpp b/FA2sp/Hooks.Debug.cpp
index 1a8e931..eae47e7 100644
--- a/FA2sp/Hooks.Debug.cpp
+++ b/FA2sp/Hooks.Debug.cpp
@@ -6,10 +6,10 @@
#include "Logger.h"
//
-DEFINE_HOOK(438DB0, CrashMePlease, 6)
-{
- return 0x114514;
-}
+//DEFINE_HOOK(438DB0, CrashMePlease, 6)
+//{
+// return 0x114514;
+//}
//DEFINE_HOOK(45AF76, CIsoView_OnMouseMove_DebugCurrentCellData, 5)
//{
diff --git a/FA2sp/Logger.cpp b/FA2sp/Logger.cpp
index da84ed2..3f09963 100644
--- a/FA2sp/Logger.cpp
+++ b/FA2sp/Logger.cpp
@@ -88,6 +88,13 @@ void Logger::Raw(const char* format, ...) {
va_end(format);
}
+void Logger::Put(const char* pBuffer) {
+ if (bInitialized) {
+ fputs(pBuffer, pFile);
+ fflush(pFile);
+ }
+}
+
void Logger::Time(char* ret) {
SYSTEMTIME Sys;
GetLocalTime(&Sys);
diff --git a/FA2sp/Logger.h b/FA2sp/Logger.h
index f3a41b3..6a8dbfb 100644
--- a/FA2sp/Logger.h
+++ b/FA2sp/Logger.h
@@ -3,6 +3,9 @@
#include
#include
+#include
+#include
+
class Logger {
public:
enum class kLoggerType { Raw = -1, Debug, Info, Warn, Error };
@@ -14,9 +17,15 @@ class Logger {
static void Warn(const char*, ...);
static void Error(const char*, ...);
static void Raw(const char*, ...);
+ static void Put(const char*);
static void Time(char*);
static void Wrap(unsigned int cnt = 1);
+ template
+ static void FormatLog(const std::string_view _Fmt, const _Types&... _Args) {
+ Logger::Put(std::format(_Fmt, _Args...).c_str());
+ }
+
private:
static char pTime[24];
static char pBuffer[0x800];
diff --git a/FA2sp/Miscs/Exception.cpp b/FA2sp/Miscs/Exception.cpp
index 2b703aa..f40a400 100644
--- a/FA2sp/Miscs/Exception.cpp
+++ b/FA2sp/Miscs/Exception.cpp
@@ -198,6 +198,74 @@ std::wstring Exception::FullDump(
ExitProcess(ExitCode);
}
+#include
+// https://stackoverflow.com/questions/70458828
+bool DetachFromDebugger()
+{
+ using NTSTATUS = LONG;
+
+ auto GetDebuggerProcessId = [](DWORD dwSelfProcessId) -> DWORD
+ {
+ DWORD dwParentProcessId = -1;
+ HANDLE hSnapshot = CreateToolhelp32Snapshot(2, 0);
+ PROCESSENTRY32 pe32;
+ pe32.dwSize = sizeof(PROCESSENTRY32);
+ Process32First(hSnapshot, &pe32);
+ do
+ {
+ if (pe32.th32ProcessID == dwSelfProcessId)
+ {
+ dwParentProcessId = pe32.th32ParentProcessID;
+ break;
+ }
+ } while (Process32Next(hSnapshot, &pe32));
+ CloseHandle(hSnapshot);
+ return dwParentProcessId;
+ };
+
+ HMODULE hModule = LoadLibrary("ntdll.dll");
+ if (hModule != NULL)
+ {
+ auto const NtRemoveProcessDebug =
+ (NTSTATUS(__stdcall*)(HANDLE, HANDLE))GetProcAddress(hModule, "NtRemoveProcessDebug");
+ auto const NtSetInformationDebugObject =
+ (NTSTATUS(__stdcall*)(HANDLE, ULONG, PVOID, ULONG, PULONG))GetProcAddress(hModule, "NtSetInformationDebugObject");
+ auto const NtQueryInformationProcess =
+ (NTSTATUS(__stdcall*)(HANDLE, ULONG, PVOID, ULONG, PULONG))GetProcAddress(hModule, "NtQueryInformationProcess");
+ auto const NtClose =
+ (NTSTATUS(__stdcall*)(HANDLE))GetProcAddress(hModule, "NtClose");
+
+ HANDLE hDebug;
+ HANDLE hCurrentProcess = GetCurrentProcess();
+ NTSTATUS status = NtQueryInformationProcess(hCurrentProcess, 30, &hDebug, sizeof(HANDLE), 0);
+ if (0 <= status)
+ {
+ ULONG killProcessOnExit = FALSE;
+ status = NtSetInformationDebugObject(
+ hDebug,
+ 1,
+ &killProcessOnExit,
+ sizeof(ULONG),
+ NULL
+ );
+ if (0 <= status)
+ {
+ const auto pid = GetDebuggerProcessId(GetProcessId(hCurrentProcess));
+ status = NtRemoveProcessDebug(hCurrentProcess, hDebug);
+ if (0 <= status)
+ {
+ WinExec(std::format("taskkill /F /PID {}", pid).c_str(), SW_HIDE);
+ return true;
+ }
+ }
+ NtClose(hDebug);
+ }
+ FreeLibrary(hModule);
+ }
+
+ return false;
+}
+
DEFINE_HOOK(435270, CFinalSunDlg_DoModal, 8)
{
GET(CFinalSunDlg*, pThis, ECX);
@@ -205,13 +273,10 @@ DEFINE_HOOK(435270, CFinalSunDlg_DoModal, 8)
::SetUnhandledExceptionFilter(Exception::ExceptionFilter);
Logger::Info("FA2sp UnhandledExceptionFliter installed!\n");
- if (DebugActiveProcessStop(GetCurrentProcessId()))
- {
- WinExec("taskkill /IM Syringe.exe /F", SW_HIDE);
+ if (DetachFromDebugger())
Logger::Info("Syringe detached!\n");
- }
else
- Logger::Warn("Failed to detach Syringe! Error code = %X!\n", GetLastError());
+ Logger::Warn("Failed to detach Syringe!\n");
R->EAX(pThis->FA2CDialog::DoModal());
diff --git a/FA2sp/Miscs/Hooks.BugFixes.cpp b/FA2sp/Miscs/Hooks.BugFixes.cpp
index dfe63f5..6ee59ef 100644
--- a/FA2sp/Miscs/Hooks.BugFixes.cpp
+++ b/FA2sp/Miscs/Hooks.BugFixes.cpp
@@ -6,6 +6,8 @@
#include
#include
#include
+#include
+#include
#include
@@ -114,14 +116,37 @@ DEFINE_HOOK(473E66, CIsoView_Draw_InfantrySubcell, B)
return 0x473E8C;
}
-DEFINE_HOOK(4C61C5, CMapData_ResizeMap_PositionFix, 5)
+// Fix the bug that up&down&left&right vk doesn't update the TileSetBrowserView
+DEFINE_HOOK(422EA4, CFinalSunApp_ProcessMessageFilter_UpdateTileSetBrowserView_UpAndDown, 8)
{
- GET(CellData*, pCell, EAX);
- auto const pSrc = CONTAINING_RECORD(R->ECX(), CellData, Flag);
+ CFinalSunDlg::Instance->MyViewFrame.pTileSetBrowserFrame->View.SelectTileSet(
+ (*CTileTypeClass::CurrentTileType)[CIsoView::CurrentType].TileSet,
+ false
+ );
- pCell->Smudge = pSrc->Smudge;
- pCell->SmudgeType = pSrc->SmudgeType;
- pCell->BaseNode = pSrc->BaseNode;
+ return 0;
+}
+
+DEFINE_HOOK_AGAIN(422BF6, CFinalSunApp_ProcessMessageFilter_UpdateTileSetBrowserView_LeftAndRight, 7) // VirtualKey_Right
+DEFINE_HOOK(422B95, CFinalSunApp_ProcessMessageFilter_UpdateTileSetBrowserView_LeftAndRight, 7) // VirtualKey_Left
+{
+ CFinalSunDlg::Instance->MyViewFrame.pTileSetBrowserFrame->View.RedrawWindow(
+ nullptr, nullptr,
+ RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW
+ );
return 0;
-}
\ No newline at end of file
+}
+
+//
+//DEFINE_HOOK(4C61C5, CMapData_ResizeMap_PositionFix, 5)
+//{
+// GET(CellData*, pCell, EAX);
+// auto const pSrc = CONTAINING_RECORD(R->ECX(), CellData, Flag);
+//
+// pCell->Smudge = pSrc->Smudge;
+// pCell->SmudgeType = pSrc->SmudgeType;
+// pCell->BaseNode = pSrc->BaseNode;
+//
+// return 0;
+//}
\ No newline at end of file
diff --git a/FA2sp/Miscs/Hooks.LoadParams.cpp b/FA2sp/Miscs/Hooks.LoadParams.cpp
index 1501637..9490f4a 100644
--- a/FA2sp/Miscs/Hooks.LoadParams.cpp
+++ b/FA2sp/Miscs/Hooks.LoadParams.cpp
@@ -5,28 +5,136 @@
#include "../FA2sp.h"
#include "../Helpers/STDHelpers.h"
+#include "../Helpers/ControlHelpers.h"
-// TODO
-//DEFINE_HOOK(43CE8D, Miscs_LoadParamToCombobox, 9)
-//{
-// GET(CComboBox*, pComboBox, ESI);
-// GET(int, nCode, EAX);
-// while (pComboBox->DeleteString(0) != -1);
-//
-// enum { default = 0x43CE96, handled = 0x43D037 };
-//
-// if (nCode < 40)
-// {
-//
-// }
-// return 0;
-//}
+DEFINE_HOOK(43CE8D, Miscs_LoadParamToCombobox, 9)
+{
+ GET(ppmfc::CComboBox*, pComboBox, ESI);
+ GET(int, nCode, EAX);
+
+ if (nCode <= 30) // 30 is our float
+ return 0;
+
+ // Consistence with FA2Ext
+ switch (nCode)
+ {
+ case 31: // Enter Status
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Sleep");
+ pComboBox->AddString("1 - Attack nearest enemy");
+ pComboBox->AddString("2 - Move");
+ pComboBox->AddString("3 - QMove");
+ pComboBox->AddString("4 - Retreat home for R&R");
+ pComboBox->AddString("5 - Guard");
+ pComboBox->AddString("6 - Sticky (never recruit)");
+ pComboBox->AddString("7 - Enter object");
+ pComboBox->AddString("8 - Capture object");
+ pComboBox->AddString("9 - Move into & get eaten");
+ pComboBox->AddString("10 - Harvest");
+ pComboBox->AddString("11 - Area Guard");
+ pComboBox->AddString("12 - Return (to refinery)");
+ pComboBox->AddString("13 - Stop");
+ pComboBox->AddString("14 - Ambush (wait until discovered)");
+ pComboBox->AddString("15 - Hunt");
+ pComboBox->AddString("16 - Unload");
+ pComboBox->AddString("17 - Sabotage (move in & destroy)");
+ pComboBox->AddString("18 - Construction");
+ pComboBox->AddString("19 - Deconstruction");
+ pComboBox->AddString("20 - Repair");
+ pComboBox->AddString("21 - Rescue");
+ pComboBox->AddString("22 - Missile");
+ pComboBox->AddString("23 - Harmless");
+ pComboBox->AddString("24 - Open");
+ pComboBox->AddString("25 - Patrol");
+ pComboBox->AddString("26 - Paradrop approach drop zone");
+ pComboBox->AddString("27 - Paradrop overlay drop zone");
+ pComboBox->AddString("28 - Wait");
+ pComboBox->AddString("29 - Attack again");
+ pComboBox->AddString("30 - Spyplane approach");
+ pComboBox->AddString("31 - Spyplane overfly");
+ break;
+ case 32: // Targets
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Not specified");
+ pComboBox->AddString("1 - Anything (uses auto-targeting)");
+ pComboBox->AddString("2 - Buildings");
+ pComboBox->AddString("3 - Harvesters");
+ pComboBox->AddString("4 - Infantry");
+ pComboBox->AddString("5 - Vehicles");
+ pComboBox->AddString("6 - Factories");
+ pComboBox->AddString("7 - Base defenses");
+ pComboBox->AddString("9 - Power plants");
+ pComboBox->AddString("10 - Occupiables");
+ pComboBox->AddString("11 - Tech Buildings");
+ break;
+ case 33: // Facing
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - NE");
+ pComboBox->AddString("1 - E");
+ pComboBox->AddString("2 - SE");
+ pComboBox->AddString("3 - S");
+ pComboBox->AddString("4 - SW");
+ pComboBox->AddString("5 - W");
+ pComboBox->AddString("6 - NW");
+ pComboBox->AddString("7 - N");
+ break;
+ case 34: // Split
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Keep Transports, Keep Units");
+ pComboBox->AddString("1 - Keep Transports, Lose Units");
+ pComboBox->AddString("2 - Lose Transports, Keep Units");
+ pComboBox->AddString("3 - Lose Transports, Lose Units");
+ break;
+ case 35: // Camera Move Speed
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Very Slow");
+ pComboBox->AddString("1 - Slow");
+ pComboBox->AddString("2 - Normal");
+ pComboBox->AddString("3 - Fast");
+ pComboBox->AddString("4 - Very Fast");
+ break;
+ case 37: // Radar Event Type
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Combat");
+ pComboBox->AddString("1 - Non Combat");
+ pComboBox->AddString("2 - Drop Zone");
+ pComboBox->AddString("3 - Base Attack");
+ pComboBox->AddString("4 - Harvest Attack");
+ pComboBox->AddString("5 - Enemy Sensed");
+ pComboBox->AddString("6 - Unit Ready");
+ pComboBox->AddString("7 - Unit Lost");
+ pComboBox->AddString("8 - Unit Repaired");
+ pComboBox->AddString("9 - Building Infiltrated");
+ pComboBox->AddString("10 - Building Captured");
+ pComboBox->AddString("11 - Beacon Placed");
+ pComboBox->AddString("12 - SW Detected");
+ pComboBox->AddString("13 - SW Activated");
+ pComboBox->AddString("14 - Bridge Repaired");
+ pComboBox->AddString("15 - Garrison Abandoned");
+ pComboBox->AddString("16 - Ally Attack");
+ break;
+ case 38: // Tabpage
+ pComboBox->DeleteAllStrings();
+ pComboBox->AddString("0 - Buildings");
+ pComboBox->AddString("1 - Defenses");
+ pComboBox->AddString("2 - Infantries");
+ pComboBox->AddString("3 - Units");
+ break;
+ case 39: // SuperWeaponTypes (ID)
+ ControlHelpers::ComboBox::LoadGenericList(*pComboBox, "SuperWeaponTypes", true, false, true);
+ break;
+ default: // Not a valid param
+ break;
+ }
+
+ return 0x43D037;
+}
DEFINE_HOOK(43D037, Miscs_LoadParams_AdjustComboboxDropdownWidth, C)
{
if (ExtConfigs::AdjustDropdownWidth)
{
- GET_STACK(CComboBox*, pComboBox, STACK_OFFS(0x18, -0x4));
+ GET_STACK(ppmfc::CComboBox*, pComboBox, STACK_OFFS(0x18, -0x4));
int nWidth = 120;
for (int i = 0; i < pComboBox->GetCount() && nWidth <= ExtConfigs::AdjustDropdownWidth_Max; ++i)
@@ -58,15 +166,15 @@ DEFINE_HOOK(43CFE4, Miscs_LoadParams_SpeechBubble, 6)
DEFINE_HOOK(441910, Miscs_LoadParams_TutorialTexts, 7)
{
- GET_STACK(CComboBox*, pComboBox, 0x4);
+ GET_STACK(ppmfc::CComboBox*, pComboBox, 0x4);
if (ExtConfigs::TutorialTexts_Hide)
{
- while (pComboBox->DeleteString(0) != CB_ERR);
+ pComboBox->DeleteAllStrings();
return 0x441A34;
}
if (ExtConfigs::TutorialTexts_Fix)
{
- while (pComboBox->DeleteString(0) != CB_ERR);
+ pComboBox->DeleteAllStrings();
for (auto x : FA2sp::TutorialTextsMap)
pComboBox->AddString(x.first + " : " + x.second);
Logger::Debug("%d csf entities added.\n", FA2sp::TutorialTextsMap.size());
@@ -79,7 +187,7 @@ DEFINE_HOOK(441A40, Miscs_LoadParams_Triggers, 6)
{
GET_STACK(ppmfc::CComboBox*, pComboBox, 0x4);
- while (pComboBox->DeleteString(0) != CB_ERR);
+ pComboBox->DeleteAllStrings();
auto const pINI = CMapData::GetMapDocument(true);
pComboBox->LockWindowUpdate();
@@ -90,7 +198,7 @@ DEFINE_HOOK(441A40, Miscs_LoadParams_Triggers, 6)
if (auto const pSection = pINI->GetSection("Triggers"))
{
- for (auto pair : pSection->EntitiesDictionary)
+ for (auto pair : pSection->GetEntities())
{
auto splits = STDHelpers::SplitString(pair.second, 2);
ppmfc::CString buffer(pair.first);
@@ -108,7 +216,7 @@ DEFINE_HOOK(441A40, Miscs_LoadParams_Triggers, 6)
{
if (auto pSection = pINI->GetSection("Triggers"))
{
- for (auto& pair : pSection->EntitiesDictionary)
+ for (auto& pair : pSection->GetEntities())
{
auto splits = STDHelpers::SplitString(pair.second, 2);
ppmfc::CString buffer = pair.first;
diff --git a/FA2sp/Miscs/Hooks.Mix.cpp b/FA2sp/Miscs/Hooks.Mix.cpp
index a6d4f05..078278a 100644
--- a/FA2sp/Miscs/Hooks.Mix.cpp
+++ b/FA2sp/Miscs/Hooks.Mix.cpp
@@ -10,13 +10,11 @@ DEFINE_HOOK(5281EE, MixFile_Open_CheckRAUnencrypted, 5)
return 0x52823E;
}
-DEFINE_HOOK(527F95, MixFile_Open_CheckRAEncrypted, 6)
+DEFINE_HOOK(5280FC, MixFile_Open_CheckRAEncrypted, 7)
{
return 0x528124;
}
-int extramix = 0;
-
#include "../FA2sp.h"
#include
#include
@@ -35,7 +33,7 @@ DEFINE_HOOK(48A1AD, CLoading_InitMixFiles_ExtraMix, 7)
{
std::map collector;
- for (auto& pair : pSection->IndicesDictionary)
+ for (auto& pair : pSection->GetIndices())
collector[pair.second] = pair.first;
ppmfc::CString path;
@@ -50,7 +48,7 @@ DEFINE_HOOK(48A1AD, CLoading_InitMixFiles_ExtraMix, 7)
if (auto id = CMixFile::Open(path, 0))
{
ExtraMixes.push_back(id);
- CFA2Logger::Write("Successfully loaded extra mix file from %s\n", path);
+ CFA2Logger::WriteLine("Successfully loaded extra mix file from %s", path);
}
}
}
diff --git a/FA2sp/Miscs/Hooks.Palette.cpp b/FA2sp/Miscs/Hooks.Palette.cpp
new file mode 100644
index 0000000..7303185
--- /dev/null
+++ b/FA2sp/Miscs/Hooks.Palette.cpp
@@ -0,0 +1,68 @@
+#include
+#include
+#include
+#include
+
+#include "Palettes.h"
+
+DEFINE_HOOK(49D2C0, LoadMap_ClearUp, 5)
+{
+ PalettesManager::Release();
+
+ return 0;
+}
+
+#define REMAP_FIX_PALETTE_SET(hook_addr, hook_name, data_off, color_off) \
+DEFINE_HOOK(hook_addr,hook_name,7) \
+{ \
+ REF_STACK(ImageDataClass, data, STACK_OFFS(0xD18, data_off)); \
+ GET_STACK(BGRStruct*, pColor, STACK_OFFS(0xD18, color_off)); \
+ data.pPalette = PalettesManager::GetPalette(data.pPalette, *pColor); \
+ return 0; \
+}
+
+#define REMAP_FIX_JMP(hook_addr,hook_name,ret_addr) \
+DEFINE_HOOK(hook_addr,hook_name,6) \
+{ \
+ return ret_addr; \
+}
+
+#define REMAP_FIX_HOOK(set_addr, hook_name, data_off, color_off, jump_addr, jump_to)\
+REMAP_FIX_PALETTE_SET(set_addr,hook_name ## _SetPalette ,0x ## data_off,0x ## color_off); \
+REMAP_FIX_JMP(jump_addr,hook_name ## _JumpAway,0x ## jump_to);
+
+REMAP_FIX_HOOK(470D34, CIsoView_Draw_Palette_Building, AFC, CF0, 470DC0, 470DEC);
+REMAP_FIX_HOOK(471555, CIsoView_Draw_Palette_PowerUp1, 96C, CF4, 4715DF, 471604);
+REMAP_FIX_HOOK(471CF0, CIsoView_Draw_Palette_PowerUp2, 94C, CF4, 471D7A, 471D9F);
+REMAP_FIX_HOOK(472444, CIsoView_Draw_Palette_PowerUp3, 98C, CF4, 4724CD, 4724F2);
+REMAP_FIX_HOOK(472DCD, CIsoView_Draw_Palette_Basenode, 9DC, CF4, 472E73, 472E96);
+REMAP_FIX_HOOK(47337C, CIsoView_Draw_Palette_UnitsSHP, B7C, D04, 4733FC, 47342A);
+REMAP_FIX_HOOK(4735CE, CIsoView_Draw_Palette_UnitsVXL, B7C, D04, 47364E, 47367C);
+REMAP_FIX_HOOK(4739FF, CIsoView_Draw_Palette_AircraftsSHP, BE4, D04, 473A7F, 473AAD);
+REMAP_FIX_HOOK(473C51, CIsoView_Draw_Palette_AircraftsVXL, BE4, D04, 473A7F, 473CFF);
+REMAP_FIX_HOOK(474087, CIsoView_Draw_Palette_Infantry, 9B0, D04, 474109, 474135);
+
+#undef REMAP_FIX_PALETTE_SET
+#undef REMAP_FIX_JMP
+#undef REMAP_FIX_HOOK
+
+DEFINE_HOOK(48C3F6, CIsoView_InitTMPs_SkipReset, 5)
+{
+ if (!PalettesManager::ManualReloadTMP)
+ CLoading::Instance->InitTMPs_Reset();
+ return 0x48C3FB;
+}
+
+DEFINE_HOOK(46DEF7, CIsoView_Draw_Palette_Iso_Set, 5)
+{
+ PalettesManager::CacheAndTintCurrentIso();
+
+ return 0;
+}
+
+DEFINE_HOOK(474AE3, CIsoView_Draw_Palette_Iso_Revert, 6)
+{
+ PalettesManager::RestoreCurrentIso();
+
+ return 0;
+}
\ No newline at end of file
diff --git a/FA2sp/Miscs/Hooks.RemapColor.cpp b/FA2sp/Miscs/Hooks.RemapColor.cpp
deleted file mode 100644
index 91a6b06..0000000
--- a/FA2sp/Miscs/Hooks.RemapColor.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include
-#include
-#include
-
-#include "Palettes.h"
-
-DEFINE_HOOK(49D2C0, LoadMap_ClearUp, 5)
-{
- Palettes::Clear();
-
- return 0;
-}
-
-#define REMAP_FIX_PALETTE_SET(hook_addr, hook_name, data_off, color_off) \
-DEFINE_HOOK(hook_addr,hook_name,7) \
-{ \
-REF_STACK(ImageDataClass, data, STACK_OFFS(0xD18, data_off)); \
-GET_STACK(BGRStruct*, pColor, STACK_OFFS(0xD18, color_off)); \
-if(data.pPalette != Palette::PALETTE_ISO && data.pPalette != Palette::PALETTE_THEATER && data.pPalette != Palette::PALETTE_LIB) \
- data.pPalette = Palettes::GetRemap(data.pPalette,*pColor); \
-return 0; \
-}
-
-#define REMAP_FIX_JMP(hook_addr,hook_name,ret_addr) \
-DEFINE_HOOK(hook_addr,hook_name,6) \
-{ \
-return ret_addr; \
-}
-
-#define REMAP_FIX_HOOK(set_addr, hook_name,data_off,color_off, jump_addr,jump_to)\
-REMAP_FIX_PALETTE_SET(set_addr,hook_name ## _SetPalette ,0x ## data_off,0x ## color_off); \
-REMAP_FIX_JMP(jump_addr,hook_name ## _JumpAway,0x ## jump_to);
-
-REMAP_FIX_HOOK(470D34, CIsoView_Draw_RemapColor_Building, AFC, CF0, 470DC0, 470DEC);
-REMAP_FIX_HOOK(471555, CIsoView_Draw_RemapColor_PowerUp1, 96C, CF4, 4715DF, 471604);
-REMAP_FIX_HOOK(471CF0, CIsoView_Draw_RemapColor_PowerUp2, 94C, CF4, 471D7A, 471D9F);
-REMAP_FIX_HOOK(472444, CIsoView_Draw_RemapColor_PowerUp3, 98C, CF4, 4724CD, 4724F2);
-REMAP_FIX_HOOK(472DCD, CIsoView_Draw_RemapColor_Basenode, 9DC, CF4, 472E73, 472E96);
-REMAP_FIX_HOOK(47337C, CIsoView_Draw_RemapColor_UnitsSHP, B7C, D04, 4733FC, 47342A);
-REMAP_FIX_HOOK(4735CE, CIsoView_Draw_RemapColor_UnitsVXL, B7C, D04, 47364E, 47367C);
-REMAP_FIX_HOOK(4739FF, CIsoView_Draw_RemapColor_AircraftsSHP, BE4, D04, 473A7F, 473AAD);
-REMAP_FIX_HOOK(473C51, CIsoView_Draw_RemapColor_AircraftsVXL, BE4, D04, 473A7F, 473CFF);
-REMAP_FIX_HOOK(474087, CIsoView_Draw_RemapColor_Infantry, 9B0, D04, 474109, 474135);
-
-#undef REMAP_FIX_PALETTE_SET
-#undef REMAP_FIX_JMP
-#undef REMAP_FIX_HOOK
\ No newline at end of file
diff --git a/FA2sp/Miscs/Palettes.cpp b/FA2sp/Miscs/Palettes.cpp
index 422a62b..0a57d21 100644
--- a/FA2sp/Miscs/Palettes.cpp
+++ b/FA2sp/Miscs/Palettes.cpp
@@ -5,83 +5,198 @@
#include
#include
-std::map Palettes::LoadedPalettes;
-std::map> Palettes::RemappedPalettes;
+#include
-void Palettes::Init()
+#include "../Ext/CFinalSunDlg/Body.h"
+
+const LightingStruct LightingStruct::NoLighting = { -1,-1,-1,-1,-1,-1 };
+
+std::map PalettesManager::OriginPaletteFiles;
+std::map, LightingPalette>> PalettesManager::CalculatedPaletteFiles;
+Palette* PalettesManager::CurrentIso;
+bool PalettesManager::ManualReloadTMP = false;
+
+void PalettesManager::Init()
{
- LoadedPalettes["isotem.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["isosno.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["isourb.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["isoubn.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["isolun.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["isodes.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isotem.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isosno.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isourb.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isoubn.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isolun.pal"] = Palette::PALETTE_ISO;
+ PalettesManager::OriginPaletteFiles["isodes.pal"] = Palette::PALETTE_ISO;
- LoadedPalettes["unittem.pal"] = Palette::PALETTE_UNIT;
- LoadedPalettes["unitsno.pal"] = Palette::PALETTE_UNIT;
- LoadedPalettes["uniturb.pal"] = Palette::PALETTE_UNIT;
- LoadedPalettes["unitubn.pal"] = Palette::PALETTE_UNIT;
- LoadedPalettes["unitlun.pal"] = Palette::PALETTE_UNIT;
- LoadedPalettes["unitdes.pal"] = Palette::PALETTE_UNIT;
-
- LoadedPalettes["temperat.pal"] = Palette::PALETTE_THEATER;
- LoadedPalettes["snow.pal"] = Palette::PALETTE_THEATER;
- LoadedPalettes["urban.pal"] = Palette::PALETTE_THEATER;
- LoadedPalettes["urbann.pal"] = Palette::PALETTE_THEATER;
- LoadedPalettes["lunar.pal"] = Palette::PALETTE_THEATER;
- LoadedPalettes["desert.pal"] = Palette::PALETTE_THEATER;
-
- LoadedPalettes["libtem.pal"] = Palette::PALETTE_LIB;
+ PalettesManager::OriginPaletteFiles["unittem.pal"] = Palette::PALETTE_UNIT;
+ PalettesManager::OriginPaletteFiles["unitsno.pal"] = Palette::PALETTE_UNIT;
+ PalettesManager::OriginPaletteFiles["uniturb.pal"] = Palette::PALETTE_UNIT;
+ PalettesManager::OriginPaletteFiles["unitubn.pal"] = Palette::PALETTE_UNIT;
+ PalettesManager::OriginPaletteFiles["unitlun.pal"] = Palette::PALETTE_UNIT;
+ PalettesManager::OriginPaletteFiles["unitdes.pal"] = Palette::PALETTE_UNIT;
+
+ PalettesManager::OriginPaletteFiles["temperat.pal"] = Palette::PALETTE_THEATER;
+ PalettesManager::OriginPaletteFiles["snow.pal"] = Palette::PALETTE_THEATER;
+ PalettesManager::OriginPaletteFiles["urban.pal"] = Palette::PALETTE_THEATER;
+ PalettesManager::OriginPaletteFiles["urbann.pal"] = Palette::PALETTE_THEATER;
+ PalettesManager::OriginPaletteFiles["lunar.pal"] = Palette::PALETTE_THEATER;
+ PalettesManager::OriginPaletteFiles["desert.pal"] = Palette::PALETTE_THEATER;
+
+ PalettesManager::OriginPaletteFiles["libtem.pal"] = Palette::PALETTE_LIB;
+}
+
+void PalettesManager::Release()
+{
+ for (auto& pair : PalettesManager::OriginPaletteFiles)
+ if (pair.second != Palette::PALETTE_UNIT &&
+ pair.second != Palette::PALETTE_ISO &&
+ pair.second != Palette::PALETTE_THEATER &&
+ pair.second != Palette::PALETTE_LIB)
+ GameDelete(pair.second);
+
+ PalettesManager::CalculatedPaletteFiles.clear();
+
+ PalettesManager::RestoreCurrentIso();
+
+ Init();
+}
+
+void PalettesManager::CacheCurrentIso()
+{
+ if (!PalettesManager::CurrentIso)
+ PalettesManager::CurrentIso = GameCreate();
+
+ memcpy(PalettesManager::CurrentIso, Palette::PALETTE_ISO, 768);
+}
+
+void PalettesManager::RestoreCurrentIso()
+{
+ if (PalettesManager::CurrentIso)
+ {
+ memcpy(Palette::PALETTE_ISO, PalettesManager::CurrentIso, 768);
+ GameDelete(PalettesManager::CurrentIso);
+ PalettesManager::CurrentIso = nullptr;
+ }
}
-Palette* Palettes::LoadPalette(ppmfc::CString palName)
+Palette* PalettesManager::GetCurrentIso()
{
- if (LoadedPalettes.size() == 0)
- Palettes::Init();
+ return PalettesManager::CurrentIso;
+}
+
+void PalettesManager::CacheAndTintCurrentIso()
+{
+ PalettesManager::CacheCurrentIso();
+ BGRStruct empty;
+ auto pPal = PalettesManager::GetPalette(Palette::PALETTE_ISO, empty, false);
+ memcpy(Palette::PALETTE_ISO, pPal, 768);
+}
- auto itr = LoadedPalettes.find(palName);
- if (itr != LoadedPalettes.end())
+Palette* PalettesManager::LoadPalette(ppmfc::CString palname)
+{
+ auto itr = PalettesManager::OriginPaletteFiles.find(palname);
+ if (itr != PalettesManager::OriginPaletteFiles.end())
return itr->second;
- if (BytePalette* pBuffer = (BytePalette*)CLoading::Instance->ReadWholeFile(palName))
+ if (auto pBuffer = (BytePalette*)CLoading::Instance->ReadWholeFile(palname))
{
- auto pPal = GameCreate();
+ auto pPalette = GameCreate();
for (int i = 0; i < 256; ++i)
{
- pPal->Data[i].R = (*pBuffer)[i].red << 2;
- pPal->Data[i].G = (*pBuffer)[i].green << 2;
- pPal->Data[i].B = (*pBuffer)[i].blue << 2;
+ pPalette->Data[i].R = pBuffer->Data[i].red << 2;
+ pPalette->Data[i].G = pBuffer->Data[i].green << 2;
+ pPalette->Data[i].B = pBuffer->Data[i].blue << 2;
}
GameDelete(pBuffer);
- LoadedPalettes[palName] = pPal;
- return pPal;
+ PalettesManager::OriginPaletteFiles[palname] = pPalette;
+ return pPalette;
}
return nullptr;
}
-Palette* Palettes::GetRemap(ppmfc::CString palName, BGRStruct color)
+Palette* PalettesManager::GetPalette(Palette* pPal, BGRStruct& color, bool remap)
{
- if (LoadedPalettes.find(palName) == LoadedPalettes.end())
- if (!LoadPalette(palName))
- return nullptr;
+ LightingStruct lighting = LightingStruct::GetCurrentLighting();
+
+ auto itr = PalettesManager::CalculatedPaletteFiles[pPal].find(std::make_pair(color, lighting));
+ if (itr != PalettesManager::CalculatedPaletteFiles[pPal].end())
+ return itr->second.GetPalette();
+
+ auto& p = PalettesManager::CalculatedPaletteFiles[pPal].emplace(
+ std::make_pair(std::make_pair(color, lighting), LightingPalette(*pPal))
+ ).first->second;
+
+ if (remap)
+ p.RemapColors(color);
+ else
+ p.ResetColors();
- return GetRemap(LoadedPalettes[palName], color);
+ if (lighting != LightingStruct::NoLighting)
+ {
+ p.AdjustLighting(lighting);
+ p.TintColors();
+ }
+ return p.GetPalette();
+}
+
+LightingStruct LightingStruct::GetCurrentLighting()
+{
+ LightingStruct ret;
+ switch (CFinalSunDlgExt::CurrentLighting)
+ {
+ case 31001:
+ ret.Red = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Red", 1.0));
+ ret.Green = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Green", 1.0));
+ ret.Blue = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Blue", 0.5));
+ ret.Ambient = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Ambient", 1.0));
+ ret.Ground = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Ground", 0.008));
+ ret.Level = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "Level", 0.087));
+ return ret;
+ case 31002:
+ ret.Red = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonRed", 1.0));
+ ret.Green = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonGreen", 1.0));
+ ret.Blue = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonBlue", 0.5));
+ ret.Ambient = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonAmbient", 1.0));
+ ret.Ground = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonGround", 0.008));
+ ret.Level = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "IonLevel", 0.087));
+ return ret;
+ case 31003:
+ ret.Red = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorRed", 1.0));
+ ret.Green = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorGreen", 1.0));
+ ret.Blue = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorBlue", 0.5));
+ ret.Ambient = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorAmbient", 1.0));
+ ret.Ground = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorGround", 0.008));
+ ret.Level = static_cast(CINI::CurrentDocument->GetDouble("Lighting", "DominatorLevel", 0.087));
+ return ret;
+ }
+
+ // 31000
+ return LightingStruct::NoLighting;
}
-Palette* Palettes::GetRemap(Palette* pal, BGRStruct color)
+LightingPalette::LightingPalette(Palette& originPal)
{
- auto itr = RemappedPalettes.find(pal);
- if (itr != RemappedPalettes.end())
+ this->OriginPalette = &originPal;
+ this->ResetColors();
+}
+
+void LightingPalette::AdjustLighting(LightingStruct& lighting, int level, bool tint)
+{
+ this->AmbientMult = lighting.Ambient - lighting.Ground + lighting.Level * level;
+ if (tint)
{
- auto itr2 = itr->second.find(color);
- if (itr2 != itr->second.end())
- return &itr2->second;
+ this->RedMult = lighting.Red;
+ this->GreenMult = lighting.Green;
+ this->BlueMult = lighting.Blue;
}
+}
- // Not found, create remap color
- auto& buffer = RemappedPalettes[pal][color];
- memcpy_s(&buffer, sizeof(Palette), pal, sizeof(Palette));
+void LightingPalette::ResetColors()
+{
+ this->Colors = *this->OriginPalette;
+}
+
+void LightingPalette::RemapColors(BGRStruct color)
+{
+ this->ResetColors();
for (int i = 16; i <= 31; ++i)
{
int ii = i - 16;
@@ -97,21 +212,42 @@ Palette* Palettes::GetRemap(Palette* pal, BGRStruct color)
hsv_remap.V = (unsigned char)(std::cos(cosval) * hsv_remap.V);
RGBClass result = hsv_remap;
- buffer[i] = { result.B,result.G,result.R };
+ this->Colors[i] = { result.B,result.G,result.R };
}
- return &buffer;
}
-void Palettes::Clear()
+void LightingPalette::TintColors(bool isObject)
{
- for (auto& pair : LoadedPalettes)
- if (pair.second != Palette::PALETTE_UNIT &&
- pair.second != Palette::PALETTE_ISO &&
- pair.second != Palette::PALETTE_THEATER &&
- pair.second != Palette::PALETTE_LIB)
- GameDelete(pair.second);
+ this->RedMult = std::clamp(this->RedMult, 0.0f, 2.0f);
+ this->GreenMult = std::clamp(this->GreenMult, 0.0f, 2.0f);
+ this->BlueMult = std::clamp(this->BlueMult, 0.0f, 2.0f);
+ this->AmbientMult = std::clamp(this->AmbientMult, 0.0f, 2.0f);
- LoadedPalettes.clear();
- RemappedPalettes.clear();
- Init();
+ auto rmult = this->AmbientMult * this->RedMult;
+ auto gmult = this->AmbientMult * this->GreenMult;
+ auto bmult = this->AmbientMult * this->BlueMult;
+
+ for (int i = 0; i < 240; ++i)
+ {
+ this->Colors[i].R = (unsigned char)std::min(this->Colors[i].R * rmult, 255.0f);
+ this->Colors[i].G = (unsigned char)std::min(this->Colors[i].G * gmult, 255.0f);
+ this->Colors[i].B = (unsigned char)std::min(this->Colors[i].B * bmult, 255.0f);
+ }
+ if (!isObject)
+ {
+ for (int i = 240; i < 255; ++i)
+ {
+ this->Colors[i].R = (unsigned char)std::min(this->Colors[i].R * rmult, 255.0f);
+ this->Colors[i].G = (unsigned char)std::min(this->Colors[i].G * gmult, 255.0f);
+ this->Colors[i].B = (unsigned char)std::min(this->Colors[i].B * bmult, 255.0f);
+ }
+ }
+ this->Colors[255].R = (unsigned char)std::min(this->Colors[255].R * rmult, 255.0f);
+ this->Colors[255].G = (unsigned char)std::min(this->Colors[255].G * gmult, 255.0f);
+ this->Colors[255].B = (unsigned char)std::min(this->Colors[255].B * bmult, 255.0f);
}
+
+Palette* LightingPalette::GetPalette()
+{
+ return &this->Colors;
+}
\ No newline at end of file
diff --git a/FA2sp/Miscs/Palettes.h b/FA2sp/Miscs/Palettes.h
index 6a60cb4..f99b675 100644
--- a/FA2sp/Miscs/Palettes.h
+++ b/FA2sp/Miscs/Palettes.h
@@ -6,16 +6,88 @@
#include