Skip to content

Commit e5b66f0

Browse files
NetsuNegiCrimRecyaCoronia
authored
Select box logic (#1608)
- Now you can use and customize select box for infantry, vehicle and aircraft. No select box for buildings in default case, but you still can specific for some building if you want. - `Frames` can be used to list frames of `Shape` file that'll be drawn as a select box when the TechnoType's health is at or below full health/the percentage defined in `[AudioVisual] -> ConditionYellow/ConditionRed`, respectively. - If `Grounded` set to true, the select box will be drawn on the ground below the TechnoType. - Select box's translucency setting can be adjusted via `Translucency`. - `VisibleToHouses` and `VisibleToHouses.Observer` can limit visibility to specific players. - `DrawAboveTechno` specific whether the select box will be drawn before drawing the TechnoType. If set to false, the select box can be obscured by the TechnoType, and the draw location will ignore `PixelSelectionBracketDelta`. In `rulesmd.ini`: ```ini [SelectBoxTypes] 0=SOMESELECTBOXTYPE [AudioVisual] DefaultInfantrySelectBox= ; Select box for infantry DefaultUnitSelectBox= ; Select box for vehicle and aircraft [SOMESELECTBOXTYPE] Shape=select.shp ; filename with .shp extension Palette=palette.pal ; filename with .pal extension Frames= ; list of integer, default 1,1,1 for infantry, 0,0,0 for vehicle and aircraft Grounded=false ; boolean Offset=0,0 ; integers - horizontal, vertical Translucency=0 ; translucency level (0/25/50/75) VisibleToHouses=all ; Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all) VisibleToHouses.Observer=true ; boolean DrawAboveTechno=true ; boolean [SOMETECHNO] SelectBox= ; Select box HideSelectBox=false ; boolean ``` In `RA2MD.INI` ```ini [Phobos] EnableSelectBox=false ; boolean ``` --------- Co-authored-by: CrimRecya <[email protected]> Co-authored-by: Coronia <[email protected]>
1 parent 3a0bbef commit e5b66f0

File tree

16 files changed

+256
-2
lines changed

16 files changed

+256
-2
lines changed

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ This page lists all the individual contributions to the project by their author.
378378
- Fix the bug that a unit can overlap with `Teleport` units after it's been damaged by a fallen unit lifted by `IsLocomotor=yes` warheads
379379
- Customize parasite culling targets
380380
- Customize harvester dump amount
381+
- Select box logic
381382
- **Apollo** - Translucent SHP drawing patches
382383
- **ststl**:
383384
- Customizable `ShowTimer` priority of superweapons

Phobos.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<ClCompile Include="src\New\Type\Affiliated\DroppodTypeClass.cpp" />
8383
<ClCompile Include="src\New\Type\DigitalDisplayTypeClass.cpp" />
8484
<ClCompile Include="src\New\Type\RadTypeClass.cpp" />
85+
<ClCompile Include="src\New\Type\SelectBoxTypeClass.cpp" />
8586
<ClCompile Include="src\New\Type\ShieldTypeClass.cpp" />
8687
<ClCompile Include="src\New\Type\LaserTrailTypeClass.cpp" />
8788
<ClCompile Include="src\New\Type\Affiliated\InterceptorTypeClass.cpp" />
@@ -226,6 +227,7 @@
226227
<ClInclude Include="src\New\Type\Affiliated\DroppodTypeClass.h" />
227228
<ClInclude Include="src\New\Type\DigitalDisplayTypeClass.h" />
228229
<ClInclude Include="src\New\Type\RadTypeClass.h" />
230+
<ClInclude Include="src\New\Type\SelectBoxTypeClass.h" />
229231
<ClInclude Include="src\New\Type\ShieldTypeClass.h" />
230232
<ClInclude Include="src\New\Type\LaserTrailTypeClass.h" />
231233
<ClInclude Include="src\New\Type\Affiliated\InterceptorTypeClass.h" />

docs/User-Interface.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,46 @@ DigitalDisplay.Enable=false ; boolean
9999
An example shape file for digits can be found on [Phobos supplementaries repo](https://github.com/Phobos-developers/PhobosSupplementaries).
100100
```
101101

102+
### Select Box
103+
104+
- Now you can use and customize select box for infantry, vehicle and aircraft. No select box for buildings in default case, but you still can specific for some building if you want.
105+
- `Frames` can be used to list frames of `Shape` file that'll be drawn as a select box when the TechnoType's health is at or below full health/the percentage defined in `[AudioVisual] -> ConditionYellow/ConditionRed`, respectively.
106+
- If `Grounded` set to true, the select box will be drawn on the ground below the TechnoType.
107+
- Select box's translucency setting can be adjusted via `Translucency`.
108+
- `VisibleToHouses` and `VisibleToHouses.Observer` can limit visibility to specific players.
109+
- `DrawAboveTechno` specific whether the select box will be drawn before drawing the TechnoType. If set to false, the select box can be obscured by the TechnoType, and the draw location will ignore `PixelSelectionBracketDelta`.
110+
111+
In `rulesmd.ini`:
112+
```ini
113+
[SelectBoxTypes]
114+
0=SOMESELECTBOXTYPE
115+
116+
[AudioVisual]
117+
DefaultInfantrySelectBox= ; Select box for infantry
118+
DefaultUnitSelectBox= ; Select box for vehicle and aircraft
119+
120+
[SOMESELECTBOXTYPE]
121+
Shape=select.shp ; filename with .shp extension
122+
Palette=palette.pal ; filename with .pal extension
123+
Frames= ; list of integer, default 1,1,1 for infantry, 0,0,0 for vehicle and aircraft
124+
Grounded=false ; boolean
125+
Offset=0,0 ; integers - horizontal, vertical
126+
Translucency=0 ; translucency level (0/25/50/75)
127+
VisibleToHouses=all ; Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
128+
VisibleToHouses.Observer=true ; boolean
129+
DrawAboveTechno=true ; boolean
130+
131+
[SOMETECHNO]
132+
SelectBox= ; Select box
133+
HideSelectBox=false ; boolean
134+
```
135+
136+
In `RA2MD.INI`
137+
```ini
138+
[Phobos]
139+
EnableSelectBox=false ; boolean
140+
```
141+
102142
### Flashing Technos on selecting
103143

104144
- Selecting technos, controlled by player, now may show a flash effect by setting `SelectionFlashDuration` parameter higher than 0.
@@ -294,7 +334,7 @@ In `rulesmd.ini`:
294334
```ini
295335
[AudioVisual]
296336
DisplayIncome=false ; boolean
297-
DisplayIncome.Houses=All ; Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
337+
DisplayIncome.Houses=all ; Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all)
298338
DisplayIncome.AllowAI=yes ; boolean
299339

300340
[SOMEBUILDING] ; BuildingType

docs/Whats-New.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ New:
363363
- [RadarInvisible for non-enemy house](Fixed-or-Improved-Logics.md#radarinvisible-for-non-enemy-house) (By TaranDahl)
364364
- New `Pips.HideIfNoStrength` and `SelfHealing.EnabledBy` additions for shields (by FS-21)
365365
- [Customize harvester dump amount](Fixed-or-Improved-Logics.md#customize-harvester-dump-amount) (by NetsuNegi)
366+
- Select box logic (by NetsuNegi)
366367
367368
Vanilla fixes:
368369
- 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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <New/Type/LaserTrailTypeClass.h>
1010
#include <New/Type/DigitalDisplayTypeClass.h>
1111
#include <New/Type/AttachEffectTypeClass.h>
12+
#include <New/Type/SelectBoxTypeClass.h>
1213
#include <Utilities/Patch.h>
1314

1415
std::unique_ptr<RulesExt::ExtData> RulesExt::Data = nullptr;
@@ -31,6 +32,7 @@ void RulesExt::LoadFromINIFile(RulesClass* pThis, CCINIClass* pINI)
3132
void RulesExt::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
3233
{
3334
DigitalDisplayTypeClass::LoadFromINIList(pINI);
35+
SelectBoxTypeClass::LoadFromINIList(pINI);
3436
RadTypeClass::LoadFromINIList(pINI);
3537
ShieldTypeClass::LoadFromINIList(pINI);
3638
LaserTrailTypeClass::LoadFromINIList(&CCINIClass::INI_Art);
@@ -201,6 +203,9 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
201203
this->Vehicles_DefaultDigitalDisplayTypes.Read(exINI, GameStrings::AudioVisual, "Vehicles.DefaultDigitalDisplayTypes");
202204
this->Aircraft_DefaultDigitalDisplayTypes.Read(exINI, GameStrings::AudioVisual, "Aircraft.DefaultDigitalDisplayTypes");
203205

206+
this->DefaultInfantrySelectBox.Read(exINI, GameStrings::AudioVisual, "DefaultInfantrySelectBox");
207+
this->DefaultUnitSelectBox.Read(exINI, GameStrings::AudioVisual, "DefaultUnitSelectBox");
208+
204209
this->DamageOwnerMultiplier.Read(exINI, GameStrings::CombatDamage, "DamageOwnerMultiplier");
205210
this->DamageAlliesMultiplier.Read(exINI, GameStrings::CombatDamage, "DamageAlliesMultiplier");
206211
this->DamageEnemiesMultiplier.Read(exINI, GameStrings::CombatDamage, "DamageEnemiesMultiplier");
@@ -423,6 +428,8 @@ void RulesExt::ExtData::Serialize(T& Stm)
423428
.Process(this->Infantry_DefaultDigitalDisplayTypes)
424429
.Process(this->Vehicles_DefaultDigitalDisplayTypes)
425430
.Process(this->Aircraft_DefaultDigitalDisplayTypes)
431+
.Process(this->DefaultInfantrySelectBox)
432+
.Process(this->DefaultUnitSelectBox)
426433
.Process(this->VisualScatter_Min)
427434
.Process(this->VisualScatter_Max)
428435
.Process(this->ShowDesignatorRange)

src/Ext/Rules/Body.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class TechnoTypeClass;
1717
class VocClass;
1818
class WarheadTypeClass;
1919
class DigitalDisplayTypeClass;
20+
class SelectBoxTypeClass;
2021

2122
class RulesExt
2223
{
@@ -143,6 +144,9 @@ class RulesExt
143144
ValueableVector<DigitalDisplayTypeClass*> Vehicles_DefaultDigitalDisplayTypes;
144145
ValueableVector<DigitalDisplayTypeClass*> Aircraft_DefaultDigitalDisplayTypes;
145146

147+
Valueable<SelectBoxTypeClass*> DefaultInfantrySelectBox;
148+
Valueable<SelectBoxTypeClass*> DefaultUnitSelectBox;
149+
146150
Valueable<Leptons> VisualScatter_Min;
147151
Valueable<Leptons> VisualScatter_Max;
148152

@@ -319,6 +323,8 @@ class RulesExt
319323
, Infantry_DefaultDigitalDisplayTypes {}
320324
, Vehicles_DefaultDigitalDisplayTypes {}
321325
, Aircraft_DefaultDigitalDisplayTypes {}
326+
, DefaultInfantrySelectBox {}
327+
, DefaultUnitSelectBox {}
322328
, VisualScatter_Min { Leptons(8) }
323329
, VisualScatter_Max { Leptons(32) }
324330
, ShowDesignatorRange { true }

src/Ext/Techno/Body.Visuals.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,69 @@ Point2D TechnoExt::GetBuildingSelectBracketPosition(TechnoClass* pThis, Building
271271
return position;
272272
}
273273

274+
void TechnoExt::DrawSelectBox(TechnoClass* pThis, const Point2D* pLocation, const RectangleStruct* pBounds, bool drawBefore)
275+
{
276+
const auto whatAmI = pThis->WhatAmI();
277+
const auto pType = pThis->GetTechnoType();
278+
const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pType);
279+
SelectBoxTypeClass* pSelectBox = nullptr;
280+
281+
if (pTypeExt->SelectBox.isset())
282+
pSelectBox = pTypeExt->SelectBox.Get();
283+
else if (whatAmI == InfantryClass::AbsID)
284+
pSelectBox = RulesExt::Global()->DefaultInfantrySelectBox.Get();
285+
else if (whatAmI != BuildingClass::AbsID)
286+
pSelectBox = RulesExt::Global()->DefaultUnitSelectBox.Get();
287+
288+
if (!pSelectBox || pSelectBox->DrawAboveTechno == drawBefore)
289+
return;
290+
291+
const auto pShape = pSelectBox->Shape.Get();
292+
293+
if (!pShape)
294+
return;
295+
296+
const bool canSee = HouseClass::IsCurrentPlayerObserver() ? pSelectBox->VisibleToHouses_Observer : EnumFunctions::CanTargetHouse(pSelectBox->VisibleToHouses, pThis->Owner, HouseClass::CurrentPlayer);
297+
298+
if (!canSee)
299+
return;
300+
301+
const auto pPalette = pSelectBox->Palette.GetOrDefaultConvert(FileSystem::PALETTE_PAL);
302+
303+
const double healthPercentage = pThis->GetHealthPercentage();
304+
const Vector3D<int> frames = pSelectBox->Frames.Get(whatAmI == AbstractType::Infantry ? CoordStruct { 1,1,1 } : CoordStruct { 0,0,0 });
305+
const int frame = healthPercentage > RulesClass::Instance->ConditionYellow ? frames.X : healthPercentage > RulesClass::Instance->ConditionRed ? frames.Y : frames.Z;
306+
307+
Point2D drawPoint = *pLocation;
308+
309+
if (pSelectBox->Grounded && whatAmI != BuildingClass::AbsID)
310+
{
311+
CoordStruct coords = pThis->GetCenterCoords();
312+
coords.Z = MapClass::Instance.GetCellFloorHeight(coords);
313+
314+
const auto& [outClient, visible] = TacticalClass::Instance->CoordsToClient(coords);
315+
316+
if (!visible)
317+
return;
318+
319+
drawPoint = outClient;
320+
}
321+
322+
drawPoint += pSelectBox->Offset;
323+
324+
if (pSelectBox->DrawAboveTechno)
325+
drawPoint.Y += pType->PixelSelectionBracketDelta;
326+
327+
if (whatAmI == AbstractType::Infantry)
328+
drawPoint += { 8, -3 };
329+
else
330+
drawPoint += { 1, -4 };
331+
332+
const auto flags = BlitterFlags::Centered | BlitterFlags::Nonzero | BlitterFlags::MultiPass | pSelectBox->Translucency;
333+
334+
DSurface::Composite->DrawSHP(pPalette, pShape, frame, &drawPoint, pBounds, flags, 0, 0, ZGradient::Ground, 1000, 0, nullptr, 0, 0, 0);
335+
}
336+
274337
void TechnoExt::ProcessDigitalDisplays(TechnoClass* pThis)
275338
{
276339
if (!Phobos::Config::DigitalDisplay_Enable)

src/Ext/Techno/Body.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ class TechnoExt
204204
static Point2D GetScreenLocation(TechnoClass* pThis);
205205
static Point2D GetFootSelectBracketPosition(TechnoClass* pThis, Anchor anchor);
206206
static Point2D GetBuildingSelectBracketPosition(TechnoClass* pThis, BuildingSelectBracketPosition bracketPosition);
207+
static void DrawSelectBox(TechnoClass* pThis, const Point2D* pLocation, const RectangleStruct* pBounds, bool drawBefore = false);
207208
static void ProcessDigitalDisplays(TechnoClass* pThis);
208209
static void GetValuesForDisplay(TechnoClass* pThis, DisplayInfoType infoType, int& value, int& maxValue);
209210

src/Ext/Techno/Hooks.Pips.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
#include <AircraftTypeClass.h>
22
#include <SpawnManagerClass.h>
33
#include <TiberiumClass.h>
4+
#include <TacticalClass.h>
45
#include "Body.h"
56

7+
DEFINE_HOOK_AGAIN(0x6D9134, TacticalClass_RenderLayers_DrawBefore, 0x5)// BuildingClass
8+
DEFINE_HOOK(0x6D9076, TacticalClass_RenderLayers_DrawBefore, 0x5)// FootClass
9+
{
10+
GET(TechnoClass*, pTechno, ESI);
11+
GET(Point2D*, pLocation, EAX);
12+
13+
if (pTechno->IsSelected && Phobos::Config::EnableSelectBox)
14+
{
15+
const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pTechno->GetTechnoType());
16+
17+
if (!pTypeExt->HealthBar_Hide && !pTypeExt->HideSelectBox)
18+
TechnoExt::DrawSelectBox(pTechno, pLocation, &DSurface::ViewBounds, true);
19+
}
20+
21+
return 0;
22+
}
23+
624
DEFINE_HOOK(0x6F64A9, TechnoClass_DrawHealthBar_Hide, 0x5)
725
{
826
GET(TechnoClass*, pThis, ECX);
@@ -23,6 +41,9 @@ DEFINE_HOOK(0x6F65D1, TechnoClass_DrawHealthBar_Buildings, 0x6)
2341

2442
const auto pExt = TechnoExt::ExtMap.Find(pThis);
2543

44+
if (pThis->IsSelected && Phobos::Config::EnableSelectBox && !pExt->TypeExtData->HideSelectBox)
45+
TechnoExt::DrawSelectBox(pThis, pLocation, pBound);
46+
2647
if (const auto pShieldData = pExt->Shield.get())
2748
{
2849
if (pShieldData->IsAvailable() && !pShieldData->IsBrokenAndNonRespawning())
@@ -43,6 +64,9 @@ DEFINE_HOOK(0x6F683C, TechnoClass_DrawHealthBar_Units, 0x7)
4364

4465
const auto pExt = TechnoExt::ExtMap.Find(pThis);
4566

67+
if (pThis->IsSelected && Phobos::Config::EnableSelectBox && !pExt->TypeExtData->HideSelectBox)
68+
TechnoExt::DrawSelectBox(pThis, pLocation, pBound);
69+
4670
if (const auto pShieldData = pExt->Shield.get())
4771
{
4872
if (pShieldData->IsAvailable() && !pShieldData->IsBrokenAndNonRespawning())

src/Ext/TechnoType/Body.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
439439
this->DigitalDisplay_Disable.Read(exINI, pSection, "DigitalDisplay.Disable");
440440
this->DigitalDisplayTypes.Read(exINI, pSection, "DigitalDisplayTypes");
441441

442+
this->SelectBox.Read(exINI, pSection, "SelectBox");
443+
this->HideSelectBox.Read(exINI, pSection, "HideSelectBox");
444+
442445
this->AmmoPipFrame.Read(exINI, pSection, "AmmoPipFrame");
443446
this->EmptyAmmoPipFrame.Read(exINI, pSection, "EmptyAmmoPipFrame");
444447
this->AmmoPipWrapStartFrame.Read(exINI, pSection, "AmmoPipWrapStartFrame");
@@ -893,6 +896,9 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
893896
.Process(this->DigitalDisplay_Disable)
894897
.Process(this->DigitalDisplayTypes)
895898

899+
.Process(this->SelectBox)
900+
.Process(this->HideSelectBox)
901+
896902
.Process(this->AmmoPipFrame)
897903
.Process(this->EmptyAmmoPipFrame)
898904
.Process(this->AmmoPipWrapStartFrame)

0 commit comments

Comments
 (0)