Skip to content

Commit bb7d1dd

Browse files
authored
[Vanilla Enhancement] Allow draw SuperWeapon timer as percentage (#2050)
- Superweapon cd timer can now draw as percentage. - 超级武器的CD倒计时现在可以以百分比形式显示了. In `rulesmd.ini`: ```ini [AudioVisual] SuperWeaponTimer.Percentage=false ; boolean [SOMESW] ; SuperWeaponType, with ShowTimer=yes ShowTimer.Percentage= ; boolean ```
1 parent d6268f5 commit bb7d1dd

8 files changed

Lines changed: 127 additions & 1 deletion

File tree

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ This page lists all the individual contributions to the project by their author.
498498
- Penetrates damage on transporter
499499
- Add amount limit of `LimboKill`
500500
- Spawns particle when spawns tiberium by terrain
501+
- Allow draw SuperWeapon timer as percentage
501502
- **Apollo** - Translucent SHP drawing patches
502503
- **ststl**:
503504
- Customizable `ShowTimer` priority of superweapons

docs/User-Interface.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,19 @@ In `rulesmd.ini`:
391391
ShowTimer.Priority=0 ; integer
392392
```
393393

394+
### Allow draw SuperWeapon timer as percentage
395+
396+
- Superweapon cd timer can now draw as percentage.
397+
398+
In `rulesmd.ini`:
399+
```ini
400+
[AudioVisual]
401+
SuperWeaponTimer.Percentage=false ; boolean
402+
403+
[SOMESW] ; SuperWeaponType, with ShowTimer=yes
404+
ShowTimer.Percentage= ; boolean
405+
```
406+
394407
### Task subtitles display in the middle of the screen
395408

396409
![Message Display In Center](_static/images/messagedisplayincenter.gif)

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ New:
541541
- [Customizations for techno type target scan/guard range](Fixed-or-Improved-Logics.md#target-scan-guard-range-customizations) (by Starkku)
542542
- Spawns particle when spawns tiberium by terrain (by NetsuNegi)
543543
- Allow jumpjet climbing ignore building height (by TaranDahl)
544+
- Allow draw SuperWeapon timer as percentage (by NetsuNegi)
544545
545546
Vanilla fixes:
546547
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)

src/Ext/Rules/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
112112
this->PlacementPreview.Read(exINI, GameStrings::AudioVisual, "PlacementPreview");
113113
this->PlacementPreview_Translucency.Read(exINI, GameStrings::AudioVisual, "PlacementPreview.Translucency");
114114

115+
this->SuperWeaponTimer_Percentage.Read(exINI, GameStrings::AudioVisual, "SuperWeaponTimer.Percentage");
115116
this->SuperWeaponSidebar_AllowByDefault.Read(exINI, GameStrings::AudioVisual, "SuperWeaponSidebar.AllowByDefault");
116117

117118
this->ConditionYellow_Terrain.Read(exINI, GameStrings::AudioVisual, "ConditionYellow.Terrain");
@@ -473,6 +474,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
473474
.Process(this->PlacementGrid_TranslucencyWithPreview)
474475
.Process(this->PlacementPreview)
475476
.Process(this->PlacementPreview_Translucency)
477+
.Process(this->SuperWeaponTimer_Percentage)
476478
.Process(this->SuperWeaponSidebar_AllowByDefault)
477479
.Process(this->ConditionYellow_Terrain)
478480
.Process(this->Shield_ConditionYellow)

src/Ext/Rules/Body.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#pragma once
1+
#pragma once
22

33
#include <RulesClass.h>
44
#include <Utilities/Container.h>
@@ -63,6 +63,7 @@ class RulesExt
6363
Valueable<bool> PlacementPreview;
6464
TranslucencyLevel PlacementPreview_Translucency;
6565

66+
Valueable<bool> SuperWeaponTimer_Percentage;
6667
Valueable<bool> SuperWeaponSidebar_AllowByDefault;
6768

6869
Nullable<double> ConditionYellow_Terrain;
@@ -353,6 +354,7 @@ class RulesExt
353354
, PlacementPreview { false }
354355
, PlacementPreview_Translucency { 75 }
355356

357+
, SuperWeaponTimer_Percentage { false }
356358
, SuperWeaponSidebar_AllowByDefault { false }
357359

358360
, Shield_ConditionYellow { }

src/Ext/SWType/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void SWTypeExt::ExtData::Serialize(T& Stm)
6969
.Process(this->SW_Next_RandomWeightsData)
7070
.Process(this->SW_Next_RollChances)
7171
.Process(this->ShowTimer_Priority)
72+
.Process(this->ShowTimer_Percentage)
7273
.Process(this->Convert_Pairs)
7374
.Process(this->ShowDesignatorRange)
7475
.Process(this->TabIndex)
@@ -152,6 +153,7 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
152153
this->SW_Next_RollChances.Read(exINI, pSection, "SW.Next.RollChances");
153154

154155
this->ShowTimer_Priority.Read(exINI, pSection, "ShowTimer.Priority");
156+
this->ShowTimer_Percentage.Read(exINI, pSection, "ShowTimer.Percentage");
155157

156158
this->EMPulse_WeaponIndex.Read(exINI, pSection, "EMPulse.WeaponIndex");
157159
this->EMPulse_SuspendOthers.Read(exINI, pSection, "EMPulse.SuspendOthers");

src/Ext/SWType/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class SWTypeExt
6565
ValueableVector<float> SW_Next_RollChances;
6666

6767
Valueable<int> ShowTimer_Priority;
68+
Nullable<bool> ShowTimer_Percentage;
6869

6970
Valueable<WarheadTypeClass*> Detonate_Warhead;
7071
Valueable<WeaponTypeClass*> Detonate_Weapon;
@@ -158,6 +159,7 @@ class SWTypeExt
158159
, SW_Next_RollChances {}
159160
, SW_Next_RandomWeightsData {}
160161
, ShowTimer_Priority { 0 }
162+
, ShowTimer_Percentage { false }
161163
, Convert_Pairs {}
162164
, ShowDesignatorRange { true }
163165
, TabIndex { 1 }

src/Misc/Hooks.UI.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,3 +502,106 @@ DEFINE_HOOK(0x55F1F8, MPDebugPrint_CheckDrawFlag, 0x8)
502502
{
503503
return Game::DrawMPDebugStats ? 0 : 0x55F280;
504504
}
505+
506+
#pragma region Draw Timer
507+
508+
namespace DrawTimerTemp
509+
{
510+
bool AdjustLocation = false;
511+
bool IsPercentage = false;
512+
double Percentage = 0.0;
513+
int TimeLeft = 0;
514+
}
515+
516+
DEFINE_HOOK(0x6D3D10, TacticalClass_Render_BeforeAll, 0x6)
517+
{
518+
using namespace DrawTimerTemp;
519+
AdjustLocation = false;
520+
IsPercentage = false;
521+
return 0;
522+
}
523+
524+
DEFINE_HOOK(0x6D4992, TacticalClass_Render_DrawMissionTimer_TimeLeft, 0x6)
525+
{
526+
DrawTimerTemp::TimeLeft = R->EDX<int>();
527+
return 0;
528+
}
529+
530+
DEFINE_HOOK(0x6D4A10, TacticalClass_Render_DrawSuperTimer_PercentageTimer, 0x6)
531+
{
532+
enum { SkipGetTimeLeft = 0x6D4A35 };
533+
534+
GET(SuperClass*, pSuper, ECX);
535+
536+
DrawTimerTemp::IsPercentage = false;
537+
const int timeLeft = pSuper->RechargeTimer.GetTimeLeft();
538+
const auto pSWTypeExt = SWTypeExt::ExtMap.Find(pSuper->Type);
539+
540+
if (pSWTypeExt->ShowTimer_Percentage.Get(RulesExt::Global()->SuperWeaponTimer_Percentage))
541+
{
542+
DrawTimerTemp::IsPercentage = true;
543+
const int recharge = pSuper->GetRechargeTime();
544+
const double percentage = DrawTimerTemp::Percentage = std::min(static_cast<double>(recharge - timeLeft) / recharge, 1.0);
545+
R->ESI(percentage >= 1.0 ? 0 : 15);
546+
}
547+
else
548+
{
549+
DrawTimerTemp::TimeLeft = timeLeft / 15;
550+
R->ESI(timeLeft);
551+
}
552+
553+
return SkipGetTimeLeft;
554+
}
555+
556+
DEFINE_HOOK(0x6D4B03, TacticalClass_Render_DrawBlackoutTimer_TimeLeft, 0x5)
557+
{
558+
DrawTimerTemp::TimeLeft = R->EDX<int>();
559+
return 0;
560+
}
561+
562+
static int __fastcall TacticalClass_DrawTimer_swprintf(wchar_t* pBuffer, size_t bufferCount, wchar_t* pFormat, ...)
563+
{
564+
using namespace DrawTimerTemp;
565+
566+
if (IsPercentage)
567+
return swprintf(pBuffer, bufferCount, L"%.2lf%s", Percentage * 100, L"%%");
568+
else
569+
return swprintf(pBuffer, bufferCount, L"%02d:%02d", TimeLeft / 60 % 60, TimeLeft % 60);
570+
}
571+
DEFINE_FUNCTION_JUMP(CALL, 0x6D4C4C, TacticalClass_DrawTimer_swprintf)
572+
573+
static Point2D* __fastcall TacticalClass_DrawTimer_Print_Wide
574+
(
575+
Point2D& retBuffer,
576+
const wchar_t* pText,
577+
Surface* pSurface,
578+
const RectangleStruct& bounds,
579+
Point2D& location,
580+
ColorScheme* pForeScheme,
581+
ColorScheme* pBackScheme,
582+
TextPrintType flag,
583+
...
584+
)
585+
{
586+
using namespace DrawTimerTemp;
587+
AdjustLocation = !AdjustLocation;
588+
589+
if (AdjustLocation)
590+
{
591+
if (IsPercentage)
592+
{
593+
IsPercentage = false;
594+
location.X += 8;
595+
}
596+
else
597+
{
598+
location.X -= 2;
599+
}
600+
}
601+
602+
return Fancy_Text_Print_Wide(retBuffer, pText, pSurface, bounds, location, pForeScheme, pBackScheme, flag);
603+
}
604+
DEFINE_FUNCTION_JUMP(CALL, 0x6D4D42, TacticalClass_DrawTimer_Print_Wide)// UIName
605+
DEFINE_FUNCTION_JUMP(CALL, 0x6D4D9A, TacticalClass_DrawTimer_Print_Wide)// Time
606+
607+
#pragma endregion

0 commit comments

Comments
 (0)