272 lines
11 KiB
Plaintext
272 lines
11 KiB
Plaintext
|
|
# ****************************************************************************
|
||
|
|
# 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 weapon_defs.txt
|
||
|
|
|
||
|
|
behavior engage_on_timeline
|
||
|
|
|
||
|
|
script_debug_writes off
|
||
|
|
|
||
|
|
script_variables
|
||
|
|
//**********************************************************************//
|
||
|
|
//** platform / agent specific shooting parameters **//
|
||
|
|
//**********************************************************************//
|
||
|
|
#bool mCoopEngageOne = false;
|
||
|
|
#bool mCoopEngageOneFlightOnly = false;
|
||
|
|
# double mDegradedFiringAngle = 55.0; //negative if not valid
|
||
|
|
# double mDegradedPercentRange = 0.50; //range constraint if past degraded firing angle
|
||
|
|
# //specify orientation limits for shooting
|
||
|
|
# double mMaxFiringRollAngle = 10.0; //dont shoot if rolled more/less than this
|
||
|
|
# double mMaxFiringPitchAngle = 15.0; //dont shoot if pitched more than this
|
||
|
|
# double mMinFiringPitchAngle = -10.0; //dont shoot if pitched less than this
|
||
|
|
|
||
|
|
//**********************************************************************//
|
||
|
|
//** threat specific shooting parameters **//
|
||
|
|
//**********************************************************************//
|
||
|
|
|
||
|
|
//require different track qualities to fire on different kinds of threats
|
||
|
|
# double DefaultRequiredTrackQuality = 0.49;
|
||
|
|
# Map<string, double> ThreatTypeRequiredTrackQuality = Map<string, double>();
|
||
|
|
# ThreatTypeRequiredTrackQuality["bomber"] = 0.49;
|
||
|
|
# ThreatTypeRequiredTrackQuality["fighter"] = 0.49;
|
||
|
|
|
||
|
|
//fire off different salvos at different types of threats
|
||
|
|
# int DefaultAirSalvo = 1;
|
||
|
|
# int DefaultGndSalvo = 1;
|
||
|
|
# Map<string, int> ThreatTypeSalvo = Map<string, int>();
|
||
|
|
# ThreatTypeSalvo["sam"] = 2;
|
||
|
|
# ThreatTypeSalvo["ship"] = 2;
|
||
|
|
# ThreatTypeSalvo["bomber"] = 2;
|
||
|
|
# ThreatTypeSalvo["fighter"] = 1;
|
||
|
|
# ThreatTypeSalvo["FIRE_CONTROL"] = 1;
|
||
|
|
# ThreatTypeSalvo["primary_target"] = 2;
|
||
|
|
# ThreatTypeSalvo["secondary_target"] = 2;
|
||
|
|
|
||
|
|
//**********************************************************************//
|
||
|
|
//** weapon + threat specific shooting parameters **//
|
||
|
|
//**********************************************************************//
|
||
|
|
//specify an Rmax based on which weapon used and which threat engaged
|
||
|
|
double DefaultPercentRangeMax = 0.80; // don't launch unless within this percent of Rmax
|
||
|
|
double DefaultPercentRangeMin = 1.20; // don't launch unless beyond this percent of Rmin
|
||
|
|
Map<string, Map<string, double>> WeaponThreatRmaxMap = Map<string, Map<string, double>>();
|
||
|
|
WeaponThreatRmaxMap["base_weapon"] = Map<string, double>();
|
||
|
|
WeaponThreatRmaxMap["base_weapon"].Set("fighter", 0.80);
|
||
|
|
end_script_variables
|
||
|
|
|
||
|
|
|
||
|
|
# script int GetSalvoForThreat(WsfTrack track)
|
||
|
|
# #writeln_d("checking salvo size for category: ", category);
|
||
|
|
# #WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetIndex() );
|
||
|
|
# WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
|
||
|
|
# if (plat.IsValid())
|
||
|
|
# {
|
||
|
|
# foreach( string aCategory : int salvo in ThreatTypeSalvo )
|
||
|
|
# {
|
||
|
|
# if( plat.CategoryMemberOf( aCategory ) )
|
||
|
|
# {
|
||
|
|
# writeln_d("salvo for type ", aCategory, " = ", salvo);
|
||
|
|
# return salvo;
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
# #extern string GetTargetDomain(WsfTrack);
|
||
|
|
# string sTargetDomain = GetTargetDomain(track);
|
||
|
|
# if ( (sTargetDomain == "LAND") || (sTargetDomain == "SURFACE") )
|
||
|
|
# {
|
||
|
|
# return DefaultGndSalvo;
|
||
|
|
# }
|
||
|
|
# return DefaultAirSalvo;
|
||
|
|
# end_script
|
||
|
|
|
||
|
|
|
||
|
|
# script double GetRequiredTrackQualityForThreat(WsfTrack threat)
|
||
|
|
# writeln_d("checking required TQ for track: ", threat.TargetName());
|
||
|
|
# WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
|
||
|
|
# if (plat.IsValid())
|
||
|
|
# {
|
||
|
|
# foreach( string aCategory : double quality in ThreatTypeRequiredTrackQuality )
|
||
|
|
# {
|
||
|
|
# if( plat.CategoryMemberOf( aCategory ) )
|
||
|
|
# {
|
||
|
|
# writeln_d("TQ for type ", aCategory, " = ", quality);
|
||
|
|
# return quality;
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
# return DefaultRequiredTrackQuality;
|
||
|
|
# end_script
|
||
|
|
|
||
|
|
|
||
|
|
script double GetLaunchPercentRangeMaxOnThreat(string weaponName, WsfTrack threat)
|
||
|
|
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
|
||
|
|
if (plat.IsValid())
|
||
|
|
{
|
||
|
|
if (WeaponThreatRmaxMap.Exists(weaponName))
|
||
|
|
{
|
||
|
|
Map<string, double> categoryRangeMap = WeaponThreatRmaxMap.Get(weaponName);
|
||
|
|
foreach (string aCategory : double percent in categoryRangeMap)
|
||
|
|
{
|
||
|
|
if( plat.CategoryMemberOf( aCategory ) )
|
||
|
|
{
|
||
|
|
return percent;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return DefaultPercentRangeMax;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
#on_init
|
||
|
|
#end_on_init
|
||
|
|
|
||
|
|
|
||
|
|
precondition
|
||
|
|
#writeln_d("precondition engage-target");
|
||
|
|
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
|
||
|
|
{
|
||
|
|
writeln_d("behavior engage... not on quantum tasker processor");
|
||
|
|
return Failure("behavior not attached to a quantum tasker processor!");
|
||
|
|
}
|
||
|
|
|
||
|
|
# todo - try using a state machine to setup the shot ??
|
||
|
|
# double pitch = PLATFORM.Pitch();
|
||
|
|
# if (MATH.Fabs(PLATFORM.Roll()) > mMaxFiringRollAngle ||
|
||
|
|
# pitch > mMaxFiringPitchAngle ||
|
||
|
|
# pitch < mMinFiringPitchAngle)
|
||
|
|
# {
|
||
|
|
# string msgStr = write_str(" ", PLATFORM.Name(), " orientation too far off to fire! (roll or pitch)");
|
||
|
|
# writeln_d(msgStr);
|
||
|
|
# //PLATFORM.Comment(msgStr);
|
||
|
|
# return Failure(msgStr);
|
||
|
|
# }
|
||
|
|
|
||
|
|
WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR;
|
||
|
|
# WsfTaskList tasks = proc.TasksReceivedOfType("WEAPON");
|
||
|
|
# if (tasks.Count() > 0)
|
||
|
|
# {
|
||
|
|
# writeln_d("behavior engage precondition passes!");
|
||
|
|
# return true;
|
||
|
|
# }
|
||
|
|
# writeln_d("no weapon task target to shoot at!");
|
||
|
|
|
||
|
|
if (GetTimelineTask(proc).IsValid())
|
||
|
|
{
|
||
|
|
writeln_d("behavior engage precondition passes!");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
writeln_d("no timeline task to engage!");
|
||
|
|
return Failure("no timeline task to engage!");
|
||
|
|
end_precondition
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
execute
|
||
|
|
writeln_d(PLATFORM.Name(), " executing engage-target, T=", TIME_NOW);
|
||
|
|
#extern WsfTrack GetTrackByName(WsfPlatform, string);
|
||
|
|
#check all possible targets on all channels
|
||
|
|
########################################################################
|
||
|
|
### fire on any pursue-target jobs we are assigned to
|
||
|
|
########################################################################
|
||
|
|
WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR;
|
||
|
|
|
||
|
|
WsfTask timeline = GetTimelineTask(proc);
|
||
|
|
if (timeline.IsValid() && timeline.AuxDataExists("targets"))
|
||
|
|
{
|
||
|
|
Array<WsfTrack> targets = (Array<WsfTrack>)timeline.AuxDataObject("targets");
|
||
|
|
foreach (WsfTrack target in targets)
|
||
|
|
{
|
||
|
|
if (!target.IsValid())
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
#do we need master track?
|
||
|
|
WsfLocalTrack masterTarget = GetMasterTrackByName(PLATFORM, target.TargetName());
|
||
|
|
if (!masterTarget.IsValid())
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
# if (mCoopEngageOne == false)
|
||
|
|
# {
|
||
|
|
# WsfLocalTrack targetLocalTrack = (WsfLocalTrack)targetTrack;
|
||
|
|
# if (targetLocalTrack.IsValid())
|
||
|
|
# {
|
||
|
|
# if(!targetLocalTrack.ContributorOf(PLATFORM) &&
|
||
|
|
# !targetLocalTrack.IsPredefined())
|
||
|
|
# {
|
||
|
|
# writeln_d(" FAIL: Not able to coop engage! ", PLATFORM.Name(), " targeting ",targetTrack.TargetName(), ". NumContributors: ", targetLocalTrack.NumContributors() );
|
||
|
|
# return;
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
# }
|
||
|
|
#
|
||
|
|
# writeln_d (" targetTrack.TrackQuality == ", targetTrack.TrackQuality());
|
||
|
|
# if (targetTrack.TrackQuality() < GetRequiredTrackQualityForThreat(targetTrack))
|
||
|
|
# {
|
||
|
|
# writeln_d(" FAIL: track quality not good enough to fire on target");
|
||
|
|
# return;
|
||
|
|
# }
|
||
|
|
|
||
|
|
if ((PLATFORM.WeaponsPendingFor(masterTarget.TrackId()) + PLATFORM.WeaponsActiveFor(masterTarget.TrackId())) > 0)
|
||
|
|
{
|
||
|
|
writeln_d("already have weapons assigned for target: ", masterTarget.TargetName());
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
WsfWeapon weapon;
|
||
|
|
bool weaponUsable = false;
|
||
|
|
#first weapon found will be used
|
||
|
|
for (int i=0; i < PLATFORM.WeaponCount(); i+=1)
|
||
|
|
{
|
||
|
|
weapon = PLATFORM.WeaponEntry(i);
|
||
|
|
writeln_d("checking if weapon ", weapon.Name(), " is usable.");
|
||
|
|
if (WeaponCapableAvailableAgainstThreat(weapon, masterTarget) &&
|
||
|
|
InRangeToFire(PLATFORM, weapon, masterTarget, GetLaunchPercentRangeMaxOnThreat(weapon.Name(), masterTarget), DefaultPercentRangeMin))
|
||
|
|
{
|
||
|
|
weaponUsable = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (weaponUsable == false)
|
||
|
|
{
|
||
|
|
writeln_d("no usable weapon found!");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
#int salvoCount = GetSalvoForThreat(targetTrack);
|
||
|
|
#writeln_d(" salvo count for ", targetTrack, " is: ", salvoCount);
|
||
|
|
int salvoCount = 1;
|
||
|
|
bool launched = false;
|
||
|
|
if (weapon.IsTurnedOn())
|
||
|
|
{
|
||
|
|
writeln_d(" Attempting launch at ", masterTarget.TargetName());
|
||
|
|
# if (salvoCount > 1)
|
||
|
|
# {
|
||
|
|
# writeln_d("FIRING SALVO AT ", masterTarget.TargetName());
|
||
|
|
# launched = weapon.FireSalvo(masterTarget, salvoCount);
|
||
|
|
# }
|
||
|
|
# else
|
||
|
|
# {
|
||
|
|
# writeln_d("FIRING AT ", masterTarget.TargetName());
|
||
|
|
# launched = weapon.Fire(masterTarget);
|
||
|
|
# }
|
||
|
|
launched = weapon.FireSalvo(masterTarget, salvoCount);
|
||
|
|
}
|
||
|
|
writeln_d(" launched == ", launched, ", weapon: ", weapon.Name());
|
||
|
|
if(launched == false)
|
||
|
|
{
|
||
|
|
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", masterTarget.TargetName(), " at time: ", TIME_NOW);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
end_execute
|
||
|
|
|
||
|
|
end_behavior
|