Skip to content

Commit ee7462d

Browse files
committed
Add a global CombatAlert.Default
1 parent e0a19ab commit ee7462d

File tree

4 files changed

+30
-33
lines changed

4 files changed

+30
-33
lines changed

docs/New-or-Enhanced-Logics.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ Promote.EliteAnimation= ; Animation
15341534
- In Vanilla, non-building technos will not generate radar events or EVAs when attacked, so players can hardly notice them until they are destroyed. You can now receive a radar event (and optionally a sound effect) when your units is attacked, so you can respond to the combats in time.
15351535
- `[AudioVisual]->CombatAlert` is a global switch, set it to `true` to enable the entire logic.
15361536
- These flags controlls when to trigger a combat alert.
1537-
- You can disable this logic on specific techno by setting `[SOMETECHNO]->CombatAlert` to `false`. It is defaultly disabled for technos with `Insignificant=yes` or `Spawned=yes`.
1537+
- You can disable this logic on specific techno by setting `[SOMETECHNO]->CombatAlert` to `false`, which default to `[AudioVisual]->CombatAlert.Default`. If `CombatAlert.Default` is also empty, it is defaultly disabled for technos with `Insignificant=yes` or `Spawned=yes`.
15381538
- `[AudioVisual]->CombatAlert.IgnoreBuilding` will turn the logic off on buildings. You can override it for specific building by setting `[SOMETECHNO]->CombatAlert.NotBuilding` to true. You may hope to use it on veh-buildings.
15391539
- `[AudioVisual]->CombatAlert.SuppressIfInScreen` decides whether to disable the logic for the units in the current screen.
15401540
- `[AudioVisual]->CombatAlert.Interval` decides the time interval (in frames) between alerts, to prevent the alert from being anonying. It is default to 150 frames.
@@ -1552,6 +1552,7 @@ In `rulesmd.ini`:
15521552
```ini
15531553
[AudioVisual]
15541554
CombatAlert=false ;boolean
1555+
CombatAlert.Default= ;boolean
15551556
CombatAlert.IgnoreBuilding=true ;boolean
15561557
CombatAlert.SuppressIfInScreen=true ;boolean
15571558
CombatAlert.Interval=150 ;integer, game frames

src/Ext/Rules/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
201201
// this->VoxelShadowLightSource.Read(exINI, GameStrings::AudioVisual, "VoxelShadowLightSource");
202202

203203
this->CombatAlert.Read(exINI, GameStrings::AudioVisual, "CombatAlert");
204+
this->CombatAlert_Default.Read(exINI, GameStrings::AudioVisual, "CombatAlert.Default");
204205
this->CombatAlert_IgnoreBuilding.Read(exINI, GameStrings::AudioVisual, "CombatAlert.IgnoreBuilding");
205206
this->CombatAlert_SuppressIfInScreen.Read(exINI, GameStrings::AudioVisual, "CombatAlert.SuppressIfInScreen");
206207
this->CombatAlert_Interval.Read(exINI, GameStrings::AudioVisual, "CombatAlert.Interval");
@@ -404,6 +405,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
404405
// .Process(this->VoxelShadowLightSource)
405406
.Process(this->BuildingWaypoint)
406407
.Process(this->CombatAlert)
408+
.Process(this->CombatAlert_Default)
407409
.Process(this->CombatAlert_IgnoreBuilding)
408410
.Process(this->CombatAlert_SuppressIfInScreen)
409411
.Process(this->CombatAlert_Interval)

src/Ext/Rules/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class RulesExt
158158
Valueable<double> JumpjetLevelLightMultiplier;
159159

160160
Valueable<bool> CombatAlert;
161+
Nullable<bool> CombatAlert_Default;
161162
Valueable<bool> CombatAlert_IgnoreBuilding;
162163
Valueable<bool> CombatAlert_SuppressIfInScreen;
163164
Valueable<int> CombatAlert_Interval;
@@ -301,6 +302,7 @@ class RulesExt
301302
// , VoxelShadowLightSource { }
302303

303304
, CombatAlert { false }
305+
, CombatAlert_Default {}
304306
, CombatAlert_IgnoreBuilding { true }
305307
, CombatAlert_SuppressIfInScreen { true }
306308
, CombatAlert_Interval { 150 }

src/Ext/Techno/Hooks.ReceiveDamage.cpp

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,77 +19,69 @@ DEFINE_HOOK(0x701900, TechnoClass_ReceiveDamage_Shield, 0x6)
1919
GET(TechnoClass*, pThis, ECX);
2020
LEA_STACK(args_ReceiveDamage*, args, 0x4);
2121

22+
const auto pRules = RulesExt::Global();
2223
const auto pExt = TechnoExt::ExtMap.Find(pThis);
23-
2424
int nDamageLeft = *args->Damage;
2525

26-
const auto pRules = RulesExt::Global();
27-
2826
if (pRules->CombatAlert && nDamageLeft > 1)
2927
{
30-
do
28+
auto raiseCombatAlert = [pThis, pExt, pRules, args]()
3129
{
3230
const auto pHouse = pThis->Owner;
3331

34-
if (!pHouse || (!pThis->IsOwnedByCurrentPlayer && !pHouse->IsInPlayerControl) || !pThis->IsInPlayfield)
35-
break;
36-
37-
const auto pSourceHouse = args->SourceHouse;
38-
39-
if (pRules->CombatAlert_SuppressIfAllyDamage && pHouse->IsAlliedWith(pSourceHouse))
40-
break;
32+
if (!pHouse->IsControlledByCurrentPlayer() || (pRules->CombatAlert_SuppressIfAllyDamage && pHouse->IsAlliedWith(args->SourceHouse)))
33+
return;
4134

4235
const auto pHouseExt = HouseExt::ExtMap.Find(pHouse);
4336

4437
if (pHouseExt->CombatAlertTimer.HasTimeLeft())
45-
break;
38+
return;
4639

47-
const auto pWHExt = WarheadTypeExt::ExtMap.Find(args->WH);
40+
const auto pTypeExt = pExt->TypeExtData;
41+
const auto pType = pTypeExt->OwnerObject();
4842

49-
if (pWHExt->CombatAlert_Suppress.Get(!pWHExt->Malicious || pWHExt->Nonprovocative))
50-
break;
43+
if (!pTypeExt->CombatAlert.Get(pRules->CombatAlert_Default.Get(!pType->Insignificant && !pType->Spawned)) || !pThis->IsInPlayfield)
44+
return;
5145

52-
const auto pType = pThis->GetTechnoType();
53-
const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pType);
46+
const auto pWHExt = WarheadTypeExt::ExtMap.Find(args->WH);
5447

55-
if (!pType || !pTypeExt || !pTypeExt->CombatAlert.Get(!pType->Insignificant && !pType->Spawned))
56-
break;
48+
if (pWHExt->CombatAlert_Suppress.Get(!pWHExt->Malicious || pWHExt->Nonprovocative))
49+
return;
5750

58-
const auto pBuilding = pThis->WhatAmI() == AbstractType::Building ? static_cast<BuildingClass*>(pThis) : nullptr;
51+
const auto pBuilding = abstract_cast<BuildingClass*>(pThis);
5952

6053
if (pRules->CombatAlert_IgnoreBuilding && pBuilding && !pTypeExt->CombatAlert_NotBuilding.Get(pBuilding->Type->IsVehicle()))
61-
break;
54+
return;
6255

63-
const CoordStruct coordInMap = pThis->GetCoords();
56+
const auto coordInMap = pThis->GetCoords();
6457

6558
if (pRules->CombatAlert_SuppressIfInScreen)
6659
{
6760
TacticalClass* const pTactical = TacticalClass::Instance;
68-
const Point2D coordInScreen = pTactical->CoordsToScreen(coordInMap) - pTactical->TacticalPos;
69-
const RectangleStruct screenArea = DSurface::Composite->GetRect();
61+
const auto coordInScreen = pTactical->CoordsToScreen(coordInMap) - pTactical->TacticalPos;
62+
const auto screenArea = DSurface::Composite->GetRect();
7063

7164
if (screenArea.Width >= coordInScreen.X && screenArea.Height >= coordInScreen.Y && coordInScreen.X >= 0 && coordInScreen.Y >= 0) // check if the unit is in screen
72-
break;
65+
return;
7366
}
7467

7568
pHouseExt->CombatAlertTimer.Start(pRules->CombatAlert_Interval);
7669
RadarEventClass::Create(RadarEventType::Combat, CellClass::Coord2Cell(coordInMap));
77-
7870
int index = -1;
7971

8072
if (!pRules->CombatAlert_MakeAVoice) // No one want to play two sound at a time, I guess?
81-
break;
82-
else if (pTypeExt->CombatAlert_UseFeedbackVoice.Get((const bool)pRules->CombatAlert_UseFeedbackVoice) && pType->VoiceFeedback.Count > 0) // Use VoiceFeedback first
73+
return;
74+
else if (pTypeExt->CombatAlert_UseFeedbackVoice.Get(pRules->CombatAlert_UseFeedbackVoice) && pType->VoiceFeedback.Count > 0) // Use VoiceFeedback first
8375
VocClass::PlayGlobal(pType->VoiceFeedback.GetItem(0), 0x2000, 1.0);
84-
else if (pTypeExt->CombatAlert_UseAttackVoice.Get((const bool)pRules->CombatAlert_UseAttackVoice) && pType->VoiceAttack.Count > 0) // Use VoiceAttack then
76+
else if (pTypeExt->CombatAlert_UseAttackVoice.Get(pRules->CombatAlert_UseAttackVoice) && pType->VoiceAttack.Count > 0) // Use VoiceAttack then
8577
VocClass::PlayGlobal(pType->VoiceAttack.GetItem(0), 0x2000, 1.0);
86-
else if (pTypeExt->CombatAlert_UseEVA.Get((const bool)pRules->CombatAlert_UseEVA)) // Use Eva finally
78+
else if (pTypeExt->CombatAlert_UseEVA.Get(pRules->CombatAlert_UseEVA)) // Use Eva finally
8779
index = pTypeExt->CombatAlert_EVA.Get(VoxClass::FindIndex((const char*)"EVA_UnitsInCombat"));
8880

8981
if (index != -1)
9082
VoxClass::PlayIndex(index);
91-
}
92-
while (false);
83+
};
84+
raiseCombatAlert();
9385
}
9486

9587
if (!args->IgnoreDefenses)

0 commit comments

Comments
 (0)