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 -class Palettes +// References from ccmaps-net +// In fact the lighting should just be integers (from YR) +// R = Lighting.R * 100.0 + 0.1 +// G = Lighting.G * 100.0 + 0.1 +// B = Lighting.B * 100.0 + 0.1 +// Ambient = Lighting.Ambient * 100.0 + 0.1 +// Ground = Lighting.Ground * 1000.0 + 0.1 +// Level = Lighting.Level * 1000.0 + 0.1 +// I just choose to take a reference from ccmaps-net code - secsome + +struct LightingStruct +{ + float Red; + float Green; + float Blue; + float Ground; + float Ambient; + float Level; + + bool operator==(const LightingStruct& another) const + { + return + Red == another.Red && + Green == another.Green && + Blue == another.Blue && + Ground == another.Ground && + Ambient == another.Ambient && + Level == another.Level; + } + bool operator!=(const LightingStruct& another) const + { + return !(*this == another); + } + bool operator<(const LightingStruct& another) const + { + return + std::tie(Red, Green, Blue, Ground, Ambient, Level) < + std::tie(another.Red, another.Green, another.Blue, another.Ground, another.Ambient, another.Level); + } + + static LightingStruct GetCurrentLighting(); + + static const LightingStruct NoLighting; +}; + +class LightingPalette +{ +private: + Palette* OriginPalette; + float RedMult; + float GreenMult; + float BlueMult; + float AmbientMult; + Palette Colors; + +public: + LightingPalette(Palette& originPal); + void AdjustLighting(LightingStruct& lighting, int level = 0, bool tint = true); + void ResetColors(); + void RemapColors(BGRStruct color); + void TintColors(bool isObject = false); + Palette* GetPalette(); +}; + +class PalettesManager { + static std::map OriginPaletteFiles; + static std::map, LightingPalette>> CalculatedPaletteFiles; + static Palette* CurrentIso; + public: + static void Init(); - static Palette* LoadPalette(ppmfc::CString palName); - static Palette* GetRemap(ppmfc::CString palName, BGRStruct color); - static Palette* GetRemap(Palette* pal, BGRStruct color); - static void Clear(); + static void Release(); -private: - static std::map LoadedPalettes; - static std::map> RemappedPalettes; + static void CacheCurrentIso(); + static void RestoreCurrentIso(); + + static bool ManualReloadTMP; + + static Palette* GetCurrentIso(); + static void CacheAndTintCurrentIso(); + static Palette* LoadPalette(ppmfc::CString palname); + static Palette* GetPalette(Palette* pPal, BGRStruct& color, bool remap = true); }; \ No newline at end of file diff --git a/FA2sp/Miscs/SaveMap.cpp b/FA2sp/Miscs/SaveMap.cpp index be0b11a..f45d01b 100644 --- a/FA2sp/Miscs/SaveMap.cpp +++ b/FA2sp/Miscs/SaveMap.cpp @@ -13,6 +13,7 @@ #include #include +#include // FA2 SaveMap is almost O(N^4), who wrote that? DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) @@ -32,18 +33,18 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) buffer.Format("%d", pINI->GetInteger("FA2spVersionControl", "Version") + 1); pINI->WriteString("FA2spVersionControl", "Version", buffer); - Logger::Debug("SaveMap : Now removing empty sections and keys.\n"); + Logger::Raw("SaveMap : Now removing empty sections and keys.\n"); std::vector sectionsToRemove; for (auto& section_pair : pINI->Dict) { ppmfc::CString buffer; buffer = section_pair.first; buffer.Trim(); - if (buffer.GetLength() == 0 || section_pair.second.EntitiesDictionary.size() == 0) + if (buffer.GetLength() == 0 || section_pair.second.GetEntities().size() == 0) sectionsToRemove.push_back(section_pair.first); std::vector keysToRemove; - for (auto& key_pair : section_pair.second.EntitiesDictionary) + for (auto& key_pair : section_pair.second.GetEntities()) { buffer = key_pair.first; buffer.Trim(); @@ -54,7 +55,7 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) for (auto& key : keysToRemove) pINI->DeleteKey(section_pair.first, key); - if (section_pair.second.EntitiesDictionary.size() == 0) + if (section_pair.second.GetEntities().size() == 0) sectionsToRemove.push_back(section_pair.first); } for (auto& section : sectionsToRemove) @@ -62,7 +63,7 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) if (bGeneratePreview) { - Logger::Debug("SaveMap : Now generating a hidden preview as vanilla FA2 does.\n"); + Logger::Raw("SaveMap : Now generating a hidden preview as vanilla FA2 does.\n"); pINI->DeleteSection("Preview"); pINI->DeleteSection("PreviewPack"); pINI->WriteString("Preview", "Size", "0,0,106,61"); @@ -79,7 +80,7 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) filepath = filepath.Mid(0, nExtIndex) + ".map"; } - Logger::Debug("SaveMap : Trying to save map to %s.\n", filepath); + Logger::FormatLog("SaveMap : Trying to save map to {}.\n", filepath); std::ofstream fout; fout.open(filepath, std::ios::out | std::ios::trunc); @@ -98,7 +99,7 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) for (auto& section : pINI->Dict) { fout << "[" << section.first << "]\n"; - for (auto& pair : section.second.EntitiesDictionary) + for (auto& pair : section.second.GetEntities()) fout << pair.first << "=" << pair.second << "\n"; fout << "\n"; } @@ -106,13 +107,13 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) fout.flush(); fout.close(); - Logger::Debug("SaveMap : Successfully saved %d sections.\n", pINI->Dict.size()); + Logger::FormatLog("SaveMap : Successfully saved {} sections.\n", pINI->Dict.size()); } else { - FA2sp::Buffer.Format("Failed to create file %s.\n", filepath); - Logger::Warn("SaveMap : %s", FA2sp::Buffer); - ::MessageBox(NULL, FA2sp::Buffer, "Error", MB_OK | MB_ICONERROR); + auto buffer = std::format("Failed to create file {}.\n", filepath); + Logger::Raw(buffer.c_str()); + ::MessageBox(NULL, buffer.c_str(), "Error", MB_OK | MB_ICONERROR); } return 0x42A859; diff --git a/FA2sp/Miscs/Hooks.TheaterInfo.cpp b/FA2sp/Miscs/TheaterInfo.cpp similarity index 77% rename from FA2sp/Miscs/Hooks.TheaterInfo.cpp rename to FA2sp/Miscs/TheaterInfo.cpp index 9ea460b..4381973 100644 --- a/FA2sp/Miscs/Hooks.TheaterInfo.cpp +++ b/FA2sp/Miscs/TheaterInfo.cpp @@ -1,3 +1,5 @@ +#include "TheaterInfo.h" + #include #include @@ -9,63 +11,49 @@ #include "../Helpers/STDHelpers.h" -struct InfoStruct +const char* TheaterInfo::GetInfoSection() { - unsigned short Ramp; - unsigned short Morphable; - unsigned short RampIndex; - unsigned short MorphableIndex; -}; + switch (CLoading::Instance->TheaterIdentifier) + { + case 'A': + return "SnowInfo"; + case 'U': + return "UrbanInfo"; + case 'D': + return "DesertInfo"; + case 'L': + return "LunarInfo"; + case 'N': + return "NewUrbanInfo"; + case 'T': + default: + return "TemperateInfo"; + } +} -class TheaterInfo +void TheaterInfo::UpdateTheaterInfo() { -public: - static const char* GetInfoSection() + CurrentInfo.clear(); + auto const pSection = GetInfoSection(); + ppmfc::CString buffer = CINI::FAData->GetString(pSection, "Morphables"); + buffer.Trim(); + for (auto& str : STDHelpers::SplitString(buffer)) { - switch (CLoading::Instance->TheaterIdentifier) - { - case 'A': - return "SnowInfo"; - case 'U': - return "UrbanInfo"; - case 'D': - return "DesertInfo"; - case 'L': - return "LunarInfo"; - case 'N': - return "NewUrbanInfo"; - case 'T': - default: - return "TemperateInfo"; - } + CurrentInfo.emplace_back(InfoStruct()); + CurrentInfo.back().Morphable = atoi(str); + CurrentInfo.back().MorphableIndex = CTileTypeClass::GetTileIndex(CurrentInfo.back().Morphable); } - - static void UpdateTheaterInfo() + buffer = CINI::FAData->GetString(pSection, "Ramps"); + buffer.Trim(); + int i = 0; + for (auto& str : STDHelpers::SplitString(buffer)) { - CurrentInfo.clear(); - auto const pSection = GetInfoSection(); - ppmfc::CString buffer = CINI::FAData->GetString(pSection, "Morphables"); - buffer.Trim(); - for (auto& str : STDHelpers::SplitString(buffer)) - { - CurrentInfo.emplace_back(InfoStruct()); - CurrentInfo.back().Morphable = atoi(str); - CurrentInfo.back().MorphableIndex = CTileTypeClass::GetTileIndex(CurrentInfo.back().Morphable); - } - buffer = CINI::FAData->GetString(pSection, "Ramps"); - buffer.Trim(); - int i = 0; - for (auto& str : STDHelpers::SplitString(buffer)) - { - CurrentInfo[i].Ramp = atoi(str); - CurrentInfo[i].RampIndex = CTileTypeClass::GetTileIndex(CurrentInfo[i].Ramp); - ++i; - } + CurrentInfo[i].Ramp = atoi(str); + CurrentInfo[i].RampIndex = CTileTypeClass::GetTileIndex(CurrentInfo[i].Ramp); + ++i; } - static std::vector CurrentInfo; -}; - +} std::vector TheaterInfo::CurrentInfo; DEFINE_HOOK(49D121, CMapData_UpdateINIFile_UpdateTheaterInfos, 7) diff --git a/FA2sp/Miscs/TheaterInfo.h b/FA2sp/Miscs/TheaterInfo.h new file mode 100644 index 0000000..b65efd1 --- /dev/null +++ b/FA2sp/Miscs/TheaterInfo.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +struct InfoStruct +{ + unsigned short Ramp; + unsigned short Morphable; + unsigned short RampIndex; + unsigned short MorphableIndex; +}; + +class TheaterInfo +{ +public: + static const char* GetInfoSection(); + static void UpdateTheaterInfo(); + + static std::vector CurrentInfo; +}; \ No newline at end of file diff --git a/FA2sp/UI/CMenu.rc b/FA2sp/UI/CMenu.rc index ed65fd1..753d057 100644 --- a/FA2sp/UI/CMenu.rc +++ b/FA2sp/UI/CMenu.rc @@ -16,7 +16,7 @@ POPUP "File" // MENUITEM SEPARATOR // MENUITEM "Run Tiberian Sun", 40017 MENUITEM SEPARATOR - MENUITEM SEPARATOR + // MENUITEM SEPARATOR MENUITEM "Quit", 40003 } POPUP "Edit" @@ -121,4 +121,11 @@ POPUP "Layers" MENUITEM "Tubes", 30011 MENUITEM "Bounds", 30012 } +POPUP "Lighting" +{ + MENUITEM "No Lighting", 31000 + MENUITEM "Normal", 31001 + MENUITEM "Lightning Storm", 31002 + MENUITEM "Dominator", 31003 +} } diff --git a/README.md b/README.md index 4524d55..7f12b69 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,22 @@ I've decided to make this repository public so that more developers can help me For now it had implemented all features that FA2Ext has and extended more logics than it. The codes might be a messy, so I'd appreciate it if someone could help me to make them better arranged. -SDK: Visual Studio 2017 - Windows XP (v141_xp) -Compile Using C++ Standard Now: C++14 +SDK: Visual Studio 2022 (v143) +Compile Using C++ Standard Now: /std:c++latest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP CHANGELOG //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +======================= Changes (2021-12-31 RELEASE 1.3.0) ============================================================================================== +***) The project now compiles under v143+/std:c++latest, Windows XP may not be able to use this dll ++) New ExtConfig: FastResize = BOOLEAN, enable it so resizing the map will be much more faster when expanding ++) Experimental Lighting, only for preview, not correct ++) More localization support ++) Added more internal param codes +*) You can now customize tile manager by regex +*) Reimplement waypoint drawing, reduce lag +*) Minor adjustments ======================= Changes (2021-11-20 RELEASE 1.2.2) ============================================================================================== +) Now you can add more ramps to be auto generated in FA2 by setting [THEATERInfo] in fadata.ini @@ -225,6 +234,7 @@ COLORREF - R,G,B each of them is in [0,255] +) SaveMap.AutoSave.MaxCount = INTERGER ; How many saving should FA2 keep, set to -1 will disable the auto cleanning, defaults to 10 +) SaveMap.OnlySaveMAP = BOOLEAN ; Determines if FA2 will only save map with .map file extension +) VerticalLayout = BOOLEAN ; Determines if FA2 will make the bottom view go to the right side + +) FastResize = BOOLEAN ; Determines if FA2 will expanding the map more rapidly +) [Sides] ** (** means Essensial, fa2sp need this section to work properly) {Contains a list of sides registered in rules} \\\ e.g. @@ -252,6 +262,24 @@ COLORREF - R,G,B each of them is in [0,255] \\\ YENGINEER=2 \\\ {A LOT OF WESTWOOD CIVILIAN VEHICLES WITH PREREQUISITE [NAWEAP] WILL BE GUESSED INTO SOVIETS, FIX THEM MANUALLY} \\\ + +) [TileManagerDataXXX] (TEM, SNO, URB, UBN, LUN, DES) + DisplayName={Regex expression} + \\\ e.g. + \\\ [TileManagerDataTEM] + \\\ Cliff=cliff + \\\ Water=water + \\\ Ramp=ramp|slope + \\\ Bridge=bridge + \\\ Road=road|highway + \\\ Feature=feature|farm + \\\ Railway=rail|train + \\\ Tunnel=tunnel|tube + \\\ Ramp=ramp|slope + \\\ Shore=shore + \\\ Pavement=pave + \\\ Fix=fix + \\\ LAT=lat + \\\ +) [TheaterInfo] (TemperateInfo, SnowInfo, UrbanInfo, NewUrbanInfo, DesertInfo, LunarInfo) Ramps=Tilesets Morphables=Tilesets @@ -554,6 +582,11 @@ COLORREF - R,G,B each of them is in [0,255] +) Menu.Layers.Smudges = TEXT +) Menu.Layers.Tubes = TEXT +) Menu.Layers.Bounds = TEXT + +) Menu.Lighting = TEXT + +) Menu.Lighting.None = TEXT + +) Menu.Lighting.Normal = TEXT + +) Menu.Lighting.Lightning = TEXT + +) Menu.Lighting.Dominator = TEXT +) AITriggerTitle = TEXT +) AITriggerList = TEXT +) AITriggerName = TEXT @@ -717,6 +750,12 @@ COLORREF - R,G,B each of them is in [0,255] +) TheaterNameUbn = TEXT +) TheaterNameLun = TEXT +) TheaterNameDes = TEXT + +) AllieEditorTitle = TEXT + +) AllieEditorEnemies = TEXT + +) AllieEditorAllies = TEXT + +) AllieEditorOK = TEXT + +) AllieEditorCancel = TEXT + +) TileManagerTitle = TEXT - WRITE IN THE END This project was developed after FA2Copy with still many bugs to fix,