165 lines
5.4 KiB
Plaintext
165 lines
5.4 KiB
Plaintext
|
|
|
||
|
|
processor ucavFire WSF_TASK_PROCESSOR
|
||
|
|
track_update_interval 5.0 sec
|
||
|
|
|
||
|
|
script_variables
|
||
|
|
string SENSOR_NAME;
|
||
|
|
string WEAPON_NAME;
|
||
|
|
int SALVO_SIZE = 2;
|
||
|
|
string mTrackTaskStr = "Track";
|
||
|
|
string mShootTaskStr = "Shoot";
|
||
|
|
end_script_variables
|
||
|
|
|
||
|
|
script bool FiringNow()
|
||
|
|
return (WeaponsActiveFor(TRACK.TrackId()) > 0);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool InInterceptEnvelopeOf(WsfPlatform shooter)
|
||
|
|
if (shooter.IsNull() || !shooter.IsValid()) return false;
|
||
|
|
WsfWeapon w = shooter.Weapon(WEAPON_NAME);
|
||
|
|
if (!w.IsValid()) return false;
|
||
|
|
if (w.LaunchComputer().IsValid())
|
||
|
|
return w.CanIntercept(TRACK);
|
||
|
|
return (shooter.GroundRangeTo(TRACK) <= 150000.0);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool InInterceptEnvelopeOfAnySub()
|
||
|
|
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||
|
|
{
|
||
|
|
if (InInterceptEnvelopeOf(sub)) return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool TrackingNow()
|
||
|
|
return (TasksAssignedFor(TRACK.TrackId(), mTrackTaskStr) > 0);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script void ReleaseResources()
|
||
|
|
CancelTask(TRACK.TrackId());
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool LaunchWeapon()
|
||
|
|
WsfWeapon weapon;
|
||
|
|
WsfPlatform platform;
|
||
|
|
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||
|
|
{
|
||
|
|
weapon = sub.Weapon(WEAPON_NAME);
|
||
|
|
if (weapon.IsTurnedOn() &&
|
||
|
|
(weapon.QuantityRemaining() >= SALVO_SIZE) &&
|
||
|
|
(TasksAssignedTo(sub, "", weapon.Name()) < 1) &&
|
||
|
|
InInterceptEnvelopeOf(sub))
|
||
|
|
{
|
||
|
|
platform = sub;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
bool launched = false;
|
||
|
|
if (weapon.IsValid() && !platform.IsNull())
|
||
|
|
launched = Fire(TRACK, mShootTaskStr, weapon.Name(), SALVO_SIZE, platform);
|
||
|
|
return launched;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool IsAssignable()
|
||
|
|
return ((PLATFORM == PLATFORM.Commander()) ||
|
||
|
|
(TasksReceivedFor(TRACK.TrackId()) > 0) ||
|
||
|
|
(OperatingLevelFor("ENGAGE") > 0));
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script int WeaponsAvailable(WsfPlatform aAssignee)
|
||
|
|
WsfWeapon weapon = aAssignee.Weapon(WEAPON_NAME);
|
||
|
|
if (!weapon.IsTurnedOn()) return 0;
|
||
|
|
return weapon.QuantityRemaining();
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script int TotalWeaponsAvailable()
|
||
|
|
int quantity = 0;
|
||
|
|
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||
|
|
quantity = quantity + WeaponsAvailable(sub);
|
||
|
|
return quantity;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script bool Engage()
|
||
|
|
if (TotalWeaponsAvailable() < 1)
|
||
|
|
{
|
||
|
|
writeln("Engage: no weapons available");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||
|
|
{
|
||
|
|
if (TasksAssignedTo(sub, TRACK.TrackId(), mTrackTaskStr) > 0) continue;
|
||
|
|
WsfSensor sensor = sub.Sensor(SENSOR_NAME);
|
||
|
|
if (!sensor.IsValid())
|
||
|
|
{
|
||
|
|
writeln("Engage: sub ", sub.Name(), " sensor ", SENSOR_NAME, " invalid");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
int maxTrack = sensor.MaximumRequestCount("TRACK");
|
||
|
|
if (maxTrack > 0 && sensor.ActiveRequestCount("TRACK") >= maxTrack)
|
||
|
|
{
|
||
|
|
writeln("Engage: sub ", sub.Name(), " TRACK slots full");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (TRACK.BelievedAlive() && InInterceptEnvelopeOf(sub))
|
||
|
|
{
|
||
|
|
bool ok = StartTracking(TRACK, mTrackTaskStr, sensor.Name(), "default", sub);
|
||
|
|
writeln("Engage: StartTracking ", sub.Name(), " -> ", ok);
|
||
|
|
if (ok) return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
writeln("Engage: no sub assigned for ", TRACK.TargetName());
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
evaluation_interval DETECTED 2.0 sec
|
||
|
|
state DETECTED
|
||
|
|
next_state DETECTED
|
||
|
|
if (TRACK.IFF_Friend()) { CancelTask(TRACK.TrackId()); return true; }
|
||
|
|
return false;
|
||
|
|
end_next_state
|
||
|
|
next_state ENGAGEABLE
|
||
|
|
return (TRACK.BelievedAlive() && !TRACK.IFF_Friend() && IsAssignable());
|
||
|
|
end_next_state
|
||
|
|
end_state
|
||
|
|
|
||
|
|
evaluation_interval ENGAGEABLE 2.0 sec
|
||
|
|
state ENGAGEABLE
|
||
|
|
next_state DETECTED
|
||
|
|
if (TRACK.BelievedDead() || TRACK.IFF_Friend() ||
|
||
|
|
((TasksAssignedFor(TRACK.TrackId(), "ENGAGE") < 1) && !IsAssignable()))
|
||
|
|
{ ReleaseResources(); return true; }
|
||
|
|
return false;
|
||
|
|
end_next_state
|
||
|
|
next_state ENGAGE
|
||
|
|
bool didEngage = Engage();
|
||
|
|
bool trackNow = TrackingNow();
|
||
|
|
int assigned = TasksAssignedFor(TRACK.TrackId(), mTrackTaskStr);
|
||
|
|
writeln("ENGAGEABLE->ENGAGE: didEngage=", didEngage, " trackNow=", trackNow, " assigned=", assigned, " target=", TRACK.TargetName());
|
||
|
|
return (trackNow && (assigned > 0));
|
||
|
|
end_next_state
|
||
|
|
end_state
|
||
|
|
|
||
|
|
evaluation_interval ENGAGE 2.0 sec
|
||
|
|
state ENGAGE
|
||
|
|
next_state ENGAGEABLE
|
||
|
|
if (TRACK.BelievedDead() || !TrackingNow() || !IsAssignable())
|
||
|
|
{ ReleaseResources(); return true; }
|
||
|
|
return false;
|
||
|
|
end_next_state
|
||
|
|
next_state FIRING
|
||
|
|
if (TRACK.BelievedAlive() && TrackingNow() && !FiringNow() && InInterceptEnvelopeOfAnySub())
|
||
|
|
return LaunchWeapon();
|
||
|
|
return false;
|
||
|
|
end_next_state
|
||
|
|
end_state
|
||
|
|
|
||
|
|
evaluation_interval FIRING 2.0 sec
|
||
|
|
state FIRING
|
||
|
|
next_state ENGAGE
|
||
|
|
return (TRACK.BelievedDead() || !InInterceptEnvelopeOfAnySub() ||
|
||
|
|
(!FiringNow() && (TasksAssignedFor(TRACK.TrackId(), mShootTaskStr) < 1)) ||
|
||
|
|
(TotalWeaponsAvailable() < 1) || !TrackingNow());
|
||
|
|
end_next_state
|
||
|
|
end_state
|
||
|
|
end_processor
|