From fe6d738bde2d2fdd1f6aa295386479dc58656e77 Mon Sep 17 00:00:00 2001 From: Starkku Date: Tue, 25 Jun 2024 16:20:37 +0300 Subject: [PATCH 01/54] Allow strafing weapons to fired at air targets if otherwise not restricted --- src/Ext/Aircraft/Hooks.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Ext/Aircraft/Hooks.cpp b/src/Ext/Aircraft/Hooks.cpp index 7c3cda14da..2691fb7dde 100644 --- a/src/Ext/Aircraft/Hooks.cpp +++ b/src/Ext/Aircraft/Hooks.cpp @@ -69,6 +69,34 @@ DEFINE_HOOK(0x417FF1, AircraftClass_Mission_Attack_StrafeShots, 0x6) return 0; } +// If strafing weapon target is in air, consider the cell it is on as the firing position instead of the object itself if can fire at it. +DEFINE_HOOK(0x4197F3, AircraftClass_GetFireLocation_Strafing, 0x5) +{ + GET(AircraftClass*, pThis, EDI); + GET(AbstractClass*, pTarget, EAX); + + if (!pTarget) + return 0; + + auto const pObject = abstract_cast(pTarget); + + if (!pObject || !pObject->IsInAir()) + return 0; + + auto const pExt = TechnoExt::ExtMap.Find(pThis); + int weaponIndex = pExt->CurrentAircraftWeaponIndex; + + if (weaponIndex < 0) + weaponIndex = pThis->SelectWeapon(pTarget); + + if (pThis->GetFireError(pTarget, weaponIndex, false) != FireError::OK) + return 0; + + R->EAX(MapClass::Instance->GetCellAt(pObject->GetCoords())); + + return 0; +} + long __stdcall AircraftClass_IFlyControl_IsStrafe(IFlyControl const* ifly) { __assume(ifly != nullptr); From 80309479e5cb68a502df96809bea631eca5024df Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 25 Jun 2024 21:25:10 +0800 Subject: [PATCH 02/54] New Engrave trajectory --- CREDITS.md | 2 + Phobos.vcxproj | 2 + docs/New-or-Enhanced-Logics.md | 58 ++- docs/Whats-New.md | 1 + src/Ext/Bullet/Hooks.cpp | 23 +- .../Bullet/Trajectories/EngraveTrajectory.cpp | 399 ++++++++++++++++++ .../Bullet/Trajectories/EngraveTrajectory.h | 142 +++++++ .../Bullet/Trajectories/PhobosTrajectory.cpp | 32 ++ .../Bullet/Trajectories/PhobosTrajectory.h | 1 + src/Ext/Techno/Body.Internal.cpp | 24 +- src/Ext/Techno/Body.cpp | 2 + src/Ext/Techno/Body.h | 8 +- src/Ext/Techno/Hooks.Firing.cpp | 24 +- 13 files changed, 694 insertions(+), 24 deletions(-) create mode 100644 src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp create mode 100644 src/Ext/Bullet/Trajectories/EngraveTrajectory.h diff --git a/CREDITS.md b/CREDITS.md index 521e2dde1e..f62ab8aa3a 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -332,6 +332,8 @@ This page lists all the individual contributions to the project by their author. - Re-enable the Veinhole Monster and Weeds from TS - Recreate the weed-charging of SWs like the TS Chemical Missile - Allow to change the speed of gas particles +- **CrimRecya** + - New Engrave trajectory - **Ares developers** - YRpp and Syringe which are used, save/load, project foundation and generally useful code from Ares - unfinished RadTypes code diff --git a/Phobos.vcxproj b/Phobos.vcxproj index 67e89c2fae..0a4e156ed5 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -38,6 +38,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 95e236a03e..c9250cd711 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -80,7 +80,7 @@ Animation.OfflineAction=Hides ; AttachedAnimFlag (None, Hides, Animation.TemporalAction=None ; AttachedAnimFlag (None, Hides, Temporal, Paused or PausedTemporal) Animation.UseInvokerAsOwner=false ; boolean CumulativeAnimations= ; list of animations -ExpireWeapon= +ExpireWeapon= ExpireWeapon.TriggerOn=expire ; List of expire weapon trigger condition enumeration (none|expire|remove|death|all) ExpireWeapon.CumulativeOnlyOnce=false ; boolean Tint.Color= ; integer - R,G,B @@ -105,7 +105,7 @@ RevengeWeapon= ; WeaponType RevengeWeapon.AffectsHouses=all ; list of Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all) DisableWeapons=false ; boolean Groups= ; comma-separated list of strings (group IDs) - + [SOMETECHNO] ; TechnoType AttachEffect.AttachTypes= ; List of AttachEffectTypes AttachEffect.DurationOverrides= ; integer - duration overrides (comma-separated) for AttachTypes in order from first to last. @@ -125,8 +125,8 @@ AttachEffect.RequiredMaxCounts= ; integer - maximum required inst AttachEffect.DisallowedMinCounts= ; integer - minimum disallowed instance count (comma-separated) for cumulative types in order from first to last. AttachEffect.DisallowedMaxCounts= ; integer - maximum disallowed instance count (comma-separated) for cumulative types in order from first to last. AttachEffect.IgnoreFromSameSource=false ; boolean - -[SOMEWARHEAD] + +[SOMEWARHEAD] AttachEffect.AttachTypes= ; List of AttachEffectTypes AttachEffect.RemoveTypes= ; List of AttachEffectTypes AttachEffect.RemoveGroups= ; comma-separated list of strings (group IDs) @@ -624,7 +624,10 @@ Currently interceptor weapons with projectiles that do not have `Inviso=true` wi - Projectiles can now have customizable trajectories. - `Trajectory` should not be combined with original game's projectile trajectory logics (`Arcing`, `ROT`, `Vertical` or `Inviso`). Attempt to do so will result in the other logics being disabled and a warning being written to log file. - - Initial speed of the projectile is defined by `Trajectory.Speed`, which unlike `Speed` used by `ROT` > 0 projectiles is defined on projectile not weapon. + - The speed of the projectile is defined by `Trajectory.Speed`, which unlike `Speed` used by `ROT` > 0 projectiles is defined on projectile not weapon. + - In `Trajectory=Straight`, it refers to the whole distance speed of the projectile and it has no restrictions. + - In `Trajectory=Bombard`, it refers to the initial speed of the projectile and it has no restrictions. + - In `Trajectory=Engrave`, it refers to the engrave speed of the projectile and it cannot exceed 128. Recommend set as about 40. In `rulesmd.ini`: ```ini @@ -662,6 +665,49 @@ Trajectory=Bombard ; Trajectory type Trajectory.Bombard.Height=0.0 ; double ``` +#### Engrave trajectory + +- Visually, like the thermal lance. Calling it 'trajectory' may not be appropriate. It does not read the settings on the weapon. + - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. + - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. + - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. + - `Trajectory.Engrave.TheDuration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. + - `Trajectory.Engrave.IsLaser` controls whether laser drawing is required. + - `Trajectory.Engrave.IsSupported` controls whether the engrave laser will be brighter and thicker. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. + - `Trajectory.Engrave.IsHouseColor` controls whether set the engrave laser to draw using player's team color. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsSupported`. + - `Trajectory.Engrave.IsSingleColor` controls whether set the engrave laser to draw using only `Trajectory.Engrave.LaserInnerColor`. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsSupported`. + - `Trajectory.Engrave.LaserInnerColor` controls the inner color of the engrave laser. + - `Trajectory.Engrave.LaserOuterColor` controls the outer color of the engrave laser. + - `Trajectory.Engrave.LaserOuterSpread` controls the spread color of the engrave laser. + - `Trajectory.Engrave.LaserThickness` controls the thickness of the engrave laser. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. + - `Trajectory.Engrave.LaserDuration` controls the duration of the engrave laser. + - `Trajectory.Engrave.LaserDelay` controls how often to draw the engrave laser. + - `Trajectory.Engrave.DamageDelay` controls how often to detonate warheads. + +In `rulesmd.ini`: +```ini +Trajectory=Engrave ; Trajectory type +Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral +Trajectory.Engrave.TargetCoord=0,0 ; integer - Forward,Lateral +Trajectory.Engrave.MirrorCoord=true ; boolean +Trajectory.Engrave.TheDuration=0 ; integer +Trajectory.Engrave.IsLaser=true ; boolean +Trajectory.Engrave.IsSupported=false ; boolean +Trajectory.Engrave.IsHouseColor=false ; boolean +Trajectory.Engrave.IsSingleColor=false ; boolean +Trajectory.Engrave.LaserInnerColor=0,0,0 ; integer - Red,Green,Blue +Trajectory.Engrave.LaserOuterColor=0,0,0 ; integer - Red,Green,Blue +Trajectory.Engrave.LaserOuterSpread=0,0,0 ; integer - Red,Green,Blue +Trajectory.Engrave.LaserThickness=3 ; integer +Trajectory.Engrave.LaserDuration=1 ; integer +Trajectory.Engrave.LaserDelay=1 ; integer +Trajectory.Engrave.DamageDelay=2 ; integer +``` + +```{note} +- It's best not to let it be intercepted. +``` + ### Shrapnel enhancements ![image](_static/images/shrapnel.gif) @@ -1500,7 +1546,7 @@ FeedbackWeapon= ; WeaponType - `Strafing.Shots` controls the number of times the weapon is fired during a single strafe run. `Ammo` is only deducted at the end of the strafe run, regardless of the number of shots fired. - `Strafing.SimulateBurst` controls whether or not the shots fired during strafing simulate behavior of `Burst`, allowing for alternating firing offset. Only takes effect if weapon has `Burst` set to 1 or undefined. - `Strafing.UseAmmoPerShot`, if set to `true` overrides the usual behaviour of only deducting ammo after a strafing run and instead doing it after each individual shot. - + In `rulesmd.ini`: ```ini [SOMEWEAPON] ; WeaponType diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 662db69c9c..8447d4c213 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -413,6 +413,7 @@ New: - Allow customizing Aircraft weapon strafing regardless of `ROT` and `Strafing.Shots` values beyond 5 (by Trsdy) - Allow strafing weapons to deduct ammo per shot instead of per strafing run (by Starkku) - Allow setting which houses can see `CloakVisible=true` laser trails (by Starkku) +- New Engrave trajectory (by CrimRecya) Vanilla fixes: - Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 8aa7bdff16..9518446125 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -64,6 +64,12 @@ DEFINE_HOOK(0x4666F7, BulletClass_AI, 0x6) } } + //Because the laser trails will be drawn before the calculation of changing the velocity direction in each frame. + //This will cause the laser trails to be drawn in the wrong position too early, resulting in a visual appearance resembling a "bouncing". + //Let trajectories draw their own laser trails after the Trajectory‘s OnAI() to avoid predicting incorrect positions or pass through targets. + if (pBulletExt->Trajectory) + return 0; + // LaserTrails update routine is in BulletClass::AI hook because BulletClass::Draw // doesn't run when the object is off-screen which leads to visual bugs - Kerbiter if (pBulletExt && pBulletExt->LaserTrails.size()) @@ -306,7 +312,8 @@ DEFINE_HOOK(0x467CCA, BulletClass_AI_TargetSnapChecks, 0x6) { if (pExt->Trajectory) { - if (pExt->Trajectory->Flag == TrajectoryFlag::Straight) + if (pExt->Trajectory->Flag == TrajectoryFlag::Straight + || pExt->Trajectory->Flag == TrajectoryFlag::Engrave) { R->EAX(pThis->Type); return SkipChecks; @@ -335,7 +342,9 @@ DEFINE_HOOK(0x468E61, BulletClass_Explode_TargetSnapChecks1, 0x6) } else if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (pExt->Trajectory && pExt->Trajectory->Flag == TrajectoryFlag::Straight && !pExt->SnappedToTarget) + if (pExt->Trajectory && !pExt->SnappedToTarget + && (pExt->Trajectory->Flag == TrajectoryFlag::Straight + || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) { R->EAX(pThis->Type); return SkipChecks; @@ -366,8 +375,13 @@ DEFINE_HOOK(0x468E9F, BulletClass_Explode_TargetSnapChecks2, 0x6) // Fixes issues with walls etc. if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (pExt->Trajectory && pExt->Trajectory->Flag == TrajectoryFlag::Straight && !pExt->SnappedToTarget) + + if (pExt->Trajectory && !pExt->SnappedToTarget + && (pExt->Trajectory->Flag == TrajectoryFlag::Straight + || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) + { return SkipSetCoordinate; + } } return 0; @@ -381,7 +395,8 @@ DEFINE_HOOK(0x468D3F, BulletClass_ShouldExplode_AirTarget, 0x6) if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (pExt->Trajectory && pExt->Trajectory->Flag == TrajectoryFlag::Straight) + if (pExt->Trajectory && (pExt->Trajectory->Flag == TrajectoryFlag::Straight + || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) return SkipCheck; } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp new file mode 100644 index 0000000000..fff510352f --- /dev/null +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -0,0 +1,399 @@ +#include "EngraveTrajectory.h" +#include +#include +#include +#include + +bool EngraveTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) +{ + this->PhobosTrajectoryType::Load(Stm, false); + + Stm + .Process(this->SourceCoord, false) + .Process(this->TargetCoord, false) + .Process(this->MirrorCoord, false) + .Process(this->TheDuration, false) + .Process(this->IsLaser, false) + .Process(this->IsSupported, false) + .Process(this->IsHouseColor, false) + .Process(this->IsSingleColor, false) + .Process(this->LaserInnerColor, false) + .Process(this->LaserOuterColor, false) + .Process(this->LaserOuterSpread, false) + .Process(this->LaserThickness, false) + .Process(this->LaserDuration, false) + .Process(this->LaserDelay, false) + .Process(this->DamageDelay, false) + ; + + return true; +} + +bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const +{ + this->PhobosTrajectoryType::Save(Stm); + + Stm + .Process(this->SourceCoord) + .Process(this->TargetCoord) + .Process(this->MirrorCoord) + .Process(this->TheDuration) + .Process(this->IsLaser) + .Process(this->IsSupported) + .Process(this->IsHouseColor) + .Process(this->IsSingleColor) + .Process(this->LaserInnerColor) + .Process(this->LaserOuterColor) + .Process(this->LaserOuterSpread) + .Process(this->LaserThickness) + .Process(this->LaserDuration) + .Process(this->LaserDelay) + .Process(this->DamageDelay) + ; + + return true; +} + +void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) +{ + INI_EX exINI(pINI); + this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); + this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); + this->MirrorCoord.Read(exINI, pSection, "Trajectory.Engrave.MirrorCoord"); + this->TheDuration.Read(exINI, pSection, "Trajectory.Engrave.TheDuration"); + this->IsLaser.Read(exINI, pSection, "Trajectory.Engrave.IsLaser"); + this->IsSupported.Read(exINI, pSection, "Trajectory.Engrave.IsSupported"); + this->IsHouseColor.Read(exINI, pSection, "Trajectory.Engrave.IsHouseColor"); + this->IsSingleColor.Read(exINI, pSection, "Trajectory.Engrave.IsSingleColor"); + this->LaserInnerColor.Read(exINI, pSection, "Trajectory.Engrave.LaserInnerColor"); + this->LaserOuterColor.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterColor"); + this->LaserOuterSpread.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterSpread"); + this->LaserThickness.Read(exINI, pSection, "Trajectory.Engrave.LaserThickness"); + this->LaserDuration.Read(exINI, pSection, "Trajectory.Engrave.LaserDuration"); + this->LaserDelay.Read(exINI, pSection, "Trajectory.Engrave.LaserDelay"); + this->DamageDelay.Read(exINI, pSection, "Trajectory.Engrave.DamageDelay"); +} + +bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) +{ + this->PhobosTrajectory::Load(Stm, false); + + Stm + .Process(this->SourceCoord) + .Process(this->TargetCoord) + .Process(this->MirrorCoord) + .Process(this->TheDuration) + .Process(this->IsLaser) + .Process(this->IsSupported) + .Process(this->IsHouseColor) + .Process(this->IsSingleColor) + .Process(this->LaserInnerColor) + .Process(this->LaserOuterColor) + .Process(this->LaserOuterSpread) + .Process(this->LaserThickness) + .Process(this->LaserDuration) + .Process(this->LaserDelay) + .Process(this->DamageDelay) + .Process(this->LaserTimer) + .Process(this->DamageTimer) + .Process(this->TechnoInLimbo) + .Process(this->NotMainWeapon) + .Process(this->FirepowerMult) + .Process(this->FLHCoord) + .Process(this->TemporaryCoord) + ; + + return true; +} + +bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const +{ + this->PhobosTrajectory::Save(Stm); + + Stm + .Process(this->SourceCoord) + .Process(this->TargetCoord) + .Process(this->MirrorCoord) + .Process(this->TheDuration) + .Process(this->IsLaser) + .Process(this->IsSupported) + .Process(this->IsHouseColor) + .Process(this->IsSingleColor) + .Process(this->LaserInnerColor) + .Process(this->LaserOuterColor) + .Process(this->LaserOuterSpread) + .Process(this->LaserThickness) + .Process(this->LaserDuration) + .Process(this->LaserDelay) + .Process(this->DamageDelay) + .Process(this->LaserTimer) + .Process(this->DamageTimer) + .Process(this->TechnoInLimbo) + .Process(this->NotMainWeapon) + .Process(this->FirepowerMult) + .Process(this->FLHCoord) + .Process(this->TemporaryCoord) + ; + + return true; +} + +void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) +{ + auto const pType = this->GetTrajectoryType(pBullet); + + this->SourceCoord = pType->SourceCoord; + this->TargetCoord = pType->TargetCoord; + this->MirrorCoord = pType->MirrorCoord; + this->TheDuration = pType->TheDuration; + this->IsLaser = pType->IsLaser; + this->IsSupported = pType->IsSupported; + this->IsHouseColor = pType->IsHouseColor; + this->IsSingleColor = pType->IsSingleColor; + this->LaserInnerColor = pType->LaserInnerColor; + this->LaserOuterColor = pType->LaserOuterColor; + this->LaserOuterSpread = pType->LaserOuterSpread; + this->LaserThickness = pType->LaserThickness > 0 ? pType->LaserThickness : 1; + this->LaserDuration = pType->LaserDuration > 0 ? pType->LaserDuration : 1; + this->LaserDelay = pType->LaserDelay > 0 ? pType->LaserDelay : 1; + this->DamageDelay = pType->DamageDelay > 0 ? pType->DamageDelay : 1; + this->LaserTimer.StartTime = 0; + this->DamageTimer.StartTime = 0; + this->TemporaryCoord = CoordStruct::Empty; + this->FLHCoord = pBullet->SourceCoords; + + if (pBullet->Owner) + { + this->TechnoInLimbo = pBullet->Owner->InLimbo; + this->NotMainWeapon = false; + this->FirepowerMult = pBullet->Owner->FirepowerMultiplier; + + this->GetTechnoFLHCoord(pBullet); + this->CheckMirrorCoord(pBullet->Owner); + this->SetEngraveDirection(pBullet, pBullet->Owner->GetCoords(), pBullet->TargetCoords); + } + else + { + this->TechnoInLimbo = false; + this->NotMainWeapon = true; + this->FirepowerMult = 1.0; + + this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); + } + + double StraightSpeed = this->GetTrajectorySpeed(pBullet); + StraightSpeed = StraightSpeed > 128.0 ? 128.0 : StraightSpeed; + const double CoordDistance = pBullet->Velocity.Magnitude(); + pBullet->Velocity *= (CoordDistance > 0) ? (StraightSpeed / CoordDistance) : 0; + + if (this->TheDuration <= 0) + this->TheDuration = static_cast(CoordDistance / StraightSpeed) + 1; +} + +bool EngraveTrajectory::OnAI(BulletClass* pBullet) +{ + if ((!pBullet->Owner && !this->NotMainWeapon) || this->TechnoInLimbo != pBullet->Owner->InLimbo) + return true; + + if (--this->TheDuration < 0) + return true; + else if (this->PlaceOnCorrectHeight(pBullet)) + return true; + + TechnoClass* const pTechno = pBullet->Owner; + HouseClass* const pOwner = pBullet->Owner->Owner; + + if (this->IsLaser && this->LaserTimer.Completed() && this->DrawEngraveLaser(pBullet, pTechno, pOwner)) + return true; + + if (this->DamageTimer.Completed()) + this->DetonateLaserWarhead(pBullet, pTechno, pOwner); + + return false; +} + +void EngraveTrajectory::OnAIPreDetonate(BulletClass* pBullet) +{ + pBullet->UnInit(); //Prevent damage again. +} + +void EngraveTrajectory::OnAIVelocity(BulletClass* pBullet, BulletVelocity* pSpeed, BulletVelocity* pPosition) +{ + pSpeed->Z += BulletTypeExt::GetAdjustedGravity(pBullet->Type); +} + +TrajectoryCheckReturnType EngraveTrajectory::OnAITargetCoordCheck(BulletClass* pBullet) +{ + return TrajectoryCheckReturnType::SkipGameCheck; +} + +TrajectoryCheckReturnType EngraveTrajectory::OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) +{ + return TrajectoryCheckReturnType::SkipGameCheck; +} + +void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet) +{ + auto const pExt = TechnoExt::ExtMap.Find(pBullet->Owner); + + if (!pExt || !pExt->LastWeaponStruct || !pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type) + this->NotMainWeapon = true; + else + this->FLHCoord = pExt->LastWeaponFLH; +} + +void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) +{ + if (pTechno->CurrentBurstIndex % 2 == 0) + return; + + if (this->MirrorCoord) + { + this->SourceCoord.Y = -(this->SourceCoord.Y); + this->TargetCoord.Y = -(this->TargetCoord.Y); + } +} + +void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct Source, CoordStruct Target) +{ + const double RotateAngle = Math::atan2(Target.Y - Source.Y , Target.X - Source.X); + + if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) + { + Source = Target; + Source.X += static_cast(this->SourceCoord.X * Math::cos(RotateAngle) + this->SourceCoord.Y * Math::sin(RotateAngle)); + Source.Y += static_cast(this->SourceCoord.X * Math::sin(RotateAngle) - this->SourceCoord.Y * Math::cos(RotateAngle)); + } + + Source.Z = this->GetFloorCoordHeight(pBullet, Source); + pBullet->SetLocation(Source); + + Target.X += static_cast(this->TargetCoord.X * Math::cos(RotateAngle) + this->TargetCoord.Y * Math::sin(RotateAngle)); + Target.Y += static_cast(this->TargetCoord.X * Math::sin(RotateAngle) - this->TargetCoord.Y * Math::cos(RotateAngle)); + + pBullet->Velocity.X = Target.X - Source.X; + pBullet->Velocity.Y = Target.Y - Source.Y; + pBullet->Velocity.Z = 0; +} + +int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct Coord) +{ + if (const CellClass* const pCell = MapClass::Instance->GetCellAt(Coord)) + { + const int OnFloor = MapClass::Instance->GetCellFloorHeight(Coord); + const int OnBridge = pCell->GetCoordsWithBridge().Z; + + if (pBullet->SourceCoords.Z >= OnBridge || pBullet->TargetCoords.Z >= OnBridge) + return OnBridge; + + return OnFloor; + } + + return Coord.Z; +} + +bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) +{ + CoordStruct BulletCoords = pBullet->Location; + + if (this->TemporaryCoord != CoordStruct::Empty) + { + pBullet->SetLocation(this->TemporaryCoord); + this->TemporaryCoord = CoordStruct::Empty; + } + + CoordStruct FutureCoords + { + BulletCoords.X + static_cast(pBullet->Velocity.X), + BulletCoords.Y + static_cast(pBullet->Velocity.Y), + BulletCoords.Z + static_cast(pBullet->Velocity.Z) + }; + + const int CheckDifference = this->GetFloorCoordHeight(pBullet, FutureCoords) - FutureCoords.Z; + + if (abs(CheckDifference) >= 384) + { + if (pBullet->Type->SubjectToCliffs) + { + return true; + } + else if (CheckDifference > 0) + { + BulletCoords.Z += CheckDifference; + pBullet->SetLocation(BulletCoords); + } + else + { + FutureCoords.Z += CheckDifference; + this->TemporaryCoord = FutureCoords; + } + } + else + { + pBullet->Velocity.Z += CheckDifference; + } + + return false; +} + +bool EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) +{ + this->LaserTimer.Start(this->LaserDelay); + LaserDrawClass* pLaser; + CoordStruct FireCoord = pTechno->GetCoords(); + + if (this->NotMainWeapon) + { + FireCoord = this->FLHCoord; + } + else if (pTechno->WhatAmI() != AbstractType::Building) + { + if (this->TechnoInLimbo) + { + if (TechnoClass* const pTransporter = pTechno->Transporter) + FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTransporter, this->FLHCoord, pTransporter->HasTurret()); + else + return true; + } + else + { + FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); + } + } + else // TODO Not accurate now, just get the similar FLH. + { + const double RotateAngle = pTechno->HasTurret() ? -(pTechno->TurretFacing().GetRadian<32>()) : -(pTechno->PrimaryFacing.Current().GetRadian<32>()); + FireCoord.X += static_cast(this->FLHCoord.X * Math::cos(RotateAngle) + this->FLHCoord.Y * Math::sin(RotateAngle)); + FireCoord.Y += static_cast(this->FLHCoord.X * Math::sin(RotateAngle) - this->FLHCoord.Y * Math::cos(RotateAngle)); + + if (const BuildingTypeClass* const pBuildingType = static_cast(pTechno->GetTechnoType())) + FireCoord.Z += this->FLHCoord.Z + 30 * (pBuildingType->GetFoundationWidth() + pBuildingType->GetFoundationHeight(false) + 2); + } + + if (this->IsHouseColor) + { + pLaser = GameCreate(FireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser->IsHouseColor = true; + } + else if (this->IsSingleColor) + { + pLaser = GameCreate(FireCoord, pBullet->Location, this->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser->IsHouseColor = true; + } + else + { + pLaser = GameCreate(FireCoord, pBullet->Location, this->LaserInnerColor, this->LaserOuterColor, this->LaserOuterSpread, this->LaserDuration); + pLaser->IsHouseColor = false; + } + + pLaser->Thickness = this->LaserThickness; + pLaser->IsSupported = this->IsSupported; + + return false; +} + +void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) +{ + this->DamageTimer.Start(this->DamageDelay); + WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, static_cast(pBullet->Health * this->FirepowerMult), pOwner); +} diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h new file mode 100644 index 0000000000..5b78576e29 --- /dev/null +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -0,0 +1,142 @@ +#pragma once + +#include "PhobosTrajectory.h" + +class EngraveTrajectoryType final : public PhobosTrajectoryType +{ +public: + EngraveTrajectoryType() : PhobosTrajectoryType(TrajectoryFlag::Engrave) + , SourceCoord { { 0, 0 } } + , TargetCoord { { 0, 0 } } + , MirrorCoord { true } + , TheDuration { 0 } + , IsLaser { true } + , IsSupported { false } + , IsHouseColor { false } + , IsSingleColor { false } + , LaserInnerColor { { 0, 0, 0 } } + , LaserOuterColor { { 0, 0, 0 } } + , LaserOuterSpread { { 0, 0, 0 } } + , LaserThickness { 3 } + , LaserDuration { 1 } + , LaserDelay { 1 } + , DamageDelay { 2 } + {} + + virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; + virtual bool Save(PhobosStreamWriter& Stm) const override; + + virtual void Read(CCINIClass* const pINI, const char* pSection) override; + + Valueable SourceCoord; + Valueable TargetCoord; + Valueable MirrorCoord; + Valueable TheDuration; + Valueable IsLaser; + Valueable IsSupported; + Valueable IsHouseColor; + Valueable IsSingleColor; + Valueable LaserInnerColor; + Valueable LaserOuterColor; + Valueable LaserOuterSpread; + Valueable LaserThickness; + Valueable LaserDuration; + Valueable LaserDelay; + Valueable DamageDelay; +}; + +class EngraveTrajectory final : public PhobosTrajectory +{ +public: + EngraveTrajectory() : PhobosTrajectory(TrajectoryFlag::Engrave) + , SourceCoord {} + , TargetCoord {} + , MirrorCoord { true } + , TheDuration { 0 } + , IsLaser { true } + , IsSupported { false } + , IsHouseColor { false } + , IsSingleColor { false } + , LaserInnerColor {} + , LaserOuterColor {} + , LaserOuterSpread {} + , LaserThickness { 3 } + , LaserDuration { 1 } + , LaserDelay { 1 } + , DamageDelay { 2 } + , LaserTimer {} + , DamageTimer {} + , TechnoInLimbo { false } + , NotMainWeapon { false } + , FirepowerMult { 1.0 } + , FLHCoord {} + , TemporaryCoord {} + {} + + EngraveTrajectory(PhobosTrajectoryType* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) + , SourceCoord {} + , TargetCoord {} + , MirrorCoord { true } + , TheDuration { 0 } + , IsLaser { true } + , IsSupported { false } + , IsHouseColor { false } + , IsSingleColor { false } + , LaserInnerColor {} + , LaserOuterColor {} + , LaserOuterSpread {} + , LaserThickness { 3 } + , LaserDuration { 1 } + , LaserDelay { 1 } + , DamageDelay { 2 } + , LaserTimer {} + , DamageTimer {} + , TechnoInLimbo { false } + , NotMainWeapon { false } + , FirepowerMult { 1.0 } + , FLHCoord {} + , TemporaryCoord {} + {} + + virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; + virtual bool Save(PhobosStreamWriter& Stm) const override; + + virtual void OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) override; + virtual bool OnAI(BulletClass* pBullet) override; + virtual void OnAIPreDetonate(BulletClass* pBullet) override; + virtual void OnAIVelocity(BulletClass* pBullet, BulletVelocity* pSpeed, BulletVelocity* pPosition) override; + virtual TrajectoryCheckReturnType OnAITargetCoordCheck(BulletClass* pBullet) override; + virtual TrajectoryCheckReturnType OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) override; + + Point2D SourceCoord; + Point2D TargetCoord; + bool MirrorCoord; + int TheDuration; + bool IsLaser; + bool IsSupported; + bool IsHouseColor; + bool IsSingleColor; + ColorStruct LaserInnerColor; + ColorStruct LaserOuterColor; + ColorStruct LaserOuterSpread; + int LaserThickness; + int LaserDuration; + int LaserDelay; + int DamageDelay; + CDTimerClass LaserTimer; + CDTimerClass DamageTimer; + bool TechnoInLimbo; + bool NotMainWeapon; + double FirepowerMult; + CoordStruct FLHCoord; + CoordStruct TemporaryCoord; + +private: + void GetTechnoFLHCoord(BulletClass* pBullet); + void CheckMirrorCoord(TechnoClass* pTechno); + void SetEngraveDirection(BulletClass* pBullet, CoordStruct Source, CoordStruct Target); + int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct Coord); + bool PlaceOnCorrectHeight(BulletClass* pBullet); + bool DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); + void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); +}; diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index dc08efd637..9176807b59 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -9,6 +9,7 @@ #include "BombardTrajectory.h" #include "StraightTrajectory.h" +#include "EngraveTrajectory.h" bool PhobosTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) { @@ -34,6 +35,8 @@ void PhobosTrajectoryType::CreateType(PhobosTrajectoryType*& pType, CCINIClass* pNewType = DLLCreate(); else if (_stricmp(Phobos::readBuffer, "Bombard") == 0) pNewType = DLLCreate(); + else if (_stricmp(Phobos::readBuffer, "Engrave") == 0) + pNewType = DLLCreate(); else bUpdateType = false; @@ -65,6 +68,9 @@ PhobosTrajectoryType* PhobosTrajectoryType::LoadFromStream(PhobosStreamReader& S case TrajectoryFlag::Bombard: pType = DLLCreate(); break; + case TrajectoryFlag::Engrave: + pType = DLLCreate(); + break; default: return nullptr; } @@ -132,6 +138,10 @@ PhobosTrajectory* PhobosTrajectory::CreateInstance(PhobosTrajectoryType* pType, case TrajectoryFlag::Bombard: pRet = DLLCreate(pType); break; + + case TrajectoryFlag::Engrave: + pRet = DLLCreate(pType); + break; } if (pRet) @@ -158,6 +168,9 @@ PhobosTrajectory* PhobosTrajectory::LoadFromStream(PhobosStreamReader& Stm) case TrajectoryFlag::Bombard: pTraj = DLLCreate(); break; + case TrajectoryFlag::Engrave: + pTraj = DLLCreate(); + break; default: return nullptr; } @@ -207,6 +220,25 @@ DEFINE_HOOK(0x4666F7, BulletClass_AI_Trajectories, 0x6) if (detonate && !pThis->SpawnNextAnim) return Detonate; + //Correct positions for trajectory. + if (pExt->Trajectory && pExt->LaserTrails.size()) + { + CoordStruct FutureCoords + { + pThis->Location.X + static_cast(pThis->Velocity.X), + pThis->Location.Y + static_cast(pThis->Velocity.Y), + pThis->Location.Z + static_cast(pThis->Velocity.Z) + }; + + for (auto& trail : pExt->LaserTrails) + { + if (!trail.LastLocation.isset()) + trail.LastLocation = pThis->Location; + + trail.Update(FutureCoords); + } + } + return 0; } diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.h b/src/Ext/Bullet/Trajectories/PhobosTrajectory.h index 3e15586431..600f822dc9 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.h +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.h @@ -13,6 +13,7 @@ enum class TrajectoryFlag : int Invalid = -1, Straight = 0, Bombard = 1, + Engrave = 3 }; enum class TrajectoryCheckReturnType : int diff --git a/src/Ext/Techno/Body.Internal.cpp b/src/Ext/Techno/Body.Internal.cpp index 6a5c22f16d..9b4f04ac55 100644 --- a/src/Ext/Techno/Body.Internal.cpp +++ b/src/Ext/Techno/Body.Internal.cpp @@ -76,31 +76,32 @@ CoordStruct TechnoExt::GetFLHAbsoluteCoords(TechnoClass* pThis, CoordStruct pCoo return location; } -CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound) +CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt) { FLHFound = false; CoordStruct FLH = CoordStruct::Empty; - auto const pExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); + if (!pTypeExt) + pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); auto pInf = abstract_cast(pThis); - auto pickedFLHs = pExt->WeaponBurstFLHs; + auto pickedFLHs = pTypeExt->WeaponBurstFLHs; if (pThis->Veterancy.IsElite()) { if (pInf && pInf->IsDeployed()) - pickedFLHs = pExt->EliteDeployedWeaponBurstFLHs; + pickedFLHs = pTypeExt->EliteDeployedWeaponBurstFLHs; else if (pInf && pInf->Crawling) - pickedFLHs = pExt->EliteCrouchedWeaponBurstFLHs; + pickedFLHs = pTypeExt->EliteCrouchedWeaponBurstFLHs; else - pickedFLHs = pExt->EliteWeaponBurstFLHs; + pickedFLHs = pTypeExt->EliteWeaponBurstFLHs; } else { if (pInf && pInf->IsDeployed()) - pickedFLHs = pExt->DeployedWeaponBurstFLHs; + pickedFLHs = pTypeExt->DeployedWeaponBurstFLHs; else if (pInf && pInf->Crawling) - pickedFLHs = pExt->CrouchedWeaponBurstFLHs; + pickedFLHs = pTypeExt->CrouchedWeaponBurstFLHs; } if ((int)pickedFLHs[weaponIndex].size() > pThis->CurrentBurstIndex) { @@ -111,12 +112,15 @@ CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FL return FLH; } -CoordStruct TechnoExt::GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound) +CoordStruct TechnoExt::GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt) { FLHFound = false; CoordStruct FLH = CoordStruct::Empty; - if (auto pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Type)) + if (!pTypeExt) + pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); + + if (pTypeExt) { Nullable pickedFLH; diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index d671024c6d..59934b5f1a 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -498,6 +498,8 @@ void TechnoExt::ExtData::Serialize(T& Stm) .Process(this->AE_Cloakable) .Process(this->AE_ForceDecloak) .Process(this->AE_DisableWeapons) + .Process(this->LastWeaponStruct) + .Process(this->LastWeaponFLH) .Process(this->FiringObstacleCell) ; } diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 08e53e1ba4..43a38df656 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -46,6 +46,8 @@ class TechnoExt int WHAnimRemainingCreationInterval; bool CanCurrentlyDeployIntoBuilding; // Only set on UnitClass technos with DeploysInto set in multiplayer games, recalculated once per frame so no need to serialize. std::vector> AttachedEffects; + WeaponStruct* LastWeaponStruct; + CoordStruct LastWeaponFLH; CellClass* FiringObstacleCell; // Set on firing if there is an obstacle cell between target and techno, used for updating WaveClass target etc. // Used for Passengers.SyncOwner.RevertOnExit instead of TechnoClass::InitialOwner / OriginallyOwnedByHouse, @@ -92,6 +94,8 @@ class TechnoExt , AE_Cloakable { false } , AE_ForceDecloak { false } , AE_DisableWeapons { false } + , LastWeaponStruct {} + , LastWeaponFLH {} , FiringObstacleCell {} { } @@ -163,8 +167,8 @@ class TechnoExt static CoordStruct GetFLHAbsoluteCoords(TechnoClass* pThis, CoordStruct flh, bool turretFLH = false); - static CoordStruct GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound); - static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound); + static CoordStruct GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt = nullptr); + static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt = nullptr); static void ChangeOwnerMissionFix(FootClass* pThis); static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, AnimTypeClass* pVanishAnimation, bool isInLimbo = false); diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 93cea122cd..50a8f7e87b 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -575,25 +575,45 @@ namespace BurstFLHTemp DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) { GET(TechnoClass*, pThis, EBX); + GET(int, OriginalX, ECX); + GET(int, OriginalY, EBP); + GET(int, OriginalZ, EAX); GET_STACK(int, weaponIndex, STACK_OFFSET(0xD8, 0x8)); + auto const pExt = TechnoExt::ExtMap.Find(pThis); + + if (!pExt) + return 0; + + auto const pTypeExt = pExt->TypeExtData; + auto const pWeaponStruct = pThis->GetWeapon(weaponIndex); + + pExt->LastWeaponFLH = { OriginalX, OriginalY, OriginalZ }; + + if (pThis->CurrentBurstIndex % 2 == 1 && weaponIndex >= 0) + pExt->LastWeaponFLH.Y = -OriginalY; + + pExt->LastWeaponStruct = pWeaponStruct; + if (weaponIndex < 0) return 0; bool FLHFound = false; CoordStruct FLH = CoordStruct::Empty; - FLH = TechnoExt::GetBurstFLH(pThis, weaponIndex, FLHFound); + FLH = TechnoExt::GetBurstFLH(pThis, weaponIndex, FLHFound, pTypeExt); BurstFLHTemp::FLHFound = FLHFound; if (!FLHFound) { if (auto pInf = abstract_cast(pThis)) - FLH = TechnoExt::GetSimpleFLH(pInf, weaponIndex, FLHFound); + FLH = TechnoExt::GetSimpleFLH(pInf, weaponIndex, FLHFound, pTypeExt); } if (FLHFound) { + pExt->LastWeaponFLH = FLH; + R->ECX(FLH.X); R->EBP(FLH.Y); R->EAX(FLH.Z); From 73eccea7bf62cfdd850ec2fa8721e0be8867465a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 25 Jun 2024 21:36:55 +0800 Subject: [PATCH 03/54] Add missing split items --- src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index 9176807b59..4573479808 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -120,9 +120,15 @@ bool PhobosTrajectory::Save(PhobosStreamWriter& Stm) const double PhobosTrajectory::GetTrajectorySpeed(BulletClass* pBullet) const { if (auto const pBulletTypeExt = BulletTypeExt::ExtMap.Find(pBullet->Type)) - return pBulletTypeExt->Trajectory_Speed; + { + double StraightSpeed = pBulletTypeExt->Trajectory_Speed; + StraightSpeed = StraightSpeed > 0.001 ? StraightSpeed : 0.001 ; + return StraightSpeed; + } else + { return 100.0; + } } PhobosTrajectory* PhobosTrajectory::CreateInstance(PhobosTrajectoryType* pType, BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) From 4f60a5c2e4b33b83f3ae7823702142b48414fbb0 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 30 Jun 2024 20:07:54 +0800 Subject: [PATCH 04/54] Get accurate building FLH --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 77 ++++++++++++------- .../Bullet/Trajectories/EngraveTrajectory.h | 7 +- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index fff510352f..9814acc0e9 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include bool EngraveTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) @@ -100,6 +101,7 @@ bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) .Process(this->NotMainWeapon) .Process(this->FirepowerMult) .Process(this->FLHCoord) + .Process(this->BuildingCoord) .Process(this->TemporaryCoord) ; @@ -132,6 +134,7 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const .Process(this->NotMainWeapon) .Process(this->FirepowerMult) .Process(this->FLHCoord) + .Process(this->BuildingCoord) .Process(this->TemporaryCoord) ; @@ -159,16 +162,17 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->DamageDelay = pType->DamageDelay > 0 ? pType->DamageDelay : 1; this->LaserTimer.StartTime = 0; this->DamageTimer.StartTime = 0; - this->TemporaryCoord = CoordStruct::Empty; this->FLHCoord = pBullet->SourceCoords; + this->BuildingCoord = CoordStruct::Empty; + this->TemporaryCoord = CoordStruct::Empty; if (pBullet->Owner) { - this->TechnoInLimbo = pBullet->Owner->InLimbo; + this->TechnoInLimbo = static_cast(pBullet->Owner->Transporter); this->NotMainWeapon = false; this->FirepowerMult = pBullet->Owner->FirepowerMultiplier; - this->GetTechnoFLHCoord(pBullet); + this->GetTechnoFLHCoord(pBullet, pBullet->Owner); this->CheckMirrorCoord(pBullet->Owner); this->SetEngraveDirection(pBullet, pBullet->Owner->GetCoords(), pBullet->TargetCoords); } @@ -192,7 +196,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul bool EngraveTrajectory::OnAI(BulletClass* pBullet) { - if ((!pBullet->Owner && !this->NotMainWeapon) || this->TechnoInLimbo != pBullet->Owner->InLimbo) + if ((!pBullet->Owner && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pBullet->Owner->Transporter)) return true; if (--this->TheDuration < 0) @@ -203,8 +207,8 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) TechnoClass* const pTechno = pBullet->Owner; HouseClass* const pOwner = pBullet->Owner->Owner; - if (this->IsLaser && this->LaserTimer.Completed() && this->DrawEngraveLaser(pBullet, pTechno, pOwner)) - return true; + if (this->IsLaser && this->LaserTimer.Completed()) + this->DrawEngraveLaser(pBullet, pTechno, pOwner); if (this->DamageTimer.Completed()) this->DetonateLaserWarhead(pBullet, pTechno, pOwner); @@ -232,14 +236,33 @@ TrajectoryCheckReturnType EngraveTrajectory::OnAITechnoCheck(BulletClass* pBulle return TrajectoryCheckReturnType::SkipGameCheck; } -void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet) +void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno) { - auto const pExt = TechnoExt::ExtMap.Find(pBullet->Owner); + TechnoExt::ExtData* pExt = TechnoExt::ExtMap.Find(pTechno); - if (!pExt || !pExt->LastWeaponStruct || !pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type) + if (!pExt || (pExt->LastWeaponStruct && (!pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type))) + { this->NotMainWeapon = true; - else - this->FLHCoord = pExt->LastWeaponFLH; + return; + } + else if (pTechno->WhatAmI() == AbstractType::Building) + { + const BuildingClass* const pBuilding = static_cast(pTechno); + Matrix3D mtx; + mtx.MakeIdentity(); + + if (pTechno->HasTurret()) + { + TechnoTypeExt::ApplyTurretOffset(pBuilding->Type, &mtx); + mtx.RotateZ(static_cast(pTechno->TurretFacing().GetRadian<32>())); + } + + mtx.Translate(static_cast(pExt->LastWeaponFLH.X), static_cast(pExt->LastWeaponFLH.Y), static_cast(pExt->LastWeaponFLH.Z)); + auto const result = mtx.GetTranslation(); + this->BuildingCoord = pBullet->SourceCoords - pBuilding->GetCoords() - CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; + } + + this->FLHCoord = pExt->LastWeaponFLH; } void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) @@ -336,7 +359,7 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) return false; } -bool EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) +void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { this->LaserTimer.Start(this->LaserDelay); LaserDrawClass* pLaser; @@ -349,25 +372,25 @@ bool EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec else if (pTechno->WhatAmI() != AbstractType::Building) { if (this->TechnoInLimbo) - { - if (TechnoClass* const pTransporter = pTechno->Transporter) - FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTransporter, this->FLHCoord, pTransporter->HasTurret()); - else - return true; - } + FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno->Transporter, this->FLHCoord, pTechno->Transporter->HasTurret()); else - { FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); - } } - else // TODO Not accurate now, just get the similar FLH. + else { - const double RotateAngle = pTechno->HasTurret() ? -(pTechno->TurretFacing().GetRadian<32>()) : -(pTechno->PrimaryFacing.Current().GetRadian<32>()); - FireCoord.X += static_cast(this->FLHCoord.X * Math::cos(RotateAngle) + this->FLHCoord.Y * Math::sin(RotateAngle)); - FireCoord.Y += static_cast(this->FLHCoord.X * Math::sin(RotateAngle) - this->FLHCoord.Y * Math::cos(RotateAngle)); + const BuildingClass* const pBuilding = static_cast(pTechno); + Matrix3D mtx; + mtx.MakeIdentity(); + + if (pTechno->HasTurret()) + { + TechnoTypeExt::ApplyTurretOffset(pBuilding->Type, &mtx); + mtx.RotateZ(static_cast(pTechno->TurretFacing().GetRadian<32>())); + } - if (const BuildingTypeClass* const pBuildingType = static_cast(pTechno->GetTechnoType())) - FireCoord.Z += this->FLHCoord.Z + 30 * (pBuildingType->GetFoundationWidth() + pBuildingType->GetFoundationHeight(false) + 2); + mtx.Translate(static_cast(this->FLHCoord.X), static_cast(this->FLHCoord.Y), static_cast(this->FLHCoord.Z)); + auto const result = mtx.GetTranslation(); + FireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; } if (this->IsHouseColor) @@ -388,8 +411,6 @@ bool EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec pLaser->Thickness = this->LaserThickness; pLaser->IsSupported = this->IsSupported; - - return false; } void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 5b78576e29..2a5374041a 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -70,6 +70,7 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FirepowerMult { 1.0 } , FLHCoord {} + , BuildingCoord {} , TemporaryCoord {} {} @@ -95,6 +96,7 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FirepowerMult { 1.0 } , FLHCoord {} + , BuildingCoord {} , TemporaryCoord {} {} @@ -129,14 +131,15 @@ class EngraveTrajectory final : public PhobosTrajectory bool NotMainWeapon; double FirepowerMult; CoordStruct FLHCoord; + CoordStruct BuildingCoord; CoordStruct TemporaryCoord; private: - void GetTechnoFLHCoord(BulletClass* pBullet); + void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); void CheckMirrorCoord(TechnoClass* pTechno); void SetEngraveDirection(BulletClass* pBullet, CoordStruct Source, CoordStruct Target); int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct Coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); - bool DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); + void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); }; From b925f9056c95680d2a31b541553f57af8e624563 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 30 Jun 2024 20:10:44 +0800 Subject: [PATCH 05/54] Fix known issue --- src/Ext/Techno/Hooks.Firing.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 50a8f7e87b..45714f46e1 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -586,17 +586,30 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) return 0; auto const pTypeExt = pExt->TypeExtData; - auto const pWeaponStruct = pThis->GetWeapon(weaponIndex); - pExt->LastWeaponFLH = { OriginalX, OriginalY, OriginalZ }; + if (weaponIndex < 0) + { + FootClass* currentPassenger = pThis->Passengers.FirstPassenger; + const int passengerIndex = -weaponIndex - 1; - if (pThis->CurrentBurstIndex % 2 == 1 && weaponIndex >= 0) - pExt->LastWeaponFLH.Y = -OriginalY; + for (int i = 0; i < passengerIndex && currentPassenger; i++) + currentPassenger = abstract_cast(currentPassenger->NextObject); - pExt->LastWeaponStruct = pWeaponStruct; + if (auto const pPassengerExt = TechnoExt::ExtMap.Find(currentPassenger)) + { + pPassengerExt->LastWeaponFLH = { OriginalX, OriginalY, OriginalZ }; + pPassengerExt->LastWeaponStruct = nullptr; + } - if (weaponIndex < 0) return 0; + } + else + { + auto const pWeaponStruct = pThis->GetWeapon(weaponIndex); + + pExt->LastWeaponStruct = pWeaponStruct; + pExt->LastWeaponFLH = { OriginalX, ((pThis->CurrentBurstIndex % 2 == 1) ? -OriginalY : OriginalY), OriginalZ }; + } bool FLHFound = false; CoordStruct FLH = CoordStruct::Empty; From 08c1edd9d66db8e5eb06d6f72c1b0b73eaa6e99a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 4 Jul 2024 20:27:48 +0800 Subject: [PATCH 06/54] Change hook --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- src/Ext/Techno/Hooks.Firing.cpp | 27 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 9814acc0e9..97e9b35f2a 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -240,7 +240,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe { TechnoExt::ExtData* pExt = TechnoExt::ExtMap.Find(pTechno); - if (!pExt || (pExt->LastWeaponStruct && (!pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type))) + if (!pExt || !pExt->LastWeaponStruct || !pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type) { this->NotMainWeapon = true; return; diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 45714f46e1..1c267a9b7d 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -395,6 +395,17 @@ DEFINE_HOOK(0x6FC689, TechnoClass_CanFire_LandNavalTarget, 0x6) #pragma endregion #pragma region TechnoClass_Fire +DEFINE_HOOK(0x6FDD6F, TechnoClass_FireAt_UpdateWeaponStruct, 0x8) +{ + GET(WeaponStruct* const, pWeaponStruct, EAX); + GET(TechnoClass* const, pThis, ESI); + + auto const pExt = TechnoExt::ExtMap.Find(pThis); + pExt->LastWeaponStruct = pWeaponStruct; + + return 0; +} + DEFINE_HOOK(0x6FE43B, TechnoClass_FireAt_OpenToppedDmgMult, 0x8) { enum { ApplyDamageMult = 0x6FE45A, ContinueCheck = 0x6FE460 }; @@ -592,24 +603,14 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) FootClass* currentPassenger = pThis->Passengers.FirstPassenger; const int passengerIndex = -weaponIndex - 1; - for (int i = 0; i < passengerIndex && currentPassenger; i++) + for (int i = 0; i < passengerIndex; i++) currentPassenger = abstract_cast(currentPassenger->NextObject); if (auto const pPassengerExt = TechnoExt::ExtMap.Find(currentPassenger)) - { pPassengerExt->LastWeaponFLH = { OriginalX, OriginalY, OriginalZ }; - pPassengerExt->LastWeaponStruct = nullptr; - } return 0; } - else - { - auto const pWeaponStruct = pThis->GetWeapon(weaponIndex); - - pExt->LastWeaponStruct = pWeaponStruct; - pExt->LastWeaponFLH = { OriginalX, ((pThis->CurrentBurstIndex % 2 == 1) ? -OriginalY : OriginalY), OriginalZ }; - } bool FLHFound = false; CoordStruct FLH = CoordStruct::Empty; @@ -631,6 +632,10 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) R->EBP(FLH.Y); R->EAX(FLH.Z); } + else + { + pExt->LastWeaponFLH = { OriginalX, ((pThis->CurrentBurstIndex % 2 == 1) ? -OriginalY : OriginalY), OriginalZ }; + } return 0; } From ca2e7406933f8214fbbf533d3965b47eaa95b8fb Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 6 Jul 2024 11:48:53 +0800 Subject: [PATCH 07/54] Merge --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 5 +++++ src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 97e9b35f2a..19044b4589 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -55,6 +55,11 @@ bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const return true; } +PhobosTrajectory* EngraveTrajectoryType::CreateInstance() const +{ + return new EngraveTrajectory(this); +} + void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) { INI_EX exINI(pINI); diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 2a5374041a..b69ce36fd3 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -25,7 +25,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; - + virtual PhobosTrajectory* CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; Valueable SourceCoord; @@ -74,7 +74,7 @@ class EngraveTrajectory final : public PhobosTrajectory , TemporaryCoord {} {} - EngraveTrajectory(PhobosTrajectoryType* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) + EngraveTrajectory(PhobosTrajectoryType const* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) , SourceCoord {} , TargetCoord {} , MirrorCoord { true } From 080e1bbf2a84c0edd18fa1d677668a71b2772bfa Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 6 Jul 2024 12:07:13 +0800 Subject: [PATCH 08/54] Fix nullptr --- src/Ext/Techno/Hooks.Firing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 1c267a9b7d..92f9445ab7 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -603,7 +603,7 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) FootClass* currentPassenger = pThis->Passengers.FirstPassenger; const int passengerIndex = -weaponIndex - 1; - for (int i = 0; i < passengerIndex; i++) + for (int i = 0; i < passengerIndex && currentPassenger; i++) currentPassenger = abstract_cast(currentPassenger->NextObject); if (auto const pPassengerExt = TechnoExt::ExtMap.Find(currentPassenger)) From 37f7144dfda2bf8456ddf415b21081afa00cb6b8 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 14 Jul 2024 22:41:27 +0800 Subject: [PATCH 09/54] Fix firepower duplicated calculate --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 6 +----- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 19044b4589..495d44c568 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -104,7 +104,6 @@ bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) .Process(this->DamageTimer) .Process(this->TechnoInLimbo) .Process(this->NotMainWeapon) - .Process(this->FirepowerMult) .Process(this->FLHCoord) .Process(this->BuildingCoord) .Process(this->TemporaryCoord) @@ -137,7 +136,6 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const .Process(this->DamageTimer) .Process(this->TechnoInLimbo) .Process(this->NotMainWeapon) - .Process(this->FirepowerMult) .Process(this->FLHCoord) .Process(this->BuildingCoord) .Process(this->TemporaryCoord) @@ -175,7 +173,6 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul { this->TechnoInLimbo = static_cast(pBullet->Owner->Transporter); this->NotMainWeapon = false; - this->FirepowerMult = pBullet->Owner->FirepowerMultiplier; this->GetTechnoFLHCoord(pBullet, pBullet->Owner); this->CheckMirrorCoord(pBullet->Owner); @@ -185,7 +182,6 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul { this->TechnoInLimbo = false; this->NotMainWeapon = true; - this->FirepowerMult = 1.0; this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); } @@ -421,5 +417,5 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { this->DamageTimer.Start(this->DamageDelay); - WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, static_cast(pBullet->Health * this->FirepowerMult), pOwner); + WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index b69ce36fd3..f7f0e4c3a8 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -68,7 +68,6 @@ class EngraveTrajectory final : public PhobosTrajectory , DamageTimer {} , TechnoInLimbo { false } , NotMainWeapon { false } - , FirepowerMult { 1.0 } , FLHCoord {} , BuildingCoord {} , TemporaryCoord {} @@ -94,7 +93,6 @@ class EngraveTrajectory final : public PhobosTrajectory , DamageTimer {} , TechnoInLimbo { false } , NotMainWeapon { false } - , FirepowerMult { 1.0 } , FLHCoord {} , BuildingCoord {} , TemporaryCoord {} @@ -129,7 +127,6 @@ class EngraveTrajectory final : public PhobosTrajectory CDTimerClass DamageTimer; bool TechnoInLimbo; bool NotMainWeapon; - double FirepowerMult; CoordStruct FLHCoord; CoordStruct BuildingCoord; CoordStruct TemporaryCoord; From 6242590b780657266e1d919e5341986ad54088ff Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 16 Jul 2024 20:45:40 +0800 Subject: [PATCH 10/54] Case --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 90 +++++++++---------- .../Bullet/Trajectories/EngraveTrajectory.h | 4 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 495d44c568..d3d6aa9cd7 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -186,13 +186,13 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); } - double StraightSpeed = this->GetTrajectorySpeed(pBullet); - StraightSpeed = StraightSpeed > 128.0 ? 128.0 : StraightSpeed; - const double CoordDistance = pBullet->Velocity.Magnitude(); - pBullet->Velocity *= (CoordDistance > 0) ? (StraightSpeed / CoordDistance) : 0; + double straightSpeed = this->GetTrajectorySpeed(pBullet); + straightSpeed = straightSpeed > 128.0 ? 128.0 : straightSpeed; + const double coordDistance = pBullet->Velocity.Magnitude(); + pBullet->Velocity *= (coordDistance > 0) ? (straightSpeed / coordDistance) : 0; if (this->TheDuration <= 0) - this->TheDuration = static_cast(CoordDistance / StraightSpeed) + 1; + this->TheDuration = static_cast(coordDistance / straightSpeed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) @@ -278,47 +278,47 @@ void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) } } -void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct Source, CoordStruct Target) +void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget) { - const double RotateAngle = Math::atan2(Target.Y - Source.Y , Target.X - Source.X); + const double rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) { - Source = Target; - Source.X += static_cast(this->SourceCoord.X * Math::cos(RotateAngle) + this->SourceCoord.Y * Math::sin(RotateAngle)); - Source.Y += static_cast(this->SourceCoord.X * Math::sin(RotateAngle) - this->SourceCoord.Y * Math::cos(RotateAngle)); + theSource = theTarget; + theSource.X += static_cast(this->SourceCoord.X * Math::cos(rotateAngle) + this->SourceCoord.Y * Math::sin(rotateAngle)); + theSource.Y += static_cast(this->SourceCoord.X * Math::sin(rotateAngle) - this->SourceCoord.Y * Math::cos(rotateAngle)); } - Source.Z = this->GetFloorCoordHeight(pBullet, Source); - pBullet->SetLocation(Source); + theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); + pBullet->SetLocation(theSource); - Target.X += static_cast(this->TargetCoord.X * Math::cos(RotateAngle) + this->TargetCoord.Y * Math::sin(RotateAngle)); - Target.Y += static_cast(this->TargetCoord.X * Math::sin(RotateAngle) - this->TargetCoord.Y * Math::cos(RotateAngle)); + theTarget.X += static_cast(this->TargetCoord.X * Math::cos(rotateAngle) + this->TargetCoord.Y * Math::sin(rotateAngle)); + theTarget.Y += static_cast(this->TargetCoord.X * Math::sin(rotateAngle) - this->TargetCoord.Y * Math::cos(rotateAngle)); - pBullet->Velocity.X = Target.X - Source.X; - pBullet->Velocity.Y = Target.Y - Source.Y; + pBullet->Velocity.X = theTarget.X - theSource.X; + pBullet->Velocity.Y = theTarget.Y - theSource.Y; pBullet->Velocity.Z = 0; } -int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct Coord) +int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord) { - if (const CellClass* const pCell = MapClass::Instance->GetCellAt(Coord)) + if (const CellClass* const pCell = MapClass::Instance->GetCellAt(coord)) { - const int OnFloor = MapClass::Instance->GetCellFloorHeight(Coord); - const int OnBridge = pCell->GetCoordsWithBridge().Z; + const int onFloor = MapClass::Instance->GetCellFloorHeight(coord); + const int onBridge = pCell->GetCoordsWithBridge().Z; - if (pBullet->SourceCoords.Z >= OnBridge || pBullet->TargetCoords.Z >= OnBridge) - return OnBridge; + if (pBullet->SourceCoords.Z >= onBridge || pBullet->TargetCoords.Z >= onBridge) + return onBridge; - return OnFloor; + return onFloor; } - return Coord.Z; + return coord.Z; } bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) { - CoordStruct BulletCoords = pBullet->Location; + CoordStruct bulletCoords = pBullet->Location; if (this->TemporaryCoord != CoordStruct::Empty) { @@ -326,35 +326,35 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) this->TemporaryCoord = CoordStruct::Empty; } - CoordStruct FutureCoords + CoordStruct futureCoords { - BulletCoords.X + static_cast(pBullet->Velocity.X), - BulletCoords.Y + static_cast(pBullet->Velocity.Y), - BulletCoords.Z + static_cast(pBullet->Velocity.Z) + bulletCoords.X + static_cast(pBullet->Velocity.X), + bulletCoords.Y + static_cast(pBullet->Velocity.Y), + bulletCoords.Z + static_cast(pBullet->Velocity.Z) }; - const int CheckDifference = this->GetFloorCoordHeight(pBullet, FutureCoords) - FutureCoords.Z; + const int checkDifference = this->GetFloorCoordHeight(pBullet, futureCoords) - futureCoords.Z; - if (abs(CheckDifference) >= 384) + if (abs(checkDifference) >= 384) { if (pBullet->Type->SubjectToCliffs) { return true; } - else if (CheckDifference > 0) + else if (checkDifference > 0) { - BulletCoords.Z += CheckDifference; - pBullet->SetLocation(BulletCoords); + bulletCoords.Z += checkDifference; + pBullet->SetLocation(bulletCoords); } else { - FutureCoords.Z += CheckDifference; - this->TemporaryCoord = FutureCoords; + futureCoords.Z += checkDifference; + this->TemporaryCoord = futureCoords; } } else { - pBullet->Velocity.Z += CheckDifference; + pBullet->Velocity.Z += checkDifference; } return false; @@ -364,18 +364,18 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec { this->LaserTimer.Start(this->LaserDelay); LaserDrawClass* pLaser; - CoordStruct FireCoord = pTechno->GetCoords(); + CoordStruct fireCoord = pTechno->GetCoords(); if (this->NotMainWeapon) { - FireCoord = this->FLHCoord; + fireCoord = this->FLHCoord; } else if (pTechno->WhatAmI() != AbstractType::Building) { if (this->TechnoInLimbo) - FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno->Transporter, this->FLHCoord, pTechno->Transporter->HasTurret()); + fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno->Transporter, this->FLHCoord, pTechno->Transporter->HasTurret()); else - FireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); + fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); } else { @@ -391,22 +391,22 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec mtx.Translate(static_cast(this->FLHCoord.X), static_cast(this->FLHCoord.Y), static_cast(this->FLHCoord.Z)); auto const result = mtx.GetTranslation(); - FireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; + fireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; } if (this->IsHouseColor) { - pLaser = GameCreate(FireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); pLaser->IsHouseColor = true; } else if (this->IsSingleColor) { - pLaser = GameCreate(FireCoord, pBullet->Location, this->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, this->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); pLaser->IsHouseColor = true; } else { - pLaser = GameCreate(FireCoord, pBullet->Location, this->LaserInnerColor, this->LaserOuterColor, this->LaserOuterSpread, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, this->LaserInnerColor, this->LaserOuterColor, this->LaserOuterSpread, this->LaserDuration); pLaser->IsHouseColor = false; } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index f7f0e4c3a8..da1599325d 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -134,8 +134,8 @@ class EngraveTrajectory final : public PhobosTrajectory private: void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); void CheckMirrorCoord(TechnoClass* pTechno); - void SetEngraveDirection(BulletClass* pBullet, CoordStruct Source, CoordStruct Target); - int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct Coord); + void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); + int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); From 8190e90f8248e9a2cf998cc3263c35a74041f89d Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 19 Jul 2024 21:02:43 +0800 Subject: [PATCH 11/54] Fix a conflict with Kratos.dll and SIWinterIsComing.dll because they can change the firing weapon --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- src/Ext/Techno/Body.cpp | 2 +- src/Ext/Techno/Body.h | 4 ++-- src/Ext/Techno/Hooks.Firing.cpp | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index d3d6aa9cd7..b1a33b15a1 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -241,7 +241,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe { TechnoExt::ExtData* pExt = TechnoExt::ExtMap.Find(pTechno); - if (!pExt || !pExt->LastWeaponStruct || !pExt->LastWeaponStruct->WeaponType || pExt->LastWeaponStruct->WeaponType->Projectile != pBullet->Type) + if (!pExt || !pExt->LastWeaponType || pExt->LastWeaponType->Projectile != pBullet->Type) { this->NotMainWeapon = true; return; diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index 0eb8f5fd3a..844326a752 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -502,7 +502,7 @@ void TechnoExt::ExtData::Serialize(T& Stm) .Process(this->AE_ForceDecloak) .Process(this->AE_DisableWeapons) .Process(this->AE_HasTint) - .Process(this->LastWeaponStruct) + .Process(this->LastWeaponType) .Process(this->LastWeaponFLH) .Process(this->FiringObstacleCell) ; diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index afb515faa9..7033176b51 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -45,7 +45,7 @@ class TechnoExt int WHAnimRemainingCreationInterval; bool CanCurrentlyDeployIntoBuilding; // Only set on UnitClass technos with DeploysInto set in multiplayer games, recalculated once per frame so no need to serialize. std::vector> AttachedEffects; - WeaponStruct* LastWeaponStruct; + WeaponTypeClass* LastWeaponType; CoordStruct LastWeaponFLH; CellClass* FiringObstacleCell; // Set on firing if there is an obstacle cell between target and techno, used for updating WaveClass target etc. @@ -95,7 +95,7 @@ class TechnoExt , AE_ForceDecloak { false } , AE_DisableWeapons { false } , AE_HasTint { false } - , LastWeaponStruct {} + , LastWeaponType {} , LastWeaponFLH {} , FiringObstacleCell {} { } diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 92f9445ab7..e229e1f591 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -395,13 +395,13 @@ DEFINE_HOOK(0x6FC689, TechnoClass_CanFire_LandNavalTarget, 0x6) #pragma endregion #pragma region TechnoClass_Fire -DEFINE_HOOK(0x6FDD6F, TechnoClass_FireAt_UpdateWeaponStruct, 0x8) +DEFINE_HOOK(0x6FDD7D, TechnoClass_FireAt_UpdateWeaponType, 0x5) { - GET(WeaponStruct* const, pWeaponStruct, EAX); + GET(WeaponTypeClass* const, pWeapon, EBX); GET(TechnoClass* const, pThis, ESI); auto const pExt = TechnoExt::ExtMap.Find(pThis); - pExt->LastWeaponStruct = pWeaponStruct; + pExt->LastWeaponType = pWeapon; return 0; } From 591dda02f5aa242363312e913159198da3c1da70 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 9 Aug 2024 14:52:37 +0800 Subject: [PATCH 12/54] Docs --- docs/New-or-Enhanced-Logics.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 5404aa6207..973d3c7c52 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -679,6 +679,7 @@ Trajectory.Bombard.Height=0.0 ; double #### Engrave trajectory - Visually, like the thermal lance. Calling it 'trajectory' may not be appropriate. It does not read the settings on the weapon. + - `Trajectory.Straight.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. @@ -698,6 +699,7 @@ Trajectory.Bombard.Height=0.0 ; double In `rulesmd.ini`: ```ini Trajectory=Engrave ; Trajectory type +Trajectory.Engrave.ApplyRangeModifiers=false ; boolean Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.TargetCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.MirrorCoord=true ; boolean From 65c39c314fabda362c5dbd16393a247eaa68f65a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 9 Aug 2024 14:55:07 +0800 Subject: [PATCH 13/54] ApplyRangeModifiers --- docs/New-or-Enhanced-Logics.md | 4 +-- .../Bullet/Trajectories/EngraveTrajectory.cpp | 30 +++++++++++++------ .../Bullet/Trajectories/EngraveTrajectory.h | 2 ++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 7a11b97af3..9216e35b9b 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -424,7 +424,7 @@ Shield.InheritStateOnReplace=false ; boolean - `CreateUnit.ConsiderPathfinding`, if set to true, will consider whether or not the cell where the animation is located is occupied by other objects or impassable to the vehicle being created and will attempt to find a nearby cell that is not. Otherwise the vehicle will be created at the animation's location despite these obstacles if possible. - `CreateUnit.SpawnAnim` can be used to play another animation at created unit's location after it has appeared. This animation has same owner and invoker as the parent animation. - `CreateUnit.SpawnHeight` can be set to override the animation's height when determining where to spawn the created unit. Ignored if `CreateUnit.AlwaysSpawnOnGround` is set to true. - + In `artmd.ini`: ```ini [SOMEANIM] ; AnimationType @@ -674,7 +674,7 @@ Trajectory.Speed=100.0 ; floating point value - `Trajectory.Straight.PassThrough` enables special case logic where the projectile does not detonate in contact with the target but ínstead travels up to a distance defined by `Trajectory.Straight.DetonationDistance`. Note that the firing angle of the projectile is adjusted with this in mind, making it fire straight ahead if the target is on same elevation. In `rulesmd.ini`: -```ini +```ini [SOMEPROJECTILE] ; Projectile Trajectory=Straight ; Trajectory type Trajectory.Straight.DetonationDistance=0.4 ; floating point value diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index b1a33b15a1..4a8c4d710f 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -1,4 +1,5 @@ #include "EngraveTrajectory.h" +#include #include #include #include @@ -10,6 +11,7 @@ bool EngraveTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange this->PhobosTrajectoryType::Load(Stm, false); Stm + .Process(this->ApplyRangeModifiers, false) .Process(this->SourceCoord, false) .Process(this->TargetCoord, false) .Process(this->MirrorCoord, false) @@ -35,6 +37,7 @@ bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const this->PhobosTrajectoryType::Save(Stm); Stm + .Process(this->ApplyRangeModifiers) .Process(this->SourceCoord) .Process(this->TargetCoord) .Process(this->MirrorCoord) @@ -63,6 +66,7 @@ PhobosTrajectory* EngraveTrajectoryType::CreateInstance() const void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) { INI_EX exINI(pINI); + this->ApplyRangeModifiers.Read(exINI, pSection, "Trajectory.Engrave.ApplyRangeModifiers"); this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); this->MirrorCoord.Read(exINI, pSection, "Trajectory.Engrave.MirrorCoord"); @@ -169,14 +173,16 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->BuildingCoord = CoordStruct::Empty; this->TemporaryCoord = CoordStruct::Empty; - if (pBullet->Owner) + TechnoClass* const pTechno = pBullet->Owner; + + if (pTechno) { - this->TechnoInLimbo = static_cast(pBullet->Owner->Transporter); + this->TechnoInLimbo = static_cast(pTechno->Transporter); this->NotMainWeapon = false; - this->GetTechnoFLHCoord(pBullet, pBullet->Owner); - this->CheckMirrorCoord(pBullet->Owner); - this->SetEngraveDirection(pBullet, pBullet->Owner->GetCoords(), pBullet->TargetCoords); + this->GetTechnoFLHCoord(pBullet, pTechno); + this->CheckMirrorCoord(pTechno); + this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords); } else { @@ -188,16 +194,23 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul double straightSpeed = this->GetTrajectorySpeed(pBullet); straightSpeed = straightSpeed > 128.0 ? 128.0 : straightSpeed; - const double coordDistance = pBullet->Velocity.Magnitude(); + double coordDistance = pBullet->Velocity.Magnitude(); pBullet->Velocity *= (coordDistance > 0) ? (straightSpeed / coordDistance) : 0; + WeaponTypeClass* const pWeapon = pBullet->WeaponType; + + if (pType->ApplyRangeModifiers && pWeapon && pTechno) + coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); + if (this->TheDuration <= 0) this->TheDuration = static_cast(coordDistance / straightSpeed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) { - if ((!pBullet->Owner && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pBullet->Owner->Transporter)) + TechnoClass* const pTechno = pBullet->Owner; + + if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) return true; if (--this->TheDuration < 0) @@ -205,8 +218,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) else if (this->PlaceOnCorrectHeight(pBullet)) return true; - TechnoClass* const pTechno = pBullet->Owner; - HouseClass* const pOwner = pBullet->Owner->Owner; + HouseClass* const pOwner = pTechno->Owner; if (this->IsLaser && this->LaserTimer.Completed()) this->DrawEngraveLaser(pBullet, pTechno, pOwner); diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index da1599325d..d3a79348e5 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -6,6 +6,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType { public: EngraveTrajectoryType() : PhobosTrajectoryType(TrajectoryFlag::Engrave) + , ApplyRangeModifiers { false } , SourceCoord { { 0, 0 } } , TargetCoord { { 0, 0 } } , MirrorCoord { true } @@ -28,6 +29,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType virtual PhobosTrajectory* CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; + Valueable ApplyRangeModifiers; Valueable SourceCoord; Valueable TargetCoord; Valueable MirrorCoord; From dc79795208a3cb50cfeae475b644d8773c49547c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 4 Sep 2024 14:49:26 +0800 Subject: [PATCH 14/54] Fix a doc mistake --- docs/New-or-Enhanced-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 2dab3f0804..ac2ebcb7ee 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -705,7 +705,7 @@ Trajectory.Bombard.Height=0.0 ; double #### Engrave trajectory - Visually, like the thermal lance. Calling it 'trajectory' may not be appropriate. It does not read the settings on the weapon. - - `Trajectory.Straight.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. + - `Trajectory.Engrave.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. From 753e9305ec9d7e2a53af812ded648982f399260b Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 4 Sep 2024 15:03:49 +0800 Subject: [PATCH 15/54] Sync with straight --- src/Ext/Bullet/Hooks.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 65f1407b10..074281463e 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -457,3 +457,19 @@ DEFINE_HOOK(0x44D23C, BuildingClass_Mission_Missile_ArcingFix, 0x7) return 0; } + +// Vanilla inertia effect only for bullets with ROT=0 +DEFINE_HOOK(0x415F25, AircraftClass_Fire_TrajectorySkipInertiaEffect, 0x6) +{ + enum { SkipCheck = 0x4160BC }; + + GET(BulletClass*, pThis, ESI); + + if (auto const pExt = BulletExt::ExtMap.Find(pThis)) + { + if (pExt->Trajectory) + return SkipCheck; + } + + return 0; +} From 3ab000c6ad88a0e3cfdf2653ee0b86f4ae4c141c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 5 Sep 2024 16:40:59 +0800 Subject: [PATCH 16/54] Fix `double` and revert `trajectory.speed` --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 4a8c4d710f..ac8a704e5c 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -195,7 +195,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul double straightSpeed = this->GetTrajectorySpeed(pBullet); straightSpeed = straightSpeed > 128.0 ? 128.0 : straightSpeed; double coordDistance = pBullet->Velocity.Magnitude(); - pBullet->Velocity *= (coordDistance > 0) ? (straightSpeed / coordDistance) : 0; + pBullet->Velocity *= (coordDistance > 1e-10) ? (straightSpeed / coordDistance) : 0; WeaponTypeClass* const pWeapon = pBullet->WeaponType; diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index daf7c2f6e8..2a7eb3785b 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -121,14 +121,11 @@ double PhobosTrajectory::GetTrajectorySpeed(BulletClass* pBullet) const { if (auto const pBulletTypeExt = BulletTypeExt::ExtMap.Find(pBullet->Type)) { - double StraightSpeed = pBulletTypeExt->Trajectory_Speed; - StraightSpeed = StraightSpeed > 0.001 ? StraightSpeed : 0.001 ; - return StraightSpeed; - } - else - { - return 100.0; + const double trajectorySpeed = pBulletTypeExt->Trajectory_Speed; + return abs(trajectorySpeed) > 1e-10 ? trajectorySpeed : 0.001; } + + return 100.0; } PhobosTrajectory* PhobosTrajectory::LoadFromStream(PhobosStreamReader& Stm) From 10c56b653f4efc33c62ee24c730461d305a18088 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Mon, 23 Sep 2024 14:45:10 +0800 Subject: [PATCH 17/54] Delete unnecessary content from the entity --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 76 ++++++++----------- .../Bullet/Trajectories/EngraveTrajectory.h | 16 +--- 2 files changed, 33 insertions(+), 59 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index ac8a704e5c..3030702565 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -89,9 +89,6 @@ bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) this->PhobosTrajectory::Load(Stm, false); Stm - .Process(this->SourceCoord) - .Process(this->TargetCoord) - .Process(this->MirrorCoord) .Process(this->TheDuration) .Process(this->IsLaser) .Process(this->IsSupported) @@ -110,7 +107,6 @@ bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) .Process(this->NotMainWeapon) .Process(this->FLHCoord) .Process(this->BuildingCoord) - .Process(this->TemporaryCoord) ; return true; @@ -121,9 +117,6 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const this->PhobosTrajectory::Save(Stm); Stm - .Process(this->SourceCoord) - .Process(this->TargetCoord) - .Process(this->MirrorCoord) .Process(this->TheDuration) .Process(this->IsLaser) .Process(this->IsSupported) @@ -142,7 +135,6 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const .Process(this->NotMainWeapon) .Process(this->FLHCoord) .Process(this->BuildingCoord) - .Process(this->TemporaryCoord) ; return true; @@ -152,9 +144,6 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul { auto const pType = this->GetTrajectoryType(pBullet); - this->SourceCoord = pType->SourceCoord; - this->TargetCoord = pType->TargetCoord; - this->MirrorCoord = pType->MirrorCoord; this->TheDuration = pType->TheDuration; this->IsLaser = pType->IsLaser; this->IsSupported = pType->IsSupported; @@ -171,9 +160,10 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->DamageTimer.StartTime = 0; this->FLHCoord = pBullet->SourceCoords; this->BuildingCoord = CoordStruct::Empty; - this->TemporaryCoord = CoordStruct::Empty; TechnoClass* const pTechno = pBullet->Owner; + Point2D sourceOffset = pType->SourceCoord; + Point2D targetOffset = pType->TargetCoord; if (pTechno) { @@ -181,21 +171,22 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->NotMainWeapon = false; this->GetTechnoFLHCoord(pBullet, pTechno); - this->CheckMirrorCoord(pTechno); - this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords); + this->CheckMirrorCoord(pTechno, sourceOffset, targetOffset, pType->MirrorCoord); + this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords, sourceOffset, targetOffset); } else { this->TechnoInLimbo = false; this->NotMainWeapon = true; - this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); + this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords, sourceOffset, targetOffset); } - double straightSpeed = this->GetTrajectorySpeed(pBullet); - straightSpeed = straightSpeed > 128.0 ? 128.0 : straightSpeed; + double engraveSpeed = this->GetTrajectorySpeed(pBullet); + engraveSpeed = engraveSpeed > 128.0 ? 128.0 : engraveSpeed; + double coordDistance = pBullet->Velocity.Magnitude(); - pBullet->Velocity *= (coordDistance > 1e-10) ? (straightSpeed / coordDistance) : 0; + pBullet->Velocity *= (coordDistance > 1e-10) ? (engraveSpeed / coordDistance) : 0; WeaponTypeClass* const pWeapon = pBullet->WeaponType; @@ -203,7 +194,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); if (this->TheDuration <= 0) - this->TheDuration = static_cast(coordDistance / straightSpeed) + 1; + this->TheDuration = static_cast(coordDistance / engraveSpeed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) @@ -213,9 +204,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) return true; - if (--this->TheDuration < 0) - return true; - else if (this->PlaceOnCorrectHeight(pBullet)) + if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) return true; HouseClass* const pOwner = pTechno->Owner; @@ -278,34 +267,34 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe this->FLHCoord = pExt->LastWeaponFLH; } -void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) +void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno, Point2D& sourceOffset, Point2D& targetOffset, bool mirror) { - if (pTechno->CurrentBurstIndex % 2 == 0) + if (this->NotMainWeapon || pTechno->CurrentBurstIndex % 2 == 0) return; - if (this->MirrorCoord) + if (mirror) { - this->SourceCoord.Y = -(this->SourceCoord.Y); - this->TargetCoord.Y = -(this->TargetCoord.Y); + sourceOffset.Y = -(sourceOffset.Y); + targetOffset.Y = -(targetOffset.Y); } } -void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget) +void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget, Point2D& sourceOffset, Point2D& targetOffset) { const double rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); - if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) + if (sourceOffset.X != 0 || sourceOffset.Y != 0) { theSource = theTarget; - theSource.X += static_cast(this->SourceCoord.X * Math::cos(rotateAngle) + this->SourceCoord.Y * Math::sin(rotateAngle)); - theSource.Y += static_cast(this->SourceCoord.X * Math::sin(rotateAngle) - this->SourceCoord.Y * Math::cos(rotateAngle)); + theSource.X += static_cast(sourceOffset.X * Math::cos(rotateAngle) + sourceOffset.Y * Math::sin(rotateAngle)); + theSource.Y += static_cast(sourceOffset.X * Math::sin(rotateAngle) - sourceOffset.Y * Math::cos(rotateAngle)); } theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); pBullet->SetLocation(theSource); - theTarget.X += static_cast(this->TargetCoord.X * Math::cos(rotateAngle) + this->TargetCoord.Y * Math::sin(rotateAngle)); - theTarget.Y += static_cast(this->TargetCoord.X * Math::sin(rotateAngle) - this->TargetCoord.Y * Math::cos(rotateAngle)); + theTarget.X += static_cast(targetOffset.X * Math::cos(rotateAngle) + targetOffset.Y * Math::sin(rotateAngle)); + theTarget.Y += static_cast(targetOffset.X * Math::sin(rotateAngle) - targetOffset.Y * Math::cos(rotateAngle)); pBullet->Velocity.X = theTarget.X - theSource.X; pBullet->Velocity.Y = theTarget.Y - theSource.Y; @@ -331,13 +320,6 @@ int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coo bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) { CoordStruct bulletCoords = pBullet->Location; - - if (this->TemporaryCoord != CoordStruct::Empty) - { - pBullet->SetLocation(this->TemporaryCoord); - this->TemporaryCoord = CoordStruct::Empty; - } - CoordStruct futureCoords { bulletCoords.X + static_cast(pBullet->Velocity.X), @@ -350,18 +332,22 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) if (abs(checkDifference) >= 384) { if (pBullet->Type->SubjectToCliffs) - { return true; - } - else if (checkDifference > 0) + + if (checkDifference > 0) { bulletCoords.Z += checkDifference; pBullet->SetLocation(bulletCoords); } else { - futureCoords.Z += checkDifference; - this->TemporaryCoord = futureCoords; + const int nowDifference = bulletCoords.Z - this->GetFloorCoordHeight(pBullet, bulletCoords); + + if (nowDifference >= 256) + { + bulletCoords.Z -= nowDifference; + pBullet->SetLocation(bulletCoords); + } } } else diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index d3a79348e5..f7f4eb5f6c 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -51,9 +51,6 @@ class EngraveTrajectory final : public PhobosTrajectory { public: EngraveTrajectory() : PhobosTrajectory(TrajectoryFlag::Engrave) - , SourceCoord {} - , TargetCoord {} - , MirrorCoord { true } , TheDuration { 0 } , IsLaser { true } , IsSupported { false } @@ -72,13 +69,9 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} - , TemporaryCoord {} {} EngraveTrajectory(PhobosTrajectoryType const* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) - , SourceCoord {} - , TargetCoord {} - , MirrorCoord { true } , TheDuration { 0 } , IsLaser { true } , IsSupported { false } @@ -97,7 +90,6 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} - , TemporaryCoord {} {} virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; @@ -110,9 +102,6 @@ class EngraveTrajectory final : public PhobosTrajectory virtual TrajectoryCheckReturnType OnAITargetCoordCheck(BulletClass* pBullet) override; virtual TrajectoryCheckReturnType OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) override; - Point2D SourceCoord; - Point2D TargetCoord; - bool MirrorCoord; int TheDuration; bool IsLaser; bool IsSupported; @@ -131,12 +120,11 @@ class EngraveTrajectory final : public PhobosTrajectory bool NotMainWeapon; CoordStruct FLHCoord; CoordStruct BuildingCoord; - CoordStruct TemporaryCoord; private: void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); - void CheckMirrorCoord(TechnoClass* pTechno); - void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); + void CheckMirrorCoord(TechnoClass* pTechno, Point2D& sourceOffset, Point2D& targetOffset, bool mirror); + void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget, Point2D& sourceOffset, Point2D& targetOffset); int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); From f9b79025dad7611df84c7c781d88d2004f6a3bb1 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 24 Sep 2024 01:45:29 +0800 Subject: [PATCH 18/54] Update with new template --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 126 ++++++------------ .../Bullet/Trajectories/EngraveTrajectory.h | 65 +++++---- .../Bullet/Trajectories/PhobosTrajectory.cpp | 4 +- 3 files changed, 82 insertions(+), 113 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 3030702565..771c631675 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -6,36 +6,14 @@ #include #include -bool EngraveTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) +PhobosTrajectory* EngraveTrajectoryType::CreateInstance() const { - this->PhobosTrajectoryType::Load(Stm, false); - - Stm - .Process(this->ApplyRangeModifiers, false) - .Process(this->SourceCoord, false) - .Process(this->TargetCoord, false) - .Process(this->MirrorCoord, false) - .Process(this->TheDuration, false) - .Process(this->IsLaser, false) - .Process(this->IsSupported, false) - .Process(this->IsHouseColor, false) - .Process(this->IsSingleColor, false) - .Process(this->LaserInnerColor, false) - .Process(this->LaserOuterColor, false) - .Process(this->LaserOuterSpread, false) - .Process(this->LaserThickness, false) - .Process(this->LaserDuration, false) - .Process(this->LaserDelay, false) - .Process(this->DamageDelay, false) - ; - - return true; + return new EngraveTrajectory(this); } -bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const +template +void EngraveTrajectoryType::Serialize(T& Stm) { - this->PhobosTrajectoryType::Save(Stm); - Stm .Process(this->ApplyRangeModifiers) .Process(this->SourceCoord) @@ -54,13 +32,20 @@ bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const .Process(this->LaserDelay) .Process(this->DamageDelay) ; +} +bool EngraveTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) +{ + this->PhobosTrajectoryType::Load(Stm, false); + this->Serialize(Stm); return true; } -PhobosTrajectory* EngraveTrajectoryType::CreateInstance() const +bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const { - return new EngraveTrajectory(this); + this->PhobosTrajectoryType::Save(Stm); + const_cast(this)->Serialize(Stm); + return true; } void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) @@ -84,11 +69,14 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->DamageDelay.Read(exINI, pSection, "Trajectory.Engrave.DamageDelay"); } -bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) +template +void EngraveTrajectory::Serialize(T& Stm) { - this->PhobosTrajectory::Load(Stm, false); - Stm + .Process(this->SourceCoord) + .Process(this->TargetCoord) + .Process(this->MirrorCoord) + .Process(this->ApplyRangeModifiers) .Process(this->TheDuration) .Process(this->IsLaser) .Process(this->IsSupported) @@ -108,62 +96,28 @@ bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) .Process(this->FLHCoord) .Process(this->BuildingCoord) ; +} +bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) +{ + this->PhobosTrajectory::Load(Stm, false); + this->Serialize(Stm); return true; } bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const { this->PhobosTrajectory::Save(Stm); - - Stm - .Process(this->TheDuration) - .Process(this->IsLaser) - .Process(this->IsSupported) - .Process(this->IsHouseColor) - .Process(this->IsSingleColor) - .Process(this->LaserInnerColor) - .Process(this->LaserOuterColor) - .Process(this->LaserOuterSpread) - .Process(this->LaserThickness) - .Process(this->LaserDuration) - .Process(this->LaserDelay) - .Process(this->DamageDelay) - .Process(this->LaserTimer) - .Process(this->DamageTimer) - .Process(this->TechnoInLimbo) - .Process(this->NotMainWeapon) - .Process(this->FLHCoord) - .Process(this->BuildingCoord) - ; - + const_cast(this)->Serialize(Stm); return true; } void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) { - auto const pType = this->GetTrajectoryType(pBullet); - - this->TheDuration = pType->TheDuration; - this->IsLaser = pType->IsLaser; - this->IsSupported = pType->IsSupported; - this->IsHouseColor = pType->IsHouseColor; - this->IsSingleColor = pType->IsSingleColor; - this->LaserInnerColor = pType->LaserInnerColor; - this->LaserOuterColor = pType->LaserOuterColor; - this->LaserOuterSpread = pType->LaserOuterSpread; - this->LaserThickness = pType->LaserThickness > 0 ? pType->LaserThickness : 1; - this->LaserDuration = pType->LaserDuration > 0 ? pType->LaserDuration : 1; - this->LaserDelay = pType->LaserDelay > 0 ? pType->LaserDelay : 1; - this->DamageDelay = pType->DamageDelay > 0 ? pType->DamageDelay : 1; - this->LaserTimer.StartTime = 0; - this->DamageTimer.StartTime = 0; this->FLHCoord = pBullet->SourceCoords; this->BuildingCoord = CoordStruct::Empty; TechnoClass* const pTechno = pBullet->Owner; - Point2D sourceOffset = pType->SourceCoord; - Point2D targetOffset = pType->TargetCoord; if (pTechno) { @@ -171,15 +125,15 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->NotMainWeapon = false; this->GetTechnoFLHCoord(pBullet, pTechno); - this->CheckMirrorCoord(pTechno, sourceOffset, targetOffset, pType->MirrorCoord); - this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords, sourceOffset, targetOffset); + this->CheckMirrorCoord(pTechno); + this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords); } else { this->TechnoInLimbo = false; this->NotMainWeapon = true; - this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords, sourceOffset, targetOffset); + this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); } double engraveSpeed = this->GetTrajectorySpeed(pBullet); @@ -190,7 +144,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul WeaponTypeClass* const pWeapon = pBullet->WeaponType; - if (pType->ApplyRangeModifiers && pWeapon && pTechno) + if (this->ApplyRangeModifiers && pWeapon && pTechno) coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); if (this->TheDuration <= 0) @@ -267,34 +221,34 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe this->FLHCoord = pExt->LastWeaponFLH; } -void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno, Point2D& sourceOffset, Point2D& targetOffset, bool mirror) +void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) { - if (this->NotMainWeapon || pTechno->CurrentBurstIndex % 2 == 0) + if (this->NotMainWeapon || !(pTechno->CurrentBurstIndex % 2)) return; - if (mirror) + if (this->MirrorCoord) { - sourceOffset.Y = -(sourceOffset.Y); - targetOffset.Y = -(targetOffset.Y); + this->SourceCoord.Y = -(this->SourceCoord.Y); + this->TargetCoord.Y = -(this->TargetCoord.Y); } } -void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget, Point2D& sourceOffset, Point2D& targetOffset) +void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget) { const double rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); - if (sourceOffset.X != 0 || sourceOffset.Y != 0) + if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) { theSource = theTarget; - theSource.X += static_cast(sourceOffset.X * Math::cos(rotateAngle) + sourceOffset.Y * Math::sin(rotateAngle)); - theSource.Y += static_cast(sourceOffset.X * Math::sin(rotateAngle) - sourceOffset.Y * Math::cos(rotateAngle)); + theSource.X += static_cast(this->SourceCoord.X * Math::cos(rotateAngle) + this->SourceCoord.Y * Math::sin(rotateAngle)); + theSource.Y += static_cast(this->SourceCoord.X * Math::sin(rotateAngle) - this->SourceCoord.Y * Math::cos(rotateAngle)); } theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); pBullet->SetLocation(theSource); - theTarget.X += static_cast(targetOffset.X * Math::cos(rotateAngle) + targetOffset.Y * Math::sin(rotateAngle)); - theTarget.Y += static_cast(targetOffset.X * Math::sin(rotateAngle) - targetOffset.Y * Math::cos(rotateAngle)); + theTarget.X += static_cast(this->TargetCoord.X * Math::cos(rotateAngle) + this->TargetCoord.Y * Math::sin(rotateAngle)); + theTarget.Y += static_cast(this->TargetCoord.X * Math::sin(rotateAngle) - this->TargetCoord.Y * Math::cos(rotateAngle)); pBullet->Velocity.X = theTarget.X - theSource.X; pBullet->Velocity.Y = theTarget.Y - theSource.Y; diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index f7f4eb5f6c..9cfc6d42ff 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -6,10 +6,10 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType { public: EngraveTrajectoryType() : PhobosTrajectoryType(TrajectoryFlag::Engrave) - , ApplyRangeModifiers { false } , SourceCoord { { 0, 0 } } , TargetCoord { { 0, 0 } } , MirrorCoord { true } + , ApplyRangeModifiers { false } , TheDuration { 0 } , IsLaser { true } , IsSupported { false } @@ -29,10 +29,10 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType virtual PhobosTrajectory* CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; - Valueable ApplyRangeModifiers; Valueable SourceCoord; Valueable TargetCoord; Valueable MirrorCoord; + Valueable ApplyRangeModifiers; Valueable TheDuration; Valueable IsLaser; Valueable IsSupported; @@ -45,33 +45,22 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable LaserDuration; Valueable LaserDelay; Valueable DamageDelay; + +private: + template + void Serialize(T& Stm); }; class EngraveTrajectory final : public PhobosTrajectory { public: - EngraveTrajectory() : PhobosTrajectory(TrajectoryFlag::Engrave) - , TheDuration { 0 } - , IsLaser { true } - , IsSupported { false } - , IsHouseColor { false } - , IsSingleColor { false } - , LaserInnerColor {} - , LaserOuterColor {} - , LaserOuterSpread {} - , LaserThickness { 3 } - , LaserDuration { 1 } - , LaserDelay { 1 } - , DamageDelay { 2 } - , LaserTimer {} - , DamageTimer {} - , TechnoInLimbo { false } - , NotMainWeapon { false } - , FLHCoord {} - , BuildingCoord {} - {} + EngraveTrajectory(noinit_t) :PhobosTrajectory { noinit_t{} } { } EngraveTrajectory(PhobosTrajectoryType const* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) + , SourceCoord {} + , TargetCoord {} + , MirrorCoord { true } + , ApplyRangeModifiers { false } , TheDuration { 0 } , IsLaser { true } , IsSupported { false } @@ -90,7 +79,26 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} - {} + { + auto const pFinalType = static_cast(pType); + + this->SourceCoord = pFinalType->SourceCoord; + this->TargetCoord = pFinalType->TargetCoord; + this->MirrorCoord = pFinalType->MirrorCoord; + this->ApplyRangeModifiers = pFinalType->ApplyRangeModifiers; + this->TheDuration = pFinalType->TheDuration; + this->IsLaser = pFinalType->IsLaser; + this->IsSupported = pFinalType->IsSupported; + this->IsHouseColor = pFinalType->IsHouseColor; + this->IsSingleColor = pFinalType->IsSingleColor; + this->LaserInnerColor = pFinalType->LaserInnerColor; + this->LaserOuterColor = pFinalType->LaserOuterColor; + this->LaserOuterSpread = pFinalType->LaserOuterSpread; + this->LaserThickness = pFinalType->LaserThickness > 0 ? pFinalType->LaserThickness : 1; + this->LaserDuration = pFinalType->LaserDuration > 0 ? pFinalType->LaserDuration : 1; + this->LaserDelay = pFinalType->LaserDelay > 0 ? pFinalType->LaserDelay : 1; + this->DamageDelay = pFinalType->DamageDelay > 0 ? pFinalType->DamageDelay : 1; + } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; @@ -102,6 +110,10 @@ class EngraveTrajectory final : public PhobosTrajectory virtual TrajectoryCheckReturnType OnAITargetCoordCheck(BulletClass* pBullet) override; virtual TrajectoryCheckReturnType OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) override; + Point2D SourceCoord; + Point2D TargetCoord; + bool MirrorCoord; + bool ApplyRangeModifiers; int TheDuration; bool IsLaser; bool IsSupported; @@ -122,9 +134,12 @@ class EngraveTrajectory final : public PhobosTrajectory CoordStruct BuildingCoord; private: + template + void Serialize(T& Stm); + void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); - void CheckMirrorCoord(TechnoClass* pTechno, Point2D& sourceOffset, Point2D& targetOffset, bool mirror); - void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget, Point2D& sourceOffset, Point2D& targetOffset); + void CheckMirrorCoord(TechnoClass* pTechno); + void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index 56ec6fb4a8..34bce8cc02 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -7,8 +7,8 @@ #include #include -#include "BombardTrajectory.h" #include "StraightTrajectory.h" +#include "BombardTrajectory.h" #include "EngraveTrajectory.h" bool PhobosTrajectoryType::Load(PhobosStreamReader& Stm, bool RegisterForChange) @@ -147,7 +147,7 @@ PhobosTrajectory* PhobosTrajectory::LoadFromStream(PhobosStreamReader& Stm) pTraj = new BombardTrajectory(noinit_t {}); break; case TrajectoryFlag::Engrave: - pTraj = DLLCreate(); + pTraj = new EngraveTrajectory(noinit_t {}); break; default: return nullptr; From 076c6a2f5c196b59be0fbc1df4104515cc5a8acc Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 24 Sep 2024 01:56:56 +0800 Subject: [PATCH 19/54] Alignment --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 771c631675..edb57e06e4 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -15,10 +15,10 @@ template void EngraveTrajectoryType::Serialize(T& Stm) { Stm - .Process(this->ApplyRangeModifiers) .Process(this->SourceCoord) .Process(this->TargetCoord) .Process(this->MirrorCoord) + .Process(this->ApplyRangeModifiers) .Process(this->TheDuration) .Process(this->IsLaser) .Process(this->IsSupported) From 211a08912d8a7898e06d0a411bca6352eb7d3361 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 24 Sep 2024 15:51:49 +0800 Subject: [PATCH 20/54] Security --- src/Ext/Techno/Hooks.Firing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 0197309bae..49f74f6830 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -415,8 +415,8 @@ DEFINE_HOOK(0x6FDD7D, TechnoClass_FireAt_UpdateWeaponType, 0x5) GET(WeaponTypeClass* const, pWeapon, EBX); GET(TechnoClass* const, pThis, ESI); - auto const pExt = TechnoExt::ExtMap.Find(pThis); - pExt->LastWeaponType = pWeapon; + if (TechnoExt::ExtData* const pExt = TechnoExt::ExtMap.Find(pThis)) + pExt->LastWeaponType = pWeapon; return 0; } From e10a5b7eccfda5a6055d6a2c20c3f425cbe2a2e1 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 24 Sep 2024 16:23:26 +0800 Subject: [PATCH 21/54] Fix initial --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index edb57e06e4..595744134f 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -114,9 +114,9 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) { + this->LaserTimer.Start(0); + this->DamageTimer.Start(0); this->FLHCoord = pBullet->SourceCoords; - this->BuildingCoord = CoordStruct::Empty; - TechnoClass* const pTechno = pBullet->Owner; if (pTechno) From 9b14e7fc760667afdaf4ce529821dbe0661a5e5a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 28 Sep 2024 16:59:09 +0800 Subject: [PATCH 22/54] Optimize --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 47 ++++++++-------- .../Bullet/Trajectories/EngraveTrajectory.h | 55 ++----------------- 2 files changed, 28 insertions(+), 74 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 595744134f..b84fa6bf06 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -73,22 +73,10 @@ template void EngraveTrajectory::Serialize(T& Stm) { Stm + .Process(this->Type) .Process(this->SourceCoord) .Process(this->TargetCoord) - .Process(this->MirrorCoord) - .Process(this->ApplyRangeModifiers) .Process(this->TheDuration) - .Process(this->IsLaser) - .Process(this->IsSupported) - .Process(this->IsHouseColor) - .Process(this->IsSingleColor) - .Process(this->LaserInnerColor) - .Process(this->LaserOuterColor) - .Process(this->LaserOuterSpread) - .Process(this->LaserThickness) - .Process(this->LaserDuration) - .Process(this->LaserDelay) - .Process(this->DamageDelay) .Process(this->LaserTimer) .Process(this->DamageTimer) .Process(this->TechnoInLimbo) @@ -114,6 +102,10 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) { + if (!this->Type) // After load + this->Type = this->GetTrajectoryType(pBullet); + + EngraveTrajectoryType* const pType = this->Type; this->LaserTimer.Start(0); this->DamageTimer.Start(0); this->FLHCoord = pBullet->SourceCoords; @@ -144,7 +136,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul WeaponTypeClass* const pWeapon = pBullet->WeaponType; - if (this->ApplyRangeModifiers && pWeapon && pTechno) + if (pType->ApplyRangeModifiers && pWeapon && pTechno) coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); if (this->TheDuration <= 0) @@ -153,6 +145,9 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul bool EngraveTrajectory::OnAI(BulletClass* pBullet) { + if (!this->Type) // After load + this->Type = this->GetTrajectoryType(pBullet); + TechnoClass* const pTechno = pBullet->Owner; if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) @@ -163,7 +158,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) HouseClass* const pOwner = pTechno->Owner; - if (this->IsLaser && this->LaserTimer.Completed()) + if (this->Type->IsLaser && this->LaserTimer.Completed()) this->DrawEngraveLaser(pBullet, pTechno, pOwner); if (this->DamageTimer.Completed()) @@ -226,7 +221,7 @@ void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) if (this->NotMainWeapon || !(pTechno->CurrentBurstIndex % 2)) return; - if (this->MirrorCoord) + if (this->Type->MirrorCoord) { this->SourceCoord.Y = -(this->SourceCoord.Y); this->TargetCoord.Y = -(this->TargetCoord.Y); @@ -314,7 +309,8 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - this->LaserTimer.Start(this->LaserDelay); + EngraveTrajectoryType* const pType = this->Type; + this->LaserTimer.Start(pType->LaserDelay > 0 ? pType->LaserDelay : 1); LaserDrawClass* pLaser; CoordStruct fireCoord = pTechno->GetCoords(); @@ -346,28 +342,29 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec fireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; } - if (this->IsHouseColor) + if (pType->IsHouseColor) { - pLaser = GameCreate(fireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); pLaser->IsHouseColor = true; } - else if (this->IsSingleColor) + else if (pType->IsSingleColor) { - pLaser = GameCreate(fireCoord, pBullet->Location, this->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, pType->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); pLaser->IsHouseColor = true; } else { - pLaser = GameCreate(fireCoord, pBullet->Location, this->LaserInnerColor, this->LaserOuterColor, this->LaserOuterSpread, this->LaserDuration); + pLaser = GameCreate(fireCoord, pBullet->Location, pType->LaserInnerColor, pType->LaserOuterColor, pType->LaserOuterSpread, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); pLaser->IsHouseColor = false; } - pLaser->Thickness = this->LaserThickness; - pLaser->IsSupported = this->IsSupported; + pLaser->Thickness = (pType->LaserThickness > 0 ? pType->LaserThickness : 1); + pLaser->IsSupported = pType->IsSupported; } void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - this->DamageTimer.Start(this->DamageDelay); + EngraveTrajectoryType* const pType = this->Type; + this->DamageTimer.Start(pType->DamageDelay > 0 ? pType->DamageDelay : 1); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 9cfc6d42ff..e5c19fa977 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -57,48 +57,17 @@ class EngraveTrajectory final : public PhobosTrajectory EngraveTrajectory(noinit_t) :PhobosTrajectory { noinit_t{} } { } EngraveTrajectory(PhobosTrajectoryType const* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) - , SourceCoord {} - , TargetCoord {} - , MirrorCoord { true } - , ApplyRangeModifiers { false } - , TheDuration { 0 } - , IsLaser { true } - , IsSupported { false } - , IsHouseColor { false } - , IsSingleColor { false } - , LaserInnerColor {} - , LaserOuterColor {} - , LaserOuterSpread {} - , LaserThickness { 3 } - , LaserDuration { 1 } - , LaserDelay { 1 } - , DamageDelay { 2 } + , Type { static_cast(const_cast(pType)) } + , SourceCoord { static_cast(Type->SourceCoord) } + , TargetCoord { static_cast(Type->TargetCoord) } + , TheDuration { Type->TheDuration } , LaserTimer {} , DamageTimer {} , TechnoInLimbo { false } , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} - { - auto const pFinalType = static_cast(pType); - - this->SourceCoord = pFinalType->SourceCoord; - this->TargetCoord = pFinalType->TargetCoord; - this->MirrorCoord = pFinalType->MirrorCoord; - this->ApplyRangeModifiers = pFinalType->ApplyRangeModifiers; - this->TheDuration = pFinalType->TheDuration; - this->IsLaser = pFinalType->IsLaser; - this->IsSupported = pFinalType->IsSupported; - this->IsHouseColor = pFinalType->IsHouseColor; - this->IsSingleColor = pFinalType->IsSingleColor; - this->LaserInnerColor = pFinalType->LaserInnerColor; - this->LaserOuterColor = pFinalType->LaserOuterColor; - this->LaserOuterSpread = pFinalType->LaserOuterSpread; - this->LaserThickness = pFinalType->LaserThickness > 0 ? pFinalType->LaserThickness : 1; - this->LaserDuration = pFinalType->LaserDuration > 0 ? pFinalType->LaserDuration : 1; - this->LaserDelay = pFinalType->LaserDelay > 0 ? pFinalType->LaserDelay : 1; - this->DamageDelay = pFinalType->DamageDelay > 0 ? pFinalType->DamageDelay : 1; - } + {} virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; @@ -110,22 +79,10 @@ class EngraveTrajectory final : public PhobosTrajectory virtual TrajectoryCheckReturnType OnAITargetCoordCheck(BulletClass* pBullet) override; virtual TrajectoryCheckReturnType OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) override; + EngraveTrajectoryType* Type; Point2D SourceCoord; Point2D TargetCoord; - bool MirrorCoord; - bool ApplyRangeModifiers; int TheDuration; - bool IsLaser; - bool IsSupported; - bool IsHouseColor; - bool IsSingleColor; - ColorStruct LaserInnerColor; - ColorStruct LaserOuterColor; - ColorStruct LaserOuterSpread; - int LaserThickness; - int LaserDuration; - int LaserDelay; - int DamageDelay; CDTimerClass LaserTimer; CDTimerClass DamageTimer; bool TechnoInLimbo; From 0edd46bcbc05e0eeea896989281738af317a9251 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 28 Sep 2024 17:41:57 +0800 Subject: [PATCH 23/54] Synchronize with other trajectory --- src/Ext/Bullet/Hooks.cpp | 46 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 074281463e..b1456fa8ca 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -305,10 +305,11 @@ DEFINE_HOOK(0x467CCA, BulletClass_AI_TargetSnapChecks, 0x6) } else if (auto const pExt = BulletAITemp::ExtData) { - if (pExt->Trajectory) + if (auto const pTrajectory = pExt->Trajectory) { - if (pExt->Trajectory->Flag == TrajectoryFlag::Straight - || pExt->Trajectory->Flag == TrajectoryFlag::Engrave) + const TrajectoryFlag flag = pTrajectory->Flag; + + if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) { R->EAX(pThis->Type); return SkipChecks; @@ -337,12 +338,18 @@ DEFINE_HOOK(0x468E61, BulletClass_Explode_TargetSnapChecks1, 0x6) } else if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (pExt->Trajectory && !pExt->SnappedToTarget - && (pExt->Trajectory->Flag == TrajectoryFlag::Straight - || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) + if (!pExt->SnappedToTarget) { - R->EAX(pThis->Type); - return SkipChecks; + if (auto const pTrajectory = pExt->Trajectory) + { + const TrajectoryFlag flag = pTrajectory->Flag; + + if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) + { + R->EAX(pThis->Type); + return SkipChecks; + } + } } } @@ -370,12 +377,15 @@ DEFINE_HOOK(0x468E9F, BulletClass_Explode_TargetSnapChecks2, 0x6) // Fixes issues with walls etc. if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - - if (pExt->Trajectory && !pExt->SnappedToTarget - && (pExt->Trajectory->Flag == TrajectoryFlag::Straight - || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) + if (!pExt->SnappedToTarget) { - return SkipSetCoordinate; + if (auto const pTrajectory = pExt->Trajectory) + { + const TrajectoryFlag flag = pTrajectory->Flag; + + if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) + return SkipSetCoordinate; + } } } @@ -390,9 +400,13 @@ DEFINE_HOOK(0x468D3F, BulletClass_ShouldExplode_AirTarget, 0x6) if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (pExt->Trajectory && (pExt->Trajectory->Flag == TrajectoryFlag::Straight - || pExt->Trajectory->Flag == TrajectoryFlag::Engrave)) - return SkipCheck; + if (auto const pTrajectory = pExt->Trajectory) + { + const TrajectoryFlag flag = pTrajectory->Flag; + + if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) + return SkipCheck; + } } return 0; From 85503314ea8f1c53da315800152f427726a3e409 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 4 Oct 2024 18:34:55 +0800 Subject: [PATCH 24/54] Fix merge --- src/Ext/Bullet/Hooks.cpp | 8 +++--- .../Bullet/Trajectories/EngraveTrajectory.cpp | 27 ++++++++----------- .../Bullet/Trajectories/EngraveTrajectory.h | 14 +++++----- .../Bullet/Trajectories/PhobosTrajectory.cpp | 24 ----------------- 4 files changed, 22 insertions(+), 51 deletions(-) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index b1456fa8ca..0ed1f526ef 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -305,7 +305,7 @@ DEFINE_HOOK(0x467CCA, BulletClass_AI_TargetSnapChecks, 0x6) } else if (auto const pExt = BulletAITemp::ExtData) { - if (auto const pTrajectory = pExt->Trajectory) + if (auto const pTrajectory = pExt->Trajectory.get()) { const TrajectoryFlag flag = pTrajectory->Flag; @@ -340,7 +340,7 @@ DEFINE_HOOK(0x468E61, BulletClass_Explode_TargetSnapChecks1, 0x6) { if (!pExt->SnappedToTarget) { - if (auto const pTrajectory = pExt->Trajectory) + if (auto const pTrajectory = pExt->Trajectory.get()) { const TrajectoryFlag flag = pTrajectory->Flag; @@ -379,7 +379,7 @@ DEFINE_HOOK(0x468E9F, BulletClass_Explode_TargetSnapChecks2, 0x6) { if (!pExt->SnappedToTarget) { - if (auto const pTrajectory = pExt->Trajectory) + if (auto const pTrajectory = pExt->Trajectory.get()) { const TrajectoryFlag flag = pTrajectory->Flag; @@ -400,7 +400,7 @@ DEFINE_HOOK(0x468D3F, BulletClass_ShouldExplode_AirTarget, 0x6) if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (auto const pTrajectory = pExt->Trajectory) + if (auto const pTrajectory = pExt->Trajectory.get()) { const TrajectoryFlag flag = pTrajectory->Flag; diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index b84fa6bf06..f243c9b59e 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -6,9 +6,9 @@ #include #include -PhobosTrajectory* EngraveTrajectoryType::CreateInstance() const +std::unique_ptr EngraveTrajectoryType::CreateInstance() const { - return new EngraveTrajectory(this); + return std::make_unique(this); } template @@ -51,6 +51,10 @@ bool EngraveTrajectoryType::Save(PhobosStreamWriter& Stm) const void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) { INI_EX exINI(pINI); + + if (this->Trajectory_Speed > 128.0) + this->Trajectory_Speed = 128.0; + this->ApplyRangeModifiers.Read(exINI, pSection, "Trajectory.Engrave.ApplyRangeModifiers"); this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); @@ -102,10 +106,7 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) { - if (!this->Type) // After load - this->Type = this->GetTrajectoryType(pBullet); - - EngraveTrajectoryType* const pType = this->Type; + const EngraveTrajectoryType* const pType = this->Type; this->LaserTimer.Start(0); this->DamageTimer.Start(0); this->FLHCoord = pBullet->SourceCoords; @@ -128,11 +129,8 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); } - double engraveSpeed = this->GetTrajectorySpeed(pBullet); - engraveSpeed = engraveSpeed > 128.0 ? 128.0 : engraveSpeed; - double coordDistance = pBullet->Velocity.Magnitude(); - pBullet->Velocity *= (coordDistance > 1e-10) ? (engraveSpeed / coordDistance) : 0; + pBullet->Velocity *= (coordDistance > 1e-10) ? (this->Speed / coordDistance) : 0; WeaponTypeClass* const pWeapon = pBullet->WeaponType; @@ -140,14 +138,11 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); if (this->TheDuration <= 0) - this->TheDuration = static_cast(coordDistance / engraveSpeed) + 1; + this->TheDuration = static_cast(coordDistance / this->Speed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) { - if (!this->Type) // After load - this->Type = this->GetTrajectoryType(pBullet); - TechnoClass* const pTechno = pBullet->Owner; if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) @@ -309,7 +304,7 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - EngraveTrajectoryType* const pType = this->Type; + const EngraveTrajectoryType* const pType = this->Type; this->LaserTimer.Start(pType->LaserDelay > 0 ? pType->LaserDelay : 1); LaserDrawClass* pLaser; CoordStruct fireCoord = pTechno->GetCoords(); @@ -364,7 +359,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - EngraveTrajectoryType* const pType = this->Type; + const EngraveTrajectoryType* const pType = this->Type; this->DamageTimer.Start(pType->DamageDelay > 0 ? pType->DamageDelay : 1); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index e5c19fa977..60a806f3fa 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -26,7 +26,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; - virtual PhobosTrajectory* CreateInstance() const override; + virtual std::unique_ptr CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; Valueable SourceCoord; @@ -56,11 +56,11 @@ class EngraveTrajectory final : public PhobosTrajectory public: EngraveTrajectory(noinit_t) :PhobosTrajectory { noinit_t{} } { } - EngraveTrajectory(PhobosTrajectoryType const* pType) : PhobosTrajectory(TrajectoryFlag::Engrave) - , Type { static_cast(const_cast(pType)) } - , SourceCoord { static_cast(Type->SourceCoord) } - , TargetCoord { static_cast(Type->TargetCoord) } - , TheDuration { Type->TheDuration } + EngraveTrajectory(EngraveTrajectoryType const* trajType) : PhobosTrajectory(TrajectoryFlag::Engrave, trajType->Trajectory_Speed) + , Type { trajType } + , SourceCoord { trajType->SourceCoord.Get() } + , TargetCoord { trajType->TargetCoord.Get() } + , TheDuration { trajType->TheDuration } , LaserTimer {} , DamageTimer {} , TechnoInLimbo { false } @@ -79,7 +79,7 @@ class EngraveTrajectory final : public PhobosTrajectory virtual TrajectoryCheckReturnType OnAITargetCoordCheck(BulletClass* pBullet) override; virtual TrajectoryCheckReturnType OnAITechnoCheck(BulletClass* pBullet, TechnoClass* pTechno) override; - EngraveTrajectoryType* Type; + const EngraveTrajectoryType* Type; Point2D SourceCoord; Point2D TargetCoord; int TheDuration; diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index 0051aa9bdd..f404e3e5c1 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -7,10 +7,7 @@ #include "StraightTrajectory.h" #include "BombardTrajectory.h" -#include "DisperseTrajectory.h" #include "EngraveTrajectory.h" -#include "ParabolaTrajectory.h" -#include "TracingTrajectory.h" TrajectoryTypePointer::TrajectoryTypePointer(TrajectoryFlag flag) { @@ -22,18 +19,9 @@ TrajectoryTypePointer::TrajectoryTypePointer(TrajectoryFlag flag) case TrajectoryFlag::Bombard: _ptr = std::make_unique(); return; - case TrajectoryFlag::Disperse: - _ptr = std::make_unique(); - return; case TrajectoryFlag::Engrave: _ptr = std::make_unique(); return; - case TrajectoryFlag::Parabola: - _ptr = std::make_unique(); - return; - case TrajectoryFlag::Tracing: - _ptr = std::make_unique(); - return; } _ptr.reset(); } @@ -49,10 +37,7 @@ namespace detail { {"Straight", TrajectoryFlag::Straight}, {"Bombard" ,TrajectoryFlag::Bombard}, - {"Disperse", TrajectoryFlag::Disperse}, {"Engrave" ,TrajectoryFlag::Engrave}, - {"Parabola", TrajectoryFlag::Parabola}, - {"Tracing" ,TrajectoryFlag::Tracing}, }; for (auto [name, flag] : FlagNames) { @@ -133,18 +118,9 @@ bool TrajectoryPointer::Load(PhobosStreamReader& Stm, bool registerForChange) case TrajectoryFlag::Bombard: _ptr = std::make_unique(noinit_t {}); break; - case TrajectoryFlag::Disperse: - _ptr = std::make_unique(noinit_t {}); - break; case TrajectoryFlag::Engrave: _ptr = std::make_unique(noinit_t {}); break; - case TrajectoryFlag::Parabola: - _ptr = std::make_unique(noinit_t {}); - break; - case TrajectoryFlag::Tracing: - _ptr = std::make_unique(noinit_t {}); - break; default: _ptr.reset(); break; From 17bf0fa8a5df52b74b299d2dae2f7fb6870a1164 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 4 Oct 2024 20:54:48 +0800 Subject: [PATCH 25/54] Fix merge --- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 60a806f3fa..fdde29dbf5 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -5,7 +5,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType { public: - EngraveTrajectoryType() : PhobosTrajectoryType(TrajectoryFlag::Engrave) + EngraveTrajectoryType() : PhobosTrajectoryType() , SourceCoord { { 0, 0 } } , TargetCoord { { 0, 0 } } , MirrorCoord { true } @@ -28,6 +28,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType virtual bool Save(PhobosStreamWriter& Stm) const override; virtual std::unique_ptr CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; + virtual TrajectoryFlag Flag() const { return TrajectoryFlag::Engrave; } Valueable SourceCoord; Valueable TargetCoord; @@ -56,7 +57,7 @@ class EngraveTrajectory final : public PhobosTrajectory public: EngraveTrajectory(noinit_t) :PhobosTrajectory { noinit_t{} } { } - EngraveTrajectory(EngraveTrajectoryType const* trajType) : PhobosTrajectory(TrajectoryFlag::Engrave, trajType->Trajectory_Speed) + EngraveTrajectory(EngraveTrajectoryType const* trajType) : PhobosTrajectory(trajType->Trajectory_Speed) , Type { trajType } , SourceCoord { trajType->SourceCoord.Get() } , TargetCoord { trajType->TargetCoord.Get() } @@ -71,7 +72,7 @@ class EngraveTrajectory final : public PhobosTrajectory virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; - + virtual TrajectoryFlag Flag() const { return TrajectoryFlag::Engrave; } virtual void OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) override; virtual bool OnAI(BulletClass* pBullet) override; virtual void OnAIPreDetonate(BulletClass* pBullet) override; From d3b3fd55662018e47d779176f4bc998754e65b03 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 6 Oct 2024 20:41:39 +0800 Subject: [PATCH 26/54] Fix merge --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 6 ++---- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 13 ++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index f243c9b59e..56a91a1578 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -92,14 +92,12 @@ void EngraveTrajectory::Serialize(T& Stm) bool EngraveTrajectory::Load(PhobosStreamReader& Stm, bool RegisterForChange) { - this->PhobosTrajectory::Load(Stm, false); this->Serialize(Stm); return true; } bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const { - this->PhobosTrajectory::Save(Stm); const_cast(this)->Serialize(Stm); return true; } @@ -130,7 +128,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul } double coordDistance = pBullet->Velocity.Magnitude(); - pBullet->Velocity *= (coordDistance > 1e-10) ? (this->Speed / coordDistance) : 0; + pBullet->Velocity *= (coordDistance > 1e-10) ? (pType->Trajectory_Speed / coordDistance) : 0; WeaponTypeClass* const pWeapon = pBullet->WeaponType; @@ -138,7 +136,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); if (this->TheDuration <= 0) - this->TheDuration = static_cast(coordDistance / this->Speed) + 1; + this->TheDuration = static_cast(coordDistance / pType->Trajectory_Speed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index fdde29dbf5..7498f0c25b 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -22,13 +22,13 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , LaserDuration { 1 } , LaserDelay { 1 } , DamageDelay { 2 } - {} + { } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; virtual std::unique_ptr CreateInstance() const override; virtual void Read(CCINIClass* const pINI, const char* pSection) override; - virtual TrajectoryFlag Flag() const { return TrajectoryFlag::Engrave; } + virtual TrajectoryFlag Flag() const override { return TrajectoryFlag::Engrave; } Valueable SourceCoord; Valueable TargetCoord; @@ -55,10 +55,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType class EngraveTrajectory final : public PhobosTrajectory { public: - EngraveTrajectory(noinit_t) :PhobosTrajectory { noinit_t{} } { } + EngraveTrajectory(noinit_t) { } - EngraveTrajectory(EngraveTrajectoryType const* trajType) : PhobosTrajectory(trajType->Trajectory_Speed) - , Type { trajType } + EngraveTrajectory(EngraveTrajectoryType const* trajType) : Type { trajType } , SourceCoord { trajType->SourceCoord.Get() } , TargetCoord { trajType->TargetCoord.Get() } , TheDuration { trajType->TheDuration } @@ -68,11 +67,11 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} - {} + { } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; virtual bool Save(PhobosStreamWriter& Stm) const override; - virtual TrajectoryFlag Flag() const { return TrajectoryFlag::Engrave; } + virtual TrajectoryFlag Flag() const override { return TrajectoryFlag::Engrave; } virtual void OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) override; virtual bool OnAI(BulletClass* pBullet) override; virtual void OnAIPreDetonate(BulletClass* pBullet) override; From 72aec0918df61341499ec4be0e839e5c45b99158 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 8 Nov 2024 00:47:57 +0800 Subject: [PATCH 27/54] Const auto --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 42 +++++++++---------- src/Ext/Techno/Hooks.Firing.cpp | 12 +++--- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 56a91a1578..809d6771e9 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -104,11 +104,11 @@ bool EngraveTrajectory::Save(PhobosStreamWriter& Stm) const void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, BulletVelocity* pVelocity) { - const EngraveTrajectoryType* const pType = this->Type; + const auto pType = this->Type; this->LaserTimer.Start(0); this->DamageTimer.Start(0); this->FLHCoord = pBullet->SourceCoords; - TechnoClass* const pTechno = pBullet->Owner; + const auto pTechno = pBullet->Owner; if (pTechno) { @@ -127,10 +127,10 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); } - double coordDistance = pBullet->Velocity.Magnitude(); + auto coordDistance = pBullet->Velocity.Magnitude(); pBullet->Velocity *= (coordDistance > 1e-10) ? (pType->Trajectory_Speed / coordDistance) : 0; - WeaponTypeClass* const pWeapon = pBullet->WeaponType; + const auto pWeapon = pBullet->WeaponType; if (pType->ApplyRangeModifiers && pWeapon && pTechno) coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); @@ -141,7 +141,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul bool EngraveTrajectory::OnAI(BulletClass* pBullet) { - TechnoClass* const pTechno = pBullet->Owner; + const auto pTechno = pBullet->Owner; if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) return true; @@ -149,7 +149,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) return true; - HouseClass* const pOwner = pTechno->Owner; + const auto pOwner = pTechno->Owner; if (this->Type->IsLaser && this->LaserTimer.Completed()) this->DrawEngraveLaser(pBullet, pTechno, pOwner); @@ -182,7 +182,7 @@ TrajectoryCheckReturnType EngraveTrajectory::OnAITechnoCheck(BulletClass* pBulle void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno) { - TechnoExt::ExtData* pExt = TechnoExt::ExtMap.Find(pTechno); + const auto pExt = TechnoExt::ExtMap.Find(pTechno); if (!pExt || !pExt->LastWeaponType || pExt->LastWeaponType->Projectile != pBullet->Type) { @@ -191,7 +191,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe } else if (pTechno->WhatAmI() == AbstractType::Building) { - const BuildingClass* const pBuilding = static_cast(pTechno); + const auto pBuilding = static_cast(pTechno); Matrix3D mtx; mtx.MakeIdentity(); @@ -202,7 +202,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe } mtx.Translate(static_cast(pExt->LastWeaponFLH.X), static_cast(pExt->LastWeaponFLH.Y), static_cast(pExt->LastWeaponFLH.Z)); - auto const result = mtx.GetTranslation(); + const auto result = mtx.GetTranslation(); this->BuildingCoord = pBullet->SourceCoords - pBuilding->GetCoords() - CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; } @@ -223,7 +223,7 @@ void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget) { - const double rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); + const auto rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) { @@ -245,10 +245,10 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct th int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord) { - if (const CellClass* const pCell = MapClass::Instance->GetCellAt(coord)) + if (const auto pCell = MapClass::Instance->GetCellAt(coord)) { - const int onFloor = MapClass::Instance->GetCellFloorHeight(coord); - const int onBridge = pCell->GetCoordsWithBridge().Z; + const auto onFloor = MapClass::Instance->GetCellFloorHeight(coord); + const auto onBridge = pCell->GetCoordsWithBridge().Z; if (pBullet->SourceCoords.Z >= onBridge || pBullet->TargetCoords.Z >= onBridge) return onBridge; @@ -261,7 +261,7 @@ int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coo bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) { - CoordStruct bulletCoords = pBullet->Location; + auto bulletCoords = pBullet->Location; CoordStruct futureCoords { bulletCoords.X + static_cast(pBullet->Velocity.X), @@ -269,7 +269,7 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) bulletCoords.Z + static_cast(pBullet->Velocity.Z) }; - const int checkDifference = this->GetFloorCoordHeight(pBullet, futureCoords) - futureCoords.Z; + const auto checkDifference = this->GetFloorCoordHeight(pBullet, futureCoords) - futureCoords.Z; if (abs(checkDifference) >= 384) { @@ -283,7 +283,7 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) } else { - const int nowDifference = bulletCoords.Z - this->GetFloorCoordHeight(pBullet, bulletCoords); + const auto nowDifference = bulletCoords.Z - this->GetFloorCoordHeight(pBullet, bulletCoords); if (nowDifference >= 256) { @@ -302,10 +302,10 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - const EngraveTrajectoryType* const pType = this->Type; + const auto pType = this->Type; this->LaserTimer.Start(pType->LaserDelay > 0 ? pType->LaserDelay : 1); LaserDrawClass* pLaser; - CoordStruct fireCoord = pTechno->GetCoords(); + auto fireCoord = pTechno->GetCoords(); if (this->NotMainWeapon) { @@ -320,7 +320,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec } else { - const BuildingClass* const pBuilding = static_cast(pTechno); + const auto pBuilding = static_cast(pTechno); Matrix3D mtx; mtx.MakeIdentity(); @@ -331,7 +331,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec } mtx.Translate(static_cast(this->FLHCoord.X), static_cast(this->FLHCoord.Y), static_cast(this->FLHCoord.Z)); - auto const result = mtx.GetTranslation(); + const auto result = mtx.GetTranslation(); fireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; } @@ -357,7 +357,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - const EngraveTrajectoryType* const pType = this->Type; + const auto pType = this->Type; this->DamageTimer.Start(pType->DamageDelay > 0 ? pType->DamageDelay : 1); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 83e8e113cf..98de994f87 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -622,29 +622,29 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) GET(int, OriginalZ, EAX); GET_STACK(int, weaponIndex, STACK_OFFSET(0xD8, 0x8)); - auto const pExt = TechnoExt::ExtMap.Find(pThis); + const auto pExt = TechnoExt::ExtMap.Find(pThis); if (!pExt) return 0; - auto const pTypeExt = pExt->TypeExtData; + const auto pTypeExt = pExt->TypeExtData; if (weaponIndex < 0) { - FootClass* currentPassenger = pThis->Passengers.FirstPassenger; - const int passengerIndex = -weaponIndex - 1; + auto currentPassenger = pThis->Passengers.FirstPassenger; + const auto passengerIndex = -weaponIndex - 1; for (int i = 0; i < passengerIndex && currentPassenger; i++) currentPassenger = abstract_cast(currentPassenger->NextObject); - if (auto const pPassengerExt = TechnoExt::ExtMap.Find(currentPassenger)) + if (const auto pPassengerExt = TechnoExt::ExtMap.Find(currentPassenger)) pPassengerExt->LastWeaponFLH = { OriginalX, OriginalY, OriginalZ }; return 0; } bool FLHFound = false; - CoordStruct FLH = CoordStruct::Empty; + auto FLH = CoordStruct::Empty; FLH = TechnoExt::GetBurstFLH(pThis, weaponIndex, FLHFound, pTypeExt); BurstFLHTemp::FLHFound = FLHFound; From 3d33d48a6abe5aa9501309fa43ed96b8d239432c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 27 Nov 2024 18:33:33 +0800 Subject: [PATCH 28/54] Clear up and fix a mistake when fired by a 'dead' techno --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 102 ++++++++++-------- .../Bullet/Trajectories/EngraveTrajectory.h | 4 +- 2 files changed, 59 insertions(+), 47 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 809d6771e9..74e50e3352 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -1,10 +1,12 @@ #include "EngraveTrajectory.h" + +#include +#include + #include #include #include #include -#include -#include std::unique_ptr EngraveTrajectoryType::CreateInstance() const { @@ -68,9 +70,24 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->LaserOuterColor.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterColor"); this->LaserOuterSpread.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterSpread"); this->LaserThickness.Read(exINI, pSection, "Trajectory.Engrave.LaserThickness"); + + if (this->LaserThickness <= 0) + this->LaserThickness = 1; + this->LaserDuration.Read(exINI, pSection, "Trajectory.Engrave.LaserDuration"); + + if (this->LaserDuration <= 0) + this->LaserDuration = 1; + this->LaserDelay.Read(exINI, pSection, "Trajectory.Engrave.LaserDelay"); + + if (this->LaserDelay <= 0) + this->LaserDelay = 1; + this->DamageDelay.Read(exINI, pSection, "Trajectory.Engrave.DamageDelay"); + + if (this->DamageDelay <= 0) + this->DamageDelay = 1; } template @@ -83,7 +100,7 @@ void EngraveTrajectory::Serialize(T& Stm) .Process(this->TheDuration) .Process(this->LaserTimer) .Process(this->DamageTimer) - .Process(this->TechnoInLimbo) + .Process(this->TechnoInTransport) .Process(this->NotMainWeapon) .Process(this->FLHCoord) .Process(this->BuildingCoord) @@ -112,8 +129,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul if (pTechno) { - this->TechnoInLimbo = static_cast(pTechno->Transporter); - this->NotMainWeapon = false; + this->TechnoInTransport = static_cast(pTechno->Transporter); this->GetTechnoFLHCoord(pBullet, pTechno); this->CheckMirrorCoord(pTechno); @@ -121,7 +137,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul } else { - this->TechnoInLimbo = false; + this->TechnoInTransport = false; this->NotMainWeapon = true; this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); @@ -143,13 +159,13 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) { const auto pTechno = pBullet->Owner; - if ((!pTechno && !this->NotMainWeapon) || this->TechnoInLimbo != static_cast(pTechno->Transporter)) + if ((!pTechno && !this->NotMainWeapon) || (pTechno && this->TechnoInTransport != static_cast(pTechno->Transporter))) return true; if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) return true; - const auto pOwner = pTechno->Owner; + const auto pOwner = pTechno ? pTechno->Owner : BulletExt::ExtMap.Find(pBullet)->FirerHouse; if (this->Type->IsLaser && this->LaserTimer.Completed()) this->DrawEngraveLaser(pBullet, pTechno, pOwner); @@ -303,61 +319,57 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { const auto pType = this->Type; - this->LaserTimer.Start(pType->LaserDelay > 0 ? pType->LaserDelay : 1); - LaserDrawClass* pLaser; - auto fireCoord = pTechno->GetCoords(); + this->LaserTimer.Start(pType->LaserDelay); - if (this->NotMainWeapon) - { - fireCoord = this->FLHCoord; - } - else if (pTechno->WhatAmI() != AbstractType::Building) - { - if (this->TechnoInLimbo) - fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno->Transporter, this->FLHCoord, pTechno->Transporter->HasTurret()); - else - fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); - } - else - { - const auto pBuilding = static_cast(pTechno); - Matrix3D mtx; - mtx.MakeIdentity(); + const auto pTransporter = pTechno->Transporter; + auto fireCoord = pBullet->SourceCoords; - if (pTechno->HasTurret()) + if (!this->NotMainWeapon && pTechno && (pTransporter || !pTechno->InLimbo)) + { + if (pTechno->WhatAmI() != AbstractType::Building) { - TechnoTypeExt::ApplyTurretOffset(pBuilding->Type, &mtx); - mtx.RotateZ(static_cast(pTechno->TurretFacing().GetRadian<32>())); + if (pTransporter) + fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTransporter, this->FLHCoord, pTransporter->HasTurret()); + else + fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); } + else + { + const auto pBuilding = static_cast(pTechno); + Matrix3D mtx; + mtx.MakeIdentity(); - mtx.Translate(static_cast(this->FLHCoord.X), static_cast(this->FLHCoord.Y), static_cast(this->FLHCoord.Z)); - const auto result = mtx.GetTranslation(); - fireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; - } + if (pTechno->HasTurret()) + { + TechnoTypeExt::ApplyTurretOffset(pBuilding->Type, &mtx); + mtx.RotateZ(static_cast(pTechno->TurretFacing().GetRadian<32>())); + } - if (pType->IsHouseColor) - { - pLaser = GameCreate(fireCoord, pBullet->Location, pOwner->LaserColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); - pLaser->IsHouseColor = true; + mtx.Translate(static_cast(this->FLHCoord.X), static_cast(this->FLHCoord.Y), static_cast(this->FLHCoord.Z)); + const auto result = mtx.GetTranslation(); + fireCoord = pBuilding->GetCoords() + this->BuildingCoord + CoordStruct { static_cast(result.X), -static_cast(result.Y), static_cast(result.Z) }; + } } - else if (pType->IsSingleColor) + + if (pType->IsHouseColor || pType->IsSingleColor) { - pLaser = GameCreate(fireCoord, pBullet->Location, pType->LaserInnerColor, ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); + const auto pLaser = GameCreate(fireCoord, pBullet->Location, ((pType->IsHouseColor && pOwner) ? pOwner->LaserColor : pType->LaserInnerColor), ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, pType->LaserDuration); pLaser->IsHouseColor = true; + pLaser->Thickness = pType->LaserThickness; + pLaser->IsSupported = pType->IsSupported; } else { - pLaser = GameCreate(fireCoord, pBullet->Location, pType->LaserInnerColor, pType->LaserOuterColor, pType->LaserOuterSpread, (pType->LaserDuration > 0 ? pType->LaserDuration : 1)); + const auto pLaser = GameCreate(fireCoord, pBullet->Location, pType->LaserInnerColor, pType->LaserOuterColor, pType->LaserOuterSpread, pType->LaserDuration); pLaser->IsHouseColor = false; + pLaser->Thickness = 3; + pLaser->IsSupported = false; } - - pLaser->Thickness = (pType->LaserThickness > 0 ? pType->LaserThickness : 1); - pLaser->IsSupported = pType->IsSupported; } void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { const auto pType = this->Type; - this->DamageTimer.Start(pType->DamageDelay > 0 ? pType->DamageDelay : 1); + this->DamageTimer.Start(pType->DamageDelay); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 7498f0c25b..a6eee73268 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -63,7 +63,7 @@ class EngraveTrajectory final : public PhobosTrajectory , TheDuration { trajType->TheDuration } , LaserTimer {} , DamageTimer {} - , TechnoInLimbo { false } + , TechnoInTransport { false } , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} @@ -85,7 +85,7 @@ class EngraveTrajectory final : public PhobosTrajectory int TheDuration; CDTimerClass LaserTimer; CDTimerClass DamageTimer; - bool TechnoInLimbo; + bool TechnoInTransport; bool NotMainWeapon; CoordStruct FLHCoord; CoordStruct BuildingCoord; From 70dd0f2658abc2d7428f8f47ce72b3aa802141dd Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 27 Nov 2024 19:55:44 +0800 Subject: [PATCH 29/54] Small fix --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 74e50e3352..804da00d16 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -159,7 +159,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) { const auto pTechno = pBullet->Owner; - if ((!pTechno && !this->NotMainWeapon) || (pTechno && this->TechnoInTransport != static_cast(pTechno->Transporter))) + if (!this->NotMainWeapon && (!pTechno || this->TechnoInTransport != static_cast(pTechno->Transporter))) return true; if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) From d414c6dfd4639316bac892ee132911fcbe3d151c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 27 Nov 2024 20:52:36 +0800 Subject: [PATCH 30/54] Check fire condition --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 17 ++++++++++++++++- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 804da00d16..5dafcc6c82 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -159,7 +159,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) { const auto pTechno = pBullet->Owner; - if (!this->NotMainWeapon && (!pTechno || this->TechnoInTransport != static_cast(pTechno->Transporter))) + if (!this->NotMainWeapon && this->InvalidFireCondition(pTechno)) return true; if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) @@ -259,6 +259,21 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct th pBullet->Velocity.Z = 0; } +bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) +{ + return (!pTechno + || !pTechno->IsAlive + || !pTechno->IsOnMap + || pTechno->InLimbo + || pTechno->IsSinking + || pTechno->Health <= 0 + || this->TechnoInTransport != static_cast(pTechno->Transporter) + || pTechno->Deactivated + || pTechno->TemporalTargetingMe + || pTechno->BeingWarpedOut + || pTechno->IsUnderEMP()); +} + int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord) { if (const auto pCell = MapClass::Instance->GetCellAt(coord)) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index a6eee73268..e5b5a17b06 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -97,6 +97,7 @@ class EngraveTrajectory final : public PhobosTrajectory void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); void CheckMirrorCoord(TechnoClass* pTechno); void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); + bool InvalidFireCondition(TechnoClass* pTechno); int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); From ef51b0c734c226950ebe5928deaae5c8d370b104 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 27 Nov 2024 22:29:41 +0800 Subject: [PATCH 31/54] Fix in transport --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 5dafcc6c82..41ccb7fa60 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -263,8 +263,7 @@ bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) { return (!pTechno || !pTechno->IsAlive - || !pTechno->IsOnMap - || pTechno->InLimbo + || (pTechno->InLimbo && !pTechno->Transporter) || pTechno->IsSinking || pTechno->Health <= 0 || this->TechnoInTransport != static_cast(pTechno->Transporter) From e77bf3fb82063c0656d41274549b6a9e175248f5 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 28 Nov 2024 23:37:47 +0800 Subject: [PATCH 32/54] Fix a mistake --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 41ccb7fa60..19b7ec2b2b 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -178,7 +178,10 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) void EngraveTrajectory::OnAIPreDetonate(BulletClass* pBullet) { - pBullet->UnInit(); //Prevent damage again. + //Prevent damage again. + pBullet->Health = 0; + pBullet->Limbo(); + pBullet->UnInit(); } void EngraveTrajectory::OnAIVelocity(BulletClass* pBullet, BulletVelocity* pSpeed, BulletVelocity* pPosition) From efe0d6f93447eb99c81efc2e226b54f05d1da3b3 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 27 Dec 2024 00:29:56 +0800 Subject: [PATCH 33/54] Remove useless codes --- src/Ext/Techno/Body.Internal.cpp | 24 ++++++++++-------------- src/Ext/Techno/Body.h | 4 ++-- src/Ext/Techno/Hooks.Firing.cpp | 18 +++++------------- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/Ext/Techno/Body.Internal.cpp b/src/Ext/Techno/Body.Internal.cpp index e4231741d9..e643505f45 100644 --- a/src/Ext/Techno/Body.Internal.cpp +++ b/src/Ext/Techno/Body.Internal.cpp @@ -72,32 +72,31 @@ CoordStruct TechnoExt::GetFLHAbsoluteCoords(TechnoClass* pThis, CoordStruct pCoo return location; } -CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt) +CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound) { FLHFound = false; CoordStruct FLH = CoordStruct::Empty; - if (!pTypeExt) - pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); + auto const pExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); auto pInf = abstract_cast(pThis); - std::span> pickedFLHs = pTypeExt->WeaponBurstFLHs; + std::span> pickedFLHs = pExt->WeaponBurstFLHs; if (pThis->Veterancy.IsElite()) { if (pInf && pInf->IsDeployed()) - pickedFLHs = pTypeExt->EliteDeployedWeaponBurstFLHs; + pickedFLHs = pExt->EliteDeployedWeaponBurstFLHs; else if (pInf && pInf->Crawling) - pickedFLHs = pTypeExt->EliteCrouchedWeaponBurstFLHs; + pickedFLHs = pExt->EliteCrouchedWeaponBurstFLHs; else - pickedFLHs = pTypeExt->EliteWeaponBurstFLHs; + pickedFLHs = pExt->EliteWeaponBurstFLHs; } else { if (pInf && pInf->IsDeployed()) - pickedFLHs = pTypeExt->DeployedWeaponBurstFLHs; + pickedFLHs = pExt->DeployedWeaponBurstFLHs; else if (pInf && pInf->Crawling) - pickedFLHs = pTypeExt->CrouchedWeaponBurstFLHs; + pickedFLHs = pExt->CrouchedWeaponBurstFLHs; } if ((int)pickedFLHs[weaponIndex].size() > pThis->CurrentBurstIndex) { @@ -108,15 +107,12 @@ CoordStruct TechnoExt::GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FL return FLH; } -CoordStruct TechnoExt::GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt) +CoordStruct TechnoExt::GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound) { FLHFound = false; CoordStruct FLH = CoordStruct::Empty; - if (!pTypeExt) - pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); - - if (pTypeExt) + if (auto pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Type)) { Nullable pickedFLH; diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 3982202497..7e477baabf 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -149,8 +149,8 @@ class TechnoExt static CoordStruct GetFLHAbsoluteCoords(TechnoClass* pThis, CoordStruct flh, bool turretFLH = false); - static CoordStruct GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt = nullptr); - static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound, TechnoTypeExt::ExtData* pTypeExt = nullptr); + static CoordStruct GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound); + static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound); static void ChangeOwnerMissionFix(FootClass* pThis); static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, AnimTypeClass* pVanishAnimation, bool isInLimbo = false); diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 1350cbd341..bf70f64dc7 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -685,13 +685,6 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) GET(int, OriginalZ, EAX); GET_STACK(int, weaponIndex, STACK_OFFSET(0xD8, 0x8)); - const auto pExt = TechnoExt::ExtMap.Find(pThis); - - if (!pExt) - return 0; - - const auto pTypeExt = pExt->TypeExtData; - if (weaponIndex < 0) { auto currentPassenger = pThis->Passengers.FirstPassenger; @@ -707,26 +700,25 @@ DEFINE_HOOK(0x6F3B37, TechnoClass_GetFLH_BurstFLH_1, 0x7) } bool FLHFound = false; - auto FLH = CoordStruct::Empty; - - FLH = TechnoExt::GetBurstFLH(pThis, weaponIndex, FLHFound, pTypeExt); + auto FLH = TechnoExt::GetBurstFLH(pThis, weaponIndex, FLHFound); BurstFLHTemp::FLHFound = FLHFound; if (!FLHFound) { if (auto pInf = abstract_cast(pThis)) - FLH = TechnoExt::GetSimpleFLH(pInf, weaponIndex, FLHFound, pTypeExt); + FLH = TechnoExt::GetSimpleFLH(pInf, weaponIndex, FLHFound); } if (FLHFound) { - pExt->LastWeaponFLH = FLH; + if (const auto pExt = TechnoExt::ExtMap.Find(pThis)) + pExt->LastWeaponFLH = FLH; R->ECX(FLH.X); R->EBP(FLH.Y); R->EAX(FLH.Z); } - else + else if (const auto pExt = TechnoExt::ExtMap.Find(pThis)) { pExt->LastWeaponFLH = { OriginalX, ((pThis->CurrentBurstIndex % 2 == 1) ? -OriginalY : OriginalY), OriginalZ }; } From a9f459559debcfdc9838c4a26340cc72c3e58cf3 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 27 Dec 2024 02:26:28 +0800 Subject: [PATCH 34/54] Fix doc --- docs/New-or-Enhanced-Logics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 77be8c8788..59a8f24a34 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -790,6 +790,7 @@ Trajectory.Bombard.Height=0.0 ; double In `rulesmd.ini`: ```ini +[SOMEPROJECTILE] ; Projectile Trajectory=Engrave ; Trajectory type Trajectory.Engrave.ApplyRangeModifiers=false ; boolean Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral From 2e141ce463a36779c09f8a6df92a7d3853a90bd6 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 27 Dec 2024 17:02:59 +0800 Subject: [PATCH 35/54] Remove useless sanity check --- src/Ext/Bullet/Hooks.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 8057e75a87..501a9dbb67 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -478,11 +478,8 @@ DEFINE_HOOK(0x415F25, AircraftClass_Fire_TrajectorySkipInertiaEffect, 0x6) GET(BulletClass*, pThis, ESI); - if (auto const pExt = BulletExt::ExtMap.Find(pThis)) - { - if (pExt->Trajectory) - return SkipCheck; - } + if (BulletExt::ExtMap.Find(pThis)->Trajectory) + return SkipCheck; return 0; } From d066904985dbb325d9cdb58ceaf9d8484c52e81c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 28 Dec 2024 00:32:58 +0800 Subject: [PATCH 36/54] Synchronize --- src/Ext/Bullet/Hooks.cpp | 52 +++++++++++++--------------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 501a9dbb67..5de11097de 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -290,6 +290,12 @@ DEFINE_HOOK(0x46902C, BulletClass_Explode_Cluster, 0x6) return SkipGameCode; } +constexpr bool CheckTrajectoryCanNotAlwaysSnap(const TrajectoryFlag flag) +{ + return flag == TrajectoryFlag::Straight + || flag == TrajectoryFlag::Engrave; +} + DEFINE_HOOK(0x467CCA, BulletClass_AI_TargetSnapChecks, 0x6) { enum { SkipChecks = 0x467CDE }; @@ -304,15 +310,10 @@ DEFINE_HOOK(0x467CCA, BulletClass_AI_TargetSnapChecks, 0x6) } else if (auto const pExt = BulletAITemp::ExtData) { - if (auto const pTrajectory = pExt->Trajectory.get()) + if (pExt->Trajectory && CheckTrajectoryCanNotAlwaysSnap(pExt->Trajectory->Flag())) { - const TrajectoryFlag flag = pTrajectory->Flag(); - - if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) - { - R->EAX(pThis->Type); - return SkipChecks; - } + R->EAX(pThis->Type); + return SkipChecks; } } @@ -337,18 +338,10 @@ DEFINE_HOOK(0x468E61, BulletClass_Explode_TargetSnapChecks1, 0x6) } else if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (!pExt->SnappedToTarget) + if (pExt->Trajectory && CheckTrajectoryCanNotAlwaysSnap(pExt->Trajectory->Flag()) && !pExt->SnappedToTarget) { - if (auto const pTrajectory = pExt->Trajectory.get()) - { - const TrajectoryFlag flag = pTrajectory->Flag(); - - if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) - { - R->EAX(pThis->Type); - return SkipChecks; - } - } + R->EAX(pThis->Type); + return SkipChecks; } } @@ -376,16 +369,8 @@ DEFINE_HOOK(0x468E9F, BulletClass_Explode_TargetSnapChecks2, 0x6) // Fixes issues with walls etc. if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (!pExt->SnappedToTarget) - { - if (auto const pTrajectory = pExt->Trajectory.get()) - { - const TrajectoryFlag flag = pTrajectory->Flag(); - - if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) - return SkipSetCoordinate; - } - } + if (pExt->Trajectory && CheckTrajectoryCanNotAlwaysSnap(pExt->Trajectory->Flag()) && !pExt->SnappedToTarget) + return SkipSetCoordinate; } return 0; @@ -399,13 +384,8 @@ DEFINE_HOOK(0x468D3F, BulletClass_ShouldExplode_AirTarget, 0x6) if (auto const pExt = BulletExt::ExtMap.Find(pThis)) { - if (auto const pTrajectory = pExt->Trajectory.get()) - { - const TrajectoryFlag flag = pTrajectory->Flag(); - - if (flag == TrajectoryFlag::Straight || flag == TrajectoryFlag::Engrave) - return SkipCheck; - } + if (pExt->Trajectory && CheckTrajectoryCanNotAlwaysSnap(pExt->Trajectory->Flag())) + return SkipCheck; } return 0; From 5bf8528d1f3c62420ddc3590a797b1f7a8b2fb2c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 29 Dec 2024 20:17:37 +0800 Subject: [PATCH 37/54] Synchronize --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 25 +++++-------------- .../Bullet/Trajectories/PhobosTrajectory.cpp | 5 +--- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 19b7ec2b2b..0623ed46fe 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -54,9 +54,7 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) { INI_EX exINI(pINI); - if (this->Trajectory_Speed > 128.0) - this->Trajectory_Speed = 128.0; - + this->Trajectory_Speed = Math::min(128.0, this->Trajectory_Speed); this->ApplyRangeModifiers.Read(exINI, pSection, "Trajectory.Engrave.ApplyRangeModifiers"); this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); @@ -70,24 +68,13 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->LaserOuterColor.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterColor"); this->LaserOuterSpread.Read(exINI, pSection, "Trajectory.Engrave.LaserOuterSpread"); this->LaserThickness.Read(exINI, pSection, "Trajectory.Engrave.LaserThickness"); - - if (this->LaserThickness <= 0) - this->LaserThickness = 1; - + this->LaserThickness = Math::max(1, this->LaserThickness); this->LaserDuration.Read(exINI, pSection, "Trajectory.Engrave.LaserDuration"); - - if (this->LaserDuration <= 0) - this->LaserDuration = 1; - + this->LaserDuration = Math::max(1, this->LaserDuration); this->LaserDelay.Read(exINI, pSection, "Trajectory.Engrave.LaserDelay"); - - if (this->LaserDelay <= 0) - this->LaserDelay = 1; - + this->LaserDelay = Math::max(1, this->LaserDelay); this->DamageDelay.Read(exINI, pSection, "Trajectory.Engrave.DamageDelay"); - - if (this->DamageDelay <= 0) - this->DamageDelay = 1; + this->DamageDelay = Math::max(1, this->DamageDelay); } template @@ -304,7 +291,7 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) const auto checkDifference = this->GetFloorCoordHeight(pBullet, futureCoords) - futureCoords.Z; - if (abs(checkDifference) >= 384) + if (std::abs(checkDifference) >= 384) { if (pBullet->Type->SubjectToCliffs) return true; diff --git a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp index 4193e3834a..e0182b5a64 100644 --- a/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/PhobosTrajectory.cpp @@ -67,10 +67,7 @@ void TrajectoryTypePointer::LoadFromINI(CCINIClass* pINI, const char* pSection) if (_ptr) { _ptr->Trajectory_Speed.Read(exINI, pSection, "Trajectory.Speed"); - - if (abs(_ptr->Trajectory_Speed) < 1e-10) - _ptr->Trajectory_Speed = 0.001; - + _ptr->Trajectory_Speed = Math::max(0.001,_ptr->Trajectory_Speed); _ptr->Read(pINI, pSection); } } From 8c215371e942d2929fc956b0db9cfb0d7f4cf486 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 31 Dec 2024 00:35:10 +0800 Subject: [PATCH 38/54] Inline some short functions --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 6 +++--- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 0623ed46fe..7170951182 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -215,7 +215,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe this->FLHCoord = pExt->LastWeaponFLH; } -void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) +inline void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) { if (this->NotMainWeapon || !(pTechno->CurrentBurstIndex % 2)) return; @@ -249,7 +249,7 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct th pBullet->Velocity.Z = 0; } -bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) +inline bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) { return (!pTechno || !pTechno->IsAlive @@ -371,7 +371,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec } } -void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) +inline void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { const auto pType = this->Type; this->DamageTimer.Start(pType->DamageDelay); diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index e5b5a17b06..3330ad927c 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -95,11 +95,11 @@ class EngraveTrajectory final : public PhobosTrajectory void Serialize(T& Stm); void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); - void CheckMirrorCoord(TechnoClass* pTechno); + inline void CheckMirrorCoord(TechnoClass* pTechno); void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); - bool InvalidFireCondition(TechnoClass* pTechno); + inline bool InvalidFireCondition(TechnoClass* pTechno); int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); - void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); + inline void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); }; From 32c90bded6f720ad15594d11a32c5f24e11b0fcd Mon Sep 17 00:00:00 2001 From: Noble Fish <89088785+DeathFishAtEase@users.noreply.github.com> Date: Mon, 3 Feb 2025 04:12:50 +0800 Subject: [PATCH 39/54] ")" --- docs/Fixed-or-Improved-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index d39932ba2b..5606546923 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -1124,7 +1124,7 @@ Palette= ; filename - excluding .pal extension and three-character the - Instead of showing at 1 point of HP left, TerrainTypes switch to damaged frames once their health reaches `[AudioVisual]` -> `ConditionYellow.Terrain` percentage of their maximum health. Defaults to `ConditionYellow` if not set. - In addition, TerrainTypes can now show 'crumbling' animation after their health has reached zero and before they are deleted from the map by setting `HasCrumblingFrames` to true. - Crumbling frames start from first frame after both regular & damaged frames and ends at halfway point of the frames in TerrainType's image. - - Note that the number of regular & damage frames considered for this depends on value of `HasDamagedFrames` and for `IsAnimated` TerrainTypes, `AnimationLength` (see [Animated TerrainTypes](#animated-terraintypes). Exercise caution and ensure there are correct amount of frames to display. + - Note that the number of regular & damage frames considered for this depends on value of `HasDamagedFrames` and for `IsAnimated` TerrainTypes, `AnimationLength` (see [Animated TerrainTypes](#animated-terraintypes)). Exercise caution and ensure there are correct amount of frames to display. - Sound event from `CrumblingSound` (if set) is played when crumbling animation starts playing. - [Destroy animation & sound](New-or-Enhanced-Logics.md#destroy-animation--sound) only play after crumbling animation has finished. From a50f79cef7ebf6156e38447b923a6e17a0ae1550 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Mon, 3 Feb 2025 23:23:07 +0800 Subject: [PATCH 40/54] New `Trajectory.Engrave.UseDisperseCoord` --- docs/New-or-Enhanced-Logics.md | 4 +++- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 ++ src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 9e86b1b93a..0c0e5067d9 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -842,7 +842,8 @@ Trajectory.Bombard.Height=0.0 ; double - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. - - `Trajectory.Engrave.TheDuration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. + - `Trajectory.Engrave.UseDisperseCoord` controls whether the emission position of the engrave laser need to replaced with the FLH of its superior's dispersed trajectory, which set `Trajectory.Disperse.RecordSourceCoord` to true. + - `Trajectory.Engrave.TheDuration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. - `Trajectory.Engrave.IsLaser` controls whether laser drawing is required. - `Trajectory.Engrave.IsSupported` controls whether the engrave laser will be brighter and thicker. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. - `Trajectory.Engrave.IsHouseColor` controls whether set the engrave laser to draw using player's team color. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsSupported`. @@ -863,6 +864,7 @@ Trajectory.Engrave.ApplyRangeModifiers=false ; boolean Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.TargetCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.MirrorCoord=true ; boolean +Trajectory.Engrave.UseDisperseCoord=false ; boolean Trajectory.Engrave.TheDuration=0 ; integer Trajectory.Engrave.IsLaser=true ; boolean Trajectory.Engrave.IsSupported=false ; boolean diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 7170951182..ef073e4cf8 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -20,6 +20,7 @@ void EngraveTrajectoryType::Serialize(T& Stm) .Process(this->SourceCoord) .Process(this->TargetCoord) .Process(this->MirrorCoord) + .Process(this->UseDisperseCoord) .Process(this->ApplyRangeModifiers) .Process(this->TheDuration) .Process(this->IsLaser) @@ -59,6 +60,7 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); this->MirrorCoord.Read(exINI, pSection, "Trajectory.Engrave.MirrorCoord"); + this->UseDisperseCoord.Read(exINI, pSection, "Trajectory.Engrave.UseDisperseCoord"); this->TheDuration.Read(exINI, pSection, "Trajectory.Engrave.TheDuration"); this->IsLaser.Read(exINI, pSection, "Trajectory.Engrave.IsLaser"); this->IsSupported.Read(exINI, pSection, "Trajectory.Engrave.IsSupported"); diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 3330ad927c..8cf67c1494 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -9,6 +9,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , SourceCoord { { 0, 0 } } , TargetCoord { { 0, 0 } } , MirrorCoord { true } + , UseDisperseCoord { false } , ApplyRangeModifiers { false } , TheDuration { 0 } , IsLaser { true } @@ -33,6 +34,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable SourceCoord; Valueable TargetCoord; Valueable MirrorCoord; + Valueable UseDisperseCoord; Valueable ApplyRangeModifiers; Valueable TheDuration; Valueable IsLaser; From 4287849dabd977c43ea0b14a3154a4e3c892d9c9 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 7 Feb 2025 14:02:16 +0800 Subject: [PATCH 41/54] Optimize --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 16 ++++++++++------ src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index ef073e4cf8..fdf612f649 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -119,17 +119,20 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul if (pTechno) { this->TechnoInTransport = static_cast(pTechno->Transporter); - this->GetTechnoFLHCoord(pBullet, pTechno); this->CheckMirrorCoord(pTechno); - this->SetEngraveDirection(pBullet, pTechno->GetCoords(), pBullet->TargetCoords); + + const auto theSource = pTechno->GetCoords(); + const auto rotateAngle = Math::atan2(pBullet->TargetCoords.Y - theSource.Y , pBullet->TargetCoords.X - theSource.X); + this->SetEngraveDirection(pBullet, rotateAngle); } else { this->TechnoInTransport = false; this->NotMainWeapon = true; - this->SetEngraveDirection(pBullet, pBullet->SourceCoords, pBullet->TargetCoords); + const auto rotateAngle = Math::atan2(pBullet->TargetCoords.Y - pBullet->SourceCoords.Y , pBullet->TargetCoords.X - pBullet->SourceCoords.X); + this->SetEngraveDirection(pBullet, rotateAngle); } auto coordDistance = pBullet->Velocity.Magnitude(); @@ -229,9 +232,10 @@ inline void EngraveTrajectory::CheckMirrorCoord(TechnoClass* pTechno) } } -void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget) +void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateAngle) { - const auto rotateAngle = Math::atan2(theTarget.Y - theSource.Y , theTarget.X - theSource.X); + auto theSource = pBullet->SourceCoords; + auto theTarget = pBullet->TargetCoords; if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) { @@ -265,7 +269,7 @@ inline bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) || pTechno->IsUnderEMP()); } -int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord) +int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord) { if (const auto pCell = MapClass::Instance->GetCellAt(coord)) { diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 8cf67c1494..037c32a33b 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -98,9 +98,9 @@ class EngraveTrajectory final : public PhobosTrajectory void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); inline void CheckMirrorCoord(TechnoClass* pTechno); - void SetEngraveDirection(BulletClass* pBullet, CoordStruct theSource, CoordStruct theTarget); + void SetEngraveDirection(BulletClass* pBullet, double rotateAngle); inline bool InvalidFireCondition(TechnoClass* pTechno); - int GetFloorCoordHeight(BulletClass* pBullet, CoordStruct coord); + int GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); inline void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); From 3bf04c276b2e92942e0237749fa3336a0cd73a5c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 8 Feb 2025 19:17:08 +0800 Subject: [PATCH 42/54] Review and add some comment --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index fdf612f649..2ab41fbf53 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -116,6 +116,7 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->FLHCoord = pBullet->SourceCoords; const auto pTechno = pBullet->Owner; + // When the launcher exists, the launcher's location will be used to calculate the direction of the coordinate axis instead of bullet's SourceCoords if (pTechno) { this->TechnoInTransport = static_cast(pTechno->Transporter); @@ -135,14 +136,17 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul this->SetEngraveDirection(pBullet, rotateAngle); } + // Substitute the speed to calculate velocity auto coordDistance = pBullet->Velocity.Magnitude(); pBullet->Velocity *= (coordDistance > 1e-10) ? (pType->Trajectory_Speed / coordDistance) : 0; + // Calculate additional range const auto pWeapon = pBullet->WeaponType; if (pType->ApplyRangeModifiers && pWeapon && pTechno) coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); + // Automatically calculate duration if (this->TheDuration <= 0) this->TheDuration = static_cast(coordDistance / pType->Trajectory_Speed) + 1; } @@ -195,6 +199,7 @@ void EngraveTrajectory::GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTe { const auto pExt = TechnoExt::ExtMap.Find(pTechno); + // Record the launch location, the building has an additional offset if (!pExt || !pExt->LastWeaponType || pExt->LastWeaponType->Projectile != pBullet->Type) { this->NotMainWeapon = true; @@ -237,6 +242,7 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA auto theSource = pBullet->SourceCoords; auto theTarget = pBullet->TargetCoords; + // Special case: Starting from the launch position if (this->SourceCoord.X != 0 || this->SourceCoord.Y != 0) { theSource = theTarget; @@ -271,18 +277,11 @@ inline bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord) { - if (const auto pCell = MapClass::Instance->GetCellAt(coord)) - { - const auto onFloor = MapClass::Instance->GetCellFloorHeight(coord); - const auto onBridge = pCell->GetCoordsWithBridge().Z; - - if (pBullet->SourceCoords.Z >= onBridge || pBullet->TargetCoords.Z >= onBridge) - return onBridge; - - return onFloor; - } + const auto pCell = MapClass::Instance->GetCellAt(coord); + const auto onFloor = MapClass::Instance->GetCellFloorHeight(coord); + const auto onBridge = pCell->GetCoordsWithBridge().Z; - return coord.Z; + return (pBullet->SourceCoords.Z >= onBridge || pBullet->TargetCoords.Z >= onBridge) ? onBridge : onFloor; } bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) @@ -295,8 +294,10 @@ bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) bulletCoords.Z + static_cast(pBullet->Velocity.Z) }; + // Calculate where will be located in the next frame const auto checkDifference = this->GetFloorCoordHeight(pBullet, futureCoords) - futureCoords.Z; + // When crossing the cliff, directly move the position of the bullet, otherwise change the vertical velocity if (std::abs(checkDifference) >= 384) { if (pBullet->Type->SubjectToCliffs) @@ -334,6 +335,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec const auto pTransporter = pTechno->Transporter; auto fireCoord = pBullet->SourceCoords; + // Considering that the CurrentBurstIndex may be different, it is not possible to call existing functions if (!this->NotMainWeapon && pTechno && (pTransporter || !pTechno->InLimbo)) { if (pTechno->WhatAmI() != AbstractType::Building) @@ -361,6 +363,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec } } + // Draw laser from head to tail if (pType->IsHouseColor || pType->IsSingleColor) { const auto pLaser = GameCreate(fireCoord, pBullet->Location, ((pType->IsHouseColor && pOwner) ? pOwner->LaserColor : pType->LaserInnerColor), ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, pType->LaserDuration); From 28c5ab4e863544cfdbaa9055d70d808baec936aa Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 9 Feb 2025 00:37:04 +0800 Subject: [PATCH 43/54] New functions similar to Straight --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 175 ++++++++++++++++++ .../Bullet/Trajectories/EngraveTrajectory.h | 23 +++ 2 files changed, 198 insertions(+) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 2ab41fbf53..5d1365a9a4 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -34,6 +34,14 @@ void EngraveTrajectoryType::Serialize(T& Stm) .Process(this->LaserDuration) .Process(this->LaserDelay) .Process(this->DamageDelay) + .Process(this->ProximityImpact) + .Process(this->ProximityWarhead) + .Process(this->ProximityDamage) + .Process(this->ProximityRadius) + .Process(this->ProximityDirect) + .Process(this->ProximityMedial) + .Process(this->ProximityAllies) + .Process(this->ProximitySuicide) ; } @@ -77,6 +85,14 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->LaserDelay = Math::max(1, this->LaserDelay); this->DamageDelay.Read(exINI, pSection, "Trajectory.Engrave.DamageDelay"); this->DamageDelay = Math::max(1, this->DamageDelay); + this->ProximityImpact.Read(exINI, pSection, "Trajectory.Engrave.ProximityImpact"); + this->ProximityWarhead.Read(exINI, pSection, "Trajectory.Engrave.ProximityWarhead"); + this->ProximityDamage.Read(exINI, pSection, "Trajectory.Engrave.ProximityDamage"); + this->ProximityRadius.Read(exINI, pSection, "Trajectory.Engrave.ProximityRadius"); + this->ProximityDirect.Read(exINI, pSection, "Trajectory.Engrave.ProximityDirect"); + this->ProximityMedial.Read(exINI, pSection, "Trajectory.Engrave.ProximityMedial"); + this->ProximityAllies.Read(exINI, pSection, "Trajectory.Engrave.ProximityAllies"); + this->ProximitySuicide.Read(exINI, pSection, "Trajectory.Engrave.ProximitySuicide"); } template @@ -93,6 +109,9 @@ void EngraveTrajectory::Serialize(T& Stm) .Process(this->NotMainWeapon) .Process(this->FLHCoord) .Process(this->BuildingCoord) + .Process(this->StartCoord) + .Process(this->ProximityImpact) + .Process(this->TheCasualty) ; } @@ -169,6 +188,9 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) if (this->DamageTimer.Completed()) this->DetonateLaserWarhead(pBullet, pTechno, pOwner); + if (this->ProximityImpact != 0 && this->Type->ProximityRadius.Get() > 0) + this->PrepareForDetonateAt(pBullet, pOwner); + return false; } @@ -251,6 +273,7 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA } theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); + this->StartCoord = theSource; pBullet->SetLocation(theSource); theTarget.X += static_cast(this->TargetCoord.X * Math::cos(rotateAngle) + this->TargetCoord.Y * Math::sin(rotateAngle)); @@ -386,3 +409,155 @@ inline void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, Techno this->DamageTimer.Start(pType->DamageDelay); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } + +// Select suitable targets and choose the closer targets then attack each target only once. +void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* pOwner) +{ + const auto pType = this->Type; + const auto pWH = pType->ProximityWarhead; + + if (!pWH) + return; + + // Step 1: Find valid targets on the ground within range. + const auto radius = pType->ProximityRadius.Get(); + std::vector recCellClass = PhobosTrajectoryType::GetCellsInProximityRadius(pBullet, radius); + const size_t cellSize = recCellClass.size() * 2; + size_t vectSize = cellSize; + size_t thisSize = 0; + + const CoordStruct velocityCrd + { + static_cast(pBullet->Velocity.X), + static_cast(pBullet->Velocity.Y), + static_cast(pBullet->Velocity.Z) + }; + const auto velocitySq = velocityCrd.MagnitudeSquared(); + const auto pTarget = pBullet->Target; + + std::vector validTechnos; + validTechnos.reserve(vectSize); + + for (const auto& pRecCell : recCellClass) + { + auto pObject = pRecCell->GetContent(); + + while (pObject) + { + const auto pTechno = abstract_cast(pObject); + pObject = pObject->NextObject; + + if (!pTechno || !pTechno->IsAlive || !pTechno->IsOnMap || pTechno->Health <= 0 || pTechno->InLimbo || pTechno->IsSinking) + continue; + + const auto technoType = pTechno->WhatAmI(); + + if (technoType == AbstractType::Building && static_cast(pTechno)->Type->InvisibleInGame) + continue; + + // Not directly harming friendly forces + if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pTarget) + continue; + + // Check distance + const auto targetCrd = pTechno->GetCoords(); + const auto pathCrd = targetCrd - this->StartCoord; + + if (pathCrd * velocityCrd < 0) // In front of the techno + continue; + + const auto distanceCrd = targetCrd - pBullet->Location; + const auto nextDistanceCrd = distanceCrd - velocityCrd; + + if (nextDistanceCrd * velocityCrd > 0) // Behind the bullet + continue; + + const auto cross = distanceCrd.CrossProduct(nextDistanceCrd).MagnitudeSquared(); + const auto distance = (velocitySq > 1e-10) ? sqrt(cross / velocitySq) : distanceCrd.Magnitude(); + + if (technoType != AbstractType::Building && distance > radius) // In the cylinder + continue; + + if (thisSize >= vectSize) + { + vectSize += cellSize; + validTechnos.reserve(vectSize); + } + + validTechnos.push_back(pTechno); + thisSize += 1; + } + } + + // Step 2: Record each target without repetition. + std::vector casualtyChecked; + casualtyChecked.reserve(std::max(validTechnos.size(), this->TheCasualty.size())); + + if (const auto pFirer = pBullet->Owner) + this->TheCasualty[pFirer->UniqueID] = 20; + + // Update Record + for (const auto& [ID, remainTime] : this->TheCasualty) + { + if (remainTime > 0) + this->TheCasualty[ID] = remainTime - 1; + else + casualtyChecked.push_back(ID); + } + + for (const auto& ID : casualtyChecked) + this->TheCasualty.erase(ID); + + std::vector validTargets; + + // checking for duplicate + for (const auto& pTechno : validTechnos) + { + if (!this->TheCasualty.contains(pTechno->UniqueID)) + validTargets.push_back(pTechno); + + this->TheCasualty[pTechno->UniqueID] = 20; + } + + // Step 3: Detonate warheads in sequence based on distance. + const auto targetsSize = validTargets.size(); + + if (this->ProximityImpact > 0 && static_cast(targetsSize) > this->ProximityImpact) + { + std::sort(&validTargets[0], &validTargets[targetsSize],[this](TechnoClass* pTechnoA, TechnoClass* pTechnoB) + { + const auto distanceA = pTechnoA->GetCoords().DistanceFromSquared(this->StartCoord); + const auto distanceB = pTechnoB->GetCoords().DistanceFromSquared(this->StartCoord); + + // Distance priority + if (distanceA < distanceB) + return true; + + if (distanceA > distanceB) + return false; + + return pTechnoA->UniqueID < pTechnoB->UniqueID; + }); + } + + for (const auto& pTechno : validTargets) + { + // Cause damage + auto damage = pType->ProximityDamage; + + if (pType->ProximityDirect) + pTechno->ReceiveDamage(&damage, 0, pWH, pBullet->Owner, false, false, pOwner); + else if (pType->ProximityMedial) + WarheadTypeExt::DetonateAt(pWH, pBullet->Location, pBullet->Owner, damage, pOwner); + else + WarheadTypeExt::DetonateAt(pWH, pTechno->GetCoords(), pBullet->Owner, damage, pOwner, pTechno); + + if (this->ProximityImpact > 0 && --this->ProximityImpact == 0) + { + if (pType->ProximitySuicide) + this->TheDuration = 0; + + break; + } + } +} diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 037c32a33b..88c3f12b45 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -23,6 +23,14 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , LaserDuration { 1 } , LaserDelay { 1 } , DamageDelay { 2 } + , ProximityImpact { 0 } + , ProximityWarhead {} + , ProximityDamage { 0 } + , ProximityRadius { Leptons(179) } + , ProximityDirect { false } + , ProximityMedial { false } + , ProximityAllies { false } + , ProximitySuicide { false } { } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; @@ -48,6 +56,14 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable LaserDuration; Valueable LaserDelay; Valueable DamageDelay; + Valueable ProximityImpact; + Valueable ProximityWarhead; + Valueable ProximityDamage; + Valueable ProximityRadius; + Valueable ProximityDirect; + Valueable ProximityMedial; + Valueable ProximityAllies; + Valueable ProximitySuicide; private: template @@ -69,6 +85,9 @@ class EngraveTrajectory final : public PhobosTrajectory , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} + , StartCoord {} + , ProximityImpact { trajType->ProximityImpact } + , TheCasualty {} { } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; @@ -91,6 +110,9 @@ class EngraveTrajectory final : public PhobosTrajectory bool NotMainWeapon; CoordStruct FLHCoord; CoordStruct BuildingCoord; + CoordStruct StartCoord; + int ProximityImpact; + std::map TheCasualty; // Only for recording existence private: template @@ -104,4 +126,5 @@ class EngraveTrajectory final : public PhobosTrajectory bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); inline void DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); + void PrepareForDetonateAt(BulletClass* pBullet, HouseClass* pOwner); }; From 5c598be0f554ccbd57f64ea18a3b8fd967e57688 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 9 Feb 2025 00:38:12 +0800 Subject: [PATCH 44/54] Doc --- docs/New-or-Enhanced-Logics.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index c07a8303ec..88a41a5a41 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -854,6 +854,13 @@ Trajectory.Bombard.Height=0.0 ; double - `Trajectory.Engrave.LaserDuration` controls the duration of the engrave laser. - `Trajectory.Engrave.LaserDelay` controls how often to draw the engrave laser. - `Trajectory.Engrave.DamageDelay` controls how often to detonate warheads. + - `Trajectory.Engrave.ProximityImpact` controls the initial proximity fuse times. When there are enough remaining times and the projectile approaches another valid target, it will detonate a warhead defined by `Trajectory.Engrave.ProximityWarhead` on it. If the number of times is exhausted, the engraving process can still continue, but it will not detonate additional warhead as a result. This function can be cancelled by setting to 0. A negative integer means unlimited times. (You can use this to cause non repeated damage to all units encountered during the flight of the projectile.) + - `Trajectory.Engrave.ProximityWarhead` defines the warhead detonated by `Trajectory.Engrave.ProximityImpact`, and `Trajectory.Engrave.ProximityDamage` defines the damage caused by `Trajectory.Engrave.ProximityWarhead`. + - `Trajectory.Engrave.ProximityRadius` controls the range of proximity fuse. It can NOT be set as a negative integer. + - `Trajectory.Engrave.ProximityDirect` controls whether let the target receive damage instead of detonating the warhead. + - `Trajectory.Engrave.ProximityMedial` controls whether to detonate `Trajectory.Engrave.ProximityWarhead` at the bullet's location rather than the proximity target's location. + - `Trajectory.Engrave.ProximityAllies` controls whether allies will also trigger the proximity fuse. + - `Trajectory.Engrave.ProximitySuicide` controls whether the projectile will self destruct after the number of proximity fuse times has been exhausted. If `Trajectory.Engrave.ProximityImpact` set to 0, this will not be enabled. In `rulesmd.ini`: ```ini @@ -876,6 +883,14 @@ Trajectory.Engrave.LaserThickness=3 ; integer Trajectory.Engrave.LaserDuration=1 ; integer Trajectory.Engrave.LaserDelay=1 ; integer Trajectory.Engrave.DamageDelay=2 ; integer +Trajectory.Engrave.ProximityImpact=0 ; integer +Trajectory.Engrave.ProximityWarhead= ; WarheadType +Trajectory.Engrave.ProximityDamage=0 ; integer +Trajectory.Engrave.ProximityRadius=0.7 ; floating point value +Trajectory.Engrave.ProximityDirect=false ; boolean +Trajectory.Engrave.ProximityMedial=false ; boolean +Trajectory.Engrave.ProximityAllies=false ; boolean +Trajectory.Engrave.ProximitySuicide=false ; boolean ``` ```{note} From 1ca3c0d92db4df3969a7c5bf36b41f6031fadcfb Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 11 Feb 2025 18:11:59 +0800 Subject: [PATCH 45/54] Rename key --- docs/New-or-Enhanced-Logics.md | 12 +++++------ .../Bullet/Trajectories/EngraveTrajectory.cpp | 20 +++++++++---------- .../Bullet/Trajectories/EngraveTrajectory.h | 12 +++++------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 59a3204a3f..4de4ef9526 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -939,11 +939,11 @@ Trajectory.Parabola.AxisOfRotation=0,0,1 ; integer - Forward,Lateral,Heig - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. - `Trajectory.Engrave.UseDisperseCoord` controls whether the emission position of the engrave laser need to replaced with the FLH of its superior's dispersed trajectory, which set `Trajectory.Disperse.RecordSourceCoord` to true. - - `Trajectory.Engrave.TheDuration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. + - `Trajectory.Engrave.Duration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. - `Trajectory.Engrave.IsLaser` controls whether laser drawing is required. - - `Trajectory.Engrave.IsSupported` controls whether the engrave laser will be brighter and thicker. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. - - `Trajectory.Engrave.IsHouseColor` controls whether set the engrave laser to draw using player's team color. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsSupported`. - - `Trajectory.Engrave.IsSingleColor` controls whether set the engrave laser to draw using only `Trajectory.Engrave.LaserInnerColor`. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsSupported`. + - `Trajectory.Engrave.IsIntense` controls whether the engrave laser will be brighter and thicker. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. + - `Trajectory.Engrave.IsHouseColor` controls whether set the engrave laser to draw using player's team color. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsIntense`. + - `Trajectory.Engrave.IsSingleColor` controls whether set the engrave laser to draw using only `Trajectory.Engrave.LaserInnerColor`. These lasers respect `Trajectory.Engrave.LaserThickness` and `Trajectory.Engrave.IsIntense`. - `Trajectory.Engrave.LaserInnerColor` controls the inner color of the engrave laser. - `Trajectory.Engrave.LaserOuterColor` controls the outer color of the engrave laser. - `Trajectory.Engrave.LaserOuterSpread` controls the spread color of the engrave laser. @@ -968,9 +968,9 @@ Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.TargetCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.MirrorCoord=true ; boolean Trajectory.Engrave.UseDisperseCoord=false ; boolean -Trajectory.Engrave.TheDuration=0 ; integer +Trajectory.Engrave.Duration=0 ; integer Trajectory.Engrave.IsLaser=true ; boolean -Trajectory.Engrave.IsSupported=false ; boolean +Trajectory.Engrave.IsIntense=false ; boolean Trajectory.Engrave.IsHouseColor=false ; boolean Trajectory.Engrave.IsSingleColor=false ; boolean Trajectory.Engrave.LaserInnerColor=0,0,0 ; integer - Red,Green,Blue diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 5d1365a9a4..71e3541dc9 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -22,9 +22,9 @@ void EngraveTrajectoryType::Serialize(T& Stm) .Process(this->MirrorCoord) .Process(this->UseDisperseCoord) .Process(this->ApplyRangeModifiers) - .Process(this->TheDuration) + .Process(this->Duration) .Process(this->IsLaser) - .Process(this->IsSupported) + .Process(this->IsIntense) .Process(this->IsHouseColor) .Process(this->IsSingleColor) .Process(this->LaserInnerColor) @@ -69,9 +69,9 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); this->MirrorCoord.Read(exINI, pSection, "Trajectory.Engrave.MirrorCoord"); this->UseDisperseCoord.Read(exINI, pSection, "Trajectory.Engrave.UseDisperseCoord"); - this->TheDuration.Read(exINI, pSection, "Trajectory.Engrave.TheDuration"); + this->Duration.Read(exINI, pSection, "Trajectory.Engrave.Duration"); this->IsLaser.Read(exINI, pSection, "Trajectory.Engrave.IsLaser"); - this->IsSupported.Read(exINI, pSection, "Trajectory.Engrave.IsSupported"); + this->IsIntense.Read(exINI, pSection, "Trajectory.Engrave.IsIntense"); this->IsHouseColor.Read(exINI, pSection, "Trajectory.Engrave.IsHouseColor"); this->IsSingleColor.Read(exINI, pSection, "Trajectory.Engrave.IsSingleColor"); this->LaserInnerColor.Read(exINI, pSection, "Trajectory.Engrave.LaserInnerColor"); @@ -102,7 +102,7 @@ void EngraveTrajectory::Serialize(T& Stm) .Process(this->Type) .Process(this->SourceCoord) .Process(this->TargetCoord) - .Process(this->TheDuration) + .Process(this->Duration) .Process(this->LaserTimer) .Process(this->DamageTimer) .Process(this->TechnoInTransport) @@ -166,8 +166,8 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); // Automatically calculate duration - if (this->TheDuration <= 0) - this->TheDuration = static_cast(coordDistance / pType->Trajectory_Speed) + 1; + if (this->Duration <= 0) + this->Duration = static_cast(coordDistance / pType->Trajectory_Speed) + 1; } bool EngraveTrajectory::OnAI(BulletClass* pBullet) @@ -177,7 +177,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) if (!this->NotMainWeapon && this->InvalidFireCondition(pTechno)) return true; - if (--this->TheDuration < 0 || this->PlaceOnCorrectHeight(pBullet)) + if (--this->Duration < 0 || this->PlaceOnCorrectHeight(pBullet)) return true; const auto pOwner = pTechno ? pTechno->Owner : BulletExt::ExtMap.Find(pBullet)->FirerHouse; @@ -392,7 +392,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec const auto pLaser = GameCreate(fireCoord, pBullet->Location, ((pType->IsHouseColor && pOwner) ? pOwner->LaserColor : pType->LaserInnerColor), ColorStruct { 0, 0, 0 }, ColorStruct { 0, 0, 0 }, pType->LaserDuration); pLaser->IsHouseColor = true; pLaser->Thickness = pType->LaserThickness; - pLaser->IsSupported = pType->IsSupported; + pLaser->IsSupported = pType->IsIntense; } else { @@ -555,7 +555,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p if (this->ProximityImpact > 0 && --this->ProximityImpact == 0) { if (pType->ProximitySuicide) - this->TheDuration = 0; + this->Duration = 0; break; } diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 88c3f12b45..4fc567f4ad 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -11,9 +11,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , MirrorCoord { true } , UseDisperseCoord { false } , ApplyRangeModifiers { false } - , TheDuration { 0 } + , Duration { 0 } , IsLaser { true } - , IsSupported { false } + , IsIntense { false } , IsHouseColor { false } , IsSingleColor { false } , LaserInnerColor { { 0, 0, 0 } } @@ -44,9 +44,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable MirrorCoord; Valueable UseDisperseCoord; Valueable ApplyRangeModifiers; - Valueable TheDuration; + Valueable Duration; Valueable IsLaser; - Valueable IsSupported; + Valueable IsIntense; Valueable IsHouseColor; Valueable IsSingleColor; Valueable LaserInnerColor; @@ -78,7 +78,7 @@ class EngraveTrajectory final : public PhobosTrajectory EngraveTrajectory(EngraveTrajectoryType const* trajType) : Type { trajType } , SourceCoord { trajType->SourceCoord.Get() } , TargetCoord { trajType->TargetCoord.Get() } - , TheDuration { trajType->TheDuration } + , Duration { trajType->Duration } , LaserTimer {} , DamageTimer {} , TechnoInTransport { false } @@ -103,7 +103,7 @@ class EngraveTrajectory final : public PhobosTrajectory const EngraveTrajectoryType* Type; Point2D SourceCoord; Point2D TargetCoord; - int TheDuration; + int Duration; CDTimerClass LaserTimer; CDTimerClass DamageTimer; bool TechnoInTransport; From e48d5cc536eb206e76d07d12a017e35d855cc95a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 11 Feb 2025 18:13:30 +0800 Subject: [PATCH 46/54] Optimize and fix --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 71e3541dc9..96d64ddd97 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -148,7 +148,6 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul } else { - this->TechnoInTransport = false; this->NotMainWeapon = true; const auto rotateAngle = Math::atan2(pBullet->TargetCoords.Y - pBullet->SourceCoords.Y , pBullet->TargetCoords.X - pBullet->SourceCoords.X); @@ -160,10 +159,11 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul pBullet->Velocity *= (coordDistance > 1e-10) ? (pType->Trajectory_Speed / coordDistance) : 0; // Calculate additional range - const auto pWeapon = pBullet->WeaponType; - - if (pType->ApplyRangeModifiers && pWeapon && pTechno) - coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); + if (pType->ApplyRangeModifiers && pTechno) + { + if (const auto pWeapon = pBullet->WeaponType) + coordDistance = static_cast(WeaponTypeExt::GetRangeWithModifiers(pWeapon, pTechno, static_cast(coordDistance))); + } // Automatically calculate duration if (this->Duration <= 0) @@ -354,16 +354,14 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec { const auto pType = this->Type; this->LaserTimer.Start(pType->LaserDelay); - - const auto pTransporter = pTechno->Transporter; auto fireCoord = pBullet->SourceCoords; // Considering that the CurrentBurstIndex may be different, it is not possible to call existing functions - if (!this->NotMainWeapon && pTechno && (pTransporter || !pTechno->InLimbo)) + if (!this->NotMainWeapon && pTechno && (pTechno->Transporter || !pTechno->InLimbo)) { if (pTechno->WhatAmI() != AbstractType::Building) { - if (pTransporter) + if (const auto pTransporter = pTechno->Transporter) fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTransporter, this->FLHCoord, pTransporter->HasTurret()); else fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); @@ -405,8 +403,7 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec inline void EngraveTrajectory::DetonateLaserWarhead(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner) { - const auto pType = this->Type; - this->DamageTimer.Start(pType->DamageDelay); + this->DamageTimer.Start(this->Type->DamageDelay); WarheadTypeExt::DetonateAt(pBullet->WH, pBullet->Location, pTechno, pBullet->Health, pOwner); } @@ -433,7 +430,6 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p static_cast(pBullet->Velocity.Z) }; const auto velocitySq = velocityCrd.MagnitudeSquared(); - const auto pTarget = pBullet->Target; std::vector validTechnos; validTechnos.reserve(vectSize); @@ -456,7 +452,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p continue; // Not directly harming friendly forces - if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pTarget) + if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pBullet->Target) continue; // Check distance From ae71e8f43819696379a05eae3fe312d9651a6d31 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 13 Feb 2025 17:00:05 +0800 Subject: [PATCH 47/54] New `Trajectory.Engrave.AllowFirerTurning` --- docs/New-or-Enhanced-Logics.md | 6 ++-- .../Bullet/Trajectories/EngraveTrajectory.cpp | 29 +++++++++++++++---- .../Bullet/Trajectories/EngraveTrajectory.h | 4 ++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 7557d1bf56..8c0e4fd330 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -934,11 +934,12 @@ Trajectory.Parabola.AxisOfRotation=0,0,1 ; integer - Forward,Lateral,Heig #### Engrave trajectory - Visually, like the thermal lance. Calling it 'trajectory' may not be appropriate. It does not read the settings on the weapon. - - `Trajectory.Engrave.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. - `Trajectory.Engrave.UseDisperseCoord` controls whether the emission position of the engrave laser need to replaced with the FLH of its superior's dispersed trajectory, which set `Trajectory.Disperse.RecordSourceCoord` to true. + - `Trajectory.Engrave.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. + - `Trajectory.Engrave.AllowFirerTurning` controls whether the projectile allow for significant changes in the orientation of the firer, otherwise it will disappear. - `Trajectory.Engrave.Duration` controls the duration of the entire engrave process. Set to 0 will automatically use `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` to calculate the process duration. - `Trajectory.Engrave.IsLaser` controls whether laser drawing is required. - `Trajectory.Engrave.IsIntense` controls whether the engrave laser will be brighter and thicker. Need to set `Trajectory.Engrave.IsHouseColor` or `Trajectory.Engrave.IsSingleColor` to true. @@ -963,11 +964,12 @@ In `rulesmd.ini`: ```ini [SOMEPROJECTILE] ; Projectile Trajectory=Engrave ; Trajectory type -Trajectory.Engrave.ApplyRangeModifiers=false ; boolean Trajectory.Engrave.SourceCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.TargetCoord=0,0 ; integer - Forward,Lateral Trajectory.Engrave.MirrorCoord=true ; boolean Trajectory.Engrave.UseDisperseCoord=false ; boolean +Trajectory.Engrave.ApplyRangeModifiers=false ; boolean +Trajectory.Engrave.AllowFirerTurning=true ; boolean Trajectory.Engrave.Duration=0 ; integer Trajectory.Engrave.IsLaser=true ; boolean Trajectory.Engrave.IsIntense=false ; boolean diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 96d64ddd97..20987ed771 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -22,6 +22,7 @@ void EngraveTrajectoryType::Serialize(T& Stm) .Process(this->MirrorCoord) .Process(this->UseDisperseCoord) .Process(this->ApplyRangeModifiers) + .Process(this->AllowFirerTurning) .Process(this->Duration) .Process(this->IsLaser) .Process(this->IsIntense) @@ -64,11 +65,12 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) INI_EX exINI(pINI); this->Trajectory_Speed = Math::min(128.0, this->Trajectory_Speed); - this->ApplyRangeModifiers.Read(exINI, pSection, "Trajectory.Engrave.ApplyRangeModifiers"); this->SourceCoord.Read(exINI, pSection, "Trajectory.Engrave.SourceCoord"); this->TargetCoord.Read(exINI, pSection, "Trajectory.Engrave.TargetCoord"); this->MirrorCoord.Read(exINI, pSection, "Trajectory.Engrave.MirrorCoord"); this->UseDisperseCoord.Read(exINI, pSection, "Trajectory.Engrave.UseDisperseCoord"); + this->ApplyRangeModifiers.Read(exINI, pSection, "Trajectory.Engrave.ApplyRangeModifiers"); + this->AllowFirerTurning.Read(exINI, pSection, "Trajectory.Engrave.AllowFirerTurning"); this->Duration.Read(exINI, pSection, "Trajectory.Engrave.Duration"); this->IsLaser.Read(exINI, pSection, "Trajectory.Engrave.IsLaser"); this->IsIntense.Read(exINI, pSection, "Trajectory.Engrave.IsIntense"); @@ -174,7 +176,7 @@ bool EngraveTrajectory::OnAI(BulletClass* pBullet) { const auto pTechno = pBullet->Owner; - if (!this->NotMainWeapon && this->InvalidFireCondition(pTechno)) + if (!this->NotMainWeapon && this->InvalidFireCondition(pBullet, pTechno)) return true; if (--this->Duration < 0 || this->PlaceOnCorrectHeight(pBullet)) @@ -284,9 +286,9 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA pBullet->Velocity.Z = 0; } -inline bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) +bool EngraveTrajectory::InvalidFireCondition(BulletClass* pBullet, TechnoClass* pTechno) { - return (!pTechno + if (!pTechno || !pTechno->IsAlive || (pTechno->InLimbo && !pTechno->Transporter) || pTechno->IsSinking @@ -295,7 +297,24 @@ inline bool EngraveTrajectory::InvalidFireCondition(TechnoClass* pTechno) || pTechno->Deactivated || pTechno->TemporalTargetingMe || pTechno->BeingWarpedOut - || pTechno->IsUnderEMP()); + || pTechno->IsUnderEMP()) + { + return true; + } + + if (this->Type->AllowFirerTurning) + return false; + + const auto SourceCrd = pTechno->GetCoords(); + const auto TargetCrd = pBullet->TargetCoords; + + const auto rotateAngle = Math::atan2(TargetCrd.Y - SourceCrd.Y , TargetCrd.X - SourceCrd.X); + const auto tgtDir = DirStruct(rotateAngle); + + const auto& face = pTechno->HasTurret() ? pTechno->SecondaryFacing : pTechno->PrimaryFacing; + const auto curDir = face.Current(); + + return (std::abs(static_cast(static_cast(tgtDir.Raw) - static_cast(curDir.Raw))) >= 4096); } int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 4fc567f4ad..300fabeb76 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -11,6 +11,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , MirrorCoord { true } , UseDisperseCoord { false } , ApplyRangeModifiers { false } + , AllowFirerTurning { true } , Duration { 0 } , IsLaser { true } , IsIntense { false } @@ -44,6 +45,7 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable MirrorCoord; Valueable UseDisperseCoord; Valueable ApplyRangeModifiers; + Valueable AllowFirerTurning; Valueable Duration; Valueable IsLaser; Valueable IsIntense; @@ -121,7 +123,7 @@ class EngraveTrajectory final : public PhobosTrajectory void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); inline void CheckMirrorCoord(TechnoClass* pTechno); void SetEngraveDirection(BulletClass* pBullet, double rotateAngle); - inline bool InvalidFireCondition(TechnoClass* pTechno); + bool InvalidFireCondition(BulletClass* pBullet, TechnoClass* pTechno); int GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); void DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTechno, HouseClass* pOwner); From ee5639bbb5f44376d7e4a4137757e1d81def265d Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Thu, 13 Feb 2025 18:41:54 +0800 Subject: [PATCH 48/54] Fix a typo --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 20987ed771..51a3b199e1 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -309,7 +309,7 @@ bool EngraveTrajectory::InvalidFireCondition(BulletClass* pBullet, TechnoClass* const auto TargetCrd = pBullet->TargetCoords; const auto rotateAngle = Math::atan2(TargetCrd.Y - SourceCrd.Y , TargetCrd.X - SourceCrd.X); - const auto tgtDir = DirStruct(rotateAngle); + const auto tgtDir = DirStruct(-rotateAngle); const auto& face = pTechno->HasTurret() ? pTechno->SecondaryFacing : pTechno->PrimaryFacing; const auto curDir = face.Current(); From 3285b762af85d5ddfc9950f09d40f673d13c5020 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 14 Feb 2025 00:27:51 +0800 Subject: [PATCH 49/54] Core Co-Authored-By: Netsu_Negi <71598172+NetsuNegi@users.noreply.github.com> --- CREDITS.md | 1 + docs/Fixed-or-Improved-Logics.md | 1 + docs/Whats-New.md | 1 + src/Misc/Hooks.BugFixes.cpp | 15 +++++++++++++++ 4 files changed, 18 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index 24236c02d5..b55139e364 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -349,6 +349,7 @@ This page lists all the individual contributions to the project by their author. - Disguised units not using the correct palette if target has custom palette bugfix - Tunnel/Walk/Mech locomotor being stuck when moving too fast bugfix - Assign Super Weapon cameo to any sidebar tab + - Fix impassable invisible barrier created by chronosphere on uncrushable unit. - **Apollo** - Translucent SHP drawing patches - **ststl** - Customizable ShowTimer priority of superweapons diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index c4ed7a68cc..cdbaeb24ce 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -190,6 +190,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Allowed `AuxBuilding` to count building upgrades. - Fix the bug that parasite will vanish if it missed its target when its previous cell is occupied. - Prevent the units with locomotors that cause problems from entering the tank bunker. +- Fix an issue where a unit will leave an impassable invisible barrier in its original position when it is teleported by ChronoSphere onto an uncrushable unit and self destruct. ## Fixes / interactions with other extensions diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 645cc7e627..313b8498a9 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -330,6 +330,7 @@ Vanilla fixes: - Aircraft will now behave as expected according to it's `MovementZone` and `SpeedType` when moving onto different surfaces. In particular, this fixes erratic behavior when vanilla aircraft is ordered to move onto water surface and instead the movement order changes to a shore nearby (by CrimRecya) - Fix the bug that parasite will vanish if it missed its target when its previous cell is occupied (by 航味麻酱) - Prevent the units with locomotors that cause problems from entering the tank bunker (by TaranDahl) +- Fix an issue where a unit will leave an impassable invisible barrier in its original position when it is teleported by ChronoSphere onto an uncrushable unit and self destruct (by NetsuNegi) Phobos fixes: - Type conversion on Warheads and Superweapons will no longer recursively convert units if applicable conversion pairs are listed, and only first applicable pair takes effect (by Starkku) diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index e13fd9bb60..cceca057ed 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -1089,6 +1089,21 @@ DEFINE_HOOK(0x743664, UnitClass_ReadFromINI_Follower3, 0x6) #pragma endregion +#pragma region TeleportLocomotionOccupationFix + +DEFINE_HOOK(0x71872C, TeleportLocomotionClass_MakeRoom_OccupationFix, 0x9) +{ + enum { SkipMarkOccupation = 0x71878F }; + + GET(const LocomotionClass* const, pLoco, EBP); + + const auto pFoot = pLoco->LinkedTo; + + return (pFoot && pFoot->IsAlive && pFoot->Health > 0 && !pFoot->IsSinking) ? 0 : SkipMarkOccupation; +} + +#pragma endregion + #pragma region StopEventFix DEFINE_HOOK(0x4C75DA, EventClass_RespondToEvent_Stop, 0x6) From 93b5f0689d120d0891a59ffa0ff11c2574b78ef8 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 14 Feb 2025 13:10:33 +0800 Subject: [PATCH 50/54] Check InLimbo --- src/Misc/Hooks.BugFixes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index cceca057ed..a9732a8f77 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -1099,7 +1099,7 @@ DEFINE_HOOK(0x71872C, TeleportLocomotionClass_MakeRoom_OccupationFix, 0x9) const auto pFoot = pLoco->LinkedTo; - return (pFoot && pFoot->IsAlive && pFoot->Health > 0 && !pFoot->IsSinking) ? 0 : SkipMarkOccupation; + return (pFoot && pFoot->IsAlive && !pFoot->InLimbo && pFoot->Health > 0 && !pFoot->IsSinking) ? 0 : SkipMarkOccupation; } #pragma endregion From f3dc2a0fd9639eefb18c236895ca3bc7ccc405dd Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 18 Feb 2025 03:04:37 +0800 Subject: [PATCH 51/54] Sync --- src/Ext/Bullet/Trajectories/EngraveTrajectory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 300fabeb76..f02d898847 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -116,13 +116,13 @@ class EngraveTrajectory final : public PhobosTrajectory int ProximityImpact; std::map TheCasualty; // Only for recording existence + void SetEngraveDirection(BulletClass* pBullet, double rotateAngle); private: template void Serialize(T& Stm); void GetTechnoFLHCoord(BulletClass* pBullet, TechnoClass* pTechno); inline void CheckMirrorCoord(TechnoClass* pTechno); - void SetEngraveDirection(BulletClass* pBullet, double rotateAngle); bool InvalidFireCondition(BulletClass* pBullet, TechnoClass* pTechno); int GetFloorCoordHeight(BulletClass* pBullet, const CoordStruct& coord); bool PlaceOnCorrectHeight(BulletClass* pBullet); From 0f30085e78e83c2394362bdb04c9ee5f6ed32fc4 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 18 Feb 2025 15:41:00 +0800 Subject: [PATCH 52/54] Fix fire in transporter --- .../Bullet/Trajectories/EngraveTrajectory.cpp | 33 +++++++++---------- .../Bullet/Trajectories/EngraveTrajectory.h | 4 +-- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index 51a3b199e1..effde23cb7 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -140,7 +140,9 @@ void EngraveTrajectory::OnUnlimbo(BulletClass* pBullet, CoordStruct* pCoord, Bul // When the launcher exists, the launcher's location will be used to calculate the direction of the coordinate axis instead of bullet's SourceCoords if (pTechno) { - this->TechnoInTransport = static_cast(pTechno->Transporter); + for (auto pTrans = pTechno->Transporter; pTrans; pTrans = pTrans->Transporter) + this->TechnoInTransport = pTrans->UniqueID; + this->GetTechnoFLHCoord(pBullet, pTechno); this->CheckMirrorCoord(pTechno); @@ -288,19 +290,14 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA bool EngraveTrajectory::InvalidFireCondition(BulletClass* pBullet, TechnoClass* pTechno) { - if (!pTechno - || !pTechno->IsAlive - || (pTechno->InLimbo && !pTechno->Transporter) - || pTechno->IsSinking - || pTechno->Health <= 0 - || this->TechnoInTransport != static_cast(pTechno->Transporter) - || pTechno->Deactivated - || pTechno->TemporalTargetingMe - || pTechno->BeingWarpedOut - || pTechno->IsUnderEMP()) - { + if (!pTechno) + return true; + + for (auto pTrans = pTechno->Transporter; pTrans; pTrans = pTrans->Transporter) + pTechno = pTrans; + + if (!TechnoExt::IsActive(pTechno) || this->TechnoInTransport != pTechno->UniqueID) return true; - } if (this->Type->AllowFirerTurning) return false; @@ -375,15 +372,15 @@ void EngraveTrajectory::DrawEngraveLaser(BulletClass* pBullet, TechnoClass* pTec this->LaserTimer.Start(pType->LaserDelay); auto fireCoord = pBullet->SourceCoords; + for (auto pTrans = pTechno->Transporter; pTrans; pTrans = pTrans->Transporter) + pTechno = pTrans; + // Considering that the CurrentBurstIndex may be different, it is not possible to call existing functions - if (!this->NotMainWeapon && pTechno && (pTechno->Transporter || !pTechno->InLimbo)) + if (!this->NotMainWeapon && pTechno && !pTechno->InLimbo) { if (pTechno->WhatAmI() != AbstractType::Building) { - if (const auto pTransporter = pTechno->Transporter) - fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTransporter, this->FLHCoord, pTransporter->HasTurret()); - else - fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); + fireCoord = TechnoExt::GetFLHAbsoluteCoords(pTechno, this->FLHCoord, pTechno->HasTurret()); } else { diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index f02d898847..395f2b5a8f 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -83,7 +83,7 @@ class EngraveTrajectory final : public PhobosTrajectory , Duration { trajType->Duration } , LaserTimer {} , DamageTimer {} - , TechnoInTransport { false } + , TechnoInTransport { 0 } , NotMainWeapon { false } , FLHCoord {} , BuildingCoord {} @@ -108,7 +108,7 @@ class EngraveTrajectory final : public PhobosTrajectory int Duration; CDTimerClass LaserTimer; CDTimerClass DamageTimer; - bool TechnoInTransport; + DWORD TechnoInTransport; bool NotMainWeapon; CoordStruct FLHCoord; CoordStruct BuildingCoord; From bf5967a98145880314d7cfc6a3dc7dd00f7026a4 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 18 Feb 2025 15:54:58 +0800 Subject: [PATCH 53/54] Fix typo --- src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index effde23cb7..b532d398d3 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -296,7 +296,7 @@ bool EngraveTrajectory::InvalidFireCondition(BulletClass* pBullet, TechnoClass* for (auto pTrans = pTechno->Transporter; pTrans; pTrans = pTrans->Transporter) pTechno = pTrans; - if (!TechnoExt::IsActive(pTechno) || this->TechnoInTransport != pTechno->UniqueID) + if (!TechnoExt::IsActive(pTechno) || (this->TechnoInTransport && this->TechnoInTransport != pTechno->UniqueID)) return true; if (this->Type->AllowFirerTurning) From a11414adc79ea6eec465573ca80082488a1cec03 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Fri, 28 Feb 2025 18:15:42 +0800 Subject: [PATCH 54/54] New `Trajectory.Engrave.ProximityFlight` and `Trajectory.Engrave.ConfineOnGround` --- docs/New-or-Enhanced-Logics.md | 12 +++- .../Bullet/Trajectories/EngraveTrajectory.cpp | 67 +++++++++++++++++-- .../Bullet/Trajectories/EngraveTrajectory.h | 4 ++ 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index ae854dfade..1cc62431dc 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -727,7 +727,7 @@ Currently interceptor weapons with projectiles that do not have `Inviso=true` wi - The speed of the projectile is defined by `Trajectory.Speed`, which unlike `Speed` used by `ROT` > 0 projectiles is defined on projectile not weapon. - In `Trajectory=Straight`, it refers to the whole distance speed of the projectile and it has no restrictions. - In `Trajectory=Bombard`, it refers to the initial speed of the projectile and it has no restrictions. - - In `Trajectory=Engrave`, it refers to the engrave speed of the projectile and it cannot exceed 128. Recommend set as about 40. + - In `Trajectory=Engrave`, it refers to the horizontal engrave speed of the projectile and it cannot exceed 128. Recommend set as about 40. - In `Trajectory=Parabola`, it refers to the horizontal velocity of the projectile and is only used for modes 0, 3, or 5 and it has no restrictions. In `rulesmd.ini`: @@ -921,8 +921,8 @@ Trajectory.Parabola.AxisOfRotation=0,0,1 ; integer - Forward,Lateral,Heig #### Engrave trajectory - Visually, like the thermal lance. Calling it 'trajectory' may not be appropriate. It does not read the settings on the weapon. - - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level. - - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level. + - `Trajectory.Engrave.SourceCoord` controls the starting point of engraving line segment. Taking the target as the coordinate center. Specifically, it will start from the firing position when set to 0,0 . The height of the point will always at ground level, unless `Trajectory.Engrave.ConfineOnGround` is set to false. + - `Trajectory.Engrave.TargetCoord` controls the end point of engraving line segment. Taking the target as the coordinate center. The height of the point will always at ground level, unless `Trajectory.Engrave.ConfineOnGround` is set to false. - `Trajectory.Engrave.MirrorCoord` controls whether `Trajectory.Engrave.SourceCoord` and `Trajectory.Engrave.TargetCoord` need to mirror the lateral value to adapt to the current FLH. - `Trajectory.Engrave.UseDisperseCoord` controls whether the emission position of the engrave laser need to replaced with the FLH of its superior's dispersed trajectory, which set `Trajectory.Disperse.RecordSourceCoord` to true. - `Trajectory.Engrave.ApplyRangeModifiers` controls whether any applicable weapon range modifiers from the firer are applied to the engrave process. @@ -945,7 +945,10 @@ Trajectory.Parabola.AxisOfRotation=0,0,1 ; integer - Forward,Lateral,Heig - `Trajectory.Engrave.ProximityDirect` controls whether let the target receive damage instead of detonating the warhead. - `Trajectory.Engrave.ProximityMedial` controls whether to detonate `Trajectory.Engrave.ProximityWarhead` at the bullet's location rather than the proximity target's location. - `Trajectory.Engrave.ProximityAllies` controls whether allies will also trigger the proximity fuse. + - `Trajectory.Engrave.ProximityFlight` controls whether to count units in the air. - `Trajectory.Engrave.ProximitySuicide` controls whether the projectile will self destruct after the number of proximity fuse times has been exhausted. If `Trajectory.Engrave.ProximityImpact` set to 0, this will not be enabled. + - `Trajectory.Engrave.ConfineOnGround` controls whether the height of the projectile will always at ground level. + In `rulesmd.ini`: ```ini @@ -976,11 +979,14 @@ Trajectory.Engrave.ProximityRadius=0.7 ; floating point value Trajectory.Engrave.ProximityDirect=false ; boolean Trajectory.Engrave.ProximityMedial=false ; boolean Trajectory.Engrave.ProximityAllies=false ; boolean +Trajectory.Engrave.ProximityFlight=false ; boolean Trajectory.Engrave.ProximitySuicide=false ; boolean +Trajectory.Engrave.ConfineOnGround=true ; boolean ``` ```{note} - It's best not to let it be intercepted. +- Make sure you set a low `Trajectory.Engrave.ProximityRadius` value unless necessary. ``` ### Shrapnel enhancements diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp index b532d398d3..28c366e06d 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -42,7 +43,9 @@ void EngraveTrajectoryType::Serialize(T& Stm) .Process(this->ProximityDirect) .Process(this->ProximityMedial) .Process(this->ProximityAllies) + .Process(this->ProximityFlight) .Process(this->ProximitySuicide) + .Process(this->ConfineOnGround) ; } @@ -94,7 +97,9 @@ void EngraveTrajectoryType::Read(CCINIClass* const pINI, const char* pSection) this->ProximityDirect.Read(exINI, pSection, "Trajectory.Engrave.ProximityDirect"); this->ProximityMedial.Read(exINI, pSection, "Trajectory.Engrave.ProximityMedial"); this->ProximityAllies.Read(exINI, pSection, "Trajectory.Engrave.ProximityAllies"); + this->ProximityFlight.Read(exINI, pSection, "Trajectory.Engrave.ProximityFlight"); this->ProximitySuicide.Read(exINI, pSection, "Trajectory.Engrave.ProximitySuicide"); + this->ConfineOnGround.Read(exINI, pSection, "Trajectory.Engrave.ConfineOnGround"); } template @@ -276,7 +281,9 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA theSource.Y += static_cast(this->SourceCoord.X * Math::sin(rotateAngle) - this->SourceCoord.Y * Math::cos(rotateAngle)); } - theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); + if (this->Type->ConfineOnGround) + theSource.Z = this->GetFloorCoordHeight(pBullet, theSource); + this->StartCoord = theSource; pBullet->SetLocation(theSource); @@ -318,13 +325,16 @@ int EngraveTrajectory::GetFloorCoordHeight(BulletClass* pBullet, const CoordStru { const auto pCell = MapClass::Instance->GetCellAt(coord); const auto onFloor = MapClass::Instance->GetCellFloorHeight(coord); - const auto onBridge = pCell->GetCoordsWithBridge().Z; + const auto onBridge = pCell->ContainsBridge() ? onFloor + CellClass::BridgeHeight : onFloor; return (pBullet->SourceCoords.Z >= onBridge || pBullet->TargetCoords.Z >= onBridge) ? onBridge : onFloor; } bool EngraveTrajectory::PlaceOnCorrectHeight(BulletClass* pBullet) { + if (!this->Type->ConfineOnGround) + return false; + auto bulletCoords = pBullet->Location; CoordStruct futureCoords { @@ -446,6 +456,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p static_cast(pBullet->Velocity.Z) }; const auto velocitySq = velocityCrd.MagnitudeSquared(); + const auto pTarget = pBullet->Target; std::vector validTechnos; validTechnos.reserve(vectSize); @@ -468,7 +479,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p continue; // Not directly harming friendly forces - if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pBullet->Target) + if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pTarget) continue; // Check distance @@ -501,7 +512,53 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p } } - // Step 2: Record each target without repetition. + // Step 2: Find valid targets in the air within range if necessary. + if (pType->ProximityFlight) + { + const auto airTracker = &AircraftTrackerClass::Instance; + airTracker->FillCurrentVector(MapClass::Instance->GetCellAt(pBullet->Location + velocityCrd * 0.5), + Game::F2I(sqrt(radius * radius + (velocitySq / 4)) / Unsorted::LeptonsPerCell)); + + for (auto pTechno = airTracker->Get(); pTechno; pTechno = airTracker->Get()) + { + if (!pTechno->IsAlive || !pTechno->IsOnMap || pTechno->Health <= 0 || pTechno->InLimbo || pTechno->IsSinking) + continue; + + // Not directly harming friendly forces + if (!pType->ProximityAllies && pOwner && pOwner->IsAlliedWith(pTechno->Owner) && pTechno != pTarget) + continue; + + // Check distance + const auto targetCrd = pTechno->GetCoords(); + const auto pathCrd = targetCrd - this->StartCoord; + + if (pathCrd * velocityCrd < 0) // In front of the techno + continue; + + const auto distanceCrd = targetCrd - pBullet->Location; + const auto nextDistanceCrd = distanceCrd - velocityCrd; + + if (nextDistanceCrd * velocityCrd > 0) // Behind the bullet + continue; + + const auto cross = distanceCrd.CrossProduct(nextDistanceCrd).MagnitudeSquared(); + const auto distance = (velocitySq > 1e-10) ? sqrt(cross / velocitySq) : distanceCrd.Magnitude(); + + if (distance > radius) // In the cylinder + continue; + + if (thisSize >= vectSize) + { + vectSize += cellSize; + validTechnos.reserve(vectSize); + } + + validTechnos.push_back(pTechno); + thisSize += 1; + } + } + + // Step 3: Record each target without repetition. std::vector casualtyChecked; casualtyChecked.reserve(std::max(validTechnos.size(), this->TheCasualty.size())); @@ -531,7 +588,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p this->TheCasualty[pTechno->UniqueID] = 20; } - // Step 3: Detonate warheads in sequence based on distance. + // Step 4: Detonate warheads in sequence based on distance. const auto targetsSize = validTargets.size(); if (this->ProximityImpact > 0 && static_cast(targetsSize) > this->ProximityImpact) diff --git a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h index 395f2b5a8f..c4fe89d1ce 100644 --- a/src/Ext/Bullet/Trajectories/EngraveTrajectory.h +++ b/src/Ext/Bullet/Trajectories/EngraveTrajectory.h @@ -31,7 +31,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType , ProximityDirect { false } , ProximityMedial { false } , ProximityAllies { false } + , ProximityFlight { false } , ProximitySuicide { false } + , ConfineOnGround { true } { } virtual bool Load(PhobosStreamReader& Stm, bool RegisterForChange) override; @@ -65,7 +67,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType Valueable ProximityDirect; Valueable ProximityMedial; Valueable ProximityAllies; + Valueable ProximityFlight; Valueable ProximitySuicide; + Valueable ConfineOnGround; private: template