Skip to content

Commit

Permalink
New Trajectory.Engrave.ProximityFlight and `Trajectory.Engrave.Conf…
Browse files Browse the repository at this point in the history
…ineOnGround`
  • Loading branch information
CrimRecya committed Feb 28, 2025
1 parent 653c3e7 commit a11414a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 8 deletions.
12 changes: 9 additions & 3 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`:
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
67 changes: 62 additions & 5 deletions src/Ext/Bullet/Trajectories/EngraveTrajectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <TacticalClass.h>
#include <LaserDrawClass.h>
#include <AircraftTrackerClass.h>

#include <Ext/WeaponType/Body.h>
#include <Ext/WarheadType/Body.h>
Expand Down Expand Up @@ -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)
;
}

Expand Down Expand Up @@ -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<typename T>
Expand Down Expand Up @@ -276,7 +281,9 @@ void EngraveTrajectory::SetEngraveDirection(BulletClass* pBullet, double rotateA
theSource.Y += static_cast<int>(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);

Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -446,6 +456,7 @@ void EngraveTrajectory::PrepareForDetonateAt(BulletClass* pBullet, HouseClass* p
static_cast<int>(pBullet->Velocity.Z)
};
const auto velocitySq = velocityCrd.MagnitudeSquared();
const auto pTarget = pBullet->Target;

std::vector<TechnoClass*> validTechnos;
validTechnos.reserve(vectSize);
Expand All @@ -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
Expand Down Expand Up @@ -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<int> casualtyChecked;
casualtyChecked.reserve(std::max(validTechnos.size(), this->TheCasualty.size()));

Expand Down Expand Up @@ -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<int>(targetsSize) > this->ProximityImpact)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Bullet/Trajectories/EngraveTrajectory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -65,7 +67,9 @@ class EngraveTrajectoryType final : public PhobosTrajectoryType
Valueable<bool> ProximityDirect;
Valueable<bool> ProximityMedial;
Valueable<bool> ProximityAllies;
Valueable<bool> ProximityFlight;
Valueable<bool> ProximitySuicide;
Valueable<bool> ConfineOnGround;

private:
template <typename T>
Expand Down

0 comments on commit a11414a

Please sign in to comment.