Skip to content

Add improvements for airstrike flare visuals #1565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ This page lists all the individual contributions to the project by their author.
- Vehicles keeping target on move command
- `IsSonic` wave drawing crash fix
- Customizable electric bolt duration and electric bolt-related fixes
- Airstrike flare visual customizations
- **Morton (MortonPL)**:
- `XDrawOffset` for animations
- Shield passthrough & absorption
Expand Down
17 changes: 17 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it.
- Fixed the issue where computer players did not search for new enemies after defeating them or forming alliances with them.
- Fixed the bug that infantry ignored `Passengers` and `SizeLimit` when entering buildings.
- Fixed an issue where airstrike flare line drawn to target at lower elevation would clip.

## Fixes / interactions with other extensions

Expand Down Expand Up @@ -702,6 +703,22 @@ BallisticScatter.Max= ; floating point value, distance in cells

## Technos

### Airstrike flare customizations

- It is now possible to customize color of airstrike flare tint on target on the TechnoType calling in the airstrike as well as customize the color of the line drawn to target.
- `LaserTargetColor` can be used to set the index of color from `[ColorAdd]` defaults to `[AudioVisual]` -> `LaserTargetColor`.
- `AirstrikeLineColor` sets the color of the line and dot drawn from firer to target, defaults to `[AudioVisual]` -> `AirstrikeLineColor`.

In `rulesmd.ini`:
```ini
[AudioVisual]
AirstrikeLineColor=255,0,0 ; integer - Red,Green,Blue

[SOMETECHNO] ; TechnoType
LaserTargetColor= ; integer - [ColorAdd] index
AirstrikeLineColor= ; integer - Red,Green,Blue
```

### Airstrike target eligibility

- By default whether or not a building can be targeted by airstrikes depends on value of `CanC4`, which also affects other things. This can now be changed independently by setting `AllowAirstrike`. If not set, defaults to value of `CanC4`.
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ New:
- [Make harvesters do addtional scan after unload](Fixed-or-Improved-Logics.md#make-harvesters-do-addtional-scan-after-unload) (by TaranDahl)
- [Passenger-based insignias](Fixed-or-Improved-Logics.md#customizable-veterancy-insignias) (by Ollerus)
- [Use `InsigniaType` to set the properties of insignia in a batch](Miscellanous.md#insignia-type) (by Ollerus)
- [Customizable airstrike flare colors](Fixed-or-Improved-Logics.md#airstrike-flare-customizations) (by Starkku)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand All @@ -393,6 +394,7 @@ Vanilla fixes:
- Fixed the bug that buildings will always be tinted as airstrike owner (by NetsuNegi)
- Fixed the issue where computer players did not search for new enemies after defeating them or forming alliances with them (by FlyStar)
- Fixed the bug that infantry ignored `Passengers` and `SizeLimit` when entering buildings (by NetsuNegi)
- Fixed an issue where airstrike flare line drawn to target at lower elevation would clip (by Starkku)

Phobos fixes:
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi)
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->IronCurtain_ExtraTintIntensity.Read(exINI, GameStrings::AudioVisual, "IronCurtain.ExtraTintIntensity");
this->ForceShield_ExtraTintIntensity.Read(exINI, GameStrings::AudioVisual, "ForceShield.ExtraTintIntensity");
this->ColorAddUse8BitRGB.Read(exINI, GameStrings::AudioVisual, "ColorAddUse8BitRGB");
this->AirstrikeLineColor.Read(exINI, GameStrings::AudioVisual, "AirstrikeLineColor");

this->CrateOnlyOnLand.Read(exINI, GameStrings::CrateRules, "CrateOnlyOnLand");
this->UnitCrateVehicleCap.Read(exINI, GameStrings::CrateRules, "UnitCrateVehicleCap");
Expand Down Expand Up @@ -413,6 +414,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->ForceShield_ExtraTintIntensity)
.Process(this->AllowWeaponSelectAgainstWalls)
.Process(this->ColorAddUse8BitRGB)
.Process(this->AirstrikeLineColor)
.Process(this->ROF_RandomDelay)
.Process(this->ToolTip_Background_Color)
.Process(this->ToolTip_Background_Opacity)
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class RulesExt
Valueable<double> IronCurtain_ExtraTintIntensity;
Valueable<double> ForceShield_ExtraTintIntensity;
Valueable<bool> ColorAddUse8BitRGB;
Valueable<ColorStruct> AirstrikeLineColor;

Valueable<PartialVector2D<int>> ROF_RandomDelay;
Valueable<ColorStruct> ToolTip_Background_Color;
Expand Down Expand Up @@ -306,6 +307,7 @@ class RulesExt
, ForceShield_ExtraTintIntensity { 0.0 }
, AllowWeaponSelectAgainstWalls { false }
, ColorAddUse8BitRGB { false }
, AirstrikeLineColor { { 255, 0, 0 } }
, ROF_RandomDelay { { 0 ,2 } }
, ToolTip_Background_Color { { 0, 0, 0 } }
, ToolTip_Background_Opacity { 100 }
Expand Down
15 changes: 13 additions & 2 deletions src/Ext/Techno/Body.Internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,22 @@ int TechnoExt::GetTintColor(TechnoClass* pThis, bool invulnerability, bool airst
if (pThis)
{
if (invulnerability && pThis->IsIronCurtained())
{
tintColor |= GeneralUtils::GetColorFromColorAdd(pThis->ForceShielded ? RulesClass::Instance->ForceShieldColor : RulesClass::Instance->IronCurtainColor);
if (airstrike && TechnoExt::ExtMap.Find(pThis)->AirstrikeTargetingMe)
tintColor |= GeneralUtils::GetColorFromColorAdd(RulesClass::Instance->LaserTargetColor);
}
if (airstrike)
{
if (auto const pAirstrike = TechnoExt::ExtMap.Find(pThis)->AirstrikeTargetingMe)
{
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pAirstrike->Owner->GetTechnoType());
auto index = pTypeExt->LaserTargetColor.Get(RulesClass::Instance->LaserTargetColor);
tintColor |= GeneralUtils::GetColorFromColorAdd(index);
}
}
if (berserk && pThis->Berzerk)
{
tintColor |= GeneralUtils::GetColorFromColorAdd(RulesClass::Instance->BerserkColor);
}
}

return tintColor;
Expand Down
48 changes: 47 additions & 1 deletion src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,4 +781,50 @@ DEFINE_HOOK(0x655DDD, RadarClass_ProcessPoint_RadarInvisible, 0x6)
return GoOtherChecks;
}

#pragma endregion
#pragma endregion

#pragma region DrawAirstrikeFlare

namespace DrawAirstrikeFlareTemp
{
TechnoClass* pTechno = nullptr;
}

DEFINE_HOOK(0x705860, TechnoClass_DrawAirstrikeFlare_SetContext, 0x8)
{
GET(TechnoClass*, pThis, ECX);

// This is not used in vanilla function so ECX gets overwritten later.
DrawAirstrikeFlareTemp::pTechno = pThis;

return 0;
}

DEFINE_HOOK(0x7058F6, TechnoClass_DrawAirstrikeFlare, 0x5)
{
enum { SkipGameCode = 0x705976 };

GET(int, zSrc, EBP);
GET(int, zDest, EBX);
REF_STACK(ColorStruct, color, STACK_OFFSET(0x70, -0x60));

// Fix depth buffer value.
int zValue = Math::min(zSrc, zDest);
R->EBP(zValue);
R->EBX(zValue);

// Allow custom colors.
auto const pThis = DrawAirstrikeFlareTemp::pTechno;
auto const baseColor = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType())->AirstrikeLineColor.Get(RulesExt::Global()->AirstrikeLineColor);
double percentage = Randomizer::Global.RandomRanged(745, 1000) / 1000.0;
color = { (BYTE)(baseColor.R * percentage), (BYTE)(baseColor.G * percentage), (BYTE)(baseColor.B * percentage) };
R->ESI(Drawing::RGB_To_Int(baseColor));

return SkipGameCode;
}

// Skip setting color for the dot, it is already done in previous hook.
DEFINE_JUMP(LJMP, 0x705986, 0x7059C7);

#pragma endregion

6 changes: 6 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)

this->ReloadInTransport.Read(exINI, pSection, "ReloadInTransport");
this->ForbidParallelAIQueues.Read(exINI, pSection, "ForbidParallelAIQueues");

this->LaserTargetColor.Read(exINI, pSection, "LaserTargetColor");
this->AirstrikeLineColor.Read(exINI, pSection, "AirstrikeLineColor");

this->ShieldType.Read<true>(exINI, pSection, "ShieldType");

this->HarvesterDumpAmount.Read(exINI, pSection, "HarvesterDumpAmount");
Expand Down Expand Up @@ -818,6 +822,8 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->InitialStrength)
.Process(this->ReloadInTransport)
.Process(this->ForbidParallelAIQueues)
.Process(this->LaserTargetColor)
.Process(this->AirstrikeLineColor)
.Process(this->ShieldType)
.Process(this->PassengerDeletionType)

Expand Down
4 changes: 4 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class TechnoTypeExt
Nullable<int> InitialStrength;
Valueable<bool> ReloadInTransport;
Valueable<bool> ForbidParallelAIQueues;
Nullable<int> LaserTargetColor;
Nullable<ColorStruct> AirstrikeLineColor;

Valueable<ShieldTypeClass*> ShieldType;
std::unique_ptr<PassengerDeletionTypeClass> PassengerDeletionType;
Expand Down Expand Up @@ -382,6 +384,8 @@ class TechnoTypeExt
, InitialStrength {}
, ReloadInTransport { false }
, ForbidParallelAIQueues { false }
, LaserTargetColor {}
, AirstrikeLineColor {}
, ShieldType {}
, PassengerDeletionType { nullptr }

Expand Down