← Home SEEBIE90 DOCS
The RIM-116 & Phalanx mod is published under the Arma Public License (APL)Example code is free to useSuggestions: Discord to the author

RIM-116 & Phalanx

Target acquisition

A world query rather than a hook on the projectile – because the projectile classes cannot be extended at all. Classification then has to separate a helicopter from its own bench seat.

In plain wordsThe mount sweeps the area for things to shoot, then sorts them into aircraft, incoming rockets and shells.

Why a world query and not a hook

Projectile and ProjectileMoveComponent live in scripts/Game/generated/ and cannot be extended with modded class – attempting it aborts the entire script module, not just that class. Their proto external methods are still callable, though, so the velocity can be read straight off a found projectile instead of being estimated from two samples.

NoteThis is the general shape of the limitation: engine classes are closed to modded class but open to calls. Anything that would have been an override becomes a query plus a call.
Example code – free to use
void MyAD_Tracker_Scan()
{
	m_aFound.Clear();
	GetGame().GetWorld().QueryEntitiesBySphere(m_vOrigin, m_fRadius, OnCandidate, null, EQueryEntitiesFlags.DYNAMIC);
}

vector MyAD_Tracker_VelocityOf(IEntity ent)
{
	ProjectileMoveComponent move = ProjectileMoveComponent.Cast(ent.FindComponent(ProjectileMoveComponent));
	if (move)
		return move.GetVelocity();		// callable even where modded class is not

	Physics phys = ent.GetPhysics();
	if (phys && phys.IsDynamic())
		return phys.GetVelocity();

	return vector.Zero;
}

An attachment is not an aircraft

A helicopter was tracked as four targets, and the mount shot at the bench seat. Seats and turrets satisfy “enterable and above ground”, so they classified as aircraft in their own right. The fix is one check at the top of classification – the same hierarchy test that fixes countermeasure detection on the chaff page.

Example code – free to use
MyAD_ETargetKind MyAD_Tracker_Classify(IEntity ent)
{
	// an entity with a parent is part of something else: a seat, a turret, a loaded flare
	if (ent.GetParent())
	{
		m_iRejectedAttachments++;
		return MyAD_ETargetKind.NONE;
	}

	...
}
NoteThe counter is not decoration. A scan report that lists how many candidates were rejected as attachments is the only way to see that a rejection rule is firing – and the only way to notice when it over-fires.
PitfallIn Reforger that single test separates a helicopter from its seats, a launcher from its loaded flares and a vehicle from its turret. It is also the easiest to forget, because everything in the world looks like a top-level entity until you ask.

What gets engaged with what

KindEngaged withNotes
AircraftMissile salvoa short delay before the first shot, longer at long range
Incoming ordnance (rockets, shells)Gun burstno delay – there is no time
Everything elseNot engaged–

Add a dead zone around the mount and a minimum altitude: targets inside either are tracked but not fired at. Both should be per-weapon values rather than shared constants, because a gun and a launcher disagree about what “too close” means.

PitfallA curve scale that looks like a range is not an engagement range. Keep the distance at which a lock-on time curve saturates apart from the distance at which the weapon is allowed to fire – they were conflated once.
Example code on this page is free to use in your own projects (credit appreciated). The RIM-116 & Phalanx mod is published under the Arma Public License (APL). Suggestions: Discord. Arma Reforger / Enfusion are trademarks of Bohemia Interactive.
Impressum · Privacy Policy