diff --git a/FA2pp b/FA2pp index a48db6d..94568cb 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit a48db6d4c24678aa490cfa0316564f958a00f43e +Subproject commit 94568cbf175f54e019120ce370b867e03fee6c93 diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 0efc64b..bb49d49 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -123,6 +123,7 @@ + @@ -149,6 +150,7 @@ + @@ -176,6 +178,7 @@ + @@ -213,6 +216,7 @@ + diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters index 3232614..b993eb3 100644 --- a/FA2sp.vcxproj.filters +++ b/FA2sp.vcxproj.filters @@ -117,6 +117,9 @@ 头文件 + + 头文件 + @@ -275,6 +278,12 @@ 源文件 + + 源文件 + + + 源文件 + @@ -328,5 +337,8 @@ 资源文件 + + 资源文件 + \ No newline at end of file diff --git a/FA2sp/Ext/CAITriggerTypes/Body.cpp b/FA2sp/Ext/CAITriggerTypes/Body.cpp index 1fe8c6c..7836370 100644 --- a/FA2sp/Ext/CAITriggerTypes/Body.cpp +++ b/FA2sp/Ext/CAITriggerTypes/Body.cpp @@ -1,18 +1,120 @@ #include "Body.h" -CAITriggerTypes* CAITriggerTypesExt::Instance = nullptr; +#include +#include + +#include "../../Helpers/STDHelpers.h" +#include "../../Helpers/Translations.h" void CAITriggerTypesExt::ProgramStartupInit() { - RunTime::ResetMemoryContentAt(0x591B08, CAITriggerTypesExt::PreTranslateMessageExt); + RunTime::ResetMemoryContentAt(0x591B34, &CAITriggerTypesExt::OnInitDialogExt); + RunTime::ResetMemoryContentAt(0x591B08, &CAITriggerTypesExt::PreTranslateMessageExt); } -BOOL CAITriggerTypesExt::PreTranslateMessageExt(MSG* pMsg) +BOOL CAITriggerTypesExt::OnInitDialogExt() { - switch (pMsg->message) { + BOOL ret = this->CAITriggerTypes::OnInitDialog(); + if (!ret) + return FALSE; + + Translations::TranslateItem(this, "AITriggerTitle"); + Translations::TranslateItem(this, 50900, "AITriggerList"); + Translations::TranslateItem(this, 50901, "AITriggerName"); + Translations::TranslateItem(this, 50902, "AITriggerTeam1"); + Translations::TranslateItem(this, 50903, "AITriggerHouse"); + Translations::TranslateItem(this, 50904, "AITriggerTeam2"); + Translations::TranslateItem(this, 50905, "AITriggerTechlevel"); + Translations::TranslateItem(this, 50906, "AITriggerType"); + Translations::TranslateItem(this, 50907, "AITriggerWeight"); + Translations::TranslateItem(this, 50908, "AITriggerMinWeight"); + Translations::TranslateItem(this, 50909, "AITriggerMaxWeight"); + Translations::TranslateItem(this, 50910, "AITriggerMinDiff"); + Translations::TranslateItem(this, 50911, "AITriggerSide"); + Translations::TranslateItem(this, 50912, "AITriggerTechnoType"); + Translations::TranslateItem(this, 50913, "AITriggerCondition"); + Translations::TranslateItem(this, 50914, "AITriggerNumber"); + Translations::TranslateItem(this, 50915, "AITriggerAdditionalDesc"); + Translations::TranslateItem(this, 1210, "AITriggerData"); + + Translations::TranslateItem(this, 1218, "AITriggerEnabled"); + Translations::TranslateItem(this, 1154, "AITriggerAdd"); + Translations::TranslateItem(this, 1066, "AITriggerDel"); + Translations::TranslateItem(this, 1919, "AITriggerClo"); + Translations::TranslateItem(this, 1452, "AITriggerBaseDefense"); + Translations::TranslateItem(this, 1453, "AITriggerSkirmish"); + Translations::TranslateItem(this, 1424, "AITriggerEasy"); + Translations::TranslateItem(this, 1425, "AITriggerMedium"); + Translations::TranslateItem(this, 1426, "AITriggerHard"); - default: - break; + HWND hSides; + GetDlgItem(1456, &hSides); + while (::SendMessage(hSides, CB_DELETESTRING, 0, NULL) != CB_ERR); + + ::SendMessage(hSides, CB_ADDSTRING, NULL, (LPARAM)"0 - All"); + int i = 1; + if (auto sides = GlobalVars::INIFiles::FAData->GetSection("Sides")) + { + for (auto& itr : sides->EntitiesDictionary) + { + ppmfc::CString buffer; + buffer.Format("%d - %s", i++, itr.second); + ::SendMessage(hSides, CB_ADDSTRING, NULL, (LPARAM)buffer.m_pchData); + } } + + return TRUE; +} + +BOOL CAITriggerTypesExt::PreTranslateMessageExt(MSG* pMsg) +{ + switch (pMsg->message) + { + case WM_LBUTTONUP: + { + if (pMsg->hwnd == this->GetDlgItem(1919)->GetSafeHwnd()) + this->OnBNCloneAITriggerClicked(); + } + } + return this->FA2CDialog::PreTranslateMessage(pMsg); -} \ No newline at end of file +} + +void CAITriggerTypesExt::OnBNCloneAITriggerClicked() +{ + if (this->CCBAITriggerList.GetCount() > 0 && this->CCBAITriggerList.GetCurSel() != CB_ERR) + { + ppmfc::CString currentID; + this->CCBAITriggerList.GetWindowText(currentID); + STDHelpers::TrimIndex(currentID); + + ppmfc::CString key = INIClass::GetAvailableIndex(); + ppmfc::CString value, name; + + HWND hName; + GetDlgItem(1010, &hName); + auto nLen = ::GetWindowTextLength(hName); + auto pStr = new char[nLen + 1]; + ::GetWindowText(hName, pStr, nLen + 1); + name.Format("%s Clone", pStr); + delete[] pStr; + + value = name + ","; + auto& results = STDHelpers::SplitString(GlobalVars::INIFiles::CurrentDocument->GetString("AITriggerTypes", currentID)); + for (int i = 1; i < results.size() - 1; ++i) + value += (results[i] + ","); + value += results.back(); + + GlobalVars::INIFiles::CurrentDocument->WriteString("AITriggerTypes", key, value); + + GlobalVars::INIFiles::CurrentDocument->WriteString( + "AITriggerTypesEnable", key, + GlobalVars::INIFiles::CurrentDocument->GetString("AITriggerTypesEnable", currentID, "no") + ); + + int idx = this->CCBAITriggerList.AddString(key + " (" + name + ")"); + this->CCBAITriggerList.SetCurSel(idx); + + this->SetDlgItemText(1010, name); // update the name huh + } +} diff --git a/FA2sp/Ext/CAITriggerTypes/Body.h b/FA2sp/Ext/CAITriggerTypes/Body.h index 4d8f4b3..cdfc175 100644 --- a/FA2sp/Ext/CAITriggerTypes/Body.h +++ b/FA2sp/Ext/CAITriggerTypes/Body.h @@ -6,18 +6,18 @@ class NOVTABLE CAITriggerTypesExt : public CAITriggerTypes { public: - typedef BOOL(*FuncT_PTM)(MSG* pMsg); - - static CAITriggerTypes* Instance; + static void ProgramStartupInit(); - //hook function to replace in virtual function map + // + // Ext Functions + // + BOOL OnInitDialogExt(); BOOL PreTranslateMessageExt(MSG* pMsg); - static void ProgramStartupInit(); - CAITriggerTypesExt() {}; ~CAITriggerTypesExt() {}; + void OnBNCloneAITriggerClicked(); private: }; \ No newline at end of file diff --git a/FA2sp/Ext/FA2Expand.cpp b/FA2sp/Ext/FA2Expand.cpp index 9bb6e9d..9f1f13a 100644 --- a/FA2sp/Ext/FA2Expand.cpp +++ b/FA2sp/Ext/FA2Expand.cpp @@ -52,6 +52,7 @@ void __stdcall FA2Expand::ExeRun() { + CAITriggerTypesExt::ProgramStartupInit(); CFinalSunDlgExt::ProgramStartupInit(); CHousesExt::ProgramStartupInit(); // CIsoViewExt::ProgramStartupInit(); diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h index dd32087..df35fed 100644 --- a/FA2sp/FA2sp.Constants.h +++ b/FA2sp/FA2sp.Constants.h @@ -1,19 +1,14 @@ #pragma once -#define wstr(x) wstr_(x) -#define wstr_(x) L ## #x -#define str(x) str_(x) -#define str_(x) #x - constexpr int PRODUCT_MAJOR = 1; constexpr int PRODUCT_MINOR = 0; constexpr int PRODUCT_REVISION = 3; -constexpr char* PRODUCT_STR = "1.0.3"; +constexpr char* PRODUCT_STR = "1.0.4"; constexpr char* DISPLAY_STR = PRODUCT_STR; -constexpr char* VERSION_STRVER = "FA2sp 1.0.3"; +constexpr char* VERSION_STRVER = "FA2sp 1.0.4"; constexpr char* PRODUCT_NAME = "FA2sp"; -constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp 1.0.3."; +constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp 1.0.4."; // constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp - " __DATE__ " - " __TIME__; constexpr char* MUTEX_HASH_VAL = "b8097bca8590a4f46c975ebb43503aab2243ce7f1c87f12f7984dbe1"; diff --git a/FA2sp/FA2sp.cpp b/FA2sp/FA2sp.cpp index 97ab221..44849b8 100644 --- a/FA2sp/FA2sp.cpp +++ b/FA2sp/FA2sp.cpp @@ -35,6 +35,10 @@ int ExtConfigs::Waypoint_Background_Color; bool ExtConfigs::ExtWaypoints; int ExtConfigs::UndoRedoLimit; bool ExtConfigs::UseRGBHouseColor; +bool ExtConfigs::SaveMap; +bool ExtConfigs::SaveMap_AutoSave; +int ExtConfigs::SaveMap_AutoSave_Interval; +int ExtConfigs::SaveMap_AutoSave_MaxCount; MultimapHelper Variables::Rules = { &GlobalVars::INIFiles::Rules(), &GlobalVars::INIFiles::CurrentDocument() }; @@ -81,6 +85,19 @@ void FA2sp::ExtConfigsInitialize() ExtConfigs::UndoRedoLimit = fadata.GetInteger("ExtConfigs", "UndoRedoLimit", 16); ExtConfigs::UseRGBHouseColor = fadata.GetBool("ExtConfigs", "UseRGBHouseColor"); + + if (ExtConfigs::SaveMap = fadata.GetBool("ExtConfigs", "SaveMap")) + { + if (ExtConfigs::SaveMap_AutoSave = fadata.GetBool("ExtConfigs", "SaveMap.AutoSave")) + { + ExtConfigs::SaveMap_AutoSave_Interval = fadata.GetInteger("ExtConfigs", "SaveMap.AutoSave.Interval", 300); + ExtConfigs::SaveMap_AutoSave_MaxCount = fadata.GetInteger("ExtConfigs", "SaveMap.AutoSave.MaxCount", 10); + } + else + { + ExtConfigs::SaveMap_AutoSave_Interval = -1; + } + } } // DllMain diff --git a/FA2sp/FA2sp.h b/FA2sp/FA2sp.h index 6410f86..d5468f9 100644 --- a/FA2sp/FA2sp.h +++ b/FA2sp/FA2sp.h @@ -45,6 +45,10 @@ class ExtConfigs static bool ExtWaypoints; static int UndoRedoLimit; static bool UseRGBHouseColor; + static bool SaveMap; + static bool SaveMap_AutoSave; + static int SaveMap_AutoSave_Interval; + static int SaveMap_AutoSave_MaxCount; }; class Variables diff --git a/FA2sp/Miscs/Exception.cpp b/FA2sp/Miscs/Exception.cpp index 4dfc0cf..c47dae7 100644 --- a/FA2sp/Miscs/Exception.cpp +++ b/FA2sp/Miscs/Exception.cpp @@ -194,10 +194,10 @@ std::wstring Exception::FullDump( } //ifdef DUMP_EXTENSIVE -DEFINE_HOOK(434920, Exception_Handler, 7) -{ - //GET(int, code, ECX); - GET(LPEXCEPTION_POINTERS, pExs, EDX); - Exception::ExceptionHandler(pExs); -} +//DEFINE_HOOK(434920, Exception_Handler, 7) +//{ +// //GET(int, code, ECX); +// GET(LPEXCEPTION_POINTERS, pExs, EDX); +// Exception::ExceptionHandler(pExs); +//} //endif diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp new file mode 100644 index 0000000..ce3fb4c --- /dev/null +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -0,0 +1,247 @@ +#include + +#include +#include +#include +#include + +#include "../FA2sp.h" +#include "../FA2sp.Constants.h" + +#include +#include + +// FA2 SaveMap is almost O(N^4), who wrote that? +DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) +{ + if (ExtConfigs::SaveMap) + { + GET(INIClass*, pINI, EAX); + GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x3F4, 0x36C)); + REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); + + pThis->MyViewFrame.StatusBar.SetWindowText("Saving..."); + pThis->MyViewFrame.StatusBar.UpdateWindow(); + + CloseHandle( + CreateFile(filepath, GENERIC_WRITE, NULL, nullptr, TRUNCATE_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL) + ); + auto hFile = CreateFile(filepath, GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL); + + std::stringstream ss; + ss << + "; Map created with FinalAlert 2(tm) Mission Editor\n" + "; Get it at http://www.westwood.com\n" + "; note that all comments were truncated\n" + "\n" + "; This FA2 uses FA2sp created by secsome\n" + "; Get the lastest dll at https://github.com/secsome/FA2sp\n" + "; Current version : "; + ss << PRODUCT_STR; + ss << "\n\n"; + + for (auto& section : pINI->Dict) + { + ss << "["; + ss << section.first; + ss << "]\n"; + for (auto& pair : section.second.EntitiesDictionary) + { + ss << pair.first; + ss << "="; + ss << pair.second; + ss << "\n"; + } + ss << "\n"; + } + + WriteFile(hFile, ss.str().c_str(), ss.str().length(), nullptr, nullptr); + CloseHandle(hFile); + + return 0x42A859; + } + + return 0; +} + +DEFINE_HOOK(42B30F, CFinalSunDlg_SaveMap_SkipMapDTOR, 7) +{ + return ExtConfigs::SaveMap ? 0x42B323 : 0; +} + +DEFINE_HOOK(42B2AF, CFinalSunDlg_SaveMap_SkipDeleteFile, 7) +{ + return ExtConfigs::SaveMap ? 0x42B2C2 : 0; +} + +DEFINE_HOOK(42A8F5, CFinalSunDlg_SaveMap_ReplaceCopyFile, 7) +{ + if (!ExtConfigs::SaveMap) + return 0; + + REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); + + HANDLE hFile = + CreateFile(filepath, GENERIC_READ, NULL, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + return 0x42A92D; + } + return 0x42A911; +} + +DEFINE_HOOK(42B2EA, CFinalSunDlg_SaveMap_SkipStringDTOR, C) +{ + return ExtConfigs::SaveMap ? 0x42B30F : 0; +} + +class SaveMapExt +{ +private: + static UINT_PTR Timer; +public: + static bool IsAutoSaving; + static ppmfc::CString FileName; + + static void ResetTimer() + { + StopTimer(); + if (ExtConfigs::SaveMap_AutoSave_Interval >= 30) + { + if (Timer = SetTimer(NULL, NULL, 1000 * ExtConfigs::SaveMap_AutoSave_Interval, SaveMapCallback)) + Logger::Debug("Successfully created timer with ID = %p\n", Timer); + else + Logger::Debug("Failed to create timer! Auto-save is currently unable to use"); + } + } + + static void StopTimer() + { + if (Timer != NULL) + { + KillTimer(NULL, Timer); + Timer = NULL; + } + } + + static void RemoveEarlySaves() + { + if (ExtConfigs::SaveMap_AutoSave_MaxCount != -1) + { + struct FileTimeComparator + { + bool operator()(const FILETIME& a, const FILETIME& b) const { return CompareFileTime(&a, &b) == -1; } + }; + + std::map m; + + ppmfc::CString buffer = GlobalVars::ExePath(); + buffer += "\\AutoSaves\\autosave-*.map"; + WIN32_FIND_DATA Data; + auto hFindData = FindFirstFile(buffer, &Data); + while (hFindData != INVALID_HANDLE_VALUE) + { + m[Data.ftLastWriteTime] = Data.cFileName; + if (!FindNextFile(hFindData, &Data)) + break; + } + + int count = m.size() - ExtConfigs::SaveMap_AutoSave_MaxCount; + if (count <= 0) + return; + + auto& itr = m.begin(); + while (count != 0) + { + buffer.Format("%s\\AutoSaves\\%s", GlobalVars::ExePath(), itr->second); + DeleteFile(buffer); + ++itr; + --count; + } + } + } + + static void CALLBACK SaveMapCallback(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime) + { + if (!GlobalVars::CMapData->MapWidthPlusHeight || !GlobalVars::CMapData->FieldDataAllocated) + { + StopTimer(); + return; + } + + SYSTEMTIME time; + GetLocalTime(&time); + + ppmfc::CString buffer = GlobalVars::ExePath(); + buffer += "\\AutoSaves"; + CreateDirectory(buffer, nullptr); + + buffer.Format("%s\\AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", + GlobalVars::ExePath(), + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond, + time.wMilliseconds + ); + + IsAutoSaving = true; + GlobalVars::Dialogs::CFinalSunDlg->SaveMap(buffer); + IsAutoSaving = false; + + RemoveEarlySaves(); + } +}; + +bool SaveMapExt::IsAutoSaving = false; +UINT_PTR SaveMapExt::Timer = NULL; + + +DEFINE_HOOK(426E50, CFinalSunDlg_SaveMap_AutoSave_StopTimer, 7) +{ + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(42B3AC, CFinalSunDlg_SaveMap_AutoSave_ResetTimer, 7) +{ + SaveMapExt::ResetTimer(); + return 0; +} + +DEFINE_HOOK(427949, CFinalSunDlg_SaveMap_AutoSave_SkipDialog, A) +{ + return SaveMapExt::IsAutoSaving ? 0x428CF6 : 0; +} + +DEFINE_HOOK(42B294, CFinalSunDlg_SaveMap_AutoSave_SkipEditFilesMenu, 8) +{ + return SaveMapExt::IsAutoSaving ? 0x42B2AF : 0; +} + +DEFINE_HOOK(437D84, CFinalSunDlg_LoadMap_StopTimer, 5) +{ + if (ExtConfigs::SaveMap_AutoSave) + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(438D90, CFinalSunDlg_LoadMap_ResetTimer, 7) +{ + if (ExtConfigs::SaveMap_AutoSave && GlobalVars::CMapData->MapWidthPlusHeight) + SaveMapExt::ResetTimer(); + return 0; +} + +DEFINE_HOOK(42CBE0, CFinalSunDlg_CreateMap_StopTimer, 5) +{ + if (ExtConfigs::SaveMap_AutoSave) + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(42E18E, CFinalSunDlg_CreateMap_ResetTimer, 7) +{ + if (ExtConfigs::SaveMap_AutoSave && GlobalVars::CMapData->MapWidthPlusHeight) + SaveMapExt::ResetTimer(); + return 0; +} \ No newline at end of file diff --git a/FA2sp/UI/CAITriggerTypes.rc b/FA2sp/UI/CAITriggerTypes.rc new file mode 100644 index 0000000..bafaabf --- /dev/null +++ b/FA2sp/UI/CAITriggerTypes.rc @@ -0,0 +1,51 @@ +#include + +205 DIALOG 0, 0, 303, 234 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "AI Trigger Types" +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +FONT 8, "Tahoma" +{ + CONTROL "AI Trigger:", 50900, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 7, 52, 16 + CONTROL "", 1199, COMBOBOX, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 7, 236, 307 + CONTROL "Name:", 50901, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 63, 43, 11 + CONTROL "", 1010, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 64, 94, 13 + CONTROL "Teamtype #1:", 50902, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 80, 43, 17 + CONTROL "", 1204, COMBOBOX, CBS_DROPDOWN | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 81, 236, 81 + CONTROL "House:", 50903, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 165, 64, 50, 16 + CONTROL "", 1205, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 220, 64, 76, 207 + CONTROL "Teamtype #2:", 50904, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 98, 43, 17 + CONTROL "", 1206, COMBOBOX, CBS_DROPDOWN | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 98, 235, 81 + CONTROL "Techlevel:", 50905, STATIC, SS_LEFT | WS_CHILD | WS_GROUP, 280, 206, 0, 0 + CONTROL "", 1162, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VSCROLL | WS_TABSTOP, 288, 222, 0, 0 + CONTROL "Type:", 50906, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 44, 53, 17 + CONTROL "", 1163, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 45, 235, 71 + CONTROL "Data:", 1210, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 265, 204, 0, 0 + CONTROL "", 1211, COMBOBOX, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CHILD | WS_VSCROLL | WS_TABSTOP, 287, 222, 0, 0 + CONTROL "Weight:", 50907, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 150, 33, 11 + CONTROL "", 1213, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 59, 148, 56, 13 + CONTROL "MinWeight:", 50908, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 165, 38, 11 + CONTROL "", 1215, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 59, 164, 56, 13 + CONTROL "MaxWeight:", 50909, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 125, 165, 40, 11 + CONTROL "", 1216, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 180, 164, 54, 13 + CONTROL "MinDiff:", 50910, STATIC, SS_LEFT | WS_CHILD | WS_GROUP, 279, 222, 0, 0 + CONTROL "", 1165, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_BORDER | WS_TABSTOP, 291, 222, 0, 0 + CONTROL "Multi-Side:", 50911, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 115, 33, 12 + CONTROL "Delete", 1066, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 240, 23, 53, 15 + CONTROL "Add", 1154, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 121, 23, 53, 15 + CONTROL "Clone", 1919, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 181, 23, 53, 15 + CONTROL "Enabled", 1218, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 23, 76, 11 + CONTROL "Easy", 1424, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 59, 133, 42, 13 + CONTROL "Medium", 1425, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 124, 132, 42, 13 + CONTROL "Hard", 1426, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 199, 132, 42, 13 + CONTROL "Base defense", 1452, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 124, 116, 67, 13 + CONTROL "Available in Skirmish", 1453, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 199, 116, 85, 14 + CONTROL "", 1456, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 116, 56, 63 + CONTROL "Unittype (X):", 50912, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 171, 200, 51, 10 + CONTROL "", 1149, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 171, 212, 125, 255 + CONTROL "Condition:", 50913, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 8, 200, 50, 11 + CONTROL "", 1449, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 8, 212, 95, 82 + CONTROL "", 1450, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 109, 212, 54, 13 + CONTROL "Number (N):", 50914, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 110, 200, 56, 11 + CONTROL "Additional parameters for the appropiate AI Trigger Types:", 50915, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 188, 295, 12 +} \ No newline at end of file diff --git a/README.md b/README.md index 098f2ba..29a6359 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,13 @@ Compile Using C++ Standard Now: C++14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP CHANGELOG //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +======================= 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) @@ -151,6 +158,10 @@ COLORREF - R,G,B each of them is in [0,255] +) 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 = BOOLEAN ; Determines if FA2 will save map using a faster method + +) SaveMap.AutoSave = BOOLEAN ; Determines if FA2 will save map automatically after one manually saving + +) SaveMap.AutoSave.Interval = INTERGER ; 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 = INTERGER ; How many saving should FA2 keep, set to -1 will disable the auto cleanning, defaults to 10 +) [Sides] ** (** means Essensial, fa2sp need this section to work properly) {Contains a list of sides registered in rules} \\\ e.g. @@ -434,6 +445,33 @@ COLORREF - R,G,B each of them is in [0,255] +) Menu.Layers.Smudges = TEXT +) Menu.Layers.Tubes = TEXT +) Menu.Layers.Bounds = 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 @@ -540,11 +578,6 @@ COLORREF - R,G,B each of them is in [0,255] +) ScriptTypesMoveUp = TEXT +) ScriptTypesMoveDown = TEXT -- WORK IN PROGRESS - - Support for taskforces & ai triggers - - Custom palettes - - ... - - 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 @@ -564,9 +597,37 @@ 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. (btw the code of FinalAlert 2 is really in a MESSY! Full of unnecessary constructors. I HATE IT!) - -- CONTACT ME -EMAIL : 3179369262@qq.com -Discord : secsome#5043 -NO OTHER AVAILABLE METHODS ... FOR NOW ;D + +Ŀ20202¿ʼʱFA2CopyΪѾܹFA2ܸһЩ +ʱҲ뵽ԼĿĽйѧôĶ׿FA2PPѾΪĿд4wд롣 +FA2Copyڵ56ӭһ汾ʱҷFA2Copyԭʵdz򵥣ûа취ʵָҪĹˡ +ʱZFңҽ˻SyringeչȻҲʹˣ722ſʼFA2+Ľ֮á +Ŀ֮ԽFA2spԭѾ벻ˣKerb˵secsome's patchҾûͦеģҲ޷ +һʼҲһһϲͨСףԼմOIҲǵһνӴĿһʼĴ·ԣɲ鿴FA2Copyȫҳһ硣 +ҲһĿļܹܹдԼҿĹȥĴˣҲһ + +ڿʱƿCINI࣬FA2ΪõSTLmapһչֱӾ͸ҸſˡһʼҲ͵AlexBINIãҲҪл +˽ɫ޸ҲġǰʱǰƣҾȥһVC5VC5mapֱӰ˳ʱһһضŴһ +ıȽϣһİѺҳӦȥ + +ٺҲûʲô˵ˣӡ̵ľǵһԼFA2ͼݴ洢ࣨDrawing.hеImageDataClassϡǵԼһ +صһذÿԱ;ڿ˵顣 + +Ҫ˵Լʲôܣֱ۵ľԼдľдˡFA2ĺܶ붼ʺɽǶmapO(n^2)ʻǷŵ߰ĽݣҿʱỳԼ +DzǿȷĴˣҪԼ⻹ʲôʵԣFA2ҲһϹĹߣҲûпǵ20һһ +ľͼԭYRRA2˵ĹѾ´࣬һЩʺɽҲ̫Ӱ졣ǵҶõʱҾһҪǵдʱһҪ +ԼдЧʾΡ + +̸̸FA2Ļͼ⣬FA2Ļͼڵһζȡijزĵʱлģֻ֮ǽڴȡbltȥˡ˼·ڿȻһܺõ˼·Ч +ؿFA2ڴռãRSҷһ֮ڹ滻FA2ĽؾߣȾԼζĻơdzӣ +֮ǰҲΪԭ;ˡʵֻһڵʱʵһͦȵģҲҪ͵èĻͼ⣬ԼÿһVXLSE139 +賿ĵ㡣û͵èĿһVXLĻƣͼֻ֧᲻֮ + +ڿиҰкܶ࣬ԱȻӳ汾BUGǹͬŬFA2øӺࡣﲻһһлˡ + +ĿԺҲ£ֻFA2spĵ߼BUG޸ˣĶΪ +ΪһԴĿȻҲӭʵĿPR棬ҪidbҲϵңҲṩ϶ܶBUGˣ + +ijͣ д2021/08/2019:031.0.4汾ǰϦ +||дӢ̫鷳ˣİ|| \ No newline at end of file