# **************************************************************************** # CUI # # The Advanced Framework for Simulation, Integration, and Modeling (AFSIM) # # The use, dissemination or disclosure of data in this file is subject to # limitation or restriction. See accompanying README and LICENSE for details. # **************************************************************************** include_once common_timeline_scripts.txt include_once air_combat_maneuvers.txt include_once weapon_defs.txt behavior timeline_delay script_debug_writes off script_variables WsfQuantumTaskerProcessor processor; end_script_variables on_init if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR")) { processor = (WsfQuantumTaskerProcessor)PROCESSOR; } end_on_init #returns true (to wait) if no free target can be shot at (current range) #if target already has weapon on it, it is ignored script bool WaitToTurnAndShoot(Array targets) #only consider free targets (a target with no weapons on it) #compare max weapon range to each free target #calculate time to turn & face for a shot #return false if any target can be turned on & engaged foreach(WsfTrack target in targets) { WsfLocalTrack masterTarget = GetMasterTrackByName(PLATFORM, target.TargetName()); if (!masterTarget.IsValid()) { continue; } bool checkPeerWeapons = false; if (FiredOn(PLATFORM, masterTarget, checkPeerWeapons)) { #LBM TODO - figure out time until weapon terminates # compare that to turn time too # dont necessarily skip this target continue; } double weaponMaxRange = 0.0; WsfWeapon maxRangeWeapon; for (int i=0; i < PLATFORM.WeaponCount(); i+=1) { WsfWeapon weapon = PLATFORM.WeaponEntry(i); if (WeaponCapableAvailableAgainstThreat(weapon, masterTarget)) { double weaponRange = MaxRange(PLATFORM,weapon,masterTarget); if (weaponRange > weaponMaxRange) { weaponMaxRange = weaponRange; maxRangeWeapon = weapon; } } } if (maxRangeWeapon.IsValid()) { #valid weapon found with an intelligible max range double targetRange = PLATFORM.GroundRangeTo(masterTarget.CurrentLocation()); #double weaponMaxRange; double rangeRemaining = targetRange - weaponMaxRange; if(rangeRemaining <= 0) { return false; } #targets speed towards me: double hisClosingSpeed = masterTarget.Speed() * MATH.Cos(masterTarget.RelativeBearingTo(PLATFORM)); #my avg speed towards him (assuming an immediate turn towards him): double myMinClosingSpeed = PLATFORM.Speed() * MATH.Cos(PLATFORM.RelativeBearingTo(masterTarget)); double myMaxClosingSpeed = PLATFORM.Speed(); #assumes I turn & face double myAvgClosingSpeed = (myMinClosingSpeed+myMaxClosingSpeed)/2.0; #closing speed to use: double closingSpeed = hisClosingSpeed + myAvgClosingSpeed; extern double mGeesToTurnWith; double turnTime = TimeToTurnAndFace(PLATFORM.MakeTrack(), masterTarget.CurrentLocation(), mGeesToTurnWith); if (turnTime >= rangeRemaining/closingSpeed) { return false; #dont wait, time to turn & shoot this guy!!! } } } return true; end_script precondition writeln_d(PLATFORM.Name(), " precondition timeline_delay, T=", TIME_NOW); if (!processor.IsValid()) { return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR"); } extern bool mRequiredToSupportWeapons; if (mRequiredToSupportWeapons == true && PLATFORM.WeaponsActiveFor(WsfTrackId()) > 0) { return Failure("required to support active weapons - do not delay"); } WsfTask timeline = GetTimeLineTask(processor); if (!timeline.IsValid()) { return Failure("not assigned a TIMELINE task"); } extern WsfLocalTrack mNearestTimeLineTarget; if (!mNearestTimeLineTarget.IsValid()) { return Failure("no TIMELINE target to fly against"); } #compare risk level with range to nearest target #only delay if risk MED: past DOR and (want to shoot but out of range or waiting on existing shot) # risk HIGH: past MAR and (want to shoot but out of range or waiting on existing shot) string RISK = timeline.AuxDataString("RISK"); if (RISK == "HIGH") { double MAR = timeline.AuxDataDouble("MAR"); #range (meters) double slantRange = PLATFORM.GroundRangeTo(mNearestTimeLineTarget.CurrentLocation()); if (slantRange > MAR) { return Failure("HIGH RISK agent outside of MAR, dont bother delaying"); } Array targets = (Array)timeline.AuxDataObject("targets"); return WaitToTurnAndShoot(targets); } else if (RISK == "MEDIUM") { double DOR = timeline.AuxDataDouble("DOR"); #range (meters) double slantRange = PLATFORM.GroundRangeTo(mNearestTimeLineTarget.CurrentLocation()); if (slantRange > DOR) { return Failure("MEDIUM RISK agent outside of DOR, dont bother delaying"); } Array targets = (Array)timeline.AuxDataObject("targets"); return WaitToTurnAndShoot(targets); } else #if (RISK == "LOW") { return Failure("LOW RISK agent does not go past DOR, no need to delay"); } end_precondition on_new_execute PLATFORM.Comment("delay"); end_on_new_execute execute #TODO - select beam or posthole or whatever Beam(PLATFORM, mNearestTimeLineTarget); end_execute end_behavior