diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 52b2176239..662369aff1 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -2766,6 +2766,23 @@ Bolt.FollowFLH= ; boolean Due to technical constraints, these features do not work with electric bolts created from support weapon of [Ares' Prism Forwarding](https://ares-developers.github.io/Ares-docs/new/buildings/prismforwarding.html) or those from `AirburstWeapon`. ``` +### Electric bolt Z-adjust + +- It is now possible to change the Z-adjust for weapon EBolt drawing via `EBoltZAdjust` per weapon. +- In vanilla, the EBolt effect fired by BuildingType takes `min(the Z-depth obtained from coordinate transformation, 0)`, this is to ensure that the EBolt effect is not blocked by other images such as tiles in some cases, and now this processing can be turned off to meet some specific needs. + - This only determines whether the Z-depth of the EBolt effect created by BuildingType can be positive; `EBoltZAdjust` can always be normally added to it. + +In `rulesmd.ini`: +```ini +[AudioVisual] +EBoltZAdjust=0 ; integer +EBoltZAdjust.ClampInitialDepthForBuilding=true ; boolean + +[SOMEWEAPON] ; WeaponType +EBoltZAdjust= ; integer, defaults to [AudioVisual] -> EBoltZAdjust +EBoltZAdjust.ClampInitialDepthForBuilding= ; boolean, defaults to [AudioVisual] -> EBoltZAdjust.ClampInitialDepthForBuilding +``` + ### Laser Z-adjust - It is now possible to change the Z-adjust for weapon laser drawing via `LaserZAdjust` per weapon, defaults to `[AudioVisual] -> LaserZAdjust`. Note that this is not available on prism support weapons. diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index d6d4f24f32..c7899196b8 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -270,6 +270,7 @@ Bolt.Color2= ; integer - Red,Green,Blue Bolt.Disable2=false ; boolean Bolt.Color3= ; integer - Red,Green,Blue Bolt.Disable3=false ; boolean +Bolt.ZAdjust=0 ; integer ; radbeam Beam.Color= ; integer - Red,Green,Blue Beam.Amplitude=40.0 ; floating point value diff --git a/docs/Whats-New.md b/docs/Whats-New.md index bc789670cd..77f28e8679 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -578,6 +578,9 @@ New: - [Laser drawing Z-adjust customization](Fixed-or-Improved-Logics.md#laser-z-adjust) (by Starkku) - Customize `HarvesterDumpRate` (by Noble_Fish) - Allow users to define the time interval of `DisplayIncome` (by Noble_Fish) +- [Electric bolt Z-adjust](Fixed-or-Improved-Logics.md#electric-bolt-z-adjust) (by Noble_Fish) +- Allow disabling the processing of the Z-depth of EBolt drawn by BuildingType being clamped to non-positive numbers (by Noble_Fish) +- Add the `Bolt.ZAdjust` setting item to the LaserTrailType with `DrawType=ebolt` (by Noble_Fish) Vanilla fixes: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) diff --git a/src/Ext/Bullet/Body.cpp b/src/Ext/Bullet/Body.cpp index 6571a5b149..2e558ea0bd 100644 --- a/src/Ext/Bullet/Body.cpp +++ b/src/Ext/Bullet/Body.cpp @@ -238,7 +238,18 @@ inline void BulletExt::SimulatedFiringElectricBolt(BulletClass* pBullet) pBolt->AlternateColor = pWeapon->IsAlternateColor; const auto targetCoords = pBullet->Type->Inviso ? pBullet->Location : pBullet->TargetCoords; - pBolt->Fire(pBullet->SourceCoords, targetCoords, 0); + const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon); + int zAdjust = pWeaponExt->EBoltZAdjust.Get(RulesExt::Global()->EBoltZAdjust); + + const auto pOwner = pBullet->Owner; + if (pOwner && pOwner->WhatAmI() == AbstractType::Building) + { + const bool clamp = pWeaponExt->EBoltZAdjust_ClampInitialDepthForBuilding.Get(RulesExt::Global()->EBoltZAdjust_ClampInitialDepthForBuilding); + if (clamp && zAdjust > 0) + zAdjust = 0; + } + + pBolt->Fire(pBullet->SourceCoords, targetCoords, zAdjust); if (const auto particle = WeaponTypeExt::ExtMap.Find(pWeapon)->Bolt_ParticleSystem.Get(RulesClass::Instance->DefaultSparkSystem)) GameCreate(particle, targetCoords, nullptr, nullptr, CoordStruct::Empty, nullptr); diff --git a/src/Ext/EBolt/Hooks.cpp b/src/Ext/EBolt/Hooks.cpp index 2b7b40b52f..083b441235 100644 --- a/src/Ext/EBolt/Hooks.cpp +++ b/src/Ext/EBolt/Hooks.cpp @@ -185,3 +185,37 @@ DEFINE_HOOK(0x4C2A02, EBolt_DestroyVector, 0x6) return SkipGameCode; } #pragma endregion + +DEFINE_HOOK(0x6FD4E4, TechnoClass_FireEBolt_Building_ClampPositive, 0x9) +{ + GET_STACK(WeaponTypeClass*, pWeapon, STACK_OFFSET(0x30, 0x8)); + GET(CoordStruct*, pV13, EAX); + GET(int, Y, ESI); + + int zAdjust = Y - pV13->Y; + + const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon); + const bool clamp = pWeaponExt->EBoltZAdjust_ClampInitialDepthForBuilding.Get(RulesExt::Global()->EBoltZAdjust_ClampInitialDepthForBuilding); + + if (clamp && zAdjust > 0) + zAdjust = 0; + + R->ESI(zAdjust); + + return 0x6FD4ED; +} + +DEFINE_HOOK(0x6FD4ED, TechnoClass_FireEBolt_ZAdjust, 0x7) +{ + GET_STACK(TechnoClass*, pTarget, STACK_OFFSET(0x30, 0x4)); + GET_STACK(WeaponTypeClass*, pWeapon, STACK_OFFSET(0x30, 0x8)); + GET(int, zAdjust, ESI); + + const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon); + zAdjust += pWeaponExt->EBoltZAdjust.Get(RulesExt::Global()->EBoltZAdjust); + + R->ESI(zAdjust); + R->ECX(pTarget); + + return (pTarget ? 0x6FD4F5 : 0x6FD50A); +} diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 562488fbc2..8f26852261 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -198,6 +198,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->AirstrikeLineZAdjust.Read(exINI, GameStrings::AudioVisual, "AirstrikeLineZAdjust"); this->LaserZAdjust.Read(exINI, GameStrings::AudioVisual, "LaserZAdjust"); + this->EBoltZAdjust.Read(exINI, GameStrings::AudioVisual, "EBoltZAdjust"); + this->EBoltZAdjust_ClampInitialDepthForBuilding.Read(exINI, GameStrings::AudioVisual, "EBoltZAdjust.ClampInitialDepthForBuilding"); this->CrateOnlyOnLand.Read(exINI, GameStrings::CrateRules, "CrateOnlyOnLand"); this->UnitCrateVehicleCap.Read(exINI, GameStrings::CrateRules, "UnitCrateVehicleCap"); @@ -573,6 +575,8 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->AirstrikeLineColor) .Process(this->AirstrikeLineZAdjust) .Process(this->LaserZAdjust) + .Process(this->EBoltZAdjust) + .Process(this->EBoltZAdjust_ClampInitialDepthForBuilding) .Process(this->ROF_RandomDelay) .Process(this->ToolTip_Background_Color) .Process(this->ToolTip_Background_Opacity) diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 6858d74959..46fa6c8b83 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -145,6 +145,8 @@ class RulesExt Valueable AirstrikeLineZAdjust; Valueable LaserZAdjust; + Valueable EBoltZAdjust; + Valueable EBoltZAdjust_ClampInitialDepthForBuilding; Valueable> ROF_RandomDelay; Valueable ToolTip_Background_Color; @@ -453,6 +455,8 @@ class RulesExt , AirstrikeLineColor { { 255, 0, 0 } } , AirstrikeLineZAdjust { 0 } , LaserZAdjust { 0 } + , EBoltZAdjust { 0 } + , EBoltZAdjust_ClampInitialDepthForBuilding { true } , ROF_RandomDelay { { 0 ,2 } } , ToolTip_Background_Color { { 0, 0, 0 } } , ToolTip_Background_Opacity { 100 } diff --git a/src/Ext/WeaponType/Body.cpp b/src/Ext/WeaponType/Body.cpp index 8f425ef816..f98678cfdc 100644 --- a/src/Ext/WeaponType/Body.cpp +++ b/src/Ext/WeaponType/Body.cpp @@ -118,6 +118,8 @@ void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->FeedbackWeapon.Read(exINI, pSection, "FeedbackWeapon"); this->Laser_IsSingleColor.Read(exINI, pSection, "IsSingleColor"); this->LaserZAdjust.Read(exINI, pSection, "LaserZAdjust"); + this->EBoltZAdjust.Read(exINI, pSection, "EBoltZAdjust"); + this->EBoltZAdjust_ClampInitialDepthForBuilding.Read(exINI, pSection, "EBoltZAdjust.ClampInitialDepthForBuilding"); this->VisualScatter.Read(exINI, pSection, "VisualScatter"); this->ROF_RandomDelay.Read(exINI, pSection, "ROF.RandomDelay"); this->ChargeTurret_Delays.Read(exINI, pSection, "ChargeTurret.Delays"); @@ -215,6 +217,8 @@ void WeaponTypeExt::ExtData::Serialize(T& Stm) .Process(this->FeedbackWeapon) .Process(this->Laser_IsSingleColor) .Process(this->LaserZAdjust) + .Process(this->EBoltZAdjust) + .Process(this->EBoltZAdjust_ClampInitialDepthForBuilding) .Process(this->VisualScatter) .Process(this->ROF_RandomDelay) .Process(this->ChargeTurret_Delays) diff --git a/src/Ext/WeaponType/Body.h b/src/Ext/WeaponType/Body.h index 5bce0d80fd..5bb8734a4b 100644 --- a/src/Ext/WeaponType/Body.h +++ b/src/Ext/WeaponType/Body.h @@ -46,6 +46,8 @@ class WeaponTypeExt Valueable FeedbackWeapon; Valueable Laser_IsSingleColor; Nullable LaserZAdjust; + Nullable EBoltZAdjust; + Nullable EBoltZAdjust_ClampInitialDepthForBuilding; Valueable VisualScatter; Nullable> ROF_RandomDelay; ValueableVector ChargeTurret_Delays; @@ -133,6 +135,8 @@ class WeaponTypeExt , FeedbackWeapon {} , Laser_IsSingleColor { false } , LaserZAdjust {} + , EBoltZAdjust {} + , EBoltZAdjust_ClampInitialDepthForBuilding {} , VisualScatter { false } , ROF_RandomDelay {} , ChargeTurret_Delays {} diff --git a/src/New/Entity/LaserTrailClass.cpp b/src/New/Entity/LaserTrailClass.cpp index 4fa07db49e..d0e9362378 100644 --- a/src/New/Entity/LaserTrailClass.cpp +++ b/src/New/Entity/LaserTrailClass.cpp @@ -60,7 +60,7 @@ bool LaserTrailClass::Update(CoordStruct location) pBolt->Lifetime = 1 << (std::clamp(pType->FadeDuration.Get(17), 1, 31) - 1); pBolt->AlternateColor = pType->IsAlternateColor; - pBolt->Fire(this->LastLocation, location, 0); + pBolt->Fire(this->LastLocation, location, pType->Bolt_ZAdjust); } else if (pType->DrawType == LaserTrailDrawType::RadBeam) { diff --git a/src/New/Type/LaserTrailTypeClass.cpp b/src/New/Type/LaserTrailTypeClass.cpp index 64d93d7bfd..34b114ed37 100644 --- a/src/New/Type/LaserTrailTypeClass.cpp +++ b/src/New/Type/LaserTrailTypeClass.cpp @@ -34,6 +34,7 @@ void LaserTrailTypeClass::LoadFromINI(CCINIClass* pINI) } this->Bolt_Arcs.Read(exINI, section, "Bolt.Arcs"); + this->Bolt_ZAdjust.Read(exINI, section, "Bolt.ZAdjust"); this->Beam_Color.Read(exINI, section, "Beam.Color"); this->Beam_Amplitude.Read(exINI, section, "Beam.Amplitude"); @@ -60,6 +61,7 @@ void LaserTrailTypeClass::Serialize(T& Stm) .Process(this->Bolt_Color) .Process(this->Bolt_Disable) .Process(this->Bolt_Arcs) + .Process(this->Bolt_ZAdjust) .Process(this->Beam_Color) .Process(this->Beam_Amplitude) .Process(this->FadeDuration) diff --git a/src/New/Type/LaserTrailTypeClass.h b/src/New/Type/LaserTrailTypeClass.h index a247048cd8..bc0c4241e5 100644 --- a/src/New/Type/LaserTrailTypeClass.h +++ b/src/New/Type/LaserTrailTypeClass.h @@ -14,6 +14,7 @@ class LaserTrailTypeClass final : public Enumerable Nullable Bolt_Color[3]; Valueable Bolt_Disable[3]; Valueable Bolt_Arcs; + Valueable Bolt_ZAdjust; Nullable Beam_Color; Valueable Beam_Amplitude; Nullable FadeDuration; @@ -34,6 +35,7 @@ class LaserTrailTypeClass final : public Enumerable , Bolt_Color {} , Bolt_Disable { Valueable(false) } , Bolt_Arcs { 8 } + , Bolt_ZAdjust { 0 } , Beam_Color {} , Beam_Amplitude { 40.0 } , FadeDuration {}