519 lines
21 KiB
Plaintext
519 lines
21 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.
|
|
# ****************************************************************************
|
|
|
|
|
|
#always requires a commander (in order to do anything interesting)
|
|
#does not create any jobs
|
|
|
|
include_once processors/ripr_agents/common/common_platform_script.txt
|
|
|
|
include_once processors/ripr_agents/aiai/behavior_bid_on_jobs.txt
|
|
include_once processors/ripr_agents/aiai/behavior_cap-route.txt
|
|
include_once processors/ripr_agents/aiai/behavior_default-flight.txt
|
|
include_once processors/ripr_agents/aiai/behavior_engage-target.txt
|
|
include_once processors/ripr_agents/aiai/behavior_escort.txt
|
|
include_once processors/ripr_agents/aiai/behavior_evade.txt
|
|
include_once processors/ripr_agents/aiai/behavior_go_home.txt
|
|
include_once processors/ripr_agents/aiai/behavior_guide_weapons.txt
|
|
include_once processors/ripr_agents/aiai/behavior_pincer.txt
|
|
include_once processors/ripr_agents/aiai/behavior_pincer_fsm.txt
|
|
include_once processors/ripr_agents/aiai/behavior_pursue-point.txt
|
|
include_once processors/ripr_agents/aiai/behavior_pursue-target.txt
|
|
include_once processors/ripr_agents/aiai/behavior_radar-control.txt
|
|
#include_once processors/ripr_agents/aiai/behavior_sar_job.txt
|
|
#include_once processors/ripr_agents/aiai/behavior_weapon-uplink.txt
|
|
|
|
|
|
|
|
processor AIAI-thinker WSF_RIPR_PROCESSOR
|
|
|
|
update_interval 1.0 sec
|
|
script_debug_writes off
|
|
|
|
script_variables
|
|
// agent constants
|
|
double cMIN_JOB_BID = -MATH.DOUBLE_MAX();
|
|
|
|
|
|
//**********************************************************************//
|
|
//** bidding parameters **//
|
|
//** slant range and closing speed are the most important **//
|
|
//** bids are now in units of distance (meters) **//
|
|
//** all other bid contributions are converted with their weight **//
|
|
//** range will dominate the bids **//
|
|
//**********************************************************************//
|
|
double cMAX_SLANT_RANGE = 1000000.0; #over 539 nm away, target ranges beyond this are considered unfavorable
|
|
double cWEIGHT_SLANT_RANGE_TO = 1.0;
|
|
#double cWEIGHT_SLANT_RANGE_TO = -4.0; #-3.0 (legacy value)
|
|
double cMIN_CLOSING_SPEED = -1050.0; #threats running away (negative closing) faster are considered unfavorable
|
|
double cWEIGHT_CLOSING_SPEED = 1.0; #scale for how closing speed translates to distance
|
|
double cWEIGHT_FUEL = 0.0; #try a value of 2.0 if you care about fuel
|
|
double cWEIGHT_MY_WEAPONS_ACTIVE = 0.0; #changes bid if your own weapons are active on target
|
|
double cWEIGHT_PEERS_WEAPONS_ACTIVE = 0.0; #changes bid if your peers weapons are active on target
|
|
double cWEIGHT_THREAT_WEAPONS_ENVELOPE = 0.0; #uses the global "mWeaponsEnvelope" array, try value of 10000 if you care about that
|
|
//careful with these two parameters, they are stateful
|
|
double cWEIGHT_CURRENT_TARGET = 0.0; #changes bid if you are currently targeting the threat
|
|
#double cWEIGHT_CURRENT_TARGET = 10.0; #cap route jobs
|
|
#double cWEIGHT_CURRENT_TARGET = 1.0; #weapon uplink jobs
|
|
double cWEIGHT_OTHERS_TARGETING = 0.0; #changes bid if peers are currently targeting the threat
|
|
|
|
//**********************************************************************//
|
|
//** control / mode of operation parameters **//
|
|
//**********************************************************************//
|
|
bool mFilterJobsOnWeapons = true; # ignore pursue-target jobs that we cant shoot a weapon at
|
|
bool mFilterJobsOnCategory = false; # ignore pursue-target jobs that are for platform of unknown category
|
|
bool mFilterJobsOnFuel = false; # ignore pursue-target jobs that we dont have the fuel to reach
|
|
bool mFilterJobsOnZone = false; # ignore pursue-target jobs that are for platforms outsize of zone "mZoneName"
|
|
string mZoneName = "";
|
|
WsfZone mFezZone;
|
|
string mRequiredWeaponForCap = "";
|
|
bool mAllowCoopEngage = true;
|
|
string mUplinkSensorName = "geo_sensor"; //name of sensor object
|
|
|
|
|
|
double cDEFAULT_ALTITUDE = 9144; // ~30,000 feet
|
|
|
|
|
|
// the interceptor uses these threat priority pairs to determine who is the most important threat of concern
|
|
Map<string, double> ThreatTypePriority = Map<string, double>();
|
|
ThreatTypePriority["unknown"] = 0.0;
|
|
ThreatTypePriority["uav"] = 2.0;
|
|
ThreatTypePriority["sam"] = 4.0;
|
|
ThreatTypePriority["ship"] = 4.0;
|
|
ThreatTypePriority["awacs"] = -500.0;
|
|
ThreatTypePriority["bomber"] = 2.0;
|
|
ThreatTypePriority["jammer"] = 0.0;
|
|
ThreatTypePriority["fighter"] = 10.0;
|
|
ThreatTypePriority["missile"] = 9.0;
|
|
ThreatTypePriority["missile_fast"] = 9.0; // try new category for cmd
|
|
|
|
Array<Map<string, Object>> mWeaponArray = Array<Map<string, Object>>();
|
|
////EXAMPLE:
|
|
//mWeaponArray[0] = Map<string, Object>();
|
|
//mWeaponArray[0].Set("name", "blue_lr_a2a_rf_missile");
|
|
//mWeaponArray[0].Set("weapon", PLATFORM.Weapon("blue_lr_a2a_rf_missile"));
|
|
//mWeaponArray[0].Set("rangeMin", 1852/2); // only used if the weapon does NOT have a launch computer
|
|
//mWeaponArray[0].Set("rangeMax", 60*1852); // only used if the weapon does NOT have a launch computer
|
|
//mWeaponArray[0].Set("onlyUseInRange", 1); // only considered if the target is already in range
|
|
//mWeaponArray[0].Set("numActiveMax", 1); // how many weapons of this type can be in play simultaneously
|
|
//mWeaponArray[0].Set("AIR", 1); // DOMAIN CAPABLE, yes, this weapon can hit air (default true)
|
|
//mWeaponArray[0].Set("LAND", 0); // DOMAIN CAPABLE, no, this weapon can NOT hit land (default false)
|
|
|
|
double mEngagementAggressiveness = 0.4; // value in range [0, 1]. 1 is suicidal, 0 is very cautious.
|
|
// used by behavior_in_danger, behavior_evade, & behavior_disengage.
|
|
end_script_variables
|
|
|
|
|
|
behavior_tree
|
|
behavior_node bid_on_jobs
|
|
selector
|
|
behavior_node evade
|
|
behavior_node go_home
|
|
behavior_node escort
|
|
behavior_node cap-route
|
|
behavior_node pincer_fsm
|
|
sequence
|
|
selector
|
|
behavior_node pursue-target
|
|
#behavior_node sar_job
|
|
behavior_node pursue-point
|
|
behavior_node default-flight
|
|
end_selector
|
|
behavior_node guide_weapons
|
|
end_sequence
|
|
end_selector
|
|
behavior_node radar-control
|
|
behavior_node engage-target
|
|
# behavior_node weapon-uplink
|
|
end_behavior_tree
|
|
|
|
|
|
|
|
###########################################################################
|
|
## utility script methods
|
|
###########################################################################
|
|
script bool HaveWeaponsForThreat(WsfTrack track)
|
|
#extern bool IsWeaponDomainCapable(WsfTrack, Map<string, Object>);
|
|
#extern Array<Map<string, Object>> mWeaponArray;
|
|
foreach (Map<string, Object> curWeapon in mWeaponArray)
|
|
{
|
|
WsfWeapon weapon = (WsfWeapon)curWeapon["weapon"];
|
|
if (weapon.QuantityRemaining() > 0 &&
|
|
IsWeaponDomainCapable(track,curWeapon))
|
|
{
|
|
if (curWeapon.Exists("onlyUseInRange") &&
|
|
(int)curWeapon["onlyUseInRange"] == 1 &&
|
|
PLATFORM.SlantRangeTo(track) > (double)curWeapon["rangeMax"] )
|
|
{
|
|
continue;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
end_script
|
|
|
|
|
|
###########################################################################
|
|
## this runs when the processor initializes (when the platform does)
|
|
###########################################################################
|
|
# on_initialize
|
|
# writeln_d(PLATFORM.Name(), " executing on initialze!");
|
|
# end_on_initialize
|
|
|
|
|
|
###########################################################################
|
|
## deprecated, plz use query_bid_type <job-name> script blocks now
|
|
###########################################################################
|
|
#query_bid
|
|
# return cMIN_JOB_BID;
|
|
#end_query_bid
|
|
|
|
|
|
|
|
query_bid_type pursue-target
|
|
|
|
#extern Map<string, double> ThreatTypePriority;
|
|
#extern WsfTrack GetTrackByName (WsfPlatform, string);
|
|
#extern bool HasEnoughFuelToTravel (WsfPlatform,double);
|
|
#extern string DetermineTrackCategory (WsfTrack);
|
|
#extern bool TestTrackCategory (WsfTrack, string);
|
|
#extern double GetWeaponsEnvelope (WsfPlatform);
|
|
#extern double GetWeaponRangeMax(WsfPlatform aPlatform, Array<Map<string, Object>> aWeaponArray);
|
|
#extern Array<Map<string, Object>> mWeaponArray;
|
|
|
|
if (!JOB.IsValid())
|
|
{
|
|
writeln_d("query_bid_type pursue-target: JOB not valid");
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
string targetTrackName = (string)JOB.GetData("targetTrackName");
|
|
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetTrackName);
|
|
if (!targetTrack.IsValid())
|
|
{
|
|
writeln_d("!!! No track for JOB: ", JOB.Name(), ", ", JOB.GetDescription(), ", ", targetTrackName);
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
double slantRangeTo = PLATFORM.SlantRangeTo(targetTrack);
|
|
double closingSpeed = PLATFORM.ClosingSpeedOf(targetTrack);
|
|
double maxWeaponRange = GetWeaponRangeMax(PLATFORM, mWeaponArray);
|
|
|
|
if (mFilterJobsOnFuel == true)
|
|
{
|
|
if (!HasEnoughFuelToTravel(PLATFORM,slantRangeTo-maxWeaponRange))
|
|
{
|
|
writeln_d("!!! Not enough fuel for JOB: ", JOB.Name(), ", ", JOB.GetDescription(), ", ", targetTrackName);
|
|
return cMIN_JOB_BID;
|
|
}
|
|
}
|
|
|
|
if (mFilterJobsOnCategory == true)
|
|
{
|
|
if (TestTrackCategory(targetTrack, "unknown"))
|
|
{
|
|
writeln_d("!!! Target type unknown for current job. ");
|
|
return cMIN_JOB_BID;
|
|
}
|
|
}
|
|
|
|
if (mFilterJobsOnWeapons == true)
|
|
{
|
|
//check here if we have any weapons remaining that are capable against target domain
|
|
if (!HaveWeaponsForThreat(targetTrack) &&
|
|
PROCESSOR.WeaponsActive(targetTrack) <= 0)
|
|
{
|
|
writeln_d("!!! No domain capable weapons left for target!");
|
|
return cMIN_JOB_BID;
|
|
}
|
|
}
|
|
|
|
if (mFilterJobsOnZone == true)
|
|
{
|
|
if (mZoneName != "")
|
|
{
|
|
mFezZone = PLATFORM.Zone(mZoneName);
|
|
if (!mFezZone.IsValid() || !mFezZone.PointIsInside(PLATFORM.Location()))
|
|
{
|
|
writeln_d("!!! Target outside of given FEZ!");
|
|
return cMIN_JOB_BID;
|
|
}
|
|
}
|
|
}
|
|
|
|
double weight_closing_speed = cWEIGHT_CLOSING_SPEED;
|
|
if (targetTrack.LandDomain())
|
|
{
|
|
weight_closing_speed = 2.0 * cWEIGHT_CLOSING_SPEED;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// calculate bulk of the bid HERE
|
|
double bid = 0.0;
|
|
bid += cWEIGHT_SLANT_RANGE_TO * (cMAX_SLANT_RANGE - slantRangeTo);
|
|
bid += weight_closing_speed * (-cMIN_CLOSING_SPEED + closingSpeed);
|
|
// the bid has its major contributers now
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//calculate other optional bid contributions here
|
|
WsfFuel fuelObj = PLATFORM.Fuel();
|
|
if (fuelObj.IsValid())
|
|
{
|
|
bid = bid + cWEIGHT_FUEL * fuelObj.QuantityRemaining();
|
|
}
|
|
//contribution if I have an active weapon on the target
|
|
bid = bid + cWEIGHT_MY_WEAPONS_ACTIVE * PROCESSOR.WeaponsActive(targetTrack);
|
|
//contribution if peers have an active weapon on the target
|
|
bid = bid + cWEIGHT_PEERS_WEAPONS_ACTIVE * PROCESSOR.PeersWeaponsActive(targetTrack);
|
|
//contribution if I am currently targeting the target
|
|
if (PROCESSOR.GetTargetName() == targetTrackName)
|
|
{
|
|
bid = bid + cWEIGHT_CURRENT_TARGET;
|
|
}
|
|
//contribution if any peers are targeting the target
|
|
WsfRIPRProcessor commander = PROCESSOR.GetRIPRCommanderProcessor();
|
|
if (commander.IsValid())
|
|
{
|
|
bid = bid + cWEIGHT_OTHERS_TARGETING * commander.SubsTargeting(targetTrack, PLATFORM);
|
|
}
|
|
//contribution bonus if you care about weapon envelopes
|
|
if (slantRangeTo < GetWeaponsEnvelope(targetTrack.Target()))
|
|
{
|
|
bid = bid + cWEIGHT_THREAT_WEAPONS_ENVELOPE;
|
|
}
|
|
//contribution bonus from threat type (category)
|
|
string targetType = DetermineTrackCategory(targetTrack);
|
|
if( ThreatTypePriority.Exists( targetType ) )
|
|
{
|
|
bid = bid + ThreatTypePriority.Get( targetType );
|
|
}
|
|
|
|
writeln_d(PLATFORM.Name(), " bid on target ", targetTrackName, ": ", bid);
|
|
return bid;
|
|
end_query_bid_type
|
|
|
|
|
|
query_bid_type cap-route
|
|
//writeln_d("BEHAVIOR NODE query_bid_type cap-route");
|
|
if (!JOB.IsValid())
|
|
{
|
|
return -MATH.DOUBLE_MAX();
|
|
}
|
|
double current_bid = 10000.0;
|
|
|
|
Map<string, Object>tempData = JOB.GetData();
|
|
WsfGeoPoint point = (WsfGeoPoint)tempData["location"];
|
|
double heading = (double)tempData["heading"];
|
|
string routeName = (string)tempData["route name"];
|
|
|
|
WsfRoute route = WsfRoute.FindGlobal(routeName);
|
|
|
|
if (!point.IsValid())
|
|
{
|
|
writeln("!!! Invalid point for current job: ",JOB.Name(), ", ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
if (!route.IsValid())
|
|
{
|
|
writeln("!!! Invalid route for job to bid on: ",JOB.Name(), ", ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
// check fuel levels
|
|
#extern bool HasEnoughFuelToTravelRoute(WsfPlatform,WsfRoute);
|
|
if (mFilterJobsOnFuel && !HasEnoughFuelToTravelRoute(PLATFORM,route))
|
|
{
|
|
writeln_d("!!! Not enough fuel for JOB: ", JOB.Name(), ", ", JOB.GetDescription());
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
double bid = 1000000 - PLATFORM.SlantRangeTo(point);
|
|
|
|
if (mRequiredWeaponForCap != "")
|
|
{
|
|
double Q = PLATFORM.Weapon(mRequiredWeaponForCap).QuantityRemaining();
|
|
if (Q <= 0)
|
|
{
|
|
return 0.001;
|
|
}
|
|
bid = bid + 20000 * Q;
|
|
}
|
|
|
|
return bid;
|
|
end_query_bid_type
|
|
|
|
|
|
query_bid_type pincer
|
|
//writeln_d("BEHAVIOR NODE querybid_type pincer");
|
|
if (!JOB.IsValid())
|
|
{
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
double current_bid = 10000.0;
|
|
WsfGeoPoint point = (WsfGeoPoint)JOB.GetData("ZonePoint");
|
|
if (!point.IsValid())
|
|
{
|
|
writeln_d("!!! Invalid point for current job: ",JOB.Name(), ", ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
##extern Map<string, double> ThreatTypePriority;
|
|
#extern string DetermineTrackCategory (WsfTrack);
|
|
#extern bool TestTrackCategory (WsfTrack, string);
|
|
#extern double GetWeaponsEnvelope (WsfPlatform);
|
|
double slantRangeTo = PLATFORM.SlantRangeTo(point);
|
|
|
|
// calculate bulk of the bid now //
|
|
double weight_closing_speed = 2.0 * cWEIGHT_CLOSING_SPEED;
|
|
double closingSpeed = PLATFORM.Speed() * MATH.Cos(PLATFORM.RelativeBearingTo(point));
|
|
current_bid += cWEIGHT_SLANT_RANGE_TO * (cMAX_SLANT_RANGE - slantRangeTo);
|
|
current_bid += weight_closing_speed * (-cMIN_CLOSING_SPEED + closingSpeed);
|
|
// // // // // // // // // //
|
|
|
|
WsfFuel fuelObj = PLATFORM.Fuel();
|
|
if (fuelObj .IsValid())
|
|
{
|
|
current_bid = current_bid + cWEIGHT_FUEL * fuelObj.QuantityRemaining();
|
|
}
|
|
current_bid = current_bid + cWEIGHT_MY_WEAPONS_ACTIVE * PROCESSOR.WeaponsActive();
|
|
|
|
# if (slantRangeTo < GetWeaponsEnvelope(targetTrack.Target()))
|
|
# {
|
|
current_bid = current_bid + cWEIGHT_THREAT_WEAPONS_ENVELOPE;
|
|
# }
|
|
# if( ThreatTypePriority.Exists( targetType ) )
|
|
# { # current_bid = current_bid + ThreatTypePriority.Get( targetType ); # }
|
|
//lets include these in just so this bid is equally competitive with pursue-target jobs
|
|
current_bid = current_bid + cWEIGHT_CURRENT_TARGET;
|
|
//current_bid = current_bid + cWEIGHT_PEERS_WEAPONS_ACTIVE * (PROCESSOR.PeersWeaponsActive());
|
|
|
|
#extern Map<string, double> ThreatTypePriority;
|
|
#extern string DetermineTrackCategory(WsfTrack);
|
|
#extern WsfTrack GetTrackByName (WsfPlatform, string);
|
|
Array<string> targetNames = (Array<string>)JOB.GetData("ZoneThreatNameArray");
|
|
foreach(string tgtName in targetNames)
|
|
{
|
|
WsfTrack tgt = GetTrackByName(PLATFORM, tgtName);
|
|
if (tgt.IsValid())
|
|
{
|
|
string targetType = DetermineTrackCategory(tgt);
|
|
if( ThreatTypePriority.Exists( targetType ) )
|
|
{
|
|
current_bid = current_bid + ThreatTypePriority.Get( targetType );
|
|
}
|
|
}
|
|
}
|
|
return current_bid;
|
|
end_query_bid_type
|
|
|
|
|
|
query_bid_type pursue-point
|
|
writeln_d("BEHAVIOR NODE query_bid_type pursue-point");
|
|
if (!JOB.IsValid())
|
|
{
|
|
return cMIN_JOB_BID;
|
|
}
|
|
double current_bid = 10000.0;
|
|
WsfGeoPoint point = (WsfGeoPoint)JOB.GetData("targetPoint");
|
|
if (!point.IsValid())
|
|
{
|
|
writeln_d("!!! Invalid point for current job: ",JOB.Name(), ", ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
double distToPoint = PLATFORM.SlantRangeTo(point);
|
|
|
|
// check fuel levels
|
|
#extern bool HasEnoughFuelToTravel(WsfPlatform,double);
|
|
if (mFilterJobsOnFuel &&
|
|
!HasEnoughFuelToTravel(PLATFORM,distToPoint))
|
|
{
|
|
writeln_d("!!! Not enough fuel for JOB: ", JOB.Name(), ", ", JOB.GetDescription());
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
current_bid += cWEIGHT_SLANT_RANGE_TO * (cMAX_SLANT_RANGE - distToPoint);
|
|
|
|
return current_bid;
|
|
end_query_bid_type
|
|
|
|
|
|
query_bid_type weapon_uplink
|
|
|
|
writeln_d("BEHAVIOR NODE query_bid_type weapon_uplink");
|
|
|
|
if (!JOB.IsValid())
|
|
{
|
|
return cMIN_JOB_BID;
|
|
}
|
|
double current_bid = 10000.0;
|
|
//check if I can support this weapon
|
|
#extern WsfTrack GetTrackByName(WsfPlatform, string);
|
|
|
|
string name = (string)JOB.GetData("targetTrackName");
|
|
int weaponPlatformIndex = (int)JOB.GetData("weaponPlatformIndex");
|
|
int targetPlatformIndex = (int)JOB.GetData("targetPlatformIndex");
|
|
|
|
WsfTrack track = GetTrackByName(PLATFORM, name);
|
|
WsfPlatform weaponPlatform = WsfSimulation.FindPlatform(weaponPlatformIndex);
|
|
WsfPlatform targetPlatform = WsfSimulation.FindPlatform(targetPlatformIndex);
|
|
WsfLocalTrack t = (WsfLocalTrack)track;
|
|
if (!weaponPlatform.IsValid() ||
|
|
!targetPlatform.IsValid() ||
|
|
!track.IsValid())
|
|
{
|
|
writeln_d("!!! Invalid weapon or target for job: ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
if (!mAllowCoopEngage &&
|
|
!t.ContributorOf(PLATFORM))
|
|
{
|
|
return cMIN_JOB_BID;
|
|
}
|
|
|
|
if (PLATFORM.WithinFieldOfView(targetPlatform, mUplinkSensorName))
|
|
{
|
|
double alreadyUplinking = 0.0;
|
|
if (PROCESSOR.IsUplinkingTo(weaponPlatform))
|
|
{
|
|
alreadyUplinking = 1.0;
|
|
}
|
|
current_bid += cWEIGHT_SLANT_RANGE_TO * (cMAX_SLANT_RANGE - PLATFORM.SlantRangeTo(targetPlatform));
|
|
current_bid += cWEIGHT_CLOSING_SPEED * (-cMIN_CLOSING_SPEED + PLATFORM.ClosingSpeedOf(targetPlatform));
|
|
current_bid += cWEIGHT_CURRENT_TARGET * alreadyUplinking;
|
|
}
|
|
else
|
|
{
|
|
writeln_d("!!! target for uplink job is out of view: ", JOB.GetDescription() );
|
|
return cMIN_JOB_BID;
|
|
}
|
|
//writeln_d(" uplink returning calculated bid: ", current_bid);
|
|
return current_bid;
|
|
end_query_bid_type
|
|
|
|
|
|
|
|
########################################################################
|
|
### this script block is executed every update interval
|
|
### it runs before the behavior tree
|
|
########################################################################
|
|
# on_update
|
|
# #double startTime = PROCESSOR.WallClockTime();
|
|
# writeln_d(PLATFORM.Name(), " executing on update!");
|
|
# #double duration = PROCESSOR.WallClockTime() - startTime;
|
|
# #writeln_d("AIAI-thinker on update duration = ", duration);
|
|
# end_on_update
|
|
|
|
end_processor
|
|
|