From dbfd24e5c69de5a89d8a60edf1299ac01a2740a8 Mon Sep 17 00:00:00 2001 From: ZivDero Date: Mon, 4 Nov 2024 00:15:24 +0300 Subject: [PATCH 01/69] Implement SW sidebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: NetsuNegi Co-authored-by: 绯红热茶 <335958461@qq.com> --- CREDITS.md | 2 + Phobos.vcxproj | 9 + docs/AI-Scripting-and-Mapping.md | 6 + docs/User-Interface.md | 33 ++ docs/Whats-New.md | 1 + src/Commands/Commands.cpp | 14 + src/Commands/FireTacticalSW.h | 59 +++ src/Commands/ToggleSWSidebar.cpp | 38 ++ src/Commands/ToggleSWSidebar.h | 14 + src/Ext/SWType/Body.cpp | 44 ++ src/Ext/SWType/Body.h | 38 ++ src/Ext/SWType/SWHelpers.cpp | 33 ++ src/Ext/Side/Body.cpp | 9 + src/Ext/Side/Body.h | 9 + src/Ext/Sidebar/Body.cpp | 2 + src/Ext/Sidebar/Body.h | 4 + src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 154 ++++++ src/Ext/Sidebar/SWSidebar/SWColumnClass.h | 28 + src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 494 ++++++++++++++++++ src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 48 ++ .../Sidebar/SWSidebar/TacticalButtonClass.cpp | 316 +++++++++++ .../Sidebar/SWSidebar/TacticalButtonClass.h | 48 ++ src/Misc/PhobosToolTip.cpp | 46 ++ src/Phobos.INI.cpp | 24 + src/Phobos.h | 4 + src/Utilities/AresAddressTable.cpp | 10 + src/Utilities/AresFunctions.h | 29 + 27 files changed, 1516 insertions(+) create mode 100644 src/Commands/FireTacticalSW.h create mode 100644 src/Commands/ToggleSWSidebar.cpp create mode 100644 src/Commands/ToggleSWSidebar.h create mode 100644 src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp create mode 100644 src/Ext/Sidebar/SWSidebar/SWColumnClass.h create mode 100644 src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp create mode 100644 src/Ext/Sidebar/SWSidebar/SWSidebarClass.h create mode 100644 src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp create mode 100644 src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h diff --git a/CREDITS.md b/CREDITS.md index 1ddaaf1b51..52cd651973 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -342,6 +342,7 @@ This page lists all the individual contributions to the project by their author. - Disguised units not using the correct palette if target has custom palette bugfix - Tunnel/Walk/Mech locomotor being stuck when moving too fast bugfix - Assign Super Weapon cameo to any sidebar tab + - Exclusive SuperWeapon Sidebar - **Apollo** - Translucent SHP drawing patches - **ststl** - Customizable ShowTimer priority of superweapons @@ -369,6 +370,7 @@ This page lists all the individual contributions to the project by their author. - Allow to change the speed of gas particles - **CrimRecya** - Fix `LimboKill` not working reliably + - Exclusive SuperWeapon Sidebar - **Ollerus** - Build limit group enhancement - Customizable rocker amplitude diff --git a/Phobos.vcxproj b/Phobos.vcxproj index 32890abf5e..c2434c0c12 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -18,6 +18,10 @@ + + + + @@ -183,6 +187,11 @@ + + + + + diff --git a/docs/AI-Scripting-and-Mapping.md b/docs/AI-Scripting-and-Mapping.md index 6794af4673..e2fd3fce5f 100644 --- a/docs/AI-Scripting-and-Mapping.md +++ b/docs/AI-Scripting-and-Mapping.md @@ -27,6 +27,12 @@ In rulesmd.ini: RepairBaseNodes=false ; boolean ``` +In rulesmd.ini: +```ini +[General] +RepairBaseNodes=false,false,false ; list of 3 booleans indicating whether AI repair basenodes in Easy / Normal / Difficult game diffculty. +``` + In map file: ```ini [Country House] diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 2e1ad86969..51e1530779 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -578,6 +578,39 @@ In `RA2MD.ini`: [Phobos] ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enabled. ``` + +### Exclusive SuperWeapon Sidebar + +- It is possible to put sw cameos on the left of screen like C&C3 when `ExclusiveSuperWeaponSidebar` is true. +- In theory, it should be compatible with Ares +- Cameos arranged in a pyramid shape. +- `ExclusiveSWSidebar.Interval` specific how many leptons between two columns. +- `ExclusiveSuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. +- `ExclusiveSWSidebar.MaxColumn` controls that maximum count of columns. +- You can also launch first 10 SW by hotkey. + +In `uimd.ini`: +```ini +[Sidebar] +ExclusiveSWSidebar=false ; boolean +ExclusiveSWSidebar.Interval=0 ; integer +ExclusiveSWSidebar.Max=0 ; integer +ExclusiveSWSidebar.MaxColumn= ; integer +``` + +In `rulesmd.ini` +```ini +[SOMESIDE] +ExclusiveSWSidebar.TopPCX= ; filename - including the .pcx extension +ExclusiveSWSidebar.CenterPCX= ; filename - including the .pcx extension +ExclusiveSWSidebar.BottomPCX= ; filename - including the .pcx extension +ExclusiveSWSidebar.ToggleShape= ; filename - including the .shp extension + +[SOMESW] +AllowInExclusiveSidebar=true ; boolean +ExclusiveSidebar.PriorityHouses= ; list of house types +ExclusiveSidebar.RequiredHouses= ; list of house types +``` ## Miscellanous ### Skip saving game on starting a new campaign diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 099dcc728e..5950fc3203 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -466,6 +466,7 @@ New: - Warheads parasite removal customization (by Starkku) - Allow infantry to use land sequences in water (by Starkku) - `` can now be used as owner for pre-placed objects on skirmish and multiplayer maps (by Starkku) +- Exclusive SuperWeapon Sidebar (by NetsuNegi & CrimRecya) Vanilla fixes: - Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy) diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index 712a596467..4f73ff25fc 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -10,6 +10,8 @@ #include "ToggleDigitalDisplay.h" #include "ToggleDesignatorRange.h" #include "SaveVariablesToFile.h" +#include "ToggleSWSidebar.h" +#include "FireTacticalSW.h" DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) { @@ -19,6 +21,18 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); MakeCommand(); + MakeCommand(); + + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); + MakeCommand>(); if (Phobos::Config::DevelopmentCommands) { diff --git a/src/Commands/FireTacticalSW.h b/src/Commands/FireTacticalSW.h new file mode 100644 index 0000000000..9e634ffbf9 --- /dev/null +++ b/src/Commands/FireTacticalSW.h @@ -0,0 +1,59 @@ +#pragma once +#include "Commands.h" + +#include +#include + +template +class FireTacticalSWCommandClass : public CommandClass +{ + virtual const char* GetName() const override; + virtual const wchar_t* GetUIName() const override; + virtual const wchar_t* GetUICategory() const override; + virtual const wchar_t* GetUIDescription() const override; + virtual void Execute(WWKey eInput) const override; +}; + +template +inline const char* FireTacticalSWCommandClass::GetName() const +{ + _snprintf_s(Phobos::readBuffer, Phobos::readLength, "FireTacticalSW%d", Index); + return Phobos::readBuffer; +} + +template +inline const wchar_t* FireTacticalSWCommandClass::GetUIName() const +{ + _snwprintf_s(Phobos::wideBuffer, Phobos::readLength, L"Fire Super Weapon %d", Index); + return StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX", Phobos::wideBuffer); +} + +template +inline const wchar_t* FireTacticalSWCommandClass::GetUICategory() const +{ + return CATEGORY_CONTROL; +} + +template +inline const wchar_t* FireTacticalSWCommandClass::GetUIDescription() const +{ + _snwprintf_s(Phobos::wideBuffer, Phobos::readLength, L"Fires Super Weapon %d.", Index); + return StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX_DESC", Phobos::wideBuffer); +} + +template +inline void FireTacticalSWCommandClass::Execute(WWKey eInput) const +{ + if (!SWSidebarClass::IsEnabled()) + return; + + const auto& columns = SWSidebarClass::Global()->Columns; + + if (columns.empty()) + return; + + const auto& buttons = columns.front()->Buttons; + + if (buttons.size() > Index) + buttons[Index]->LaunchSuper(); +} diff --git a/src/Commands/ToggleSWSidebar.cpp b/src/Commands/ToggleSWSidebar.cpp new file mode 100644 index 0000000000..1fcd08d86d --- /dev/null +++ b/src/Commands/ToggleSWSidebar.cpp @@ -0,0 +1,38 @@ +#include "ToggleSWSidebar.h" +#include + +#include +#include + +const char* ToggleSWSidebar::GetName() const +{ + return "Toggle Super Weapon Sidebar"; +} + +const wchar_t* ToggleSWSidebar::GetUIName() const +{ + return GeneralUtils::LoadStringUnlessMissing("TXT_TOGGLE_SW_SIDEBAR", L"Toggle Super Weapon Sidebar"); +} + +const wchar_t* ToggleSWSidebar::GetUICategory() const +{ + return CATEGORY_INTERFACE; +} + +const wchar_t* ToggleSWSidebar::GetUIDescription() const +{ + return GeneralUtils::LoadStringUnlessMissing("TXT_TOGGLE_SW_SIDEBAR_DESC", L"Toggle the Super Weapon Sidebar."); +} + +void ToggleSWSidebar::Execute(WWKey eInput) const +{ + ToggleSWButtonClass::SwitchSidebar(); + + if (SidebarExt::Global()->SWSidebar_Enable) + MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("TXT_EX_SW_SIDEBAR_ENABLE", L"Super Weapon Sidebar Enabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); + else + MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("TXT_EX_SW_SIDEBAR_DISABLE", L"Super Weapon Sidebar Disabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); + + if (SWSidebarClass::Global()->CurrentColumn) + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); +} diff --git a/src/Commands/ToggleSWSidebar.h b/src/Commands/ToggleSWSidebar.h new file mode 100644 index 0000000000..e12ac13364 --- /dev/null +++ b/src/Commands/ToggleSWSidebar.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Commands.h" + +// Display damage strings +class ToggleSWSidebar : public CommandClass +{ +public: + virtual const char* GetName() const override; + virtual const wchar_t* GetUIName() const override; + virtual const wchar_t* GetUICategory() const override; + virtual const wchar_t* GetUIDescription() const override; + virtual void Execute(WWKey eInput) const override; +}; diff --git a/src/Ext/SWType/Body.cpp b/src/Ext/SWType/Body.cpp index 15c847f068..7c503da469 100644 --- a/src/Ext/SWType/Body.cpp +++ b/src/Ext/SWType/Body.cpp @@ -12,6 +12,14 @@ void SWTypeExt::ExtData::Serialize(T& Stm) { Stm .Process(this->Money_Amount) + .Process(this->EVA_Impatient) + .Process(this->EVA_InsufficientFunds) + .Process(this->EVA_SelectTarget) + .Process(this->SW_UseAITargeting) + .Process(this->SW_AutoFire) + .Process(this->SW_ManualFire) + .Process(this->SW_ShowCameo) + .Process(this->SW_Unstoppable) .Process(this->SW_Inhibitors) .Process(this->SW_AnyInhibitor) .Process(this->SW_Designators) @@ -26,6 +34,10 @@ void SWTypeExt::ExtData::Serialize(T& Stm) .Process(this->SW_PostDependent) .Process(this->SW_MaxCount) .Process(this->SW_Shots) + .Process(this->Message_CannotFire) + .Process(this->Message_InsufficientFunds) + .Process(this->Message_ColorScheme) + .Process(this->Message_FirerColor) .Process(this->UIDescription) .Process(this->CameoPriority) .Process(this->LimboDelivery_Types) @@ -50,6 +62,11 @@ void SWTypeExt::ExtData::Serialize(T& Stm) .Process(this->Convert_Pairs) .Process(this->ShowDesignatorRange) .Process(this->TabIndex) + .Process(this->ExclusiveSidebar_Allow) + .Process(this->ExclusiveSidebar_PriorityHouses) + .Process(this->ExclusiveSidebar_RequiredHouses) + .Process(this->SidebarPal) + .Process(this->SidebarPCX) .Process(this->UseWeeds) .Process(this->UseWeeds_Amount) .Process(this->UseWeeds_StorageTimer) @@ -75,6 +92,14 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) // from ares this->Money_Amount.Read(exINI, pSection, "Money.Amount"); + this->EVA_Impatient.Read(exINI, pSection, "EVA.Impatient"); + this->EVA_InsufficientFunds.Read(exINI, pSection, "EVA.InsufficientFunds"); + this->EVA_SelectTarget.Read(exINI, pSection, "EVA.SelectTarget"); + this->SW_UseAITargeting.Read(exINI, pSection, "SW.UseAITargeting"); + this->SW_AutoFire.Read(exINI, pSection, "SW.AutoFire"); + this->SW_ManualFire.Read(exINI, pSection, "SW.ManualFire"); + this->SW_ShowCameo.Read(exINI, pSection, "SW.ShowCameo"); + this->SW_Unstoppable.Read(exINI, pSection, "SW.Unstoppable"); this->SW_Inhibitors.Read(exINI, pSection, "SW.Inhibitors"); this->SW_AnyInhibitor.Read(exINI, pSection, "SW.AnyInhibitor"); this->SW_Designators.Read(exINI, pSection, "SW.Designators"); @@ -90,6 +115,18 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->SW_MaxCount.Read(exINI, pSection, "SW.MaxCount"); this->SW_Shots.Read(exINI, pSection, "SW.Shots"); + this->Message_CannotFire.Read(exINI, pSection, "Message.CannotFire"); + this->Message_InsufficientFunds.Read(exINI, pSection, "Message.InsufficientFunds"); + + // messages and their properties + this->Message_FirerColor.Read(exINI, pSection, "Message.FirerColor"); + if (pINI->ReadString(pSection, "Message.Color", NONE_STR, Phobos::readBuffer)) + { + this->Message_ColorScheme = ColorScheme::FindIndex(Phobos::readBuffer); + if (this->Message_ColorScheme < 0) + Debug::INIParseFailed(pSection, "Message.Color", Phobos::readBuffer, "Expected a valid color scheme name."); + } + this->UIDescription.Read(exINI, pSection, "UIDescription"); this->CameoPriority.Read(exINI, pSection, "CameoPriority"); this->LimboDelivery_Types.Read(exINI, pSection, "LimboDelivery.Types"); @@ -176,6 +213,13 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->TabIndex.Read(exINI, pSection, "TabIndex"); GeneralUtils::IntValidCheck(&this->TabIndex, pSection, "TabIndex", 1, 0, 3); + + this->ExclusiveSidebar_Allow.Read(exINI, pSection, "ExclusiveSidebar.Allow"); + this->ExclusiveSidebar_PriorityHouses = pINI->ReadHouseTypesList(pSection, "ExclusiveSidebar.PriorityHouses", this->ExclusiveSidebar_PriorityHouses); + this->ExclusiveSidebar_RequiredHouses = pINI->ReadHouseTypesList(pSection, "ExclusiveSidebar.RequiredHouses", this->ExclusiveSidebar_RequiredHouses); + + this->SidebarPal.LoadFromINI(pINI, pSection, "SidebarPalette"); + this->SidebarPCX.Read(pINI, pSection, "SidebarPCX"); this->UseWeeds.Read(exINI, pSection, "UseWeeds"); this->UseWeeds_Amount.Read(exINI, pSection, "UseWeeds.Amount"); diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index 2232ca71f6..a740a78b41 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -24,6 +24,14 @@ class SWTypeExt //Ares 0.A Valueable Money_Amount; + ValueableIdx EVA_Impatient; + ValueableIdx EVA_InsufficientFunds; + ValueableIdx EVA_SelectTarget; + Valueable SW_UseAITargeting; + Valueable SW_AutoFire; + Valueable SW_ManualFire; + Valueable SW_ShowCameo; + Valueable SW_Unstoppable; ValueableVector SW_Inhibitors; Valueable SW_AnyInhibitor; ValueableVector SW_Designators; @@ -40,6 +48,11 @@ class SWTypeExt ValueableIdx SW_PostDependent; Valueable SW_MaxCount; + Valueable Message_CannotFire; + Valueable Message_InsufficientFunds; + Valueable Message_ColorScheme; + Valueable Message_FirerColor; + Valueable UIDescription; Valueable CameoPriority; ValueableVector LimboDelivery_Types; @@ -64,6 +77,13 @@ class SWTypeExt Valueable ShowDesignatorRange; Valueable TabIndex; + + Valueable ExclusiveSidebar_Allow; + DWORD ExclusiveSidebar_PriorityHouses; + DWORD ExclusiveSidebar_RequiredHouses; + + CustomPalette SidebarPal; + PhobosPCXFile SidebarPCX; std::vector> LimboDelivery_RandomWeightsData; std::vector> SW_Next_RandomWeightsData; @@ -82,6 +102,14 @@ class SWTypeExt ExtData(SuperWeaponTypeClass* OwnerObject) : Extension(OwnerObject) , Money_Amount { 0 } + , EVA_Impatient { -1 } + , EVA_InsufficientFunds { -1 } + , EVA_SelectTarget { -1 } + , SW_UseAITargeting { false } + , SW_AutoFire { false } + , SW_ManualFire { true } + , SW_ShowCameo { true } + , SW_Unstoppable { false } , SW_Inhibitors {} , SW_AnyInhibitor { false } , SW_Designators { } @@ -96,6 +124,10 @@ class SWTypeExt , SW_PostDependent {} , SW_MaxCount { -1 } , SW_Shots { -1 } + , Message_CannotFire {} + , Message_InsufficientFunds {} + , Message_ColorScheme { -1 } + , Message_FirerColor { false } , UIDescription {} , CameoPriority { 0 } , LimboDelivery_Types {} @@ -120,6 +152,11 @@ class SWTypeExt , Convert_Pairs {} , ShowDesignatorRange { true } , TabIndex { 1 } + , ExclusiveSidebar_Allow { true } + , ExclusiveSidebar_PriorityHouses { 0u } + , ExclusiveSidebar_RequiredHouses { 0xFFFFFFFFu } + , SidebarPal {} + , SidebarPCX {} , UseWeeds { false } , UseWeeds_Amount { RulesClass::Instance->WeedCapacity } , UseWeeds_StorageTimer { false } @@ -141,6 +178,7 @@ class SWTypeExt bool IsLaunchSite(BuildingClass* pBuilding) const; std::pair GetLaunchSiteRange(BuildingClass* pBuilding = nullptr) const; bool IsAvailable(HouseClass* pHouse) const; + void PrintMessage(const CSFText& message, HouseClass* pFirer) const; void ApplyLimboDelivery(HouseClass* pHouse); void ApplyLimboKill(HouseClass* pHouse); diff --git a/src/Ext/SWType/SWHelpers.cpp b/src/Ext/SWType/SWHelpers.cpp index 2fdaf45969..bb20108aa1 100644 --- a/src/Ext/SWType/SWHelpers.cpp +++ b/src/Ext/SWType/SWHelpers.cpp @@ -1,4 +1,5 @@ #include "Body.h" +#include // Universal handler of the rolls-weights system std::vector SWTypeExt::ExtData::WeightedRollsHandler(ValueableVector* rolls, std::vector>* weights, size_t size) @@ -254,3 +255,35 @@ std::pair SWTypeExt::ExtData::GetEMPulseCannonRange(BuildingClas return std::make_pair(this->SW_RangeMinimum.Get(), this->SW_RangeMaximum.Get()); } + +void SWTypeExt::ExtData::PrintMessage(const CSFText& message, HouseClass* pFirer) const +{ + if (message.empty()) + return; + + int color = ColorScheme::FindIndex("Gold"); + if (this->Message_FirerColor) + { + // firer color + if (pFirer) + { + color = pFirer->ColorSchemeIndex; + } + } + else + { + if (this->Message_ColorScheme > -1) + { + // user defined color + color = this->Message_ColorScheme; + } + else if (const auto pCurrent = HouseClass::CurrentPlayer()) + { + // default way: the current player's color + color = pCurrent->ColorSchemeIndex; + } + } + + // print the message + MessageListClass::Instance->PrintMessage(message, RulesClass::Instance->MessageDelay, color); +} diff --git a/src/Ext/Side/Body.cpp b/src/Ext/Side/Body.cpp index 2bfdebfee1..fbc5e33aec 100644 --- a/src/Ext/Side/Body.cpp +++ b/src/Ext/Side/Body.cpp @@ -42,6 +42,11 @@ void SideExt::ExtData::LoadFromINIFile(CCINIClass* pINI) this->ToolTip_Background_Opacity.Read(exINI, pSection, "ToolTip.Background.Opacity"); this->ToolTip_Background_BlurSize.Read(exINI, pSection, "ToolTip.Background.BlurSize"); this->BriefingTheme = pINI->ReadTheme(pSection, "BriefingTheme", this->BriefingTheme); + + this->ExclusiveSWSidebar_TopPCX.Read(pINI, pSection, "ExclusiveSWSidebar.TopPCX"); + this->ExclusiveSWSidebar_CenterPCX.Read(pINI, pSection, "ExclusiveSWSidebar.CenterPCX"); + this->ExclusiveSWSidebar_BottomPCX.Read(pINI, pSection, "ExclusiveSWSidebar.BottomPCX"); + this->ExclusiveSWSidebar_ToggleShape.Read(exINI, pSection, "ExclusiveSWSidebar.ToggleShape"); } // ============================= @@ -71,6 +76,10 @@ void SideExt::ExtData::Serialize(T& Stm) .Process(this->IngameScore_WinTheme) .Process(this->IngameScore_LoseTheme) .Process(this->BriefingTheme) + .Process(this->ExclusiveSWSidebar_TopPCX) + .Process(this->ExclusiveSWSidebar_CenterPCX) + .Process(this->ExclusiveSWSidebar_BottomPCX) + .Process(this->ExclusiveSWSidebar_ToggleShape) ; } diff --git a/src/Ext/Side/Body.h b/src/Ext/Side/Body.h index 88e694aa0c..7803b9840f 100644 --- a/src/Ext/Side/Body.h +++ b/src/Ext/Side/Body.h @@ -37,6 +37,11 @@ class SideExt Nullable ToolTip_Background_BlurSize; Valueable BriefingTheme; + PhobosPCXFile ExclusiveSWSidebar_TopPCX; + PhobosPCXFile ExclusiveSWSidebar_CenterPCX; + PhobosPCXFile ExclusiveSWSidebar_BottomPCX; + Valueable ExclusiveSWSidebar_ToggleShape; + ExtData(SideClass* OwnerObject) : Extension(OwnerObject) , ArrayIndex { -1 } , Sidebar_GDIPositions { false } @@ -58,6 +63,10 @@ class SideExt , ToolTip_Background_Opacity { } , ToolTip_Background_BlurSize { } , BriefingTheme { -1 } + , ExclusiveSWSidebar_TopPCX { } + , ExclusiveSWSidebar_CenterPCX { } + , ExclusiveSWSidebar_BottomPCX { } + , ExclusiveSWSidebar_ToggleShape { nullptr } { } virtual ~ExtData() = default; diff --git a/src/Ext/Sidebar/Body.cpp b/src/Ext/Sidebar/Body.cpp index 4674584781..e9d4ea45c5 100644 --- a/src/Ext/Sidebar/Body.cpp +++ b/src/Ext/Sidebar/Body.cpp @@ -21,6 +21,8 @@ template void SidebarExt::ExtData::Serialize(T& Stm) { Stm + .Process(this->SWSidebar_Enable) + .Process(this->SWSidebar_Indices) ; } diff --git a/src/Ext/Sidebar/Body.h b/src/Ext/Sidebar/Body.h index b3ccbfd9ac..1864b79b2e 100644 --- a/src/Ext/Sidebar/Body.h +++ b/src/Ext/Sidebar/Body.h @@ -18,8 +18,12 @@ class SidebarExt class ExtData final : public Extension { public: + bool SWSidebar_Enable; + DynamicVectorClass SWSidebar_Indices; ExtData(SidebarClass* OwnerObject) : Extension(OwnerObject) + , SWSidebar_Enable { true } + , SWSidebar_Indices {} { } virtual ~ExtData() = default; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp new file mode 100644 index 0000000000..527453ca75 --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -0,0 +1,154 @@ +#include "SWColumnClass.h" +#include "SWSidebarClass.h" + +#include +#include + +SWColumnClass::SWColumnClass(unsigned int id, int x, int y, int width, int height) + : ControlClass(id, x, y, width, height, static_cast(0), true) +{ + auto& columns = SWSidebarClass::Global()->Columns; + columns.emplace_back(this); + + this->MaxButtons = Phobos::UI::ExclusiveSWSidebar_Max - (static_cast(columns.size()) - 1); +} + +bool SWColumnClass::Draw(bool forced) +{ + if (!SWSidebarClass::IsEnabled()) + return false; + + const auto pSurface = DSurface::Composite(); + auto bounds = pSurface->GetRect(); + + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto centerPCX = pSideExt->ExclusiveSWSidebar_CenterPCX.GetSurface(); + + if (centerPCX) + { + RectangleStruct backRect = { this->X, this->Y, centerPCX->GetWidth(), centerPCX->GetHeight() }; + backRect.Width = centerPCX->GetWidth(); + backRect.Height = centerPCX->GetHeight(); + PCX::Instance->BlitToSurface(&backRect, pSurface, centerPCX); + } + + if (const auto topPCX = pSideExt->ExclusiveSWSidebar_TopPCX.GetSurface()) + { + RectangleStruct backRect = { this->X, this->Y, topPCX->GetWidth(), topPCX->GetHeight() };; + backRect.Y -= backRect.Height; + PCX::Instance->BlitToSurface(&backRect, pSurface, topPCX); + } + + if (const auto bottomPCX = pSideExt->ExclusiveSWSidebar_BottomPCX.GetSurface()) + { + RectangleStruct backRect = { this->X, this->Y, bottomPCX->GetWidth(), bottomPCX->GetHeight() };; + backRect.Y += this->Height; + PCX::Instance->BlitToSurface(&backRect, pSurface, bottomPCX); + } + + for (const auto button : this->Buttons) + button->Draw(true); + + return true; +} + +void SWColumnClass::OnMouseEnter() +{ + if (!SWSidebarClass::IsEnabled()) + return; + + SWSidebarClass::Global()->CurrentColumn = this; +} + +void SWColumnClass::OnMouseLeave() +{ + SWSidebarClass::Global()->CurrentColumn = nullptr; +} + +bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) +{ + for (const auto button : this->Buttons) + { + if (button->Clicked(pKey, flags, x, y, modifier)) + return true; + } + + return false; +} + +bool SWColumnClass::AddButton(int superIdx) +{ + if (const auto pSWType = SuperWeaponTypeClass::Array->GetItemOrDefault(superIdx)) + { + const auto pSWExt = SWTypeExt::ExtMap.Find(pSWType); + + if (!pSWExt->SW_ShowCameo) + return true; + + if (!Phobos::UI::ExclusiveSWSidebar) + return false; + + if (!pSWExt->ExclusiveSidebar_Allow) + return false; + + const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; + + if ((pSWExt->ExclusiveSidebar_RequiredHouses & ownerBits) == 0) + return false; + } + else + { + return true; + } + + auto& buttons = this->Buttons; + + if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Global()->AddColumn()) + return false; + + const auto button = DLLCreate(TacticalButtonClass::StartID + superIdx, superIdx, 0, 0, 60, 48); + + if (!button) + return false; + + button->Zap(); + GScreenClass::Instance->AddButton(button); + SWSidebarClass::Global()->SortButtons(); + return true; +} + +bool SWColumnClass::RemoveButton(int superIdx) +{ + auto& buttons = this->Buttons; + + const auto it = std::find_if(buttons.begin(), buttons.end(), [superIdx](TacticalButtonClass* const button) { return button->SuperIndex == superIdx; }); + + if (it == buttons.end()) + return false; + + AnnounceInvalidPointer(SWSidebarClass::Global()->CurrentButton, *it); + GScreenClass::Instance->RemoveButton(*it); + + DLLDelete(*it); + buttons.erase(it); + SWSidebarClass::Global()->SortButtons(); + return true; +} + +void SWColumnClass::ClearButtons(bool remove) +{ + auto& buttons = this->Buttons; + + if (remove) + { + for (const auto button : buttons) + GScreenClass::Instance->RemoveButton(button); + } + + buttons.clear(); +} + +void SWColumnClass::SetHeight(int height) +{ + this->Height = height; +} diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.h b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h new file mode 100644 index 0000000000..13ffccfd1f --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h @@ -0,0 +1,28 @@ +#pragma once +#include "TacticalButtonClass.h" +#include + +#include + +class SWColumnClass : public ControlClass +{ +public: + SWColumnClass() = default; + SWColumnClass(unsigned int id, int x, int y, int width, int height); + + ~SWColumnClass() = default; + + virtual bool Draw(bool forced) override; + virtual void OnMouseEnter() override; + virtual void OnMouseLeave() override; + virtual bool Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) override; + + bool AddButton(int superIdx); + bool RemoveButton(int superIdx); + void ClearButtons(bool remove = true); + + void SetHeight(int height); + + std::vector Buttons {}; + int MaxButtons { 0 }; +}; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp new file mode 100644 index 0000000000..3b3859d264 --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -0,0 +1,494 @@ +#include "SWSidebarClass.h" +#include +#include +#include +#include + +std::unique_ptr SWSidebarClass::Instance = nullptr; + +void SWSidebarClass::Allocate() +{ + Instance = std::make_unique(); +} + +void SWSidebarClass::Remove() +{ + Instance = nullptr; +} + +static PhobosMap CreateKeyboardCodeTextMap() +{ + PhobosMap Code2Text; + + Code2Text[0x00] = L" "; + Code2Text[0x01] = L"MouseLeft"; + Code2Text[0x02] = L"MouseRight"; + Code2Text[0x03] = L"Cancel"; + Code2Text[0x04] = L"MouseCenter"; + + Code2Text[0x08] = L"Back"; + Code2Text[0x09] = L"Tab"; + + Code2Text[0x0C] = L"Clear"; + Code2Text[0x0D] = L"Enter"; + + Code2Text[0x10] = L"Shift"; + Code2Text[0x11] = L"Ctrl"; + Code2Text[0x12] = L"Alt"; + Code2Text[0x13] = L"Pause"; + Code2Text[0x14] = L"CapsLock"; + + Code2Text[0x1B] = L"Esc"; + + Code2Text[0x20] = L"Space"; + Code2Text[0x21] = L"PageUp"; + Code2Text[0x22] = L"PageDown"; + Code2Text[0x23] = L"End"; + Code2Text[0x24] = L"Home"; + Code2Text[0x25] = L"Left"; + Code2Text[0x26] = L"Up"; + Code2Text[0x27] = L"Right"; + Code2Text[0x28] = L"Down"; + Code2Text[0x29] = L"Select"; + Code2Text[0x2A] = L"Print"; + Code2Text[0x2B] = L"Execute"; + Code2Text[0x2C] = L"PrintScreen"; + Code2Text[0x2D] = L"Insert"; + Code2Text[0x2E] = L"Delete"; + Code2Text[0x2F] = L"Help"; + Code2Text[0x30] = L"0"; + Code2Text[0x31] = L"1"; + Code2Text[0x32] = L"2"; + Code2Text[0x33] = L"3"; + Code2Text[0x34] = L"4"; + Code2Text[0x35] = L"5"; + Code2Text[0x36] = L"6"; + Code2Text[0x37] = L"7"; + Code2Text[0x38] = L"8"; + Code2Text[0x39] = L"9"; + + Code2Text[0x41] = L"A"; + Code2Text[0x42] = L"B"; + Code2Text[0x43] = L"C"; + Code2Text[0x44] = L"D"; + Code2Text[0x45] = L"E"; + Code2Text[0x46] = L"F"; + Code2Text[0x47] = L"G"; + Code2Text[0x48] = L"H"; + Code2Text[0x49] = L"I"; + Code2Text[0x4A] = L"J"; + Code2Text[0x4B] = L"K"; + Code2Text[0x4C] = L"L"; + Code2Text[0x4D] = L"M"; + Code2Text[0x4E] = L"N"; + Code2Text[0x4F] = L"O"; + Code2Text[0x50] = L"P"; + Code2Text[0x51] = L"Q"; + Code2Text[0x52] = L"R"; + Code2Text[0x53] = L"S"; + Code2Text[0x54] = L"T"; + Code2Text[0x55] = L"U"; + Code2Text[0x56] = L"V"; + Code2Text[0x57] = L"W"; + Code2Text[0x58] = L"X"; + Code2Text[0x59] = L"Y"; + Code2Text[0x5A] = L"Z"; + Code2Text[0x5B] = L"LWin"; + Code2Text[0x5C] = L"RWin"; + Code2Text[0x5D] = L"Menu"; + + Code2Text[0x60] = L"Num0"; + Code2Text[0x61] = L"Num1"; + Code2Text[0x62] = L"Num2"; + Code2Text[0x63] = L"Num3"; + Code2Text[0x64] = L"Num4"; + Code2Text[0x65] = L"Num5"; + Code2Text[0x66] = L"Num6"; + Code2Text[0x67] = L"Num7"; + Code2Text[0x68] = L"Num8"; + Code2Text[0x69] = L"Num9"; + Code2Text[0x6A] = L"Num*"; + Code2Text[0x6B] = L"Num+"; + Code2Text[0x6C] = L"Separator"; + Code2Text[0x6D] = L"Num-"; + Code2Text[0x6E] = L"Num."; + Code2Text[0x6F] = L"Num/"; + Code2Text[0x70] = L"F1"; + Code2Text[0x71] = L"F2"; + Code2Text[0x72] = L"F3"; + Code2Text[0x73] = L"F4"; + Code2Text[0x74] = L"F5"; + Code2Text[0x75] = L"F6"; + Code2Text[0x76] = L"F7"; + Code2Text[0x77] = L"F8"; + Code2Text[0x78] = L"F9"; + Code2Text[0x79] = L"F10"; + Code2Text[0x7A] = L"F11"; + Code2Text[0x7B] = L"F12"; + + Code2Text[0x90] = L"NumLock"; + Code2Text[0x91] = L"ScrollLock"; + + Code2Text[0xBA] = L";"; + Code2Text[0xBB] = L"="; + Code2Text[0xBC] = L","; + Code2Text[0xBD] = L"-"; + Code2Text[0xBE] = L"."; + Code2Text[0xBF] = L"/"; + Code2Text[0xC0] = L"`"; + + Code2Text[0xDB] = L"["; + Code2Text[0xDC] = L"\\"; + Code2Text[0xDD] = L"]"; + Code2Text[0xDE] = L"'"; + + Code2Text[static_cast(WWKey::Shift)] = L"Shift"; + Code2Text[static_cast(WWKey::Ctrl)] = L"Ctrl"; + Code2Text[static_cast(WWKey::Alt)] = L"Alt"; + + return Code2Text; +} + +PhobosMap SWSidebarClass::KeyboardCodeTextMap = CreateKeyboardCodeTextMap(); + +// ============================= +// functions + +bool SWSidebarClass::AddColumn() +{ + auto& columns = this->Columns; + + if (static_cast(columns.size()) >= Phobos::UI::ExclusiveSWSidebar_MaxColumn) + return false; + + const auto column = DLLCreate(TacticalButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::ExclusiveSWSidebar_Interval, 48); + + if (!column) + return false; + + column->Zap(); + GScreenClass::Instance->AddButton(column); + return true; +} + +bool SWSidebarClass::RemoveColumn() +{ + auto& columns = this->Columns; + + if (columns.empty()) + return false; + + if (const auto backColumn = columns.back()) + { + AnnounceInvalidPointer(SWSidebarClass::Global()->CurrentColumn, backColumn); + GScreenClass::Instance->RemoveButton(backColumn); + + DLLDelete(backColumn); + columns.erase(columns.end() - 1); + return true; + } + + return false; +} + +void SWSidebarClass::InitClear() +{ + this->CurrentColumn = nullptr; + this->CurrentButton = nullptr; + + if (const auto toggleButton = this->ToggleButton) + { + this->ToggleButton = nullptr; + GScreenClass::Instance->RemoveButton(toggleButton); + DLLDelete(toggleButton); + } + + auto& columns = this->Columns; + + for (const auto column : columns) + { + column->ClearButtons(); + GScreenClass::Instance->RemoveButton(column); + DLLDelete(column); + } + + columns.clear(); +} + +bool SWSidebarClass::AddButton(int superIdx) +{ + auto& columns = this->Columns; + + if (columns.empty() && !this->AddColumn()) + return false; + + if (std::any_of(columns.begin(), columns.end(), [superIdx](SWColumnClass* column) { return std::any_of(column->Buttons.begin(), column->Buttons.end(), [superIdx](TacticalButtonClass* button) { return button->SuperIndex == superIdx; }); })) + return true; + + const bool success = columns.back()->AddButton(superIdx); + + if (success) + SidebarExt::Global()->SWSidebar_Indices.AddUnique(superIdx); + + return success; +} + +void SWSidebarClass::SortButtons() +{ + auto& columns = this->Columns; + + if (columns.empty()) + return; + + columns.erase( + std::remove_if(columns.begin(), columns.end(), + [](SWColumnClass* const column) + { return column->Buttons.empty(); } + ), + columns.end() + ); + + if (columns.empty()) + { + if (const auto toggleButton = this->ToggleButton) + toggleButton->UpdatePosition(); + + return; + } + + std::vector vec_Buttons; + vec_Buttons.reserve(this->GetMaximumButtonCount()); + + for (const auto column : columns) + { + for (const auto button : column->Buttons) + vec_Buttons.emplace_back(button); + + column->ClearButtons(false); + } + + std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [](TacticalButtonClass* const a, TacticalButtonClass* const b) + { + return BuildType::SortsBefore(AbstractType::Special, a->SuperIndex, AbstractType::Special, b->SuperIndex); + }); + + const int buttonCount = static_cast(vec_Buttons.size()); + const int cameoWidth = 60, cameoHeight = 48; + const int maximum = Phobos::UI::ExclusiveSWSidebar_Max; + Point2D location = { 0, (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * cameoHeight) / 2 }; + int location_Y = location.Y; + int rowIdx = 0, columnIdx = 0; + + for (const auto button : vec_Buttons) + { + const auto column = columns[columnIdx]; + + if (rowIdx == 0) + column->SetPosition(location.X, location.Y); + + column->Buttons.emplace_back(button); + button->SetColumn(columnIdx); + button->SetPosition(location.X, location.Y); + rowIdx++; + + if (rowIdx >= maximum - columnIdx) + { + rowIdx = 0; + columnIdx++; + location_Y += cameoHeight / 2; + location = { location.X + cameoWidth + Phobos::UI::ExclusiveSWSidebar_Interval, location_Y }; + } + else + { + location.Y += cameoHeight; + } + } + + for (const auto column : columns) + column->SetHeight(column->Buttons.size() * 48); + + if (const auto toggleButton = this->ToggleButton) + toggleButton->UpdatePosition(); +} + +void SWSidebarClass::RecordHotkey(int buttonIndex, int key) +{ + const int index = buttonIndex - 1; + + if (this->KeyCodeData[index] == key) + return; + + this->KeyCodeData[index] = key; + std::wostringstream oss; + + if (key & static_cast(WWKey::Shift)) + oss << KeyboardCodeTextMap[static_cast(WWKey::Shift)] << L"+"; + + if (key & static_cast(WWKey::Ctrl)) + oss << KeyboardCodeTextMap[static_cast(WWKey::Ctrl)] << L"+"; + + if (key & static_cast(WWKey::Alt)) + oss << KeyboardCodeTextMap[static_cast(WWKey::Alt)] << L"+"; + + const int pureKey = key & 0xFF; + + if (KeyboardCodeTextMap.contains(pureKey)) + oss << KeyboardCodeTextMap[pureKey]; + else + oss << L"Unknown"; + + this->KeyCodeText[index] = oss.str(); +} + +int SWSidebarClass::GetMaximumButtonCount() +{ + const int firstColumn = Phobos::UI::ExclusiveSWSidebar_Max; + const int columns = std::min(firstColumn, Phobos::UI::ExclusiveSWSidebar_MaxColumn); + return (firstColumn + (firstColumn - (columns - 1))) * columns / 2; +} + +bool SWSidebarClass::IsEnabled() +{ + return SidebarExt::Global()->SWSidebar_Enable; +} + +// Hooks + +DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) +{ + enum { Nothing = 0x6925FC }; + + if (SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentColumn) + return Nothing; + + const auto toggleButton = SWSidebarClass::Global()->ToggleButton; + + return toggleButton && toggleButton->IsHovering ? Nothing : 0; +} + +// I cannot add it into YRppp :( +// It always failed, help me +static void __fastcall HouseClass_UpdateSuperWeaponsUnavailable(HouseClass* pHouse) +{ + JMP_STD(0x50B1D0); +} + +DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) +{ + enum { SkipGameCode = 0x4F9302 }; + + GET(HouseClass*, pHouse, ESI); + + HouseClass_UpdateSuperWeaponsUnavailable(pHouse); + + if (pHouse->IsCurrentPlayer()) + { + for (const auto column : SWSidebarClass::Global()->Columns) + { + for (const auto button : column->Buttons) + { + if (HouseClass::CurrentPlayer->Supers[button->SuperIndex]->IsPresent) + continue; + + if (column->RemoveButton(button->SuperIndex)) + SidebarExt::Global()->SWSidebar_Indices.Remove(button->SuperIndex); + } + } + } + + return SkipGameCode; +} + +DEFINE_HOOK(0x6A6316, SidebarClass_AddCameo_SuperWeapon_SWSidebar, 0x6) +{ + enum { ReturnFalse = 0x6A65FF }; + + GET_STACK(AbstractType, whatAmI, STACK_OFFSET(0x14, 0x4)); + GET_STACK(int, index, STACK_OFFSET(0x14, 0x8)); + + switch (whatAmI) + { + case AbstractType::Super: + case AbstractType::SuperWeaponType: + case AbstractType::Special: + if (SWSidebarClass::Global()->AddButton(index)) + return ReturnFalse; + + break; + + default: + break; + } + + return 0; +} + +DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) +{ + SWSidebarClass::Global()->InitClear(); + return 0; +} + +DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) +{ + if (!Phobos::UI::ExclusiveSWSidebar || Unsorted::ArmageddonMode) + return 0; + + if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) + { + if (const auto toggleShape = pSideExt->ExclusiveSWSidebar_ToggleShape.Get()) + { + if (const auto toggleButton = DLLCreate(TacticalButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, toggleShape->Width, toggleShape->Height)) + { + toggleButton->Zap(); + GScreenClass::Instance->AddButton(toggleButton); + SWSidebarClass::Global()->ToggleButton = toggleButton; + toggleButton->UpdatePosition(); + } + } + } + + for (const auto superIdx : SidebarExt::Global()->SWSidebar_Indices) + SWSidebarClass::Global()->AddButton(superIdx); + + return 0; +} + +// Shortcuts keys hooks +DEFINE_HOOK(0x533E69, UnknownClass_sub_533D20_LoadKeyboardCodeFromINI, 0x6) +{ + GET(CommandClass*, pCommand, ESI); + GET(int, key, EDI); + + const char* name = pCommand->GetName(); + char buffer[29]; + + for (int idx = 1; idx <= 10; idx++) + { + sprintf_s(buffer, "SW Sidebar Shortcuts Num %02d", idx); + + if (!_strcmpi(name, buffer)) + SWSidebarClass::Global()->RecordHotkey(idx, key); + } + + return 0; +} + +DEFINE_HOOK(0x5FB992, UnknownClass_sub_5FB320_SaveKeyboardCodeToINI, 0x6) +{ + GET(CommandClass*, pCommand, ECX); + GET(int, key, EAX); + + const char* name = pCommand->GetName(); + char buffer[30]; + + for (int idx = 1; idx <= 10; idx++) + { + sprintf_s(buffer, "SW Sidebar Shortcuts Num %02d", idx); + + if (!_strcmpi(name, buffer)) + SWSidebarClass::Global()->RecordHotkey(idx, key); + } + + return 0; +} diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h new file mode 100644 index 0000000000..3ad768fea0 --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -0,0 +1,48 @@ +#pragma once +#include "TacticalButtonClass.h" +#include "SWColumnClass.h" +#include + +class SWSidebarClass +{ +public: + bool AddColumn(); + bool RemoveColumn(); + + void InitClear(); + + bool AddButton(int superIdx); + void SortButtons(); + + void RecordHotkey(int buttonIndex, int key); + int GetMaximumButtonCount(); + + static bool IsEnabled(); + +private: + static std::unique_ptr Instance; + static PhobosMap KeyboardCodeTextMap; + +public: + static void Allocate(); + static void Remove(); + + static SWSidebarClass* Global() + { + return Instance.get(); + } + + static void Clear() + { + Allocate(); + } + +public: + std::vector Columns {}; + SWColumnClass* CurrentColumn { nullptr }; + TacticalButtonClass* CurrentButton { nullptr }; + ToggleSWButtonClass* ToggleButton { nullptr }; + + std::wstring KeyCodeText[10] {}; + int KeyCodeData[10] {}; +}; diff --git a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp new file mode 100644 index 0000000000..cd51c01907 --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp @@ -0,0 +1,316 @@ +#include "TacticalButtonClass.h" +#include "SWSidebarClass.h" +#include +#include +#include + +#include +#include +#include + +TacticalButtonClass::TacticalButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) + : ControlClass(id, x, y, width, height, GadgetFlag::LeftPress, true) + , SuperIndex(superIdx) +{ + if (const auto backColumn = SWSidebarClass::Global()->Columns.back()) + backColumn->Buttons.emplace_back(this); +} + +bool TacticalButtonClass::Draw(bool forced) +{ + if (!forced) + return false; + + const auto pSurface = DSurface::Composite(); + auto bounds = pSurface->GetRect(); + Point2D location = { this->X, this->Y }; + RectangleStruct destRect = { location.X, location.Y, this->Width, this->Height }; + + const auto pCurrent = HouseClass::CurrentPlayer(); + const auto pSuper = pCurrent->Supers[this->SuperIndex]; + const auto pSWExt = SWTypeExt::ExtMap.Find(pSuper->Type); + + // support for pcx cameos + if (const auto pPCXCameo = pSWExt->SidebarPCX.GetSurface()) + { + PCX::Instance->BlitToSurface(&destRect, pSurface, pPCXCameo); + } + else if (const auto pCameo = pSuper->Type->SidebarImage) // old shp cameos, fixed palette + { + const auto pCameoRef = pCameo->AsReference(); + char pFilename[0x20]; + strcpy_s(pFilename, RulesExt::Global()->MissingCameo.data()); + _strlwr_s(pFilename); + + if (!_stricmp(pCameoRef->Filename, GameStrings::XXICON_SHP) && strstr(pFilename, ".pcx")) + { + PCX::Instance->LoadFile(pFilename); + + if (const auto CameoPCX = PCX::Instance->GetSurface(pFilename)) + PCX::Instance->BlitToSurface(&destRect, pSurface, CameoPCX); + } + else + { + const auto pConvert = pSWExt->SidebarPal.Convert ? pSWExt->SidebarPal.GetConvert() : FileSystem::CAMEO_PAL; + pSurface->DrawSHP(pConvert, pCameo, 0, &location, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + } + } + + if (this->IsHovering) + { + RectangleStruct cameoRect = { location.X, location.Y, this->Width, this->Height }; + const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); + pSurface->DrawRect(&cameoRect, tooltipColor); + } + + if (pSuper->IsReady && !pCurrent->CanTransactMoney(pSWExt->Money_Amount) || + (pSWExt->SW_UseAITargeting && AresHelper::CanUseAres && !AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) + { + RectangleStruct darkenBounds { 0, 0, location.X + this->Width, location.Y + this->Height }; + pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, FileSystem::DARKEN_SHP, 0, &location, &darkenBounds, BlitterFlags::bf_400 | BlitterFlags::Darken, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + } + + const bool ready = !pSuper->IsSuspended && (pSuper->Type->UseChargeDrain ? pSuper->ChargeDrainState == ChargeDrainState::Ready : pSuper->IsReady); + bool drawReadiness = true; + + if (ready && this->ColumnIndex == 0) + { + auto& buttons = SWSidebarClass::Global()->Columns[this->ColumnIndex]->Buttons; + const int distance = std::distance(buttons.begin(), std::find(buttons.begin(), buttons.end(), this)); + + if (distance < 10 && !SWSidebarClass::Global()->KeyCodeText[distance].empty()) + { + const auto buffer = SWSidebarClass::Global()->KeyCodeText[distance].c_str(); + Point2D textLoc = { location.X + this->Width / 2, location.Y }; + const COLORREF foreColor = Drawing::RGB_To_Int(Drawing::TooltipColor); + TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; + + pSurface->DrawTextA(buffer, &bounds, &textLoc, foreColor, 0, printType); + drawReadiness = false; + } + } + + if (drawReadiness) + { + if (const auto buffer = pSuper->NameReadiness()) + { + Point2D textLoc = { location.X + this->Width / 2, location.Y }; + const COLORREF foreColor = Drawing::RGB_To_Int(Drawing::TooltipColor); + TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; + + pSurface->DrawTextA(buffer, &bounds, &textLoc, foreColor, 0, printType); + } + } + + if (pSuper->ShouldDrawProgress()) + { + Point2D loc = { location.X, location.Y }; + pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, FileSystem::GCLOCK2_SHP, pSuper->AnimStage() + 1, &loc, &bounds, BlitterFlags::bf_400 | BlitterFlags::TransLucent50, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + } + + return true; +} + +void TacticalButtonClass::OnMouseEnter() +{ + if (!SWSidebarClass::IsEnabled()) + return; + + this->IsHovering = true; + SWSidebarClass::Global()->CurrentButton = this; + SWSidebarClass::Global()->Columns[this->ColumnIndex]->OnMouseEnter(); + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); +} + +void TacticalButtonClass::OnMouseLeave() +{ + if (!SWSidebarClass::IsEnabled()) + return; + + this->IsHovering = false; + SWSidebarClass::Global()->CurrentButton = nullptr; + SWSidebarClass::Global()->Columns[this->ColumnIndex]->OnMouseLeave(); + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); +} + +bool TacticalButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) +{ + if ((int)flags & (int)GadgetFlag::LeftPress) + { + VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); + this->LaunchSuper(); + } + + return this->ControlClass::Action(flags, pKey, KeyModifier::None); +} + +void TacticalButtonClass::SetColumn(int column) +{ + this->ColumnIndex = column; +} + +bool TacticalButtonClass::LaunchSuper() const +{ + const auto pCurrent = HouseClass::CurrentPlayer(); + const auto pSuper = pCurrent->Supers[this->SuperIndex]; + const auto pSWExt = SWTypeExt::ExtMap.Find(pSuper->Type); + const bool manual = !pSWExt->SW_ManualFire && pSWExt->SW_AutoFire; + const bool unstopable = pSuper->Type->UseChargeDrain && pSuper->ChargeDrainState == ChargeDrainState::Draining && pSWExt->SW_Unstoppable; + + if (!pSuper->CanFire() && !manual) + { + VoxClass::PlayIndex(pSWExt->EVA_Impatient); + return false; + } + + if (!pCurrent->CanTransactMoney(pSWExt->Money_Amount)) + { + VoxClass::PlayIndex(pSWExt->EVA_InsufficientFunds); + pSWExt->PrintMessage(pSWExt->Message_InsufficientFunds, pCurrent); + } + else if (!pSWExt->SW_UseAITargeting || (AresHelper::CanUseAres && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) + { + if (!manual && !unstopable) + { + const auto swIndex = pSuper->Type->ArrayIndex; + + if (pSuper->Type->Action == Action::None || pSWExt->SW_UseAITargeting) + { + EventClass Event = EventClass(pCurrent->ArrayIndex, EventType::SpecialPlace, swIndex, CellStruct::Empty); + EventClass::AddEvent(Event); + } + else + { + DisplayClass::Instance->CurrentBuilding = nullptr; + DisplayClass::Instance->CurrentBuildingType = nullptr; + DisplayClass::Instance->unknown_11AC = static_cast(-1); + DisplayClass::Instance->SetActiveFoundation(nullptr); + MapClass::Instance->SetRepairMode(0); + DisplayClass::Instance->SetSellMode(0); + DisplayClass::Instance->PowerToggleMode = false; + DisplayClass::Instance->PlanningMode = false; + DisplayClass::Instance->PlaceBeaconMode = false; + DisplayClass::Instance->CurrentSWTypeIndex = swIndex; + MapClass::Instance->UnselectAll(); + VoxClass::PlayIndex(pSWExt->EVA_SelectTarget); + } + + return true; + } + } + else + { + pSWExt->PrintMessage(pSWExt->Message_CannotFire, pCurrent); + } + + return false; +} + +ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) + : ControlClass(id, x, y, width, height, static_cast((int)GadgetFlag::LeftPress | (int)GadgetFlag::LeftRelease), true) +{ + SWSidebarClass::Global()->ToggleButton = this; +} + +bool ToggleSWButtonClass::Draw(bool forced) +{ + auto& columns = SWSidebarClass::Global()->Columns; + + if (columns.empty()) + return false; + + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pShape = pSideExt->ExclusiveSWSidebar_ToggleShape.Get(); + + if (!pShape) + return false; + + const auto pConvert = FileSystem::SIDEBAR_PAL(); + const auto pSurface = DSurface::Composite(); + Point2D position = { this->X, this->Y }; + RectangleStruct destRect = { position.X, position.Y, this->Width, this->Height }; + pSurface->DrawSHP(pConvert, pShape, SWSidebarClass::IsEnabled(), &position, &destRect, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + + if (this->IsHovering) + { + const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); + pSurface->DrawRect(&destRect, tooltipColor); + } + + return true; +} + +void ToggleSWButtonClass::OnMouseEnter() +{ + auto& columns = SWSidebarClass::Global()->Columns; + + if (columns.empty()) + return; + + this->IsHovering = true; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); +} + +void ToggleSWButtonClass::OnMouseLeave() +{ + auto& columns = SWSidebarClass::Global()->Columns; + + if (columns.empty()) + return; + + this->IsHovering = false; + this->IsPressed = false; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); +} + +bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) +{ + auto& columns = SWSidebarClass::Global()->Columns; + + if (columns.empty()) + return false; + + if ((int)flags & (int)GadgetFlag::LeftPress) + this->IsPressed = true; + + if (((int)flags & (int)GadgetFlag::LeftRelease) && this->IsPressed) + { + this->IsPressed = false; + VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); + ToggleSWButtonClass::SwitchSidebar(); + } + + return this->ControlClass::Action(flags, pKey, KeyModifier::None); +} + +void ToggleSWButtonClass::UpdatePosition() +{ + Point2D position = Point2D::Empty; + auto& columns = SWSidebarClass::Global()->Columns; + + if (!columns.empty()) + { + const auto backColumn = columns.back(); + position.X = SWSidebarClass::Global()->IsEnabled() ? backColumn->X + backColumn->Width : 0; + position.Y = backColumn->Y + (backColumn->Height - this->Height) / 2; + } + else + { + position.X = 0; + position.Y = (GameOptionsClass::Instance->ScreenHeight - this->Height) / 2; + } + + this->SetPosition(position.X, position.Y); +} + +bool ToggleSWButtonClass::SwitchSidebar() +{ + SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; + + if (const auto toggleButton = SWSidebarClass::Global()->ToggleButton) + toggleButton->UpdatePosition(); + + return SWSidebarClass::Global()->IsEnabled(); +} diff --git a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h new file mode 100644 index 0000000000..90edc2b5ef --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h @@ -0,0 +1,48 @@ +#pragma once +#include + +class TacticalButtonClass : public ControlClass +{ +public: + TacticalButtonClass() = default; + TacticalButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height); + + ~TacticalButtonClass() = default; + + virtual bool Draw(bool forced) override; + virtual void OnMouseEnter() override; + virtual void OnMouseLeave() override; + virtual bool Action(GadgetFlag fags, DWORD* pKey, KeyModifier modifier) override; + + void SetColumn(int column); + bool LaunchSuper() const; + +public: + static constexpr int StartID = 2200; + + bool IsHovering { false }; + int ColumnIndex { -1 }; + int SuperIndex { -1 }; +}; + +class ToggleSWButtonClass : public ControlClass +{ +public: + ToggleSWButtonClass() = default; + ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height); + + ~ToggleSWButtonClass() = default; + + virtual bool Draw(bool forced) override; + virtual void OnMouseEnter() override; + virtual void OnMouseLeave() override; + virtual bool Action(GadgetFlag fags, DWORD* pKey, KeyModifier modifier) override; + + void UpdatePosition(); + + static bool SwitchSidebar(); + +public: + bool IsHovering { false }; + bool IsPressed { false }; +}; diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index 9e780a2aa7..a8ed6043a2 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -214,6 +215,51 @@ DEFINE_HOOK(0x6A9316, SidebarClass_StripClass_HelpText, 0x6) return 0x6A93DE; } +DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) +{ + enum { ApplyToolTip = 0x4AE69D }; + + if (!SWSidebarClass::IsEnabled()) + return 0; + + const auto button = SWSidebarClass::Global()->CurrentButton; + + if (!button) + return 0; + + PhobosToolTip::Instance.IsCameo = true; + PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); + R->EAX(PhobosToolTip::Instance.GetBuffer()); + return ApplyToolTip; +} + +DEFINE_HOOK(0x72426F, ToolTipManager_ProcessMessage_SetDelay, 0x5) +{ + if (SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentButton) + R->EDX(0); + + return 0; +} + +DEFINE_HOOK(0x72428C, ToolTipManager_ProcessMessage_Redraw, 0x5) +{ + return SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentButton ? 0x724297 : 0; +} + +DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) +{ + if (SWSidebarClass::IsEnabled()) + { + if (const auto button = SWSidebarClass::Global()->CurrentButton) + { + R->EDX(button->X + button->Width); + R->EAX(button->Y + 27); + } + } + + return 0; +} + // TODO: reimplement CCToolTip::Draw2 completely DEFINE_HOOK(0x478EE1, CCToolTip_Draw2_SetBuffer, 0x6) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 1f5d20345d..0ebb1ee5be 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,10 @@ bool Phobos::UI::PowerDelta_Show = false; double Phobos::UI::PowerDelta_ConditionYellow = 0.75; double Phobos::UI::PowerDelta_ConditionRed = 1.0; bool Phobos::UI::CenterPauseMenuBackground = false; +bool Phobos::UI::ExclusiveSWSidebar = false; +int Phobos::UI::ExclusiveSWSidebar_Interval = 0; +int Phobos::UI::ExclusiveSWSidebar_Max = 0; +int Phobos::UI::ExclusiveSWSidebar_MaxColumn = INT32_MAX; bool Phobos::UI::WeedsCounter_Show = false; bool Phobos::UI::AnchoredToolTips = false; @@ -160,6 +165,25 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::UI::CenterPauseMenuBackground = ini_uimd.ReadBool(SIDEBAR_SECTION, "CenterPauseMenuBackground", Phobos::UI::CenterPauseMenuBackground); + + Phobos::UI::ExclusiveSWSidebar = + ini_uimd.ReadBool(SIDEBAR_SECTION, "ExclusiveSWSidebar", Phobos::UI::ExclusiveSWSidebar); + + Phobos::UI::ExclusiveSWSidebar_Interval = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.Interval", Phobos::UI::ExclusiveSWSidebar_Interval); + + Phobos::UI::ExclusiveSWSidebar_Max = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.Max", Phobos::UI::ExclusiveSWSidebar_Max); + + const int screenHeight = GameOptionsClass::Instance->ScreenHeight - 192; + + if (Phobos::UI::ExclusiveSWSidebar_Max > 0) + Phobos::UI::ExclusiveSWSidebar_Max = std::min(Phobos::UI::ExclusiveSWSidebar_Max, screenHeight / 48); + else + Phobos::UI::ExclusiveSWSidebar_Max = screenHeight / 48; + + Phobos::UI::ExclusiveSWSidebar_MaxColumn = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.MaxColumn", Phobos::UI::ExclusiveSWSidebar_MaxColumn); } // UISettings diff --git a/src/Phobos.h b/src/Phobos.h index 720f48e95a..33720b8d59 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -55,6 +55,10 @@ class Phobos static double PowerDelta_ConditionYellow; static double PowerDelta_ConditionRed; static bool CenterPauseMenuBackground; + static bool ExclusiveSWSidebar; + static int ExclusiveSWSidebar_Interval; + static int ExclusiveSWSidebar_Max; + static int ExclusiveSWSidebar_MaxColumn; static bool WeedsCounter_Show; static bool AnchoredToolTips; diff --git a/src/Utilities/AresAddressTable.cpp b/src/Utilities/AresAddressTable.cpp index d7093860ee..423af8aba5 100644 --- a/src/Utilities/AresAddressTable.cpp +++ b/src/Utilities/AresAddressTable.cpp @@ -10,6 +10,11 @@ const AresHelper::AresVersionFunctionMap AresHelper::AresFunctionOffsets = { ARES_FUN(SpawnSurvivors), 0x0464C0 }, { ARES_FUN(HasFactory), 0x0217C0 }, { ARES_FUN(CanBeBuiltAt), 0x03E3B0 }, + + { "IsTargetConstraintsEligible", 0x032110 }, + + { "ExtMap_Find", 0x057C70 }, + { "SWTypeExt_Map", 0x0C1C54 }, } }, { @@ -19,6 +24,11 @@ const AresHelper::AresVersionFunctionMap AresHelper::AresFunctionOffsets = { ARES_FUN(SpawnSurvivors), 0x047030 }, { ARES_FUN(HasFactory), 0x0217C0 }, { ARES_FUN(CanBeBuiltAt), 0x03E3B0 }, + + { "IsTargetConstraintsEligible", 0x032AF0 }, + + { "ExtMap_Find", 0x058900 }, + { "SWTypeExt_Map", 0x0C2C50 }, } }, }; diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index 583d734320..381631094d 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -10,6 +10,7 @@ class TechnoTypeClass; class FootClass; class HouseClass; class BuildingTypeClass; +class SuperWeaponTypeClass; class AresTechnoTypeExt { @@ -48,6 +49,34 @@ class AresFunctions return THIS_CALL_ARES(&AresTechnoTypeExt::CanBeBuiltAt, pExt, pBuildingType); } + // SWTypeExt + static bool IsTargetConstraintsEligible(void* pItem, HouseClass* pFirer, bool isPlayer) + { + DWORD function = AresHelper::AresFunctionOffsetsFinal[__func__]; + DWORD _isPlayer = isPlayer; + + __asm { + push _isPlayer + push pFirer + mov ecx, pItem + } + + CALL(function) + } + + static void* SWTypeExtMap_Find(SuperWeaponTypeClass* key) + { + DWORD function = AresHelper::AresFunctionOffsetsFinal["ExtMap_Find"]; + DWORD extMap = AresHelper::AresFunctionOffsetsFinal["SWTypeExt_Map"]; + + __asm { + push key + mov ecx, extMap + } + + CALL(function) + } + #undef CALL_ARES #undef THIS_CALL_ARES }; From 6579e695889a37acf3f2348a55067ec0f2b2c9da Mon Sep 17 00:00:00 2001 From: ZivDero Date: Mon, 4 Nov 2024 01:52:50 +0300 Subject: [PATCH 02/69] Cleanup, use vanilla function to get hotkey string --- YRpp | 2 +- src/Commands/Commands.cpp | 21 +- src/Commands/Commands.h | 3 +- src/Commands/FireTacticalSW.h | 18 +- src/Commands/ToggleSWSidebar.cpp | 2 +- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 14 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 242 +----------------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 14 +- .../Sidebar/SWSidebar/TacticalButtonClass.cpp | 58 +++-- src/Misc/PhobosToolTip.cpp | 8 +- 10 files changed, 87 insertions(+), 295 deletions(-) diff --git a/YRpp b/YRpp index 55764af23e..55b5ace55f 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 55764af23ef01aae9f7598a3410d0a1ed61de63d +Subproject commit 55b5ace55fcd93eaa630fea7e85ae0e5018910de diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index 4f73ff25fc..79a39b4db0 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -12,6 +12,7 @@ #include "SaveVariablesToFile.h" #include "ToggleSWSidebar.h" #include "FireTacticalSW.h" +#include DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) { @@ -23,16 +24,16 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); - MakeCommand>(); + SWSidebarClass::Commands[0] = MakeCommand>(); + SWSidebarClass::Commands[1] = MakeCommand>(); + SWSidebarClass::Commands[2] = MakeCommand>(); + SWSidebarClass::Commands[3] = MakeCommand>(); + SWSidebarClass::Commands[4] = MakeCommand>(); + SWSidebarClass::Commands[5] = MakeCommand>(); + SWSidebarClass::Commands[6] = MakeCommand>(); + SWSidebarClass::Commands[7] = MakeCommand>(); + SWSidebarClass::Commands[8] = MakeCommand>(); + SWSidebarClass::Commands[9] = MakeCommand>(); if (Phobos::Config::DevelopmentCommands) { diff --git a/src/Commands/Commands.h b/src/Commands/Commands.h index 969198a477..e19ad95ef6 100644 --- a/src/Commands/Commands.h +++ b/src/Commands/Commands.h @@ -7,10 +7,11 @@ #include template -void MakeCommand() +T* MakeCommand() { T* command = GameCreate(); CommandClass::Array->AddItem(command); + return command; }; #define CATEGORY_TEAM StringTable::LoadString(GameStrings::TXT_TEAM) diff --git a/src/Commands/FireTacticalSW.h b/src/Commands/FireTacticalSW.h index 9e634ffbf9..e4777a2dd2 100644 --- a/src/Commands/FireTacticalSW.h +++ b/src/Commands/FireTacticalSW.h @@ -17,28 +17,30 @@ class FireTacticalSWCommandClass : public CommandClass template inline const char* FireTacticalSWCommandClass::GetName() const { - _snprintf_s(Phobos::readBuffer, Phobos::readLength, "FireTacticalSW%d", Index); + _snprintf_s(Phobos::readBuffer, Phobos::readLength, "FireTacticalSW%d", Index + 1); return Phobos::readBuffer; } template inline const wchar_t* FireTacticalSWCommandClass::GetUIName() const { - _snwprintf_s(Phobos::wideBuffer, Phobos::readLength, L"Fire Super Weapon %d", Index); - return StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX", Phobos::wideBuffer); + const wchar_t* csfString = StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX", L"Fire Super Weapon %d"); + _snwprintf_s(Phobos::wideBuffer, std::size(Phobos::wideBuffer), csfString, Index + 1); + return Phobos::wideBuffer; } template inline const wchar_t* FireTacticalSWCommandClass::GetUICategory() const { - return CATEGORY_CONTROL; + return CATEGORY_INTERFACE; } template inline const wchar_t* FireTacticalSWCommandClass::GetUIDescription() const { - _snwprintf_s(Phobos::wideBuffer, Phobos::readLength, L"Fires Super Weapon %d.", Index); - return StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX_DESC", Phobos::wideBuffer); + const wchar_t* csfString = StringTable::TryFetchString("TXT_FIRE_TACTICAL_SW_XX_DESC", L"Fires the Super Weapon at position %d in the Super Weapon sidebar."); + _snwprintf_s(Phobos::wideBuffer, std::size(Phobos::wideBuffer), csfString, Index + 1); + return Phobos::wideBuffer; } template @@ -47,13 +49,13 @@ inline void FireTacticalSWCommandClass::Execute(WWKey eInput) const if (!SWSidebarClass::IsEnabled()) return; - const auto& columns = SWSidebarClass::Global()->Columns; + const auto& columns = SWSidebarClass::Instance.Columns; if (columns.empty()) return; const auto& buttons = columns.front()->Buttons; - if (buttons.size() > Index) + if (Index < buttons.size()) buttons[Index]->LaunchSuper(); } diff --git a/src/Commands/ToggleSWSidebar.cpp b/src/Commands/ToggleSWSidebar.cpp index 1fcd08d86d..1c8e58c767 100644 --- a/src/Commands/ToggleSWSidebar.cpp +++ b/src/Commands/ToggleSWSidebar.cpp @@ -33,6 +33,6 @@ void ToggleSWSidebar::Execute(WWKey eInput) const else MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("TXT_EX_SW_SIDEBAR_DISABLE", L"Super Weapon Sidebar Disabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); - if (SWSidebarClass::Global()->CurrentColumn) + if (SWSidebarClass::Instance.CurrentColumn) MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 527453ca75..e1533b8c4d 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -7,7 +7,7 @@ SWColumnClass::SWColumnClass(unsigned int id, int x, int y, int width, int height) : ControlClass(id, x, y, width, height, static_cast(0), true) { - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; columns.emplace_back(this); this->MaxButtons = Phobos::UI::ExclusiveSWSidebar_Max - (static_cast(columns.size()) - 1); @@ -57,12 +57,12 @@ void SWColumnClass::OnMouseEnter() if (!SWSidebarClass::IsEnabled()) return; - SWSidebarClass::Global()->CurrentColumn = this; + SWSidebarClass::Instance.CurrentColumn = this; } void SWColumnClass::OnMouseLeave() { - SWSidebarClass::Global()->CurrentColumn = nullptr; + SWSidebarClass::Instance.CurrentColumn = nullptr; } bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) @@ -103,7 +103,7 @@ bool SWColumnClass::AddButton(int superIdx) auto& buttons = this->Buttons; - if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Global()->AddColumn()) + if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) return false; const auto button = DLLCreate(TacticalButtonClass::StartID + superIdx, superIdx, 0, 0, 60, 48); @@ -113,7 +113,7 @@ bool SWColumnClass::AddButton(int superIdx) button->Zap(); GScreenClass::Instance->AddButton(button); - SWSidebarClass::Global()->SortButtons(); + SWSidebarClass::Instance.SortButtons(); return true; } @@ -126,12 +126,12 @@ bool SWColumnClass::RemoveButton(int superIdx) if (it == buttons.end()) return false; - AnnounceInvalidPointer(SWSidebarClass::Global()->CurrentButton, *it); + AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentButton, *it); GScreenClass::Instance->RemoveButton(*it); DLLDelete(*it); buttons.erase(it); - SWSidebarClass::Global()->SortButtons(); + SWSidebarClass::Instance.SortButtons(); return true; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 3b3859d264..fb063a7b1f 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -4,152 +4,9 @@ #include #include -std::unique_ptr SWSidebarClass::Instance = nullptr; +SWSidebarClass SWSidebarClass::Instance; +CommandClass* SWSidebarClass::Commands[10]; -void SWSidebarClass::Allocate() -{ - Instance = std::make_unique(); -} - -void SWSidebarClass::Remove() -{ - Instance = nullptr; -} - -static PhobosMap CreateKeyboardCodeTextMap() -{ - PhobosMap Code2Text; - - Code2Text[0x00] = L" "; - Code2Text[0x01] = L"MouseLeft"; - Code2Text[0x02] = L"MouseRight"; - Code2Text[0x03] = L"Cancel"; - Code2Text[0x04] = L"MouseCenter"; - - Code2Text[0x08] = L"Back"; - Code2Text[0x09] = L"Tab"; - - Code2Text[0x0C] = L"Clear"; - Code2Text[0x0D] = L"Enter"; - - Code2Text[0x10] = L"Shift"; - Code2Text[0x11] = L"Ctrl"; - Code2Text[0x12] = L"Alt"; - Code2Text[0x13] = L"Pause"; - Code2Text[0x14] = L"CapsLock"; - - Code2Text[0x1B] = L"Esc"; - - Code2Text[0x20] = L"Space"; - Code2Text[0x21] = L"PageUp"; - Code2Text[0x22] = L"PageDown"; - Code2Text[0x23] = L"End"; - Code2Text[0x24] = L"Home"; - Code2Text[0x25] = L"Left"; - Code2Text[0x26] = L"Up"; - Code2Text[0x27] = L"Right"; - Code2Text[0x28] = L"Down"; - Code2Text[0x29] = L"Select"; - Code2Text[0x2A] = L"Print"; - Code2Text[0x2B] = L"Execute"; - Code2Text[0x2C] = L"PrintScreen"; - Code2Text[0x2D] = L"Insert"; - Code2Text[0x2E] = L"Delete"; - Code2Text[0x2F] = L"Help"; - Code2Text[0x30] = L"0"; - Code2Text[0x31] = L"1"; - Code2Text[0x32] = L"2"; - Code2Text[0x33] = L"3"; - Code2Text[0x34] = L"4"; - Code2Text[0x35] = L"5"; - Code2Text[0x36] = L"6"; - Code2Text[0x37] = L"7"; - Code2Text[0x38] = L"8"; - Code2Text[0x39] = L"9"; - - Code2Text[0x41] = L"A"; - Code2Text[0x42] = L"B"; - Code2Text[0x43] = L"C"; - Code2Text[0x44] = L"D"; - Code2Text[0x45] = L"E"; - Code2Text[0x46] = L"F"; - Code2Text[0x47] = L"G"; - Code2Text[0x48] = L"H"; - Code2Text[0x49] = L"I"; - Code2Text[0x4A] = L"J"; - Code2Text[0x4B] = L"K"; - Code2Text[0x4C] = L"L"; - Code2Text[0x4D] = L"M"; - Code2Text[0x4E] = L"N"; - Code2Text[0x4F] = L"O"; - Code2Text[0x50] = L"P"; - Code2Text[0x51] = L"Q"; - Code2Text[0x52] = L"R"; - Code2Text[0x53] = L"S"; - Code2Text[0x54] = L"T"; - Code2Text[0x55] = L"U"; - Code2Text[0x56] = L"V"; - Code2Text[0x57] = L"W"; - Code2Text[0x58] = L"X"; - Code2Text[0x59] = L"Y"; - Code2Text[0x5A] = L"Z"; - Code2Text[0x5B] = L"LWin"; - Code2Text[0x5C] = L"RWin"; - Code2Text[0x5D] = L"Menu"; - - Code2Text[0x60] = L"Num0"; - Code2Text[0x61] = L"Num1"; - Code2Text[0x62] = L"Num2"; - Code2Text[0x63] = L"Num3"; - Code2Text[0x64] = L"Num4"; - Code2Text[0x65] = L"Num5"; - Code2Text[0x66] = L"Num6"; - Code2Text[0x67] = L"Num7"; - Code2Text[0x68] = L"Num8"; - Code2Text[0x69] = L"Num9"; - Code2Text[0x6A] = L"Num*"; - Code2Text[0x6B] = L"Num+"; - Code2Text[0x6C] = L"Separator"; - Code2Text[0x6D] = L"Num-"; - Code2Text[0x6E] = L"Num."; - Code2Text[0x6F] = L"Num/"; - Code2Text[0x70] = L"F1"; - Code2Text[0x71] = L"F2"; - Code2Text[0x72] = L"F3"; - Code2Text[0x73] = L"F4"; - Code2Text[0x74] = L"F5"; - Code2Text[0x75] = L"F6"; - Code2Text[0x76] = L"F7"; - Code2Text[0x77] = L"F8"; - Code2Text[0x78] = L"F9"; - Code2Text[0x79] = L"F10"; - Code2Text[0x7A] = L"F11"; - Code2Text[0x7B] = L"F12"; - - Code2Text[0x90] = L"NumLock"; - Code2Text[0x91] = L"ScrollLock"; - - Code2Text[0xBA] = L";"; - Code2Text[0xBB] = L"="; - Code2Text[0xBC] = L","; - Code2Text[0xBD] = L"-"; - Code2Text[0xBE] = L"."; - Code2Text[0xBF] = L"/"; - Code2Text[0xC0] = L"`"; - - Code2Text[0xDB] = L"["; - Code2Text[0xDC] = L"\\"; - Code2Text[0xDD] = L"]"; - Code2Text[0xDE] = L"'"; - - Code2Text[static_cast(WWKey::Shift)] = L"Shift"; - Code2Text[static_cast(WWKey::Ctrl)] = L"Ctrl"; - Code2Text[static_cast(WWKey::Alt)] = L"Alt"; - - return Code2Text; -} - -PhobosMap SWSidebarClass::KeyboardCodeTextMap = CreateKeyboardCodeTextMap(); // ============================= // functions @@ -180,7 +37,7 @@ bool SWSidebarClass::RemoveColumn() if (const auto backColumn = columns.back()) { - AnnounceInvalidPointer(SWSidebarClass::Global()->CurrentColumn, backColumn); + AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentColumn, backColumn); GScreenClass::Instance->RemoveButton(backColumn); DLLDelete(backColumn); @@ -270,7 +127,7 @@ void SWSidebarClass::SortButtons() std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [](TacticalButtonClass* const a, TacticalButtonClass* const b) { return BuildType::SortsBefore(AbstractType::Special, a->SuperIndex, AbstractType::Special, b->SuperIndex); - }); + }); const int buttonCount = static_cast(vec_Buttons.size()); const int cameoWidth = 60, cameoHeight = 48; @@ -311,35 +168,6 @@ void SWSidebarClass::SortButtons() toggleButton->UpdatePosition(); } -void SWSidebarClass::RecordHotkey(int buttonIndex, int key) -{ - const int index = buttonIndex - 1; - - if (this->KeyCodeData[index] == key) - return; - - this->KeyCodeData[index] = key; - std::wostringstream oss; - - if (key & static_cast(WWKey::Shift)) - oss << KeyboardCodeTextMap[static_cast(WWKey::Shift)] << L"+"; - - if (key & static_cast(WWKey::Ctrl)) - oss << KeyboardCodeTextMap[static_cast(WWKey::Ctrl)] << L"+"; - - if (key & static_cast(WWKey::Alt)) - oss << KeyboardCodeTextMap[static_cast(WWKey::Alt)] << L"+"; - - const int pureKey = key & 0xFF; - - if (KeyboardCodeTextMap.contains(pureKey)) - oss << KeyboardCodeTextMap[pureKey]; - else - oss << L"Unknown"; - - this->KeyCodeText[index] = oss.str(); -} - int SWSidebarClass::GetMaximumButtonCount() { const int firstColumn = Phobos::UI::ExclusiveSWSidebar_Max; @@ -358,32 +186,25 @@ DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) { enum { Nothing = 0x6925FC }; - if (SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentColumn) + if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentColumn) return Nothing; - const auto toggleButton = SWSidebarClass::Global()->ToggleButton; + const auto toggleButton = SWSidebarClass::Instance.ToggleButton; return toggleButton && toggleButton->IsHovering ? Nothing : 0; } -// I cannot add it into YRppp :( -// It always failed, help me -static void __fastcall HouseClass_UpdateSuperWeaponsUnavailable(HouseClass* pHouse) -{ - JMP_STD(0x50B1D0); -} - DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) { enum { SkipGameCode = 0x4F9302 }; GET(HouseClass*, pHouse, ESI); - HouseClass_UpdateSuperWeaponsUnavailable(pHouse); + pHouse->AISupers(); if (pHouse->IsCurrentPlayer()) { - for (const auto column : SWSidebarClass::Global()->Columns) + for (const auto column : SWSidebarClass::Instance.Columns) { for (const auto button : column->Buttons) { @@ -411,7 +232,7 @@ DEFINE_HOOK(0x6A6316, SidebarClass_AddCameo_SuperWeapon_SWSidebar, 0x6) case AbstractType::Super: case AbstractType::SuperWeaponType: case AbstractType::Special: - if (SWSidebarClass::Global()->AddButton(index)) + if (SWSidebarClass::Instance.AddButton(index)) return ReturnFalse; break; @@ -425,7 +246,7 @@ DEFINE_HOOK(0x6A6316, SidebarClass_AddCameo_SuperWeapon_SWSidebar, 0x6) DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) { - SWSidebarClass::Global()->InitClear(); + SWSidebarClass::Instance.InitClear(); return 0; } @@ -442,53 +263,14 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) { toggleButton->Zap(); GScreenClass::Instance->AddButton(toggleButton); - SWSidebarClass::Global()->ToggleButton = toggleButton; + SWSidebarClass::Instance.ToggleButton = toggleButton; toggleButton->UpdatePosition(); } } } for (const auto superIdx : SidebarExt::Global()->SWSidebar_Indices) - SWSidebarClass::Global()->AddButton(superIdx); - - return 0; -} - -// Shortcuts keys hooks -DEFINE_HOOK(0x533E69, UnknownClass_sub_533D20_LoadKeyboardCodeFromINI, 0x6) -{ - GET(CommandClass*, pCommand, ESI); - GET(int, key, EDI); - - const char* name = pCommand->GetName(); - char buffer[29]; - - for (int idx = 1; idx <= 10; idx++) - { - sprintf_s(buffer, "SW Sidebar Shortcuts Num %02d", idx); - - if (!_strcmpi(name, buffer)) - SWSidebarClass::Global()->RecordHotkey(idx, key); - } - - return 0; -} - -DEFINE_HOOK(0x5FB992, UnknownClass_sub_5FB320_SaveKeyboardCodeToINI, 0x6) -{ - GET(CommandClass*, pCommand, ECX); - GET(int, key, EAX); - - const char* name = pCommand->GetName(); - char buffer[30]; - - for (int idx = 1; idx <= 10; idx++) - { - sprintf_s(buffer, "SW Sidebar Shortcuts Num %02d", idx); - - if (!_strcmpi(name, buffer)) - SWSidebarClass::Global()->RecordHotkey(idx, key); - } + SWSidebarClass::Instance.AddButton(superIdx); return 0; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 3ad768fea0..93880f46f4 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -2,6 +2,7 @@ #include "TacticalButtonClass.h" #include "SWColumnClass.h" #include +#include class SWSidebarClass { @@ -14,24 +15,16 @@ class SWSidebarClass bool AddButton(int superIdx); void SortButtons(); - void RecordHotkey(int buttonIndex, int key); int GetMaximumButtonCount(); static bool IsEnabled(); -private: - static std::unique_ptr Instance; - static PhobosMap KeyboardCodeTextMap; + static SWSidebarClass Instance; public: static void Allocate(); static void Remove(); - static SWSidebarClass* Global() - { - return Instance.get(); - } - static void Clear() { Allocate(); @@ -43,6 +36,5 @@ class SWSidebarClass TacticalButtonClass* CurrentButton { nullptr }; ToggleSWButtonClass* ToggleButton { nullptr }; - std::wstring KeyCodeText[10] {}; - int KeyCodeData[10] {}; + static CommandClass* Commands[10]; }; diff --git a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp index cd51c01907..14bd79c2f3 100644 --- a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp @@ -2,7 +2,9 @@ #include "SWSidebarClass.h" #include #include +#include #include +#include #include #include @@ -12,7 +14,7 @@ TacticalButtonClass::TacticalButtonClass(unsigned int id, int superIdx, int x, i : ControlClass(id, x, y, width, height, GadgetFlag::LeftPress, true) , SuperIndex(superIdx) { - if (const auto backColumn = SWSidebarClass::Global()->Columns.back()) + if (const auto backColumn = SWSidebarClass::Instance.Columns.back()) backColumn->Buttons.emplace_back(this); } @@ -75,18 +77,30 @@ bool TacticalButtonClass::Draw(bool forced) if (ready && this->ColumnIndex == 0) { - auto& buttons = SWSidebarClass::Global()->Columns[this->ColumnIndex]->Buttons; - const int distance = std::distance(buttons.begin(), std::find(buttons.begin(), buttons.end(), this)); + auto& buttons = SWSidebarClass::Instance.Columns[this->ColumnIndex]->Buttons; + const int buttonId = std::distance(buttons.begin(), std::find(buttons.begin(), buttons.end(), this)); - if (distance < 10 && !SWSidebarClass::Global()->KeyCodeText[distance].empty()) + if (buttonId < 10) { - const auto buffer = SWSidebarClass::Global()->KeyCodeText[distance].c_str(); + unsigned short hotkey = 0; + for (int i = 0; i < CommandClass::Hotkeys->IndexCount; i++) + { + if (CommandClass::Hotkeys->IndexTable[i].Data == SWSidebarClass::Commands[buttonId]) + hotkey = CommandClass::Hotkeys->IndexTable[i].ID; + } + Point2D textLoc = { location.X + this->Width / 2, location.Y }; const COLORREF foreColor = Drawing::RGB_To_Int(Drawing::TooltipColor); - TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; + constexpr TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; - pSurface->DrawTextA(buffer, &bounds, &textLoc, foreColor, 0, printType); - drawReadiness = false; + wchar_t buffer[64]; + UI::GetKeyboardKeyString(hotkey, buffer); + + if (std::wcslen(buffer)) + { + pSurface->DrawTextA(buffer, &bounds, &textLoc, foreColor, 0, printType); + drawReadiness = false; + } } } @@ -96,7 +110,7 @@ bool TacticalButtonClass::Draw(bool forced) { Point2D textLoc = { location.X + this->Width / 2, location.Y }; const COLORREF foreColor = Drawing::RGB_To_Int(Drawing::TooltipColor); - TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; + constexpr TextPrintType printType = TextPrintType::FullShadow | TextPrintType::Point8 | TextPrintType::Background | TextPrintType::Center; pSurface->DrawTextA(buffer, &bounds, &textLoc, foreColor, 0, printType); } @@ -117,8 +131,8 @@ void TacticalButtonClass::OnMouseEnter() return; this->IsHovering = true; - SWSidebarClass::Global()->CurrentButton = this; - SWSidebarClass::Global()->Columns[this->ColumnIndex]->OnMouseEnter(); + SWSidebarClass::Instance.CurrentButton = this; + SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseEnter(); MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } @@ -128,8 +142,8 @@ void TacticalButtonClass::OnMouseLeave() return; this->IsHovering = false; - SWSidebarClass::Global()->CurrentButton = nullptr; - SWSidebarClass::Global()->Columns[this->ColumnIndex]->OnMouseLeave(); + SWSidebarClass::Instance.CurrentButton = nullptr; + SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseLeave(); MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); } @@ -210,12 +224,12 @@ bool TacticalButtonClass::LaunchSuper() const ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) : ControlClass(id, x, y, width, height, static_cast((int)GadgetFlag::LeftPress | (int)GadgetFlag::LeftRelease), true) { - SWSidebarClass::Global()->ToggleButton = this; + SWSidebarClass::Instance.ToggleButton = this; } bool ToggleSWButtonClass::Draw(bool forced) { - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; if (columns.empty()) return false; @@ -243,7 +257,7 @@ bool ToggleSWButtonClass::Draw(bool forced) void ToggleSWButtonClass::OnMouseEnter() { - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; if (columns.empty()) return; @@ -254,7 +268,7 @@ void ToggleSWButtonClass::OnMouseEnter() void ToggleSWButtonClass::OnMouseLeave() { - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; if (columns.empty()) return; @@ -267,7 +281,7 @@ void ToggleSWButtonClass::OnMouseLeave() bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; if (columns.empty()) return false; @@ -288,12 +302,12 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi void ToggleSWButtonClass::UpdatePosition() { Point2D position = Point2D::Empty; - auto& columns = SWSidebarClass::Global()->Columns; + auto& columns = SWSidebarClass::Instance.Columns; if (!columns.empty()) { const auto backColumn = columns.back(); - position.X = SWSidebarClass::Global()->IsEnabled() ? backColumn->X + backColumn->Width : 0; + position.X = SWSidebarClass::Instance.IsEnabled() ? backColumn->X + backColumn->Width : 0; position.Y = backColumn->Y + (backColumn->Height - this->Height) / 2; } else @@ -309,8 +323,8 @@ bool ToggleSWButtonClass::SwitchSidebar() { SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; - if (const auto toggleButton = SWSidebarClass::Global()->ToggleButton) + if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) toggleButton->UpdatePosition(); - return SWSidebarClass::Global()->IsEnabled(); + return SWSidebarClass::Instance.IsEnabled(); } diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index a8ed6043a2..a0c9d4ba50 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -222,7 +222,7 @@ DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) if (!SWSidebarClass::IsEnabled()) return 0; - const auto button = SWSidebarClass::Global()->CurrentButton; + const auto button = SWSidebarClass::Instance.CurrentButton; if (!button) return 0; @@ -235,7 +235,7 @@ DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) DEFINE_HOOK(0x72426F, ToolTipManager_ProcessMessage_SetDelay, 0x5) { - if (SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentButton) + if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton) R->EDX(0); return 0; @@ -243,14 +243,14 @@ DEFINE_HOOK(0x72426F, ToolTipManager_ProcessMessage_SetDelay, 0x5) DEFINE_HOOK(0x72428C, ToolTipManager_ProcessMessage_Redraw, 0x5) { - return SWSidebarClass::IsEnabled() && SWSidebarClass::Global()->CurrentButton ? 0x724297 : 0; + return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? 0x724297 : 0; } DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) { if (SWSidebarClass::IsEnabled()) { - if (const auto button = SWSidebarClass::Global()->CurrentButton) + if (const auto button = SWSidebarClass::Instance.CurrentButton) { R->EDX(button->X + button->Width); R->EAX(button->Y + 27); From c286439fd477f0d445d64aa296acba74d765a3ba Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 10 Nov 2024 09:40:27 +0800 Subject: [PATCH 03/69] finished --- Phobos.vcxproj | 4 ++-- ...TacticalButtonClass.cpp => SWButtonClass.cpp} | 16 ++++++++-------- .../{TacticalButtonClass.h => SWButtonClass.h} | 8 ++++---- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 13 +++++++++---- src/Ext/Sidebar/SWSidebar/SWColumnClass.h | 4 ++-- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 10 +++++----- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 4 ++-- 7 files changed, 32 insertions(+), 27 deletions(-) rename src/Ext/Sidebar/SWSidebar/{TacticalButtonClass.cpp => SWButtonClass.cpp} (95%) rename src/Ext/Sidebar/SWSidebar/{TacticalButtonClass.h => SWButtonClass.h} (82%) diff --git a/Phobos.vcxproj b/Phobos.vcxproj index c2434c0c12..dad8fc1bfb 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -21,7 +21,7 @@ - + @@ -191,7 +191,7 @@ - + diff --git a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp similarity index 95% rename from src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp rename to src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 14bd79c2f3..12481cda8e 100644 --- a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -1,4 +1,4 @@ -#include "TacticalButtonClass.h" +#include "SWButtonClass.h" #include "SWSidebarClass.h" #include #include @@ -10,7 +10,7 @@ #include #include -TacticalButtonClass::TacticalButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) +SWButtonClass::SWButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) : ControlClass(id, x, y, width, height, GadgetFlag::LeftPress, true) , SuperIndex(superIdx) { @@ -18,7 +18,7 @@ TacticalButtonClass::TacticalButtonClass(unsigned int id, int superIdx, int x, i backColumn->Buttons.emplace_back(this); } -bool TacticalButtonClass::Draw(bool forced) +bool SWButtonClass::Draw(bool forced) { if (!forced) return false; @@ -125,7 +125,7 @@ bool TacticalButtonClass::Draw(bool forced) return true; } -void TacticalButtonClass::OnMouseEnter() +void SWButtonClass::OnMouseEnter() { if (!SWSidebarClass::IsEnabled()) return; @@ -136,7 +136,7 @@ void TacticalButtonClass::OnMouseEnter() MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } -void TacticalButtonClass::OnMouseLeave() +void SWButtonClass::OnMouseLeave() { if (!SWSidebarClass::IsEnabled()) return; @@ -148,7 +148,7 @@ void TacticalButtonClass::OnMouseLeave() CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); } -bool TacticalButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) +bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { if ((int)flags & (int)GadgetFlag::LeftPress) { @@ -159,12 +159,12 @@ bool TacticalButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi return this->ControlClass::Action(flags, pKey, KeyModifier::None); } -void TacticalButtonClass::SetColumn(int column) +void SWButtonClass::SetColumn(int column) { this->ColumnIndex = column; } -bool TacticalButtonClass::LaunchSuper() const +bool SWButtonClass::LaunchSuper() const { const auto pCurrent = HouseClass::CurrentPlayer(); const auto pSuper = pCurrent->Supers[this->SuperIndex]; diff --git a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h similarity index 82% rename from src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h rename to src/Ext/Sidebar/SWSidebar/SWButtonClass.h index 90edc2b5ef..cf78966dee 100644 --- a/src/Ext/Sidebar/SWSidebar/TacticalButtonClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h @@ -1,13 +1,13 @@ #pragma once #include -class TacticalButtonClass : public ControlClass +class SWButtonClass : public ControlClass { public: - TacticalButtonClass() = default; - TacticalButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height); + SWButtonClass() = default; + SWButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height); - ~TacticalButtonClass() = default; + ~SWButtonClass() = default; virtual bool Draw(bool forced) override; virtual void OnMouseEnter() override; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index e1533b8c4d..2080bb38e6 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -26,10 +26,15 @@ bool SWColumnClass::Draw(bool forced) if (centerPCX) { - RectangleStruct backRect = { this->X, this->Y, centerPCX->GetWidth(), centerPCX->GetHeight() }; + RectangleStruct backRect = { this->X, 0, centerPCX->GetWidth(), centerPCX->GetHeight() }; backRect.Width = centerPCX->GetWidth(); backRect.Height = centerPCX->GetHeight(); - PCX::Instance->BlitToSurface(&backRect, pSurface, centerPCX); + + for (const auto button : this->Buttons) + { + backRect.Y = button->Y; + PCX::Instance->BlitToSurface(&backRect, pSurface, centerPCX); + } } if (const auto topPCX = pSideExt->ExclusiveSWSidebar_TopPCX.GetSurface()) @@ -106,7 +111,7 @@ bool SWColumnClass::AddButton(int superIdx) if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) return false; - const auto button = DLLCreate(TacticalButtonClass::StartID + superIdx, superIdx, 0, 0, 60, 48); + const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, 60, 48); if (!button) return false; @@ -121,7 +126,7 @@ bool SWColumnClass::RemoveButton(int superIdx) { auto& buttons = this->Buttons; - const auto it = std::find_if(buttons.begin(), buttons.end(), [superIdx](TacticalButtonClass* const button) { return button->SuperIndex == superIdx; }); + const auto it = std::find_if(buttons.begin(), buttons.end(), [superIdx](SWButtonClass* const button) { return button->SuperIndex == superIdx; }); if (it == buttons.end()) return false; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.h b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h index 13ffccfd1f..fc20a3464e 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h @@ -1,5 +1,5 @@ #pragma once -#include "TacticalButtonClass.h" +#include "SWButtonClass.h" #include #include @@ -23,6 +23,6 @@ class SWColumnClass : public ControlClass void SetHeight(int height); - std::vector Buttons {}; + std::vector Buttons {}; int MaxButtons { 0 }; }; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index fb063a7b1f..d2e42ef0c5 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -18,7 +18,7 @@ bool SWSidebarClass::AddColumn() if (static_cast(columns.size()) >= Phobos::UI::ExclusiveSWSidebar_MaxColumn) return false; - const auto column = DLLCreate(TacticalButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::ExclusiveSWSidebar_Interval, 48); + const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::ExclusiveSWSidebar_Interval, 48); if (!column) return false; @@ -79,7 +79,7 @@ bool SWSidebarClass::AddButton(int superIdx) if (columns.empty() && !this->AddColumn()) return false; - if (std::any_of(columns.begin(), columns.end(), [superIdx](SWColumnClass* column) { return std::any_of(column->Buttons.begin(), column->Buttons.end(), [superIdx](TacticalButtonClass* button) { return button->SuperIndex == superIdx; }); })) + if (std::any_of(columns.begin(), columns.end(), [superIdx](SWColumnClass* column) { return std::any_of(column->Buttons.begin(), column->Buttons.end(), [superIdx](SWButtonClass* button) { return button->SuperIndex == superIdx; }); })) return true; const bool success = columns.back()->AddButton(superIdx); @@ -113,7 +113,7 @@ void SWSidebarClass::SortButtons() return; } - std::vector vec_Buttons; + std::vector vec_Buttons; vec_Buttons.reserve(this->GetMaximumButtonCount()); for (const auto column : columns) @@ -124,7 +124,7 @@ void SWSidebarClass::SortButtons() column->ClearButtons(false); } - std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [](TacticalButtonClass* const a, TacticalButtonClass* const b) + std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [](SWButtonClass* const a, SWButtonClass* const b) { return BuildType::SortsBefore(AbstractType::Special, a->SuperIndex, AbstractType::Special, b->SuperIndex); }); @@ -259,7 +259,7 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) { if (const auto toggleShape = pSideExt->ExclusiveSWSidebar_ToggleShape.Get()) { - if (const auto toggleButton = DLLCreate(TacticalButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, toggleShape->Width, toggleShape->Height)) + if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, toggleShape->Width, toggleShape->Height)) { toggleButton->Zap(); GScreenClass::Instance->AddButton(toggleButton); diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 93880f46f4..6aa1530306 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -1,5 +1,5 @@ #pragma once -#include "TacticalButtonClass.h" +#include "SWButtonClass.h" #include "SWColumnClass.h" #include #include @@ -33,7 +33,7 @@ class SWSidebarClass public: std::vector Columns {}; SWColumnClass* CurrentColumn { nullptr }; - TacticalButtonClass* CurrentButton { nullptr }; + SWButtonClass* CurrentButton { nullptr }; ToggleSWButtonClass* ToggleButton { nullptr }; static CommandClass* Commands[10]; From ded978f878c7462bfb5487582e2adaf21240f24f Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Mon, 11 Nov 2024 10:48:40 +0800 Subject: [PATCH 04/69] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20YRpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 001812ddab..55b5ace55f 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 001812ddab407d1b920d2abff4ac3fa426039e1e +Subproject commit 55b5ace55fcd93eaa630fea7e85ae0e5018910de From 14343f774a9218732afcaf72fc51f5d7054b552b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Mon, 11 Nov 2024 10:56:55 +0800 Subject: [PATCH 05/69] =?UTF-8?q?Revert=20"=E6=9B=B4=E6=96=B0=20YRpp"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ded978f878c7462bfb5487582e2adaf21240f24f. --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 55b5ace55f..001812ddab 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 55b5ace55fcd93eaa630fea7e85ae0e5018910de +Subproject commit 001812ddab407d1b920d2abff4ac3fa426039e1e From 5588ff44ee24989de24a4a820d98b0d6e81c3d6a Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Mon, 11 Nov 2024 10:58:16 +0800 Subject: [PATCH 06/69] fix error --- YRpp | 2 +- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 4 ++-- src/Utilities/AresFunctions.h | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/YRpp b/YRpp index 001812ddab..55b5ace55f 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 001812ddab407d1b920d2abff4ac3fa426039e1e +Subproject commit 55b5ace55fcd93eaa630fea7e85ae0e5018910de diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 12481cda8e..411b9f1fbc 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -66,7 +66,7 @@ bool SWButtonClass::Draw(bool forced) } if (pSuper->IsReady && !pCurrent->CanTransactMoney(pSWExt->Money_Amount) || - (pSWExt->SW_UseAITargeting && AresHelper::CanUseAres && !AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) + (pSWExt->SW_UseAITargeting && AresFunctions::IsTargetConstraintsEligible && !AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(AresFunctions::SWTypeExtMap, pSuper->Type), HouseClass::CurrentPlayer, true))) { RectangleStruct darkenBounds { 0, 0, location.X + this->Width, location.Y + this->Height }; pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, FileSystem::DARKEN_SHP, 0, &location, &darkenBounds, BlitterFlags::bf_400 | BlitterFlags::Darken, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); @@ -183,7 +183,7 @@ bool SWButtonClass::LaunchSuper() const VoxClass::PlayIndex(pSWExt->EVA_InsufficientFunds); pSWExt->PrintMessage(pSWExt->Message_InsufficientFunds, pCurrent); } - else if (!pSWExt->SW_UseAITargeting || (AresHelper::CanUseAres && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) + else if (!pSWExt->SW_UseAITargeting || (AresFunctions::IsTargetConstraintsEligible && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(AresFunctions::SWTypeExtMap, pSuper->Type), HouseClass::CurrentPlayer, true))) { if (!manual && !unstopable) { diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index a60dffc8f9..85a8309418 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -19,8 +19,9 @@ class AresFunctions static bool(__thiscall* IsTargetConstraintsEligible)(void*, HouseClass*, bool); static void*(__thiscall* SWTypeExtMap_Find)(void*, SuperWeaponTypeClass*); -private: + static void* SWTypeExtMap; +private: static constexpr bool _maybe = false; From 41e15ca37e49e909c69c0789a7047693cc6aa408 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Mon, 11 Nov 2024 11:10:30 +0800 Subject: [PATCH 07/69] fix YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 55b5ace55f..d5a45c8df1 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 55b5ace55fcd93eaa630fea7e85ae0e5018910de +Subproject commit d5a45c8df1615985246fb64d2cc218f221a014ff From ce59a567430185184e336c33958ca9ddec3d7abd Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:10:18 +0800 Subject: [PATCH 08/69] YRpp fix --- .gitmodules | 2 +- YRpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index d2420043fd..adf6beaea1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "YRpp"] path = YRpp - url = https://github.com/Phobos-developers/YRpp.git + url = git@github.com:Phobos-developers/YRpp.git diff --git a/YRpp b/YRpp index d5a45c8df1..0b7b61a49c 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit d5a45c8df1615985246fb64d2cc218f221a014ff +Subproject commit 0b7b61a49c2a5890fee918edcdc58008814f79f7 From 88b4b574dfe8b80b88d9953c866d9b74223aa4d1 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 7 Dec 2024 18:49:58 +0800 Subject: [PATCH 09/69] fix something --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 4 ++-- src/Utilities/AresFunctions.h | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 411b9f1fbc..a51734fc2a 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -66,7 +66,7 @@ bool SWButtonClass::Draw(bool forced) } if (pSuper->IsReady && !pCurrent->CanTransactMoney(pSWExt->Money_Amount) || - (pSWExt->SW_UseAITargeting && AresFunctions::IsTargetConstraintsEligible && !AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(AresFunctions::SWTypeExtMap, pSuper->Type), HouseClass::CurrentPlayer, true))) + (pSWExt->SW_UseAITargeting && AresFunctions::IsTargetConstraintsEligible && !AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) { RectangleStruct darkenBounds { 0, 0, location.X + this->Width, location.Y + this->Height }; pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, FileSystem::DARKEN_SHP, 0, &location, &darkenBounds, BlitterFlags::bf_400 | BlitterFlags::Darken, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); @@ -183,7 +183,7 @@ bool SWButtonClass::LaunchSuper() const VoxClass::PlayIndex(pSWExt->EVA_InsufficientFunds); pSWExt->PrintMessage(pSWExt->Message_InsufficientFunds, pCurrent); } - else if (!pSWExt->SW_UseAITargeting || (AresFunctions::IsTargetConstraintsEligible && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(AresFunctions::SWTypeExtMap, pSuper->Type), HouseClass::CurrentPlayer, true))) + else if (!pSWExt->SW_UseAITargeting || (AresFunctions::IsTargetConstraintsEligible && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) { if (!manual && !unstopable) { diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index d782ef0446..e19f9acde4 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -27,10 +27,6 @@ class AresFunctions static bool(__thiscall* IsTargetConstraintsEligible)(void*, HouseClass*, bool); - static void*(__thiscall* SWTypeExtMap_Find)(void*, SuperWeaponTypeClass*); - - static void* SWTypeExtMap; - static std::function SWTypeExtMap_Find; private: From f83770d075bdfdfa8c4db337d7fa3ad3688cfdea Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:05:16 +0800 Subject: [PATCH 10/69] Update .gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index adf6beaea1..d2420043fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "YRpp"] path = YRpp - url = git@github.com:Phobos-developers/YRpp.git + url = https://github.com/Phobos-developers/YRpp.git From 09dc6d581b7f676719856cd83e2a85b162beff75 Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sat, 7 Dec 2024 20:20:32 +0800 Subject: [PATCH 11/69] Update AresAddressInit.cpp --- src/Utilities/AresAddressInit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Utilities/AresAddressInit.cpp b/src/Utilities/AresAddressInit.cpp index 48c247c43d..320f064703 100644 --- a/src/Utilities/AresAddressInit.cpp +++ b/src/Utilities/AresAddressInit.cpp @@ -5,6 +5,7 @@ decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr; decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr; +decltype(AresFunctions::IsTargetConstraintsEligible) AresFunctions::IsTargetConstraintsEligible = nullptr; std::function AresFunctions::SWTypeExtMap_Find; void* AresFunctions::_SWTypeExtMap = nullptr; From 59aaa4aa01b71c6cc14f7ad9e41ee6ba3092c7d5 Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sat, 7 Dec 2024 20:25:04 +0800 Subject: [PATCH 12/69] Update User-Interface.md --- docs/User-Interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 51e1530779..0c2df6dcf6 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -607,7 +607,7 @@ ExclusiveSWSidebar.BottomPCX= ; filename - including the .pcx extension ExclusiveSWSidebar.ToggleShape= ; filename - including the .shp extension [SOMESW] -AllowInExclusiveSidebar=true ; boolean +ExclusiveSidebar.Allow=true ; boolean ExclusiveSidebar.PriorityHouses= ; list of house types ExclusiveSidebar.RequiredHouses= ; list of house types ``` From 1a816347212f56f69f8419dd72287453d193dbff Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 10 Dec 2024 11:05:32 +0800 Subject: [PATCH 13/69] change tags and update docs --- docs/User-Interface.md | 33 ++++++++++---------- src/Commands/ToggleSWSidebar.cpp | 4 +-- src/Ext/SWType/Body.cpp | 12 +++---- src/Ext/SWType/Body.h | 12 +++---- src/Ext/Side/Body.cpp | 16 +++++----- src/Ext/Side/Body.h | 16 +++++----- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 2 +- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 14 ++++----- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 16 +++++----- src/Phobos.INI.cpp | 30 +++++++++--------- src/Phobos.h | 8 ++--- 11 files changed, 82 insertions(+), 81 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 0c2df6dcf6..9373d67196 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -581,35 +581,36 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable ### Exclusive SuperWeapon Sidebar -- It is possible to put sw cameos on the left of screen like C&C3 when `ExclusiveSuperWeaponSidebar` is true. +- It is possible to put sw cameos on the left of screen like C&C3 when `SuperWeaponSidebar` is true. - In theory, it should be compatible with Ares - Cameos arranged in a pyramid shape. -- `ExclusiveSWSidebar.Interval` specific how many leptons between two columns. -- `ExclusiveSuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. -- `ExclusiveSWSidebar.MaxColumn` controls that maximum count of columns. -- You can also launch first 10 SW by hotkey. +- `SuperWeaponSidebar.Interval` specific how many leptons between two columns. +- `SuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. +- `SuperWeaponSidebar.MaxColumn` controls that maximum count of columns. +- You can also launch first 10 SW by hotkey in INTERFACE category. +- For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR`, `TXT_TOGGLE_SW_SIDEBAR_DESC`, `MSG:SuperWeaponSidebarEnabled` and `MSG:SuperWeaponSidebarDisabled` into your `.csf` file. In `uimd.ini`: ```ini [Sidebar] -ExclusiveSWSidebar=false ; boolean -ExclusiveSWSidebar.Interval=0 ; integer -ExclusiveSWSidebar.Max=0 ; integer -ExclusiveSWSidebar.MaxColumn= ; integer +SuperWeaponSidebar=false ; boolean +SuperWeaponSidebar.Interval=0 ; integer +SuperWeaponSidebar.Max=0 ; integer +SuperWeaponSidebar.MaxColumn= ; integer ``` In `rulesmd.ini` ```ini [SOMESIDE] -ExclusiveSWSidebar.TopPCX= ; filename - including the .pcx extension -ExclusiveSWSidebar.CenterPCX= ; filename - including the .pcx extension -ExclusiveSWSidebar.BottomPCX= ; filename - including the .pcx extension -ExclusiveSWSidebar.ToggleShape= ; filename - including the .shp extension +SuperWeaponSidebar.TopPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.CenterPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.BottomPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.ToggleShape= ; filename - including the .shp extension [SOMESW] -ExclusiveSidebar.Allow=true ; boolean -ExclusiveSidebar.PriorityHouses= ; list of house types -ExclusiveSidebar.RequiredHouses= ; list of house types +SuperWeaponSidebar.Allow=true ; boolean +SuperWeaponSidebar.PriorityHouses= ; list of house types +SuperWeaponSidebar.RequiredHouses= ; list of house types ``` ## Miscellanous diff --git a/src/Commands/ToggleSWSidebar.cpp b/src/Commands/ToggleSWSidebar.cpp index 1c8e58c767..09450c5e8e 100644 --- a/src/Commands/ToggleSWSidebar.cpp +++ b/src/Commands/ToggleSWSidebar.cpp @@ -29,9 +29,9 @@ void ToggleSWSidebar::Execute(WWKey eInput) const ToggleSWButtonClass::SwitchSidebar(); if (SidebarExt::Global()->SWSidebar_Enable) - MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("TXT_EX_SW_SIDEBAR_ENABLE", L"Super Weapon Sidebar Enabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); + MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("MSG:SuperWeaponSidebarEnabled", L"Super Weapon Sidebar Enabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); else - MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("TXT_EX_SW_SIDEBAR_DISABLE", L"Super Weapon Sidebar Disabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); + MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("MSG:SuperWeaponSidebarDisabled", L"Super Weapon Sidebar Disabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); if (SWSidebarClass::Instance.CurrentColumn) MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); diff --git a/src/Ext/SWType/Body.cpp b/src/Ext/SWType/Body.cpp index 7c503da469..8124860353 100644 --- a/src/Ext/SWType/Body.cpp +++ b/src/Ext/SWType/Body.cpp @@ -62,9 +62,9 @@ void SWTypeExt::ExtData::Serialize(T& Stm) .Process(this->Convert_Pairs) .Process(this->ShowDesignatorRange) .Process(this->TabIndex) - .Process(this->ExclusiveSidebar_Allow) - .Process(this->ExclusiveSidebar_PriorityHouses) - .Process(this->ExclusiveSidebar_RequiredHouses) + .Process(this->SuperWeaponSidebar_Allow) + .Process(this->SuperWeaponSidebar_PriorityHouses) + .Process(this->SuperWeaponSidebar_RequiredHouses) .Process(this->SidebarPal) .Process(this->SidebarPCX) .Process(this->UseWeeds) @@ -214,9 +214,9 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->TabIndex.Read(exINI, pSection, "TabIndex"); GeneralUtils::IntValidCheck(&this->TabIndex, pSection, "TabIndex", 1, 0, 3); - this->ExclusiveSidebar_Allow.Read(exINI, pSection, "ExclusiveSidebar.Allow"); - this->ExclusiveSidebar_PriorityHouses = pINI->ReadHouseTypesList(pSection, "ExclusiveSidebar.PriorityHouses", this->ExclusiveSidebar_PriorityHouses); - this->ExclusiveSidebar_RequiredHouses = pINI->ReadHouseTypesList(pSection, "ExclusiveSidebar.RequiredHouses", this->ExclusiveSidebar_RequiredHouses); + this->SuperWeaponSidebar_Allow.Read(exINI, pSection, "SuperWeaponSidebar.Allow"); + this->SuperWeaponSidebar_PriorityHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.PriorityHouses", this->SuperWeaponSidebar_PriorityHouses); + this->SuperWeaponSidebar_RequiredHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.RequiredHouses", this->SuperWeaponSidebar_RequiredHouses); this->SidebarPal.LoadFromINI(pINI, pSection, "SidebarPalette"); this->SidebarPCX.Read(pINI, pSection, "SidebarPCX"); diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index a740a78b41..2e7e93475a 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -78,9 +78,9 @@ class SWTypeExt Valueable TabIndex; - Valueable ExclusiveSidebar_Allow; - DWORD ExclusiveSidebar_PriorityHouses; - DWORD ExclusiveSidebar_RequiredHouses; + Valueable SuperWeaponSidebar_Allow; + DWORD SuperWeaponSidebar_PriorityHouses; + DWORD SuperWeaponSidebar_RequiredHouses; CustomPalette SidebarPal; PhobosPCXFile SidebarPCX; @@ -152,9 +152,9 @@ class SWTypeExt , Convert_Pairs {} , ShowDesignatorRange { true } , TabIndex { 1 } - , ExclusiveSidebar_Allow { true } - , ExclusiveSidebar_PriorityHouses { 0u } - , ExclusiveSidebar_RequiredHouses { 0xFFFFFFFFu } + , SuperWeaponSidebar_Allow { true } + , SuperWeaponSidebar_PriorityHouses { 0u } + , SuperWeaponSidebar_RequiredHouses { 0xFFFFFFFFu } , SidebarPal {} , SidebarPCX {} , UseWeeds { false } diff --git a/src/Ext/Side/Body.cpp b/src/Ext/Side/Body.cpp index fbc5e33aec..0db95a68a9 100644 --- a/src/Ext/Side/Body.cpp +++ b/src/Ext/Side/Body.cpp @@ -43,10 +43,10 @@ void SideExt::ExtData::LoadFromINIFile(CCINIClass* pINI) this->ToolTip_Background_BlurSize.Read(exINI, pSection, "ToolTip.Background.BlurSize"); this->BriefingTheme = pINI->ReadTheme(pSection, "BriefingTheme", this->BriefingTheme); - this->ExclusiveSWSidebar_TopPCX.Read(pINI, pSection, "ExclusiveSWSidebar.TopPCX"); - this->ExclusiveSWSidebar_CenterPCX.Read(pINI, pSection, "ExclusiveSWSidebar.CenterPCX"); - this->ExclusiveSWSidebar_BottomPCX.Read(pINI, pSection, "ExclusiveSWSidebar.BottomPCX"); - this->ExclusiveSWSidebar_ToggleShape.Read(exINI, pSection, "ExclusiveSWSidebar.ToggleShape"); + this->SuperWeaponSidebar_TopPCX.Read(pINI, pSection, "SuperWeaponSidebar.TopPCX"); + this->SuperWeaponSidebar_CenterPCX.Read(pINI, pSection, "SuperWeaponSidebar.CenterPCX"); + this->SuperWeaponSidebar_BottomPCX.Read(pINI, pSection, "SuperWeaponSidebar.BottomPCX"); + this->SuperWeaponSidebar_ToggleShape.Read(exINI, pSection, "SuperWeaponSidebar.ToggleShape"); } // ============================= @@ -76,10 +76,10 @@ void SideExt::ExtData::Serialize(T& Stm) .Process(this->IngameScore_WinTheme) .Process(this->IngameScore_LoseTheme) .Process(this->BriefingTheme) - .Process(this->ExclusiveSWSidebar_TopPCX) - .Process(this->ExclusiveSWSidebar_CenterPCX) - .Process(this->ExclusiveSWSidebar_BottomPCX) - .Process(this->ExclusiveSWSidebar_ToggleShape) + .Process(this->SuperWeaponSidebar_TopPCX) + .Process(this->SuperWeaponSidebar_CenterPCX) + .Process(this->SuperWeaponSidebar_BottomPCX) + .Process(this->SuperWeaponSidebar_ToggleShape) ; } diff --git a/src/Ext/Side/Body.h b/src/Ext/Side/Body.h index 7803b9840f..5326d5ac97 100644 --- a/src/Ext/Side/Body.h +++ b/src/Ext/Side/Body.h @@ -37,10 +37,10 @@ class SideExt Nullable ToolTip_Background_BlurSize; Valueable BriefingTheme; - PhobosPCXFile ExclusiveSWSidebar_TopPCX; - PhobosPCXFile ExclusiveSWSidebar_CenterPCX; - PhobosPCXFile ExclusiveSWSidebar_BottomPCX; - Valueable ExclusiveSWSidebar_ToggleShape; + PhobosPCXFile SuperWeaponSidebar_TopPCX; + PhobosPCXFile SuperWeaponSidebar_CenterPCX; + PhobosPCXFile SuperWeaponSidebar_BottomPCX; + Valueable SuperWeaponSidebar_ToggleShape; ExtData(SideClass* OwnerObject) : Extension(OwnerObject) , ArrayIndex { -1 } @@ -63,10 +63,10 @@ class SideExt , ToolTip_Background_Opacity { } , ToolTip_Background_BlurSize { } , BriefingTheme { -1 } - , ExclusiveSWSidebar_TopPCX { } - , ExclusiveSWSidebar_CenterPCX { } - , ExclusiveSWSidebar_BottomPCX { } - , ExclusiveSWSidebar_ToggleShape { nullptr } + , SuperWeaponSidebar_TopPCX { } + , SuperWeaponSidebar_CenterPCX { } + , SuperWeaponSidebar_BottomPCX { } + , SuperWeaponSidebar_ToggleShape { nullptr } { } virtual ~ExtData() = default; diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index a51734fc2a..2c570efbcc 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -235,7 +235,7 @@ bool ToggleSWButtonClass::Draw(bool forced) return false; const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - const auto pShape = pSideExt->ExclusiveSWSidebar_ToggleShape.Get(); + const auto pShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get(); if (!pShape) return false; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 2080bb38e6..d20b80ece6 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -10,7 +10,7 @@ SWColumnClass::SWColumnClass(unsigned int id, int x, int y, int width, int heigh auto& columns = SWSidebarClass::Instance.Columns; columns.emplace_back(this); - this->MaxButtons = Phobos::UI::ExclusiveSWSidebar_Max - (static_cast(columns.size()) - 1); + this->MaxButtons = Phobos::UI::SuperWeaponSidebar_Max - (static_cast(columns.size()) - 1); } bool SWColumnClass::Draw(bool forced) @@ -22,7 +22,7 @@ bool SWColumnClass::Draw(bool forced) auto bounds = pSurface->GetRect(); const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - const auto centerPCX = pSideExt->ExclusiveSWSidebar_CenterPCX.GetSurface(); + const auto centerPCX = pSideExt->SuperWeaponSidebar_CenterPCX.GetSurface(); if (centerPCX) { @@ -37,14 +37,14 @@ bool SWColumnClass::Draw(bool forced) } } - if (const auto topPCX = pSideExt->ExclusiveSWSidebar_TopPCX.GetSurface()) + if (const auto topPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) { RectangleStruct backRect = { this->X, this->Y, topPCX->GetWidth(), topPCX->GetHeight() };; backRect.Y -= backRect.Height; PCX::Instance->BlitToSurface(&backRect, pSurface, topPCX); } - if (const auto bottomPCX = pSideExt->ExclusiveSWSidebar_BottomPCX.GetSurface()) + if (const auto bottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) { RectangleStruct backRect = { this->X, this->Y, bottomPCX->GetWidth(), bottomPCX->GetHeight() };; backRect.Y += this->Height; @@ -90,15 +90,15 @@ bool SWColumnClass::AddButton(int superIdx) if (!pSWExt->SW_ShowCameo) return true; - if (!Phobos::UI::ExclusiveSWSidebar) + if (!Phobos::UI::SuperWeaponSidebar) return false; - if (!pSWExt->ExclusiveSidebar_Allow) + if (!pSWExt->SuperWeaponSidebar_Allow) return false; const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; - if ((pSWExt->ExclusiveSidebar_RequiredHouses & ownerBits) == 0) + if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) return false; } else diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index d2e42ef0c5..b3aca6f7a0 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -15,10 +15,10 @@ bool SWSidebarClass::AddColumn() { auto& columns = this->Columns; - if (static_cast(columns.size()) >= Phobos::UI::ExclusiveSWSidebar_MaxColumn) + if (static_cast(columns.size()) >= Phobos::UI::SuperWeaponSidebar_MaxColumn) return false; - const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::ExclusiveSWSidebar_Interval, 48); + const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::SuperWeaponSidebar_Interval, 48); if (!column) return false; @@ -131,7 +131,7 @@ void SWSidebarClass::SortButtons() const int buttonCount = static_cast(vec_Buttons.size()); const int cameoWidth = 60, cameoHeight = 48; - const int maximum = Phobos::UI::ExclusiveSWSidebar_Max; + const int maximum = Phobos::UI::SuperWeaponSidebar_Max; Point2D location = { 0, (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * cameoHeight) / 2 }; int location_Y = location.Y; int rowIdx = 0, columnIdx = 0; @@ -153,7 +153,7 @@ void SWSidebarClass::SortButtons() rowIdx = 0; columnIdx++; location_Y += cameoHeight / 2; - location = { location.X + cameoWidth + Phobos::UI::ExclusiveSWSidebar_Interval, location_Y }; + location = { location.X + cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, location_Y }; } else { @@ -170,8 +170,8 @@ void SWSidebarClass::SortButtons() int SWSidebarClass::GetMaximumButtonCount() { - const int firstColumn = Phobos::UI::ExclusiveSWSidebar_Max; - const int columns = std::min(firstColumn, Phobos::UI::ExclusiveSWSidebar_MaxColumn); + const int firstColumn = Phobos::UI::SuperWeaponSidebar_Max; + const int columns = std::min(firstColumn, Phobos::UI::SuperWeaponSidebar_MaxColumn); return (firstColumn + (firstColumn - (columns - 1))) * columns / 2; } @@ -252,12 +252,12 @@ DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) { - if (!Phobos::UI::ExclusiveSWSidebar || Unsorted::ArmageddonMode) + if (!Phobos::UI::SuperWeaponSidebar || Unsorted::ArmageddonMode) return 0; if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) { - if (const auto toggleShape = pSideExt->ExclusiveSWSidebar_ToggleShape.Get()) + if (const auto toggleShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get()) { if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, toggleShape->Width, toggleShape->Height)) { diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 0ebb1ee5be..277a3f56dd 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -33,10 +33,10 @@ bool Phobos::UI::PowerDelta_Show = false; double Phobos::UI::PowerDelta_ConditionYellow = 0.75; double Phobos::UI::PowerDelta_ConditionRed = 1.0; bool Phobos::UI::CenterPauseMenuBackground = false; -bool Phobos::UI::ExclusiveSWSidebar = false; -int Phobos::UI::ExclusiveSWSidebar_Interval = 0; -int Phobos::UI::ExclusiveSWSidebar_Max = 0; -int Phobos::UI::ExclusiveSWSidebar_MaxColumn = INT32_MAX; +bool Phobos::UI::SuperWeaponSidebar = false; +int Phobos::UI::SuperWeaponSidebar_Interval = 0; +int Phobos::UI::SuperWeaponSidebar_Max = 0; +int Phobos::UI::SuperWeaponSidebar_MaxColumn = INT32_MAX; bool Phobos::UI::WeedsCounter_Show = false; bool Phobos::UI::AnchoredToolTips = false; @@ -166,24 +166,24 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::UI::CenterPauseMenuBackground = ini_uimd.ReadBool(SIDEBAR_SECTION, "CenterPauseMenuBackground", Phobos::UI::CenterPauseMenuBackground); - Phobos::UI::ExclusiveSWSidebar = - ini_uimd.ReadBool(SIDEBAR_SECTION, "ExclusiveSWSidebar", Phobos::UI::ExclusiveSWSidebar); + Phobos::UI::SuperWeaponSidebar = + ini_uimd.ReadBool(SIDEBAR_SECTION, "SuperWeaponSidebar", Phobos::UI::SuperWeaponSidebar); - Phobos::UI::ExclusiveSWSidebar_Interval = - ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.Interval", Phobos::UI::ExclusiveSWSidebar_Interval); + Phobos::UI::SuperWeaponSidebar_Interval = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Interval", Phobos::UI::SuperWeaponSidebar_Interval); - Phobos::UI::ExclusiveSWSidebar_Max = - ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.Max", Phobos::UI::ExclusiveSWSidebar_Max); + Phobos::UI::SuperWeaponSidebar_Max = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Max", Phobos::UI::SuperWeaponSidebar_Max); const int screenHeight = GameOptionsClass::Instance->ScreenHeight - 192; - if (Phobos::UI::ExclusiveSWSidebar_Max > 0) - Phobos::UI::ExclusiveSWSidebar_Max = std::min(Phobos::UI::ExclusiveSWSidebar_Max, screenHeight / 48); + if (Phobos::UI::SuperWeaponSidebar_Max > 0) + Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / 48); else - Phobos::UI::ExclusiveSWSidebar_Max = screenHeight / 48; + Phobos::UI::SuperWeaponSidebar_Max = screenHeight / 48; - Phobos::UI::ExclusiveSWSidebar_MaxColumn = - ini_uimd.ReadInteger(SIDEBAR_SECTION, "ExclusiveSWSidebar.MaxColumn", Phobos::UI::ExclusiveSWSidebar_MaxColumn); + Phobos::UI::SuperWeaponSidebar_MaxColumn = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumn", Phobos::UI::SuperWeaponSidebar_MaxColumn); } // UISettings diff --git a/src/Phobos.h b/src/Phobos.h index 6803bfda40..33a99817bf 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -53,10 +53,10 @@ class Phobos static double PowerDelta_ConditionYellow; static double PowerDelta_ConditionRed; static bool CenterPauseMenuBackground; - static bool ExclusiveSWSidebar; - static int ExclusiveSWSidebar_Interval; - static int ExclusiveSWSidebar_Max; - static int ExclusiveSWSidebar_MaxColumn; + static bool SuperWeaponSidebar; + static int SuperWeaponSidebar_Interval; + static int SuperWeaponSidebar_Max; + static int SuperWeaponSidebar_MaxColumn; static bool WeedsCounter_Show; static bool AnchoredToolTips; From 497f371da4c12fb63629c8a75a5fcc30260f9897 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 10 Dec 2024 13:17:35 +0800 Subject: [PATCH 14/69] changes --- Phobos.vcxproj | 2 + docs/User-Interface.md | 2 +- src/Commands/ToggleSWSidebar.cpp | 5 - src/Ext/Side/Body.cpp | 12 +- src/Ext/Side/Body.h | 12 +- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 115 +----------------- src/Ext/Sidebar/SWSidebar/SWButtonClass.h | 22 ---- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 25 ++-- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 10 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 1 + .../Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 115 ++++++++++++++++++ .../Sidebar/SWSidebar/ToggleSWButtonClass.h | 24 ++++ src/Phobos.INI.cpp | 6 +- src/Phobos.h | 2 +- 14 files changed, 176 insertions(+), 177 deletions(-) create mode 100644 src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp create mode 100644 src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.h diff --git a/Phobos.vcxproj b/Phobos.vcxproj index d43169e9a9..d4ab308b6b 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -22,6 +22,7 @@ + @@ -192,6 +193,7 @@ + diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 9373d67196..ab807837ad 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -588,7 +588,7 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable - `SuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. - `SuperWeaponSidebar.MaxColumn` controls that maximum count of columns. - You can also launch first 10 SW by hotkey in INTERFACE category. -- For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR`, `TXT_TOGGLE_SW_SIDEBAR_DESC`, `MSG:SuperWeaponSidebarEnabled` and `MSG:SuperWeaponSidebarDisabled` into your `.csf` file. +- For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. In `uimd.ini`: ```ini diff --git a/src/Commands/ToggleSWSidebar.cpp b/src/Commands/ToggleSWSidebar.cpp index 09450c5e8e..f924e6d854 100644 --- a/src/Commands/ToggleSWSidebar.cpp +++ b/src/Commands/ToggleSWSidebar.cpp @@ -28,11 +28,6 @@ void ToggleSWSidebar::Execute(WWKey eInput) const { ToggleSWButtonClass::SwitchSidebar(); - if (SidebarExt::Global()->SWSidebar_Enable) - MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("MSG:SuperWeaponSidebarEnabled", L"Super Weapon Sidebar Enabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); - else - MessageListClass::Instance->PrintMessage(GeneralUtils::LoadStringUnlessMissing("MSG:SuperWeaponSidebarDisabled", L"Super Weapon Sidebar Disabled."), RulesClass::Instance->MessageDelay, HouseClass::CurrentPlayer->ColorSchemeIndex, true); - if (SWSidebarClass::Instance.CurrentColumn) MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } diff --git a/src/Ext/Side/Body.cpp b/src/Ext/Side/Body.cpp index 0db95a68a9..532b17acf5 100644 --- a/src/Ext/Side/Body.cpp +++ b/src/Ext/Side/Body.cpp @@ -43,9 +43,9 @@ void SideExt::ExtData::LoadFromINIFile(CCINIClass* pINI) this->ToolTip_Background_BlurSize.Read(exINI, pSection, "ToolTip.Background.BlurSize"); this->BriefingTheme = pINI->ReadTheme(pSection, "BriefingTheme", this->BriefingTheme); - this->SuperWeaponSidebar_TopPCX.Read(pINI, pSection, "SuperWeaponSidebar.TopPCX"); - this->SuperWeaponSidebar_CenterPCX.Read(pINI, pSection, "SuperWeaponSidebar.CenterPCX"); - this->SuperWeaponSidebar_BottomPCX.Read(pINI, pSection, "SuperWeaponSidebar.BottomPCX"); + this->SuperWeaponSidebar_TopShape.Read(exINI, pSection, "SuperWeaponSidebar.TopShape"); + this->SuperWeaponSidebar_CenterShape.Read(exINI, pSection, "SuperWeaponSidebar.CenterShape"); + this->SuperWeaponSidebar_BottomShape.Read(exINI, pSection, "SuperWeaponSidebar.BottomShape"); this->SuperWeaponSidebar_ToggleShape.Read(exINI, pSection, "SuperWeaponSidebar.ToggleShape"); } @@ -76,9 +76,9 @@ void SideExt::ExtData::Serialize(T& Stm) .Process(this->IngameScore_WinTheme) .Process(this->IngameScore_LoseTheme) .Process(this->BriefingTheme) - .Process(this->SuperWeaponSidebar_TopPCX) - .Process(this->SuperWeaponSidebar_CenterPCX) - .Process(this->SuperWeaponSidebar_BottomPCX) + .Process(this->SuperWeaponSidebar_TopShape) + .Process(this->SuperWeaponSidebar_CenterShape) + .Process(this->SuperWeaponSidebar_BottomShape) .Process(this->SuperWeaponSidebar_ToggleShape) ; } diff --git a/src/Ext/Side/Body.h b/src/Ext/Side/Body.h index 5326d5ac97..bf1910662a 100644 --- a/src/Ext/Side/Body.h +++ b/src/Ext/Side/Body.h @@ -37,9 +37,9 @@ class SideExt Nullable ToolTip_Background_BlurSize; Valueable BriefingTheme; - PhobosPCXFile SuperWeaponSidebar_TopPCX; - PhobosPCXFile SuperWeaponSidebar_CenterPCX; - PhobosPCXFile SuperWeaponSidebar_BottomPCX; + Valueable SuperWeaponSidebar_TopShape; + Valueable SuperWeaponSidebar_CenterShape; + Valueable SuperWeaponSidebar_BottomShape; Valueable SuperWeaponSidebar_ToggleShape; ExtData(SideClass* OwnerObject) : Extension(OwnerObject) @@ -63,9 +63,9 @@ class SideExt , ToolTip_Background_Opacity { } , ToolTip_Background_BlurSize { } , BriefingTheme { -1 } - , SuperWeaponSidebar_TopPCX { } - , SuperWeaponSidebar_CenterPCX { } - , SuperWeaponSidebar_BottomPCX { } + , SuperWeaponSidebar_TopShape { } + , SuperWeaponSidebar_CenterShape { } + , SuperWeaponSidebar_BottomShape { } , SuperWeaponSidebar_ToggleShape { nullptr } { } diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 2c570efbcc..0f278ba109 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -3,12 +3,10 @@ #include #include #include -#include #include #include #include -#include SWButtonClass::SWButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) : ControlClass(id, x, y, width, height, GadgetFlag::LeftPress, true) @@ -152,6 +150,7 @@ bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { if ((int)flags & (int)GadgetFlag::LeftPress) { + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); this->LaunchSuper(); } @@ -170,7 +169,7 @@ bool SWButtonClass::LaunchSuper() const const auto pSuper = pCurrent->Supers[this->SuperIndex]; const auto pSWExt = SWTypeExt::ExtMap.Find(pSuper->Type); const bool manual = !pSWExt->SW_ManualFire && pSWExt->SW_AutoFire; - const bool unstopable = pSuper->Type->UseChargeDrain && pSuper->ChargeDrainState == ChargeDrainState::Draining && pSWExt->SW_Unstoppable; + const bool unstoppable = pSuper->Type->UseChargeDrain && pSuper->ChargeDrainState == ChargeDrainState::Draining && pSWExt->SW_Unstoppable; if (!pSuper->CanFire() && !manual) { @@ -185,7 +184,7 @@ bool SWButtonClass::LaunchSuper() const } else if (!pSWExt->SW_UseAITargeting || (AresFunctions::IsTargetConstraintsEligible && AresFunctions::IsTargetConstraintsEligible(AresFunctions::SWTypeExtMap_Find(pSuper->Type), HouseClass::CurrentPlayer, true))) { - if (!manual && !unstopable) + if (!manual && !unstoppable) { const auto swIndex = pSuper->Type->ArrayIndex; @@ -220,111 +219,3 @@ bool SWButtonClass::LaunchSuper() const return false; } - -ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, static_cast((int)GadgetFlag::LeftPress | (int)GadgetFlag::LeftRelease), true) -{ - SWSidebarClass::Instance.ToggleButton = this; -} - -bool ToggleSWButtonClass::Draw(bool forced) -{ - auto& columns = SWSidebarClass::Instance.Columns; - - if (columns.empty()) - return false; - - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - const auto pShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get(); - - if (!pShape) - return false; - - const auto pConvert = FileSystem::SIDEBAR_PAL(); - const auto pSurface = DSurface::Composite(); - Point2D position = { this->X, this->Y }; - RectangleStruct destRect = { position.X, position.Y, this->Width, this->Height }; - pSurface->DrawSHP(pConvert, pShape, SWSidebarClass::IsEnabled(), &position, &destRect, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); - - if (this->IsHovering) - { - const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); - pSurface->DrawRect(&destRect, tooltipColor); - } - - return true; -} - -void ToggleSWButtonClass::OnMouseEnter() -{ - auto& columns = SWSidebarClass::Instance.Columns; - - if (columns.empty()) - return; - - this->IsHovering = true; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); -} - -void ToggleSWButtonClass::OnMouseLeave() -{ - auto& columns = SWSidebarClass::Instance.Columns; - - if (columns.empty()) - return; - - this->IsHovering = false; - this->IsPressed = false; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); -} - -bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) -{ - auto& columns = SWSidebarClass::Instance.Columns; - - if (columns.empty()) - return false; - - if ((int)flags & (int)GadgetFlag::LeftPress) - this->IsPressed = true; - - if (((int)flags & (int)GadgetFlag::LeftRelease) && this->IsPressed) - { - this->IsPressed = false; - VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); - ToggleSWButtonClass::SwitchSidebar(); - } - - return this->ControlClass::Action(flags, pKey, KeyModifier::None); -} - -void ToggleSWButtonClass::UpdatePosition() -{ - Point2D position = Point2D::Empty; - auto& columns = SWSidebarClass::Instance.Columns; - - if (!columns.empty()) - { - const auto backColumn = columns.back(); - position.X = SWSidebarClass::Instance.IsEnabled() ? backColumn->X + backColumn->Width : 0; - position.Y = backColumn->Y + (backColumn->Height - this->Height) / 2; - } - else - { - position.X = 0; - position.Y = (GameOptionsClass::Instance->ScreenHeight - this->Height) / 2; - } - - this->SetPosition(position.X, position.Y); -} - -bool ToggleSWButtonClass::SwitchSidebar() -{ - SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; - - if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) - toggleButton->UpdatePosition(); - - return SWSidebarClass::Instance.IsEnabled(); -} diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h index cf78966dee..3defc7e7ff 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h @@ -24,25 +24,3 @@ class SWButtonClass : public ControlClass int ColumnIndex { -1 }; int SuperIndex { -1 }; }; - -class ToggleSWButtonClass : public ControlClass -{ -public: - ToggleSWButtonClass() = default; - ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height); - - ~ToggleSWButtonClass() = default; - - virtual bool Draw(bool forced) override; - virtual void OnMouseEnter() override; - virtual void OnMouseLeave() override; - virtual bool Action(GadgetFlag fags, DWORD* pKey, KeyModifier modifier) override; - - void UpdatePosition(); - - static bool SwitchSidebar(); - -public: - bool IsHovering { false }; - bool IsPressed { false }; -}; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index d20b80ece6..4e6d9dfb8b 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -22,33 +22,26 @@ bool SWColumnClass::Draw(bool forced) auto bounds = pSurface->GetRect(); const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - const auto centerPCX = pSideExt->SuperWeaponSidebar_CenterPCX.GetSurface(); - if (centerPCX) + if (const auto centerShape = pSideExt->SuperWeaponSidebar_CenterShape.Get()) { - RectangleStruct backRect = { this->X, 0, centerPCX->GetWidth(), centerPCX->GetHeight() }; - backRect.Width = centerPCX->GetWidth(); - backRect.Height = centerPCX->GetHeight(); - for (const auto button : this->Buttons) { - backRect.Y = button->Y; - PCX::Instance->BlitToSurface(&backRect, pSurface, centerPCX); + Point2D drawPoint = { this->X, button->Y }; + pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, centerShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); } } - if (const auto topPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) + if (const auto topShape = pSideExt->SuperWeaponSidebar_TopShape.Get()) { - RectangleStruct backRect = { this->X, this->Y, topPCX->GetWidth(), topPCX->GetHeight() };; - backRect.Y -= backRect.Height; - PCX::Instance->BlitToSurface(&backRect, pSurface, topPCX); + Point2D drawPoint = { this->X, this->Y - topShape->Height }; + pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, topShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); } - if (const auto bottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) + if (const auto bottomShape = pSideExt->SuperWeaponSidebar_BottomShape.Get()) { - RectangleStruct backRect = { this->X, this->Y, bottomPCX->GetWidth(), bottomPCX->GetHeight() };; - backRect.Y += this->Height; - PCX::Instance->BlitToSurface(&backRect, pSurface, bottomPCX); + Point2D drawPoint = { this->X, this->Y + bottomShape->Height }; + pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, bottomShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); } for (const auto button : this->Buttons) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index b3aca6f7a0..fb793dcd81 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -15,7 +15,7 @@ bool SWSidebarClass::AddColumn() { auto& columns = this->Columns; - if (static_cast(columns.size()) >= Phobos::UI::SuperWeaponSidebar_MaxColumn) + if (static_cast(columns.size()) >= Phobos::UI::SuperWeaponSidebar_MaxColumns) return false; const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::SuperWeaponSidebar_Interval, 48); @@ -171,7 +171,7 @@ void SWSidebarClass::SortButtons() int SWSidebarClass::GetMaximumButtonCount() { const int firstColumn = Phobos::UI::SuperWeaponSidebar_Max; - const int columns = std::min(firstColumn, Phobos::UI::SuperWeaponSidebar_MaxColumn); + const int columns = std::min(firstColumn, Phobos::UI::SuperWeaponSidebar_MaxColumns); return (firstColumn + (firstColumn - (columns - 1))) * columns / 2; } @@ -184,14 +184,14 @@ bool SWSidebarClass::IsEnabled() DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) { - enum { Nothing = 0x6925FC }; + enum { DoNothing = 0x6925FC }; if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentColumn) - return Nothing; + return DoNothing; const auto toggleButton = SWSidebarClass::Instance.ToggleButton; - return toggleButton && toggleButton->IsHovering ? Nothing : 0; + return toggleButton && toggleButton->IsHovering ? DoNothing : 0; } DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 6aa1530306..b5bd386da2 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -1,6 +1,7 @@ #pragma once #include "SWButtonClass.h" #include "SWColumnClass.h" +#include "ToggleSWButtonClass.h" #include #include diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp new file mode 100644 index 0000000000..a8083f58d2 --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -0,0 +1,115 @@ +#include "ToggleSWButtonClass.h" +#include "SWSidebarClass.h" +#include +#include +#include + +#include + +ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) + : ControlClass(id, x, y, width, height, static_cast((int)GadgetFlag::LeftPress | (int)GadgetFlag::LeftRelease), true) +{ + SWSidebarClass::Instance.ToggleButton = this; +} + +bool ToggleSWButtonClass::Draw(bool forced) +{ + auto& columns = SWSidebarClass::Instance.Columns; + + if (columns.empty()) + return false; + + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get(); + + if (!pShape) + return false; + + const auto pConvert = FileSystem::SIDEBAR_PAL(); + const auto pSurface = DSurface::Composite(); + Point2D position = { this->X, this->Y }; + RectangleStruct destRect = { position.X, position.Y, this->Width, this->Height }; + pSurface->DrawSHP(pConvert, pShape, SWSidebarClass::IsEnabled(), &position, &destRect, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + + if (this->IsHovering) + { + const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); + pSurface->DrawRect(&destRect, tooltipColor); + } + + return true; +} + +void ToggleSWButtonClass::OnMouseEnter() +{ + auto& columns = SWSidebarClass::Instance.Columns; + + if (columns.empty()) + return; + + this->IsHovering = true; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); +} + +void ToggleSWButtonClass::OnMouseLeave() +{ + auto& columns = SWSidebarClass::Instance.Columns; + + if (columns.empty()) + return; + + this->IsHovering = false; + this->IsPressed = false; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); +} + +bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) +{ + auto& columns = SWSidebarClass::Instance.Columns; + + if (columns.empty()) + return false; + + if ((int)flags & (int)GadgetFlag::LeftPress) + this->IsPressed = true; + + if (((int)flags & (int)GadgetFlag::LeftRelease) && this->IsPressed) + { + this->IsPressed = false; + VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); + ToggleSWButtonClass::SwitchSidebar(); + } + + return this->ControlClass::Action(flags, pKey, KeyModifier::None); +} + +void ToggleSWButtonClass::UpdatePosition() +{ + Point2D position = Point2D::Empty; + auto& columns = SWSidebarClass::Instance.Columns; + + if (!columns.empty()) + { + const auto backColumn = columns.back(); + position.X = SWSidebarClass::Instance.IsEnabled() ? backColumn->X + backColumn->Width : 0; + position.Y = backColumn->Y + (backColumn->Height - this->Height) / 2; + } + else + { + position.X = 0; + position.Y = (GameOptionsClass::Instance->ScreenHeight - this->Height) / 2; + } + + this->SetPosition(position.X, position.Y); +} + +bool ToggleSWButtonClass::SwitchSidebar() +{ + SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; + + if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) + toggleButton->UpdatePosition(); + + return SWSidebarClass::Instance.IsEnabled(); +} diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.h b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.h new file mode 100644 index 0000000000..45e293f1ce --- /dev/null +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.h @@ -0,0 +1,24 @@ +#pragma once +#include + +class ToggleSWButtonClass : public ControlClass +{ +public: + ToggleSWButtonClass() = default; + ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height); + + ~ToggleSWButtonClass() = default; + + virtual bool Draw(bool forced) override; + virtual void OnMouseEnter() override; + virtual void OnMouseLeave() override; + virtual bool Action(GadgetFlag fags, DWORD* pKey, KeyModifier modifier) override; + + void UpdatePosition(); + + static bool SwitchSidebar(); + +public: + bool IsHovering { false }; + bool IsPressed { false }; +}; diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 277a3f56dd..5bc0e687a8 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -36,7 +36,7 @@ bool Phobos::UI::CenterPauseMenuBackground = false; bool Phobos::UI::SuperWeaponSidebar = false; int Phobos::UI::SuperWeaponSidebar_Interval = 0; int Phobos::UI::SuperWeaponSidebar_Max = 0; -int Phobos::UI::SuperWeaponSidebar_MaxColumn = INT32_MAX; +int Phobos::UI::SuperWeaponSidebar_MaxColumns = INT32_MAX; bool Phobos::UI::WeedsCounter_Show = false; bool Phobos::UI::AnchoredToolTips = false; @@ -182,8 +182,8 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) else Phobos::UI::SuperWeaponSidebar_Max = screenHeight / 48; - Phobos::UI::SuperWeaponSidebar_MaxColumn = - ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumn", Phobos::UI::SuperWeaponSidebar_MaxColumn); + Phobos::UI::SuperWeaponSidebar_MaxColumns = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumns", Phobos::UI::SuperWeaponSidebar_MaxColumns); } // UISettings diff --git a/src/Phobos.h b/src/Phobos.h index 33a99817bf..f24290259e 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -56,7 +56,7 @@ class Phobos static bool SuperWeaponSidebar; static int SuperWeaponSidebar_Interval; static int SuperWeaponSidebar_Max; - static int SuperWeaponSidebar_MaxColumn; + static int SuperWeaponSidebar_MaxColumns; static bool WeedsCounter_Show; static bool AnchoredToolTips; From 9462d82a6fa9c5d006d1fbcb622ab7f937e13cde Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 10 Dec 2024 13:19:41 +0800 Subject: [PATCH 15/69] docs fix --- docs/User-Interface.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index ab807837ad..7b51c638db 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -586,7 +586,7 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable - Cameos arranged in a pyramid shape. - `SuperWeaponSidebar.Interval` specific how many leptons between two columns. - `SuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. -- `SuperWeaponSidebar.MaxColumn` controls that maximum count of columns. +- `SuperWeaponSidebar.MaxColumns` controls that maximum count of columns. - You can also launch first 10 SW by hotkey in INTERFACE category. - For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. @@ -596,7 +596,7 @@ In `uimd.ini`: SuperWeaponSidebar=false ; boolean SuperWeaponSidebar.Interval=0 ; integer SuperWeaponSidebar.Max=0 ; integer -SuperWeaponSidebar.MaxColumn= ; integer +SuperWeaponSidebar.MaxColumns= ; integer ``` In `rulesmd.ini` From 8bdf383fc96522f2ebaa4bd15dd4806e7038dc8e Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Wed, 11 Dec 2024 09:57:18 +0800 Subject: [PATCH 16/69] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20AresAddressInit.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Utilities/AresAddressInit.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Utilities/AresAddressInit.cpp b/src/Utilities/AresAddressInit.cpp index 320f064703..1c741e396d 100644 --- a/src/Utilities/AresAddressInit.cpp +++ b/src/Utilities/AresAddressInit.cpp @@ -23,7 +23,11 @@ void AresFunctions::InitAres3_0() Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x48C69, { 0x30 }); } else + { NOTE_ARES_FUN(SpawnSurvivors, 0x464C0); + } + + NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032110); NOTE_ARES_FUN(_SWTypeExtMapFind, 0x57C70); NOTE_ARES_FUN(_SWTypeExtMap, 0xC1C54); @@ -43,7 +47,11 @@ void AresFunctions::InitAres3_0p1() Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x498B9, { 0x30 }); } else + { NOTE_ARES_FUN(SpawnSurvivors, 0x47030); + } + + NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032AF0); NOTE_ARES_FUN(_SWTypeExtMapFind, 0x58900); NOTE_ARES_FUN(_SWTypeExtMap, 0xC2C50); From ca25cbd3091838aad87d38cbc3c99491bf5385cc Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Wed, 11 Dec 2024 09:59:43 +0800 Subject: [PATCH 17/69] =?UTF-8?q?=E5=88=A0=E9=99=A4=20AresAddressTable.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Utilities/AresAddressTable.cpp | 47 ------------------------------ 1 file changed, 47 deletions(-) delete mode 100644 src/Utilities/AresAddressTable.cpp diff --git a/src/Utilities/AresAddressTable.cpp b/src/Utilities/AresAddressTable.cpp deleted file mode 100644 index e0c24452b5..0000000000 --- a/src/Utilities/AresAddressTable.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "AresFunctions.h" -#include "AresHelper.h" -#include "Patch.h" -#define NOTE_ARES_FUN(name,reladdr) AresFunctions::name = reinterpret_cast(AresHelper::AresBaseAddress + reladdr) - -decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr; -decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr; -decltype(AresFunctions::IsTargetConstraintsEligible) AresFunctions::IsTargetConstraintsEligible = nullptr; -decltype(AresFunctions::SWTypeExtMap_Find) AresFunctions::SWTypeExtMap_Find = nullptr; -decltype(AresFunctions::SWTypeExtMap) AresFunctions::SWTypeExtMap = nullptr; - -void AresFunctions::InitAres3_0() -{ - NOTE_ARES_FUN(ConvertTypeTo, 0x043650); - if constexpr (AresFunctions::AresWasWrongAboutSpawnSurvivors) - { - Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x4C0EB, { 0x5C }); - Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x48C69, { 0x30 }); - } - else - { - NOTE_ARES_FUN(SpawnSurvivors, 0x0464C0); - NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032110); - NOTE_ARES_FUN(SWTypeExtMap_Find, 0x057C70); - NOTE_ARES_FUN(SWTypeExtMap, 0x0C1C54); - } -} - -void AresFunctions::InitAres3_0p1() -{ - NOTE_ARES_FUN(ConvertTypeTo, 0x044130); - if constexpr (AresFunctions::AresWasWrongAboutSpawnSurvivors) - { - Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x4CD4B, { 0x5C }); - Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x498B9, { 0x30 }); - } - else - { - NOTE_ARES_FUN(SpawnSurvivors, 0x047030); - NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032AF0); - NOTE_ARES_FUN(SWTypeExtMap_Find, 0x058900); - NOTE_ARES_FUN(SWTypeExtMap, 0x0C2C50); - } -} - -#undef NOTE_ARES_FUN From 05d78cfb2808560f3361b75dd923dd4156692575 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 12 Dec 2024 13:00:58 +0800 Subject: [PATCH 18/69] update ToggleSWButtonClass.cpp --- src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index a8083f58d2..b40e2ac5f5 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -77,7 +77,7 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi if (((int)flags & (int)GadgetFlag::LeftRelease) && this->IsPressed) { this->IsPressed = false; - VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); + VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); ToggleSWButtonClass::SwitchSidebar(); } From 2686746896821dd0b8f85a7b3f6b59b7b4876d7b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Fri, 20 Dec 2024 09:18:28 +0800 Subject: [PATCH 19/69] named some magic number --- src/Ext/Sidebar/SWSidebar/SWButtonClass.h | 2 ++ src/Misc/PhobosToolTip.cpp | 2 +- src/Phobos.INI.cpp | 7 ++++--- src/Phobos.h | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h index 3defc7e7ff..ca0fbe9b1a 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h @@ -20,6 +20,8 @@ class SWButtonClass : public ControlClass public: static constexpr int StartID = 2200; + static constexpr int Magic_Align_Y = 27; + bool IsHovering { false }; int ColumnIndex { -1 }; int SuperIndex { -1 }; diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index a0c9d4ba50..bcab664b6e 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -253,7 +253,7 @@ DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) if (const auto button = SWSidebarClass::Instance.CurrentButton) { R->EDX(button->X + button->Width); - R->EAX(button->Y + 27); + R->EAX(button->Y + SWButtonClass::Magic_Align_Y); } } diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 5bc0e687a8..eedf0141fd 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -37,6 +37,7 @@ bool Phobos::UI::SuperWeaponSidebar = false; int Phobos::UI::SuperWeaponSidebar_Interval = 0; int Phobos::UI::SuperWeaponSidebar_Max = 0; int Phobos::UI::SuperWeaponSidebar_MaxColumns = INT32_MAX; +int Phobos::UI::SuperWeaponSidebar_CameoHeight = 48; bool Phobos::UI::WeedsCounter_Show = false; bool Phobos::UI::AnchoredToolTips = false; @@ -175,12 +176,12 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::UI::SuperWeaponSidebar_Max = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Max", Phobos::UI::SuperWeaponSidebar_Max); - const int screenHeight = GameOptionsClass::Instance->ScreenHeight - 192; + const int screenHeight = GameOptionsClass::Instance->ScreenHeight; if (Phobos::UI::SuperWeaponSidebar_Max > 0) - Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / 48); + Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); else - Phobos::UI::SuperWeaponSidebar_Max = screenHeight / 48; + Phobos::UI::SuperWeaponSidebar_Max = screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight; Phobos::UI::SuperWeaponSidebar_MaxColumns = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumns", Phobos::UI::SuperWeaponSidebar_MaxColumns); diff --git a/src/Phobos.h b/src/Phobos.h index f24290259e..2449bbf092 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -57,6 +57,7 @@ class Phobos static int SuperWeaponSidebar_Interval; static int SuperWeaponSidebar_Max; static int SuperWeaponSidebar_MaxColumns; + static int SuperWeaponSidebar_CameoHeight; static bool WeedsCounter_Show; static bool AnchoredToolTips; From ad89d947c774cd086cd9233c93e80953711084dc Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Fri, 20 Dec 2024 15:25:45 +0800 Subject: [PATCH 20/69] fix docs --- docs/User-Interface.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 7b51c638db..9ed6090d88 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -602,9 +602,9 @@ SuperWeaponSidebar.MaxColumns= ; integer In `rulesmd.ini` ```ini [SOMESIDE] -SuperWeaponSidebar.TopPCX= ; filename - including the .pcx extension -SuperWeaponSidebar.CenterPCX= ; filename - including the .pcx extension -SuperWeaponSidebar.BottomPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.TopShape= ; filename - including the .shp extension +SuperWeaponSidebar.CenterShape= ; filename - including the .shp extension +SuperWeaponSidebar.BottomShape= ; filename - including the .shp extension SuperWeaponSidebar.ToggleShape= ; filename - including the .shp extension [SOMESW] From 5ac6ce55c7fcf468772acdfac720810adaa7eac1 Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sat, 21 Dec 2024 05:47:18 +0800 Subject: [PATCH 21/69] [Minor] [Ares Fix] Ares academy fix (#1456) Bug Description: This is a fix to the Ares bug: Academy feature doesn't apply to the initial payload of vehicles built off a War Factory. Curiously, Academy applies to the initial payloads of vehicles under any other circumstances, even when built off a Naval Shipyard. Cause: It is "Unsorted::IKnowWhatImDoing" prevented the "HouseExt::ApplyAcademy" from taking effect. Fix: The fix is simple, when Ares is supposed to have initialized the initial payload, and Academy is prevented from taking any effect, temporarily turn off "Unsorted::IKnowWhatImDoing", invoke "HouseExt::ApplyAcademy", then turn on "Unsorted::IKnowWhatImDoing" again. --------- Co-authored-by: Kerbiter --- CREDITS.md | 1 + docs/Fixed-or-Improved-Logics.md | 1 + docs/Whats-New.md | 1 + src/Misc/Hooks.BugFixes.cpp | 53 +++++++++++++++++++++++++++++++ src/Utilities/AresAddressInit.cpp | 16 ++++++++++ src/Utilities/AresFunctions.h | 9 ++++++ 6 files changed, 81 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index f977b2a3ed..44672248ee 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -408,3 +408,4 @@ This page lists all the individual contributions to the project by their author. - **Damfoos** - extensive and thorough testing - **Dmitry Volkov** - extensive and thorough testing - **Rise of the East community** - extensive playtesting of in-dev features +- **Aephiex** - fixed Ares academy not working on the initial payloads of vehicles built from a war factory diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 3cf0271d9b..6d56a1369f 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -191,6 +191,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed an issue introduced by Ares that caused `Grinding=true` building `ActiveAnim` to be incorrectly restored while `SpecialAnim` was playing and the building was sold, erased or destroyed. - Fixed Ares' Abductor weapon leaves permanent placement stats when abducting moving vehicles. - Suppressed Ares' swizzle warning when parsing `Tags` and `TaskForces` (typically begin with `[Developer fatal]Pointer 00000000 declared change to both`). +- Fixed Academy *(Ares feature)* not working on the initial payloads *(Ares feature)* of vehicles built from a war factory. ## Aircraft diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 0b6f8c19c6..dd839399d8 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -610,6 +610,7 @@ Fixes / interactions with other extensions: - Appended Ares' `SW.Shots` usage to extended tooltips (by Trsdy) - Fixed Ares' Abductor weapon leaves permanent placement stats when abducting moving vehicles (by Trsdy) - Suppressed Ares' swizzle warning when parsing `Tags` and `TaskForces` (by Trsdy) +- Fixed Academy *(Ares feature)* not working on the initial payloads *(Ares feature)* of vehicles built from a war factory. (by Aephiex) ### 0.3.0.1 diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index 984c546dc4..e0376e0a2b 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -32,6 +32,7 @@ #include #include #include +#include /* Allow usage of TileSet of 255 and above without making NE-SW broken bridges unrepairable @@ -1089,3 +1090,55 @@ size_t __fastcall HexStr2Int_replacement(const char* str) } DEFINE_JUMP(CALL, 0x6E8305, GET_OFFSET(HexStr2Int_replacement)); // TaskForce DEFINE_JUMP(CALL, 0x6E5FA6, GET_OFFSET(HexStr2Int_replacement)); // TagType + +// This is the inline function to get the academy type that a techno enjoys. +inline static const AbstractType GetAresAcademyType(TechnoClass* pTechno) +{ + if (pTechno->WhatAmI() == AbstractType::Unit) + { + if (pTechno->GetTechnoType()->ConsideredAircraft) + return AbstractType::Aircraft; + else if (pTechno->GetTechnoType()->Organic) + return AbstractType::Infantry; + else + return AbstractType::Unit; + } + else if (pTechno->WhatAmI() == AbstractType::Infantry + || pTechno->WhatAmI() == AbstractType::Aircraft + || pTechno->WhatAmI() == AbstractType::Building) + { + return pTechno->WhatAmI(); + } + return AbstractType::None; +} + +// This is a fix to the Ares bug: Academy feature doesn't apply to the initial payload of vehicles built off a War Factory. +// Curiously, Academy applies to the initial payloads of vehicles under any other circumstances, even when built off a Naval Shipyard. +// It is "Unsorted::IKnowWhatImDoing" prevented the "HouseExt::ApplyAcademy" from taking effect. +// The fix is simple, when Ares is supposed to have initialized the initial payload, and Academy is prevented from taking any effect, +// temporarily turn off "Unsorted::IKnowWhatImDoing", invoke "HouseExt::ApplyAcademy", then turn on "Unsorted::IKnowWhatImDoing" again. +DEFINE_HOOK(0x4D71A0, FootClass_Put_InitialPayload_AfterAres, 0x6) +{ + GET(FootClass* const, pThis, ESI); + + if (AresFunctions::ApplyAcademy && Unsorted::IKnowWhatImDoing) + { + if (pThis && !pThis->InLimbo && pThis->IsOnMap && pThis->WhatAmI() == AbstractType::Unit + && pThis->GetTechnoType()->Passengers > 0 + && pThis->Passengers.NumPassengers > 0) + { + for (auto pNext = pThis->Passengers.FirstPassenger; pNext; pNext = abstract_cast(pNext->NextObject)) + { + auto abstractType = GetAresAcademyType(pNext); + if (abstractType != AbstractType::None) + { + --Unsorted::IKnowWhatImDoing; + AresFunctions::ApplyAcademy(AresFunctions::HouseExtMap_Find(pNext->Owner), pNext, abstractType); + ++Unsorted::IKnowWhatImDoing; + } + } + } + } + + return 0; +} diff --git a/src/Utilities/AresAddressInit.cpp b/src/Utilities/AresAddressInit.cpp index 48c247c43d..491a25fb4d 100644 --- a/src/Utilities/AresAddressInit.cpp +++ b/src/Utilities/AresAddressInit.cpp @@ -5,10 +5,14 @@ decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr; decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr; +decltype(AresFunctions::ApplyAcademy) AresFunctions::ApplyAcademy = nullptr; std::function AresFunctions::SWTypeExtMap_Find; +std::function AresFunctions::HouseExtMap_Find; void* AresFunctions::_SWTypeExtMap = nullptr; decltype(AresFunctions::_SWTypeExtMapFind) AresFunctions::_SWTypeExtMapFind = nullptr; +void* AresFunctions::_HouseExtMap = nullptr; +decltype(AresFunctions::_HouseExtMapFind) AresFunctions::_HouseExtMapFind = nullptr; void Apply_Ares3_0_Patches(); void Apply_Ares3_0p1_Patches(); @@ -24,10 +28,16 @@ void AresFunctions::InitAres3_0() else NOTE_ARES_FUN(SpawnSurvivors, 0x464C0); + NOTE_ARES_FUN(ApplyAcademy, 0x020750); + NOTE_ARES_FUN(_SWTypeExtMapFind, 0x57C70); NOTE_ARES_FUN(_SWTypeExtMap, 0xC1C54); SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); }; + NOTE_ARES_FUN(_HouseExtMapFind, 0x57C70); + NOTE_ARES_FUN(_HouseExtMap, 0xC1AA8); + HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); }; + #ifndef USING_MULTIFINITE_SYRINGE Apply_Ares3_0_Patches(); #endif @@ -44,10 +54,16 @@ void AresFunctions::InitAres3_0p1() else NOTE_ARES_FUN(SpawnSurvivors, 0x47030); + NOTE_ARES_FUN(ApplyAcademy, 0x0211D0); + NOTE_ARES_FUN(_SWTypeExtMapFind, 0x58900); NOTE_ARES_FUN(_SWTypeExtMap, 0xC2C50); SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); }; + NOTE_ARES_FUN(_HouseExtMapFind, 0x589A0); + NOTE_ARES_FUN(_HouseExtMap, 0xC2B08); + HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); }; + #ifndef USING_MULTIFINITE_SYRINGE Apply_Ares3_0p1_Patches(); #endif diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index 9418cd3831..27230b633d 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -1,5 +1,6 @@ #pragma once #include +#include class TechnoClass; class TechnoTypeClass; class FootClass; @@ -24,12 +25,20 @@ class AresFunctions static bool(__stdcall* ConvertTypeTo)(TechnoClass* pFoot, TechnoTypeClass* pConvertTo); static void(__stdcall* SpawnSurvivors)(FootClass* pThis, TechnoClass* pKiller, bool Select, bool IgnoreDefenses); + + static void(__thiscall* ApplyAcademy)(void*, TechnoClass* pTechno, AbstractType considerAs); + static std::function SWTypeExtMap_Find; + + static std::function HouseExtMap_Find; + private: static constexpr bool _maybe = false; static constexpr bool AresWasWrongAboutSpawnSurvivors = _maybe; static void* _SWTypeExtMap; + static void* _HouseExtMap; static AresSWTypeExtData* (__thiscall* _SWTypeExtMapFind)(void*, SuperWeaponTypeClass*); + static AresHouseExtData* (__thiscall* _HouseExtMapFind)(void*, HouseClass*); }; From d10e50345c205424bd3ead4b84f59594dc77599a Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 21 Dec 2024 09:49:16 +0800 Subject: [PATCH 22/69] align bottom background --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 4e6d9dfb8b..d657990775 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -40,7 +40,7 @@ bool SWColumnClass::Draw(bool forced) if (const auto bottomShape = pSideExt->SuperWeaponSidebar_BottomShape.Get()) { - Point2D drawPoint = { this->X, this->Y + bottomShape->Height }; + Point2D drawPoint = { this->X, this->Y + static_cast(this->Buttons.size()) * Phobos::UI::SuperWeaponSidebar_CameoHeight }; pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, bottomShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); } From 8d31bc4425785f2a450716e75f9a402a4839247b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 21 Dec 2024 10:09:15 +0800 Subject: [PATCH 23/69] impl --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 5 +++-- src/Misc/PhobosToolTip.cpp | 14 ++++++++++++-- src/Utilities/AresFunctions.h | 2 -- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index d657990775..4bb8596484 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -40,7 +40,7 @@ bool SWColumnClass::Draw(bool forced) if (const auto bottomShape = pSideExt->SuperWeaponSidebar_BottomShape.Get()) { - Point2D drawPoint = { this->X, this->Y + static_cast(this->Buttons.size()) * Phobos::UI::SuperWeaponSidebar_CameoHeight }; + Point2D drawPoint = { this->X, this->Y + this->Height }; pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, bottomShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); } @@ -104,7 +104,8 @@ bool SWColumnClass::AddButton(int superIdx) if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) return false; - const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, 60, 48); + const int cameoWidth = 60; + const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, Phobos::UI::SuperWeaponSidebar_CameoHeight); if (!button) return false; diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index bcab664b6e..d1f44691b4 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -228,8 +228,18 @@ DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) return 0; PhobosToolTip::Instance.IsCameo = true; - PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); - R->EAX(PhobosToolTip::Instance.GetBuffer()); + + if (PhobosToolTip::Instance.IsEnabled()) + { + PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); + R->EAX(PhobosToolTip::Instance.GetBuffer()); + } + else + { + const auto pSuper = HouseClass::CurrentPlayer->Supers[button->SuperIndex]; + R->EAX(pSuper->Type->UIName); + } + return ApplyToolTip; } diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index a0be184e3b..8564ca7c0a 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -28,8 +28,6 @@ class AresFunctions static bool(__thiscall* IsTargetConstraintsEligible)(void*, HouseClass*, bool); - static std::function SWTypeExtMap_Find; - static void(__thiscall* ApplyAcademy)(void*, TechnoClass* pTechno, AbstractType considerAs); static std::function SWTypeExtMap_Find; From b9d901a2cac319a7a3031bf3555dade0e8996402 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 9 Jan 2025 19:48:34 +0800 Subject: [PATCH 24/69] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YRpp | 2 +- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YRpp b/YRpp index 0cc38feea7..31cf219918 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 0cc38feea7590cf0478e2f194b766eea80b9a26d +Subproject commit 31cf21991824f68f1fe5331b4612cf9b135951f6 diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 0f278ba109..168c407a00 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -197,7 +197,7 @@ bool SWButtonClass::LaunchSuper() const { DisplayClass::Instance->CurrentBuilding = nullptr; DisplayClass::Instance->CurrentBuildingType = nullptr; - DisplayClass::Instance->unknown_11AC = static_cast(-1); + DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; DisplayClass::Instance->SetActiveFoundation(nullptr); MapClass::Instance->SetRepairMode(0); DisplayClass::Instance->SetSellMode(0); From d14dcd869669aa26f0259bd87b39fdae26e017d1 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 9 Jan 2025 20:52:38 +0800 Subject: [PATCH 25/69] Update SWButtonClass.cpp --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 0f278ba109..168c407a00 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -197,7 +197,7 @@ bool SWButtonClass::LaunchSuper() const { DisplayClass::Instance->CurrentBuilding = nullptr; DisplayClass::Instance->CurrentBuildingType = nullptr; - DisplayClass::Instance->unknown_11AC = static_cast(-1); + DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; DisplayClass::Instance->SetActiveFoundation(nullptr); MapClass::Instance->SetRepairMode(0); DisplayClass::Instance->SetSellMode(0); From a2a48fab271db42d159071320b735d96bed436b9 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 03:17:34 +0800 Subject: [PATCH 26/69] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CREDITS.md | 1 - docs/AI-Scripting-and-Mapping.md | 6 ---- src/Ext/SWType/Body.cpp | 2 +- src/Ext/SWType/Body.h | 2 +- src/Misc/Hooks.BugFixes.cpp | 53 ------------------------------- src/Utilities/AresAddressInit.cpp | 16 ---------- src/Utilities/AresFunctions.h | 7 ---- 7 files changed, 2 insertions(+), 85 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 224b522d31..dfa02afb30 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -416,4 +416,3 @@ This page lists all the individual contributions to the project by their author. - **Damfoos** - extensive and thorough testing - **Dmitry Volkov** - extensive and thorough testing - **Rise of the East community** - extensive playtesting of in-dev features -- **Aephiex** - fixed Ares academy not working on the initial payloads of vehicles built from a war factory diff --git a/docs/AI-Scripting-and-Mapping.md b/docs/AI-Scripting-and-Mapping.md index e2fd3fce5f..6794af4673 100644 --- a/docs/AI-Scripting-and-Mapping.md +++ b/docs/AI-Scripting-and-Mapping.md @@ -27,12 +27,6 @@ In rulesmd.ini: RepairBaseNodes=false ; boolean ``` -In rulesmd.ini: -```ini -[General] -RepairBaseNodes=false,false,false ; list of 3 booleans indicating whether AI repair basenodes in Easy / Normal / Difficult game diffculty. -``` - In map file: ```ini [Country House] diff --git a/src/Ext/SWType/Body.cpp b/src/Ext/SWType/Body.cpp index 8124860353..864dc39f6c 100644 --- a/src/Ext/SWType/Body.cpp +++ b/src/Ext/SWType/Body.cpp @@ -213,7 +213,7 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->TabIndex.Read(exINI, pSection, "TabIndex"); GeneralUtils::IntValidCheck(&this->TabIndex, pSection, "TabIndex", 1, 0, 3); - + this->SuperWeaponSidebar_Allow.Read(exINI, pSection, "SuperWeaponSidebar.Allow"); this->SuperWeaponSidebar_PriorityHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.PriorityHouses", this->SuperWeaponSidebar_PriorityHouses); this->SuperWeaponSidebar_RequiredHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.RequiredHouses", this->SuperWeaponSidebar_RequiredHouses); diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index 2e7e93475a..ee2524f69f 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -77,7 +77,7 @@ class SWTypeExt Valueable ShowDesignatorRange; Valueable TabIndex; - + Valueable SuperWeaponSidebar_Allow; DWORD SuperWeaponSidebar_PriorityHouses; DWORD SuperWeaponSidebar_RequiredHouses; diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index f1bf3bf1dc..0f36dd5355 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -32,7 +32,6 @@ #include #include #include -#include /* Allow usage of TileSet of 255 and above without making NE-SW broken bridges unrepairable @@ -1170,55 +1169,3 @@ size_t __fastcall HexStr2Int_replacement(const char* str) } DEFINE_JUMP(CALL, 0x6E8305, GET_OFFSET(HexStr2Int_replacement)); // TaskForce DEFINE_JUMP(CALL, 0x6E5FA6, GET_OFFSET(HexStr2Int_replacement)); // TagType - -// This is the inline function to get the academy type that a techno enjoys. -inline static const AbstractType GetAresAcademyType(TechnoClass* pTechno) -{ - if (pTechno->WhatAmI() == AbstractType::Unit) - { - if (pTechno->GetTechnoType()->ConsideredAircraft) - return AbstractType::Aircraft; - else if (pTechno->GetTechnoType()->Organic) - return AbstractType::Infantry; - else - return AbstractType::Unit; - } - else if (pTechno->WhatAmI() == AbstractType::Infantry - || pTechno->WhatAmI() == AbstractType::Aircraft - || pTechno->WhatAmI() == AbstractType::Building) - { - return pTechno->WhatAmI(); - } - return AbstractType::None; -} - -// This is a fix to the Ares bug: Academy feature doesn't apply to the initial payload of vehicles built off a War Factory. -// Curiously, Academy applies to the initial payloads of vehicles under any other circumstances, even when built off a Naval Shipyard. -// It is "Unsorted::IKnowWhatImDoing" prevented the "HouseExt::ApplyAcademy" from taking effect. -// The fix is simple, when Ares is supposed to have initialized the initial payload, and Academy is prevented from taking any effect, -// temporarily turn off "Unsorted::IKnowWhatImDoing", invoke "HouseExt::ApplyAcademy", then turn on "Unsorted::IKnowWhatImDoing" again. -DEFINE_HOOK(0x4D71A0, FootClass_Put_InitialPayload_AfterAres, 0x6) -{ - GET(FootClass* const, pThis, ESI); - - if (AresFunctions::ApplyAcademy && Unsorted::IKnowWhatImDoing) - { - if (pThis && !pThis->InLimbo && pThis->IsOnMap && pThis->WhatAmI() == AbstractType::Unit - && pThis->GetTechnoType()->Passengers > 0 - && pThis->Passengers.NumPassengers > 0) - { - for (auto pNext = pThis->Passengers.FirstPassenger; pNext; pNext = abstract_cast(pNext->NextObject)) - { - auto abstractType = GetAresAcademyType(pNext); - if (abstractType != AbstractType::None) - { - --Unsorted::IKnowWhatImDoing; - AresFunctions::ApplyAcademy(AresFunctions::HouseExtMap_Find(pNext->Owner), pNext, abstractType); - ++Unsorted::IKnowWhatImDoing; - } - } - } - } - - return 0; -} diff --git a/src/Utilities/AresAddressInit.cpp b/src/Utilities/AresAddressInit.cpp index 1325d1a2dc..1c741e396d 100644 --- a/src/Utilities/AresAddressInit.cpp +++ b/src/Utilities/AresAddressInit.cpp @@ -6,14 +6,10 @@ decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr; decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr; decltype(AresFunctions::IsTargetConstraintsEligible) AresFunctions::IsTargetConstraintsEligible = nullptr; -decltype(AresFunctions::ApplyAcademy) AresFunctions::ApplyAcademy = nullptr; std::function AresFunctions::SWTypeExtMap_Find; -std::function AresFunctions::HouseExtMap_Find; void* AresFunctions::_SWTypeExtMap = nullptr; decltype(AresFunctions::_SWTypeExtMapFind) AresFunctions::_SWTypeExtMapFind = nullptr; -void* AresFunctions::_HouseExtMap = nullptr; -decltype(AresFunctions::_HouseExtMapFind) AresFunctions::_HouseExtMapFind = nullptr; void Apply_Ares3_0_Patches(); void Apply_Ares3_0p1_Patches(); @@ -33,16 +29,10 @@ void AresFunctions::InitAres3_0() NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032110); - NOTE_ARES_FUN(ApplyAcademy, 0x020750); - NOTE_ARES_FUN(_SWTypeExtMapFind, 0x57C70); NOTE_ARES_FUN(_SWTypeExtMap, 0xC1C54); SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); }; - NOTE_ARES_FUN(_HouseExtMapFind, 0x57C70); - NOTE_ARES_FUN(_HouseExtMap, 0xC1AA8); - HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); }; - #ifndef USING_MULTIFINITE_SYRINGE Apply_Ares3_0_Patches(); #endif @@ -63,16 +53,10 @@ void AresFunctions::InitAres3_0p1() NOTE_ARES_FUN(IsTargetConstraintsEligible, 0x032AF0); - NOTE_ARES_FUN(ApplyAcademy, 0x0211D0); - NOTE_ARES_FUN(_SWTypeExtMapFind, 0x58900); NOTE_ARES_FUN(_SWTypeExtMap, 0xC2C50); SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); }; - NOTE_ARES_FUN(_HouseExtMapFind, 0x589A0); - NOTE_ARES_FUN(_HouseExtMap, 0xC2B08); - HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); }; - #ifndef USING_MULTIFINITE_SYRINGE Apply_Ares3_0p1_Patches(); #endif diff --git a/src/Utilities/AresFunctions.h b/src/Utilities/AresFunctions.h index 8564ca7c0a..e19f9acde4 100644 --- a/src/Utilities/AresFunctions.h +++ b/src/Utilities/AresFunctions.h @@ -1,6 +1,5 @@ #pragma once #include -#include class TechnoClass; class TechnoTypeClass; class FootClass; @@ -28,12 +27,8 @@ class AresFunctions static bool(__thiscall* IsTargetConstraintsEligible)(void*, HouseClass*, bool); - static void(__thiscall* ApplyAcademy)(void*, TechnoClass* pTechno, AbstractType considerAs); - static std::function SWTypeExtMap_Find; - static std::function HouseExtMap_Find; - private: static constexpr bool _maybe = false; @@ -41,7 +36,5 @@ class AresFunctions static constexpr bool AresWasWrongAboutSpawnSurvivors = _maybe; static void* _SWTypeExtMap; - static void* _HouseExtMap; static AresSWTypeExtData* (__thiscall* _SWTypeExtMapFind)(void*, SuperWeaponTypeClass*); - static AresHouseExtData* (__thiscall* _HouseExtMapFind)(void*, HouseClass*); }; From 9ec6df546c625af90033addf1fbd66f4685a368a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 03:19:50 +0800 Subject: [PATCH 27/69] =?UTF-8?q?=E6=94=B9=E6=88=90=E7=94=BBPCX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/User-Interface.md | 10 +++++--- src/Ext/Side/Body.cpp | 19 +++++++------- src/Ext/Side/Body.h | 19 +++++++------- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 25 ++++++++++--------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 13 ++++------ .../Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 18 +++++++------ 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 9ed6090d88..7528954e54 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -602,16 +602,18 @@ SuperWeaponSidebar.MaxColumns= ; integer In `rulesmd.ini` ```ini [SOMESIDE] -SuperWeaponSidebar.TopShape= ; filename - including the .shp extension -SuperWeaponSidebar.CenterShape= ; filename - including the .shp extension -SuperWeaponSidebar.BottomShape= ; filename - including the .shp extension -SuperWeaponSidebar.ToggleShape= ; filename - including the .shp extension +SuperWeaponSidebar.OnPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.OffPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.TopPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.CenterPCX= ; filename - including the .pcx extension +SuperWeaponSidebar.BottomPCX= ; filename - including the .pcx extension [SOMESW] SuperWeaponSidebar.Allow=true ; boolean SuperWeaponSidebar.PriorityHouses= ; list of house types SuperWeaponSidebar.RequiredHouses= ; list of house types ``` + ## Miscellanous ### Skip saving game on starting a new campaign diff --git a/src/Ext/Side/Body.cpp b/src/Ext/Side/Body.cpp index 532b17acf5..388ee8d178 100644 --- a/src/Ext/Side/Body.cpp +++ b/src/Ext/Side/Body.cpp @@ -42,11 +42,11 @@ void SideExt::ExtData::LoadFromINIFile(CCINIClass* pINI) this->ToolTip_Background_Opacity.Read(exINI, pSection, "ToolTip.Background.Opacity"); this->ToolTip_Background_BlurSize.Read(exINI, pSection, "ToolTip.Background.BlurSize"); this->BriefingTheme = pINI->ReadTheme(pSection, "BriefingTheme", this->BriefingTheme); - - this->SuperWeaponSidebar_TopShape.Read(exINI, pSection, "SuperWeaponSidebar.TopShape"); - this->SuperWeaponSidebar_CenterShape.Read(exINI, pSection, "SuperWeaponSidebar.CenterShape"); - this->SuperWeaponSidebar_BottomShape.Read(exINI, pSection, "SuperWeaponSidebar.BottomShape"); - this->SuperWeaponSidebar_ToggleShape.Read(exINI, pSection, "SuperWeaponSidebar.ToggleShape"); + this->SuperWeaponSidebar_OnPCX.Read(pINI, pSection, "SuperWeaponSidebar.OnPCX"); + this->SuperWeaponSidebar_OffPCX.Read(pINI, pSection, "SuperWeaponSidebar.OffPCX"); + this->SuperWeaponSidebar_TopPCX.Read(pINI, pSection, "SuperWeaponSidebar.TopPCX"); + this->SuperWeaponSidebar_CenterPCX.Read(pINI, pSection, "SuperWeaponSidebar.CenterPCX"); + this->SuperWeaponSidebar_BottomPCX.Read(pINI, pSection, "SuperWeaponSidebar.BottomPCX"); } // ============================= @@ -76,10 +76,11 @@ void SideExt::ExtData::Serialize(T& Stm) .Process(this->IngameScore_WinTheme) .Process(this->IngameScore_LoseTheme) .Process(this->BriefingTheme) - .Process(this->SuperWeaponSidebar_TopShape) - .Process(this->SuperWeaponSidebar_CenterShape) - .Process(this->SuperWeaponSidebar_BottomShape) - .Process(this->SuperWeaponSidebar_ToggleShape) + .Process(this->SuperWeaponSidebar_OnPCX) + .Process(this->SuperWeaponSidebar_OffPCX) + .Process(this->SuperWeaponSidebar_TopPCX) + .Process(this->SuperWeaponSidebar_CenterPCX) + .Process(this->SuperWeaponSidebar_BottomPCX) ; } diff --git a/src/Ext/Side/Body.h b/src/Ext/Side/Body.h index bf1910662a..e0f3362ef0 100644 --- a/src/Ext/Side/Body.h +++ b/src/Ext/Side/Body.h @@ -36,11 +36,11 @@ class SideExt Nullable ToolTip_Background_Opacity; Nullable ToolTip_Background_BlurSize; Valueable BriefingTheme; - - Valueable SuperWeaponSidebar_TopShape; - Valueable SuperWeaponSidebar_CenterShape; - Valueable SuperWeaponSidebar_BottomShape; - Valueable SuperWeaponSidebar_ToggleShape; + PhobosPCXFile SuperWeaponSidebar_OnPCX; + PhobosPCXFile SuperWeaponSidebar_OffPCX; + PhobosPCXFile SuperWeaponSidebar_TopPCX; + PhobosPCXFile SuperWeaponSidebar_CenterPCX; + PhobosPCXFile SuperWeaponSidebar_BottomPCX; ExtData(SideClass* OwnerObject) : Extension(OwnerObject) , ArrayIndex { -1 } @@ -63,10 +63,11 @@ class SideExt , ToolTip_Background_Opacity { } , ToolTip_Background_BlurSize { } , BriefingTheme { -1 } - , SuperWeaponSidebar_TopShape { } - , SuperWeaponSidebar_CenterShape { } - , SuperWeaponSidebar_BottomShape { } - , SuperWeaponSidebar_ToggleShape { nullptr } + , SuperWeaponSidebar_OnPCX {} + , SuperWeaponSidebar_OffPCX {} + , SuperWeaponSidebar_TopPCX {} + , SuperWeaponSidebar_CenterPCX {} + , SuperWeaponSidebar_BottomPCX {} { } virtual ~ExtData() = default; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 4bb8596484..1018e34733 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -18,30 +18,31 @@ bool SWColumnClass::Draw(bool forced) if (!SWSidebarClass::IsEnabled()) return false; - const auto pSurface = DSurface::Composite(); - auto bounds = pSurface->GetRect(); - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const int cameoWidth = 60, cameoHeight = 48; + const int cameoBackgroundWidth = Phobos::UI::SuperWeaponSidebar_Interval + cameoWidth; - if (const auto centerShape = pSideExt->SuperWeaponSidebar_CenterShape.Get()) + if (const auto pCenterPCX = pSideExt->SuperWeaponSidebar_CenterPCX.GetSurface()) { + const int cameoHarfInterval = (Phobos::UI::SuperWeaponSidebar_CameoHeight - cameoHeight) / 2; + for (const auto button : this->Buttons) { - Point2D drawPoint = { this->X, button->Y }; - pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, centerShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + RectangleStruct drawRect { this->X, button->Y - cameoHarfInterval, cameoBackgroundWidth, Phobos::UI::SuperWeaponSidebar_CameoHeight }; + PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pCenterPCX); } } - if (const auto topShape = pSideExt->SuperWeaponSidebar_TopShape.Get()) + if (const auto pTopPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) { - Point2D drawPoint = { this->X, this->Y - topShape->Height }; - pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, topShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + RectangleStruct drawRect { this->X, this->Y - 20, cameoBackgroundWidth, 20 }; + PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pTopPCX); } - if (const auto bottomShape = pSideExt->SuperWeaponSidebar_BottomShape.Get()) + if (const auto pBottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) { - Point2D drawPoint = { this->X, this->Y + this->Height }; - pSurface->DrawSHP(FileSystem::SIDEBAR_PAL, bottomShape, 0, &drawPoint, &bounds, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + RectangleStruct drawRect { this->X, this->Y + this->Height, cameoBackgroundWidth, 20 }; + PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pBottomPCX); } for (const auto button : this->Buttons) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index fb793dcd81..126427be43 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -257,15 +257,12 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) { - if (const auto toggleShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get()) + if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, 10, 50)) { - if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, toggleShape->Width, toggleShape->Height)) - { - toggleButton->Zap(); - GScreenClass::Instance->AddButton(toggleButton); - SWSidebarClass::Instance.ToggleButton = toggleButton; - toggleButton->UpdatePosition(); - } + toggleButton->Zap(); + GScreenClass::Instance->AddButton(toggleButton); + SWSidebarClass::Instance.ToggleButton = toggleButton; + toggleButton->UpdatePosition(); } } diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index b40e2ac5f5..eea554eb36 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -20,21 +20,18 @@ bool ToggleSWButtonClass::Draw(bool forced) return false; const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - const auto pShape = pSideExt->SuperWeaponSidebar_ToggleShape.Get(); + const auto pTogglePCX = SWSidebarClass::IsEnabled() ? pSideExt->SuperWeaponSidebar_OnPCX.GetSurface() : pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); - if (!pShape) + if (!pTogglePCX) return false; - const auto pConvert = FileSystem::SIDEBAR_PAL(); - const auto pSurface = DSurface::Composite(); - Point2D position = { this->X, this->Y }; - RectangleStruct destRect = { position.X, position.Y, this->Width, this->Height }; - pSurface->DrawSHP(pConvert, pShape, SWSidebarClass::IsEnabled(), &position, &destRect, BlitterFlags::bf_400, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0); + RectangleStruct destRect { this->X, this->Y, this->Width, this->Height }; + PCX::Instance->BlitToSurface(&destRect, DSurface::Composite, pTogglePCX); if (this->IsHovering) { const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); - pSurface->DrawRect(&destRect, tooltipColor); + DSurface::Composite->DrawRect(&destRect, tooltipColor); } return true; @@ -71,6 +68,11 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi if (columns.empty()) return false; + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + + if (SWSidebarClass::IsEnabled() ? !pSideExt->SuperWeaponSidebar_OnPCX.GetSurface() : !pSideExt->SuperWeaponSidebar_OffPCX.GetSurface()) + return false; + if ((int)flags & (int)GadgetFlag::LeftPress) this->IsPressed = true; From 25e4580c9cf9f28df6c573247c914d2eddd83f83 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 03:20:25 +0800 Subject: [PATCH 28/69] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E6=89=80=E5=B1=9E=E6=96=B9=E4=BC=98=E5=85=88=E7=BA=A7=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 126427be43..c485218660 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -124,8 +124,19 @@ void SWSidebarClass::SortButtons() column->ClearButtons(false); } - std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [](SWButtonClass* const a, SWButtonClass* const b) + const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; + + std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [ownerBits](SWButtonClass* const a, SWButtonClass* const b) { + const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(a->SuperIndex)); + const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(b->SuperIndex)); + + if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) + return false; + + if ((!pExtB || !(pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits)) && pExtA && (pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits)) + return true; + return BuildType::SortsBefore(AbstractType::Special, a->SuperIndex, AbstractType::Special, b->SuperIndex); }); From 71d6ac6322e77ab23b8a02a2126f4daf77252dfc Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 03:21:47 +0800 Subject: [PATCH 29/69] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/User-Interface.md | 14 +++++++++----- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 4 ++-- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 20 ++++++++++++-------- src/Phobos.INI.cpp | 15 +++++++++++++-- src/Phobos.h | 3 ++- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 7528954e54..5f963868f2 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -585,18 +585,22 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable - In theory, it should be compatible with Ares - Cameos arranged in a pyramid shape. - `SuperWeaponSidebar.Interval` specific how many leptons between two columns. -- `SuperWeaponSidebar.Max` controls the maximum number of icons on the leftmost side, which also depends on the current game resolution. +- `SuperWeaponSidebar.Max` controls the maximum number of cameos on the leftmost side, which also depends on the current game resolution. - `SuperWeaponSidebar.MaxColumns` controls that maximum count of columns. +- `SuperWeaponSidebar.CameoHeight` controls the distance from the top of the previous cameo to the top of the next cameo. +- `SuperWeaponSidebar.LeftOffset` controls the distance between the leftmost cameo and the leftmost part of the screen. - You can also launch first 10 SW by hotkey in INTERFACE category. - For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. In `uimd.ini`: ```ini [Sidebar] -SuperWeaponSidebar=false ; boolean -SuperWeaponSidebar.Interval=0 ; integer -SuperWeaponSidebar.Max=0 ; integer -SuperWeaponSidebar.MaxColumns= ; integer +SuperWeaponSidebar=false ; boolean +SuperWeaponSidebar.Interval=0 ; integer +SuperWeaponSidebar.LeftOffset=0 ; integer +SuperWeaponSidebar.CameoHeight=48 ; integer +SuperWeaponSidebar.Max=0 ; integer +SuperWeaponSidebar.MaxColumns= ; integer ``` In `rulesmd.ini` diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 1018e34733..291b44a1a2 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -105,8 +105,8 @@ bool SWColumnClass::AddButton(int superIdx) if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) return false; - const int cameoWidth = 60; - const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, Phobos::UI::SuperWeaponSidebar_CameoHeight); + const int cameoWidth = 60, cameoHeight = 48; + const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, cameoHeight); if (!button) return false; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index c485218660..1e0e433712 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -18,7 +18,8 @@ bool SWSidebarClass::AddColumn() if (static_cast(columns.size()) >= Phobos::UI::SuperWeaponSidebar_MaxColumns) return false; - const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, 60 + Phobos::UI::SuperWeaponSidebar_Interval, 48); + const int cameoWidth = 60; + const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); if (!column) return false; @@ -143,8 +144,10 @@ void SWSidebarClass::SortButtons() const int buttonCount = static_cast(vec_Buttons.size()); const int cameoWidth = 60, cameoHeight = 48; const int maximum = Phobos::UI::SuperWeaponSidebar_Max; - Point2D location = { 0, (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * cameoHeight) / 2 }; - int location_Y = location.Y; + const int cameoHarfInterval = (Phobos::UI::SuperWeaponSidebar_CameoHeight - cameoHeight) / 2; + int location_Y = (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * Phobos::UI::SuperWeaponSidebar_CameoHeight) / 2; + Point2D location = { Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y }; + location_Y -= cameoHarfInterval; int rowIdx = 0, columnIdx = 0; for (const auto button : vec_Buttons) @@ -152,7 +155,7 @@ void SWSidebarClass::SortButtons() const auto column = columns[columnIdx]; if (rowIdx == 0) - column->SetPosition(location.X, location.Y); + column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location.Y); column->Buttons.emplace_back(button); button->SetColumn(columnIdx); @@ -163,17 +166,18 @@ void SWSidebarClass::SortButtons() { rowIdx = 0; columnIdx++; - location_Y += cameoHeight / 2; - location = { location.X + cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, location_Y }; + location_Y += Phobos::UI::SuperWeaponSidebar_CameoHeight / 2; + location.X += cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval; + location.Y = location_Y + cameoHarfInterval; } else { - location.Y += cameoHeight; + location.Y += Phobos::UI::SuperWeaponSidebar_CameoHeight; } } for (const auto column : columns) - column->SetHeight(column->Buttons.size() * 48); + column->SetHeight(column->Buttons.size() * Phobos::UI::SuperWeaponSidebar_CameoHeight); if (const auto toggleButton = this->ToggleButton) toggleButton->UpdatePosition(); diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index eedf0141fd..9de0b557de 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -35,9 +35,10 @@ double Phobos::UI::PowerDelta_ConditionRed = 1.0; bool Phobos::UI::CenterPauseMenuBackground = false; bool Phobos::UI::SuperWeaponSidebar = false; int Phobos::UI::SuperWeaponSidebar_Interval = 0; +int Phobos::UI::SuperWeaponSidebar_LeftOffset = 0; +int Phobos::UI::SuperWeaponSidebar_CameoHeight = 48; int Phobos::UI::SuperWeaponSidebar_Max = 0; int Phobos::UI::SuperWeaponSidebar_MaxColumns = INT32_MAX; -int Phobos::UI::SuperWeaponSidebar_CameoHeight = 48; bool Phobos::UI::WeedsCounter_Show = false; bool Phobos::UI::AnchoredToolTips = false; @@ -173,6 +174,16 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::UI::SuperWeaponSidebar_Interval = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Interval", Phobos::UI::SuperWeaponSidebar_Interval); + Phobos::UI::SuperWeaponSidebar_LeftOffset = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.LeftOffset", Phobos::UI::SuperWeaponSidebar_LeftOffset); + + Phobos::UI::SuperWeaponSidebar_LeftOffset = std::min(Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_LeftOffset); + + Phobos::UI::SuperWeaponSidebar_CameoHeight = + ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.CameoHeight", Phobos::UI::SuperWeaponSidebar_CameoHeight); + + Phobos::UI::SuperWeaponSidebar_CameoHeight = std::max(48, Phobos::UI::SuperWeaponSidebar_CameoHeight); + Phobos::UI::SuperWeaponSidebar_Max = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Max", Phobos::UI::SuperWeaponSidebar_Max); @@ -181,7 +192,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) if (Phobos::UI::SuperWeaponSidebar_Max > 0) Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); else - Phobos::UI::SuperWeaponSidebar_Max = screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight; + Phobos::UI::SuperWeaponSidebar_Max = (screenHeight - 40) / Phobos::UI::SuperWeaponSidebar_CameoHeight; Phobos::UI::SuperWeaponSidebar_MaxColumns = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumns", Phobos::UI::SuperWeaponSidebar_MaxColumns); diff --git a/src/Phobos.h b/src/Phobos.h index 2449bbf092..3ad5cb8abd 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -55,9 +55,10 @@ class Phobos static bool CenterPauseMenuBackground; static bool SuperWeaponSidebar; static int SuperWeaponSidebar_Interval; + static int SuperWeaponSidebar_LeftOffset; + static int SuperWeaponSidebar_CameoHeight; static int SuperWeaponSidebar_Max; static int SuperWeaponSidebar_MaxColumns; - static int SuperWeaponSidebar_CameoHeight; static bool WeedsCounter_Show; static bool AnchoredToolTips; From 13b791de876cfdbe146acf926e9433d17b0de08d Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 03:23:58 +0800 Subject: [PATCH 30/69] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E6=97=B6=E9=9C=80=E8=A6=81=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E7=9A=84=E5=A4=B4=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 1e0e433712..e6cb9ab461 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -1,8 +1,10 @@ #include "SWSidebarClass.h" #include +#include + #include #include -#include +#include SWSidebarClass SWSidebarClass::Instance; CommandClass* SWSidebarClass::Commands[10]; From de62ff9c149137f4e0f80c9feee9dcedd4caed51 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 04:50:31 +0800 Subject: [PATCH 31/69] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A0=8F=E7=9B=AE?= =?UTF-8?q?=E5=9B=9E=E6=94=B6=E6=9C=BA=E5=88=B6=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 1 - src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 40 ++++++++++++-------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 291b44a1a2..ea17afd317 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -131,7 +131,6 @@ bool SWColumnClass::RemoveButton(int superIdx) DLLDelete(*it); buttons.erase(it); - SWSidebarClass::Instance.SortButtons(); return true; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index e6cb9ab461..633fbf2745 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -97,17 +97,6 @@ void SWSidebarClass::SortButtons() { auto& columns = this->Columns; - if (columns.empty()) - return; - - columns.erase( - std::remove_if(columns.begin(), columns.end(), - [](SWColumnClass* const column) - { return column->Buttons.empty(); } - ), - columns.end() - ); - if (columns.empty()) { if (const auto toggleButton = this->ToggleButton) @@ -221,17 +210,38 @@ DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) if (pHouse->IsCurrentPlayer()) { - for (const auto column : SWSidebarClass::Instance.Columns) + auto& sidebar = SWSidebarClass::Instance; + + for (const auto& column : sidebar.Columns) { - for (const auto button : column->Buttons) + std::vector removeButtons; + + for (const auto& button : column->Buttons) { if (HouseClass::CurrentPlayer->Supers[button->SuperIndex]->IsPresent) continue; - if (column->RemoveButton(button->SuperIndex)) - SidebarExt::Global()->SWSidebar_Indices.Remove(button->SuperIndex); + removeButtons.push_back(button->SuperIndex); + } + + for (const auto& index : removeButtons) + { + if (column->RemoveButton(index)) + SidebarExt::Global()->SWSidebar_Indices.Remove(index); } } + + SWSidebarClass::Instance.SortButtons(); + int removes = 0; + + for (const auto& column : sidebar.Columns) + { + if (column->Buttons.empty()) + ++removes; + } + + for (; removes > 0; --removes) + sidebar.RemoveColumn(); } return SkipGameCode; From a5b03f01c990dda2247eddaa7cd47c019989867f Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 13:07:08 +0800 Subject: [PATCH 32/69] =?UTF-8?q?=E4=B8=8D=E5=BD=B1=E5=93=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 6 +++--- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 1 - src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 168c407a00..d35b6b3918 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -148,14 +148,14 @@ void SWButtonClass::OnMouseLeave() bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { - if ((int)flags & (int)GadgetFlag::LeftPress) + if (flags & GadgetFlag::LeftPress) { MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); this->LaunchSuper(); } - return this->ControlClass::Action(flags, pKey, KeyModifier::None); + return this->GadgetClass::Action(flags, pKey, KeyModifier::None); } void SWButtonClass::SetColumn(int column) @@ -200,7 +200,7 @@ bool SWButtonClass::LaunchSuper() const DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; DisplayClass::Instance->SetActiveFoundation(nullptr); MapClass::Instance->SetRepairMode(0); - DisplayClass::Instance->SetSellMode(0); + MapClass::Instance->SetSellMode(0); DisplayClass::Instance->PowerToggleMode = false; DisplayClass::Instance->PlanningMode = false; DisplayClass::Instance->PlaceBeaconMode = false; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 633fbf2745..c19b5f7ef0 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -9,7 +9,6 @@ SWSidebarClass SWSidebarClass::Instance; CommandClass* SWSidebarClass::Commands[10]; - // ============================= // functions diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index eea554eb36..5e375d4383 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -7,7 +7,7 @@ #include ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, static_cast((int)GadgetFlag::LeftPress | (int)GadgetFlag::LeftRelease), true) + : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::LeftRelease), true) { SWSidebarClass::Instance.ToggleButton = this; } @@ -73,10 +73,10 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi if (SWSidebarClass::IsEnabled() ? !pSideExt->SuperWeaponSidebar_OnPCX.GetSurface() : !pSideExt->SuperWeaponSidebar_OffPCX.GetSurface()) return false; - if ((int)flags & (int)GadgetFlag::LeftPress) + if (flags & GadgetFlag::LeftPress) this->IsPressed = true; - if (((int)flags & (int)GadgetFlag::LeftRelease) && this->IsPressed) + if ((flags & GadgetFlag::LeftRelease) && this->IsPressed) { this->IsPressed = false; VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); From 7baaae4ab9c891dbdd8c12a727904771917b7680 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 13:07:53 +0800 Subject: [PATCH 33/69] =?UTF-8?q?=E9=BC=A0=E6=A0=87=E5=9C=A8=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E4=B8=8A=E6=97=B6=E9=87=8D=E7=BD=AE=E6=8C=87=E9=92=88?= =?UTF-8?q?=E5=9B=BE=E5=BD=A2=E5=B9=B6=E8=B7=B3=E8=BF=87=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 10 +++++++--- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index ea17afd317..9b809a8073 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -35,13 +35,13 @@ bool SWColumnClass::Draw(bool forced) if (const auto pTopPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) { - RectangleStruct drawRect { this->X, this->Y - 20, cameoBackgroundWidth, 20 }; + RectangleStruct drawRect { this->X, this->Y, cameoBackgroundWidth, 20 }; PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pTopPCX); } if (const auto pBottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) { - RectangleStruct drawRect { this->X, this->Y + this->Height, cameoBackgroundWidth, 20 }; + RectangleStruct drawRect { this->X, this->Y + this->Height - 20, cameoBackgroundWidth, 20 }; PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pBottomPCX); } @@ -57,11 +57,13 @@ void SWColumnClass::OnMouseEnter() return; SWSidebarClass::Instance.CurrentColumn = this; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } void SWColumnClass::OnMouseLeave() { SWSidebarClass::Instance.CurrentColumn = nullptr; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); } bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) @@ -149,5 +151,7 @@ void SWColumnClass::ClearButtons(bool remove) void SWColumnClass::SetHeight(int height) { - this->Height = height; + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + + this->Height = height + (pSideExt->SuperWeaponSidebar_TopPCX.GetSurface() ? 20 : 0) + (pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface() ? 20 : 0); } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index c19b5f7ef0..dd7f9b4ec3 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -145,7 +145,7 @@ void SWSidebarClass::SortButtons() const auto column = columns[columnIdx]; if (rowIdx == 0) - column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location.Y); + column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location.Y - (SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])->SuperWeaponSidebar_TopPCX.GetSurface() ? 20 : 0)); column->Buttons.emplace_back(button); button->SetColumn(columnIdx); From ab66211051997421d948b61adcd18c3c6ad32288 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 17:32:21 +0800 Subject: [PATCH 34/69] =?UTF-8?q?=E5=8F=B3=E9=94=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index d35b6b3918..d2597b73fc 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -9,7 +9,7 @@ #include SWButtonClass::SWButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, GadgetFlag::LeftPress, true) + : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::RightPress), true) , SuperIndex(superIdx) { if (const auto backColumn = SWSidebarClass::Instance.Columns.back()) @@ -148,6 +148,9 @@ void SWButtonClass::OnMouseLeave() bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { + if (flags & GadgetFlag::RightPress) + DisplayClass::Instance->CurrentSWTypeIndex = -1; + if (flags & GadgetFlag::LeftPress) { MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); @@ -155,7 +158,9 @@ bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) this->LaunchSuper(); } - return this->GadgetClass::Action(flags, pKey, KeyModifier::None); + // this->ControlClass::Action(flags, pKey, KeyModifier::None); + reinterpret_cast(0x48E5A0)(this, flags, pKey, KeyModifier::None); + return true; } void SWButtonClass::SetColumn(int column) From 7f091962646e3684c331bdf0f642373f76789236 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 17:32:30 +0800 Subject: [PATCH 35/69] =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Phobos.INI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 9de0b557de..0f6c01342a 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -190,7 +190,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) const int screenHeight = GameOptionsClass::Instance->ScreenHeight; if (Phobos::UI::SuperWeaponSidebar_Max > 0) - Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); + Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, (screenHeight - 40) / Phobos::UI::SuperWeaponSidebar_CameoHeight); else Phobos::UI::SuperWeaponSidebar_Max = (screenHeight - 40) / Phobos::UI::SuperWeaponSidebar_CameoHeight; From bac33dc63e25c0ad197e2efb2823970fc519744b Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 18:23:04 +0800 Subject: [PATCH 36/69] Update YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 31cf219918..0cc38feea7 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 31cf21991824f68f1fe5331b4612cf9b135951f6 +Subproject commit 0cc38feea7590cf0478e2f194b766eea80b9a26d From c2d74df6f52bdf26c1b59da634d8d26442934a80 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 22:47:55 +0800 Subject: [PATCH 37/69] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=A1=AC=E7=BC=96?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E5=B0=BA=E5=AF=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 18 +++++++-- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 42 ++++++++++++++++---- src/Phobos.INI.cpp | 4 +- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 9b809a8073..d974d26fa2 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -35,13 +35,15 @@ bool SWColumnClass::Draw(bool forced) if (const auto pTopPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) { - RectangleStruct drawRect { this->X, this->Y, cameoBackgroundWidth, 20 }; + const int height = pTopPCX->GetHeight(); + RectangleStruct drawRect { this->X, this->Y, cameoBackgroundWidth, height }; PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pTopPCX); } if (const auto pBottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) { - RectangleStruct drawRect { this->X, this->Y + this->Height - 20, cameoBackgroundWidth, 20 }; + const int height = pBottomPCX->GetHeight(); + RectangleStruct drawRect { this->X, this->Y + this->Height - height, cameoBackgroundWidth, height }; PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pBottomPCX); } @@ -116,6 +118,10 @@ bool SWColumnClass::AddButton(int superIdx) button->Zap(); GScreenClass::Instance->AddButton(button); SWSidebarClass::Instance.SortButtons(); + + if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) + toggleButton->UpdatePosition(); + return true; } @@ -153,5 +159,11 @@ void SWColumnClass::SetHeight(int height) { const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); - this->Height = height + (pSideExt->SuperWeaponSidebar_TopPCX.GetSurface() ? 20 : 0) + (pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface() ? 20 : 0); + this->Height = height; + + if (const auto pTopPCX = pSideExt->SuperWeaponSidebar_TopPCX.GetSurface()) + this->Height += pTopPCX->GetHeight(); + + if (const auto pBottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) + this->Height += pBottomPCX->GetHeight(); } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index dd7f9b4ec3..01c4a7c867 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -168,9 +168,6 @@ void SWSidebarClass::SortButtons() for (const auto column : columns) column->SetHeight(column->Buttons.size() * Phobos::UI::SuperWeaponSidebar_CameoHeight); - - if (const auto toggleButton = this->ToggleButton) - toggleButton->UpdatePosition(); } int SWSidebarClass::GetMaximumButtonCount() @@ -241,6 +238,9 @@ DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) for (; removes > 0; --removes) sidebar.RemoveColumn(); + + if (const auto toggleButton = sidebar.ToggleButton) + toggleButton->UpdatePosition(); } return SkipGameCode; @@ -283,12 +283,38 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) { - if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, 10, 50)) + const auto pOnPCX = pSideExt->SuperWeaponSidebar_OnPCX.GetSurface(); + const auto pOffPCX = pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); + int width = 0, height = 0; + + if (pOnPCX) { - toggleButton->Zap(); - GScreenClass::Instance->AddButton(toggleButton); - SWSidebarClass::Instance.ToggleButton = toggleButton; - toggleButton->UpdatePosition(); + if (pOffPCX) + { + width = std::max(pOnPCX->GetWidth(), pOffPCX->GetWidth()); + height = std::max(pOnPCX->GetHeight(), pOffPCX->GetHeight()); + } + else + { + width = pOnPCX->GetWidth(); + height = pOnPCX->GetHeight(); + } + } + else if (pOffPCX) + { + width = pOffPCX->GetWidth(); + height = pOffPCX->GetHeight(); + } + + if (width > 0 && height > 0) + { + if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) + { + toggleButton->Zap(); + GScreenClass::Instance->AddButton(toggleButton); + SWSidebarClass::Instance.ToggleButton = toggleButton; + toggleButton->UpdatePosition(); + } } } diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 0f6c01342a..621d4c2e9b 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -190,9 +190,9 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) const int screenHeight = GameOptionsClass::Instance->ScreenHeight; if (Phobos::UI::SuperWeaponSidebar_Max > 0) - Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, (screenHeight - 40) / Phobos::UI::SuperWeaponSidebar_CameoHeight); + Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); else - Phobos::UI::SuperWeaponSidebar_Max = (screenHeight - 40) / Phobos::UI::SuperWeaponSidebar_CameoHeight; + Phobos::UI::SuperWeaponSidebar_Max = screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight; Phobos::UI::SuperWeaponSidebar_MaxColumns = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.MaxColumns", Phobos::UI::SuperWeaponSidebar_MaxColumns); From 464e851e9d99a32797f50bc178dfb0183bbf9b16 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 10 Jan 2025 22:48:10 +0800 Subject: [PATCH 38/69] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20DLLDelete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 1 - src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index d974d26fa2..4f2bf2cca5 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -137,7 +137,6 @@ bool SWColumnClass::RemoveButton(int superIdx) AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentButton, *it); GScreenClass::Instance->RemoveButton(*it); - DLLDelete(*it); buttons.erase(it); return true; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 01c4a7c867..7bc8d4db69 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -42,7 +42,6 @@ bool SWSidebarClass::RemoveColumn() AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentColumn, backColumn); GScreenClass::Instance->RemoveButton(backColumn); - DLLDelete(backColumn); columns.erase(columns.end() - 1); return true; } @@ -59,7 +58,6 @@ void SWSidebarClass::InitClear() { this->ToggleButton = nullptr; GScreenClass::Instance->RemoveButton(toggleButton); - DLLDelete(toggleButton); } auto& columns = this->Columns; @@ -68,7 +66,6 @@ void SWSidebarClass::InitClear() { column->ClearButtons(); GScreenClass::Instance->RemoveButton(column); - DLLDelete(column); } columns.clear(); From d1712bbea933071664bd7bb3ed9bfc8e28b3573c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 11 Jan 2025 01:28:00 +0800 Subject: [PATCH 39/69] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E5=B0=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 7bc8d4db69..61b2f9ce8c 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -133,8 +133,7 @@ void SWSidebarClass::SortButtons() const int maximum = Phobos::UI::SuperWeaponSidebar_Max; const int cameoHarfInterval = (Phobos::UI::SuperWeaponSidebar_CameoHeight - cameoHeight) / 2; int location_Y = (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * Phobos::UI::SuperWeaponSidebar_CameoHeight) / 2; - Point2D location = { Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y }; - location_Y -= cameoHarfInterval; + Point2D location = { Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y + cameoHarfInterval }; int rowIdx = 0, columnIdx = 0; for (const auto button : vec_Buttons) @@ -142,7 +141,10 @@ void SWSidebarClass::SortButtons() const auto column = columns[columnIdx]; if (rowIdx == 0) - column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location.Y - (SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])->SuperWeaponSidebar_TopPCX.GetSurface() ? 20 : 0)); + { + const auto pTopPCX = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])->SuperWeaponSidebar_TopPCX.GetSurface(); + column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y - (pTopPCX ? pTopPCX->GetHeight() : 0)); + } column->Buttons.emplace_back(button); button->SetColumn(columnIdx); From 8a311800663ecec0214c9732c339cf4e0bf8aeae Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 11 Jan 2025 12:38:05 +0800 Subject: [PATCH 40/69] Update Phobos.INI.cpp --- src/Phobos.INI.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 621d4c2e9b..ddd3465640 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -187,7 +187,8 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::UI::SuperWeaponSidebar_Max = ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Max", Phobos::UI::SuperWeaponSidebar_Max); - const int screenHeight = GameOptionsClass::Instance->ScreenHeight; + const int reserveHeight = 96; + const int screenHeight = GameOptionsClass::Instance->ScreenHeight - reserveHeight; if (Phobos::UI::SuperWeaponSidebar_Max > 0) Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); From c7f9d7369545263ae67db5969f1955e59edf391f Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 11 Jan 2025 12:53:34 +0800 Subject: [PATCH 41/69] maybe GameCreate() is better? --- src/Ext/Sidebar/SWSidebar/SWButtonClass.h | 2 +- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 2 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 4 ++-- src/Misc/PhobosToolTip.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h index ca0fbe9b1a..6ca068ed86 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h @@ -20,7 +20,7 @@ class SWButtonClass : public ControlClass public: static constexpr int StartID = 2200; - static constexpr int Magic_Align_Y = 27; + static constexpr int ToolTip_Align_Y = 27; bool IsHovering { false }; int ColumnIndex { -1 }; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 4f2bf2cca5..ecbbaff738 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -110,7 +110,7 @@ bool SWColumnClass::AddButton(int superIdx) return false; const int cameoWidth = 60, cameoHeight = 48; - const auto button = DLLCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, cameoHeight); + const auto button = GameCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, cameoHeight); if (!button) return false; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 61b2f9ce8c..daba33e5ca 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -20,7 +20,7 @@ bool SWSidebarClass::AddColumn() return false; const int cameoWidth = 60; - const auto column = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); + const auto column = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); if (!column) return false; @@ -307,7 +307,7 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) if (width > 0 && height > 0) { - if (const auto toggleButton = DLLCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) + if (const auto toggleButton = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) { toggleButton->Zap(); GScreenClass::Instance->AddButton(toggleButton); diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index d1f44691b4..616f916349 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -263,7 +263,7 @@ DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) if (const auto button = SWSidebarClass::Instance.CurrentButton) { R->EDX(button->X + button->Width); - R->EAX(button->Y + SWButtonClass::Magic_Align_Y); + R->EAX(button->Y + SWButtonClass::ToolTip_Align_Y); } } From 2f3ce7fe30ec0acd61e34125b0c0cfce023e495b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 11 Jan 2025 13:47:28 +0800 Subject: [PATCH 42/69] prevent sw sidebar triggered when hidden --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index d2597b73fc..23ccc937a2 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -148,6 +148,9 @@ void SWButtonClass::OnMouseLeave() bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) { + if (!SWSidebarClass::IsEnabled()) + return false; + if (flags & GadgetFlag::RightPress) DisplayClass::Instance->CurrentSWTypeIndex = -1; From 68fc05aeb8f044c53d45e98054035f09e488b9bb Mon Sep 17 00:00:00 2001 From: Aephiex <34618932+Aephiex@users.noreply.github.com> Date: Sun, 12 Jan 2025 14:09:15 +0800 Subject: [PATCH 43/69] Update PhobosToolTip.cpp --- src/Misc/PhobosToolTip.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index 616f916349..1280778728 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -377,7 +377,11 @@ DEFINE_HOOK(0x478FDC, CCToolTip_Draw2_FillRect, 0x5) const bool isCameo = PhobosToolTip::Instance.IsCameo; - if (isCameo && Phobos::UI::AnchoredToolTips && PhobosToolTip::Instance.IsEnabled() && Phobos::Config::ToolTipDescriptions) + if (isCameo && Phobos::UI::AnchoredToolTips + && PhobosToolTip::Instance.IsEnabled() + && Phobos::Config::ToolTipDescriptions + // If inspecting a cameo from the super weapon sidebar, "AnchoredToolTips=true" shouldn't apply. + && !SWSidebarClass::Instance.CurrentButton) { LEA_STACK(LTRBStruct*, a2, STACK_OFFSET(0x44, -0x20)); auto x = DSurface::SidebarBounds->X - pRect->Width - 2; From 71731702a1c78dc82e453b0641a3062ce972cf38 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 16 Jan 2025 13:07:38 +0800 Subject: [PATCH 44/69] add global tag --- src/Ext/Rules/Body.cpp | 3 +++ src/Ext/Rules/Body.h | 4 ++++ src/Ext/SWType/Body.h | 4 ++-- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 2cfe87a114..dbb218fea4 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -97,6 +97,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->PlacementPreview.Read(exINI, GameStrings::AudioVisual, "PlacementPreview"); this->PlacementPreview_Translucency.Read(exINI, GameStrings::AudioVisual, "PlacementPreview.Translucency"); + this->SuperWeaponSidebar_AllowByDefault.Read(exINI, GameStrings::AudioVisual, "SuperWeaponSidebar.AllowByDefault"); + this->ConditionYellow_Terrain.Read(exINI, GameStrings::AudioVisual, "ConditionYellow.Terrain"); this->Shield_ConditionYellow.Read(exINI, GameStrings::AudioVisual, "Shield.ConditionYellow"); this->Shield_ConditionRed.Read(exINI, GameStrings::AudioVisual, "Shield.ConditionRed"); @@ -307,6 +309,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->PlacementGrid_TranslucencyWithPreview) .Process(this->PlacementPreview) .Process(this->PlacementPreview_Translucency) + .Process(this->SuperWeaponSidebar_AllowByDefault) .Process(this->ConditionYellow_Terrain) .Process(this->Shield_ConditionYellow) .Process(this->Shield_ConditionRed) diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 34be37d8bd..bd54fca7d7 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -66,6 +66,8 @@ class RulesExt Valueable PlacementPreview; TranslucencyLevel PlacementPreview_Translucency; + Valueable SuperWeaponSidebar_AllowByDefault; + Nullable ConditionYellow_Terrain; Nullable Shield_ConditionYellow; Nullable Shield_ConditionRed; @@ -200,6 +202,8 @@ class RulesExt , PlacementPreview { false } , PlacementPreview_Translucency { 75 } + , SuperWeaponSidebar_AllowByDefault { false } + , Shield_ConditionYellow { } , Shield_ConditionRed { } , Pips_Shield_Background { } diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index ee2524f69f..72ca379922 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -78,7 +78,7 @@ class SWTypeExt Valueable TabIndex; - Valueable SuperWeaponSidebar_Allow; + Nullable SuperWeaponSidebar_Allow; DWORD SuperWeaponSidebar_PriorityHouses; DWORD SuperWeaponSidebar_RequiredHouses; @@ -152,7 +152,7 @@ class SWTypeExt , Convert_Pairs {} , ShowDesignatorRange { true } , TabIndex { 1 } - , SuperWeaponSidebar_Allow { true } + , SuperWeaponSidebar_Allow {} , SuperWeaponSidebar_PriorityHouses { 0u } , SuperWeaponSidebar_RequiredHouses { 0xFFFFFFFFu } , SidebarPal {} diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index ecbbaff738..ab1ff04d59 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -91,7 +91,7 @@ bool SWColumnClass::AddButton(int superIdx) if (!Phobos::UI::SuperWeaponSidebar) return false; - if (!pSWExt->SuperWeaponSidebar_Allow) + if (!pSWExt->SuperWeaponSidebar_Allow.Get(RulesExt::Global()->SuperWeaponSidebar_AllowByDefault)) return false; const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; From 2029d84095de5cf54bfe1e19b478e028be637cd9 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 16 Jan 2025 14:01:36 +0800 Subject: [PATCH 45/69] try to fix --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 8 +++----- src/Ext/Sidebar/SWSidebar/SWColumnClass.h | 2 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 7 ++++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index ab1ff04d59..8bbc8f3924 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -4,13 +4,11 @@ #include #include -SWColumnClass::SWColumnClass(unsigned int id, int x, int y, int width, int height) +SWColumnClass::SWColumnClass(unsigned int id, int maxButtons, int x, int y, int width, int height) : ControlClass(id, x, y, width, height, static_cast(0), true) + , MaxButtons(maxButtons) { - auto& columns = SWSidebarClass::Instance.Columns; - columns.emplace_back(this); - - this->MaxButtons = Phobos::UI::SuperWeaponSidebar_Max - (static_cast(columns.size()) - 1); + SWSidebarClass::Instance.Columns.emplace_back(this); } bool SWColumnClass::Draw(bool forced) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.h b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h index fc20a3464e..4f3181a091 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.h @@ -8,7 +8,7 @@ class SWColumnClass : public ControlClass { public: SWColumnClass() = default; - SWColumnClass(unsigned int id, int x, int y, int width, int height); + SWColumnClass(unsigned int id, int maxButtons, int x, int y, int width, int height); ~SWColumnClass() = default; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index daba33e5ca..688c81e4c5 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -19,8 +19,13 @@ bool SWSidebarClass::AddColumn() if (static_cast(columns.size()) >= Phobos::UI::SuperWeaponSidebar_MaxColumns) return false; + const int maxButtons = Phobos::UI::SuperWeaponSidebar_Max - static_cast(columns.size()); + + if (maxButtons <= 0) + return false; + const int cameoWidth = 60; - const auto column = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); + const auto column = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), maxButtons, 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); if (!column) return false; From 867164225835ed02b996525506119350fd4143bd Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 16 Jan 2025 14:03:48 +0800 Subject: [PATCH 46/69] fix docs --- docs/User-Interface.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 5f963868f2..292b7cce1d 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -581,30 +581,31 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable ### Exclusive SuperWeapon Sidebar -- It is possible to put sw cameos on the left of screen like C&C3 when `SuperWeaponSidebar` is true. -- In theory, it should be compatible with Ares -- Cameos arranged in a pyramid shape. -- `SuperWeaponSidebar.Interval` specific how many leptons between two columns. -- `SuperWeaponSidebar.Max` controls the maximum number of cameos on the leftmost side, which also depends on the current game resolution. -- `SuperWeaponSidebar.MaxColumns` controls that maximum count of columns. -- `SuperWeaponSidebar.CameoHeight` controls the distance from the top of the previous cameo to the top of the next cameo. -- `SuperWeaponSidebar.LeftOffset` controls the distance between the leftmost cameo and the leftmost part of the screen. +- It is possible to put sw cameos on the left of screen like C&C3 when `SuperWeaponSidebar` is true. Cameos arranged in a pyramid shape. In theory, it should be compatible with Ares. + - `SuperWeaponSidebar.Interval` controls the distance between two column cameos (excluding the background). When you need to make a background, the width of the background should be (`SuperWeaponSidebar.Interval` + cameo fixed width 60). + - `SuperWeaponSidebar.LeftOffset` controls the distance between the left side of cameo and the left side of its column (background). This will not be greater than `SuperWeaponSidebar.Interval`. + - `SuperWeaponSidebar.CameoHeight` controls the distance from the top of the previous cameo to the top of the next cameo. That is, the space between the upper and lower cameos is (`SuperWeaponSidebar.CameoHeight` - cameo fixed height 48). This will not be less than 48. When you need to make a background, this is the height of the background. + - `SuperWeaponSidebar.Max` controls the maximum number of cameos on the leftmost column, which also depends on the current game resolution. + - `SuperWeaponSidebar.MaxColumns` controls that maximum count of columns. - You can also launch first 10 SW by hotkey in INTERFACE category. -- For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. + - For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. In `uimd.ini`: ```ini [Sidebar] SuperWeaponSidebar=false ; boolean -SuperWeaponSidebar.Interval=0 ; integer -SuperWeaponSidebar.LeftOffset=0 ; integer -SuperWeaponSidebar.CameoHeight=48 ; integer +SuperWeaponSidebar.Interval=0 ; integer, pixels +SuperWeaponSidebar.LeftOffset=0 ; integer, pixels +SuperWeaponSidebar.CameoHeight=48 ; integer, pixels SuperWeaponSidebar.Max=0 ; integer SuperWeaponSidebar.MaxColumns= ; integer ``` In `rulesmd.ini` ```ini +[AudioVisual] +SuperWeaponSidebar.AllowByDefault=false ; boolean + [SOMESIDE] SuperWeaponSidebar.OnPCX= ; filename - including the .pcx extension SuperWeaponSidebar.OffPCX= ; filename - including the .pcx extension @@ -613,7 +614,7 @@ SuperWeaponSidebar.CenterPCX= ; filename - including the .pcx extension SuperWeaponSidebar.BottomPCX= ; filename - including the .pcx extension [SOMESW] -SuperWeaponSidebar.Allow=true ; boolean +SuperWeaponSidebar.Allow= ; boolean SuperWeaponSidebar.PriorityHouses= ; list of house types SuperWeaponSidebar.RequiredHouses= ; list of house types ``` From c45fa4346b244924ca5c9d899592f1f4b5d25381 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 19 Jan 2025 20:59:27 +0800 Subject: [PATCH 47/69] add screenshots --- docs/User-Interface.md | 3 +++ docs/_static/images/sw_sidebar-01-on.png | Bin 0 -> 213564 bytes docs/_static/images/sw_sidebar-02-on.png | Bin 0 -> 159157 bytes 3 files changed, 3 insertions(+) create mode 100644 docs/_static/images/sw_sidebar-01-on.png create mode 100644 docs/_static/images/sw_sidebar-02-on.png diff --git a/docs/User-Interface.md b/docs/User-Interface.md index f2a62d5416..d4286772d5 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -581,6 +581,9 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable ### Exclusive SuperWeapon Sidebar +![image](_static/images/sw_sidebar-01-on.png) +![image](_static/images/sw_sidebar-02-on.png) + - It is possible to put sw cameos on the left of screen like C&C3 when `SuperWeaponSidebar` is true. Cameos arranged in a pyramid shape. In theory, it should be compatible with Ares. - `SuperWeaponSidebar.Interval` controls the distance between two column cameos (excluding the background). When you need to make a background, the width of the background should be (`SuperWeaponSidebar.Interval` + cameo fixed width 60). - `SuperWeaponSidebar.LeftOffset` controls the distance between the left side of cameo and the left side of its column (background). This will not be greater than `SuperWeaponSidebar.Interval`. diff --git a/docs/_static/images/sw_sidebar-01-on.png b/docs/_static/images/sw_sidebar-01-on.png new file mode 100644 index 0000000000000000000000000000000000000000..81fd8681625e34e6597b734dff12cdc387e73df9 GIT binary patch literal 213564 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 V+XBNLfIUFSUR3>v>Ft7L{v&o_*lR2 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 Sn0F%p00000la~CUd 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±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 literal 0 HcmV?d00001 From c63757b4bf6b5d8a8b10bcb66ccd2a2364f155df Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 21 Jan 2025 09:54:00 +0800 Subject: [PATCH 48/69] improve the response speed of ToolTip --- src/Misc/PhobosToolTip.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index 1280778728..051b48c08a 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -243,17 +243,18 @@ DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) return ApplyToolTip; } -DEFINE_HOOK(0x72426F, ToolTipManager_ProcessMessage_SetDelay, 0x5) +DEFINE_HOOK(0x724247, ToolTipManager_ProcessMessage_SetDelayTimer, 0x6) { - if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton) - R->EDX(0); + enum { SkipDelay = 0x72429E }; - return 0; + return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? SkipDelay : 0; } DEFINE_HOOK(0x72428C, ToolTipManager_ProcessMessage_Redraw, 0x5) { - return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? 0x724297 : 0; + enum { SkipRedraw = 0x724297 }; + + return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? SkipRedraw : 0; } DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) From dbe8a1edbbf51bd52f96763fe45f9c4ff09ea45a Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 21 Jan 2025 10:18:03 +0800 Subject: [PATCH 49/69] cameos automatic filling --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 31 ++++++----- src/Misc/Hooks.Ares.cpp | 54 ++++++++++++++++++++ 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 688c81e4c5..edb3aa3393 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -255,25 +255,32 @@ DEFINE_HOOK(0x6A6316, SidebarClass_AddCameo_SuperWeapon_SWSidebar, 0x6) enum { ReturnFalse = 0x6A65FF }; GET_STACK(AbstractType, whatAmI, STACK_OFFSET(0x14, 0x4)); - GET_STACK(int, index, STACK_OFFSET(0x14, 0x8)); - switch (whatAmI) - { - case AbstractType::Super: - case AbstractType::SuperWeaponType: - case AbstractType::Special: - if (SWSidebarClass::Instance.AddButton(index)) - return ReturnFalse; + if (whatAmI != AbstractType::Special && whatAmI != AbstractType::SuperWeaponType && whatAmI != AbstractType::Super) + return 0; - break; + GET_STACK(int, index, STACK_OFFSET(0x14, 0x8)); - default: - break; - } + if (SWSidebarClass::Instance.AddButton(index)) + return ReturnFalse; return 0; } +DEFINE_HOOK(0x6AA790, StripClass_RecheckCameo_RemoveCameo, 0x6) +{ + enum { ShouldRemove = 0x6AA7B6, ShouldNotRemove = 0x6AAA68 }; + + GET(BuildType*, pItem, ESI); + const auto pCurrent = HouseClass::CurrentPlayer(); + const auto& supers = pCurrent->Supers; + + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) + return ShouldNotRemove; + + return ShouldRemove; +} + DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) { SWSidebarClass::Instance.InitClear(); diff --git a/src/Misc/Hooks.Ares.cpp b/src/Misc/Hooks.Ares.cpp index e4e0016b77..2a436c5c5c 100644 --- a/src/Misc/Hooks.Ares.cpp +++ b/src/Misc/Hooks.Ares.cpp @@ -1,9 +1,14 @@ #include #include +#include +#include +#include +#include #include #include #include +#include // In vanilla YR, game destroys building animations directly by calling constructor. // Ares changed this to call UnInit() which has a consequence of doing pointer invalidation on the AnimClass pointer. @@ -27,6 +32,49 @@ DEFINE_HOOK(0x44E9FA, BuildingClass_Detach_RestoreAnims, 0x6) // Patches presented here are exceptions rather that the rule. They must be short, concise and correct. // DO NOT POLLUTE ISSUEs and PRs. +static bool __stdcall AresTabCameo_RemoveCameo(BuildType* pItem) +{ + const auto pTechnoType = TechnoTypeClass::GetByTypeAndIndex(pItem->ItemType, pItem->ItemIndex); + const auto pCurrent = HouseClass::CurrentPlayer(); + + if (pTechnoType) + { + const auto pFactory = pTechnoType->FindFactory(true, false, false, pCurrent); + + if (pFactory && pFactory->Owner->CanBuild(pTechnoType, false, true) != CanBuildResult::Unbuildable) + return false; + } + else + { + const auto& supers = pCurrent->Supers; + + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) + return false; + } + + if (pItem->CurrentFactory) + { + EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::Abandon, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType && pTechnoType->Naval); + EventClass::AddEvent(nEvent); + } + + if (pItem->ItemType == BuildingTypeClass::AbsID || pItem->ItemType == BuildingClass::AbsID) + { + DisplayClass::Instance->CurrentBuilding = nullptr; + DisplayClass::Instance->CurrentBuildingType = nullptr; + DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; + DisplayClass::Instance->SetActiveFoundation(nullptr); + } + + if (pTechnoType && pCurrent->GetPrimaryFactory(pTechnoType->WhatAmI(), pTechnoType->Naval, BuildCat::DontCare)) + { + EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::AbandonAll, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType->Naval); + EventClass::AddEvent(nEvent); + } + + return true; +} + ObjectClass* __fastcall CreateInitialPayload(TechnoTypeClass* type, void*, HouseClass* owner) { // temporarily reset the mutex since it's not part of the design @@ -46,6 +94,9 @@ void Apply_Ares3_0_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x528C8, &Helpers::Alex::getCellSpreadItems); Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x5273A, &Helpers::Alex::getCellSpreadItems); + // Redirect Ares's RemoveCameo to out implementation: + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(AresTabCameo_RemoveCameo)); + // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x43D5D, &CreateInitialPayload); } @@ -62,6 +113,9 @@ void Apply_Ares3_0p1_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x53578, &Helpers::Alex::getCellSpreadItems); Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x533EA, &Helpers::Alex::getCellSpreadItems); + // Redirect Ares's RemoveCameo to out implementation: + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(AresTabCameo_RemoveCameo)); + // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x4483D, &CreateInitialPayload); } From 68db175986c723e5080f8c5b289674f6ecc1f26b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 21 Jan 2025 12:15:11 +0800 Subject: [PATCH 50/69] change something --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 45 ++++++++++++++++- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 11 +---- src/Misc/Hooks.Ares.cpp | 51 +------------------- 3 files changed, 48 insertions(+), 59 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index edb3aa3393..bf7f307f70 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -1,6 +1,6 @@ #include "SWSidebarClass.h" #include -#include +#include #include #include @@ -186,6 +186,49 @@ bool SWSidebarClass::IsEnabled() return SidebarExt::Global()->SWSidebar_Enable; } +bool __stdcall SWSidebarClass::AresTabCameo_RemoveCameo(BuildType* pItem) +{ + const auto pTechnoType = TechnoTypeClass::GetByTypeAndIndex(pItem->ItemType, pItem->ItemIndex); + const auto pCurrent = HouseClass::CurrentPlayer(); + + if (pTechnoType) + { + const auto pFactory = pTechnoType->FindFactory(true, false, false, pCurrent); + + if (pFactory && pFactory->Owner->CanBuild(pTechnoType, false, true) != CanBuildResult::Unbuildable) + return false; + } + else + { + const auto& supers = pCurrent->Supers; + + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) + return false; + } + + if (pItem->CurrentFactory) + { + EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::Abandon, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType && pTechnoType->Naval); + EventClass::AddEvent(nEvent); + } + + if (pItem->ItemType == BuildingTypeClass::AbsID || pItem->ItemType == BuildingClass::AbsID) + { + DisplayClass::Instance->CurrentBuilding = nullptr; + DisplayClass::Instance->CurrentBuildingType = nullptr; + DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; + DisplayClass::Instance->SetActiveFoundation(nullptr); + } + + if (pTechnoType && pCurrent->GetPrimaryFactory(pTechnoType->WhatAmI(), pTechnoType->Naval, BuildCat::DontCare)) + { + EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::AbandonAll, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType->Naval); + EventClass::AddEvent(nEvent); + } + + return true; +} + // Hooks DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index b5bd386da2..e4e5405c57 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -20,16 +20,9 @@ class SWSidebarClass static bool IsEnabled(); - static SWSidebarClass Instance; - -public: - static void Allocate(); - static void Remove(); + static bool __stdcall AresTabCameo_RemoveCameo(BuildType* pItem); - static void Clear() - { - Allocate(); - } + static SWSidebarClass Instance; public: std::vector Columns {}; diff --git a/src/Misc/Hooks.Ares.cpp b/src/Misc/Hooks.Ares.cpp index 2a436c5c5c..21317e56b3 100644 --- a/src/Misc/Hooks.Ares.cpp +++ b/src/Misc/Hooks.Ares.cpp @@ -1,9 +1,5 @@ #include #include -#include -#include -#include -#include #include #include @@ -32,49 +28,6 @@ DEFINE_HOOK(0x44E9FA, BuildingClass_Detach_RestoreAnims, 0x6) // Patches presented here are exceptions rather that the rule. They must be short, concise and correct. // DO NOT POLLUTE ISSUEs and PRs. -static bool __stdcall AresTabCameo_RemoveCameo(BuildType* pItem) -{ - const auto pTechnoType = TechnoTypeClass::GetByTypeAndIndex(pItem->ItemType, pItem->ItemIndex); - const auto pCurrent = HouseClass::CurrentPlayer(); - - if (pTechnoType) - { - const auto pFactory = pTechnoType->FindFactory(true, false, false, pCurrent); - - if (pFactory && pFactory->Owner->CanBuild(pTechnoType, false, true) != CanBuildResult::Unbuildable) - return false; - } - else - { - const auto& supers = pCurrent->Supers; - - if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) - return false; - } - - if (pItem->CurrentFactory) - { - EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::Abandon, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType && pTechnoType->Naval); - EventClass::AddEvent(nEvent); - } - - if (pItem->ItemType == BuildingTypeClass::AbsID || pItem->ItemType == BuildingClass::AbsID) - { - DisplayClass::Instance->CurrentBuilding = nullptr; - DisplayClass::Instance->CurrentBuildingType = nullptr; - DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; - DisplayClass::Instance->SetActiveFoundation(nullptr); - } - - if (pTechnoType && pCurrent->GetPrimaryFactory(pTechnoType->WhatAmI(), pTechnoType->Naval, BuildCat::DontCare)) - { - EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::AbandonAll, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType->Naval); - EventClass::AddEvent(nEvent); - } - - return true; -} - ObjectClass* __fastcall CreateInitialPayload(TechnoTypeClass* type, void*, HouseClass* owner) { // temporarily reset the mutex since it's not part of the design @@ -95,7 +48,7 @@ void Apply_Ares3_0_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x5273A, &Helpers::Alex::getCellSpreadItems); // Redirect Ares's RemoveCameo to out implementation: - Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(AresTabCameo_RemoveCameo)); + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(SWSidebarClass::AresTabCameo_RemoveCameo)); // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x43D5D, &CreateInitialPayload); @@ -114,7 +67,7 @@ void Apply_Ares3_0p1_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x533EA, &Helpers::Alex::getCellSpreadItems); // Redirect Ares's RemoveCameo to out implementation: - Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(AresTabCameo_RemoveCameo)); + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(SWSidebarClass::AresTabCameo_RemoveCameo)); // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x4483D, &CreateInitialPayload); From a474978a03088cb1160ab741b3eefa47d774639f Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 22 Feb 2025 10:42:00 +0800 Subject: [PATCH 51/69] fix priority --- src/Ext/Sidebar/Body.h | 2 +- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 70 ++++++++++++++------ src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 10 +-- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 1 + 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/Ext/Sidebar/Body.h b/src/Ext/Sidebar/Body.h index 9d48c20583..ac03d63a6d 100644 --- a/src/Ext/Sidebar/Body.h +++ b/src/Ext/Sidebar/Body.h @@ -19,7 +19,7 @@ class SidebarExt { public: bool SWSidebar_Enable; - DynamicVectorClass SWSidebar_Indices; + std::vector SWSidebar_Indices; ExtData(SidebarClass* OwnerObject) : Extension(OwnerObject) , SWSidebar_Enable { true } diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 8bbc8f3924..2b3263898f 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -79,33 +79,57 @@ bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModi bool SWColumnClass::AddButton(int superIdx) { - if (const auto pSWType = SuperWeaponTypeClass::Array->GetItemOrDefault(superIdx)) - { - const auto pSWExt = SWTypeExt::ExtMap.Find(pSWType); + const auto pSWType = SuperWeaponTypeClass::Array->GetItemOrDefault(superIdx); - if (!pSWExt->SW_ShowCameo) - return true; + if (!pSWType) + return false; - if (!Phobos::UI::SuperWeaponSidebar) - return false; + const auto pSWExt = SWTypeExt::ExtMap.Find(pSWType); - if (!pSWExt->SuperWeaponSidebar_Allow.Get(RulesExt::Global()->SuperWeaponSidebar_AllowByDefault)) - return false; + if (!pSWExt->SW_ShowCameo || !Phobos::UI::SuperWeaponSidebar || !pSWExt->SuperWeaponSidebar_Allow.Get(RulesExt::Global()->SuperWeaponSidebar_AllowByDefault)) + return false; - const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; + const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; - if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) - return false; - } - else - { - return true; - } + if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) + return false; auto& buttons = this->Buttons; + const int buttonCount = static_cast(buttons.size()); + auto& sidebar = SWSidebarClass::Instance; - if (static_cast(buttons.size()) >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) - return false; + if (buttonCount >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) + { + std::vector vec_SW; + vec_SW.reserve(buttonCount + 1); + + for (const auto button : buttons) + vec_SW.emplace_back(button->SuperIndex); + + vec_SW.emplace_back(superIdx); + std::stable_sort(vec_SW.begin(), vec_SW.end(), [ownerBits](const int left, const int right) + { + const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(left)); + const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(right)); + + if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) + return false; + + if ((!pExtB || !(pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits)) && pExtA && (pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits)) + return true; + + return BuildType::SortsBefore(AbstractType::Special, left, AbstractType::Special, right); + } + ); + + if (vec_SW.back() == superIdx) + return false; + + this->RemoveButton(vec_SW.back()); + sidebar.DisableEntry = true; + SidebarClass::Instance->AddCameo(AbstractType::Special, vec_SW.back()); + sidebar.DisableEntry = false; + } const int cameoWidth = 60, cameoHeight = 48; const auto button = GameCreate(SWButtonClass::StartID + superIdx, superIdx, 0, 0, cameoWidth, cameoHeight); @@ -133,8 +157,14 @@ bool SWColumnClass::RemoveButton(int superIdx) return false; AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentButton, *it); - GScreenClass::Instance->RemoveButton(*it); + auto& indices = SidebarExt::Global()->SWSidebar_Indices; + const auto it_Idx = std::find(indices.cbegin(), indices.cend(), superIdx); + + if (it_Idx != indices.cend()) + indices.erase(it_Idx); + + GScreenClass::Instance->RemoveButton(*it); buttons.erase(it); return true; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index bf7f307f70..98d2df7777 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -78,6 +78,9 @@ void SWSidebarClass::InitClear() bool SWSidebarClass::AddButton(int superIdx) { + if (this->DisableEntry) + return false; + auto& columns = this->Columns; if (columns.empty() && !this->AddColumn()) @@ -89,7 +92,7 @@ bool SWSidebarClass::AddButton(int superIdx) const bool success = columns.back()->AddButton(superIdx); if (success) - SidebarExt::Global()->SWSidebar_Indices.AddUnique(superIdx); + SidebarExt::Global()->SWSidebar_Indices.emplace_back(superIdx); return success; } @@ -268,10 +271,7 @@ DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) } for (const auto& index : removeButtons) - { - if (column->RemoveButton(index)) - SidebarExt::Global()->SWSidebar_Indices.Remove(index); - } + column->RemoveButton(index); } SWSidebarClass::Instance.SortButtons(); diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index e4e5405c57..f35918e1b3 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -29,6 +29,7 @@ class SWSidebarClass SWColumnClass* CurrentColumn { nullptr }; SWButtonClass* CurrentButton { nullptr }; ToggleSWButtonClass* ToggleButton { nullptr }; + bool DisableEntry { false }; static CommandClass* Commands[10]; }; From 6cc849e83a7061005556aa76b070327aa6cdcedd Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 22 Feb 2025 10:54:42 +0800 Subject: [PATCH 52/69] fix EVA_SelectTarget --- src/Ext/SWType/Body.cpp | 8 ++++++++ src/Ext/SWType/Body.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/Ext/SWType/Body.cpp b/src/Ext/SWType/Body.cpp index 864dc39f6c..c5d578804b 100644 --- a/src/Ext/SWType/Body.cpp +++ b/src/Ext/SWType/Body.cpp @@ -4,6 +4,14 @@ SWTypeExt::ExtContainer SWTypeExt::ExtMap; +void SWTypeExt::ExtData::Initialize() +{ + this->EVA_InsufficientFunds = VoxClass::FindIndex(GameStrings::EVA_InsufficientFunds); + this->EVA_SelectTarget = VoxClass::FindIndex("EVA_SelectTarget"); + + this->Message_CannotFire = CSFText("MSG:CannotFire"); +} + // ============================= // load / save diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index 72ca379922..aea5930b35 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -190,6 +190,8 @@ class SWTypeExt std::pair GetEMPulseCannonRange(BuildingClass* pBuilding) const; virtual void LoadFromINIFile(CCINIClass* pINI) override; + virtual void Initialize() override; + virtual ~ExtData() = default; virtual void InvalidatePointer(void* ptr, bool bRemoved) override { } From a1a5660ec0c78ffeb0a2c97babc45bddf8c829f5 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 22 Feb 2025 15:00:06 +0800 Subject: [PATCH 53/69] . --- src/Ext/Sidebar/Hooks.cpp | 49 +++++++++ src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 6 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 100 +++++++++---------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 1 + src/Misc/PhobosToolTip.cpp | 42 -------- 5 files changed, 101 insertions(+), 97 deletions(-) diff --git a/src/Ext/Sidebar/Hooks.cpp b/src/Ext/Sidebar/Hooks.cpp index c81ec2a650..7e25378935 100644 --- a/src/Ext/Sidebar/Hooks.cpp +++ b/src/Ext/Sidebar/Hooks.cpp @@ -1,9 +1,11 @@ #include "Body.h" +#include "SWSidebar/SWSidebarClass.h" #include #include #include #include +#include DEFINE_HOOK(0x6A593E, SidebarClass_InitForHouse_AdditionalFiles, 0x5) { @@ -97,3 +99,50 @@ DEFINE_HOOK(0x72FCB5, InitSideRectangles_CenterBackground, 0x5) return 0; } + +DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) +{ + enum { ApplyToolTip = 0x4AE69D }; + + if (SWSidebarClass::IsEnabled()) + { + const auto& swSidebar = SWSidebarClass::Instance; + + if (const auto button = swSidebar.CurrentButton) + { + PhobosToolTip::Instance.IsCameo = true; + + if (PhobosToolTip::Instance.IsEnabled()) + { + PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); + R->EAX(PhobosToolTip::Instance.GetBuffer()); + } + else + { + const auto pSuper = HouseClass::CurrentPlayer->Supers[button->SuperIndex]; + R->EAX(pSuper->Type->UIName); + } + + return ApplyToolTip; + } + else if (swSidebar.CurrentColumn || (swSidebar.ToggleButton && swSidebar.ToggleButton->IsHovering)) + { + R->EAX(0); + return ApplyToolTip; + } + } + + return 0; +} + +DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) +{ + SWSidebarClass::Instance.InitClear(); + return 0; +} + +DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) +{ + SWSidebarClass::Instance.InitIO(); + return 0; +} diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 23ccc937a2..62e3d97feb 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -132,6 +132,9 @@ void SWButtonClass::OnMouseEnter() SWSidebarClass::Instance.CurrentButton = this; SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseEnter(); MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + + CCToolTip::Instance->SaveTimerDelay(); + CCToolTip::Instance->SetTimerDelay(0); } void SWButtonClass::OnMouseLeave() @@ -143,7 +146,8 @@ void SWButtonClass::OnMouseLeave() SWSidebarClass::Instance.CurrentButton = nullptr; SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseLeave(); MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); + + CCToolTip::Instance->RestoreTimeDelay(); } bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 98d2df7777..ccb739e601 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -76,6 +76,52 @@ void SWSidebarClass::InitClear() columns.clear(); } +void SWSidebarClass::InitIO() +{ + if (!Phobos::UI::SuperWeaponSidebar || Unsorted::ArmageddonMode) + return; + + if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) + { + const auto pOnPCX = pSideExt->SuperWeaponSidebar_OnPCX.GetSurface(); + const auto pOffPCX = pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); + int width = 0, height = 0; + + if (pOnPCX) + { + if (pOffPCX) + { + width = std::max(pOnPCX->GetWidth(), pOffPCX->GetWidth()); + height = std::max(pOnPCX->GetHeight(), pOffPCX->GetHeight()); + } + else + { + width = pOnPCX->GetWidth(); + height = pOnPCX->GetHeight(); + } + } + else if (pOffPCX) + { + width = pOffPCX->GetWidth(); + height = pOffPCX->GetHeight(); + } + + if (width > 0 && height > 0) + { + if (const auto toggleButton = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) + { + toggleButton->Zap(); + GScreenClass::Instance->AddButton(toggleButton); + SWSidebarClass::Instance.ToggleButton = toggleButton; + toggleButton->UpdatePosition(); + } + } + } + + for (const auto superIdx : SidebarExt::Global()->SWSidebar_Indices) + SWSidebarClass::Instance.AddButton(superIdx); +} + bool SWSidebarClass::AddButton(int superIdx) { if (this->DisableEntry) @@ -323,57 +369,3 @@ DEFINE_HOOK(0x6AA790, StripClass_RecheckCameo_RemoveCameo, 0x6) return ShouldRemove; } - -DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) -{ - SWSidebarClass::Instance.InitClear(); - return 0; -} - -DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) -{ - if (!Phobos::UI::SuperWeaponSidebar || Unsorted::ArmageddonMode) - return 0; - - if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) - { - const auto pOnPCX = pSideExt->SuperWeaponSidebar_OnPCX.GetSurface(); - const auto pOffPCX = pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); - int width = 0, height = 0; - - if (pOnPCX) - { - if (pOffPCX) - { - width = std::max(pOnPCX->GetWidth(), pOffPCX->GetWidth()); - height = std::max(pOnPCX->GetHeight(), pOffPCX->GetHeight()); - } - else - { - width = pOnPCX->GetWidth(); - height = pOnPCX->GetHeight(); - } - } - else if (pOffPCX) - { - width = pOffPCX->GetWidth(); - height = pOffPCX->GetHeight(); - } - - if (width > 0 && height > 0) - { - if (const auto toggleButton = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) - { - toggleButton->Zap(); - GScreenClass::Instance->AddButton(toggleButton); - SWSidebarClass::Instance.ToggleButton = toggleButton; - toggleButton->UpdatePosition(); - } - } - } - - for (const auto superIdx : SidebarExt::Global()->SWSidebar_Indices) - SWSidebarClass::Instance.AddButton(superIdx); - - return 0; -} diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index f35918e1b3..2ffa4fd14b 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -12,6 +12,7 @@ class SWSidebarClass bool RemoveColumn(); void InitClear(); + void InitIO(); bool AddButton(int superIdx); void SortButtons(); diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index 408699b939..f93601f305 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -231,48 +231,6 @@ DEFINE_HOOK(0x6A9316, SidebarClass_StripClass_HelpText, 0x6) return 0x6A93DE; } -DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) -{ - enum { ApplyToolTip = 0x4AE69D }; - - if (!SWSidebarClass::IsEnabled()) - return 0; - - const auto button = SWSidebarClass::Instance.CurrentButton; - - if (!button) - return 0; - - PhobosToolTip::Instance.IsCameo = true; - - if (PhobosToolTip::Instance.IsEnabled()) - { - PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); - R->EAX(PhobosToolTip::Instance.GetBuffer()); - } - else - { - const auto pSuper = HouseClass::CurrentPlayer->Supers[button->SuperIndex]; - R->EAX(pSuper->Type->UIName); - } - - return ApplyToolTip; -} - -DEFINE_HOOK(0x724247, ToolTipManager_ProcessMessage_SetDelayTimer, 0x6) -{ - enum { SkipDelay = 0x72429E }; - - return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? SkipDelay : 0; -} - -DEFINE_HOOK(0x72428C, ToolTipManager_ProcessMessage_Redraw, 0x5) -{ - enum { SkipRedraw = 0x724297 }; - - return SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentButton ? SkipRedraw : 0; -} - DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) { if (SWSidebarClass::IsEnabled()) From e9a6f574fc6995891e6554a178c6aa1e1421c92f Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 22 Feb 2025 15:22:13 +0800 Subject: [PATCH 54/69] fix error --- src/Ext/Sidebar/Hooks.cpp | 35 ++++---------------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 12 ------- src/Misc/PhobosToolTip.cpp | 35 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Ext/Sidebar/Hooks.cpp b/src/Ext/Sidebar/Hooks.cpp index 7e25378935..7704d8f7e4 100644 --- a/src/Ext/Sidebar/Hooks.cpp +++ b/src/Ext/Sidebar/Hooks.cpp @@ -100,39 +100,16 @@ DEFINE_HOOK(0x72FCB5, InitSideRectangles_CenterBackground, 0x5) return 0; } -DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) +DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) { - enum { ApplyToolTip = 0x4AE69D }; + enum { DoNothing = 0x6925FC }; - if (SWSidebarClass::IsEnabled()) - { - const auto& swSidebar = SWSidebarClass::Instance; - - if (const auto button = swSidebar.CurrentButton) - { - PhobosToolTip::Instance.IsCameo = true; + if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentColumn) + return DoNothing; - if (PhobosToolTip::Instance.IsEnabled()) - { - PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); - R->EAX(PhobosToolTip::Instance.GetBuffer()); - } - else - { - const auto pSuper = HouseClass::CurrentPlayer->Supers[button->SuperIndex]; - R->EAX(pSuper->Type->UIName); - } + const auto toggleButton = SWSidebarClass::Instance.ToggleButton; - return ApplyToolTip; - } - else if (swSidebar.CurrentColumn || (swSidebar.ToggleButton && swSidebar.ToggleButton->IsHovering)) - { - R->EAX(0); - return ApplyToolTip; - } - } - - return 0; + return toggleButton && toggleButton->IsHovering ? DoNothing : 0; } DEFINE_HOOK(0x6A5082, SidebarClass_InitClear_InitializeSWSidebar, 0x5) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index ccb739e601..2d00b10bc0 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -280,18 +280,6 @@ bool __stdcall SWSidebarClass::AresTabCameo_RemoveCameo(BuildType* pItem) // Hooks -DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) -{ - enum { DoNothing = 0x6925FC }; - - if (SWSidebarClass::IsEnabled() && SWSidebarClass::Instance.CurrentColumn) - return DoNothing; - - const auto toggleButton = SWSidebarClass::Instance.ToggleButton; - - return toggleButton && toggleButton->IsHovering ? DoNothing : 0; -} - DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) { enum { SkipGameCode = 0x4F9302 }; diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index f93601f305..a2aa18e1bb 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -231,6 +231,41 @@ DEFINE_HOOK(0x6A9316, SidebarClass_StripClass_HelpText, 0x6) return 0x6A93DE; } +DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) +{ + enum { ApplyToolTip = 0x4AE69D }; + + if (SWSidebarClass::IsEnabled()) + { + const auto& swSidebar = SWSidebarClass::Instance; + + if (const auto button = swSidebar.CurrentButton) + { + PhobosToolTip::Instance.IsCameo = true; + + if (PhobosToolTip::Instance.IsEnabled()) + { + PhobosToolTip::Instance.HelpText_Super(button->SuperIndex); + R->EAX(PhobosToolTip::Instance.GetBuffer()); + } + else + { + const auto pSuper = HouseClass::CurrentPlayer->Supers[button->SuperIndex]; + R->EAX(pSuper->Type->UIName); + } + + return ApplyToolTip; + } + else if (swSidebar.CurrentColumn || (swSidebar.ToggleButton && swSidebar.ToggleButton->IsHovering)) + { + R->EAX(0); + return ApplyToolTip; + } + } + + return 0; +} + DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) { if (SWSidebarClass::IsEnabled()) From 5c4a2307e65d4528f3ccc009e81c308ba3b24605 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 22 Feb 2025 17:46:55 +0800 Subject: [PATCH 55/69] Fix some bugs related to mouse clicking or hovering --- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 9 +-------- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 8 +------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 7 +++++++ src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 12 ++++-------- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 62e3d97feb..3ef34b3134 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -9,7 +9,7 @@ #include SWButtonClass::SWButtonClass(unsigned int id, int superIdx, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::RightPress), true) + : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::RightPress), false) , SuperIndex(superIdx) { if (const auto backColumn = SWSidebarClass::Instance.Columns.back()) @@ -131,22 +131,15 @@ void SWButtonClass::OnMouseEnter() this->IsHovering = true; SWSidebarClass::Instance.CurrentButton = this; SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseEnter(); - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - CCToolTip::Instance->SaveTimerDelay(); CCToolTip::Instance->SetTimerDelay(0); } void SWButtonClass::OnMouseLeave() { - if (!SWSidebarClass::IsEnabled()) - return; - this->IsHovering = false; SWSidebarClass::Instance.CurrentButton = nullptr; SWSidebarClass::Instance.Columns[this->ColumnIndex]->OnMouseLeave(); - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - CCToolTip::Instance->RestoreTimeDelay(); } diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 2b3263898f..e1ceed0db5 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -5,7 +5,7 @@ #include SWColumnClass::SWColumnClass(unsigned int id, int maxButtons, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, static_cast(0), true) + : ControlClass(id, x, y, width, height, static_cast(0), false) , MaxButtons(maxButtons) { SWSidebarClass::Instance.Columns.emplace_back(this); @@ -68,12 +68,6 @@ void SWColumnClass::OnMouseLeave() bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) { - for (const auto button : this->Buttons) - { - if (button->Clicked(pKey, flags, x, y, modifier)) - return true; - } - return false; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 2d00b10bc0..2a25839c53 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -304,6 +304,13 @@ DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) removeButtons.push_back(button->SuperIndex); } + // A better solution is to swap the order of each function: + // first check the availability of SW, + // then remove the cameo from the SWsidebar, + // and finally remove the cameo from the YRsidebar + if (removeButtons.size()) + pHouse->RecheckTechTree = true; + for (const auto& index : removeButtons) column->RemoveButton(index); } diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index 5e375d4383..588ca37904 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -7,7 +7,7 @@ #include ToggleSWButtonClass::ToggleSWButtonClass(unsigned int id, int x, int y, int width, int height) - : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::LeftRelease), true) + : ControlClass(id, x, y, width, height, (GadgetFlag::LeftPress | GadgetFlag::LeftRelease), false) { SWSidebarClass::Instance.ToggleButton = this; } @@ -50,15 +50,9 @@ void ToggleSWButtonClass::OnMouseEnter() void ToggleSWButtonClass::OnMouseLeave() { - auto& columns = SWSidebarClass::Instance.Columns; - - if (columns.empty()) - return; - this->IsHovering = false; this->IsPressed = false; MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - CCToolTip::Instance->MarkToRedraw(CCToolTip::Instance->CurrentToolTipData); } bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) @@ -83,7 +77,9 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi ToggleSWButtonClass::SwitchSidebar(); } - return this->ControlClass::Action(flags, pKey, KeyModifier::None); + // this->ControlClass::Action(flags, pKey, KeyModifier::None); + reinterpret_cast(0x48E5A0)(this, flags, pKey, KeyModifier::None); + return true; } void ToggleSWButtonClass::UpdatePosition() From 1e42476ae64ea04376cca92ea03b619654acee45 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 22 Feb 2025 20:48:13 +0800 Subject: [PATCH 56/69] Fit with develop --- src/Ext/Sidebar/Body.cpp | 3 +- src/Ext/Sidebar/Hooks.cpp | 4 ++ src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 45 -------------------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 2 - src/Misc/Hooks.Ares.cpp | 9 ++-- 5 files changed, 10 insertions(+), 53 deletions(-) diff --git a/src/Ext/Sidebar/Body.cpp b/src/Ext/Sidebar/Body.cpp index f2800eab1c..4721fa47db 100644 --- a/src/Ext/Sidebar/Body.cpp +++ b/src/Ext/Sidebar/Body.cpp @@ -1,4 +1,5 @@ #include "Body.h" +#include "SWSidebar/SWSidebarClass.h" #include #include @@ -36,7 +37,7 @@ bool __stdcall SidebarExt::AresTabCameo_RemoveCameo(BuildType* pItem) { const auto& supers = pCurrent->Supers; - if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent) + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) return false; } diff --git a/src/Ext/Sidebar/Hooks.cpp b/src/Ext/Sidebar/Hooks.cpp index 7704d8f7e4..996d9157a6 100644 --- a/src/Ext/Sidebar/Hooks.cpp +++ b/src/Ext/Sidebar/Hooks.cpp @@ -100,6 +100,8 @@ DEFINE_HOOK(0x72FCB5, InitSideRectangles_CenterBackground, 0x5) return 0; } +#pragma region SWSidebarButtonsRelated + DEFINE_HOOK(0x692419, DisplayClass_ProcessClickCoords_SWSidebar, 0x7) { enum { DoNothing = 0x6925FC }; @@ -123,3 +125,5 @@ DEFINE_HOOK(0x6A5839, SidebarClass_InitIO_InitializeSWSidebar, 0x5) SWSidebarClass::Instance.InitIO(); return 0; } + +#pragma endregion diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 2a25839c53..57759d8aea 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -1,6 +1,5 @@ #include "SWSidebarClass.h" #include -#include #include #include @@ -234,50 +233,6 @@ bool SWSidebarClass::IsEnabled() { return SidebarExt::Global()->SWSidebar_Enable; } - -bool __stdcall SWSidebarClass::AresTabCameo_RemoveCameo(BuildType* pItem) -{ - const auto pTechnoType = TechnoTypeClass::GetByTypeAndIndex(pItem->ItemType, pItem->ItemIndex); - const auto pCurrent = HouseClass::CurrentPlayer(); - - if (pTechnoType) - { - const auto pFactory = pTechnoType->FindFactory(true, false, false, pCurrent); - - if (pFactory && pFactory->Owner->CanBuild(pTechnoType, false, true) != CanBuildResult::Unbuildable) - return false; - } - else - { - const auto& supers = pCurrent->Supers; - - if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) - return false; - } - - if (pItem->CurrentFactory) - { - EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::Abandon, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType && pTechnoType->Naval); - EventClass::AddEvent(nEvent); - } - - if (pItem->ItemType == BuildingTypeClass::AbsID || pItem->ItemType == BuildingClass::AbsID) - { - DisplayClass::Instance->CurrentBuilding = nullptr; - DisplayClass::Instance->CurrentBuildingType = nullptr; - DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; - DisplayClass::Instance->SetActiveFoundation(nullptr); - } - - if (pTechnoType && pCurrent->GetPrimaryFactory(pTechnoType->WhatAmI(), pTechnoType->Naval, BuildCat::DontCare)) - { - EventClass nEvent = EventClass(pCurrent->ArrayIndex, EventType::AbandonAll, static_cast(pItem->ItemType), pItem->ItemIndex, pTechnoType->Naval); - EventClass::AddEvent(nEvent); - } - - return true; -} - // Hooks DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 2ffa4fd14b..6a7670f6e8 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -21,8 +21,6 @@ class SWSidebarClass static bool IsEnabled(); - static bool __stdcall AresTabCameo_RemoveCameo(BuildType* pItem); - static SWSidebarClass Instance; public: diff --git a/src/Misc/Hooks.Ares.cpp b/src/Misc/Hooks.Ares.cpp index cfc59b71cd..e53e0e3bc4 100644 --- a/src/Misc/Hooks.Ares.cpp +++ b/src/Misc/Hooks.Ares.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -49,8 +48,8 @@ void Apply_Ares3_0_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x528C8, &Helpers::Alex::getCellSpreadItems); Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x5273A, &Helpers::Alex::getCellSpreadItems); - // Redirect Ares's RemoveCameo to out implementation: - Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(SWSidebarClass::AresTabCameo_RemoveCameo)); + // Redirect Ares's RemoveCameo to our implementation: + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02BDD0, GET_OFFSET(SidebarExt::AresTabCameo_RemoveCameo)); // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x43D5D, &CreateInitialPayload); @@ -68,8 +67,8 @@ void Apply_Ares3_0p1_Patches() Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x53578, &Helpers::Alex::getCellSpreadItems); Patch::Apply_CALL(AresHelper::AresBaseAddress + 0x533EA, &Helpers::Alex::getCellSpreadItems); - // Redirect Ares's RemoveCameo to out implementation: - Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(SWSidebarClass::AresTabCameo_RemoveCameo)); + // Redirect Ares's RemoveCameo to our implementation: + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x02C910, GET_OFFSET(SidebarExt::AresTabCameo_RemoveCameo)); // InitialPayload creation: Patch::Apply_CALL6(AresHelper::AresBaseAddress + 0x4483D, &CreateInitialPayload); From 06d9e9ec28416fe3800f02cf033358d3add7e9c3 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 22 Feb 2025 20:49:13 +0800 Subject: [PATCH 57/69] Timely update current button and optimize function order --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 117 +++++++++++++----- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 2 + .../Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 7 +- 3 files changed, 89 insertions(+), 37 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 57759d8aea..1d3533713a 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -233,59 +233,112 @@ bool SWSidebarClass::IsEnabled() { return SidebarExt::Global()->SWSidebar_Enable; } -// Hooks -DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) +void SWSidebarClass::RecheckInput() { - enum { SkipGameCode = 0x4F9302 }; + const auto& sidebar = SWSidebarClass::Instance; + + if (!sidebar.IsEnabled()) + { + if (const auto pToggle = sidebar.ToggleButton) + { + pToggle->UpdatePosition(); + pToggle->Input(); + } - GET(HouseClass*, pHouse, ESI); + if (const auto pButton = sidebar.CurrentButton) + pButton->Input(); + else if (const auto pColumn = sidebar.CurrentColumn) + pColumn->Input(); - pHouse->AISupers(); + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + return; + } - if (pHouse->IsCurrentPlayer()) + if (const auto pToggle = sidebar.ToggleButton) { - auto& sidebar = SWSidebarClass::Instance; + pToggle->UpdatePosition(); + pToggle->Input(); + } - for (const auto& column : sidebar.Columns) + const auto& columns = sidebar.Columns; + + if (!columns.empty()) + { + for (const auto& pColumn : columns) { - std::vector removeButtons; + const auto& buttons = pColumn->Buttons; - for (const auto& button : column->Buttons) + if (!buttons.empty()) { - if (HouseClass::CurrentPlayer->Supers[button->SuperIndex]->IsPresent) - continue; - - removeButtons.push_back(button->SuperIndex); + for (const auto& pButton : buttons) + pButton->Input(); } + } + } - // A better solution is to swap the order of each function: - // first check the availability of SW, - // then remove the cameo from the SWsidebar, - // and finally remove the cameo from the YRsidebar - if (removeButtons.size()) - pHouse->RecheckTechTree = true; + MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); +} - for (const auto& index : removeButtons) - column->RemoveButton(index); - } +void SWSidebarClass::RecheckCameo() +{ + auto& sidebar = SWSidebarClass::Instance; - SWSidebarClass::Instance.SortButtons(); - int removes = 0; + for (const auto& column : sidebar.Columns) + { + std::vector removeButtons; - for (const auto& column : sidebar.Columns) + for (const auto& button : column->Buttons) { - if (column->Buttons.empty()) - ++removes; + if (HouseClass::CurrentPlayer->Supers[button->SuperIndex]->IsPresent) + continue; + + removeButtons.push_back(button->SuperIndex); } - for (; removes > 0; --removes) - sidebar.RemoveColumn(); + for (const auto& index : removeButtons) + column->RemoveButton(index); + } - if (const auto toggleButton = sidebar.ToggleButton) - toggleButton->UpdatePosition(); + sidebar.SortButtons(); + int removes = 0; + + for (const auto& column : sidebar.Columns) + { + if (column->Buttons.empty()) + ++removes; } + for (; removes > 0; --removes) + sidebar.RemoveColumn(); + + if (const auto toggleButton = sidebar.ToggleButton) + toggleButton->UpdatePosition(); + + sidebar.RecheckInput(); +} + +// Hooks + +DEFINE_HOOK(0x4F92DD, HouseClass_UpdateTechTree_ReorderFunctions, 0x5) +{ + enum { SkipGameCode = 0x4F9302 }; + + GET(HouseClass*, pHouse, ESI); // Only HouseClass::CurrentPlayer + + // Mark redraw + SidebarClass::Instance->SidebarBackgroundNeedsRedraw = true; + + // Update SWs + reinterpret_cast(0x50AF10)(pHouse); + pHouse->AISupers(); + + // Recheck SWSidebar Cameo + SWSidebarClass::RecheckCameo(); + + // Recheck YRSidebar Cameo + reinterpret_cast(0x6A7D20)(SidebarClass::Instance()); + return SkipGameCode; } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 6a7670f6e8..9b66493b8d 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -20,6 +20,8 @@ class SWSidebarClass int GetMaximumButtonCount(); static bool IsEnabled(); + static void RecheckInput(); + static void RecheckCameo(); static SWSidebarClass Instance; diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index 588ca37904..919b51dd61 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -73,7 +73,6 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi if ((flags & GadgetFlag::LeftRelease) && this->IsPressed) { this->IsPressed = false; - VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); ToggleSWButtonClass::SwitchSidebar(); } @@ -104,10 +103,8 @@ void ToggleSWButtonClass::UpdatePosition() bool ToggleSWButtonClass::SwitchSidebar() { + VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; - - if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) - toggleButton->UpdatePosition(); - + SWSidebarClass::Instance.RecheckInput(); return SWSidebarClass::Instance.IsEnabled(); } From d74fb640906d36c05d94e88efcbaba6e9b7cad0d Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 22 Feb 2025 20:52:42 +0800 Subject: [PATCH 58/69] Fix doc --- CREDITS.md | 2 +- docs/Whats-New.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 9cbe8b06e8..2c8f7fb567 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -380,7 +380,6 @@ This page lists all the individual contributions to the project by their author. - Allow to change the speed of gas particles - **CrimRecya** - Fix `LimboKill` not working reliably - - Exclusive SuperWeapon Sidebar - Allow using waypoints, area guard and attack move with aircraft - Fix `Stop` command not working so well in some cases - Fix aircraft `MovementZone` and `SpeedType` inconsistencies @@ -390,6 +389,7 @@ This page lists all the individual contributions to the project by their author. - Fix for sidebar not updating queued unit numbers when on hold - New Parabola trajectory - Enhanced Bombard trajectory + - Exclusive SuperWeapon Sidebar - **Ollerus** - Build limit group enhancement - Customizable rocker amplitude diff --git a/docs/Whats-New.md b/docs/Whats-New.md index cd711e96a1..459fefafb1 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -324,6 +324,7 @@ New: - Enhanced Bombard trajectory (by CrimRecya & Ollerus, based on knowledge of NaotoYuuki) - Toggle waypoint for building (by TaranDahl) - Bunkerable checks dehardcode (by TaranDahl) +- Exclusive SuperWeapon Sidebar (by NetsuNegi & CrimRecya) Vanilla fixes: - Prevent the units with locomotors that cause problems from entering the tank bunker (by TaranDahl) @@ -500,7 +501,6 @@ New: - Allow customizing charge turret delays per burst on a weapon (by Starkku) - Unit `Speed` setting now accepts floating point values (by Starkku) - Custom exit cell for infantry factory (by Starkku) -- Exclusive SuperWeapon Sidebar (by NetsuNegi & CrimRecya) - Extending `Power` to all TechnoTypes (by Morton) Vanilla fixes: From cc3c4892475e8249a323f235c06c3732de3cd0ba Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 22 Feb 2025 23:09:31 +0800 Subject: [PATCH 59/69] Optimize --- src/Ext/Sidebar/Hooks.cpp | 1 - src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 2 + src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 1 + src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 48 ------------------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 1 - .../Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 26 ++++++++-- 6 files changed, 26 insertions(+), 53 deletions(-) diff --git a/src/Ext/Sidebar/Hooks.cpp b/src/Ext/Sidebar/Hooks.cpp index 996d9157a6..d9c156d990 100644 --- a/src/Ext/Sidebar/Hooks.cpp +++ b/src/Ext/Sidebar/Hooks.cpp @@ -5,7 +5,6 @@ #include #include #include -#include DEFINE_HOOK(0x6A593E, SidebarClass_InitForHouse_AdditionalFiles, 0x5) { diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 3ef34b3134..01b1d02c58 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -14,6 +14,8 @@ SWButtonClass::SWButtonClass(unsigned int id, int superIdx, int x, int y, int wi { if (const auto backColumn = SWSidebarClass::Instance.Columns.back()) backColumn->Buttons.emplace_back(this); + + this->Disabled = !SWSidebarClass::IsEnabled(); } bool SWButtonClass::Draw(bool forced) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index e1ceed0db5..94b3c2a677 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -9,6 +9,7 @@ SWColumnClass::SWColumnClass(unsigned int id, int maxButtons, int x, int y, int , MaxButtons(maxButtons) { SWSidebarClass::Instance.Columns.emplace_back(this); + this->Disabled = !SWSidebarClass::IsEnabled(); } bool SWColumnClass::Draw(bool forced) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 1d3533713a..592cf484f1 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -234,52 +234,6 @@ bool SWSidebarClass::IsEnabled() return SidebarExt::Global()->SWSidebar_Enable; } -void SWSidebarClass::RecheckInput() -{ - const auto& sidebar = SWSidebarClass::Instance; - - if (!sidebar.IsEnabled()) - { - if (const auto pToggle = sidebar.ToggleButton) - { - pToggle->UpdatePosition(); - pToggle->Input(); - } - - if (const auto pButton = sidebar.CurrentButton) - pButton->Input(); - else if (const auto pColumn = sidebar.CurrentColumn) - pColumn->Input(); - - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); - return; - } - - if (const auto pToggle = sidebar.ToggleButton) - { - pToggle->UpdatePosition(); - pToggle->Input(); - } - - const auto& columns = sidebar.Columns; - - if (!columns.empty()) - { - for (const auto& pColumn : columns) - { - const auto& buttons = pColumn->Buttons; - - if (!buttons.empty()) - { - for (const auto& pButton : buttons) - pButton->Input(); - } - } - } - - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); -} - void SWSidebarClass::RecheckCameo() { auto& sidebar = SWSidebarClass::Instance; @@ -314,8 +268,6 @@ void SWSidebarClass::RecheckCameo() if (const auto toggleButton = sidebar.ToggleButton) toggleButton->UpdatePosition(); - - sidebar.RecheckInput(); } // Hooks diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index 9b66493b8d..c07488249d 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -20,7 +20,6 @@ class SWSidebarClass int GetMaximumButtonCount(); static bool IsEnabled(); - static void RecheckInput(); static void RecheckCameo(); static SWSidebarClass Instance; diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index 919b51dd61..b4397122eb 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -1,6 +1,5 @@ #include "ToggleSWButtonClass.h" #include "SWSidebarClass.h" -#include #include #include @@ -105,6 +104,27 @@ bool ToggleSWButtonClass::SwitchSidebar() { VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; - SWSidebarClass::Instance.RecheckInput(); - return SWSidebarClass::Instance.IsEnabled(); + + const bool disabled = !SWSidebarClass::IsEnabled(); + const auto& columns = SWSidebarClass::Instance.Columns; + + if (!columns.empty()) + { + for (const auto& pColumn : columns) + { + pColumn->Disabled = disabled; + const auto& buttons = pColumn->Buttons; + + if (!buttons.empty()) + { + for (const auto& pButton : buttons) + pButton->Disabled = disabled; + } + } + } + + if (const auto pToggle = SWSidebarClass::Instance.ToggleButton) + pToggle->UpdatePosition(); + + return !disabled; } From 3c15e8798036fee94916ff7624ed34340b14d2e2 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 28 Feb 2025 21:49:24 +0800 Subject: [PATCH 60/69] Revert commit --- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 592cf484f1..37da53d1a2 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -250,6 +250,9 @@ void SWSidebarClass::RecheckCameo() removeButtons.push_back(button->SuperIndex); } + if (removeButtons.size()) + HouseClass::CurrentPlayer->RecheckTechTree = true; + for (const auto& index : removeButtons) column->RemoveButton(index); } @@ -272,24 +275,16 @@ void SWSidebarClass::RecheckCameo() // Hooks -DEFINE_HOOK(0x4F92DD, HouseClass_UpdateTechTree_ReorderFunctions, 0x5) +DEFINE_HOOK(0x4F92FB, HouseClass_UpdateTechTree_SWSidebar, 0x7) { enum { SkipGameCode = 0x4F9302 }; - GET(HouseClass*, pHouse, ESI); // Only HouseClass::CurrentPlayer - - // Mark redraw - SidebarClass::Instance->SidebarBackgroundNeedsRedraw = true; + GET(HouseClass*, pHouse, ESI); - // Update SWs - reinterpret_cast(0x50AF10)(pHouse); pHouse->AISupers(); - // Recheck SWSidebar Cameo - SWSidebarClass::RecheckCameo(); - - // Recheck YRSidebar Cameo - reinterpret_cast(0x6A7D20)(SidebarClass::Instance()); + if (pHouse->IsCurrentPlayer()) + SWSidebarClass::RecheckCameo(); return SkipGameCode; } From 3661982ebdec3251a997def5bf89f4826e1c7b01 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Mon, 3 Mar 2025 16:29:34 +0800 Subject: [PATCH 61/69] improve --- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 35 +++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 94b3c2a677..4f427ddb2e 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -95,34 +95,29 @@ bool SWColumnClass::AddButton(int superIdx) if (buttonCount >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) { - std::vector vec_SW; - vec_SW.reserve(buttonCount + 1); - - for (const auto button : buttons) - vec_SW.emplace_back(button->SuperIndex); + auto Compare = [ownerBits](const int left, const int right) + { + const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(left)); + const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(right)); - vec_SW.emplace_back(superIdx); - std::stable_sort(vec_SW.begin(), vec_SW.end(), [ownerBits](const int left, const int right) - { - const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(left)); - const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(right)); + if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) + return false; - if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) - return false; + if ((!pExtB || !(pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits)) && pExtA && (pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits)) + return true; - if ((!pExtB || !(pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits)) && pExtA && (pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits)) - return true; + return BuildType::SortsBefore(AbstractType::Special, left, AbstractType::Special, right); + }; - return BuildType::SortsBefore(AbstractType::Special, left, AbstractType::Special, right); - } - ); + const int backIdx = buttons.back()->SuperIndex; - if (vec_SW.back() == superIdx) + if (!Compare(superIdx, backIdx)) return false; - this->RemoveButton(vec_SW.back()); + this->RemoveButton(backIdx); sidebar.DisableEntry = true; - SidebarClass::Instance->AddCameo(AbstractType::Special, vec_SW.back()); + SidebarClass::Instance->AddCameo(AbstractType::Special, backIdx); + SidebarClass::Instance->RepaintSidebar(SidebarClass::GetObjectTabIdx(AbstractType::Super, backIdx, false)); sidebar.DisableEntry = false; } From 4f5abfb9063d13d1c2f5ed1dff68f5afbfb91707 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Wed, 19 Mar 2025 14:25:11 +0800 Subject: [PATCH 62/69] move --- src/Ext/Scenario/Body.cpp | 2 ++ src/Ext/Scenario/Body.h | 5 +++++ src/Ext/Sidebar/Body.cpp | 2 -- src/Ext/Sidebar/Body.h | 4 ---- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 2 +- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 6 +++--- src/Ext/Sidebar/SWSidebar/SWSidebarClass.h | 2 +- src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Ext/Scenario/Body.cpp b/src/Ext/Scenario/Body.cpp index 53c8ef3985..3fcfcf1304 100644 --- a/src/Ext/Scenario/Body.cpp +++ b/src/Ext/Scenario/Body.cpp @@ -162,6 +162,8 @@ void ScenarioExt::ExtData::Serialize(T& Stm) .Process(this->BriefingTheme) .Process(this->AutoDeathObjects) .Process(this->TransportReloaders) + .Process(this->SWSidebar_Enable) + .Process(this->SWSidebar_Indices) ; } diff --git a/src/Ext/Scenario/Body.h b/src/Ext/Scenario/Body.h index 3d296a5c5f..6a51659d2b 100644 --- a/src/Ext/Scenario/Body.h +++ b/src/Ext/Scenario/Body.h @@ -36,6 +36,9 @@ class ScenarioExt std::vector AutoDeathObjects; std::vector TransportReloaders; // Objects that can reload ammo in limbo + bool SWSidebar_Enable; + std::vector SWSidebar_Indices; + ExtData(ScenarioClass* OwnerObject) : Extension(OwnerObject) , ShowBriefing { false } , BriefingTheme { -1 } @@ -43,6 +46,8 @@ class ScenarioExt , Variables { } , AutoDeathObjects {} , TransportReloaders {} + , SWSidebar_Enable { true } + , SWSidebar_Indices {} { } void SetVariableToByID(bool bIsGlobal, int nIndex, char bState); diff --git a/src/Ext/Sidebar/Body.cpp b/src/Ext/Sidebar/Body.cpp index 4721fa47db..a57d0f4237 100644 --- a/src/Ext/Sidebar/Body.cpp +++ b/src/Ext/Sidebar/Body.cpp @@ -120,8 +120,6 @@ template void SidebarExt::ExtData::Serialize(T& Stm) { Stm - .Process(this->SWSidebar_Enable) - .Process(this->SWSidebar_Indices) ; } diff --git a/src/Ext/Sidebar/Body.h b/src/Ext/Sidebar/Body.h index ac03d63a6d..33d6a757f2 100644 --- a/src/Ext/Sidebar/Body.h +++ b/src/Ext/Sidebar/Body.h @@ -18,12 +18,8 @@ class SidebarExt class ExtData final : public Extension { public: - bool SWSidebar_Enable; - std::vector SWSidebar_Indices; ExtData(SidebarClass* OwnerObject) : Extension(OwnerObject) - , SWSidebar_Enable { true } - , SWSidebar_Indices {} { } virtual ~ExtData() = default; diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 4f427ddb2e..e3aab4d3c3 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -148,7 +148,7 @@ bool SWColumnClass::RemoveButton(int superIdx) AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentButton, *it); - auto& indices = SidebarExt::Global()->SWSidebar_Indices; + auto& indices = ScenarioExt::Global()->SWSidebar_Indices; const auto it_Idx = std::find(indices.cbegin(), indices.cend(), superIdx); if (it_Idx != indices.cend()) diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 37da53d1a2..339371fe25 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -117,7 +117,7 @@ void SWSidebarClass::InitIO() } } - for (const auto superIdx : SidebarExt::Global()->SWSidebar_Indices) + for (const auto superIdx : ScenarioExt::Global()->SWSidebar_Indices) SWSidebarClass::Instance.AddButton(superIdx); } @@ -137,7 +137,7 @@ bool SWSidebarClass::AddButton(int superIdx) const bool success = columns.back()->AddButton(superIdx); if (success) - SidebarExt::Global()->SWSidebar_Indices.emplace_back(superIdx); + ScenarioExt::Global()->SWSidebar_Indices.emplace_back(superIdx); return success; } @@ -231,7 +231,7 @@ int SWSidebarClass::GetMaximumButtonCount() bool SWSidebarClass::IsEnabled() { - return SidebarExt::Global()->SWSidebar_Enable; + return ScenarioExt::Global()->SWSidebar_Enable; } void SWSidebarClass::RecheckCameo() diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h index c07488249d..5cfaf415a9 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.h @@ -2,7 +2,7 @@ #include "SWButtonClass.h" #include "SWColumnClass.h" #include "ToggleSWButtonClass.h" -#include +#include #include class SWSidebarClass diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index b4397122eb..2188a049b7 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -103,7 +103,7 @@ void ToggleSWButtonClass::UpdatePosition() bool ToggleSWButtonClass::SwitchSidebar() { VocClass::PlayGlobal(RulesClass::Instance->GUIMainButtonSound, 0x2000, 1.0); - SidebarExt::Global()->SWSidebar_Enable = !SidebarExt::Global()->SWSidebar_Enable; + ScenarioExt::Global()->SWSidebar_Enable = !ScenarioExt::Global()->SWSidebar_Enable; const bool disabled = !SWSidebarClass::IsEnabled(); const auto& columns = SWSidebarClass::Instance.Columns; From 9d654f6c226047f49170abe736e73c4bc4ea68e0 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Wed, 19 Mar 2025 14:58:18 +0800 Subject: [PATCH 63/69] what can i say --- src/Commands/Commands.h | 2 +- src/Commands/ToggleSWSidebar.cpp | 2 +- src/Ext/SWType/SWHelpers.cpp | 4 +- src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp | 49 ++++++++++--------- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 30 ++++++------ src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 26 +++++----- .../Sidebar/SWSidebar/ToggleSWButtonClass.cpp | 14 +++--- src/Phobos.INI.cpp | 2 +- 8 files changed, 65 insertions(+), 64 deletions(-) diff --git a/src/Commands/Commands.h b/src/Commands/Commands.h index e19ad95ef6..ae3c89f503 100644 --- a/src/Commands/Commands.h +++ b/src/Commands/Commands.h @@ -10,7 +10,7 @@ template T* MakeCommand() { T* command = GameCreate(); - CommandClass::Array->AddItem(command); + CommandClass::Array.AddItem(command); return command; }; diff --git a/src/Commands/ToggleSWSidebar.cpp b/src/Commands/ToggleSWSidebar.cpp index f924e6d854..49369828c7 100644 --- a/src/Commands/ToggleSWSidebar.cpp +++ b/src/Commands/ToggleSWSidebar.cpp @@ -29,5 +29,5 @@ void ToggleSWSidebar::Execute(WWKey eInput) const ToggleSWButtonClass::SwitchSidebar(); if (SWSidebarClass::Instance.CurrentColumn) - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); } diff --git a/src/Ext/SWType/SWHelpers.cpp b/src/Ext/SWType/SWHelpers.cpp index f708f29ae5..82a85faf71 100644 --- a/src/Ext/SWType/SWHelpers.cpp +++ b/src/Ext/SWType/SWHelpers.cpp @@ -291,7 +291,7 @@ void SWTypeExt::ExtData::PrintMessage(const CSFText& message, HouseClass* pFirer // user defined color color = this->Message_ColorScheme; } - else if (const auto pCurrent = HouseClass::CurrentPlayer()) + else if (const auto pCurrent = HouseClass::CurrentPlayer) { // default way: the current player's color color = pCurrent->ColorSchemeIndex; @@ -299,5 +299,5 @@ void SWTypeExt::ExtData::PrintMessage(const CSFText& message, HouseClass* pFirer } // print the message - MessageListClass::Instance->PrintMessage(message, RulesClass::Instance->MessageDelay, color); + MessageListClass::Instance.PrintMessage(message, RulesClass::Instance->MessageDelay, color); } diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp index 01b1d02c58..9ab43f48a0 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.cpp @@ -23,19 +23,19 @@ bool SWButtonClass::Draw(bool forced) if (!forced) return false; - const auto pSurface = DSurface::Composite(); + const auto pSurface = DSurface::Composite; auto bounds = pSurface->GetRect(); Point2D location = { this->X, this->Y }; RectangleStruct destRect = { location.X, location.Y, this->Width, this->Height }; - const auto pCurrent = HouseClass::CurrentPlayer(); + const auto pCurrent = HouseClass::CurrentPlayer; const auto pSuper = pCurrent->Supers[this->SuperIndex]; const auto pSWExt = SWTypeExt::ExtMap.Find(pSuper->Type); // support for pcx cameos if (const auto pPCXCameo = pSWExt->SidebarPCX.GetSurface()) { - PCX::Instance->BlitToSurface(&destRect, pSurface, pPCXCameo); + PCX::Instance.BlitToSurface(&destRect, pSurface, pPCXCameo); } else if (const auto pCameo = pSuper->Type->SidebarImage) // old shp cameos, fixed palette { @@ -46,10 +46,10 @@ bool SWButtonClass::Draw(bool forced) if (!_stricmp(pCameoRef->Filename, GameStrings::XXICON_SHP) && strstr(pFilename, ".pcx")) { - PCX::Instance->LoadFile(pFilename); + PCX::Instance.LoadFile(pFilename); - if (const auto CameoPCX = PCX::Instance->GetSurface(pFilename)) - PCX::Instance->BlitToSurface(&destRect, pSurface, CameoPCX); + if (const auto CameoPCX = PCX::Instance.GetSurface(pFilename)) + PCX::Instance.BlitToSurface(&destRect, pSurface, CameoPCX); } else { @@ -61,7 +61,7 @@ bool SWButtonClass::Draw(bool forced) if (this->IsHovering) { RectangleStruct cameoRect = { location.X, location.Y, this->Width, this->Height }; - const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); + const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor); pSurface->DrawRect(&cameoRect, tooltipColor); } @@ -83,10 +83,11 @@ bool SWButtonClass::Draw(bool forced) if (buttonId < 10) { unsigned short hotkey = 0; - for (int i = 0; i < CommandClass::Hotkeys->IndexCount; i++) + + for (int idx = 0; idx < CommandClass::Hotkeys.IndexCount; idx++) { - if (CommandClass::Hotkeys->IndexTable[i].Data == SWSidebarClass::Commands[buttonId]) - hotkey = CommandClass::Hotkeys->IndexTable[i].ID; + if (CommandClass::Hotkeys.IndexTable[idx].Data == SWSidebarClass::Commands[buttonId]) + hotkey = CommandClass::Hotkeys.IndexTable[idx].ID; } Point2D textLoc = { location.X + this->Width / 2, location.Y }; @@ -151,11 +152,11 @@ bool SWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) return false; if (flags & GadgetFlag::RightPress) - DisplayClass::Instance->CurrentSWTypeIndex = -1; + DisplayClass::Instance.CurrentSWTypeIndex = -1; if (flags & GadgetFlag::LeftPress) { - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); VocClass::PlayGlobal(RulesClass::Instance->GUIBuildSound, 0x2000, 1.0); this->LaunchSuper(); } @@ -172,7 +173,7 @@ void SWButtonClass::SetColumn(int column) bool SWButtonClass::LaunchSuper() const { - const auto pCurrent = HouseClass::CurrentPlayer(); + const auto pCurrent = HouseClass::CurrentPlayer; const auto pSuper = pCurrent->Supers[this->SuperIndex]; const auto pSWExt = SWTypeExt::ExtMap.Find(pSuper->Type); const bool manual = !pSWExt->SW_ManualFire && pSWExt->SW_AutoFire; @@ -202,17 +203,17 @@ bool SWButtonClass::LaunchSuper() const } else { - DisplayClass::Instance->CurrentBuilding = nullptr; - DisplayClass::Instance->CurrentBuildingType = nullptr; - DisplayClass::Instance->CurrentBuildingOwnerArrayIndex = -1; - DisplayClass::Instance->SetActiveFoundation(nullptr); - MapClass::Instance->SetRepairMode(0); - MapClass::Instance->SetSellMode(0); - DisplayClass::Instance->PowerToggleMode = false; - DisplayClass::Instance->PlanningMode = false; - DisplayClass::Instance->PlaceBeaconMode = false; - DisplayClass::Instance->CurrentSWTypeIndex = swIndex; - MapClass::Instance->UnselectAll(); + DisplayClass::Instance.CurrentBuilding = nullptr; + DisplayClass::Instance.CurrentBuildingType = nullptr; + DisplayClass::Instance.CurrentBuildingOwnerArrayIndex = -1; + DisplayClass::Instance.SetActiveFoundation(nullptr); + MapClass::Instance.SetRepairMode(0); + MapClass::Instance.SetSellMode(0); + DisplayClass::Instance.PowerToggleMode = false; + DisplayClass::Instance.PlanningMode = false; + DisplayClass::Instance.PlaceBeaconMode = false; + DisplayClass::Instance.CurrentSWTypeIndex = swIndex; + MapClass::Instance.UnselectAll(); VoxClass::PlayIndex(pSWExt->EVA_SelectTarget); } diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index e3aab4d3c3..162d242d28 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -17,7 +17,7 @@ bool SWColumnClass::Draw(bool forced) if (!SWSidebarClass::IsEnabled()) return false; - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex]); const int cameoWidth = 60, cameoHeight = 48; const int cameoBackgroundWidth = Phobos::UI::SuperWeaponSidebar_Interval + cameoWidth; @@ -28,7 +28,7 @@ bool SWColumnClass::Draw(bool forced) for (const auto button : this->Buttons) { RectangleStruct drawRect { this->X, button->Y - cameoHarfInterval, cameoBackgroundWidth, Phobos::UI::SuperWeaponSidebar_CameoHeight }; - PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pCenterPCX); + PCX::Instance.BlitToSurface(&drawRect, DSurface::Composite, pCenterPCX); } } @@ -36,14 +36,14 @@ bool SWColumnClass::Draw(bool forced) { const int height = pTopPCX->GetHeight(); RectangleStruct drawRect { this->X, this->Y, cameoBackgroundWidth, height }; - PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pTopPCX); + PCX::Instance.BlitToSurface(&drawRect, DSurface::Composite, pTopPCX); } if (const auto pBottomPCX = pSideExt->SuperWeaponSidebar_BottomPCX.GetSurface()) { const int height = pBottomPCX->GetHeight(); RectangleStruct drawRect { this->X, this->Y + this->Height - height, cameoBackgroundWidth, height }; - PCX::Instance->BlitToSurface(&drawRect, DSurface::Composite, pBottomPCX); + PCX::Instance.BlitToSurface(&drawRect, DSurface::Composite, pBottomPCX); } for (const auto button : this->Buttons) @@ -58,13 +58,13 @@ void SWColumnClass::OnMouseEnter() return; SWSidebarClass::Instance.CurrentColumn = this; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); } void SWColumnClass::OnMouseLeave() { SWSidebarClass::Instance.CurrentColumn = nullptr; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); } bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModifier modifier) @@ -74,7 +74,7 @@ bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModi bool SWColumnClass::AddButton(int superIdx) { - const auto pSWType = SuperWeaponTypeClass::Array->GetItemOrDefault(superIdx); + const auto pSWType = SuperWeaponTypeClass::Array.GetItemOrDefault(superIdx); if (!pSWType) return false; @@ -97,8 +97,8 @@ bool SWColumnClass::AddButton(int superIdx) { auto Compare = [ownerBits](const int left, const int right) { - const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(left)); - const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(right)); + const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array.GetItemOrDefault(left)); + const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array.GetItemOrDefault(right)); if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) return false; @@ -116,8 +116,8 @@ bool SWColumnClass::AddButton(int superIdx) this->RemoveButton(backIdx); sidebar.DisableEntry = true; - SidebarClass::Instance->AddCameo(AbstractType::Special, backIdx); - SidebarClass::Instance->RepaintSidebar(SidebarClass::GetObjectTabIdx(AbstractType::Super, backIdx, false)); + SidebarClass::Instance.AddCameo(AbstractType::Special, backIdx); + SidebarClass::Instance.RepaintSidebar(SidebarClass::GetObjectTabIdx(AbstractType::Super, backIdx, false)); sidebar.DisableEntry = false; } @@ -128,7 +128,7 @@ bool SWColumnClass::AddButton(int superIdx) return false; button->Zap(); - GScreenClass::Instance->AddButton(button); + GScreenClass::Instance.AddButton(button); SWSidebarClass::Instance.SortButtons(); if (const auto toggleButton = SWSidebarClass::Instance.ToggleButton) @@ -154,7 +154,7 @@ bool SWColumnClass::RemoveButton(int superIdx) if (it_Idx != indices.cend()) indices.erase(it_Idx); - GScreenClass::Instance->RemoveButton(*it); + GScreenClass::Instance.RemoveButton(*it); buttons.erase(it); return true; } @@ -166,7 +166,7 @@ void SWColumnClass::ClearButtons(bool remove) if (remove) { for (const auto button : buttons) - GScreenClass::Instance->RemoveButton(button); + GScreenClass::Instance.RemoveButton(button); } buttons.clear(); @@ -174,7 +174,7 @@ void SWColumnClass::ClearButtons(bool remove) void SWColumnClass::SetHeight(int height) { - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex]); this->Height = height; diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 339371fe25..9505fdbe1a 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -24,13 +24,13 @@ bool SWSidebarClass::AddColumn() return false; const int cameoWidth = 60; - const auto column = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count + 1 + static_cast(columns.size()), maxButtons, 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); + const auto column = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array.Count + 1 + static_cast(columns.size()), maxButtons, 0, 0, cameoWidth + Phobos::UI::SuperWeaponSidebar_Interval, Phobos::UI::SuperWeaponSidebar_CameoHeight); if (!column) return false; column->Zap(); - GScreenClass::Instance->AddButton(column); + GScreenClass::Instance.AddButton(column); return true; } @@ -44,7 +44,7 @@ bool SWSidebarClass::RemoveColumn() if (const auto backColumn = columns.back()) { AnnounceInvalidPointer(SWSidebarClass::Instance.CurrentColumn, backColumn); - GScreenClass::Instance->RemoveButton(backColumn); + GScreenClass::Instance.RemoveButton(backColumn); columns.erase(columns.end() - 1); return true; @@ -61,7 +61,7 @@ void SWSidebarClass::InitClear() if (const auto toggleButton = this->ToggleButton) { this->ToggleButton = nullptr; - GScreenClass::Instance->RemoveButton(toggleButton); + GScreenClass::Instance.RemoveButton(toggleButton); } auto& columns = this->Columns; @@ -69,7 +69,7 @@ void SWSidebarClass::InitClear() for (const auto column : columns) { column->ClearButtons(); - GScreenClass::Instance->RemoveButton(column); + GScreenClass::Instance.RemoveButton(column); } columns.clear(); @@ -80,7 +80,7 @@ void SWSidebarClass::InitIO() if (!Phobos::UI::SuperWeaponSidebar || Unsorted::ArmageddonMode) return; - if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])) + if (const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex])) { const auto pOnPCX = pSideExt->SuperWeaponSidebar_OnPCX.GetSurface(); const auto pOffPCX = pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); @@ -107,10 +107,10 @@ void SWSidebarClass::InitIO() if (width > 0 && height > 0) { - if (const auto toggleButton = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array->Count, 0, 0, width, height)) + if (const auto toggleButton = GameCreate(SWButtonClass::StartID + SuperWeaponTypeClass::Array.Count, 0, 0, width, height)) { toggleButton->Zap(); - GScreenClass::Instance->AddButton(toggleButton); + GScreenClass::Instance.AddButton(toggleButton); SWSidebarClass::Instance.ToggleButton = toggleButton; toggleButton->UpdatePosition(); } @@ -169,8 +169,8 @@ void SWSidebarClass::SortButtons() std::stable_sort(vec_Buttons.begin(), vec_Buttons.end(), [ownerBits](SWButtonClass* const a, SWButtonClass* const b) { - const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(a->SuperIndex)); - const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array->GetItemOrDefault(b->SuperIndex)); + const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array.GetItemOrDefault(a->SuperIndex)); + const auto pExtB = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array.GetItemOrDefault(b->SuperIndex)); if (pExtB && (pExtB->SuperWeaponSidebar_PriorityHouses & ownerBits) && (!pExtA || !(pExtA->SuperWeaponSidebar_PriorityHouses & ownerBits))) return false; @@ -185,7 +185,7 @@ void SWSidebarClass::SortButtons() const int cameoWidth = 60, cameoHeight = 48; const int maximum = Phobos::UI::SuperWeaponSidebar_Max; const int cameoHarfInterval = (Phobos::UI::SuperWeaponSidebar_CameoHeight - cameoHeight) / 2; - int location_Y = (DSurface::ViewBounds().Height - std::min(buttonCount, maximum) * Phobos::UI::SuperWeaponSidebar_CameoHeight) / 2; + int location_Y = (DSurface::ViewBounds.Height - std::min(buttonCount, maximum) * Phobos::UI::SuperWeaponSidebar_CameoHeight) / 2; Point2D location = { Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y + cameoHarfInterval }; int rowIdx = 0, columnIdx = 0; @@ -195,7 +195,7 @@ void SWSidebarClass::SortButtons() if (rowIdx == 0) { - const auto pTopPCX = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex])->SuperWeaponSidebar_TopPCX.GetSurface(); + const auto pTopPCX = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex])->SuperWeaponSidebar_TopPCX.GetSurface(); column->SetPosition(location.X - Phobos::UI::SuperWeaponSidebar_LeftOffset, location_Y - (pTopPCX ? pTopPCX->GetHeight() : 0)); } @@ -311,7 +311,7 @@ DEFINE_HOOK(0x6AA790, StripClass_RecheckCameo_RemoveCameo, 0x6) enum { ShouldRemove = 0x6AA7B6, ShouldNotRemove = 0x6AAA68 }; GET(BuildType*, pItem, ESI); - const auto pCurrent = HouseClass::CurrentPlayer(); + const auto pCurrent = HouseClass::CurrentPlayer; const auto& supers = pCurrent->Supers; if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) diff --git a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp index 2188a049b7..92204e1c1f 100644 --- a/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/ToggleSWButtonClass.cpp @@ -18,18 +18,18 @@ bool ToggleSWButtonClass::Draw(bool forced) if (columns.empty()) return false; - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex]); const auto pTogglePCX = SWSidebarClass::IsEnabled() ? pSideExt->SuperWeaponSidebar_OnPCX.GetSurface() : pSideExt->SuperWeaponSidebar_OffPCX.GetSurface(); if (!pTogglePCX) return false; RectangleStruct destRect { this->X, this->Y, this->Width, this->Height }; - PCX::Instance->BlitToSurface(&destRect, DSurface::Composite, pTogglePCX); + PCX::Instance.BlitToSurface(&destRect, DSurface::Composite, pTogglePCX); if (this->IsHovering) { - const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor()); + const COLORREF tooltipColor = Drawing::RGB_To_Int(Drawing::TooltipColor); DSurface::Composite->DrawRect(&destRect, tooltipColor); } @@ -44,14 +44,14 @@ void ToggleSWButtonClass::OnMouseEnter() return; this->IsHovering = true; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); } void ToggleSWButtonClass::OnMouseLeave() { this->IsHovering = false; this->IsPressed = false; - MouseClass::Instance->UpdateCursor(MouseCursorType::Default, false); + MouseClass::Instance.UpdateCursor(MouseCursorType::Default, false); } bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modifier) @@ -61,7 +61,7 @@ bool ToggleSWButtonClass::Action(GadgetFlag flags, DWORD* pKey, KeyModifier modi if (columns.empty()) return false; - const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array->Items[ScenarioClass::Instance->PlayerSideIndex]); + const auto pSideExt = SideExt::ExtMap.Find(SideClass::Array.Items[ScenarioClass::Instance->PlayerSideIndex]); if (SWSidebarClass::IsEnabled() ? !pSideExt->SuperWeaponSidebar_OnPCX.GetSurface() : !pSideExt->SuperWeaponSidebar_OffPCX.GetSurface()) return false; @@ -94,7 +94,7 @@ void ToggleSWButtonClass::UpdatePosition() else { position.X = 0; - position.Y = (GameOptionsClass::Instance->ScreenHeight - this->Height) / 2; + position.Y = (GameOptionsClass::Instance.ScreenHeight - this->Height) / 2; } this->SetPosition(position.X, position.Y); diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 38389ba4df..83316f2823 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -191,7 +191,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) ini_uimd.ReadInteger(SIDEBAR_SECTION, "SuperWeaponSidebar.Max", Phobos::UI::SuperWeaponSidebar_Max); const int reserveHeight = 96; - const int screenHeight = GameOptionsClass::Instance->ScreenHeight - reserveHeight; + const int screenHeight = GameOptionsClass::Instance.ScreenHeight - reserveHeight; if (Phobos::UI::SuperWeaponSidebar_Max > 0) Phobos::UI::SuperWeaponSidebar_Max = std::min(Phobos::UI::SuperWeaponSidebar_Max, screenHeight / Phobos::UI::SuperWeaponSidebar_CameoHeight); From c1851d2f1470f8c460222b80106141dbde0f3c77 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 27 May 2025 01:02:05 +0800 Subject: [PATCH 64/69] Fit with `AnchoredToolTips` --- src/Ext/Sidebar/SWSidebar/SWButtonClass.h | 2 - src/Misc/PhobosToolTip.cpp | 70 +++++++++++++++-------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h index 6ca068ed86..3defc7e7ff 100644 --- a/src/Ext/Sidebar/SWSidebar/SWButtonClass.h +++ b/src/Ext/Sidebar/SWSidebar/SWButtonClass.h @@ -20,8 +20,6 @@ class SWButtonClass : public ControlClass public: static constexpr int StartID = 2200; - static constexpr int ToolTip_Align_Y = 27; - bool IsHovering { false }; int ColumnIndex { -1 }; int SuperIndex { -1 }; diff --git a/src/Misc/PhobosToolTip.cpp b/src/Misc/PhobosToolTip.cpp index 98ca3ae77e..6321cacf6e 100644 --- a/src/Misc/PhobosToolTip.cpp +++ b/src/Misc/PhobosToolTip.cpp @@ -266,20 +266,6 @@ DEFINE_HOOK(0x4AE51E, DisplayClass_GetToolTip_HelpText, 0x6) return 0; } -DEFINE_HOOK(0x724B2E, ToolTipManager_SetX, 0x6) -{ - if (SWSidebarClass::IsEnabled()) - { - if (const auto button = SWSidebarClass::Instance.CurrentButton) - { - R->EDX(button->X + button->Width); - R->EAX(button->Y + SWButtonClass::ToolTip_Align_Y); - } - } - - return 0; -} - // TODO: reimplement CCToolTip::Draw2 completely DEFINE_HOOK(0x478EE1, CCToolTip_Draw2_SetBuffer, 0x6) @@ -332,7 +318,6 @@ DEFINE_HOOK(0x478EF8, CCToolTip_Draw2_SetMaxWidth, 0x5) R->EAX(Phobos::UI::MaxToolTipWidth); else R->EAX(DSurface::ViewBounds.Width); - } return 0; } @@ -389,16 +374,55 @@ DEFINE_HOOK(0x478FDC, CCToolTip_Draw2_FillRect, 0x5) if (isCameo && Phobos::UI::AnchoredToolTips && PhobosToolTip::Instance.IsEnabled() - && Phobos::Config::ToolTipDescriptions - // If inspecting a cameo from the super weapon sidebar, "AnchoredToolTips=true" shouldn't apply. - && !SWSidebarClass::Instance.CurrentButton) + && Phobos::Config::ToolTipDescriptions) + { + LEA_STACK(LTRBStruct*, pTextRect, STACK_OFFSET(0x44, -0x20)); + + if (const auto pButton = SWSidebarClass::Instance.CurrentButton) + { + // Being too far away may actually be bad + /* + const auto& columns = SWSidebarClass::Instance.Columns; + const int size = columns.size(); + const int y = pButton->Y + 3; + + auto pColumn = columns.back(); + if (columns.size() > 1 && y > (pColumn->Y + pColumn->Height)) + pColumn = columns[size - 2]; + + const int x = pColumn->X + pColumn->Width + 2; + */ + const auto pColumn = SWSidebarClass::Instance.Columns[pButton->ColumnIndex]; + const int x = pColumn->X + pColumn->Width + 2; + const int y = pButton->Y + 3; + pRect->X = x; + pTextRect->Right += (x - pTextRect->Left); + pTextRect->Left = x; + pRect->Y = y; + pTextRect->Bottom += (y - pTextRect->Top); + pTextRect->Top = y; + } + else + { + const int x = DSurface::SidebarBounds.X - pRect->Width - 2; + pRect->X = x; + pTextRect->Left = x; + pRect->Y -= 40; + pTextRect->Top -= 40; + } + } + else if (const auto pButton = SWSidebarClass::Instance.CurrentButton) { - LEA_STACK(LTRBStruct*, a2, STACK_OFFSET(0x44, -0x20)); - auto x = DSurface::SidebarBounds.X - pRect->Width - 2; + LEA_STACK(LTRBStruct*, pTextRect, STACK_OFFSET(0x44, -0x20)); + + const int x = pButton->X + pButton->Width; + const int y = pButton->Y + 43; pRect->X = x; - a2->Left = x; - pRect->Y -= 40; - a2->Top -= 40; + pTextRect->Right += (x - pTextRect->Left); + pTextRect->Left = x; + pRect->Y = y; + pTextRect->Bottom += (y - pTextRect->Top); + pTextRect->Top = y; } // Should we make some SideExt items as static to improve the effeciency? From 589fb5e1534333c9c61e2d17dfc4af128e5f70bb Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Tue, 27 May 2025 12:36:42 +0800 Subject: [PATCH 65/69] add switch if hotkeys is enabled --- docs/User-Interface.md | 3 +++ src/Commands/Commands.cpp | 25 ++++++++++++++----------- src/Phobos.INI.cpp | 2 ++ src/Phobos.h | 1 + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 8c3b9bc41a..90fc720f90 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -706,6 +706,9 @@ SuperWeaponSidebar.MaxColumns= ; integer In `rulesmd.ini` ```ini +[GlobalControls] +SuperWeaponSidebarKeysEnabled=false ; boolean + [AudioVisual] SuperWeaponSidebar.AllowByDefault=false ; boolean diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index 79a39b4db0..d45b7e53c1 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -22,18 +22,21 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); MakeCommand(); - MakeCommand(); - SWSidebarClass::Commands[0] = MakeCommand>(); - SWSidebarClass::Commands[1] = MakeCommand>(); - SWSidebarClass::Commands[2] = MakeCommand>(); - SWSidebarClass::Commands[3] = MakeCommand>(); - SWSidebarClass::Commands[4] = MakeCommand>(); - SWSidebarClass::Commands[5] = MakeCommand>(); - SWSidebarClass::Commands[6] = MakeCommand>(); - SWSidebarClass::Commands[7] = MakeCommand>(); - SWSidebarClass::Commands[8] = MakeCommand>(); - SWSidebarClass::Commands[9] = MakeCommand>(); + if (Phobos::Config::SuperWeaponSidebarCommands) + { + SWSidebarClass::Commands[0] = MakeCommand>(); + SWSidebarClass::Commands[1] = MakeCommand>(); + SWSidebarClass::Commands[2] = MakeCommand>(); + SWSidebarClass::Commands[3] = MakeCommand>(); + SWSidebarClass::Commands[4] = MakeCommand>(); + SWSidebarClass::Commands[5] = MakeCommand>(); + SWSidebarClass::Commands[6] = MakeCommand>(); + SWSidebarClass::Commands[7] = MakeCommand>(); + SWSidebarClass::Commands[8] = MakeCommand>(); + SWSidebarClass::Commands[9] = MakeCommand>(); + MakeCommand(); + } if (Phobos::Config::DevelopmentCommands) { diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 173c39d215..4a05a50bef 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -46,6 +46,7 @@ bool Phobos::Config::ToolTipDescriptions = true; bool Phobos::Config::ToolTipBlur = false; bool Phobos::Config::PrioritySelectionFiltering = true; bool Phobos::Config::DevelopmentCommands = true; +bool Phobos::Config::SuperWeaponSidebarCommands = false; bool Phobos::Config::ShowPlanningPath = false; bool Phobos::Config::ArtImageSwap = false; bool Phobos::Config::ShowPlacementPreview = false; @@ -259,6 +260,7 @@ DEFINE_HOOK(0x52D21F, InitRules_ThingsThatShouldntBeSerailized, 0x6) #ifndef DEBUG Phobos::Config::DevelopmentCommands = pINI_RULESMD->ReadBool("GlobalControls", "DebugKeysEnabled", Phobos::Config::DevelopmentCommands); #endif + Phobos::Config::SuperWeaponSidebarCommands = pINI_RULESMD->ReadBool("GlobalControls", "SuperWeaponSidebarKeysEnabled", Phobos::Config::SuperWeaponSidebarCommands); Phobos::Config::ShowPlanningPath = pINI_RULESMD->ReadBool("GlobalControls", "DebugPlanningPaths", Phobos::Config::ShowPlanningPath); return 0; diff --git a/src/Phobos.h b/src/Phobos.h index 9aee4b0519..cb1f81a950 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -80,6 +80,7 @@ class Phobos static bool ToolTipBlur; static bool PrioritySelectionFiltering; static bool DevelopmentCommands; + static bool SuperWeaponSidebarCommands; static bool ArtImageSwap; static bool ShowPlacementPreview; static bool EnableBuildingPlacementPreview; From 4f7d5acb68c73a075193edb3b0d3750af6bd6686 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 29 May 2025 09:04:30 +0800 Subject: [PATCH 66/69] optimize --- src/Ext/Sidebar/Body.cpp | 10 ++++-- src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp | 17 ++------- src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 36 +++++++++++++++----- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/Ext/Sidebar/Body.cpp b/src/Ext/Sidebar/Body.cpp index 6e2f82b692..a463cc63ca 100644 --- a/src/Ext/Sidebar/Body.cpp +++ b/src/Ext/Sidebar/Body.cpp @@ -37,8 +37,13 @@ bool __stdcall SidebarExt::AresTabCameo_RemoveCameo(BuildType* pItem) { const auto& supers = pCurrent->Supers; - if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) - return false; + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent) + { + if (SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) + ScenarioExt::Global()->SWSidebar_Indices.emplace_back(pItem->ItemIndex); + else + return false; + } } // The following sections have been modified @@ -46,6 +51,7 @@ bool __stdcall SidebarExt::AresTabCameo_RemoveCameo(BuildType* pItem) if (pItem->ItemType == AbstractType::BuildingType || pItem->ItemType == AbstractType::Building) { + __assume(pTechnoType != nullptr); buildCat = static_cast(pTechnoType)->BuildCat; auto& pDisplay = DisplayClass::Instance; pDisplay.SetActiveFoundation(nullptr); diff --git a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp index 162d242d28..50073f6dd3 100644 --- a/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWColumnClass.cpp @@ -74,27 +74,14 @@ bool SWColumnClass::Clicked(DWORD* pKey, GadgetFlag flags, int x, int y, KeyModi bool SWColumnClass::AddButton(int superIdx) { - const auto pSWType = SuperWeaponTypeClass::Array.GetItemOrDefault(superIdx); - - if (!pSWType) - return false; - - const auto pSWExt = SWTypeExt::ExtMap.Find(pSWType); - - if (!pSWExt->SW_ShowCameo || !Phobos::UI::SuperWeaponSidebar || !pSWExt->SuperWeaponSidebar_Allow.Get(RulesExt::Global()->SuperWeaponSidebar_AllowByDefault)) - return false; - - const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; - - if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) - return false; - auto& buttons = this->Buttons; const int buttonCount = static_cast(buttons.size()); auto& sidebar = SWSidebarClass::Instance; if (buttonCount >= this->MaxButtons && !SWSidebarClass::Instance.AddColumn()) { + const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; + auto Compare = [ownerBits](const int left, const int right) { const auto pExtA = SWTypeExt::ExtMap.Find(SuperWeaponTypeClass::Array.GetItemOrDefault(left)); diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index 9505fdbe1a..c58988fa54 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -123,7 +123,22 @@ void SWSidebarClass::InitIO() bool SWSidebarClass::AddButton(int superIdx) { - if (this->DisableEntry) + if (!Phobos::UI::SuperWeaponSidebar || this->DisableEntry) + return false; + + const auto pSWType = SuperWeaponTypeClass::Array.GetItemOrDefault(superIdx); + + if (!pSWType) + return false; + + const auto pSWExt = SWTypeExt::ExtMap.Find(pSWType); + + if (!pSWExt->SW_ShowCameo || !pSWExt->SuperWeaponSidebar_Allow.Get(RulesExt::Global()->SuperWeaponSidebar_AllowByDefault)) + return false; + + const unsigned int ownerBits = 1u << HouseClass::CurrentPlayer->Type->ArrayIndex; + + if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) return false; auto& columns = this->Columns; @@ -134,12 +149,7 @@ bool SWSidebarClass::AddButton(int superIdx) if (std::any_of(columns.begin(), columns.end(), [superIdx](SWColumnClass* column) { return std::any_of(column->Buttons.begin(), column->Buttons.end(), [superIdx](SWButtonClass* button) { return button->SuperIndex == superIdx; }); })) return true; - const bool success = columns.back()->AddButton(superIdx); - - if (success) - ScenarioExt::Global()->SWSidebar_Indices.emplace_back(superIdx); - - return success; + return columns.back()->AddButton(superIdx); } void SWSidebarClass::SortButtons() @@ -301,7 +311,10 @@ DEFINE_HOOK(0x6A6316, SidebarClass_AddCameo_SuperWeapon_SWSidebar, 0x6) GET_STACK(int, index, STACK_OFFSET(0x14, 0x8)); if (SWSidebarClass::Instance.AddButton(index)) + { + ScenarioExt::Global()->SWSidebar_Indices.emplace_back(index); return ReturnFalse; + } return 0; } @@ -314,8 +327,13 @@ DEFINE_HOOK(0x6AA790, StripClass_RecheckCameo_RemoveCameo, 0x6) const auto pCurrent = HouseClass::CurrentPlayer; const auto& supers = pCurrent->Supers; - if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent && !SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) - return ShouldNotRemove; + if (supers.ValidIndex(pItem->ItemIndex) && supers[pItem->ItemIndex]->IsPresent) + { + if (SWSidebarClass::Instance.AddButton(pItem->ItemIndex)) + ScenarioExt::Global()->SWSidebar_Indices.emplace_back(pItem->ItemIndex); + else + return ShouldNotRemove; + } return ShouldRemove; } From 47ea9185f5b0c9b65f05130b8fa33653812ed0a0 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 29 May 2025 09:36:51 +0800 Subject: [PATCH 67/69] significance --- docs/User-Interface.md | 9 +++++ src/Ext/SWType/Body.cpp | 2 ++ src/Ext/SWType/Body.h | 2 ++ src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp | 3 ++ src/Phobos.INI.cpp | 38 +++++++++++--------- src/Phobos.h | 1 + 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 90fc720f90..39e3b47bf7 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -690,6 +690,8 @@ ToolTipBlur=false ; boolean, whether the blur effect of tooltips will be enable - `SuperWeaponSidebar.CameoHeight` controls the distance from the top of the previous cameo to the top of the next cameo. That is, the space between the upper and lower cameos is (`SuperWeaponSidebar.CameoHeight` - cameo fixed height 48). This will not be less than 48. When you need to make a background, this is the height of the background. - `SuperWeaponSidebar.Max` controls the maximum number of cameos on the leftmost column, which also depends on the current game resolution. - `SuperWeaponSidebar.MaxColumns` controls that maximum count of columns. + - Only sw with `SuperWeaponSidebar.Significance` not lower than `SuperWeaponSidebar.RequiredSignificance` are allowed to be added to the sw sidebar. +- `SuperWeaponSidebarKeysEnabled` should be true that you can use hotkeys about superweapon sidebar. - You can also launch first 10 SW by hotkey in INTERFACE category. - For localization of hotkey, add `TXT_FIRE_TACTICAL_SW_XX`, `TXT_FIRE_TACTICAL_SW_XX_DESC`, `TXT_TOGGLE_SW_SIDEBAR` and `TXT_TOGGLE_SW_SIDEBAR_DESC` into your `.csf` file. @@ -723,6 +725,13 @@ SuperWeaponSidebar.BottomPCX= ; filename - including the .pcx extension SuperWeaponSidebar.Allow= ; boolean SuperWeaponSidebar.PriorityHouses= ; list of house types SuperWeaponSidebar.RequiredHouses= ; list of house types +SuperWeaponSidebar.Significance=0 ; integer +``` + +In `ra2md.ini` +```ini +[Phobos] +SuperWeaponSidebar.RequiredSignificance=0 ; integer ``` ## Miscellanous diff --git a/src/Ext/SWType/Body.cpp b/src/Ext/SWType/Body.cpp index b5a80fd4f2..a937ed5e6f 100644 --- a/src/Ext/SWType/Body.cpp +++ b/src/Ext/SWType/Body.cpp @@ -76,6 +76,7 @@ void SWTypeExt::ExtData::Serialize(T& Stm) .Process(this->SuperWeaponSidebar_Allow) .Process(this->SuperWeaponSidebar_PriorityHouses) .Process(this->SuperWeaponSidebar_RequiredHouses) + .Process(this->SuperWeaponSidebar_Significance) .Process(this->SidebarPal) .Process(this->SidebarPCX) .Process(this->UseWeeds) @@ -230,6 +231,7 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->SuperWeaponSidebar_Allow.Read(exINI, pSection, "SuperWeaponSidebar.Allow"); this->SuperWeaponSidebar_PriorityHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.PriorityHouses", this->SuperWeaponSidebar_PriorityHouses); this->SuperWeaponSidebar_RequiredHouses = pINI->ReadHouseTypesList(pSection, "SuperWeaponSidebar.RequiredHouses", this->SuperWeaponSidebar_RequiredHouses); + this->SuperWeaponSidebar_Significance.Read(exINI, pSection, "SuperWeaponSidebar.Significance"); this->SidebarPal.LoadFromINI(pINI, pSection, "SidebarPalette"); this->SidebarPCX.Read(pINI, pSection, "SidebarPCX"); diff --git a/src/Ext/SWType/Body.h b/src/Ext/SWType/Body.h index 87a85ce885..e4fd387560 100644 --- a/src/Ext/SWType/Body.h +++ b/src/Ext/SWType/Body.h @@ -83,6 +83,7 @@ class SWTypeExt Nullable SuperWeaponSidebar_Allow; DWORD SuperWeaponSidebar_PriorityHouses; DWORD SuperWeaponSidebar_RequiredHouses; + Valueable SuperWeaponSidebar_Significance; CustomPalette SidebarPal; PhobosPCXFile SidebarPCX; @@ -158,6 +159,7 @@ class SWTypeExt , SuperWeaponSidebar_Allow {} , SuperWeaponSidebar_PriorityHouses { 0u } , SuperWeaponSidebar_RequiredHouses { 0xFFFFFFFFu } + , SuperWeaponSidebar_Significance { 0 } , SidebarPal {} , SidebarPCX {} , UseWeeds { false } diff --git a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp index c58988fa54..b96e71b574 100644 --- a/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp +++ b/src/Ext/Sidebar/SWSidebar/SWSidebarClass.cpp @@ -141,6 +141,9 @@ bool SWSidebarClass::AddButton(int superIdx) if ((pSWExt->SuperWeaponSidebar_RequiredHouses & ownerBits) == 0) return false; + if (pSWExt->SuperWeaponSidebar_Significance < Phobos::Config::SuperWeaponSidebar_RequiredSignificance) + return false; + auto& columns = this->Columns; if (columns.empty() && !this->AddColumn()) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 4a05a50bef..2052d2c766 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -66,6 +66,7 @@ bool Phobos::Config::ShowWeedsCounter = false; bool Phobos::Config::HideLightFlashEffects = true; bool Phobos::Config::ShowFlashOnSelecting = false; bool Phobos::Config::UnitPowerDrain = false; +int Phobos::Config::SuperWeaponSidebar_RequiredSignificance = 0; bool Phobos::Misc::CustomGS = false; int Phobos::Misc::CustomGS_ChangeInterval[7] = { -1, -1, -1, -1, -1, -1, -1 }; @@ -74,24 +75,27 @@ int Phobos::Misc::CustomGS_DefaultDelay[7] = { 0, 1, 2, 3, 4, 5, 6 }; DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) { - Phobos::Config::ToolTipDescriptions = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ToolTipDescriptions", true); - Phobos::Config::ToolTipBlur = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ToolTipBlur", false); - Phobos::Config::PrioritySelectionFiltering = CCINIClass::INI_RA2MD.ReadBool("Phobos", "PrioritySelectionFiltering", true); - Phobos::Config::ShowPlacementPreview = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowPlacementPreview", true); - Phobos::Config::RealTimeTimers = CCINIClass::INI_RA2MD.ReadBool("Phobos", "RealTimeTimers", false); - Phobos::Config::RealTimeTimers_Adaptive = CCINIClass::INI_RA2MD.ReadBool("Phobos", "RealTimeTimers.Adaptive", false); - Phobos::Config::EnableSelectBox = CCINIClass::INI_RA2MD.ReadBool("Phobos", "EnableSelectBox", false); - Phobos::Config::DigitalDisplay_Enable = CCINIClass::INI_RA2MD.ReadBool("Phobos", "DigitalDisplay.Enable", false); - Phobos::Config::SaveGameOnScenarioStart = CCINIClass::INI_RA2MD.ReadBool("Phobos", "SaveGameOnScenarioStart", true); - Phobos::Config::ShowBriefing = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowBriefing", true); - Phobos::Config::ShowPowerDelta = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowPowerDelta", true); - Phobos::Config::ShowHarvesterCounter = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowHarvesterCounter", true); - Phobos::Config::ShowWeedsCounter = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowWeedsCounter", true); - Phobos::Config::HideLightFlashEffects = CCINIClass::INI_RA2MD.ReadBool("Phobos", "HideLightFlashEffects", false); - Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowFlashOnSelecting", false); + const auto phobos_Section = "Phobos"; + + Phobos::Config::ToolTipDescriptions = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ToolTipDescriptions", true); + Phobos::Config::ToolTipBlur = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ToolTipBlur", false); + Phobos::Config::PrioritySelectionFiltering = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "PrioritySelectionFiltering", true); + Phobos::Config::ShowPlacementPreview = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowPlacementPreview", true); + Phobos::Config::RealTimeTimers = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "RealTimeTimers", false); + Phobos::Config::RealTimeTimers_Adaptive = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "RealTimeTimers.Adaptive", false); + Phobos::Config::EnableSelectBox = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "EnableSelectBox", false); + Phobos::Config::DigitalDisplay_Enable = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "DigitalDisplay.Enable", false); + Phobos::Config::SaveGameOnScenarioStart = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "SaveGameOnScenarioStart", true); + Phobos::Config::ShowBriefing = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowBriefing", true); + Phobos::Config::ShowPowerDelta = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowPowerDelta", true); + Phobos::Config::ShowHarvesterCounter = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowHarvesterCounter", true); + Phobos::Config::ShowWeedsCounter = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowWeedsCounter", true); + Phobos::Config::HideLightFlashEffects = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "HideLightFlashEffects", false); + Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowFlashOnSelecting", false); + Phobos::Config::SuperWeaponSidebar_RequiredSignificance = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "SuperWeaponSidebar.RequiredSignificance", 0); // Custom game speeds, 6 - i so that GS6 is index 0, just like in the engine - Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger("Phobos", "CampaignDefaultGameSpeed", 4); + Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger(phobos_Section, "CampaignDefaultGameSpeed", 4); if (Phobos::Config::CampaignDefaultGameSpeed > 6 || Phobos::Config::CampaignDefaultGameSpeed < 0) { Phobos::Config::CampaignDefaultGameSpeed = 2; @@ -104,7 +108,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Patch::Apply_RAW(0x55D78D, { temp }); // when speed control is off. Doesn't need a hook. } - Phobos::Config::ShowDesignatorRange = CCINIClass::INI_RA2MD.ReadBool("Phobos", "ShowDesignatorRange", false); + Phobos::Config::ShowDesignatorRange = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowDesignatorRange", false); CCINIClass ini_uimd {}; ini_uimd.LoadFromFile(GameStrings::UIMD_INI); diff --git a/src/Phobos.h b/src/Phobos.h index cb1f81a950..3573722d64 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -101,6 +101,7 @@ class Phobos static bool HideLightFlashEffects; static bool ShowFlashOnSelecting; static bool UnitPowerDrain; + static int SuperWeaponSidebar_RequiredSignificance; }; class Misc From 14e59acfbd6ae2aff6aaec76257ae9a4ac3125b1 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Thu, 29 May 2025 20:27:35 +0800 Subject: [PATCH 68/69] change --- docs/User-Interface.md | 12 ------------ src/Phobos.INI.cpp | 40 ++++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 39e3b47bf7..4cd348e580 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -733,15 +733,3 @@ In `ra2md.ini` [Phobos] SuperWeaponSidebar.RequiredSignificance=0 ; integer ``` - -## Miscellanous - -### Skip saving game on starting a new campaign - -When starting a new campaign, the game automatically saves the game. Now you can decide whether you want that to happen or not. - -In `RA2MD.INI`: -```ini -[Phobos] -SaveGameOnScenarioStart=true ; boolean -``` diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 2052d2c766..552cc8f8f6 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -75,27 +75,27 @@ int Phobos::Misc::CustomGS_DefaultDelay[7] = { 0, 1, 2, 3, 4, 5, 6 }; DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) { - const auto phobos_Section = "Phobos"; - - Phobos::Config::ToolTipDescriptions = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ToolTipDescriptions", true); - Phobos::Config::ToolTipBlur = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ToolTipBlur", false); - Phobos::Config::PrioritySelectionFiltering = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "PrioritySelectionFiltering", true); - Phobos::Config::ShowPlacementPreview = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowPlacementPreview", true); - Phobos::Config::RealTimeTimers = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "RealTimeTimers", false); - Phobos::Config::RealTimeTimers_Adaptive = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "RealTimeTimers.Adaptive", false); - Phobos::Config::EnableSelectBox = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "EnableSelectBox", false); - Phobos::Config::DigitalDisplay_Enable = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "DigitalDisplay.Enable", false); - Phobos::Config::SaveGameOnScenarioStart = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "SaveGameOnScenarioStart", true); - Phobos::Config::ShowBriefing = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowBriefing", true); - Phobos::Config::ShowPowerDelta = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowPowerDelta", true); - Phobos::Config::ShowHarvesterCounter = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowHarvesterCounter", true); - Phobos::Config::ShowWeedsCounter = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowWeedsCounter", true); - Phobos::Config::HideLightFlashEffects = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "HideLightFlashEffects", false); - Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowFlashOnSelecting", false); - Phobos::Config::SuperWeaponSidebar_RequiredSignificance = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "SuperWeaponSidebar.RequiredSignificance", 0); + const auto phobosSection = "Phobos"; + + Phobos::Config::ToolTipDescriptions = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ToolTipDescriptions", true); + Phobos::Config::ToolTipBlur = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ToolTipBlur", false); + Phobos::Config::PrioritySelectionFiltering = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "PrioritySelectionFiltering", true); + Phobos::Config::ShowPlacementPreview = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowPlacementPreview", true); + Phobos::Config::RealTimeTimers = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "RealTimeTimers", false); + Phobos::Config::RealTimeTimers_Adaptive = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "RealTimeTimers.Adaptive", false); + Phobos::Config::EnableSelectBox = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "EnableSelectBox", false); + Phobos::Config::DigitalDisplay_Enable = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "DigitalDisplay.Enable", false); + Phobos::Config::SaveGameOnScenarioStart = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "SaveGameOnScenarioStart", true); + Phobos::Config::ShowBriefing = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowBriefing", true); + Phobos::Config::ShowPowerDelta = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowPowerDelta", true); + Phobos::Config::ShowHarvesterCounter = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowHarvesterCounter", true); + Phobos::Config::ShowWeedsCounter = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowWeedsCounter", true); + Phobos::Config::HideLightFlashEffects = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "HideLightFlashEffects", false); + Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowFlashOnSelecting", false); + Phobos::Config::SuperWeaponSidebar_RequiredSignificance = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "SuperWeaponSidebar.RequiredSignificance", 0); // Custom game speeds, 6 - i so that GS6 is index 0, just like in the engine - Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger(phobos_Section, "CampaignDefaultGameSpeed", 4); + Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "CampaignDefaultGameSpeed", 4); if (Phobos::Config::CampaignDefaultGameSpeed > 6 || Phobos::Config::CampaignDefaultGameSpeed < 0) { Phobos::Config::CampaignDefaultGameSpeed = 2; @@ -108,7 +108,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Patch::Apply_RAW(0x55D78D, { temp }); // when speed control is off. Doesn't need a hook. } - Phobos::Config::ShowDesignatorRange = CCINIClass::INI_RA2MD.ReadBool(phobos_Section, "ShowDesignatorRange", false); + Phobos::Config::ShowDesignatorRange = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowDesignatorRange", false); CCINIClass ini_uimd {}; ini_uimd.LoadFromFile(GameStrings::UIMD_INI); From 44451dc6856bcc6bac56984e19852018b6e8f55c Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 1 Jun 2025 00:18:32 +0800 Subject: [PATCH 69/69] Update Commands.cpp --- src/Commands/Commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index d45b7e53c1..8d9d2611a1 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -22,6 +22,7 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); MakeCommand(); + MakeCommand(); if (Phobos::Config::SuperWeaponSidebarCommands) { @@ -35,7 +36,6 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) SWSidebarClass::Commands[7] = MakeCommand>(); SWSidebarClass::Commands[8] = MakeCommand>(); SWSidebarClass::Commands[9] = MakeCommand>(); - MakeCommand(); } if (Phobos::Config::DevelopmentCommands)