From a77b7c6ceec2f00db1e3a56506b3eee704dfbb0c Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Thu, 11 Dec 2025 00:44:04 +0800 Subject: [PATCH 1/7] Damage Display Rewrite --- src/Commands/Commands.cpp | 2 +- src/Commands/DamageDisplay.cpp | 2 +- src/Ext/Bullet/Body.cpp | 2 +- src/Ext/Techno/Hooks.ReceiveDamage.cpp | 2 +- src/New/Entity/ShieldClass.cpp | 2 +- src/Phobos.INI.cpp | 2 ++ src/Phobos.cpp | 1 - src/Phobos.h | 2 +- src/Utilities/GeneralUtils.cpp | 18 ++++++++++++++++-- 9 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index 0e5ad329af..1b05786fd8 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -29,6 +29,7 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); MakeCommand(); + MakeCommand(); if (Phobos::Config::SuperWeaponSidebarCommands) { @@ -46,7 +47,6 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) if (Phobos::Config::DevelopmentCommands) { - MakeCommand(); MakeCommand(); MakeCommand(); MakeCommand(); diff --git a/src/Commands/DamageDisplay.cpp b/src/Commands/DamageDisplay.cpp index 33ae3548de..513bdc0dd8 100644 --- a/src/Commands/DamageDisplay.cpp +++ b/src/Commands/DamageDisplay.cpp @@ -25,5 +25,5 @@ const wchar_t* DamageDisplayCommandClass::GetUIDescription() const void DamageDisplayCommandClass::Execute(WWKey eInput) const { - Phobos::DisplayDamageNumbers = !Phobos::DisplayDamageNumbers; + Phobos::Config::DisplayDamageNumbers = !Phobos::Config::DisplayDamageNumbers; } diff --git a/src/Ext/Bullet/Body.cpp b/src/Ext/Bullet/Body.cpp index c5c7a3e989..810ed510c6 100644 --- a/src/Ext/Bullet/Body.cpp +++ b/src/Ext/Bullet/Body.cpp @@ -35,7 +35,7 @@ void BulletExt::ExtData::InterceptBullet(TechnoClass* pSource, BulletClass* pInt const int damage = static_cast(pInterceptor->Health * versus); this->CurrentStrength -= damage; - if (Phobos::DisplayDamageNumbers && damage != 0) + if (Phobos::Config::DisplayDamageNumbers && damage != 0) GeneralUtils::DisplayDamageNumberString(damage, DamageDisplayType::Intercept, pThis->GetRenderCoords(), this->DamageNumberOffset); if (this->CurrentStrength <= 0) diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index 9e57d97361..51ac329a1b 100644 --- a/src/Ext/Techno/Hooks.ReceiveDamage.cpp +++ b/src/Ext/Techno/Hooks.ReceiveDamage.cpp @@ -204,7 +204,7 @@ DEFINE_HOOK(0x702819, TechnoClass_ReceiveDamage_Decloak, 0xA) DEFINE_HOOK(0x701DFF, TechnoClass_ReceiveDamage_FlyingStrings, 0x7) { - if (!Phobos::DisplayDamageNumbers) + if (!Phobos::Config::DisplayDamageNumbers) return 0; GET(TechnoClass* const, pThis, ESI); diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 1d747b6f3f..8bac28c15b 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -227,7 +227,7 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) const int maxDmg = GeneralUtils::SafeMultiply(max, pWHExt->Shield_ReceivedDamage_MaxMultiplier); shieldDamage = Math::clamp(shieldDamage, minDmg, maxDmg); - if (Phobos::DisplayDamageNumbers && shieldDamage != 0) + if (Phobos::Config::DisplayDamageNumbers && shieldDamage != 0) GeneralUtils::DisplayDamageNumberString(shieldDamage, DamageDisplayType::Shield, pTechno->GetRenderCoords(), TechnoExt::ExtMap.Find(pTechno)->DamageNumberOffset); if (shieldDamage > 0) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 270d8e9770..1a7a8bd038 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -75,6 +75,7 @@ bool Phobos::Config::HideShakeEffects = true; bool Phobos::Config::ShowFlashOnSelecting = false; bool Phobos::Config::UnitPowerDrain = false; int Phobos::Config::SuperWeaponSidebar_RequiredSignificance = 0; +bool Phobos::Config::DisplayDamageNumbers = false; bool Phobos::Misc::CustomGS = false; int Phobos::Misc::CustomGS_ChangeInterval[7] = { -1, -1, -1, -1, -1, -1, -1 }; @@ -108,6 +109,7 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::Config::HideShakeEffects = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "HideShakeEffects", false); Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowFlashOnSelecting", false); Phobos::Config::SuperWeaponSidebar_RequiredSignificance = CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "SuperWeaponSidebar.RequiredSignificance", 0); + Phobos::Config::DisplayDamageNumbers = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "DisplayDamageNumbers", false); // Custom game speeds, 6 - i so that GS6 is index 0, just like in the engine Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "CampaignDefaultGameSpeed", 4); diff --git a/src/Phobos.cpp b/src/Phobos.cpp index c061b50170..ba24ccacac 100644 --- a/src/Phobos.cpp +++ b/src/Phobos.cpp @@ -21,7 +21,6 @@ wchar_t Phobos::wideBuffer[Phobos::readLength]; const char* Phobos::AppIconPath = nullptr; -bool Phobos::DisplayDamageNumbers = false; bool Phobos::IsLoadingSaveGame = false; bool Phobos::Optimizations::Applied = false; diff --git a/src/Phobos.h b/src/Phobos.h index e925be2e77..b821263dd3 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -30,7 +30,6 @@ class Phobos static const char* AppIconPath; static const wchar_t* VersionDescription; - static bool DisplayDamageNumbers; static bool IsLoadingSaveGame; static bool ShouldSave; static std::wstring CustomGameSaveDescription; @@ -111,6 +110,7 @@ class Phobos static bool ShowFlashOnSelecting; static bool UnitPowerDrain; static int SuperWeaponSidebar_RequiredSignificance; + static bool DisplayDamageNumbers; }; class Misc diff --git a/src/Utilities/GeneralUtils.cpp b/src/Utilities/GeneralUtils.cpp index 906e9c5e4f..4f9b85a59f 100644 --- a/src/Utilities/GeneralUtils.cpp +++ b/src/Utilities/GeneralUtils.cpp @@ -239,14 +239,28 @@ void GeneralUtils::DisplayDamageNumberString(int damage, DamageDisplayType type, const int maxOffset = Unsorted::CellWidthInPixels / 2; int width = 0, height = 0; wchar_t damageStr[0x20]; - swprintf_s(damageStr, L"%d", damage); + swprintf_s(damageStr, L"%c%d", damage > 0 ? L'-' : L'+', abs(damage)); BitFont::Instance->GetTextDimension(damageStr, &width, &height, 120); if (offset >= maxOffset || offset == INT32_MIN) offset = -maxOffset; - FlyingStrings::Add(damageStr, coords, color, Point2D { offset - (width / 2), 0 }); + Point2D basePos { offset - (width / 2), 0 }; + + FlyingStrings::Add( + damageStr, + coords, + color, + basePos + ); + + FlyingStrings::Add( + damageStr, + coords, + ColorStruct { 84, 84, 84 }, + Point2D { basePos.X + 1, basePos.Y + 1 } + ); offset = offset + width; } From 47138fa2818f196a01a8654c26cb91a65dd9d52c Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Thu, 11 Dec 2025 00:54:58 +0800 Subject: [PATCH 2/7] Update Explanation --- CREDITS.md | 4 +++- docs/Miscellanous.md | 4 ---- docs/User-Interface.md | 11 +++++++++++ docs/Whats-New.md | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 6a2035cd83..0c0846c155 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -651,7 +651,9 @@ This page lists all the individual contributions to the project by their author. - **solar-III (凤九歌)** - Target scanning delay customization (documentation) - Skip target scanning function calling for unarmed technos (documentation) -- **Flactine** - add target filtering options to attacheffect system +- **Flactine** + - Add target filtering options to attacheffect system + - Improve Damage Number Display Configuration and Readability - **tyuah8**: - Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix - Destroyed unit leaves sensors bugfix diff --git a/docs/Miscellanous.md b/docs/Miscellanous.md index 903e40d2bb..af3ad27ff2 100644 --- a/docs/Miscellanous.md +++ b/docs/Miscellanous.md @@ -12,10 +12,6 @@ This page describes every change in Phobos that wasn't categorized into a proper - Phobos writes additional information to the `SYNC#.txt` log files when a desynchronization occurs such as calls to random number generator functions, facing / target / destination changes etc. -### Display Damage Numbers - -- There's a [new hotkey](User-Interface.md#display-damage-numbers) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. Available only if `DebugKeysEnabled` under `[GlobalControls]` is set to true in `rulesmd.ini`. - ### Dump Object Info ![image](_static/images/objectinfo-01.png) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 28212091ca..45d753bc1f 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -152,6 +152,17 @@ The arrangement of static images on the plane is entirely up to you to draw free Of course, this is just the implementation method. To balance freedom with efficiency—that is, how to efficiently draw the patterns you need—you still need to independently explore a workflow that suits you. ```` +### Display Damage Numbers + +- There's a [new hotkey](User-Interface.md#display-damage-numbers) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. + - Whether the feature is enabled by default is determined by `DisplayDamageNumbers` setting in `RA2MD.INI`. + +In `RA2MD.INI`: +```ini +[Phobos] +DisplayDamageNumbers=false ; boolean +``` + ### Flashing Technos on selecting - Selecting technos, controlled by player, now may show a flash effect by setting `SelectionFlashDuration` parameter higher than 0. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 6ad7bee8f6..5b016750dc 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -466,6 +466,7 @@ New: - [Customize type selection for IFV](Fixed-or-Improved-Logics.md#customize-type-selection-for-ifv) (by NetsuNegi) - CellSpread in cylinder shape (by TaranDahl) - CellSpread damage check if victim is in air or on floor (by TaranDahl) +- Improve Damage Number Display Configuration and Readability (by Flactine) Vanilla fixes: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) From d25683b0d24054b64b1fe42b1386f595009f11b5 Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Thu, 11 Dec 2025 08:42:17 +0800 Subject: [PATCH 3/7] Edit FlyingStrings --- src/Commands/Commands.cpp | 6 +++++- src/Ext/Bullet/Body.cpp | 2 +- src/Ext/Techno/Hooks.ReceiveDamage.cpp | 2 +- src/Misc/FlyingStrings.cpp | 16 +++++++++------- src/New/Entity/ShieldClass.cpp | 2 +- src/Phobos.INI.cpp | 2 ++ src/Phobos.h | 1 + src/Utilities/GeneralUtils.cpp | 16 +--------------- 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/Commands/Commands.cpp b/src/Commands/Commands.cpp index 1b05786fd8..bd1630f91a 100644 --- a/src/Commands/Commands.cpp +++ b/src/Commands/Commands.cpp @@ -29,7 +29,6 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) MakeCommand(); MakeCommand(); MakeCommand(); - MakeCommand(); if (Phobos::Config::SuperWeaponSidebarCommands) { @@ -45,6 +44,11 @@ DEFINE_HOOK(0x533066, CommandClassCallback_Register, 0x6) SWSidebarClass::Commands[9] = MakeCommand>(); } + if (Phobos::Config::DamageNumbersCommands) + { + MakeCommand(); + } + if (Phobos::Config::DevelopmentCommands) { MakeCommand(); diff --git a/src/Ext/Bullet/Body.cpp b/src/Ext/Bullet/Body.cpp index 810ed510c6..9bd3ddcc24 100644 --- a/src/Ext/Bullet/Body.cpp +++ b/src/Ext/Bullet/Body.cpp @@ -35,7 +35,7 @@ void BulletExt::ExtData::InterceptBullet(TechnoClass* pSource, BulletClass* pInt const int damage = static_cast(pInterceptor->Health * versus); this->CurrentStrength -= damage; - if (Phobos::Config::DisplayDamageNumbers && damage != 0) + if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && damage != 0) GeneralUtils::DisplayDamageNumberString(damage, DamageDisplayType::Intercept, pThis->GetRenderCoords(), this->DamageNumberOffset); if (this->CurrentStrength <= 0) diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index 51ac329a1b..ae13f8427d 100644 --- a/src/Ext/Techno/Hooks.ReceiveDamage.cpp +++ b/src/Ext/Techno/Hooks.ReceiveDamage.cpp @@ -204,7 +204,7 @@ DEFINE_HOOK(0x702819, TechnoClass_ReceiveDamage_Decloak, 0xA) DEFINE_HOOK(0x701DFF, TechnoClass_ReceiveDamage_FlyingStrings, 0x7) { - if (!Phobos::Config::DisplayDamageNumbers) + if (!Phobos::Config::DamageNumbersCommands || !Phobos::Config::DisplayDamageNumbers) return 0; GET(TechnoClass* const, pThis, ESI); diff --git a/src/Misc/FlyingStrings.cpp b/src/Misc/FlyingStrings.cpp index 331c393b6f..3ff2ff449e 100644 --- a/src/Misc/FlyingStrings.cpp +++ b/src/Misc/FlyingStrings.cpp @@ -71,14 +71,16 @@ void FlyingStrings::UpdateAll() bound.Height -= 32; if (Unsorted::CurrentFrame > dataItem.CreationFrame + Duration - 70) - { point.Y -= (Unsorted::CurrentFrame - dataItem.CreationFrame); - DSurface::Temp->DrawText(dataItem.Text, &bound, &point, dataItem.Color, 0, TextPrintType::NoShadow); - } - else - { - DSurface::Temp->DrawText(dataItem.Text, &bound, &point, dataItem.Color, 0, TextPrintType::NoShadow); - } + + const COLORREF shadowColor = Drawing::RGB_To_Int(84, 84, 84); + + Point2D shadowPoint = point; + shadowPoint.X += 1; + shadowPoint.Y += 1; + + DSurface::Temp->DrawText(dataItem.Text, &bound, &shadowPoint, shadowColor, 0, TextPrintType::NoShadow); + DSurface::Temp->DrawText(dataItem.Text, &bound, &point, dataItem.Color, 0, TextPrintType::NoShadow); if (Unsorted::CurrentFrame > dataItem.CreationFrame + Duration || Unsorted::CurrentFrame < dataItem.CreationFrame) Data.erase(Data.begin() + i); diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 8bac28c15b..07e6b8d610 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -227,7 +227,7 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) const int maxDmg = GeneralUtils::SafeMultiply(max, pWHExt->Shield_ReceivedDamage_MaxMultiplier); shieldDamage = Math::clamp(shieldDamage, minDmg, maxDmg); - if (Phobos::Config::DisplayDamageNumbers && shieldDamage != 0) + if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && shieldDamage != 0) GeneralUtils::DisplayDamageNumberString(shieldDamage, DamageDisplayType::Shield, pTechno->GetRenderCoords(), TechnoExt::ExtMap.Find(pTechno)->DamageNumberOffset); if (shieldDamage > 0) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 1a7a8bd038..616fd5167c 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -47,6 +47,7 @@ bool Phobos::Config::ToolTipDescriptions = true; bool Phobos::Config::ToolTipBlur = false; bool Phobos::Config::PrioritySelectionFiltering = true; bool Phobos::Config::DevelopmentCommands = true; +bool Phobos::Config::DamageNumbersCommands = false; bool Phobos::Config::SuperWeaponSidebarCommands = false; bool Phobos::Config::ShowPlanningPath = false; bool Phobos::Config::ArtImageSwap = false; @@ -283,6 +284,7 @@ DEFINE_HOOK(0x52D21F, InitRules_ThingsThatShouldntBeSerailized, 0x6) Phobos::Config::SaveVariablesOnScenarioEnd = pINI_RULESMD->ReadBool(GameStrings::General, "SaveVariablesOnScenarioEnd", false); #ifndef DEBUG Phobos::Config::DevelopmentCommands = pINI_RULESMD->ReadBool("GlobalControls", "DebugKeysEnabled", Phobos::Config::DevelopmentCommands); + Phobos::Config::DamageNumbersCommands = pINI_RULESMD->ReadBool("GlobalControls", "DamageNumbersEnabled", Phobos::Config::DamageNumbersCommands); #endif Phobos::Config::SuperWeaponSidebarCommands = pINI_RULESMD->ReadBool("GlobalControls", "SuperWeaponSidebarKeysEnabled", Phobos::Config::SuperWeaponSidebarCommands); Phobos::Config::ShowPlanningPath = pINI_RULESMD->ReadBool("GlobalControls", "DebugPlanningPaths", Phobos::Config::ShowPlanningPath); diff --git a/src/Phobos.h b/src/Phobos.h index b821263dd3..321ef3b1b2 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -81,6 +81,7 @@ class Phobos static bool ToolTipBlur; static bool PrioritySelectionFiltering; static bool DevelopmentCommands; + static bool DamageNumbersCommands; static bool SuperWeaponSidebarCommands; static bool ArtImageSwap; static bool ShowPlacementPreview; diff --git a/src/Utilities/GeneralUtils.cpp b/src/Utilities/GeneralUtils.cpp index 4f9b85a59f..e303236a4b 100644 --- a/src/Utilities/GeneralUtils.cpp +++ b/src/Utilities/GeneralUtils.cpp @@ -246,21 +246,7 @@ void GeneralUtils::DisplayDamageNumberString(int damage, DamageDisplayType type, if (offset >= maxOffset || offset == INT32_MIN) offset = -maxOffset; - Point2D basePos { offset - (width / 2), 0 }; - - FlyingStrings::Add( - damageStr, - coords, - color, - basePos - ); - - FlyingStrings::Add( - damageStr, - coords, - ColorStruct { 84, 84, 84 }, - Point2D { basePos.X + 1, basePos.Y + 1 } - ); + FlyingStrings::Add(damageStr, coords, color, Point2D { offset - (width / 2), 0 }); offset = offset + width; } From 28f23bc140d2f5e89a1931ae00fe973124156e14 Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Thu, 11 Dec 2025 09:18:11 +0800 Subject: [PATCH 4/7] Update User-Interface.md --- docs/User-Interface.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 45d753bc1f..45a37acded 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -155,7 +155,11 @@ Of course, this is just the implementation method. To balance freedom with effic ### Display Damage Numbers - There's a [new hotkey](User-Interface.md#display-damage-numbers) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. - - Whether the feature is enabled by default is determined by `DisplayDamageNumbers` setting in `RA2MD.INI`. + - The feature is **available only when** `DamageNumbersEnabled` under `[GlobalControls]` in `rulesmd.ini` is set to `true`. If this setting is `false`, the feature is completely disabled and cannot be used. + - The initial state of the feature (enabled or disabled when entering a game) is controlled by the `DisplayDamageNumbers` setting in `RA2MD.INI`. + - If set to `yes`, the feature starts enabled. + - If set to `no`, the feature starts disabled, but the player can still toggle it manually using the hotkey. + - Regardless of the default state, the hotkey always allows enabling or disabling the feature during gameplay. In `RA2MD.INI`: ```ini From 9bee9bb0a805815a212e50de7a7487164705c246 Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Fri, 12 Dec 2025 10:15:12 +0800 Subject: [PATCH 5/7] HiddenDamageNumbers for WarheadTypes --- docs/User-Interface.md | 7 +++++++ src/Ext/Bullet/Body.cpp | 4 +++- src/Ext/Techno/Hooks.ReceiveDamage.cpp | 4 ++++ src/Ext/WarheadType/Body.cpp | 3 +++ src/Ext/WarheadType/Body.h | 4 ++++ src/New/Entity/ShieldClass.cpp | 4 +++- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 45a37acded..33d92f24e4 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -160,6 +160,7 @@ Of course, this is just the implementation method. To balance freedom with effic - If set to `yes`, the feature starts enabled. - If set to `no`, the feature starts disabled, but the player can still toggle it manually using the hotkey. - Regardless of the default state, the hotkey always allows enabling or disabling the feature during gameplay. + - Individual warheads can suppress damage number display by setting `HiddenDamageNumbers`. In `RA2MD.INI`: ```ini @@ -167,6 +168,12 @@ In `RA2MD.INI`: DisplayDamageNumbers=false ; boolean ``` +In `rulesmd.ini`: +```ini +[SOMEWARHEAD] +HiddenDamageNumbers=false ; boolean +``` + ### Flashing Technos on selecting - Selecting technos, controlled by player, now may show a flash effect by setting `SelectionFlashDuration` parameter higher than 0. diff --git a/src/Ext/Bullet/Body.cpp b/src/Ext/Bullet/Body.cpp index 9bd3ddcc24..d5e3cd3631 100644 --- a/src/Ext/Bullet/Body.cpp +++ b/src/Ext/Bullet/Body.cpp @@ -35,7 +35,9 @@ void BulletExt::ExtData::InterceptBullet(TechnoClass* pSource, BulletClass* pInt const int damage = static_cast(pInterceptor->Health * versus); this->CurrentStrength -= damage; - if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && damage != 0) + const bool HiddenNumbers = WarheadTypeExt::ExtMap.Find(pThis->WH)->HiddenDamageNumbers; + + if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && !HiddenNumbers && damage != 0) GeneralUtils::DisplayDamageNumberString(damage, DamageDisplayType::Intercept, pThis->GetRenderCoords(), this->DamageNumberOffset); if (this->CurrentStrength <= 0) diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index ae13f8427d..e5d22a598c 100644 --- a/src/Ext/Techno/Hooks.ReceiveDamage.cpp +++ b/src/Ext/Techno/Hooks.ReceiveDamage.cpp @@ -209,6 +209,10 @@ DEFINE_HOOK(0x701DFF, TechnoClass_ReceiveDamage_FlyingStrings, 0x7) GET(TechnoClass* const, pThis, ESI); GET(int* const, pDamage, EBX); + GET_STACK(WarheadTypeClass*, pWarhead, STACK_OFFSET(0xC4, 0xC)); + + if (WarheadTypeExt::ExtMap.Find(pWarhead)->HiddenDamageNumbers) + return 0; if (*pDamage) GeneralUtils::DisplayDamageNumberString(*pDamage, DamageDisplayType::Regular, pThis->GetRenderCoords(), TechnoExt::ExtMap.Find(pThis)->DamageNumberOffset); diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 1dc39c2a42..951bd902b9 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -272,6 +272,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->CombatAlert_Suppress.Read(exINI, pSection, "CombatAlert.Suppress"); this->CanKill.Read(exINI, pSection, "CanKill"); + this->HiddenDamageNumbers.Read(exINI, pSection, "HiddenDamageNumbers"); this->KillWeapon.Read(exINI, pSection, "KillWeapon"); this->KillWeapon_OnFirer.Read(exINI, pSection, "KillWeapon.OnFirer"); @@ -586,6 +587,8 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->CanKill) + .Process(this->HiddenDamageNumbers) + .Process(this->ReverseEngineer) .Process(this->UnlimboDetonate) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index f2dc250213..ce954000d5 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -201,6 +201,8 @@ class WarheadTypeExt Valueable CanKill; + Valueable HiddenDamageNumbers; + Valueable UnlimboDetonate; Valueable UnlimboDetonate_ForceLocation; Valueable UnlimboDetonate_KeepTarget; @@ -427,6 +429,8 @@ class WarheadTypeExt , CanKill { true } + , HiddenDamageNumbers { false } + , KillWeapon {} , KillWeapon_OnFirer {} , KillWeapon_AffectsHouses { AffectedHouse::All } diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 07e6b8d610..6fa776c3b1 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -227,7 +227,9 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) const int maxDmg = GeneralUtils::SafeMultiply(max, pWHExt->Shield_ReceivedDamage_MaxMultiplier); shieldDamage = Math::clamp(shieldDamage, minDmg, maxDmg); - if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && shieldDamage != 0) + const bool HiddenNumbers = pWHExt->HiddenDamageNumbers; + + if (Phobos::Config::DamageNumbersCommands && Phobos::Config::DisplayDamageNumbers && !HiddenNumbers && shieldDamage != 0) GeneralUtils::DisplayDamageNumberString(shieldDamage, DamageDisplayType::Shield, pTechno->GetRenderCoords(), TechnoExt::ExtMap.Find(pTechno)->DamageNumberOffset); if (shieldDamage > 0) From 5cf680146cc785bb5b2d3a7e8782eccbb13ace59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=9D=E5=8D=83=E5=A4=A9=E5=8D=8E?= <1065703286@qq.com> Date: Thu, 11 Dec 2025 18:48:56 +0800 Subject: [PATCH 6/7] Jump positioning issue with duplicate headings (anchor) --- 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 33d92f24e4..7038532bd6 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -154,7 +154,7 @@ Of course, this is just the implementation method. To balance freedom with effic ### Display Damage Numbers -- There's a [new hotkey](User-Interface.md#display-damage-numbers) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. +- There's a [new hotkey](User-Interface.md#toggle-damage-numbers-display) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. - The feature is **available only when** `DamageNumbersEnabled` under `[GlobalControls]` in `rulesmd.ini` is set to `true`. If this setting is `false`, the feature is completely disabled and cannot be used. - The initial state of the feature (enabled or disabled when entering a game) is controlled by the `DisplayDamageNumbers` setting in `RA2MD.INI`. - If set to `yes`, the feature starts enabled. @@ -477,9 +477,9 @@ DisplayIncome.Offset=0,0 ; X,Y, pixels relative to default ## Hotkey Commands -### `[ ]` Display Damage Numbers +### `[ ]` Toggle Damage Numbers Display -- Switches on/off floating numbers when dealing damage. See [this](Miscellanous.md#display-damage-numbers) for details. +- Switches on/off floating numbers when dealing damage. See [this](User-Interface.md#display-damage-numbers) for details. - For localization add `TXT_DISPLAY_DAMAGE` and `TXT_DISPLAY_DAMAGE_DESC` into your `.csf` file. ### `[ ]` Dump Object Info From 037bb13c2581861cbd95c4bdb23b1854b42b14b7 Mon Sep 17 00:00:00 2001 From: Flactine <1716455702@qq.com> Date: Fri, 12 Dec 2025 18:03:09 +0800 Subject: [PATCH 7/7] Edit 'DamageNumbersEnabled' if not specified If `DamageNumbersEnabled` is not specified, its value defaults to the value of `DebugKeysEnabled`. --- docs/User-Interface.md | 1 + src/Misc/FlyingStrings.cpp | 7 ------- src/Phobos.INI.cpp | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 7038532bd6..f1b1cf2b51 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -156,6 +156,7 @@ Of course, this is just the implementation method. To balance freedom with effic - There's a [new hotkey](User-Interface.md#toggle-damage-numbers-display) to show exact numbers of damage dealt on units & buildings. The numbers are shown in red (blue against shields) for damage, and for healing damage in green (cyan against shields). They are shown on the affected units and will move upwards after appearing. - The feature is **available only when** `DamageNumbersEnabled` under `[GlobalControls]` in `rulesmd.ini` is set to `true`. If this setting is `false`, the feature is completely disabled and cannot be used. + - If `DamageNumbersEnabled` is not specified, its value defaults to the value of `DebugKeysEnabled`. - The initial state of the feature (enabled or disabled when entering a game) is controlled by the `DisplayDamageNumbers` setting in `RA2MD.INI`. - If set to `yes`, the feature starts enabled. - If set to `no`, the feature starts disabled, but the player can still toggle it manually using the hotkey. diff --git a/src/Misc/FlyingStrings.cpp b/src/Misc/FlyingStrings.cpp index 3ff2ff449e..2d84871d6f 100644 --- a/src/Misc/FlyingStrings.cpp +++ b/src/Misc/FlyingStrings.cpp @@ -73,13 +73,6 @@ void FlyingStrings::UpdateAll() if (Unsorted::CurrentFrame > dataItem.CreationFrame + Duration - 70) point.Y -= (Unsorted::CurrentFrame - dataItem.CreationFrame); - const COLORREF shadowColor = Drawing::RGB_To_Int(84, 84, 84); - - Point2D shadowPoint = point; - shadowPoint.X += 1; - shadowPoint.Y += 1; - - DSurface::Temp->DrawText(dataItem.Text, &bound, &shadowPoint, shadowColor, 0, TextPrintType::NoShadow); DSurface::Temp->DrawText(dataItem.Text, &bound, &point, dataItem.Color, 0, TextPrintType::NoShadow); if (Unsorted::CurrentFrame > dataItem.CreationFrame + Duration || Unsorted::CurrentFrame < dataItem.CreationFrame) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index 616fd5167c..bc4f22a668 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -284,7 +284,7 @@ DEFINE_HOOK(0x52D21F, InitRules_ThingsThatShouldntBeSerailized, 0x6) Phobos::Config::SaveVariablesOnScenarioEnd = pINI_RULESMD->ReadBool(GameStrings::General, "SaveVariablesOnScenarioEnd", false); #ifndef DEBUG Phobos::Config::DevelopmentCommands = pINI_RULESMD->ReadBool("GlobalControls", "DebugKeysEnabled", Phobos::Config::DevelopmentCommands); - Phobos::Config::DamageNumbersCommands = pINI_RULESMD->ReadBool("GlobalControls", "DamageNumbersEnabled", Phobos::Config::DamageNumbersCommands); + Phobos::Config::DamageNumbersCommands = pINI_RULESMD->ReadBool("GlobalControls", "DamageNumbersEnabled", 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);