From abe5d81e125d8158a27a7441348fa84627c9faa2 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 18 Feb 2022 17:14:30 +0800 Subject: [PATCH 01/14] Reimplement CTeamTypes::OnCBCurrentTeamSelectChanged --- FA2pp | 2 +- FA2sp.vcxproj | 2 +- FA2sp/Ext/CTeamTypes/Hooks.cpp | 80 +++++++++++++++++++ FA2sp/Helpers/STDHelpers.h | 13 ++++ FA2sp/Miscs/Hooks.ExtWaypoints.cpp | 121 ++++++++++++++--------------- 5 files changed, 153 insertions(+), 65 deletions(-) diff --git a/FA2pp b/FA2pp index 7305baa..212197b 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit 7305baa0d7f10bf0eb2cd72b992307ec4bfe414a +Subproject commit 212197ba82e5dc327f27cb0c431ca9e942c0af48 diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 2806823..5936142 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -242,7 +242,7 @@ - + diff --git a/FA2sp/Ext/CTeamTypes/Hooks.cpp b/FA2sp/Ext/CTeamTypes/Hooks.cpp index d81d08e..232327d 100644 --- a/FA2sp/Ext/CTeamTypes/Hooks.cpp +++ b/FA2sp/Ext/CTeamTypes/Hooks.cpp @@ -2,3 +2,83 @@ #include +#include +#include + +#include "../../Helpers/STDHelpers.h" + +#include "../../FA2sp.h" + +DEFINE_HOOK(4E7900, CTeamTypes_OnCBCurrentTeamSelectChanged, 7) +{ + GET(CTeamTypes*, pThis, ECX); + auto pINI = CMapData::Instance->UpdateCurrentDocument(); + + if (pThis->CCBTeamList.GetCurSel() >= 0) + { + ppmfc::CString ID = STDHelpers::GetComboBoxText(pThis->CCBTeamList); + STDHelpers::TrimIndex(ID); + if (pINI->SectionExists(ID)) + { + pThis->BOOL_Aggressive = pINI->GetBool(ID, "Aggressive"); + pThis->BOOL_Annoyance = pINI->GetBool(ID, "Annoyance"); + pThis->BOOL_AreTeamMembersRecruitable = pINI->GetBool(ID, "AreTeamMembersRecruitable"); + pThis->BOOL_Autocreate = pINI->GetBool(ID, "Autocreate"); + pThis->BOOL_AvoidThreats = pINI->GetBool(ID, "AvoidThreats"); + pThis->BOOL_CargoPlane = pINI->GetBool(ID, "CargoPlane"); + pThis->BOOL_Full = pINI->GetBool(ID, "Full"); + pThis->BOOL_GuardSlower = pINI->GetBool(ID, "GuardSlower"); + pThis->BOOL_IonImmune = pINI->GetBool(ID, "IonImmune"); + pThis->BOOL_IsBaseDefense = pINI->GetBool(ID, "IsBaseDefense"); + pThis->BOOL_Loadable = pINI->GetBool(ID, "Loadable"); + pThis->BOOL_LooseRecruit = pINI->GetBool(ID, "LooseRecruit"); + pThis->BOOL_OnlyTargetHouseEnemy = pINI->GetBool(ID, "OnlyTargetHouseEnemy"); + pThis->BOOL_OnTransOnly = pINI->GetBool(ID, "OnTransOnly"); + pThis->BOOL_Prebuild = pINI->GetBool(ID, "Prebuild"); + pThis->BOOL_Recruiter = pINI->GetBool(ID, "Recruiter"); + pThis->BOOL_Reinforce = pINI->GetBool(ID, "Reinforce"); + pThis->BOOL_Suicide = pINI->GetBool(ID, "Suicide"); + pThis->BOOL_TransportsReturnOnUnload = pINI->GetBool(ID, "TransportsReturnOnUnload"); + pThis->BOOL_Whiner = pINI->GetBool(ID, "Whiner"); + pThis->CString_Group = pINI->GetString(ID, "Group"); + pThis->CString_House = pINI->GetString(ID, "House"); + pThis->CString_Max = pINI->GetString(ID, "Max"); + pThis->CString_Name = pINI->GetString(ID, "Name"); + pThis->CString_Priority = pINI->GetString(ID, "Priority"); + pThis->CString_TechLevel = pINI->GetString(ID, "TechLevel"); + + pThis->CString_VeteranLevel = pINI->GetString(ID, "VeteranLevel"); + if (CLoading::HasMdFile) + pThis->CString_MindControlDecision = pINI->GetString(ID, "MindControlDecision"); + + pThis->CString_Waypoint.Format("%d", Waypoints::String_To_Waypoint(pINI->GetString(ID, "Waypoint"))); + if (auto ppStr = pINI->TryGetString(ID, "TransportWaypoint")) + pThis->CString_TransportWaypoint.Format("%d", Waypoints::String_To_Waypoint(*ppStr)); + else + pThis->CString_TransportWaypoint = "None"; + + auto GetNamedString = [&](ppmfc::CString& des, const char* KeyName, const char* SectionName) + { + des = pINI->GetString(ID, KeyName); + des += " (" + pINI->GetString(des, "Name") + ")"; + }; + + GetNamedString(pThis->CString_Script, "Script", "ScriptTypes"); + GetNamedString(pThis->CString_TaskForce, "TaskForce", "TaskForces"); + + if (auto ppStr = pINI->TryGetString(ID, "Tag")) + { + pThis->CString_Tag = *ppStr; + auto tagcontent = STDHelpers::SplitString(pINI->GetString("Tags", ID)); + if (tagcontent.size() >= 2) + pThis->CString_Tag += " (" + tagcontent[1] + ")"; + } + else + pThis->CString_Tag = "None"; + + pThis->UpdateData(FALSE); + } + } + + return 0x4E9B11; +} \ No newline at end of file diff --git a/FA2sp/Helpers/STDHelpers.h b/FA2sp/Helpers/STDHelpers.h index 06923f0..c7cca72 100644 --- a/FA2sp/Helpers/STDHelpers.h +++ b/FA2sp/Helpers/STDHelpers.h @@ -109,4 +109,17 @@ class STDHelpers else return pStr.Find(pQuery) != -1; } + + static ppmfc::CString GetComboBoxText(const ppmfc::CComboBox& cbb) + { + int nCurSel = cbb.GetCurSel(); + ppmfc::CString ret; + + if (nCurSel == CB_ERR) + cbb.GetWindowText(ret); + else + cbb.GetLBText(nCurSel, ret); + + return ret; + } }; \ No newline at end of file diff --git a/FA2sp/Miscs/Hooks.ExtWaypoints.cpp b/FA2sp/Miscs/Hooks.ExtWaypoints.cpp index 0c20459..5581d84 100644 --- a/FA2sp/Miscs/Hooks.ExtWaypoints.cpp +++ b/FA2sp/Miscs/Hooks.ExtWaypoints.cpp @@ -1,14 +1,17 @@ #include "../FA2sp.h" #include -#include -#include #include -class ExtWaypoint + +DEFINE_HOOK(4E5F30, String_To_Waypoint, 5) { -public: - static int String_To_Waypoint(const char* s) + if (!ExtConfigs::ExtWaypoints) + return 0; + + GET_STACK(const char*, pString, 0x4); + + auto process = [](const char* s) { int n = 0; int len = strlen(s); @@ -21,9 +24,22 @@ class ExtWaypoint if (n <= 0) return -1; return n - 1; - } + }; + + R->EAX(process(pString)); + + return 0x4E5F87; +} + +DEFINE_HOOK(4E5F90, Waypoint_To_String, 7) +{ + if (!ExtConfigs::ExtWaypoints) + return 0; - static const char* Waypoint_To_String(int nWaypoint) + GET_STACK(ppmfc::CString*, pString, 0x4); + GET_STACK(int, nWaypoint, 0x8); + + auto process = [](int nWaypoint) -> const char* { static char buffer[8]{ '\0' }; @@ -45,66 +61,45 @@ class ExtWaypoint } return buffer + pos; } - } -}; - -DEFINE_HOOK(4E5F30, String_To_Waypoint, 5) -{ - if (!ExtConfigs::ExtWaypoints) - return 0; - - GET_STACK(const char*, pString, 0x4); + }; - R->EAX(ExtWaypoint::String_To_Waypoint(pString)); - - return 0x4E5F87; -} - -DEFINE_HOOK(4E5F90, Waypoint_To_String, 7) -{ - if (!ExtConfigs::ExtWaypoints) - return 0; - - GET_STACK(ppmfc::CString*, pString, 0x4); - GET_STACK(int, nWaypoint, 0x8); - - new(pString) ppmfc::CString(ExtWaypoint::Waypoint_To_String(nWaypoint)); + new(pString) ppmfc::CString(process(nWaypoint)); R->EAX(pString); return 0x4E60FA; } -DEFINE_HOOK(4E97F4, CTeamTypes_OnCBCurrentTeamSelectChanged_String_To_Waypoint_1, 5) -{ - if (!ExtConfigs::ExtWaypoints) - return 0; - - GET(CTeamTypes*, pThis, EBP); - REF_STACK(ppmfc::CString, lpWaypoint, STACK_OFFS(0x178, 0x160)); - - const int wp = ExtWaypoint::String_To_Waypoint(lpWaypoint); - if (wp != -1) - pThis->CString_Waypoint.Format("%d", wp); - else - pThis->CString_Waypoint = ""; - - return 0x4E9890; -} - -DEFINE_HOOK(4E9959, CTeamTypes_OnCBCurrentTeamSelectChanged_String_To_Waypoint_2, 5) -{ - if (!ExtConfigs::ExtWaypoints) - return 0; - - GET(CTeamTypes*, pThis, EBP); - REF_STACK(ppmfc::CString, lpWaypoint, STACK_OFFS(0x178, 0x128)); - - const int wp = ExtWaypoint::String_To_Waypoint(lpWaypoint); - if (wp != -1) - pThis->CString_TransportWaypoint.Format("%d", wp); - else - pThis->CString_TransportWaypoint = "None"; - - return 0x4E9A44; -} \ No newline at end of file +//DEFINE_HOOK(4E97F4, CTeamTypes_OnCBCurrentTeamSelectChanged_String_To_Waypoint_1, 5) +//{ +// if (!ExtConfigs::ExtWaypoints) +// return 0; +// +// GET(CTeamTypes*, pThis, EBP); +// REF_STACK(ppmfc::CString, lpWaypoint, STACK_OFFS(0x178, 0x160)); +// +// const int wp = ExtWaypoint::String_To_Waypoint(lpWaypoint); +// if (wp != -1) +// pThis->CString_Waypoint.Format("%d", wp); +// else +// pThis->CString_Waypoint = ""; +// +// return 0x4E9890; +//} +// +//DEFINE_HOOK(4E9959, CTeamTypes_OnCBCurrentTeamSelectChanged_String_To_Waypoint_2, 5) +//{ +// if (!ExtConfigs::ExtWaypoints) +// return 0; +// +// GET(CTeamTypes*, pThis, EBP); +// REF_STACK(ppmfc::CString, lpWaypoint, STACK_OFFS(0x178, 0x128)); +// +// const int wp = ExtWaypoint::String_To_Waypoint(lpWaypoint); +// if (wp != -1) +// pThis->CString_TransportWaypoint.Format("%d", wp); +// else +// pThis->CString_TransportWaypoint = "None"; +// +// return 0x4E9A44; +//} \ No newline at end of file From 09e7b7101d155ba082bf343e3f0a38c1f4e9f827 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 18 Feb 2022 17:35:27 +0800 Subject: [PATCH 02/14] Fixup House --- FA2pp | 2 +- FA2sp/Ext/CTeamTypes/Hooks.cpp | 3 ++- FA2sp/Miscs/Hooks.LoadParams.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/FA2pp b/FA2pp index 212197b..2a13629 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit 212197ba82e5dc327f27cb0c431ca9e942c0af48 +Subproject commit 2a136290a05d79223ca4a1b343f68b2f16356127 diff --git a/FA2sp/Ext/CTeamTypes/Hooks.cpp b/FA2sp/Ext/CTeamTypes/Hooks.cpp index 232327d..4f2e5f6 100644 --- a/FA2sp/Ext/CTeamTypes/Hooks.cpp +++ b/FA2sp/Ext/CTeamTypes/Hooks.cpp @@ -1,6 +1,7 @@ #include "Body.h" #include +#include #include #include @@ -41,11 +42,11 @@ DEFINE_HOOK(4E7900, CTeamTypes_OnCBCurrentTeamSelectChanged, 7) pThis->BOOL_TransportsReturnOnUnload = pINI->GetBool(ID, "TransportsReturnOnUnload"); pThis->BOOL_Whiner = pINI->GetBool(ID, "Whiner"); pThis->CString_Group = pINI->GetString(ID, "Group"); - pThis->CString_House = pINI->GetString(ID, "House"); pThis->CString_Max = pINI->GetString(ID, "Max"); pThis->CString_Name = pINI->GetString(ID, "Name"); pThis->CString_Priority = pINI->GetString(ID, "Priority"); pThis->CString_TechLevel = pINI->GetString(ID, "TechLevel"); + Miscs::ParseHouseName(&pThis->CString_House, pINI->GetString(ID, "House"), true); pThis->CString_VeteranLevel = pINI->GetString(ID, "VeteranLevel"); if (CLoading::HasMdFile) diff --git a/FA2sp/Miscs/Hooks.LoadParams.cpp b/FA2sp/Miscs/Hooks.LoadParams.cpp index 81a657b..823eace 100644 --- a/FA2sp/Miscs/Hooks.LoadParams.cpp +++ b/FA2sp/Miscs/Hooks.LoadParams.cpp @@ -228,4 +228,4 @@ DEFINE_HOOK(441A40, Miscs_LoadParams_Triggers, 6) pComboBox->UnlockWindowUpdate(); return 0x441DF6; -} +} \ No newline at end of file From 7c8e77bcbe7098d019959073c121876490b9cff1 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sat, 19 Feb 2022 11:36:25 +0800 Subject: [PATCH 03/14] Adapt lastest FA2pp --- FA2pp | 2 +- FA2sp/Ext/CDialog289/Body.cpp | 20 ------------------- FA2sp/Ext/CScriptsSelectionDialog/Body.cpp | 20 +++++++++++++++++++ .../Body.h | 10 +++++----- FA2sp/Ext/FA2Expand.cpp | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) delete mode 100644 FA2sp/Ext/CDialog289/Body.cpp create mode 100644 FA2sp/Ext/CScriptsSelectionDialog/Body.cpp rename FA2sp/Ext/{CDialog289 => CScriptsSelectionDialog}/Body.h (50%) diff --git a/FA2pp b/FA2pp index 2a13629..bdefe60 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit 2a136290a05d79223ca4a1b343f68b2f16356127 +Subproject commit bdefe608b0ceb26285ab0c5a37f989330426bbc5 diff --git a/FA2sp/Ext/CDialog289/Body.cpp b/FA2sp/Ext/CDialog289/Body.cpp deleted file mode 100644 index b55a7e9..0000000 --- a/FA2sp/Ext/CDialog289/Body.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "Body.h" - -CDialog289* CDialog289Ext::Instance = nullptr; - -void CDialog289Ext::ProgramStartupInit() -{ - RunTime::ResetMemoryContentAt(0x5926A8, &CDialog289Ext::PreTranslateMessageExt); -} - -BOOL CDialog289Ext::PreTranslateMessageExt(MSG* pMsg) -{ - switch (pMsg->message) { - case WM_CREATE: - Logger::Debug(__FUNCTION__"\n"); - break; - default: - break; - } - return this->ppmfc::CDialog::PreTranslateMessage(pMsg); -} \ No newline at end of file diff --git a/FA2sp/Ext/CScriptsSelectionDialog/Body.cpp b/FA2sp/Ext/CScriptsSelectionDialog/Body.cpp new file mode 100644 index 0000000..e078740 --- /dev/null +++ b/FA2sp/Ext/CScriptsSelectionDialog/Body.cpp @@ -0,0 +1,20 @@ +#include "Body.h" + +CScriptsSelectionDialog* CScriptsSelectionDialogExt::Instance = nullptr; + +void CScriptsSelectionDialogExt::ProgramStartupInit() +{ + RunTime::ResetMemoryContentAt(0x5926A8, &CScriptsSelectionDialogExt::PreTranslateMessageExt); +} + +BOOL CScriptsSelectionDialogExt::PreTranslateMessageExt(MSG* pMsg) +{ + switch (pMsg->message) { + case WM_CREATE: + Logger::Debug(__FUNCTION__"\n"); + break; + default: + break; + } + return this->ppmfc::CDialog::PreTranslateMessage(pMsg); +} \ No newline at end of file diff --git a/FA2sp/Ext/CDialog289/Body.h b/FA2sp/Ext/CScriptsSelectionDialog/Body.h similarity index 50% rename from FA2sp/Ext/CDialog289/Body.h rename to FA2sp/Ext/CScriptsSelectionDialog/Body.h index 947a283..cd6c69c 100644 --- a/FA2sp/Ext/CDialog289/Body.h +++ b/FA2sp/Ext/CScriptsSelectionDialog/Body.h @@ -1,22 +1,22 @@ #pragma once -#include +#include #include "../FA2Expand.h" -class NOVTABLE CDialog289Ext : public CDialog289 +class NOVTABLE CScriptsSelectionDialogExt : public CScriptsSelectionDialog { public: typedef BOOL(*FuncT_PTM)(MSG* pMsg); - static CDialog289* Instance; + static CScriptsSelectionDialog* Instance; //hook function to replace in virtual function map BOOL PreTranslateMessageExt(MSG* pMsg); static void ProgramStartupInit(); - CDialog289Ext() {}; - ~CDialog289Ext() {}; + CScriptsSelectionDialogExt() = delete; + ~CScriptsSelectionDialogExt() {}; private: diff --git a/FA2sp/Ext/FA2Expand.cpp b/FA2sp/Ext/FA2Expand.cpp index 45d2668..a943988 100644 --- a/FA2sp/Ext/FA2Expand.cpp +++ b/FA2sp/Ext/FA2Expand.cpp @@ -12,7 +12,7 @@ #include "CCreateMap3B/Body.h" #include "CCreateMap4/Body.h" #include "CCredits/Body.h" -#include "CDialog289/Body.h" +#include "CScriptsSelectionDialog/Body.h" #include "CEasterEgg/Body.h" #include "CHouses/Body.h" #include "CINIEditor/Body.h" From 377cd2d52ab94b76fa597bde9fc679be8b20225a Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sat, 19 Feb 2022 13:17:00 +0800 Subject: [PATCH 04/14] Support for lower case Theater name --- FA2pp | 2 +- FA2sp/Ext/CMapData/Hooks.cpp | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/FA2pp b/FA2pp index bdefe60..92068cd 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit bdefe608b0ceb26285ab0c5a37f989330426bbc5 +Subproject commit 92068cdcbf8ca59403b976bab4a265492ed01381 diff --git a/FA2sp/Ext/CMapData/Hooks.cpp b/FA2sp/Ext/CMapData/Hooks.cpp index dc6747a..c499571 100644 --- a/FA2sp/Ext/CMapData/Hooks.cpp +++ b/FA2sp/Ext/CMapData/Hooks.cpp @@ -85,13 +85,24 @@ DEFINE_HOOK(47AB50, CLoading_InitPics_InitOverlayTypeDatas, 7) DEFINE_HOOK(49DFB4, CMapData_LoadMap_InvalidTheater, 6) { - GET(char*, theaterName, EDI); + GET(const char*, lpTheaterName, EDI); - for (auto& str : TheaterHelpers::GetEnabledTheaterNames()) + for (const auto& lpStr : TheaterHelpers::GetEnabledTheaterNames()) { - if (strcmp(str, theaterName) == 0) + if (_strcmpi(lpStr, lpTheaterName) == 0) return 0; } return 0x49EDD9; -} \ No newline at end of file +} + +#define DEFINE_THEATER_NAME_FIX(addr, name) \ +DEFINE_HOOK(addr, CMapData_LoadMap_SupportLowerCaseTheaterName_##name, 5) \ +{R->EAX(_strcmpi(R->EDI(), #name)); return (0x##addr + 0xE);} + +DEFINE_THEATER_NAME_FIX(49DFB4, TEMPERATE); +DEFINE_THEATER_NAME_FIX(49E1D9, SNOW); +DEFINE_THEATER_NAME_FIX(49E3FF, URBAN); +DEFINE_THEATER_NAME_FIX(49E631, NEWURBAN); +DEFINE_THEATER_NAME_FIX(49E863, LUNAR); +DEFINE_THEATER_NAME_FIX(49EAA4, DESERT); \ No newline at end of file From 0c0991d70764bd8d3a3b1e072ecdeb88a85c1514 Mon Sep 17 00:00:00 2001 From: Chlorine2048 <60431010+Chlorine2048@users.noreply.github.com> Date: Wed, 2 Mar 2022 18:09:30 +0800 Subject: [PATCH 05/14] define Syringe Ver2 in Debug86 --- FA2sp.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 5936142..1db12f7 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -95,7 +95,7 @@ true false true - WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) + WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;SYR_VER=2;%(PreprocessorDefinitions) false false From ec598162c06243a976d0fde2729064a16cf99f6e Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sat, 5 Mar 2022 00:00:14 +0800 Subject: [PATCH 06/14] Stupid register bugfix --- FA2sp/Ext/CFinalSunApp/Body.cpp | 3 ++- FA2sp/Ext/CMapData/Hooks.cpp | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/FA2sp/Ext/CFinalSunApp/Body.cpp b/FA2sp/Ext/CFinalSunApp/Body.cpp index bd6e765..7121c17 100644 --- a/FA2sp/Ext/CFinalSunApp/Body.cpp +++ b/FA2sp/Ext/CFinalSunApp/Body.cpp @@ -34,9 +34,10 @@ BOOL CFinalSunAppExt::InitInstanceExt() exit(0); } - std::string cmdline = this->m_lpCmdLine; CFinalSunDlg::SE2KMODE = FALSE; // We don't need SE2K stuff CFinalSunApp::MapPath[0] = '\0'; + // Now let's parse the command line + // Nothing yet huh... std::string path; path = CFinalSunApp::ExePath + "\\FAData.ini"; diff --git a/FA2sp/Ext/CMapData/Hooks.cpp b/FA2sp/Ext/CMapData/Hooks.cpp index c499571..7c04975 100644 --- a/FA2sp/Ext/CMapData/Hooks.cpp +++ b/FA2sp/Ext/CMapData/Hooks.cpp @@ -96,13 +96,15 @@ DEFINE_HOOK(49DFB4, CMapData_LoadMap_InvalidTheater, 6) return 0x49EDD9; } -#define DEFINE_THEATER_NAME_FIX(addr, name) \ +#define DEFINE_THEATER_NAME_FIX(addr, name, reg) \ DEFINE_HOOK(addr, CMapData_LoadMap_SupportLowerCaseTheaterName_##name, 5) \ -{R->EAX(_strcmpi(R->EDI(), #name)); return (0x##addr + 0xE);} - -DEFINE_THEATER_NAME_FIX(49DFB4, TEMPERATE); -DEFINE_THEATER_NAME_FIX(49E1D9, SNOW); -DEFINE_THEATER_NAME_FIX(49E3FF, URBAN); -DEFINE_THEATER_NAME_FIX(49E631, NEWURBAN); -DEFINE_THEATER_NAME_FIX(49E863, LUNAR); -DEFINE_THEATER_NAME_FIX(49EAA4, DESERT); \ No newline at end of file +{R->EAX(_strcmpi(R->reg(), #name)); return (0x##addr + 0xE);} + +DEFINE_THEATER_NAME_FIX(49DFB4, TEMPERATE, EDI); +DEFINE_THEATER_NAME_FIX(49E1D9, SNOW, EDI); +DEFINE_THEATER_NAME_FIX(49E3FF, URBAN, EDI); +DEFINE_THEATER_NAME_FIX(49E631, NEWURBAN, EDI); +DEFINE_THEATER_NAME_FIX(49E863, LUNAR, EDI); +DEFINE_THEATER_NAME_FIX(49EAA4, DESERT, ESI); + +#undef DEFINE_THEATER_NAME_FIX \ No newline at end of file From d3b8d6ad021fb76b883c172fd3e0b09aa11fa4a8 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sun, 6 Mar 2022 20:25:05 +0800 Subject: [PATCH 07/14] Fix a possible memory leak --- FA2sp/Ext/CLoading/Hooks.LoadObjects.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/FA2sp/Ext/CLoading/Hooks.LoadObjects.cpp b/FA2sp/Ext/CLoading/Hooks.LoadObjects.cpp index 59709fe..653ba37 100644 --- a/FA2sp/Ext/CLoading/Hooks.LoadObjects.cpp +++ b/FA2sp/Ext/CLoading/Hooks.LoadObjects.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -77,6 +78,16 @@ DEFINE_HOOK(49D2C0, CMapData_LoadMap_ClearCLoadingExtData, 5) return 0; } +DEFINE_HOOK(49D5CC, CLoading_LoadMap_CallMissingRelease, 5) +{ + GET(CLoading*, pThis, ESI); + + pThis->Release(); + pThis->InitializeDDraw(); + + return 0; +} + DEFINE_HOOK(491FD4, CLoading_Release_SetImageDataToNullptr, 5) { GET(char*, pNode, ESI); // Map node in fact From aab9b5a672cbcd6e8d933aabbd0d7fa51204ed3d Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sun, 6 Mar 2022 22:00:05 +0800 Subject: [PATCH 08/14] Update FA2PP --- FA2pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FA2pp b/FA2pp index 92068cd..41bb2a9 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit 92068cdcbf8ca59403b976bab4a265492ed01381 +Subproject commit 41bb2a98814eb541e1879bda9170fb270cd1c1f1 From 7763ca200d3b7d0ddd6d33a47752b306a6b4f16e Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Thu, 10 Mar 2022 21:30:30 +0800 Subject: [PATCH 09/14] Add a space before RegName --- FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp index 7cdb4cd..389a986 100644 --- a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp +++ b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp @@ -287,7 +287,7 @@ void CViewObjectsExt::Redraw_Infantry() if (subNodes.find(side) == subNodes.end()) side = -1; this->InsertString( - QueryUIName(inf.second) + "(" + inf.second + ")", + QueryUIName(inf.second) + " (" + inf.second + ")", Const_Infantry + index, subNodes[side] ); @@ -336,7 +336,7 @@ void CViewObjectsExt::Redraw_Vehicle() if (subNodes.find(side) == subNodes.end()) side = -1; this->InsertString( - QueryUIName(veh.second) + "(" + veh.second + ")", + QueryUIName(veh.second) + " (" + veh.second + ")", Const_Vehicle + index, subNodes[side] ); @@ -386,7 +386,7 @@ void CViewObjectsExt::Redraw_Aircraft() if (subNodes.find(side) == subNodes.end()) side = -1; this->InsertString( - QueryUIName(air.second) + "(" + air.second + ")", + QueryUIName(air.second) + " (" + air.second + ")", Const_Aircraft + index, subNodes[side] ); @@ -436,7 +436,7 @@ void CViewObjectsExt::Redraw_Building() if (subNodes.find(side) == subNodes.end()) side = -1; this->InsertString( - QueryUIName(bud.second) + "(" + bud.second + ")", + QueryUIName(bud.second) + " (" + bud.second + ")", Const_Building + index, subNodes[side] ); @@ -483,7 +483,7 @@ void CViewObjectsExt::Redraw_Terrain() if (IgnoreSet.find(terrains[i]) == IgnoreSet.end()) { FA2sp::Buffer = QueryUIName(terrains[i]); - FA2sp::Buffer += "(" + terrains[i] + ")"; + FA2sp::Buffer += " (" + terrains[i] + ")"; bool bNotOther = false; for (const auto& node : nodes) { @@ -590,7 +590,7 @@ void CViewObjectsExt::Redraw_Overlay() { CString buffer; buffer = QueryUIName(overlays[i]); - buffer += "(" + overlays[i] + ")"; + buffer += " (" + overlays[i] + ")"; if (rules.GetBool(overlays[i], "Wall")) this->InsertString( QueryUIName(overlays[i]), From 1aedb200e0c74f590495b36d92be5de185303d49 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Tue, 10 May 2022 15:28:41 +0800 Subject: [PATCH 10/14] Replace Memory Handlers --- FA2sp.vcxproj | 1 + FA2sp.vcxproj.filters | 3 +++ FA2sp/Miscs/Hooks.Memory.cpp | 15 +++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 FA2sp/Miscs/Hooks.Memory.cpp diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 1db12f7..0c63142 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -180,6 +180,7 @@ + diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters index e7a97f9..af5e480 100644 --- a/FA2sp.vcxproj.filters +++ b/FA2sp.vcxproj.filters @@ -407,6 +407,9 @@ 源文件 + + 源文件 + diff --git a/FA2sp/Miscs/Hooks.Memory.cpp b/FA2sp/Miscs/Hooks.Memory.cpp new file mode 100644 index 0000000..a532040 --- /dev/null +++ b/FA2sp/Miscs/Hooks.Memory.cpp @@ -0,0 +1,15 @@ +#include "../RunTime.h" + +#include + +DEFINE_HOOK(537128, ExeStart_MemoryHooks, 5) +{ + RunTime::ResetMemoryContentAt(0x591110, HeapFree); + RunTime::ResetMemoryContentAt(0x591128, HeapReAlloc); + RunTime::ResetMemoryContentAt(0x59112C, HeapAlloc); + RunTime::ResetMemoryContentAt(0x591138, HeapSize); + RunTime::ResetMemoryContentAt(0x591154, HeapDestroy); + RunTime::ResetMemoryContentAt(0x591158, HeapCreate); + + return 0; +} \ No newline at end of file From a3262c8805b103a65b47ce481ede4edccb74e339 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Tue, 10 May 2022 15:42:39 +0800 Subject: [PATCH 11/14] Disable MultiSelection, Exclude Memory Handler --- FA2sp.vcxproj | 1 - FA2sp.vcxproj.filters | 3 --- FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp | 12 ++++++++++-- FA2sp/Miscs/MultiSelection.cpp | 7 ++++++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 0c63142..1db12f7 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -180,7 +180,6 @@ - diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters index af5e480..e7a97f9 100644 --- a/FA2sp.vcxproj.filters +++ b/FA2sp.vcxproj.filters @@ -407,9 +407,6 @@ 源文件 - - 源文件 - diff --git a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp index 389a986..46938da 100644 --- a/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp +++ b/FA2sp/Ext/CFinalSunDlg/Body.ObjectBrowserControl.cpp @@ -139,11 +139,19 @@ void CViewObjectsExt::Redraw_Initialize() if (auto ignores = fadata.GetSection("IgnoreRA2")) for (auto& item : ignores->GetEntities()) - IgnoreSet.insert(item.second); + { + ppmfc::CString tmp = item.second; + tmp.Trim(); + IgnoreSet.insert(tmp); + } if (auto forcenames = fadata.GetSection("ForceName")) for (auto& item : forcenames->GetEntities()) - ForceName.insert(item.second); + { + ppmfc::CString tmp = item.second; + tmp.Trim(); + ForceName.insert(tmp); + } } diff --git a/FA2sp/Miscs/MultiSelection.cpp b/FA2sp/Miscs/MultiSelection.cpp index 6b76e16..92d6154 100644 --- a/FA2sp/Miscs/MultiSelection.cpp +++ b/FA2sp/Miscs/MultiSelection.cpp @@ -72,6 +72,9 @@ inline bool MultiSelection::IsSelected(int X, int Y) return SelectedCoords.find(MapCoord{ X,Y }) != SelectedCoords.end(); } +/* + + DEFINE_HOOK(456EFC, CIsoView_OnMouseMove_MultiSelect_ReverseStatus, 6) { GET_STACK(UINT, eFlags, STACK_OFFS(0x3D528, -0x4)); @@ -350,4 +353,6 @@ DEFINE_HOOK(49D2C0, LoadMap_ClearUp_MultiSelection, 5) MultiSelection::Clear(); return 0; -} \ No newline at end of file +} + +*/ \ No newline at end of file From e294ecd2b7dd443a8eab92f00db2c1158a99e485 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Tue, 10 May 2022 16:03:09 +0800 Subject: [PATCH 12/14] Adjust UI --- FA2sp/Ext/CTileSetBrowserFrame/Hooks.cpp | 14 +++++++++++--- FA2sp/UI/CTileBrowserFrame.DialogBar.rc | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/FA2sp/Ext/CTileSetBrowserFrame/Hooks.cpp b/FA2sp/Ext/CTileSetBrowserFrame/Hooks.cpp index 4616fef..43b0869 100644 --- a/FA2sp/Ext/CTileSetBrowserFrame/Hooks.cpp +++ b/FA2sp/Ext/CTileSetBrowserFrame/Hooks.cpp @@ -18,7 +18,7 @@ DEFINE_HOOK(4F1A40, CTileSetBrowserFrame_CreateContent, 5) RECT rect; pThis->GetClientRect(&rect); - pThis->DialogBar.Create(pTab, MAKEINTRESOURCE(0xE3), 0x2800, 5); + pThis->DialogBar.Create(pTab, MAKEINTRESOURCE(ExtConfigs::VerticalLayout ? 0xE4 : 0xE3), 0x2800, 5); Translations::TranslateItem(&pThis->DialogBar, 6102, "DialogBar.TileManager"); Translations::TranslateItem(&pThis->DialogBar, 1368, "DialogBar.TerrainOrGround"); @@ -44,8 +44,16 @@ DEFINE_HOOK(4F1B00, CTileSetBrowserFrame_RecalcLayout, 7) ::GetClientRect(CTileSetBrowserFrameExt::hTabCtrl, &tabRect); - pThis->DialogBar.MoveWindow(2, 29, tabRect.right - tabRect.left - 6, 110, FALSE); - pThis->View.MoveWindow(2, 139, tabRect.right - tabRect.left - 6, tabRect.bottom - 145, FALSE); + if (ExtConfigs::VerticalLayout) + { + pThis->DialogBar.MoveWindow(2, 29, tabRect.right - tabRect.left - 6, 110, FALSE); + pThis->View.MoveWindow(2, 139, tabRect.right - tabRect.left - 6, tabRect.bottom - 145, FALSE); + } + else + { + pThis->DialogBar.MoveWindow(2, 29, tabRect.right - tabRect.left - 6, 49, FALSE); + pThis->View.MoveWindow(2, 78, tabRect.right - tabRect.left - 6, tabRect.bottom - 54, FALSE); + } SIZE sz{ tabRect.right,pThis->View.ScrollWidth }; pThis->View.SetScrollSizes(1, sz); diff --git a/FA2sp/UI/CTileBrowserFrame.DialogBar.rc b/FA2sp/UI/CTileBrowserFrame.DialogBar.rc index 441fd47..f088158 100644 --- a/FA2sp/UI/CTileBrowserFrame.DialogBar.rc +++ b/FA2sp/UI/CTileBrowserFrame.DialogBar.rc @@ -1,6 +1,20 @@ #include "Windows.h" -227 DIALOG 0, 0, 363, 78 +// Horizonal +227 DIALOG 0, 0, 480, 29 +STYLE DS_SETFONT | WS_CHILD +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +FONT 8, "MS Sans Serif" +{ + CONTROL "Terrain / Ground:", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 7, 32, 20 + CONTROL "", 1366, COMBOBOX, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 42, 7, 141, 169 + CONTROL "Overlay && Special:", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 204, 7, 32, 20 + CONTROL "", 1367, COMBOBOX, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 239, 7, 141, 169 + CONTROL "Tile Manager", 6102, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 390, 7, 65, 17 +} + +// Vertical +228 DIALOG 0, 0, 363, 78 STYLE DS_SETFONT | WS_CHILD LANGUAGE LANG_GERMAN, SUBLANG_GERMAN FONT 8, "MS Sans Serif" @@ -10,4 +24,4 @@ FONT 8, "MS Sans Serif" CONTROL "Overlay && Special:", 1369, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 29, 97, 10 CONTROL "", 1367, COMBOBOX, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 119, 28, 141, 163 CONTROL "Tile Manager", 6102, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 46, 65, 17 -} +} \ No newline at end of file From fc6c6b70e55b2b6f293f747fd7992a6d69d0a097 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Thu, 9 Jun 2022 11:18:24 +0800 Subject: [PATCH 13/14] Dirty fix: vanilla YR needs Preview and PreviewPack before Map --- .gitignore | 2 ++ FA2pp | 2 +- FA2sp/Ext/CIsoView/Body.cpp | 2 +- FA2sp/FA2sp.Constants.h | 10 +++++----- FA2sp/Logger.h | 9 +-------- FA2sp/Miscs/Exception.cpp | 21 ++++++++++++++------- FA2sp/Miscs/SaveMap.cpp | 29 ++++++++++++++++++++++------- 7 files changed, 46 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 1e857c6..11bcf3c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ !/Release/vxl_drawing_lib.lib /.vs/FA2sp/project-colors.json + +.vs/ diff --git a/FA2pp b/FA2pp index 41bb2a9..c9062b9 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit 41bb2a98814eb541e1879bda9170fb270cd1c1f1 +Subproject commit c9062b94ae5a92079ec80f190f7ca3f6e086ec65 diff --git a/FA2sp/Ext/CIsoView/Body.cpp b/FA2sp/Ext/CIsoView/Body.cpp index ea47b39..2c7d45d 100644 --- a/FA2sp/Ext/CIsoView/Body.cpp +++ b/FA2sp/Ext/CIsoView/Body.cpp @@ -32,7 +32,7 @@ void CIsoViewExt::ProgramStartupInit() void CIsoViewExt::AddTube(int EnterX, int EnterY, int ExitX, int ExitY) { - Logger::FormatLog("Generating tube from ({}, {}) to ({}, {})\n", EnterX, EnterY, ExitX, ExitY); + Logger::Raw("Generating tube from (%d, %d) to (%d, %d)\n", EnterX, EnterY, ExitX, ExitY); TubeData tube; memset(tube.Directions, 0xFF, sizeof(tube.Directions)); diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h index ca33039..1c464cf 100644 --- a/FA2sp/FA2sp.Constants.h +++ b/FA2sp/FA2sp.Constants.h @@ -5,8 +5,8 @@ #define PRODUCT_MAJOR 1 #define PRODUCT_MINOR 4 -#define PRODUCT_REVISION 0 -#define PRODUCT_HOTFIX 1 +#define PRODUCT_REVISION 1 +#define PRODUCT_HOTFIX 0 #define PRODUCT_STR __str(PRODUCT_MAJOR) "." __str(PRODUCT_MINOR) "." __str(PRODUCT_REVISION) "." __str(PRODUCT_HOTFIX) #define DISPLAY_STR PRODUCT_STR @@ -19,6 +19,6 @@ #define APPLY_INFO "Found Final Alert 2 version 1.02. Applying " VERSION_STRVER -constexpr char* MUTEX_HASH_VAL = "b8097bca8590a4f46c975ebb43503aab2243ce7f1c87f12f7984dbe1"; -constexpr char* MUTEX_INIT_ERROR_MSG = "The program has already launched! Some function may work not correctly. Do you still want to launch it?"; -constexpr char* MUTEX_INIT_ERROR_TIT = "FA2sp Init Checker"; +#define MUTEX_HASH_VAL "b8097bca8590a4f46c975ebb43503aab2243ce7f1c87f12f7984dbe1" +#define MUTEX_INIT_ERROR_MSG "The program has already launched! Some function may work not correctly. Do you still want to launch it?" +#define MUTEX_INIT_ERROR_TIT "FA2sp Init Checker" diff --git a/FA2sp/Logger.h b/FA2sp/Logger.h index 6a8dbfb..99baab3 100644 --- a/FA2sp/Logger.h +++ b/FA2sp/Logger.h @@ -1,9 +1,7 @@ #pragma once -#include +#include #include - -#include #include class Logger { @@ -21,11 +19,6 @@ class Logger { 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 2926416..2a98319 100644 --- a/FA2sp/Miscs/Exception.cpp +++ b/FA2sp/Miscs/Exception.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include LONG CALLBACK Exception::ExceptionFilter(PEXCEPTION_POINTERS const pExs) @@ -121,15 +122,21 @@ LONG CALLBACK Exception::ExceptionFilter(PEXCEPTION_POINTERS const pExs) break; } - Logger::Raw("Trying to save current map.\n"); - ppmfc::CString fcrash_backup = CFinalSunApp::ExePath(); - fcrash_backup += "\\fcrash_backup.map"; + if (CMapData::Instance->MapWidthPlusHeight) + { + Logger::Raw("Trying to save current map.\n"); + ppmfc::CString fcrash_backup = CFinalSunApp::ExePath(); + fcrash_backup += "\\fcrash_backup.map"; - SaveMapExt::IsAutoSaving = true; - CFinalSunDlg::Instance->SaveMap(fcrash_backup); - SaveMapExt::IsAutoSaving = false; + SaveMapExt::IsAutoSaving = true; + CFinalSunDlg::Instance->SaveMap(fcrash_backup); + SaveMapExt::IsAutoSaving = false; - MessageBox(CFinalSunDlg::Instance->m_hWnd, "Current MapData has been saved as fcrash_backup.map.", "Fatal Error!", MB_OK | MB_ICONINFORMATION); + MessageBox(CFinalSunDlg::Instance->m_hWnd, "Current MapData has been saved as fcrash_backup.map.", "Fatal Error!", MB_OK | MB_ICONINFORMATION); + } + else + MessageBox(CFinalSunDlg::Instance->m_hWnd, "Seems there's no map had been loaded.", "Fatal Error!", MB_OK | MB_ICONINFORMATION); + CLoading::Instance->Release(); CINI::Rules->Release(); diff --git a/FA2sp/Miscs/SaveMap.cpp b/FA2sp/Miscs/SaveMap.cpp index 68520bb..af5e86c 100644 --- a/FA2sp/Miscs/SaveMap.cpp +++ b/FA2sp/Miscs/SaveMap.cpp @@ -103,8 +103,8 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) filepath = filepath.Mid(0, nExtIndex) + ".map"; } - Logger::FormatLog("SaveMap : Trying to save map to {}.\n", filepath); - + Logger::Raw("SaveMap : Trying to save map to %s.\n", filepath); + std::ofstream fout; fout.open(filepath, std::ios::out | std::ios::trunc); @@ -119,6 +119,20 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) "; Get the lastest dll at https://github.com/secsome/FA2sp\n" "; Current version : " << PRODUCT_STR << "\n\n"; + // Dirty fix: vanilla YR needs Preview and PreviewPack before Map + // So we just put them at first + + if (const auto pSection = pINI->GetSection("Preview")) + { + for (const auto& pair : pSection->GetEntities()) + fout << pair.first << "=" << pair.second << "\n"; + } + if (const auto pSection = pINI->GetSection("PreviewPack")) + { + for (const auto& pair : pSection->GetEntities()) + fout << pair.first << "=" << pair.second << "\n"; + } + for (auto& section : pINI->Dict) { fout << "[" << section.first << "]\n"; @@ -130,13 +144,14 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) fout.flush(); fout.close(); - Logger::FormatLog("SaveMap : Successfully saved {} sections.\n", pINI->Dict.size()); + Logger::Raw("SaveMap : Successfully saved %u sections.\n", pINI->Dict.size()); } else { - 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); + ppmfc::CString buffer; + buffer.Format("Failed to create file %s.\n", filepath); + Logger::Put(buffer); + ::MessageBox(NULL, buffer, "Error", MB_OK | MB_ICONERROR); } return 0x42A859; @@ -245,7 +260,7 @@ void SaveMapExt::RemoveEarlySaves() if (count <= 0) return; - auto& itr = m.begin(); + auto itr = m.begin(); while (count != 0) { buffer.Format("%s\\AutoSaves\\%s\\%s", CFinalSunApp::ExePath(), mapName, itr->second); From 9bce098a22577daf8caa5e57f6ac0b8d6ebdeec8 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Sat, 18 Jun 2022 12:06:18 +0800 Subject: [PATCH 14/14] Update documents --- CHANGELOG.md | 395 ++++++++-------- DOCUMENT.md | 1241 +++++++++++++++++++++++++------------------------ UNEXPLORED.md | 4 +- 3 files changed, 827 insertions(+), 813 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee1b5c..852b1f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,196 +1,199 @@ -
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP CHANGELOG //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-======================= Changes (2022-02-11 RELEASE 1.4.0.1) ==============================================================================================
-*) Fixed the bug that Powerups are not being rendered in several cases
-*) Fixed the bug that MoneyCounter is not working properly
-
-======================= Changes (2022-02-10 RELEASE 1.4.0) ==============================================================================================
-+) Now you can create a map with size up to 255*255
-+) New ExtConfig: RecentFileLimit = INTEGER, defaults to 6, should be a integer between 4 and 9 
-*) Optimized mouse attached building drawing
-+) Reimplemented tube generation
-+) Support for multi-selection, the detailed usage can be looked up in the document below
-+) New ExtConfig : MultiSelectionColor = COLORREF, back color of selected tiles
-+) Theater order in dropdown is now customizable and theaters can be disabled
-+) New ExtConfig : Waypoint.Text.ExtraOffset = POINT, WP text offsets
-+) New ExtConfig : SaveMap.DefaultPreviewOptionMP = INTEGER, SaveMap.DefaultPreviewOptionSP = INTEGER, read the doc below
-*) ExtConfig : SaveMap tag has been removed, it will be forced to enable now
-
-======================= 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
-+) Now you can specify the display name of theaters
-+) Support for ExtraMixes, will be read before any other mixes
-+) Support for OverlayDisplayLimit, the frame after this number won't be displayed in the TilesetBrowserView, up to 60
-*) ExtConfig : Stringtable tag has been removed, it will be forced to enable now
-*) Minor fixes
-
-======================= Changes (2021-11-12 RELEASE 1.2.1) ==============================================================================================
-*) Remove a hook that might lead to some problem
-*) Adjust some rc file
-*) Fixed BrowserRedraw.SafeHouses not working correctly
-*) Now property brush handles mouse move too
-
-======================= Changes (2021-11-04 RELEASE 1.2.0) ==============================================================================================
-+) New ObjectBrowser items: Property brushes (FALanguage has been updated)
-
-======================= Changes (2021-11-02 RELEASE 1.1.3) ==============================================================================================
-*) Fixed the bug that EVA(md).ini cannot be loaded
-*) Now ScriptsRA2 will correctly read inconsistent keys
-+) New ExtConfig: BrowserRedraw.SafeHouses, enable it so that the houses being displayed in ObjectBrowserView will be rearranged correctly but won't update until you load the map again
-
-======================= Changes (2021-10-16 RELEASE 1.1.2) ==============================================================================================
-*) Fixed the bug that FA2sp crashes while trying to read/write file on some systems
-
-======================= Changes (2021-10-12 RELEASE 1.1.1) ==============================================================================================
-*) Minor bugfixes
-*) Now FA2sp will apply Visual Style depending on your system instead of keeping them look like Windows95 style
-
-======================= Changes (2021-10-03 RELEASE 1.1.0) ==============================================================================================
-+) Trigger sort, which will provide you some handy in trigger classification
-+) Now you can directly edit [Ranking] in SingleplayerSettings
-+) Now you can edit all stuff of [Lighting]
-+) New ExtConfig: VerticalLayout = BOOLEAN, enable it so that FA2sp will make the bottom view go to the right side
-*) Now you can delete a trigger and its celltags at the same time
-*) Now you can custom script param typelist
-
-======================= Changes (2021-09-28 RELEASE 1.0.7) ==============================================================================================
-*) Changed the layout of CRightView::CTileSetBrowserFrame from [0, 1] to [1, 0], it's vertical now
-*) Now FA2 will not only read default palettes from cache.mix but read them like the normal files
-*) Fix the remaining autosave bug cannot removing earlier maps
-*) Fix the bug that Multiplayer map cannot save PreviewPack correctly
-
-======================= Changes (2021-09-23 RELEASE 1.0.6) ==============================================================================================
-*) Fix the autosave bug caused by Loritas
-*) Fix the problem that FA2 crashes after kill focus
-*) Fix the problem that Allie Editor not being applied to the data automatically
-*) Fix the bug that resize map not take basenodes and smudges into consideration
-
-==  Known Bug : SaveMap = Yes will sometimes crashes the PreviewPack  ==
-== consider to save it again with origin FA2 after finishing your map ==
-
-======================= Changes (2021-08-25 RELEASE 1.0.5) ==============================================================================================
-+) Enhanced SaveMap logic by Loritas
-+) New ExtConfig: SaveMap.OnlySaveMAP, enable it so that FA2 will only save map with .map file extension
-*) Now VXL drawing lib no longer requires DirectX 9 anymore
-*) Reimplemented Building & Basenode outline rendering, also Celltags, Waypoints and Tubes rendering
-*) Significantly reduce the lag of Building & Celltag & Waypoint & Tube rendering
-
-======================= Changes (2021-08-20 RELEASE 1.0.4) ==============================================================================================
-+) Now you can copy AITriggers
-+) New ExtConfig: SaveMap = BOOLEAN, enable it so that we will replace FA2's vanilla slow saving function
-    +) New ExtConfig: SaveMap.AutoSave = BOOLEAN, enable it so that we will enable FA2 to save map automatically after one save
-        +) New ExtConfig: SaveMap.AutoSave.Interval = INTEGER, set the interval between two auto saving, need to be greater than or equal to than 30
-        +) New ExtConfig: SaveMap.AutoSave.MaxCount = INTEGER, how many auto saving files can FA2 keep, set to -1 will disable the auto cleanning up
-
-======================= Changes (2021-08-19 RELEASE 1.0.3) ==============================================================================================
-*) Now we read file without extracting them to the game folder, this might fix some reading bugs
-*) The ObjectBrowserView will show player locations again in Multiplayer maps (with Basic -> MultiplayerOnly=yes)
--) Easy mode is disabled, and it won't be displayed in menu either anymore
-
-======================= Changes (2021-08-18 RELEASE 1.0.2) ==============================================================================================
-+) Now Allie Editor receive double click command for listboxes
-*) Fixed the bug that TransportWP was not correctly copied
-*) ScriptTypes and VXLDrawing will no longer cause memory leak
-
-======================= Changes (2021-08-14 RELEASE 1.0.1) ==============================================================================================
-*) Now Unit&Aircraft&Infantry dialog will show up at the center of the screen
-*) Fixed the bug that delete script do not delete the key in [ScriptTypes]
-*) Fixed the bug that copy team do not really clone "Droppod" key
-
-======================= Changes (2021-08-13 RELEASE 1.0.0) ==============================================================================================
-*) Minor adjustments on ObjectBrowserControl
-+) Replace the exception handler, now you can save a dmp file when FA2 crashes
-*) Fix the bug that some building cannot be drawn correctly
-
-======================= Changes (2021-08-11) ==============================================================================================
-*) VXL Units' TurretOffset and Buildings' VXL turrets should be drawn at correct place
-+) New ignore keys: IgnoreIdleAnim and IgnoreActiveAnimX
-+) New drawing config: VehicleVoxelBarrelsRA2
-*) IgnoreSuperAnimX will be read correctly now
-+) Import AllieEditor for CHouses from FA2Copy
-*) Adjustments on several dialogs
-*) Now you can run multiple FA2sp at the same time
-
-======================= Changes (2021-08-07B) ==============================================================================================
-*) Fixed the bug for PowerUpLocs
-
-======================= Changes (2021-08-07) ==============================================================================================
-*) The drawing function is fixed for several items
-*) The Isoview now will be redrawn automatically after layers are set
-+) New tags in falanguage so you can translate menu items
-
-======================= Changes (2021-08-06) ==============================================================================================
-+) New param code: 30 for float, this param code can be used for action 71 & 72
-+) New menu checkboxes: Layers, you can hide Strutures, Infantries and so on through this system
-*) The drawing function for Structures, Infantries, Vehicles, Terrains, Smudges and Aircrafts have been completely rewritten
-
-======================= Changes (2021-08-02) ==============================================================================================
-*) Fixed fatal error on STDHelper::SplitString caused bugs on Clone Actions/Events and ExtConfig::SortByTriggerName
-
-======================= Changes (2021-07-31) ==============================================================================================
-*) Fixed wrongly painted infantry subcell place
-*) Undo/Redo limit is now controlled by ExtConfig: UndoRedoLimit = INTEGER, defaults to 16
-+) New ExtConfig: UseRGBHouseColor
-+) Now you can copy single action/event in trigger editor
-+) Now you can copy taskforce and its member
-
-======================= Changes (2021-07-19) ==============================================================================================
-*) Undo/Redo extended to 2147483647 steps, be careful about your memory
-*) Fixed wrongly painted Remap color for technos using UNITXXX.PAL
-*) Fixed buildings with shp turret can only been painted to NORTH
-*) Refactored ScriptTypes window, now you can use MoveUp, MoveDown, InsertMode and Clones
-
-======================= Changes (2021-06-11) ==============================================================================================
-+) New ExtConfig: ExtWaypoints = BOOLEAN, enable it to support no limitation of waypoints, defaults to false (Phobos required)
-+) New ExtConfig: Waypoint.Background = BOOLEAN, enable it to draw a background rectangle for waypoints, defaults to false
-    +) New ExtConfig: Waypoint.Background.Color = COLORREF, custom the waypoint background color
-+) New ExtConfig: Waypoint.Color = COLORREF, custom the waypoint text color
-+) New ExtConfig: CopySelectionBound.Color = COLORREF, custom the copy selection bound color, defaults to 255,0,0
-+) New ExtConfig: CursorSelectionBound.Color = COLORREF, same as the above one, defaults to 60,160,60
-+) New ExtConfig: CursorSelectionBound.HeightIndicatorColor = COLORREF, same as the above one, defaults to 60,60,60
-
-======================= Changes (2021-05-07) ==============================================================================================
-+) New ExtConfig: SortByTriggerName = BOOLEAN, enable it so FA2 will sort the triggers dropdown and sort them by their name instead of ID
-+) New ExtConfig: AdjustDropdownWidth = BOOLEAN, enable it so FA2 will adjust the param dropdown width automatically
-    +) New ExtConfig: AdjustDropdownWidth.Factor = INTEGER, determines how long is a single char takes, defaults to 8
-    +) New ExtConfig: AdjustDropdownWidth.Max = INTEGER, determines the max length of the combobox, defaults to 360
--) Remove ExtConfig: OverlayFilter, enable it always.
-
-======================= Changes (2021-03-22) ==============================================================================================
-*) Now you can force to use Name first instead of UIName in the ObjectBrowserControl under [ForceName] just like [IgnoreRA2]
-*) More accelerators and fixes from E1Elite
-
-======================= Changes (2021-03-05) ==============================================================================================
-*) Now the game directory FA2 reads would use the path in FinalAlert.ini instead of the one in registry
-*) Coordinates are now shown as X / Y - H
-*) Undo/Redo extended to 127 steps (was 15 steps)
-*) ObjectBrowserControl refactored
-    +) Not only Buildings, but Infantrys, Aircrafts and Vehicles now have been classified into sides
-    +) Not only the original hardcoded overlays but also all overlays having Wall=yes will be auto connected
-*) Now infantry's facing will be correctly shown
-*) Overlay which has the index bigger than 255 will be ignored
-*) Teamtypes and Scripttypes are now able to use Clone just as Triggers
-*) House colors will be correctly drawn instead of using a hardcoded set of colors (for most, yellow)
-*) For most dialogs, the content will only be updated while lose focus. (Used to be content changed, and lead to famous stupid lag teamtype) 
-*) Several dialogs UI Redrawn
-+) Support Ares' += and #include functions (not recommended to use, still has several bugs)
-+) Support Ares' stringtableXX.csf
-+) ScriptTypes now use a different set of params and can be extended
-+) Mix Extension and INI Filenames can be customed
-+) Ctrl+S, Ctrl+O, Ctrl+N and Ctrl+Shift+S are now supported
-+) Easy encrypted mix files will be correctly read
-+) Tile manager, can be helpful while you are having lots of tiles
-
\ No newline at end of file +# FINALALERT2 - SP CHANGELOG + +## RELEASE 1.4.1 (2022-06-18) +- *This is a **cumulative** update* +- Reimplemented CTeamTypes message handler +- Support for lower case of theater names +- Fix a possible memory leak +- Disable `MultiSelection` +- Optimizations on UI +- Put `Preview` and `PreviewPack` at the beginning of the map file if they exist +- Update the changelog file and document file, now really using **Markdown** + +## RELEASE 1.4.0.1 (2022-02-11) +- Fixed the bug that Powerups are not being rendered in several cases +- Fixed the bug that MoneyCounter is not working properly + +## RELEASE 1.4.0 (2022-02-10) +- Now you can create a map with size up to $255$ * $255$ +- New ***ExtConfig*** : `RecentFileLimit` = **INTEGER**, defaults to $6$, should be a integer between $4$ and $9$ +- Optimized mouse attached building drawing +- Reimplemented tube generation +- Support for multi-selection, the detailed usage can be looked up in the document below +- New ***ExtConfig*** : `MultiSelectionColor` = COLORREF, back color of selected tiles +- Theater order in dropdown is now customizable and theaters can be disabled +- New ***ExtConfig*** : `Waypoint.Text.ExtraOffset` = POINT, WP text offsets +- New ***ExtConfig*** : `SaveMap.DefaultPreviewOptionMP` = **INTEGER**, `SaveMap.DefaultPreviewOptionSP` = **INTEGER**, read the doc below +- ***ExtConfig*** : `SaveMap` tag has been removed, it will be forced to enable now + +## RELEASE 1.3.0 (2021-12-31) +- The project now compiles under **v143** with `/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 + +## RELEASE 1.2.2 (2021-11-20) +- Now you can add more ramps to be auto generated in FA2 by setting `[THEATERInfo]` in `fadata.ini` +- Now you can specify the **display** name of theaters +- Support for ExtraMixes, will be read **before any other** mixes +- Support for OverlayDisplayLimit, the frame after this number won't be displayed in the TilesetBrowserView, up to 60 +- ***ExtConfig*** : `Stringtable` tag has been **removed**, it will be **forced to enable** now +- Minor fixes + +## RELEASE 1.2.1 (2021-11-12) +- Remove a hook that might lead to some problem +- Adjust some rc file +- Fixed `BrowserRedraw.SafeHouses` not working correctly +- Now property brush handles mouse move too + +## RELEASE 1.2.0 (2021-11-04) +- New ObjectBrowser items: **Property brushes** (`FALanguage` has been updated) + +## RELEASE 1.1.3 (2021-11-02) +- Fixed the bug that `EVA(md).ini` cannot be loaded +- Now ScriptsRA2 will correctly read inconsistent keys +- New ***ExtConfig*** : `BrowserRedraw.SafeHouses`, enable it so that the houses being displayed in ObjectBrowserView will be rearranged correctly but won't update until you load the map again + +## RELEASE 1.1.2 (2021-10-16) +*) Fixed the bug that FA2sp crashes while trying to read/write file on some PCs + +## RELEASE 1.1.1 (2021-10-12) +- Minor bugfixes +- Now FA2sp will apply Visual Style depending on your system **instead of** keeping them look like **Windows95** style + +## RELEASE 1.1.0 (2021-10-03) +- Trigger sort, which will provide you some handy in trigger classification +- Now you can directly edit `[Ranking]` in SingleplayerSettings +- Now you can edit all stuff of `[Lighting]` +- New ***ExtConfig*** : `VerticalLayout` = **BOOLEAN**, enable it so that FA2sp will make the bottom view go to the right side +- Now you can delete a trigger and its celltags at the same time +- Now you can customize script param typelist + +## RELEASE 1.0.7 (2021-09-28) +- Changed the layout of CRightView::CTileSetBrowserFrame from [0, 1] to [1, 0], it's vertical now +- Now FA2 will not only read default palettes from cache.mix but read them like the normal files +- Fix the remaining autosave bug cannot removing earlier maps +- Fix the bug that Multiplayer map cannot save PreviewPack correctly + +## RELEASE 1.0.6 (2021-09-23) +- Fix the autosave bug caused by Loritas +- Fix the problem that FA2 crashes after kill focus +- Fix the problem that Allie Editor not being applied to the data automatically +- Fix the bug that resize map not take basenodes and smudges into consideration + +## RELEASE 1.0.5 (2021-08-25) +- Enhanced SaveMap logic by Loritas +- New ***ExtConfig*** : `SaveMap.OnlySaveMAP`, enable it so that FA2 will only save map with .map file extension +- Now VXL drawing lib no longer requires DirectX 9 anymore +- Reimplemented Building & Basenode outline rendering, also Celltags, Waypoints and Tubes rendering +- **Significantly** reduce the lag of Building & Celltag & Waypoint & Tube rendering + +## RELEASE 1.0.4 (2021-08-20) +- Now you can copy *AITriggers* +- New ***ExtConfig*** : `SaveMap` = **BOOLEAN**, enable it so that we will replace FA2's vanilla slow saving function + - New ***ExtConfig*** : `SaveMap.AutoSave` = **BOOLEAN**, enable it so that we will enable FA2 to save map automatically after one save + - New ***ExtConfig*** : `SaveMap.AutoSave.Interval` = **INTEGER**, set the interval between two auto saving, need to be greater than or equal to than `30` + - New ***ExtConfig*** : `SaveMap.AutoSave.MaxCount` = **INTEGER**, how many auto saving files can FA2 keep, set to `-1` will disable the auto cleanning up + +## RELEASE 1.0.3 (2021-08-19) +- Now we read file without extracting them to the game folder, this might fix some reading bugs +- The ObjectBrowserView will show player locations again in Multiplayer maps (with Basic -> MultiplayerOnly=yes) +- **Easy mode** is disabled, and it won't be displayed in menu either anymore + +## RELEASE 1.0.2 (2021-08-18) +- Now Allie Editor answer double click command for listboxes +- Fixed the bug that TransportWP was not correctly copied +- ScriptTypes and VXLDrawing will no longer cause memory leak + +## RELEASE 1.0.1 (2021-08-14) +- Now `Unit/Aircraft/Infantry` dialog will show up at the center of the screen +- Fixed the bug that delete script do not delete the key in `[ScriptTypes]` +- Fixed the bug that copy team do not really clone `Droppod` key + +## RELEASE 1.0.0 (2021-08-13) +- Minor adjustments on ObjectBrowserControl +- Replace the exception handler, now you can save a dmp file when FA2 crashes +- Fix the bug that some building cannot be drawn correctly + +## Build20210811 (2021-08-11) +- VXL Units' TurretOffset and Buildings' VXL turrets should be drawn at correct place +- New ignore keys: `IgnoreIdleAnim` and `IgnoreActiveAnimX` +- New drawing config: `VehicleVoxelBarrelsRA2` +- `IgnoreSuperAnimX` will be read correctly now +- Import AllieEditor for CHouses from FA2Copy +- Adjustments on several dialogs +- Now you can run *multiple* FA2sp at the same time + +## Build20210807B (2021-08-07) +- Fixed the bug for PowerUpLocs + +## Build20210807 (2021-08-07) +- The drawing function is fixed for several items +- The Isoview now will be redrawn automatically after layers are set +- New tags in falanguage so you can translate menu items + +## Build20210806 (2021-08-06) +- New param code: $30$ for **float**, this param code can be used for action $71$ & $72$ +- New menu checkboxes: **Layers**, you can hide Strutures, Infantries and so on through this system +- The drawing function for Structures, Infantries, Vehicles, Terrains, Smudges and Aircrafts have been **completely rewritten** + +## Build20210802 (2021-08-02) +- Fixed fatal error on STDHelper::SplitString caused bugs on Clone Actions/Events and ***ExtConfig***::`SortByTriggerName` + +## Build20210731 (2021-07-31) +- Fixed wrongly painted infantry subcell place +- Undo/Redo limit is now controlled by ***ExtConfig*** : `UndoRedoLimit` = **INTEGER**, defaults to $16$ +- New ***ExtConfig*** : `UseRGBHouseColor` +- Now you can copy single action/event in trigger editor +- Now you can copy taskforce and its member + +## Build20210719 (2021-07-19) +- Undo/Redo extended to $2147483647$ steps, be careful about your memory +- Fixed wrongly painted Remap color for technos using `UNITXXX.PAL` +- Fixed buildings with shp turret can only been painted to NORTH +- Refactored ScriptTypes window, now you can use `MoveUp`, `MoveDown`, `InsertMode` and `Clones` + +## Build20210611 (2021-06-11) +- New ***ExtConfig*** : `ExtWaypoints` = **BOOLEAN**, enable it to support no limitation of waypoints, defaults to false (Phobos required) +- New ***ExtConfig*** : `Waypoint.Background` = **BOOLEAN**, enable it to draw a background rectangle for waypoints, defaults to false + - New ***ExtConfig*** : `Waypoint.Background.Color` = **COLORREF**, custom the waypoint background color +- New ***ExtConfig*** : `Waypoint.Color` = **COLORREF**, custom the waypoint text color +- New ***ExtConfig*** : `CopySelectionBound.Color` = **COLORREF**, custom the copy selection bound color, defaults to $255,0,0$ +- New ***ExtConfig*** : `CursorSelectionBound.Color` = **COLORREF**, same as the above one, defaults to $60,160,60$ +- New ***ExtConfig*** : `CursorSelectionBound.HeightIndicatorColor` = **COLORREF**, same as the above one, defaults to $60,60,60$ + +## Build20210507 (2021-05-07) +- New ***ExtConfig*** : `SortByTriggerName` = **BOOLEAN**, enable it so FA2 will sort the triggers dropdown and sort them by their name instead of ID +- New ***ExtConfig*** : `AdjustDropdownWidth` = **BOOLEAN**, enable it so FA2 will adjust the param dropdown width automatically + - New ***ExtConfig*** : `AdjustDropdownWidth.Factor` = **INTEGER**, determines how long is a single char takes, defaults to $8$ + - New ***ExtConfig*** : `AdjustDropdownWidth.Max` = **INTEGER**, determines the max length of the combobox, defaults to $360$ +- Remove ***ExtConfig*** : `OverlayFilter`, enable it always. + +## Build20210322 (2021-03-22) +- Now you can force to use Name first instead of UIName in the ObjectBrowserControl under `[ForceName]` just like `[IgnoreRA2]` +- More accelerators and fixes from E1Elite + +## Build20210305 (2021-03-05) +- Now the game directory FA2 reads would use the path in FinalAlert.ini instead of the one in registry +- Coordinates are now shown as X / Y - H +- Undo/Redo extended to $127$ steps (was $15$ steps) +- ObjectBrowserControl refactored + - Not only Buildings, but Infantrys, Aircrafts and Vehicles now have been classified into sides + - Not only the original hardcoded overlays but also all overlays having `Wall=yes` will be auto connected +- Now infantry's facing will be correctly shown +- Overlay which has the index bigger than $255$ will be ignored +- Teamtypes and Scripttypes are now able to use Clone just as Triggers +- House colors will be correctly drawn instead of using a hardcoded set of colors (for most, yellow) +- For most dialogs, the content will only be updated while lose focus. (Used to be content changed, and lead to famous stupid lag teamtype) +- Several dialogs UI Redrawn +- Support Ares' += and #include functions (not recommended to use, still has several bugs) +- Support Ares' stringtableXX.csf +- ScriptTypes now use a different set of params and can be extended +- Mix Extension and INI Filenames can be customed +- `Ctrl+S`, `Ctrl+O`, `Ctrl+N` and `Ctrl+Shift+S` are now supported +- Easy encrypted mix files will be correctly read +- Tile manager, can be helpful while you are having lots of tiles \ No newline at end of file diff --git a/DOCUMENT.md b/DOCUMENT.md index 068e3b1..e867889 100644 --- a/DOCUMENT.md +++ b/DOCUMENT.md @@ -1,628 +1,639 @@ -
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP  DOCUMENT //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# FINALALERT2 - SP  DOCUMENT
 
-- GETTING START
-Just like Ares, FA2sp needs Syringe to work properly, so you can just take Ares as a reference.
+## GETTING START
+- Just like Ares, FA2sp needs Syringe to work properly, so you can just take Ares as a reference.
+- What you need to know is that FA2sp requires Vanilla FinalAlert 2 1.02, any modified version may lead to unexpected errors!
+- Before you launch it for the first time, write the ini files below properly, especially for essential ones (marked by **x**).
+- If you still have any problem about it or something wrong occured while using it, please contact me directly or mail me at 3179369262@qq.com.
+- Now you can also join Discord server https://discord.gg/k4SVuMm, and found `map-editor-patches` under `DEDICATED PROJECTS`.
+- For now, I cannot ensure the stability of it, so save your maps frequently before heavy loss! XD
 
-What you need to know is that FA2sp requires Vanilla FinalAlert 2 1.02, any modified version may lead to unexpected errors!
-Before you launch it for the first time, write the ini files below properly, especially for essential ones (marked by **)
+~~The multiple selection function is now available. Press Ctrl key to select tiles and press Ctrl+Shift key to deselect them. Ctrl+D can clear all selected tiles.
+Now this feature supports RaiseSingleTile/LowerSingleTile (though they are not "Single" anymore) and calucate selected area ore value.
+NOTICE THAT UNDOREDO AND COPYPASTE HASN'T BEEN SUPPORTED YET!~~
 
-If you still have any problem about it or something wrong occured while using it, please contact me directly or mail me at 3179369262@qq.com
-For now, I cannot ensure the stability of it, so save your maps frequently before heavy loss! XD
+## BASIC TYPES
+- **INTEGER** 
+  - Ranges in $[-2147483648,2147483647]$
+    - $-1$ $|$ $2$ $|$ $114514$
+- **POINT** 
+  - **INTEGER**, **INTEGER**
+    - $1, 2$ $|$ $114514, 1919810$
+- **BOOLEAN** 
+  - $Yes/No$, $True/False$, $1/0$
+    - $Yes$ $|$ $true$ $|$ $1$
+- **COLORREF** 
+  - R,G,B each of them ranges in $[0,255]$
+    - $255, 255 ,0$ $|$ $0, 0, 60$
 
-The multiple selection function is now available. Press Ctrl key to select tiles and press Ctrl+Shift key to deselect them. Ctrl+D can clear all selected tiles.
-Now this feature supports RaiseSingleTile/LowerSingleTile (though they are not "Single" anymore) and calucate selected area ore value.
-NOTICE THAT UNDOREDO AND COPYPASTE HASN'T BEEN SUPPORTED YET!
+## BASIC TYPES
+- FAData.ini
+    - [ExtConfigs]
+        - `BrowserRedraw` = **BOOLEAN** ; Enable refactored ObjectBrowserView
+          - `BrowserRedraw.GuessMode` = **$0/1$** ; Determines how FA2sp guess Technos' side, $0$(Default) to Prerequisite, $1$ to use first Owner 
+          - `BrowserRedraw.CleanUp` = **BOOLEAN** ; Sides classification will clear empty items
+          - `BrowserRedraw.SafeHouses` = **BOOLEAN** ; Determines whether FA2sp will rearrangement the houses or not
+        - `AllowIncludes` = **BOOLEAN** ; Read #include section for other ini (NOT RECOMMENDED) 
+        - `AllowPlusEqual` = **BOOLEAN** ; Read += (NOT RECOMMENDED)
+        - `TutorialTexts.Fix` = **BOOLEAN** ; Replace original process while loading texts to comboboxes
+        - `TutorialTexts.Hide` = **BOOLEAN** ; Reduce lags, for texts in combobox might be useless
+        - `SortByTriggerName` = **BOOLEAN** ; Enable this feature so we can sort the triggers by their names
+        - `AdjustDropdownWidth` = **BOOLEAN** ; Enable it so FA2 will adjust the param dropdown width automatically
+            - `AdjustDropdownWidth.Factor` = **INTEGER** ; Determines how long is a single char takes, defaults to $8$
+            - `AdjustDropdownWidth.Max` = **INTEGER** ; Determines the max length of the combobox, defaults to 360
+        - `CopySelectionBound.Color` = **COLORREF** ; Determines the color of the selection boundary while copying, defaults to $255,0,0$
+        - `CursorSelectionBound.Color` = **COLORREF** ; Determines the color of the boundary for current cell, defaults to $60,160,60$
+        - `HeightIndicatorColor.Color` = **COLORREF** ; Determines the color of the height indicator for current cell, defaults to $60,60,60$
+        - `Waypoint.Color` = **COLORREF** ; Determines the color of waypoint texts, default to $0,0,255$
+        - `Waypoint.Background` = **BOOLEAN** ; Determines whether draw a rectangle background for waypoints or not. defaults to false
+        - `Waypoint.Background.Color` = **COLORREF** ; Determines the color of the waypoint background, defaults to $255,255,255$
+        - `Waypoint.Text.ExtraOffset` = **POINT** ; Additional X and Y-axis offset for waypoint text, defaults to $0,0$
+        - `ExtWaypoints` = **BOOLEAN** ; Determines if FA2sp supports unlimited count of waypoints, defaults to **false** (Phobos required)
+        - `UndoRedoLimit` = **INTEGER** ; Determines the maximun step of undo/redo, defaults to $16$
+        - `UseRGBHouseColor` = **BOOLEAN** ; Determines if House colors are recognized as RGB color instead of HSV, defaults to **false** 
+        - `SaveMap.AutoSave` = **BOOLEAN** ; Determines if FA2 will save map automatically
+            - `SaveMap.AutoSave.Interval` = **INTEGER** ; Should be greater than or equal to $30$, defaults to $300$, determines how many seconds should we wait during the two auto saving
+            - `SaveMap.AutoSave.MaxCount` = **INTEGER** ; 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
+        - `SaveMap.DefaultPreviewOptionMP` = **INTEGER** ; Default radio option button for preview generation when saving multiplayer maps. 
+          - $0$ = Always generate new preview
+          - $1$ = Do no generate new preview
+          - $2$ = Always generate hidden preview
+          - defaults to $0$.
+        - `SaveMap.DefaultPreviewOptionSP` = **INTEGER** ; Same as the **MP** one but for **SP** maps, defaults to $1$.
+        - `VerticalLayout` = **BOOLEAN** ; Determines if FA2 will make the bottom view go to the right side
+        - `RecentFileLimit` = **INTEGER** ; How many recent files should I keep? ranges from $4$ to $9$
+        - `MultiSelectionColor` = **COLORREF** ; Determines the back color of selected tiles
+    - **`[Sides]`** (**x** means this item is **essensial**, fa2sp need this section to work properly)
+        - Contains a list of sides registered in rules
+        ```ini
+        [Sides]
+        0=Allied
+        1=Soviet
+        2=Yuri
+        3=Neutral
+        4=Special
+        ```
+    - `[Theaters]`
+        - Contains a list of theater names, only the existing 6 names are valid. If not listed then all default 6 theaters are used and displayed in order below:
+        ```ini
+        [Theaters]
+        0=TEMPERATE
+        1=SNOW
+        2=URBAN
+        3=NEWURBAN
+        4=LUNAR
+        5=DESERT
+        ```
+    - `[ForceName]`
+        - xxx = Objecttype
+        - Contains a list of objecttypes forced to use Name instead of UIName
+        ```ini
+        [ForceName]
+        0=E1
+        ```
+    - `[ForceSides]`
+        - Technotype = SideIndex
+        - Contains a list of technotypes whose side cannot be correctly guessed
+        ```ini
+        [ForceSides]
+        ENGINEER=0
+        SENGINEER=1
+        YENGINEER=2
+        ; A LOT OF WESTWOOD CIVILIAN VEHICLES WITH PREREQUISITE 
+        ; [NAWEAP] WILL BE GUESSED INTO SOVIETS, FIX THEM MANUALLY
+        ```
+    - `[ObjectBrowser.SmudgeTypes]` and `[ObjectBrowser.TerrainTypes]`
+        - Contained string = translation key in falanguage
+        ```ini
+        [ObjectBrowser.SmudgeTypes]
+        CRATER=SmudgeCraterObList
+        BURNT=SmudgeBurntObList
+        
+        [ObjectBrowser.TerrainTypes]
+        TREE=TreesObList
+        TRFF=TrafficLightsObList
+        SIGN=SignsObList
+        LT=LightPostsObList
+        ```
+    - `[TileManagerDataXXX]` *TEM, SNO, URB, UBN, LUN, DES*
+        - DisplayName = Regex expression
+        ```ini
+        [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
+        ```
+    - `[XXXInfo]` *TemperateInfo, SnowInfo, UrbanInfo, NewUrbanInfo, DesertInfo, LunarInfo*
+        - `Ramps=Tilesets`
+        - `Morphables=Tilesets`
+          - All tilesets here should have `Morphable=true`. You don't need to write RampBase here, only other ramps need to be added here. The Ramps and Morphables should have the same length of tilesets, and those tilesets should be one-to-one correspondence. The old NewUrbanInfo's key `Ramps2` and `Morphable2` had been abandoned, so you need to add them manually.
+        ```ini
+        [NewUrbanInfo]
+        Morphables=114,123
+        Ramps=117,193 
+        ```
+    - `[ExtraMixes]`
+        - `Filename = ReadFromMapEditorPathInsteadOfGamePath`
+        ```ini
+        [ExtraConfigs]
+        buxu\123.mix=Yes
+        money.txt=No
+        
+        ; This means FA2 takes {FA2PATH\buxu\123.mix} into consider, and if not found the file,
+        ; it will search the file in {GAMEPATH\money.txt}, if this one still doesn't have the file,
+        ; FA2 will try to find the file as it used to be.
+        ```
+    - `[OverlayDisplayLimit]`
+        - `OverlayIndex = DisplayLimit` *DisplayLimit should be less than or equals to $60$*
+        ```ini
+        [OverlayDisplayLimit]
+        243=48
+        ; This means FA2 won't display overlay 243's frames after 48
+        ```
+    - `[Filenames]`
+        - `EVA = FILENAME`
+        - `EVAYR = FILENAME`
+        - `Sound = FILENAME`
+        - `SoundYR = FILENAME`
+        - `Theme = FILENAME`
+        - `ThemeYR = FILENAME`
+        - `AI = FILENAME`
+        - `AIYR = FILENAME`
+        - `RulesYR = FILENAME`
+        - `Rules = FILENAME`
+        - `ArtYR = FILENAME`
+        - `Art = FILENAME`
+        - `TemperateYR = FILENAME`
+        - `Temperate = FILENAME`
+        - `SnowYR = FILENAME`
+        - `Snow = FILENAME`
+        - `UrbanYR = FILENAME`
+        - `Urban = FILENAME`
+        - `UrbanNYR = FILENAME`
+        - `LunarYR = FILENAME`
+        - `DesertYR = FILENAME`
+        - `MixExtension = FILENAME SUFFIX`
+        ```ini
+        EVAYR=evamp.ini
+        SoundYR=soundmp.ini
+        ThemeYR=thememp.ini
+        AIYR=aimp.ini
+        RulesYR=rulesmp.ini
+        ArtYR=artmp.ini
+        TemperateYR=temperatmp.ini
+        SnowYR=snowmp.ini
+        UrbanYR=urbanmp.ini
+        UrbanNYR=urbannmp.ini
+        LunarYR=lunarmp.ini
+        DesertYR=desertmp.ini
+        MixExtension=mp
+        ```
+    - `[ScriptTypeLists]`
+        - Contains a list of param type lists
+            - NOTICE THAT KEY BEGINS FROM $1$ AND HAS TO BE **INTEGER** 
+        - `X=TypeListName`
+    - `[TypeListName]`
+        - This name is just an example, it should be registered in the `[ScriptTypeLists]`
+    ```ini
+    [TypeListName]
+    HasExtraParam = BOOLEAN
+    ExtraParamType = ExtraParamTypeListName
+    BuiltInType = INTEGER
+    ScriptActionParam = Read the Description below 
+    ; Like 0=Buildings, key must be integer, will be ignored if BuiltInType being set and not -1
+    ```
+    - [ExtraParamTypeListName]
+        - This name is just an example, it needn't to be registered in the `[ScriptTypeLists]`
+    ```ini
+    [ExtraParamTypeListName]
+    BuiltInType = INTEGER
+    ScriptActionExtraParam = Read the Description below
+    ; Like 0=Nearest, key must be integer, will be ignored if BuiltInType being set and not -1
+    ```
+    - **`[ScriptParams]`**
+        - Contains a list of param types used for scripts
+            - NOTICE THAT OUR SCRIPT PARAMS ARE INDEPENDENT
 
-- BASIC TYPES
-INTEGER - [-2147483648,2147483647]
-POINT - INTEGER,INTEGER
-BOOLEAN - Yes/No ; True/False ; 1/0
-COLORREF - R,G,B each of them is in [0,255]
+        | ID | Meaning |
+        | :-: | :-: |
+        | 0 | Nothing |
+        | 1 | Target |
+        | 2 | Waypoint |
+        | 3 | ScriptLine |
+        | 4 | SplitGroup |
+        | 5 | GlobalVariable |
+        | 6 | ScriptTypes |
+        | 7 | TeamTypes |
+        | 8 | Houses |
+        | 9 | Speeches |
+        | 10 | Sounds |
+        | 11 | Movies |
+        | 12 | Themes |
+        | 13 | Countries | 
+        | 14 | LocalVariables |
+        | 15 | Facing |
+        | 16 | BuildingTypes | 
+        | 17 | Animations |
+        | 18 | TalkBubbles |
+        | 19 | Status |
+        | 20 | Boolean |
+        | -X | ScriptTypeList at `[ScriptTypeLists]` X |
 
-- BEFORE LAUNCHING IT
-    - FAData.ini
-        +) [ExtConfigs] (All switches defaults to false)
-            +) BrowserRedraw=BOOLEAN ; Enable refactored ObjectBrowserView
-                +) BrowserRedraw.GuessMode=0/1 ; Determines how FA2sp guess Technos' side, 0(Default) to Prerequisite, 1 to use first Owner 
-                +) BrowserRedraw.CleanUp=BOOLEAN ; Sides classification will clear empty items
-                +) BrowserRedraw.SafeHouses=BOOLEAN ; Determines whether FA2sp will rearrangement the houses or not
-            +) AllowIncludes=BOOLEAN ; Read #include section for other ini (NOT RECOMMENDED) 
-            +) AllowPlusEqual=BOOLEAN ; Read += (NOT RECOMMENDED)
-            +) TutorialTexts.Fix=BOOLEAN ; Replace original process while loading texts to comboboxes
-            +) TutorialTexts.Hide=BOOLEAN ; Reduce lags, for texts in combobox might be useless
-            +) SortByTriggerName=BOOLEAN ; Enable this feature so we can sort the triggers by their names
-            +) AdjustDropdownWidth = BOOLEAN ; Enable it so FA2 will adjust the param dropdown width automatically
-                +) AdjustDropdownWidth.Factor = INTEGER ; Determines how long is a single char takes, defaults to 8
-                +) AdjustDropdownWidth.Max = INTEGER ; Determines the max length of the combobox, defaults to 360
-            +) CopySelectionBound.Color = COLORREF ; Determines the color of the selection boundary while copying, defaults to 255,0,0
-            +) CursorSelectionBound.Color = COLORREF ; Determines the color of the boundary for current cell, defaults to 60,160,60
-            +) HeightIndicatorColor.Color = COLORREF ; Determines the color of the height indicator for current cell, defaults to 60,60,60
-            +) Waypoint.Color = COLORREF ; Determines the color of waypoint texts, default to 0,0,255
-            +) Waypoint.Background = BOOLEAN ; Determines whether draw a rectangle background for waypoints or not. defaults to false
-                +) Waypoint.Background.Color = COLORREF ; Determines the color of the waypoint background, defaults to 255,255,255
-            +) Waypoint.Text.ExtraOffset = POINT ; Additional X and Y-axis offset for waypoint text, defaults to 0,0
-            +) ExtWaypoints = BOOLEAN ; Determines if FA2sp supports unlimited count of waypoints, defaults to false (Phobos required)
-            +) UndoRedoLimit = INTEGER ; Determines the maximun step of undo/redo, defaults to 16
-            +) UseRGBHouseColor = BOOLEAN ; Determines if House colors are recognized as RGB color instead of HSV, defaults to false 
-            +) SaveMap.AutoSave = BOOLEAN ; Determines if FA2 will save map automatically
-                +) SaveMap.AutoSave.Interval = INTEGER ; Should be greater than or equal to 30, defaults to 300, determines how many seconds should we wait during the two auto saving
-                +) SaveMap.AutoSave.MaxCount = INTEGER ; 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
-            +) SaveMap.DefaultPreviewOptionMP = INTEGER ; Default radio option button for preview generation when saving multiplayer maps. 0 = Always generate new preview, 1 = Do no generate new preview, 2 = Always generate hidden preview, defaults to 0.
-            +) SaveMap.DefaultPreviewOptionSP = INTEGER ; Same as the MP one but for SP maps, defaults to 1.
-            +) VerticalLayout = BOOLEAN ; Determines if FA2 will make the bottom view go to the right side
-            +) RecentFileLimit = INTEGER ; How many recent files should I keep? ranges from 4 to 9
-            +) MultiSelectionColor = COLORREF ; Determines the back color of selected tiles
-        +) [Sides] ** (** means Essensial, fa2sp need this section to work properly)
-            {Contains a list of sides registered in rules}
-            \\\ e.g.
-            \\\ [Sides]
-            \\\ 0=Allied
-            \\\ 1=Soviet
-            \\\ 2=Yuri
-            \\\ 3=Neutral
-            \\\ 4=Special
-            \\\
-        +) [Theaters]
-            {Contains a list of theater names, only the existing 6 names are valid. If not listed then all default 6 theaters are used and displayed in order shown below}
-            \\\ e.g.
-            \\\ [Theaters]
-            \\\ 0=TEMPERATE
-            \\\ 1=SNOW
-            \\\ 2=URBAN
-            \\\ 3=NEWURBAN
-            \\\ 4=LUNAR
-            \\\ 5=DESERT
-            \\\
-        +) [ForceName]
-            (xxx = Objecttype)
-            {Contains a list of objecttypes forced to use Name instead of UIName}
-            \\\ e.g.
-            \\\ [ForceName]
-            \\\ 0=E1
-            \\\
-        +) [ForceSides]
-            (Technotype = SideIndex)
-            {Contains a list of technotypes whose side cannot be correctly guessed}
-            \\\ e.g.
-            \\\ [ForceSides]
-            \\\ ENGINEER=0
-            \\\ SENGINEER=1
-            \\\ YENGINEER=2
-            \\\ {A LOT OF WESTWOOD CIVILIAN VEHICLES WITH PREREQUISITE [NAWEAP] WILL BE GUESSED INTO SOVIETS, FIX THEM MANUALLY}
-            \\\
-        +) [ObjectBrowser.SmudgeTypes] and [ObjectBrowser.TerrainTypes]
-            (Contained string = translation key in falanguage)
-            \\\ e.g.
-            \\\ [ObjectBrowser.SmudgeTypes]
-            \\\ CRATER=SmudgeCraterObList
-            \\\ BURNT=SmudgeBurntObList
-            \\\ [ObjectBrowser.TerrainTypes]
-            \\\ TREE=TreesObList
-            \\\ TRFF=TrafficLightsObList
-            \\\ SIGN=SignsObList
-            \\\ LT=LightPostsObList
-            \\\ 
-        +) [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
-            \\\ All tilesets here should have Morphable=true
-            \\\ You don't need to write RampBase here, only other ramps need to be added here
-            \\\ The Ramps and Morphables should have the same length of tilesets, and those tilesets should be one-to-one correspondence
-            \\\ The old NewUrbanInfo's key Ramps2 and Morphable2 had been abandoned, so you need to add them manually
-            \\\ e.g.
-            \\\ [NewUrbanInfo]
-            \\\ Morphables=114,123
-            \\\ Ramps=117,193 
-            \\\
-        +) [ExtraMixes]
-            (Filename = ReadFromMapEditorPathInsteadOfGamePath)
-            \\\ e.g.
-            \\\ [ExtraConfigs]
-            \\\ buxu\123.mix=Yes
-            \\\ money.txt=No
-            \\\
-            \\\ This means FA2 takes {FA2PATH\buxu\123.mix} into consider, and if not found the file,
-            \\\ it will search the file in {GAMEPATH\money.txt}, if this one still doesn't have the file,
-            \\\ FA2 will try to find the file as it used to be.
-            \\\
-        +) [OverlayDisplayLimit]
-            (OverlayIndex = DisplayLimit) (DisplayLimit should be less than or equals to 60)
-            \\\ e.g.
-            \\\ [OverlayDisplayLimit]
-            \\\ 243=48
-            \\\
-            \\\ This means FA2 won't display overlay 243's frames after 48
-        +) [Filenames]
-            +) EVA = FILENAME
-            +) EVAYR = FILENAME
-            +) Sound = FILENAME
-            +) SoundYR = FILENAME
-            +) Theme = FILENAME
-            +) ThemeYR = FILENAME
-            +) AI = FILENAME
-            +) AIYR = FILENAME
-            +) RulesYR = FILENAME
-            +) Rules = FILENAME
-            +) ArtYR = FILENAME
-            +) Art = FILENAME
-            +) TemperateYR = FILENAME
-            +) Temperate = FILENAME
-            +) SnowYR = FILENAME
-            +) Snow = FILENAME
-            +) UrbanYR = FILENAME
-            +) Urban = FILENAME
-            +) UrbanNYR = FILENAME
-            +) LunarYR = FILENAME
-            +) DesertYR = FILENAME
-            +) MixExtension = FILENAME SUFFIX
-            \\\ e.g.
-            \\\ EVAYR=evamp.ini
-            \\\ SoundYR=soundmp.ini
-            \\\ ThemeYR=thememp.ini
-            \\\ AIYR=aimp.ini
-            \\\ RulesYR=rulesmp.ini
-            \\\ ArtYR=artmp.ini
-            \\\ TemperateYR=temperatmp.ini
-            \\\ SnowYR=snowmp.ini
-            \\\ UrbanYR=urbanmp.ini
-            \\\ UrbanNYR=urbannmp.ini
-            \\\ LunarYR=lunarmp.ini
-            \\\ DesertYR=desertmp.ini
-            \\\ MixExtension=mp
-            \\\ 
-        +) [ScriptTypeLists]
-            {Contains a list of param type lists}
-            \\\ NOTICE THAT KEY BEGINS FROM 1 AND HAS TO BE INTEGER
-            \\\ 
-            \\\ X=TypeListName
-        +) [TypeListName]
-            {This name is just an example, it should be registered in the [ScriptTypeLists]}
-            \\\ HasExtraParam = BOOLEAN
-            \\\ ExtraParamType = ExtraParamTypeListName
-            \\\ BuiltInType = INTEGER
-            \\\ ScriptActionParam = Description (Like 0=Buildings, key must be integer, will be ignored if BuiltInType being set and not -1)
-        +) [ExtraParamTypeListName]
-            {This name is just an example, it needn't to be registered in the [ScriptTypeLists]}
-            \\\ BuiltInType = INTEGER
-            \\\ ScriptActionExtraParam = Description (Like 0=Nearest, key must be integer, will be ignored if BuiltInType being set and not -1)
-        +) [ScriptParams] **
-            {Contains a list of param types used for scripts}
-            \\\ NOTICE THAT OUR SCRIPT PARAMS ARE INDEPENDENT
-            \\\ HERE IS THE LIST:
-            \\\ 
-            \\\ (LIST BEGIN)
-            \\\ 0-Nothing
-            \\\ 1-Target
-            \\\ 2-Waypoint
-            \\\ 3-ScriptLine
-            \\\ 4-SplitGroup
-            \\\ 5-GlobalVariable
-            \\\ 6-ScriptTypes
-            \\\ 7-TeamTypes
-            \\\ 8-Houses
-            \\\ 9-Speeches
-            \\\ 10-Sounds
-            \\\ 11=Movies 
-            \\\ 12=Themes 
-            \\\ 13=Countries 
-            \\\ 14=LocalVariables
-            \\\ 15=Facing
-            \\\ 16=BuildingTypes 
-            \\\ 17=Animations
-            \\\ 18=TalkBubbles
-            \\\ 19=Status
-            \\\ 20=Boolean
-            \\\ -X = ScriptTypeList at [ScriptTypeLists] X
-            \\\ (LIST END)
-            \\\
-            \\\ Or just copy the section below:
-            \\\ [ScriptParams]
-            \\\ 0=Nothing,0
-            \\\ 1=Target,1
-            \\\ 2=Waypoint,2
-            \\\ 3=Jump To Line #,3
-            \\\ 4=Split Group,4
-            \\\ 5=Global,5
-            \\\ 6=Script,6
-            \\\ 7=Team,7
-            \\\ 8=House,8
-            \\\ 9=Speech,9
-            \\\ 10=Sound,10
-            \\\ 11=Movie,11
-            \\\ 12=Theme,12
-            \\\ 13=Country,13
-            \\\ 14=Local,14
-            \\\ 15=Facing,15
-            \\\ 16=Building,16
-            \\\ 17=Animation,17
-            \\\ 18=Talk Bubble,18
-            \\\ 19=Enter Status,19
-            \\\ 20=Integer,0
-            \\\ 21=Boolean,20
-            \\\ 
-        +) [ScriptsRA2] **
-            (index = name, param, invisible, has param, description)
-            {Contains a list of script types used for scripts}
-            \\\ e.g. (by caco)
-            \\\ [ScriptsRA2]
-            \\\ 0=0 - Attack,1,0,1,Attack some general TARGET.
-            \\\ 1=1 - Attack WP,2,0,1,Attack specified WAYPOINT (or THINGS on it).
-            \\\ 2=2 - Go Berserk,0,1,0,Cyborgs go berserk (--Obsolete--)
-            \\\ 3=3 - Move to WP,2,0,1,Move to WAYPOINT.
-            \\\ 4=4 - Move to Cell,20,0,1,Move to specified CELL (formula to result: x+y*128).
-            \\\ 5=5 - Guard in Sec,20,0,1,Do AREA GUARD for SECOND(S) defined by argument.
-            \\\ 6=6 - Jump to Line #,3,0,1,Jump to specified LINE with scripts above done.
-            \\\ 7=7 - Player Win,0,0,0,Force player to WIN.
-            \\\ 8=8 - Unload,4,0,1,Kick ALL passengers. Use argument to set which type(s) should CONTINUE the script.
-            \\\ 9=9 - Deploy,0,0,0,Deploy all deployable units.
-            \\\ 10=10 - Follow friendlies,0,0,0,Follow the NEAREST friendly units.
-            \\\ 11=11 - Do this,19,0,1,Cause the team to DO specified MISSION.
-            \\\ 12=12 - Set Global var,5,0,1,Set a GLOBAL variable (1/On).
-            \\\ 13=13 - Idle,0,0,0,Infantries in this team PLAY IDLE ANIMS.
-            \\\ 14=14 - Load onto Transport,0,0,0,Let all units enter the transportation IF POSSIBLE.
-            \\\ 15=15 - Spy into,0,1,0,(--Obsolete--)
-            \\\ 16=16 - Patrol to WP,2,0,1,Patrol (Attack-Move) to WAYPOINT.
-            \\\ 17=17 - Change Script,6,0,1,Change SCRIPT the taskforce used. 
-            \\\ 18=18 - Change Team,7,0,1,Change TEAM the taskforce belong to. 
-            \\\ 19=19 - Panic,0,0,0,Causes all units in the team to panic. (Usually for civilian use)
-            \\\ 20=20 - Change Owner,13,0,1,Specified COUNTRY will own the whole team.
-            \\\ 21=21 - Scatter,0,0,0,Scatter all units.
-            \\\ 22=22 - Escape to Shroud,0,0,0,Cause all units escape to SHROUD.
-            \\\ 23=23 - Player Lose,0,0,0,Force player to LOSE.
-            \\\ 24=24 - Play EVA Speech,9,0,1,Play specified SPEECH.
-            \\\ 25=25 - Play Sound,10,0,1,Play specified SOUND.
-            \\\ 26=26 - Play Movie,11,0,1,Play specified MOVIE (on radar screen).
-            \\\ 27=27 - Play Theme,12,0,1,Play specified THEME.
-            \\\ 28=28 - Reduce Ore,0,0,0,Reduce the value of ORE AROUND TEAM MEMBERS.
-            \\\ 29=29 - Begin Production,0,0,0,Cause the OWNER OF THIS TEAM produce (as planned).
-            \\\ 30=30 - Sell 'n' Hunt,0,0,0,Cause AI SELL their buildings and HUNT their enemies.
-            \\\ 31=31 - Self Destroy,0,0,0,Destroy the team ITSELF.
-            \\\ 32=32 - Start Storm in Sec,20,0,1,Begin the Lightning Storm after specified SECOND(S).
-            \\\ 33=33 - End Storm,0,0,0,End up the CURRENT Lightning Storm.
-            \\\ 34=34 - Center focus on this team,20,0,1,Center focus on this team with specified MOVE SPEED.
-            \\\ 35=35 - Reshroud Map,0,0,0,Reshroud current map.
-            \\\ 36=36 - Reveal Map,0,0,0,Reveal ALL terrain of current map.
-            \\\ 37=37 - Delete Team,0,0,0,Delete ALL members of this team.
-            \\\ 38=38 - Clear Global Var,5,0,1,Clear specified GLOBAL var (0/Off).
-            \\\ 39=39 - Set Local Var,14,0,1,Set specified LOCAL var (1/On).
-            \\\ 40=40 - Clear Local Var,14,0,1,Clear specified LOCAL var (0/Off).
-            \\\ 41=41 - Unpanic,0,0,0,Calm down all units in this team.
-            \\\ 42=42 - Force Facing,15,0,1,Turn all units in this team to a specified direction.
-            \\\ 43=43 - Wait till full,0,0,0,Wait until all passengers loaded.
-            \\\ 44=44 - Truck unload,0,0,0,UNLOAD the goods as all trucks go empty.
-            \\\ 45=45 - Truck load,0,0,0,LOAD the goods as all trucks go full.
-            \\\ 46=46 - Attack enemy buildings,16,0,1,Attack specified BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
-            \\\ 47=47 - Move to enemy buildings,16,0,1,Move to specified BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
-            \\\ 48=48 - Scout,0,0,0,The team would scout the shroud area.
-            \\\ 49=49 - Success,0,0,0,Put up the weight of AI trigger attached.
-            \\\ 50=50 - Flash for frames,20,0,1,Flash this team for a number of FRAMES.
-            \\\ 51=51 - Play Animation,17,0,1,Play specified anim on each unit.
-            \\\ 52=52 - Talk bubble,18,0,1,Show a talk bubble on the FIRST UNIT of this team.
-            \\\ 53=53 - Gather outside enemy,20,0,1,Gather outside the enemy's base. Arguments with positive or negative could affect the global distance since Ares 2.0.
-            \\\ 54=54 - Gather outside team,20,0,1,Gather outside the team's base. Arguments with positive or negative could affect the global distance since Ares 2.0.
-            \\\ 55=55 - Ask for SW,20,0,1,AI would queue a SuperWeapon for this team. Arguments decide which group of SW since Ares 2.0 (SW.Group).
-            \\\ 56=56 - Chronoshift to Building,16,0,1,Chronoshift the team to specified buildings if possible. Need EXTRA orders however.
-            \\\ 57=57 - Chronoshift to Target,1,0,1,Chronoshift the team to specified type if possible. Need EXTRA orders however.
-            \\\ ;YR Only
-            \\\ 58=58 - Move to friendlies buildings,16,0,1,Move to friendlies BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
-            \\\ 59=59 - Attack (or Garrison) buildings on WP,2,0,1,Attack the building on specified WP. AI would usually try to GARRISON if possible.
-            \\\ 60=60 - Enter Grinder,0,0,0,Get the team into nearest grinder.
-            \\\ 61=61 - Enter Tank Bunker,0,0,0,Get EACH unit in the team into nearest tank bunker.
-            \\\ 62=62 - Enter Bio Reactor,0,0,0,Get EACH infantry in the team into nearest bio reactor.
-            \\\ 63=63 - Enter Battle Bunker,0,0,0,Get EACH infantry in the team into nearest battle bunker (if possible).
-            \\\ 64=64 - Enter Neutral Buildings,0,0,0,Get EACH infantry in the team into nearest civilian buildings (if possible).
-            \\\ ;Ares 3.0 Only
-            \\\ 65=65 - Auxiliary Power (Ares 3.0 Only),20,0,1,Permanently changes the power output of the house owning the team.
-            \\\ 66=66 - Kill Drivers (Ares 3.0 Only),0,0,0,Kills ALL drivers of the units in this team.
-            \\\ 67=67 - Take Vehicles (Ares 3.0 Only),0,0,0,All CanDrive or VehicleThief infantry in this team will be assigned the closest vehicle they can drive or hijack.
-            \\\ 68=68 - Convert Type (Ares 3.0 Only),0,0,0,Immediately changes all members of this team into their respective script conversion types (Convert.Script).
-            \\\ 69=69 - Sonar Reveal (Ares 3.0 Only),20,0,1,Disables the ability of all team members to cloak themselves for a number of FRAMES.
-            \\\ 70=70 - Disable Weapons (Ares 3.0 Only),20,0,1,Disables the ability of all team members to fire for a number of FRAMES.
-        +) [VehicleVoxelBarrelsRA2]
-    - FALanguage.ini
-        *)  [CURRENTLANGUAGE-StringsRA2]
-            [CURRENTLANGUAGE-Strings]
-            [CURRENTLANGUAGE-TranslationsRA2]
-            [CURRENTLANGUAGE-Translations]
-                +) TabPages.TilePlacement = TEXT
-                +) TabPages.TriggerSort = TEXT
-                +) Menu.File = TEXT
-                +) Menu.File.New = TEXT
-                +) Menu.File.Open = TEXT
-                +) Menu.File.Save = TEXT
-                +) Menu.File.SaveAs = TEXT
-                +) Menu.File.CheckMap = TEXT
-                +) Menu.File.RunGame = TEXT
-                +) Menu.File.Quit = TEXT
-                +) Menu.Edit = TEXT
-                +) Menu.Edit.Undo = TEXT
-                +) Menu.Edit.Redo = TEXT
-                +) Menu.Edit.Copy = TEXT
-                +) Menu.Edit.CopyWholeMap = TEXT
-                +) Menu.Edit.Paste = TEXT
-                +) Menu.Edit.PasteCentered = TEXT
-                +) Menu.Edit.Map = TEXT
-                +) Menu.Edit.Basic = TEXT
-                +) Menu.Edit.SpecialFlags = TEXT
-                +) Menu.Edit.Lighting = TEXT
-                +) Menu.Edit.Houses = TEXT
-                +) Menu.Edit.TriggerEditor = TEXT
-                +) Menu.Edit.TagEditor = TEXT
-                +) Menu.Edit.Taskforces = TEXT
-                +) Menu.Edit.Scripts = TEXT
-                +) Menu.Edit.Teams = TEXT
-                +) Menu.Edit.AITriggers = TEXT
-                +) Menu.Edit.AITriggerEnable = TEXT
-                +) Menu.Edit.LocalVariables = TEXT
-                +) Menu.Edit.SingleplayerSettings = TEXT
-                +) Menu.Edit.INIEditor = TEXT
-                +) Menu.Terrain = TEXT
-                +) Menu.Terrain.RaiseGround = TEXT
-                +) Menu.Terrain.LowerGround = TEXT
-                +) Menu.Terrain.FlattenGround = TEXT
-                +) Menu.Terrain.HideTileset = TEXT
-                +) Menu.Terrain.ShowEveryTileset = TEXT
-                +) Menu.Terrain.HideSingleField = TEXT
-                +) Menu.Terrain.ShowAllFields = TEXT
-                +) Menu.Terrain.RaiseSingleTile = TEXT
-                +) Menu.Terrain.LowerSingleTile = TEXT
-                +) Menu.MapTools = TEXT
-                +) Menu.MapTools.ChangeMapHeight = TEXT
-                +) Menu.MapTools.AutoCreateShores = TEXT
-                +) Menu.MapTools.AutoLevelUsingCliffs = TEXT
-                +) Menu.MapTools.PaintCliffFront = TEXT
-                +) Menu.MapTools.PaintCliffBack = TEXT
-                +) Menu.MapTools.SearchWaypoint = TEXT
-                +) Menu.MapTools.ToolScripts = TEXT
-                +) Menu.Online = TEXT
-                +) Menu.Online.Westwood = TEXT
-                +) Menu.Online.FA2Fansite = TEXT
-                +) Menu.Online.FA2Forum = TEXT
-                +) Menu.Options = TEXT
-                +) Menu.Options.Settings = TEXT
-                +) Menu.Options.ShowMinimap = TEXT
-                +) Menu.Options.Easymode = TEXT
-                +) Menu.Options.Sounds = TEXT
-                +) Menu.Options.ShowBuildingOutline = TEXT
-                +) Menu.Options.DisableAutoShore = TEXT
-                +) Menu.Options.DisableAutoLAT = TEXT
-                +) Menu.Options.DisableSlopeCorrection = TEXT
-                +) Menu.Help = TEXT
-                +) Menu.Help.Manual = TEXT
-                +) Menu.Help.Info = TEXT
-                +) Menu.Help.Credits = TEXT
-                +) Menu.Help.TipOfTheDay = TEXT
-                +) Menu.Layers = TEXT
-                +) Menu.Layers.Structures = TEXT
-                +) Menu.Layers.Infantries = TEXT
-                +) Menu.Layers.Units = TEXT
-                +) Menu.Layers.Aircrafts = TEXT
-                +) Menu.Layers.Basenodes = TEXT
-                +) Menu.Layers.Waypoints = TEXT
-                +) Menu.Layers.Celltags = TEXT
-                +) Menu.Layers.MoneyOnMap = TEXT
-                +) Menu.Layers.Overlays = TEXT
-                +) Menu.Layers.Terrains = TEXT
-                +) 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
-                +) DialogBar.TileManager = TEXT
-                +) DialogBar.TerrainOrGround = TEXT
-                +) DialogBar.OverlayAndSpecial = TEXT
-                +) AITriggerTitle = TEXT
-                +) AITriggerList = TEXT
-                +) AITriggerName = TEXT
-                +) AITriggerTeam1 = TEXT
-                +) AITriggerHouse = TEXT
-                +) AITriggerTeam2 = TEXT
-                +) AITriggerTechlevel = TEXT
-                +) AITriggerType = TEXT
-                +) AITriggerWeight = TEXT
-                +) AITriggerMinWeight = TEXT
-                +) AITriggerMaxWeight = TEXT
-                +) AITriggerMinDiff = TEXT
-                +) AITriggerSide = TEXT
-                +) AITriggerTechnoType = TEXT
-                +) AITriggerCondition = TEXT
-                +) AITriggerNumber = TEXT
-                +) AITriggerAdditionalDesc = TEXT
-                +) AITriggerData = TEXT
-                +) AITriggerEnabled = TEXT
-                +) AITriggerAdd = TEXT
-                +) AITriggerDel = TEXT
-                +) AITriggerClo = TEXT
-                +) AITriggerBaseDefense = TEXT
-                +) AITriggerSkirmish = TEXT
-                +) AITriggerEasy = TEXT
-                +) AITriggerMedium = TEXT
-                +) AITriggerHard = TEXT
-                +) TaskforceTitle = TEXT
-                +) TaskforceList = TEXT
-                +) TaskforceUnits = TEXT
-                +) TaskforceGroup = TEXT
-                +) TaskforceUnitNumber = TEXT
-                +) TaskforceUnitType = TEXT
-                +) TaskforceSelected = TEXT
-                +) TaskforceName = TEXT
-                +) TaskforceNewTask = TEXT
-                +) TaskforceDelTask = TEXT
-                +) TaskforceCloTask = TEXT
-                +) TaskforceNewUnit = TEXT
-                +) TaskforceDelUnit = TEXT
-                +) TaskforceCloUnit = TEXT
-                +) TeamTypesTitle = TEXT
-                +) TeamTypesNewTeam = TEXT
-                +) TeamTypesDelTeam = TEXT
-                +) TeamTypesCloTeam = TEXT
-                +) TeamTypesMainDesc = TEXT
-                +) TeamTypesCurrentTeamLabel = TEXT
-                +) TeamTypesSelectedTeam = TEXT
-                +) TeamTypesLabelName = TEXT
-                +) TeamTypesLabelHouse = TEXT
-                +) TeamTypesLabelTaskforce = TEXT
-                +) TeamTypesLabelScript = TEXT
-                +) TeamTypesLabelTag = TEXT
-                +) TeamTypesLabelVeteranLevel = TEXT
-                +) TeamTypesLabelPriority = TEXT
-                +) TeamTypesLabelMax = TEXT
-                +) TeamTypesLabelTechlevel = TEXT
-                +) TeamTypesLabelTransportWaypoint = TEXT
-                +) TeamTypesLabelGroup = TEXT
-                +) TeamTypesLabelWaypoint = TEXT
-                +) TeamTypesLabelMindControlDecision = TEXT
-                +) TeamTypesCheckBoxLoadable = TEXT
-                +) TeamTypesCheckBoxFull = TEXT
-                +) TeamTypesCheckBoxAnnoyance = TEXT
-                +) TeamTypesCheckBoxGuardSlower = TEXT
-                +) TeamTypesCheckBoxRecruiter = TEXT
-                +) TeamTypesCheckBoxAutoCreate = TEXT
-                +) TeamTypesCheckBoxPrebuild = TEXT
-                +) TeamTypesCheckBoxReinforce = TEXT
-                +) TeamTypesCheckBoxCargoPlane = TEXT
-                +) TeamTypesCheckBoxWhiner = TEXT
-                +) TeamTypesCheckBoxLooseRecruit = TEXT
-                +) TeamTypesCheckBoxAggressive = TEXT
-                +) TeamTypesCheckBoxSuicide = TEXT
-                +) TeamTypesCheckBoxOnTransOnly = TEXT
-                +) TeamTypesCheckBoxAvoidThreats = TEXT
-                +) TeamTypesCheckBoxIonImmune = TEXT
-                +) TeamTypesCheckBoxTransportsReturnOnUnload = TEXT
-                +) TeamTypesCheckBoxAreTeamMembersRecruitable = TEXT
-                +) TeamTypesCheckBoxIsBaseDefense = TEXT
-                +) TeamTypesCheckBoxOnlyTargetHouseEnemy = TEXT
-                +) TriggerFrameTitle = TEXT
-                +) TriggerFrameSelectedTrigger = TEXT
-                +) TriggerFrameNew = TEXT
-                +) TriggerFrameDel = TEXT
-                +) TriggerFramePlace = TEXT
-                +) TriggerFrameClone = TEXT
-                +) TriggerOptionType = TEXT
-                +) TriggerOptionName = TEXT
-                +) TriggerOptionHouse = TEXT
-                +) TriggerOptionAttached = TEXT
-                +) TriggerOptionDisabled = TEXT
-                +) TriggerOptionDisabledDesc = TEXT
-                +) TriggerOptionEasy = TEXT
-                +) TriggerOptionMedium = TEXT
-                +) TriggerOptionHard = TEXT
-                +) TriggerEventCurrent = TEXT
-                +) TriggerEventNew = TEXT
-                +) TriggerEventDel = TEXT
-                +) TriggerEventClo = TEXT
-                +) TriggerEventOptions = TEXT
-                +) TriggerEventType = TEXT
-                +) TriggerEventParameter = TEXT
-                +) TriggerEventParamValue = TEXT
-                +) TriggerEventDesc = TEXT
-                +) TriggerActionCurrent = TEXT
-                +) TriggerActionNew = TEXT
-                +) TriggerActionDel = TEXT
-                +) TriggerActionClo = TEXT
-                +) TriggerActionOptions = TEXT
-                +) TriggerActionType = TEXT
-                +) TriggerActionParameter = TEXT
-                +) TriggerActionParamValue = TEXT
-                +) TriggerActionDesc = TEXT
-                +) ScriptTypesTitle = TEXT
-                +) ScriptTypesDesc = TEXT
-                +) ScriptTypesSelectedScript = TEXT
-                +) ScriptTypesName = TEXT
-                +) ScriptTypesActions = TEXT
-                +) ScriptTypesActionType = TEXT
-                +) ScriptTypesActionDesc = TEXT
-                +) ScriptTypesAddScript = TEXT
-                +) ScriptTypesDelScript = TEXT
-                +) ScriptTypesCloScript = TEXT
-                +) ScriptTypesAddAction = TEXT
-                +) ScriptTypesDelAction = TEXT
-                +) ScriptTypesActionParam = TEXT
-                +) ScriptTypesCloAction = TEXT
-                +) ScriptTypesInsertMode = TEXT
-                +) ScriptTypesExtraParam = TEXT
-                +) ScriptTypesMoveUp = TEXT
-                +) ScriptTypesMoveDown = TEXT
-                +) SingleplayerParTimeEasy = TEXT
-                +) SingleplayerParTimeMedium = TEXT
-                +) SingleplayerParTimeHard = TEXT
-                +) SingleplayerOverParTitle = TEXT
-                +) SingleplayerOverParMessage = TEXT
-                +) SingleplayerUnderParTitle = TEXT
-                +) SingleplayerUnderParMessage = TEXT
-                +) LightingTitle = TEXT
-                +) LightingDesc = TEXT
-                +) LightingNormal = TEXT
-                +) LightingIonStorm = TEXT
-                +) LightingDominator = TEXT
-                +) LightingAmbient = TEXT
-                +) LightingGreen = TEXT
-                +) LightingRed = TEXT
-                +) LightingBlue = TEXT
-                +) LightingLevel = TEXT
-                +) LightingGround = TEXT
-                +) LightingNukeAmbientChangeRate = TEXT
-                +) LightingDominatorAmbientChangeRate = TEXT
-                +) PropertyBrushObList = TEXT
-                +) PropertyBrushBuilding = TEXT
-                +) PropertyBrushInfantry = TEXT
-                +) PropertyBrushVehicle = TEXT
-                +) PropertyBrushAircraft = TEXT
-                +) TheaterNameTem = TEXT
-                +) TheaterNameSno = TEXT
-                +) TheaterNameUrb = TEXT
-                +) TheaterNameUbn = TEXT
-                +) TheaterNameLun = TEXT
-                +) TheaterNameDes = TEXT
-                +) AllieEditorTitle = TEXT
-                +) AllieEditorEnemies = TEXT
-                +) AllieEditorAllies = TEXT
-                +) AllieEditorOK = TEXT
-                +) AllieEditorCancel = TEXT
-                +) TileManagerTitle = TEXT
+        ```ini
+        [ScriptParams] ; Our sample list
+        0=Nothing,0
+        1=Target,1
+        2=Waypoint,2
+        3=Jump To Line #,3
+        4=Split Group,4
+        5=Global,5
+        6=Script,6
+        7=Team,7
+        8=House,8
+        9=Speech,9
+        10=Sound,10
+        11=Movie,11
+        12=Theme,12
+        13=Country,13
+        14=Local,14
+        15=Facing,15
+        16=Building,16
+        17=Animation,17
+        18=Talk Bubble,18
+        19=Enter Status,19
+        20=Integer,0
+        21=Boolean,20
+        ```
+    - **`[ScriptsRA2]`**
+        - `index = name, param, invisible, has param, description`
+        - Contains a list of script types used for scripts
+        ```ini
+        [ScriptsRA2] ; Sample by Caco
+        0=0 - Attack,1,0,1,Attack some general TARGET.
+        1=1 - Attack WP,2,0,1,Attack specified WAYPOINT (or THINGS on it).
+        2=2 - Go Berserk,0,1,0,Cyborgs go berserk (--Obsolete--)
+        3=3 - Move to WP,2,0,1,Move to WAYPOINT.
+        4=4 - Move to Cell,20,0,1,Move to specified CELL (formula to result: x+y*128).
+        5=5 - Guard in Sec,20,0,1,Do AREA GUARD for SECOND(S) defined by argument.
+        6=6 - Jump to Line #,3,0,1,Jump to specified LINE with scripts above done.
+        7=7 - Player Win,0,0,0,Force player to WIN.
+        8=8 - Unload,4,0,1,Kick ALL passengers. Use argument to set which type(s) should CONTINUE the script.
+        9=9 - Deploy,0,0,0,Deploy all deployable units.
+        10=10 - Follow friendlies,0,0,0,Follow the NEAREST friendly units.
+        11=11 - Do this,19,0,1,Cause the team to DO specified MISSION.
+        12=12 - Set Global var,5,0,1,Set a GLOBAL variable (1/On).
+        13=13 - Idle,0,0,0,Infantries in this team PLAY IDLE ANIMS.
+        14=14 - Load onto Transport,0,0,0,Let all units enter the transportation IF POSSIBLE.
+        15=15 - Spy into,0,1,0,(--Obsolete--)
+        16=16 - Patrol to WP,2,0,1,Patrol (Attack-Move) to WAYPOINT.
+        17=17 - Change Script,6,0,1,Change SCRIPT the taskforce used. 
+        18=18 - Change Team,7,0,1,Change TEAM the taskforce belong to. 
+        19=19 - Panic,0,0,0,Causes all units in the team to panic. (Usually for civilian use)
+        20=20 - Change Owner,13,0,1,Specified COUNTRY will own the whole team.
+        21=21 - Scatter,0,0,0,Scatter all units.
+        22=22 - Escape to Shroud,0,0,0,Cause all units escape to SHROUD.
+        23=23 - Player Lose,0,0,0,Force player to LOSE.
+        24=24 - Play EVA Speech,9,0,1,Play specified SPEECH.
+        25=25 - Play Sound,10,0,1,Play specified SOUND.
+        26=26 - Play Movie,11,0,1,Play specified MOVIE (on radar screen).
+        27=27 - Play Theme,12,0,1,Play specified THEME.
+        28=28 - Reduce Ore,0,0,0,Reduce the value of ORE AROUND TEAM MEMBERS.
+        29=29 - Begin Production,0,0,0,Cause the OWNER OF THIS TEAM produce (as planned).
+        30=30 - Sell 'n' Hunt,0,0,0,Cause AI SELL their buildings and HUNT their enemies.
+        31=31 - Self Destroy,0,0,0,Destroy the team ITSELF.
+        32=32 - Start Storm in Sec,20,0,1,Begin the Lightning Storm after specified SECOND(S).
+        33=33 - End Storm,0,0,0,End up the CURRENT Lightning Storm.
+        34=34 - Center focus on this team,20,0,1,Center focus on this team with specified MOVE SPEED.
+        35=35 - Reshroud Map,0,0,0,Reshroud current map.
+        36=36 - Reveal Map,0,0,0,Reveal ALL terrain of current map.
+        37=37 - Delete Team,0,0,0,Delete ALL members of this team.
+        38=38 - Clear Global Var,5,0,1,Clear specified GLOBAL var (0/Off).
+        39=39 - Set Local Var,14,0,1,Set specified LOCAL var (1/On).
+        40=40 - Clear Local Var,14,0,1,Clear specified LOCAL var (0/Off).
+        41=41 - Unpanic,0,0,0,Calm down all units in this team.
+        42=42 - Force Facing,15,0,1,Turn all units in this team to a specified direction.
+        43=43 - Wait till full,0,0,0,Wait until all passengers loaded.
+        44=44 - Truck unload,0,0,0,UNLOAD the goods as all trucks go empty.
+        45=45 - Truck load,0,0,0,LOAD the goods as all trucks go full.
+        46=46 - Attack enemy buildings,16,0,1,Attack specified BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
+        47=47 - Move to enemy buildings,16,0,1,Move to specified BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
+        48=48 - Scout,0,0,0,The team would scout the shroud area.
+        49=49 - Success,0,0,0,Put up the weight of AI trigger attached.
+        50=50 - Flash for frames,20,0,1,Flash this team for a number of FRAMES.
+        51=51 - Play Animation,17,0,1,Play specified anim on each unit.
+        52=52 - Talk bubble,18,0,1,Show a talk bubble on the FIRST UNIT of this team.
+        53=53 - Gather outside enemy,20,0,1,Gather outside the enemy's base. Arguments with positive or negative could affect the global distance since Ares 2.0.
+        54=54 - Gather outside team,20,0,1,Gather outside the team's base. Arguments with positive or negative could affect the global distance since Ares 2.0.
+        55=55 - Ask for SW,20,0,1,AI would queue a SuperWeapon for this team. Arguments decide which group of SW since Ares 2.0 (SW.Group).
+        56=56 - Chronoshift to Building,16,0,1,Chronoshift the team to specified buildings if possible. Need EXTRA orders however.
+        57=57 - Chronoshift to Target,1,0,1,Chronoshift the team to specified type if possible. Need EXTRA orders however.
+        ;YR Only
+        58=58 - Move to friendlies buildings,16,0,1,Move to friendlies BUILDINGS. (+0: MIN threat +65536: MAX threat +131072: nearest, +262144: furthest).
+        59=59 - Attack (or Garrison) buildings on WP,2,0,1,Attack the building on specified WP. AI would usually try to GARRISON if possible.
+        60=60 - Enter Grinder,0,0,0,Get the team into nearest grinder.
+        61=61 - Enter Tank Bunker,0,0,0,Get EACH unit in the team into nearest tank bunker.
+        62=62 - Enter Bio Reactor,0,0,0,Get EACH infantry in the team into nearest bio reactor.
+        63=63 - Enter Battle Bunker,0,0,0,Get EACH infantry in the team into nearest battle bunker (if possible).
+        64=64 - Enter Neutral Buildings,0,0,0,Get EACH infantry in the team into nearest civilian buildings (if possible).
+        ;Ares 3.0 Only
+        65=65 - Auxiliary Power (Ares 3.0 Only),20,0,1,Permanently changes the power output of the house owning the team.
+        66=66 - Kill Drivers (Ares 3.0 Only),0,0,0,Kills ALL drivers of the units in this team.
+        67=67 - Take Vehicles (Ares 3.0 Only),0,0,0,All CanDrive or VehicleThief infantry in this team will be assigned the closest vehicle they can drive or hijack.
+        68=68 - Convert Type (Ares 3.0 Only),0,0,0,Immediately changes all members of this team into their respective script conversion types (Convert.Script).
+        69=69 - Sonar Reveal (Ares 3.0 Only),20,0,1,Disables the ability of all team members to cloak themselves for a number of FRAMES.
+        70=70 - Disable Weapons (Ares 3.0 Only),20,0,1,Disables the ability of all team members to fire for a number of FRAMES.
+        ```
+    - `[VehicleVoxelBarrelsRA2]`
+- `FALanguage.ini`
+    ```ini
+    [CURRENTLANGUAGE-StringsRA2]
+    [CURRENTLANGUAGE-Strings]
+    [CURRENTLANGUAGE-TranslationsRA2]
+    [CURRENTLANGUAGE-Translations]
+    ; Those four are all acceptable, just write under one of them is okey
+    TabPages.TilePlacement = TEXT
+    TabPages.TriggerSort = TEXT
+    Menu.File = TEXT
+    Menu.File.New = TEXT
+    Menu.File.Open = TEXT
+    Menu.File.Save = TEXT
+    Menu.File.SaveAs = TEXT
+    Menu.File.CheckMap = TEXT
+    Menu.File.RunGame = TEXT
+    Menu.File.Quit = TEXT
+    Menu.Edit = TEXT
+    Menu.Edit.Undo = TEXT
+    Menu.Edit.Redo = TEXT
+    Menu.Edit.Copy = TEXT
+    Menu.Edit.CopyWholeMap = TEXT
+    Menu.Edit.Paste = TEXT
+    Menu.Edit.PasteCentered = TEXT
+    Menu.Edit.Map = TEXT
+    Menu.Edit.Basic = TEXT
+    Menu.Edit.SpecialFlags = TEXT
+    Menu.Edit.Lighting = TEXT
+    Menu.Edit.Houses = TEXT
+    Menu.Edit.TriggerEditor = TEXT
+    Menu.Edit.TagEditor = TEXT
+    Menu.Edit.Taskforces = TEXT
+    Menu.Edit.Scripts = TEXT
+    Menu.Edit.Teams = TEXT
+    Menu.Edit.AITriggers = TEXT
+    Menu.Edit.AITriggerEnable = TEXT
+    Menu.Edit.LocalVariables = TEXT
+    Menu.Edit.SingleplayerSettings = TEXT
+    Menu.Edit.INIEditor = TEXT
+    Menu.Terrain = TEXT
+    Menu.Terrain.RaiseGround = TEXT
+    Menu.Terrain.LowerGround = TEXT
+    Menu.Terrain.FlattenGround = TEXT
+    Menu.Terrain.HideTileset = TEXT
+    Menu.Terrain.ShowEveryTileset = TEXT
+    Menu.Terrain.HideSingleField = TEXT
+    Menu.Terrain.ShowAllFields = TEXT
+    Menu.Terrain.RaiseSingleTile = TEXT
+    Menu.Terrain.LowerSingleTile = TEXT
+    Menu.MapTools = TEXT
+    Menu.MapTools.ChangeMapHeight = TEXT
+    Menu.MapTools.AutoCreateShores = TEXT
+    Menu.MapTools.AutoLevelUsingCliffs = TEXT
+    Menu.MapTools.PaintCliffFront = TEXT
+    Menu.MapTools.PaintCliffBack = TEXT
+    Menu.MapTools.SearchWaypoint = TEXT
+    Menu.MapTools.ToolScripts = TEXT
+    Menu.Online = TEXT
+    Menu.Online.Westwood = TEXT
+    Menu.Online.FA2Fansite = TEXT
+    Menu.Online.FA2Forum = TEXT
+    Menu.Options = TEXT
+    Menu.Options.Settings = TEXT
+    Menu.Options.ShowMinimap = TEXT
+    Menu.Options.Easymode = TEXT
+    Menu.Options.Sounds = TEXT
+    Menu.Options.ShowBuildingOutline = TEXT
+    Menu.Options.DisableAutoShore = TEXT
+    Menu.Options.DisableAutoLAT = TEXT
+    Menu.Options.DisableSlopeCorrection = TEXT
+    Menu.Help = TEXT
+    Menu.Help.Manual = TEXT
+    Menu.Help.Info = TEXT
+    Menu.Help.Credits = TEXT
+    Menu.Help.TipOfTheDay = TEXT
+    Menu.Layers = TEXT
+    Menu.Layers.Structures = TEXT
+    Menu.Layers.Infantries = TEXT
+    Menu.Layers.Units = TEXT
+    Menu.Layers.Aircrafts = TEXT
+    Menu.Layers.Basenodes = TEXT
+    Menu.Layers.Waypoints = TEXT
+    Menu.Layers.Celltags = TEXT
+    Menu.Layers.MoneyOnMap = TEXT
+    Menu.Layers.Overlays = TEXT
+    Menu.Layers.Terrains = TEXT
+    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
+    DialogBar.TileManager = TEXT
+    DialogBar.TerrainOrGround = TEXT
+    DialogBar.OverlayAndSpecial = TEXT
+    AITriggerTitle = TEXT
+    AITriggerList = TEXT
+    AITriggerName = TEXT
+    AITriggerTeam1 = TEXT
+    AITriggerHouse = TEXT
+    AITriggerTeam2 = TEXT
+    AITriggerTechlevel = TEXT
+    AITriggerType = TEXT
+    AITriggerWeight = TEXT
+    AITriggerMinWeight = TEXT
+    AITriggerMaxWeight = TEXT
+    AITriggerMinDiff = TEXT
+    AITriggerSide = TEXT
+    AITriggerTechnoType = TEXT
+    AITriggerCondition = TEXT
+    AITriggerNumber = TEXT
+    AITriggerAdditionalDesc = TEXT
+    AITriggerData = TEXT
+    AITriggerEnabled = TEXT
+    AITriggerAdd = TEXT
+    AITriggerDel = TEXT
+    AITriggerClo = TEXT
+    AITriggerBaseDefense = TEXT
+    AITriggerSkirmish = TEXT
+    AITriggerEasy = TEXT
+    AITriggerMedium = TEXT
+    AITriggerHard = TEXT
+    TaskforceTitle = TEXT
+    TaskforceList = TEXT
+    TaskforceUnits = TEXT
+    TaskforceGroup = TEXT
+    TaskforceUnitNumber = TEXT
+    TaskforceUnitType = TEXT
+    TaskforceSelected = TEXT
+    TaskforceName = TEXT
+    TaskforceNewTask = TEXT
+    TaskforceDelTask = TEXT
+    TaskforceCloTask = TEXT
+    TaskforceNewUnit = TEXT
+    TaskforceDelUnit = TEXT
+    TaskforceCloUnit = TEXT
+    TeamTypesTitle = TEXT
+    TeamTypesNewTeam = TEXT
+    TeamTypesDelTeam = TEXT
+    TeamTypesCloTeam = TEXT
+    TeamTypesMainDesc = TEXT
+    TeamTypesCurrentTeamLabel = TEXT
+    TeamTypesSelectedTeam = TEXT
+    TeamTypesLabelName = TEXT
+    TeamTypesLabelHouse = TEXT
+    TeamTypesLabelTaskforce = TEXT
+    TeamTypesLabelScript = TEXT
+    TeamTypesLabelTag = TEXT
+    TeamTypesLabelVeteranLevel = TEXT
+    TeamTypesLabelPriority = TEXT
+    TeamTypesLabelMax = TEXT
+    TeamTypesLabelTechlevel = TEXT
+    TeamTypesLabelTransportWaypoint = TEXT
+    TeamTypesLabelGroup = TEXT
+    TeamTypesLabelWaypoint = TEXT
+    TeamTypesLabelMindControlDecision = TEXT
+    TeamTypesCheckBoxLoadable = TEXT
+    TeamTypesCheckBoxFull = TEXT
+    TeamTypesCheckBoxAnnoyance = TEXT
+    TeamTypesCheckBoxGuardSlower = TEXT
+    TeamTypesCheckBoxRecruiter = TEXT
+    TeamTypesCheckBoxAutoCreate = TEXT
+    TeamTypesCheckBoxPrebuild = TEXT
+    TeamTypesCheckBoxReinforce = TEXT
+    TeamTypesCheckBoxCargoPlane = TEXT
+    TeamTypesCheckBoxWhiner = TEXT
+    TeamTypesCheckBoxLooseRecruit = TEXT
+    TeamTypesCheckBoxAggressive = TEXT
+    TeamTypesCheckBoxSuicide = TEXT
+    TeamTypesCheckBoxOnTransOnly = TEXT
+    TeamTypesCheckBoxAvoidThreats = TEXT
+    TeamTypesCheckBoxIonImmune = TEXT
+    TeamTypesCheckBoxTransportsReturnOnUnload = TEXT
+    TeamTypesCheckBoxAreTeamMembersRecruitable = TEXT
+    TeamTypesCheckBoxIsBaseDefense = TEXT
+    TeamTypesCheckBoxOnlyTargetHouseEnemy = TEXT
+    TriggerFrameTitle = TEXT
+    TriggerFrameSelectedTrigger = TEXT
+    TriggerFrameNew = TEXT
+    TriggerFrameDel = TEXT
+    TriggerFramePlace = TEXT
+    TriggerFrameClone = TEXT
+    TriggerOptionType = TEXT
+    TriggerOptionName = TEXT
+    TriggerOptionHouse = TEXT
+    TriggerOptionAttached = TEXT
+    TriggerOptionDisabled = TEXT
+    TriggerOptionDisabledDesc = TEXT
+    TriggerOptionEasy = TEXT
+    TriggerOptionMedium = TEXT
+    TriggerOptionHard = TEXT
+    TriggerEventCurrent = TEXT
+    TriggerEventNew = TEXT
+    TriggerEventDel = TEXT
+    TriggerEventClo = TEXT
+    TriggerEventOptions = TEXT
+    TriggerEventType = TEXT
+    TriggerEventParameter = TEXT
+    TriggerEventParamValue = TEXT
+    TriggerEventDesc = TEXT
+    TriggerActionCurrent = TEXT
+    TriggerActionNew = TEXT
+    TriggerActionDel = TEXT
+    TriggerActionClo = TEXT
+    TriggerActionOptions = TEXT
+    TriggerActionType = TEXT
+    TriggerActionParameter = TEXT
+    TriggerActionParamValue = TEXT
+    TriggerActionDesc = TEXT
+    ScriptTypesTitle = TEXT
+    ScriptTypesDesc = TEXT
+    ScriptTypesSelectedScript = TEXT
+    ScriptTypesName = TEXT
+    ScriptTypesActions = TEXT
+    ScriptTypesActionType = TEXT
+    ScriptTypesActionDesc = TEXT
+    ScriptTypesAddScript = TEXT
+    ScriptTypesDelScript = TEXT
+    ScriptTypesCloScript = TEXT
+    ScriptTypesAddAction = TEXT
+    ScriptTypesDelAction = TEXT
+    ScriptTypesActionParam = TEXT
+    ScriptTypesCloAction = TEXT
+    ScriptTypesInsertMode = TEXT
+    ScriptTypesExtraParam = TEXT
+    ScriptTypesMoveUp = TEXT
+    ScriptTypesMoveDown = TEXT
+    SingleplayerParTimeEasy = TEXT
+    SingleplayerParTimeMedium = TEXT
+    SingleplayerParTimeHard = TEXT
+    SingleplayerOverParTitle = TEXT
+    SingleplayerOverParMessage = TEXT
+    SingleplayerUnderParTitle = TEXT
+    SingleplayerUnderParMessage = TEXT
+    LightingTitle = TEXT
+    LightingDesc = TEXT
+    LightingNormal = TEXT
+    LightingIonStorm = TEXT
+    LightingDominator = TEXT
+    LightingAmbient = TEXT
+    LightingGreen = TEXT
+    LightingRed = TEXT
+    LightingBlue = TEXT
+    LightingLevel = TEXT
+    LightingGround = TEXT
+    LightingNukeAmbientChangeRate = TEXT
+    LightingDominatorAmbientChangeRate = TEXT
+    PropertyBrushObList = TEXT
+    PropertyBrushBuilding = TEXT
+    PropertyBrushInfantry = TEXT
+    PropertyBrushVehicle = TEXT
+    PropertyBrushAircraft = TEXT
+    TheaterNameTem = TEXT
+    TheaterNameSno = TEXT
+    TheaterNameUrb = TEXT
+    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,
-then Zero Fanker advised to use inline hooks instead of Win32API message hooks to implement
-more functions and fix more bugs, and finally we comes to FA2sp. 
+## WRITE IN THE END
+- This project was developed after FA2Copy with still many bugs to fix, then Zero Fanker advised to use inline hooks instead of Win32API message hooks to implement more functions and fix more bugs, and finally we comes to FA2sp. 
 
-Thanks to AlexB, who gave me many suggestions and useful infomation while disassembling it.
-(Chatting with him in the midnight because of time difference is quite interesting, too)
+- Thanks to AlexB, who gave me many suggestions and useful infomation while disassembling it. Chatting with him in the midnight because of time difference is quite interesting, too.
 
-Zero Fanker has made a great contribution to the setting up of this project, with many
-essential suggestions put forward.
+- Zero Fanker has made a great contribution to the setting up of this project, with many essential suggestions put forward.
 
-Caco did quite much test works for this project, also bringing out many problems I haven't 
-noticed before.
+- Caco did quite much test works for this project, also bringing out many problems I haven't noticed before.
 
-tomsons26 has made great assistance on disassembing it(REALLY HELPFUL).
+- tomsons26 has made great assistance on disassembing it, REALLY HELPFUL.
 
-thomassneddon provided me with vxl drawing lib and drawing stuff assistence, without I cannot draw the VXL stuffs.
+- thomassneddon provided me with vxl drawing lib and drawing stuff assistence, without I cannot draw the VXL stuffs.
 
-(btw the code of FinalAlert 2 is really in a MESSY! Full of unnecessary constructors. I HATE IT!)
-
\ No newline at end of file +- btw the code of FinalAlert 2 is really in a MESSY! Full of unnecessary constructors. I HATE IT! \ No newline at end of file diff --git a/UNEXPLORED.md b/UNEXPLORED.md index 0ef1be6..64b2ccc 100644 --- a/UNEXPLORED.md +++ b/UNEXPLORED.md @@ -1,4 +1,4 @@ -
+```
 这个项目从2020年的2月开始,当时它还是FA2Copy,因为我已经受够了FA2不能复制一些东西。
 当时我也不会想到自己能在这个项目的进行过程中学到这么多的东西,回首看来,算上FA2PP我已经为这个项目写了4w多行代码。
 FA2Copy在当年的5月6号迎来了最后一个版本,当时我放弃FA2Copy的原因其实非常简单:没有办法实现更多想要的功能了。
@@ -31,4 +31,4 @@ FA2Copy在当年的5月6号迎来了最后一个版本,当时我放弃FA2Copy
 
 某书纪, 写于2021/08/20,19:03,1.0.4版本发布前夕
 (这个写英文太麻烦了,就中文吧)
-
\ No newline at end of file +``` \ No newline at end of file